-
Notifications
You must be signed in to change notification settings - Fork 3
/
main.go
122 lines (100 loc) · 2.72 KB
/
main.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
package main
import (
"context"
"fmt"
"github.com/aws/aws-lambda-go/lambda"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/elbv2"
"github.com/glassechidna/awsctx/service/elbv2ctx"
"github.com/pkg/errors"
)
func main() {
sess := session.Must(session.NewSession())
api := elbv2ctx.New(elbv2.New(sess), nil)
handler := lambda.NewHandler(New(api).Handle)
handler = &logger{handler}
lambda.StartHandler(handler)
}
type handler struct {
api elbv2ctx.ELBV2
}
func New(api elbv2ctx.ELBV2) *handler {
return &handler{api: api}
}
func (h *handler) Handle(ctx context.Context, input *MacroInput) (*MacroOutput, error) {
tf := &templateFragment{fragment: input.Fragment}
v := &myvisitor{}
err := tf.Visit(ctx, v)
if err != nil {
return nil, err
}
err = h.handleAssociation(ctx, tf, v.props)
if err != nil {
return nil, err
}
return &MacroOutput{
Status: MacroOutputStatusSuccess,
RequestId: input.RequestId,
Fragment: tf.fragment,
}, nil
}
func (h *handler) handleAssociation(ctx context.Context, tf *templateFragment, props []albEventProperties) error {
seen := map[string]bool{}
for _, prop := range props {
if len(prop.ListenerArn) == 0 || prop.VpcConfig != nil {
return errors.New("TODO: support vpc config")
}
tgName := fmt.Sprintf("%sAlbTargetGroup", prop.Resource)
pjName := fmt.Sprintf("%sAlbPermission", prop.Resource)
lrName := fmt.Sprintf("%sAlb%sListenerRule", prop.Resource, prop.EventName)
target := targetFunctionJson(prop.Resource)
if len(prop.Alias) > 0 {
target = targetAliasJson(prop.Resource + ".Alias")
}
if _, found := seen[prop.Resource]; !found {
seen[prop.Resource] = true
tg := targetGroupJson(prop.Resource, target, prop.Tags)
err := tf.PutResource(tgName, tg)
if err != nil {
return err
}
pj := permissionJson(target)
err = tf.PutResource(pjName, pj)
if err != nil {
return err
}
}
conds := convertConditions(prop.Conditions)
//rnd := rand.New(rand.NewSource(time.Now().UnixNano()))
//priority := 40_000 + rnd.Intn(10_000)
//priority := calculatePriority(conds)
priority := prop.Priority
if priority == 0 {
priority = 50_000
}
forward := ActionProperty{
Type: elbv2.ActionTypeEnumForward,
TargetGroupArn: &stringOrRef{Ref: tgName},
}
rule := rule{
Priority: priority,
ListenerArn: prop.ListenerArn,
Conditions: conds,
Actions: []ActionProperty{forward},
}
if prop.Oidc != nil {
auth, err := oidcAction(prop.Oidc)
if err != nil {
return err
}
forward.Order = 2
rule.Actions = []ActionProperty{*auth, forward}
}
lr := listenerRuleJson(rule)
err := tf.PutResource(lrName, lr)
if err != nil {
return err
}
}
return nil
}