Merge pull request #9294 from burgerdev/burgerdev/genpolicy-configurable-pause

genpolicy: support insecure registries and custom pause containers
This commit is contained in:
Dan Mihai 2024-04-16 09:39:33 -07:00 committed by GitHub
commit c26dad8fe5
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 42 additions and 28 deletions

View File

@ -272,7 +272,8 @@
"confidential_guest": false
},
"cluster_config": {
"default_namespace": "default"
"default_namespace": "default",
"pause_container_image": "mcr.microsoft.com/oss/kubernetes/pause:3.6"
},
"request_defaults": {
"CreateContainerRequest": {

View File

@ -834,9 +834,7 @@ fn compress_capabilities(capabilities: &mut Vec<String>, defaults: &policy::Comm
pub async fn add_pause_container(containers: &mut Vec<Container>, config: &Config) {
debug!("Adding pause container...");
let mut pause_container = Container {
// TODO: load this path from the settings file.
image: "mcr.microsoft.com/oss/kubernetes/pause:3.6".to_string(),
image: config.settings.cluster_config.pause_container_image.clone(),
name: String::new(),
imagePullPolicy: None,
securityContext: Some(SecurityContext {

View File

@ -13,7 +13,6 @@ use crate::pod;
use crate::policy;
use crate::registry;
use crate::secret;
use crate::settings;
use crate::utils;
use crate::yaml;
@ -47,10 +46,7 @@ pub struct AgentPolicy {
/// Rego rules read from a file (rules.rego).
pub rules: String,
/// Settings loaded from genpolicy-settings.json.
pub settings: settings::Settings,
/// Additional Policy settings.
/// Policy settings.
pub config: utils::Config,
}
@ -73,7 +69,7 @@ pub struct PolicyData {
/// is ordered, thus resulting in the same output policy contents every time
/// when this apps runs with the same inputs. Also, it preserves the upper
/// case field names, for consistency with the structs used by agent's rpc.rs.
#[derive(Debug, Deserialize, Serialize)]
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct KataSpec {
/// Version of the Open Container Initiative Runtime Specification with which the bundle complies.
#[serde(default = "version_default")]
@ -366,6 +362,9 @@ pub struct CommonData {
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct ClusterConfig {
default_namespace: String,
/// Pause container image reference.
pub pause_container_image: String,
}
impl AgentPolicy {
@ -402,8 +401,6 @@ impl AgentPolicy {
}
}
let settings = settings::Settings::new(&config.json_settings_path);
if let Some(config_map_files) = &config.config_map_files {
for file in config_map_files {
config_maps.push(config_map::ConfigMap::new(file)?);
@ -414,7 +411,6 @@ impl AgentPolicy {
Ok(AgentPolicy {
resources,
rules,
settings,
config_maps,
secrets,
config: config.clone(),
@ -460,8 +456,8 @@ impl AgentPolicy {
let policy_data = policy::PolicyData {
containers: policy_containers,
request_defaults: self.settings.request_defaults.clone(),
common: self.settings.common.clone(),
request_defaults: self.config.settings.request_defaults.clone(),
common: self.config.settings.common.clone(),
};
let json_data = serde_json::to_string_pretty(&policy_data).unwrap();
@ -478,14 +474,21 @@ impl AgentPolicy {
yaml_container: &pod::Container,
is_pause_container: bool,
) -> ContainerPolicy {
let c_settings = self.settings.get_container_settings(is_pause_container);
let c_settings = self
.config
.settings
.get_container_settings(is_pause_container);
let mut root = c_settings.Root.clone();
root.Readonly = yaml_container.read_only_root_filesystem();
let namespace = if let Some(ns) = resource.get_namespace() {
ns
} else {
self.settings.cluster_config.default_namespace.clone()
self.config
.settings
.cluster_config
.default_namespace
.clone()
};
let use_host_network = resource.use_host_network();
@ -510,7 +513,7 @@ impl AgentPolicy {
let mut mounts = containerd::get_mounts(is_pause_container, is_privileged);
mount_and_storage::get_policy_mounts(
&self.settings,
&self.config.settings,
&mut mounts,
yaml_container,
is_pause_container,
@ -523,7 +526,7 @@ impl AgentPolicy {
&mut mounts,
&mut storages,
yaml_container,
&self.settings,
&self.config.settings,
);
let mut linux = containerd::get_linux(is_privileged);
@ -570,9 +573,9 @@ impl AgentPolicy {
) -> KataProcess {
// Start with the Default Unix Spec from
// https://github.com/containerd/containerd/blob/release/1.6/oci/spec.go#L132
let mut process = containerd::get_process(is_privileged, &self.settings.common);
let mut process = containerd::get_process(is_privileged, &self.config.settings.common);
yaml_container.apply_capabilities(&mut process.Capabilities, &self.settings.common);
yaml_container.apply_capabilities(&mut process.Capabilities, &self.config.settings.common);
let (yaml_has_command, yaml_has_args) = yaml_container.get_process_args(&mut process.Args);
yaml_container

View File

@ -15,7 +15,7 @@ use anyhow::{anyhow, bail, Result};
use docker_credential::{CredentialRetrievalError, DockerCredential};
use log::warn;
use log::{debug, info, LevelFilter};
use oci_distribution::client::{linux_amd64_resolver, ClientConfig};
use oci_distribution::client::{linux_amd64_resolver, ClientConfig, ClientProtocol};
use oci_distribution::{manifest, secrets::RegistryAuth, Client, Reference};
use serde::{Deserialize, Serialize};
use sha2::{digest::typenum::Unsigned, digest::OutputSizeUser, Sha256};
@ -64,13 +64,14 @@ pub struct ImageLayer {
}
impl Container {
pub async fn new(use_cached_files: bool, image: &str) -> Result<Self> {
pub async fn new(config: &Config, image: &str) -> Result<Self> {
info!("============================================");
info!("Pulling manifest and config for {:?}", image);
let reference: Reference = image.to_string().parse().unwrap();
let auth = build_auth(&reference);
let mut client = Client::new(ClientConfig {
protocol: ClientProtocol::HttpsExcept(config.insecure_registries.clone()),
platform_resolver: Some(Box::new(linux_amd64_resolver)),
..Default::default()
});
@ -93,7 +94,7 @@ impl Container {
let config_layer: DockerConfigLayer =
serde_json::from_str(&config_layer_str).unwrap();
let image_layers = get_image_layers(
use_cached_files,
config.use_cache,
&mut client,
&reference,
&manifest,
@ -430,7 +431,7 @@ pub async fn get_container(config: &Config, image: &str) -> Result<Container> {
if let Some(socket_path) = &config.containerd_socket_path {
return Container::new_containerd_pull(config.use_cache, image, socket_path).await;
}
Container::new(config.use_cache, image).await
Container::new(config, image).await
}
fn build_auth(reference: &Reference) -> RegistryAuth {

View File

@ -14,7 +14,7 @@ use std::fs::File;
use std::str;
/// Policy settings loaded from genpolicy-settings.json.
#[derive(Debug, Deserialize, Serialize)]
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct Settings {
pub pause_container: policy::KataSpec,
pub other_container: policy::KataSpec,

View File

@ -3,6 +3,7 @@
// SPDX-License-Identifier: Apache-2.0
//
use crate::settings;
use clap::Parser;
#[derive(Debug, Parser)]
@ -75,16 +76,23 @@ struct CommandLineOptions {
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>,
}
/// Application configuration, derived from on command line parameters.
#[derive(Clone, Debug)]
pub struct Config {
pub use_cache: bool,
pub insecure_registries: Vec<String>,
pub yaml_file: Option<String>,
pub rego_rules_path: String,
pub json_settings_path: String,
pub settings: settings::Settings,
pub config_map_files: Option<Vec<String>>,
pub silent_unsupported_fields: bool,
@ -108,11 +116,14 @@ impl Config {
None
};
let settings = settings::Settings::new(&args.json_settings_path);
Self {
use_cache: args.use_cached_files,
insecure_registries: args.insecure_registry,
yaml_file: args.yaml_file,
rego_rules_path: args.rego_rules_path,
json_settings_path: args.json_settings_path,
settings,
config_map_files: cm_files,
silent_unsupported_fields: args.silent_unsupported_fields,
raw_out: args.raw_out,