configMap() {
@RequiredArgsConstructor(access = AccessLevel.PRIVATE)
class Etcd implements ServiceConfig {
/**
- * certificate authority file path
+ * PEM certificate authority file used to verify the server.
+ * Enables TLS independently of cert_path and key_path.
* default is None
*/
public final String caPath;
/**
- * cert path
+ * PEM client certificate file used for mutual TLS.
+ * Must be configured together with key_path.
* default is None
*/
public final String certPath;
/**
* network address of the Etcd services.
- * If use https, must set TLS options: ca_path, cert_path, key_path.
+ * Use HTTPS endpoints for TLS. Set ca_path to trust a custom certificate authority.
+ * Client authentication additionally requires both cert_path and 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"
*/
public final String endpoints;
/**
- * key path
+ * PEM client private key file used for mutual TLS.
+ * Must be configured together with cert_path.
* default is None
*/
public final String keyPath;
diff --git a/core/services/etcd/src/backend.rs b/core/services/etcd/src/backend.rs
index d199a17e0760..59883a033153 100644
--- a/core/services/etcd/src/backend.rs
+++ b/core/services/etcd/src/backend.rs
@@ -84,9 +84,12 @@ impl EtcdBuilder {
self
}
- /// Set the certificate authority file path.
+ /// Set the PEM certificate authority file used to verify the server.
///
- /// default is None
+ /// This enables TLS without requiring a client certificate or private key.
+ /// Use HTTPS endpoints when configuring TLS.
+ ///
+ /// No custom certificate authority is configured by default.
pub fn ca_path(mut self, ca_path: &str) -> Self {
if !ca_path.is_empty() {
self.config.ca_path = Some(ca_path.to_string())
@@ -94,9 +97,12 @@ impl EtcdBuilder {
self
}
- /// Set the certificate file path.
+ /// Set the PEM client certificate file used for mutual TLS.
+ ///
+ /// Set this together with [`Self::key_path`]. Building an operator with
+ /// only one of these paths returns [`ErrorKind::ConfigInvalid`].
///
- /// default is None
+ /// No client certificate is configured by default.
pub fn cert_path(mut self, cert_path: &str) -> Self {
if !cert_path.is_empty() {
self.config.cert_path = Some(cert_path.to_string())
@@ -104,9 +110,12 @@ impl EtcdBuilder {
self
}
- /// Set the key file path.
+ /// Set the PEM client private key file used for mutual TLS.
///
- /// default is None
+ /// Set this together with [`Self::cert_path`]. Building an operator with
+ /// only one of these paths returns [`ErrorKind::ConfigInvalid`].
+ ///
+ /// No client private key is configured by default.
pub fn key_path(mut self, key_path: &str) -> Self {
if !key_path.is_empty() {
self.config.key_path = Some(key_path.to_string())
@@ -137,17 +146,28 @@ impl Builder for EtcdBuilder {
let mut options = ConnectOptions::new();
- 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));
+ if self.config.cert_path.is_some() != self.config.key_path.is_some() {
+ return Err(Error::new(
+ ErrorKind::ConfigInvalid,
+ "cert_path and key_path must be configured together",
+ )
+ .with_operation("Builder::build")
+ .with_context("service", ETCD_SCHEME));
+ }
+
+ if self.config.ca_path.is_some() || self.config.cert_path.is_some() {
+ let mut tls_options = TlsOptions::default();
+ if let Some(path) = &self.config.ca_path {
+ let ca = self.load_pem(path)?;
+ tls_options = tls_options.ca_certificate(Certificate::from_pem(ca));
+ }
+ if let (Some(cert_path), Some(key_path)) =
+ (&self.config.cert_path, &self.config.key_path)
+ {
+ let cert = self.load_pem(cert_path)?;
+ let key = self.load_pem(key_path)?;
+ tls_options = tls_options.identity(Identity::from_pem(cert, key));
+ }
options = options.with_tls(tls_options);
}
@@ -178,6 +198,31 @@ impl EtcdBuilder {
}
}
+#[cfg(test)]
+mod tests {
+ use super::*;
+
+ #[test]
+ fn incomplete_client_identity_is_rejected() {
+ for ca_path in [None, Some("ca.pem")] {
+ for (cert_path, key_path) in
+ [(Some("client.pem"), None), (None, Some("client-key.pem"))]
+ {
+ let config = EtcdConfig {
+ ca_path: ca_path.map(str::to_owned),
+ cert_path: cert_path.map(str::to_owned),
+ key_path: key_path.map(str::to_owned),
+ ..Default::default()
+ };
+ let err = Operator::from_config(config).expect_err(
+ "incomplete client identity must fail before reading certificate files",
+ );
+ assert_eq!(err.kind(), ErrorKind::ConfigInvalid);
+ }
+ }
+ }
+}
+
#[derive(Debug, Clone)]
pub struct EtcdBackend {
pub(crate) core: Arc,
diff --git a/core/services/etcd/src/config.rs b/core/services/etcd/src/config.rs
index 4bf7ded0d920..6eda92ef3791 100644
--- a/core/services/etcd/src/config.rs
+++ b/core/services/etcd/src/config.rs
@@ -28,7 +28,8 @@ use super::backend::EtcdBuilder;
#[non_exhaustive]
pub struct EtcdConfig {
/// network address of the Etcd services.
- /// If use https, must set TLS options: `ca_path`, `cert_path`, `key_path`.
+ /// Use HTTPS endpoints for TLS. Set `ca_path` to trust a custom certificate authority.
+ /// Client authentication additionally requires both `cert_path` and `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"
@@ -45,15 +46,18 @@ pub struct EtcdConfig {
///
/// default is "/"
pub root: Option,
- /// certificate authority file path
+ /// PEM certificate authority file used to verify the server.
+ /// Enables TLS independently of `cert_path` and `key_path`.
///
/// default is None
pub ca_path: Option,
- /// cert path
+ /// PEM client certificate file used for mutual TLS.
+ /// Must be configured together with `key_path`.
///
/// default is None
pub cert_path: Option,
- /// key path
+ /// PEM client private key file used for mutual TLS.
+ /// Must be configured together with `cert_path`.
///
/// default is None
pub key_path: Option,
diff --git a/core/services/etcd/src/docs.md b/core/services/etcd/src/docs.md
index d38ea007c017..a7bc8dd343f1 100644
--- a/core/services/etcd/src/docs.md
+++ b/core/services/etcd/src/docs.md
@@ -21,6 +21,8 @@ Use [`crate::EtcdConfig`] for serializable configuration and this builder's
methods for direct construction. The field and method documentation defines
accepted values, defaults, and environment interaction.
+For server-authenticated TLS, configure an HTTPS endpoint and `ca_path`. The server certificate must be trusted by the supplied CA. For mutual TLS, also configure `cert_path` and `key_path`; these two paths must always be supplied together.
+
## Example
### Via Builder
diff --git a/fixtures/etcd/docker-compose-standalone-server-tls.yml b/fixtures/etcd/docker-compose-standalone-server-tls.yml
new file mode 100644
index 000000000000..d10cdd4e84f0
--- /dev/null
+++ b/fixtures/etcd/docker-compose-standalone-server-tls.yml
@@ -0,0 +1,47 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+services:
+ etcd:
+ image: gcr.io/etcd-development/etcd:v3.6.4
+ ports:
+ - "2379:2379"
+ volumes:
+ - ./ca.pem:/etc/etcd/certs/ca.pem:ro
+ - ./server.pem:/etc/etcd/certs/server.pem:ro
+ - ./server-key.pem:/etc/etcd/certs/server-key.pem:ro
+ command:
+ - /usr/local/bin/etcd
+ - --name=etcd
+ - --listen-client-urls=https://0.0.0.0:2379
+ - --advertise-client-urls=https://127.0.0.1:2379
+ - --max-request-bytes=10485760
+ - --client-cert-auth=false
+ - --cert-file=/etc/etcd/certs/server.pem
+ - --key-file=/etc/etcd/certs/server-key.pem
+ healthcheck:
+ test: [
+ "CMD",
+ "/usr/local/bin/etcdctl",
+ "endpoint", "health",
+ "--endpoints=https://127.0.0.1:2379",
+ "--cacert=/etc/etcd/certs/ca.pem"
+ ]
+ interval: 30s
+ timeout: 20s
+ retries: 5
+ start_period: 40s
diff --git a/website/data/services.json b/website/data/services.json
index 50b778d526ab..d3aa21b40c95 100644
--- a/website/data/services.json
+++ b/website/data/services.json
@@ -1122,7 +1122,7 @@
"type": "string",
"required": false,
"group": "General",
- "comments": "network address of the Etcd services.\nIf use https, must set TLS options: `ca_path`, `cert_path`, `key_path`.\ne.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\"\n\ndefault is \"http://127.0.0.1:2379\""
+ "comments": "network address of the Etcd services.\nUse HTTPS endpoints for TLS. Set `ca_path` to trust a custom certificate authority.\nClient authentication additionally requires both `cert_path` and `key_path`.\ne.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\"\n\ndefault is \"http://127.0.0.1:2379\""
},
{
"name": "username",
@@ -1150,21 +1150,21 @@
"type": "string",
"required": false,
"group": "General",
- "comments": "certificate authority file path\n\ndefault is None"
+ "comments": "PEM certificate authority file used to verify the server.\nEnables TLS independently of `cert_path` and `key_path`.\n\ndefault is None"
},
{
"name": "cert_path",
"type": "string",
"required": false,
"group": "General",
- "comments": "cert path\n\ndefault is None"
+ "comments": "PEM client certificate file used for mutual TLS.\nMust be configured together with `key_path`.\n\ndefault is None"
},
{
"name": "key_path",
"type": "string",
"required": false,
"group": "General",
- "comments": "key path\n\ndefault is None"
+ "comments": "PEM client private key file used for mutual TLS.\nMust be configured together with `cert_path`.\n\ndefault is None"
},
{
"name": "max_decoding_message_size",
@@ -1179,31 +1179,31 @@
"binding": "rust",
"language": "rust",
"minimal": "use opendal::Operator;\n\nlet operator = Operator::via_iter(\"etcd\", [\n])?;",
- "full": "use opendal::Operator;\n\nlet operator = Operator::via_iter(\"etcd\", [\n // network address of the Etcd services.\n // If use https, must set TLS options: `ca_path`, `cert_path`, `key_path`.\n // 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\"\n //\n // default is \"http://127.0.0.1:2379\"\n // (\"endpoints\".to_string(), \"...\".to_string()),\n\n // the username to connect etcd service.\n //\n // default is None\n // (\"username\".to_string(), \"...\".to_string()),\n\n // the password for authentication\n //\n // default is None\n // (\"password\".to_string(), \"...\".to_string()),\n\n // the working directory of the etcd service. Can be \"/path/to/dir\"\n //\n // default is \"/\"\n // (\"root\".to_string(), \"...\".to_string()),\n\n // certificate authority file path\n //\n // default is None\n // (\"ca_path\".to_string(), \"...\".to_string()),\n\n // cert path\n //\n // default is None\n // (\"cert_path\".to_string(), \"...\".to_string()),\n\n // key path\n //\n // default is None\n // (\"key_path\".to_string(), \"...\".to_string()),\n\n // the maximum size in bytes of a gRPC response that the etcd client decodes.\n //\n // Set this to read values larger than the etcd client's own limit. The etcd\n // server must also allow responses of that size.\n //\n // 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)\n //\n // default is None, which keeps the etcd client default of 4 MiB\n // (\"max_decoding_message_size\".to_string(), \"1000\".to_string()),\n])?;"
+ "full": "use opendal::Operator;\n\nlet operator = Operator::via_iter(\"etcd\", [\n // network address of the Etcd services.\n // Use HTTPS endpoints for TLS. Set `ca_path` to trust a custom certificate authority.\n // Client authentication additionally requires both `cert_path` and `key_path`.\n // 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\"\n //\n // default is \"http://127.0.0.1:2379\"\n // (\"endpoints\".to_string(), \"...\".to_string()),\n\n // the username to connect etcd service.\n //\n // default is None\n // (\"username\".to_string(), \"...\".to_string()),\n\n // the password for authentication\n //\n // default is None\n // (\"password\".to_string(), \"...\".to_string()),\n\n // the working directory of the etcd service. Can be \"/path/to/dir\"\n //\n // default is \"/\"\n // (\"root\".to_string(), \"...\".to_string()),\n\n // PEM certificate authority file used to verify the server.\n // Enables TLS independently of `cert_path` and `key_path`.\n //\n // default is None\n // (\"ca_path\".to_string(), \"...\".to_string()),\n\n // PEM client certificate file used for mutual TLS.\n // Must be configured together with `key_path`.\n //\n // default is None\n // (\"cert_path\".to_string(), \"...\".to_string()),\n\n // PEM client private key file used for mutual TLS.\n // Must be configured together with `cert_path`.\n //\n // default is None\n // (\"key_path\".to_string(), \"...\".to_string()),\n\n // the maximum size in bytes of a gRPC response that the etcd client decodes.\n //\n // Set this to read values larger than the etcd client's own limit. The etcd\n // server must also allow responses of that size.\n //\n // 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)\n //\n // default is None, which keeps the etcd client default of 4 MiB\n // (\"max_decoding_message_size\".to_string(), \"1000\".to_string()),\n])?;"
},
{
"binding": "java",
"language": "java",
"minimal": "import java.util.HashMap;\nimport java.util.Map;\nimport org.apache.opendal.Operator;\n\nMap config = new HashMap<>();\nOperator operator = Operator.of(\"etcd\", config);",
- "full": "import java.util.HashMap;\nimport java.util.Map;\nimport org.apache.opendal.Operator;\n\nMap config = new HashMap<>();\n// network address of the Etcd services.\n// If use https, must set TLS options: `ca_path`, `cert_path`, `key_path`.\n// 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\"\n//\n// default is \"http://127.0.0.1:2379\"\n// config.put(\"endpoints\", \"...\");\n\n// the username to connect etcd service.\n//\n// default is None\n// config.put(\"username\", \"...\");\n\n// the password for authentication\n//\n// default is None\n// config.put(\"password\", \"...\");\n\n// the working directory of the etcd service. Can be \"/path/to/dir\"\n//\n// default is \"/\"\n// config.put(\"root\", \"...\");\n\n// certificate authority file path\n//\n// default is None\n// config.put(\"ca_path\", \"...\");\n\n// cert path\n//\n// default is None\n// config.put(\"cert_path\", \"...\");\n\n// key path\n//\n// default is None\n// config.put(\"key_path\", \"...\");\n\n// the maximum size in bytes of a gRPC response that the etcd client decodes.\n//\n// Set this to read values larger than the etcd client's own limit. The etcd\n// server must also allow responses of that size.\n//\n// 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)\n//\n// default is None, which keeps the etcd client default of 4 MiB\n// config.put(\"max_decoding_message_size\", \"1000\");\nOperator operator = Operator.of(\"etcd\", config);"
+ "full": "import java.util.HashMap;\nimport java.util.Map;\nimport org.apache.opendal.Operator;\n\nMap config = new HashMap<>();\n// network address of the Etcd services.\n// Use HTTPS endpoints for TLS. Set `ca_path` to trust a custom certificate authority.\n// Client authentication additionally requires both `cert_path` and `key_path`.\n// 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\"\n//\n// default is \"http://127.0.0.1:2379\"\n// config.put(\"endpoints\", \"...\");\n\n// the username to connect etcd service.\n//\n// default is None\n// config.put(\"username\", \"...\");\n\n// the password for authentication\n//\n// default is None\n// config.put(\"password\", \"...\");\n\n// the working directory of the etcd service. Can be \"/path/to/dir\"\n//\n// default is \"/\"\n// config.put(\"root\", \"...\");\n\n// PEM certificate authority file used to verify the server.\n// Enables TLS independently of `cert_path` and `key_path`.\n//\n// default is None\n// config.put(\"ca_path\", \"...\");\n\n// PEM client certificate file used for mutual TLS.\n// Must be configured together with `key_path`.\n//\n// default is None\n// config.put(\"cert_path\", \"...\");\n\n// PEM client private key file used for mutual TLS.\n// Must be configured together with `cert_path`.\n//\n// default is None\n// config.put(\"key_path\", \"...\");\n\n// the maximum size in bytes of a gRPC response that the etcd client decodes.\n//\n// Set this to read values larger than the etcd client's own limit. The etcd\n// server must also allow responses of that size.\n//\n// 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)\n//\n// default is None, which keeps the etcd client default of 4 MiB\n// config.put(\"max_decoding_message_size\", \"1000\");\nOperator operator = Operator.of(\"etcd\", config);"
},
{
"binding": "python",
"language": "python",
"minimal": "import opendal\n\noperator = opendal.Operator(\n \"etcd\",\n)",
- "full": "import opendal\n\noperator = opendal.Operator(\n \"etcd\",\n # network address of the Etcd services.\n # If use https, must set TLS options: `ca_path`, `cert_path`, `key_path`.\n # 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\"\n #\n # default is \"http://127.0.0.1:2379\"\n # endpoints=\"...\",\n\n # the username to connect etcd service.\n #\n # default is None\n # username=\"...\",\n\n # the password for authentication\n #\n # default is None\n # password=\"...\",\n\n # the working directory of the etcd service. Can be \"/path/to/dir\"\n #\n # default is \"/\"\n # root=\"...\",\n\n # certificate authority file path\n #\n # default is None\n # ca_path=\"...\",\n\n # cert path\n #\n # default is None\n # cert_path=\"...\",\n\n # key path\n #\n # default is None\n # key_path=\"...\",\n\n # the maximum size in bytes of a gRPC response that the etcd client decodes.\n #\n # Set this to read values larger than the etcd client's own limit. The etcd\n # server must also allow responses of that size.\n #\n # 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)\n #\n # default is None, which keeps the etcd client default of 4 MiB\n # max_decoding_message_size=\"1000\",\n)"
+ "full": "import opendal\n\noperator = opendal.Operator(\n \"etcd\",\n # network address of the Etcd services.\n # Use HTTPS endpoints for TLS. Set `ca_path` to trust a custom certificate authority.\n # Client authentication additionally requires both `cert_path` and `key_path`.\n # 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\"\n #\n # default is \"http://127.0.0.1:2379\"\n # endpoints=\"...\",\n\n # the username to connect etcd service.\n #\n # default is None\n # username=\"...\",\n\n # the password for authentication\n #\n # default is None\n # password=\"...\",\n\n # the working directory of the etcd service. Can be \"/path/to/dir\"\n #\n # default is \"/\"\n # root=\"...\",\n\n # PEM certificate authority file used to verify the server.\n # Enables TLS independently of `cert_path` and `key_path`.\n #\n # default is None\n # ca_path=\"...\",\n\n # PEM client certificate file used for mutual TLS.\n # Must be configured together with `key_path`.\n #\n # default is None\n # cert_path=\"...\",\n\n # PEM client private key file used for mutual TLS.\n # Must be configured together with `cert_path`.\n #\n # default is None\n # key_path=\"...\",\n\n # the maximum size in bytes of a gRPC response that the etcd client decodes.\n #\n # Set this to read values larger than the etcd client's own limit. The etcd\n # server must also allow responses of that size.\n #\n # 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)\n #\n # default is None, which keeps the etcd client default of 4 MiB\n # max_decoding_message_size=\"1000\",\n)"
},
{
"binding": "nodejs",
"language": "javascript",
"minimal": "import { Operator } from \"opendal\";\n\nconst operator = new Operator(\"etcd\", {\n});",
- "full": "import { Operator } from \"opendal\";\n\nconst operator = new Operator(\"etcd\", {\n // network address of the Etcd services.\n // If use https, must set TLS options: `ca_path`, `cert_path`, `key_path`.\n // 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\"\n //\n // default is \"http://127.0.0.1:2379\"\n // endpoints: \"...\",\n\n // the username to connect etcd service.\n //\n // default is None\n // username: \"...\",\n\n // the password for authentication\n //\n // default is None\n // password: \"...\",\n\n // the working directory of the etcd service. Can be \"/path/to/dir\"\n //\n // default is \"/\"\n // root: \"...\",\n\n // certificate authority file path\n //\n // default is None\n // ca_path: \"...\",\n\n // cert path\n //\n // default is None\n // cert_path: \"...\",\n\n // key path\n //\n // default is None\n // key_path: \"...\",\n\n // the maximum size in bytes of a gRPC response that the etcd client decodes.\n //\n // Set this to read values larger than the etcd client's own limit. The etcd\n // server must also allow responses of that size.\n //\n // 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)\n //\n // default is None, which keeps the etcd client default of 4 MiB\n // max_decoding_message_size: \"1000\",\n});"
+ "full": "import { Operator } from \"opendal\";\n\nconst operator = new Operator(\"etcd\", {\n // network address of the Etcd services.\n // Use HTTPS endpoints for TLS. Set `ca_path` to trust a custom certificate authority.\n // Client authentication additionally requires both `cert_path` and `key_path`.\n // 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\"\n //\n // default is \"http://127.0.0.1:2379\"\n // endpoints: \"...\",\n\n // the username to connect etcd service.\n //\n // default is None\n // username: \"...\",\n\n // the password for authentication\n //\n // default is None\n // password: \"...\",\n\n // the working directory of the etcd service. Can be \"/path/to/dir\"\n //\n // default is \"/\"\n // root: \"...\",\n\n // PEM certificate authority file used to verify the server.\n // Enables TLS independently of `cert_path` and `key_path`.\n //\n // default is None\n // ca_path: \"...\",\n\n // PEM client certificate file used for mutual TLS.\n // Must be configured together with `key_path`.\n //\n // default is None\n // cert_path: \"...\",\n\n // PEM client private key file used for mutual TLS.\n // Must be configured together with `cert_path`.\n //\n // default is None\n // key_path: \"...\",\n\n // the maximum size in bytes of a gRPC response that the etcd client decodes.\n //\n // Set this to read values larger than the etcd client's own limit. The etcd\n // server must also allow responses of that size.\n //\n // 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)\n //\n // default is None, which keeps the etcd client default of 4 MiB\n // max_decoding_message_size: \"1000\",\n});"
},
{
"binding": "go",
"language": "go",
"minimal": "import (\n\t\"github.com/apache/opendal-go-services/etcd\"\n\topendal \"github.com/apache/opendal/bindings/go\"\n)\n\noperator, err := opendal.NewOperator(etcd.Scheme, opendal.OperatorOptions{\n})",
- "full": "import (\n\t\"github.com/apache/opendal-go-services/etcd\"\n\topendal \"github.com/apache/opendal/bindings/go\"\n)\n\noperator, err := opendal.NewOperator(etcd.Scheme, opendal.OperatorOptions{\n\t// network address of the Etcd services.\n\t// If use https, must set TLS options: `ca_path`, `cert_path`, `key_path`.\n\t// 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\"\n\t//\n\t// default is \"http://127.0.0.1:2379\"\n\t// \"endpoints\": \"...\",\n\n\t// the username to connect etcd service.\n\t//\n\t// default is None\n\t// \"username\": \"...\",\n\n\t// the password for authentication\n\t//\n\t// default is None\n\t// \"password\": \"...\",\n\n\t// the working directory of the etcd service. Can be \"/path/to/dir\"\n\t//\n\t// default is \"/\"\n\t// \"root\": \"...\",\n\n\t// certificate authority file path\n\t//\n\t// default is None\n\t// \"ca_path\": \"...\",\n\n\t// cert path\n\t//\n\t// default is None\n\t// \"cert_path\": \"...\",\n\n\t// key path\n\t//\n\t// default is None\n\t// \"key_path\": \"...\",\n\n\t// the maximum size in bytes of a gRPC response that the etcd client decodes.\n\t//\n\t// Set this to read values larger than the etcd client's own limit. The etcd\n\t// server must also allow responses of that size.\n\t//\n\t// 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)\n\t//\n\t// default is None, which keeps the etcd client default of 4 MiB\n\t// \"max_decoding_message_size\": \"1000\",\n})"
+ "full": "import (\n\t\"github.com/apache/opendal-go-services/etcd\"\n\topendal \"github.com/apache/opendal/bindings/go\"\n)\n\noperator, err := opendal.NewOperator(etcd.Scheme, opendal.OperatorOptions{\n\t// network address of the Etcd services.\n\t// Use HTTPS endpoints for TLS. Set `ca_path` to trust a custom certificate authority.\n\t// Client authentication additionally requires both `cert_path` and `key_path`.\n\t// 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\"\n\t//\n\t// default is \"http://127.0.0.1:2379\"\n\t// \"endpoints\": \"...\",\n\n\t// the username to connect etcd service.\n\t//\n\t// default is None\n\t// \"username\": \"...\",\n\n\t// the password for authentication\n\t//\n\t// default is None\n\t// \"password\": \"...\",\n\n\t// the working directory of the etcd service. Can be \"/path/to/dir\"\n\t//\n\t// default is \"/\"\n\t// \"root\": \"...\",\n\n\t// PEM certificate authority file used to verify the server.\n\t// Enables TLS independently of `cert_path` and `key_path`.\n\t//\n\t// default is None\n\t// \"ca_path\": \"...\",\n\n\t// PEM client certificate file used for mutual TLS.\n\t// Must be configured together with `key_path`.\n\t//\n\t// default is None\n\t// \"cert_path\": \"...\",\n\n\t// PEM client private key file used for mutual TLS.\n\t// Must be configured together with `cert_path`.\n\t//\n\t// default is None\n\t// \"key_path\": \"...\",\n\n\t// the maximum size in bytes of a gRPC response that the etcd client decodes.\n\t//\n\t// Set this to read values larger than the etcd client's own limit. The etcd\n\t// server must also allow responses of that size.\n\t//\n\t// 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)\n\t//\n\t// default is None, which keeps the etcd client default of 4 MiB\n\t// \"max_decoding_message_size\": \"1000\",\n})"
}
]
},