Unverified Commit 43eac29a authored by Bohdan Parkhomchuk's avatar Bohdan Parkhomchuk 💬
Browse files

feat(health-check): multi-namespace targets with StatefulSet support

parent 35e8eda9
Loading
Loading
Loading
Loading
+2 −8
Original line number Diff line number Diff line
@@ -93,15 +93,9 @@ for f in listdir('helm/local/dashboards'):
k8s_yaml(blob(dashboards_cm))
k8s_yaml('helm/local/grafana.yaml')

# Vendor helm chart: bootstrap on fresh clone, re-sync when config changes
# Vendor helm chart on fresh clone only; re-sync manually with `helm/sync.sh`
if not os.path.exists('helm/gkg/Chart.yaml'):
    local('helm/sync.sh')
local_resource(
    'helm-sync',
    cmd='helm/sync.sh',
    deps=['helm/vendir.yml', 'helm/vendir.lock.yml', 'helm/patches'],
    labels=['setup'],
)

# Deploy gkg chart (vendored official chart + patches)
k8s_yaml(helm(
@@ -114,7 +108,7 @@ k8s_yaml(helm(
# Skip readiness checks for components that may take time to connect
k8s_resource('gkg-dispatcher', pod_readiness='ignore')
k8s_resource('gkg-indexer', pod_readiness='ignore')
k8s_resource('gkg-webserver', pod_readiness='ignore', port_forwards=['8080:8080'])
k8s_resource('gkg-webserver', pod_readiness='ignore', port_forwards=['8080:8080', '50054:50054'])
k8s_resource('gkg-health-check', pod_readiness='ignore', port_forwards=['4201:4201'])
k8s_resource('grafana', port_forwards=['3030:3000'])
k8s_resource('prometheus', port_forwards=['9090:9090'])
+1 −6
Original line number Diff line number Diff line
@@ -83,12 +83,7 @@ schedule:

health_check:
  bind_address: "0.0.0.0:4201"
  namespace: default
  services:
    - siphon-consumer
    - siphon-producer
    - gkg-indexer
    - nats
  targets: []

grpc:
  keepalive_interval_secs: 20
+31 −19
Original line number Diff line number Diff line
@@ -108,13 +108,7 @@
      "$ref": "#/$defs/HealthCheckConfig",
      "default": {
        "bind_address": "0.0.0.0:4201",
        "namespace": "default",
        "services": [
          "siphon-consumer",
          "siphon-producer",
          "gkg-indexer",
          "nats"
        ]
        "targets": []
      }
    },
    "health_check_url": {
@@ -530,20 +524,11 @@
          "type": "string",
          "default": "0.0.0.0:4201"
        },
        "namespace": {
          "type": "string",
          "default": "default"
        },
        "services": {
        "targets": {
          "type": "array",
          "default": [
            "siphon-consumer",
            "siphon-producer",
            "gkg-indexer",
            "nats"
          ],
          "default": [],
          "items": {
            "type": "string"
            "$ref": "#/$defs/NamespaceTarget"
          }
        }
      },
@@ -722,6 +707,33 @@
        }
      }
    },
    "NamespaceTarget": {
      "description": "A namespace with lists of deployments and/or statefulsets to monitor.",
      "type": "object",
      "properties": {
        "deployments": {
          "type": "array",
          "default": [],
          "items": {
            "type": "string"
          }
        },
        "namespace": {
          "type": "string"
        },
        "statefulsets": {
          "type": "array",
          "default": [],
          "items": {
            "type": "string"
          }
        }
      },
      "additionalProperties": false,
      "required": [
        "namespace"
      ]
    },
    "NatsConfiguration": {
      "description": "NATS connection settings.\n\nMatches siphon's QueuingConfig fields.",
      "type": "object",
+56 −17
Original line number Diff line number Diff line
@@ -9,17 +9,15 @@ fn default_bind_address() -> SocketAddr {
    SocketAddr::from(([0, 0, 0, 0], 4201))
}

fn default_namespace() -> String {
    "default".to_string()
}

fn default_services() -> Vec<String> {
    vec![
        "siphon-consumer".to_string(),
        "siphon-producer".to_string(),
        "gkg-indexer".to_string(),
        "nats".to_string(),
    ]
/// A namespace with lists of deployments and/or statefulsets to monitor.
#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema)]
#[schemars(deny_unknown_fields)]
pub struct NamespaceTarget {
    pub namespace: String,
    #[serde(default)]
    pub deployments: Vec<String>,
    #[serde(default)]
    pub statefulsets: Vec<String>,
}

#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema)]
@@ -27,18 +25,59 @@ fn default_services() -> Vec<String> {
pub struct HealthCheckConfig {
    #[serde(default = "default_bind_address")]
    pub bind_address: SocketAddr,
    #[serde(default = "default_namespace")]
    pub namespace: String,
    #[serde(default = "default_services")]
    pub services: Vec<String>,
    #[serde(default)]
    pub targets: Vec<NamespaceTarget>,
}

impl Default for HealthCheckConfig {
    fn default() -> Self {
        Self {
            bind_address: default_bind_address(),
            namespace: default_namespace(),
            services: default_services(),
            targets: Vec::new(),
        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn deserialize_targets_from_yaml() {
        let yaml = r#"
bind_address: "0.0.0.0:4201"
targets:
  - namespace: gkg
    deployments:
      - gkg-indexer
      - gkg-webserver
    statefulsets:
      - clickhouse
  - namespace: siphon
    deployments:
      - siphon-consumer
"#;
        let config: HealthCheckConfig = serde_yaml::from_str(yaml).unwrap();
        assert_eq!(config.targets.len(), 2);
        assert_eq!(config.targets[0].namespace, "gkg");
        assert_eq!(config.targets[0].deployments.len(), 2);
        assert_eq!(config.targets[0].statefulsets, vec!["clickhouse"]);
        assert_eq!(config.targets[1].namespace, "siphon");
        assert!(config.targets[1].statefulsets.is_empty());
    }

    #[test]
    fn empty_targets_is_valid_default() {
        let yaml = "bind_address: \"0.0.0.0:4201\"";
        let config: HealthCheckConfig = serde_yaml::from_str(yaml).unwrap();
        assert!(config.targets.is_empty());
    }

    #[test]
    fn namespace_target_omits_optional_lists() {
        let yaml = "namespace: gkg";
        let target: NamespaceTarget = serde_yaml::from_str(yaml).unwrap();
        assert!(target.deployments.is_empty());
        assert!(target.statefulsets.is_empty());
    }
}
+1 −1
Original line number Diff line number Diff line
@@ -31,7 +31,7 @@ pub use engine::{
};
pub use gitlab::{GitlabClientConfiguration, GitlabConfig, JwtConfig};
pub use grpc::GrpcConfig;
pub use health_check::HealthCheckConfig;
pub use health_check::{HealthCheckConfig, NamespaceTarget};
pub use metrics::{MetricsConfig, OtelConfig, PrometheusConfig};
pub use nats::NatsConfiguration;
pub use query::{QueryConfig, QuerySettings};
Loading