sigs.k8s.io/cluster-api-provider-aws@v1.5.5/cmd/clusterawsadm/credentials/credentials.go (about)

     1  /*
     2  Copyright 2020 The Kubernetes Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8  	http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package credentials
    18  
    19  import (
    20  	"bytes"
    21  	"encoding/base64"
    22  	"errors"
    23  	"text/template"
    24  
    25  	"github.com/aws/aws-sdk-go/aws"
    26  	"github.com/aws/aws-sdk-go/aws/session"
    27  
    28  	"sigs.k8s.io/cluster-api-provider-aws/cmd/clusterawsadm/cmd/util"
    29  )
    30  
    31  // AWSCredentialsTemplate generates an AWS credentials file that can
    32  // be loaded by the various SDKs.
    33  // nolint:gosec
    34  const AWSCredentialsTemplate = `[default]
    35  aws_access_key_id = {{ .AccessKeyID }}
    36  aws_secret_access_key = {{ .SecretAccessKey }}
    37  region = {{ .Region }}
    38  {{if .SessionToken }}
    39  aws_session_token = {{ .SessionToken }}
    40  {{end}}
    41  `
    42  
    43  // AWSDefaultRegion is the default AWS region.
    44  const AWSDefaultRegion = "us-east-1"
    45  
    46  // ErrNoAWSRegionConfigured is an error singleton for when no AWS region is configured.
    47  var ErrNoAWSRegionConfigured = errors.New("no AWS region configured. Use --region or set AWS_REGION or DEFAULT_AWS_REGION environment variable")
    48  
    49  // AWSCredentials defines the specs for AWS credentials.
    50  type AWSCredentials struct {
    51  	AccessKeyID     string
    52  	SecretAccessKey string
    53  	SessionToken    string
    54  	Region          string
    55  }
    56  
    57  // NewAWSCredentialFromDefaultChain will create a new credential provider chain from the
    58  // default chain.
    59  func NewAWSCredentialFromDefaultChain(region string) (*AWSCredentials, error) {
    60  	creds := AWSCredentials{}
    61  	conf := aws.NewConfig()
    62  	conf.CredentialsChainVerboseErrors = aws.Bool(true)
    63  	sess, err := session.NewSessionWithOptions(session.Options{
    64  		SharedConfigState: session.SharedConfigEnable,
    65  		Config:            *conf,
    66  	})
    67  	if err != nil {
    68  		return nil, err
    69  	}
    70  	chainCreds, err := sess.Config.Credentials.Get()
    71  	if err != nil {
    72  		return nil, err
    73  	}
    74  	creds.Region = region
    75  	creds.AccessKeyID = chainCreds.AccessKeyID
    76  	creds.SecretAccessKey = chainCreds.SecretAccessKey
    77  	creds.SessionToken = chainCreds.SessionToken
    78  
    79  	return &creds, nil
    80  }
    81  
    82  // ResolveRegion will attempt to resolve an AWS region based on the customer's configuration.
    83  func ResolveRegion(explicitRegion string) (string, error) {
    84  	if explicitRegion != "" {
    85  		return explicitRegion, nil
    86  	}
    87  	region, err := util.GetEnv("AWS_REGION")
    88  	if err == nil {
    89  		return region, nil
    90  	}
    91  	region, err = util.GetEnv("DEFAULT_AWS_REGION")
    92  	if err == nil {
    93  		return region, nil
    94  	}
    95  	return "", ErrNoAWSRegionConfigured
    96  }
    97  
    98  // RenderAWSDefaultProfile will render the AWS default profile.
    99  func (c AWSCredentials) RenderAWSDefaultProfile() (string, error) {
   100  	tmpl, err := template.New("AWS Credentials").Parse(AWSCredentialsTemplate)
   101  	if err != nil {
   102  		return "", err
   103  	}
   104  
   105  	var credsFileStr bytes.Buffer
   106  	err = tmpl.Execute(&credsFileStr, c)
   107  	if err != nil {
   108  		return "", err
   109  	}
   110  
   111  	return credsFileStr.String(), nil
   112  }
   113  
   114  // RenderBase64EncodedAWSDefaultProfile will render the AWS default profile, encoded in base 64.
   115  func (c AWSCredentials) RenderBase64EncodedAWSDefaultProfile() (string, error) {
   116  	profile, err := c.RenderAWSDefaultProfile()
   117  	if err != nil {
   118  		return "", err
   119  	}
   120  
   121  	return base64.StdEncoding.EncodeToString([]byte(profile)), nil
   122  }