Skip to content

Commit 71521c3

Browse files
committed
VWC logic now moved to operator code for both OLM and Helm.
Signed-off-by: Aryan <[email protected]>
1 parent 54c8d6f commit 71521c3

File tree

5 files changed

+203
-44
lines changed

5 files changed

+203
-44
lines changed

bundle/manifests/k8s-nim-operator.clusterserviceversion.yaml

Lines changed: 24 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1345,6 +1345,18 @@ spec:
13451345
- watch
13461346
- create
13471347
- delete
1348+
- apiGroups:
1349+
- admissionregistration.k8s.io
1350+
resources:
1351+
- validatingwebhookconfigurations
1352+
verbs:
1353+
- get
1354+
- list
1355+
- watch
1356+
- create
1357+
- update
1358+
- patch
1359+
- delete
13481360
deployments:
13491361
- name: k8s-nim-operator
13501362
spec:
@@ -1401,6 +1413,8 @@ spec:
14011413
fieldPath: metadata.namespace
14021414
- name: ENABLE_WEBHOOKS
14031415
value: "true"
1416+
- name: OPERATOR_NAME_PREFIX
1417+
value: "k8s-nim-operator"
14041418
image: 'ghcr.io/nvidia/k8s-nim-operator:main'
14051419
imagePullPolicy: Always
14061420
livenessProbe:
@@ -1414,6 +1428,10 @@ spec:
14141428
successThreshold: 1
14151429
timeoutSeconds: 1
14161430
name: manager
1431+
volumeMounts:
1432+
- name: cert
1433+
mountPath: /tmp/k8s-webhook-server/serving-certs
1434+
readOnly: true
14171435
readinessProbe:
14181436
failureThreshold: 3
14191437
httpGet:
@@ -1435,6 +1453,11 @@ spec:
14351453
allowPrivilegeEscalation: false
14361454
terminationMessagePath: /dev/termination-log
14371455
terminationMessagePolicy: File
1456+
volumes:
1457+
- name: cert
1458+
secret:
1459+
secretName: k8s-nim-operator-webhook-server-cert
1460+
defaultMode: 420
14381461
dnsPolicy: ClusterFirst
14391462
imagePullSecrets: []
14401463
restartPolicy: Always
@@ -1457,46 +1480,4 @@ spec:
14571480
- type: MultiNamespace
14581481
supported: false
14591482
- type: AllNamespaces
1460-
supported: true
1461-
webhookdefinitions:
1462-
- type: ValidatingAdmissionWebhook
1463-
admissionReviewVersions:
1464-
- v1
1465-
containerPort: 9443
1466-
targetPort: 9443
1467-
deploymentName: k8s-nim-operator
1468-
failurePolicy: Fail
1469-
generateName: vnimcache-v1alpha1.kb.io
1470-
rules:
1471-
- apiGroups:
1472-
- apps.nvidia.com
1473-
apiVersions:
1474-
- v1alpha1
1475-
operations:
1476-
- CREATE
1477-
- UPDATE
1478-
resources:
1479-
- nimcaches
1480-
sideEffects: None
1481-
webhookPath: /validate-apps-nvidia-com-v1alpha1-nimcache
1482-
- type: ValidatingAdmissionWebhook
1483-
admissionReviewVersions:
1484-
- v1
1485-
containerPort: 9443
1486-
targetPort: 9443
1487-
deploymentName: k8s-nim-operator
1488-
failurePolicy: Fail
1489-
generateName: vnimservice-v1alpha1.kb.io
1490-
rules:
1491-
- apiGroups:
1492-
- apps.nvidia.com
1493-
apiVersions:
1494-
- v1alpha1
1495-
operations:
1496-
- CREATE
1497-
- UPDATE
1498-
resources:
1499-
- nimservices
1500-
sideEffects: None
1501-
webhookPath: /validate-apps-nvidia-com-v1alpha1-nimservice
1502-
1483+
supported: true
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
apiVersion: v1
2+
kind: Service
3+
metadata:
4+
name: k8s-nim-operator-webhook-service
5+
labels:
6+
app.kubernetes.io/name: k8s-nim-operator
7+
app.kubernetes.io/instance: nim-operator
8+
control-plane: controller-manager
9+
annotations:
10+
service.beta.openshift.io/serving-cert-secret-name: k8s-nim-operator-webhook-server-cert
11+
spec:
12+
selector:
13+
app.kubernetes.io/name: k8s-nim-operator
14+
app.kubernetes.io/instance: nim-operator
15+
control-plane: controller-manager
16+
ports:
17+
- port: 443
18+
targetPort: 9443
19+
protocol: TCP

deployments/helm/k8s-nim-operator/templates/manager-rbac.yaml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -582,8 +582,10 @@ rules:
582582
- get
583583
- list
584584
- watch
585-
- patch
585+
- create
586586
- update
587+
- patch
588+
- delete
587589

588590
---
589591
apiVersion: rbac.authorization.k8s.io/v1

internal/config/config.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package config
2+
3+
import "github.com/NVIDIA/k8s-nim-operator/internal/k8sutil"
4+
5+
var (
6+
OrchestratorType k8sutil.OrchestratorType
7+
)
Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
package v1alpha1
2+
3+
import (
4+
"context"
5+
"encoding/json"
6+
7+
admissionv1 "k8s.io/api/admissionregistration/v1"
8+
"k8s.io/apimachinery/pkg/api/errors"
9+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
10+
"k8s.io/apimachinery/pkg/types"
11+
"sigs.k8s.io/controller-runtime/pkg/client"
12+
13+
"github.com/NVIDIA/k8s-nim-operator/internal/config"
14+
"github.com/NVIDIA/k8s-nim-operator/internal/k8sutil"
15+
)
16+
17+
// EnsureValidatingWebhook creates or updates the ValidatingWebhookConfiguration
18+
// that used to be templated by Helm. It is a best-effort reconciliation and
19+
// returns an error only when we cannot make the desired state match the spec.
20+
func EnsureValidatingWebhook(
21+
ctx context.Context,
22+
apiReader client.Reader,
23+
writer client.Client,
24+
namespace string,
25+
fullNamePrefix string,
26+
) error {
27+
// Desired validatingwebhookconfiguration spec.
28+
desired := buildConfigurationSpec(namespace, fullNamePrefix)
29+
30+
// Check if there is already a spec.
31+
existing := &admissionv1.ValidatingWebhookConfiguration{}
32+
err := apiReader.Get(ctx, types.NamespacedName{Name: desired.Name}, existing)
33+
if err != nil && !errors.IsNotFound(err) {
34+
return err
35+
}
36+
37+
if errors.IsNotFound(err) {
38+
return writer.Create(ctx, desired)
39+
}
40+
41+
// Deep-compare; update only if something differs.
42+
cur, _ := json.Marshal(existing.Webhooks)
43+
want, _ := json.Marshal(desired.Webhooks)
44+
45+
if string(cur) == string(want) {
46+
return nil
47+
}
48+
49+
existing.Webhooks = desired.Webhooks
50+
existing.Annotations = desired.Annotations
51+
return writer.Update(ctx, existing)
52+
}
53+
54+
// buildDesired reproduces the spec that used to be in Helm.
55+
func buildConfigurationSpec(namespace, namePrefix string) *admissionv1.ValidatingWebhookConfiguration {
56+
pathCache := "/validate-apps-nvidia-com-v1alpha1-nimcache"
57+
pathService := "/validate-apps-nvidia-com-v1alpha1-nimservice"
58+
59+
// Use appropriate annotations/labels as per deployment mode.
60+
var annotations map[string]string
61+
var labels map[string]string
62+
var clientconfignimcache admissionv1.WebhookClientConfig
63+
var clientconfignimservice admissionv1.WebhookClientConfig
64+
65+
clientconfignimcache = admissionv1.WebhookClientConfig{
66+
Service: &admissionv1.ServiceReference{
67+
Namespace: namespace,
68+
Name: namePrefix + "-webhook-service",
69+
Path: &pathCache,
70+
},
71+
}
72+
clientconfignimservice = admissionv1.WebhookClientConfig{
73+
Service: &admissionv1.ServiceReference{
74+
Namespace: namespace,
75+
Name: namePrefix + "-webhook-service",
76+
Path: &pathService,
77+
},
78+
}
79+
80+
// Deployment specific values.
81+
if config.OrchestratorType == k8sutil.K8s {
82+
annotations = map[string]string{"cert-manager.io/inject-ca-from": namespace + "/" + namePrefix + "-serving-cert"}
83+
labels = map[string]string{
84+
"app.kubernetes.io/name": "k8s-nim-operator",
85+
"app.kubernetes.io/managed-by": "helm",
86+
}
87+
} else {
88+
annotations = map[string]string{"service.beta.openshift.io/inject-cabundle": "true"}
89+
labels = map[string]string{
90+
"app.kubernetes.io/name": "k8s-nim-operator",
91+
"app.kubernetes.io/managed-by": "openshift",
92+
}
93+
}
94+
95+
return &admissionv1.ValidatingWebhookConfiguration{
96+
ObjectMeta: metav1.ObjectMeta{
97+
Name: namePrefix + "-validating-webhook-configuration",
98+
Annotations: annotations,
99+
Labels: labels,
100+
},
101+
Webhooks: []admissionv1.ValidatingWebhook{
102+
{
103+
Name: "vnimcache-v1alpha1.kb.io",
104+
AdmissionReviewVersions: []string{"v1"},
105+
ClientConfig: clientconfignimcache,
106+
FailurePolicy: func() *admissionv1.FailurePolicyType {
107+
fp := admissionv1.Fail
108+
return &fp
109+
}(),
110+
SideEffects: func() *admissionv1.SideEffectClass {
111+
s := admissionv1.SideEffectClassNone
112+
return &s
113+
}(),
114+
Rules: []admissionv1.RuleWithOperations{{
115+
Operations: []admissionv1.OperationType{
116+
admissionv1.Create, admissionv1.Update,
117+
},
118+
Rule: admissionv1.Rule{
119+
APIGroups: []string{"apps.nvidia.com"},
120+
APIVersions: []string{"v1alpha1"},
121+
Resources: []string{"nimcaches"},
122+
},
123+
}},
124+
},
125+
{
126+
Name: "vnimservice-v1alpha1.kb.io",
127+
AdmissionReviewVersions: []string{"v1"},
128+
ClientConfig: clientconfignimservice,
129+
FailurePolicy: func() *admissionv1.FailurePolicyType {
130+
fp := admissionv1.Fail
131+
return &fp
132+
}(),
133+
SideEffects: func() *admissionv1.SideEffectClass {
134+
s := admissionv1.SideEffectClassNone
135+
return &s
136+
}(),
137+
Rules: []admissionv1.RuleWithOperations{{
138+
Operations: []admissionv1.OperationType{
139+
admissionv1.Create, admissionv1.Update,
140+
},
141+
Rule: admissionv1.Rule{
142+
APIGroups: []string{"apps.nvidia.com"},
143+
APIVersions: []string{"v1alpha1"},
144+
Resources: []string{"nimservices"},
145+
},
146+
}},
147+
},
148+
},
149+
}
150+
}

0 commit comments

Comments
 (0)