Skip to content

Commit dca0fe4

Browse files
lnguyen1401Linh Nguyenlranjbarcblecker
authored
Add Mutating Webhook PodImageSpec (#305)
* updated webhook * update webhook to use jsonpatch * a few minor updates * optimize podimagespec webhook logic * remove unused code paths * add regex unit tests * add unit tests for pod contains regex match * provide rbac permissions * fix a couple bugs * Added UID to response return and a few minor updated * go fmt --------- Co-authored-by: Linh Nguyen <[email protected]> Co-authored-by: Lisa Rashidi-Ranjbar <[email protected]> Co-authored-by: Christoph Blecker <[email protected]>
1 parent 8bda2d2 commit dca0fe4

File tree

8 files changed

+721
-1
lines changed

8 files changed

+721
-1
lines changed

build/resources.go

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,55 @@ func createRoleBinding() *rbacv1.RoleBinding {
162162
}
163163
}
164164

165+
func createClusterRole() *rbacv1.ClusterRole {
166+
return &rbacv1.ClusterRole{
167+
TypeMeta: metav1.TypeMeta{
168+
Kind: "ClusterRole",
169+
APIVersion: rbacv1.SchemeGroupVersion.String(),
170+
},
171+
ObjectMeta: metav1.ObjectMeta{
172+
Name: roleName,
173+
},
174+
Rules: []rbacv1.PolicyRule{
175+
{
176+
APIGroups: []string{
177+
"imageregistry.operator.openshift.io",
178+
},
179+
Resources: []string{
180+
"configs",
181+
},
182+
Verbs: []string{
183+
"get",
184+
},
185+
},
186+
},
187+
}
188+
}
189+
190+
func createClusterRoleBinding() *rbacv1.ClusterRoleBinding {
191+
return &rbacv1.ClusterRoleBinding{
192+
TypeMeta: metav1.TypeMeta{
193+
Kind: "ClusterRoleBinding",
194+
APIVersion: rbacv1.SchemeGroupVersion.String(),
195+
},
196+
ObjectMeta: metav1.ObjectMeta{
197+
Name: fmt.Sprintf("%s:%s", roleName, serviceAccountName),
198+
},
199+
Subjects: []rbacv1.Subject{
200+
{
201+
Kind: "ServiceAccount",
202+
Name: serviceAccountName,
203+
Namespace: *namespace,
204+
},
205+
},
206+
RoleRef: rbacv1.RoleRef{
207+
Name: roleName,
208+
Kind: "ClusterRole",
209+
APIGroup: rbacv1.GroupName,
210+
},
211+
}
212+
}
213+
165214
func createPrometheusRole() *rbacv1.Role {
166215
return &rbacv1.Role{
167216
TypeMeta: metav1.TypeMeta{
@@ -779,6 +828,8 @@ func main() {
779828
templateResources.Add(utils.DefaultLabelSelector(), runtime.RawExtension{Object: createServiceAccount()})
780829
templateResources.Add(utils.DefaultLabelSelector(), runtime.RawExtension{Object: createRole()})
781830
templateResources.Add(utils.DefaultLabelSelector(), runtime.RawExtension{Object: createRoleBinding()})
831+
templateResources.Add(utils.DefaultLabelSelector(), runtime.RawExtension{Object: createClusterRole()})
832+
templateResources.Add(utils.DefaultLabelSelector(), runtime.RawExtension{Object: createClusterRoleBinding()})
782833
templateResources.Add(utils.DefaultLabelSelector(), runtime.RawExtension{Object: createPrometheusRole()})
783834
templateResources.Add(utils.DefaultLabelSelector(), runtime.RawExtension{Object: createPromethusRoleBinding()})
784835
templateResources.Add(utils.DefaultLabelSelector(), runtime.RawExtension{Object: createServiceMonitor()})

build/selectorsyncset.yaml

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,31 @@ objects:
6767
- kind: ServiceAccount
6868
name: validation-webhook
6969
namespace: openshift-validation-webhook
70+
- apiVersion: rbac.authorization.k8s.io/v1
71+
kind: ClusterRole
72+
metadata:
73+
creationTimestamp: null
74+
name: validation-webhook
75+
rules:
76+
- apiGroups:
77+
- imageregistry.operator.openshift.io
78+
resources:
79+
- configs
80+
verbs:
81+
- get
82+
- apiVersion: rbac.authorization.k8s.io/v1
83+
kind: ClusterRoleBinding
84+
metadata:
85+
creationTimestamp: null
86+
name: validation-webhook:validation-webhook
87+
roleRef:
88+
apiGroup: rbac.authorization.k8s.io
89+
kind: ClusterRole
90+
name: validation-webhook
91+
subjects:
92+
- kind: ServiceAccount
93+
name: validation-webhook
94+
namespace: openshift-validation-webhook
7095
- apiVersion: rbac.authorization.k8s.io/v1
7196
kind: Role
7297
metadata:

config/package/resources.yaml.gotmpl

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,36 @@ webhooks:
269269
timeoutSeconds: 2
270270
---
271271
apiVersion: admissionregistration.k8s.io/v1
272+
kind: MutatingWebhookConfiguration
273+
metadata:
274+
annotations:
275+
package-operator.run/phase: webhooks
276+
service.beta.openshift.io/inject-cabundle: "false"
277+
creationTimestamp: null
278+
name: sre-podimagespec-mutation
279+
webhooks:
280+
- admissionReviewVersions:
281+
- v1
282+
clientConfig:
283+
caBundle: '{{.config.serviceca | b64enc }}'
284+
url: https://validation-webhook.{{.package.metadata.namespace}}.svc.cluster.local/podimagespec-mutation
285+
failurePolicy: Ignore
286+
matchPolicy: Equivalent
287+
name: podimagespec-mutation.managed.openshift.io
288+
rules:
289+
- apiGroups:
290+
- ""
291+
apiVersions:
292+
- v1
293+
operations:
294+
- CREATE
295+
resources:
296+
- pods
297+
scope: Namespaced
298+
sideEffects: None
299+
timeoutSeconds: 2
300+
---
301+
apiVersion: admissionregistration.k8s.io/v1
272302
kind: ValidatingWebhookConfiguration
273303
metadata:
274304
annotations:

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ require (
1616
k8s.io/api v0.26.2
1717
k8s.io/apiextensions-apiserver v0.26.1
1818
k8s.io/apimachinery v0.26.2
19+
k8s.io/client-go v0.26.2
1920
k8s.io/klog/v2 v2.110.1
2021
k8s.io/utils v0.0.0-20230726121419-3b25d923346b
2122
sigs.k8s.io/controller-runtime v0.14.6
@@ -70,7 +71,6 @@ require (
7071
gopkg.in/inf.v0 v0.9.1 // indirect
7172
gopkg.in/yaml.v2 v2.4.0 // indirect
7273
gopkg.in/yaml.v3 v3.0.1 // indirect
73-
k8s.io/client-go v0.26.2 // indirect
7474
k8s.io/kube-openapi v0.0.0-20221012153701-172d655c2280 // indirect
7575
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect
7676
sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect

pkg/k8sutil/k8sutil.go

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@ import (
55
"os"
66
"strings"
77

8+
"k8s.io/apimachinery/pkg/runtime"
9+
"k8s.io/client-go/rest"
10+
"sigs.k8s.io/controller-runtime/pkg/client"
811
logf "sigs.k8s.io/controller-runtime/pkg/log"
912
)
1013

@@ -25,6 +28,22 @@ var (
2528
ErrRunLocal = fmt.Errorf("operator run mode forced to local")
2629
)
2730

31+
// KubeClient creates a new kubeclient that interacts with the Kube api with the service account secrets
32+
func KubeClient(s *runtime.Scheme) (client.Client, error) {
33+
config, err := rest.InClusterConfig()
34+
if err != nil {
35+
return nil, err
36+
}
37+
38+
c, err := client.New(config, client.Options{
39+
Scheme: s,
40+
})
41+
if err != nil {
42+
return nil, err
43+
}
44+
return c, nil
45+
}
46+
2847
func isRunModeLocal() bool {
2948
return os.Getenv(ForceRunModeEnv) == string(LocalRunMode)
3049
}

pkg/webhooks/add_podimagespec.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package webhooks
2+
3+
import (
4+
"github.com/openshift/managed-cluster-validating-webhooks/pkg/webhooks/podimagespec"
5+
)
6+
7+
func init() {
8+
Register(podimagespec.WebhookName, func() Webhook { return podimagespec.NewWebhook() })
9+
}

0 commit comments

Comments
 (0)