Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 20 additions & 34 deletions src/ocp_postprocess/ip_rename.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,15 @@ pub(crate) async fn rename_all_dual_stack(
.await
.context("extracting original dual-stack IPs")?;

ensure!(
original_ips.len() == ips.len(),
"original IPs count ({}) must equal new IPs count ({})",
original_ips.len(),
ips.len()
);

log::info!("Applying dual-stack IP changes");

fix_etcd_resources_dual_stack(etcd_client, &original_ips, ips)
.await
.context("modifying etcd resources for dual stack")?;
Expand Down Expand Up @@ -73,15 +82,11 @@ async fn fix_dir_resources(original_ip: &str, ip: &str, dir: &Path) -> Result<()
}

async fn fix_dir_resources_dual_stack(original_ips: &[String], ips: &[String], dir: &Path) -> Result<()> {
// Apply IPv4 replacement (original IPv4 → new IPv4)
filesystem_rename::fix_filesystem_ip(&original_ips[0], &ips[0], dir)
.await
.context(format!("fix filesystem IPv4 in {:?}", dir))?;

// Apply IPv6 replacement (original IPv6 → new IPv6) - both are guaranteed to be present
filesystem_rename::fix_filesystem_ip(&original_ips[1], &ips[1], dir)
.await
.context(format!("fix filesystem IPv6 in {:?}", dir))?;
for (idx, (original_ip, new_ip)) in original_ips.iter().zip(ips.iter()).enumerate() {
filesystem_rename::fix_filesystem_ip(original_ip, new_ip, dir)
.await
.context(format!("fix filesystem IP replacement pair {} in {:?}", idx, dir))?;
}

Ok(())
}
Expand Down Expand Up @@ -181,31 +186,12 @@ async fn extract_original_dual_stack_ips(etcd_client: &Arc<InMemoryK8sEtcd>) ->
}

async fn fix_etcd_resources_dual_stack(etcd_client: &Arc<InMemoryK8sEtcd>, original_ips: &[String], new_ips: &[String]) -> Result<()> {
let original_ipv4 = &original_ips[0];
let original_ipv6 = &original_ips[1];

let new_ipv4 = &new_ips[0];
let new_ipv6 = new_ips.get(1).context("Second IP (IPv6) is required for dual-stack processing")?;

log::info!(
"Applying dual-stack IP changes - IPv4: {} → {}, IPv6: {} → {}",
original_ipv4,
new_ipv4,
original_ipv6,
new_ipv6
);

log::info!("Applying IPv4 replacements: {} → {}", original_ipv4, new_ipv4);

fix_etcd_resources_for_ip_pair(etcd_client, original_ipv4, new_ipv4)
.await
.context("applying IPv4 etcd resource fixes")?;

log::info!("Applying IPv6 replacements: {} → {}", original_ipv6, new_ipv6);

fix_etcd_resources_for_ip_pair(etcd_client, original_ipv6, new_ipv6)
.await
.context("applying IPv6 etcd resource fixes")?;
for (idx, (original_ip, new_ip)) in original_ips.iter().zip(new_ips.iter()).enumerate() {
log::info!("Applying replacements pair {}: {} → {}", idx, original_ip, new_ip);
fix_etcd_resources_for_ip_pair(etcd_client, original_ip, new_ip)
.await
.context(format!("applying etcd resource fixes for pair {}", idx))?;
}
Comment on lines +189 to +194
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Avoid logging IPs at info level; downgrade to debug.

IPs can be sensitive operational data and are noisy at info. Keep the message but at debug.

-        log::info!("Applying replacements pair {}: {} → {}", idx, original_ip, new_ip);
+        log::debug!("Applying replacements pair {}: {} → {}", idx, original_ip, new_ip);
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
for (idx, (original_ip, new_ip)) in original_ips.iter().zip(new_ips.iter()).enumerate() {
log::info!("Applying replacements pair {}: {} → {}", idx, original_ip, new_ip);
fix_etcd_resources_for_ip_pair(etcd_client, original_ip, new_ip)
.await
.context(format!("applying etcd resource fixes for pair {}", idx))?;
}
for (idx, (original_ip, new_ip)) in original_ips.iter().zip(new_ips.iter()).enumerate() {
log::debug!("Applying replacements pair {}: {} → {}", idx, original_ip, new_ip);
fix_etcd_resources_for_ip_pair(etcd_client, original_ip, new_ip)
.await
.context(format!("applying etcd resource fixes for pair {}", idx))?;
}
🤖 Prompt for AI Agents
In src/ocp_postprocess/ip_rename.rs around lines 189 to 194, the code logs IP
addresses at info level; change the log call from info to debug so the same
replacement message is retained but emitted at debug level
(log::debug!("Applying replacements pair {}: {} → {}", idx, original_ip,
new_ip);), leaving the rest of the loop and error handling unchanged.


Ok(())
}
30 changes: 4 additions & 26 deletions src/ocp_postprocess/ip_rename/etcd_rename.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,9 @@ use crate::{
use anyhow::{bail, ensure, Context, Result};
use futures_util::future::join_all;
use serde_json::Value;
use std::net::{IpAddr, Ipv6Addr};
use std::net::Ipv6Addr;
use std::sync::Arc;

fn is_ipv6(ip: &str) -> Result<bool> {
let addr = ip
.parse::<IpAddr>()
.with_context(|| format!("Failed to parse IP address: {}", ip))?;
Ok(addr.is_ipv6())
}

// Extract both original IPv4 and IPv6 IPs from dual-stack cluster node configuration
pub(crate) async fn extract_original_ips(etcd_client: &Arc<InMemoryK8sEtcd>) -> Result<Vec<String>> {
// Extract IPs from node addresses - works for both single-stack and dual-stack
Expand Down Expand Up @@ -43,40 +36,25 @@ async fn extract_original_ips_from_nodes(etcd_client: &Arc<InMemoryK8sEtcd>) ->
.and_then(|a| a.as_array())
.context("Node does not have /status/addresses array")?;

let mut original_ipv4: Option<String> = None;
let mut original_ipv6: Option<String> = None;
let mut result = Vec::new();

for address in addresses {
if let (Some(addr_type), Some(addr_value)) = (
address.pointer("/type").and_then(|t| t.as_str()),
address.pointer("/address").and_then(|a| a.as_str()),
) {
if addr_type == "InternalIP" {
if is_ipv6(addr_value)? {
original_ipv6 = Some(addr_value.to_string());
} else {
original_ipv4 = Some(addr_value.to_string());
}
result.push(addr_value.to_string());
}
}
}

let mut result = Vec::new();

if let Some(ipv4) = original_ipv4 {
result.push(ipv4);
}

if let Some(ipv6) = original_ipv6 {
result.push(ipv6);
}

ensure!(!result.is_empty(), "No InternalIP addresses found in node configuration");

if result.len() == 1 {
log::info!("Found single-stack IP: {}", result[0]);
} else {
log::info!("Found dual-stack IPs - IPv4: {}, IPv6: {}", result[0], result[1]);
log::info!("Found {} InternalIP(s) {}", result.len(), result.join(", "));
}

Ok(result)
Expand Down
Loading