genpolicy: add support for List YAML input

Generate policy for K8s List YAML.

Signed-off-by: Dan Mihai <dmihai@microsoft.com>
This commit is contained in:
Dan Mihai
2023-10-18 20:58:37 +00:00
parent a03452637b
commit d84300f1ee
3 changed files with 113 additions and 0 deletions

View File

@@ -0,0 +1,103 @@
// Copyright (c) 2023 Microsoft Corporation
//
// SPDX-License-Identifier: Apache-2.0
//
// Allow K8s YAML field names.
#![allow(non_snake_case)]
use crate::pod;
use crate::policy;
use crate::settings;
use crate::yaml;
use async_trait::async_trait;
use core::fmt::Debug;
use protocols::agent;
use serde::{Deserialize, Serialize};
use serde_yaml::Value;
use std::boxed;
use std::collections::BTreeMap;
use std::marker::{Send, Sync};
#[derive(Debug, Serialize, Deserialize)]
pub struct List {
apiVersion: String,
kind: String,
items: Vec<serde_yaml::Value>,
#[serde(skip)]
resources: Vec<boxed::Box<dyn yaml::K8sResource + Sync + Send>>,
}
impl Debug for dyn yaml::K8sResource + Send + Sync {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
write!(f, "K8sResource")
}
}
#[async_trait]
impl yaml::K8sResource for List {
async fn init(&mut self, use_cache: bool, _doc_mapping: &serde_yaml::Value, silent: bool) {
// Create K8sResource objects for each item in this List.
for item in &self.items {
let yaml_string = serde_yaml::to_string(&item).unwrap();
let (mut resource, _kind) = yaml::new_k8s_resource(&yaml_string, silent).unwrap();
resource.init(use_cache, item, silent).await;
self.resources.push(resource);
}
}
fn get_sandbox_name(&self) -> Option<String> {
panic!("Unsupported");
}
fn get_namespace(&self) -> String {
panic!("Unsupported");
}
fn get_container_mounts_and_storages(
&self,
_policy_mounts: &mut Vec<policy::KataMount>,
_storages: &mut Vec<agent::Storage>,
_container: &pod::Container,
_settings: &settings::Settings,
) {
}
fn generate_policy(&self, agent_policy: &policy::AgentPolicy) -> String {
let mut policies: Vec<String> = Vec::new();
for resource in &self.resources {
policies.push(resource.generate_policy(agent_policy));
}
policies.join(":")
}
fn serialize(&mut self, policy: &str) -> String {
let policies: Vec<&str> = policy.split(":").collect();
let len = policies.len();
assert!(len == self.resources.len());
self.items.clear();
for i in 0..len {
let yaml = self.resources[i].serialize(policies[i]);
let document = serde_yaml::Deserializer::from_str(&yaml);
let doc_value = Value::deserialize(document).unwrap();
self.items.push(doc_value.clone());
}
serde_yaml::to_string(&self).unwrap()
}
fn get_containers(&self) -> &Vec<pod::Container> {
panic!("Unsupported");
}
fn get_annotations(&self) -> &Option<BTreeMap<String, String>> {
panic!("Unsupported");
}
fn use_host_network(&self) -> bool {
panic!("Unsupported");
}
}

View File

@@ -12,6 +12,7 @@ mod containerd;
mod daemon_set;
mod deployment;
mod job;
mod list;
mod mount_and_storage;
mod no_policy;
mod obj_meta;

View File

@@ -10,6 +10,7 @@ use crate::config_map;
use crate::daemon_set;
use crate::deployment;
use crate::job;
use crate::list;
use crate::mount_and_storage;
use crate::no_policy;
use crate::pod;
@@ -126,6 +127,14 @@ pub fn new_k8s_resource(
debug!("{:#?}", &job);
Ok((boxed::Box::new(job), header.kind))
}
"List" => {
let list: list::List = serde_ignored::deserialize(d, |path| {
handle_unused_field(&path.to_string(), silent_unsupported_fields);
})
.unwrap();
debug!("{:#?}", &list);
Ok((boxed::Box::new(list), header.kind))
}
"Pod" => {
let pod: pod::Pod = serde_ignored::deserialize(d, |path| {
handle_unused_field(&path.to_string(), silent_unsupported_fields);