Browse Source

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

pull/5416/head
Nikita Borzykh 9 months ago
committed by GitHub
parent
commit
1f3742850d
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 1
      docker/compose/test-etcd-filer.yml
  2. 6
      weed/command/scaffold/filer.toml
  3. 72
      weed/filer/etcd/etcd_store.go
  4. 2
      weed/filer/etcd/etcd_store_test.go

1
docker/compose/test-etcd-filer.yml

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

6
weed/command/scaffold/filer.toml

@ -270,6 +270,12 @@ username = ""
password = "" password = ""
key_prefix = "seaweedfs." key_prefix = "seaweedfs."
timeout = "3s" 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] [mongodb]
enabled = false enabled = false

72
weed/filer/etcd/etcd_store.go

@ -1,9 +1,10 @@
package etcd package etcd
import ( import (
"bytes"
"context" "context"
"crypto/tls"
"fmt" "fmt"
"go.etcd.io/etcd/client/pkg/v3/transport"
"strings" "strings"
"time" "time"
@ -26,49 +27,78 @@ func init() {
type EtcdStore struct { type EtcdStore struct {
client *clientv3.Client client *clientv3.Client
etcdKeyPrefix string etcdKeyPrefix string
timeout time.Duration
} }
func (store *EtcdStore) GetName() string { func (store *EtcdStore) GetName() string {
return "etcd" 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") servers := configuration.GetString(prefix + "servers")
if servers == "" {
servers = "localhost:2379"
}
username := configuration.GetString(prefix + "username") username := configuration.GetString(prefix + "username")
password := configuration.GetString(prefix + "password") password := configuration.GetString(prefix + "password")
store.etcdKeyPrefix = configuration.GetString(prefix + "key_prefix") store.etcdKeyPrefix = configuration.GetString(prefix + "key_prefix")
timeout := configuration.GetString(prefix + "timeout")
if timeout == "" {
timeout = "3s"
}
return store.initialize(servers, username, password, timeout)
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
func (store *EtcdStore) initialize(servers string, username string, password string, timeout string) (err error) {
glog.Infof("filer store etcd: %s", servers)
certFile := configuration.GetString(prefix + "tls_client_crt_file")
keyFile := configuration.GetString(prefix + "tls_client_key_file")
caFile := configuration.GetString(prefix + "tls_ca_file")
to, err := time.ParseDuration(timeout)
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 { if err != nil {
return fmt.Errorf("parse timeout %s: %s", timeout, err)
return fmt.Errorf("TLS client configuration error: %v", err)
}
}
return store.initialize(servers, username, password, store.timeout, tlsConfig)
} }
store.client, err = clientv3.New(clientv3.Config{
func (store *EtcdStore) initialize(servers, username, password string, timeout time.Duration, tlsConfig *tls.Config) error {
glog.Infof("filer store etcd: %s", servers)
client, err := clientv3.New(clientv3.Config{
Endpoints: strings.Split(servers, ","), Endpoints: strings.Split(servers, ","),
Username: username, Username: username,
Password: password, Password: password,
DialTimeout: to,
DialTimeout: timeout,
TLS: tlsConfig,
}) })
if err != nil { if err != nil {
return fmt.Errorf("connect to etcd %s: %s", servers, err) 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) { 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), 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 { if err != nil {
return lastFileName, fmt.Errorf("list %s : %v", dirPath, err) return lastFileName, fmt.Errorf("list %s : %v", dirPath, err)
} }
for _, kv := range resp.Kvs { for _, kv := range resp.Kvs {
if !bytes.HasPrefix(kv.Key, directoryPrefix) {
break
}
fileName := getNameFromKey(kv.Key) fileName := getNameFromKey(kv.Key)
if fileName == "" { if fileName == "" {
continue continue

2
weed/filer/etcd/etcd_store_test.go

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