From 029b6fbcd60bc733bd8992f78a1f8f1c3052ebaf Mon Sep 17 00:00:00 2001 From: disaster37 Date: Thu, 2 Jul 2026 08:47:36 +0000 Subject: [PATCH 1/2] fix: fix issue #1668 about auto renew certificat on mutating / validation deployment --- webhook/workspace/mutating_cfg.go | 5 +++++ webhook/workspace/validating_cfg.go | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/webhook/workspace/mutating_cfg.go b/webhook/workspace/mutating_cfg.go index c7433c8c4..fb05594d8 100644 --- a/webhook/workspace/mutating_cfg.go +++ b/webhook/workspace/mutating_cfg.go @@ -16,6 +16,8 @@ package workspace import ( + "fmt" + admregv1 "k8s.io/api/admissionregistration/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -155,6 +157,9 @@ func BuildMutateWebhookCfg(namespace string) *admregv1.MutatingWebhookConfigurat ObjectMeta: metav1.ObjectMeta{ Name: MutateWebhookCfgName, Labels: server.WebhookServerAppLabels(), + Annotations: map[string]string{ + "cert-manager.io/inject-ca-from": fmt.Sprintf("%s/devworkspace-controller-serving-cert", namespace), + }, }, Webhooks: []admregv1.MutatingWebhook{ workspaceMutateWebhook, diff --git a/webhook/workspace/validating_cfg.go b/webhook/workspace/validating_cfg.go index 86c22f15b..e3e3f02aa 100644 --- a/webhook/workspace/validating_cfg.go +++ b/webhook/workspace/validating_cfg.go @@ -16,6 +16,8 @@ package workspace import ( + "fmt" + admregv1 "k8s.io/api/admissionregistration/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -36,6 +38,9 @@ func buildValidatingWebhookCfg(namespace string) *admregv1.ValidatingWebhookConf ObjectMeta: metav1.ObjectMeta{ Name: ValidateWebhookCfgName, Labels: server.WebhookServerAppLabels(), + Annotations: map[string]string{ + "cert-manager.io/inject-ca-from": fmt.Sprintf("%s/devworkspace-controller-serving-cert", namespace), + }, }, Webhooks: []admregv1.ValidatingWebhook{ { From d2e0eb84049949c73c33d78d4368348d2607f927 Mon Sep 17 00:00:00 2001 From: disaster37 Date: Fri, 10 Jul 2026 08:32:20 +0000 Subject: [PATCH 2/2] feat: Add OCP annotations when OpenShift's Native Service CA Operator is used --- pkg/infrastructure/cluster.go | 24 +++++++++++++++++++--- webhook/workspace/annotations.go | 32 +++++++++++++++++++++++++++++ webhook/workspace/mutating_cfg.go | 12 ++++------- webhook/workspace/validating_cfg.go | 12 ++++------- 4 files changed, 61 insertions(+), 19 deletions(-) create mode 100644 webhook/workspace/annotations.go diff --git a/pkg/infrastructure/cluster.go b/pkg/infrastructure/cluster.go index 702d6e1ab..82e86c510 100644 --- a/pkg/infrastructure/cluster.go +++ b/pkg/infrastructure/cluster.go @@ -1,5 +1,5 @@ // -// Copyright (c) 2019-2025 Red Hat, Inc. +// Copyright (c) 2019-2026 Red Hat, Inc. // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at @@ -35,8 +35,9 @@ const ( var ( // current is the infrastructure that we're currently running on. - current Type - initialized = false + current Type + certManagerDetected bool + initialized = false ) // Initialize attempts to determine the type of cluster its currently running on (OpenShift or Kubernetes). This function @@ -57,6 +58,14 @@ func Initialize() error { // InitializeForTesting is used to mock running on a specific type of cluster (Kubernetes, OpenShift) in testing code. func InitializeForTesting(currentInfrastructure Type) { current = currentInfrastructure + certManagerDetected = false + initialized = true +} + +// InitializeForTestingWithCertManager is used to mock running on a cluster with cert-manager installed. +func InitializeForTestingWithCertManager(currentInfrastructure Type) { + current = currentInfrastructure + certManagerDetected = true initialized = true } @@ -72,6 +81,14 @@ func IsOpenShift() bool { return current == OpenShiftv4 } +// CertManagerDetected returns true if the cert-manager API group was detected on the cluster. +func CertManagerDetected() bool { + if !initialized { + panic("Attempting to determine information about the cluster without initializing first") + } + return certManagerDetected +} + func detect() (Type, error) { kubeCfg, err := config.GetConfig() if err != nil { @@ -85,6 +102,7 @@ func detect() (Type, error) { if err != nil { return Unsupported, fmt.Errorf("could not read API groups: %w", err) } + certManagerDetected = findAPIGroup(apiList.Groups, "cert-manager.io") != nil if findAPIGroup(apiList.Groups, "route.openshift.io") == nil { return Kubernetes, nil } else { diff --git a/webhook/workspace/annotations.go b/webhook/workspace/annotations.go new file mode 100644 index 000000000..9495b6fe6 --- /dev/null +++ b/webhook/workspace/annotations.go @@ -0,0 +1,32 @@ +// +// Copyright (c) 2019-2026 Red Hat, Inc. +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package workspace + +import ( + "fmt" + + "github.com/devfile/devworkspace-operator/pkg/infrastructure" +) + +func getWebhookAnnotations(namespace string) map[string]string { + annotations := map[string]string{} + if infrastructure.CertManagerDetected() { + annotations["cert-manager.io/inject-ca-from"] = fmt.Sprintf("%s/devworkspace-controller-serving-cert", namespace) + } else if infrastructure.IsOpenShift() { + annotations["service.beta.openshift.io/inject-cabundle"] = "true" + } + return annotations +} diff --git a/webhook/workspace/mutating_cfg.go b/webhook/workspace/mutating_cfg.go index fb05594d8..6a6e6d143 100644 --- a/webhook/workspace/mutating_cfg.go +++ b/webhook/workspace/mutating_cfg.go @@ -1,5 +1,5 @@ // -// Copyright (c) 2019-2025 Red Hat, Inc. +// Copyright (c) 2019-2026 Red Hat, Inc. // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at @@ -16,8 +16,6 @@ package workspace import ( - "fmt" - admregv1 "k8s.io/api/admissionregistration/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -155,11 +153,9 @@ func BuildMutateWebhookCfg(namespace string) *admregv1.MutatingWebhookConfigurat return &admregv1.MutatingWebhookConfiguration{ ObjectMeta: metav1.ObjectMeta{ - Name: MutateWebhookCfgName, - Labels: server.WebhookServerAppLabels(), - Annotations: map[string]string{ - "cert-manager.io/inject-ca-from": fmt.Sprintf("%s/devworkspace-controller-serving-cert", namespace), - }, + Name: MutateWebhookCfgName, + Labels: server.WebhookServerAppLabels(), + Annotations: getWebhookAnnotations(namespace), }, Webhooks: []admregv1.MutatingWebhook{ workspaceMutateWebhook, diff --git a/webhook/workspace/validating_cfg.go b/webhook/workspace/validating_cfg.go index e3e3f02aa..4c95cad7c 100644 --- a/webhook/workspace/validating_cfg.go +++ b/webhook/workspace/validating_cfg.go @@ -1,5 +1,5 @@ // -// Copyright (c) 2019-2025 Red Hat, Inc. +// Copyright (c) 2019-2026 Red Hat, Inc. // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at @@ -16,8 +16,6 @@ package workspace import ( - "fmt" - admregv1 "k8s.io/api/admissionregistration/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -36,11 +34,9 @@ func buildValidatingWebhookCfg(namespace string) *admregv1.ValidatingWebhookConf sideEffectsNone := admregv1.SideEffectClassNone return &admregv1.ValidatingWebhookConfiguration{ ObjectMeta: metav1.ObjectMeta{ - Name: ValidateWebhookCfgName, - Labels: server.WebhookServerAppLabels(), - Annotations: map[string]string{ - "cert-manager.io/inject-ca-from": fmt.Sprintf("%s/devworkspace-controller-serving-cert", namespace), - }, + Name: ValidateWebhookCfgName, + Labels: server.WebhookServerAppLabels(), + Annotations: getWebhookAnnotations(namespace), }, Webhooks: []admregv1.ValidatingWebhook{ {