Browse Source

shell: fix s3.configure to use credential manager when configured

Fixes #8025

This commit resolves the user management inconsistency between the Admin UI
and the s3.configure command when using a credential backend (e.g., PostgreSQL).

Previously:
- Admin UI used credentialManager to read/write users from the configured backend
- s3.configure always wrote directly to filer at /etc/iam/identity.json
- This caused users created via Admin UI to not appear in listings, and users
  created via s3.configure to not persist to the credential backend

Changes:
- s3.configure now detects if a credential backend is configured via credential.toml
- When a backend is detected, it uses credentialManager to load and save configuration
- Falls back to filer-based storage when no backend is configured (backward compatible)

This ensures both Admin UI and s3.configure use the same storage backend,
resolving the inconsistency.
fix-s3-configure-consistency
Chris Lu 4 weeks ago
parent
commit
65afbcc572
  1. 85
      weed/shell/command_s3_configure.go

85
weed/shell/command_s3_configure.go

@ -2,13 +2,16 @@ package shell
import (
"bytes"
"context"
"flag"
"fmt"
"io"
"sort"
"strings"
"github.com/seaweedfs/seaweedfs/weed/credential"
"github.com/seaweedfs/seaweedfs/weed/filer"
"github.com/seaweedfs/seaweedfs/weed/glog"
"github.com/seaweedfs/seaweedfs/weed/pb/filer_pb"
"github.com/seaweedfs/seaweedfs/weed/pb/iam_pb"
@ -57,6 +60,31 @@ func (c *commandS3Configure) Do(args []string, commandEnv *CommandEnv, writer io
return nil
}
// Try to detect if a credential backend is configured
credConfig, err := credential.LoadCredentialConfiguration()
if err != nil {
return fmt.Errorf("failed to load credential configuration: %w", err)
}
// Use credential manager if a backend is configured
var credentialManager *credential.CredentialManager
useCredentialManager := false
if credConfig != nil {
glog.V(0).Infof("Credential backend detected: %s. Using credential manager for s3.configure", credConfig.Store)
credentialManager, err = credential.NewCredentialManager(
credential.CredentialStoreTypeName(credConfig.Store),
credConfig.Config,
credConfig.Prefix,
)
if err != nil {
return fmt.Errorf("failed to initialize credential manager: %w", err)
}
defer credentialManager.Shutdown()
useCredentialManager = true
} else {
glog.V(1).Info("No credential backend configured. Using filer-based storage for s3.configure")
}
// Check which account flags were provided and build update functions
var accountUpdates []func(*iam_pb.Account)
s3ConfigureCommand.Visit(func(f *flag.Flag) {
@ -82,18 +110,32 @@ func (c *commandS3Configure) Do(args []string, commandEnv *CommandEnv, writer io
}
}
var buf bytes.Buffer
if err = commandEnv.WithFilerClient(false, func(client filer_pb.SeaweedFilerClient) error {
return filer.ReadEntry(commandEnv.MasterClient, client, filer.IamConfigDirectory, filer.IamIdentityFile, &buf)
}); err != nil && err != filer_pb.ErrNotFound {
return err
}
// Load configuration from appropriate source
s3cfg := &iam_pb.S3ApiConfiguration{}
if buf.Len() > 0 {
if err = filer.ParseS3ConfigurationFromBytes(buf.Bytes(), s3cfg); err != nil {
if useCredentialManager {
// Load from credential manager
ctx := context.Background()
config, err := credentialManager.LoadConfiguration(ctx)
if err != nil {
return fmt.Errorf("failed to load configuration from credential manager: %w", err)
}
if config != nil {
s3cfg = config
}
} else {
// Load from filer (legacy behavior)
var buf bytes.Buffer
if err = commandEnv.WithFilerClient(false, func(client filer_pb.SeaweedFilerClient) error {
return filer.ReadEntry(commandEnv.MasterClient, client, filer.IamConfigDirectory, filer.IamIdentityFile, &buf)
}); err != nil && err != filer_pb.ErrNotFound {
return err
}
if buf.Len() > 0 {
if err = filer.ParseS3ConfigurationFromBytes(buf.Bytes(), s3cfg); err != nil {
return err
}
}
}
idx := 0
@ -208,20 +250,29 @@ func (c *commandS3Configure) Do(args []string, commandEnv *CommandEnv, writer io
return err
}
buf.Reset()
// Display configuration
var buf bytes.Buffer
filer.ProtoToText(&buf, s3cfg)
fmt.Fprint(writer, buf.String())
fmt.Fprintln(writer)
// Save configuration if apply flag is set
if *apply {
if err := commandEnv.WithFilerClient(false, func(client filer_pb.SeaweedFilerClient) error {
return filer.SaveInsideFiler(client, filer.IamConfigDirectory, filer.IamIdentityFile, buf.Bytes())
}); err != nil {
return err
if useCredentialManager {
// Save to credential manager
ctx := context.Background()
if err := credentialManager.SaveConfiguration(ctx, s3cfg); err != nil {
return fmt.Errorf("failed to save configuration to credential manager: %w", err)
}
glog.V(0).Infof("Configuration saved to credential backend: %s", credConfig.Store)
} else {
// Save to filer (legacy behavior)
if err := commandEnv.WithFilerClient(false, func(client filer_pb.SeaweedFilerClient) error {
return filer.SaveInsideFiler(client, filer.IamConfigDirectory, filer.IamIdentityFile, buf.Bytes())
}); err != nil {
return err
}
}
}
return nil

Loading…
Cancel
Save