mirror of
https://github.com/kata-containers/kata-containers.git
synced 2026-03-18 10:44:10 +00:00
Merge pull request #12542 from fidencio/topic/genpolicy-distribute-different-settings-rather-than-patching-for-ci
genpolicy: settings.d drop-ins and scenario example drop-ins
This commit is contained in:
27
src/tools/genpolicy/Cargo.lock
generated
27
src/tools/genpolicy/Cargo.lock
generated
@@ -958,6 +958,7 @@ dependencies = [
|
||||
"env_logger",
|
||||
"flate2",
|
||||
"fs2",
|
||||
"json-patch 4.1.0",
|
||||
"k8s-cri",
|
||||
"kata-agent-policy",
|
||||
"kata-types",
|
||||
@@ -1532,7 +1533,19 @@ version = "2.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5b1fb8864823fad91877e6caea0baca82e49e8db50f8e5c9f9a453e27d3330fc"
|
||||
dependencies = [
|
||||
"jsonptr",
|
||||
"jsonptr 0.4.7",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"thiserror 1.0.40",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "json-patch"
|
||||
version = "4.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f300e415e2134745ef75f04562dd0145405c2f7fd92065db029ac4b16b57fe90"
|
||||
dependencies = [
|
||||
"jsonptr 0.7.1",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"thiserror 1.0.40",
|
||||
@@ -1549,6 +1562,16 @@ dependencies = [
|
||||
"serde_json",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "jsonptr"
|
||||
version = "0.7.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a5a3cc660ba5d72bce0b3bb295bf20847ccbb40fd423f3f05b61273672e561fe"
|
||||
dependencies = [
|
||||
"serde",
|
||||
"serde_json",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "jwt"
|
||||
version = "0.16.0"
|
||||
@@ -1581,7 +1604,7 @@ name = "kata-agent-policy"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"json-patch",
|
||||
"json-patch 2.0.0",
|
||||
"regorus",
|
||||
"serde",
|
||||
"serde_json",
|
||||
|
||||
@@ -46,6 +46,7 @@ oci-client = { version = "0.12.0" }
|
||||
openssl = { version = "0.10.73", features = ["vendored"] }
|
||||
serde_ignored = "0.1.7"
|
||||
serde_json = "1.0.39"
|
||||
json-patch = "4.1"
|
||||
tempfile = "3.19.1"
|
||||
tokio = { version = "1.38.0", features = ["rt-multi-thread"] }
|
||||
|
||||
|
||||
@@ -47,6 +47,13 @@ For advanced command line parameters, see [`genpolicy` advanced command line par
|
||||
|
||||
`genpolicy` has support for automatic Policy generation based on Kubernetes `DaemonSet`, `Deployment`, `Job`, `Pod`, `ReplicaSet`, `ReplicationController`, and `StatefulSet` input `YAML` files.
|
||||
|
||||
# Settings directory and drop-ins
|
||||
|
||||
You can pass a **directory** to `-j` instead of a single file. In that case `genpolicy` loads `genpolicy-settings.json` from that directory and applies all `genpolicy-settings.d/*.json` files (sorted by name) in order. Each drop-in must be an [RFC 6902 JSON Patch](https://datatracker.ietf.org/doc/html/rfc6902): a JSON array of operations (`add`, `remove`, `replace`, `move`, `copy`, `test`). This gives precise control (e.g. array indices) and optional `test` for assertions.
|
||||
|
||||
- **`genpolicy-settings.d/`** — empty by default; add your drop-in JSON Patch files here.
|
||||
- **`drop-in-examples/`** — example scenario drop-ins (`10-*.json` platform base, `20-*.json` overlays), each a JSON Patch array. Copy the ones you need into your own `genpolicy-settings.d/`. See the [drop-in examples documentation](drop-in-examples/README.md). These examples are tested in Kata Containers CI.
|
||||
|
||||
# Policy details
|
||||
|
||||
See [auto-generated Policy details](genpolicy-auto-generated-policy-details.md).
|
||||
|
||||
@@ -0,0 +1,82 @@
|
||||
[
|
||||
{
|
||||
"op": "replace",
|
||||
"path": "/cluster_config/guest_pull",
|
||||
"value": false
|
||||
},
|
||||
{
|
||||
"op": "replace",
|
||||
"path": "/cluster_config/pause_container_id_policy",
|
||||
"value": "v2"
|
||||
},
|
||||
{
|
||||
"op": "replace",
|
||||
"path": "/cluster_config/pause_container_image",
|
||||
"value": "mcr.microsoft.com/oss/v2/kubernetes/pause:3.6"
|
||||
},
|
||||
{
|
||||
"op": "replace",
|
||||
"path": "/common/root_path",
|
||||
"value": "/run/kata-containers/shared/containers/$(bundle-id)/rootfs"
|
||||
},
|
||||
{
|
||||
"op": "replace",
|
||||
"path": "/kata_config/enable_configmap_secret_storages",
|
||||
"value": true
|
||||
},
|
||||
{
|
||||
"op": "replace",
|
||||
"path": "/pause_container/Process/User/UID",
|
||||
"value": 0
|
||||
},
|
||||
{
|
||||
"op": "replace",
|
||||
"path": "/pause_container/Process/User/GID",
|
||||
"value": 0
|
||||
},
|
||||
{
|
||||
"op": "replace",
|
||||
"path": "/request_defaults/UpdateEphemeralMountsRequest",
|
||||
"value": true
|
||||
},
|
||||
{
|
||||
"op": "replace",
|
||||
"path": "/sandbox/storages",
|
||||
"value": [
|
||||
{
|
||||
"driver": "ephemeral",
|
||||
"driver_options": [],
|
||||
"fs_group": null,
|
||||
"fstype": "tmpfs",
|
||||
"mount_point": "/run/kata-containers/sandbox/shm",
|
||||
"options": [
|
||||
"noexec",
|
||||
"nosuid",
|
||||
"nodev",
|
||||
"mode=1777",
|
||||
"size=67108864"
|
||||
],
|
||||
"source": "shm"
|
||||
},
|
||||
{
|
||||
"driver": "virtio-fs",
|
||||
"driver_options": [],
|
||||
"fs_group": null,
|
||||
"fstype": "virtiofs",
|
||||
"mount_point": "/run/kata-containers/shared/containers/",
|
||||
"options": [],
|
||||
"source": "kataShared"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"op": "replace",
|
||||
"path": "/volumes/configMap/driver",
|
||||
"value": "watchable-bind"
|
||||
},
|
||||
{
|
||||
"op": "replace",
|
||||
"path": "/volumes/configMap/mount_point",
|
||||
"value": "^$(cpath)/watchable/$(bundle-id)-[a-z0-9]{16}-"
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,82 @@
|
||||
[
|
||||
{
|
||||
"op": "replace",
|
||||
"path": "/cluster_config/guest_pull",
|
||||
"value": false
|
||||
},
|
||||
{
|
||||
"op": "replace",
|
||||
"path": "/cluster_config/pause_container_id_policy",
|
||||
"value": "v2"
|
||||
},
|
||||
{
|
||||
"op": "replace",
|
||||
"path": "/cluster_config/pause_container_image",
|
||||
"value": "mcr.microsoft.com/oss/v2/kubernetes/pause:3.6"
|
||||
},
|
||||
{
|
||||
"op": "replace",
|
||||
"path": "/common/root_path",
|
||||
"value": "/run/kata-containers/shared/containers/$(bundle-id)/rootfs"
|
||||
},
|
||||
{
|
||||
"op": "replace",
|
||||
"path": "/kata_config/enable_configmap_secret_storages",
|
||||
"value": true
|
||||
},
|
||||
{
|
||||
"op": "replace",
|
||||
"path": "/pause_container/Process/User/UID",
|
||||
"value": 0
|
||||
},
|
||||
{
|
||||
"op": "replace",
|
||||
"path": "/pause_container/Process/User/GID",
|
||||
"value": 0
|
||||
},
|
||||
{
|
||||
"op": "replace",
|
||||
"path": "/request_defaults/UpdateEphemeralMountsRequest",
|
||||
"value": true
|
||||
},
|
||||
{
|
||||
"op": "replace",
|
||||
"path": "/sandbox/storages",
|
||||
"value": [
|
||||
{
|
||||
"driver": "ephemeral",
|
||||
"driver_options": [],
|
||||
"fs_group": null,
|
||||
"fstype": "tmpfs",
|
||||
"mount_point": "/run/kata-containers/sandbox/shm",
|
||||
"options": [
|
||||
"noexec",
|
||||
"nosuid",
|
||||
"nodev",
|
||||
"mode=1777",
|
||||
"size=67108864"
|
||||
],
|
||||
"source": "shm"
|
||||
},
|
||||
{
|
||||
"driver": "virtio-fs",
|
||||
"driver_options": [],
|
||||
"fs_group": null,
|
||||
"fstype": "virtiofs",
|
||||
"mount_point": "/run/kata-containers/shared/containers/",
|
||||
"options": [],
|
||||
"source": "kataShared"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"op": "replace",
|
||||
"path": "/volumes/configMap/driver",
|
||||
"value": "watchable-bind"
|
||||
},
|
||||
{
|
||||
"op": "replace",
|
||||
"path": "/volumes/configMap/mount_point",
|
||||
"value": "^$(cpath)/watchable/$(bundle-id)-[a-z0-9]{16}-"
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,62 @@
|
||||
[
|
||||
{
|
||||
"op": "replace",
|
||||
"path": "/cluster_config/guest_pull",
|
||||
"value": false
|
||||
},
|
||||
{
|
||||
"op": "replace",
|
||||
"path": "/common/root_path",
|
||||
"value": "/run/kata-containers/shared/containers/$(bundle-id)/rootfs"
|
||||
},
|
||||
{
|
||||
"op": "replace",
|
||||
"path": "/kata_config/enable_configmap_secret_storages",
|
||||
"value": true
|
||||
},
|
||||
{
|
||||
"op": "replace",
|
||||
"path": "/request_defaults/UpdateEphemeralMountsRequest",
|
||||
"value": true
|
||||
},
|
||||
{
|
||||
"op": "replace",
|
||||
"path": "/sandbox/storages",
|
||||
"value": [
|
||||
{
|
||||
"driver": "ephemeral",
|
||||
"driver_options": [],
|
||||
"fs_group": null,
|
||||
"fstype": "tmpfs",
|
||||
"mount_point": "/run/kata-containers/sandbox/shm",
|
||||
"options": [
|
||||
"noexec",
|
||||
"nosuid",
|
||||
"nodev",
|
||||
"mode=1777",
|
||||
"size=67108864"
|
||||
],
|
||||
"source": "shm"
|
||||
},
|
||||
{
|
||||
"driver": "virtio-fs",
|
||||
"driver_options": [],
|
||||
"fs_group": null,
|
||||
"fstype": "virtiofs",
|
||||
"mount_point": "/run/kata-containers/shared/containers/",
|
||||
"options": [],
|
||||
"source": "kataShared"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"op": "replace",
|
||||
"path": "/volumes/configMap/driver",
|
||||
"value": "watchable-bind"
|
||||
},
|
||||
{
|
||||
"op": "replace",
|
||||
"path": "/volumes/configMap/mount_point",
|
||||
"value": "^$(cpath)/watchable/$(bundle-id)-[a-z0-9]{16}-"
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,7 @@
|
||||
[
|
||||
{
|
||||
"op": "replace",
|
||||
"path": "/cluster_config/guest_pull",
|
||||
"value": false
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,7 @@
|
||||
[
|
||||
{
|
||||
"op": "replace",
|
||||
"path": "/kata_config/oci_version",
|
||||
"value": "1.2.0"
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,7 @@
|
||||
[
|
||||
{
|
||||
"op": "replace",
|
||||
"path": "/kata_config/oci_version",
|
||||
"value": "1.2.1"
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,7 @@
|
||||
[
|
||||
{
|
||||
"op": "replace",
|
||||
"path": "/kata_config/oci_version",
|
||||
"value": "1.3.0"
|
||||
}
|
||||
]
|
||||
31
src/tools/genpolicy/drop-in-examples/README.md
Normal file
31
src/tools/genpolicy/drop-in-examples/README.md
Normal file
@@ -0,0 +1,31 @@
|
||||
# Example drop-ins for genpolicy settings
|
||||
|
||||
Copy the drop-in file(s) you need into the `genpolicy-settings.d/` subdirectory next to your `genpolicy-settings.json`, then point `genpolicy -j` at the parent directory. For example:
|
||||
|
||||
```
|
||||
my-settings/
|
||||
genpolicy-settings.json
|
||||
genpolicy-settings.d/
|
||||
10-non-coco-drop-in.json
|
||||
20-oci-1.2.1-drop-in.json
|
||||
```
|
||||
|
||||
```sh
|
||||
genpolicy -j my-settings/ ...
|
||||
```
|
||||
|
||||
Each drop-in is an [RFC 6902 JSON Patch](https://datatracker.ietf.org/doc/html/rfc6902): a JSON array of operations (`add`, `remove`, `replace`, `move`, `copy`, `test`). Use `replace` for existing paths, `add` for new keys or array append (path ending in `/-`), and optional `test` to assert values before changing them.
|
||||
|
||||
Drop-ins are layered: `10-*` files set the platform base, `20-*` files overlay OCI version and other adjustments. You can combine multiple drop-ins (e.g. `10-non-coco-drop-in.json` + `20-oci-1.2.1-drop-in.json`).
|
||||
|
||||
| Drop-in file | Use case |
|
||||
|--------------|----------|
|
||||
| `10-non-coco-drop-in.json` | Non-confidential guest (e.g. standard VMs) |
|
||||
| `10-non-coco-aks-drop-in.json` | Non-confidential guest on AKS |
|
||||
| `10-non-coco-aks-cbl-mariner-drop-in.json` | Non-confidential guest on AKS with CBL-Mariner host |
|
||||
| `20-oci-1.2.0-drop-in.json` | OCI bundle version 1.2.0 (e.g. CBL-Mariner) |
|
||||
| `20-oci-1.2.1-drop-in.json` | OCI bundle version 1.2.1 (e.g. k3s, rke2, NVIDIA GPU) |
|
||||
| `20-oci-1.3.0-drop-in.json` | OCI bundle version 1.3.0 (e.g. containerd 2.2.x) |
|
||||
| `20-experimental-force-guest-pull-drop-in.json` | Disable guest pull |
|
||||
|
||||
Request/exec overrides (e.g. allowing `kubectl exec` or specific ttRPC requests) are not shipped as drop-in examples; build your own drop-in or merge the needed `request_defaults` into a local file in `genpolicy-settings.d/`.
|
||||
@@ -86,20 +86,22 @@ To print the `base64` encoded Policy, in addition to adding it into the `YAML` f
|
||||
$ genpolicy -b -y test.yaml
|
||||
```
|
||||
|
||||
# Use a custom `genpolicy` settings file
|
||||
# Use a custom `genpolicy` settings file or directory
|
||||
|
||||
The default `genpolicy` settings file is `./genpolicy-settings.json`. Users can specify in the command line a different settings file by using the `-j` parameter - e.g.,
|
||||
The default is `./genpolicy-settings.json`. With the `-j` parameter you can pass either a settings file or a **directory**. If you pass a directory, `genpolicy` loads `genpolicy-settings.json` from it and applies all `genpolicy-settings.d/*.json` drop-ins (sorted by name) as RFC 6902 JSON Patches.
|
||||
|
||||
```bash
|
||||
$ genpolicy -j my-settings.json -y test.yaml
|
||||
$ genpolicy -j /path/to/settings-dir -y test.yaml
|
||||
```
|
||||
|
||||
# Use a custom path to `genpolicy` input files
|
||||
|
||||
By default, the `genpolicy` input files [`rules.rego`](rules.rego) and [`genpolicy-settings.json`](genpolicy-settings.json) must be present in the current directory - otherwise `genpolicy` returns an error. Users can specify different paths to these two files, using the `-p` and `-j` command line parameters - e.g.,
|
||||
By default, the `genpolicy` input files [`rules.rego`](rules.rego) and [`genpolicy-settings.json`](genpolicy-settings.json) must be present in the current directory - otherwise `genpolicy` returns an error. You can pass a different file or directory with `-j` and a different rules file with `-p` - e.g.,
|
||||
|
||||
```bash
|
||||
$ genpolicy -p /tmp/rules.rego -j /tmp/genpolicy-settings.json -y test.yaml
|
||||
$ genpolicy -p /tmp/rules.rego -j /tmp/settings-dir -y test.yaml
|
||||
```
|
||||
|
||||
# Silently ignore unsupported input `YAML` fields
|
||||
|
||||
@@ -8,10 +8,12 @@
|
||||
|
||||
use crate::policy;
|
||||
|
||||
use json_patch::{patch, Patch};
|
||||
use log::debug;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::fs::File;
|
||||
use std::str;
|
||||
use serde_json::Value;
|
||||
use std::fs;
|
||||
use std::path::Path;
|
||||
|
||||
/// Policy settings loaded from genpolicy-settings.json.
|
||||
#[derive(Clone, Debug, Deserialize, Serialize)]
|
||||
@@ -79,17 +81,64 @@ pub struct KataConfig {
|
||||
pub enable_configmap_secret_storages: bool,
|
||||
}
|
||||
|
||||
/// Drop-ins in genpolicy-settings.d/ must be RFC 6902 JSON Patch documents (JSON array of
|
||||
/// operations: add, remove, replace, move, copy, test). This allows precise control (e.g. array
|
||||
/// indices) and optional `test` for assertions.
|
||||
impl Settings {
|
||||
pub fn new(json_settings_path: &str) -> Self {
|
||||
debug!("Loading settings file...");
|
||||
if let Ok(file) = File::open(json_settings_path) {
|
||||
let settings: Self = serde_json::from_reader(file).unwrap();
|
||||
debug!("settings = {:?}", &settings);
|
||||
Self::validate_settings(&settings);
|
||||
settings
|
||||
debug!("Loading settings from: {}", json_settings_path);
|
||||
let path = Path::new(json_settings_path);
|
||||
let (base_path, drop_in_dir) = if path.is_dir() {
|
||||
(
|
||||
path.join("genpolicy-settings.json"),
|
||||
Some(path.join("genpolicy-settings.d")),
|
||||
)
|
||||
} else {
|
||||
panic!("Cannot open file {json_settings_path}. Please copy it to the current directory or specify the path to it using the -j parameter.");
|
||||
(path.to_path_buf(), None)
|
||||
};
|
||||
|
||||
let mut base: Value = {
|
||||
let contents = fs::read_to_string(&base_path).unwrap_or_else(|e| {
|
||||
panic!(
|
||||
"Cannot read {}: {}. Specify the path using the -j parameter.",
|
||||
base_path.display(),
|
||||
e
|
||||
)
|
||||
});
|
||||
serde_json::from_str(&contents)
|
||||
.unwrap_or_else(|e| panic!("Invalid JSON in {}: {}", base_path.display(), e))
|
||||
};
|
||||
|
||||
if let Some(ref drop_in_dir) = drop_in_dir {
|
||||
if drop_in_dir.is_dir() {
|
||||
let mut entries: Vec<_> = fs::read_dir(drop_in_dir)
|
||||
.unwrap_or_else(|e| {
|
||||
panic!("Cannot read drop-in dir {}: {}", drop_in_dir.display(), e)
|
||||
})
|
||||
.filter_map(|e| e.ok())
|
||||
.filter(|e| e.path().extension().is_some_and(|ext| ext == "json"))
|
||||
.collect();
|
||||
entries.sort_by_cached_key(|e| e.file_name());
|
||||
for entry in entries {
|
||||
let p = entry.path();
|
||||
debug!("Applying drop-in: {:?}", p);
|
||||
let contents = fs::read_to_string(&p)
|
||||
.unwrap_or_else(|e| panic!("Cannot read drop-in {}: {}", p.display(), e));
|
||||
let patch_ops: Patch = serde_json::from_str(&contents).unwrap_or_else(|e| {
|
||||
panic!("Invalid JSON Patch in drop-in {}: {}", p.display(), e)
|
||||
});
|
||||
patch(&mut base, &patch_ops).unwrap_or_else(|e| {
|
||||
panic!("Failed to apply JSON Patch from {}: {}", p.display(), e)
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let settings: Self = serde_json::from_value(base)
|
||||
.unwrap_or_else(|e| panic!("Merged settings are invalid: {}", e));
|
||||
debug!("settings = {:?}", &settings);
|
||||
Self::validate_settings(&settings);
|
||||
settings
|
||||
}
|
||||
|
||||
pub fn get_container_settings(&self, is_pause_container: bool) -> &policy::KataSpec {
|
||||
|
||||
@@ -42,7 +42,7 @@ struct CommandLineOptions {
|
||||
short = 'j',
|
||||
long,
|
||||
default_value_t = String::from("genpolicy-settings.json"),
|
||||
help = "Path to genpolicy settings file"
|
||||
help = "Path to genpolicy settings file or directory (with genpolicy-settings.json and optional genpolicy-settings.d/*.json)"
|
||||
)]
|
||||
json_settings_path: String,
|
||||
|
||||
|
||||
Reference in New Issue
Block a user