Skip to content

Commit

Permalink
refactor(service/etcd): Add EtcdConfig to implement ConfigDeserializer (
Browse files Browse the repository at this point in the history
#3543)

* refactor(service/etcd): Add EtcdConfig to implement ConfigDeserializer

* refactor(service/etcd): Add pub

* refactor(service/etcd): cargo format

* refactor(service/etcd): fix wrong naming
  • Loading branch information
Xuxiaotuan authored Nov 9, 2023
1 parent dbdeadf commit 60b4d3a
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 27 deletions.
90 changes: 63 additions & 27 deletions core/src/services/etcd/backend.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ use etcd_client::Error as EtcdError;
use etcd_client::GetOptions;
use etcd_client::Identity;
use etcd_client::TlsOptions;
use serde::Deserialize;
use tokio::sync::OnceCell;

use crate::raw::adapters::kv;
Expand All @@ -37,45 +38,47 @@ use crate::*;

const DEFAULT_ETCD_ENDPOINTS: &str = "http://127.0.0.1:2379";

/// [Etcd](https://etcd.io/) services support.
#[doc = include_str!("docs.md")]
#[derive(Clone, Default)]
pub struct EtcdBuilder {
/// Config for Etcd services support.
#[derive(Default, Deserialize, Clone)]
#[serde(default)]
#[non_exhaustive]
pub struct EtcdConfig {
/// network address of the Etcd services.
/// If use https, must set TLS options: `ca_path`, `cert_path`, `key_path`.
/// e.g. "127.0.0.1:23790,127.0.0.1:23791,127.0.0.1:23792" or "http://127.0.0.1:23790,http://127.0.0.1:23791,http://127.0.0.1:23792" or "https://127.0.0.1:23790,https://127.0.0.1:23791,https://127.0.0.1:23792"
///
/// default is "http://127.0.0.1:2379"
endpoints: Option<String>,
pub endpoints: Option<String>,
/// the username to connect etcd service.
///
/// default is None
username: Option<String>,
pub username: Option<String>,
/// the password for authentication
///
/// default is None
password: Option<String>,
pub password: Option<String>,
/// the working directory of the etcd service. Can be "/path/to/dir"
///
/// default is "/"
root: Option<String>,
pub root: Option<String>,
/// certificate authority file path
///
/// default is None
ca_path: Option<String>,
pub ca_path: Option<String>,
/// cert path
///
/// default is None
cert_path: Option<String>,
pub cert_path: Option<String>,
/// key path
///
/// default is None
key_path: Option<String>,
pub key_path: Option<String>,
}

impl Debug for EtcdBuilder {
impl Debug for EtcdConfig {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
let mut ds = f.debug_struct("Builder");
let mut ds = f.debug_struct("EtcdConfig");

ds.field("root", &self.root);
if let Some(endpoints) = self.endpoints.clone() {
ds.field("endpoints", &endpoints);
Expand All @@ -86,6 +89,31 @@ impl Debug for EtcdBuilder {
if self.password.is_some() {
ds.field("password", &"<redacted>");
}
if let Some(ca_path) = self.ca_path.clone() {
ds.field("ca_path", &ca_path);
}
if let Some(cert_path) = self.cert_path.clone() {
ds.field("cert_path", &cert_path);
}
if let Some(key_path) = self.key_path.clone() {
ds.field("key_path", &key_path);
}
ds.finish()
}
}

/// [Etcd](https://etcd.io/) services support.
#[doc = include_str!("docs.md")]
#[derive(Clone, Default)]
pub struct EtcdBuilder {
config: EtcdConfig,
}

impl Debug for EtcdBuilder {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
let mut ds = f.debug_struct("Builder");

ds.field("config", &self.config);
ds.finish()
}
}
Expand All @@ -96,7 +124,7 @@ impl EtcdBuilder {
/// default: "http://127.0.0.1:2379"
pub fn endpoints(&mut self, endpoints: &str) -> &mut Self {
if !endpoints.is_empty() {
self.endpoints = Some(endpoints.to_owned());
self.config.endpoints = Some(endpoints.to_owned());
}
self
}
Expand All @@ -106,7 +134,7 @@ impl EtcdBuilder {
/// default: no username
pub fn username(&mut self, username: &str) -> &mut Self {
if !username.is_empty() {
self.username = Some(username.to_owned());
self.config.username = Some(username.to_owned());
}
self
}
Expand All @@ -116,7 +144,7 @@ impl EtcdBuilder {
/// default: no password
pub fn password(&mut self, password: &str) -> &mut Self {
if !password.is_empty() {
self.password = Some(password.to_owned());
self.config.password = Some(password.to_owned());
}
self
}
Expand All @@ -126,7 +154,7 @@ impl EtcdBuilder {
/// default: "/"
pub fn root(&mut self, root: &str) -> &mut Self {
if !root.is_empty() {
self.root = Some(root.to_owned());
self.config.root = Some(root.to_owned());
}
self
}
Expand All @@ -136,7 +164,7 @@ impl EtcdBuilder {
/// default is None
pub fn ca_path(&mut self, ca_path: &str) -> &mut Self {
if !ca_path.is_empty() {
self.ca_path = Some(ca_path.to_string())
self.config.ca_path = Some(ca_path.to_string())
}
self
}
Expand All @@ -146,7 +174,7 @@ impl EtcdBuilder {
/// default is None
pub fn cert_path(&mut self, cert_path: &str) -> &mut Self {
if !cert_path.is_empty() {
self.cert_path = Some(cert_path.to_string())
self.config.cert_path = Some(cert_path.to_string())
}
self
}
Expand All @@ -156,7 +184,7 @@ impl EtcdBuilder {
/// default is None
pub fn key_path(&mut self, key_path: &str) -> &mut Self {
if !key_path.is_empty() {
self.key_path = Some(key_path.to_string())
self.config.key_path = Some(key_path.to_string())
}
self
}
Expand All @@ -182,6 +210,7 @@ impl Builder for EtcdBuilder {

fn build(&mut self) -> Result<Self::Accessor> {
let endpoints = self
.config
.endpoints
.clone()
.unwrap_or_else(|| DEFAULT_ETCD_ENDPOINTS.to_string());
Expand All @@ -190,23 +219,30 @@ impl Builder for EtcdBuilder {

let mut options = ConnectOptions::new();

if self.ca_path.is_some() && self.cert_path.is_some() && self.key_path.is_some() {
let ca = self.load_pem(self.ca_path.clone().unwrap().as_str())?;
let key = self.load_pem(self.key_path.clone().unwrap().as_str())?;
let cert = self.load_pem(self.cert_path.clone().unwrap().as_str())?;
if self.config.ca_path.is_some()
&& self.config.cert_path.is_some()
&& self.config.key_path.is_some()
{
let ca = self.load_pem(self.config.ca_path.clone().unwrap().as_str())?;
let key = self.load_pem(self.config.key_path.clone().unwrap().as_str())?;
let cert = self.load_pem(self.config.cert_path.clone().unwrap().as_str())?;

let tls_options = TlsOptions::default()
.ca_certificate(Certificate::from_pem(ca))
.identity(Identity::from_pem(cert, key));
options = options.with_tls(tls_options);
}

if let Some(username) = self.username.clone() {
options = options.with_user(username, self.password.clone().unwrap_or("".to_string()));
if let Some(username) = self.config.username.clone() {
options = options.with_user(
username,
self.config.password.clone().unwrap_or("".to_string()),
);
}

let root = normalize_root(
self.root
self.config
.root
.clone()
.unwrap_or_else(|| "/".to_string())
.as_str(),
Expand Down
1 change: 1 addition & 0 deletions core/src/services/etcd/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,4 @@

mod backend;
pub use backend::EtcdBuilder as Etcd;
pub use backend::EtcdConfig;
2 changes: 2 additions & 0 deletions core/src/services/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ pub use self::dashmap::Dashmap;
mod etcd;
#[cfg(feature = "services-etcd")]
pub use self::etcd::Etcd;
#[cfg(feature = "services-etcd")]
pub use self::etcd::EtcdConfig;

#[cfg(feature = "services-fs")]
mod fs;
Expand Down

0 comments on commit 60b4d3a

Please sign in to comment.