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 }