Skip to content

Commit cacc668

Browse files
committed
feat(controller): support hostNetwork
This commit adds the support to enable host network in the Kubewarden stack. This is done by enabling a CLI flag in the controller. Once this is done, all the policy server deployments are configured to use host network as well. Furthermore, to allow user to fix port conflicts issues, 3 new fields have been added to the policy server spec. This fields allow users to define the ports to be used by the policy server deployment. Assisted-by: Github Copilot Signed-off-by: José Guilherme Vanz <jguilhermevanz@suse.com>
1 parent e9aee77 commit cacc668

25 files changed

Lines changed: 778 additions & 78 deletions

Makefile

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,9 @@ helm-unittest:
5454
test-e2e: controller-image audit-scanner-image policy-server-image
5555
$(GO_BUILD_ENV) go test ./e2e/ -v
5656

57+
.PHONY: test-all
58+
test-all: test helm-unittest test-e2e
59+
5760
.PHONY: fmt-go
5861
fmt-go:
5962
$(GO_BUILD_ENV) go fmt ./...

api/policies/v1/factories.go

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -486,6 +486,9 @@ type PolicyServerBuilder struct {
486486
limits corev1.ResourceList
487487
requests corev1.ResourceList
488488
sigstoreTrustConfigMap string
489+
webhookPort *int32
490+
readinessProbePort *int32
491+
metricsPort *int32
489492
}
490493

491494
func NewPolicyServerFactory() *PolicyServerBuilder {
@@ -529,6 +532,21 @@ func (f *PolicyServerBuilder) WithRequests(requests corev1.ResourceList) *Policy
529532
return f
530533
}
531534

535+
func (f *PolicyServerBuilder) WithWebhookPort(port int32) *PolicyServerBuilder {
536+
f.webhookPort = &port
537+
return f
538+
}
539+
540+
func (f *PolicyServerBuilder) WithReadinessProbePort(port int32) *PolicyServerBuilder {
541+
f.readinessProbePort = &port
542+
return f
543+
}
544+
545+
func (f *PolicyServerBuilder) WithMetricsPort(port int32) *PolicyServerBuilder {
546+
f.metricsPort = &port
547+
return f
548+
}
549+
532550
func (f *PolicyServerBuilder) Build() *PolicyServer {
533551
policyServer := PolicyServer{
534552
ObjectMeta: metav1.ObjectMeta{
@@ -552,6 +570,9 @@ func (f *PolicyServerBuilder) Build() *PolicyServer {
552570
Limits: f.limits,
553571
Requests: f.requests,
554572
SigstoreTrustConfig: f.sigstoreTrustConfigMap,
573+
WebhookPort: f.webhookPort,
574+
ReadinessProbePort: f.readinessProbePort,
575+
MetricsPort: f.metricsPort,
555576
Env: []corev1.EnvVar{
556577
{
557578
Name: "KUBEWARDEN_LOG_LEVEL",

api/policies/v1/policyserver_types.go

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,28 @@ type PolicyServerSpec struct {
139139
// remain unchanged, but new pods that reference it cannot be created.
140140
// +optional
141141
PriorityClassName string `json:"priorityClassName,omitempty"`
142+
143+
// Port where the policy server listens for incoming webhook requests.
144+
// When unset, defaults to 8443. This is the port the Kubernetes API server
145+
// reaches when evaluating admission requests.
146+
// +optional
147+
// +kubebuilder:validation:Minimum=1
148+
// +kubebuilder:validation:Maximum=65535
149+
WebhookPort *int32 `json:"webhookPort,omitempty"`
150+
151+
// Port used by the policy server to expose the readiness probe endpoint.
152+
// When unset, defaults to 8081.
153+
// +optional
154+
// +kubebuilder:validation:Minimum=1
155+
// +kubebuilder:validation:Maximum=65535
156+
ReadinessProbePort *int32 `json:"readinessProbePort,omitempty"`
157+
158+
// Port used by the policy server to expose the metrics endpoint.
159+
// When unset, defaults to 8080. Only relevant when metrics are enabled.
160+
// +optional
161+
// +kubebuilder:validation:Minimum=1
162+
// +kubebuilder:validation:Maximum=65535
163+
MetricsPort *int32 `json:"metricsPort,omitempty"`
142164
}
143165

144166
type ReconciliationTransitionReason string
@@ -211,6 +233,33 @@ func (ps *PolicyServer) AppLabel() string {
211233
return "kubewarden-" + ps.NameWithPrefix()
212234
}
213235

236+
// EffectiveWebhookPort returns the port the policy server listens on for
237+
// admission webhook requests, using the CRD field when set or the default constant.
238+
func (ps *PolicyServer) EffectiveWebhookPort() int32 {
239+
if ps.Spec.WebhookPort != nil {
240+
return *ps.Spec.WebhookPort
241+
}
242+
return constants.PolicyServerListenPort
243+
}
244+
245+
// EffectiveReadinessProbePort returns the port used for the readiness probe,
246+
// using the CRD field when set or the default constant.
247+
func (ps *PolicyServer) EffectiveReadinessProbePort() int32 {
248+
if ps.Spec.ReadinessProbePort != nil {
249+
return *ps.Spec.ReadinessProbePort
250+
}
251+
return constants.PolicyServerReadinessProbePort
252+
}
253+
254+
// EffectiveMetricsPort returns the port used to expose the metrics endpoint,
255+
// using the CRD field when set or the default constant.
256+
func (ps *PolicyServer) EffectiveMetricsPort() int32 {
257+
if ps.Spec.MetricsPort != nil {
258+
return *ps.Spec.MetricsPort
259+
}
260+
return constants.PolicyServerMetricsPort
261+
}
262+
214263
// CommonLabels returns the common labels to be used with the resources
215264
// associated to a Policy Server. The labels defined follow
216265
// Kubernetes guidelines: https://kubernetes.io/docs/concepts/overview/working-with-objects/common-labels/#labels

api/policies/v1/policyserver_webhook.go

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,7 @@ func (v *policyServerValidator) validate(ctx context.Context, policyServer *Poli
131131
}
132132

133133
allErrs = append(allErrs, validateLimitsAndRequests(policyServer.Spec.Limits, policyServer.Spec.Requests)...)
134+
allErrs = append(allErrs, validatePorts(policyServer)...)
134135

135136
if len(allErrs) == 0 {
136137
return nil
@@ -208,3 +209,38 @@ func validateLimitsAndRequests(limits, requests corev1.ResourceList) field.Error
208209

209210
return allErrs
210211
}
212+
213+
// validatePorts checks that the port fields in the PolicyServer spec do not
214+
// conflict with each other. Effective ports (field value or constant default)
215+
// are compared so that partial overrides are also caught.
216+
func validatePorts(policyServer *PolicyServer) field.ErrorList {
217+
var allErrs field.ErrorList
218+
219+
webhookPort := policyServer.EffectiveWebhookPort()
220+
readinessPort := policyServer.EffectiveReadinessProbePort()
221+
metricsPort := policyServer.EffectiveMetricsPort()
222+
223+
if webhookPort == readinessPort {
224+
allErrs = append(allErrs, field.Invalid(
225+
field.NewPath("spec").Child("readinessProbePort"),
226+
readinessPort,
227+
fmt.Sprintf("readinessProbePort must differ from webhookPort (%d)", webhookPort),
228+
))
229+
}
230+
if webhookPort == metricsPort {
231+
allErrs = append(allErrs, field.Invalid(
232+
field.NewPath("spec").Child("metricsPort"),
233+
metricsPort,
234+
fmt.Sprintf("metricsPort must differ from webhookPort (%d)", webhookPort),
235+
))
236+
}
237+
if readinessPort == metricsPort {
238+
allErrs = append(allErrs, field.Invalid(
239+
field.NewPath("spec").Child("metricsPort"),
240+
metricsPort,
241+
fmt.Sprintf("metricsPort must differ from readinessProbePort (%d)", readinessPort),
242+
))
243+
}
244+
245+
return allErrs
246+
}

api/policies/v1/policyserver_webhook_test.go

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -279,3 +279,80 @@ func TestPolicyServerValidateSigstoreTrustConfig(t *testing.T) {
279279
})
280280
}
281281
}
282+
283+
func TestValidatePorts(t *testing.T) {
284+
tests := []struct {
285+
name string
286+
webhookPort *int32
287+
readiness *int32
288+
metrics *int32
289+
errContains string
290+
}{
291+
{
292+
name: "all defaults, no conflict",
293+
errContains: "",
294+
},
295+
{
296+
name: "webhookPort equals readinessProbePort",
297+
webhookPort: ptr.To[int32](8081),
298+
readiness: ptr.To[int32](8081),
299+
errContains: "readinessProbePort must differ from webhookPort",
300+
},
301+
{
302+
name: "webhookPort equals metricsPort",
303+
webhookPort: ptr.To[int32](8080),
304+
metrics: ptr.To[int32](8080),
305+
errContains: "metricsPort must differ from webhookPort",
306+
},
307+
{
308+
name: "readinessProbePort equals metricsPort",
309+
readiness: ptr.To[int32](9000),
310+
metrics: ptr.To[int32](9000),
311+
errContains: "metricsPort must differ from readinessProbePort",
312+
},
313+
{
314+
name: "all three ports the same",
315+
webhookPort: ptr.To[int32](9999),
316+
readiness: ptr.To[int32](9999),
317+
metrics: ptr.To[int32](9999),
318+
errContains: "readinessProbePort must differ from webhookPort",
319+
},
320+
{
321+
name: "all three ports distinct custom values",
322+
webhookPort: ptr.To[int32](9443),
323+
readiness: ptr.To[int32](9081),
324+
metrics: ptr.To[int32](9080),
325+
errContains: "",
326+
},
327+
}
328+
329+
for _, test := range tests {
330+
t.Run(test.name, func(t *testing.T) {
331+
k8sClient := fake.NewClientBuilder().Build()
332+
builder := NewPolicyServerFactory()
333+
if test.webhookPort != nil {
334+
builder = builder.WithWebhookPort(*test.webhookPort)
335+
}
336+
if test.readiness != nil {
337+
builder = builder.WithReadinessProbePort(*test.readiness)
338+
}
339+
if test.metrics != nil {
340+
builder = builder.WithMetricsPort(*test.metrics)
341+
}
342+
policyServer := builder.Build()
343+
344+
validator := policyServerValidator{
345+
deploymentsNamespace: "default",
346+
k8sClient: k8sClient,
347+
logger: logr.Discard(),
348+
}
349+
err := validator.validate(t.Context(), policyServer)
350+
351+
if test.errContains != "" {
352+
require.ErrorContains(t, err, test.errContains)
353+
} else {
354+
require.NoError(t, err)
355+
}
356+
})
357+
}
358+
}

api/policies/v1/zz_generated.deepcopy.go

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

charts/kubewarden-controller/templates/_helpers.tpl

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,3 +181,20 @@ are configured.
181181
- {{ .Values.auditScanner.reportCRDsKind }}
182182
{{- end -}}
183183
{{- end -}}
184+
185+
{{/*
186+
Compute the effective affinity for the controller deployment.
187+
Uses the controller-specific affinity if set, otherwise falls back to
188+
global.affinity for backward compatibility.
189+
190+
NOTE: When hostNetwork is enabled, users are responsible for setting
191+
appropriate podAntiAffinity rules to prevent host-port conflicts between
192+
controller replicas on the same node.
193+
*/}}
194+
{{- define "kubewarden-controller.effectiveAffinity" -}}
195+
{{- if .Values.affinity -}}
196+
{{- toYaml .Values.affinity -}}
197+
{{- else if .Values.global.affinity -}}
198+
{{- toYaml .Values.global.affinity -}}
199+
{{- end -}}
200+
{{- end -}}

charts/kubewarden-controller/templates/deployment.yaml

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,9 @@ spec:
3232
{{- include "imagePullSecrets" .Values.imagePullSecrets | nindent 8 }}
3333
{{- end }}
3434
serviceAccountName: {{ include "kubewarden-controller.serviceAccountName" . }}
35-
{{- if .Values.global.affinity }}
36-
affinity: {{ .Values.global.affinity | toYaml | nindent 8 }}
35+
{{- $effectiveAffinity := include "kubewarden-controller.effectiveAffinity" . }}
36+
{{- if $effectiveAffinity }}
37+
affinity: {{ $effectiveAffinity | nindent 8 }}
3738
{{- end }}
3839
{{- if .Values.global.tolerations }}
3940
tolerations: {{ .Values.global.tolerations | toYaml | nindent 8 }}
@@ -45,12 +46,19 @@ spec:
4546
{{- if .Values.global.priorityClassName }}
4647
priorityClassName: {{ .Values.global.priorityClassName | toYaml | nindent 8 }}
4748
{{- end }}
49+
{{- if .Values.hostNetwork }}
50+
hostNetwork: true
51+
dnsPolicy: ClusterFirstWithHostNet
52+
{{- end }}
4853
containers:
4954
- name: controller
5055
args:
5156
- --leader-elect
5257
- --deployments-namespace={{ .Release.Namespace }}
5358
- --webhook-service-name={{ include "kubewarden-controller.fullname" . }}-webhook-service
59+
- --webhook-server-port={{ .Values.ports.webhook }}
60+
- --health-probe-bind-address=:{{ .Values.ports.healthProbe }}
61+
- --metrics-bind-address=:{{ .Values.ports.metrics }}
5462
{{- if .Values.alwaysAcceptAdmissionReviewsOnDeploymentsNamespace }}
5563
- --always-accept-admission-reviews-on-deployments-namespace
5664
{{- end }}
@@ -62,6 +70,9 @@ spec:
6270
{{- if $imagePullSecretNames }}
6371
- --image-pull-secrets={{ $imagePullSecretNames }}
6472
{{- end }}
73+
{{- if .Values.hostNetwork }}
74+
- --host-network
75+
{{- end }}
6576
{{- if or .Values.telemetry.metrics .Values.telemetry.tracing }}
6677
{{- if eq .Values.telemetry.mode "sidecar" }}
6778
- --enable-otel-sidecar
@@ -117,13 +128,13 @@ spec:
117128
livenessProbe:
118129
httpGet:
119130
path: /healthz
120-
port: 8081
131+
port: {{ .Values.ports.healthProbe }}
121132
initialDelaySeconds: 15
122133
periodSeconds: 20
123134
readinessProbe:
124135
httpGet:
125136
path: /readyz
126-
port: 8081
137+
port: {{ .Values.ports.healthProbe }}
127138
initialDelaySeconds: 5
128139
periodSeconds: 10
129140
{{- if and .Values.resources .Values.resources.controller }}
@@ -154,7 +165,7 @@ spec:
154165
readOnly: true
155166
{{- end }}
156167
ports:
157-
- containerPort: 9443
168+
- containerPort: {{ .Values.ports.webhook }}
158169
name: webhook-server
159170
protocol: TCP
160171
volumes:

charts/kubewarden-controller/templates/service.yaml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,11 @@ spec:
1313
{{- if .Values.telemetry.metrics }}
1414
- name: metrics
1515
port: 8080
16-
targetPort: 8080
16+
targetPort: {{ .Values.ports.metrics }}
1717
{{- end}}
1818
- name: https
1919
port: 8443
20-
targetPort: https
20+
targetPort: {{ .Values.ports.webhook }}
2121
selector:
2222
{{- include "kubewarden-controller.selectorLabels" . | nindent 4 }}
2323
---
@@ -33,6 +33,6 @@ metadata:
3333
spec:
3434
ports:
3535
- port: 443
36-
targetPort: 9443
36+
targetPort: {{ .Values.ports.webhook }}
3737
selector:
3838
{{- include "kubewarden-controller.selectorLabels" . | nindent 4 }}

0 commit comments

Comments
 (0)