Skip to content

Commit c8f451a

Browse files
authored
add webhook for TargetGroupBinding (#1450)
1 parent a3f3744 commit c8f451a

15 files changed

+887
-39
lines changed

Makefile

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11

22
# Image URL to use all building/pushing image targets
33
IMG ?= amazon/aws-alb-ingress-controller:v2.0.0-rc1
4-
# Produce CRDs that work back to Kubernetes 1.11 (no version conversion)
5-
CRD_OPTIONS ?= "crd:trivialVersions=true"
4+
5+
CRD_OPTIONS ?= "crd:trivialVersions=false,crdVersions=v1beta1"
66

77
# Get the currently used golang install path (in GOPATH/bin, unless GOBIN is set)
88
ifeq (,$(shell go env GOBIN))
@@ -41,6 +41,7 @@ deploy: manifests
4141
# Generate manifests e.g. CRD, RBAC etc.
4242
manifests: controller-gen
4343
$(CONTROLLER_GEN) $(CRD_OPTIONS) rbac:roleName=controller-role webhook paths="./..." output:crd:artifacts:config=config/crd/bases
44+
yq w -i config/webhook/manifests.v1beta1.yaml -d'*' "metadata.name" "webhook"
4445

4546
# Run go fmt against code
4647
fmt:
@@ -70,7 +71,7 @@ ifeq (, $(shell which controller-gen))
7071
CONTROLLER_GEN_TMP_DIR=$$(mktemp -d) ;\
7172
cd $$CONTROLLER_GEN_TMP_DIR ;\
7273
go mod init tmp ;\
73-
go get sigs.k8s.io/controller-tools/cmd/controller-gen@v0.2.5 ;\
74+
go get sigs.k8s.io/controller-tools/cmd/controller-gen@v0.4.0 ;\
7475
rm -rf $$CONTROLLER_GEN_TMP_DIR ;\
7576
}
7677
CONTROLLER_GEN=$(GOBIN)/controller-gen

apis/elbv2/v1alpha1/targetgroupbinding_types.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,10 @@ type TargetGroupBindingStatus struct {
129129
}
130130

131131
// +kubebuilder:object:root=true
132+
// +kubebuilder:resource:categories=all
133+
// +kubebuilder:subresource:status
134+
// +kubebuilder:printcolumn:name="TARGET-TYPE",type="string",JSONPath=".spec.targetType",description="The AWS TargetGroup's TargetType"
135+
// +kubebuilder:printcolumn:name="ARN",type="string",JSONPath=".spec.targetGroupARN",description="The AWS TargetGroup's Amazon Resource Name"
132136

133137
// TargetGroupBinding is the Schema for the TargetGroupBinding API
134138
type TargetGroupBinding struct {
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
apiVersion: apps/v1
2+
kind: Deployment
3+
metadata:
4+
name: controller
5+
spec:
6+
template:
7+
spec:
8+
securityContext:
9+
fsGroup: 1337

config/controller/kustomization.yaml

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
resources:
2-
- controller.yaml
2+
- controller.yaml
3+
patchesStrategicMerge:
4+
- iam_for_sa_patch.yaml
5+
36
apiVersion: kustomize.config.k8s.io/v1beta1
47
kind: Kustomization
58
images:
69
- name: controller
710
newName: amazon/aws-alb-ingress-controller
8-
newTag: v2.0.0-rc1
11+
newTag: v2.0.0-rc1

config/crd/bases/elbv2.k8s.aws_targetgroupbindings.yaml

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,30 @@ apiVersion: apiextensions.k8s.io/v1beta1
44
kind: CustomResourceDefinition
55
metadata:
66
annotations:
7-
controller-gen.kubebuilder.io/version: v0.2.5
7+
controller-gen.kubebuilder.io/version: v0.4.0
88
creationTimestamp: null
99
name: targetgroupbindings.elbv2.k8s.aws
1010
spec:
11+
additionalPrinterColumns:
12+
- JSONPath: .spec.targetType
13+
description: The AWS TargetGroup's TargetType
14+
name: TARGET-TYPE
15+
type: string
16+
- JSONPath: .spec.targetGroupARN
17+
description: The AWS TargetGroup's Amazon Resource Name
18+
name: ARN
19+
type: string
1120
group: elbv2.k8s.aws
1221
names:
22+
categories:
23+
- all
1324
kind: TargetGroupBinding
1425
listKind: TargetGroupBindingList
1526
plural: targetgroupbindings
1627
singular: targetgroupbinding
1728
scope: Namespaced
29+
subresources:
30+
status: {}
1831
validation:
1932
openAPIV3Schema:
2033
description: TargetGroupBinding is the Schema for the TargetGroupBinding API

config/default/webhookcainjection_patch.yaml

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@ metadata:
77
annotations:
88
cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME)
99
---
10-
#apiVersion: admissionregistration.k8s.io/v1beta1
11-
#kind: ValidatingWebhookConfiguration
12-
#metadata:
13-
# name: webhook
14-
# annotations:
15-
# cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME)
10+
apiVersion: admissionregistration.k8s.io/v1beta1
11+
kind: ValidatingWebhookConfiguration
12+
metadata:
13+
name: webhook
14+
annotations:
15+
cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME)

config/webhook/kustomization.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
resources:
2-
- manifests.yaml
2+
- manifests.v1beta1.yaml
33
- service.yaml
44

55
configurations:

config/webhook/manifests.v1beta1.yaml

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
apiVersion: admissionregistration.k8s.io/v1beta1
2+
kind: MutatingWebhookConfiguration
3+
metadata:
4+
creationTimestamp: null
5+
name: webhook
6+
webhooks:
7+
- clientConfig:
8+
caBundle: Cg==
9+
service:
10+
name: webhook-service
11+
namespace: system
12+
path: /mutate-v1-pod
13+
failurePolicy: Fail
14+
name: mpod.elbv2.k8s.aws
15+
rules:
16+
- apiGroups:
17+
- ""
18+
apiVersions:
19+
- v1
20+
operations:
21+
- CREATE
22+
resources:
23+
- pods
24+
sideEffects: None
25+
- clientConfig:
26+
caBundle: Cg==
27+
service:
28+
name: webhook-service
29+
namespace: system
30+
path: /mutate-elbv2-k8s-aws-v1alpha1-targetgroupbinding
31+
failurePolicy: Fail
32+
name: mtargetgroupbinding.elbv2.k8s.aws
33+
rules:
34+
- apiGroups:
35+
- elbv2.k8s.aws
36+
apiVersions:
37+
- v1alpha1
38+
operations:
39+
- CREATE
40+
- UPDATE
41+
resources:
42+
- targetgroupbindings
43+
sideEffects: None
44+
---
45+
apiVersion: admissionregistration.k8s.io/v1beta1
46+
kind: ValidatingWebhookConfiguration
47+
metadata:
48+
creationTimestamp: null
49+
name: webhook
50+
webhooks:
51+
- clientConfig:
52+
caBundle: Cg==
53+
service:
54+
name: webhook-service
55+
namespace: system
56+
path: /validate-elbv2-k8s-aws-v1alpha1-targetgroupbinding
57+
failurePolicy: Fail
58+
name: vtargetgroupbinding.elbv2.k8s.aws
59+
rules:
60+
- apiGroups:
61+
- elbv2.k8s.aws
62+
apiVersions:
63+
- v1alpha1
64+
operations:
65+
- CREATE
66+
- UPDATE
67+
resources:
68+
- targetgroupbindings
69+
sideEffects: None

config/webhook/manifests.yaml

Lines changed: 0 additions & 25 deletions
This file was deleted.

main.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ import (
3535
"sigs.k8s.io/aws-load-balancer-controller/pkg/networking"
3636
"sigs.k8s.io/aws-load-balancer-controller/pkg/targetgroupbinding"
3737
corewebhook "sigs.k8s.io/aws-load-balancer-controller/webhooks/core"
38+
elbv2webhook "sigs.k8s.io/aws-load-balancer-controller/webhooks/elbv2"
3839
ctrl "sigs.k8s.io/controller-runtime"
3940
"sigs.k8s.io/controller-runtime/pkg/log/zap"
4041
"sigs.k8s.io/controller-runtime/pkg/metrics"
@@ -140,6 +141,8 @@ func main() {
140141

141142
podReadinessGateInjector := inject.NewPodReadinessGate(injectConfig, mgr.GetClient(), ctrl.Log.WithName("pod-readiness-gate-injector"))
142143
corewebhook.NewPodMutator(podReadinessGateInjector).SetupWithManager(mgr)
144+
elbv2webhook.NewTargetGroupBindingMutator(cloud.ELBV2(), ctrl.Log).SetupWithManager(mgr)
145+
elbv2webhook.NewTargetGroupBindingValidator(ctrl.Log).SetupWithManager(mgr)
143146
// +kubebuilder:scaffold:builder
144147

145148
setupLog.Info("starting manager")

webhooks/core/pod_mutator.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ func (m *podMutator) MutateUpdate(ctx context.Context, obj runtime.Object, oldOb
4343
return obj, nil
4444
}
4545

46-
// +kubebuilder:webhook:path=/mutate-v1-pod,mutating=true,failurePolicy=fail,groups="",resources=pods,verbs=create,versions=v1,name=mpod.elbv2.k8s.aws
46+
// +kubebuilder:webhook:path=/mutate-v1-pod,mutating=true,failurePolicy=fail,groups="",resources=pods,verbs=create,versions=v1,name=mpod.elbv2.k8s.aws,sideEffects=None,webhookVersions=v1beta1
4747

4848
func (m *podMutator) SetupWithManager(mgr ctrl.Manager) {
4949
mgr.GetWebhookServer().Register(apiPathMutatePod, webhook.MutatingWebhookForMutator(m))
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
package elbv2
2+
3+
import (
4+
"context"
5+
awssdk "github.com/aws/aws-sdk-go/aws"
6+
elbv2sdk "github.com/aws/aws-sdk-go/service/elbv2"
7+
"github.com/go-logr/logr"
8+
"github.com/pkg/errors"
9+
"k8s.io/apimachinery/pkg/runtime"
10+
elbv2api "sigs.k8s.io/aws-load-balancer-controller/apis/elbv2/v1alpha1"
11+
"sigs.k8s.io/aws-load-balancer-controller/pkg/aws/services"
12+
"sigs.k8s.io/aws-load-balancer-controller/pkg/webhook"
13+
ctrl "sigs.k8s.io/controller-runtime"
14+
"sigs.k8s.io/controller-runtime/pkg/webhook/admission"
15+
)
16+
17+
const apiPathMutateELBv2TargetGroupBinding = "/mutate-elbv2-k8s-aws-v1alpha1-targetgroupbinding"
18+
19+
// NewTargetGroupBindingMutator returns a mutator for TargetGroupBinding CRD.
20+
func NewTargetGroupBindingMutator(elbv2Client services.ELBV2, logger logr.Logger) *targetGroupBindingMutator {
21+
return &targetGroupBindingMutator{
22+
elbv2Client: elbv2Client,
23+
logger: logger,
24+
}
25+
}
26+
27+
var _ webhook.Mutator = &targetGroupBindingMutator{}
28+
29+
type targetGroupBindingMutator struct {
30+
elbv2Client services.ELBV2
31+
logger logr.Logger
32+
}
33+
34+
func (m *targetGroupBindingMutator) Prototype(_ admission.Request) (runtime.Object, error) {
35+
return &elbv2api.TargetGroupBinding{}, nil
36+
}
37+
38+
func (m *targetGroupBindingMutator) MutateCreate(ctx context.Context, obj runtime.Object) (runtime.Object, error) {
39+
tgb := obj.(*elbv2api.TargetGroupBinding)
40+
if err := m.defaultingTargetType(ctx, tgb); err != nil {
41+
return nil, err
42+
}
43+
return tgb, nil
44+
}
45+
46+
func (m *targetGroupBindingMutator) MutateUpdate(ctx context.Context, obj runtime.Object, oldObj runtime.Object) (runtime.Object, error) {
47+
return obj, nil
48+
}
49+
50+
func (m *targetGroupBindingMutator) defaultingTargetType(ctx context.Context, tgb *elbv2api.TargetGroupBinding) error {
51+
if tgb.Spec.TargetType != nil {
52+
return nil
53+
}
54+
tgARN := tgb.Spec.TargetGroupARN
55+
sdkTargetType, err := m.obtainSDKTargetTypeFromAWS(ctx, tgARN)
56+
if err != nil {
57+
return errors.Wrap(err, "couldn't determine TargetType")
58+
}
59+
var targetType elbv2api.TargetType
60+
switch sdkTargetType {
61+
case elbv2sdk.TargetTypeEnumInstance:
62+
targetType = elbv2api.TargetTypeInstance
63+
case elbv2sdk.TargetTypeEnumIp:
64+
targetType = elbv2api.TargetTypeIP
65+
default:
66+
return errors.Errorf("unsupported TargetType: %v", sdkTargetType)
67+
}
68+
69+
tgb.Spec.TargetType = &targetType
70+
return nil
71+
}
72+
73+
func (m *targetGroupBindingMutator) obtainSDKTargetTypeFromAWS(ctx context.Context, tgARN string) (string, error) {
74+
req := &elbv2sdk.DescribeTargetGroupsInput{
75+
TargetGroupArns: awssdk.StringSlice([]string{tgARN}),
76+
}
77+
tgList, err := m.elbv2Client.DescribeTargetGroupsAsList(ctx, req)
78+
if err != nil {
79+
return "", err
80+
}
81+
if len(tgList) != 1 {
82+
return "", errors.Errorf("expecting a single targetGroup but got %v", len(tgList))
83+
}
84+
return awssdk.StringValue(tgList[0].TargetType), nil
85+
}
86+
87+
// +kubebuilder:webhook:path=/mutate-elbv2-k8s-aws-v1alpha1-targetgroupbinding,mutating=true,failurePolicy=fail,groups=elbv2.k8s.aws,resources=targetgroupbindings,verbs=create;update,versions=v1alpha1,name=mtargetgroupbinding.elbv2.k8s.aws,sideEffects=None,webhookVersions=v1beta1
88+
89+
func (m *targetGroupBindingMutator) SetupWithManager(mgr ctrl.Manager) {
90+
mgr.GetWebhookServer().Register(apiPathMutateELBv2TargetGroupBinding, webhook.MutatingWebhookForMutator(m))
91+
}

0 commit comments

Comments
 (0)