Private
Public Access
1
0

style: apply cargo fmt formatting
Some checks failed
CI/CD Pipeline / Code Format (push) Successful in 3s
CI/CD Pipeline / Clippy Lints (push) Failing after 44s
CI/CD Pipeline / Enrollment Tests (push) Has been skipped
CI/CD Pipeline / Verify Enrollment CLI Flag (push) Has been skipped
CI/CD Pipeline / All Unit Tests (push) Successful in 1m12s
CI/CD Pipeline / Build Debian Package (push) Has been skipped
CI/CD Pipeline / Build Debian Package (Ubuntu 22.04) (push) Has been skipped
CI/CD Pipeline / Build RPM Package (push) Has been skipped
CI/CD Pipeline / Build Alpine Package (push) Has been skipped
CI/CD Pipeline / Build Arch Package (push) Has been skipped
CI/CD Pipeline / Security Audit (push) Successful in 5s

This commit is contained in:
2026-05-18 02:06:25 +00:00
parent 7c55c99e48
commit 0d582f2fda
5 changed files with 33 additions and 31 deletions

View File

@ -165,10 +165,7 @@ pub fn get_primary_ip(report_interface: Option<&str>, report_ip: Option<&str>) -
// Validate it parses as IPv4 // Validate it parses as IPv4
if let Ok(addr) = ip.parse::<Ipv4Addr>() { if let Ok(addr) = ip.parse::<Ipv4Addr>() {
if !addr.is_loopback() { if !addr.is_loopback() {
tracing::info!( tracing::info!(ip = ip, "Using explicitly configured report_ip");
ip = ip,
"Using explicitly configured report_ip"
);
return Ok(ip.to_string()); return Ok(ip.to_string());
} }
tracing::warn!( tracing::warn!(
@ -375,7 +372,10 @@ mod tests {
Ok(ip) => { Ok(ip) => {
assert!(!ip.is_empty(), "Primary IP should not be empty"); assert!(!ip.is_empty(), "Primary IP should not be empty");
let parsed: Ipv4Addr = ip.parse().expect("Primary IP should be valid IPv4"); let parsed: Ipv4Addr = ip.parse().expect("Primary IP should be valid IPv4");
assert!(!is_container_bridge(&parsed), "Auto-detected IP should not be Docker bridge"); assert!(
!is_container_bridge(&parsed),
"Auto-detected IP should not be Docker bridge"
);
} }
Err(_) => { Err(_) => {
eprintln!("NOTE: No routable IPs found — likely running inside a Docker container"); eprintln!("NOTE: No routable IPs found — likely running inside a Docker container");
@ -386,8 +386,7 @@ mod tests {
#[test] #[test]
fn test_get_primary_ip_explicit_override() { fn test_get_primary_ip_explicit_override() {
// Explicit IP should be returned as-is // Explicit IP should be returned as-is
let ip = get_primary_ip(None, Some("10.99.99.1")) let ip = get_primary_ip(None, Some("10.99.99.1")).expect("Failed with explicit IP");
.expect("Failed with explicit IP");
assert_eq!(ip, "10.99.99.1"); assert_eq!(ip, "10.99.99.1");
} }
@ -398,7 +397,9 @@ mod tests {
match get_primary_ip(None, Some("127.0.0.1")) { match get_primary_ip(None, Some("127.0.0.1")) {
Ok(ip) => assert_ne!(ip, "127.0.0.1"), Ok(ip) => assert_ne!(ip, "127.0.0.1"),
Err(_) => { Err(_) => {
eprintln!("NOTE: Loopback rejected but no routable IPs for fallback — Docker container"); eprintln!(
"NOTE: Loopback rejected but no routable IPs for fallback — Docker container"
);
} }
} }
} }
@ -410,7 +411,9 @@ mod tests {
match get_primary_ip(None, Some("not-an-ip")) { match get_primary_ip(None, Some("not-an-ip")) {
Ok(ip) => assert!(!ip.is_empty()), Ok(ip) => assert!(!ip.is_empty()),
Err(_) => { Err(_) => {
eprintln!("NOTE: Invalid IP rejected but no routable IPs for fallback — Docker container"); eprintln!(
"NOTE: Invalid IP rejected but no routable IPs for fallback — Docker container"
);
} }
} }
} }

View File

@ -15,7 +15,10 @@ pub use client::{
EnrollmentClient, EnrollmentRequest, EnrollmentResponse, EnrollmentStatusResponse, PkiBundle, EnrollmentClient, EnrollmentRequest, EnrollmentResponse, EnrollmentStatusResponse, PkiBundle,
}; };
/// Re-export identity extraction functions. /// Re-export identity extraction functions.
pub use identity::{get_fqdn, get_ip_addresses, get_ip_for_interface, get_machine_id, get_os_details, get_primary_ip, is_container_bridge, is_link_local}; pub use identity::{
get_fqdn, get_ip_addresses, get_ip_for_interface, get_machine_id, get_os_details,
get_primary_ip, is_container_bridge, is_link_local,
};
/// Run the full enrollment flow against the manager at the given URL. /// Run the full enrollment flow against the manager at the given URL.
/// ///

View File

@ -85,11 +85,7 @@ fn build_tls_config(cert_dir: &std::path::Path) -> TlsConfig {
/// Uses a test report_ip so enrollment works inside Docker containers /// Uses a test report_ip so enrollment works inside Docker containers
/// where the only IPs are in the 172.16.0.0/12 bridge range (filtered). /// where the only IPs are in the 172.16.0.0/12 bridge range (filtered).
fn build_client(base_url: &str) -> EnrollmentClient { fn build_client(base_url: &str) -> EnrollmentClient {
EnrollmentClient::with_ip_overrides( EnrollmentClient::with_ip_overrides(base_url, None, Some("192.168.1.10".to_string()))
base_url,
None,
Some("192.168.1.10".to_string()),
)
} }
// ============================================================================= // =============================================================================

View File

@ -36,11 +36,7 @@ async fn create_mock_manager() -> (MockServer, String) {
/// Uses a test report_ip so enrollment works inside Docker containers /// Uses a test report_ip so enrollment works inside Docker containers
/// where the only IPs are in the 172.16.0.0/12 bridge range (filtered). /// where the only IPs are in the 172.16.0.0/12 bridge range (filtered).
fn build_client(base_url: &str) -> EnrollmentClient { fn build_client(base_url: &str) -> EnrollmentClient {
EnrollmentClient::with_ip_overrides( EnrollmentClient::with_ip_overrides(base_url, None, Some("192.168.1.10".to_string()))
base_url,
None,
Some("192.168.1.10".to_string()),
)
} }
// ============================================================================= // =============================================================================

View File

@ -4,8 +4,8 @@
//! Verifies machine-id, FQDN, IP address collection, and OS detail parsing. //! Verifies machine-id, FQDN, IP address collection, and OS detail parsing.
use linux_patch_api::enroll::identity::{ use linux_patch_api::enroll::identity::{
get_fqdn, get_ip_addresses, get_machine_id, get_os_details, get_fqdn, get_ip_addresses, get_machine_id, get_os_details, get_primary_ip,
get_primary_ip, is_container_bridge, is_link_local, is_container_bridge, is_link_local,
}; };
use linux_patch_api::enroll::EnrollmentRequest; use linux_patch_api::enroll::EnrollmentRequest;
use serde_json::Value; use serde_json::Value;
@ -367,7 +367,10 @@ fn test_enrollment_payload_construction() {
let os_details = get_os_details().expect("Failed to get OS details"); let os_details = get_os_details().expect("Failed to get OS details");
// In Docker containers, all IPs may be in 172.16.0.0/12 (filtered), so use fallback // In Docker containers, all IPs may be in 172.16.0.0/12 (filtered), so use fallback
let primary_ip = ip_addrs.first().cloned().unwrap_or_else(|| "127.0.0.1".to_string()); let primary_ip = ip_addrs
.first()
.cloned()
.unwrap_or_else(|| "127.0.0.1".to_string());
let request = EnrollmentRequest { let request = EnrollmentRequest {
machine_id, machine_id,
@ -559,8 +562,7 @@ fn test_is_not_link_local() {
fn test_get_ip_addresses_excludes_docker_bridge() { fn test_get_ip_addresses_excludes_docker_bridge() {
let addrs = get_ip_addresses().expect("Failed to get IP addresses"); let addrs = get_ip_addresses().expect("Failed to get IP addresses");
for addr in &addrs { for addr in &addrs {
let parsed: std::net::Ipv4Addr = let parsed: std::net::Ipv4Addr = addr.parse().expect("Should parse as IPv4");
addr.parse().expect("Should parse as IPv4");
assert!( assert!(
!is_container_bridge(&parsed), !is_container_bridge(&parsed),
"IP '{}' is in Docker bridge range 172.16.0.0/12 — should be excluded", "IP '{}' is in Docker bridge range 172.16.0.0/12 — should be excluded",
@ -573,8 +575,7 @@ fn test_get_ip_addresses_excludes_docker_bridge() {
fn test_get_ip_addresses_excludes_link_local() { fn test_get_ip_addresses_excludes_link_local() {
let addrs = get_ip_addresses().expect("Failed to get IP addresses"); let addrs = get_ip_addresses().expect("Failed to get IP addresses");
for addr in &addrs { for addr in &addrs {
let parsed: std::net::Ipv4Addr = let parsed: std::net::Ipv4Addr = addr.parse().expect("Should parse as IPv4");
addr.parse().expect("Should parse as IPv4");
assert!( assert!(
!is_link_local(&parsed), !is_link_local(&parsed),
"IP '{}' is link-local 169.254.0.0/16 — should be excluded", "IP '{}' is link-local 169.254.0.0/16 — should be excluded",
@ -603,8 +604,7 @@ fn test_get_primary_ip_auto_detect_no_bridge() {
#[test] #[test]
fn test_get_primary_ip_explicit_override() { fn test_get_primary_ip_explicit_override() {
let ip = get_primary_ip(None, Some("10.99.99.1")) let ip = get_primary_ip(None, Some("10.99.99.1")).expect("Failed with explicit IP");
.expect("Failed with explicit IP");
assert_eq!(ip, "10.99.99.1"); assert_eq!(ip, "10.99.99.1");
} }
@ -614,7 +614,9 @@ fn test_get_primary_ip_rejects_loopback_override() {
match get_primary_ip(None, Some("127.0.0.1")) { match get_primary_ip(None, Some("127.0.0.1")) {
Ok(ip) => assert_ne!(ip, "127.0.0.1"), Ok(ip) => assert_ne!(ip, "127.0.0.1"),
Err(_) => { Err(_) => {
eprintln!("NOTE: Loopback rejected but no routable IPs for fallback — Docker container"); eprintln!(
"NOTE: Loopback rejected but no routable IPs for fallback — Docker container"
);
} }
} }
} }
@ -625,7 +627,9 @@ fn test_get_primary_ip_invalid_override_falls_back() {
match get_primary_ip(None, Some("not-an-ip")) { match get_primary_ip(None, Some("not-an-ip")) {
Ok(ip) => assert!(!ip.is_empty()), Ok(ip) => assert!(!ip.is_empty()),
Err(_) => { Err(_) => {
eprintln!("NOTE: Invalid IP rejected but no routable IPs for fallback — Docker container"); eprintln!(
"NOTE: Invalid IP rejected but no routable IPs for fallback — Docker container"
);
} }
} }
} }