a way better config merge system
This commit is contained in:
parent
8d4d2d4264
commit
e6e646b888
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "trifid-api"
|
||||
version = "0.1.1"
|
||||
version = "0.1.2"
|
||||
edition = "2021"
|
||||
description = "Pure-rust Defined Networking compatible management server"
|
||||
license = "GPL-3.0-or-later"
|
||||
|
|
|
@ -197,63 +197,31 @@ pub async fn generate_config(
|
|||
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 {
|
||||
let key_split = k.split('.').collect::<Vec<&str>>();
|
||||
for (key, kv_value) in &info.config_overrides {
|
||||
// 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] {
|
||||
if !value.contains_key(ks_k) {
|
||||
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();
|
||||
for key_iter in &key_split[..key_split.len()-1] {
|
||||
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(key_split[key_split.len()-1].to_string()), serde_yaml::from_str(v)?);
|
||||
current_val.as_mapping_mut().unwrap().insert(Value::String(key_split[key_split.len()-1].to_string()), serde_yaml::from_str(kv_value)?);
|
||||
}
|
||||
|
||||
let overrides_value = Value::Mapping(val);
|
||||
let config_str_merged = serde_yaml::to_string(&value)?;
|
||||
|
||||
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)?;
|
||||
let nebula_config = serde_yaml::from_str(&config_str_merged)?;
|
||||
|
||||
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>(
|
||||
db: &'a Data<AppState>,
|
||||
host: &'a str,
|
||||
|
|
Loading…
Reference in New Issue