From 8ad5459beb56ea06febf5b3f8be463f0e8d96229 Mon Sep 17 00:00:00 2001 From: Dan Mihai Date: Thu, 25 Jan 2024 15:12:07 +0000 Subject: [PATCH] genpolicy: optional PodTemplateSpec metadata field Add metadata containing the Policy annotation if the user didn't provide any metadata in the input yaml file. For a simple sanity test using a Kata CI YAML file: genpolicy -u -y job.yaml kubectl apply -f job.yaml kubectl get pods | grep job job-pi-test-64dxs 0/1 Completed 0 14s Fixes: #8891 Signed-off-by: Dan Mihai --- src/tools/genpolicy/src/daemon_set.rs | 7 +++++-- src/tools/genpolicy/src/deployment.rs | 7 +++++-- src/tools/genpolicy/src/job.rs | 7 +++++-- src/tools/genpolicy/src/pod.rs | 2 +- src/tools/genpolicy/src/pod_template.rs | 4 +++- src/tools/genpolicy/src/replica_set.rs | 7 +++++-- .../genpolicy/src/replication_controller.rs | 7 +++++-- src/tools/genpolicy/src/stateful_set.rs | 7 +++++-- src/tools/genpolicy/src/yaml.rs | 19 ++++++++++++++++--- 9 files changed, 50 insertions(+), 17 deletions(-) diff --git a/src/tools/genpolicy/src/daemon_set.rs b/src/tools/genpolicy/src/daemon_set.rs index aa19b12fbf..69fc4e0976 100644 --- a/src/tools/genpolicy/src/daemon_set.rs +++ b/src/tools/genpolicy/src/daemon_set.rs @@ -111,7 +111,7 @@ impl yaml::K8sResource for DaemonSet { } fn serialize(&mut self, policy: &str) -> String { - yaml::add_policy_annotation(&mut self.doc_mapping, "spec.template.metadata", policy); + yaml::add_policy_annotation(&mut self.doc_mapping, "spec.template", policy); serde_yaml::to_string(&self.doc_mapping).unwrap() } @@ -120,7 +120,10 @@ impl yaml::K8sResource for DaemonSet { } fn get_annotations(&self) -> &Option> { - &self.spec.template.metadata.annotations + if let Some(metadata) = &self.spec.template.metadata { + return &metadata.annotations; + } + &None } fn use_host_network(&self) -> bool { diff --git a/src/tools/genpolicy/src/deployment.rs b/src/tools/genpolicy/src/deployment.rs index 397d1344d1..6973a16b62 100644 --- a/src/tools/genpolicy/src/deployment.rs +++ b/src/tools/genpolicy/src/deployment.rs @@ -109,7 +109,7 @@ impl yaml::K8sResource for Deployment { } fn serialize(&mut self, policy: &str) -> String { - yaml::add_policy_annotation(&mut self.doc_mapping, "spec.template.metadata", policy); + yaml::add_policy_annotation(&mut self.doc_mapping, "spec.template", policy); serde_yaml::to_string(&self.doc_mapping).unwrap() } @@ -118,7 +118,10 @@ impl yaml::K8sResource for Deployment { } fn get_annotations(&self) -> &Option> { - &self.spec.template.metadata.annotations + if let Some(metadata) = &self.spec.template.metadata { + return &metadata.annotations; + } + &None } fn use_host_network(&self) -> bool { diff --git a/src/tools/genpolicy/src/job.rs b/src/tools/genpolicy/src/job.rs index 8bda6c8b5f..574400093f 100644 --- a/src/tools/genpolicy/src/job.rs +++ b/src/tools/genpolicy/src/job.rs @@ -83,7 +83,7 @@ impl yaml::K8sResource for Job { } fn serialize(&mut self, policy: &str) -> String { - yaml::add_policy_annotation(&mut self.doc_mapping, "spec.template.metadata", policy); + yaml::add_policy_annotation(&mut self.doc_mapping, "spec.template", policy); serde_yaml::to_string(&self.doc_mapping).unwrap() } @@ -92,7 +92,10 @@ impl yaml::K8sResource for Job { } fn get_annotations(&self) -> &Option> { - &self.spec.template.metadata.annotations + if let Some(metadata) = &self.spec.template.metadata { + return &metadata.annotations; + } + &None } fn use_host_network(&self) -> bool { diff --git a/src/tools/genpolicy/src/pod.rs b/src/tools/genpolicy/src/pod.rs index b85b7b9829..d563fd1368 100644 --- a/src/tools/genpolicy/src/pod.rs +++ b/src/tools/genpolicy/src/pod.rs @@ -719,7 +719,7 @@ impl yaml::K8sResource for Pod { } fn serialize(&mut self, policy: &str) -> String { - yaml::add_policy_annotation(&mut self.doc_mapping, "metadata", policy); + yaml::add_policy_annotation(&mut self.doc_mapping, "", policy); serde_yaml::to_string(&self.doc_mapping).unwrap() } diff --git a/src/tools/genpolicy/src/pod_template.rs b/src/tools/genpolicy/src/pod_template.rs index f4b7c6c2eb..37933c2d38 100644 --- a/src/tools/genpolicy/src/pod_template.rs +++ b/src/tools/genpolicy/src/pod_template.rs @@ -23,6 +23,8 @@ pub struct PodTemplate { /// Reference / Kubernetes API / Workload / Resources / PodTemplate. #[derive(Clone, Debug, Serialize, Deserialize)] pub struct PodTemplateSpec { - pub metadata: obj_meta::ObjectMeta, + #[serde(skip_serializing_if = "Option::is_none")] + pub metadata: Option, + pub spec: pod::PodSpec, } diff --git a/src/tools/genpolicy/src/replica_set.rs b/src/tools/genpolicy/src/replica_set.rs index a038273d1c..2f082182ee 100644 --- a/src/tools/genpolicy/src/replica_set.rs +++ b/src/tools/genpolicy/src/replica_set.rs @@ -81,7 +81,7 @@ impl yaml::K8sResource for ReplicaSet { } fn serialize(&mut self, policy: &str) -> String { - yaml::add_policy_annotation(&mut self.doc_mapping, "spec.template.metadata", policy); + yaml::add_policy_annotation(&mut self.doc_mapping, "spec.template", policy); serde_yaml::to_string(&self.doc_mapping).unwrap() } @@ -90,7 +90,10 @@ impl yaml::K8sResource for ReplicaSet { } fn get_annotations(&self) -> &Option> { - &self.spec.template.metadata.annotations + if let Some(metadata) = &self.spec.template.metadata { + return &metadata.annotations; + } + &None } fn use_host_network(&self) -> bool { diff --git a/src/tools/genpolicy/src/replication_controller.rs b/src/tools/genpolicy/src/replication_controller.rs index a519c63620..d3f2f5987a 100644 --- a/src/tools/genpolicy/src/replication_controller.rs +++ b/src/tools/genpolicy/src/replication_controller.rs @@ -83,7 +83,7 @@ impl yaml::K8sResource for ReplicationController { } fn serialize(&mut self, policy: &str) -> String { - yaml::add_policy_annotation(&mut self.doc_mapping, "spec.template.metadata", policy); + yaml::add_policy_annotation(&mut self.doc_mapping, "spec.template", policy); serde_yaml::to_string(&self.doc_mapping).unwrap() } @@ -92,7 +92,10 @@ impl yaml::K8sResource for ReplicationController { } fn get_annotations(&self) -> &Option> { - &self.spec.template.metadata.annotations + if let Some(metadata) = &self.spec.template.metadata { + return &metadata.annotations; + } + &None } fn use_host_network(&self) -> bool { diff --git a/src/tools/genpolicy/src/stateful_set.rs b/src/tools/genpolicy/src/stateful_set.rs index 9a31c29fa5..77f6fef3a3 100644 --- a/src/tools/genpolicy/src/stateful_set.rs +++ b/src/tools/genpolicy/src/stateful_set.rs @@ -156,7 +156,7 @@ impl yaml::K8sResource for StatefulSet { } fn serialize(&mut self, policy: &str) -> String { - yaml::add_policy_annotation(&mut self.doc_mapping, "spec.template.metadata", policy); + yaml::add_policy_annotation(&mut self.doc_mapping, "spec.template", policy); serde_yaml::to_string(&self.doc_mapping).unwrap() } @@ -165,7 +165,10 @@ impl yaml::K8sResource for StatefulSet { } fn get_annotations(&self) -> &Option> { - &self.spec.template.metadata.annotations + if let Some(metadata) = &self.spec.template.metadata { + return &metadata.annotations; + } + &None } fn use_host_network(&self) -> bool { diff --git a/src/tools/genpolicy/src/yaml.rs b/src/tools/genpolicy/src/yaml.rs index b1f38c57b3..c81fc527b5 100644 --- a/src/tools/genpolicy/src/yaml.rs +++ b/src/tools/genpolicy/src/yaml.rs @@ -264,11 +264,24 @@ pub fn add_policy_annotation( let policy_key = serde_yaml::Value::String("io.katacontainers.config.agent.policy".to_string()); let policy_value = serde_yaml::Value::String(policy.to_string()); - let path_components = metadata_path.split('.'); - for name in path_components { - ancestor = ancestor.get_mut(name).unwrap(); + if !metadata_path.is_empty() { + let path_components = metadata_path.split('.'); + for name in path_components { + ancestor = ancestor.get_mut(name).unwrap(); + } } + // Add metadata to the output if the input YAML didn't include it. + let metadata = "metadata"; + if ancestor.get(metadata).is_none() { + let new_mapping = serde_yaml::Value::Mapping(serde_yaml::Mapping::new()); + ancestor + .as_mapping_mut() + .unwrap() + .insert(serde_yaml::Value::String(metadata.to_string()), new_mapping); + } + ancestor = ancestor.get_mut(metadata).unwrap(); + if let Some(annotations) = ancestor.get_mut(&annotations_key) { if let Some(annotation) = annotations.get_mut(&policy_key) { *annotation = policy_value;