Skip to content

Commit 3ec48ee

Browse files
committed
feat: add settings model for notation image verifier
Add basic setting for an image verification plugin that configures the notation CLI with a trustpolicy. The settings accepts a base64 encoded trustpolicy.json to be decoded and written to notation's configuration. Signed-off-by: Gavin Inglis <[email protected]>
1 parent 724d2fc commit 3ec48ee

File tree

7 files changed

+160
-0
lines changed

7 files changed

+160
-0
lines changed

Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ members = [
3030
"bottlerocket-settings-models/settings-extensions/dns",
3131
"bottlerocket-settings-models/settings-extensions/ecs",
3232
"bottlerocket-settings-models/settings-extensions/host-containers",
33+
"bottlerocket-settings-models/settings-extensions/image-verification-plugins",
3334
"bottlerocket-settings-models/settings-extensions/kernel",
3435
"bottlerocket-settings-models/settings-extensions/kubernetes",
3536
"bottlerocket-settings-models/settings-extensions/kubelet-device-plugins",
@@ -75,6 +76,7 @@ settings-extension-container-runtime-plugins = { path = "./bottlerocket-settings
7576
settings-extension-dns = { path = "./bottlerocket-settings-models/settings-extensions/dns", version = "0.1" }
7677
settings-extension-ecs = { path = "./bottlerocket-settings-models/settings-extensions/ecs", version = "0.1" }
7778
settings-extension-host-containers = { path = "./bottlerocket-settings-models/settings-extensions/host-containers", version = "0.2" }
79+
settings-extension-image-verification-plugins = { path = "./bottlerocket-settings-models/settings-extensions/image-verification-plugins", version = "0.1" }
7880
settings-extension-kernel = { path = "./bottlerocket-settings-models/settings-extensions/kernel", version = "0.1" }
7981
settings-extension-kubernetes = { path = "./bottlerocket-settings-models/settings-extensions/kubernetes", version = "0.6" }
8082
settings-extension-kubelet-device-plugins = { path = "./bottlerocket-settings-models/settings-extensions/kubelet-device-plugins", version = "0.3" }
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
[package]
2+
name = "settings-extension-image-verification-plugins"
3+
version = "0.1.0"
4+
authors = ["Gavin Inglis <[email protected]>"]
5+
license = "Apache-2.0 OR MIT"
6+
edition = "2021"
7+
publish = false
8+
9+
[dependencies]
10+
bottlerocket-modeled-types.workspace = true
11+
bottlerocket-model-derive.workspace = true
12+
bottlerocket-settings-sdk.workspace = true
13+
env_logger.workspace = true
14+
lazy_static.workspace = true
15+
regex.workspace = true
16+
serde = { workspace = true, features = ["derive"] }
17+
serde_json.workspace = true
18+
toml.workspace = true
19+
20+
[lints]
21+
workspace = true
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
[extension]
2+
supported-versions = [
3+
"v1"
4+
]
5+
default-version = "v1"
6+
7+
[v1]
8+
[v1.validation.cross-validates]
9+
10+
[v1.templating]
11+
helpers = []
12+
13+
[v1.generation.requires]
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
//! Settings related to Image Verification Plugins
2+
3+
use bottlerocket_model_derive::model;
4+
use bottlerocket_modeled_types::ValidBase64;
5+
use bottlerocket_settings_sdk::{GenerateResult, SettingsModel};
6+
use std::convert::Infallible;
7+
8+
#[model(impl_default = true)]
9+
pub struct ImageVerificationPluginsSettingsV1 {
10+
notation: NotationSettings,
11+
}
12+
13+
#[model(impl_default = true)]
14+
pub struct NotationSettings {
15+
/// Base64 encoded trustpolicy.json
16+
/// https://github.com/notaryproject/specifications/blob/main/specs/trust-store-trust-policy.md#trust-store
17+
trustpolicy: ValidBase64,
18+
}
19+
20+
type Result<T> = std::result::Result<T, Infallible>;
21+
22+
impl SettingsModel for ImageVerificationPluginsSettingsV1 {
23+
type PartialKind = Self;
24+
type ErrorKind = Infallible;
25+
26+
fn get_version() -> &'static str {
27+
"v1"
28+
}
29+
30+
fn set(_current_value: Option<Self>, _target: Self) -> Result<()> {
31+
// Set anything that can be parsed as ImageVerificationPluginsSettingsV1.
32+
Ok(())
33+
}
34+
35+
fn generate(
36+
existing_partial: Option<Self::PartialKind>,
37+
_dependent_settings: Option<serde_json::Value>,
38+
) -> Result<GenerateResult<Self::PartialKind, Self>> {
39+
Ok(GenerateResult::Complete(
40+
existing_partial.unwrap_or_default(),
41+
))
42+
}
43+
44+
fn validate(_value: Self, _validated_settings: Option<serde_json::Value>) -> Result<()> {
45+
// ImageVerificationPluginsSettingsV1 is validated during deserialization.
46+
Ok(())
47+
}
48+
}
49+
50+
#[cfg(test)]
51+
mod test {
52+
use super::*;
53+
use serde_json::json;
54+
55+
#[test]
56+
fn test_generate_image_verification_plugins_settings() {
57+
assert_eq!(
58+
ImageVerificationPluginsSettingsV1::generate(None, None),
59+
Ok(GenerateResult::Complete(
60+
ImageVerificationPluginsSettingsV1 { notation: None }
61+
))
62+
)
63+
}
64+
65+
#[test]
66+
fn test_serde_image_verification_plugins() {
67+
let test_json = json!({
68+
"notation": {
69+
"trustpolicy": "ewogICJ2ZXJzaW9uIjogIjEuMCIsCiAgInRydXN0UG9saWNpZXMiOiBbXQp9"
70+
}
71+
});
72+
73+
let test_json_str = test_json.to_string();
74+
75+
let image_verification_plugins_settings: ImageVerificationPluginsSettingsV1 =
76+
serde_json::from_str(&test_json_str).unwrap();
77+
78+
assert_eq!(
79+
image_verification_plugins_settings
80+
.notation
81+
.as_ref()
82+
.unwrap()
83+
.trustpolicy
84+
.as_ref()
85+
.unwrap()
86+
.as_ref(),
87+
"ewogICJ2ZXJzaW9uIjogIjEuMCIsCiAgInRydXN0UG9saWNpZXMiOiBbXQp9"
88+
);
89+
}
90+
91+
#[test]
92+
fn test_serde_image_verification_plugins_empty() {
93+
let test_json = json!({});
94+
95+
let test_json_str = test_json.to_string();
96+
97+
let image_verification_plugins_settings: ImageVerificationPluginsSettingsV1 =
98+
serde_json::from_str(&test_json_str).unwrap();
99+
100+
assert!(image_verification_plugins_settings.notation.is_none());
101+
}
102+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
use bottlerocket_settings_sdk::{BottlerocketSetting, NullMigratorExtensionBuilder};
2+
use settings_extension_image_verification_plugins::ImageVerificationPluginsSettingsV1;
3+
use std::process::ExitCode;
4+
5+
fn main() -> ExitCode {
6+
env_logger::init();
7+
8+
match NullMigratorExtensionBuilder::with_name("image-verification-plugins")
9+
.with_models(vec![BottlerocketSetting::<
10+
ImageVerificationPluginsSettingsV1,
11+
>::model()])
12+
.build()
13+
{
14+
Ok(extension) => extension.run(),
15+
Err(e) => {
16+
println!("{e}");
17+
ExitCode::FAILURE
18+
}
19+
}
20+
}

bottlerocket-settings-models/settings-models/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ settings-extension-container-runtime-plugins.workspace = true
3333
settings-extension-dns.workspace = true
3434
settings-extension-ecs.workspace = true
3535
settings-extension-host-containers.workspace = true
36+
settings-extension-image-verification-plugins.workspace = true
3637
settings-extension-kernel.workspace = true
3738
settings-extension-kubernetes.workspace = true
3839
settings-extension-kubelet-device-plugins.workspace = true

bottlerocket-settings-models/settings-models/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ pub use settings_extension_container_runtime_plugins::{self, ContainerRuntimePlu
3636
pub use settings_extension_dns::{self, DnsSettingsV1};
3737
pub use settings_extension_ecs::{self, ECSSettingsV1};
3838
pub use settings_extension_host_containers::{self, HostContainersSettingsV1};
39+
pub use settings_extension_image_verification_plugins::{self, ImageVerificationPluginsSettingsV1};
3940
pub use settings_extension_kernel::{self, KernelSettingsV1};
4041
pub use settings_extension_kubelet_device_plugins::{self, KubeletDevicePluginsV1};
4142
pub use settings_extension_kubernetes::{self, KubernetesSettingsV1};

0 commit comments

Comments
 (0)