syncable_cli/analyzer/k8s_optimize/rules/
k8s_opt_009.rs

1//! K8S-OPT-009: Requests equal limits (no bursting allowed).
2
3use super::{OptimizationRule, RuleContext, codes};
4use crate::analyzer::k8s_optimize::config::K8sOptimizeConfig;
5use crate::analyzer::k8s_optimize::types::{
6    OptimizationIssue, ResourceRecommendation, RuleCode, Severity,
7};
8
9/// Rule: Requests equal limits (Guaranteed QoS).
10pub struct RequestsEqualLimitsRule;
11
12impl OptimizationRule for RequestsEqualLimitsRule {
13    fn code(&self) -> &'static str {
14        codes::REQUESTS_EQUAL_LIMITS
15    }
16
17    fn description(&self) -> &'static str {
18        "Requests equal limits (no bursting allowed)"
19    }
20
21    fn default_severity(&self) -> Severity {
22        Severity::Info
23    }
24
25    fn check(
26        &self,
27        ctx: &RuleContext,
28        config: &K8sOptimizeConfig,
29    ) -> Option<ResourceRecommendation> {
30        // Only report if include_info is set
31        if !config.include_info {
32            return None;
33        }
34
35        // Must have both requests and limits
36        if !ctx.current.has_requests() || !ctx.current.has_limits() {
37            return None;
38        }
39
40        // Check if requests equal limits
41        let cpu_equal = ctx.current.cpu_request == ctx.current.cpu_limit;
42        let memory_equal = ctx.current.memory_request == ctx.current.memory_limit;
43
44        if !cpu_equal || !memory_equal {
45            return None;
46        }
47
48        // Keep as-is - this is just informational
49        Some(ResourceRecommendation {
50            resource_kind: ctx.resource_kind.clone(),
51            resource_name: ctx.resource_name.clone(),
52            namespace: ctx.namespace.clone(),
53            container: ctx.container_name.clone(),
54            file_path: ctx.file_path.clone(),
55            line: ctx.line,
56            issue: OptimizationIssue::UnbalancedResources,
57            severity: self.default_severity(),
58            message: "Requests equal limits. This creates a Guaranteed QoS class, which is good for stability but prevents bursting.".to_string(),
59            workload_type: ctx.workload_type,
60            current: ctx.current.clone(),
61            actual_usage: None,
62            recommended: ctx.current.clone(), // Keep as-is
63            savings: None,
64            fix_yaml: ctx.current.to_yaml(),
65            rule_code: RuleCode::new(self.code()),
66        })
67    }
68}