opendal_service_etcd/config.rs
1// Licensed to the Apache Software Foundation (ASF) under one
2// or more contributor license agreements. See the NOTICE file
3// distributed with this work for additional information
4// regarding copyright ownership. The ASF licenses this file
5// to you under the Apache License, Version 2.0 (the
6// "License"); you may not use this file except in compliance
7// with the License. You may obtain a copy of the License at
8//
9// http://www.apache.org/licenses/LICENSE-2.0
10//
11// Unless required by applicable law or agreed to in writing,
12// software distributed under the License is distributed on an
13// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14// KIND, either express or implied. See the License for the
15// specific language governing permissions and limitations
16// under the License.
17
18use std::fmt::Debug;
19
20use serde::Deserialize;
21use serde::Serialize;
22
23use super::backend::EtcdBuilder;
24
25/// Config for Etcd services support.
26#[derive(Default, Serialize, Deserialize, Clone, PartialEq, Eq)]
27#[serde(default)]
28#[non_exhaustive]
29pub struct EtcdConfig {
30 /// network address of the Etcd services.
31 /// If use https, must set TLS options: `ca_path`, `cert_path`, `key_path`.
32 /// 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"
33 ///
34 /// default is "http://127.0.0.1:2379"
35 pub endpoints: Option<String>,
36 /// the username to connect etcd service.
37 ///
38 /// default is None
39 pub username: Option<String>,
40 /// the password for authentication
41 ///
42 /// default is None
43 pub password: Option<String>,
44 /// the working directory of the etcd service. Can be "/path/to/dir"
45 ///
46 /// default is "/"
47 pub root: Option<String>,
48 /// certificate authority file path
49 ///
50 /// default is None
51 pub ca_path: Option<String>,
52 /// cert path
53 ///
54 /// default is None
55 pub cert_path: Option<String>,
56 /// key path
57 ///
58 /// default is None
59 pub key_path: Option<String>,
60 /// the maximum size in bytes of a gRPC response that the etcd client decodes.
61 ///
62 /// Set this to read values larger than the etcd client's own limit. The etcd
63 /// server must also allow responses of that size.
64 ///
65 /// Refer to [`etcd_client::KvClient::max_decoding_message_size`](https://docs.rs/etcd-client/latest/etcd_client/struct.KvClient.html#method.max_decoding_message_size)
66 ///
67 /// default is None, which keeps the etcd client default of 4 MiB
68 pub max_decoding_message_size: Option<usize>,
69}
70
71impl Debug for EtcdConfig {
72 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
73 f.debug_struct("EtcdConfig")
74 .field("root", &self.root)
75 .field("endpoints", &self.endpoints)
76 .field("username", &self.username)
77 .field("ca_path", &self.ca_path)
78 .field("cert_path", &self.cert_path)
79 .field("key_path", &self.key_path)
80 .field("max_decoding_message_size", &self.max_decoding_message_size)
81 .finish_non_exhaustive()
82 }
83}
84
85impl opendal_core::Configurator for EtcdConfig {
86 type Builder = EtcdBuilder;
87
88 fn from_uri(uri: &opendal_core::OperatorUri) -> opendal_core::Result<Self> {
89 let mut map = uri.options().clone();
90
91 if let Some(authority) = uri.authority() {
92 map.entry("endpoints".to_string())
93 .or_insert_with(|| format!("http://{authority}"));
94 }
95
96 if let Some(root) = uri.root()
97 && !root.is_empty()
98 {
99 map.insert("root".to_string(), root.to_string());
100 }
101
102 Self::from_iter(map)
103 }
104
105 fn into_builder(self) -> Self::Builder {
106 EtcdBuilder { config: self }
107 }
108}
109
110#[cfg(test)]
111mod tests {
112 use super::*;
113 use opendal_core::Configurator;
114 use opendal_core::OperatorUri;
115
116 #[test]
117 fn from_uri_sets_endpoints_and_root() {
118 let uri = OperatorUri::new(
119 "etcd://127.0.0.1:2379/app/config",
120 Vec::<(String, String)>::new(),
121 )
122 .unwrap();
123
124 let cfg = EtcdConfig::from_uri(&uri).unwrap();
125 assert_eq!(cfg.endpoints.as_deref(), Some("http://127.0.0.1:2379"));
126 assert_eq!(cfg.root.as_deref(), Some("app/config"));
127 }
128}