mirror of
https://github.com/kata-containers/kata-containers.git
synced 2025-06-28 08:17:37 +00:00
genpolicy: add ability to filter for runtimeClassName
Add the CLI flag --runtime-class-names, which is used during policy generation. For resources that can define a runtimeClassName (e.g., Pods, Deployments, ReplicaSets,...) the value must have any of the --runtime-class-names as prefix, otherwise the resource is ignored. This allows to run genpolicy on larger yaml files defining many different resources and only generating a policy for resources which will be deployed in a confidential context. Signed-off-by: Leonard Cohnen <lc@edgeless.systems>
This commit is contained in:
parent
2f686b1179
commit
1d1690e2a4
@ -140,4 +140,13 @@ impl yaml::K8sResource for DaemonSet {
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
fn get_runtime_class_name(&self) -> Option<String> {
|
||||
self.spec
|
||||
.template
|
||||
.spec
|
||||
.runtimeClassName
|
||||
.clone()
|
||||
.or_else(|| Some(String::new()))
|
||||
}
|
||||
}
|
||||
|
@ -138,4 +138,13 @@ impl yaml::K8sResource for Deployment {
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
fn get_runtime_class_name(&self) -> Option<String> {
|
||||
self.spec
|
||||
.template
|
||||
.spec
|
||||
.runtimeClassName
|
||||
.clone()
|
||||
.or_else(|| Some(String::new()))
|
||||
}
|
||||
}
|
||||
|
@ -46,7 +46,7 @@ pub struct PodSpec {
|
||||
restartPolicy: Option<String>,
|
||||
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
runtimeClassName: Option<String>,
|
||||
pub runtimeClassName: Option<String>,
|
||||
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub initContainers: Option<Vec<Container>>,
|
||||
@ -755,6 +755,13 @@ impl yaml::K8sResource for Pod {
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
fn get_runtime_class_name(&self) -> Option<String> {
|
||||
self.spec
|
||||
.runtimeClassName
|
||||
.clone()
|
||||
.or_else(|| Some(String::new()))
|
||||
}
|
||||
}
|
||||
|
||||
impl Container {
|
||||
|
@ -9,6 +9,7 @@
|
||||
use crate::config_map;
|
||||
use crate::containerd;
|
||||
use crate::mount_and_storage;
|
||||
use crate::no_policy;
|
||||
use crate::pod;
|
||||
use crate::policy;
|
||||
use crate::registry;
|
||||
@ -380,6 +381,22 @@ impl AgentPolicy {
|
||||
let yaml_string = serde_yaml::to_string(&doc_mapping)?;
|
||||
let silent = config.silent_unsupported_fields;
|
||||
let (mut resource, kind) = yaml::new_k8s_resource(&yaml_string, silent)?;
|
||||
|
||||
// Filter out resources that don't match the runtime class name.
|
||||
if let Some(resource_runtime_name) = resource.get_runtime_class_name() {
|
||||
if !config.runtime_class_names.is_empty()
|
||||
&& !config
|
||||
.runtime_class_names
|
||||
.iter()
|
||||
.any(|prefix| resource_runtime_name.starts_with(prefix))
|
||||
{
|
||||
resource =
|
||||
boxed::Box::new(no_policy::NoPolicyResource { yaml: yaml_string });
|
||||
resources.push(resource);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
resource.init(config, &doc_mapping, silent).await;
|
||||
|
||||
// ConfigMap and Secret documents contain additional input for policy generation.
|
||||
|
@ -185,6 +185,15 @@ impl yaml::K8sResource for StatefulSet {
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
fn get_runtime_class_name(&self) -> Option<String> {
|
||||
self.spec
|
||||
.template
|
||||
.spec
|
||||
.runtimeClassName
|
||||
.clone()
|
||||
.or_else(|| Some(String::new()))
|
||||
}
|
||||
}
|
||||
|
||||
impl StatefulSet {
|
||||
|
@ -82,6 +82,12 @@ struct CommandLineOptions {
|
||||
help = "Registry that uses plain HTTP. Can be passed more than once to configure multiple insecure registries."
|
||||
)]
|
||||
insecure_registry: Vec<String>,
|
||||
|
||||
#[clap(
|
||||
long,
|
||||
help = "If specified, resources that have a runtimeClassName field defined will only receive a policy if the parameter is a prefix one of the given runtime class names."
|
||||
)]
|
||||
runtime_class_names: Vec<String>,
|
||||
}
|
||||
|
||||
/// Application configuration, derived from on command line parameters.
|
||||
@ -89,6 +95,7 @@ struct CommandLineOptions {
|
||||
pub struct Config {
|
||||
pub use_cache: bool,
|
||||
pub insecure_registries: Vec<String>,
|
||||
pub runtime_class_names: Vec<String>,
|
||||
|
||||
pub yaml_file: Option<String>,
|
||||
pub rego_rules_path: String,
|
||||
@ -121,6 +128,7 @@ impl Config {
|
||||
Self {
|
||||
use_cache: args.use_cached_files,
|
||||
insecure_registries: args.insecure_registry,
|
||||
runtime_class_names: args.runtime_class_names,
|
||||
yaml_file: args.yaml_file,
|
||||
rego_rules_path: args.rego_rules_path,
|
||||
settings,
|
||||
|
@ -90,6 +90,10 @@ pub trait K8sResource {
|
||||
fn use_sandbox_pidns(&self) -> bool {
|
||||
panic!("Unsupported");
|
||||
}
|
||||
|
||||
fn get_runtime_class_name(&self) -> Option<String> {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
/// See Reference / Kubernetes API / Common Definitions / LabelSelector.
|
||||
|
@ -17,13 +17,22 @@ setup() {
|
||||
get_pod_config_dir
|
||||
|
||||
correct_configmap_yaml="${pod_config_dir}/k8s-policy-configmap.yaml"
|
||||
pre_generate_configmap_yaml="${pod_config_dir}/k8s-policy-configmap-pre-generation.yaml"
|
||||
incorrect_configmap_yaml="${pod_config_dir}/k8s-policy-configmap-incorrect.yaml"
|
||||
testcase_pre_generate_configmap_yaml="${pod_config_dir}/k8s-policy-configmap-testcase-pre-generation.yaml"
|
||||
|
||||
correct_pod_yaml="${pod_config_dir}/k8s-policy-pod.yaml"
|
||||
pre_generate_pod_yaml="${pod_config_dir}/k8s-policy-pod-pre-generation.yaml"
|
||||
incorrect_pod_yaml="${pod_config_dir}/k8s-policy-pod-incorrect.yaml"
|
||||
testcase_pre_generate_pod_yaml="${pod_config_dir}/k8s-policy-pod-testcase-pre-generation.yaml"
|
||||
|
||||
|
||||
# Save some time by executing genpolicy a single time.
|
||||
if [ "${BATS_TEST_NUMBER}" == "1" ]; then
|
||||
# Save pre-generated yaml files
|
||||
cp "${correct_configmap_yaml}" "${pre_generate_configmap_yaml}"
|
||||
cp "${correct_pod_yaml}" "${pre_generate_pod_yaml}"
|
||||
|
||||
# Add policy to the correct pod yaml file
|
||||
auto_generate_policy "${pod_config_dir}" "${correct_pod_yaml}" "${correct_configmap_yaml}"
|
||||
fi
|
||||
@ -31,6 +40,10 @@ setup() {
|
||||
# Start each test case with a copy of the correct yaml files.
|
||||
cp "${correct_configmap_yaml}" "${incorrect_configmap_yaml}"
|
||||
cp "${correct_pod_yaml}" "${incorrect_pod_yaml}"
|
||||
|
||||
# Also give each testcase a copy of the pre-generated yaml files.
|
||||
cp "${pre_generate_configmap_yaml}" "${testcase_pre_generate_configmap_yaml}"
|
||||
cp "${pre_generate_pod_yaml}" "${testcase_pre_generate_pod_yaml}"
|
||||
}
|
||||
|
||||
@test "Successful pod with auto-generated policy" {
|
||||
@ -39,6 +52,17 @@ setup() {
|
||||
kubectl wait --for=condition=Ready "--timeout=${timeout}" pod "${pod_name}"
|
||||
}
|
||||
|
||||
@test "Successful pod with auto-generated policy and runtimeClassName filter" {
|
||||
runtime_class_name=$(yq read "${testcase_pre_generate_pod_yaml}" "spec.runtimeClassName")
|
||||
|
||||
auto_generate_policy "${pod_config_dir}" "${testcase_pre_generate_pod_yaml}" "${testcase_pre_generate_configmap_yaml}" \
|
||||
"--runtime-class-names=other-runtime-class-name --runtime-class-names=${runtime_class_name}"
|
||||
|
||||
kubectl create -f "${testcase_pre_generate_configmap_yaml}"
|
||||
kubectl create -f "${testcase_pre_generate_pod_yaml}"
|
||||
kubectl wait --for=condition=Ready "--timeout=${timeout}" pod "${pod_name}"
|
||||
}
|
||||
|
||||
# Common function for several test cases from this bats script.
|
||||
test_pod_policy_error() {
|
||||
kubectl create -f "${correct_configmap_yaml}"
|
||||
@ -143,6 +167,17 @@ test_pod_policy_error() {
|
||||
waitForProcess "${wait_time}" "$sleep_time" "${command}" | grep -v "Message:"
|
||||
}
|
||||
|
||||
@test "RuntimeClassName filter: no policy" {
|
||||
# The policy should not be generated because the pod spec does not have a runtimeClassName.
|
||||
runtime_class_name=$(yq read "${testcase_pre_generate_pod_yaml}" "spec.runtimeClassName")
|
||||
|
||||
auto_generate_policy "${pod_config_dir}" "${testcase_pre_generate_pod_yaml}" "${testcase_pre_generate_configmap_yaml}" \
|
||||
"--runtime-class-names=other-${runtime_class_name}"
|
||||
|
||||
# Check that the pod yaml does not contain a policy annotation.
|
||||
run ! grep -q "io.katacontainers.config.agent.policy" "${testcase_pre_generate_pod_yaml}"
|
||||
}
|
||||
|
||||
teardown() {
|
||||
auto_generate_policy_enabled || skip "Auto-generated policy tests are disabled."
|
||||
|
||||
@ -154,4 +189,6 @@ teardown() {
|
||||
kubectl delete configmap "${configmap_name}"
|
||||
rm -f "${incorrect_pod_yaml}"
|
||||
rm -f "${incorrect_configmap_yaml}"
|
||||
rm -f "${testcase_pre_generate_pod_yaml}"
|
||||
rm -f "${testcase_pre_generate_configmap_yaml}"
|
||||
}
|
||||
|
@ -171,6 +171,7 @@ auto_generate_policy() {
|
||||
declare -r settings_dir="$1"
|
||||
declare -r yaml_file="$2"
|
||||
declare -r config_map_yaml_file="$3"
|
||||
declare -r additional_flags="$4"
|
||||
|
||||
auto_generate_policy_enabled || return 0
|
||||
local genpolicy_command="RUST_LOG=info /opt/kata/bin/genpolicy -u -y ${yaml_file}"
|
||||
@ -185,6 +186,8 @@ auto_generate_policy() {
|
||||
genpolicy_command+=" -d"
|
||||
fi
|
||||
|
||||
genpolicy_command+=" ${additional_flags}"
|
||||
|
||||
info "Executing: ${genpolicy_command}"
|
||||
eval "${genpolicy_command}"
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user