diff --git a/PROJECT b/PROJECT index c14704e315..aef72ff836 100644 --- a/PROJECT +++ b/PROJECT @@ -39,4 +39,7 @@ resources: - group: infrastructure kind: VSphereFailureDomain version: v1alpha4 +- group: infrastructure + kind: VSphereClusterTemplate + version: v1alpha4 version: "2" diff --git a/api/v1alpha4/vspherecluster_webhook.go b/api/v1alpha4/vspherecluster_webhook.go index 27ec54ed74..2ac736665a 100644 --- a/api/v1alpha4/vspherecluster_webhook.go +++ b/api/v1alpha4/vspherecluster_webhook.go @@ -20,6 +20,7 @@ import ( "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/util/validation/field" ctrl "sigs.k8s.io/controller-runtime" + "sigs.k8s.io/controller-runtime/pkg/webhook" ) func (c *VSphereCluster) SetupWebhookWithManager(mgr ctrl.Manager) error { @@ -30,15 +31,14 @@ func (c *VSphereCluster) SetupWebhookWithManager(mgr ctrl.Manager) error { // +kubebuilder:webhook:verbs=create;update,path=/validate-infrastructure-cluster-x-k8s-io-v1alpha4-vspherecluster,mutating=false,failurePolicy=fail,matchPolicy=Equivalent,groups=infrastructure.cluster.x-k8s.io,resources=vsphereclusters,versions=v1alpha4,name=validation.vspherecluster.infrastructure.x-k8s.io,sideEffects=None,admissionReviewVersions=v1beta1 +var _ webhook.Validator = &VSphereCluster{} + // ValidateCreate implements webhook.Validator so a webhook will be registered for the type func (c *VSphereCluster) ValidateCreate() error { - var allErrs field.ErrorList - spec := c.Spec - - if spec.Thumbprint != "" && spec.Insecure != nil && *spec.Insecure { - allErrs = append(allErrs, field.Invalid(field.NewPath("spec", "Insecure"), spec.Insecure, "cannot be set to true at the same time as .spec.Thumbprint")) + allErrs := validateVSphereClusterSpec(c.Spec) + if len(allErrs) == 0 { + return nil } - return aggregateObjErrors(c.GroupVersionKind().GroupKind(), c.Name, allErrs) } @@ -51,3 +51,11 @@ func (c *VSphereCluster) ValidateUpdate(old runtime.Object) error { func (c *VSphereCluster) ValidateDelete() error { return nil } + +func validateVSphereClusterSpec(s VSphereClusterSpec) field.ErrorList { + var allErrs field.ErrorList + if s.Thumbprint != "" && s.Insecure != nil && *s.Insecure { + allErrs = append(allErrs, field.Invalid(field.NewPath("spec", "Insecure"), s.Insecure, "cannot be set to true at the same time as .spec.Thumbprint")) + } + return allErrs +} diff --git a/api/v1alpha4/vsphereclustertemplate_types.go b/api/v1alpha4/vsphereclustertemplate_types.go new file mode 100644 index 0000000000..6b290dbd33 --- /dev/null +++ b/api/v1alpha4/vsphereclustertemplate_types.go @@ -0,0 +1,55 @@ +/* +Copyright 2021 The Kubernetes Authors. + +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 v1alpha4 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// VSphereClusterTemplateSpec defines the desired state of VSphereClusterTemplate +type VSphereClusterTemplateSpec struct { + Template VSphereClusterTemplateResource `json:"template"` +} + +// +kubebuilder:object:root=true +// +kubebuilder:resource:path=vsphereclustertemplates,scope=Namespaced,categories=cluster-api +// +kubebuilder:storageversion + +// VSphereClusterTemplate is the Schema for the vsphereclustertemplates API +type VSphereClusterTemplate struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + Spec VSphereClusterTemplateSpec `json:"spec,omitempty"` +} + +// +kubebuilder:object:root=true + +// VSphereClusterTemplateList contains a list of VSphereClusterTemplate. +type VSphereClusterTemplateList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []VSphereClusterTemplate `json:"items"` +} + +func init() { + SchemeBuilder.Register(&VSphereClusterTemplate{}, &VSphereClusterTemplateList{}) +} + +type VSphereClusterTemplateResource struct { + Spec VSphereClusterSpec `json:"spec"` +} diff --git a/api/v1alpha4/vsphereclustertemplate_webhook.go b/api/v1alpha4/vsphereclustertemplate_webhook.go new file mode 100644 index 0000000000..9ffeccde7d --- /dev/null +++ b/api/v1alpha4/vsphereclustertemplate_webhook.go @@ -0,0 +1,59 @@ +/* +Copyright 2019 The Kubernetes Authors. + +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 v1alpha4 + +import ( + "reflect" + + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/util/validation/field" + ctrl "sigs.k8s.io/controller-runtime" + "sigs.k8s.io/controller-runtime/pkg/webhook" +) + +func (r *VSphereClusterTemplate) SetupWebhookWithManager(mgr ctrl.Manager) error { + return ctrl.NewWebhookManagedBy(mgr). + For(r). + Complete() +} + +// +kubebuilder:webhook:verbs=create;update,path=/validate-infrastructure-cluster-x-k8s-io-v1alpha4-vsphereclustertemplate,mutating=false,failurePolicy=fail,matchPolicy=Equivalent,groups=infrastructure.cluster.x-k8s.io,resources=vsphereclustertemplates,versions=v1alpha4,name=validation.vsphereclustertemplate.infrastructure.x-k8s.io,sideEffects=None,admissionReviewVersions=v1beta1 + +var _ webhook.Validator = &VSphereClusterTemplate{} + +// ValidateCreate implements webhook.Validator so a webhook will be registered for the type +func (r *VSphereClusterTemplate) ValidateCreate() error { + allErrs := validateVSphereClusterSpec(r.Spec.Template.Spec) + if len(allErrs) == 0 { + return nil + } + return aggregateObjErrors(r.GroupVersionKind().GroupKind(), r.Name, allErrs) +} + +// ValidateUpdate implements webhook.Validator so a webhook will be registered for the type +func (r *VSphereClusterTemplate) ValidateUpdate(oldRaw runtime.Object) error { + old := oldRaw.(*VSphereClusterTemplate) + if !reflect.DeepEqual(r.Spec.Template.Spec, old.Spec.Template.Spec) { + return field.Forbidden(field.NewPath("spec", "template", "spec"), "VSphereClusterTemplate spec is immutable") + } + return nil +} + +// ValidateDelete implements webhook.Validator so a webhook will be registered for the type +func (r *VSphereClusterTemplate) ValidateDelete() error { + return nil +} diff --git a/api/v1alpha4/zz_generated.deepcopy.go b/api/v1alpha4/zz_generated.deepcopy.go index 62471c4452..d2b0055c56 100644 --- a/api/v1alpha4/zz_generated.deepcopy.go +++ b/api/v1alpha4/zz_generated.deepcopy.go @@ -793,6 +793,96 @@ func (in *VSphereClusterStatus) DeepCopy() *VSphereClusterStatus { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *VSphereClusterTemplate) DeepCopyInto(out *VSphereClusterTemplate) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VSphereClusterTemplate. +func (in *VSphereClusterTemplate) DeepCopy() *VSphereClusterTemplate { + if in == nil { + return nil + } + out := new(VSphereClusterTemplate) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *VSphereClusterTemplate) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *VSphereClusterTemplateList) DeepCopyInto(out *VSphereClusterTemplateList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]VSphereClusterTemplate, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VSphereClusterTemplateList. +func (in *VSphereClusterTemplateList) DeepCopy() *VSphereClusterTemplateList { + if in == nil { + return nil + } + out := new(VSphereClusterTemplateList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *VSphereClusterTemplateList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *VSphereClusterTemplateResource) DeepCopyInto(out *VSphereClusterTemplateResource) { + *out = *in + in.Spec.DeepCopyInto(&out.Spec) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VSphereClusterTemplateResource. +func (in *VSphereClusterTemplateResource) DeepCopy() *VSphereClusterTemplateResource { + if in == nil { + return nil + } + out := new(VSphereClusterTemplateResource) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *VSphereClusterTemplateSpec) DeepCopyInto(out *VSphereClusterTemplateSpec) { + *out = *in + in.Template.DeepCopyInto(&out.Template) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VSphereClusterTemplateSpec. +func (in *VSphereClusterTemplateSpec) DeepCopy() *VSphereClusterTemplateSpec { + if in == nil { + return nil + } + out := new(VSphereClusterTemplateSpec) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *VSphereDeploymentZone) DeepCopyInto(out *VSphereDeploymentZone) { *out = *in diff --git a/config/crd/bases/infrastructure.cluster.x-k8s.io_vsphereclustertemplates.yaml b/config/crd/bases/infrastructure.cluster.x-k8s.io_vsphereclustertemplates.yaml new file mode 100644 index 0000000000..7fa803798a --- /dev/null +++ b/config/crd/bases/infrastructure.cluster.x-k8s.io_vsphereclustertemplates.yaml @@ -0,0 +1,351 @@ + +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.4.1-0.20201002000720-57250aac17f6 + creationTimestamp: null + name: vsphereclustertemplates.infrastructure.cluster.x-k8s.io +spec: + group: infrastructure.cluster.x-k8s.io + names: + categories: + - cluster-api + kind: VSphereClusterTemplate + listKind: VSphereClusterTemplateList + plural: vsphereclustertemplates + singular: vsphereclustertemplate + scope: Namespaced + versions: + - name: v1alpha4 + schema: + openAPIV3Schema: + description: VSphereClusterTemplate is the Schema for the vsphereclustertemplates + API + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: VSphereClusterTemplateSpec defines the desired state of VSphereClusterTemplate + properties: + template: + properties: + spec: + description: VSphereClusterSpec defines the desired state of VSphereCluster + properties: + cloudProviderConfiguration: + description: 'CloudProviderConfiguration holds the cluster-wide + configuration for the DEPRECATED: will be removed in v1alpha4 + vSphere cloud provider.' + properties: + disk: + description: Disk is the vSphere cloud provider's disk + configuration. + properties: + scsiControllerType: + description: SCSIControllerType defines SCSI controller + to be used. + type: string + type: object + global: + description: Global is the vSphere cloud provider's global + configuration. + properties: + apiBindPort: + description: APIBindPort configures the vSphere cloud + controller manager API port. Defaults to 43001. + type: string + apiDisable: + description: APIDisable disables the vSphere cloud + controller manager API. Defaults to true. + type: boolean + caFile: + description: CAFile Specifies the path to a CA certificate + in PEM format. If not configured, the system's CA + certificates will be used. + type: string + datacenters: + description: Datacenters is a CSV string of the datacenters + in which VMs are located. + type: string + insecure: + description: Insecure is a flag that disables TLS + peer verification. + type: boolean + password: + description: Password is the password used to access + a vSphere endpoint. + type: string + port: + description: Port is the port on which the vSphere + endpoint is listening. Defaults to 443. + type: string + roundTripperCount: + description: RoundTripperCount specifies the SOAP + round tripper count (retries = RoundTripper - 1) + format: int32 + type: integer + secretName: + description: SecretName is the name of the Kubernetes + secret in which the vSphere credentials are located. + type: string + secretNamespace: + description: SecretNamespace is the namespace for + SecretName. + type: string + secretsDirectory: + description: 'SecretsDirectory is a directory in which + secrets may be found. This may used in the event + that: 1. It is not desirable to use the K8s API + to watch changes to secrets 2. The cloud controller + manager is not running in a K8s environment, such + as DC/OS. For example, the container storage interface + (CSI) is container orcehstrator (CO) agnostic, + and should support non-K8s COs. Defaults to /etc/cloud/credentials.' + type: string + serviceAccount: + description: ServiceAccount is the Kubernetes service + account used to launch the cloud controller manager. + Defaults to cloud-controller-manager. + type: string + thumbprint: + description: Thumbprint is the cryptographic thumbprint + of the vSphere endpoint's certificate. + type: string + username: + description: Username is the username used to access + a vSphere endpoint. + type: string + type: object + labels: + description: Labels is the vSphere cloud provider's zone + and region configuration. + properties: + region: + description: Region is the region in which VMs are + created/located. + type: string + zone: + description: Zone is the zone in which VMs are created/located. + type: string + type: object + network: + description: Network is the vSphere cloud provider's network + configuration. + properties: + name: + description: Name is the name of the network to which + VMs are connected. + type: string + type: object + providerConfig: + description: CPIProviderConfig contains extra information + used to configure the vSphere cloud provider. + properties: + cloud: + properties: + controllerImage: + type: string + extraArgs: + additionalProperties: + type: string + description: ExtraArgs passes through extra arguments + to the cloud provider. The arguments here are + passed to the cloud provider daemonset specification + type: object + type: object + storage: + properties: + attacherImage: + type: string + controllerImage: + type: string + livenessProbeImage: + type: string + metadataSyncerImage: + type: string + nodeDriverImage: + type: string + provisionerImage: + type: string + registrarImage: + type: string + type: object + type: object + virtualCenter: + additionalProperties: + description: CPIVCenterConfig is a vSphere cloud provider's + vCenter configuration. + properties: + datacenters: + description: Datacenters is a CSV string of the + datacenters in which VMs are located. + type: string + password: + description: Password is the password used to access + a vSphere endpoint. + type: string + port: + description: Port is the port on which the vSphere + endpoint is listening. Defaults to 443. + type: string + roundTripperCount: + description: RoundTripperCount specifies the SOAP + round tripper count (retries = RoundTripper - + 1) + format: int32 + type: integer + thumbprint: + description: Thumbprint is the cryptographic thumbprint + of the vSphere endpoint's certificate. + type: string + username: + description: Username is the username used to access + a vSphere endpoint. + type: string + type: object + description: VCenter is a list of vCenter configurations. + type: object + workspace: + description: Workspace is the vSphere cloud provider's + workspace configuration. + properties: + datacenter: + description: Datacenter is the datacenter in which + VMs are created/located. + type: string + datastore: + description: Datastore is the datastore in which VMs + are created/located. + type: string + folder: + description: Folder is the folder in which VMs are + created/located. + type: string + resourcePool: + description: ResourcePool is the resource pool in + which VMs are created/located. + type: string + server: + description: Server is the IP address or FQDN of the + vSphere endpoint. + type: string + type: object + type: object + controlPlaneEndpoint: + description: ControlPlaneEndpoint represents the endpoint + used to communicate with the control plane. + properties: + host: + description: The hostname on which the API server is serving. + type: string + port: + description: The port on which the API server is serving. + format: int32 + type: integer + required: + - host + - port + type: object + identityRef: + description: IdentityRef is a reference to either a Secret + or VSphereClusterIdentity that contains the identity to + use when reconciling the cluster. + properties: + kind: + description: Kind of the identity. Can either be VSphereClusterIdentity + or Secret + enum: + - VSphereClusterIdentity + - Secret + type: string + name: + description: Name of the identity. + minLength: 1 + type: string + required: + - kind + - name + type: object + insecure: + description: 'Insecure is a flag that controls whether or + not to validate the vSphere server''s certificate. DEPRECATED: + will be removed in v1alpha4' + type: boolean + loadBalancerRef: + description: 'LoadBalancerRef may be used to enable a control + plane load balancer for this cluster. When a LoadBalancerRef + is provided, the VSphereCluster.Status.Ready field will + not be true until the referenced resource is Status.Ready + and has a non-empty Status.Address value. DEPRECATED: will + be removed in v1alpha4' + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: 'If referring to a piece of an object instead + of an entire object, this string should contain a valid + JSON/Go field access statement, such as desiredState.manifest.containers[2]. + For example, if the object reference is to a container + within a pod, this would take on a value like: "spec.containers{name}" + (where "name" refers to the name of the container that + triggered the event) or if no container name is specified + "spec.containers[2]" (container with index 2 in this + pod). This syntax is chosen only to have some well-defined + way of referencing a part of an object. TODO: this design + is not final and this field is subject to change in + the future.' + type: string + kind: + description: 'Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + namespace: + description: 'Namespace of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/' + type: string + resourceVersion: + description: 'Specific resourceVersion to which this reference + is made, if any. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency' + type: string + uid: + description: 'UID of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids' + type: string + type: object + server: + description: Server is the address of the vSphere endpoint. + type: string + thumbprint: + description: Thumbprint is the colon-separated SHA-1 checksum + of the given vCenter server's host certificate When provided, + Insecure should not be set to true + type: string + type: object + required: + - spec + type: object + required: + - template + type: object + type: object + served: true + storage: true +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/config/crd/kustomization.yaml b/config/crd/kustomization.yaml index 5d491ae5ad..792c27065a 100644 --- a/config/crd/kustomization.yaml +++ b/config/crd/kustomization.yaml @@ -15,6 +15,7 @@ resources: - bases/infrastructure.cluster.x-k8s.io_vspherefailuredomains.yaml - bases/infrastructure.cluster.x-k8s.io_vspheredeploymentzones.yaml - bases/infrastructure.cluster.x-k8s.io_vsphereclusteridentities.yaml +- bases/infrastructure.cluster.x-k8s.io_vsphereclustertemplates.yaml # +kubebuilder:scaffold:crdkustomizeresource patches: @@ -25,9 +26,10 @@ patches: - patches/webhook_in_vspheremachinetemplates.yaml - patches/webhook_in_vspherevms.yaml - patches/webhook_in_haproxyloadbalancers.yaml +- patches/webhook_in_vsphereclustertemplates.yaml #- patches/webhook_in_vspherefailuredomains.yaml #- patches/webhook_in_vspheredeploymentzones.yaml - # +kubebuilder:scaffold:crdkustomizewebhookpatch +# +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 @@ -36,6 +38,7 @@ patches: - patches/cainjection_in_vspheremachinetemplates.yaml - patches/cainjection_in_vspherevms.yaml - patches/cainjection_in_haproxyloadbalancers.yaml +- patches/cainjection_in_vsphereclustertemplates.yaml #- patches/cainjection_in_vspherefailuredomains.yaml #- patches/cainjection_in_vspheredeploymentzones.yaml # +kubebuilder:scaffold:crdkustomizecainjectionpatch diff --git a/config/crd/patches/cainjection_in_vsphereclustertemplates.yaml b/config/crd/patches/cainjection_in_vsphereclustertemplates.yaml new file mode 100644 index 0000000000..566225bcbe --- /dev/null +++ b/config/crd/patches/cainjection_in_vsphereclustertemplates.yaml @@ -0,0 +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/v1 +kind: CustomResourceDefinition +metadata: + annotations: + cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME) + name: vsphereclustertemplates.infrastructure.cluster.x-k8s.io diff --git a/config/crd/patches/webhook_in_vsphereclustertemplates.yaml b/config/crd/patches/webhook_in_vsphereclustertemplates.yaml new file mode 100644 index 0000000000..2295b77538 --- /dev/null +++ b/config/crd/patches/webhook_in_vsphereclustertemplates.yaml @@ -0,0 +1,19 @@ +# The following patch enables conversion webhook for CRD +# CRD conversion requires k8s 1.13 or later. +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: vsphereclustertemplates.infrastructure.cluster.x-k8s.io +spec: + conversion: + strategy: Webhook + 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/config/default/webhookcainjection_patch.yaml b/config/default/webhookcainjection_patch.yaml index f1b5d0ad1c..ab69fe9496 100644 --- a/config/default/webhookcainjection_patch.yaml +++ b/config/default/webhookcainjection_patch.yaml @@ -6,3 +6,10 @@ metadata: name: validating-webhook-configuration annotations: cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME) +--- +apiVersion: admissionregistration.k8s.io/v1 +kind: MutatingWebhookConfiguration +metadata: + name: mutating-webhook-configuration + annotations: + cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME) diff --git a/config/webhook/manifests.yaml b/config/webhook/manifests.yaml index 32f5872df0..65bfdd3676 100644 --- a/config/webhook/manifests.yaml +++ b/config/webhook/manifests.yaml @@ -28,6 +28,28 @@ webhooks: resources: - vsphereclusters sideEffects: None +- admissionReviewVersions: + - v1beta1 + clientConfig: + caBundle: Cg== + service: + name: webhook-service + namespace: system + path: /validate-infrastructure-cluster-x-k8s-io-v1alpha4-vsphereclustertemplate + failurePolicy: Fail + matchPolicy: Equivalent + name: validation.vsphereclustertemplate.infrastructure.x-k8s.io + rules: + - apiGroups: + - infrastructure.cluster.x-k8s.io + apiVersions: + - v1alpha4 + operations: + - CREATE + - UPDATE + resources: + - vsphereclustertemplates + sideEffects: None - admissionReviewVersions: - v1beta1 clientConfig: diff --git a/main.go b/main.go index 41b0f09ce9..c8eacfbf2d 100644 --- a/main.go +++ b/main.go @@ -150,6 +150,9 @@ func main() { if err := (&v1alpha4.VSphereCluster{}).SetupWebhookWithManager(mgr); err != nil { return err } + if err := (&v1alpha4.VSphereClusterTemplate{}).SetupWebhookWithManager(mgr); err != nil { + return err + } if err := (&v1alpha4.VSphereClusterList{}).SetupWebhookWithManager(mgr); err != nil { return err }