github.com/mweagle/Sparta@v1.15.0/archetype/cloudwatch.go (about) 1 package archetype 2 3 import ( 4 "context" 5 "reflect" 6 "runtime" 7 8 awsLambdaEvents "github.com/aws/aws-lambda-go/events" 9 sparta "github.com/mweagle/Sparta" 10 "github.com/pkg/errors" 11 ) 12 13 // CloudWatchReactor represents a lambda function that responds to CW messages 14 type CloudWatchReactor interface { 15 // OnLogMessage when an SNS event occurs. Check the snsEvent field 16 // for the specific event 17 OnCloudWatchMessage(ctx context.Context, 18 cwLogs awsLambdaEvents.CloudwatchLogsEvent) (interface{}, error) 19 } 20 21 // CloudWatchReactorFunc is a free function that adapts a CloudWatchReactor 22 // compliant signature into a function that exposes an OnEvent 23 // function 24 type CloudWatchReactorFunc func(ctx context.Context, 25 cwLogs awsLambdaEvents.CloudwatchLogsEvent) (interface{}, error) 26 27 // OnCloudWatchMessage satisfies the CloudWatchReactor interface 28 func (reactorFunc CloudWatchReactorFunc) OnCloudWatchMessage(ctx context.Context, 29 cwLogs awsLambdaEvents.CloudwatchLogsEvent) (interface{}, error) { 30 return reactorFunc(ctx, cwLogs) 31 } 32 33 // ReactorName provides the name of the reactor func 34 func (reactorFunc CloudWatchReactorFunc) ReactorName() string { 35 return runtime.FuncForPC(reflect.ValueOf(reactorFunc).Pointer()).Name() 36 } 37 38 // NewCloudWatchEventedReactor returns a CloudWatch logs reactor lambda function 39 // that executes in response to the given events. The eventPatterns map is a map of names 40 // to map[string]interface{} values that represents the events to listen to. See 41 // https://docs.aws.amazon.com/AmazonCloudWatch/latest/events/CloudWatchEventsandEventPatterns.html 42 // for the proper syntax. Example: 43 // map[string]interface{}{ 44 // "source": []string{"aws.ec2"}, 45 // "detail-type": []string{"EC2 Instance state change"}, 46 // } 47 func NewCloudWatchEventedReactor(reactor CloudWatchReactor, 48 eventPatterns map[string]map[string]interface{}, 49 additionalLambdaPermissions []sparta.IAMRolePrivilege) (*sparta.LambdaAWSInfo, error) { 50 51 subscriptions := make(map[string]sparta.CloudWatchEventsRule) 52 for eachName, eachPattern := range eventPatterns { 53 subscriptions[eachName] = sparta.CloudWatchEventsRule{ 54 EventPattern: eachPattern, 55 } 56 } 57 return NewCloudWatchReactor(reactor, subscriptions, additionalLambdaPermissions) 58 } 59 60 // NewCloudWatchScheduledReactor returns a CloudWatch logs reactor lambda function 61 // that executes with the given schedule. The cronSchedules map is a map of names 62 // to ScheduleExpressions. See 63 // https://docs.aws.amazon.com/AmazonCloudWatch/latest/events/ScheduledEvents.html#RateExpressions 64 // for the proper syntax. Example: 65 // "rate(5 minutes)" 66 // 67 func NewCloudWatchScheduledReactor(reactor CloudWatchReactor, 68 cronSchedules map[string]string, 69 additionalLambdaPermissions []sparta.IAMRolePrivilege) (*sparta.LambdaAWSInfo, error) { 70 71 subscriptions := make(map[string]sparta.CloudWatchEventsRule) 72 for eachName, eachSchedule := range cronSchedules { 73 subscriptions[eachName] = sparta.CloudWatchEventsRule{ 74 ScheduleExpression: eachSchedule, 75 } 76 } 77 return NewCloudWatchReactor(reactor, subscriptions, additionalLambdaPermissions) 78 } 79 80 // NewCloudWatchReactor returns a CloudWatch logs reactor lambda function 81 func NewCloudWatchReactor(reactor CloudWatchReactor, 82 subscriptions map[string]sparta.CloudWatchEventsRule, 83 additionalLambdaPermissions []sparta.IAMRolePrivilege) (*sparta.LambdaAWSInfo, error) { 84 if len(subscriptions) <= 0 { 85 return nil, errors.Errorf("CloudWatchLogs subscription map must not be empty") 86 } 87 88 reactorLambda := func(ctx context.Context, cwLogs awsLambdaEvents.CloudwatchLogsEvent) (interface{}, error) { 89 return reactor.OnCloudWatchMessage(ctx, cwLogs) 90 } 91 lambdaFn, lambdaFnErr := sparta.NewAWSLambda(reactorName(reactor), 92 reactorLambda, 93 sparta.IAMRoleDefinition{}) 94 if lambdaFnErr != nil { 95 return nil, errors.Wrapf(lambdaFnErr, "attempting to create reactor") 96 } 97 cloudWatchEventsPermission := sparta.CloudWatchEventsPermission{} 98 cloudWatchEventsPermission.Rules = make(map[string]sparta.CloudWatchEventsRule) 99 for eachRuleName, eachRule := range subscriptions { 100 cloudWatchEventsPermission.Rules[eachRuleName] = eachRule 101 } 102 lambdaFn.Permissions = append(lambdaFn.Permissions, cloudWatchEventsPermission) 103 104 if len(additionalLambdaPermissions) != 0 { 105 lambdaFn.RoleDefinition.Privileges = additionalLambdaPermissions 106 } 107 return lambdaFn, nil 108 }