From 0e9b965387439095c4dadf7c759a2a640d3888bf Mon Sep 17 00:00:00 2001 From: Andrei Pavlov Date: Fri, 21 Jun 2024 14:14:01 +0700 Subject: [PATCH 1/2] Set template type and providers in template spec Signed-off-by: Andrei Pavlov --- api/v1alpha1/template_types.go | 9 ++++- api/v1alpha1/zz_generated.deepcopy.go | 1 + .../crd/bases/hmc.mirantis.com_templates.yaml | 33 +++++++++++++++++++ internal/controller/template_controller.go | 2 +- templates/hmc/templates/template-crd.yaml | 32 ++++++++++++++++++ 5 files changed, 75 insertions(+), 2 deletions(-) diff --git a/api/v1alpha1/template_types.go b/api/v1alpha1/template_types.go index fa8833533..57ba39adf 100644 --- a/api/v1alpha1/template_types.go +++ b/api/v1alpha1/template_types.go @@ -62,6 +62,13 @@ type TemplateSpec struct { // Helm holds a reference to a Helm chart representing the HMC template // +kubebuilder:validation:Required Helm HelmSpec `json:"helm"` + // Type specifies the type of the provided template. + // Should be set if not present in the Helm chart metadata. + // +kubebuilder:validation:Enum=deployment;provider;core + Type TemplateType `json:"type,omitempty"` + // Providers represent required/exposed CAPI providers depending on the template type. + // Should be set if not present in the Helm chart metadata. + Providers Providers `json:"providers,omitempty"` } // +kubebuilder:validation:XValidation:rule="(has(self.chartName) && !has(self.chartRef)) || (!has(self.chartName) && has(self.chartRef))", message="either chartName or chartRef must be set" @@ -96,7 +103,7 @@ type TemplateStatus struct { ChartRef *helmcontrollerv2.CrossNamespaceSourceReference `json:"chartRef,omitempty"` // Type specifies the type of the provided template, as discovered from the Helm chart metadata. // +kubebuilder:validation:Enum=deployment;provider;core - Type string `json:"type,omitempty"` + Type TemplateType `json:"type,omitempty"` // Providers represent required/exposed CAPI providers depending on the template type. Providers Providers `json:"providers,omitempty"` // ObservedGeneration is the last observed generation. diff --git a/api/v1alpha1/zz_generated.deepcopy.go b/api/v1alpha1/zz_generated.deepcopy.go index 03c952055..bfa5e42a9 100644 --- a/api/v1alpha1/zz_generated.deepcopy.go +++ b/api/v1alpha1/zz_generated.deepcopy.go @@ -485,6 +485,7 @@ func (in *TemplateList) DeepCopyObject() runtime.Object { func (in *TemplateSpec) DeepCopyInto(out *TemplateSpec) { *out = *in in.Helm.DeepCopyInto(&out.Helm) + in.Providers.DeepCopyInto(&out.Providers) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TemplateSpec. diff --git a/config/crd/bases/hmc.mirantis.com_templates.yaml b/config/crd/bases/hmc.mirantis.com_templates.yaml index 76ece9ad8..f8216a898 100644 --- a/config/crd/bases/hmc.mirantis.com_templates.yaml +++ b/config/crd/bases/hmc.mirantis.com_templates.yaml @@ -108,6 +108,39 @@ spec: - message: either chartName or chartRef must be set rule: (has(self.chartName) && !has(self.chartRef)) || (!has(self.chartName) && has(self.chartRef)) + providers: + description: |- + Providers represent required/exposed CAPI providers depending on the template type. + Should be set if not present in the Helm chart metadata. + properties: + bootstrap: + description: BootstrapProviders is the list of CAPI bootstrap + providers + items: + type: string + type: array + controlPlane: + description: ControlPlaneProviders is the list of CAPI control + plane providers + items: + type: string + type: array + infrastructure: + description: InfrastructureProviders is the list of CAPI infrastructure + providers + items: + type: string + type: array + type: object + type: + description: |- + Type specifies the type of the provided template. + Should be set if not present in the Helm chart metadata. + enum: + - deployment + - provider + - core + type: string required: - helm type: object diff --git a/internal/controller/template_controller.go b/internal/controller/template_controller.go index 58a36ed34..49d5e5865 100644 --- a/internal/controller/template_controller.go +++ b/internal/controller/template_controller.go @@ -154,7 +154,7 @@ func (r *TemplateReconciler) parseChartMetadata(template *hmc.Template, chart *c bootstrapProviders := chart.Metadata.Annotations[hmc.ChartAnnotationBootstrapProviders] cpProviders := chart.Metadata.Annotations[hmc.ChartAnnotationControlPlaneProviders] - template.Status.Type = templateType + template.Status.Type = hmc.TemplateType(templateType) if infraProviders != "" { template.Status.Providers.InfrastructureProviders = strings.Split(infraProviders, ",") } diff --git a/templates/hmc/templates/template-crd.yaml b/templates/hmc/templates/template-crd.yaml index 5cc2bbfbd..369554e26 100644 --- a/templates/hmc/templates/template-crd.yaml +++ b/templates/hmc/templates/template-crd.yaml @@ -109,6 +109,38 @@ spec: - message: either chartName or chartRef must be set rule: (has(self.chartName) && !has(self.chartRef)) || (!has(self.chartName) && has(self.chartRef)) + providers: + description: |- + Providers represent required/exposed CAPI providers depending on the template type. + Should be set if not present in the Helm chart metadata. + properties: + bootstrap: + description: BootstrapProviders is the list of CAPI bootstrap providers + items: + type: string + type: array + controlPlane: + description: ControlPlaneProviders is the list of CAPI control plane + providers + items: + type: string + type: array + infrastructure: + description: InfrastructureProviders is the list of CAPI infrastructure + providers + items: + type: string + type: array + type: object + type: + description: |- + Type specifies the type of the provided template. + Should be set if not present in the Helm chart metadata. + enum: + - deployment + - provider + - core + type: string required: - helm type: object From e9ae6bd45df7f16da2ca519baee2f208eceec8fb Mon Sep 17 00:00:00 2001 From: Andrei Pavlov Date: Fri, 21 Jun 2024 14:32:43 +0700 Subject: [PATCH 2/2] Consider tempalte spec when setting status Type and Providers in the spec have precedence over discovered in the chart metadata. Signed-off-by: Andrei Pavlov --- internal/controller/template_controller.go | 33 +++++++++++++++------- 1 file changed, 23 insertions(+), 10 deletions(-) diff --git a/internal/controller/template_controller.go b/internal/controller/template_controller.go index 49d5e5865..180a99a46 100644 --- a/internal/controller/template_controller.go +++ b/internal/controller/template_controller.go @@ -150,19 +150,32 @@ func (r *TemplateReconciler) parseChartMetadata(template *hmc.Template, chart *c default: return errNoProviderType } - infraProviders := chart.Metadata.Annotations[hmc.ChartAnnotationInfraProviders] - bootstrapProviders := chart.Metadata.Annotations[hmc.ChartAnnotationBootstrapProviders] - cpProviders := chart.Metadata.Annotations[hmc.ChartAnnotationControlPlaneProviders] - template.Status.Type = hmc.TemplateType(templateType) - if infraProviders != "" { - template.Status.Providers.InfrastructureProviders = strings.Split(infraProviders, ",") + + // the value in spec has higher priority + if len(template.Spec.Providers.InfrastructureProviders) > 0 { + template.Status.Providers.InfrastructureProviders = template.Spec.Providers.InfrastructureProviders + } else { + infraProviders := chart.Metadata.Annotations[hmc.ChartAnnotationInfraProviders] + if infraProviders != "" { + template.Status.Providers.InfrastructureProviders = strings.Split(infraProviders, ",") + } } - if bootstrapProviders != "" { - template.Status.Providers.BootstrapProviders = strings.Split(bootstrapProviders, ",") + if len(template.Spec.Providers.BootstrapProviders) > 0 { + template.Status.Providers.BootstrapProviders = template.Spec.Providers.BootstrapProviders + } else { + bootstrapProviders := chart.Metadata.Annotations[hmc.ChartAnnotationBootstrapProviders] + if bootstrapProviders != "" { + template.Status.Providers.BootstrapProviders = strings.Split(bootstrapProviders, ",") + } } - if cpProviders != "" { - template.Status.Providers.ControlPlaneProviders = strings.Split(cpProviders, ",") + if len(template.Spec.Providers.ControlPlaneProviders) > 0 { + template.Status.Providers.ControlPlaneProviders = template.Spec.Providers.ControlPlaneProviders + } else { + cpProviders := chart.Metadata.Annotations[hmc.ChartAnnotationControlPlaneProviders] + if cpProviders != "" { + template.Status.Providers.InfrastructureProviders = strings.Split(cpProviders, ",") + } } return nil }