syncable_cli/analyzer/kubelint/templates/
readonlyrootfs.rs1use crate::analyzer::kubelint::context::Object;
4use crate::analyzer::kubelint::extract;
5use crate::analyzer::kubelint::templates::{CheckFunc, ParameterDesc, Template, TemplateError};
6use crate::analyzer::kubelint::types::{Diagnostic, ObjectKindsDesc};
7
8pub struct ReadOnlyRootFsTemplate;
10
11impl Template for ReadOnlyRootFsTemplate {
12 fn key(&self) -> &str {
13 "read-only-root-fs"
14 }
15
16 fn human_name(&self) -> &str {
17 "Read-Only Root Filesystem"
18 }
19
20 fn description(&self) -> &str {
21 "Detects containers without a read-only root filesystem"
22 }
23
24 fn supported_object_kinds(&self) -> ObjectKindsDesc {
25 ObjectKindsDesc::default()
26 }
27
28 fn parameters(&self) -> Vec<ParameterDesc> {
29 Vec::new()
30 }
31
32 fn instantiate(
33 &self,
34 _params: &serde_yaml::Value,
35 ) -> Result<Box<dyn CheckFunc>, TemplateError> {
36 Ok(Box::new(ReadOnlyRootFsCheck))
37 }
38}
39
40struct ReadOnlyRootFsCheck;
41
42impl CheckFunc for ReadOnlyRootFsCheck {
43 fn check(&self, object: &Object) -> Vec<Diagnostic> {
44 let mut diagnostics = Vec::new();
45
46 if let Some(pod_spec) = extract::pod_spec::extract_pod_spec(&object.k8s_object) {
47 for container in extract::container::all_containers(pod_spec) {
48 let read_only = container
49 .security_context
50 .as_ref()
51 .and_then(|sc| sc.read_only_root_filesystem);
52
53 if read_only != Some(true) {
54 diagnostics.push(Diagnostic {
55 message: format!(
56 "Container '{}' does not have a read-only root filesystem",
57 container.name
58 ),
59 remediation: Some(
60 "Set securityContext.readOnlyRootFilesystem to true.".to_string(),
61 ),
62 });
63 }
64 }
65 }
66
67 diagnostics
68 }
69}