github.phpd.cn/hashicorp/packer@v1.3.2/builder/amazon/common/errors.go (about)

     1  package common
     2  
     3  import (
     4  	"fmt"
     5  	"log"
     6  	"regexp"
     7  
     8  	"github.com/aws/aws-sdk-go/aws/awserr"
     9  
    10  	"github.com/aws/aws-sdk-go/aws"
    11  	"github.com/aws/aws-sdk-go/aws/request"
    12  	"github.com/aws/aws-sdk-go/aws/session"
    13  	"github.com/aws/aws-sdk-go/service/sts"
    14  )
    15  
    16  var encodedFailureMessagePattern = regexp.MustCompile(`(?i)(.*) Encoded authorization failure message: ([\w-]+) ?( .*)?`)
    17  
    18  type stsDecoder interface {
    19  	DecodeAuthorizationMessage(input *sts.DecodeAuthorizationMessageInput) (*sts.DecodeAuthorizationMessageOutput, error)
    20  }
    21  
    22  // decodeError replaces encoded authorization messages with the
    23  // decoded results
    24  func decodeAWSError(decoder stsDecoder, err error) error {
    25  
    26  	groups := encodedFailureMessagePattern.FindStringSubmatch(err.Error())
    27  	if groups != nil && len(groups) > 1 {
    28  		result, decodeErr := decoder.DecodeAuthorizationMessage(&sts.DecodeAuthorizationMessageInput{
    29  			EncodedMessage: aws.String(groups[2]),
    30  		})
    31  		if decodeErr == nil {
    32  			msg := aws.StringValue(result.DecodedMessage)
    33  			return fmt.Errorf("%s Authorization failure message: '%s'%s", groups[1], msg, groups[3])
    34  		}
    35  		log.Printf("[WARN] Attempted to decode authorization message, but received: %v", decodeErr)
    36  	}
    37  	return err
    38  }
    39  
    40  // DecodeAuthZMessages enables automatic decoding of any
    41  // encoded authorization messages
    42  func DecodeAuthZMessages(sess *session.Session) {
    43  	azd := &authZMessageDecoder{
    44  		Decoder: sts.New(sess),
    45  	}
    46  	sess.Handlers.UnmarshalError.AfterEachFn = azd.afterEachFn
    47  }
    48  
    49  type authZMessageDecoder struct {
    50  	Decoder stsDecoder
    51  }
    52  
    53  func (a *authZMessageDecoder) afterEachFn(item request.HandlerListRunItem) bool {
    54  	if err, ok := item.Request.Error.(awserr.Error); ok && err.Code() == "UnauthorizedOperation" {
    55  		item.Request.Error = decodeAWSError(a.Decoder, err)
    56  	}
    57  	return true
    58  }