github.com/mweagle/Sparta@v1.15.0/aws/cloudformation/resources/s3LambdaEventSourceResource.go (about)

     1  package resources
     2  
     3  import (
     4  	"encoding/json"
     5  	"strings"
     6  
     7  	"github.com/aws/aws-sdk-go/aws"
     8  	"github.com/aws/aws-sdk-go/aws/session"
     9  	"github.com/aws/aws-sdk-go/service/s3"
    10  	gocf "github.com/mweagle/go-cloudformation"
    11  	"github.com/sirupsen/logrus"
    12  )
    13  
    14  // S3LambdaEventSourceResourceRequest is what the UserProperties
    15  // should be set to in the CustomResource invocation
    16  type S3LambdaEventSourceResourceRequest struct {
    17  	BucketArn       *gocf.StringExpr
    18  	Events          []string
    19  	LambdaTargetArn *gocf.StringExpr
    20  	Filter          *s3.NotificationConfigurationFilter `json:"Filter,omitempty"`
    21  }
    22  
    23  // S3LambdaEventSourceResource manages registering a Lambda function with S3 event
    24  type S3LambdaEventSourceResource struct {
    25  	gocf.CloudFormationCustomResource
    26  	S3LambdaEventSourceResourceRequest
    27  }
    28  
    29  // IAMPrivileges returns the IAM privs for this custom action
    30  func (command *S3LambdaEventSourceResource) IAMPrivileges() []string {
    31  	return []string{"s3:GetBucketLocation",
    32  		"s3:GetBucketNotification",
    33  		"s3:PutBucketNotification",
    34  		"s3:GetBucketNotificationConfiguration",
    35  		"s3:PutBucketNotificationConfiguration"}
    36  }
    37  
    38  func (command S3LambdaEventSourceResource) updateNotification(isTargetActive bool,
    39  	session *session.Session,
    40  	event *CloudFormationLambdaEvent,
    41  	logger *logrus.Logger) (map[string]interface{}, error) {
    42  
    43  	unmarshalErr := json.Unmarshal(event.ResourceProperties, &command)
    44  	if unmarshalErr != nil {
    45  		return nil, unmarshalErr
    46  	}
    47  
    48  	s3Svc := s3.New(session)
    49  	bucketParts := strings.Split(command.BucketArn.Literal, ":")
    50  	bucketName := bucketParts[len(bucketParts)-1]
    51  
    52  	params := &s3.GetBucketNotificationConfigurationRequest{
    53  		Bucket: aws.String(bucketName),
    54  	}
    55  	config, configErr := s3Svc.GetBucketNotificationConfiguration(params)
    56  	if nil != configErr {
    57  		return nil, configErr
    58  	}
    59  	// First thing, eliminate existing references...
    60  	var lambdaConfigurations []*s3.LambdaFunctionConfiguration
    61  	for _, eachLambdaConfig := range config.LambdaFunctionConfigurations {
    62  		if *eachLambdaConfig.LambdaFunctionArn != command.LambdaTargetArn.Literal {
    63  			lambdaConfigurations = append(lambdaConfigurations, eachLambdaConfig)
    64  		}
    65  	}
    66  
    67  	if isTargetActive {
    68  		var eventPtrs []*string
    69  		for _, eachString := range command.Events {
    70  			eventPtrs = append(eventPtrs, aws.String(eachString))
    71  		}
    72  		commandConfig := &s3.LambdaFunctionConfiguration{
    73  			LambdaFunctionArn: aws.String(command.LambdaTargetArn.Literal),
    74  			Events:            eventPtrs,
    75  		}
    76  		if command.Filter != nil {
    77  			commandConfig.Filter = command.Filter
    78  		}
    79  		lambdaConfigurations = append(lambdaConfigurations, commandConfig)
    80  	}
    81  	config.LambdaFunctionConfigurations = lambdaConfigurations
    82  
    83  	putBucketNotificationConfigurationInput := &s3.PutBucketNotificationConfigurationInput{
    84  		Bucket:                    aws.String(bucketName),
    85  		NotificationConfiguration: config,
    86  	}
    87  
    88  	logger.WithFields(logrus.Fields{
    89  		"PutBucketNotificationConfigurationInput": putBucketNotificationConfigurationInput,
    90  	}).Debug("Updating bucket configuration")
    91  
    92  	_, putErr := s3Svc.PutBucketNotificationConfiguration(putBucketNotificationConfigurationInput)
    93  	return nil, putErr
    94  }
    95  
    96  // Create implements the custom resource create operation
    97  func (command S3LambdaEventSourceResource) Create(awsSession *session.Session,
    98  	event *CloudFormationLambdaEvent,
    99  	logger *logrus.Logger) (map[string]interface{}, error) {
   100  	return command.updateNotification(true, awsSession, event, logger)
   101  }
   102  
   103  // Update implements the custom resource update operation
   104  func (command S3LambdaEventSourceResource) Update(awsSession *session.Session,
   105  	event *CloudFormationLambdaEvent,
   106  	logger *logrus.Logger) (map[string]interface{}, error) {
   107  	return command.updateNotification(true, awsSession, event, logger)
   108  }
   109  
   110  // Delete implements the custom resource delete operation
   111  func (command S3LambdaEventSourceResource) Delete(awsSession *session.Session,
   112  	event *CloudFormationLambdaEvent,
   113  	logger *logrus.Logger) (map[string]interface{}, error) {
   114  	return command.updateNotification(false, awsSession, event, logger)
   115  }