diff --git a/src/ocp_postprocess/proxy_rename.rs b/src/ocp_postprocess/proxy_rename.rs index 947447e0..d526346f 100644 --- a/src/ocp_postprocess/proxy_rename.rs +++ b/src/ocp_postprocess/proxy_rename.rs @@ -46,6 +46,8 @@ async fn fix_dir_resources(proxy: &Proxy, dir: &Path) -> Result<()> { .await .context("renaming currentconfig")?; + filesystem_rename::fix_pods_yaml(proxy, dir).await.context("renaming pod yaml")?; + Ok(()) } @@ -64,5 +66,9 @@ async fn fix_etcd_resources(etcd_client: &Arc, proxy: &Proxy) - etcd_rename::fix_proxy(etcd_client, proxy).await.context("fixing proxy")?; + etcd_rename::fix_controllerconfigs(etcd_client, proxy) + .await + .context("fixing machineconfigs")?; + Ok(()) } diff --git a/src/ocp_postprocess/proxy_rename/etcd_rename.rs b/src/ocp_postprocess/proxy_rename/etcd_rename.rs index ae7e370b..9e3dcf0d 100644 --- a/src/ocp_postprocess/proxy_rename/etcd_rename.rs +++ b/src/ocp_postprocess/proxy_rename/etcd_rename.rs @@ -85,3 +85,47 @@ pub(crate) async fn fix_proxy(etcd_client: &InMemoryK8sEtcd, proxy: &Proxy) -> R Ok(()) } + +pub(crate) async fn fix_controllerconfigs(etcd_client: &InMemoryK8sEtcd, proxy: &Proxy) -> Result<()> { + join_all( + etcd_client + .list_keys("machineconfiguration.openshift.io/controllerconfigs/machine-config-controller") + .await? + .into_iter() + .map(|key| async move { + let etcd_result = etcd_client + .get(key.clone()) + .await + .with_context(|| format!("getting key {:?}", key))? + .context("key disappeared")?; + + let value: Value = serde_yaml::from_slice(etcd_result.value.as_slice()) + .with_context(|| format!("deserializing value of key {:?}", key,))?; + + let k8s_resource_location = K8sResourceLocation::try_from(&value)?; + + let mut cluster_proxy = get_etcd_json(etcd_client, &k8s_resource_location) + .await? + .context("no machineconfig")?; + + let spec_proxy = cluster_proxy + .pointer_mut("/spec/proxy") + .context("no /spec/proxy")? + .as_object_mut() + .context("/spec/proxy not an object")?; + + spec_proxy.insert("httpProxy".to_string(), Value::String(proxy.http_proxy.clone())); + spec_proxy.insert("httpsProxy".to_string(), Value::String(proxy.https_proxy.clone())); + spec_proxy.insert("noProxy".to_string(), Value::String(proxy.no_proxy.clone())); + + put_etcd_yaml(etcd_client, &k8s_resource_location, cluster_proxy).await?; + + Ok(()) + }), + ) + .await + .into_iter() + .collect::>>()?; + + Ok(()) +} diff --git a/src/ocp_postprocess/proxy_rename/filesystem_rename.rs b/src/ocp_postprocess/proxy_rename/filesystem_rename.rs index 2d8cdb42..9a52a2bd 100644 --- a/src/ocp_postprocess/proxy_rename/filesystem_rename.rs +++ b/src/ocp_postprocess/proxy_rename/filesystem_rename.rs @@ -97,3 +97,34 @@ pub(crate) async fn fix_filesystem_currentconfig(proxy: &Proxy, dir: &Path) -> R Ok(()) } + +pub(crate) async fn fix_pods_yaml(proxy: &Proxy, dir: &Path) -> Result<()> { + join_all(file_utils::globvec(dir, "**/*pod.yaml")?.into_iter().map(|file_path| { + let pod_path = file_path.clone(); + let proxy = proxy.clone(); + tokio::spawn(async move { + async move { + let contents = read_file_to_string(&file_path).await.context("reading pods.yaml")?; + + let mut config: Value = serde_yaml::from_str(&contents).context("parsing pods.yaml")?; + + fix_containers_proxy(&mut config, &proxy)?; + + commit_file(file_path, serde_yaml::to_string(&config).context("serializing pods.yaml")?) + .await + .context("writing pods.yaml to disk")?; + + anyhow::Ok(()) + } + .await + .context(format!("fixing pods.yaml {:?}", pod_path)) + }) + })) + .await + .into_iter() + .collect::, _>>()? + .into_iter() + .collect::>>()?; + + Ok(()) +} diff --git a/src/ocp_postprocess/proxy_rename/utils.rs b/src/ocp_postprocess/proxy_rename/utils.rs index 157d0e1e..3e8eafcf 100644 --- a/src/ocp_postprocess/proxy_rename/utils.rs +++ b/src/ocp_postprocess/proxy_rename/utils.rs @@ -69,3 +69,81 @@ pub(crate) fn fix_machineconfig(machineconfig: &mut Value, proxy: &Proxy) -> Res Ok(()) } + +pub(crate) fn fix_containers_proxy(config: &mut Value, proxy: &Proxy) -> Result<()> { + let prefix = match config.pointer("kind").context("no /kind")?.as_str().context("kind not a string")? { + "Deployment" | "DaemonSet" | "StatefulSet" | "ReplicaSet" => "/spec/template/spec/", + "Pod" => "/spec/", + }; + + let suffixes = &["containers", "initContainers"]; + + for suffix in suffixes { + let pointer_mut = config.pointer_mut(format!("{prefix}/{suffix}").as_str()); + + let containers = match pointer_mut { + Some(containers) => containers, + None => continue, + }; + + for container in containers.as_array_mut().context("containers not an array")? { + let container_env = container + .pointer_mut("/env") + .context("no /env")? + .as_array_mut() + .context("env not an array")?; + + let proxies = [ + ( + "HTTP_PROXY", + if !proxy.http_proxy.is_empty() { + Some(proxy.http_proxy.as_str()) + } else { + None + }, + ), + ( + "HTTPS_PROXY", + if !proxy.https_proxy.is_empty() { + Some(proxy.https_proxy.as_str()) + } else { + None + }, + ), + ( + "NO_PROXY", + if !proxy.no_proxy.is_empty() { + Some(proxy.no_proxy.as_str()) + } else { + None + }, + ), + ]; + + for (proxy_env_name, desired_proxy_env_value) in proxies.iter() { + match desired_proxy_env_value { + Some(desired_proxy_env_value) => { + let found_env = container_env + .iter_mut() + .find_map(|env| (env.pointer("/name")? == proxy_env_name).then_some(env)); + + match found_env { + Some(env) => { + env["value"] = serde_json::Value::String(desired_proxy_env_value.to_string()); + } + None => { + container_env.push(serde_json::json!({"name": proxy_env_name, "value": desired_proxy_env_value})); + } + } + } + None => { + // Remove the env var if it exists + container_env.retain(|env| env.pointer("/name")? != proxy_env_name); + } + } + } + } + } + + Ok(()) +}