-
Notifications
You must be signed in to change notification settings - Fork 640
Expand file tree
/
Copy pathwebhookhandler.go
More file actions
97 lines (83 loc) · 3.42 KB
/
Copy pathwebhookhandler.go
File metadata and controls
97 lines (83 loc) · 3.42 KB
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
// Copyright The OpenTelemetry Authors
// SPDX-License-Identifier: Apache-2.0
// Package podmutation contains the webhook that injects sidecars into pods.
package podmutation
import (
"context"
"encoding/json"
"net/http"
"github.com/go-logr/logr"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/types"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/webhook/admission"
"github.com/open-telemetry/opentelemetry-operator/internal/config"
)
// +kubebuilder:webhook:path=/mutate-v1-pod,mutating=true,failurePolicy=ignore,groups="",resources=pods,verbs=create,versions=v1,name=mpod.kb.io,sideEffects=none,admissionReviewVersions=v1
// +kubebuilder:rbac:groups="",resources=namespaces;secrets,verbs=get;list;watch
// +kubebuilder:rbac:groups=opentelemetry.io,resources=opentelemetrycollectors,verbs=get;list;watch
// +kubebuilder:rbac:groups=opentelemetry.io,resources=instrumentations,verbs=get;list;watch
// +kubebuilder:rbac:groups="apps",resources=replicasets,verbs=get;list;watch
// +kubebuilder:rbac:groups="batch",resources=jobs,verbs=get;list;watch
var _ WebhookHandler = (*podMutationWebhook)(nil)
// WebhookHandler is a webhook handler that analyzes new pods and injects appropriate sidecars into it.
type WebhookHandler interface {
admission.Handler
}
// the implementation.
type podMutationWebhook struct {
client client.Client
decoder admission.Decoder
logger logr.Logger
podMutators []PodMutator
config config.Config
}
// PodMutator mutates a pod.
type PodMutator interface {
Mutate(ctx context.Context, ns corev1.Namespace, pod corev1.Pod) (corev1.Pod, error)
}
// NewWebhookHandler creates a new WebhookHandler.
func NewWebhookHandler(cfg config.Config, logger logr.Logger, decoder admission.Decoder, cl client.Client, podMutators []PodMutator) WebhookHandler {
return &podMutationWebhook{
config: cfg,
decoder: decoder,
logger: logger,
client: cl,
podMutators: podMutators,
}
}
func (p *podMutationWebhook) Handle(ctx context.Context, req admission.Request) admission.Response {
pod := corev1.Pod{}
err := p.decoder.Decode(req, &pod)
if err != nil {
return admission.Errored(http.StatusBadRequest, err)
}
// we use the req.Namespace here because the pod might have not been created yet
ns := corev1.Namespace{}
err = p.client.Get(ctx, types.NamespacedName{Name: req.Namespace, Namespace: ""}, &ns)
if err != nil {
res := admission.Errored(http.StatusInternalServerError, err)
// By default, admission.Errored sets Allowed to false which blocks pod creation even though the failurePolicy=ignore.
// Allowed set to true makes sure failure does not block pod creation in case of an error.
// Using the http.StatusInternalServerError creates a k8s event associated with the replica set.
// The admission.Allowed("").WithWarnings(err.Error()) or http.StatusBadRequest does not
// create any event. Additionally, an event/log cannot be created explicitly because the pod name is not known.
res.Allowed = true
return res
}
for _, m := range p.podMutators {
pod, err = m.Mutate(ctx, ns, pod)
if err != nil {
res := admission.Errored(http.StatusInternalServerError, err)
res.Allowed = true
return res
}
}
marshaledPod, err := json.Marshal(pod)
if err != nil {
res := admission.Errored(http.StatusInternalServerError, err)
res.Allowed = true
return res
}
return admission.PatchResponseFromRaw(req.Object.Raw, marshaledPod)
}