diff --git a/src/tools/genpolicy/src/daemon_set.rs b/src/tools/genpolicy/src/daemon_set.rs new file mode 100644 index 0000000000..aa19b12fbf --- /dev/null +++ b/src/tools/genpolicy/src/daemon_set.rs @@ -0,0 +1,132 @@ +// 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 / DaemonSet. +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct DaemonSet { + apiVersion: String, + kind: String, + metadata: obj_meta::ObjectMeta, + spec: DaemonSetSpec, + + #[serde(skip)] + doc_mapping: serde_yaml::Value, +} + +/// See Reference Kubernetes API / Workload Resources / DaemonSet. +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct DaemonSetSpec { + #[serde(skip_serializing_if = "Option::is_none")] + selector: Option, + + pub template: pod_template::PodTemplateSpec, + + #[serde(skip_serializing_if = "Option::is_none")] + minReadySeconds: Option, + + #[serde(skip_serializing_if = "Option::is_none")] + updateStrategy: Option, + + #[serde(skip_serializing_if = "Option::is_none")] + revisionHistoryLimit: Option, +} + +/// See Reference Kubernetes API / Workload Resources / DaemonSet. +#[derive(Clone, Debug, Serialize, Deserialize)] +struct DaemonSetUpdateStrategy { + #[serde(skip_serializing_if = "Option::is_none")] + r#type: Option, + + #[serde(skip_serializing_if = "Option::is_none")] + rollingUpdate: Option, +} + +/// See Reference Kubernetes API / Workload Resources / DaemonSet. +#[derive(Clone, Debug, Serialize, Deserialize)] +struct RollingUpdateDaemonSet { + #[serde(skip_serializing_if = "Option::is_none")] + maxSurge: Option, + + #[serde(skip_serializing_if = "Option::is_none")] + maxUnavailable: Option, +} + +#[async_trait] +impl yaml::K8sResource for DaemonSet { + async fn init( + &mut self, + use_cache: bool, + doc_mapping: &serde_yaml::Value, + _silent_unsupported_fields: 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/main.rs b/src/tools/genpolicy/src/main.rs index 1c582b798f..c56d013108 100644 --- a/src/tools/genpolicy/src/main.rs +++ b/src/tools/genpolicy/src/main.rs @@ -9,6 +9,7 @@ use log::{debug, info}; mod config_map; mod containerd; +mod daemon_set; mod mount_and_storage; mod no_policy; mod obj_meta; diff --git a/src/tools/genpolicy/src/yaml.rs b/src/tools/genpolicy/src/yaml.rs index 200c9d552c..8703c0dc92 100644 --- a/src/tools/genpolicy/src/yaml.rs +++ b/src/tools/genpolicy/src/yaml.rs @@ -7,6 +7,7 @@ #![allow(non_snake_case)] use crate::config_map; +use crate::daemon_set; use crate::mount_and_storage; use crate::no_policy; use crate::pod; @@ -99,6 +100,14 @@ pub fn new_k8s_resource( debug!("{:#?}", &config_map); Ok((boxed::Box::new(config_map), header.kind)) } + "DaemonSet" => { + let daemon: daemon_set::DaemonSet = serde_ignored::deserialize(d, |path| { + handle_unused_field(&path.to_string(), silent_unsupported_fields); + }) + .unwrap(); + debug!("{:#?}", &daemon); + Ok((boxed::Box::new(daemon), header.kind)) + } "Pod" => { let pod: pod::Pod = serde_ignored::deserialize(d, |path| { handle_unused_field(&path.to_string(), silent_unsupported_fields);