diff --git a/src/tools/genpolicy/tests/main.rs b/src/tools/genpolicy/tests/main.rs index 26d7e676c3..b3fa518f10 100644 --- a/src/tools/genpolicy/tests/main.rs +++ b/src/tools/genpolicy/tests/main.rs @@ -6,7 +6,7 @@ #[cfg(test)] mod tests { use base64::prelude::*; - use std::any; + use std::fmt::{self, Display}; use std::fs::{self, File}; use std::path; use std::str; @@ -15,16 +15,39 @@ mod tests { CopyFileRequest, CreateContainerRequest, CreateSandboxRequest, UpdateInterfaceRequest, UpdateRoutesRequest, }; - use serde::de::DeserializeOwned; use serde::{Deserialize, Serialize}; use kata_agent_policy::policy::AgentPolicy; + // Translate each test case in testcases.json + // to one request type. #[derive(Clone, Debug, Deserialize, Serialize)] - struct TestCase { + #[serde(tag = "type")] + enum TestRequest { + CopyFile(CopyFileRequest), + CreateContainer(CreateContainerRequest), + CreateSandbox(CreateSandboxRequest), + UpdateInterface(UpdateInterfaceRequest), + UpdateRoutes(UpdateRoutesRequest), + } + + impl Display for TestRequest { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + TestRequest::CopyFile(_) => write!(f, "CopyFileRequest"), + TestRequest::CreateContainer(_) => write!(f, "CreateContainerRequest"), + TestRequest::CreateSandbox(_) => write!(f, "CreateSandboxRequest"), + TestRequest::UpdateInterface(_) => write!(f, "UpdateInterfaceRequest"), + TestRequest::UpdateRoutes(_) => write!(f, "UpdateRoutesRequest"), + } + } + } + + #[derive(Clone, Debug, Deserialize, Serialize)] + struct TestCase { description: String, allowed: bool, - request: T, + request: TestRequest, } /// Run tests from the given directory. @@ -32,11 +55,9 @@ mod tests { /// it must contain a `resources.yaml` file as well as a `testcases.json` file. /// The resources must produce a policy when fed into genpolicy, so there /// should be exactly one entry with a PodSpec. The test case file must contain - /// a JSON list of [TestCase] instances appropriate for `T`. - async fn runtests(test_case_dir: &str) - where - T: DeserializeOwned + Serialize, - { + /// a JSON list of [TestCase] instances. Each instance will be of type enum TestRequest, + /// 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) @@ -102,7 +123,7 @@ mod tests { let case_file = File::open(testdata_dir.join("testcases.json")).expect("test case file should open"); - let test_cases: Vec> = + let test_cases: Vec = serde_json::from_reader(case_file).expect("test case file should parse"); for test_case in test_cases { @@ -112,7 +133,7 @@ mod tests { let results = pol .allow_request( - any::type_name::().split("::").last().unwrap(), + &test_case.request.to_string(), &serde_json::to_string(&v).unwrap(), ) .await; @@ -130,36 +151,36 @@ mod tests { #[tokio::test] async fn test_copyfile() { - runtests::("copyfile").await; + runtests("copyfile").await; } #[tokio::test] async fn test_create_sandbox() { - runtests::("createsandbox").await; + runtests("createsandbox").await; } #[tokio::test] async fn test_update_routes() { - runtests::("updateroutes").await; + runtests("updateroutes").await; } #[tokio::test] async fn test_update_interface() { - runtests::("updateinterface").await; + runtests("updateinterface").await; } #[tokio::test] async fn test_create_container_network_namespace() { - runtests::("createcontainer/network_namespace").await; + runtests("createcontainer/network_namespace").await; } #[tokio::test] async fn test_create_container_sysctls() { - runtests::("createcontainer/sysctls").await; + runtests("createcontainer/sysctls").await; } #[tokio::test] async fn test_create_container_generate_name() { - runtests::("createcontainer/generate_name").await; + runtests("createcontainer/generate_name").await; } } diff --git a/src/tools/genpolicy/tests/testdata/copyfile/testcases.json b/src/tools/genpolicy/tests/testdata/copyfile/testcases.json index d6b56f7a19..fce3a84e52 100644 --- a/src/tools/genpolicy/tests/testdata/copyfile/testcases.json +++ b/src/tools/genpolicy/tests/testdata/copyfile/testcases.json @@ -3,6 +3,7 @@ "description": "copy initiated by k8s mount", "allowed": true, "request": { + "type": "CopyFile", "path": "/run/kata-containers/shared/containers/81e5f43bc8599c5661e66f959ac28df5bfb30da23c5d583f2dcc6f9e0c5186dc-ce23cfeb91e75aaa-resolv.conf" } }, @@ -10,6 +11,7 @@ "description": "a dirname can have trailing dots", "allowed": true, "request": { + "type": "CopyFile", "path": "/run/kata-containers/shared/containers/81e5f43bc8599c5661e66f959ac28df5bfb30da23c5d583f2dcc6f9e0c5186dc-ce23cfeb91e75aaa-foo../bar" } }, @@ -17,6 +19,7 @@ "description": "attempt to copy outside of container root", "allowed": false, "request": { + "type": "CopyFile", "path": "/etc/ssl/cert.pem" } }, @@ -24,6 +27,7 @@ "description": "attempt to write into container root", "allowed": false, "request": { + "type": "CopyFile", "path": "/run/kata-containers/shared/containers/81e5f43bc8599c5661e66f959ac28df5bfb30da23c5d583f2dcc6f9e0c5186dc/rootfs/bin/sh" } }, @@ -31,6 +35,7 @@ "description": "attempt to write into container root - guest pull", "allowed": false, "request": { + "type": "CopyFile", "path": "/run/kata-containers/81e5f43bc8599c5661e66f959ac28df5bfb30da23c5d583f2dcc6f9e0c5186dc/rootfs/bin/sh" } }, @@ -38,6 +43,7 @@ "description": "attempted directory traversal", "allowed": false, "request": { + "type": "CopyFile", "path": "/run/kata-containers/shared/containers/81e5f43bc8599c5661e66f959ac28df5bfb30da23c5d583f2dcc6f9e0c5186dc-ce23cfeb91e75aaa-foo/../../../../../etc/ssl/cert.pem" } }, @@ -45,6 +51,7 @@ "description": "attempted directory traversal - parent directory", "allowed": false, "request": { + "type": "CopyFile", "path": "/run/kata-containers/shared/containers/81e5f43bc8599c5661e66f959ac28df5bfb30da23c5d583f2dcc6f9e0c5186dc-ce23cfeb91e75aaa-foo/.." } }, @@ -52,6 +59,7 @@ "description": "relative path", "allowed": false, "request": { + "type": "CopyFile", "path": "etc/ssl/cert.pem" } }, @@ -59,6 +67,7 @@ "description": "relative path - parent directory", "allowed": false, "request": { + "type": "CopyFile", "path": ".." } } diff --git a/src/tools/genpolicy/tests/testdata/createcontainer/generate_name/testcases.json b/src/tools/genpolicy/tests/testdata/createcontainer/generate_name/testcases.json index 031b3062e1..87865f4c5b 100644 --- a/src/tools/genpolicy/tests/testdata/createcontainer/generate_name/testcases.json +++ b/src/tools/genpolicy/tests/testdata/createcontainer/generate_name/testcases.json @@ -3,6 +3,7 @@ "description": "generated name with valid prefix (dummyxyz)", "allowed": true, "request": { + "type": "CreateContainer", "OCI": { "Version": "1.1.0", "Annotations": { @@ -134,6 +135,7 @@ "description": "generated name with invalid prefix (xyzdummy)", "allowed": false, "request": { + "type": "CreateContainer", "OCI": { "Version": "1.1.0", "Annotations": { diff --git a/src/tools/genpolicy/tests/testdata/createcontainer/network_namespace/testcases.json b/src/tools/genpolicy/tests/testdata/createcontainer/network_namespace/testcases.json index 5de73c5fcc..67b780f71c 100644 --- a/src/tools/genpolicy/tests/testdata/createcontainer/network_namespace/testcases.json +++ b/src/tools/genpolicy/tests/testdata/createcontainer/network_namespace/testcases.json @@ -3,6 +3,7 @@ "description": "one network namespace", "allowed": true, "request": { + "type": "CreateContainer", "OCI": { "Version": "1.1.0", "Annotations": { @@ -134,6 +135,7 @@ "description": "same network namespace", "allowed": true, "request": { + "type": "CreateContainer", "OCI": { "Version": "1.1.0", "Annotations": { @@ -265,6 +267,7 @@ "description": "no network namespace", "allowed": false, "request": { + "type": "CreateContainer", "OCI": { "Version": "1.1.0", "Annotations": { @@ -392,6 +395,7 @@ "description": "different network namespace", "allowed": false, "request": { + "type": "CreateContainer", "OCI": { "Version": "1.1.0", "Annotations": { @@ -519,4 +523,4 @@ } } } -] \ No newline at end of file +] diff --git a/src/tools/genpolicy/tests/testdata/createcontainer/sysctls/testcases.json b/src/tools/genpolicy/tests/testdata/createcontainer/sysctls/testcases.json index 3985006481..a3209134ba 100644 --- a/src/tools/genpolicy/tests/testdata/createcontainer/sysctls/testcases.json +++ b/src/tools/genpolicy/tests/testdata/createcontainer/sysctls/testcases.json @@ -4,6 +4,7 @@ "allowed": true, "state": {"sandbox_name": "policy-redis-deployment-6674f9448-xjrzf"}, "request": { + "type": "CreateContainer", "OCI": { "Annotations": { "io.katacontainers.pkg.oci.bundle_path": "/run/containerd/io.containerd.runtime.v2.task/k8s.io/4bae4a8e74302a8edfe17424aff0b632cae893687f4d9ad2f2115666899f9a12", @@ -279,6 +280,7 @@ "allowed": false, "state": {"sandbox_name": "policy-redis-deployment-6674f9448-xjrzf"}, "request": { + "type": "CreateContainer", "OCI": { "Annotations": { "io.katacontainers.pkg.oci.bundle_path": "/run/containerd/io.containerd.runtime.v2.task/k8s.io/4bae4a8e74302a8edfe17424aff0b632cae893687f4d9ad2f2115666899f9a12", diff --git a/src/tools/genpolicy/tests/testdata/createsandbox/testcases.json b/src/tools/genpolicy/tests/testdata/createsandbox/testcases.json index 430c1d7af3..dfda33479c 100644 --- a/src/tools/genpolicy/tests/testdata/createsandbox/testcases.json +++ b/src/tools/genpolicy/tests/testdata/createsandbox/testcases.json @@ -3,6 +3,7 @@ "description": "no pidns", "allowed": true, "request": { + "type": "CreateSandbox", "sandbox_pidns": false } }, @@ -10,6 +11,7 @@ "description": "pidns", "allowed": false, "request": { + "type": "CreateSandbox", "sandbox_pidns": true } }, @@ -17,6 +19,7 @@ "description": "kernel modules", "allowed": false, "request": { + "type": "CreateSandbox", "sandbox_pidns": false, "kernel_modules": [{"name": "evil.ko"}] } @@ -25,6 +28,7 @@ "description": "guest hooks", "allowed": false, "request": { + "type": "CreateSandbox", "sandbox_pidns": false, "guest_hook_path": "/attacker/controlled/path" } diff --git a/src/tools/genpolicy/tests/testdata/updateinterface/testcases.json b/src/tools/genpolicy/tests/testdata/updateinterface/testcases.json index 70ebb4200c..490c2c00a8 100644 --- a/src/tools/genpolicy/tests/testdata/updateinterface/testcases.json +++ b/src/tools/genpolicy/tests/testdata/updateinterface/testcases.json @@ -3,6 +3,7 @@ "description": "no flags", "allowed": true, "request": { + "type": "UpdateInterface", "interface": { "device": "eth0", "name": "eth0", @@ -22,6 +23,7 @@ "description": "allowed arp flag", "allowed": true, "request": { + "type": "UpdateInterface", "interface": { "device": "eth0", "name": "eth0", @@ -41,6 +43,7 @@ "description": "forbidden flag", "allowed": false, "request": { + "type": "UpdateInterface", "interface": { "device": "eth0", "name": "eth0", @@ -60,6 +63,7 @@ "description": "forbidden name", "allowed": false, "request": { + "type": "UpdateInterface", "interface": { "device": "eth0", "name": "lo", @@ -79,6 +83,7 @@ "description": "forbidden hwAddr", "allowed": false, "request": { + "type": "UpdateInterface", "interface": { "device": "eth0", "name": "eth0", diff --git a/src/tools/genpolicy/tests/testdata/updateroutes/testcases.json b/src/tools/genpolicy/tests/testdata/updateroutes/testcases.json index bc581e6bad..8ada7478d0 100644 --- a/src/tools/genpolicy/tests/testdata/updateroutes/testcases.json +++ b/src/tools/genpolicy/tests/testdata/updateroutes/testcases.json @@ -3,6 +3,7 @@ "description": "compliant routes", "allowed": true, "request": { + "type": "UpdateRoutes", "routes": { "Routes": [ { @@ -21,6 +22,7 @@ "description": "forbidden device", "allowed": false, "request": { + "type": "UpdateRoutes", "routes": { "Routes": [ { @@ -39,6 +41,7 @@ "description": "one compliant route, one noncompliant", "allowed": false, "request": { + "type": "UpdateRoutes", "routes": { "Routes": [ { @@ -65,6 +68,7 @@ "description": "noncompliant routes", "allowed": false, "request": { + "type": "UpdateRoutes", "routes": { "Routes": [ { @@ -83,6 +87,7 @@ "description": "noncompliant routes ipv6 1", "allowed": false, "request": { + "type": "UpdateRoutes", "routes": { "Routes": [ { @@ -101,6 +106,7 @@ "description": "noncompliant routes ipv6 2", "allowed": false, "request": { + "type": "UpdateRoutes", "routes": { "Routes": [ {