diff --git a/app/caps-controller-manager/config/default/webhookcainjection_patch.yaml b/app/caps-controller-manager/config/default/webhookcainjection_patch.yaml index 7e79bf995..6b2c0f3ab 100644 --- a/app/caps-controller-manager/config/default/webhookcainjection_patch.yaml +++ b/app/caps-controller-manager/config/default/webhookcainjection_patch.yaml @@ -1,13 +1,4 @@ -# This patch add annotation to admission webhook config and -# the variables $(CERTIFICATE_NAMESPACE) and $(CERTIFICATE_NAME) will be substituted by kustomize. -apiVersion: admissionregistration.k8s.io/v1beta1 -kind: MutatingWebhookConfiguration -metadata: - name: mutating-webhook-configuration - annotations: - cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME) ---- -apiVersion: admissionregistration.k8s.io/v1beta1 +apiVersion: admissionregistration.k8s.io/v1 kind: ValidatingWebhookConfiguration metadata: name: validating-webhook-configuration diff --git a/app/caps-controller-manager/main.go b/app/caps-controller-manager/main.go index 4a53b13e8..407512230 100644 --- a/app/caps-controller-manager/main.go +++ b/app/caps-controller-manager/main.go @@ -144,6 +144,22 @@ func main() { os.Exit(1) } + // +kubebuilder:scaffold:builder + + setupWebhooks(mgr) + setupChecks(mgr) + + setupLog.Info("starting manager") + + if err := mgr.Start(ctx); err != nil { + setupLog.Error(err, "problem running manager") + os.Exit(1) + } +} + +func setupWebhooks(mgr ctrl.Manager) { + var err error + if err = (&infrav1alpha3.MetalCluster{}).SetupWebhookWithManager(mgr); err != nil { setupLog.Error(err, "unable to create webhook", "webhook", "MetalCluster") os.Exit(1) @@ -163,16 +179,6 @@ func main() { setupLog.Error(err, "unable to create webhook", "webhook", "ServerBinding") os.Exit(1) } - // +kubebuilder:scaffold:builder - - setupChecks(mgr) - - setupLog.Info("starting manager") - - if err := mgr.Start(ctx); err != nil { - setupLog.Error(err, "problem running manager") - os.Exit(1) - } } func setupChecks(mgr ctrl.Manager) { diff --git a/app/sidero-controller-manager/api/v1alpha1/environment_webhook.go b/app/sidero-controller-manager/api/v1alpha1/environment_webhook.go new file mode 100644 index 000000000..679ff2614 --- /dev/null +++ b/app/sidero-controller-manager/api/v1alpha1/environment_webhook.go @@ -0,0 +1,15 @@ +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +package v1alpha1 + +import ( + ctrl "sigs.k8s.io/controller-runtime" +) + +func (r *Environment) SetupWebhookWithManager(mgr ctrl.Manager) error { + return ctrl.NewWebhookManagedBy(mgr). + For(r). + Complete() +} diff --git a/app/sidero-controller-manager/api/v1alpha1/server_webhook.go b/app/sidero-controller-manager/api/v1alpha1/server_webhook.go new file mode 100644 index 000000000..668f858d1 --- /dev/null +++ b/app/sidero-controller-manager/api/v1alpha1/server_webhook.go @@ -0,0 +1,112 @@ +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +package v1alpha1 + +import ( + "fmt" + "sort" + + apierrors "k8s.io/apimachinery/pkg/api/errors" + runtime "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/util/validation/field" + ctrl "sigs.k8s.io/controller-runtime" + "sigs.k8s.io/controller-runtime/pkg/webhook" + + siderotypes "github.com/talos-systems/sidero/app/sidero-controller-manager/pkg/types" +) + +var operations = map[string]struct{}{ + "add": {}, + "remove": {}, + "replace": {}, + "copy": {}, + "move": {}, + "test": {}, +} + +var operationKinds = []string{} + +func (r *Server) SetupWebhookWithManager(mgr ctrl.Manager) error { + return ctrl.NewWebhookManagedBy(mgr). + For(r). + Complete() +} + +//+kubebuilder:webhook:verbs=create;update;delete,path=/validate-metal-sidero-dev-v1alpha1-server,mutating=false,failurePolicy=fail,groups=metal.sidero.dev,resources=servers,versions=v1alpha1,name=vservers.metal.sidero.dev,sideEffects=None,admissionReviewVersions=v1 + +var _ webhook.Validator = &Server{} + +// ValidateCreate implements webhook.Validator so a webhook will be registered for the type. +func (r *Server) ValidateCreate() error { + return r.validate() +} + +// ValidateUpdate implements webhook.Validator so a webhook will be registered for the type. +func (r *Server) ValidateUpdate(old runtime.Object) error { + return r.validate() +} + +// ValidateDelete implements webhook.Validator so a webhook will be registered for the type. +func (r *Server) ValidateDelete() error { + return nil +} + +func (r *Server) validate() error { + var allErrs field.ErrorList + + validValues := []siderotypes.BootFromDisk{ + "", + siderotypes.BootIPXEExit, + siderotypes.Boot404, + siderotypes.BootSANDisk, + } + + var valid bool + + for _, v := range validValues { + if r.Spec.BootFromDiskMethod == v { + valid = true + + break + } + } + + if !valid { + allErrs = append(allErrs, + field.Invalid(field.NewPath("spec").Child("bootFromDiskMethod"), r.Spec.BootFromDiskMethod, + fmt.Sprintf("valid values are: %q", validValues), + ), + ) + } + + for index, patch := range r.Spec.ConfigPatches { + if _, ok := operations[patch.Op]; !ok { + allErrs = append(allErrs, + field.Invalid(field.NewPath("spec").Child("configPatches").Child(fmt.Sprintf("%d", index)).Child("op"), patch.Op, + fmt.Sprintf("valid values are: %q", operationKinds), + ), + ) + } + } + + if len(allErrs) == 0 { + return nil + } + + return apierrors.NewInvalid( + schema.GroupKind{Group: GroupVersion.Group, Kind: "Server"}, + r.Name, allErrs) +} + +func init() { + operationKinds = make([]string, 0, len(operations)) + + for key := range operations { + operationKinds = append(operationKinds, key) + } + + sort.Strings(operationKinds) +} diff --git a/app/sidero-controller-manager/api/v1alpha1/serverclass_webhook.go b/app/sidero-controller-manager/api/v1alpha1/serverclass_webhook.go new file mode 100644 index 000000000..de5a8d92a --- /dev/null +++ b/app/sidero-controller-manager/api/v1alpha1/serverclass_webhook.go @@ -0,0 +1,15 @@ +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +package v1alpha1 + +import ( + ctrl "sigs.k8s.io/controller-runtime" +) + +func (r *ServerClass) SetupWebhookWithManager(mgr ctrl.Manager) error { + return ctrl.NewWebhookManagedBy(mgr). + For(r). + Complete() +} diff --git a/app/sidero-controller-manager/api/v1alpha1/zz_generated.deepcopy.go b/app/sidero-controller-manager/api/v1alpha1/zz_generated.deepcopy.go index 2d9fb112b..5e2066efd 100644 --- a/app/sidero-controller-manager/api/v1alpha1/zz_generated.deepcopy.go +++ b/app/sidero-controller-manager/api/v1alpha1/zz_generated.deepcopy.go @@ -11,7 +11,7 @@ package v1alpha1 import ( v1 "k8s.io/api/core/v1" - runtime "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime" "sigs.k8s.io/cluster-api/api/v1beta1" ) diff --git a/app/sidero-controller-manager/config/certmanager/certificate.yaml b/app/sidero-controller-manager/config/certmanager/certificate.yaml index fac5aa1bb..adf4a3c12 100644 --- a/app/sidero-controller-manager/config/certmanager/certificate.yaml +++ b/app/sidero-controller-manager/config/certmanager/certificate.yaml @@ -15,11 +15,11 @@ metadata: name: serving-cert # this name should match the one appeared in kustomizeconfig.yaml namespace: system spec: - # $(SERVICE_NAME) and $(SERVICE_NAMESPACE) will be substituted by kustomize + # $(SIDERO_SERVICE_NAME) and $(SERVICE_NAMESPACE) will be substituted by kustomize dnsNames: - - $(SERVICE_NAME).$(SERVICE_NAMESPACE).svc - - $(SERVICE_NAME).$(SERVICE_NAMESPACE).svc.cluster.local + - $(SIDERO_SERVICE_NAME).$(SERVICE_NAMESPACE).svc + - $(SIDERO_SERVICE_NAME).$(SERVICE_NAMESPACE).svc.cluster.local issuerRef: kind: Issuer name: selfsigned-issuer - secretName: webhook-server-cert # this secret will not be prefixed, since it's not managed by kustomize + secretName: $(SIDERO_SERVICE_NAME)-cert # this secret will not be prefixed, since it's not managed by kustomize diff --git a/app/sidero-controller-manager/config/crd/kustomization.yaml b/app/sidero-controller-manager/config/crd/kustomization.yaml index eb4523e0f..1f8011ba1 100644 --- a/app/sidero-controller-manager/config/crd/kustomization.yaml +++ b/app/sidero-controller-manager/config/crd/kustomization.yaml @@ -13,16 +13,16 @@ commonLabels: patchesStrategicMerge: # [WEBHOOK] To enable webhook, uncomment all the sections with [WEBHOOK] prefix. # patches here are for enabling the conversion webhook for each CRD -#- patches/webhook_in_environments.yaml -#- patches/webhook_in_servers.yaml -#- patches/webhook_in_serverclasses.yaml +- patches/webhook_in_environments.yaml +- patches/webhook_in_servers.yaml +- patches/webhook_in_serverclasses.yaml # +kubebuilder:scaffold:crdkustomizewebhookpatch # [CERTMANAGER] To enable webhook, uncomment all the sections with [CERTMANAGER] prefix. # patches here are for enabling the CA injection for each CRD -#- patches/cainjection_in_environments.yaml -#- patches/cainjection_in_servers.yaml -#- patches/cainjection_in_serverclasses.yaml +- patches/cainjection_in_environments.yaml +- patches/cainjection_in_servers.yaml +- patches/cainjection_in_serverclasses.yaml # +kubebuilder:scaffold:crdkustomizecainjectionpatch # the following config is for teaching kustomize how to do kustomization for CRDs. diff --git a/app/sidero-controller-manager/config/crd/kustomizeconfig.yaml b/app/sidero-controller-manager/config/crd/kustomizeconfig.yaml index 6f83d9a94..8e2d8d6b1 100644 --- a/app/sidero-controller-manager/config/crd/kustomizeconfig.yaml +++ b/app/sidero-controller-manager/config/crd/kustomizeconfig.yaml @@ -5,12 +5,12 @@ nameReference: fieldSpecs: - kind: CustomResourceDefinition group: apiextensions.k8s.io - path: spec/conversion/webhookClientConfig/service/name + path: spec/conversion/webhook/clientConfig/service/name namespace: - kind: CustomResourceDefinition group: apiextensions.k8s.io - path: spec/conversion/webhookClientConfig/service/namespace + path: spec/conversion/webhook/clientConfig/service/namespace create: false varReference: diff --git a/app/sidero-controller-manager/config/crd/patches/cainjection_in_environments.yaml b/app/sidero-controller-manager/config/crd/patches/cainjection_in_environments.yaml index 91fc9ab43..f578af67c 100644 --- a/app/sidero-controller-manager/config/crd/patches/cainjection_in_environments.yaml +++ b/app/sidero-controller-manager/config/crd/patches/cainjection_in_environments.yaml @@ -1,8 +1,8 @@ # The following patch adds a directive for certmanager to inject CA into the CRD # CRD conversion requires k8s 1.13 or later. -apiVersion: apiextensions.k8s.io/v1beta1 +apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME) + cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(SIDERO_CERTIFICATE_NAME) name: environments.metal.sidero.dev diff --git a/app/sidero-controller-manager/config/crd/patches/cainjection_in_serverclasses.yaml b/app/sidero-controller-manager/config/crd/patches/cainjection_in_serverclasses.yaml index 6dc47f854..9a0174df2 100644 --- a/app/sidero-controller-manager/config/crd/patches/cainjection_in_serverclasses.yaml +++ b/app/sidero-controller-manager/config/crd/patches/cainjection_in_serverclasses.yaml @@ -1,8 +1,8 @@ # The following patch adds a directive for certmanager to inject CA into the CRD # CRD conversion requires k8s 1.13 or later. -apiVersion: apiextensions.k8s.io/v1beta1 +apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME) + cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(SIDERO_CERTIFICATE_NAME) name: serverclasses.metal.sidero.dev diff --git a/app/sidero-controller-manager/config/crd/patches/cainjection_in_servers.yaml b/app/sidero-controller-manager/config/crd/patches/cainjection_in_servers.yaml index d5d9a02dd..5912feff0 100644 --- a/app/sidero-controller-manager/config/crd/patches/cainjection_in_servers.yaml +++ b/app/sidero-controller-manager/config/crd/patches/cainjection_in_servers.yaml @@ -1,8 +1,8 @@ # The following patch adds a directive for certmanager to inject CA into the CRD # CRD conversion requires k8s 1.13 or later. -apiVersion: apiextensions.k8s.io/v1beta1 +apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME) + cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(SIDERO_CERTIFICATE_NAME) name: servers.metal.sidero.dev diff --git a/app/sidero-controller-manager/config/crd/patches/webhook_in_environments.yaml b/app/sidero-controller-manager/config/crd/patches/webhook_in_environments.yaml index 3c264e887..b66be96c2 100644 --- a/app/sidero-controller-manager/config/crd/patches/webhook_in_environments.yaml +++ b/app/sidero-controller-manager/config/crd/patches/webhook_in_environments.yaml @@ -1,17 +1,19 @@ # The following patch enables conversion webhook for CRD # CRD conversion requires k8s 1.13 or later. -apiVersion: apiextensions.k8s.io/v1beta1 +apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: name: environments.metal.sidero.dev spec: conversion: strategy: Webhook - webhookClientConfig: - # this is "\n" used as a placeholder, otherwise it will be rejected by the apiserver for being blank, - # but we're going to set it later using the cert-manager (or potentially a patch if not using cert-manager) - caBundle: Cg== - service: - namespace: system - name: webhook-service - path: /convert + webhook: + conversionReviewVersions: ["v1", "v1beta1"] + clientConfig: + # this is "\n" used as a placeholder, otherwise it will be rejected by the apiserver for being blank, + # but we're going to set it later using the cert-manager (or potentially a patch if not using cert-manager) + caBundle: Cg== + service: + namespace: system + name: webhook-service + path: /convert diff --git a/app/sidero-controller-manager/config/crd/patches/webhook_in_serverclasses.yaml b/app/sidero-controller-manager/config/crd/patches/webhook_in_serverclasses.yaml index f784b1027..73196078f 100644 --- a/app/sidero-controller-manager/config/crd/patches/webhook_in_serverclasses.yaml +++ b/app/sidero-controller-manager/config/crd/patches/webhook_in_serverclasses.yaml @@ -1,17 +1,19 @@ # The following patch enables conversion webhook for CRD # CRD conversion requires k8s 1.13 or later. -apiVersion: apiextensions.k8s.io/v1beta1 +apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: name: serverclasses.metal.sidero.dev spec: conversion: strategy: Webhook - webhookClientConfig: - # this is "\n" used as a placeholder, otherwise it will be rejected by the apiserver for being blank, - # but we're going to set it later using the cert-manager (or potentially a patch if not using cert-manager) - caBundle: Cg== - service: - namespace: system - name: webhook-service - path: /convert + webhook: + conversionReviewVersions: ["v1", "v1beta1"] + clientConfig: + # this is "\n" used as a placeholder, otherwise it will be rejected by the apiserver for being blank, + # but we're going to set it later using the cert-manager (or potentially a patch if not using cert-manager) + caBundle: Cg== + service: + namespace: system + name: webhook-service + path: /convert diff --git a/app/sidero-controller-manager/config/crd/patches/webhook_in_servers.yaml b/app/sidero-controller-manager/config/crd/patches/webhook_in_servers.yaml index 404ad5977..99a9aa48e 100644 --- a/app/sidero-controller-manager/config/crd/patches/webhook_in_servers.yaml +++ b/app/sidero-controller-manager/config/crd/patches/webhook_in_servers.yaml @@ -1,17 +1,19 @@ # The following patch enables conversion webhook for CRD # CRD conversion requires k8s 1.13 or later. -apiVersion: apiextensions.k8s.io/v1beta1 +apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: name: servers.metal.sidero.dev spec: conversion: strategy: Webhook - webhookClientConfig: - # this is "\n" used as a placeholder, otherwise it will be rejected by the apiserver for being blank, - # but we're going to set it later using the cert-manager (or potentially a patch if not using cert-manager) - caBundle: Cg== - service: - namespace: system - name: webhook-service - path: /convert + webhook: + conversionReviewVersions: ["v1", "v1beta1"] + clientConfig: + # this is "\n" used as a placeholder, otherwise it will be rejected by the apiserver for being blank, + # but we're going to set it later using the cert-manager (or potentially a patch if not using cert-manager) + caBundle: Cg== + service: + namespace: system + name: webhook-service + path: /convert diff --git a/app/sidero-controller-manager/config/kustomization.yaml b/app/sidero-controller-manager/config/kustomization.yaml index 2d6c596c0..1875fd3f8 100644 --- a/app/sidero-controller-manager/config/kustomization.yaml +++ b/app/sidero-controller-manager/config/kustomization.yaml @@ -5,10 +5,8 @@ bases: - crd - rbac - manager -# [WEBHOOK] To enable webhook, uncomment all the sections with [WEBHOOK] prefix including the one in crd/kustomization.yaml -#- ../webhook -# [CERTMANAGER] To enable cert-manager, uncomment all sections with 'CERTMANAGER'. 'WEBHOOK' components are required. -#- ../certmanager + - certmanager + - webhook # [PROMETHEUS] To enable prometheus monitor, uncomment all sections with 'PROMETHEUS'. #- ../prometheus @@ -25,43 +23,19 @@ patchesStrategicMerge: # Only one of manager_auth_proxy_patch.yaml and # manager_prometheus_metrics_patch.yaml should be enabled. #- manager_prometheus_metrics_patch.yaml - -# [WEBHOOK] To enable webhook, uncomment all the sections with [WEBHOOK] prefix including the one in crd/kustomization.yaml -#- manager_webhook_patch.yaml - -# [CERTMANAGER] To enable cert-manager, uncomment all sections with 'CERTMANAGER'. -# Uncomment 'CERTMANAGER' sections in crd/kustomization.yaml to enable the CA injection in the admission webhooks. -# 'CERTMANAGER' needs to be enabled to use ca injection -#- webhookcainjection_patch.yaml - -# the following config is for teaching kustomize how to do var substitution + - manager_webhook_patch.yaml + - webhookcainjection_patch.yaml vars: -# [CERTMANAGER] To enable cert-manager, uncomment all sections with 'CERTMANAGER' prefix. -#- name: CERTIFICATE_NAMESPACE # namespace of the certificate CR -# objref: -# kind: Certificate -# group: cert-manager.io -# version: v1 -# name: serving-cert # this name should match the one in certificate.yaml -# fieldref: -# fieldpath: metadata.namespace -#- name: CERTIFICATE_NAME -# objref: -# kind: Certificate -# group: cert-manager.io -# version: v1 -# name: serving-cert # this name should match the one in certificate.yaml -#- name: SERVICE_NAMESPACE # namespace of the service -# objref: -# kind: Service -# version: v1 -# name: webhook-service -# fieldref: -# fieldpath: metadata.namespace -#- name: SERVICE_NAME -# objref: -# kind: Service -# version: v1 -# name: webhook-service + - name: SIDERO_CERTIFICATE_NAME + objref: + kind: Certificate + group: cert-manager.io + version: v1 + name: serving-cert # this name should match the one in certificate.yaml + - name: SIDERO_SERVICE_NAME + objref: + kind: Service + version: v1 + name: webhook-service namespace: sidero-system diff --git a/app/sidero-controller-manager/config/manager_webhook_patch.yaml b/app/sidero-controller-manager/config/manager_webhook_patch.yaml index 738de350b..7272da278 100644 --- a/app/sidero-controller-manager/config/manager_webhook_patch.yaml +++ b/app/sidero-controller-manager/config/manager_webhook_patch.yaml @@ -20,4 +20,4 @@ spec: - name: cert secret: defaultMode: 420 - secretName: webhook-server-cert + secretName: $(SIDERO_SERVICE_NAME)-cert diff --git a/app/sidero-controller-manager/config/webhook/kustomization.yaml b/app/sidero-controller-manager/config/webhook/kustomization.yaml index 7ed6560ae..7feb516a7 100644 --- a/app/sidero-controller-manager/config/webhook/kustomization.yaml +++ b/app/sidero-controller-manager/config/webhook/kustomization.yaml @@ -1,4 +1,5 @@ resources: + - manifests.yaml - service.yaml configurations: diff --git a/app/sidero-controller-manager/config/webhook/manifests.yaml b/app/sidero-controller-manager/config/webhook/manifests.yaml new file mode 100644 index 000000000..763cf66d6 --- /dev/null +++ b/app/sidero-controller-manager/config/webhook/manifests.yaml @@ -0,0 +1,28 @@ +--- +apiVersion: admissionregistration.k8s.io/v1 +kind: ValidatingWebhookConfiguration +metadata: + creationTimestamp: null + name: validating-webhook-configuration +webhooks: +- admissionReviewVersions: + - v1 + clientConfig: + service: + name: webhook-service + namespace: system + path: /validate-metal-sidero-dev-v1alpha1-server + failurePolicy: Fail + name: vservers.metal.sidero.dev + rules: + - apiGroups: + - metal.sidero.dev + apiVersions: + - v1alpha1 + operations: + - CREATE + - UPDATE + - DELETE + resources: + - servers + sideEffects: None diff --git a/app/sidero-controller-manager/config/webhook/service.yaml b/app/sidero-controller-manager/config/webhook/service.yaml index ad5d8bab7..839dc6ebf 100644 --- a/app/sidero-controller-manager/config/webhook/service.yaml +++ b/app/sidero-controller-manager/config/webhook/service.yaml @@ -8,4 +8,4 @@ spec: - port: 443 targetPort: 9443 selector: - control-plane: caps-controller-manager + control-plane: sidero-controller-manager diff --git a/app/sidero-controller-manager/config/webhookcainjection_patch.yaml b/app/sidero-controller-manager/config/webhookcainjection_patch.yaml index 7e79bf995..668b41aa9 100644 --- a/app/sidero-controller-manager/config/webhookcainjection_patch.yaml +++ b/app/sidero-controller-manager/config/webhookcainjection_patch.yaml @@ -1,15 +1,7 @@ -# This patch add annotation to admission webhook config and -# the variables $(CERTIFICATE_NAMESPACE) and $(CERTIFICATE_NAME) will be substituted by kustomize. -apiVersion: admissionregistration.k8s.io/v1beta1 -kind: MutatingWebhookConfiguration -metadata: - name: mutating-webhook-configuration - annotations: - cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME) --- -apiVersion: admissionregistration.k8s.io/v1beta1 +apiVersion: admissionregistration.k8s.io/v1 kind: ValidatingWebhookConfiguration metadata: name: validating-webhook-configuration annotations: - cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME) + cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(SIDERO_CERTIFICATE_NAME) diff --git a/app/sidero-controller-manager/main.go b/app/sidero-controller-manager/main.go index 950ad064f..99258fd57 100644 --- a/app/sidero-controller-manager/main.go +++ b/app/sidero-controller-manager/main.go @@ -30,6 +30,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/manager" infrav1alpha3 "github.com/talos-systems/sidero/app/caps-controller-manager/api/v1alpha3" + "github.com/talos-systems/sidero/app/sidero-controller-manager/api/v1alpha1" metalv1alpha1 "github.com/talos-systems/sidero/app/sidero-controller-manager/api/v1alpha1" "github.com/talos-systems/sidero/app/sidero-controller-manager/controllers" "github.com/talos-systems/sidero/app/sidero-controller-manager/internal/ipxe" @@ -216,6 +217,7 @@ func main() { os.Exit(1) } + setupWebhooks(mgr) setupChecks(mgr, httpPort) // +kubebuilder:scaffold:builder @@ -326,6 +328,23 @@ func main() { } } +func setupWebhooks(mgr ctrl.Manager) { + if err := (&v1alpha1.ServerClass{}).SetupWebhookWithManager(mgr); err != nil { + setupLog.Error(err, "unable to create webhook", "webhook", "ServerClass") + os.Exit(1) + } + + if err := (&v1alpha1.Environment{}).SetupWebhookWithManager(mgr); err != nil { + setupLog.Error(err, "unable to create webhook", "webhook", "Environment") + os.Exit(1) + } + + if err := (&v1alpha1.Server{}).SetupWebhookWithManager(mgr); err != nil { + setupLog.Error(err, "unable to create webhook", "webhook", "Server") + os.Exit(1) + } +} + func setupChecks(mgr ctrl.Manager, httpPort int) { addr := fmt.Sprintf("127.0.0.1:%d", httpPort) diff --git a/sfyra/pkg/tests/server.go b/sfyra/pkg/tests/server.go index 43ee11949..e407f4760 100644 --- a/sfyra/pkg/tests/server.go +++ b/sfyra/pkg/tests/server.go @@ -31,6 +31,7 @@ import ( infrav1 "github.com/talos-systems/sidero/app/caps-controller-manager/api/v1alpha3" metalv1 "github.com/talos-systems/sidero/app/sidero-controller-manager/api/v1alpha1" + siderotypes "github.com/talos-systems/sidero/app/sidero-controller-manager/pkg/types" "github.com/talos-systems/sidero/sfyra/pkg/capi" "github.com/talos-systems/sidero/sfyra/pkg/constants" "github.com/talos-systems/sidero/sfyra/pkg/talos" @@ -117,6 +118,36 @@ func TestServerMgmtAPI(ctx context.Context, metalClient client.Client, vmSet *vm } } +// TestServerValidation checks that server validation webhook works. +func TestServerValidation(ctx context.Context, metalClient client.Client) TestFunc { + return func(t *testing.T) { + servers := &metalv1.ServerList{} + + require.NoError(t, metalClient.List(ctx, servers)) + + installPatch := configPatchToJSON(t, map[string]interface{}{"test": 1}) + + server := servers.Items[0] + + patchHelper, err := patch.NewHelper(&server, metalClient) + require.NoError(t, err) + + server.Spec.ConfigPatches = append(server.Spec.ConfigPatches, metalv1.ConfigPatches{ + Op: "error", + Path: "/machine/install", + Value: apiextensions.JSON{Raw: installPatch}, + }) + + require.ErrorContains(t, patchHelper.Patch(ctx, &server), "Invalid value: \"error\"") + + server.Spec.ConfigPatches = nil + + server.Spec.BootFromDiskMethod = siderotypes.BootFromDisk("explode") + + require.ErrorContains(t, patchHelper.Patch(ctx, &server), "Invalid value: \"explode\"") + } +} + // TestServerPatch patches all the servers for the config. func TestServerPatch(ctx context.Context, metalClient client.Client, registryMirrors []string) TestFunc { return func(t *testing.T) { diff --git a/sfyra/pkg/tests/tests.go b/sfyra/pkg/tests/tests.go index 98e6090ab..4157a9525 100644 --- a/sfyra/pkg/tests/tests.go +++ b/sfyra/pkg/tests/tests.go @@ -54,6 +54,10 @@ func Run(ctx context.Context, cluster talos.Cluster, vmSet *vm.Set, capiManager "TestServerPatch", TestServerPatch(ctx, metalClient, options.RegistryMirrors), }, + { + "TestServerValidation", + TestServerValidation(ctx, metalClient), + }, { "TestServerAcceptance", TestServerAcceptance(ctx, metalClient, vmSet),