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.
This commit is contained in:
@@ -11,10 +11,8 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/seaweedfs/seaweedfs/weed/filer"
|
|
||||||
"github.com/seaweedfs/seaweedfs/weed/glog"
|
"github.com/seaweedfs/seaweedfs/weed/glog"
|
||||||
"github.com/seaweedfs/seaweedfs/weed/pb"
|
"github.com/seaweedfs/seaweedfs/weed/pb"
|
||||||
iam_pb "github.com/seaweedfs/seaweedfs/weed/pb/iam_pb"
|
|
||||||
"github.com/seaweedfs/seaweedfs/weed/security"
|
"github.com/seaweedfs/seaweedfs/weed/security"
|
||||||
stats_collect "github.com/seaweedfs/seaweedfs/weed/stats"
|
stats_collect "github.com/seaweedfs/seaweedfs/weed/stats"
|
||||||
"github.com/seaweedfs/seaweedfs/weed/util"
|
"github.com/seaweedfs/seaweedfs/weed/util"
|
||||||
@@ -916,37 +914,7 @@ func startS3Service() {
|
|||||||
secretKey := os.Getenv("AWS_SECRET_ACCESS_KEY")
|
secretKey := os.Getenv("AWS_SECRET_ACCESS_KEY")
|
||||||
|
|
||||||
if accessKey != "" && secretKey != "" {
|
if accessKey != "" && secretKey != "" {
|
||||||
user := "mini"
|
createdInitialIAM = true
|
||||||
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)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
miniS3Options.localFilerSocket = miniFilerOptions.localSocket
|
miniS3Options.localFilerSocket = miniFilerOptions.localSocket
|
||||||
@@ -1153,9 +1121,7 @@ const credentialsInstructionTemplate = `
|
|||||||
`
|
`
|
||||||
|
|
||||||
const credentialsCreatedMessage = `
|
const credentialsCreatedMessage = `
|
||||||
Initial S3 credentials created:
|
Initial S3 credentials loaded from environment variables.
|
||||||
user: mini
|
|
||||||
Note: credentials have been written to the IAM configuration file.
|
|
||||||
`
|
`
|
||||||
|
|
||||||
// printWelcomeMessage prints the welcome message after all services are running
|
// printWelcomeMessage prints the welcome message after all services are running
|
||||||
|
|||||||
@@ -160,9 +160,6 @@ func NewIdentityAccessManagementWithStore(option *S3ApiServerOption, explicitSto
|
|||||||
|
|
||||||
iam.credentialManager = credentialManager
|
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
|
||||||
// First, try to load configurations from file or filer
|
// First, try to load configurations from file or filer
|
||||||
startConfigFile := option.Config
|
startConfigFile := option.Config
|
||||||
@@ -184,7 +181,6 @@ func NewIdentityAccessManagementWithStore(option *S3ApiServerOption, explicitSto
|
|||||||
for _, identity := range iam.identities {
|
for _, identity := range iam.identities {
|
||||||
iam.staticIdentityNames[identity.Name] = true
|
iam.staticIdentityNames[identity.Name] = true
|
||||||
}
|
}
|
||||||
configLoaded = len(iam.identities) > 0
|
|
||||||
iam.m.Unlock()
|
iam.m.Unlock()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -197,51 +193,91 @@ func NewIdentityAccessManagementWithStore(option *S3ApiServerOption, explicitSto
|
|||||||
|
|
||||||
// Only consider config loaded if we actually have identities
|
// Only consider config loaded if we actually have identities
|
||||||
// Don't block environment variable fallback just because filer call succeeded
|
// Don't block environment variable fallback just because filer call succeeded
|
||||||
iam.m.RLock()
|
// iam.m.RLock()
|
||||||
configLoaded = len(iam.identities) > 0
|
// configLoaded = len(iam.identities) > 0
|
||||||
iam.m.RUnlock()
|
// iam.m.RUnlock()
|
||||||
|
|
||||||
// Only use environment variables as fallback if no configuration was loaded
|
// Check for AWS environment variables and merge them if present
|
||||||
if !configLoaded {
|
// This serves as an in-memory "static" configuration
|
||||||
accessKeyId := os.Getenv("AWS_ACCESS_KEY_ID")
|
accessKeyId := os.Getenv("AWS_ACCESS_KEY_ID")
|
||||||
secretAccessKey := os.Getenv("AWS_SECRET_ACCESS_KEY")
|
secretAccessKey := os.Getenv("AWS_SECRET_ACCESS_KEY")
|
||||||
|
|
||||||
if accessKeyId != "" && secretAccessKey != "" {
|
if accessKeyId != "" && secretAccessKey != "" {
|
||||||
glog.V(1).Infof("No S3 configuration found, using AWS environment variables as fallback")
|
// Create environment variable identity name
|
||||||
|
identityNameSuffix := accessKeyId
|
||||||
// Create environment variable identity name
|
if len(accessKeyId) > 8 {
|
||||||
identityNameSuffix := accessKeyId
|
identityNameSuffix = accessKeyId[:8]
|
||||||
if len(accessKeyId) > 8 {
|
|
||||||
identityNameSuffix = accessKeyId[:8]
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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
|
|
||||||
}
|
|
||||||
iam.m.Unlock()
|
|
||||||
|
|
||||||
glog.V(1).Infof("Added admin identity from AWS environment variables: %s", envIdentity.Name)
|
|
||||||
}
|
}
|
||||||
|
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,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
iam.m.Lock()
|
||||||
|
|
||||||
|
// Initialize maps if they are nil (if no config loaded yet)
|
||||||
|
if iam.staticIdentityNames == nil {
|
||||||
|
iam.staticIdentityNames = make(map[string]bool)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if identity already exists (avoid duplicates)
|
||||||
|
exists := false
|
||||||
|
for _, ident := range iam.identities {
|
||||||
|
if ident.Name == identityName {
|
||||||
|
exists = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
if iam.nameToIdentity == nil {
|
||||||
|
iam.nameToIdentity = make(map[string]*Identity)
|
||||||
|
}
|
||||||
|
iam.nameToIdentity[envIdentity.Name] = envIdentity
|
||||||
|
|
||||||
|
// 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
|
return iam
|
||||||
|
|||||||
Reference in New Issue
Block a user