forked from NationTech/harmony
		
	wip: helm chart deploys to namespace with resource limits and requests, trying to fix connection refused to api error
This commit is contained in:
		
							parent
							
								
									8e857bc72a
								
							
						
					
					
						commit
						460c8b59e1
					
				
							
								
								
									
										13
									
								
								examples/monitoring_with_tenant/Cargo.toml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								examples/monitoring_with_tenant/Cargo.toml
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,13 @@ | |||||||
|  | [package] | ||||||
|  | name = "example-monitoring-with-tenant" | ||||||
|  | edition = "2024" | ||||||
|  | version.workspace = true | ||||||
|  | readme.workspace = true | ||||||
|  | license.workspace = true | ||||||
|  | 
 | ||||||
|  | [dependencies] | ||||||
|  | cidr.workspace = true | ||||||
|  | harmony = { version = "0.1.0", path = "../../harmony" } | ||||||
|  | harmony_cli = { version = "0.1.0", path = "../../harmony_cli" } | ||||||
|  | tokio.workspace = true | ||||||
|  | url.workspace = true | ||||||
							
								
								
									
										63
									
								
								examples/monitoring_with_tenant/src/main.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										63
									
								
								examples/monitoring_with_tenant/src/main.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,63 @@ | |||||||
|  | use cidr::Ipv4Cidr; | ||||||
|  | use harmony::{ | ||||||
|  |     data::Id, | ||||||
|  |     inventory::Inventory, | ||||||
|  |     maestro::Maestro, | ||||||
|  |     modules::{ | ||||||
|  |         monitoring::{ | ||||||
|  |             alert_channel::discord_alert_channel::DiscordWebhook, | ||||||
|  |             alert_rule::prometheus_alert_rule::AlertManagerRuleGroup, | ||||||
|  |             kube_prometheus::helm_prometheus_alert_score::HelmPrometheusAlertingScore, | ||||||
|  |         }, | ||||||
|  |         prometheus::alerts::k8s::pvc::high_pvc_fill_rate_over_two_days, | ||||||
|  |         tenant::TenantScore, | ||||||
|  |     }, | ||||||
|  |     topology::{ | ||||||
|  |         K8sAnywhereTopology, Url, | ||||||
|  |         tenant::{InternetEgressPolicy, ResourceLimits, TenantConfig, TenantNetworkPolicy}, | ||||||
|  |     }, | ||||||
|  | }; | ||||||
|  | use std::net::Ipv4Addr; | ||||||
|  | use std::str::FromStr; | ||||||
|  | 
 | ||||||
|  | #[tokio::main] | ||||||
|  | async fn main() { | ||||||
|  |     let tenant = TenantScore { | ||||||
|  |         config: TenantConfig { | ||||||
|  |             id: Id::from_string("1234".to_string()), | ||||||
|  |             name: "test-tenant".to_string(), | ||||||
|  |             resource_limits: ResourceLimits { | ||||||
|  |                 cpu_request_cores: 4.0, | ||||||
|  |                 cpu_limit_cores: 4.0, | ||||||
|  |                 memory_request_gb: 4.0, | ||||||
|  |                 memory_limit_gb: 4.0, | ||||||
|  |                 storage_total_gb: 10.0, | ||||||
|  |             }, | ||||||
|  |             network_policy: TenantNetworkPolicy::default(), | ||||||
|  |         }, | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|  |     let discord_receiver = DiscordWebhook { | ||||||
|  |         name: "test-discord".to_string(), | ||||||
|  |         url: Url::Url(url::Url::parse("https://discord.doesnt.exist.com").unwrap()), | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|  |     let high_pvc_fill_rate_over_two_days_alert = high_pvc_fill_rate_over_two_days(); | ||||||
|  | 
 | ||||||
|  |     let additional_rules = | ||||||
|  |         AlertManagerRuleGroup::new("pvc-alerts", vec![high_pvc_fill_rate_over_two_days_alert]); | ||||||
|  | 
 | ||||||
|  |     let alerting_score = HelmPrometheusAlertingScore { | ||||||
|  |         receivers: vec![Box::new(discord_receiver)], | ||||||
|  |         rules: vec![Box::new(additional_rules)], | ||||||
|  |     }; | ||||||
|  |     let mut maestro = Maestro::<K8sAnywhereTopology>::initialize( | ||||||
|  |         Inventory::autoload(), | ||||||
|  |         K8sAnywhereTopology::from_env(), | ||||||
|  |     ) | ||||||
|  |     .await | ||||||
|  |     .unwrap(); | ||||||
|  | 
 | ||||||
|  |     maestro.register_all(vec![Box::new(tenant), Box::new(alerting_score)]); | ||||||
|  |     harmony_cli::init(maestro, None).await.unwrap(); | ||||||
|  | } | ||||||
| @ -185,13 +185,18 @@ impl K8sAnywhereTopology { | |||||||
|         self.tenant_manager |         self.tenant_manager | ||||||
|             .get_or_try_init(async || -> Result<K8sTenantManager, String> { |             .get_or_try_init(async || -> Result<K8sTenantManager, String> { | ||||||
|                 let k8s_client = self.k8s_client().await?; |                 let k8s_client = self.k8s_client().await?; | ||||||
|                 Ok(K8sTenantManager::new(k8s_client, TenantConfig::default())) |                 Ok(K8sTenantManager::new(k8s_client)) | ||||||
|             }) |             }) | ||||||
|             .await |             .await | ||||||
|             .unwrap(); |             .unwrap(); | ||||||
| 
 | 
 | ||||||
|         Ok(()) |         Ok(()) | ||||||
|     } |     } | ||||||
|  |     async fn store_tenant_config(&self, config: TenantConfig) { | ||||||
|  |         self.tenant_manager_config | ||||||
|  |             .get_or_init(|| async { config }) | ||||||
|  |             .await; | ||||||
|  |     } | ||||||
| 
 | 
 | ||||||
|     fn get_k8s_tenant_manager(&self) -> Result<&K8sTenantManager, ExecutorError> { |     fn get_k8s_tenant_manager(&self) -> Result<&K8sTenantManager, ExecutorError> { | ||||||
|         match self.tenant_manager.get() { |         match self.tenant_manager.get() { | ||||||
| @ -271,6 +276,7 @@ impl HelmCommand for K8sAnywhereTopology {} | |||||||
| #[async_trait] | #[async_trait] | ||||||
| impl TenantManager for K8sAnywhereTopology { | impl TenantManager for K8sAnywhereTopology { | ||||||
|     async fn provision_tenant(&self, config: &TenantConfig) -> Result<(), ExecutorError> { |     async fn provision_tenant(&self, config: &TenantConfig) -> Result<(), ExecutorError> { | ||||||
|  |         self.store_tenant_config(config.clone()).await; | ||||||
|         self.get_k8s_tenant_manager()? |         self.get_k8s_tenant_manager()? | ||||||
|             .provision_tenant(config) |             .provision_tenant(config) | ||||||
|             .await |             .await | ||||||
|  | |||||||
| @ -25,7 +25,6 @@ use super::{TenantConfig, TenantManager}; | |||||||
| #[derive(new)] | #[derive(new)] | ||||||
| pub struct K8sTenantManager { | pub struct K8sTenantManager { | ||||||
|     k8s_client: Arc<K8sClient>, |     k8s_client: Arc<K8sClient>, | ||||||
|     k8s_tenant_config: TenantConfig, |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| impl K8sTenantManager { | impl K8sTenantManager { | ||||||
| @ -326,6 +325,6 @@ impl TenantManager for K8sTenantManager { | |||||||
|         Ok(()) |         Ok(()) | ||||||
|     } |     } | ||||||
|     fn get_tenant_config(&self) -> Option<TenantConfig> { |     fn get_tenant_config(&self) -> Option<TenantConfig> { | ||||||
|         Some(self.k8s_tenant_config.clone()) |         todo!() | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | |||||||
| @ -1,8 +1,8 @@ | |||||||
| use serde::Serialize; | use serde::Serialize; | ||||||
| 
 | 
 | ||||||
| use crate::modules::monitoring:: | use crate::modules::monitoring::kube_prometheus::types::{ | ||||||
|     kube_prometheus::types::{AlertManagerAdditionalPromRules, AlertManagerChannelConfig} |     AlertManagerAdditionalPromRules, AlertManagerChannelConfig, | ||||||
| ; | }; | ||||||
| 
 | 
 | ||||||
| #[derive(Debug, Clone, Serialize)] | #[derive(Debug, Clone, Serialize)] | ||||||
| pub struct KubePrometheusConfig { | pub struct KubePrometheusConfig { | ||||||
|  | |||||||
| @ -12,7 +12,8 @@ use crate::modules::{ | |||||||
|     helm::chart::HelmChartScore, |     helm::chart::HelmChartScore, | ||||||
|     monitoring::kube_prometheus::types::{ |     monitoring::kube_prometheus::types::{ | ||||||
|         AlertGroup, AlertManager, AlertManagerAdditionalPromRules, AlertManagerConfig, |         AlertGroup, AlertManager, AlertManagerAdditionalPromRules, AlertManagerConfig, | ||||||
|         AlertManagerRoute, AlertManagerValues, |         AlertManagerRoute, AlertManagerSpec, AlertManagerValues, Cpu, CpuUnit, Limits, Memory, | ||||||
|  |         MemoryUnit, Requests, Resources, | ||||||
|     }, |     }, | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| @ -36,8 +37,53 @@ pub fn kube_prometheus_helm_chart_score( | |||||||
|     let node_exporter = config.node_exporter.to_string(); |     let node_exporter = config.node_exporter.to_string(); | ||||||
|     let prometheus_operator = config.prometheus_operator.to_string(); |     let prometheus_operator = config.prometheus_operator.to_string(); | ||||||
|     let prometheus = config.prometheus.to_string(); |     let prometheus = config.prometheus.to_string(); | ||||||
|  |     let resource_limit = Resources { | ||||||
|  |         limits: Limits { | ||||||
|  |             memory: Memory { | ||||||
|  |                 value: 100, | ||||||
|  |                 unit: MemoryUnit::Mi, | ||||||
|  |             }, | ||||||
|  |             cpu: Cpu { | ||||||
|  |                 value: 100, | ||||||
|  |                 unit: CpuUnit::Milli, | ||||||
|  |             }, | ||||||
|  |         }, | ||||||
|  |         requests: Requests { | ||||||
|  |             memory: Memory { | ||||||
|  |                 value: 100, | ||||||
|  |                 unit: MemoryUnit::Mi, | ||||||
|  |             }, | ||||||
|  |             cpu: Cpu { | ||||||
|  |                 value: 100, | ||||||
|  |                 unit: CpuUnit::Milli, | ||||||
|  |             }, | ||||||
|  |         }, | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|  |     fn indent_lines(s: &str, spaces: usize) -> String { | ||||||
|  |         let pad = " ".repeat(spaces); | ||||||
|  |         s.lines() | ||||||
|  |             .map(|line| format!("{pad}{line}")) | ||||||
|  |             .collect::<Vec<_>>() | ||||||
|  |             .join("\n") | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     fn resource_block(resource: &Resources, indent_level: usize) -> String { | ||||||
|  |         let yaml = serde_yaml::to_string(resource).unwrap(); | ||||||
|  |         format!( | ||||||
|  |             "{}resources:\n{}", | ||||||
|  |             " ".repeat(indent_level), | ||||||
|  |             indent_lines(&yaml, indent_level + 2) | ||||||
|  |         ) | ||||||
|  |     } | ||||||
|  |     let resource_section = resource_block(&resource_limit, 2); | ||||||
|  | 
 | ||||||
|     let mut values = format!( |     let mut values = format!( | ||||||
|         r#" |         r#" | ||||||
|  | prometheus: | ||||||
|  |   enabled: {prometheus} | ||||||
|  |   prometheusSpec: | ||||||
|  |   {resource_section} | ||||||
| defaultRules: | defaultRules: | ||||||
|   create: {default_rules} |   create: {default_rules} | ||||||
|   rules: |   rules: | ||||||
| @ -77,32 +123,59 @@ defaultRules: | |||||||
|     windows: true |     windows: true | ||||||
| windowsMonitoring: | windowsMonitoring: | ||||||
|   enabled: {windows_monitoring} |   enabled: {windows_monitoring} | ||||||
|  | {resource_section} | ||||||
| grafana: | grafana: | ||||||
|   enabled: {grafana} |   enabled: {grafana} | ||||||
|  | {resource_section} | ||||||
| kubernetesServiceMonitors: | kubernetesServiceMonitors: | ||||||
|   enabled: {kubernetes_service_monitors} |   enabled: {kubernetes_service_monitors} | ||||||
|  | {resource_section} | ||||||
| kubeApiServer: | kubeApiServer: | ||||||
|   enabled: {kubernetes_api_server} |   enabled: {kubernetes_api_server} | ||||||
|  | {resource_section} | ||||||
| kubelet: | kubelet: | ||||||
|   enabled: {kubelet} |   enabled: {kubelet} | ||||||
|  | {resource_section} | ||||||
| kubeControllerManager: | kubeControllerManager: | ||||||
|   enabled: {kube_controller_manager} |   enabled: {kube_controller_manager} | ||||||
|  | {resource_section} | ||||||
| coreDns: | coreDns: | ||||||
|   enabled: {core_dns} |   enabled: {core_dns} | ||||||
|  | {resource_section} | ||||||
| kubeEtcd: | kubeEtcd: | ||||||
|   enabled: {kube_etcd} |   enabled: {kube_etcd} | ||||||
|  | {resource_section} | ||||||
| kubeScheduler: | kubeScheduler: | ||||||
|   enabled: {kube_scheduler} |   enabled: {kube_scheduler} | ||||||
|  | {resource_section} | ||||||
| kubeProxy: | kubeProxy: | ||||||
|   enabled: {kube_proxy} |   enabled: {kube_proxy} | ||||||
|  | {resource_section} | ||||||
| kubeStateMetrics: | kubeStateMetrics: | ||||||
|   enabled: {kube_state_metrics} |   enabled: {kube_state_metrics} | ||||||
|  | {resource_section} | ||||||
| nodeExporter: | nodeExporter: | ||||||
|   enabled: {node_exporter} |   enabled: {node_exporter} | ||||||
|  | {resource_section} | ||||||
| prometheusOperator: | prometheusOperator: | ||||||
|   enabled: {prometheus_operator} |   enabled: {prometheus_operator} | ||||||
| prometheus: |   admissionWebhooks: | ||||||
|   enabled: {prometheus} |     deployment: | ||||||
|  |       resources: | ||||||
|  |         limits: | ||||||
|  |           cpu: 10m | ||||||
|  |           memory: 100Mi | ||||||
|  |         requests:  | ||||||
|  |           cpu: 10m | ||||||
|  |           memory: 100Mi | ||||||
|  |     patch: | ||||||
|  |       resources: | ||||||
|  |         limits: | ||||||
|  |           cpu: 10m | ||||||
|  |           memory: 100Mi | ||||||
|  |         requests:  | ||||||
|  |           cpu: 10m | ||||||
|  |           memory: 100Mi | ||||||
| "#,
 | "#,
 | ||||||
|     ); |     ); | ||||||
| 
 | 
 | ||||||
| @ -145,6 +218,30 @@ prometheus: | |||||||
|         alertmanager: AlertManager { |         alertmanager: AlertManager { | ||||||
|             enabled: config.alert_manager, |             enabled: config.alert_manager, | ||||||
|             config: alert_manager_channel_config, |             config: alert_manager_channel_config, | ||||||
|  |             alertManagerSpec: AlertManagerSpec { | ||||||
|  |                 resources: Resources { | ||||||
|  |                     limits: Limits { | ||||||
|  |                         memory: Memory { | ||||||
|  |                             value: 100, | ||||||
|  |                             unit: MemoryUnit::Mi, | ||||||
|  |                         }, | ||||||
|  |                         cpu: Cpu { | ||||||
|  |                             value: 100, | ||||||
|  |                             unit: CpuUnit::Milli, | ||||||
|  |                         }, | ||||||
|  |                     }, | ||||||
|  |                     requests: Requests { | ||||||
|  |                         memory: Memory { | ||||||
|  |                             value: 100, | ||||||
|  |                             unit: MemoryUnit::Mi, | ||||||
|  |                         }, | ||||||
|  |                         cpu: Cpu { | ||||||
|  |                             value: 100, | ||||||
|  |                             unit: CpuUnit::Milli, | ||||||
|  |                         }, | ||||||
|  |                     }, | ||||||
|  |                 }, | ||||||
|  |             }, | ||||||
|         }, |         }, | ||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
| @ -184,7 +281,6 @@ prometheus: | |||||||
|     values.push_str(&alert_manager_additional_rules_yaml); |     values.push_str(&alert_manager_additional_rules_yaml); | ||||||
|     debug!("full values.yaml: \n {:#}", values); |     debug!("full values.yaml: \n {:#}", values); | ||||||
| 
 | 
 | ||||||
| 
 |  | ||||||
|     HelmChartScore { |     HelmChartScore { | ||||||
|         namespace: Some(NonBlankString::from_str(&config.namespace.clone().unwrap()).unwrap()), |         namespace: Some(NonBlankString::from_str(&config.namespace.clone().unwrap()).unwrap()), | ||||||
|         release_name: NonBlankString::from_str("kube-prometheus").unwrap(), |         release_name: NonBlankString::from_str("kube-prometheus").unwrap(), | ||||||
|  | |||||||
| @ -21,7 +21,7 @@ pub struct HelmPrometheusAlertingScore { | |||||||
| impl<T: Topology + HelmCommand + TenantManager> Score<T> for HelmPrometheusAlertingScore { | impl<T: Topology + HelmCommand + TenantManager> Score<T> for HelmPrometheusAlertingScore { | ||||||
|     fn create_interpret(&self) -> Box<dyn crate::interpret::Interpret<T>> { |     fn create_interpret(&self) -> Box<dyn crate::interpret::Interpret<T>> { | ||||||
|         Box::new(AlertingInterpret { |         Box::new(AlertingInterpret { | ||||||
|             sender: Prometheus::new() , |             sender: Prometheus::new(), | ||||||
|             receivers: self.receivers.clone(), |             receivers: self.receivers.clone(), | ||||||
|             rules: self.rules.clone(), |             rules: self.rules.clone(), | ||||||
|         }) |         }) | ||||||
|  | |||||||
| @ -63,8 +63,11 @@ impl Prometheus { | |||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     pub fn configure_with_topology<T: TenantManager>(&self, topology: &T) { |     pub fn configure_with_topology<T: TenantManager>(&self, topology: &T) { | ||||||
|         let ns = topology.get_tenant_config().map(|cfg| cfg.name.clone()) |         let ns = topology | ||||||
|         .unwrap_or_else(|| "monitoring".to_string()); |             .get_tenant_config() | ||||||
|  |             .map(|cfg| cfg.name.clone()) | ||||||
|  |             .unwrap_or_else(|| "monitoring".to_string()); | ||||||
|  |         debug!("NS: {}", ns); | ||||||
|         self.config.lock().unwrap().namespace = Some(ns); |         self.config.lock().unwrap().namespace = Some(ns); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -19,6 +19,7 @@ pub struct AlertManagerValues { | |||||||
| pub struct AlertManager { | pub struct AlertManager { | ||||||
|     pub enabled: bool, |     pub enabled: bool, | ||||||
|     pub config: AlertManagerConfig, |     pub config: AlertManagerConfig, | ||||||
|  |     pub alertManagerSpec: AlertManagerSpec, | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #[derive(Debug, Clone, Serialize)] | #[derive(Debug, Clone, Serialize)] | ||||||
| @ -43,6 +44,58 @@ pub struct AlertManagerChannelConfig { | |||||||
|     pub channel_receiver: Value, |     pub channel_receiver: Value, | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | #[derive(Debug, Clone, Serialize)] | ||||||
|  | pub struct AlertManagerSpec { | ||||||
|  |     pub(crate) resources: Resources, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #[derive(Debug, Clone, Serialize)] | ||||||
|  | pub struct Resources { | ||||||
|  |     pub limits: Limits, | ||||||
|  |     pub requests: Requests, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #[derive(Debug, Clone, Serialize)] | ||||||
|  | pub struct Limits { | ||||||
|  |     pub memory: Memory, | ||||||
|  |     pub cpu: Cpu, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #[derive(Debug, Clone, Serialize)] | ||||||
|  | pub struct Requests { | ||||||
|  |     pub memory: Memory, | ||||||
|  |     pub cpu: Cpu, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #[derive(Debug, Clone, Serialize)] | ||||||
|  | pub struct Memory { | ||||||
|  |     pub value: u64, | ||||||
|  |     pub unit: MemoryUnit, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #[derive(Debug, Clone, Serialize)] | ||||||
|  | pub struct Cpu { | ||||||
|  |     pub value: u64, | ||||||
|  |     pub unit: CpuUnit, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #[derive(Debug, Clone, Serialize)] | ||||||
|  | #[serde(rename_all = "lowercase")] | ||||||
|  | pub enum MemoryUnit { | ||||||
|  |     Ki, | ||||||
|  |     Mi, | ||||||
|  |     Gi, | ||||||
|  |     Ti, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #[derive(Debug, Clone, Serialize)] | ||||||
|  | #[serde(rename_all = "lowercase")] | ||||||
|  | pub enum CpuUnit { | ||||||
|  |     // 1 = 1 core, m = millicore
 | ||||||
|  |     Core, | ||||||
|  |     Milli, | ||||||
|  | } | ||||||
|  | 
 | ||||||
| #[derive(Debug, Clone, Serialize)] | #[derive(Debug, Clone, Serialize)] | ||||||
| pub struct AlertManagerAdditionalPromRules { | pub struct AlertManagerAdditionalPromRules { | ||||||
|     #[serde(flatten)] |     #[serde(flatten)] | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user