Browse Source

cleanup: deduplicate environment variable credential loading

Previously, `weed mini` logic duplicated the credential loading process
by creating a temporary IAM config file from environment variables.
`auth_credentials.go` also had fallback logic to load these variables.

This change:
1. Updates `auth_credentials.go` to *always* check for and merge
   AWS environment variable credentials (`AWS_ACCESS_KEY_ID`, etc.)
   into the identity list. This ensures they are available regardless
   of whether other configurations (static file or filer) are loaded.
2. Removes the redundant file creation logic from `weed/command/mini.go`.
3. Updates `weed mini` user messages to accurately reflect that
   credentials are loaded from environment variables in-memory.

This results in a cleaner implementation where `weed/s3api` manages
all credential loading logic, and `weed mini` simply relies on it.
pull/7992/head
Chris Lu 3 weeks ago
parent
commit
1ea6b0c0d9
  1. 38
      weed/command/mini.go
  2. 114
      weed/s3api/auth_credentials.go

38
weed/command/mini.go

@ -11,10 +11,8 @@ import (
"strings"
"time"
"github.com/seaweedfs/seaweedfs/weed/filer"
"github.com/seaweedfs/seaweedfs/weed/glog"
"github.com/seaweedfs/seaweedfs/weed/pb"
iam_pb "github.com/seaweedfs/seaweedfs/weed/pb/iam_pb"
"github.com/seaweedfs/seaweedfs/weed/security"
stats_collect "github.com/seaweedfs/seaweedfs/weed/stats"
"github.com/seaweedfs/seaweedfs/weed/util"
@ -916,37 +914,7 @@ func startS3Service() {
secretKey := os.Getenv("AWS_SECRET_ACCESS_KEY")
if accessKey != "" && secretKey != "" {
user := "mini"
iamCfg := &iam_pb.S3ApiConfiguration{}
ident := &iam_pb.Identity{Name: user}
ident.Credentials = append(ident.Credentials, &iam_pb.Credential{AccessKey: accessKey, SecretKey: secretKey})
ident.Actions = append(ident.Actions, "Admin")
iamCfg.Identities = append(iamCfg.Identities, ident)
iamPath := filepath.Join(*miniDataFolders, "iam_config.json")
// Check if IAM config file already exists
if _, err := os.Stat(iamPath); err == nil {
// File exists, skip writing to preserve existing configuration
glog.V(1).Infof("IAM config file already exists at %s, preserving existing configuration", iamPath)
*miniIamConfig = iamPath
} else if os.IsNotExist(err) {
// File does not exist, create and write new configuration
f, err := os.OpenFile(iamPath, os.O_CREATE|os.O_WRONLY, 0600)
if err != nil {
glog.Fatalf("failed to create IAM config file %s: %v", iamPath, err)
}
defer f.Close()
if err := filer.ProtoToText(f, iamCfg); err != nil {
glog.Fatalf("failed to write IAM config to %s: %v", iamPath, err)
}
*miniIamConfig = iamPath
createdInitialIAM = true // Mark that we created initial IAM config
glog.V(1).Infof("Created initial IAM config at %s", iamPath)
} else {
// Error checking file existence
glog.Fatalf("failed to check IAM config file existence at %s: %v", iamPath, err)
}
createdInitialIAM = true
}
miniS3Options.localFilerSocket = miniFilerOptions.localSocket
@ -1153,9 +1121,7 @@ const credentialsInstructionTemplate = `
`
const credentialsCreatedMessage = `
Initial S3 credentials created:
user: mini
Note: credentials have been written to the IAM configuration file.
Initial S3 credentials loaded from environment variables.
`
// printWelcomeMessage prints the welcome message after all services are running

114
weed/s3api/auth_credentials.go

@ -160,9 +160,6 @@ func NewIdentityAccessManagementWithStore(option *S3ApiServerOption, explicitSto
iam.credentialManager = credentialManager
// Track whether any configuration was successfully loaded
configLoaded := false
// First, try to load configurations from file or filer
// First, try to load configurations from file or filer
startConfigFile := option.Config
@ -184,7 +181,6 @@ func NewIdentityAccessManagementWithStore(option *S3ApiServerOption, explicitSto
for _, identity := range iam.identities {
iam.staticIdentityNames[identity.Name] = true
}
configLoaded = len(iam.identities) > 0
iam.m.Unlock()
}
@ -197,51 +193,91 @@ func NewIdentityAccessManagementWithStore(option *S3ApiServerOption, explicitSto
// Only consider config loaded if we actually have identities
// Don't block environment variable fallback just because filer call succeeded
iam.m.RLock()
configLoaded = len(iam.identities) > 0
iam.m.RUnlock()
// iam.m.RLock()
// configLoaded = len(iam.identities) > 0
// iam.m.RUnlock()
// Check for AWS environment variables and merge them if present
// This serves as an in-memory "static" configuration
accessKeyId := os.Getenv("AWS_ACCESS_KEY_ID")
secretAccessKey := os.Getenv("AWS_SECRET_ACCESS_KEY")
if accessKeyId != "" && secretAccessKey != "" {
// Create environment variable identity name
identityNameSuffix := accessKeyId
if len(accessKeyId) > 8 {
identityNameSuffix = accessKeyId[:8]
}
identityName := "admin-" + identityNameSuffix
// Create admin identity with environment variable credentials
envIdentity := &Identity{
Name: identityName,
Account: &AccountAdmin,
Credentials: []*Credential{
{
AccessKey: accessKeyId,
SecretKey: secretAccessKey,
},
},
Actions: []Action{
s3_constants.ACTION_ADMIN,
},
}
// Only use environment variables as fallback if no configuration was loaded
if !configLoaded {
accessKeyId := os.Getenv("AWS_ACCESS_KEY_ID")
secretAccessKey := os.Getenv("AWS_SECRET_ACCESS_KEY")
iam.m.Lock()
if accessKeyId != "" && secretAccessKey != "" {
glog.V(1).Infof("No S3 configuration found, using AWS environment variables as fallback")
// Initialize maps if they are nil (if no config loaded yet)
if iam.staticIdentityNames == nil {
iam.staticIdentityNames = make(map[string]bool)
}
// Create environment variable identity name
identityNameSuffix := accessKeyId
if len(accessKeyId) > 8 {
identityNameSuffix = accessKeyId[:8]
// Check if identity already exists (avoid duplicates)
exists := false
for _, ident := range iam.identities {
if ident.Name == identityName {
exists = true
break
}
}
// Create admin identity with environment variable credentials
envIdentity := &Identity{
Name: "admin-" + identityNameSuffix,
Account: &AccountAdmin,
Credentials: []*Credential{
{
AccessKey: accessKeyId,
SecretKey: secretAccessKey,
},
},
Actions: []Action{
s3_constants.ACTION_ADMIN,
},
if !exists {
glog.V(1).Infof("Added admin identity from AWS environment variables: %s", envIdentity.Name)
// Add to identities list
iam.identities = append(iam.identities, envIdentity)
// Update credential mappings
if iam.accessKeyIdent == nil {
iam.accessKeyIdent = make(map[string]*Identity)
}
iam.accessKeyIdent[accessKeyId] = envIdentity
// Set as the only configuration
iam.m.Lock()
if len(iam.identities) == 0 {
iam.identities = []*Identity{envIdentity}
iam.accessKeyIdent = map[string]*Identity{accessKeyId: envIdentity}
iam.nameToIdentity = map[string]*Identity{envIdentity.Name: envIdentity}
iam.isAuthEnabled = true
if iam.nameToIdentity == nil {
iam.nameToIdentity = make(map[string]*Identity)
}
iam.m.Unlock()
iam.nameToIdentity[envIdentity.Name] = envIdentity
glog.V(1).Infof("Added admin identity from AWS environment variables: %s", envIdentity.Name)
// Treat env var identity as static (immutable)
iam.staticIdentityNames[envIdentity.Name] = true
// Ensure defaults exist if this is the first identity
if iam.accounts == nil {
iam.accounts = make(map[string]*Account)
iam.accounts[AccountAdmin.Id] = &AccountAdmin
iam.accounts[AccountAnonymous.Id] = &AccountAnonymous
}
if iam.emailAccount == nil {
iam.emailAccount = make(map[string]*Account)
iam.emailAccount[AccountAdmin.EmailAddress] = &AccountAdmin
iam.emailAccount[AccountAnonymous.EmailAddress] = &AccountAnonymous
}
// Enable auth if we have identities
iam.isAuthEnabled = true
}
iam.m.Unlock()
}
return iam

Loading…
Cancel
Save