use crate::common::string_utils::StringUtils;
use crate::ldap::model::LdapConfig;
use crate::oauth2::model::OAuth2Config;
use crate::user::permission;
use crate::user::permission::UserRoleHelper;
use std::collections::HashSet;
use std::sync::Arc;
use uuid::Uuid;
pub mod actor_utils;
pub mod appdata;
pub mod byte_utils;
pub mod constant;
pub mod crypto_utils;
pub mod cycle_queue;
pub mod datetime_utils;
pub mod delay_notify;
pub mod error_code;
pub mod hash_utils;
pub mod limiter_utils;
pub mod log_utils;
pub mod macros;
pub mod model;
pub mod option_utils;
pub mod pb;
pub mod protobuf_utils;
pub mod rusqlite_utils;
pub mod sequence_utils;
pub mod sled_utils;
pub mod sqlx_utils;
pub mod string_utils;
pub mod tempfile;
pub mod web_utils;
const DEFAULT_DB_PATH: &str = "nacos_db";
#[derive(Default, Clone, Debug)]
pub struct NamingSysConfig {
pub once_time_check_size: usize,
pub service_time_out_millis: u64,
pub instance_metadata_time_out_millis: u64,
pub instance_health_timeout_millis: i64,
pub instance_timeout_millis: i64,
pub perpetual_instance_probe_interval: i32,
}
impl NamingSysConfig {
pub fn new() -> Self {
Self {
once_time_check_size: 10000,
service_time_out_millis: 30000,
instance_metadata_time_out_millis: 60000,
instance_health_timeout_millis: 18000,
instance_timeout_millis: 33000,
perpetual_instance_probe_interval: 60,
}
}
}
#[derive(Default, Clone, Debug)]
pub struct AppSysConfig {
pub config_db_file: String,
pub local_db_dir: String,
pub config_max_content: usize,
pub http_port: u16,
pub sdk_host: String,
pub http_console_port: u16,
pub console_host: String,
pub enable_no_auth_console: bool,
pub http_workers: Option<usize>,
pub grpc_port: u16,
pub raft_node_id: u64,
pub raft_node_addr: String,
pub raft_auto_init: bool,
pub raft_join_addr: String,
pub raft_snapshot_log_size: u64,
pub console_login_timeout: i32,
pub console_login_one_hour_limit: u32,
pub gmt_fixed_offset_hours: Option<i32>,
pub openapi_login_timeout: i32,
pub openapi_login_one_minute_limit: u32,
pub openapi_enable_auth: bool,
pub cluster_token: Arc<String>,
pub backup_token: Arc<String>,
pub init_admin_username: String,
pub init_admin_password: String,
pub metrics_enable: bool,
pub metrics_collect_interval_second: u64,
pub metrics_log_interval_second: u64,
pub metrics_log_enable: bool,
pub console_captcha_enable: bool,
pub run_in_docker: bool,
pub naming_health_timeout: u64,
pub naming_instance_timeout: u64,
pub naming_perpetual_instance_probe_interval: i32,
pub ldap_enable: bool,
pub ldap_url: Arc<String>,
pub ldap_user_base_dn: Arc<String>,
pub ldap_user_filter: Arc<String>,
pub ldap_user_developer_groups: Arc<HashSet<String>>,
pub ldap_user_admin_groups: Arc<HashSet<String>>,
pub ldap_user_default_role: Arc<String>,
pub mcp_http_timeout: u64,
pub oauth2_enable: bool,
pub oauth2_server_url: Arc<String>,
pub oauth2_client_id: Arc<String>,
pub oauth2_client_secret: Arc<String>,
pub oauth2_authorization_url: Arc<String>,
pub oauth2_token_url: Arc<String>,
pub oauth2_userinfo_url: Arc<String>,
pub oauth2_redirect_uri: Arc<String>,
pub oauth2_scopes: Arc<String>,
pub oauth2_username_claim_name: Arc<String>,
pub oauth2_nickname_claim_name: Arc<String>,
pub oauth2_user_default_role: Arc<String>,
pub oauth2_button: Arc<String>,
pub grpc_detection_timeout: u64,
pub enable_grpc_detection_log: bool,
pub naming_instance_metadata_persistence_enable: bool,
}
impl AppSysConfig {
pub fn init_from_env() -> Self {
let config_db_file =
std::env::var("RNACOS_CONFIG_DB_FILE").unwrap_or("config.db".to_owned());
let config_max_content = std::env::var("RNACOS_CONFIG_MAX_CONTENT")
.unwrap_or("10485760".to_owned())
.parse()
.unwrap_or(10 * 1024 * 1024);
let http_port = std::env::var("RNACOS_HTTP_PORT")
.unwrap_or("8848".to_owned())
.parse()
.unwrap_or(8848);
let sdk_host = std::env::var("RNACOS_SDK_HOST").unwrap_or("0.0.0.0".to_owned());
let http_workers = std::env::var("RNACOS_HTTP_WORKERS")
.unwrap_or("".to_owned())
.parse()
.ok();
let grpc_port = std::env::var("RNACOS_GRPC_PORT")
.unwrap_or("".to_owned())
.parse()
.unwrap_or(http_port + 1000);
let http_console_port = std::env::var("RNACOS_HTTP_CONSOLE_PORT")
.unwrap_or("".to_owned())
.parse()
.unwrap_or(http_port + 2000);
let console_host =
std::env::var("RNACOS_CONSOLE_HOST").unwrap_or_else(|_| sdk_host.clone());
let run_in_docker = std::env::var("RNACOS_RUN_IN_DOCKER")
.unwrap_or("".to_owned())
.eq_ignore_ascii_case("true");
let local_db_dir = Self::get_data_dir(run_in_docker);
let raft_node_id = std::env::var("RNACOS_RAFT_NODE_ID")
.unwrap_or("1".to_owned())
.parse()
.unwrap_or(1);
let raft_node_addr =
std::env::var("RNACOS_RAFT_NODE_ADDR").unwrap_or(format!("127.0.0.1:{}", &grpc_port));
let raft_auto_init = std::env::var("RNACOS_RAFT_AUTO_INIT")
.unwrap_or("".to_owned())
.parse()
.unwrap_or(raft_node_id == 1);
let raft_join_addr = std::env::var("RNACOS_RAFT_JOIN_ADDR").unwrap_or_default();
let console_login_timeout = std::env::var("RNACOS_CONSOLE_LOGIN_TIMEOUT")
.unwrap_or("86400".to_owned())
.parse()
.unwrap_or(86400);
let console_login_one_hour_limit = std::env::var("RNACOS_CONSOLE_LOGIN_ONE_HOUR_LIMIT")
.unwrap_or("5".to_owned())
.parse()
.unwrap_or(5);
let openapi_login_timeout = std::env::var("RNACOS_API_LOGIN_TIMEOUT")
.unwrap_or("3600".to_owned())
.parse()
.unwrap_or(3600);
let openapi_login_one_minute_limit = std::env::var("RNACOS_API_LOGIN_ONE_MINUTE_LIMIT")
.unwrap_or("100".to_owned())
.parse()
.unwrap_or(100);
let raft_snapshot_log_size = std::env::var("RNACOS_RAFT_SNAPSHOT_LOG_SIZE")
.unwrap_or("10000".to_owned())
.parse()
.unwrap_or(10000);
let enable_no_auth_console = std::env::var("RNACOS_ENABLE_NO_AUTH_CONSOLE")
.unwrap_or("false".to_owned())
.parse()
.unwrap_or(false);
let gmt_fixed_offset_hours = std::env::var("RNACOS_GMT_OFFSET_HOURS")
.unwrap_or_default()
.parse()
.ok();
let openapi_enable_auth = std::env::var("RNACOS_ENABLE_OPEN_API_AUTH")
.unwrap_or("false".to_owned())
.parse()
.unwrap_or(false);
let cluster_token = std::env::var("RNACOS_CLUSTER_TOKEN")
.map(Arc::new)
.unwrap_or(constant::EMPTY_ARC_STRING.clone());
let mut backup_token = std::env::var("RNACOS_BACKUP_TOKEN")
.map(Arc::new)
.unwrap_or(constant::EMPTY_ARC_STRING.clone());
if backup_token.len() < 32 {
backup_token = constant::EMPTY_ARC_STRING.clone();
}
let init_admin_username =
StringUtils::map_not_empty(std::env::var("RNACOS_INIT_ADMIN_USERNAME").ok())
.unwrap_or("admin".to_owned());
let init_admin_password =
StringUtils::map_not_empty(std::env::var("RNACOS_INIT_ADMIN_PASSWORD").ok())
.unwrap_or("admin".to_owned());
let metrics_enable = std::env::var("RNACOS_ENABLE_METRICS")
.unwrap_or("true".to_owned())
.parse()
.unwrap_or(true);
let mut metrics_collect_interval_second =
std::env::var("RNACOS_METRICS_COLLECT_INTERVAL_SECOND")
.unwrap_or("15".to_owned())
.parse()
.unwrap_or(15);
let console_captcha_enable = std::env::var("RNACOS_CONSOLE_ENABLE_CAPTCHA")
.unwrap_or("true".to_owned())
.parse()
.unwrap_or(true);
if metrics_collect_interval_second < 1 {
metrics_collect_interval_second = 1;
}
let metrics_log_enable = std::env::var("RNACOS_METRICS_ENABLE_LOG")
.unwrap_or("false".to_owned())
.parse()
.unwrap_or(false);
let mut metrics_log_interval_second = std::env::var("RNACOS_METRICS_LOG_INTERVAL_SECOND")
.unwrap_or("60".to_owned())
.parse()
.unwrap_or(60);
if metrics_log_interval_second < 5 {
metrics_log_interval_second = 5;
}
if metrics_log_interval_second < metrics_collect_interval_second {
metrics_collect_interval_second = metrics_log_interval_second;
}
let naming_health_timeout = std::env::var("RNACOS_NAMING_HEALTH_TIMEOUT_SECOND")
.unwrap_or("15".to_owned())
.parse()
.unwrap_or(15)
* 1000;
let mut naming_instance_timeout = std::env::var("RNACOS_NAMING_INSTANCE_TIMEOUT_SECOND")
.unwrap_or("30".to_owned())
.parse()
.unwrap_or(30)
* 1000;
if naming_health_timeout >= naming_instance_timeout {
naming_instance_timeout = naming_health_timeout + 15 * 1000;
}
let mut naming_perpetual_instance_probe_interval =
std::env::var("RNACOS_NAMING_PERPETUAL_INSTANCE_PROBE_INTERVAL_SECOND")
.unwrap_or("60".to_owned())
.parse()
.unwrap_or(60);
if naming_perpetual_instance_probe_interval < 5
&& naming_perpetual_instance_probe_interval > 0
{
naming_perpetual_instance_probe_interval = 5;
}
let ldap_enable = std::env::var("RNACOS_LDAP_ENABLE")
.unwrap_or("false".to_owned())
.parse()
.unwrap_or(false);
let ldap_url = std::env::var("RNACOS_LDAP_URL")
.map(Arc::new)
.unwrap_or(constant::EMPTY_ARC_STRING.clone());
let ldap_user_base_dn = std::env::var("RNACOS_LDAP_USER_BASE_DN")
.map(Arc::new)
.unwrap_or(constant::EMPTY_ARC_STRING.clone());
let ldap_user_filter = std::env::var("RNACOS_LDAP_USER_FILTER")
.map(Arc::new)
.unwrap_or(constant::EMPTY_ARC_STRING.clone());
let ldap_user_developer_groups = Arc::new(StringUtils::split_to_hashset(
&std::env::var("RNACOS_LDAP_USER_DEVELOPER_GROUP").unwrap_or_default(),
));
let ldap_user_admin_groups = Arc::new(StringUtils::split_to_hashset(
&std::env::var("RNACOS_LDAP_USER_ADMIN_GROUP").unwrap_or_default(),
));
let ldap_user_default_role = std::env::var("RNACOS_LDAP_USER_DEFAULT_ROLE")
.map(|v| {
let upper = v.to_uppercase();
UserRoleHelper::get_role_by_name(&upper, permission::USER_ROLE_VISITOR.clone())
})
.unwrap_or(permission::USER_ROLE_VISITOR.clone());
let mcp_http_timeout = std::env::var("RNACOS_MCP_HTTP_TIMEOUT_SECOND")
.unwrap_or("30".to_owned())
.parse()
.unwrap_or(30);
let oauth2_enable = std::env::var("RNACOS_OAUTH2_ENABLE")
.unwrap_or("false".to_owned())
.parse()
.unwrap_or(false);
let oauth2_server_url = std::env::var("RNACOS_OAUTH2_SERVER_URL")
.map(Arc::new)
.unwrap_or(constant::EMPTY_ARC_STRING.clone());
let oauth2_client_id = std::env::var("RNACOS_OAUTH2_CLIENT_ID")
.map(Arc::new)
.unwrap_or(constant::EMPTY_ARC_STRING.clone());
let oauth2_client_secret = std::env::var("RNACOS_OAUTH2_CLIENT_SECRET")
.map(Arc::new)
.unwrap_or(constant::EMPTY_ARC_STRING.clone());
let oauth2_authorization_url = std::env::var("RNACOS_OAUTH2_AUTHORIZATION_URL")
.map(Arc::new)
.unwrap_or_else(|_| {
let server_url = std::env::var("RNACOS_OAUTH2_SERVER_URL").unwrap_or_default();
Arc::new(format!("{}/oauth/authorize", server_url))
});
let oauth2_token_url = std::env::var("RNACOS_OAUTH2_TOKEN_URL")
.map(Arc::new)
.unwrap_or_else(|_| {
let server_url = std::env::var("RNACOS_OAUTH2_SERVER_URL").unwrap_or_default();
Arc::new(format!("{}/oauth/token", server_url))
});
let oauth2_userinfo_url = std::env::var("RNACOS_OAUTH2_USERINFO_URL")
.map(Arc::new)
.unwrap_or_else(|_| {
let server_url = std::env::var("RNACOS_OAUTH2_SERVER_URL").unwrap_or_default();
Arc::new(format!("{}/oauth/userinfo", server_url))
});
let oauth2_redirect_uri = std::env::var("RNACOS_OAUTH2_REDIRECT_URI")
.map(Arc::new)
.unwrap_or(constant::EMPTY_ARC_STRING.clone());
let oauth2_scopes = std::env::var("RNACOS_OAUTH2_SCOPES")
.map(Arc::new)
.unwrap_or_else(|_| Arc::new("openid profile".to_string()));
let oauth2_username_claim_name = std::env::var("RNACOS_OAUTH2_USERNAME_CLAIM_NAME")
.map(Arc::new)
.unwrap_or_else(|_| Arc::new("username".to_string()));
let oauth2_nickname_claim_name = std::env::var("RNACOS_OAUTH2_NICKNAME_CLAIM_NAME")
.map(Arc::new)
.unwrap_or_else(|_| Arc::new("name".to_string()));
let oauth2_user_default_role = std::env::var("RNACOS_OAUTH2_USER_DEFAULT_ROLE")
.map(|v| {
let upper = v.to_uppercase();
UserRoleHelper::get_role_by_name(&upper, permission::USER_ROLE_DEVELOPER.clone())
})
.unwrap_or(permission::USER_ROLE_DEVELOPER.clone());
let oauth2_button = std::env::var("RNACOS_OAUTH2_BUTTON")
.map(Arc::new)
.unwrap_or_else(|_| Arc::new("OAuth2.0 登录".to_string()));
let grpc_detection_timeout = std::env::var("RNACOS_GRPC_DETECTION_TIMEOUT_SECOND")
.unwrap_or("15".to_owned())
.parse()
.unwrap_or(15)
* 1000;
let enable_grpc_detection_log = std::env::var("RNACOS_ENABLE_GRPC_DETECTION_LOG")
.unwrap_or("false".to_owned())
.parse()
.unwrap_or(false);
let naming_instance_metadata_persistence_enable =
std::env::var("RNACOS_NAMING_INSTANCE_METADATA_PERSISTENCE_ENABLE")
.unwrap_or("true".to_owned())
.parse()
.unwrap_or(true);
Self {
local_db_dir,
config_db_file,
config_max_content,
http_port,
sdk_host,
http_console_port,
console_host,
enable_no_auth_console,
grpc_port,
http_workers,
raft_node_id,
raft_node_addr,
raft_auto_init,
raft_join_addr,
raft_snapshot_log_size,
console_login_timeout,
console_login_one_hour_limit,
openapi_login_timeout,
openapi_login_one_minute_limit,
gmt_fixed_offset_hours,
openapi_enable_auth,
cluster_token,
backup_token,
init_admin_username,
init_admin_password,
metrics_enable,
metrics_log_enable,
metrics_collect_interval_second,
metrics_log_interval_second,
console_captcha_enable,
run_in_docker,
naming_health_timeout,
naming_instance_timeout,
naming_perpetual_instance_probe_interval,
ldap_enable,
ldap_url,
ldap_user_base_dn,
ldap_user_filter,
ldap_user_developer_groups,
ldap_user_admin_groups,
ldap_user_default_role,
mcp_http_timeout,
oauth2_enable,
oauth2_server_url,
oauth2_client_id,
oauth2_client_secret,
oauth2_authorization_url,
oauth2_token_url,
oauth2_userinfo_url,
oauth2_redirect_uri,
oauth2_scopes,
oauth2_username_claim_name,
oauth2_nickname_claim_name,
oauth2_user_default_role,
oauth2_button,
grpc_detection_timeout,
enable_grpc_detection_log,
naming_instance_metadata_persistence_enable,
}
}
fn get_data_dir(run_in_docker: bool) -> String {
if let Ok(v) = std::env::var("RNACOS_DATA_DIR") {
v
} else if let Ok(v) = std::env::var("RNACOS_CONFIG_DB_DIR") {
v
} else if run_in_docker {
DEFAULT_DB_PATH.to_owned()
} else {
#[cfg(any(target_os = "linux", target_os = "macos"))]
{
if let Some(mut home) = dirs::home_dir() {
home.push(".local/share/r-nacos/nacos_db");
return home.to_string_lossy().to_string();
}
}
DEFAULT_DB_PATH.to_owned()
}
}
pub fn get_grpc_addr(&self) -> String {
format!("{}:{}", &self.sdk_host, &self.grpc_port)
}
pub fn get_http_addr(&self) -> String {
format!("{}:{}", &self.sdk_host, &self.http_port)
}
pub fn get_http_console_addr(&self) -> String {
format!("{}:{}", &self.console_host, &self.http_console_port)
}
pub fn get_ldap_config(&self) -> Arc<LdapConfig> {
Arc::new(LdapConfig {
ldap_url: self.ldap_url.clone(),
ldap_user_base_dn: self.ldap_user_base_dn.clone(),
ldap_user_filter: self.ldap_user_filter.clone(),
ldap_user_developer_groups: self.ldap_user_developer_groups.clone(),
ldap_user_admin_groups: self.ldap_user_admin_groups.clone(),
ldap_user_default_role: self.ldap_user_default_role.clone(),
})
}
pub fn get_oauth2_config(&self) -> Arc<OAuth2Config> {
Arc::new(OAuth2Config {
oauth2_server_url: self.oauth2_server_url.clone(),
oauth2_client_id: self.oauth2_client_id.clone(),
oauth2_client_secret: self.oauth2_client_secret.clone(),
oauth2_authorization_url: self.oauth2_authorization_url.clone(),
oauth2_token_url: self.oauth2_token_url.clone(),
oauth2_userinfo_url: self.oauth2_userinfo_url.clone(),
oauth2_redirect_uri: self.oauth2_redirect_uri.clone(),
oauth2_scopes: self.oauth2_scopes.clone(),
oauth2_username_claim_name: self.oauth2_username_claim_name.clone(),
oauth2_nickname_claim_name: self.oauth2_nickname_claim_name.clone(),
oauth2_user_default_role: self.oauth2_user_default_role.clone(),
})
}
}
pub fn gen_uuid() -> i64 {
let uuid = Uuid::new_v4();
let bytes = uuid.as_bytes();
let msb = u64::from_be_bytes([
bytes[0], bytes[1], bytes[2], bytes[3], bytes[4], bytes[5], bytes[6], bytes[7],
]);
let lsb = u64::from_be_bytes([
bytes[8], bytes[9], bytes[10], bytes[11], bytes[12], bytes[13], bytes[14], bytes[15],
]);
((msb << 32) | lsb) as i64
}
pub fn get_app_version() -> &'static str {
env!("CARGO_PKG_VERSION")
}