mirror of
https://github.com/vmware-tanzu/velero.git
synced 2026-01-03 11:45:20 +00:00
Respect the config in BSL when IRSA is configured
This commit makes sure when kopia connects to the repository the crendentials file specified in BSL.spec.config has the higher priority over Pod Environment credentials when IRSA is configured. Signed-off-by: Daniel Jiang <jiangd@vmware.com>
This commit is contained in:
1
changelogs/unreleased/7374-reasonerjt
Normal file
1
changelogs/unreleased/7374-reasonerjt
Normal file
@@ -0,0 +1 @@
|
||||
Respect and use `credentialsFile` specified in BSL.spec.config when IRSA is configured over Velero Pod Environment credentials
|
||||
4
go.mod
4
go.mod
@@ -18,9 +18,11 @@ require (
|
||||
github.com/Azure/go-autorest/autorest/to v0.3.0
|
||||
github.com/aws/aws-sdk-go-v2 v1.24.1
|
||||
github.com/aws/aws-sdk-go-v2/config v1.26.3
|
||||
github.com/aws/aws-sdk-go-v2/credentials v1.16.14
|
||||
github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.15.11
|
||||
github.com/aws/aws-sdk-go-v2/service/ec2 v1.143.0
|
||||
github.com/aws/aws-sdk-go-v2/service/s3 v1.48.0
|
||||
github.com/aws/aws-sdk-go-v2/service/sts v1.26.7
|
||||
github.com/bombsimon/logrusr/v3 v3.0.0
|
||||
github.com/evanphx/json-patch v5.6.0+incompatible
|
||||
github.com/fatih/color v1.15.0
|
||||
@@ -83,7 +85,6 @@ require (
|
||||
github.com/Azure/go-autorest/tracing v0.6.0 // indirect
|
||||
github.com/AzureAD/microsoft-authentication-library-for-go v1.1.1 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.5.4 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/credentials v1.16.14 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.14.11 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.2.10 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.5.10 // indirect
|
||||
@@ -95,7 +96,6 @@ require (
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.16.10 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/sso v1.18.6 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.21.6 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/sts v1.26.7 // indirect
|
||||
github.com/aws/smithy-go v1.19.0 // indirect
|
||||
github.com/beorn7/perks v1.0.1 // indirect
|
||||
github.com/cespare/xxhash/v2 v2.2.0 // indirect
|
||||
|
||||
@@ -19,7 +19,13 @@ package config
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/aws/aws-sdk-go-v2/credentials"
|
||||
"github.com/aws/aws-sdk-go-v2/credentials/stscreds"
|
||||
"github.com/aws/aws-sdk-go-v2/service/sts"
|
||||
|
||||
"github.com/aws/aws-sdk-go-v2/aws"
|
||||
awsconfig "github.com/aws/aws-sdk-go-v2/config"
|
||||
@@ -31,13 +37,13 @@ import (
|
||||
const (
|
||||
// AWS specific environment variable
|
||||
awsProfileEnvVar = "AWS_PROFILE"
|
||||
awsRoleEnvVar = "AWS_ROLE_ARN"
|
||||
awsKeyIDEnvVar = "AWS_ACCESS_KEY_ID"
|
||||
awsSecretKeyEnvVar = "AWS_SECRET_ACCESS_KEY"
|
||||
awsSessTokenEnvVar = "AWS_SESSION_TOKEN"
|
||||
awsProfileKey = "profile"
|
||||
awsCredentialsFileEnvVar = "AWS_SHARED_CREDENTIALS_FILE"
|
||||
awsConfigFileEnvVar = "AWS_CONFIG_FILE"
|
||||
awsDefaultProfile = "default"
|
||||
)
|
||||
|
||||
// GetS3ResticEnvVars gets the environment variables that restic
|
||||
@@ -72,10 +78,6 @@ func GetS3ResticEnvVars(config map[string]string) (map[string]string, error) {
|
||||
// GetS3Credentials gets the S3 credential values according to the information
|
||||
// of the provided config or the system's environment variables
|
||||
func GetS3Credentials(config map[string]string) (*aws.Credentials, error) {
|
||||
if os.Getenv(awsRoleEnvVar) != "" {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
var opts []func(*awsconfig.LoadOptions) error
|
||||
credentialsFile := config[CredentialsFileKey]
|
||||
if credentialsFile == "" {
|
||||
@@ -93,6 +95,25 @@ func GetS3Credentials(config map[string]string) (*aws.Credentials, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if credentialsFile != "" && os.Getenv("AWS_WEB_IDENTITY_TOKEN_FILE") != "" && os.Getenv("AWS_ROLE_ARN") != "" {
|
||||
// Reset the config to use the credentials from the credentials/config file
|
||||
profile := config[awsProfileKey]
|
||||
if profile == "" {
|
||||
profile = awsDefaultProfile
|
||||
}
|
||||
sfp, err := awsconfig.LoadSharedConfigProfile(context.Background(), profile, func(o *awsconfig.LoadSharedConfigOptions) {
|
||||
o.ConfigFiles = []string{credentialsFile}
|
||||
o.CredentialsFiles = []string{credentialsFile}
|
||||
})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error loading config profile '%s': %v", profile, err)
|
||||
}
|
||||
if err := resolveCredsFromProfile(&cfg, &sfp); err != nil {
|
||||
return nil, fmt.Errorf("error resolving creds from profile '%s': %v", profile, err)
|
||||
}
|
||||
}
|
||||
|
||||
creds, err := cfg.Credentials.Retrieve(context.Background())
|
||||
|
||||
return &creds, err
|
||||
@@ -115,3 +136,44 @@ func GetAWSBucketRegion(bucket string) (string, error) {
|
||||
}
|
||||
return region, nil
|
||||
}
|
||||
|
||||
func resolveCredsFromProfile(cfg *aws.Config, sharedConfig *awsconfig.SharedConfig) error {
|
||||
var err error
|
||||
switch {
|
||||
case sharedConfig.Source != nil:
|
||||
// Assume IAM role with credentials source from a different profile.
|
||||
err = resolveCredsFromProfile(cfg, sharedConfig.Source)
|
||||
case sharedConfig.Credentials.HasKeys():
|
||||
// Static Credentials from Shared Config/Credentials file.
|
||||
cfg.Credentials = credentials.StaticCredentialsProvider{
|
||||
Value: sharedConfig.Credentials,
|
||||
}
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(sharedConfig.RoleARN) > 0 {
|
||||
credsFromAssumeRole(cfg, sharedConfig)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func credsFromAssumeRole(cfg *aws.Config, sharedCfg *awsconfig.SharedConfig) {
|
||||
optFns := []func(*stscreds.AssumeRoleOptions){
|
||||
func(options *stscreds.AssumeRoleOptions) {
|
||||
options.RoleSessionName = sharedCfg.RoleSessionName
|
||||
if sharedCfg.RoleDurationSeconds != nil {
|
||||
if *sharedCfg.RoleDurationSeconds/time.Minute > 15 {
|
||||
options.Duration = *sharedCfg.RoleDurationSeconds
|
||||
}
|
||||
}
|
||||
if len(sharedCfg.ExternalID) > 0 {
|
||||
options.ExternalID = aws.String(sharedCfg.ExternalID)
|
||||
}
|
||||
if len(sharedCfg.MFASerial) != 0 {
|
||||
options.SerialNumber = aws.String(sharedCfg.MFASerial)
|
||||
}
|
||||
},
|
||||
}
|
||||
cfg.Credentials = stscreds.NewAssumeRoleProvider(sts.NewFromConfig(*cfg), sharedCfg.RoleARN, optFns...)
|
||||
}
|
||||
|
||||
@@ -505,7 +505,7 @@ func getStorageVariables(backupLocation *velerov1api.BackupStorageLocation, repo
|
||||
}
|
||||
|
||||
s3URL = url.Host
|
||||
disableTLS = (url.Scheme == "http")
|
||||
disableTLS = url.Scheme == "http"
|
||||
}
|
||||
|
||||
result[udmrepo.StoreOptionS3Endpoint] = strings.Trim(s3URL, "/")
|
||||
|
||||
Reference in New Issue
Block a user