diff --git a/src/tools/genpolicy/src/main.rs b/src/tools/genpolicy/src/main.rs index 19ef76653b..97bdcc3d55 100644 --- a/src/tools/genpolicy/src/main.rs +++ b/src/tools/genpolicy/src/main.rs @@ -21,6 +21,7 @@ mod pod; mod pod_template; mod policy; mod registry; +mod replica_set; mod secret; mod settings; mod utils; diff --git a/src/tools/genpolicy/src/replica_set.rs b/src/tools/genpolicy/src/replica_set.rs new file mode 100644 index 0000000000..a038273d1c --- /dev/null +++ b/src/tools/genpolicy/src/replica_set.rs @@ -0,0 +1,102 @@ +// Copyright (c) 2023 Microsoft Corporation +// +// SPDX-License-Identifier: Apache-2.0 +// + +// Allow K8s YAML field names. +#![allow(non_snake_case)] + +use crate::obj_meta; +use crate::pod; +use crate::pod_template; +use crate::policy; +use crate::settings; +use crate::yaml; + +use async_trait::async_trait; +use protocols::agent; +use serde::{Deserialize, Serialize}; +use std::collections::BTreeMap; + +/// See Reference / Kubernetes API / Workload Resources / ReplicaSet. +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct ReplicaSet { + apiVersion: String, + kind: String, + metadata: obj_meta::ObjectMeta, + spec: ReplicaSetSpec, + + #[serde(skip)] + doc_mapping: serde_yaml::Value, +} + +/// See ReplicaSetSpec in the Kubernetes API reference. +#[derive(Clone, Debug, Serialize, Deserialize)] +struct ReplicaSetSpec { + selector: yaml::LabelSelector, + template: pod_template::PodTemplateSpec, + + #[serde(skip_serializing_if = "Option::is_none")] + replicas: Option, + + #[serde(skip_serializing_if = "Option::is_none")] + minReadySeconds: Option, +} + +#[async_trait] +impl yaml::K8sResource for ReplicaSet { + async fn init(&mut self, use_cache: bool, doc_mapping: &serde_yaml::Value, _silent: bool) { + yaml::k8s_resource_init(&mut self.spec.template.spec, use_cache).await; + self.doc_mapping = doc_mapping.clone(); + } + + fn get_sandbox_name(&self) -> Option { + None + } + + fn get_namespace(&self) -> String { + self.metadata.get_namespace() + } + + fn get_container_mounts_and_storages( + &self, + policy_mounts: &mut Vec, + storages: &mut Vec, + container: &pod::Container, + settings: &settings::Settings, + ) { + if let Some(volumes) = &self.spec.template.spec.volumes { + yaml::get_container_mounts_and_storages( + policy_mounts, + storages, + container, + settings, + volumes, + ); + } + } + + fn generate_policy(&self, agent_policy: &policy::AgentPolicy) -> String { + agent_policy.generate_policy(self) + } + + fn serialize(&mut self, policy: &str) -> String { + yaml::add_policy_annotation(&mut self.doc_mapping, "spec.template.metadata", policy); + serde_yaml::to_string(&self.doc_mapping).unwrap() + } + + fn get_containers(&self) -> &Vec { + &self.spec.template.spec.containers + } + + fn get_annotations(&self) -> &Option> { + &self.spec.template.metadata.annotations + } + + fn use_host_network(&self) -> bool { + if let Some(host_network) = self.spec.template.spec.hostNetwork { + return host_network; + } + false + } +} diff --git a/src/tools/genpolicy/src/yaml.rs b/src/tools/genpolicy/src/yaml.rs index 5373e3bf02..b63cff7ec4 100644 --- a/src/tools/genpolicy/src/yaml.rs +++ b/src/tools/genpolicy/src/yaml.rs @@ -15,6 +15,7 @@ use crate::mount_and_storage; use crate::no_policy; use crate::pod; use crate::policy; +use crate::replica_set; use crate::secret; use crate::settings; use crate::volume; @@ -143,6 +144,14 @@ pub fn new_k8s_resource( debug!("{:#?}", &pod); Ok((boxed::Box::new(pod), header.kind)) } + "ReplicaSet" => { + let set: replica_set::ReplicaSet = serde_ignored::deserialize(d, |path| { + handle_unused_field(&path.to_string(), silent_unsupported_fields); + }) + .unwrap(); + debug!("{:#?}", &set); + Ok((boxed::Box::new(set), header.kind)) + } "Secret" => { let secret: secret::Secret = serde_ignored::deserialize(d, |path| { handle_unused_field(&path.to_string(), silent_unsupported_fields);