Skip to content

Commit 1ef574c

Browse files
authored
Merge branch 'main' into change_cert-manager_apiversion
2 parents ef83d66 + 1eb373b commit 1ef574c

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+4359
-265
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ site
2323

2424
# editor and IDE paraphernalia
2525
.idea
26+
.vscode
2627
*.swp
2728
*.swo
2829
*~

config/rbac/role.yaml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,14 @@ rules:
7777
verbs:
7878
- patch
7979
- update
80+
- apiGroups:
81+
- discovery.k8s.io
82+
resources:
83+
- endpointslices
84+
verbs:
85+
- get
86+
- list
87+
- watch
8088
- apiGroups:
8189
- elbv2.k8s.aws
8290
resources:
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
package eventhandlers
2+
3+
import (
4+
"context"
5+
6+
"github.com/go-logr/logr"
7+
"github.com/pkg/errors"
8+
discv1 "k8s.io/api/discovery/v1beta1"
9+
"k8s.io/apimachinery/pkg/api/equality"
10+
"k8s.io/apimachinery/pkg/types"
11+
"k8s.io/client-go/util/workqueue"
12+
elbv2api "sigs.k8s.io/aws-load-balancer-controller/apis/elbv2/v1beta1"
13+
"sigs.k8s.io/aws-load-balancer-controller/pkg/k8s"
14+
"sigs.k8s.io/aws-load-balancer-controller/pkg/targetgroupbinding"
15+
"sigs.k8s.io/controller-runtime/pkg/client"
16+
"sigs.k8s.io/controller-runtime/pkg/event"
17+
"sigs.k8s.io/controller-runtime/pkg/handler"
18+
"sigs.k8s.io/controller-runtime/pkg/reconcile"
19+
)
20+
21+
const svcNameLabel = "kubernetes.io/service-name"
22+
23+
// NewEnqueueRequestsForEndpointSlicesEvent constructs new enqueueRequestsForEndpointSlicesEvent.
24+
func NewEnqueueRequestsForEndpointSlicesEvent(k8sClient client.Client, logger logr.Logger) handler.EventHandler {
25+
return &enqueueRequestsForEndpointSlicesEvent{
26+
k8sClient: k8sClient,
27+
logger: logger,
28+
}
29+
}
30+
31+
var _ handler.EventHandler = (*enqueueRequestsForEndpointSlicesEvent)(nil)
32+
33+
type enqueueRequestsForEndpointSlicesEvent struct {
34+
k8sClient client.Client
35+
logger logr.Logger
36+
}
37+
38+
// Create is called in response to an create event - e.g. EndpointSlice Creation.
39+
func (h *enqueueRequestsForEndpointSlicesEvent) Create(e event.CreateEvent, queue workqueue.RateLimitingInterface) {
40+
epNew := e.Object.(*discv1.EndpointSlice)
41+
h.logger.V(1).Info("Create event for EndpointSlices", "name", epNew.Name)
42+
h.enqueueImpactedTargetGroupBindings(queue, epNew)
43+
}
44+
45+
// Update is called in response to an update event - e.g. EndpointSlice Updated.
46+
func (h *enqueueRequestsForEndpointSlicesEvent) Update(e event.UpdateEvent, queue workqueue.RateLimitingInterface) {
47+
epOld := e.ObjectOld.(*discv1.EndpointSlice)
48+
epNew := e.ObjectNew.(*discv1.EndpointSlice)
49+
h.logger.V(1).Info("Update event for EndpointSlices", "name", epNew.Name)
50+
if !equality.Semantic.DeepEqual(epOld.Ports, epNew.Ports) || !equality.Semantic.DeepEqual(epOld.Endpoints, epNew.Endpoints) {
51+
h.logger.V(1).Info("Enqueue EndpointSlice", "name", epNew.Name)
52+
h.enqueueImpactedTargetGroupBindings(queue, epNew)
53+
}
54+
}
55+
56+
// Delete is called in response to a delete event - e.g. EndpointSlice Deleted.
57+
func (h *enqueueRequestsForEndpointSlicesEvent) Delete(e event.DeleteEvent, queue workqueue.RateLimitingInterface) {
58+
epOld := e.Object.(*discv1.EndpointSlice)
59+
h.logger.V(1).Info("Deletion event for EndpointSlices", "name", epOld.Name)
60+
h.enqueueImpactedTargetGroupBindings(queue, epOld)
61+
}
62+
63+
// Generic is called in response to an event of an unknown type or a synthetic event triggered as a cron or
64+
// external trigger request - e.g. reconcile AutoScaling, or a WebHook.
65+
func (h *enqueueRequestsForEndpointSlicesEvent) Generic(event.GenericEvent, workqueue.RateLimitingInterface) {
66+
}
67+
68+
func (h *enqueueRequestsForEndpointSlicesEvent) enqueueImpactedTargetGroupBindings(queue workqueue.RateLimitingInterface, epSlice *discv1.EndpointSlice) {
69+
tgbList := &elbv2api.TargetGroupBindingList{}
70+
svcName, present := epSlice.Labels[svcNameLabel]
71+
if !present {
72+
err := errors.Errorf("EndpointSlice does not have a %v label", svcNameLabel)
73+
h.logger.Error(err, "unable to find service name for endpointslice")
74+
return
75+
}
76+
if err := h.k8sClient.List(context.Background(), tgbList,
77+
client.InNamespace(epSlice.Namespace),
78+
client.MatchingFields{targetgroupbinding.IndexKeyServiceRefName: svcName}); err != nil {
79+
h.logger.Error(err, "failed to fetch targetGroupBindings")
80+
return
81+
}
82+
83+
epSliceKey := k8s.NamespacedName(epSlice)
84+
for _, tgb := range tgbList.Items {
85+
if tgb.Spec.TargetType == nil || (*tgb.Spec.TargetType) != elbv2api.TargetTypeIP {
86+
continue
87+
}
88+
89+
h.logger.V(1).Info("enqueue targetGroupBinding for endpointslices event",
90+
"endpointslices", epSliceKey,
91+
"targetGroupBinding", k8s.NamespacedName(&tgb),
92+
)
93+
queue.Add(reconcile.Request{
94+
NamespacedName: types.NamespacedName{
95+
Namespace: tgb.Namespace,
96+
Name: tgb.Name,
97+
},
98+
})
99+
}
100+
}
Lines changed: 183 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,183 @@
1+
package eventhandlers
2+
3+
import (
4+
"context"
5+
"testing"
6+
7+
"github.com/golang/mock/gomock"
8+
"github.com/google/go-cmp/cmp"
9+
"github.com/stretchr/testify/assert"
10+
discv1 "k8s.io/api/discovery/v1beta1"
11+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
12+
"k8s.io/apimachinery/pkg/types"
13+
"k8s.io/client-go/util/workqueue"
14+
elbv2api "sigs.k8s.io/aws-load-balancer-controller/apis/elbv2/v1beta1"
15+
mock_client "sigs.k8s.io/aws-load-balancer-controller/mocks/controller-runtime/client"
16+
"sigs.k8s.io/aws-load-balancer-controller/pkg/testutils"
17+
ctrl "sigs.k8s.io/controller-runtime"
18+
"sigs.k8s.io/controller-runtime/pkg/client"
19+
"sigs.k8s.io/controller-runtime/pkg/controller/controllertest"
20+
"sigs.k8s.io/controller-runtime/pkg/log"
21+
)
22+
23+
func Test_enqueueRequestsForEndpointSlicesEvent_enqueueImpactedTargetGroupBindings(t *testing.T) {
24+
instanceTargetType := elbv2api.TargetTypeInstance
25+
ipTargetType := elbv2api.TargetTypeIP
26+
27+
type tgbListCall struct {
28+
opts []client.ListOption
29+
tgbs []*elbv2api.TargetGroupBinding
30+
err error
31+
}
32+
type fields struct {
33+
tgbListCalls []tgbListCall
34+
}
35+
type args struct {
36+
epslice *discv1.EndpointSlice
37+
}
38+
tests := []struct {
39+
name string
40+
fields fields
41+
args args
42+
wantRequests []ctrl.Request
43+
}{
44+
{
45+
name: "service event should enqueue impacted ip TargetType TGBs",
46+
fields: fields{
47+
tgbListCalls: []tgbListCall{
48+
{
49+
opts: []client.ListOption{
50+
client.InNamespace("awesome-ns"),
51+
client.MatchingFields{"spec.serviceRef.name": "awesome-svc"},
52+
},
53+
tgbs: []*elbv2api.TargetGroupBinding{
54+
{
55+
ObjectMeta: metav1.ObjectMeta{
56+
Namespace: "awesome-ns",
57+
Name: "tgb-1",
58+
},
59+
Spec: elbv2api.TargetGroupBindingSpec{
60+
TargetType: &ipTargetType,
61+
},
62+
},
63+
{
64+
ObjectMeta: metav1.ObjectMeta{
65+
Namespace: "awesome-ns",
66+
Name: "tgb-2",
67+
},
68+
Spec: elbv2api.TargetGroupBindingSpec{
69+
TargetType: &instanceTargetType,
70+
},
71+
},
72+
{
73+
ObjectMeta: metav1.ObjectMeta{
74+
Namespace: "awesome-ns",
75+
Name: "tgb-3",
76+
},
77+
Spec: elbv2api.TargetGroupBindingSpec{
78+
TargetType: &ipTargetType,
79+
},
80+
},
81+
},
82+
},
83+
},
84+
},
85+
args: args{
86+
epslice: &discv1.EndpointSlice{
87+
ObjectMeta: metav1.ObjectMeta{
88+
Namespace: "awesome-ns",
89+
Name: "awesome-svc",
90+
Labels: map[string]string{"kubernetes.io/service-name": "awesome-svc"},
91+
},
92+
},
93+
},
94+
wantRequests: []ctrl.Request{
95+
{
96+
NamespacedName: types.NamespacedName{Namespace: "awesome-ns", Name: "tgb-1"},
97+
},
98+
{
99+
NamespacedName: types.NamespacedName{Namespace: "awesome-ns", Name: "tgb-3"},
100+
},
101+
},
102+
},
103+
{
104+
name: "service event should enqueue impacted ip TargetType TGBs - ignore nil TargetType",
105+
fields: fields{
106+
tgbListCalls: []tgbListCall{
107+
{
108+
opts: []client.ListOption{
109+
client.InNamespace("awesome-ns"),
110+
client.MatchingFields{"spec.serviceRef.name": "awesome-svc"},
111+
},
112+
tgbs: []*elbv2api.TargetGroupBinding{
113+
{
114+
ObjectMeta: metav1.ObjectMeta{
115+
Namespace: "awesome-ns",
116+
Name: "tgb-1",
117+
},
118+
Spec: elbv2api.TargetGroupBindingSpec{
119+
TargetType: &ipTargetType,
120+
},
121+
},
122+
{
123+
ObjectMeta: metav1.ObjectMeta{
124+
Namespace: "awesome-ns",
125+
Name: "tgb-2",
126+
},
127+
Spec: elbv2api.TargetGroupBindingSpec{
128+
TargetType: nil,
129+
},
130+
},
131+
},
132+
},
133+
},
134+
},
135+
args: args{
136+
epslice: &discv1.EndpointSlice{
137+
ObjectMeta: metav1.ObjectMeta{
138+
Namespace: "awesome-ns",
139+
Name: "awesome-svc",
140+
Labels: map[string]string{"kubernetes.io/service-name": "awesome-svc"},
141+
},
142+
},
143+
},
144+
wantRequests: []ctrl.Request{
145+
{
146+
NamespacedName: types.NamespacedName{Namespace: "awesome-ns", Name: "tgb-1"},
147+
},
148+
},
149+
},
150+
}
151+
for _, tt := range tests {
152+
t.Run(tt.name, func(t *testing.T) {
153+
ctrl := gomock.NewController(t)
154+
defer ctrl.Finish()
155+
156+
k8sClient := mock_client.NewMockClient(ctrl)
157+
for _, call := range tt.fields.tgbListCalls {
158+
var extraMatchers []interface{}
159+
for _, opt := range call.opts {
160+
extraMatchers = append(extraMatchers, testutils.NewListOptionEquals(opt))
161+
}
162+
k8sClient.EXPECT().List(gomock.Any(), gomock.Any(), extraMatchers...).DoAndReturn(
163+
func(ctx context.Context, tgbList *elbv2api.TargetGroupBindingList, opts ...client.ListOption) error {
164+
for _, tgb := range call.tgbs {
165+
tgbList.Items = append(tgbList.Items, *(tgb.DeepCopy()))
166+
}
167+
return call.err
168+
},
169+
)
170+
}
171+
172+
h := &enqueueRequestsForEndpointSlicesEvent{
173+
k8sClient: k8sClient,
174+
logger: &log.NullLogger{},
175+
}
176+
queue := controllertest.Queue{Interface: workqueue.New()}
177+
h.enqueueImpactedTargetGroupBindings(queue, tt.args.epslice)
178+
gotRequests := testutils.ExtractCTRLRequestsFromQueue(queue)
179+
assert.True(t, cmp.Equal(tt.wantRequests, gotRequests),
180+
"diff", cmp.Diff(tt.wantRequests, gotRequests))
181+
})
182+
}
183+
}

0 commit comments

Comments
 (0)