Feat: etcd filer store keys should have customizable prefix (#4484)

An etcd cluster is not necessarily only dedicated to seaweedfs.
This security enhancement adds a customizable key_prefix option to the etcd filer store.
This will allow an etcd cluster administrator to limit the seaweedfs etcd user to only read/write a subset of keys under the
key_prefix, instead of all keys on the etcd cluster.
This commit is contained in:
Mesar Hameed 2023-05-19 07:08:56 +01:00 committed by GitHub
parent 17e91d2917
commit a90b777ff4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 11 additions and 8 deletions

View file

@ -264,6 +264,7 @@ enabled = false
servers = "localhost:2379" servers = "localhost:2379"
username = "" username = ""
password = "" password = ""
key_prefix = "seaweedfs."
timeout = "3s" timeout = "3s"
[mongodb] [mongodb]

View file

@ -25,6 +25,7 @@ func init() {
type EtcdStore struct { type EtcdStore struct {
client *clientv3.Client client *clientv3.Client
etcdKeyPrefix string
} }
func (store *EtcdStore) GetName() string { func (store *EtcdStore) GetName() string {
@ -39,6 +40,7 @@ func (store *EtcdStore) Initialize(configuration weed_util.Configuration, prefix
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")
timeout := configuration.GetString(prefix + "timeout") timeout := configuration.GetString(prefix + "timeout")
if timeout == "" { if timeout == "" {
@ -91,7 +93,7 @@ func (store *EtcdStore) InsertEntry(ctx context.Context, entry *filer.Entry) (er
meta = weed_util.MaybeGzipData(meta) meta = weed_util.MaybeGzipData(meta)
} }
if _, err := store.client.Put(ctx, string(key), string(meta)); err != nil { if _, err := store.client.Put(ctx, store.etcdKeyPrefix + string(key), string(meta)); err != nil {
return fmt.Errorf("persisting %s : %v", entry.FullPath, err) return fmt.Errorf("persisting %s : %v", entry.FullPath, err)
} }
@ -105,7 +107,7 @@ func (store *EtcdStore) UpdateEntry(ctx context.Context, entry *filer.Entry) (er
func (store *EtcdStore) FindEntry(ctx context.Context, fullpath weed_util.FullPath) (entry *filer.Entry, err error) { func (store *EtcdStore) FindEntry(ctx context.Context, fullpath weed_util.FullPath) (entry *filer.Entry, err error) {
key := genKey(fullpath.DirAndName()) key := genKey(fullpath.DirAndName())
resp, err := store.client.Get(ctx, string(key)) resp, err := store.client.Get(ctx, store.etcdKeyPrefix + string(key))
if err != nil { if err != nil {
return nil, fmt.Errorf("get %s : %v", fullpath, err) return nil, fmt.Errorf("get %s : %v", fullpath, err)
} }
@ -128,7 +130,7 @@ func (store *EtcdStore) FindEntry(ctx context.Context, fullpath weed_util.FullPa
func (store *EtcdStore) DeleteEntry(ctx context.Context, fullpath weed_util.FullPath) (err error) { func (store *EtcdStore) DeleteEntry(ctx context.Context, fullpath weed_util.FullPath) (err error) {
key := genKey(fullpath.DirAndName()) key := genKey(fullpath.DirAndName())
if _, err := store.client.Delete(ctx, string(key)); err != nil { if _, err := store.client.Delete(ctx, store.etcdKeyPrefix + string(key)); err != nil {
return fmt.Errorf("delete %s : %v", fullpath, err) return fmt.Errorf("delete %s : %v", fullpath, err)
} }
@ -138,7 +140,7 @@ func (store *EtcdStore) DeleteEntry(ctx context.Context, fullpath weed_util.Full
func (store *EtcdStore) DeleteFolderChildren(ctx context.Context, fullpath weed_util.FullPath) (err error) { func (store *EtcdStore) DeleteFolderChildren(ctx context.Context, fullpath weed_util.FullPath) (err error) {
directoryPrefix := genDirectoryKeyPrefix(fullpath, "") directoryPrefix := genDirectoryKeyPrefix(fullpath, "")
if _, err := store.client.Delete(ctx, string(directoryPrefix), clientv3.WithPrefix()); err != nil { if _, err := store.client.Delete(ctx, store.etcdKeyPrefix + string(directoryPrefix), clientv3.WithPrefix()); err != nil {
return fmt.Errorf("deleteFolderChildren %s : %v", fullpath, err) return fmt.Errorf("deleteFolderChildren %s : %v", fullpath, err)
} }
@ -156,7 +158,7 @@ func (store *EtcdStore) ListDirectoryEntries(ctx context.Context, dirPath weed_u
lastFileStart = genDirectoryKeyPrefix(dirPath, startFileName) lastFileStart = genDirectoryKeyPrefix(dirPath, startFileName)
} }
resp, err := store.client.Get(ctx, string(lastFileStart), resp, err := store.client.Get(ctx, store.etcdKeyPrefix + string(lastFileStart),
clientv3.WithFromKey(), clientv3.WithLimit(limit+1)) clientv3.WithFromKey(), 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)

View file

@ -8,7 +8,7 @@ import (
func (store *EtcdStore) KvPut(ctx context.Context, key []byte, value []byte) (err error) { func (store *EtcdStore) KvPut(ctx context.Context, key []byte, value []byte) (err error) {
_, err = store.client.Put(ctx, string(key), string(value)) _, err = store.client.Put(ctx, store.etcdKeyPrefix + string(key), string(value))
if err != nil { if err != nil {
return fmt.Errorf("kv put: %v", err) return fmt.Errorf("kv put: %v", err)
@ -19,7 +19,7 @@ func (store *EtcdStore) KvPut(ctx context.Context, key []byte, value []byte) (er
func (store *EtcdStore) KvGet(ctx context.Context, key []byte) (value []byte, err error) { func (store *EtcdStore) KvGet(ctx context.Context, key []byte) (value []byte, err error) {
resp, err := store.client.Get(ctx, string(key)) resp, err := store.client.Get(ctx, store.etcdKeyPrefix + string(key))
if err != nil { if err != nil {
return nil, fmt.Errorf("kv get: %v", err) return nil, fmt.Errorf("kv get: %v", err)
@ -34,7 +34,7 @@ func (store *EtcdStore) KvGet(ctx context.Context, key []byte) (value []byte, er
func (store *EtcdStore) KvDelete(ctx context.Context, key []byte) (err error) { func (store *EtcdStore) KvDelete(ctx context.Context, key []byte) (err error) {
_, err = store.client.Delete(ctx, string(key)) _, err = store.client.Delete(ctx, store.etcdKeyPrefix + string(key))
if err != nil { if err != nil {
return fmt.Errorf("kv delete: %v", err) return fmt.Errorf("kv delete: %v", err)