Skip to content

Commit

Permalink
Change update/delete directives to target-state based override dire…
Browse files Browse the repository at this point in the history
…ctive

Signed-off-by: Christina Ying Wang <[email protected]>
  • Loading branch information
cywang117 committed Sep 4, 2023
1 parent 861cd08 commit 206117c
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 52 deletions.
48 changes: 36 additions & 12 deletions src/migrate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use crate::config_json::ConfigMap;
use crate::remote::ConfigMigrationInstructions;
use crate::schema::OsConfigSchema;
use anyhow::Result;
use std::collections::HashMap;

pub fn generate_config_json_migration(
schema: &OsConfigSchema,
Expand All @@ -18,31 +19,52 @@ pub fn generate_config_json_migration(

let mut new_config = config_json.clone();

handle_update_directives(schema, migration_config, config_json, &mut new_config);
let (to_update, to_delete) = separate_migration_directives(migration_config);

handle_delete_directives(schema, migration_config, config_json, &mut new_config);
handle_update_directives(schema, to_update, &to_delete, config_json, &mut new_config);

handle_delete_directives(schema, &to_delete, config_json, &mut new_config);

Ok(new_config)
}

// Separate the migration_config.overrides directives into update
// or delete directives. If a value is null, it is considered a delete directive.
fn separate_migration_directives(
migration_config: &ConfigMigrationInstructions,
) -> (HashMap<String, serde_json::Value>, Vec<String>) {
let mut to_update = migration_config.overrides.clone();
let mut to_delete = Vec::new();

for (key, value) in migration_config.overrides.iter() {
if value.is_null() {
to_update.remove(key);
to_delete.push(key.to_string());
}
}

(to_update, to_delete)
}

fn handle_update_directives(
schema: &OsConfigSchema,
migration_config: &ConfigMigrationInstructions,
to_update: HashMap<String, serde_json::Value>,
to_delete: &Vec<String>,
config_json: &ConfigMap,
new_config: &mut ConfigMap,
) {
for key in migration_config.update.keys() {
for key in to_update.keys() {
if !schema.config.whitelist.contains(key) {
debug!("Key `{}` not in whitelist, skipping", key);
continue;
}

// If also deleting, delete takes precedence
if migration_config.delete.contains(key) {
if to_delete.contains(key) {
continue;
}

if let Some(future) = migration_config.update.get(key) {
if let Some(future) = to_update.get(key) {
if !config_json.contains_key(key) {
info!("Key `{}` not found, will insert", key);
new_config.insert(key.to_string(), future.clone());
Expand All @@ -66,11 +88,11 @@ fn handle_update_directives(

fn handle_delete_directives(
schema: &OsConfigSchema,
migration_config: &ConfigMigrationInstructions,
to_delete: &Vec<String>,
config_json: &ConfigMap,
new_config: &mut ConfigMap,
) {
for key in migration_config.delete.iter() {
for key in to_delete.iter() {
if !schema.config.whitelist.contains(key) {
debug!("Key `{}` not in whitelist, skipping", key);
continue;
Expand Down Expand Up @@ -123,16 +145,18 @@ mod tests {
let configuration = unindent::unindent(
r#"
{
"update": {
"overrides": {
"deadbeef": 2,
"deadca1f": "3",
"deadca2f": false,
"deadca3f": "string0",
"deadca4f": "new_field",
"not_on_whitelist1": "not_on_whitelist",
"on_both_lists": "on_both_lists2"
},
"delete": ["deadca5f", "not_on_whitelist2", "on_both_lists"]
"on_both_lists": "on_both_lists2",
"deadca5f": null,
"not_on_whitelist2": null,
"on_both_lists": null
}
}
"#,
);
Expand Down
19 changes: 8 additions & 11 deletions src/remote.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,7 @@ pub struct RemoteConfiguration {

#[derive(Debug, Serialize, Deserialize, PartialEq)]
pub struct ConfigMigrationInstructions {
pub update: HashMap<String, serde_json::Value>,
pub delete: Vec<String>,
pub overrides: HashMap<String, serde_json::Value>,
}

impl RemoteConfiguration {
Expand Down Expand Up @@ -158,12 +157,10 @@ mod tests {
}
},
"config": {
"update": {
"logsEndpoint": "https://logs.balenadev.io"
},
"delete": [
"pubnubSubscribeKey"
]
"overrides": {
"logsEndpoint": "https://logs.balenadev.io",
"pubnubSubscribeKey": null
}
}
}"#;

Expand All @@ -184,10 +181,10 @@ mod tests {
}
},
config: ConfigMigrationInstructions {
update: hashmap! {
"logsEndpoint".into() => "https://logs.balenadev.io".into()
overrides: hashmap! {
"logsEndpoint".into() => "https://logs.balenadev.io".into(),
"pubnubSubscribeKey".into() => serde_json::Value::Null
},
delete: vec!["pubnubSubscribeKey".into()],
},
};

Expand Down
49 changes: 20 additions & 29 deletions tests/integration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,8 +102,7 @@ fn join() {
}
},
"config": {
"update": {},
"delete": []
"overrides": {}
}
}
"#,
Expand Down Expand Up @@ -281,8 +280,7 @@ fn join_flasher() {
}
},
"config": {
"update": {},
"delete": []
"overrides": {}
}
}
"#,
Expand Down Expand Up @@ -418,8 +416,7 @@ fn join_with_root_certificate() {
"services": {
},
"config": {
"update": {},
"delete": []
"overrides": {}
}
}
"#,
Expand Down Expand Up @@ -643,8 +640,7 @@ fn reconfigure() {
"services": {
},
"config": {
"update": {},
"delete": []
"overrides": {}
}
}
"#,
Expand Down Expand Up @@ -792,8 +788,7 @@ fn reconfigure_stored() {
"services": {
},
"config": {
"update": {},
"delete": []
"overrides": {}
}
}
"#,
Expand Down Expand Up @@ -996,8 +991,7 @@ fn update() {
}
},
"config": {
"update": {},
"delete": []
"overrides": {}
}
}
"#,
Expand Down Expand Up @@ -1163,8 +1157,7 @@ fn update_no_config_changes() {
}
},
"config": {
"update": {},
"delete": []
"overrides": {}
}
}
"#,
Expand Down Expand Up @@ -1269,8 +1262,7 @@ fn update_with_root_certificate() {
"services": {
},
"config": {
"update": {},
"delete": []
"overrides": {}
}
}
"#,
Expand Down Expand Up @@ -1335,8 +1327,7 @@ fn update_unmanaged() {
"services": {
},
"config": {
"update": {},
"delete": []
"overrides": {}
}
}
"#,
Expand Down Expand Up @@ -1436,8 +1427,7 @@ fn leave() {
}
},
"config": {
"update": {},
"delete": []
"overrides": {}
}
}
"#,
Expand Down Expand Up @@ -1536,8 +1526,7 @@ fn leave_unmanaged() {
"services": {
},
"config": {
"update": {},
"delete": []
"overrides": {}
}
}
"#,
Expand Down Expand Up @@ -1905,25 +1894,27 @@ fn migrate_config_json() {
// - deadbeef: value changed, should update (stringified u64)
// - vpnEndpoint: on whitelist & in update, should delete and not update
// Delete:
// - apiKey: not on whitelist, should skip
// - mixpanelToken: on whitelist, should delete
// - vpnEndpoint: on whitelist & in update, should delete and not update
// - apiKey: not on whitelist, is null, should skip
// - mixpanelToken: on whitelist, is null, should delete
// - vpnEndpoint: on whitelist, is null AND has value, delete takes precedence
let configuration = unindent::unindent(
r#"
{
"services": {},
"config": {
"update": {
"overrides": {
"apiEndpoint": "http://api.balenadev.io",
"logsEndpoint": "https://logs.balenadev.io",
"registryEndpoint": "registry2.balenadev.io",
"deltaEndpoint": "https://delta2.balenadev.io",
"applicationId": 1234568,
"persistentLogging": true,
"deadbeef": "1234567890",
"vpnEndpoint": "vpn2.balenadev.io"
},
"delete": ["apiKey", "mixpanelToken", "vpnEndpoint"]
"vpnEndpoint": "vpn2.balenadev.io",
"apiKey": null,
"mixpanelToken": null,
"vpnEndpoint": null
}
}
}
"#,
Expand Down

0 comments on commit 206117c

Please sign in to comment.