Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Force to Credentials file when IRSA is configured #7374

Merged
merged 1 commit into from
Feb 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 @@

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 @@
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 @@
// 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 @@
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)
}

Check warning on line 114 in pkg/repository/config/aws.go

View check run for this annotation

Codecov / codecov/patch

pkg/repository/config/aws.go#L100-L114

Added lines #L100 - L114 were not covered by tests
}

creds, err := cfg.Credentials.Retrieve(context.Background())

return &creds, err
Expand All @@ -115,3 +136,44 @@
}
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,
}

Check warning on line 150 in pkg/repository/config/aws.go

View check run for this annotation

Codecov / codecov/patch

pkg/repository/config/aws.go#L140-L150

Added lines #L140 - L150 were not covered by tests
}
if err != nil {
return err
}
if len(sharedConfig.RoleARN) > 0 {
credsFromAssumeRole(cfg, sharedConfig)
}
return nil

Check warning on line 158 in pkg/repository/config/aws.go

View check run for this annotation

Codecov / codecov/patch

pkg/repository/config/aws.go#L152-L158

Added lines #L152 - L158 were not covered by tests
}

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
}

Check warning on line 168 in pkg/repository/config/aws.go

View check run for this annotation

Codecov / codecov/patch

pkg/repository/config/aws.go#L161-L168

Added lines #L161 - L168 were not covered by tests
}
if len(sharedCfg.ExternalID) > 0 {
options.ExternalID = aws.String(sharedCfg.ExternalID)
}
if len(sharedCfg.MFASerial) != 0 {
options.SerialNumber = aws.String(sharedCfg.MFASerial)
}

Check warning on line 175 in pkg/repository/config/aws.go

View check run for this annotation

Codecov / codecov/patch

pkg/repository/config/aws.go#L170-L175

Added lines #L170 - L175 were not covered by tests
},
}
cfg.Credentials = stscreds.NewAssumeRoleProvider(sts.NewFromConfig(*cfg), sharedCfg.RoleARN, optFns...)

Check warning on line 178 in pkg/repository/config/aws.go

View check run for this annotation

Codecov / codecov/patch

pkg/repository/config/aws.go#L178

Added line #L178 was not covered by tests
}
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
Loading