syncable_cli/analyzer/kubelint/templates/
dangling.rs

1//! Dangling resource validation templates.
2//!
3//! These templates check for resources that reference other resources that don't exist.
4//! Note: Full implementation requires cross-resource validation which needs access to
5//! the full set of resources being analyzed.
6
7use crate::analyzer::kubelint::context::Object;
8use crate::analyzer::kubelint::templates::{CheckFunc, ParameterDesc, Template, TemplateError};
9use crate::analyzer::kubelint::types::{Diagnostic, ObjectKindsDesc};
10
11/// Template for checking dangling services (services with selectors that don't match any pods).
12pub struct DanglingServiceTemplate;
13
14impl Template for DanglingServiceTemplate {
15    fn key(&self) -> &str {
16        "dangling-service"
17    }
18
19    fn human_name(&self) -> &str {
20        "Dangling Service"
21    }
22
23    fn description(&self) -> &str {
24        "Checks for services with selectors that don't match any pods"
25    }
26
27    fn supported_object_kinds(&self) -> ObjectKindsDesc {
28        ObjectKindsDesc::new(&["Service"])
29    }
30
31    fn parameters(&self) -> Vec<ParameterDesc> {
32        Vec::new()
33    }
34
35    fn instantiate(
36        &self,
37        _params: &serde_yaml::Value,
38    ) -> Result<Box<dyn CheckFunc>, TemplateError> {
39        // Note: This check requires cross-resource validation
40        // Full implementation needs access to all pods in the context
41        Ok(Box::new(DanglingServiceCheck))
42    }
43}
44
45struct DanglingServiceCheck;
46
47impl CheckFunc for DanglingServiceCheck {
48    fn check(&self, _object: &Object) -> Vec<Diagnostic> {
49        // Requires cross-resource validation - placeholder
50        Vec::new()
51    }
52}
53
54/// Template for checking dangling ingresses (ingresses referencing non-existent services).
55pub struct DanglingIngressTemplate;
56
57impl Template for DanglingIngressTemplate {
58    fn key(&self) -> &str {
59        "dangling-ingress"
60    }
61
62    fn human_name(&self) -> &str {
63        "Dangling Ingress"
64    }
65
66    fn description(&self) -> &str {
67        "Checks for ingresses that reference non-existent services"
68    }
69
70    fn supported_object_kinds(&self) -> ObjectKindsDesc {
71        ObjectKindsDesc::new(&["Ingress"])
72    }
73
74    fn parameters(&self) -> Vec<ParameterDesc> {
75        Vec::new()
76    }
77
78    fn instantiate(
79        &self,
80        _params: &serde_yaml::Value,
81    ) -> Result<Box<dyn CheckFunc>, TemplateError> {
82        Ok(Box::new(DanglingIngressCheck))
83    }
84}
85
86struct DanglingIngressCheck;
87
88impl CheckFunc for DanglingIngressCheck {
89    fn check(&self, _object: &Object) -> Vec<Diagnostic> {
90        // Requires cross-resource validation - placeholder
91        Vec::new()
92    }
93}
94
95/// Template for checking dangling HPAs (HPAs targeting non-existent deployments).
96pub struct DanglingHpaTemplate;
97
98impl Template for DanglingHpaTemplate {
99    fn key(&self) -> &str {
100        "dangling-hpa"
101    }
102
103    fn human_name(&self) -> &str {
104        "Dangling HPA"
105    }
106
107    fn description(&self) -> &str {
108        "Checks for HPAs that target non-existent deployments"
109    }
110
111    fn supported_object_kinds(&self) -> ObjectKindsDesc {
112        ObjectKindsDesc::new(&["HorizontalPodAutoscaler"])
113    }
114
115    fn parameters(&self) -> Vec<ParameterDesc> {
116        Vec::new()
117    }
118
119    fn instantiate(
120        &self,
121        _params: &serde_yaml::Value,
122    ) -> Result<Box<dyn CheckFunc>, TemplateError> {
123        Ok(Box::new(DanglingHpaCheck))
124    }
125}
126
127struct DanglingHpaCheck;
128
129impl CheckFunc for DanglingHpaCheck {
130    fn check(&self, _object: &Object) -> Vec<Diagnostic> {
131        // Requires cross-resource validation - placeholder
132        Vec::new()
133    }
134}
135
136/// Template for checking dangling network policies.
137pub struct DanglingNetworkPolicyTemplate;
138
139impl Template for DanglingNetworkPolicyTemplate {
140    fn key(&self) -> &str {
141        "dangling-network-policy"
142    }
143
144    fn human_name(&self) -> &str {
145        "Dangling NetworkPolicy"
146    }
147
148    fn description(&self) -> &str {
149        "Checks for network policies with selectors that don't match any pods"
150    }
151
152    fn supported_object_kinds(&self) -> ObjectKindsDesc {
153        ObjectKindsDesc::new(&["NetworkPolicy"])
154    }
155
156    fn parameters(&self) -> Vec<ParameterDesc> {
157        Vec::new()
158    }
159
160    fn instantiate(
161        &self,
162        _params: &serde_yaml::Value,
163    ) -> Result<Box<dyn CheckFunc>, TemplateError> {
164        Ok(Box::new(DanglingNetworkPolicyCheck))
165    }
166}
167
168struct DanglingNetworkPolicyCheck;
169
170impl CheckFunc for DanglingNetworkPolicyCheck {
171    fn check(&self, _object: &Object) -> Vec<Diagnostic> {
172        // Requires cross-resource validation - placeholder
173        Vec::new()
174    }
175}
176
177/// Template for checking dangling network policy peer selectors.
178pub struct DanglingNetworkPolicyPeerTemplate;
179
180impl Template for DanglingNetworkPolicyPeerTemplate {
181    fn key(&self) -> &str {
182        "dangling-network-policy-peer"
183    }
184
185    fn human_name(&self) -> &str {
186        "Dangling NetworkPolicy Peer"
187    }
188
189    fn description(&self) -> &str {
190        "Checks for network policy peer selectors that don't match any pods"
191    }
192
193    fn supported_object_kinds(&self) -> ObjectKindsDesc {
194        ObjectKindsDesc::new(&["NetworkPolicy"])
195    }
196
197    fn parameters(&self) -> Vec<ParameterDesc> {
198        Vec::new()
199    }
200
201    fn instantiate(
202        &self,
203        _params: &serde_yaml::Value,
204    ) -> Result<Box<dyn CheckFunc>, TemplateError> {
205        Ok(Box::new(DanglingNetworkPolicyPeerCheck))
206    }
207}
208
209struct DanglingNetworkPolicyPeerCheck;
210
211impl CheckFunc for DanglingNetworkPolicyPeerCheck {
212    fn check(&self, _object: &Object) -> Vec<Diagnostic> {
213        // Requires cross-resource validation - placeholder
214        Vec::new()
215    }
216}
217
218/// Template for checking dangling service monitors.
219pub struct DanglingServiceMonitorTemplate;
220
221impl Template for DanglingServiceMonitorTemplate {
222    fn key(&self) -> &str {
223        "dangling-service-monitor"
224    }
225
226    fn human_name(&self) -> &str {
227        "Dangling ServiceMonitor"
228    }
229
230    fn description(&self) -> &str {
231        "Checks for service monitors with selectors that don't match any services"
232    }
233
234    fn supported_object_kinds(&self) -> ObjectKindsDesc {
235        ObjectKindsDesc::new(&["ServiceMonitor"])
236    }
237
238    fn parameters(&self) -> Vec<ParameterDesc> {
239        Vec::new()
240    }
241
242    fn instantiate(
243        &self,
244        _params: &serde_yaml::Value,
245    ) -> Result<Box<dyn CheckFunc>, TemplateError> {
246        Ok(Box::new(DanglingServiceMonitorCheck))
247    }
248}
249
250struct DanglingServiceMonitorCheck;
251
252impl CheckFunc for DanglingServiceMonitorCheck {
253    fn check(&self, _object: &Object) -> Vec<Diagnostic> {
254        // Requires cross-resource validation - placeholder
255        Vec::new()
256    }
257}
258
259/// Template for checking non-existent service accounts.
260pub struct NonExistentServiceAccountTemplate;
261
262impl Template for NonExistentServiceAccountTemplate {
263    fn key(&self) -> &str {
264        "non-existent-service-account"
265    }
266
267    fn human_name(&self) -> &str {
268        "Non-existent ServiceAccount"
269    }
270
271    fn description(&self) -> &str {
272        "Checks for pods referencing non-existent service accounts"
273    }
274
275    fn supported_object_kinds(&self) -> ObjectKindsDesc {
276        ObjectKindsDesc::default()
277    }
278
279    fn parameters(&self) -> Vec<ParameterDesc> {
280        Vec::new()
281    }
282
283    fn instantiate(
284        &self,
285        _params: &serde_yaml::Value,
286    ) -> Result<Box<dyn CheckFunc>, TemplateError> {
287        Ok(Box::new(NonExistentServiceAccountCheck))
288    }
289}
290
291struct NonExistentServiceAccountCheck;
292
293impl CheckFunc for NonExistentServiceAccountCheck {
294    fn check(&self, _object: &Object) -> Vec<Diagnostic> {
295        // Requires cross-resource validation - placeholder
296        Vec::new()
297    }
298}
299
300/// Template for checking non-isolated pods.
301pub struct NonIsolatedPodTemplate;
302
303impl Template for NonIsolatedPodTemplate {
304    fn key(&self) -> &str {
305        "non-isolated-pod"
306    }
307
308    fn human_name(&self) -> &str {
309        "Non-isolated Pod"
310    }
311
312    fn description(&self) -> &str {
313        "Checks for pods not covered by any network policy"
314    }
315
316    fn supported_object_kinds(&self) -> ObjectKindsDesc {
317        ObjectKindsDesc::default()
318    }
319
320    fn parameters(&self) -> Vec<ParameterDesc> {
321        Vec::new()
322    }
323
324    fn instantiate(
325        &self,
326        _params: &serde_yaml::Value,
327    ) -> Result<Box<dyn CheckFunc>, TemplateError> {
328        Ok(Box::new(NonIsolatedPodCheck))
329    }
330}
331
332struct NonIsolatedPodCheck;
333
334impl CheckFunc for NonIsolatedPodCheck {
335    fn check(&self, _object: &Object) -> Vec<Diagnostic> {
336        // Requires cross-resource validation - placeholder
337        Vec::new()
338    }
339}
340
341/// Template for checking SecurityContextConstraints (OpenShift).
342pub struct SccDenyPrivilegedTemplate;
343
344impl Template for SccDenyPrivilegedTemplate {
345    fn key(&self) -> &str {
346        "scc-deny-privileged"
347    }
348
349    fn human_name(&self) -> &str {
350        "SCC Deny Privileged Container"
351    }
352
353    fn description(&self) -> &str {
354        "Checks if SecurityContextConstraints allow privileged containers"
355    }
356
357    fn supported_object_kinds(&self) -> ObjectKindsDesc {
358        ObjectKindsDesc::new(&["SecurityContextConstraints"])
359    }
360
361    fn parameters(&self) -> Vec<ParameterDesc> {
362        Vec::new()
363    }
364
365    fn instantiate(
366        &self,
367        _params: &serde_yaml::Value,
368    ) -> Result<Box<dyn CheckFunc>, TemplateError> {
369        Ok(Box::new(SccDenyPrivilegedCheck))
370    }
371}
372
373struct SccDenyPrivilegedCheck;
374
375impl CheckFunc for SccDenyPrivilegedCheck {
376    fn check(&self, _object: &Object) -> Vec<Diagnostic> {
377        // OpenShift-specific check - placeholder for unknown resource types
378        Vec::new()
379    }
380}