From 7282c547a59e2941c340bd9c88e256aae6f2bac3 Mon Sep 17 00:00:00 2001 From: Hatter Jiang Date: Sat, 30 Nov 2019 00:31:37 +0800 Subject: [PATCH] config_util.rs --- Cargo.toml | 2 + src/config_util.rs | 199 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 201 insertions(+) diff --git a/Cargo.toml b/Cargo.toml index ee0e860..7e32ff1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,7 +7,9 @@ edition = "2018" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] +dirs = "2.0.1" argparse = "0.2.2" +json = "0.11.14" rust-crypto = "0.2.36" indicatif = "0.13.0" urlencoding = "1.0.0" diff --git a/src/config_util.rs b/src/config_util.rs index c52ef04..ca432ec 100644 --- a/src/config_util.rs +++ b/src/config_util.rs @@ -1,4 +1,203 @@ +use std::{ + fs, + path::Path, +}; +use rust_util::{ + XResult, + new_box_ioerror, + util_msg::*, +}; pub const ETC_OSS_BACKUPD_CONFIG: &str = "/etc/oss-backupd/config.json"; pub const OSS_BACKUPD_CONFIG: &str = "oss-backupd-config.json"; pub const DOT_OSS_BACKUPD_CONFIG: &str = ".oss-backupd-config.json"; + +/* +{ + "oss_config": { + "endpoint": "", + "access_key_id": "", + "access_key_secret": "", + "bucket": "", + "path": "" + }, + encrypt_pubkey_file: "", + "items": [ + { + "oss_config": null, + "target": "", + "encrypt_pubkey_file": "" + } + ] +} +*/ + +pub struct OSSConfig { + pub endpoint: Option, + pub access_key_id: Option, + pub access_key_secret: Option, + pub bucket: Option, + pub path: Option, +} + +pub struct OSSBackupdConfigItem { + pub target: Option, + pub oss_config: Option, + pub encrypt_pubkey_file: Option, +} + +pub struct OSSBackupdConfig { + pub oss_config: Option, + pub items: Vec, +} + +pub fn parse_config(config_json: &json::JsonValue) -> OSSBackupdConfig { + let root_oss_config_object = parse_sub_oss_config(config_json); + let encrypt_pubkey_file = get_string_value(config_json, "encrypt_pubkey_file"); + let items = &config_json["items"]; + let mut items_objects: Vec = vec![]; + if items.is_array() { + for i in 0..items.len() { + items_objects.push(parse_oss_backupd_config_item(&items[i], &root_oss_config_object, &encrypt_pubkey_file)); + } + } + + OSSBackupdConfig { + oss_config: root_oss_config_object, + items: items_objects, + } +} + +pub fn parse_oss_backupd_config_item(item: &json::JsonValue, root_oss_config_object: &Option, root_encrypt_pubkey_file: &Option) -> OSSBackupdConfigItem { + let target = get_string_value(item, "target"); + let mut encrypt_pubkey_file = get_string_value(item, "encrypt_pubkey_file"); + let mut oss_config = parse_sub_oss_config(item); + if oss_config.is_some() && root_oss_config_object.is_some() { + let mut oc = oss_config.unwrap(); + let root_oc = root_oss_config_object.as_ref().unwrap(); + + if oc.endpoint.is_none() && root_oc.endpoint.is_some() { + oc.endpoint = root_oc.endpoint.clone() + } + if oc.access_key_id.is_none() && root_oc.access_key_id.is_some() { + oc.access_key_id = root_oc.access_key_id.clone() + } + if oc.access_key_secret.is_none() && root_oc.access_key_secret.is_some() { + oc.access_key_secret = root_oc.access_key_secret.clone(); + } + if oc.bucket.is_none() && root_oc.bucket.is_some() { + oc.bucket = root_oc.bucket.clone(); + } + if oc.path.is_none() && root_oc.path.is_some() { + oc.path = root_oc.path.clone(); + } + oss_config = Some(oc); + } + + if encrypt_pubkey_file.is_none() && root_encrypt_pubkey_file.is_some() { + encrypt_pubkey_file = root_encrypt_pubkey_file.clone(); + } + + OSSBackupdConfigItem { + target: target, + oss_config: oss_config, + encrypt_pubkey_file: encrypt_pubkey_file, + } +} + +pub fn parse_sub_oss_config(json: &json::JsonValue) -> Option { + let root_oss_config = &json["oss_config"]; + let root_oss_config_object: Option = match root_oss_config.is_null() { + true => None, + false => Some(parse_oss_config(root_oss_config)), + }; + root_oss_config_object +} + +pub fn parse_oss_config(oss_config: &json::JsonValue) -> OSSConfig { + OSSConfig { + endpoint: get_string_value(oss_config, "endpoint"), + access_key_id: get_string_value(oss_config, "access_key_id"), + access_key_secret: get_string_value(oss_config, "access_key_secret"), + bucket: get_string_value(oss_config, "bucket"), + path: get_string_value(oss_config, "path"), + } +} + +pub fn get_string_value(json: &json::JsonValue, key: &str) -> Option { + let value = &json[key]; + match value.is_string() { + true => Some(value.as_str().unwrap().to_string()), + false => None, + } +} + +pub fn get_config_json() -> Option { + let config_content = get_config_content()?; + match json::parse(&config_content) { + Err(e) => { + print_message(MessageType::ERROR, &format!("Parse config json failed: {}", e)); + None + }, + Ok(o) => Some(o), + } +} + +pub fn get_config_content() -> Option { + let oss_backupd_config_path = Path::new(OSS_BACKUPD_CONFIG); + if oss_backupd_config_path.exists() { + match fs::read_to_string(oss_backupd_config_path) { + Err(e) => { + print_message(MessageType::ERROR, &format!("Read config file {} error: {}", OSS_BACKUPD_CONFIG, e)); + return None; + }, + Ok(o) => return Some(o), + }; + } + let home_dot_oss_backupd_config = & match get_user_home_dir(DOT_OSS_BACKUPD_CONFIG) { + Err(e) => { + print_message(MessageType::WARN, &format!("Get user home error: {}", e)); + String::new() + }, + Ok(o) => o, + }; + if home_dot_oss_backupd_config != "" { + let home_dot_oss_backupd_config_path = Path::new(home_dot_oss_backupd_config); + if home_dot_oss_backupd_config_path.exists() { + match fs::read_to_string(home_dot_oss_backupd_config_path) { + Err(e) => { + print_message(MessageType::ERROR, &format!("Read config file {} error: {}", home_dot_oss_backupd_config, e)); + return None; + }, + Ok(o) => return Some(o), + }; + } + } + let etc_oss_backupd_config_path = Path::new(ETC_OSS_BACKUPD_CONFIG); + if etc_oss_backupd_config_path.exists() { + match fs::read_to_string(etc_oss_backupd_config_path) { + Err(e) => { + print_message(MessageType::ERROR, &format!("Read config file {} error: {}", ETC_OSS_BACKUPD_CONFIG, e)); + return None; + }, + Ok(o) => return Some(o), + }; + } + + print_message(MessageType::ERROR, "Cannot find config file"); + None +} + +pub fn get_user_home() -> XResult { + match dirs::home_dir() { + None => Err(new_box_ioerror("Home dir not found!")), + Some(home_dir_o) => match home_dir_o.to_str() { + None => Err(new_box_ioerror("Home dir not found!")), + Some(home_dir_str) => Ok(home_dir_str.to_string()), + }, + } + } + + pub fn get_user_home_dir(dir: &str) -> XResult { + Ok(format!("{}/{}", get_user_home()?, dir)) + }