Skip to content

Commit 6beeff0

Browse files
Merge pull request #730 from danmanor/remove-pods-nodes-ip-change
MGMT-22237: Implement the required changes for IP Configuration flow
2 parents 99eed60 + 826b003 commit 6beeff0

File tree

4 files changed

+116
-1
lines changed

4 files changed

+116
-1
lines changed

src/etcd_encoding.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use super::protobuf_gen::{
55
admissionregistration::v1::{MutatingWebhookConfiguration, ValidatingWebhookConfiguration},
66
apps::v1::{ControllerRevision, DaemonSet, Deployment, StatefulSet},
77
batch::v1::{CronJob, Job},
8-
core::v1::{ConfigMap, Node, Secret},
8+
core::v1::{ConfigMap, Node, Pod, Secret},
99
},
1010
apimachinery::pkg::runtime::{TypeMeta, Unknown},
1111
},
@@ -58,6 +58,7 @@ k8s_type!(StatefulSetWithMeta, StatefulSet);
5858
k8s_type!(ConfigMapWithMeta, ConfigMap);
5959
k8s_type!(NodeWithMeta, Node);
6060
k8s_type!(SecretWithMeta, Secret);
61+
k8s_type!(PodWithMeta, Pod);
6162
k8s_type!(ValidatingWebhookConfigurationWithMeta, ValidatingWebhookConfiguration);
6263
k8s_type!(MutatingWebhookConfigurationWithMeta, MutatingWebhookConfiguration);
6364
k8s_type!(OAuthClientWithMeta, OAuthClient);
@@ -89,6 +90,7 @@ pub(crate) async fn decode(data: &[u8]) -> Result<Vec<u8>> {
8990
"ConfigMap" => serde_json::to_vec(&ConfigMapWithMeta::try_from(unknown)?)?,
9091
"Node" => serde_json::to_vec(&NodeWithMeta::try_from(unknown)?)?,
9192
"Secret" => serde_json::to_vec(&SecretWithMeta::try_from(unknown)?)?,
93+
"Pod" => serde_json::to_vec(&PodWithMeta::try_from(unknown)?)?,
9294
"ValidatingWebhookConfiguration" => serde_json::to_vec(&ValidatingWebhookConfigurationWithMeta::try_from(unknown)?)?,
9395
"MutatingWebhookConfiguration" => serde_json::to_vec(&MutatingWebhookConfigurationWithMeta::try_from(unknown)?)?,
9496
"OAuthClient" => serde_json::to_vec(&OAuthClientWithMeta::try_from(unknown)?)?,
@@ -111,6 +113,8 @@ pub(crate) async fn encode(data: &[u8]) -> Result<Vec<u8>> {
111113
"ConfigMap" => Unknown::from(serde_json::from_slice::<ConfigMapWithMeta>(data)?),
112114
"Route" => Unknown::from(serde_json::from_slice::<RouteWithMeta>(data)?),
113115
"Secret" => Unknown::from(serde_json::from_slice::<SecretWithMeta>(data)?),
116+
"Node" => Unknown::from(serde_json::from_slice::<NodeWithMeta>(data)?),
117+
"Pod" => Unknown::from(serde_json::from_slice::<PodWithMeta>(data)?),
114118
"Deployment" => Unknown::from(serde_json::from_slice::<DeploymentWithMeta>(data)?),
115119
"ControllerRevision" => Unknown::from(serde_json::from_slice::<ControllerRevisionWithMeta>(data)?),
116120
"Job" => Unknown::from(serde_json::from_slice::<JobWithMeta>(data)?),

src/ocp_postprocess/ip_rename.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,14 @@ async fn fix_etcd_resources_for_ip_pair(etcd_client: &Arc<InMemoryK8sEtcd>, orig
149149
.await
150150
.context("fixing etcd member")?;
151151

152+
etcd_rename::fix_pods_status(etcd_client, original_ip, new_ip)
153+
.await
154+
.context("fixing pods status")?;
155+
156+
etcd_rename::delete_minions_if_exist(etcd_client)
157+
.await
158+
.context("deleting minions if exist")?;
159+
152160
Ok(())
153161
}
154162

src/ocp_postprocess/ip_rename/etcd_rename.rs

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -597,6 +597,108 @@ pub(crate) async fn fix_etcd_member(etcd_client: &Arc<InMemoryK8sEtcd>, original
597597
Ok(())
598598
}
599599

600+
pub(crate) async fn fix_pods_status(etcd_client: &Arc<InMemoryK8sEtcd>, original_ip: &str, ip: &str) -> Result<()> {
601+
// Only mutate known Pod status IP fields if they equal the original IP
602+
fn replace_status_ips(pod: &mut Value, original_ip: &str, new_ip: &str) -> Result<bool> {
603+
let mut changed = false;
604+
605+
// status.podIP
606+
if let Some(v) = pod.pointer_mut("/status/podIP") {
607+
if let Some(curr) = v.as_str() {
608+
if curr == original_ip {
609+
*v = Value::String(new_ip.to_string());
610+
changed = true;
611+
}
612+
}
613+
}
614+
615+
// status.hostIP
616+
if let Some(v) = pod.pointer_mut("/status/hostIP") {
617+
if let Some(curr) = v.as_str() {
618+
if curr == original_ip {
619+
*v = Value::String(new_ip.to_string());
620+
changed = true;
621+
}
622+
}
623+
}
624+
625+
// status.podIPs (array of objects {ip: string} or strings)
626+
if let Some(arr) = pod.pointer_mut("/status/podIPs").and_then(|v| v.as_array_mut()) {
627+
for entry in arr.iter_mut() {
628+
if let Some(s) = entry.as_str() {
629+
if s == original_ip {
630+
*entry = Value::String(new_ip.to_string());
631+
changed = true;
632+
}
633+
continue;
634+
}
635+
if let Some(ip_field) = entry.as_object_mut().and_then(|m| m.get_mut("ip")) {
636+
if let Some(s) = ip_field.as_str() {
637+
if s == original_ip {
638+
*ip_field = Value::String(new_ip.to_string());
639+
changed = true;
640+
}
641+
}
642+
}
643+
}
644+
}
645+
646+
// status.hostIPs (array of objects {ip: string} or strings) - if present
647+
if let Some(arr) = pod.pointer_mut("/status/hostIPs").and_then(|v| v.as_array_mut()) {
648+
for entry in arr.iter_mut() {
649+
if let Some(s) = entry.as_str() {
650+
if s == original_ip {
651+
*entry = Value::String(new_ip.to_string());
652+
changed = true;
653+
}
654+
continue;
655+
}
656+
if let Some(ip_field) = entry.as_object_mut().and_then(|m| m.get_mut("ip")) {
657+
if let Some(s) = ip_field.as_str() {
658+
if s == original_ip {
659+
*ip_field = Value::String(new_ip.to_string());
660+
changed = true;
661+
}
662+
}
663+
}
664+
}
665+
}
666+
667+
Ok(changed)
668+
}
669+
670+
join_all(etcd_client.list_keys("pods/").await?.into_iter().map(|key| async move {
671+
let etcd_result = etcd_client
672+
.get(key.clone())
673+
.await
674+
.with_context(|| format!("getting key {:?}", key))?
675+
.context("key disappeared")?;
676+
let value: Value =
677+
serde_yaml::from_slice(etcd_result.value.as_slice()).with_context(|| format!("deserializing value of key {:?}", key,))?;
678+
let k8s_resource_location = K8sResourceLocation::try_from(&value)?;
679+
680+
let mut pod = get_etcd_json(etcd_client, &k8s_resource_location).await?.context("getting pod")?;
681+
682+
if replace_status_ips(&mut pod, original_ip, ip)? {
683+
put_etcd_yaml(etcd_client, &k8s_resource_location, pod).await?;
684+
}
685+
686+
Ok(())
687+
}))
688+
.await
689+
.into_iter()
690+
.collect::<Result<Vec<_>>>()?;
691+
692+
Ok(())
693+
}
694+
695+
pub(crate) async fn delete_minions_if_exist(etcd_client: &Arc<InMemoryK8sEtcd>) -> Result<()> {
696+
for key in etcd_client.list_keys("minions").await? {
697+
etcd_client.delete(&key).await.context(format!("deleting {}", key))?;
698+
}
699+
Ok(())
700+
}
701+
600702
fn replace_etcd_servers(cluster: &mut Value, original_ip: &str, ip: &str) -> Result<()> {
601703
let observed_config = cluster.pointer_mut("/spec/observedConfig").context("no /spec/observedConfig")?;
602704

src/ocp_postprocess/ip_rename/filesystem_rename.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ pub(crate) async fn fix_filesystem_ip(original_ip: &str, ip: &str, dir: &Path) -
1111
file_utils::globvec(dir, "**/etcd-pod.yaml")?
1212
.into_iter()
1313
.chain(file_utils::globvec(dir, "**/*etcd-pod/pod.yaml")?)
14+
.chain(file_utils::globvec(dir, "**/restore-etcd-pod/quorum-restore-pod.yaml")?)
1415
.chain(file_utils::globvec(dir, "**/etcd-scripts/etcd.env")?)
1516
.chain(file_utils::globvec(dir, "**/etcd-endpoints/*")?)
1617
.chain(file_utils::globvec(dir, "**/kube-apiserver-pod-*/configmaps/config/config.yaml")?)

0 commit comments

Comments
 (0)