mirror of
https://github.com/rustfs/rustfs.git
synced 2026-08-30 08:49:26 +00:00
feat(targets): add AMQP support for notify and audit (#2879)
Co-authored-by: Hyesook Yun <74169420+suk13574@users.noreply.github.com>
This commit is contained in:
@@ -15,14 +15,16 @@
|
||||
use crate::config::{KV, KVS};
|
||||
use rustfs_config::audit::AUDIT_REDIS_DEFAULT_CHANNEL;
|
||||
use rustfs_config::{
|
||||
COMMENT_KEY, DEFAULT_LIMIT, ENABLE_KEY, EVENT_DEFAULT_DIR, EnableState, KAFKA_ACKS, KAFKA_BROKERS, KAFKA_QUEUE_DIR,
|
||||
KAFKA_QUEUE_LIMIT, KAFKA_TLS_CA, KAFKA_TLS_CLIENT_CERT, KAFKA_TLS_CLIENT_KEY, KAFKA_TLS_ENABLE, KAFKA_TOPIC, MQTT_BROKER,
|
||||
MQTT_KEEP_ALIVE_INTERVAL, MQTT_PASSWORD, MQTT_QOS, MQTT_QUEUE_DIR, MQTT_QUEUE_LIMIT, MQTT_RECONNECT_INTERVAL, MQTT_TLS_CA,
|
||||
MQTT_TLS_CLIENT_CERT, MQTT_TLS_CLIENT_KEY, MQTT_TLS_POLICY, MQTT_TLS_TRUST_LEAF_AS_CA, MQTT_TOPIC, MQTT_USERNAME,
|
||||
MQTT_WS_PATH_ALLOWLIST, MYSQL_DSN_STRING, MYSQL_FORMAT, MYSQL_MAX_OPEN_CONNECTIONS, MYSQL_QUEUE_DIR, MYSQL_QUEUE_LIMIT,
|
||||
MYSQL_TABLE, MYSQL_TLS_CA, MYSQL_TLS_CLIENT_CERT, MYSQL_TLS_CLIENT_KEY, NATS_ADDRESS, NATS_CREDENTIALS_FILE, NATS_PASSWORD,
|
||||
NATS_QUEUE_DIR, NATS_QUEUE_LIMIT, NATS_SUBJECT, NATS_TLS_CA, NATS_TLS_CLIENT_CERT, NATS_TLS_CLIENT_KEY, NATS_TLS_REQUIRED,
|
||||
NATS_TOKEN, NATS_USERNAME, POSTGRES_DSN_STRING, POSTGRES_FORMAT, POSTGRES_QUEUE_DIR, POSTGRES_QUEUE_LIMIT, POSTGRES_TABLE,
|
||||
AMQP_EXCHANGE, AMQP_MANDATORY, AMQP_PASSWORD, AMQP_PERSISTENT, AMQP_QUEUE_DIR, AMQP_QUEUE_LIMIT, AMQP_ROUTING_KEY,
|
||||
AMQP_TLS_CA, AMQP_TLS_CLIENT_CERT, AMQP_TLS_CLIENT_KEY, AMQP_URL, AMQP_USERNAME, COMMENT_KEY, DEFAULT_LIMIT, ENABLE_KEY,
|
||||
EVENT_DEFAULT_DIR, EnableState, KAFKA_ACKS, KAFKA_BROKERS, KAFKA_QUEUE_DIR, KAFKA_QUEUE_LIMIT, KAFKA_TLS_CA,
|
||||
KAFKA_TLS_CLIENT_CERT, KAFKA_TLS_CLIENT_KEY, KAFKA_TLS_ENABLE, KAFKA_TOPIC, MQTT_BROKER, MQTT_KEEP_ALIVE_INTERVAL,
|
||||
MQTT_PASSWORD, MQTT_QOS, MQTT_QUEUE_DIR, MQTT_QUEUE_LIMIT, MQTT_RECONNECT_INTERVAL, MQTT_TLS_CA, MQTT_TLS_CLIENT_CERT,
|
||||
MQTT_TLS_CLIENT_KEY, MQTT_TLS_POLICY, MQTT_TLS_TRUST_LEAF_AS_CA, MQTT_TOPIC, MQTT_USERNAME, MQTT_WS_PATH_ALLOWLIST,
|
||||
MYSQL_DSN_STRING, MYSQL_FORMAT, MYSQL_MAX_OPEN_CONNECTIONS, MYSQL_QUEUE_DIR, MYSQL_QUEUE_LIMIT, MYSQL_TABLE, MYSQL_TLS_CA,
|
||||
MYSQL_TLS_CLIENT_CERT, MYSQL_TLS_CLIENT_KEY, NATS_ADDRESS, NATS_CREDENTIALS_FILE, NATS_PASSWORD, NATS_QUEUE_DIR,
|
||||
NATS_QUEUE_LIMIT, NATS_SUBJECT, NATS_TLS_CA, NATS_TLS_CLIENT_CERT, NATS_TLS_CLIENT_KEY, NATS_TLS_REQUIRED, NATS_TOKEN,
|
||||
NATS_USERNAME, POSTGRES_DSN_STRING, POSTGRES_FORMAT, POSTGRES_QUEUE_DIR, POSTGRES_QUEUE_LIMIT, POSTGRES_TABLE,
|
||||
POSTGRES_TLS_CA, POSTGRES_TLS_CLIENT_CERT, POSTGRES_TLS_CLIENT_KEY, POSTGRES_TLS_REQUIRED, PULSAR_AUTH_TOKEN, PULSAR_BROKER,
|
||||
PULSAR_PASSWORD, PULSAR_QUEUE_DIR, PULSAR_QUEUE_LIMIT, PULSAR_TLS_ALLOW_INSECURE, PULSAR_TLS_CA,
|
||||
PULSAR_TLS_HOSTNAME_VERIFICATION, PULSAR_TOPIC, PULSAR_USERNAME, REDIS_CHANNEL, REDIS_CONNECTION_TIMEOUT,
|
||||
@@ -206,6 +208,81 @@ pub static DEFAULT_AUDIT_MQTT_KVS: LazyLock<KVS> = LazyLock::new(|| {
|
||||
])
|
||||
});
|
||||
|
||||
pub static DEFAULT_AUDIT_AMQP_KVS: LazyLock<KVS> = LazyLock::new(|| {
|
||||
KVS(vec![
|
||||
KV {
|
||||
key: ENABLE_KEY.to_owned(),
|
||||
value: EnableState::Off.to_string(),
|
||||
hidden_if_empty: false,
|
||||
},
|
||||
KV {
|
||||
key: AMQP_URL.to_owned(),
|
||||
value: "".to_owned(),
|
||||
hidden_if_empty: false,
|
||||
},
|
||||
KV {
|
||||
key: AMQP_EXCHANGE.to_owned(),
|
||||
value: "".to_owned(),
|
||||
hidden_if_empty: false,
|
||||
},
|
||||
KV {
|
||||
key: AMQP_ROUTING_KEY.to_owned(),
|
||||
value: "".to_owned(),
|
||||
hidden_if_empty: false,
|
||||
},
|
||||
KV {
|
||||
key: AMQP_MANDATORY.to_owned(),
|
||||
value: EnableState::Off.to_string(),
|
||||
hidden_if_empty: false,
|
||||
},
|
||||
KV {
|
||||
key: AMQP_PERSISTENT.to_owned(),
|
||||
value: EnableState::On.to_string(),
|
||||
hidden_if_empty: false,
|
||||
},
|
||||
KV {
|
||||
key: AMQP_USERNAME.to_owned(),
|
||||
value: "".to_owned(),
|
||||
hidden_if_empty: false,
|
||||
},
|
||||
KV {
|
||||
key: AMQP_PASSWORD.to_owned(),
|
||||
value: "".to_owned(),
|
||||
hidden_if_empty: true,
|
||||
},
|
||||
KV {
|
||||
key: AMQP_TLS_CA.to_owned(),
|
||||
value: "".to_owned(),
|
||||
hidden_if_empty: true,
|
||||
},
|
||||
KV {
|
||||
key: AMQP_TLS_CLIENT_CERT.to_owned(),
|
||||
value: "".to_owned(),
|
||||
hidden_if_empty: true,
|
||||
},
|
||||
KV {
|
||||
key: AMQP_TLS_CLIENT_KEY.to_owned(),
|
||||
value: "".to_owned(),
|
||||
hidden_if_empty: true,
|
||||
},
|
||||
KV {
|
||||
key: AMQP_QUEUE_DIR.to_owned(),
|
||||
value: EVENT_DEFAULT_DIR.to_owned(),
|
||||
hidden_if_empty: false,
|
||||
},
|
||||
KV {
|
||||
key: AMQP_QUEUE_LIMIT.to_owned(),
|
||||
value: DEFAULT_LIMIT.to_string(),
|
||||
hidden_if_empty: false,
|
||||
},
|
||||
KV {
|
||||
key: COMMENT_KEY.to_owned(),
|
||||
value: "".to_owned(),
|
||||
hidden_if_empty: false,
|
||||
},
|
||||
])
|
||||
});
|
||||
|
||||
pub static DEFAULT_AUDIT_NATS_KVS: LazyLock<KVS> = LazyLock::new(|| {
|
||||
KVS(vec![
|
||||
KV {
|
||||
|
||||
@@ -19,14 +19,15 @@ use crate::global::is_first_cluster_node_local;
|
||||
use crate::store_api::{ObjectInfo, ObjectOptions, PutObjReader, StorageAPI};
|
||||
use http::HeaderMap;
|
||||
use rustfs_config::audit::{
|
||||
AUDIT_KAFKA_KEYS, AUDIT_KAFKA_SUB_SYS, AUDIT_MQTT_KEYS, AUDIT_MQTT_SUB_SYS, AUDIT_MYSQL_KEYS, AUDIT_MYSQL_SUB_SYS,
|
||||
AUDIT_NATS_KEYS, AUDIT_NATS_SUB_SYS, AUDIT_POSTGRES_KEYS, AUDIT_POSTGRES_SUB_SYS, AUDIT_PULSAR_KEYS, AUDIT_PULSAR_SUB_SYS,
|
||||
AUDIT_REDIS_KEYS, AUDIT_REDIS_SUB_SYS, AUDIT_WEBHOOK_KEYS, AUDIT_WEBHOOK_SUB_SYS,
|
||||
AUDIT_AMQP_KEYS, AUDIT_AMQP_SUB_SYS, AUDIT_KAFKA_KEYS, AUDIT_KAFKA_SUB_SYS, AUDIT_MQTT_KEYS, AUDIT_MQTT_SUB_SYS,
|
||||
AUDIT_MYSQL_KEYS, AUDIT_MYSQL_SUB_SYS, AUDIT_NATS_KEYS, AUDIT_NATS_SUB_SYS, AUDIT_POSTGRES_KEYS, AUDIT_POSTGRES_SUB_SYS,
|
||||
AUDIT_PULSAR_KEYS, AUDIT_PULSAR_SUB_SYS, AUDIT_REDIS_KEYS, AUDIT_REDIS_SUB_SYS, AUDIT_WEBHOOK_KEYS, AUDIT_WEBHOOK_SUB_SYS,
|
||||
};
|
||||
use rustfs_config::notify::{
|
||||
NOTIFY_KAFKA_KEYS, NOTIFY_KAFKA_SUB_SYS, NOTIFY_MQTT_KEYS, NOTIFY_MQTT_SUB_SYS, NOTIFY_MYSQL_KEYS, NOTIFY_MYSQL_SUB_SYS,
|
||||
NOTIFY_NATS_KEYS, NOTIFY_NATS_SUB_SYS, NOTIFY_POSTGRES_KEYS, NOTIFY_POSTGRES_SUB_SYS, NOTIFY_PULSAR_KEYS,
|
||||
NOTIFY_PULSAR_SUB_SYS, NOTIFY_REDIS_KEYS, NOTIFY_REDIS_SUB_SYS, NOTIFY_WEBHOOK_KEYS, NOTIFY_WEBHOOK_SUB_SYS,
|
||||
NOTIFY_AMQP_KEYS, NOTIFY_AMQP_SUB_SYS, NOTIFY_KAFKA_KEYS, NOTIFY_KAFKA_SUB_SYS, NOTIFY_MQTT_KEYS, NOTIFY_MQTT_SUB_SYS,
|
||||
NOTIFY_MYSQL_KEYS, NOTIFY_MYSQL_SUB_SYS, NOTIFY_NATS_KEYS, NOTIFY_NATS_SUB_SYS, NOTIFY_POSTGRES_KEYS,
|
||||
NOTIFY_POSTGRES_SUB_SYS, NOTIFY_PULSAR_KEYS, NOTIFY_PULSAR_SUB_SYS, NOTIFY_REDIS_KEYS, NOTIFY_REDIS_SUB_SYS,
|
||||
NOTIFY_WEBHOOK_KEYS, NOTIFY_WEBHOOK_SUB_SYS,
|
||||
};
|
||||
use rustfs_config::oidc::{IDENTITY_OPENID_KEYS, IDENTITY_OPENID_SUB_SYS, OIDC_REDIRECT_URI_DYNAMIC};
|
||||
use rustfs_config::{COMMENT_KEY, DEFAULT_DELIMITER, ENABLE_KEY, EnableState, RUSTFS_REGION};
|
||||
@@ -60,7 +61,7 @@ struct TargetConfigDescriptor {
|
||||
valid_keys: &'static [&'static str],
|
||||
}
|
||||
|
||||
fn notify_target_descriptors() -> [TargetConfigDescriptor; 8] {
|
||||
fn notify_target_descriptors() -> [TargetConfigDescriptor; 9] {
|
||||
[
|
||||
TargetConfigDescriptor {
|
||||
external_key: "webhook",
|
||||
@@ -68,6 +69,12 @@ fn notify_target_descriptors() -> [TargetConfigDescriptor; 8] {
|
||||
default_kvs: ¬ify::DEFAULT_NOTIFY_WEBHOOK_KVS,
|
||||
valid_keys: NOTIFY_WEBHOOK_KEYS,
|
||||
},
|
||||
TargetConfigDescriptor {
|
||||
external_key: "amqp",
|
||||
subsystem_key: NOTIFY_AMQP_SUB_SYS,
|
||||
default_kvs: ¬ify::DEFAULT_NOTIFY_AMQP_KVS,
|
||||
valid_keys: NOTIFY_AMQP_KEYS,
|
||||
},
|
||||
TargetConfigDescriptor {
|
||||
external_key: "kafka",
|
||||
subsystem_key: NOTIFY_KAFKA_SUB_SYS,
|
||||
@@ -113,7 +120,7 @@ fn notify_target_descriptors() -> [TargetConfigDescriptor; 8] {
|
||||
]
|
||||
}
|
||||
|
||||
fn audit_target_descriptors() -> [TargetConfigDescriptor; 8] {
|
||||
fn audit_target_descriptors() -> [TargetConfigDescriptor; 9] {
|
||||
[
|
||||
TargetConfigDescriptor {
|
||||
external_key: "webhook",
|
||||
@@ -121,6 +128,12 @@ fn audit_target_descriptors() -> [TargetConfigDescriptor; 8] {
|
||||
default_kvs: &audit::DEFAULT_AUDIT_WEBHOOK_KVS,
|
||||
valid_keys: AUDIT_WEBHOOK_KEYS,
|
||||
},
|
||||
TargetConfigDescriptor {
|
||||
external_key: "amqp",
|
||||
subsystem_key: AUDIT_AMQP_SUB_SYS,
|
||||
default_kvs: &audit::DEFAULT_AUDIT_AMQP_KVS,
|
||||
valid_keys: AUDIT_AMQP_KEYS,
|
||||
},
|
||||
TargetConfigDescriptor {
|
||||
external_key: "kafka",
|
||||
subsystem_key: AUDIT_KAFKA_SUB_SYS,
|
||||
@@ -717,6 +730,8 @@ fn is_target_bool_key(key: &str) -> bool {
|
||||
matches!(
|
||||
key,
|
||||
ENABLE_KEY
|
||||
| rustfs_config::AMQP_MANDATORY
|
||||
| rustfs_config::AMQP_PERSISTENT
|
||||
| rustfs_config::WEBHOOK_SKIP_TLS_VERIFY
|
||||
| rustfs_config::KAFKA_TLS_ENABLE
|
||||
| rustfs_config::MQTT_TLS_TRUST_LEAF_AS_CA
|
||||
@@ -726,14 +741,31 @@ fn is_target_bool_key(key: &str) -> bool {
|
||||
)
|
||||
}
|
||||
|
||||
fn parse_target_bool_scalar(value: &str) -> Option<bool> {
|
||||
if let Ok(state) = value.parse::<EnableState>() {
|
||||
return Some(state.is_enabled());
|
||||
}
|
||||
if let Ok(boolean) = value.parse::<bool>() {
|
||||
return Some(boolean);
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
fn target_scalar_values_equal(key: &str, lhs: &str, rhs: &str) -> bool {
|
||||
if is_target_bool_key(key)
|
||||
&& let (Some(lhs), Some(rhs)) = (parse_target_bool_scalar(lhs), parse_target_bool_scalar(rhs))
|
||||
{
|
||||
return lhs == rhs;
|
||||
}
|
||||
|
||||
lhs == rhs
|
||||
}
|
||||
|
||||
fn encode_target_scalar_value(key: &str, value: &str) -> Value {
|
||||
if is_target_bool_key(key) {
|
||||
if let Ok(state) = value.parse::<EnableState>() {
|
||||
return Value::Bool(state.is_enabled());
|
||||
}
|
||||
if let Ok(boolean) = value.parse::<bool>() {
|
||||
return Value::Bool(boolean);
|
||||
}
|
||||
if is_target_bool_key(key)
|
||||
&& let Some(boolean) = parse_target_bool_scalar(value)
|
||||
{
|
||||
return Value::Bool(boolean);
|
||||
}
|
||||
|
||||
Value::String(value.to_string())
|
||||
@@ -759,7 +791,7 @@ fn build_target_instance_diff_object(kvs: &KVS, baseline: &KVS, valid_keys: &[&s
|
||||
let baseline_value = baseline.lookup(key).unwrap_or_default();
|
||||
let effective_value = kvs.lookup(key).unwrap_or_else(|| baseline_value.clone());
|
||||
|
||||
if effective_value == baseline_value {
|
||||
if target_scalar_values_equal(key, &effective_value, &baseline_value) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -1169,8 +1201,10 @@ mod tests {
|
||||
ObjectOptions, ObjectToDelete, PartInfo, PutObjReader, StorageAPI, WalkOptions,
|
||||
};
|
||||
use http::HeaderMap;
|
||||
use rustfs_config::audit::{AUDIT_KAFKA_SUB_SYS, AUDIT_MQTT_SUB_SYS, AUDIT_WEBHOOK_SUB_SYS};
|
||||
use rustfs_config::notify::{NOTIFY_KAFKA_SUB_SYS, NOTIFY_MQTT_SUB_SYS, NOTIFY_MYSQL_SUB_SYS, NOTIFY_WEBHOOK_SUB_SYS};
|
||||
use rustfs_config::audit::{AUDIT_AMQP_SUB_SYS, AUDIT_KAFKA_SUB_SYS, AUDIT_MQTT_SUB_SYS, AUDIT_WEBHOOK_SUB_SYS};
|
||||
use rustfs_config::notify::{
|
||||
NOTIFY_AMQP_SUB_SYS, NOTIFY_KAFKA_SUB_SYS, NOTIFY_MQTT_SUB_SYS, NOTIFY_MYSQL_SUB_SYS, NOTIFY_WEBHOOK_SUB_SYS,
|
||||
};
|
||||
use rustfs_config::oidc::IDENTITY_OPENID_SUB_SYS;
|
||||
use rustfs_config::{
|
||||
DEFAULT_DELIMITER, ENABLE_KEY, EnableState, MYSQL_DSN_STRING, MYSQL_MAX_OPEN_CONNECTIONS, MYSQL_QUEUE_DIR, MYSQL_TABLE,
|
||||
@@ -1816,6 +1850,15 @@ mod tests {
|
||||
"tls_enable":true
|
||||
}
|
||||
},
|
||||
"amqp":{
|
||||
"primary":{
|
||||
"enable":true,
|
||||
"url":"amqp://127.0.0.1:5672/%2f",
|
||||
"exchange":"rustfs.events",
|
||||
"routing_key":"objects",
|
||||
"persistent":true
|
||||
}
|
||||
},
|
||||
"mysql":{
|
||||
"primary":{
|
||||
"enable":true,
|
||||
@@ -1861,6 +1904,15 @@ mod tests {
|
||||
assert_eq!(kafka.get(rustfs_config::KAFKA_ACKS), "all");
|
||||
assert_eq!(kafka.get(rustfs_config::KAFKA_TLS_ENABLE), "true");
|
||||
|
||||
let amqp = cfg
|
||||
.get_value(NOTIFY_AMQP_SUB_SYS, "primary")
|
||||
.expect("amqp target should be decoded");
|
||||
assert_eq!(amqp.get(ENABLE_KEY), EnableState::On.to_string());
|
||||
assert_eq!(amqp.get(rustfs_config::AMQP_URL), "amqp://127.0.0.1:5672/%2f");
|
||||
assert_eq!(amqp.get(rustfs_config::AMQP_EXCHANGE), "rustfs.events");
|
||||
assert_eq!(amqp.get(rustfs_config::AMQP_ROUTING_KEY), "objects");
|
||||
assert_eq!(amqp.get(rustfs_config::AMQP_PERSISTENT), "true");
|
||||
|
||||
let mysql = cfg
|
||||
.get_value(NOTIFY_MYSQL_SUB_SYS, "primary")
|
||||
.expect("mysql target should be decoded");
|
||||
@@ -1928,6 +1980,15 @@ mod tests {
|
||||
"queue_dir":"/tmp/audit-queue"
|
||||
}
|
||||
},
|
||||
"amqp":{
|
||||
"primary":{
|
||||
"enable":true,
|
||||
"url":"amqp://127.0.0.1:5672/%2f",
|
||||
"exchange":"rustfs.audit",
|
||||
"routing_key":"audit",
|
||||
"persistent":true
|
||||
}
|
||||
},
|
||||
"mqtt":{
|
||||
"default":{
|
||||
"enable":true,
|
||||
@@ -1959,6 +2020,15 @@ mod tests {
|
||||
assert_eq!(webhook.get(rustfs_config::WEBHOOK_ENDPOINT), "https://example.com/audit-hook");
|
||||
assert_eq!(webhook.get(rustfs_config::WEBHOOK_QUEUE_DIR), "/tmp/audit-queue");
|
||||
|
||||
let amqp = cfg
|
||||
.get_value(AUDIT_AMQP_SUB_SYS, "primary")
|
||||
.expect("audit amqp target should be decoded");
|
||||
assert_eq!(amqp.get(ENABLE_KEY), EnableState::On.to_string());
|
||||
assert_eq!(amqp.get(rustfs_config::AMQP_URL), "amqp://127.0.0.1:5672/%2f");
|
||||
assert_eq!(amqp.get(rustfs_config::AMQP_EXCHANGE), "rustfs.audit");
|
||||
assert_eq!(amqp.get(rustfs_config::AMQP_ROUTING_KEY), "audit");
|
||||
assert_eq!(amqp.get(rustfs_config::AMQP_PERSISTENT), "true");
|
||||
|
||||
let mqtt_default = cfg
|
||||
.get_value(AUDIT_MQTT_SUB_SYS, DEFAULT_DELIMITER)
|
||||
.expect("audit mqtt default should be decoded");
|
||||
@@ -2127,6 +2197,44 @@ mod tests {
|
||||
);
|
||||
cfg.0.insert(NOTIFY_KAFKA_SUB_SYS.to_string(), kafka_section);
|
||||
|
||||
let mut amqp_section = std::collections::HashMap::new();
|
||||
amqp_section.insert(
|
||||
"primary".to_string(),
|
||||
crate::config::KVS(vec![
|
||||
crate::config::KV {
|
||||
key: ENABLE_KEY.to_string(),
|
||||
value: EnableState::On.to_string(),
|
||||
hidden_if_empty: false,
|
||||
},
|
||||
crate::config::KV {
|
||||
key: rustfs_config::AMQP_URL.to_string(),
|
||||
value: "amqp://127.0.0.1:5672/%2f".to_string(),
|
||||
hidden_if_empty: false,
|
||||
},
|
||||
crate::config::KV {
|
||||
key: rustfs_config::AMQP_EXCHANGE.to_string(),
|
||||
value: "rustfs.events".to_string(),
|
||||
hidden_if_empty: false,
|
||||
},
|
||||
crate::config::KV {
|
||||
key: rustfs_config::AMQP_ROUTING_KEY.to_string(),
|
||||
value: "objects".to_string(),
|
||||
hidden_if_empty: false,
|
||||
},
|
||||
crate::config::KV {
|
||||
key: rustfs_config::AMQP_MANDATORY.to_string(),
|
||||
value: "false".to_string(),
|
||||
hidden_if_empty: false,
|
||||
},
|
||||
crate::config::KV {
|
||||
key: rustfs_config::AMQP_PERSISTENT.to_string(),
|
||||
value: "false".to_string(),
|
||||
hidden_if_empty: false,
|
||||
},
|
||||
]),
|
||||
);
|
||||
cfg.0.insert(NOTIFY_AMQP_SUB_SYS.to_string(), amqp_section);
|
||||
|
||||
let out = encode_server_config_blob(&cfg, None).expect("encode should succeed");
|
||||
let v: Value = serde_json::from_slice(&out).expect("output should be json");
|
||||
let notify = v
|
||||
@@ -2175,6 +2283,21 @@ mod tests {
|
||||
);
|
||||
assert_eq!(kafka.get(rustfs_config::KAFKA_ACKS).and_then(Value::as_str), Some("all"));
|
||||
assert_eq!(kafka.get(rustfs_config::KAFKA_TLS_ENABLE).and_then(Value::as_bool), Some(true));
|
||||
|
||||
let amqp = notify
|
||||
.get("amqp")
|
||||
.and_then(Value::as_object)
|
||||
.and_then(|targets| targets.get("primary"))
|
||||
.and_then(Value::as_object)
|
||||
.expect("amqp target should be encoded");
|
||||
assert_eq!(
|
||||
amqp.get(rustfs_config::AMQP_URL).and_then(Value::as_str),
|
||||
Some("amqp://127.0.0.1:5672/%2f")
|
||||
);
|
||||
assert_eq!(amqp.get(rustfs_config::AMQP_EXCHANGE).and_then(Value::as_str), Some("rustfs.events"));
|
||||
assert_eq!(amqp.get(rustfs_config::AMQP_ROUTING_KEY).and_then(Value::as_str), Some("objects"));
|
||||
assert!(!amqp.contains_key(rustfs_config::AMQP_MANDATORY));
|
||||
assert_eq!(amqp.get(rustfs_config::AMQP_PERSISTENT).and_then(Value::as_bool), Some(false));
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -2204,6 +2327,44 @@ mod tests {
|
||||
);
|
||||
cfg.0.insert(AUDIT_WEBHOOK_SUB_SYS.to_string(), webhook_section);
|
||||
|
||||
let mut amqp_section = std::collections::HashMap::new();
|
||||
amqp_section.insert(
|
||||
"primary".to_string(),
|
||||
crate::config::KVS(vec![
|
||||
crate::config::KV {
|
||||
key: ENABLE_KEY.to_string(),
|
||||
value: EnableState::On.to_string(),
|
||||
hidden_if_empty: false,
|
||||
},
|
||||
crate::config::KV {
|
||||
key: rustfs_config::AMQP_URL.to_string(),
|
||||
value: "amqp://127.0.0.1:5672/%2f".to_string(),
|
||||
hidden_if_empty: false,
|
||||
},
|
||||
crate::config::KV {
|
||||
key: rustfs_config::AMQP_EXCHANGE.to_string(),
|
||||
value: "rustfs.audit".to_string(),
|
||||
hidden_if_empty: false,
|
||||
},
|
||||
crate::config::KV {
|
||||
key: rustfs_config::AMQP_ROUTING_KEY.to_string(),
|
||||
value: "audit".to_string(),
|
||||
hidden_if_empty: false,
|
||||
},
|
||||
crate::config::KV {
|
||||
key: rustfs_config::AMQP_MANDATORY.to_string(),
|
||||
value: "false".to_string(),
|
||||
hidden_if_empty: false,
|
||||
},
|
||||
crate::config::KV {
|
||||
key: rustfs_config::AMQP_PERSISTENT.to_string(),
|
||||
value: "false".to_string(),
|
||||
hidden_if_empty: false,
|
||||
},
|
||||
]),
|
||||
);
|
||||
cfg.0.insert(AUDIT_AMQP_SUB_SYS.to_string(), amqp_section);
|
||||
|
||||
let mut mqtt_default = audit::DEFAULT_AUDIT_MQTT_KVS.clone();
|
||||
mqtt_default.insert(ENABLE_KEY.to_string(), EnableState::On.to_string());
|
||||
mqtt_default.insert(rustfs_config::MQTT_TOPIC.to_string(), "audit-events".to_string());
|
||||
@@ -2266,6 +2427,21 @@ mod tests {
|
||||
);
|
||||
assert_eq!(webhook.get(ENABLE_KEY).and_then(Value::as_bool), Some(true));
|
||||
|
||||
let amqp = logger
|
||||
.get("amqp")
|
||||
.and_then(Value::as_object)
|
||||
.and_then(|targets| targets.get("primary"))
|
||||
.and_then(Value::as_object)
|
||||
.expect("audit amqp target should be encoded");
|
||||
assert_eq!(
|
||||
amqp.get(rustfs_config::AMQP_URL).and_then(Value::as_str),
|
||||
Some("amqp://127.0.0.1:5672/%2f")
|
||||
);
|
||||
assert_eq!(amqp.get(rustfs_config::AMQP_EXCHANGE).and_then(Value::as_str), Some("rustfs.audit"));
|
||||
assert_eq!(amqp.get(rustfs_config::AMQP_ROUTING_KEY).and_then(Value::as_str), Some("audit"));
|
||||
assert!(!amqp.contains_key(rustfs_config::AMQP_MANDATORY));
|
||||
assert_eq!(amqp.get(rustfs_config::AMQP_PERSISTENT).and_then(Value::as_bool), Some(false));
|
||||
|
||||
let mqtt_default = logger
|
||||
.get("mqtt")
|
||||
.and_then(Value::as_object)
|
||||
|
||||
@@ -26,12 +26,12 @@ use com::{STORAGE_CLASS_SUB_SYS, lookup_configs, read_config_without_migrate};
|
||||
use rustfs_config::COMMENT_KEY;
|
||||
use rustfs_config::DEFAULT_DELIMITER;
|
||||
use rustfs_config::audit::{
|
||||
AUDIT_KAFKA_SUB_SYS, AUDIT_MQTT_SUB_SYS, AUDIT_MYSQL_SUB_SYS, AUDIT_NATS_SUB_SYS, AUDIT_POSTGRES_SUB_SYS,
|
||||
AUDIT_AMQP_SUB_SYS, AUDIT_KAFKA_SUB_SYS, AUDIT_MQTT_SUB_SYS, AUDIT_MYSQL_SUB_SYS, AUDIT_NATS_SUB_SYS, AUDIT_POSTGRES_SUB_SYS,
|
||||
AUDIT_PULSAR_SUB_SYS, AUDIT_REDIS_SUB_SYS, AUDIT_WEBHOOK_SUB_SYS,
|
||||
};
|
||||
use rustfs_config::notify::{
|
||||
NOTIFY_KAFKA_SUB_SYS, NOTIFY_MQTT_SUB_SYS, NOTIFY_MYSQL_SUB_SYS, NOTIFY_NATS_SUB_SYS, NOTIFY_POSTGRES_SUB_SYS,
|
||||
NOTIFY_PULSAR_SUB_SYS, NOTIFY_REDIS_SUB_SYS, NOTIFY_WEBHOOK_SUB_SYS,
|
||||
NOTIFY_AMQP_SUB_SYS, NOTIFY_KAFKA_SUB_SYS, NOTIFY_MQTT_SUB_SYS, NOTIFY_MYSQL_SUB_SYS, NOTIFY_NATS_SUB_SYS,
|
||||
NOTIFY_POSTGRES_SUB_SYS, NOTIFY_PULSAR_SUB_SYS, NOTIFY_REDIS_SUB_SYS, NOTIFY_WEBHOOK_SUB_SYS,
|
||||
};
|
||||
use rustfs_config::oidc::IDENTITY_OPENID_SUB_SYS;
|
||||
use serde::{Deserialize, Serialize};
|
||||
@@ -243,6 +243,8 @@ pub fn init() {
|
||||
kvs.insert(AUDIT_WEBHOOK_SUB_SYS.to_owned(), audit::DEFAULT_AUDIT_WEBHOOK_KVS.clone());
|
||||
kvs.insert(NOTIFY_MQTT_SUB_SYS.to_owned(), notify::DEFAULT_NOTIFY_MQTT_KVS.clone());
|
||||
kvs.insert(AUDIT_MQTT_SUB_SYS.to_owned(), audit::DEFAULT_AUDIT_MQTT_KVS.clone());
|
||||
kvs.insert(NOTIFY_AMQP_SUB_SYS.to_owned(), notify::DEFAULT_NOTIFY_AMQP_KVS.clone());
|
||||
kvs.insert(AUDIT_AMQP_SUB_SYS.to_owned(), audit::DEFAULT_AUDIT_AMQP_KVS.clone());
|
||||
kvs.insert(NOTIFY_NATS_SUB_SYS.to_owned(), notify::DEFAULT_NOTIFY_NATS_KVS.clone());
|
||||
kvs.insert(AUDIT_NATS_SUB_SYS.to_owned(), audit::DEFAULT_AUDIT_NATS_KVS.clone());
|
||||
kvs.insert(NOTIFY_REDIS_SUB_SYS.to_owned(), notify::DEFAULT_NOTIFY_REDIS_KVS.clone());
|
||||
|
||||
@@ -15,14 +15,16 @@
|
||||
use crate::config::{KV, KVS};
|
||||
use rustfs_config::notify::NOTIFY_REDIS_DEFAULT_CHANNEL;
|
||||
use rustfs_config::{
|
||||
COMMENT_KEY, DEFAULT_LIMIT, ENABLE_KEY, EVENT_DEFAULT_DIR, EnableState, KAFKA_ACKS, KAFKA_BROKERS, KAFKA_QUEUE_DIR,
|
||||
KAFKA_QUEUE_LIMIT, KAFKA_TLS_CA, KAFKA_TLS_CLIENT_CERT, KAFKA_TLS_CLIENT_KEY, KAFKA_TLS_ENABLE, KAFKA_TOPIC, MQTT_BROKER,
|
||||
MQTT_KEEP_ALIVE_INTERVAL, MQTT_PASSWORD, MQTT_QOS, MQTT_QUEUE_DIR, MQTT_QUEUE_LIMIT, MQTT_RECONNECT_INTERVAL, MQTT_TLS_CA,
|
||||
MQTT_TLS_CLIENT_CERT, MQTT_TLS_CLIENT_KEY, MQTT_TLS_POLICY, MQTT_TLS_TRUST_LEAF_AS_CA, MQTT_TOPIC, MQTT_USERNAME,
|
||||
MQTT_WS_PATH_ALLOWLIST, MYSQL_DSN_STRING, MYSQL_FORMAT, MYSQL_MAX_OPEN_CONNECTIONS, MYSQL_QUEUE_DIR, MYSQL_QUEUE_LIMIT,
|
||||
MYSQL_TABLE, MYSQL_TLS_CA, MYSQL_TLS_CLIENT_CERT, MYSQL_TLS_CLIENT_KEY, NATS_ADDRESS, NATS_CREDENTIALS_FILE, NATS_PASSWORD,
|
||||
NATS_QUEUE_DIR, NATS_QUEUE_LIMIT, NATS_SUBJECT, NATS_TLS_CA, NATS_TLS_CLIENT_CERT, NATS_TLS_CLIENT_KEY, NATS_TLS_REQUIRED,
|
||||
NATS_TOKEN, NATS_USERNAME, POSTGRES_DSN_STRING, POSTGRES_FORMAT, POSTGRES_QUEUE_DIR, POSTGRES_QUEUE_LIMIT, POSTGRES_TABLE,
|
||||
AMQP_EXCHANGE, AMQP_MANDATORY, AMQP_PASSWORD, AMQP_PERSISTENT, AMQP_QUEUE_DIR, AMQP_QUEUE_LIMIT, AMQP_ROUTING_KEY,
|
||||
AMQP_TLS_CA, AMQP_TLS_CLIENT_CERT, AMQP_TLS_CLIENT_KEY, AMQP_URL, AMQP_USERNAME, COMMENT_KEY, DEFAULT_LIMIT, ENABLE_KEY,
|
||||
EVENT_DEFAULT_DIR, EnableState, KAFKA_ACKS, KAFKA_BROKERS, KAFKA_QUEUE_DIR, KAFKA_QUEUE_LIMIT, KAFKA_TLS_CA,
|
||||
KAFKA_TLS_CLIENT_CERT, KAFKA_TLS_CLIENT_KEY, KAFKA_TLS_ENABLE, KAFKA_TOPIC, MQTT_BROKER, MQTT_KEEP_ALIVE_INTERVAL,
|
||||
MQTT_PASSWORD, MQTT_QOS, MQTT_QUEUE_DIR, MQTT_QUEUE_LIMIT, MQTT_RECONNECT_INTERVAL, MQTT_TLS_CA, MQTT_TLS_CLIENT_CERT,
|
||||
MQTT_TLS_CLIENT_KEY, MQTT_TLS_POLICY, MQTT_TLS_TRUST_LEAF_AS_CA, MQTT_TOPIC, MQTT_USERNAME, MQTT_WS_PATH_ALLOWLIST,
|
||||
MYSQL_DSN_STRING, MYSQL_FORMAT, MYSQL_MAX_OPEN_CONNECTIONS, MYSQL_QUEUE_DIR, MYSQL_QUEUE_LIMIT, MYSQL_TABLE, MYSQL_TLS_CA,
|
||||
MYSQL_TLS_CLIENT_CERT, MYSQL_TLS_CLIENT_KEY, NATS_ADDRESS, NATS_CREDENTIALS_FILE, NATS_PASSWORD, NATS_QUEUE_DIR,
|
||||
NATS_QUEUE_LIMIT, NATS_SUBJECT, NATS_TLS_CA, NATS_TLS_CLIENT_CERT, NATS_TLS_CLIENT_KEY, NATS_TLS_REQUIRED, NATS_TOKEN,
|
||||
NATS_USERNAME, POSTGRES_DSN_STRING, POSTGRES_FORMAT, POSTGRES_QUEUE_DIR, POSTGRES_QUEUE_LIMIT, POSTGRES_TABLE,
|
||||
POSTGRES_TLS_CA, POSTGRES_TLS_CLIENT_CERT, POSTGRES_TLS_CLIENT_KEY, POSTGRES_TLS_REQUIRED, PULSAR_AUTH_TOKEN, PULSAR_BROKER,
|
||||
PULSAR_PASSWORD, PULSAR_QUEUE_DIR, PULSAR_QUEUE_LIMIT, PULSAR_TLS_ALLOW_INSECURE, PULSAR_TLS_CA,
|
||||
PULSAR_TLS_HOSTNAME_VERIFICATION, PULSAR_TOPIC, PULSAR_USERNAME, REDIS_CHANNEL, REDIS_CONNECTION_TIMEOUT,
|
||||
@@ -184,6 +186,81 @@ pub static DEFAULT_NOTIFY_MQTT_KVS: LazyLock<KVS> = LazyLock::new(|| {
|
||||
])
|
||||
});
|
||||
|
||||
pub static DEFAULT_NOTIFY_AMQP_KVS: LazyLock<KVS> = LazyLock::new(|| {
|
||||
KVS(vec![
|
||||
KV {
|
||||
key: ENABLE_KEY.to_owned(),
|
||||
value: EnableState::Off.to_string(),
|
||||
hidden_if_empty: false,
|
||||
},
|
||||
KV {
|
||||
key: AMQP_URL.to_owned(),
|
||||
value: "".to_owned(),
|
||||
hidden_if_empty: false,
|
||||
},
|
||||
KV {
|
||||
key: AMQP_EXCHANGE.to_owned(),
|
||||
value: "".to_owned(),
|
||||
hidden_if_empty: false,
|
||||
},
|
||||
KV {
|
||||
key: AMQP_ROUTING_KEY.to_owned(),
|
||||
value: "".to_owned(),
|
||||
hidden_if_empty: false,
|
||||
},
|
||||
KV {
|
||||
key: AMQP_MANDATORY.to_owned(),
|
||||
value: EnableState::Off.to_string(),
|
||||
hidden_if_empty: false,
|
||||
},
|
||||
KV {
|
||||
key: AMQP_PERSISTENT.to_owned(),
|
||||
value: EnableState::On.to_string(),
|
||||
hidden_if_empty: false,
|
||||
},
|
||||
KV {
|
||||
key: AMQP_USERNAME.to_owned(),
|
||||
value: "".to_owned(),
|
||||
hidden_if_empty: false,
|
||||
},
|
||||
KV {
|
||||
key: AMQP_PASSWORD.to_owned(),
|
||||
value: "".to_owned(),
|
||||
hidden_if_empty: true,
|
||||
},
|
||||
KV {
|
||||
key: AMQP_TLS_CA.to_owned(),
|
||||
value: "".to_owned(),
|
||||
hidden_if_empty: true,
|
||||
},
|
||||
KV {
|
||||
key: AMQP_TLS_CLIENT_CERT.to_owned(),
|
||||
value: "".to_owned(),
|
||||
hidden_if_empty: true,
|
||||
},
|
||||
KV {
|
||||
key: AMQP_TLS_CLIENT_KEY.to_owned(),
|
||||
value: "".to_owned(),
|
||||
hidden_if_empty: true,
|
||||
},
|
||||
KV {
|
||||
key: AMQP_QUEUE_DIR.to_owned(),
|
||||
value: EVENT_DEFAULT_DIR.to_owned(),
|
||||
hidden_if_empty: false,
|
||||
},
|
||||
KV {
|
||||
key: AMQP_QUEUE_LIMIT.to_owned(),
|
||||
value: DEFAULT_LIMIT.to_string(),
|
||||
hidden_if_empty: false,
|
||||
},
|
||||
KV {
|
||||
key: COMMENT_KEY.to_owned(),
|
||||
value: "".to_owned(),
|
||||
hidden_if_empty: false,
|
||||
},
|
||||
])
|
||||
});
|
||||
|
||||
pub static DEFAULT_NOTIFY_NATS_KVS: LazyLock<KVS> = LazyLock::new(|| {
|
||||
KVS(vec![
|
||||
KV {
|
||||
|
||||
Reference in New Issue
Block a user