controller/
configmap.rs
1use crate::{apis::coredb_types::CoreDB, Context, Error};
2use k8s_openapi::api::core::v1::ConfigMap;
3use kube::{
4 api::{Api, ObjectMeta, Patch, PatchParams},
5 runtime::controller::Action,
6 Client, ResourceExt,
7};
8use std::{collections::BTreeMap, sync::Arc};
9
10use tracing::{debug, error, instrument};
11
12#[instrument(skip(cdb, ctx) fields(trace_id, instance_name = %cdb.name_any()))]
13pub async fn reconcile_generic_metrics_configmap(
14 cdb: &CoreDB,
15 ctx: Arc<Context>,
16) -> Result<(), Action> {
17 let (custom_metrics_namespace, custom_metrics_name) = match custom_metrics_configmap_settings()
18 {
19 Some(value) => value,
20 _ => return Ok(()),
21 };
22
23 let namespace = cdb.namespace().unwrap();
24 let client = ctx.client.clone();
25 let configmap_api_dataplane_namespace: Api<ConfigMap> =
26 Api::namespaced(client.clone(), &custom_metrics_namespace);
27
28 let configmap_name = format!("{}-custom", cdb.name_any());
29
30 match configmap_api_dataplane_namespace
31 .get(&custom_metrics_name)
32 .await
33 {
34 Ok(original_configmap) => {
35 let data = original_configmap.data.clone().unwrap_or_default();
36 match apply_configmap(client, &namespace, &configmap_name, data).await {
37 Ok(_) => {
38 debug!(
39 "ConfigMap data applied successfully to namespace '{}'",
40 namespace
41 );
42 }
43 Err(e) => {
44 error!(
45 "Failed to apply ConfigMap in namespace '{}': {:?}",
46 namespace, e
47 );
48 return Err(Action::requeue(std::time::Duration::from_secs(300)));
49 }
50 }
51 }
52 Err(e) => {
53 println!(
54 "Failed to get ConfigMap from '{}' namespace: {:?}",
55 &custom_metrics_namespace, e
56 );
57 return Err(Action::requeue(std::time::Duration::from_secs(300)));
58 }
59 }
60
61 Ok(())
62}
63
64pub fn custom_metrics_configmap_settings() -> Option<(String, String)> {
65 let custom_metrics_namespace = match std::env::var("CUSTOM_METRICS_CONFIGMAP_NAMESPACE") {
66 Ok(namespace) => namespace,
67 Err(_) => {
68 debug!("CUSTOM_METRICS_CONFIGMAP_NAMESPACE not set, skipping adding custom metrics");
69 return None;
70 }
71 };
72 let custom_metrics_name = match std::env::var("CUSTOM_METRICS_CONFIGMAP_NAME") {
73 Ok(name) => name,
74 Err(_) => {
75 debug!("CUSTOM_METRICS_CONFIGMAP_NAME not set, skipping adding custom metrics");
76 return None;
77 }
78 };
79 Some((custom_metrics_namespace, custom_metrics_name))
80}
81
82pub async fn apply_configmap(
83 client: Client,
84 namespace: &str,
85 cm_name: &str,
86 data: BTreeMap<String, String>,
87) -> Result<(), Error> {
88 let mut labels: BTreeMap<String, String> = BTreeMap::new();
89 labels.insert("cnpg.io/reload".to_owned(), "true".to_owned());
90 let cm_api: Api<ConfigMap> = Api::namespaced(client, namespace);
91 let cm = ConfigMap {
92 metadata: ObjectMeta {
93 name: Some(cm_name.to_string()),
94 labels: Some(labels),
95 ..Default::default()
96 },
97 data: Some(data),
98 ..Default::default()
99 };
100
101 let patch_params = PatchParams::apply("cntrlr");
102 let patch = Patch::Apply(&cm);
103
104 match cm_api.patch(cm_name, &patch_params, &patch).await {
105 Ok(o) => {
106 debug!("Set configmap: {}", o.metadata.name.unwrap());
107 }
108 Err(e) => {
109 error!("Failed to set configmap: {}", e);
110 }
111 };
112 Ok(())
113}