updates
This commit is contained in:
33
Cargo.lock
generated
33
Cargo.lock
generated
@@ -1898,6 +1898,8 @@ dependencies = [
|
|||||||
"reqwest",
|
"reqwest",
|
||||||
"rust_util",
|
"rust_util",
|
||||||
"sequoia-openpgp",
|
"sequoia-openpgp",
|
||||||
|
"serde",
|
||||||
|
"serde_json",
|
||||||
"sha-1",
|
"sha-1",
|
||||||
"tar",
|
"tar",
|
||||||
"tiny-encrypt",
|
"tiny-encrypt",
|
||||||
@@ -2666,18 +2668,28 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde"
|
name = "serde"
|
||||||
version = "1.0.216"
|
version = "1.0.228"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "0b9781016e935a97e8beecf0c933758c97a5520d32930e460142b4cd80c6338e"
|
checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e"
|
||||||
|
dependencies = [
|
||||||
|
"serde_core",
|
||||||
|
"serde_derive",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde_core"
|
||||||
|
version = "1.0.228"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"serde_derive",
|
"serde_derive",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde_derive"
|
name = "serde_derive"
|
||||||
version = "1.0.216"
|
version = "1.0.228"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "46f859dbbf73865c6627ed570e78961cd3ac92407a2d117204c49232485da55e"
|
checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
@@ -2686,14 +2698,15 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde_json"
|
name = "serde_json"
|
||||||
version = "1.0.133"
|
version = "1.0.149"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c7fceb2473b9166b2294ef05efcb65a3db80803f0b03ef86a5fc88a2b85ee377"
|
checksum = "83fc039473c5595ace860d8c4fafa220ff474b3fc6bfdb4293327f1a37e94d86"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"itoa",
|
"itoa",
|
||||||
"memchr",
|
"memchr",
|
||||||
"ryu",
|
|
||||||
"serde",
|
"serde",
|
||||||
|
"serde_core",
|
||||||
|
"zmij",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -3873,6 +3886,12 @@ dependencies = [
|
|||||||
"zstd",
|
"zstd",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "zmij"
|
||||||
|
version = "1.0.21"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "zopfli"
|
name = "zopfli"
|
||||||
version = "0.8.1"
|
version = "0.8.1"
|
||||||
|
|||||||
@@ -29,3 +29,5 @@ tar = "0.4"
|
|||||||
flate2 = "1.0"
|
flate2 = "1.0"
|
||||||
rust_util = "0.6"
|
rust_util = "0.6"
|
||||||
tiny-encrypt = { version = "1.8", default-features = false }
|
tiny-encrypt = { version = "1.8", default-features = false }
|
||||||
|
serde = { version = "1.0.228", features = ["serde_derive"] }
|
||||||
|
serde_json = "1.0.149"
|
||||||
|
|||||||
15
README.md
15
README.md
@@ -68,3 +68,18 @@ cd nettle
|
|||||||
make
|
make
|
||||||
sudo make install
|
sudo make install
|
||||||
```
|
```
|
||||||
|
|
||||||
|
<br>
|
||||||
|
|
||||||
|
Use STS token resolver:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"oss_config": {
|
||||||
|
"endpoint": "_endpoint",
|
||||||
|
"sts_token_resolver": ["assume-role.ts", "ROLE_ARN"],
|
||||||
|
"bucket": "_bucket",
|
||||||
|
"path": "_path"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
```
|
||||||
|
|||||||
@@ -1,10 +1,9 @@
|
|||||||
use chrono::Utc;
|
use chrono::Utc;
|
||||||
use json::JsonValue;
|
use json::JsonValue;
|
||||||
use rust_util::{new_box_ioerror, XResult};
|
use rust_util::{new_box_ioerror, util_cmd, XResult};
|
||||||
use std::{
|
use serde::Deserialize;
|
||||||
fs,
|
use std::process::Command;
|
||||||
path::Path,
|
use std::{fs, path::Path};
|
||||||
};
|
|
||||||
|
|
||||||
pub const NAME: &str = env!("CARGO_PKG_NAME");
|
pub const NAME: &str = env!("CARGO_PKG_NAME");
|
||||||
pub const VERSION: &str = env!("CARGO_PKG_VERSION");
|
pub const VERSION: &str = env!("CARGO_PKG_VERSION");
|
||||||
@@ -37,11 +36,22 @@ const ETC_OSS_BACKUPD_CONFIG: &str = "/etc/oss-backupd/config.json";
|
|||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize)]
|
||||||
|
pub struct StsResolverResponse {
|
||||||
|
pub mode: String,
|
||||||
|
pub access_key_id: String,
|
||||||
|
pub access_key_secret: String,
|
||||||
|
pub sts_token: String,
|
||||||
|
pub expiration: String,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct OSSConfig {
|
pub struct OSSConfig {
|
||||||
pub endpoint: Option<String>,
|
pub endpoint: Option<String>,
|
||||||
pub access_key_id: Option<String>,
|
pub access_key_id: Option<String>,
|
||||||
pub access_key_secret: Option<String>,
|
pub access_key_secret: Option<String>,
|
||||||
|
pub security_token: Option<String>,
|
||||||
|
pub sts_token_resolver: Option<Vec<String>>,
|
||||||
pub bucket: Option<String>,
|
pub bucket: Option<String>,
|
||||||
pub path: Option<String>,
|
pub path: Option<String>,
|
||||||
}
|
}
|
||||||
@@ -184,6 +194,12 @@ fn parse_oss_backupd_config_item(
|
|||||||
if oc.access_key_secret.is_none() && root_oc.access_key_secret.is_some() {
|
if oc.access_key_secret.is_none() && root_oc.access_key_secret.is_some() {
|
||||||
oc.access_key_secret = root_oc.access_key_secret.clone();
|
oc.access_key_secret = root_oc.access_key_secret.clone();
|
||||||
}
|
}
|
||||||
|
if oc.security_token.is_none() && root_oc.security_token.is_some() {
|
||||||
|
oc.security_token = root_oc.security_token.clone();
|
||||||
|
}
|
||||||
|
if oc.sts_token_resolver.is_none() && root_oc.sts_token_resolver.is_some() {
|
||||||
|
oc.sts_token_resolver = root_oc.sts_token_resolver.clone();
|
||||||
|
}
|
||||||
if oc.bucket.is_none() && root_oc.bucket.is_some() {
|
if oc.bucket.is_none() && root_oc.bucket.is_some() {
|
||||||
oc.bucket = root_oc.bucket.clone();
|
oc.bucket = root_oc.bucket.clone();
|
||||||
}
|
}
|
||||||
@@ -249,13 +265,68 @@ fn parse_sub_oss_config(json: &json::JsonValue) -> Option<OSSConfig> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn parse_oss_config(oss_config: &json::JsonValue) -> OSSConfig {
|
fn parse_oss_config(oss_config: &json::JsonValue) -> OSSConfig {
|
||||||
OSSConfig {
|
let mut oss_config = OSSConfig {
|
||||||
endpoint: get_string_value(oss_config, "endpoint"),
|
endpoint: get_string_value(oss_config, "endpoint"),
|
||||||
access_key_id: get_string_value(oss_config, "access_key_id"),
|
access_key_id: get_string_value(oss_config, "access_key_id"),
|
||||||
access_key_secret: get_string_value(oss_config, "access_key_secret"),
|
access_key_secret: get_string_value(oss_config, "access_key_secret"),
|
||||||
|
security_token: None,
|
||||||
|
sts_token_resolver: get_string_array_value(oss_config, "sts_token_resolver"),
|
||||||
bucket: get_string_value(oss_config, "bucket"),
|
bucket: get_string_value(oss_config, "bucket"),
|
||||||
path: get_string_value(oss_config, "path"),
|
path: get_string_value(oss_config, "path"),
|
||||||
|
};
|
||||||
|
|
||||||
|
if oss_config.sts_token_resolver.is_some()
|
||||||
|
&& oss_config.access_key_id.is_none()
|
||||||
|
&& oss_config.access_key_secret.is_none()
|
||||||
|
{
|
||||||
|
if let Some(sts_token_resolver) = &oss_config.sts_token_resolver {
|
||||||
|
if sts_token_resolver.len() > 0 {
|
||||||
|
let mut cmd = Command::new(&sts_token_resolver[0]);
|
||||||
|
for arg in sts_token_resolver.iter().skip(1) {
|
||||||
|
cmd.arg(arg);
|
||||||
}
|
}
|
||||||
|
match util_cmd::run_command_and_wait(&mut cmd) {
|
||||||
|
Ok(exit_status) => {
|
||||||
|
if exit_status.success() {
|
||||||
|
match cmd.output() {
|
||||||
|
Ok(output) => {
|
||||||
|
match serde_json::from_slice::<StsResolverResponse>(
|
||||||
|
output.stdout.as_slice(),
|
||||||
|
) {
|
||||||
|
Ok(sts_resolver_response) => {
|
||||||
|
oss_config.access_key_id = Some(sts_resolver_response.access_key_id);
|
||||||
|
oss_config.access_key_secret = Some(sts_resolver_response.access_key_secret);
|
||||||
|
oss_config.security_token = Some(sts_resolver_response.sts_token);
|
||||||
|
}
|
||||||
|
Err(err) => {
|
||||||
|
failure!(
|
||||||
|
"Parse {:?} response failed: {}",
|
||||||
|
sts_token_resolver,
|
||||||
|
err
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(err) => {
|
||||||
|
failure!("Execute {:?} failed: {}", sts_token_resolver, err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
failure!(
|
||||||
|
"Execute {:?} exit failed: {}",
|
||||||
|
sts_token_resolver,
|
||||||
|
exit_status
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(err) => {
|
||||||
|
failure!("Execute {:?} failed: {}", sts_token_resolver, err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
oss_config
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_string_value(json: &JsonValue, key: &str) -> Option<String> {
|
fn get_string_value(json: &JsonValue, key: &str) -> Option<String> {
|
||||||
@@ -263,6 +334,20 @@ fn get_string_value(json: &JsonValue, key: &str) -> Option<String> {
|
|||||||
value.as_str().map(|s| s.to_owned())
|
value.as_str().map(|s| s.to_owned())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get_string_array_value(json: &JsonValue, key: &str) -> Option<Vec<String>> {
|
||||||
|
let value = &json[key];
|
||||||
|
if let JsonValue::Array(array) = value {
|
||||||
|
let mut arr = vec![];
|
||||||
|
for value in array {
|
||||||
|
if let Some(s) = value.as_str() {
|
||||||
|
arr.push(s.to_owned());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Some(arr);
|
||||||
|
}
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
fn get_tiny_encrypt_value(json: &JsonValue) -> Option<TinyEncryptConfig> {
|
fn get_tiny_encrypt_value(json: &JsonValue) -> Option<TinyEncryptConfig> {
|
||||||
let tiny_encrypt = &json["tiny_encrypt"];
|
let tiny_encrypt = &json["tiny_encrypt"];
|
||||||
let config = get_string_value(tiny_encrypt, "config");
|
let config = get_string_value(tiny_encrypt, "config");
|
||||||
@@ -324,7 +409,8 @@ fn get_config_content(custom_oss_backupd_config: Option<&str>, verbose: bool) ->
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
let home_dot_oss_backupd_config = &get_user_home_dir(DOT_OSS_BACKUPD_CONFIG).unwrap_or_else(|e| {
|
let home_dot_oss_backupd_config =
|
||||||
|
&get_user_home_dir(DOT_OSS_BACKUPD_CONFIG).unwrap_or_else(|e| {
|
||||||
warning!("Get user home error: {}", e);
|
warning!("Get user home error: {}", e);
|
||||||
String::new()
|
String::new()
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ use std::{
|
|||||||
fs::{ self, File },
|
fs::{ self, File },
|
||||||
};
|
};
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use rust_util::{XResult, util_time::*, util_msg::*};
|
use rust_util::{XResult, util_time::*};
|
||||||
use tiny_encrypt::CmdEncrypt;
|
use tiny_encrypt::CmdEncrypt;
|
||||||
use oss_util::*;
|
use oss_util::*;
|
||||||
use config_util::*;
|
use config_util::*;
|
||||||
|
|||||||
Reference in New Issue
Block a user