/
codeCommitLambdaEventSourceResource.go
143 lines (127 loc) · 4.99 KB
/
codeCommitLambdaEventSourceResource.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
package resources
import (
"context"
"encoding/json"
awsv2 "github.com/aws/aws-sdk-go-v2/aws"
awsv2CodeCommit "github.com/aws/aws-sdk-go-v2/service/codecommit"
awsv2CodeCommitTypes "github.com/aws/aws-sdk-go-v2/service/codecommit/types"
gof "github.com/awslabs/goformation/v5/cloudformation"
"github.com/rs/zerolog"
)
// CodeCommitLambdaEventSourceResourceRequest defines the request properties to configure
// SNS
type CodeCommitLambdaEventSourceResourceRequest struct {
CustomResourceRequest
LambdaTargetArn string
RepositoryName string
TriggerName string
Events []string `json:",omitempty"`
Branches []string `json:",omitempty"`
}
// CodeCommitLambdaEventSourceResource is a simple POC showing how to create custom resources
type CodeCommitLambdaEventSourceResource struct {
gof.CustomResource
}
func (command CodeCommitLambdaEventSourceResource) updateRegistration(ctx context.Context,
isTargetActive bool,
awsConfig awsv2.Config,
event *CloudFormationLambdaEvent,
logger *zerolog.Logger) (map[string]interface{}, error) {
request := CodeCommitLambdaEventSourceResourceRequest{}
unmarshalErr := json.Unmarshal(event.ResourceProperties, &request)
if unmarshalErr != nil {
return nil, unmarshalErr
}
logger.Info().
Interface("Event", command).
Msg("CodeCommit Custom Resource info")
// We need the repo in here...
codeCommitSvc := awsv2CodeCommit.NewFromConfig(awsConfig)
// Get the current subscriptions...
ccInput := &awsv2CodeCommit.GetRepositoryTriggersInput{
RepositoryName: awsv2.String(request.RepositoryName),
}
triggers, triggersErr := codeCommitSvc.GetRepositoryTriggers(ctx, ccInput)
if triggersErr != nil {
return nil, triggersErr
}
// Find the lambda ARN for this function...
putTriggers := make([]awsv2CodeCommitTypes.RepositoryTrigger, 0)
var preexistingTrigger *awsv2CodeCommitTypes.RepositoryTrigger
for _, eachTrigger := range triggers.Triggers {
// Treat the preexisting one specially
if *eachTrigger.DestinationArn == request.LambdaTargetArn {
preexistingTrigger = &eachTrigger
} else {
putTriggers = append(putTriggers, eachTrigger)
}
}
// Just log it...
logger.Info().
Str("RepositoryName", request.RepositoryName).
Interface("Trigger", preexistingTrigger).
Interface("LambdaArn", request.LambdaTargetArn).
Msg("Current CodeCommit trigger status")
reqBranches := make([]string, len(request.Branches))
for idx, eachBranch := range request.Branches {
reqBranches[idx] = eachBranch
}
reqEvents := make([]awsv2CodeCommitTypes.RepositoryTriggerEventEnum, len(request.Events))
for idx, eachEvent := range request.Events {
reqEvents[idx] = awsv2CodeCommitTypes.RepositoryTriggerEventEnum(eachEvent)
}
if len(reqEvents) <= 0 {
logger.Info().Msg("No events found. Defaulting to `all`.")
reqEvents = []awsv2CodeCommitTypes.RepositoryTriggerEventEnum{
awsv2CodeCommitTypes.RepositoryTriggerEventEnumAll,
}
}
if isTargetActive && preexistingTrigger == nil {
// Add one...
putTriggers = append(putTriggers, awsv2CodeCommitTypes.RepositoryTrigger{
DestinationArn: awsv2.String(request.LambdaTargetArn),
Name: awsv2.String(request.TriggerName),
Branches: reqBranches,
Events: reqEvents,
})
} else if !isTargetActive {
// It's already removed...
} else if isTargetActive {
putTriggers = append(putTriggers, *preexistingTrigger)
}
// Put it back...
putTriggersInput := &awsv2CodeCommit.PutRepositoryTriggersInput{
RepositoryName: awsv2.String(request.RepositoryName),
Triggers: putTriggers,
}
putTriggersResp, putTriggersRespErr := codeCommitSvc.PutRepositoryTriggers(ctx, putTriggersInput)
// Just log it...
logger.Info().
Interface("Response", putTriggersResp).
Interface("Error", putTriggersRespErr).
Msg("CodeCommit PutRepositoryTriggers")
return nil, putTriggersRespErr
}
// IAMPrivileges returns the IAM privs for this custom action
func (command *CodeCommitLambdaEventSourceResource) IAMPrivileges() []string {
return []string{"codecommit:GetRepositoryTriggers",
"codecommit:PutRepositoryTriggers"}
}
// Create implements the custom resource create operation
func (command CodeCommitLambdaEventSourceResource) Create(ctx context.Context, awsConfig awsv2.Config,
event *CloudFormationLambdaEvent,
logger *zerolog.Logger) (map[string]interface{}, error) {
return command.updateRegistration(ctx, true, awsConfig, event, logger)
}
// Update implements the custom resource update operation
func (command CodeCommitLambdaEventSourceResource) Update(ctx context.Context, awsConfig awsv2.Config,
event *CloudFormationLambdaEvent,
logger *zerolog.Logger) (map[string]interface{}, error) {
return command.updateRegistration(ctx, true, awsConfig, event, logger)
}
// Delete implements the custom resource delete operation
func (command CodeCommitLambdaEventSourceResource) Delete(ctx context.Context, awsConfig awsv2.Config,
event *CloudFormationLambdaEvent,
logger *zerolog.Logger) (map[string]interface{}, error) {
return command.updateRegistration(ctx, false, awsConfig, event, logger)
}