-
Notifications
You must be signed in to change notification settings - Fork 1.4k
/
target_group_binding_synthesizer.go
149 lines (130 loc) · 5 KB
/
target_group_binding_synthesizer.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
144
145
146
147
148
149
package elbv2
import (
"context"
"github.com/go-logr/logr"
"k8s.io/apimachinery/pkg/util/sets"
elbv2api "sigs.k8s.io/aws-load-balancer-controller/apis/elbv2/v1beta1"
"sigs.k8s.io/aws-load-balancer-controller/pkg/deploy/tracking"
"sigs.k8s.io/aws-load-balancer-controller/pkg/model/core"
elbv2model "sigs.k8s.io/aws-load-balancer-controller/pkg/model/elbv2"
"sigs.k8s.io/controller-runtime/pkg/client"
)
// NewTargetGroupBindingSynthesizer constructs new targetGroupBindingSynthesizer
func NewTargetGroupBindingSynthesizer(k8sClient client.Client, trackingProvider tracking.Provider, tgbManager TargetGroupBindingManager, logger logr.Logger, stack core.Stack) *targetGroupBindingSynthesizer {
return &targetGroupBindingSynthesizer{
k8sClient: k8sClient,
trackingProvider: trackingProvider,
tgbManager: tgbManager,
logger: logger,
stack: stack,
unmatchedK8sTGBs: nil,
}
}
// targetGroupBindingSynthesizer is responsible for synthesize TargetGroupBinding resources types for certain stack.
type targetGroupBindingSynthesizer struct {
k8sClient client.Client
trackingProvider tracking.Provider
tgbManager TargetGroupBindingManager
logger logr.Logger
stack core.Stack
unmatchedK8sTGBs []*elbv2api.TargetGroupBinding
}
func (s *targetGroupBindingSynthesizer) Synthesize(ctx context.Context) error {
var resTGBs []*elbv2model.TargetGroupBindingResource
s.stack.ListResources(&resTGBs)
k8sTGBs, err := s.findK8sTargetGroupBindings(ctx)
if err != nil {
return err
}
matchedResAndK8sTGBs, unmatchedResTGBs, unmatchedK8sTGBs, err := matchResAndK8sTargetGroupBindings(resTGBs, k8sTGBs)
if err != nil {
return err
}
s.unmatchedK8sTGBs = unmatchedK8sTGBs
for _, resTGB := range unmatchedResTGBs {
tgbStatus, err := s.tgbManager.Create(ctx, resTGB)
if err != nil {
return err
}
resTGB.SetStatus(tgbStatus)
}
for _, resAndK8sTGB := range matchedResAndK8sTGBs {
tgbStatus, err := s.tgbManager.Update(ctx, resAndK8sTGB.resTGB, resAndK8sTGB.k8sTGB)
if err != nil {
return err
}
resAndK8sTGB.resTGB.SetStatus(tgbStatus)
}
return nil
}
func (s *targetGroupBindingSynthesizer) PostSynthesize(ctx context.Context) error {
for _, k8sTGB := range s.unmatchedK8sTGBs {
if err := s.tgbManager.Delete(ctx, k8sTGB); err != nil {
return err
}
}
return nil
}
func (s *targetGroupBindingSynthesizer) findK8sTargetGroupBindings(ctx context.Context) ([]*elbv2api.TargetGroupBinding, error) {
stackLabels := s.trackingProvider.StackLabels(s.stack)
tgbList := &elbv2api.TargetGroupBindingList{}
if err := s.k8sClient.List(ctx, tgbList, client.MatchingLabels(stackLabels)); err != nil {
return nil, err
}
tgbs := make([]*elbv2api.TargetGroupBinding, 0, len(tgbList.Items))
for i := range tgbList.Items {
tgbs = append(tgbs, &tgbList.Items[i])
}
return tgbs, nil
}
type resAndK8sTargetGroupBindingPair struct {
resTGB *elbv2model.TargetGroupBindingResource
k8sTGB *elbv2api.TargetGroupBinding
}
func matchResAndK8sTargetGroupBindings(resTGBs []*elbv2model.TargetGroupBindingResource, k8sTGBs []*elbv2api.TargetGroupBinding) ([]resAndK8sTargetGroupBindingPair, []*elbv2model.TargetGroupBindingResource, []*elbv2api.TargetGroupBinding, error) {
var matchedResAndK8sTGBs []resAndK8sTargetGroupBindingPair
var unmatchedResTGBs []*elbv2model.TargetGroupBindingResource
var unmatchedK8sTGBs []*elbv2api.TargetGroupBinding
resTGBsByARN, err := mapResTargetGroupBindingByARN(resTGBs)
if err != nil {
return nil, nil, nil, err
}
k8sTGBsByARN := mapK8sTargetGroupBindingByARN(k8sTGBs)
resTGBARNs := sets.StringKeySet(resTGBsByARN)
k8sTGBARNs := sets.StringKeySet(k8sTGBsByARN)
for _, tgARN := range resTGBARNs.Intersection(k8sTGBARNs).List() {
resTGB := resTGBsByARN[tgARN]
k8sTGB := k8sTGBsByARN[tgARN]
matchedResAndK8sTGBs = append(matchedResAndK8sTGBs, resAndK8sTargetGroupBindingPair{
resTGB: resTGB,
k8sTGB: k8sTGB,
})
}
for _, tgARN := range resTGBARNs.Difference(k8sTGBARNs).List() {
unmatchedResTGBs = append(unmatchedResTGBs, resTGBsByARN[tgARN])
}
for _, tgARN := range k8sTGBARNs.Difference(resTGBARNs).List() {
unmatchedK8sTGBs = append(unmatchedK8sTGBs, k8sTGBsByARN[tgARN])
}
return matchedResAndK8sTGBs, unmatchedResTGBs, unmatchedK8sTGBs, nil
}
func mapResTargetGroupBindingByARN(resTGBs []*elbv2model.TargetGroupBindingResource) (map[string]*elbv2model.TargetGroupBindingResource, error) {
ctx := context.Background()
resTGBsByARN := make(map[string]*elbv2model.TargetGroupBindingResource, len(resTGBs))
for _, resTGB := range resTGBs {
tgARN, err := resTGB.Spec.Template.Spec.TargetGroupARN.Resolve(ctx)
if err != nil {
return nil, err
}
resTGBsByARN[tgARN] = resTGB
}
return resTGBsByARN, nil
}
func mapK8sTargetGroupBindingByARN(k8sTGBs []*elbv2api.TargetGroupBinding) map[string]*elbv2api.TargetGroupBinding {
k8sTGBsByARN := make(map[string]*elbv2api.TargetGroupBinding, len(k8sTGBs))
for _, k8sTGB := range k8sTGBs {
tgARN := k8sTGB.Spec.TargetGroupARN
k8sTGBsByARN[tgARN] = k8sTGB
}
return k8sTGBsByARN
}