diff --git a/src/tools/genpolicy/Cargo.lock b/src/tools/genpolicy/Cargo.lock index 5849bfb15..0f7540cc4 100644 --- a/src/tools/genpolicy/Cargo.lock +++ b/src/tools/genpolicy/Cargo.lock @@ -41,6 +41,12 @@ dependencies = [ "libc", ] +[[package]] +name = "anstyle" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9" + [[package]] name = "anyhow" version = "1.0.69" @@ -53,6 +59,22 @@ version = "1.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "69f7f8c3906b62b754cd5326047894316021dcfe5a194c8ea52bdd94934a3457" +[[package]] +name = "assert_cmd" +version = "2.0.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2bd389a4b2970a01282ee455294913c0a43724daedcd1a24c3eb0ec1c1320b66" +dependencies = [ + "anstyle", + "bstr", + "doc-comment", + "libc", + "predicates", + "predicates-core", + "predicates-tree", + "wait-timeout", +] + [[package]] name = "async-trait" version = "0.1.68" @@ -169,6 +191,17 @@ dependencies = [ "generic-array", ] +[[package]] +name = "bstr" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "234113d19d0d7d613b40e86fb654acf958910802bcceab913a4f9e7cda03b1a4" +dependencies = [ + "memchr", + "regex-automata", + "serde", +] + [[package]] name = "bumpalo" version = "3.12.0" @@ -451,6 +484,12 @@ dependencies = [ "syn 2.0.58", ] +[[package]] +name = "difflib" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6184e33543162437515c2e2b48714794e37845ec9851711914eec9d308f6ebe8" + [[package]] name = "digest" version = "0.10.6" @@ -462,6 +501,12 @@ dependencies = [ "subtle", ] +[[package]] +name = "doc-comment" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fea41bba32d969b513997752735605054bc0dfa92b4c56bf1189f2e174be7a10" + [[package]] name = "docker_credential" version = "1.3.1" @@ -699,6 +744,7 @@ name = "genpolicy" version = "0.1.0" dependencies = [ "anyhow", + "assert_cmd", "async-trait", "base64 0.21.7", "clap", @@ -1580,6 +1626,33 @@ version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" +[[package]] +name = "predicates" +version = "3.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5d19ee57562043d37e82899fade9a22ebab7be9cef5026b07fda9cdd4293573" +dependencies = [ + "anstyle", + "difflib", + "predicates-core", +] + +[[package]] +name = "predicates-core" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "727e462b119fe9c93fd0eb1429a5f7647394014cf3c04ab2c0350eeb09095ffa" + +[[package]] +name = "predicates-tree" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72dd2d6d381dfb73a193c7fca536518d7caee39fc8503f74e7dc0be0531b425c" +dependencies = [ + "predicates-core", + "termtree", +] + [[package]] name = "prettyplease" version = "0.1.25" @@ -2351,6 +2424,12 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "termtree" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f50febec83f5ee1df3015341d8bd429f2d1cc62bcba7ea2076759d315084683" + [[package]] name = "thiserror" version = "1.0.40" @@ -2695,6 +2774,15 @@ version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" +[[package]] +name = "wait-timeout" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ac3b126d3914f9849036f826e054cbabdc8519970b8998ddaf3b5bd3c65f11" +dependencies = [ + "libc", +] + [[package]] name = "want" version = "0.3.0" diff --git a/src/tools/genpolicy/Cargo.toml b/src/tools/genpolicy/Cargo.toml index 17bfc29d9..04685b8fe 100644 --- a/src/tools/genpolicy/Cargo.toml +++ b/src/tools/genpolicy/Cargo.toml @@ -40,14 +40,16 @@ serde_yaml = "0.8" anyhow = "1.0.32" async-trait = "0.1.68" docker_credential = "1.3.1" -flate2 = { version = "1.0.26", features = ["zlib-ng"], default-features = false } +flate2 = { version = "1.0.26", features = [ + "zlib-ng", +], default-features = false } libz-ng-sys = "1.1.15" # force newer version that compiles on ppc64le oci-client = { version = "0.12.0" } openssl = { version = "0.10.72", features = ["vendored"] } serde_ignored = "0.1.7" serde_json = "1.0.39" serde-transcode = "1.1.1" -tokio = {version = "1.38.0", features = ["rt-multi-thread"]} +tokio = { version = "1.38.0", features = ["rt-multi-thread"] } # OCI container specs. oci-spec = { version = "0.6.8", features = ["runtime"] } @@ -76,3 +78,4 @@ tar = "0.4.41" [dev-dependencies] kata-agent-policy = { path = "../../agent/policy" } slog = "2.5.2" +assert_cmd = "2.0.14" diff --git a/src/tools/genpolicy/src/config_map.rs b/src/tools/genpolicy/src/config_map.rs index 69519bd9d..49d816688 100644 --- a/src/tools/genpolicy/src/config_map.rs +++ b/src/tools/genpolicy/src/config_map.rs @@ -13,10 +13,8 @@ use crate::utils::Config; use crate::yaml; use async_trait::async_trait; -use log::debug; use serde::{Deserialize, Serialize}; use std::collections::BTreeMap; -use std::fs::File; /// See Reference / Kubernetes API / Config and Storage Resources / ConfigMap. #[derive(Clone, Debug, Serialize, Deserialize)] @@ -41,14 +39,6 @@ pub struct ConfigMap { } impl ConfigMap { - pub fn new(file: &str) -> anyhow::Result { - debug!("Reading ConfigMap..."); - let config_map: ConfigMap = serde_yaml::from_reader(File::open(file)?)?; - debug!("\nRead ConfigMap => {:#?}", config_map); - - Ok(config_map) - } - pub fn get_value(&self, value_from: &pod::EnvVarSource) -> Option { if let Some(key_ref) = &value_from.configMapKeyRef { if let Some(name) = &key_ref.name { diff --git a/src/tools/genpolicy/src/policy.rs b/src/tools/genpolicy/src/policy.rs index e55ef4951..ee0a92894 100644 --- a/src/tools/genpolicy/src/policy.rs +++ b/src/tools/genpolicy/src/policy.rs @@ -438,6 +438,11 @@ pub struct SandboxData { pub storages: Vec, } +enum K8sEnvFromSource { + ConfigMap(config_map::ConfigMap), + Secret(secret::Secret), +} + impl AgentPolicy { pub async fn from_files(config: &utils::Config) -> Result { let mut config_maps = Vec::new(); @@ -488,9 +493,18 @@ impl AgentPolicy { } } - if let Some(config_map_files) = &config.config_map_files { - for file in config_map_files { - config_maps.push(config_map::ConfigMap::new(file)?); + if let Some(config_files) = &config.config_files { + for resource_file in config_files { + for config_resource in parse_config_file(resource_file.to_string(), config).await? { + match config_resource { + K8sEnvFromSource::ConfigMap(config_map) => { + config_maps.push(config_map); + } + K8sEnvFromSource::Secret(secret) => { + secrets.push(secret); + } + } + } } } @@ -822,6 +836,37 @@ fn get_image_layer_storages( storages.push(overlay_storage); } +async fn parse_config_file( + yaml_file: String, + config: &utils::Config, +) -> Result> { + let mut k8sRes = Vec::new(); + let yaml_contents = yaml::get_input_yaml(&Some(yaml_file))?; + for document in serde_yaml::Deserializer::from_str(&yaml_contents) { + let doc_mapping = Value::deserialize(document)?; + if doc_mapping != Value::Null { + 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)?; + + resource.init(config, &doc_mapping, silent).await; + + // ConfigMap and Secret documents contain additional input for policy generation. + if kind.eq("ConfigMap") { + let config_map: config_map::ConfigMap = serde_yaml::from_str(&yaml_string)?; + debug!("{:#?}", &config_map); + k8sRes.push(K8sEnvFromSource::ConfigMap(config_map)); + } else if kind.eq("Secret") { + let secret: secret::Secret = serde_yaml::from_str(&yaml_string)?; + debug!("{:#?}", &secret); + k8sRes.push(K8sEnvFromSource::Secret(secret)); + } + } + } + + Ok(k8sRes) +} + /// Converts the given name to a string representation of its sha256 hash. fn name_to_hash(name: &str) -> String { let mut hasher = Sha256::new(); diff --git a/src/tools/genpolicy/src/utils.rs b/src/tools/genpolicy/src/utils.rs index 6696338cd..26f619825 100644 --- a/src/tools/genpolicy/src/utils.rs +++ b/src/tools/genpolicy/src/utils.rs @@ -18,10 +18,16 @@ struct CommandLineOptions { #[clap( short, long, - help = "Optional Kubernetes config map YAML input file path" + help = "Optional Kubernetes config map YAML input file path. DEPRECATED: use --config-file instead" )] config_map_file: Option, + #[clap( + long, + help = "Optional Kubernetes YAML input file path containing config resources such as ConfigMaps and Secrets" + )] + config_file: Option>, + #[clap( short = 'p', long, @@ -111,7 +117,7 @@ pub struct Config { pub yaml_file: Option, pub rego_rules_path: String, pub settings: settings::Settings, - pub config_map_files: Option>, + pub config_files: Option>, pub silent_unsupported_fields: bool, pub raw_out: bool, @@ -125,16 +131,15 @@ impl Config { pub fn new() -> Self { let args = CommandLineOptions::parse(); - let mut config_map_files = Vec::new(); - if let Some(config_map_file) = &args.config_map_file { - config_map_files.push(config_map_file.clone()); - } + // Migrate all files from the old `config_map_file` to the new `config_files` field + let config_files = args + .config_file + .unwrap_or_default() + .into_iter() + .chain(args.config_map_file.iter().cloned()) + .collect::>(); - let cm_files = if !config_map_files.is_empty() { - Some(config_map_files.clone()) - } else { - None - }; + let config_files = (!config_files.is_empty()).then_some(config_files); let mut layers_cache_file_path = args.layers_cache_file_path; // preserve backwards compatibility for only using the `use_cached_files` flag @@ -151,7 +156,7 @@ impl Config { yaml_file: args.yaml_file, rego_rules_path: args.rego_rules_path, settings, - config_map_files: cm_files, + config_files, silent_unsupported_fields: args.silent_unsupported_fields, raw_out: args.raw_out, base64_out: args.base64_out, diff --git a/src/tools/genpolicy/tests/generate/main.rs b/src/tools/genpolicy/tests/generate/main.rs new file mode 100644 index 000000000..f228eb9a0 --- /dev/null +++ b/src/tools/genpolicy/tests/generate/main.rs @@ -0,0 +1,99 @@ +// Copyright (c) 2025 Edgeless Systems GmbH +// +// SPDX-License-Identifier: Apache-2.0 +// + +use assert_cmd::prelude::*; +use std::fs::{self}; +use std::path; +use std::process::Command; + +#[test] +fn config_map_in_separate_file_config_map_flag() -> Result<(), Box> { + // Prepare temp dir for running genpolicy. + let test_case_dir = "config_map_separate_file_config_map_flag"; + let pod_yaml_name = "pod_with_config_map_ref.yaml"; + let config_file = "config_map.yaml"; + let workdir = prepare_workdir(test_case_dir, &[pod_yaml_name, config_file]); + + let mut cmd = Command::cargo_bin("genpolicy")?; + cmd.arg("--yaml-file").arg(workdir.join(pod_yaml_name)); + cmd.assert().failure(); + + let mut cmd = Command::cargo_bin("genpolicy")?; + cmd.arg("--yaml-file").arg(workdir.join(pod_yaml_name)); + cmd.arg("--config-map-file").arg(workdir.join(config_file)); + cmd.assert().success(); + + Ok(()) +} + +#[test] +fn config_map_in_separate_file_workdir_flag() -> Result<(), Box> { + // Prepare temp dir for running genpolicy. + let test_case_dir = "config_map_separate_file_workdir_flag"; + let pod_yaml_name = "pod_with_config_map_ref.yaml"; + let config_file = "config_map.yaml"; + let workdir = prepare_workdir(test_case_dir, &[pod_yaml_name, config_file]); + + let mut cmd = Command::cargo_bin("genpolicy")?; + cmd.arg("--yaml-file").arg(workdir.join(pod_yaml_name)); + cmd.assert().failure(); + + let mut cmd = Command::cargo_bin("genpolicy")?; + cmd.arg("--yaml-file").arg(workdir.join(pod_yaml_name)); + cmd.arg("--config-file").arg(workdir.join(config_file)); + cmd.assert().success(); + + Ok(()) +} + +#[test] +fn secret_in_separate_file() -> Result<(), Box> { + // Prepare temp dir for running genpolicy. + let test_case_dir = "secret_separate_file"; + let pod_yaml_name = "pod_with_secret_ref.yaml"; + let config_file = "secret.yaml"; + let workdir = prepare_workdir(test_case_dir, &[pod_yaml_name, config_file]); + + let mut cmd = Command::cargo_bin("genpolicy")?; + cmd.arg("--yaml-file").arg(workdir.join(pod_yaml_name)); + cmd.assert().failure(); + + let mut cmd = Command::cargo_bin("genpolicy")?; + cmd.arg("--yaml-file").arg(workdir.join(pod_yaml_name)); + cmd.arg("--config-file").arg(workdir.join(config_file)); + cmd.assert().success(); + + Ok(()) +} + +fn prepare_workdir(test_case_dir: &str, files_to_copy: &[&str]) -> path::PathBuf { + // Prepare temp dir for running genpolicy. + let workdir = path::PathBuf::from(env!("CARGO_TARGET_TMPDIR")).join(test_case_dir); + fs::create_dir_all(&workdir) + .expect("should be able to create directories under CARGO_TARGET_TMPDIR"); + + let testdata_dir = + path::PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("tests/generate/testdata"); + + // Make sure that workdir is empty. + for entry in fs::read_dir(&workdir).expect("should be able to read directories") { + let entry = entry.expect("should be able to read directory entries"); + fs::remove_file(entry.path()).expect("should be able to remove files"); + } + + for file in files_to_copy { + fs::copy(testdata_dir.join(file), workdir.join(file)) + .expect("copying files around should not fail"); + } + + let genpolicy_dir = path::PathBuf::from(env!("CARGO_MANIFEST_DIR")); + + for base in ["rules.rego", "genpolicy-settings.json"] { + fs::copy(genpolicy_dir.join(base), workdir.join(base)) + .expect("copying files around should not fail"); + } + + workdir +} diff --git a/src/tools/genpolicy/tests/generate/testdata/config_map.yaml b/src/tools/genpolicy/tests/generate/testdata/config_map.yaml new file mode 100644 index 000000000..c42f67b73 --- /dev/null +++ b/src/tools/genpolicy/tests/generate/testdata/config_map.yaml @@ -0,0 +1,75 @@ +apiVersion: v1 +data: + key: YmFyCg== +kind: ConfigMap +metadata: + name: configmap-sample +--- +apiVersion: v1 +data: + key: YmFyCg== +kind: ConfigMap +metadata: + name: configmap-sample2 +--- +# Add some other yaml document to make sure that we can parse out +# ConfigMaps and Secrets from yaml files with multiple documents. +apiVersion: v1 +kind: Pod +metadata: + name: one-container-config-map + labels: + run: busybox +spec: + restartPolicy: Never + runtimeClassName: kata-cc + containers: + - name: busybox + image: "quay.io/prometheus/busybox:latest" + stdin: true + env: + - name: ENV_FROM_CONFIGMAP + valueFrom: + configMapKeyRef: + key: key + name: configmap-sample + - name: POD_NAME + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.name + - name: POD_NAMESPACE + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.namespace + - name: POD_IP + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: status.podIP + - name: SERVICE_ACCOUNT + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: spec.serviceAccountName + - name: PROXY_CONFIG + value: "{}\n" + - name: ISTIO_META_POD_PORTS + value: "[\n]" + - name: ISTIO_META_APP_CONTAINERS + value: serviceaclient + - name: ISTIO_META_CLUSTER_ID + value: Kubernetes + - name: ISTIO_META_NODE_NAME + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: spec.nodeName + securityContext: + privileged: true + command: + - /bin/sh + args: + - "-c" + - while true; do echo $(POD_NAME); sleep 10; done diff --git a/src/tools/genpolicy/tests/generate/testdata/pod_with_config_map_ref.yaml b/src/tools/genpolicy/tests/generate/testdata/pod_with_config_map_ref.yaml new file mode 100644 index 000000000..76a39f4e3 --- /dev/null +++ b/src/tools/genpolicy/tests/generate/testdata/pod_with_config_map_ref.yaml @@ -0,0 +1,60 @@ +--- +apiVersion: v1 +kind: Pod +metadata: + name: one-container + labels: + run: busybox +spec: + restartPolicy: Never + runtimeClassName: kata-cc + containers: + - name: busybox + image: "quay.io/prometheus/busybox:latest" + stdin: true + env: + - name: ENV_FROM_CONFIGMAP + valueFrom: + configMapKeyRef: + key: key + name: configmap-sample + - name: POD_NAME + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.name + - name: POD_NAMESPACE + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.namespace + - name: POD_IP + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: status.podIP + - name: SERVICE_ACCOUNT + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: spec.serviceAccountName + - name: PROXY_CONFIG + value: "{}\n" + - name: ISTIO_META_POD_PORTS + value: "[\n]" + - name: ISTIO_META_APP_CONTAINERS + value: serviceaclient + - name: ISTIO_META_CLUSTER_ID + value: Kubernetes + - name: ISTIO_META_NODE_NAME + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: spec.nodeName + securityContext: + privileged: true + command: + - /bin/sh + args: + - "-c" + - while true; do echo $(POD_NAME); sleep 10; done diff --git a/src/tools/genpolicy/tests/generate/testdata/pod_with_secret_ref.yaml b/src/tools/genpolicy/tests/generate/testdata/pod_with_secret_ref.yaml new file mode 100644 index 000000000..062da520c --- /dev/null +++ b/src/tools/genpolicy/tests/generate/testdata/pod_with_secret_ref.yaml @@ -0,0 +1,60 @@ +--- +apiVersion: v1 +kind: Pod +metadata: + name: one-container + labels: + run: busybox +spec: + restartPolicy: Never + runtimeClassName: kata-cc + containers: + - name: busybox + image: "quay.io/prometheus/busybox:latest" + stdin: true + env: + - name: ENV_FROM_SECRET + valueFrom: + secretKeyRef: + key: key + name: secret-sample + - name: POD_NAME + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.name + - name: POD_NAMESPACE + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.namespace + - name: POD_IP + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: status.podIP + - name: SERVICE_ACCOUNT + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: spec.serviceAccountName + - name: PROXY_CONFIG + value: "{}\n" + - name: ISTIO_META_POD_PORTS + value: "[\n]" + - name: ISTIO_META_APP_CONTAINERS + value: serviceaclient + - name: ISTIO_META_CLUSTER_ID + value: Kubernetes + - name: ISTIO_META_NODE_NAME + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: spec.nodeName + securityContext: + privileged: true + command: + - /bin/sh + args: + - "-c" + - while true; do echo $(POD_NAME); sleep 10; done diff --git a/src/tools/genpolicy/tests/generate/testdata/secret.yaml b/src/tools/genpolicy/tests/generate/testdata/secret.yaml new file mode 100644 index 000000000..9d8c6c696 --- /dev/null +++ b/src/tools/genpolicy/tests/generate/testdata/secret.yaml @@ -0,0 +1,73 @@ +apiVersion: v1 +data: + key: YmFyCg== +kind: Secret +metadata: + name: secret-sample +--- +apiVersion: v1 +data: + key: YmFyCg== +kind: ConfigMap +metadata: + name: configmap-sample3 +--- +apiVersion: v1 +kind: Pod +metadata: + name: one-container-secret + labels: + run: busybox +spec: + restartPolicy: Never + runtimeClassName: kata-cc + containers: + - name: busybox + image: "quay.io/prometheus/busybox:latest" + stdin: true + env: + - name: ENV_FROM_CONFIGMAP + valueFrom: + configMapKeyRef: + key: key + name: configmap-sample + - name: POD_NAME + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.name + - name: POD_NAMESPACE + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.namespace + - name: POD_IP + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: status.podIP + - name: SERVICE_ACCOUNT + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: spec.serviceAccountName + - name: PROXY_CONFIG + value: "{}\n" + - name: ISTIO_META_POD_PORTS + value: "[\n]" + - name: ISTIO_META_APP_CONTAINERS + value: serviceaclient + - name: ISTIO_META_CLUSTER_ID + value: Kubernetes + - name: ISTIO_META_NODE_NAME + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: spec.nodeName + securityContext: + privileged: true + command: + - /bin/sh + args: + - "-c" + - while true; do echo $(POD_NAME); sleep 10; done diff --git a/src/tools/genpolicy/tests/main.rs b/src/tools/genpolicy/tests/policy/main.rs similarity index 84% rename from src/tools/genpolicy/tests/main.rs rename to src/tools/genpolicy/tests/policy/main.rs index e6a827573..be89899bb 100644 --- a/src/tools/genpolicy/tests/main.rs +++ b/src/tools/genpolicy/tests/policy/main.rs @@ -5,6 +5,7 @@ #[cfg(test)] mod tests { + use anyhow::Context; use base64::prelude::*; use std::fmt::{self, Display}; use std::fs::{self, File}; @@ -63,29 +64,13 @@ mod tests { /// with the tag `type` listing the exact type of request. async fn runtests(test_case_dir: &str) { // Prepare temp dir for running genpolicy. - let workdir = path::PathBuf::from(env!("CARGO_TARGET_TMPDIR")).join(test_case_dir); - fs::create_dir_all(&workdir) - .expect("should be able to create directories under CARGO_TARGET_TMPDIR"); - - let testdata_dir = path::PathBuf::from(env!("CARGO_MANIFEST_DIR")) - .join("tests/testdata") - .join(test_case_dir); - fs::copy(testdata_dir.join("pod.yaml"), workdir.join("pod.yaml")) - .expect("copying files around should not fail"); - - let genpolicy_dir = - path::PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("../../tools/genpolicy"); - - for base in ["rules.rego", "genpolicy-settings.json"] { - fs::copy(genpolicy_dir.join(base), workdir.join(base)) - .expect("copying files around should not fail"); - } + let (workdir, testdata_dir) = prepare_workdir(test_case_dir, &["pod.yaml"]); // Run the command and return the generated policy. let config = genpolicy::utils::Config { base64_out: false, - config_map_files: None, + config_files: None, containerd_socket_path: None, // Some(String::from("/var/run/containerd/containerd.sock")), insecure_registries: Vec::new(), layers_cache_file_path: None, @@ -153,6 +138,50 @@ mod tests { } } + fn prepare_workdir( + test_case_dir: &str, + files_to_copy: &[&str], + ) -> (path::PathBuf, path::PathBuf) { + // Prepare temp dir for running genpolicy. + let workdir = path::PathBuf::from(env!("CARGO_TARGET_TMPDIR")).join(test_case_dir); + fs::create_dir_all(&workdir) + .expect("should be able to create directories under CARGO_TARGET_TMPDIR"); + + let testdata_dir = path::PathBuf::from(env!("CARGO_MANIFEST_DIR")) + .join("tests/policy/testdata") + .join(test_case_dir); + + // Make sure that workdir is empty. + for entry in fs::read_dir(&workdir).expect("should be able to read directories") { + let entry = entry.expect("should be able to read directory entries"); + fs::remove_file(entry.path()).expect("should be able to remove files"); + } + + for file in files_to_copy { + fs::copy(testdata_dir.join(file), workdir.join(file)) + .context(format!( + "{:?} --> {:?}", + testdata_dir.join(file), + workdir.join(file) + )) + .expect("copying files around should not fail"); + } + + let genpolicy_dir = path::PathBuf::from(env!("CARGO_MANIFEST_DIR")); + + for base in ["rules.rego", "genpolicy-settings.json"] { + fs::copy(genpolicy_dir.join(base), workdir.join(base)) + .context(format!( + "{:?} --> {:?}", + genpolicy_dir.join(base), + workdir.join(base) + )) + .expect("copying files around should not fail"); + } + + (workdir, testdata_dir) + } + #[tokio::test] async fn test_copyfile() { runtests("copyfile").await; diff --git a/src/tools/genpolicy/tests/testdata/copyfile/pod.yaml b/src/tools/genpolicy/tests/policy/testdata/copyfile/pod.yaml similarity index 100% rename from src/tools/genpolicy/tests/testdata/copyfile/pod.yaml rename to src/tools/genpolicy/tests/policy/testdata/copyfile/pod.yaml diff --git a/src/tools/genpolicy/tests/testdata/copyfile/testcases.json b/src/tools/genpolicy/tests/policy/testdata/copyfile/testcases.json similarity index 100% rename from src/tools/genpolicy/tests/testdata/copyfile/testcases.json rename to src/tools/genpolicy/tests/policy/testdata/copyfile/testcases.json diff --git a/src/tools/genpolicy/tests/testdata/createcontainer/generate_name/pod.yaml b/src/tools/genpolicy/tests/policy/testdata/createcontainer/generate_name/pod.yaml similarity index 100% rename from src/tools/genpolicy/tests/testdata/createcontainer/generate_name/pod.yaml rename to src/tools/genpolicy/tests/policy/testdata/createcontainer/generate_name/pod.yaml diff --git a/src/tools/genpolicy/tests/testdata/createcontainer/generate_name/testcases.json b/src/tools/genpolicy/tests/policy/testdata/createcontainer/generate_name/testcases.json similarity index 100% rename from src/tools/genpolicy/tests/testdata/createcontainer/generate_name/testcases.json rename to src/tools/genpolicy/tests/policy/testdata/createcontainer/generate_name/testcases.json diff --git a/src/tools/genpolicy/tests/testdata/createcontainer/network_namespace/pod.yaml b/src/tools/genpolicy/tests/policy/testdata/createcontainer/network_namespace/pod.yaml similarity index 100% rename from src/tools/genpolicy/tests/testdata/createcontainer/network_namespace/pod.yaml rename to src/tools/genpolicy/tests/policy/testdata/createcontainer/network_namespace/pod.yaml diff --git a/src/tools/genpolicy/tests/testdata/createcontainer/network_namespace/testcases.json b/src/tools/genpolicy/tests/policy/testdata/createcontainer/network_namespace/testcases.json similarity index 100% rename from src/tools/genpolicy/tests/testdata/createcontainer/network_namespace/testcases.json rename to src/tools/genpolicy/tests/policy/testdata/createcontainer/network_namespace/testcases.json diff --git a/src/tools/genpolicy/tests/testdata/createcontainer/security_context/pod.yaml b/src/tools/genpolicy/tests/policy/testdata/createcontainer/security_context/pod.yaml similarity index 100% rename from src/tools/genpolicy/tests/testdata/createcontainer/security_context/pod.yaml rename to src/tools/genpolicy/tests/policy/testdata/createcontainer/security_context/pod.yaml diff --git a/src/tools/genpolicy/tests/testdata/createcontainer/security_context/testcases.json b/src/tools/genpolicy/tests/policy/testdata/createcontainer/security_context/testcases.json similarity index 100% rename from src/tools/genpolicy/tests/testdata/createcontainer/security_context/testcases.json rename to src/tools/genpolicy/tests/policy/testdata/createcontainer/security_context/testcases.json diff --git a/src/tools/genpolicy/tests/testdata/createcontainer/sysctls/pod.yaml b/src/tools/genpolicy/tests/policy/testdata/createcontainer/sysctls/pod.yaml similarity index 100% rename from src/tools/genpolicy/tests/testdata/createcontainer/sysctls/pod.yaml rename to src/tools/genpolicy/tests/policy/testdata/createcontainer/sysctls/pod.yaml diff --git a/src/tools/genpolicy/tests/testdata/createcontainer/sysctls/testcases.json b/src/tools/genpolicy/tests/policy/testdata/createcontainer/sysctls/testcases.json similarity index 100% rename from src/tools/genpolicy/tests/testdata/createcontainer/sysctls/testcases.json rename to src/tools/genpolicy/tests/policy/testdata/createcontainer/sysctls/testcases.json diff --git a/src/tools/genpolicy/tests/testdata/createcontainer/volumes/emptydir/pod.yaml b/src/tools/genpolicy/tests/policy/testdata/createcontainer/volumes/emptydir/pod.yaml similarity index 100% rename from src/tools/genpolicy/tests/testdata/createcontainer/volumes/emptydir/pod.yaml rename to src/tools/genpolicy/tests/policy/testdata/createcontainer/volumes/emptydir/pod.yaml diff --git a/src/tools/genpolicy/tests/testdata/createcontainer/volumes/emptydir/testcases.json b/src/tools/genpolicy/tests/policy/testdata/createcontainer/volumes/emptydir/testcases.json similarity index 100% rename from src/tools/genpolicy/tests/testdata/createcontainer/volumes/emptydir/testcases.json rename to src/tools/genpolicy/tests/policy/testdata/createcontainer/volumes/emptydir/testcases.json diff --git a/src/tools/genpolicy/tests/testdata/createsandbox/pod.yaml b/src/tools/genpolicy/tests/policy/testdata/createsandbox/pod.yaml similarity index 100% rename from src/tools/genpolicy/tests/testdata/createsandbox/pod.yaml rename to src/tools/genpolicy/tests/policy/testdata/createsandbox/pod.yaml diff --git a/src/tools/genpolicy/tests/testdata/createsandbox/testcases.json b/src/tools/genpolicy/tests/policy/testdata/createsandbox/testcases.json similarity index 100% rename from src/tools/genpolicy/tests/testdata/createsandbox/testcases.json rename to src/tools/genpolicy/tests/policy/testdata/createsandbox/testcases.json diff --git a/src/tools/genpolicy/tests/testdata/state/createcontainer/pod.yaml b/src/tools/genpolicy/tests/policy/testdata/state/createcontainer/pod.yaml similarity index 100% rename from src/tools/genpolicy/tests/testdata/state/createcontainer/pod.yaml rename to src/tools/genpolicy/tests/policy/testdata/state/createcontainer/pod.yaml diff --git a/src/tools/genpolicy/tests/testdata/state/createcontainer/testcases.json b/src/tools/genpolicy/tests/policy/testdata/state/createcontainer/testcases.json similarity index 100% rename from src/tools/genpolicy/tests/testdata/state/createcontainer/testcases.json rename to src/tools/genpolicy/tests/policy/testdata/state/createcontainer/testcases.json diff --git a/src/tools/genpolicy/tests/testdata/state/execprocess/pod.yaml b/src/tools/genpolicy/tests/policy/testdata/state/execprocess/pod.yaml similarity index 100% rename from src/tools/genpolicy/tests/testdata/state/execprocess/pod.yaml rename to src/tools/genpolicy/tests/policy/testdata/state/execprocess/pod.yaml diff --git a/src/tools/genpolicy/tests/testdata/state/execprocess/testcases.json b/src/tools/genpolicy/tests/policy/testdata/state/execprocess/testcases.json similarity index 100% rename from src/tools/genpolicy/tests/testdata/state/execprocess/testcases.json rename to src/tools/genpolicy/tests/policy/testdata/state/execprocess/testcases.json diff --git a/src/tools/genpolicy/tests/testdata/updateinterface/pod.yaml b/src/tools/genpolicy/tests/policy/testdata/updateinterface/pod.yaml similarity index 100% rename from src/tools/genpolicy/tests/testdata/updateinterface/pod.yaml rename to src/tools/genpolicy/tests/policy/testdata/updateinterface/pod.yaml diff --git a/src/tools/genpolicy/tests/testdata/updateinterface/testcases.json b/src/tools/genpolicy/tests/policy/testdata/updateinterface/testcases.json similarity index 100% rename from src/tools/genpolicy/tests/testdata/updateinterface/testcases.json rename to src/tools/genpolicy/tests/policy/testdata/updateinterface/testcases.json diff --git a/src/tools/genpolicy/tests/testdata/updateroutes/pod.yaml b/src/tools/genpolicy/tests/policy/testdata/updateroutes/pod.yaml similarity index 100% rename from src/tools/genpolicy/tests/testdata/updateroutes/pod.yaml rename to src/tools/genpolicy/tests/policy/testdata/updateroutes/pod.yaml diff --git a/src/tools/genpolicy/tests/testdata/updateroutes/testcases.json b/src/tools/genpolicy/tests/policy/testdata/updateroutes/testcases.json similarity index 100% rename from src/tools/genpolicy/tests/testdata/updateroutes/testcases.json rename to src/tools/genpolicy/tests/policy/testdata/updateroutes/testcases.json