syncable-cli 0.37.1

A Rust-based CLI that analyzes code repositories and generates Infrastructure as Code configurations
Documentation
//! Dangling resource validation templates.
//!
//! These templates check for resources that reference other resources that don't exist.
//! Note: Full implementation requires cross-resource validation which needs access to
//! the full set of resources being analyzed.

use crate::analyzer::kubelint::context::Object;
use crate::analyzer::kubelint::templates::{CheckFunc, ParameterDesc, Template, TemplateError};
use crate::analyzer::kubelint::types::{Diagnostic, ObjectKindsDesc};

/// Template for checking dangling services (services with selectors that don't match any pods).
pub struct DanglingServiceTemplate;

impl Template for DanglingServiceTemplate {
    fn key(&self) -> &str {
        "dangling-service"
    }

    fn human_name(&self) -> &str {
        "Dangling Service"
    }

    fn description(&self) -> &str {
        "Checks for services with selectors that don't match any pods"
    }

    fn supported_object_kinds(&self) -> ObjectKindsDesc {
        ObjectKindsDesc::new(&["Service"])
    }

    fn parameters(&self) -> Vec<ParameterDesc> {
        Vec::new()
    }

    fn instantiate(
        &self,
        _params: &serde_yaml::Value,
    ) -> Result<Box<dyn CheckFunc>, TemplateError> {
        // Note: This check requires cross-resource validation
        // Full implementation needs access to all pods in the context
        Ok(Box::new(DanglingServiceCheck))
    }
}

struct DanglingServiceCheck;

impl CheckFunc for DanglingServiceCheck {
    fn check(&self, _object: &Object) -> Vec<Diagnostic> {
        // Requires cross-resource validation - placeholder
        Vec::new()
    }
}

/// Template for checking dangling ingresses (ingresses referencing non-existent services).
pub struct DanglingIngressTemplate;

impl Template for DanglingIngressTemplate {
    fn key(&self) -> &str {
        "dangling-ingress"
    }

    fn human_name(&self) -> &str {
        "Dangling Ingress"
    }

    fn description(&self) -> &str {
        "Checks for ingresses that reference non-existent services"
    }

    fn supported_object_kinds(&self) -> ObjectKindsDesc {
        ObjectKindsDesc::new(&["Ingress"])
    }

    fn parameters(&self) -> Vec<ParameterDesc> {
        Vec::new()
    }

    fn instantiate(
        &self,
        _params: &serde_yaml::Value,
    ) -> Result<Box<dyn CheckFunc>, TemplateError> {
        Ok(Box::new(DanglingIngressCheck))
    }
}

struct DanglingIngressCheck;

impl CheckFunc for DanglingIngressCheck {
    fn check(&self, _object: &Object) -> Vec<Diagnostic> {
        // Requires cross-resource validation - placeholder
        Vec::new()
    }
}

/// Template for checking dangling HPAs (HPAs targeting non-existent deployments).
pub struct DanglingHpaTemplate;

impl Template for DanglingHpaTemplate {
    fn key(&self) -> &str {
        "dangling-hpa"
    }

    fn human_name(&self) -> &str {
        "Dangling HPA"
    }

    fn description(&self) -> &str {
        "Checks for HPAs that target non-existent deployments"
    }

    fn supported_object_kinds(&self) -> ObjectKindsDesc {
        ObjectKindsDesc::new(&["HorizontalPodAutoscaler"])
    }

    fn parameters(&self) -> Vec<ParameterDesc> {
        Vec::new()
    }

    fn instantiate(
        &self,
        _params: &serde_yaml::Value,
    ) -> Result<Box<dyn CheckFunc>, TemplateError> {
        Ok(Box::new(DanglingHpaCheck))
    }
}

struct DanglingHpaCheck;

impl CheckFunc for DanglingHpaCheck {
    fn check(&self, _object: &Object) -> Vec<Diagnostic> {
        // Requires cross-resource validation - placeholder
        Vec::new()
    }
}

/// Template for checking dangling network policies.
pub struct DanglingNetworkPolicyTemplate;

impl Template for DanglingNetworkPolicyTemplate {
    fn key(&self) -> &str {
        "dangling-network-policy"
    }

    fn human_name(&self) -> &str {
        "Dangling NetworkPolicy"
    }

    fn description(&self) -> &str {
        "Checks for network policies with selectors that don't match any pods"
    }

    fn supported_object_kinds(&self) -> ObjectKindsDesc {
        ObjectKindsDesc::new(&["NetworkPolicy"])
    }

    fn parameters(&self) -> Vec<ParameterDesc> {
        Vec::new()
    }

    fn instantiate(
        &self,
        _params: &serde_yaml::Value,
    ) -> Result<Box<dyn CheckFunc>, TemplateError> {
        Ok(Box::new(DanglingNetworkPolicyCheck))
    }
}

struct DanglingNetworkPolicyCheck;

impl CheckFunc for DanglingNetworkPolicyCheck {
    fn check(&self, _object: &Object) -> Vec<Diagnostic> {
        // Requires cross-resource validation - placeholder
        Vec::new()
    }
}

/// Template for checking dangling network policy peer selectors.
pub struct DanglingNetworkPolicyPeerTemplate;

impl Template for DanglingNetworkPolicyPeerTemplate {
    fn key(&self) -> &str {
        "dangling-network-policy-peer"
    }

    fn human_name(&self) -> &str {
        "Dangling NetworkPolicy Peer"
    }

    fn description(&self) -> &str {
        "Checks for network policy peer selectors that don't match any pods"
    }

    fn supported_object_kinds(&self) -> ObjectKindsDesc {
        ObjectKindsDesc::new(&["NetworkPolicy"])
    }

    fn parameters(&self) -> Vec<ParameterDesc> {
        Vec::new()
    }

    fn instantiate(
        &self,
        _params: &serde_yaml::Value,
    ) -> Result<Box<dyn CheckFunc>, TemplateError> {
        Ok(Box::new(DanglingNetworkPolicyPeerCheck))
    }
}

struct DanglingNetworkPolicyPeerCheck;

impl CheckFunc for DanglingNetworkPolicyPeerCheck {
    fn check(&self, _object: &Object) -> Vec<Diagnostic> {
        // Requires cross-resource validation - placeholder
        Vec::new()
    }
}

/// Template for checking dangling service monitors.
pub struct DanglingServiceMonitorTemplate;

impl Template for DanglingServiceMonitorTemplate {
    fn key(&self) -> &str {
        "dangling-service-monitor"
    }

    fn human_name(&self) -> &str {
        "Dangling ServiceMonitor"
    }

    fn description(&self) -> &str {
        "Checks for service monitors with selectors that don't match any services"
    }

    fn supported_object_kinds(&self) -> ObjectKindsDesc {
        ObjectKindsDesc::new(&["ServiceMonitor"])
    }

    fn parameters(&self) -> Vec<ParameterDesc> {
        Vec::new()
    }

    fn instantiate(
        &self,
        _params: &serde_yaml::Value,
    ) -> Result<Box<dyn CheckFunc>, TemplateError> {
        Ok(Box::new(DanglingServiceMonitorCheck))
    }
}

struct DanglingServiceMonitorCheck;

impl CheckFunc for DanglingServiceMonitorCheck {
    fn check(&self, _object: &Object) -> Vec<Diagnostic> {
        // Requires cross-resource validation - placeholder
        Vec::new()
    }
}

/// Template for checking non-existent service accounts.
pub struct NonExistentServiceAccountTemplate;

impl Template for NonExistentServiceAccountTemplate {
    fn key(&self) -> &str {
        "non-existent-service-account"
    }

    fn human_name(&self) -> &str {
        "Non-existent ServiceAccount"
    }

    fn description(&self) -> &str {
        "Checks for pods referencing non-existent service accounts"
    }

    fn supported_object_kinds(&self) -> ObjectKindsDesc {
        ObjectKindsDesc::default()
    }

    fn parameters(&self) -> Vec<ParameterDesc> {
        Vec::new()
    }

    fn instantiate(
        &self,
        _params: &serde_yaml::Value,
    ) -> Result<Box<dyn CheckFunc>, TemplateError> {
        Ok(Box::new(NonExistentServiceAccountCheck))
    }
}

struct NonExistentServiceAccountCheck;

impl CheckFunc for NonExistentServiceAccountCheck {
    fn check(&self, _object: &Object) -> Vec<Diagnostic> {
        // Requires cross-resource validation - placeholder
        Vec::new()
    }
}

/// Template for checking non-isolated pods.
pub struct NonIsolatedPodTemplate;

impl Template for NonIsolatedPodTemplate {
    fn key(&self) -> &str {
        "non-isolated-pod"
    }

    fn human_name(&self) -> &str {
        "Non-isolated Pod"
    }

    fn description(&self) -> &str {
        "Checks for pods not covered by any network policy"
    }

    fn supported_object_kinds(&self) -> ObjectKindsDesc {
        ObjectKindsDesc::default()
    }

    fn parameters(&self) -> Vec<ParameterDesc> {
        Vec::new()
    }

    fn instantiate(
        &self,
        _params: &serde_yaml::Value,
    ) -> Result<Box<dyn CheckFunc>, TemplateError> {
        Ok(Box::new(NonIsolatedPodCheck))
    }
}

struct NonIsolatedPodCheck;

impl CheckFunc for NonIsolatedPodCheck {
    fn check(&self, _object: &Object) -> Vec<Diagnostic> {
        // Requires cross-resource validation - placeholder
        Vec::new()
    }
}

/// Template for checking SecurityContextConstraints (OpenShift).
pub struct SccDenyPrivilegedTemplate;

impl Template for SccDenyPrivilegedTemplate {
    fn key(&self) -> &str {
        "scc-deny-privileged"
    }

    fn human_name(&self) -> &str {
        "SCC Deny Privileged Container"
    }

    fn description(&self) -> &str {
        "Checks if SecurityContextConstraints allow privileged containers"
    }

    fn supported_object_kinds(&self) -> ObjectKindsDesc {
        ObjectKindsDesc::new(&["SecurityContextConstraints"])
    }

    fn parameters(&self) -> Vec<ParameterDesc> {
        Vec::new()
    }

    fn instantiate(
        &self,
        _params: &serde_yaml::Value,
    ) -> Result<Box<dyn CheckFunc>, TemplateError> {
        Ok(Box::new(SccDenyPrivilegedCheck))
    }
}

struct SccDenyPrivilegedCheck;

impl CheckFunc for SccDenyPrivilegedCheck {
    fn check(&self, _object: &Object) -> Vec<Diagnostic> {
        // OpenShift-specific check - placeholder for unknown resource types
        Vec::new()
    }
}