Add TLS support, initial etcd connection check, fix key_prefix handling for etcd backend meta storage (#5403)

This commit is contained in:
Nikita Borzykh 2024-03-24 18:36:21 +03:00 committed by GitHub
parent dc9568fc0d
commit 1f3742850d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 58 additions and 23 deletions

View File

@ -30,6 +30,7 @@ services:
environment:
WEED_LEVELDB2_ENABLED: 'false'
WEED_ETCD_ENABLED: 'true'
WEED_ETCD_KEY_PREFIX: 'seaweedfs.'
WEED_ETCD_SERVERS: "http://etcd:2379"
volumes:
- ./s3.json:/etc/seaweedfs/s3.json

View File

@ -270,6 +270,12 @@ username = ""
password = ""
key_prefix = "seaweedfs."
timeout = "3s"
# Set the CA certificate path
tls_ca_file=""
# Set the client certificate path
tls_client_crt_file=""
# Set the client private key path
tls_client_key_file=""
[mongodb]
enabled = false

View File

@ -1,9 +1,10 @@
package etcd
import (
"bytes"
"context"
"crypto/tls"
"fmt"
"go.etcd.io/etcd/client/pkg/v3/transport"
"strings"
"time"
@ -26,49 +27,78 @@ func init() {
type EtcdStore struct {
client *clientv3.Client
etcdKeyPrefix string
timeout time.Duration
}
func (store *EtcdStore) GetName() string {
return "etcd"
}
func (store *EtcdStore) Initialize(configuration weed_util.Configuration, prefix string) (err error) {
func (store *EtcdStore) Initialize(configuration weed_util.Configuration, prefix string) error {
configuration.SetDefault(prefix+"servers", "localhost:2379")
configuration.SetDefault(prefix+"timeout", "3s")
servers := configuration.GetString(prefix + "servers")
if servers == "" {
servers = "localhost:2379"
}
username := configuration.GetString(prefix + "username")
password := configuration.GetString(prefix + "password")
store.etcdKeyPrefix = configuration.GetString(prefix + "key_prefix")
timeout := configuration.GetString(prefix + "timeout")
if timeout == "" {
timeout = "3s"
timeoutStr := configuration.GetString(prefix + "timeout")
timeout, err := time.ParseDuration(timeoutStr)
if err != nil {
return fmt.Errorf("parse etcd store timeout: %v", err)
}
store.timeout = timeout
certFile := configuration.GetString(prefix + "tls_client_crt_file")
keyFile := configuration.GetString(prefix + "tls_client_key_file")
caFile := configuration.GetString(prefix + "tls_ca_file")
var tlsConfig *tls.Config
if caFile != "" {
tlsInfo := transport.TLSInfo{
CertFile: certFile,
KeyFile: keyFile,
TrustedCAFile: caFile,
}
var err error
tlsConfig, err = tlsInfo.ClientConfig()
if err != nil {
return fmt.Errorf("TLS client configuration error: %v", err)
}
}
return store.initialize(servers, username, password, timeout)
return store.initialize(servers, username, password, store.timeout, tlsConfig)
}
func (store *EtcdStore) initialize(servers string, username string, password string, timeout string) (err error) {
func (store *EtcdStore) initialize(servers, username, password string, timeout time.Duration, tlsConfig *tls.Config) error {
glog.Infof("filer store etcd: %s", servers)
to, err := time.ParseDuration(timeout)
if err != nil {
return fmt.Errorf("parse timeout %s: %s", timeout, err)
}
store.client, err = clientv3.New(clientv3.Config{
client, err := clientv3.New(clientv3.Config{
Endpoints: strings.Split(servers, ","),
Username: username,
Password: password,
DialTimeout: to,
DialTimeout: timeout,
TLS: tlsConfig,
})
if err != nil {
return fmt.Errorf("connect to etcd %s: %s", servers, err)
}
return
ctx, cancel := context.WithTimeout(context.Background(), store.timeout)
defer cancel()
resp, err := client.Status(ctx, client.Endpoints()[0])
if err != nil {
client.Close()
return fmt.Errorf("error checking etcd connection: %s", err)
}
glog.V(0).Infof("сonnection to etcd has been successfully verified. etcd version: %s", resp.Version)
store.client = client
return nil
}
func (store *EtcdStore) BeginTransaction(ctx context.Context) (context.Context, error) {
@ -159,15 +189,13 @@ func (store *EtcdStore) ListDirectoryEntries(ctx context.Context, dirPath weed_u
}
resp, err := store.client.Get(ctx, store.etcdKeyPrefix+string(lastFileStart),
clientv3.WithFromKey(), clientv3.WithLimit(limit+1))
clientv3.WithRange(clientv3.GetPrefixRangeEnd(store.etcdKeyPrefix+string(directoryPrefix))),
clientv3.WithLimit(limit+1))
if err != nil {
return lastFileName, fmt.Errorf("list %s : %v", dirPath, err)
}
for _, kv := range resp.Kvs {
if !bytes.HasPrefix(kv.Key, directoryPrefix) {
break
}
fileName := getNameFromKey(kv.Key)
if fileName == "" {
continue

View File

@ -10,7 +10,7 @@ func TestStore(t *testing.T) {
// to set up local env
if false {
store := &EtcdStore{}
store.initialize("localhost:2379", "", "", "3s")
store.initialize("localhost:2379", "", "", 3, nil)
store_test.TestFilerStore(t, store)
}
}