@@ -17,56 +17,63 @@ package webhook
17
17
18
18
import (
19
19
"context"
20
- "encoding/json"
21
20
"fmt"
22
- "net/http"
21
+ "k8s.io/apimachinery/pkg/runtime"
22
+ ctrl "sigs.k8s.io/controller-runtime"
23
+ logf "sigs.k8s.io/controller-runtime/pkg/log"
24
+ "sigs.k8s.io/controller-runtime/pkg/webhook"
23
25
"sort"
24
26
"strings"
25
27
26
28
"github.com/att-cloudnative-labs/kconfig-controller/api/v1beta1"
27
- "github.com/go-logr/logr"
28
29
v1 "k8s.io/api/core/v1"
29
30
v12 "k8s.io/apimachinery/pkg/apis/meta/v1"
30
31
"k8s.io/apimachinery/pkg/labels"
31
32
"sigs.k8s.io/controller-runtime/pkg/client"
32
- "sigs.k8s.io/controller-runtime/pkg/webhook/admission"
33
33
)
34
34
35
- const (
36
- InjectConfigAnnotation = "kconfigcontroller.atteg.com/inject"
37
- ExclusiveEnvConfigAnnotation = "kconfigcontroller.atteg.com/exclusive-env"
38
- )
35
+ var podConfigInjectorLog = logf .Log .WithName ("pod-config-injector" )
36
+
37
+ func SetupPodConfigInjectorWithManager (mgr ctrl.Manager , sel * v12.LabelSelector ) error {
38
+ return ctrl .NewWebhookManagedBy (mgr ).For (& v1.Pod {}).
39
+ WithDefaulter (
40
+ & PodConfigInjector {
41
+ Client : mgr .GetClient (),
42
+ DefaultContainerSelector : sel ,
43
+ },
44
+ ).
45
+ Complete ()
46
+ }
39
47
40
- // +kubebuilder:webhook:path=/mutate-v1-pod,admissionReviewVersions=[v1],sideEffects=None, mutating=true,failurePolicy=ignore,groups="",resources=pods,verbs=create,versions=v1,name=config-injector.kconfigcontroller.aeg.cloud
48
+ // +kubebuilder:webhook:path=/mutate-v1-pod,mutating=true,failurePolicy=ignore,sideEffects=None, groups="",resources=pods,verbs=create,versions=v1,name=config-injector.kconfigcontroller.aeg.cloud,admissionReviewVersions=v1
41
49
42
50
type PodConfigInjector struct {
43
51
Client client.Client
44
- decoder admission.Decoder
45
- Log logr.Logger
46
52
DefaultContainerSelector * v12.LabelSelector
47
53
}
48
54
49
- func ( r * PodConfigInjector ) InjectDecoder ( d * admission. Decoder ) error {
50
- r . decoder = * d
51
- return nil
52
- }
55
+ const (
56
+ InjectConfigAnnotation = "kconfigcontroller.atteg.com/inject"
57
+ ExclusiveEnvConfigAnnotation = "kconfigcontroller.atteg.com/exclusive-env"
58
+ )
53
59
54
- func (r * PodConfigInjector ) Handle (ctx context.Context , req admission.Request ) admission.Response {
55
- pod := & v1.Pod {}
60
+ var _ webhook.CustomDefaulter = & PodConfigInjector {}
56
61
57
- err := r .decoder .Decode (req , pod )
58
- if err != nil {
59
- return admission .Errored (http .StatusBadRequest , err )
62
+ func (r * PodConfigInjector ) Default (ctx context.Context , obj runtime.Object ) error {
63
+ pod , ok := obj .(* v1.Pod )
64
+ if ! ok {
65
+ return fmt .Errorf ("expected an Pod object but got %T" , obj )
60
66
}
61
67
62
68
// only inject into pods with proper annotation
63
69
if pod .Annotations == nil || strings .ToLower (pod .Annotations [InjectConfigAnnotation ]) != "true" {
64
- return admission .Allowed ("kconfig inject not indicated" )
70
+ podConfigInjectorLog .Info (fmt .Sprintf ("skipping %s - not annotated" , pod .Name ))
71
+ return nil
65
72
}
66
73
// get bindings that select this rs
67
74
kcbs := v1beta1.KconfigBindingList {}
68
- if err := r .Client .List (ctx , & kcbs , client .InNamespace (req .Namespace )); err != nil {
69
- return admission . Errored ( http . StatusInternalServerError , fmt .Errorf ("could not get kconfigbininglist: %s" , err .Error () ))
75
+ if err := r .Client .List (ctx , & kcbs , client .InNamespace (pod .Namespace )); err != nil {
76
+ return fmt .Errorf ("could not get kconfigbininglist: %s" , err .Error ())
70
77
}
71
78
72
79
// cleanup old pod env configs
@@ -78,7 +85,7 @@ func (r *PodConfigInjector) Handle(ctx context.Context, req admission.Request) a
78
85
for _ , kcb := range kcbs .Items {
79
86
ls , err := v12 .LabelSelectorAsSelector (& kcb .Spec .Selector )
80
87
if err != nil {
81
- r . Log .Error (err , fmt .Sprintf ("couldn't get selector of kcb: %s" , err .Error ()))
88
+ podConfigInjectorLog .Error (err , fmt .Sprintf ("couldn't get selector of kcb: %s" , err .Error ()))
82
89
continue
83
90
}
84
91
@@ -98,7 +105,7 @@ func (r *PodConfigInjector) Handle(ctx context.Context, req admission.Request) a
98
105
}
99
106
selector , err := v12 .LabelSelectorAsSelector (labelSelector )
100
107
if err != nil {
101
- r . Log .Error (err , fmt .Sprintf ("error reading kcb containerSelector: %s" , err .Error ()))
108
+ podConfigInjectorLog .Error (err , fmt .Sprintf ("error reading kcb containerSelector: %s" , err .Error ()))
102
109
continue
103
110
}
104
111
if selector .Matches (labelsForContainer ) {
@@ -109,11 +116,7 @@ func (r *PodConfigInjector) Handle(ctx context.Context, req admission.Request) a
109
116
}
110
117
}
111
118
}
112
- marshaledPod , err := json .Marshal (pod )
113
- if err != nil {
114
- return admission .Errored (http .StatusInternalServerError , fmt .Errorf ("could not marshal pod json: %s" , err .Error ()))
115
- }
116
- return admission .PatchResponseFromRaw (req .Object .Raw , marshaledPod )
119
+ return nil
117
120
}
118
121
119
122
// ByLevel sort function for sorting array of KconfigBindingSpecs by their level
0 commit comments