Skip to content

Commit

Permalink
Merge pull request #7374 from reasonerjt/bypass-irsa-kopia
Browse files Browse the repository at this point in the history
Force to Credentials file when IRSA is configured
  • Loading branch information
reasonerjt authored Feb 2, 2024
2 parents b509df5 + 30728c2 commit cc9c954
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 8 deletions.
1 change: 1 addition & 0 deletions changelogs/unreleased/7374-reasonerjt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Respect and use `credentialsFile` specified in BSL.spec.config when IRSA is configured over Velero Pod Environment credentials
4 changes: 2 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -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
Expand Down
72 changes: 67 additions & 5 deletions pkg/repository/config/aws.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -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
Expand Down Expand Up @@ -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 == "" {
Expand All @@ -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
Expand All @@ -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...)
}
2 changes: 1 addition & 1 deletion pkg/repository/provider/unified_repo.go
Original file line number Diff line number Diff line change
Expand Up @@ -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, "/")
Expand Down

0 comments on commit cc9c954

Please sign in to comment.