Files
kata-containers/src/tools/genpolicy/src/utils.rs
Saul Paredes dfd269eb87 genpolicy: take path to initdata from command line if provided
Otherwise use default initdata.

Signed-off-by: Saul Paredes <saulparedes@microsoft.com>
2025-10-13 10:47:53 -07:00

194 lines
6.0 KiB
Rust

// Copyright (c) 2023 Microsoft Corporation
//
// SPDX-License-Identifier: Apache-2.0
//
use crate::layers_cache;
use crate::settings;
use anyhow::Context;
use clap::Parser;
#[derive(Debug, Parser)]
struct CommandLineOptions {
#[clap(
short,
long,
help = "Kubernetes input/output YAML file path. stdin/stdout get used if this option is not specified."
)]
yaml_file: Option<String>,
#[clap(
short,
long,
help = "Optional Kubernetes config map YAML input file path. DEPRECATED: use --config-file instead"
)]
config_map_file: Option<String>,
#[clap(
long,
help = "Optional Kubernetes YAML input file path containing config resources such as ConfigMaps and Secrets"
)]
config_file: Option<Vec<String>>,
#[clap(
short = 'p',
long,
default_value_t = String::from("rules.rego"),
help = "Path to rego rules file"
)]
rego_rules_path: String,
#[clap(
short = 'j',
long,
default_value_t = String::from("genpolicy-settings.json"),
help = "Path to genpolicy settings file"
)]
json_settings_path: String,
#[clap(
short,
long,
help = "Create and use a cache of container image layer contents and dm-verity information (in ./layers_cache/)"
)]
use_cached_files: bool,
#[clap(
short,
long,
help = "Print the output Rego policy text to standard output"
)]
raw_out: bool,
#[clap(
short,
long,
help = "Print the base64 encoded output Rego policy to standard output"
)]
base64_out: bool,
#[clap(
short,
long,
help = "Ignore unsupported input Kubernetes YAML fields. This is not recommeded unless you understand exactly how genpolicy works!"
)]
silent_unsupported_fields: bool,
#[clap(
short = 'd',
long,
help = "If specified, will use existing containerd service to pull container images. This option is only supported on Linux",
// from https://docs.rs/clap/4.1.8/clap/struct.Arg.html#method.default_missing_value
default_missing_value = "/var/run/containerd/containerd.sock", // used if flag is present but no value is given
num_args = 0..=1,
require_equals= true
)]
containerd_socket_path: Option<String>,
#[clap(
long,
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>,
#[clap(
long,
help = "Path to the layers cache file. This file is used to store the layers cache information. The default value is ./layers-cache.json.",
default_missing_value = "./layers-cache.json",
require_equals = true
)]
layers_cache_file_path: Option<String>,
#[clap(short, long, help = "Print version information and exit")]
version: bool,
#[clap(long, help = "Path to the initdata TOML file", require_equals = true)]
initdata_path: Option<String>,
}
/// Application configuration, derived from on command line parameters.
#[derive(Clone, Debug)]
pub struct Config {
#[allow(dead_code)]
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,
pub settings: settings::Settings,
pub config_files: Option<Vec<String>>,
pub silent_unsupported_fields: bool,
pub raw_out: bool,
pub base64_out: bool,
pub containerd_socket_path: Option<String>,
pub layers_cache: layers_cache::ImageLayersCache,
pub version: bool,
pub initdata: kata_types::initdata::InitData,
}
impl Config {
pub fn new() -> Self {
let args = CommandLineOptions::parse();
// 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::<Vec<_>>();
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
if args.use_cached_files && layers_cache_file_path.is_none() {
layers_cache_file_path = Some(String::from("./layers-cache.json"));
}
let settings = settings::Settings::new(&args.json_settings_path);
let initdata = match args.initdata_path.as_deref() {
Some(p) => {
let s = std::fs::read_to_string(p)
.context(format!("Failed to read initdata file {}", p))
.unwrap();
kata_types::initdata::parse_initdata(&s)
.context(format!("Failed to parse initdata from {}", p))
.unwrap()
}
None => kata_types::initdata::InitData::new("sha256", "0.1.0"),
};
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,
config_files,
silent_unsupported_fields: args.silent_unsupported_fields,
raw_out: args.raw_out,
base64_out: args.base64_out,
containerd_socket_path: args.containerd_socket_path,
layers_cache: layers_cache::ImageLayersCache::new(&layers_cache_file_path),
version: args.version,
initdata,
}
}
}
impl Default for Config {
fn default() -> Self {
Self::new()
}
}