From 2c26bbfc7f5c8205b81524b2ddb27b229cd63411 Mon Sep 17 00:00:00 2001 From: Tobias Giese Date: Fri, 9 Jul 2021 22:33:12 +0200 Subject: [PATCH] Add OpenStackClusterTemplates Type Signed-off-by: Tobias Giese --- PROJECT | 3 + api/v1alpha4/openstackcluster_webhook.go | 4 +- .../openstackclustertemplate_types.go | 55 ++ .../openstackclustertemplate_webhook.go | 79 +++ .../openstackmachinetemplate_webhook.go | 2 +- api/v1alpha4/zz_generated.deepcopy.go | 90 +++ ...er.x-k8s.io_openstackclustertemplates.yaml | 646 ++++++++++++++++++ config/crd/kustomization.yaml | 3 + ...njection_in_openstackclustertemplates.yaml | 8 + .../webhook_in_openstackclustertemplates.yaml | 17 + config/webhook/manifests.yaml | 48 +- main.go | 4 + 12 files changed, 953 insertions(+), 6 deletions(-) create mode 100644 api/v1alpha4/openstackclustertemplate_types.go create mode 100644 api/v1alpha4/openstackclustertemplate_webhook.go create mode 100644 config/crd/bases/infrastructure.cluster.x-k8s.io_openstackclustertemplates.yaml create mode 100644 config/crd/patches/cainjection_in_openstackclustertemplates.yaml create mode 100644 config/crd/patches/webhook_in_openstackclustertemplates.yaml diff --git a/PROJECT b/PROJECT index 61f6a2ed36..c34721b61a 100644 --- a/PROJECT +++ b/PROJECT @@ -20,3 +20,6 @@ resources: - group: infrastructure version: v1alpha4 kind: OpenStackMachineTemplate +- group: infrastructure + kind: OpenStackClusterTemplate + version: v1alpha4 diff --git a/api/v1alpha4/openstackcluster_webhook.go b/api/v1alpha4/openstackcluster_webhook.go index 6c7a346951..603fe3538c 100644 --- a/api/v1alpha4/openstackcluster_webhook.go +++ b/api/v1alpha4/openstackcluster_webhook.go @@ -34,8 +34,8 @@ func (r *OpenStackCluster) SetupWebhookWithManager(mgr manager.Manager) error { Complete() } -// +kubebuilder:webhook:verbs=create;update,path=/validate-infrastructure-cluster-x-k8s-io-v1alpha4-openstackcluster,mutating=false,failurePolicy=fail,matchPolicy=Equivalent,groups=infrastructure.cluster.x-k8s.io,resources=openstackcluster,versions=v1alpha4,name=validation.openstackcluster.infrastructure.x-k8s.io,sideEffects=None,admissionReviewVersions=v1beta1 -// +kubebuilder:webhook:verbs=create;update,path=/mutate-infrastructure-cluster-x-k8s-io-v1alpha4-openstackcluster,mutating=true,failurePolicy=fail,matchPolicy=Equivalent,groups=infrastructure.cluster.x-k8s.io,resources=openstackcluster,versions=v1alpha4,name=default.openstackcluster.infrastructure.x-k8s.io,sideEffects=None,admissionReviewVersions=v1beta1 +// +kubebuilder:webhook:verbs=create;update,path=/validate-infrastructure-cluster-x-k8s-io-v1alpha4-openstackcluster,mutating=false,failurePolicy=fail,matchPolicy=Equivalent,groups=infrastructure.cluster.x-k8s.io,resources=openstackcluster,versions=v1alpha4,name=validation.openstackcluster.infrastructure.cluster.x-k8s.io,sideEffects=None,admissionReviewVersions=v1beta1 +// +kubebuilder:webhook:verbs=create;update,path=/mutate-infrastructure-cluster-x-k8s-io-v1alpha4-openstackcluster,mutating=true,failurePolicy=fail,matchPolicy=Equivalent,groups=infrastructure.cluster.x-k8s.io,resources=openstackcluster,versions=v1alpha4,name=default.openstackcluster.infrastructure.cluster.x-k8s.io,sideEffects=None,admissionReviewVersions=v1beta1 var ( _ webhook.Defaulter = &OpenStackCluster{} diff --git a/api/v1alpha4/openstackclustertemplate_types.go b/api/v1alpha4/openstackclustertemplate_types.go new file mode 100644 index 0000000000..413bef0966 --- /dev/null +++ b/api/v1alpha4/openstackclustertemplate_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" +) + +// OpenStackClusterTemplateResource describes the data needed to create a OpenStackCluster from a template. +type OpenStackClusterTemplateResource struct { + Spec OpenStackClusterSpec `json:"spec"` +} + +// OpenStackClusterTemplateSpec defines the desired state of OpenStackClusterTemplate. +type OpenStackClusterTemplateSpec struct { + Template OpenStackClusterTemplateResource `json:"template"` +} + +//+kubebuilder:object:root=true +//+kubebuilder:resource:path=openstackclustertemplates,scope=Namespaced,categories=cluster-api,shortName=osct + +// OpenStackClusterTemplate is the Schema for the openstackclustertemplates API. +type OpenStackClusterTemplate struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + Spec OpenStackClusterTemplateSpec `json:"spec,omitempty"` +} + +//+kubebuilder:object:root=true + +// OpenStackClusterTemplateList contains a list of OpenStackClusterTemplate. +type OpenStackClusterTemplateList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []OpenStackClusterTemplate `json:"items"` +} + +func init() { + SchemeBuilder.Register(&OpenStackClusterTemplate{}, &OpenStackClusterTemplateList{}) +} diff --git a/api/v1alpha4/openstackclustertemplate_webhook.go b/api/v1alpha4/openstackclustertemplate_webhook.go new file mode 100644 index 0000000000..db64ff8e99 --- /dev/null +++ b/api/v1alpha4/openstackclustertemplate_webhook.go @@ -0,0 +1,79 @@ +/* +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 ( + "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" +) + +const openStackClusterTemplateImmutableMsg = "OpenStackClusterTemplate spec.template.spec field is immutable. Please create new resource instead." + +func (r *OpenStackClusterTemplate) SetupWebhookWithManager(mgr ctrl.Manager) error { + return ctrl.NewWebhookManagedBy(mgr). + For(r). + Complete() +} + +// +kubebuilder:webhook:verbs=create;update,path=/mutate-infrastructure-cluster-x-k8s-io-v1alpha4-openstackclustertemplate,mutating=true,failurePolicy=fail,matchPolicy=Equivalent,groups=infrastructure.cluster.x-k8s.io,resources=openstackclustertemplates,versions=v1alpha4,name=default.openstackclustertemplate.infrastructure.cluster.x-k8s.io,sideEffects=None,admissionReviewVersions=v1beta1 +// +kubebuilder:webhook:verbs=create;update,path=/validate-infrastructure-cluster-x-k8s-io-v1alpha4-openstackclustertemplate,mutating=false,failurePolicy=fail,matchPolicy=Equivalent,groups=infrastructure.cluster.x-k8s.io,resources=openstackclustertemplates,versions=v1alpha4,name=validation.openstackclustertemplate.infrastructure.cluster.x-k8s.io,sideEffects=None,admissionReviewVersions=v1beta1 + +var ( + _ webhook.Defaulter = &OpenStackClusterTemplate{} + _ webhook.Validator = &OpenStackClusterTemplate{} +) + +// Default implements webhook.Defaulter so a webhook will be registered for the type. +func (r *OpenStackClusterTemplate) Default() { + if r.Spec.Template.Spec.IdentityRef != nil && r.Spec.Template.Spec.IdentityRef.Kind == "" { + r.Spec.Template.Spec.IdentityRef.Kind = defaultIdentityRefKind + } +} + +// ValidateCreate implements webhook.Validator so a webhook will be registered for the type. +func (r *OpenStackClusterTemplate) ValidateCreate() error { + var allErrs field.ErrorList + + if r.Spec.Template.Spec.IdentityRef != nil && r.Spec.Template.Spec.IdentityRef.Kind != defaultIdentityRefKind { + allErrs = append(allErrs, field.Forbidden(field.NewPath("spec", "template", "spec", "identityRef", "kind"), "must be a Secret")) + } + + return aggregateObjErrors(r.GroupVersionKind().GroupKind(), r.Name, allErrs) +} + +// ValidateUpdate implements webhook.Validator so a webhook will be registered for the type. +func (r *OpenStackClusterTemplate) ValidateUpdate(oldRaw runtime.Object) error { + var allErrs field.ErrorList + + old := oldRaw.(*OpenStackClusterTemplate) + if !reflect.DeepEqual(r.Spec.Template.Spec, old.Spec.Template.Spec) { + allErrs = append(allErrs, + field.Invalid(field.NewPath("OpenStackClusterTemplate", "spec", "template", "spec"), r, openStackClusterTemplateImmutableMsg), + ) + } + + return aggregateObjErrors(r.GroupVersionKind().GroupKind(), r.Name, allErrs) +} + +// ValidateDelete implements webhook.Validator so a webhook will be registered for the type. +func (r *OpenStackClusterTemplate) ValidateDelete() error { + return nil +} diff --git a/api/v1alpha4/openstackmachinetemplate_webhook.go b/api/v1alpha4/openstackmachinetemplate_webhook.go index 06df4c7304..dc802c51a7 100644 --- a/api/v1alpha4/openstackmachinetemplate_webhook.go +++ b/api/v1alpha4/openstackmachinetemplate_webhook.go @@ -35,7 +35,7 @@ func (r *OpenStackMachineTemplate) SetupWebhookWithManager(mgr manager.Manager) Complete() } -// +kubebuilder:webhook:verbs=create;update,path=/validate-infrastructure-cluster-x-k8s-io-v1alpha4-openstackmachinetemplate,mutating=false,failurePolicy=fail,matchPolicy=Equivalent,groups=infrastructure.cluster.x-k8s.io,resources=openstackmachinetemplates,versions=v1alpha4,name=validation.openstackmachinetemplate.infrastructure.x-k8s.io,sideEffects=None,admissionReviewVersions=v1beta1 +// +kubebuilder:webhook:verbs=create;update,path=/validate-infrastructure-cluster-x-k8s-io-v1alpha4-openstackmachinetemplate,mutating=false,failurePolicy=fail,matchPolicy=Equivalent,groups=infrastructure.cluster.x-k8s.io,resources=openstackmachinetemplates,versions=v1alpha4,name=validation.openstackmachinetemplate.infrastructure.cluster.x-k8s.io,sideEffects=None,admissionReviewVersions=v1beta1 var _ webhook.Validator = &OpenStackMachineTemplate{} diff --git a/api/v1alpha4/zz_generated.deepcopy.go b/api/v1alpha4/zz_generated.deepcopy.go index 0818c40f27..7bed4b2273 100644 --- a/api/v1alpha4/zz_generated.deepcopy.go +++ b/api/v1alpha4/zz_generated.deepcopy.go @@ -425,6 +425,96 @@ func (in *OpenStackClusterStatus) DeepCopy() *OpenStackClusterStatus { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *OpenStackClusterTemplate) DeepCopyInto(out *OpenStackClusterTemplate) { + *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 OpenStackClusterTemplate. +func (in *OpenStackClusterTemplate) DeepCopy() *OpenStackClusterTemplate { + if in == nil { + return nil + } + out := new(OpenStackClusterTemplate) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *OpenStackClusterTemplate) 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 *OpenStackClusterTemplateList) DeepCopyInto(out *OpenStackClusterTemplateList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]OpenStackClusterTemplate, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OpenStackClusterTemplateList. +func (in *OpenStackClusterTemplateList) DeepCopy() *OpenStackClusterTemplateList { + if in == nil { + return nil + } + out := new(OpenStackClusterTemplateList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *OpenStackClusterTemplateList) 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 *OpenStackClusterTemplateResource) DeepCopyInto(out *OpenStackClusterTemplateResource) { + *out = *in + in.Spec.DeepCopyInto(&out.Spec) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OpenStackClusterTemplateResource. +func (in *OpenStackClusterTemplateResource) DeepCopy() *OpenStackClusterTemplateResource { + if in == nil { + return nil + } + out := new(OpenStackClusterTemplateResource) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *OpenStackClusterTemplateSpec) DeepCopyInto(out *OpenStackClusterTemplateSpec) { + *out = *in + in.Template.DeepCopyInto(&out.Template) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OpenStackClusterTemplateSpec. +func (in *OpenStackClusterTemplateSpec) DeepCopy() *OpenStackClusterTemplateSpec { + if in == nil { + return nil + } + out := new(OpenStackClusterTemplateSpec) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *OpenStackIdentityReference) DeepCopyInto(out *OpenStackIdentityReference) { *out = *in diff --git a/config/crd/bases/infrastructure.cluster.x-k8s.io_openstackclustertemplates.yaml b/config/crd/bases/infrastructure.cluster.x-k8s.io_openstackclustertemplates.yaml new file mode 100644 index 0000000000..6a40d5c2c3 --- /dev/null +++ b/config/crd/bases/infrastructure.cluster.x-k8s.io_openstackclustertemplates.yaml @@ -0,0 +1,646 @@ + +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.5.0 + creationTimestamp: null + name: openstackclustertemplates.infrastructure.cluster.x-k8s.io +spec: + group: infrastructure.cluster.x-k8s.io + names: + categories: + - cluster-api + kind: OpenStackClusterTemplate + listKind: OpenStackClusterTemplateList + plural: openstackclustertemplates + shortNames: + - osct + singular: openstackclustertemplate + scope: Namespaced + versions: + - name: v1alpha4 + schema: + openAPIV3Schema: + description: OpenStackClusterTemplate is the Schema for the openstackclustertemplates + 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: OpenStackClusterTemplateSpec defines the desired state of + OpenStackClusterTemplate. + properties: + template: + description: OpenStackClusterTemplateResource describes the data needed + to create a OpenStackCluster from a template. + properties: + spec: + description: OpenStackClusterSpec defines the desired state of + OpenStackCluster. + properties: + apiServerFloatingIP: + description: APIServerFloatingIP is the floatingIP which will + be associated to the APIServer. The floatingIP will be created + if it not already exists. + type: string + apiServerLoadBalancerAdditionalPorts: + description: APIServerLoadBalancerAdditionalPorts adds additional + ports to the APIServerLoadBalancer + items: + type: integer + type: array + apiServerPort: + description: APIServerPort is the port on which the listener + on the APIServer will be created + type: integer + bastion: + description: Bastion is the OpenStack instance to login the + nodes + properties: + availabilityZone: + type: string + enabled: + type: boolean + instance: + description: Instance for the bastion itself + properties: + cloudName: + description: The name of the cloud to use from the + clouds secret + type: string + configDrive: + description: Config Drive support + type: boolean + flavor: + description: The flavor reference for the flavor for + your server instance. + type: string + floatingIP: + description: The floatingIP which will be associated + to the machine, only used for master. The floatingIP + should have been created and haven't been associated. + type: string + identityRef: + description: IdentityRef is a reference to a identity + to be used when reconciling this cluster + properties: + kind: + description: Kind of the identity. Must be supported + by the infrastructure provider and may be either + cluster or namespace-scoped. + minLength: 1 + type: string + name: + description: Name of the infrastructure identity + to be used. Must be either a cluster-scoped + resource, or namespaced-scoped resource the + same namespace as the resource(s) being provisioned. + type: string + required: + - kind + - name + type: object + image: + description: The name of the image to use for your + server instance. If the RootVolume is specified, + this will be ignored and use rootVolume directly. + type: string + instanceID: + description: InstanceID is the OpenStack instance + ID for this machine. + type: string + networks: + description: A networks object. Required parameter + when there are multiple networks defined for the + tenant. When you do not specify both networks and + ports parameters, the server attaches to the only + network created for the current tenant. + items: + properties: + filter: + description: Filters for optional network query + properties: + adminStateUp: + type: boolean + description: + type: string + id: + type: string + limit: + type: integer + marker: + type: string + name: + type: string + notTags: + type: string + notTagsAny: + type: string + projectId: + type: string + shared: + type: boolean + sortDir: + type: string + sortKey: + type: string + status: + type: string + tags: + type: string + tagsAny: + type: string + tenantId: + type: string + type: object + fixedIP: + description: A fixed IPv4 address for the NIC. + type: string + subnets: + description: Subnet within a network to use + items: + properties: + filter: + description: Filters for optional network + query + properties: + cidr: + type: string + description: + type: string + enableDhcp: + type: boolean + gateway_ip: + type: string + id: + type: string + ipVersion: + type: integer + ipv6AddressMode: + type: string + ipv6RaMode: + type: string + limit: + type: integer + marker: + type: string + name: + type: string + networkId: + type: string + notTags: + type: string + notTagsAny: + type: string + projectId: + type: string + sortDir: + type: string + sortKey: + type: string + subnetpoolId: + type: string + tags: + type: string + tagsAny: + type: string + tenantId: + type: string + type: object + uuid: + description: The UUID of the network. + Required if you omit the port attribute. + type: string + type: object + type: array + uuid: + description: The UUID of the network. Required + if you omit the port attribute. + type: string + type: object + type: array + ports: + description: Ports to be attached to the server instance. + They are created if a port with the given name does + not already exist. When you do not specify both + networks and ports parameters, the server attaches + to the only network created for the current tenant. + items: + properties: + adminStateUp: + type: boolean + allowedAddressPairs: + items: + properties: + ipAddress: + type: string + macAddress: + type: string + type: object + type: array + description: + type: string + fixedIPs: + description: Specify pairs of subnet and/or + IP address. These should be subnets of the + network with the given NetworkID. + items: + properties: + ipAddress: + type: string + subnetId: + type: string + required: + - subnetId + type: object + type: array + hostId: + description: The ID of the host where the port + is allocated + type: string + macAddress: + type: string + nameSuffix: + description: Used to make the name of the port + unique. If unspecified, instead the 0-based + index of the port in the list is used. + type: string + networkId: + description: ID of the OpenStack network on + which to create the port. If unspecified, + create the port on the default cluster network. + type: string + projectId: + type: string + securityGroups: + items: + type: string + type: array + tenantId: + type: string + vnicType: + description: The virtual network interface card + (vNIC) type that is bound to the neutron port. + type: string + type: object + type: array + providerID: + description: ProviderID is the unique identifier as + specified by the cloud provider. + type: string + rootVolume: + description: The volume metadata to boot from + properties: + deviceType: + type: string + diskSize: + type: integer + sourceType: + type: string + sourceUUID: + type: string + type: object + securityGroups: + description: The names of the security groups to assign + to the instance + items: + properties: + filter: + description: Filters used to query security + groups in openstack + properties: + description: + type: string + id: + type: string + limit: + type: integer + marker: + type: string + name: + type: string + notTags: + type: string + notTagsAny: + type: string + projectId: + type: string + sortDir: + type: string + sortKey: + type: string + tags: + type: string + tagsAny: + type: string + tenantId: + type: string + type: object + name: + description: Security Group name + type: string + uuid: + description: Security Group UID + type: string + type: object + type: array + serverGroupID: + description: The server group to assign the machine + to + type: string + serverMetadata: + additionalProperties: + type: string + description: Metadata mapping. Allows you to create + a map of key value pairs to add to the server instance. + type: object + sshKeyName: + description: The ssh key to inject in the instance + type: string + subnet: + description: UUID, IP address of a port from this + subnet will be marked as AccessIPv4 on the created + compute instance + type: string + tags: + description: Machine tags Requires Nova api 2.52 minimum! + items: + type: string + type: array + trunk: + description: Whether the server instance is created + on a trunk port or not. + type: boolean + required: + - flavor + type: object + type: object + cloudName: + description: The name of the cloud to use from the clouds + secret + type: string + controlPlaneAvailabilityZones: + description: ControlPlaneAvailabilityZones is the az to deploy + control plane to + items: + type: string + type: array + 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 + disablePortSecurity: + description: DisablePortSecurity disables the port security + of the network created for the Kubernetes cluster, which + also disables SecurityGroups + type: boolean + dnsNameservers: + description: DNSNameservers is the list of nameservers for + OpenStack Subnet being created. Set this value when you + need create a new network/subnet while the access through + DNS is required. + items: + type: string + type: array + externalNetworkId: + description: ExternalNetworkID is the ID of an external OpenStack + Network. This is necessary to get public internet to the + VMs. + type: string + externalRouterIPs: + description: ExternalRouterIPs is an array of externalIPs + on the respective subnets. This is necessary if the router + needs a fixed ip in a specific subnet. + items: + properties: + fixedIP: + description: The FixedIP in the corresponding subnet + type: string + subnet: + description: The subnet in which the FixedIP is used + for the Gateway of this router + properties: + filter: + description: Filters for optional network query + properties: + cidr: + type: string + description: + type: string + enableDhcp: + type: boolean + gateway_ip: + type: string + id: + type: string + ipVersion: + type: integer + ipv6AddressMode: + type: string + ipv6RaMode: + type: string + limit: + type: integer + marker: + type: string + name: + type: string + networkId: + type: string + notTags: + type: string + notTagsAny: + type: string + projectId: + type: string + sortDir: + type: string + sortKey: + type: string + subnetpoolId: + type: string + tags: + type: string + tagsAny: + type: string + tenantId: + type: string + type: object + uuid: + description: The UUID of the network. Required if + you omit the port attribute. + type: string + type: object + required: + - subnet + type: object + type: array + identityRef: + description: IdentityRef is a reference to a identity to be + used when reconciling this cluster + properties: + kind: + description: Kind of the identity. Must be supported by + the infrastructure provider and may be either cluster + or namespace-scoped. + minLength: 1 + type: string + name: + description: Name of the infrastructure identity to be + used. Must be either a cluster-scoped resource, or namespaced-scoped + resource the same namespace as the resource(s) being + provisioned. + type: string + required: + - kind + - name + type: object + managedAPIServerLoadBalancer: + description: 'ManagedAPIServerLoadBalancer defines whether + a LoadBalancer for the APIServer should be created. If set + to true the following properties are mandatory: APIServerFloatingIP, + APIServerPort' + type: boolean + managedSecurityGroups: + description: 'ManagedSecurityGroups defines that kubernetes + manages the OpenStack security groups for now, that means + that we''ll create security group allows traffic to/from + machines belonging to that group based on Calico CNI plugin + default network requirements: BGP and IP-in-IP for master + node(s) and worker node(s) respectively. In the future, + we could make this more flexible.' + type: boolean + network: + description: If NodeCIDR cannot be set this can be used to + detect an existing network. + properties: + adminStateUp: + type: boolean + description: + type: string + id: + type: string + limit: + type: integer + marker: + type: string + name: + type: string + notTags: + type: string + notTagsAny: + type: string + projectId: + type: string + shared: + type: boolean + sortDir: + type: string + sortKey: + type: string + status: + type: string + tags: + type: string + tagsAny: + type: string + tenantId: + type: string + type: object + nodeCidr: + description: NodeCIDR is the OpenStack Subnet to be created. + Cluster actuator will create a network, a subnet with NodeCIDR, + and a router connected to this subnet. If you leave this + empty, no network will be created. + type: string + subnet: + description: If NodeCIDR cannot be set this can be used to + detect an existing subnet. + properties: + cidr: + type: string + description: + type: string + enableDhcp: + type: boolean + gateway_ip: + type: string + id: + type: string + ipVersion: + type: integer + ipv6AddressMode: + type: string + ipv6RaMode: + type: string + limit: + type: integer + marker: + type: string + name: + type: string + networkId: + type: string + notTags: + type: string + notTagsAny: + type: string + projectId: + type: string + sortDir: + type: string + sortKey: + type: string + subnetpoolId: + type: string + tags: + type: string + tagsAny: + type: string + tenantId: + type: string + type: object + tags: + description: Tags for all resources in cluster + items: + type: string + type: array + 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 500f16acec..166684971a 100644 --- a/config/crd/kustomization.yaml +++ b/config/crd/kustomization.yaml @@ -9,6 +9,7 @@ resources: - bases/infrastructure.cluster.x-k8s.io_openstackclusters.yaml - bases/infrastructure.cluster.x-k8s.io_openstackmachines.yaml - bases/infrastructure.cluster.x-k8s.io_openstackmachinetemplates.yaml +- bases/infrastructure.cluster.x-k8s.io_openstackclustertemplates.yaml # +kubebuilder:scaffold:crdkustomizeresource patchesStrategicMerge: @@ -17,6 +18,7 @@ patchesStrategicMerge: - patches/webhook_in_openstackclusters.yaml - patches/webhook_in_openstackmachines.yaml - patches/webhook_in_openstackmachinetemplates.yaml +- patches/webhook_in_openstackclustertemplates.yaml # +kubebuilder:scaffold:crdkustomizewebhookpatch # [CERTMANAGER] To enable webhook, uncomment all the sections with [CERTMANAGER] prefix. @@ -24,6 +26,7 @@ patchesStrategicMerge: - patches/cainjection_in_openstackclusters.yaml - patches/cainjection_in_openstackmachines.yaml - patches/cainjection_in_openstackmachinetemplates.yaml +- patches/cainjection_in_openstackclustertemplates.yaml # +kubebuilder:scaffold:crdkustomizecainjectionpatch # the following config is for teaching kustomize how to do kustomization for CRDs. diff --git a/config/crd/patches/cainjection_in_openstackclustertemplates.yaml b/config/crd/patches/cainjection_in_openstackclustertemplates.yaml new file mode 100644 index 0000000000..f7bc3a1156 --- /dev/null +++ b/config/crd/patches/cainjection_in_openstackclustertemplates.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: openstackclustertemplates.infrastructure.cluster.x-k8s.io diff --git a/config/crd/patches/webhook_in_openstackclustertemplates.yaml b/config/crd/patches/webhook_in_openstackclustertemplates.yaml new file mode 100644 index 0000000000..311b52e017 --- /dev/null +++ b/config/crd/patches/webhook_in_openstackclustertemplates.yaml @@ -0,0 +1,17 @@ +# 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: openstackclustertemplates.infrastructure.cluster.x-k8s.io +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 diff --git a/config/webhook/manifests.yaml b/config/webhook/manifests.yaml index 502ed2cce7..68ffc27a0b 100644 --- a/config/webhook/manifests.yaml +++ b/config/webhook/manifests.yaml @@ -15,7 +15,7 @@ webhooks: path: /mutate-infrastructure-cluster-x-k8s-io-v1alpha4-openstackcluster failurePolicy: Fail matchPolicy: Equivalent - name: default.openstackcluster.infrastructure.x-k8s.io + name: default.openstackcluster.infrastructure.cluster.x-k8s.io rules: - apiGroups: - infrastructure.cluster.x-k8s.io @@ -27,6 +27,27 @@ webhooks: resources: - openstackcluster sideEffects: None +- admissionReviewVersions: + - v1beta1 + clientConfig: + service: + name: webhook-service + namespace: system + path: /mutate-infrastructure-cluster-x-k8s-io-v1alpha4-openstackclustertemplate + failurePolicy: Fail + matchPolicy: Equivalent + name: default.openstackclustertemplate.infrastructure.cluster.x-k8s.io + rules: + - apiGroups: + - infrastructure.cluster.x-k8s.io + apiVersions: + - v1alpha4 + operations: + - CREATE + - UPDATE + resources: + - openstackclustertemplates + sideEffects: None - admissionReviewVersions: - v1beta1 clientConfig: @@ -65,7 +86,7 @@ webhooks: path: /validate-infrastructure-cluster-x-k8s-io-v1alpha4-openstackcluster failurePolicy: Fail matchPolicy: Equivalent - name: validation.openstackcluster.infrastructure.x-k8s.io + name: validation.openstackcluster.infrastructure.cluster.x-k8s.io rules: - apiGroups: - infrastructure.cluster.x-k8s.io @@ -77,6 +98,27 @@ webhooks: resources: - openstackcluster sideEffects: None +- admissionReviewVersions: + - v1beta1 + clientConfig: + service: + name: webhook-service + namespace: system + path: /validate-infrastructure-cluster-x-k8s-io-v1alpha4-openstackclustertemplate + failurePolicy: Fail + matchPolicy: Equivalent + name: validation.openstackclustertemplate.infrastructure.cluster.x-k8s.io + rules: + - apiGroups: + - infrastructure.cluster.x-k8s.io + apiVersions: + - v1alpha4 + operations: + - CREATE + - UPDATE + resources: + - openstackclustertemplates + sideEffects: None - admissionReviewVersions: - v1beta1 clientConfig: @@ -107,7 +149,7 @@ webhooks: path: /validate-infrastructure-cluster-x-k8s-io-v1alpha4-openstackmachinetemplate failurePolicy: Fail matchPolicy: Equivalent - name: validation.openstackmachinetemplate.infrastructure.x-k8s.io + name: validation.openstackmachinetemplate.infrastructure.cluster.x-k8s.io rules: - apiGroups: - infrastructure.cluster.x-k8s.io diff --git a/main.go b/main.go index 7c19454073..a9b88f58e0 100644 --- a/main.go +++ b/main.go @@ -227,6 +227,10 @@ func setupWebhooks(mgr ctrl.Manager) { setupLog.Error(err, "unable to create webhook", "webhook", "OpenStackCluster") os.Exit(1) } + if err := (&infrav1.OpenStackClusterTemplate{}).SetupWebhookWithManager(mgr); err != nil { + setupLog.Error(err, "unable to create webhook", "webhook", "OpenStackClusterTemplate") + os.Exit(1) + } if err := (&infrav1.OpenStackMachine{}).SetupWebhookWithManager(mgr); err != nil { setupLog.Error(err, "unable to create webhook", "webhook", "OpenStackMachine") os.Exit(1)