Selaa lähdekoodia

config: merge [mikrotik] from cluster_sources (with the HA endpoint it merges from) — a RouterOS-named extra_entity 404s as raw HA when the section is dropped

Alexander Korolev 1 kuukausi sitten
vanhempi
sitoutus
3f52b0072a
2 muutettua tiedostoa jossa 57 lisäystä ja 0 poistoa
  1. 16 0
      src/config.rs
  2. 41 0
      src/config/mikrotik_tests.rs

+ 16 - 0
src/config.rs

@@ -124,6 +124,11 @@ pub struct ClusterSource {
     /// when the main config has none.
     #[serde(default)]
     pub home_assistant: Option<HomeAssistantConfig>,
+    /// RouterOS devices for `[mikrotik]`-named `extra_entities`; merged per
+    /// device by name (main-config entries win). Without this the name falls
+    /// through to a raw HA lookup and 404s on every probe tick.
+    #[serde(default)]
+    pub mikrotik: Option<MikrotikConfig>,
 }
 
 /// Merge each `Config.cluster_sources` file into `config`: extra clusters
@@ -146,6 +151,17 @@ pub async fn merge_cluster_sources(config: &mut Config) -> Result<()> {
         if config.home_assistant.is_none() {
             config.home_assistant = src.home_assistant.clone();
         }
+        match (&mut config.mikrotik, src.mikrotik) {
+            (None, Some(m)) => config.mikrotik = Some(m),
+            (Some(main_m), Some(src_m)) => {
+                for d in src_m.devices {
+                    if !main_m.devices.iter().any(|x| x.name == d.name) {
+                        main_m.devices.push(d);
+                    }
+                }
+            }
+            _ => {}
+        }
         for c in src.clusters {
             if !config.clusters.iter().any(|x| x.name == c.name) {
                 config.clusters.push(c);

+ 41 - 0
src/config/mikrotik_tests.rs

@@ -40,3 +40,44 @@ fn test_config_mikrotik_absent() {
     let c: Config = toml::from_str("ssh_user = \"a\"\n").unwrap();
     assert!(c.mikrotik.is_none());
 }
+
+#[tokio::test]
+async fn test_merge_cluster_sources_merges_mikrotik() {
+    use super::Config;
+    let dir = std::env::temp_dir().join(format!("sm121-csrc-mk-{}", std::process::id()));
+    std::fs::create_dir_all(&dir).unwrap();
+    let src_path = dir.join("clusters-mk.toml");
+    std::fs::write(
+        &src_path,
+        r#"
+[[clusters]]
+name = "c1"
+nodes = [{ name = "n0", ssh_ip = "10.9.0.1", rank = 0 }]
+
+[home_assistant]
+url = "http://ha.lan:8123"
+token = "sufficiently-long-test-token"
+shutdown_delay_seconds = 30
+
+[mikrotik]
+[[mikrotik.devices]]
+name = "SW2-MUC"
+address = "192.168.88.39"
+username = "sm121"
+password = "secret"
+on_entity = "switch.sw6_mt"
+"#,
+    )
+    .unwrap();
+    // Main config without [mikrotik] (the global-config case): the HA
+    // endpoint and the RouterOS devices must both arrive from the source,
+    // or the device name 404s as a raw HA entity on every probe tick.
+    let mut cfg: Config =
+        toml::from_str("ssh_user = \"a\"\ncluster_sources = [\"/nonexistent\"]\n").unwrap();
+    cfg.cluster_sources = vec![src_path.to_string_lossy().into_owned()];
+    super::merge_cluster_sources(&mut cfg).await.unwrap();
+    assert!(cfg.home_assistant.is_some(), "HA merged from source");
+    let mk = cfg.mikrotik.as_ref().expect("mikrotik merged from source");
+    assert_eq!(mk.devices[0].name, "SW2-MUC");
+    assert_eq!(mk.devices[0].on_entity.as_deref(), Some("switch.sw6_mt"));
+}