a way better config merge system
This commit is contained in:
parent
8d4d2d4264
commit
e6e646b888
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "trifid-api"
|
name = "trifid-api"
|
||||||
version = "0.1.1"
|
version = "0.1.2"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
description = "Pure-rust Defined Networking compatible management server"
|
description = "Pure-rust Defined Networking compatible management server"
|
||||||
license = "GPL-3.0-or-later"
|
license = "GPL-3.0-or-later"
|
||||||
|
|
|
@ -197,63 +197,31 @@ pub async fn generate_config(
|
||||||
local_range: None,
|
local_range: None,
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut val = Mapping::new();
|
// Merge with config overrides and re-parse
|
||||||
|
let config_str = serde_yaml::to_string(&nebula_config)?;
|
||||||
|
let mut value: serde_yaml::Value = serde_yaml::from_str(&config_str)?;
|
||||||
|
|
||||||
for (k, v) in &info.config_overrides {
|
for (key, kv_value) in &info.config_overrides {
|
||||||
let key_split = k.split('.').collect::<Vec<&str>>();
|
// split up the key
|
||||||
|
// a.b.c.d = ['a']['b']['c']['d'] = value
|
||||||
|
let key_split = key.split('.').collect::<Vec<_>>();
|
||||||
|
|
||||||
let mut value = &mut val;
|
let mut current_val = &mut value;
|
||||||
|
|
||||||
for ks_k in &key_split[..key_split.len()-1] {
|
for key_iter in &key_split[..key_split.len()-1] {
|
||||||
if !value.contains_key(ks_k) {
|
current_val = current_val.as_mapping_mut().unwrap().entry(Value::String(key_iter.to_string())).or_insert(Value::Mapping(Mapping::new()));
|
||||||
value.insert(Value::String(ks_k.to_string()), Value::Mapping(Mapping::new()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
value = value.get_mut(ks_k).ok_or("Invalid key-value pair")?.as_mapping_mut().unwrap();
|
current_val.as_mapping_mut().unwrap().insert(Value::String(key_split[key_split.len()-1].to_string()), serde_yaml::from_str(kv_value)?);
|
||||||
}
|
}
|
||||||
|
|
||||||
value.insert(Value::String(key_split[key_split.len()-1].to_string()), serde_yaml::from_str(v)?);
|
let config_str_merged = serde_yaml::to_string(&value)?;
|
||||||
}
|
|
||||||
|
|
||||||
let overrides_value = Value::Mapping(val);
|
let nebula_config = serde_yaml::from_str(&config_str_merged)?;
|
||||||
|
|
||||||
debug!("{:?}", overrides_value);
|
|
||||||
|
|
||||||
let mut value = serde_yaml::to_value(nebula_config)?;
|
|
||||||
|
|
||||||
debug!("{:?}", value);
|
|
||||||
|
|
||||||
merge_yaml(&mut value, overrides_value);
|
|
||||||
|
|
||||||
debug!("{:?}", value);
|
|
||||||
|
|
||||||
let nebula_config = serde_yaml::from_value(value)?;
|
|
||||||
|
|
||||||
Ok((nebula_config, cert))
|
Ok((nebula_config, cert))
|
||||||
}
|
}
|
||||||
|
|
||||||
// This cursed abomination credit https://stackoverflow.com/questions/67727239/how-to-combine-including-nested-array-values-two-serde-yamlvalue-objects
|
|
||||||
fn merge_yaml(a: &mut serde_yaml::Value, b: serde_yaml::Value) {
|
|
||||||
match (a, b) {
|
|
||||||
(a @ &mut serde_yaml::Value::Mapping(_), serde_yaml::Value::Mapping(b)) => {
|
|
||||||
let a = a.as_mapping_mut().unwrap();
|
|
||||||
for (k, v) in b {
|
|
||||||
if v.is_sequence() && a.contains_key(&k) && a[&k].is_sequence() {
|
|
||||||
let mut _b = a.get(&k).unwrap().as_sequence().unwrap().to_owned();
|
|
||||||
_b.append(&mut v.as_sequence().unwrap().to_owned());
|
|
||||||
a[&k] = serde_yaml::Value::from(_b);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if !a.contains_key(&k) {a.insert(k.to_owned(), v.to_owned());}
|
|
||||||
else { merge_yaml(&mut a[&k], v); }
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
(a, b) => *a = b,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn collect_info<'a>(
|
pub async fn collect_info<'a>(
|
||||||
db: &'a Data<AppState>,
|
db: &'a Data<AppState>,
|
||||||
host: &'a str,
|
host: &'a str,
|
||||||
|
|
Loading…
Reference in New Issue