mirror of
https://github.com/kata-containers/kata-containers.git
synced 2025-07-19 01:39:48 +00:00
genpolicy: add cli integration tests
Add a new type of integration test to genpolicy. Now we can test flag handling and how the CLI behaves with certain yaml inputs. The first tests cover the case when a Pod references a Kubernetes secret of config map in another file. Those need to be explicitly added via the --config-files flag. In the future we can easily add test suites that cover that all yaml fields of all resources are understood by genpolicy. Signed-off-by: Leonard Cohnen <leonard.cohnen@gmail.com>
This commit is contained in:
parent
61ee330029
commit
bad0cd0003
88
src/tools/genpolicy/Cargo.lock
generated
88
src/tools/genpolicy/Cargo.lock
generated
@ -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"
|
||||
|
@ -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"
|
||||
|
99
src/tools/genpolicy/tests/generate/main.rs
Normal file
99
src/tools/genpolicy/tests/generate/main.rs
Normal file
@ -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<dyn std::error::Error>> {
|
||||
// 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<dyn std::error::Error>> {
|
||||
// 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<dyn std::error::Error>> {
|
||||
// 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
|
||||
}
|
75
src/tools/genpolicy/tests/generate/testdata/config_map.yaml
vendored
Normal file
75
src/tools/genpolicy/tests/generate/testdata/config_map.yaml
vendored
Normal file
@ -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
|
60
src/tools/genpolicy/tests/generate/testdata/pod_with_config_map_ref.yaml
vendored
Normal file
60
src/tools/genpolicy/tests/generate/testdata/pod_with_config_map_ref.yaml
vendored
Normal file
@ -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
|
60
src/tools/genpolicy/tests/generate/testdata/pod_with_secret_ref.yaml
vendored
Normal file
60
src/tools/genpolicy/tests/generate/testdata/pod_with_secret_ref.yaml
vendored
Normal file
@ -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
|
73
src/tools/genpolicy/tests/generate/testdata/secret.yaml
vendored
Normal file
73
src/tools/genpolicy/tests/generate/testdata/secret.yaml
vendored
Normal file
@ -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
|
Loading…
Reference in New Issue
Block a user