mirror of
https://github.com/kata-containers/kata-containers.git
synced 2025-08-11 21:02:34 +00:00
agent: alternative implementation for sealed_secret as volume
The earlier implementation relied on using a specific mount-path prefix - `/sealed` to determine that the referenced secret is a sealed secret. However that was restrictive for certain use cases as it forced the user to always use a specific mountpath naming convention. This commit introduces an alternative implementation to relax the restriction. A sealed secret can be mounted in any mount-path. However it comes with a potential performance penality. The implementation loops through all volume mounts and reads the file to determine if it's a sealed secret or not. Fixes: #10398 Signed-off-by: Pradipta Banerjee <pradipta.banerjee@gmail.com>
This commit is contained in:
parent
2d9baf899a
commit
5218345e34
@ -2158,6 +2158,25 @@ fn load_kernel_module(module: &protocols::agent::KernelModule) -> Result<()> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn is_sealed_secret_path(source_path: &str) -> bool {
|
||||||
|
// Base path to check
|
||||||
|
let base_path = "/run/kata-containers/shared/containers";
|
||||||
|
// Paths to exclude
|
||||||
|
let excluded_suffixes = [
|
||||||
|
"resolv.conf",
|
||||||
|
"termination-log",
|
||||||
|
"hostname",
|
||||||
|
"hosts",
|
||||||
|
"serviceaccount",
|
||||||
|
];
|
||||||
|
|
||||||
|
// Ensure the path starts with the base path and does not end with any excluded suffix
|
||||||
|
source_path.starts_with(base_path)
|
||||||
|
&& !excluded_suffixes
|
||||||
|
.iter()
|
||||||
|
.any(|suffix| source_path.ends_with(suffix))
|
||||||
|
}
|
||||||
|
|
||||||
async fn cdh_handler(oci: &mut Spec) -> Result<()> {
|
async fn cdh_handler(oci: &mut Spec) -> Result<()> {
|
||||||
if !cdh::is_cdh_client_initialized().await {
|
if !cdh::is_cdh_client_initialized().await {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
@ -2183,17 +2202,34 @@ async fn cdh_handler(oci: &mut Spec) -> Result<()> {
|
|||||||
.ok_or_else(|| anyhow!("Spec didn't contain mounts field"))?;
|
.ok_or_else(|| anyhow!("Spec didn't contain mounts field"))?;
|
||||||
|
|
||||||
for m in mounts.iter_mut() {
|
for m in mounts.iter_mut() {
|
||||||
if m.destination().starts_with("/sealed") {
|
let Some(source_path) = m.source().as_ref().and_then(|p| p.to_str()) else {
|
||||||
info!(
|
warn!(sl(), "Mount source is None or invalid");
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Check if source_path starts with "/run/kata-containers/shared/containers"
|
||||||
|
// For a volume mount path /mydir,
|
||||||
|
// the secret file path will be like this under the /run/kata-containers/shared/containers dir
|
||||||
|
// a128482812bad768f404e063f225decd425fc94a673aec4add45a9caa1122ccb-75490e32e51da3ff-mydir
|
||||||
|
// We can ignore few paths like: resolv.conf, termination-log, hostname,hosts,serviceaccount
|
||||||
|
if is_sealed_secret_path(source_path) {
|
||||||
|
debug!(
|
||||||
sl(),
|
sl(),
|
||||||
"sealed mount destination: {:?} source: {:?}",
|
"Calling unseal_file for - source: {:?} destination: {:?}",
|
||||||
m.destination(),
|
source_path,
|
||||||
m.source()
|
m.destination()
|
||||||
);
|
);
|
||||||
if let Some(source_str) = m.source().as_ref().and_then(|p| p.to_str()) {
|
// Call unseal_file. This function checks the files under the source_path
|
||||||
cdh::unseal_file(source_str).await?;
|
// for the sealed secret header and unseal it if the header is present.
|
||||||
} else {
|
// This is suboptimal as we are going through every file under the source_path.
|
||||||
warn!(sl(), "Failed to unseal: Mount source is None or invalid");
|
// But currently there is no quick way to determine which volume-mount is referring
|
||||||
|
// to a sealed secret without reading the file.
|
||||||
|
// And relying on file naming heuristic is inflexible. So we are going with this approach.
|
||||||
|
if let Err(e) = cdh::unseal_file(source_path).await {
|
||||||
|
warn!(
|
||||||
|
sl(),
|
||||||
|
"Failed to unseal file: {:?}, Error: {:?}", source_path, e
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3192,4 +3228,54 @@ COMMIT
|
|||||||
"We should see the resulting rule"
|
"We should see the resulting rule"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn test_is_sealed_secret_path() {
|
||||||
|
#[derive(Debug)]
|
||||||
|
struct TestData<'a> {
|
||||||
|
source_path: &'a str,
|
||||||
|
result: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
let tests = &[
|
||||||
|
TestData {
|
||||||
|
source_path: "/run/kata-containers/shared/containers/somefile",
|
||||||
|
result: true,
|
||||||
|
},
|
||||||
|
TestData {
|
||||||
|
source_path: "/run/kata-containers/shared/containers/a128482812bad768f404e063f225decd425fc94a673aec4add45a9caa1122ccb-75490e32e51da3ff-resolv.conf",
|
||||||
|
result: false,
|
||||||
|
},
|
||||||
|
TestData {
|
||||||
|
source_path: "/run/kata-containers/shared/containers/a128482812bad768f404e063f225decd425fc94a673aec4add45a9caa1122ccb-75490e32e51da3ff-termination-log",
|
||||||
|
result: false,
|
||||||
|
},
|
||||||
|
TestData {
|
||||||
|
source_path: "/run/kata-containers/shared/containers/a128482812bad768f404e063f225decd425fc94a673aec4add45a9caa1122ccb-75490e32e51da3ff-hostname",
|
||||||
|
result: false,
|
||||||
|
},
|
||||||
|
TestData {
|
||||||
|
source_path: "/run/kata-containers/shared/containers/a128482812bad768f404e063f225decd425fc94a673aec4add45a9caa1122ccb-75490e32e51da3ff-hosts",
|
||||||
|
result: false,
|
||||||
|
},
|
||||||
|
TestData {
|
||||||
|
source_path: "/run/kata-containers/shared/containers/a128482812bad768f404e063f225decd425fc94a673aec4add45a9caa1122ccb-75490e32e51da3ff-serviceaccount",
|
||||||
|
result: false,
|
||||||
|
},
|
||||||
|
TestData {
|
||||||
|
source_path: "/run/kata-containers/shared/containers/a128482812bad768f404e063f225decd425fc94a673aec4add45a9caa1122ccb-75490e32e51da3ff-mysecret",
|
||||||
|
result: true,
|
||||||
|
},
|
||||||
|
TestData {
|
||||||
|
source_path: "/some/other/path",
|
||||||
|
result: false,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
for (i, d) in tests.iter().enumerate() {
|
||||||
|
let msg = format!("test[{}]: {:?}", i, d);
|
||||||
|
let result = is_sealed_secret_path(d.source_path);
|
||||||
|
assert_eq!(d.result, result, "{}", msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user