sigs.k8s.io/cluster-api-provider-aws@v1.5.5/pkg/cloud/scope/clients.go (about)

     1  /*
     2  Copyright 2018 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 scope
    18  
    19  import (
    20  	"github.com/aws/aws-sdk-go/aws"
    21  	"github.com/aws/aws-sdk-go/aws/awserr"
    22  	"github.com/aws/aws-sdk-go/aws/request"
    23  	"github.com/aws/aws-sdk-go/service/autoscaling"
    24  	"github.com/aws/aws-sdk-go/service/autoscaling/autoscalingiface"
    25  	"github.com/aws/aws-sdk-go/service/ec2"
    26  	"github.com/aws/aws-sdk-go/service/ec2/ec2iface"
    27  	"github.com/aws/aws-sdk-go/service/eks"
    28  	"github.com/aws/aws-sdk-go/service/eks/eksiface"
    29  	"github.com/aws/aws-sdk-go/service/elb"
    30  	"github.com/aws/aws-sdk-go/service/elb/elbiface"
    31  	"github.com/aws/aws-sdk-go/service/elbv2"
    32  	"github.com/aws/aws-sdk-go/service/elbv2/elbv2iface"
    33  	"github.com/aws/aws-sdk-go/service/eventbridge"
    34  	"github.com/aws/aws-sdk-go/service/eventbridge/eventbridgeiface"
    35  	"github.com/aws/aws-sdk-go/service/iam"
    36  	"github.com/aws/aws-sdk-go/service/iam/iamiface"
    37  	"github.com/aws/aws-sdk-go/service/resourcegroupstaggingapi"
    38  	"github.com/aws/aws-sdk-go/service/resourcegroupstaggingapi/resourcegroupstaggingapiiface"
    39  	"github.com/aws/aws-sdk-go/service/s3"
    40  	"github.com/aws/aws-sdk-go/service/s3/s3iface"
    41  	"github.com/aws/aws-sdk-go/service/secretsmanager"
    42  	"github.com/aws/aws-sdk-go/service/secretsmanager/secretsmanageriface"
    43  	"github.com/aws/aws-sdk-go/service/sqs"
    44  	"github.com/aws/aws-sdk-go/service/sqs/sqsiface"
    45  	"github.com/aws/aws-sdk-go/service/ssm"
    46  	"github.com/aws/aws-sdk-go/service/ssm/ssmiface"
    47  	"github.com/aws/aws-sdk-go/service/sts"
    48  	"github.com/aws/aws-sdk-go/service/sts/stsiface"
    49  	"k8s.io/apimachinery/pkg/runtime"
    50  
    51  	"sigs.k8s.io/cluster-api-provider-aws/pkg/cloud"
    52  	awslogs "sigs.k8s.io/cluster-api-provider-aws/pkg/cloud/logs"
    53  	awsmetrics "sigs.k8s.io/cluster-api-provider-aws/pkg/cloud/metrics"
    54  	"sigs.k8s.io/cluster-api-provider-aws/pkg/record"
    55  	"sigs.k8s.io/cluster-api-provider-aws/version"
    56  )
    57  
    58  // NewASGClient creates a new ASG API client for a given session.
    59  func NewASGClient(scopeUser cloud.ScopeUsage, session cloud.Session, logger cloud.Logger, target runtime.Object) autoscalingiface.AutoScalingAPI {
    60  	asgClient := autoscaling.New(session.Session(), aws.NewConfig().WithLogLevel(awslogs.GetAWSLogLevel(logger)).WithLogger(awslogs.NewWrapLogr(logger)))
    61  	asgClient.Handlers.Build.PushFrontNamed(getUserAgentHandler())
    62  	asgClient.Handlers.CompleteAttempt.PushFront(awsmetrics.CaptureRequestMetrics(scopeUser.ControllerName()))
    63  	asgClient.Handlers.Complete.PushBack(recordAWSPermissionsIssue(target))
    64  
    65  	return asgClient
    66  }
    67  
    68  // NewEC2Client creates a new EC2 API client for a given session.
    69  func NewEC2Client(scopeUser cloud.ScopeUsage, session cloud.Session, logger cloud.Logger, target runtime.Object) ec2iface.EC2API {
    70  	ec2Client := ec2.New(session.Session(), aws.NewConfig().WithLogLevel(awslogs.GetAWSLogLevel(logger)).WithLogger(awslogs.NewWrapLogr(logger)))
    71  	ec2Client.Handlers.Build.PushFrontNamed(getUserAgentHandler())
    72  	if session.ServiceLimiter(ec2.ServiceID) != nil {
    73  		ec2Client.Handlers.Sign.PushFront(session.ServiceLimiter(ec2.ServiceID).LimitRequest)
    74  	}
    75  	ec2Client.Handlers.CompleteAttempt.PushFront(awsmetrics.CaptureRequestMetrics(scopeUser.ControllerName()))
    76  	if session.ServiceLimiter(ec2.ServiceID) != nil {
    77  		ec2Client.Handlers.CompleteAttempt.PushFront(session.ServiceLimiter(ec2.ServiceID).ReviewResponse)
    78  	}
    79  	ec2Client.Handlers.Complete.PushBack(recordAWSPermissionsIssue(target))
    80  
    81  	return ec2Client
    82  }
    83  
    84  // NewELBClient creates a new ELB API client for a given session.
    85  func NewELBClient(scopeUser cloud.ScopeUsage, session cloud.Session, logger cloud.Logger, target runtime.Object) elbiface.ELBAPI {
    86  	elbClient := elb.New(session.Session(), aws.NewConfig().WithLogLevel(awslogs.GetAWSLogLevel(logger)).WithLogger(awslogs.NewWrapLogr(logger)))
    87  	elbClient.Handlers.Build.PushFrontNamed(getUserAgentHandler())
    88  	elbClient.Handlers.Sign.PushFront(session.ServiceLimiter(elb.ServiceID).LimitRequest)
    89  	elbClient.Handlers.CompleteAttempt.PushFront(awsmetrics.CaptureRequestMetrics(scopeUser.ControllerName()))
    90  	elbClient.Handlers.CompleteAttempt.PushFront(session.ServiceLimiter(elb.ServiceID).ReviewResponse)
    91  	elbClient.Handlers.Complete.PushBack(recordAWSPermissionsIssue(target))
    92  
    93  	return elbClient
    94  }
    95  
    96  // NewELBv2Client creates a new ELB v2 API client for a given session.
    97  func NewELBv2Client(scopeUser cloud.ScopeUsage, session cloud.Session, logger cloud.Logger, target runtime.Object) elbv2iface.ELBV2API {
    98  	elbClient := elbv2.New(session.Session(), aws.NewConfig().WithLogLevel(awslogs.GetAWSLogLevel(logger)).WithLogger(awslogs.NewWrapLogr(logger)))
    99  	elbClient.Handlers.Build.PushFrontNamed(getUserAgentHandler())
   100  	elbClient.Handlers.Sign.PushFront(session.ServiceLimiter(elbv2.ServiceID).LimitRequest)
   101  	elbClient.Handlers.CompleteAttempt.PushFront(awsmetrics.CaptureRequestMetrics(scopeUser.ControllerName()))
   102  	elbClient.Handlers.CompleteAttempt.PushFront(session.ServiceLimiter(elbv2.ServiceID).ReviewResponse)
   103  	elbClient.Handlers.Complete.PushBack(recordAWSPermissionsIssue(target))
   104  
   105  	return elbClient
   106  }
   107  
   108  // NewEventBridgeClient creates a new EventBridge API client for a given session.
   109  func NewEventBridgeClient(scopeUser cloud.ScopeUsage, session cloud.Session, target runtime.Object) eventbridgeiface.EventBridgeAPI {
   110  	eventBridgeClient := eventbridge.New(session.Session())
   111  	eventBridgeClient.Handlers.Build.PushFrontNamed(getUserAgentHandler())
   112  	eventBridgeClient.Handlers.CompleteAttempt.PushFront(awsmetrics.CaptureRequestMetrics(scopeUser.ControllerName()))
   113  	eventBridgeClient.Handlers.Complete.PushBack(recordAWSPermissionsIssue(target))
   114  
   115  	return eventBridgeClient
   116  }
   117  
   118  // NewSQSClient creates a new SQS API client for a given session.
   119  func NewSQSClient(scopeUser cloud.ScopeUsage, session cloud.Session, target runtime.Object) sqsiface.SQSAPI {
   120  	SQSClient := sqs.New(session.Session())
   121  	SQSClient.Handlers.Build.PushFrontNamed(getUserAgentHandler())
   122  	SQSClient.Handlers.CompleteAttempt.PushFront(awsmetrics.CaptureRequestMetrics(scopeUser.ControllerName()))
   123  	SQSClient.Handlers.Complete.PushBack(recordAWSPermissionsIssue(target))
   124  
   125  	return SQSClient
   126  }
   127  
   128  // NewGlobalSQSClient for creating a new SQS API client that isn't tied to a cluster.
   129  func NewGlobalSQSClient(scopeUser cloud.ScopeUsage, session cloud.Session) sqsiface.SQSAPI {
   130  	SQSClient := sqs.New(session.Session())
   131  	SQSClient.Handlers.Build.PushFrontNamed(getUserAgentHandler())
   132  	SQSClient.Handlers.CompleteAttempt.PushFront(awsmetrics.CaptureRequestMetrics(scopeUser.ControllerName()))
   133  
   134  	return SQSClient
   135  }
   136  
   137  // NewResourgeTaggingClient creates a new Resource Tagging API client for a given session.
   138  func NewResourgeTaggingClient(scopeUser cloud.ScopeUsage, session cloud.Session, logger cloud.Logger, target runtime.Object) resourcegroupstaggingapiiface.ResourceGroupsTaggingAPIAPI {
   139  	resourceTagging := resourcegroupstaggingapi.New(session.Session(), aws.NewConfig().WithLogLevel(awslogs.GetAWSLogLevel(logger)).WithLogger(awslogs.NewWrapLogr(logger)))
   140  	resourceTagging.Handlers.Build.PushFrontNamed(getUserAgentHandler())
   141  	resourceTagging.Handlers.Sign.PushFront(session.ServiceLimiter(resourceTagging.ServiceID).LimitRequest)
   142  	resourceTagging.Handlers.CompleteAttempt.PushFront(awsmetrics.CaptureRequestMetrics(scopeUser.ControllerName()))
   143  	resourceTagging.Handlers.CompleteAttempt.PushFront(session.ServiceLimiter(resourceTagging.ServiceID).ReviewResponse)
   144  	resourceTagging.Handlers.Complete.PushBack(recordAWSPermissionsIssue(target))
   145  
   146  	return resourceTagging
   147  }
   148  
   149  // NewSecretsManagerClient creates a new Secrets API client for a given session..
   150  func NewSecretsManagerClient(scopeUser cloud.ScopeUsage, session cloud.Session, logger cloud.Logger, target runtime.Object) secretsmanageriface.SecretsManagerAPI {
   151  	secretsClient := secretsmanager.New(session.Session(), aws.NewConfig().WithLogLevel(awslogs.GetAWSLogLevel(logger)).WithLogger(awslogs.NewWrapLogr(logger)))
   152  	secretsClient.Handlers.Build.PushFrontNamed(getUserAgentHandler())
   153  	secretsClient.Handlers.Sign.PushFront(session.ServiceLimiter(secretsClient.ServiceID).LimitRequest)
   154  	secretsClient.Handlers.CompleteAttempt.PushFront(awsmetrics.CaptureRequestMetrics(scopeUser.ControllerName()))
   155  	secretsClient.Handlers.CompleteAttempt.PushFront(session.ServiceLimiter(secretsClient.ServiceID).ReviewResponse)
   156  	secretsClient.Handlers.Complete.PushBack(recordAWSPermissionsIssue(target))
   157  
   158  	return secretsClient
   159  }
   160  
   161  // NewEKSClient creates a new EKS API client for a given session.
   162  func NewEKSClient(scopeUser cloud.ScopeUsage, session cloud.Session, logger cloud.Logger, target runtime.Object) eksiface.EKSAPI {
   163  	eksClient := eks.New(session.Session(), aws.NewConfig().WithLogLevel(awslogs.GetAWSLogLevel(logger)).WithLogger(awslogs.NewWrapLogr(logger)))
   164  	eksClient.Handlers.Build.PushFrontNamed(getUserAgentHandler())
   165  	eksClient.Handlers.CompleteAttempt.PushFront(awsmetrics.CaptureRequestMetrics(scopeUser.ControllerName()))
   166  	eksClient.Handlers.Complete.PushBack(recordAWSPermissionsIssue(target))
   167  
   168  	return eksClient
   169  }
   170  
   171  // NewIAMClient creates a new IAM API client for a given session.
   172  func NewIAMClient(scopeUser cloud.ScopeUsage, session cloud.Session, logger cloud.Logger, target runtime.Object) iamiface.IAMAPI {
   173  	iamClient := iam.New(session.Session(), aws.NewConfig().WithLogLevel(awslogs.GetAWSLogLevel(logger)).WithLogger(awslogs.NewWrapLogr(logger)))
   174  	iamClient.Handlers.Build.PushFrontNamed(getUserAgentHandler())
   175  	iamClient.Handlers.CompleteAttempt.PushFront(awsmetrics.CaptureRequestMetrics(scopeUser.ControllerName()))
   176  	iamClient.Handlers.Complete.PushBack(recordAWSPermissionsIssue(target))
   177  
   178  	return iamClient
   179  }
   180  
   181  // NewSTSClient creates a new STS API client for a given session.
   182  func NewSTSClient(scopeUser cloud.ScopeUsage, session cloud.Session, logger cloud.Logger, target runtime.Object) stsiface.STSAPI {
   183  	stsClient := sts.New(session.Session(), aws.NewConfig().WithLogLevel(awslogs.GetAWSLogLevel(logger)).WithLogger(awslogs.NewWrapLogr(logger)))
   184  	stsClient.Handlers.Build.PushFrontNamed(getUserAgentHandler())
   185  	stsClient.Handlers.CompleteAttempt.PushFront(awsmetrics.CaptureRequestMetrics(scopeUser.ControllerName()))
   186  	stsClient.Handlers.Complete.PushBack(recordAWSPermissionsIssue(target))
   187  
   188  	return stsClient
   189  }
   190  
   191  // NewSSMClient creates a new Secrets API client for a given session.
   192  func NewSSMClient(scopeUser cloud.ScopeUsage, session cloud.Session, logger cloud.Logger, target runtime.Object) ssmiface.SSMAPI {
   193  	ssmClient := ssm.New(session.Session(), aws.NewConfig().WithLogLevel(awslogs.GetAWSLogLevel(logger)).WithLogger(awslogs.NewWrapLogr(logger)))
   194  	ssmClient.Handlers.Build.PushFrontNamed(getUserAgentHandler())
   195  	ssmClient.Handlers.CompleteAttempt.PushFront(awsmetrics.CaptureRequestMetrics(scopeUser.ControllerName()))
   196  	ssmClient.Handlers.Complete.PushBack(recordAWSPermissionsIssue(target))
   197  
   198  	return ssmClient
   199  }
   200  
   201  // NewS3Client creates a new S3 API client for a given session.
   202  func NewS3Client(scopeUser cloud.ScopeUsage, session cloud.Session, logger cloud.Logger, target runtime.Object) s3iface.S3API {
   203  	s3Client := s3.New(session.Session(), aws.NewConfig().WithLogLevel(awslogs.GetAWSLogLevel(logger)).WithLogger(awslogs.NewWrapLogr(logger)))
   204  	s3Client.Handlers.Build.PushFrontNamed(getUserAgentHandler())
   205  	s3Client.Handlers.CompleteAttempt.PushFront(awsmetrics.CaptureRequestMetrics(scopeUser.ControllerName()))
   206  	s3Client.Handlers.Complete.PushBack(recordAWSPermissionsIssue(target))
   207  
   208  	return s3Client
   209  }
   210  
   211  func recordAWSPermissionsIssue(target runtime.Object) func(r *request.Request) {
   212  	return func(r *request.Request) {
   213  		if awsErr, ok := r.Error.(awserr.Error); ok {
   214  			switch awsErr.Code() {
   215  			case "AuthFailure", "UnauthorizedOperation", "NoCredentialProviders":
   216  				record.Warnf(target, awsErr.Code(), "Operation %s failed with a credentials or permission issue", r.Operation.Name)
   217  			}
   218  		}
   219  	}
   220  }
   221  
   222  func getUserAgentHandler() request.NamedHandler {
   223  	return request.NamedHandler{
   224  		Name: "capa/user-agent",
   225  		Fn:   request.MakeAddToUserAgentHandler("aws.cluster.x-k8s.io", version.Get().String()),
   226  	}
   227  }
   228  
   229  // AWSClients contains all the aws clients used by the scopes.
   230  type AWSClients struct {
   231  	ASG             autoscalingiface.AutoScalingAPI
   232  	EC2             ec2iface.EC2API
   233  	ELB             elbiface.ELBAPI
   234  	SecretsManager  secretsmanageriface.SecretsManagerAPI
   235  	ResourceTagging resourcegroupstaggingapiiface.ResourceGroupsTaggingAPIAPI
   236  }