Skip to content

Commit

Permalink
Update provider configuration
Browse files Browse the repository at this point in the history
Signed-off-by: SK Ali Arman <[email protected]>
  • Loading branch information
sheikh-arman committed Nov 23, 2023
1 parent e9aa1a5 commit b797a47
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 63 deletions.
111 changes: 53 additions & 58 deletions internal/clients/aws.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ package clients

import (
"context"
"encoding/json"
"github.com/aws/aws-sdk-go-v2/aws"
"github.com/crossplane/crossplane-runtime/pkg/fieldpath"
"github.com/crossplane/crossplane-runtime/pkg/resource"
Expand All @@ -26,22 +25,32 @@ import (

const (
// error messages
errNoProviderConfig = "no providerConfigRef provided"
errGetProviderConfig = "cannot get referenced ProviderConfig"
errTrackUsage = "cannot track ProviderConfig usage"
errExtractCredentials = "cannot extract credentials"
errUnmarshalCredentials = "cannot unmarshal aws credentials as JSON"
errRegionNotFound = "can not found region for terraform provider config"

accessKeyID = "access_key"
secretAccessKey = "secret_key"
//errNoProviderConfig = "no providerConfigRef provided"
//errGetProviderConfig = "cannot get referenced ProviderConfig"
//errTrackUsage = "cannot track ProviderConfig usage"
//errExtractCredentials = "cannot extract credentials"
//errUnmarshalCredentials = "cannot unmarshal aws credentials as JSON"
//errRegionNotFound = "can not found region for terraform provider config"

//accessKeyID = "access_key"
keyAccessKeyID = "aws_access"
//secretAccessKey = "secret_key"
keySecretAccessKey = "secret_key"

keyRegion = "region"
keySessionToken = "token"
)

// TerraformSetupBuilder builds Terraform a terraform.SetupFn function which
// returns Terraform provider setup configuration
func TerraformSetupBuilder(version, providerSource, providerVersion string, mta *schema.Provider) terraform.SetupFn {
return func(ctx context.Context, client client.Client, mg resource.Managed) (terraform.Setup, error) {

pc := &v1beta1.ProviderConfig{}
var err error
if err = client.Get(ctx, types.NamespacedName{Name: mg.GetProviderConfigReference().Name}, pc); err != nil {
return terraform.Setup{}, errors.Wrapf(err, "cannot get referenced Provider: %s", mg.GetProviderConfigReference().Name)
}
ps := terraform.Setup{
Version: version,
Requirement: terraform.ProviderRequirement{
Expand All @@ -50,21 +59,7 @@ func TerraformSetupBuilder(version, providerSource, providerVersion string, mta
},
}

configRef := mg.GetProviderConfigReference()
if configRef == nil {
return ps, errors.New(errNoProviderConfig)
}
pc := &v1beta1.ProviderConfig{}
if err := client.Get(ctx, types.NamespacedName{Name: configRef.Name}, pc); err != nil {
return ps, errors.Wrap(err, errGetProviderConfig)
}

t := resource.NewProviderConfigUsageTracker(client, &v1beta1.ProviderConfigUsage{})
if err := t.Track(ctx, mg); err != nil {
return ps, errors.Wrap(err, errTrackUsage)
}

err := pushDownTerraformSetupBuilder(ctx, client, mg, pc, &ps)
err = pushDownTerraformSetupBuilder(ctx, client, mg, pc, &ps)
if err != nil {
return terraform.Setup{}, errors.Wrap(err, "cannot build terraform configuration")
}
Expand All @@ -86,37 +81,38 @@ func TerraformSetupBuilder(version, providerSource, providerVersion string, mta
}
}

func pushDownTerraformSetupBuilder(ctx context.Context, client client.Client, mg resource.Managed, pc *v1beta1.ProviderConfig, ps *terraform.Setup) error {
data, err := resource.CommonCredentialExtractor(ctx, pc.Spec.Credentials.Source, client, pc.Spec.Credentials.CommonCredentialSelectors)
func pushDownTerraformSetupBuilder(ctx context.Context, c client.Client, mg resource.Managed, pc *v1beta1.ProviderConfig, ps *terraform.Setup) error {
s := pc.Spec.Credentials.Source
cfg, err := getAWSConfig(ctx, c, mg)
if err != nil {
return errors.Wrap(err, errExtractCredentials)
return errors.Wrap(err, "cannot get AWS config")
}
creds := map[string]string{}
if err := json.Unmarshal(data, &creds); err != nil {
return errors.Wrap(err, errUnmarshalCredentials)
ps.Configuration = map[string]any{
keyRegion: cfg.Region,
}

region, err := getRegion(mg)
data, err := resource.CommonCredentialExtractor(ctx, s, c, pc.Spec.Credentials.CommonCredentialSelectors)
if err != nil {
return errors.Wrap(err, errRegionNotFound)
return errors.Wrap(err, "cannot get credentials")
}
cfg, err = UseProviderSecret(ctx, data, DefaultSection, cfg.Region)
if err != nil {
return errors.Wrap(err, errAWSConfig)
}
creds, err := cfg.Credentials.Retrieve(ctx)
if err != nil {
return errors.Wrap(err, "failed to retrieve aws credentials from aws config")
}

// Set credentials in Terraform provider configuration.
ps.Configuration = map[string]any{
accessKeyID: creds[accessKeyID],
secretAccessKey: creds[secretAccessKey],
keyRegion: region,
keyRegion: cfg.Region,
keyAccessKeyID: creds.AccessKeyID,
keySecretAccessKey: creds.SecretAccessKey,
keySessionToken: creds.SessionToken,
}
return nil
}

func configureNoForkAWSClient(ctx context.Context, c client.Client, mg resource.Managed, pc *v1beta1.ProviderConfig, ps *terraform.Setup) (xpprovider.AWSConfig, error) { //nolint:gocyclo

if len(pc.Spec.AssumeRoleChain) > 1 || pc.Spec.Endpoint != nil {
return xpprovider.AWSConfig{}, errors.New("cannot configure no-fork client because the length of assume role chain array " +
"is more than 1 or endpoint configuration is not nil")
}

cfg, err := getAWSConfig(ctx, c, mg)
if err != nil {
return xpprovider.AWSConfig{}, errors.Wrap(err, "cannot get AWS config")
Expand All @@ -126,28 +122,27 @@ func configureNoForkAWSClient(ctx context.Context, c client.Client, mg resource.
Region: cfg.Region,
TerraformVersion: ps.Version,
}

data, err := resource.CommonCredentialExtractor(ctx, pc.Spec.Credentials.Source, c, pc.Spec.Credentials.CommonCredentialSelectors)
s := pc.Spec.Credentials.Source
data, err := resource.CommonCredentialExtractor(ctx, s, c, pc.Spec.Credentials.CommonCredentialSelectors)
if err != nil {
return xpprovider.AWSConfig{}, errors.Wrap(err, errExtractCredentials)
return xpprovider.AWSConfig{}, errors.Wrap(err, "cannot get credentials")
}
creds := map[string]string{}
if err := json.Unmarshal(data, &creds); err != nil {
return xpprovider.AWSConfig{}, errors.Wrap(err, errUnmarshalCredentials)
cfg, err = UseProviderSecret(ctx, data, DefaultSection, cfg.Region)
if err != nil {
return xpprovider.AWSConfig{}, errors.Wrap(err, errAWSConfig)
}

region, err := getRegion(mg)
creds, err := cfg.Credentials.Retrieve(ctx)
if err != nil {
return xpprovider.AWSConfig{}, errors.Wrap(err, errRegionNotFound)
return xpprovider.AWSConfig{}, errors.Wrap(err, "failed to retrieve aws credentials from aws config")
}

// Set credentials in Terraform provider configuration.

awsConfig.AccessKey = creds[accessKeyID]
awsConfig.SecretKey = creds[secretAccessKey]
awsConfig.Region = region
awsConfig.Region = cfg.Region
awsConfig.AccessKey = creds.AccessKeyID
awsConfig.SecretKey = creds.SecretAccessKey
awsConfig.Token = creds.SessionToken

return awsConfig, nil

}

func getAWSConfig(ctx context.Context, c client.Client, mg resource.Managed) (*aws.Config, error) {
Expand Down
12 changes: 7 additions & 5 deletions internal/clients/provider_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -174,21 +174,23 @@ func CredentialsIDSecret(data []byte, profile string) (aws.Credentials, error) {
return aws.Credentials{}, errors.Wrap(err, fmt.Sprintf("cannot get %s profile in credentials secret", profile))
}

accessKeyID := iniProfile.Key("aws_access_key_id")
secretAccessKey := iniProfile.Key("aws_secret_access_key")
sessionToken := iniProfile.Key("aws_session_token")
//accessKeyID := iniProfile.Key("aws_access_key_id")
accessKeyID := iniProfile.Key("access_key")
//secretAccessKey := iniProfile.Key("aws_secret_access_key")
secretAccessKey := iniProfile.Key("secret_key")
//sessionToken := iniProfile.Key("aws_session_token")

// NOTE(muvaf): Key function implementation never returns nil but still its
// type is pointer so we check to make sure its next versions doesn't break
// that implicit contract.
if accessKeyID == nil || secretAccessKey == nil || sessionToken == nil {
if accessKeyID == nil || secretAccessKey == nil {
return aws.Credentials{}, errors.New("returned key can be empty but cannot be nil")
}

return aws.Credentials{
AccessKeyID: accessKeyID.Value(),
SecretAccessKey: secretAccessKey.Value(),
SessionToken: sessionToken.Value(),
//SessionToken: sessionToken.Value(),
}, nil
}

Expand Down

0 comments on commit b797a47

Please sign in to comment.