Skip to content

Commit 58a08d8

Browse files
authored
Merge pull request #323 from DirectXMan12/tmp/webhook-decouple
⚠️ webhook redesign for generic case
2 parents bd46773 + 286b0b4 commit 58a08d8

Some content is hidden

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

64 files changed

+1217
-1711
lines changed

Gopkg.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

alias.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,11 @@ import (
2222
"sigs.k8s.io/controller-runtime/pkg/builder"
2323
"sigs.k8s.io/controller-runtime/pkg/client/config"
2424
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
25+
"sigs.k8s.io/controller-runtime/pkg/log"
2526
"sigs.k8s.io/controller-runtime/pkg/manager"
27+
"sigs.k8s.io/controller-runtime/pkg/manager/signals"
2628
"sigs.k8s.io/controller-runtime/pkg/reconcile"
27-
"sigs.k8s.io/controller-runtime/pkg/log"
2829
"sigs.k8s.io/controller-runtime/pkg/scheme"
29-
"sigs.k8s.io/controller-runtime/pkg/manager/signals"
3030
)
3131

3232
// Builder builds an Application ControllerManagedBy (e.g. Operator) and returns a manager.Manager to start it.
@@ -47,7 +47,7 @@ type Manager = manager.Manager
4747
// Options are the arguments for creating a new Manager
4848
type Options = manager.Options
4949

50-
// Builder builds a new Scheme for mapping go types to Kubernetes GroupVersionKinds.
50+
// SchemeBuilder builds a new Scheme for mapping go types to Kubernetes GroupVersionKinds.
5151
type SchemeBuilder = scheme.Builder
5252

5353
// GroupVersion contains the "group" and the "version", which uniquely identifies the API.

doc.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ limitations under the License.
110110
// controller-runtime.
111111
//
112112
// Metrics (pkg/metrics) provided by controller-runtime are registered into a
113-
// controller-runtime-specific Prometheus metrics registery. The manager can
113+
// controller-runtime-specific Prometheus metrics registry. The manager can
114114
// serve these by an HTTP endpoint, and additional metrics may be registered to
115115
// this Registry as normal.
116116
//

example/main.go

Lines changed: 6 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@ import (
3232
"sigs.k8s.io/controller-runtime/pkg/manager/signals"
3333
"sigs.k8s.io/controller-runtime/pkg/source"
3434
"sigs.k8s.io/controller-runtime/pkg/webhook"
35-
"sigs.k8s.io/controller-runtime/pkg/webhook/admission/builder"
3635
)
3736

3837
var log = logf.Log.WithName("example-controller")
@@ -78,35 +77,19 @@ func main() {
7877
}
7978

8079
// Setup webhooks
81-
entryLog.Info("setting up webhooks")
82-
mutatingWebhook := builder.NewWebhookBuilder().
83-
Path("/mutate-pods").
84-
Mutating().
85-
Handlers(&podAnnotator{}).
86-
Build()
87-
88-
validatingWebhook := builder.NewWebhookBuilder().
89-
Path("/validate-pods").
90-
Validating().
91-
Handlers(&podValidator{}).
92-
Build()
93-
9480
entryLog.Info("setting up webhook server")
95-
as, err := webhook.NewServer(mgr, webhook.ServerOptions{
81+
hookServer := &webhook.Server{
9682
Port: 9876,
9783
CertDir: "/tmp/cert",
98-
})
99-
if err != nil {
100-
entryLog.Error(err, "unable to create a new webhook server")
84+
}
85+
if err := mgr.Add(hookServer); err != nil {
86+
entryLog.Error(err, "unable register webhook server with manager")
10187
os.Exit(1)
10288
}
10389

10490
entryLog.Info("registering webhooks to the webhook server")
105-
err = as.Register(mutatingWebhook, validatingWebhook)
106-
if err != nil {
107-
entryLog.Error(err, "unable to setup the admission server")
108-
os.Exit(1)
109-
}
91+
hookServer.Register("/mutate-pods", &webhook.Admission{Handler: &podAnnotator{}})
92+
hookServer.Register("/validate-pods", &webhook.Admission{Handler: &podValidator{}})
11093

11194
entryLog.Info("starting manager")
11295
if err := mgr.Start(signals.SetupSignalHandler()); err != nil {

example/mutatingwebhook.go

Lines changed: 11 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -23,67 +23,51 @@ import (
2323

2424
corev1 "k8s.io/api/core/v1"
2525
"sigs.k8s.io/controller-runtime/pkg/client"
26-
"sigs.k8s.io/controller-runtime/pkg/runtime/inject"
2726
"sigs.k8s.io/controller-runtime/pkg/webhook/admission"
28-
"sigs.k8s.io/controller-runtime/pkg/webhook/admission/types"
2927
)
3028

3129
// podAnnotator annotates Pods
3230
type podAnnotator struct {
3331
client client.Client
34-
decoder types.Decoder
32+
decoder *admission.Decoder
3533
}
3634

37-
// Implement admission.Handler so the controller can handle admission request.
38-
var _ admission.Handler = &podAnnotator{}
39-
4035
// podAnnotator adds an annotation to every incoming pods.
41-
func (a *podAnnotator) Handle(ctx context.Context, req types.Request) types.Response {
36+
func (a *podAnnotator) Handle(ctx context.Context, req admission.Request) admission.Response {
4237
pod := &corev1.Pod{}
4338

4439
err := a.decoder.Decode(req, pod)
4540
if err != nil {
46-
return admission.ErrorResponse(http.StatusBadRequest, err)
41+
return admission.Errored(http.StatusBadRequest, err)
4742
}
4843

49-
err = a.mutatePodsFn(ctx, pod)
50-
if err != nil {
51-
return admission.ErrorResponse(http.StatusInternalServerError, err)
44+
if pod.Annotations == nil {
45+
pod.Annotations = map[string]string{}
5246
}
47+
pod.Annotations["example-mutating-admission-webhook"] = "foo"
5348

5449
marshaledPod, err := json.Marshal(pod)
5550
if err != nil {
56-
return admission.ErrorResponse(http.StatusInternalServerError, err)
51+
return admission.Errored(http.StatusInternalServerError, err)
5752
}
5853

5954
return admission.PatchResponseFromRaw(req.AdmissionRequest.Object.Raw, marshaledPod)
6055
}
6156

62-
// mutatePodsFn add an annotation to the given pod
63-
func (a *podAnnotator) mutatePodsFn(ctx context.Context, pod *corev1.Pod) error {
64-
if pod.Annotations == nil {
65-
pod.Annotations = map[string]string{}
66-
}
67-
pod.Annotations["example-mutating-admission-webhook"] = "foo"
68-
return nil
69-
}
70-
7157
// podAnnotator implements inject.Client.
7258
// A client will be automatically injected.
73-
var _ inject.Client = &podAnnotator{}
7459

7560
// InjectClient injects the client.
76-
func (v *podAnnotator) InjectClient(c client.Client) error {
77-
v.client = c
61+
func (a *podAnnotator) InjectClient(c client.Client) error {
62+
a.client = c
7863
return nil
7964
}
8065

8166
// podAnnotator implements inject.Decoder.
8267
// A decoder will be automatically injected.
83-
var _ inject.Decoder = &podAnnotator{}
8468

8569
// InjectDecoder injects the decoder.
86-
func (v *podAnnotator) InjectDecoder(d types.Decoder) error {
87-
v.decoder = d
70+
func (a *podAnnotator) InjectDecoder(d *admission.Decoder) error {
71+
a.decoder = d
8872
return nil
8973
}

example/validatingwebhook.go

Lines changed: 11 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -23,54 +23,38 @@ import (
2323

2424
corev1 "k8s.io/api/core/v1"
2525
"sigs.k8s.io/controller-runtime/pkg/client"
26-
"sigs.k8s.io/controller-runtime/pkg/runtime/inject"
2726
"sigs.k8s.io/controller-runtime/pkg/webhook/admission"
28-
"sigs.k8s.io/controller-runtime/pkg/webhook/admission/types"
2927
)
3028

3129
// podValidator validates Pods
3230
type podValidator struct {
3331
client client.Client
34-
decoder types.Decoder
32+
decoder *admission.Decoder
3533
}
3634

37-
// Implement admission.Handler so the controller can handle admission request.
38-
var _ admission.Handler = &podValidator{}
39-
4035
// podValidator admits a pod iff a specific annotation exists.
41-
func (v *podValidator) Handle(ctx context.Context, req types.Request) types.Response {
36+
func (v *podValidator) Handle(ctx context.Context, req admission.Request) admission.Response {
4237
pod := &corev1.Pod{}
4338

4439
err := v.decoder.Decode(req, pod)
4540
if err != nil {
46-
return admission.ErrorResponse(http.StatusBadRequest, err)
41+
return admission.Errored(http.StatusBadRequest, err)
4742
}
4843

49-
allowed, reason, err := v.validatePodsFn(ctx, pod)
50-
if err != nil {
51-
return admission.ErrorResponse(http.StatusInternalServerError, err)
52-
}
53-
return admission.ValidationResponse(allowed, reason)
54-
}
55-
56-
func (v *podValidator) validatePodsFn(ctx context.Context, pod *corev1.Pod) (bool, string, error) {
5744
key := "example-mutating-admission-webhook"
5845
anno, found := pod.Annotations[key]
59-
switch {
60-
case !found:
61-
return found, fmt.Sprintf("failed to find annotation with key: %q", key), nil
62-
case found && anno == "foo":
63-
return found, "", nil
64-
case found && anno != "foo":
65-
return false,
66-
fmt.Sprintf("the value associate with key %q is expected to be %q, but got %q", key, "foo", anno), nil
46+
if !found {
47+
return admission.Denied(fmt.Sprintf("missing annotation %s", key))
48+
}
49+
if anno != "foo" {
50+
return admission.Denied(fmt.Sprintf("annotation %s did not have value %q", key, "foo"))
6751
}
68-
return false, "", nil
52+
53+
return admission.Allowed("")
6954
}
7055

7156
// podValidator implements inject.Client.
7257
// A client will be automatically injected.
73-
var _ inject.Client = &podValidator{}
7458

7559
// InjectClient injects the client.
7660
func (v *podValidator) InjectClient(c client.Client) error {
@@ -80,10 +64,9 @@ func (v *podValidator) InjectClient(c client.Client) error {
8064

8165
// podValidator implements inject.Decoder.
8266
// A decoder will be automatically injected.
83-
var _ inject.Decoder = &podValidator{}
8467

8568
// InjectDecoder injects the decoder.
86-
func (v *podValidator) InjectDecoder(d types.Decoder) error {
69+
func (v *podValidator) InjectDecoder(d *admission.Decoder) error {
8770
v.decoder = d
8871
return nil
8972
}

example_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ func (a *ReplicaSetReconciler) Reconcile(req controllers.Request) (controllers.R
8181

8282
// List the Pods matching the PodTemplate Labels
8383
pods := &corev1.PodList{}
84-
err = a.List(context.TODO(), client.InNamespace(req.Namespace).MatchingLabels(rs.Spec.Template.Labels), pods)
84+
err = a.List(context.TODO(), pods, client.InNamespace(req.Namespace), client.MatchingLabels(rs.Spec.Template.Labels))
8585
if err != nil {
8686
return controllers.Result{}, err
8787
}

hack/test-all.sh

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,16 +22,16 @@ setup_envs
2222

2323
header_text "running go test"
2424

25-
go test ./pkg/... -parallel 4
25+
go test ./... -parallel 4
2626

2727
header_text "running coverage"
2828

2929
# Verify no coverage regressions have been introduced. Remove the exception list from here
3030
# once the coverage has been brought back up
31-
if [[ ! $(go test ./pkg/... -coverprofile cover.out -parallel 4 | grep -v "coverage: 100.0% of statements" | grep "controller-runtime/pkg " | grep -v "controller-runtime/pkg \|controller-runtime/pkg/recorder \|pkg/admission/certprovisioner \|pkg/internal/admission \|pkg/cache\|pkg/client \|pkg/event \|pkg/client/config \|pkg/controller/controllertest \|pkg/reconcile/reconciletest \|pkg/test ") ]]; then
31+
if [[ ! $(go test ./pkg/... -coverprofile cover.out -parallel 4 | grep -v "coverage: 100.0% of statements" | grep "controller-runtime/pkg " | grep -v "controller-runtime/pkg \|controller-runtime/pkg/recorder \|pkg/cache\|pkg/client \|pkg/event \|pkg/client/config \|pkg/controller/controllertest \|pkg/reconcile/reconciletest \|pkg/test ") ]]; then
3232
echo "ok"
3333
else
34-
go test ./pkg/... -coverprofile cover.out -parallel 4 | grep -v "coverage: 100.0% of statements" | grep "controller-runtime/pkg " | grep -v "controller-runtime/pkg \|controller-runtime/pkg/recorder \|pkg/admission/certprovisioner \|pkg/internal/admission \|pkg/cache\|pkg/client \|pkg/event \|pkg/client/config \|pkg/controller/controllertest \|pkg/reconcile/reconciletest \|pkg/test "
34+
go test ./pkg/... -coverprofile cover.out -parallel 4 | grep -v "coverage: 100.0% of statements" | grep "controller-runtime/pkg " | grep -v "controller-runtime/pkg \|controller-runtime/pkg/recorder \|pkg/cache\|pkg/client \|pkg/event \|pkg/client/config \|pkg/controller/controllertest \|pkg/reconcile/reconciletest \|pkg/test "
3535
echo "missing test coverage"
3636
exit 1
3737
fi

hack/verify.sh

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ source $(dirname ${BASH_SOURCE})/common.sh
2020

2121
header_text "running go vet"
2222

23-
go vet ./pkg/...
23+
go vet ./...
2424

2525
# go get is broken for golint. re-enable this once it is fixed.
2626
#header_text "running golint"
@@ -49,9 +49,9 @@ gometalinter.v2 --disable-all \
4949
--dupl-threshold=400 \
5050
--enable=dupl \
5151
--skip=atomic \
52-
./pkg/...
52+
--enable=goimports \
53+
./pkg/... ./example/... .
5354
# TODO: Enable these as we fix them to make them pass
54-
# --enable=goimports \
5555
# --enable=gosec \
5656
# --enable=maligned \
5757
# --enable=safesql \

pkg/builder/builder_suite_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,9 @@ import (
2323
. "github.com/onsi/gomega"
2424
"k8s.io/client-go/rest"
2525
"sigs.k8s.io/controller-runtime/pkg/envtest"
26-
"sigs.k8s.io/controller-runtime/pkg/metrics"
2726
logf "sigs.k8s.io/controller-runtime/pkg/log"
2827
"sigs.k8s.io/controller-runtime/pkg/log/zap"
28+
"sigs.k8s.io/controller-runtime/pkg/metrics"
2929
)
3030

3131
func TestSource(t *testing.T) {

0 commit comments

Comments
 (0)