mirror of
https://github.com/vmware-tanzu/velero.git
synced 2026-01-08 06:15:40 +00:00
Merge pull request #7374 from reasonerjt/bypass-irsa-kopia
Force to Credentials file when IRSA is configured
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