sigs.k8s.io/cluster-api-provider-aws@v1.5.5/pkg/cloud/awserrors/errors.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 awserrors
    18  
    19  import (
    20  	"net/http"
    21  
    22  	"github.com/aws/aws-sdk-go/aws/awserr"
    23  	"github.com/aws/aws-sdk-go/service/ssm"
    24  )
    25  
    26  // Error singletons for AWS errors.
    27  const (
    28  	AssociationIDNotFound      = "InvalidAssociationID.NotFound"
    29  	AuthFailure                = "AuthFailure"
    30  	BucketAlreadyOwnedByYou    = "BucketAlreadyOwnedByYou"
    31  	EIPNotFound                = "InvalidElasticIpID.NotFound"
    32  	GatewayNotFound            = "InvalidGatewayID.NotFound"
    33  	GroupNotFound              = "InvalidGroup.NotFound"
    34  	InternetGatewayNotFound    = "InvalidInternetGatewayID.NotFound"
    35  	InUseIPAddress             = "InvalidIPAddress.InUse"
    36  	InvalidAccessKeyID         = "InvalidAccessKeyId"
    37  	InvalidClientTokenID       = "InvalidClientTokenId"
    38  	InvalidInstanceID          = "InvalidInstanceID.NotFound"
    39  	InvalidSubnet              = "InvalidSubnet"
    40  	LaunchTemplateNameNotFound = "InvalidLaunchTemplateName.NotFoundException"
    41  	LoadBalancerNotFound       = "LoadBalancerNotFound"
    42  	NATGatewayNotFound         = "InvalidNatGatewayID.NotFound"
    43  	// nolint:gosec
    44  	NoCredentialProviders                   = "NoCredentialProviders"
    45  	NoSuchKey                               = "NoSuchKey"
    46  	PermissionNotFound                      = "InvalidPermission.NotFound"
    47  	ResourceExists                          = "ResourceExistsException"
    48  	ResourceNotFound                        = "InvalidResourceID.NotFound"
    49  	RouteTableNotFound                      = "InvalidRouteTableID.NotFound"
    50  	SubnetNotFound                          = "InvalidSubnetID.NotFound"
    51  	UnrecognizedClientException             = "UnrecognizedClientException"
    52  	VPCNotFound                             = "InvalidVpcID.NotFound"
    53  	ErrCodeRepositoryAlreadyExistsException = "RepositoryAlreadyExistsException"
    54  )
    55  
    56  var _ error = &EC2Error{}
    57  
    58  // Code returns the AWS error code as a string.
    59  func Code(err error) (string, bool) {
    60  	if awserr, ok := err.(awserr.Error); ok {
    61  		return awserr.Code(), true
    62  	}
    63  	return "", false
    64  }
    65  
    66  // Message returns the AWS error message as a string.
    67  func Message(err error) string {
    68  	if awserr, ok := err.(awserr.Error); ok {
    69  		return awserr.Message()
    70  	}
    71  	return ""
    72  }
    73  
    74  // EC2Error is an error exposed to users of this library.
    75  type EC2Error struct {
    76  	msg string
    77  
    78  	Code int
    79  }
    80  
    81  // Error implements the Error interface.
    82  func (e *EC2Error) Error() string {
    83  	return e.msg
    84  }
    85  
    86  // NewNotFound returns an error which indicates that the resource of the kind and the name was not found.
    87  func NewNotFound(msg string) error {
    88  	return &EC2Error{
    89  		msg:  msg,
    90  		Code: http.StatusNotFound,
    91  	}
    92  }
    93  
    94  // NewConflict returns an error which indicates that the request cannot be processed due to a conflict.
    95  func NewConflict(msg string) error {
    96  	return &EC2Error{
    97  		msg:  msg,
    98  		Code: http.StatusConflict,
    99  	}
   100  }
   101  
   102  func IsBucketAlreadyOwnedByYou(err error) bool {
   103  	if code, ok := Code(err); ok {
   104  		return code == BucketAlreadyOwnedByYou
   105  	}
   106  	return false
   107  }
   108  
   109  // IsResourceExists checks the state of the resource.
   110  func IsResourceExists(err error) bool {
   111  	if code, ok := Code(err); ok {
   112  		return code == ResourceExists
   113  	}
   114  	return false
   115  }
   116  
   117  // IsRepositoryExists checks if there is already a repository with the same name.
   118  func IsRepositoryExists(err error) bool {
   119  	if code, ok := Code(err); ok {
   120  		return code == ErrCodeRepositoryAlreadyExistsException
   121  	}
   122  	return false
   123  }
   124  
   125  // NewFailedDependency returns an error which indicates that a dependency failure status.
   126  func NewFailedDependency(msg string) error {
   127  	return &EC2Error{
   128  		msg:  msg,
   129  		Code: http.StatusFailedDependency,
   130  	}
   131  }
   132  
   133  // IsFailedDependency checks if the error is pf http.StatusFailedDependency.
   134  func IsFailedDependency(err error) bool {
   135  	return ReasonForError(err) == http.StatusFailedDependency
   136  }
   137  
   138  // IsNotFound returns true if the error was created by NewNotFound.
   139  func IsNotFound(err error) bool {
   140  	if ReasonForError(err) == http.StatusNotFound {
   141  		return true
   142  	}
   143  	return IsInvalidNotFoundError(err)
   144  }
   145  
   146  // IsConflict returns true if the error was created by NewConflict.
   147  func IsConflict(err error) bool {
   148  	return ReasonForError(err) == http.StatusConflict
   149  }
   150  
   151  // IsSDKError returns true if the error is of type awserr.Error.
   152  func IsSDKError(err error) (ok bool) {
   153  	_, ok = err.(awserr.Error)
   154  	return
   155  }
   156  
   157  // IsInvalidNotFoundError tests for common aws not found errors.
   158  func IsInvalidNotFoundError(err error) bool {
   159  	if code, ok := Code(err); ok {
   160  		switch code {
   161  		case VPCNotFound:
   162  			return true
   163  		case InvalidInstanceID:
   164  			return true
   165  		case ssm.ErrCodeParameterNotFound:
   166  			return true
   167  		case LaunchTemplateNameNotFound:
   168  			return true
   169  		}
   170  	}
   171  
   172  	return false
   173  }
   174  
   175  // ReasonForError returns the HTTP status for a particular error.
   176  func ReasonForError(err error) int {
   177  	if t, ok := err.(*EC2Error); ok {
   178  		return t.Code
   179  	}
   180  
   181  	return -1
   182  }
   183  
   184  // IsIgnorableSecurityGroupError checks for errors in SG that can be ignored and then return nil.
   185  func IsIgnorableSecurityGroupError(err error) error {
   186  	if code, ok := Code(err); ok {
   187  		switch code {
   188  		case GroupNotFound, PermissionNotFound:
   189  			return nil
   190  		default:
   191  			return err
   192  		}
   193  	}
   194  	return nil
   195  }