From 7cecb256e389fe910cda354ea7b56da73cbb363c Mon Sep 17 00:00:00 2001 From: Martin Schuppert Date: Fri, 3 May 2024 16:48:29 +0200 Subject: [PATCH] [wip] improve cert defaulting --- ....openstack.org_openstackcontrolplanes.yaml | 60 ++++ .../v1beta1/openstackcontrolplane_types.go | 32 +- apis/core/v1beta1/zz_generated.deepcopy.go | 11 +- ....openstack.org_openstackcontrolplanes.yaml | 60 ++++ pkg/openstack/ca.go | 12 +- tests/functional/base_test.go | 42 +-- .../openstackoperator_controller_test.go | 338 ++++++++++++++++++ 7 files changed, 502 insertions(+), 53 deletions(-) diff --git a/apis/bases/core.openstack.org_openstackcontrolplanes.yaml b/apis/bases/core.openstack.org_openstackcontrolplanes.yaml index 31ffdb892..148b4d9d0 100644 --- a/apis/bases/core.openstack.org_openstackcontrolplanes.yaml +++ b/apis/bases/core.openstack.org_openstackcontrolplanes.yaml @@ -17136,17 +17136,28 @@ spec: caBundleSecretName: type: string ingress: + default: + ca: + duration: 87600h + cert: + duration: 10950h + enabled: true properties: ca: + default: + duration: 87600h properties: customIssuer: type: string duration: + default: 87600h type: string renewBefore: type: string type: object cert: + default: + duration: 10950h properties: duration: type: string @@ -17154,24 +17165,53 @@ spec: type: string type: object enabled: + default: true type: boolean type: object podLevel: + default: + enabled: true + internal: + ca: + duration: 87600h + cert: + duration: 10950h + libvirt: + ca: + duration: 87600h + cert: + duration: 43800h + ovn: + ca: + duration: 87600h + cert: + duration: 10950h properties: enabled: + default: true type: boolean internal: + default: + ca: + duration: 87600h + cert: + duration: 10950h properties: ca: + default: + duration: 87600h properties: customIssuer: type: string duration: + default: 87600h type: string renewBefore: type: string type: object cert: + default: + duration: 10950h properties: duration: type: string @@ -17180,17 +17220,27 @@ spec: type: object type: object libvirt: + default: + ca: + duration: 87600h + cert: + duration: 43800h properties: ca: + default: + duration: 87600h properties: customIssuer: type: string duration: + default: 87600h type: string renewBefore: type: string type: object cert: + default: + duration: 10950h properties: duration: type: string @@ -17199,17 +17249,27 @@ spec: type: object type: object ovn: + default: + ca: + duration: 87600h + cert: + duration: 10950h properties: ca: + default: + duration: 87600h properties: customIssuer: type: string duration: + default: 87600h type: string renewBefore: type: string type: object cert: + default: + duration: 10950h properties: duration: type: string diff --git a/apis/core/v1beta1/openstackcontrolplane_types.go b/apis/core/v1beta1/openstackcontrolplane_types.go index cbd4bdd5e..4c55f91ca 100644 --- a/apis/core/v1beta1/openstackcontrolplane_types.go +++ b/apis/core/v1beta1/openstackcontrolplane_types.go @@ -190,10 +190,12 @@ type OpenStackControlPlaneSpec struct { type TLSSection struct { // +kubebuilder:validation:optional //+operator-sdk:csv:customresourcedefinitions:type=spec + // +kubebuilder:default={enabled: true, ca: {duration: "87600h"}, cert: {duration: "10950h"}} Ingress TLSIngressConfig `json:"ingress,omitempty"` // +kubebuilder:validation:optional //+operator-sdk:csv:customresourcedefinitions:type=spec + // +kubebuilder:default={enabled: true, internal:{ca: {duration: "87600h"}, cert: {duration: "10950h"}}, libvirt: {ca: {duration: "87600h"}, cert: {duration: "43800h"}}, ovn: {ca: {duration: "87600h"}, cert: {duration: "10950h"}}} PodLevel TLSPodLevelConfig `json:"podLevel,omitempty"` // +kubebuilder:validation:optional @@ -209,6 +211,7 @@ type TLSIngressConfig struct { // +kubebuilder:validation:Optional // +operator-sdk:csv:customresourcedefinitions:type=spec,xDescriptors={"urn:alm:descriptor:com.tectonic.ui:booleanSwitch"} // Enabled - Whether TLS should be enabled for endpoint type + // +kubebuilder:default=true Enabled bool `json:"enabled"` // +kubebuilder:validation:optional @@ -221,21 +224,25 @@ type TLSPodLevelConfig struct { // +kubebuilder:validation:Optional // +operator-sdk:csv:customresourcedefinitions:type=spec,xDescriptors={"urn:alm:descriptor:com.tectonic.ui:booleanSwitch"} // Enabled - Whether TLS should be enabled for endpoint type + // +kubebuilder:default=true Enabled bool `json:"enabled"` // +kubebuilder:validation:Optional // +operator-sdk:csv:customresourcedefinitions:type=spec + // +kubebuilder:default={ca: {duration: "87600h"}, cert: {duration: "10950h"}} // Internal - default CA used for all OpenStackControlPlane and OpenStackDataplane endpoints, // except OVN related CA and certs Internal CertSection `json:"internal,omitempty"` // +kubebuilder:validation:Optional // +operator-sdk:csv:customresourcedefinitions:type=spec + // +kubebuilder:default={ca: {duration: "87600h"}, cert: {duration: "43800h"}} // Libvirt - CA used for libvirt/qemu services on OpenStackControlPlane and OpenStackDataplane Libvirt CertSection `json:"libvirt,omitempty"` // +kubebuilder:validation:Optional // +operator-sdk:csv:customresourcedefinitions:type=spec + // +kubebuilder:default={ca: {duration: "87600h"}, cert: {duration: "10950h"}} // Ovn - CA used for all OVN services on OpenStackControlPlane and OpenStackDataplane Ovn CertSection `json:"ovn,omitempty"` } @@ -244,20 +251,35 @@ type TLSPodLevelConfig struct { type CertSection struct { // +kubebuilder:validation:Optional // +operator-sdk:csv:customresourcedefinitions:type=spec + // +kubebuilder:default={duration: "10950h"} // Cert - defines details for cert config Cert CertConfig `json:"cert,omitempty"` // +kubebuilder:validation:Optional // +operator-sdk:csv:customresourcedefinitions:type=spec + // +kubebuilder:default={duration: "87600h"} // Ca - defines details for CA cert config Ca CACertConfig `json:"ca,omitempty"` } // CACertConfig defines details for ca cert configs type CACertConfig struct { - // +kubebuilder:validation:optional - //+operator-sdk:csv:customresourcedefinitions:type=spec - CertConfig `json:",inline"` + // +kubebuilder:validation:Optional + // +kubebuilder:default="87600h" + // The requested 'duration' (i.e. lifetime) of the Certificate. + // The Certificate will be renewed either 2/3 through its duration or + // `renewBefore` period before its expiry, whichever is later. Minimum + // accepted duration is 1 hour. Value must be in units accepted by Go + // time.ParseDuration https://golang.org/pkg/time/#ParseDuration + Duration *metav1.Duration `json:"duration,omitempty"` + + // +kubebuilder:validation:Optional + // How long before the currently issued certificate's expiry + // cert-manager should renew the certificate. The default is 2/3 of the + // issued certificate's duration. Minimum accepted value is 5 minutes. + // Value must be in units accepted by Go time.ParseDuration + // https://golang.org/pkg/time/#ParseDuration + RenewBefore *metav1.Duration `json:"renewBefore,omitempty"` // +kubebuilder:validation:Optional // CustomIssuer - use pre-created issue for this CA. No CA and issure is being created @@ -267,20 +289,20 @@ type CACertConfig struct { // CertConfig defines details for cert configs type CertConfig struct { + // +kubebuilder:validation:Optional // The requested 'duration' (i.e. lifetime) of the Certificate. // The Certificate will be renewed either 2/3 through its duration or // `renewBefore` period before its expiry, whichever is later. Minimum // accepted duration is 1 hour. Value must be in units accepted by Go // time.ParseDuration https://golang.org/pkg/time/#ParseDuration - // +optional Duration *metav1.Duration `json:"duration,omitempty"` + // +kubebuilder:validation:Optional // How long before the currently issued certificate's expiry // cert-manager should renew the certificate. The default is 2/3 of the // issued certificate's duration. Minimum accepted value is 5 minutes. // Value must be in units accepted by Go time.ParseDuration // https://golang.org/pkg/time/#ParseDuration - // +optional RenewBefore *metav1.Duration `json:"renewBefore,omitempty"` } diff --git a/apis/core/v1beta1/zz_generated.deepcopy.go b/apis/core/v1beta1/zz_generated.deepcopy.go index b87a244de..92e447ea4 100644 --- a/apis/core/v1beta1/zz_generated.deepcopy.go +++ b/apis/core/v1beta1/zz_generated.deepcopy.go @@ -52,7 +52,16 @@ func (in *BarbicanSection) DeepCopy() *BarbicanSection { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *CACertConfig) DeepCopyInto(out *CACertConfig) { *out = *in - in.CertConfig.DeepCopyInto(&out.CertConfig) + if in.Duration != nil { + in, out := &in.Duration, &out.Duration + *out = new(v1.Duration) + **out = **in + } + if in.RenewBefore != nil { + in, out := &in.RenewBefore, &out.RenewBefore + *out = new(v1.Duration) + **out = **in + } if in.CustomIssuer != nil { in, out := &in.CustomIssuer, &out.CustomIssuer *out = new(string) diff --git a/config/crd/bases/core.openstack.org_openstackcontrolplanes.yaml b/config/crd/bases/core.openstack.org_openstackcontrolplanes.yaml index 31ffdb892..148b4d9d0 100644 --- a/config/crd/bases/core.openstack.org_openstackcontrolplanes.yaml +++ b/config/crd/bases/core.openstack.org_openstackcontrolplanes.yaml @@ -17136,17 +17136,28 @@ spec: caBundleSecretName: type: string ingress: + default: + ca: + duration: 87600h + cert: + duration: 10950h + enabled: true properties: ca: + default: + duration: 87600h properties: customIssuer: type: string duration: + default: 87600h type: string renewBefore: type: string type: object cert: + default: + duration: 10950h properties: duration: type: string @@ -17154,24 +17165,53 @@ spec: type: string type: object enabled: + default: true type: boolean type: object podLevel: + default: + enabled: true + internal: + ca: + duration: 87600h + cert: + duration: 10950h + libvirt: + ca: + duration: 87600h + cert: + duration: 43800h + ovn: + ca: + duration: 87600h + cert: + duration: 10950h properties: enabled: + default: true type: boolean internal: + default: + ca: + duration: 87600h + cert: + duration: 10950h properties: ca: + default: + duration: 87600h properties: customIssuer: type: string duration: + default: 87600h type: string renewBefore: type: string type: object cert: + default: + duration: 10950h properties: duration: type: string @@ -17180,17 +17220,27 @@ spec: type: object type: object libvirt: + default: + ca: + duration: 87600h + cert: + duration: 43800h properties: ca: + default: + duration: 87600h properties: customIssuer: type: string duration: + default: 87600h type: string renewBefore: type: string type: object cert: + default: + duration: 10950h properties: duration: type: string @@ -17199,17 +17249,27 @@ spec: type: object type: object ovn: + default: + ca: + duration: 87600h + cert: + duration: 10950h properties: ca: + default: + duration: 87600h properties: customIssuer: type: string duration: + default: 87600h type: string renewBefore: type: string type: object cert: + default: + duration: 10950h properties: duration: type: string diff --git a/pkg/openstack/ca.go b/pkg/openstack/ca.go index fce68c746..f64d164e4 100644 --- a/pkg/openstack/ca.go +++ b/pkg/openstack/ca.go @@ -108,7 +108,7 @@ func ReconcileCAs(ctx context.Context, instance *corev1.OpenStackControlPlane, h issuerLabels, bundle, caOnlyBundle, - instance.Spec.TLS.Ingress.Ca.CertConfig, + instance.Spec.TLS.Ingress.Ca, ) if err != nil { return ctrlResult, err @@ -172,7 +172,7 @@ func ReconcileCAs(ctx context.Context, instance *corev1.OpenStackControlPlane, h issuerLabels, bundle, caOnlyBundle, - instance.Spec.TLS.PodLevel.Internal.Ca.CertConfig, + instance.Spec.TLS.PodLevel.Internal.Ca, ) if err != nil { return ctrlResult, err @@ -236,7 +236,7 @@ func ReconcileCAs(ctx context.Context, instance *corev1.OpenStackControlPlane, h issuerLabels, bundle, caOnlyBundle, - instance.Spec.TLS.PodLevel.Libvirt.Ca.CertConfig, + instance.Spec.TLS.PodLevel.Libvirt.Ca, ) if err != nil { return ctrlResult, err @@ -299,7 +299,7 @@ func ReconcileCAs(ctx context.Context, instance *corev1.OpenStackControlPlane, h issuerLabels, bundle, caOnlyBundle, - instance.Spec.TLS.PodLevel.Ovn.Ca.CertConfig, + instance.Spec.TLS.PodLevel.Ovn.Ca, ) if err != nil { return ctrlResult, err @@ -450,7 +450,7 @@ func ensureRootCA( labels map[string]string, bundle *caBundle, caOnlyBundle *caBundle, - caCfg corev1.CertConfig, + caCfg corev1.CACertConfig, ) (ctrl.Result, error) { // always create a root CA and issuer for the endpoint as we can // not expect that all services are yet configured to be provided with @@ -518,7 +518,7 @@ func createRootCACertAndIssuer( selfsignedIssuerReq *certmgrv1.Issuer, caName string, labels map[string]string, - caCfg corev1.CertConfig, + caCfg corev1.CACertConfig, ) ([]byte, ctrl.Result, error) { // create RootCA Certificate used to sign certificates caCertReq := certmanager.Cert( diff --git a/tests/functional/base_test.go b/tests/functional/base_test.go index 6791e4573..cc8a80307 100644 --- a/tests/functional/base_test.go +++ b/tests/functional/base_test.go @@ -276,47 +276,8 @@ func CreateOpenStackControlPlane(name types.NamespacedName, spec map[string]inte func GetTLSPublicSpec() map[string]interface{} { return map[string]interface{}{ - "ingress": map[string]interface{}{ - "enabled": true, - "ca": map[string]interface{}{ - "duration": "100h", - }, - "cert": map[string]interface{}{ - "duration": "10h", - }, - }, - } -} - -func GetTLSeSpec() map[string]interface{} { - return map[string]interface{}{ - "ingress": map[string]interface{}{ - "enabled": true, - "ca": map[string]interface{}{ - "duration": "100h", - }, - "cert": map[string]interface{}{ - "duration": "10h", - }, - }, "podLevel": map[string]interface{}{ - "enabled": true, - "internal": map[string]interface{}{ - "ca": map[string]interface{}{ - "duration": "100h", - }, - "cert": map[string]interface{}{ - "duration": "10h", - }, - }, - "ovn": map[string]interface{}{ - "ca": map[string]interface{}{ - "duration": "100h", - }, - "cert": map[string]interface{}{ - "duration": "10h", - }, - }, + "enabled": false, }, } } @@ -389,7 +350,6 @@ func GetDefaultOpenStackControlPlaneSpec() map[string]interface{} { return map[string]interface{}{ "secret": "osp-secret", "storageClass": "local-storage", - "tls": GetTLSeSpec(), "galera": map[string]interface{}{ "enabled": true, "templates": galeraTemplate, diff --git a/tests/functional/openstackoperator_controller_test.go b/tests/functional/openstackoperator_controller_test.go index 62e7edb52..b0b420ee9 100644 --- a/tests/functional/openstackoperator_controller_test.go +++ b/tests/functional/openstackoperator_controller_test.go @@ -67,6 +67,344 @@ var _ = Describe("OpenStackOperator controller", func() { DeferCleanup(k8sClient.Delete, ctx, th.CreateCertSecret(names.DBCell1CertName)) }) + // + // Validate TLS input settings + // + When("TLS - A public TLS OpenStackControlplane instance is created", func() { + BeforeEach(func() { + spec := GetDefaultOpenStackControlPlaneSpec() + spec["tls"] = GetTLSPublicSpec() + DeferCleanup( + th.DeleteInstance, + CreateOpenStackControlPlane(names.OpenStackControlplaneName, spec), + ) + }) + It("should have the TLS Spec fields defaulted", func() { + OSCtlplane := GetOpenStackControlPlane(names.OpenStackControlplaneName) + Expect(OSCtlplane.Spec.TLS.Ingress.Enabled).Should(BeTrue()) + Expect(OSCtlplane.Spec.TLS.Ingress.Ca.Duration.Duration.Hours()).Should(Equal(float64(87600))) + Expect(OSCtlplane.Spec.TLS.Ingress.Cert.Duration.Duration.Hours()).Should(Equal(float64(10950))) + Expect(OSCtlplane.Spec.TLS.PodLevel.Enabled).Should(BeFalse()) + }) + }) + When("TLS - A public TLS OpenStackControlplane instance is created with customized ca duration", func() { + BeforeEach(func() { + spec := GetDefaultOpenStackControlPlaneSpec() + tlsSpec := GetTLSPublicSpec() + tlsSpec["ingress"] = map[string]interface{}{ + "ca": map[string]interface{}{ + "duration": "100h", + }, + } + spec["tls"] = tlsSpec + + DeferCleanup( + th.DeleteInstance, + CreateOpenStackControlPlane(names.OpenStackControlplaneName, spec), + ) + }) + It("should have the TLS Spec fields set/defaulted", func() { + OSCtlplane := GetOpenStackControlPlane(names.OpenStackControlplaneName) + Expect(OSCtlplane.Spec.TLS.Ingress.Enabled).Should(BeTrue()) + Expect(OSCtlplane.Spec.TLS.Ingress.Ca.Duration.Duration.Hours()).Should(Equal(float64(100))) + Expect(OSCtlplane.Spec.TLS.Ingress.Cert.Duration.Duration.Hours()).Should(Equal(float64(10950))) + Expect(OSCtlplane.Spec.TLS.PodLevel.Enabled).Should(BeFalse()) + }) + }) + When("TLS - A public TLS OpenStackControlplane instance is created with customized cert duration", func() { + BeforeEach(func() { + spec := GetDefaultOpenStackControlPlaneSpec() + tlsSpec := GetTLSPublicSpec() + tlsSpec["ingress"] = map[string]interface{}{ + "cert": map[string]interface{}{ + "duration": "10h", + }, + } + spec["tls"] = tlsSpec + + DeferCleanup( + th.DeleteInstance, + CreateOpenStackControlPlane(names.OpenStackControlplaneName, spec), + ) + }) + It("should have the TLS Spec fields set/defaulted", func() { + OSCtlplane := GetOpenStackControlPlane(names.OpenStackControlplaneName) + Expect(OSCtlplane.Spec.TLS.Ingress.Enabled).Should(BeTrue()) + Expect(OSCtlplane.Spec.TLS.Ingress.Ca.Duration.Duration.Hours()).Should(Equal(float64(87600))) + Expect(OSCtlplane.Spec.TLS.Ingress.Cert.Duration.Duration.Hours()).Should(Equal(float64(10))) + Expect(OSCtlplane.Spec.TLS.PodLevel.Enabled).Should(BeFalse()) + }) + }) + When("TLS - A public TLS OpenStackControlplane instance is created with customized ca and cert duration", func() { + BeforeEach(func() { + spec := GetDefaultOpenStackControlPlaneSpec() + tlsSpec := GetTLSPublicSpec() + tlsSpec["ingress"] = map[string]interface{}{ + "ca": map[string]interface{}{ + "duration": "100h", + }, + "cert": map[string]interface{}{ + "duration": "10h", + }, + } + spec["tls"] = tlsSpec + + DeferCleanup( + th.DeleteInstance, + CreateOpenStackControlPlane(names.OpenStackControlplaneName, spec), + ) + }) + It("should have the TLS Spec fields set/defaulted", func() { + OSCtlplane := GetOpenStackControlPlane(names.OpenStackControlplaneName) + Expect(OSCtlplane.Spec.TLS.Ingress.Enabled).Should(BeTrue()) + Expect(OSCtlplane.Spec.TLS.Ingress.Ca.Duration.Duration.Hours()).Should(Equal(float64(100))) + Expect(OSCtlplane.Spec.TLS.Ingress.Cert.Duration.Duration.Hours()).Should(Equal(float64(10))) + Expect(OSCtlplane.Spec.TLS.PodLevel.Enabled).Should(BeFalse()) + }) + }) + When("TLS - A public TLS OpenStackControlplane instance is created with customized renewBefore", func() { + BeforeEach(func() { + spec := GetDefaultOpenStackControlPlaneSpec() + tlsSpec := GetTLSPublicSpec() + tlsSpec["ingress"] = map[string]interface{}{ + "ca": map[string]interface{}{ + "renewBefore": "100h", + }, + "cert": map[string]interface{}{ + "renewBefore": "10h", + }, + } + spec["tls"] = tlsSpec + + DeferCleanup( + th.DeleteInstance, + CreateOpenStackControlPlane(names.OpenStackControlplaneName, spec), + ) + }) + It("should have the TLS Spec fields set/defaulted", func() { + OSCtlplane := GetOpenStackControlPlane(names.OpenStackControlplaneName) + Expect(OSCtlplane.Spec.TLS.Ingress.Enabled).Should(BeTrue()) + Expect(OSCtlplane.Spec.TLS.Ingress.Ca.RenewBefore.Duration.Hours()).Should(Equal(float64(100))) + Expect(OSCtlplane.Spec.TLS.Ingress.Cert.RenewBefore.Duration.Hours()).Should(Equal(float64(10))) + Expect(OSCtlplane.Spec.TLS.PodLevel.Enabled).Should(BeFalse()) + }) + }) + When("TLS - A public TLS OpenStackControlplane instance is created with a custom issuer", func() { + BeforeEach(func() { + spec := GetDefaultOpenStackControlPlaneSpec() + tlsSpec := GetTLSPublicSpec() + tlsSpec["ingress"] = map[string]interface{}{ + "ca": map[string]interface{}{ + "customIssuer": "myissuer", + }, + } + spec["tls"] = tlsSpec + + DeferCleanup( + th.DeleteInstance, + CreateOpenStackControlPlane(names.OpenStackControlplaneName, spec), + ) + }) + It("should have the TLS Spec fields set/defaulted", func() { + OSCtlplane := GetOpenStackControlPlane(names.OpenStackControlplaneName) + Expect(OSCtlplane.Spec.TLS.Ingress.Enabled).Should(BeTrue()) + Expect(OSCtlplane.Spec.TLS.Ingress.Ca.CustomIssuer).Should(Not(BeNil())) + Expect(*OSCtlplane.Spec.TLS.Ingress.Ca.CustomIssuer).Should(Equal("myissuer")) + Expect(OSCtlplane.Spec.TLS.Ingress.Ca.Duration.Duration.Hours()).Should(Equal(float64(87600))) + Expect(OSCtlplane.Spec.TLS.Ingress.Cert.Duration.Duration.Hours()).Should(Equal(float64(10950))) + Expect(OSCtlplane.Spec.TLS.PodLevel.Enabled).Should(BeFalse()) + }) + }) + When("TLS - A TLSe OpenStackControlplane instance is created", func() { + BeforeEach(func() { + spec := GetDefaultOpenStackControlPlaneSpec() + DeferCleanup( + th.DeleteInstance, + CreateOpenStackControlPlane(names.OpenStackControlplaneName, spec), + ) + }) + It("should have the TLS Spec fields set/defaulted", func() { + OSCtlplane := GetOpenStackControlPlane(names.OpenStackControlplaneName) + Expect(OSCtlplane.Spec.TLS.Ingress.Enabled).Should(BeTrue()) + Expect(OSCtlplane.Spec.TLS.Ingress.Ca.Duration.Duration.Hours()).Should(Equal(float64(87600))) + Expect(OSCtlplane.Spec.TLS.Ingress.Cert.Duration.Duration.Hours()).Should(Equal(float64(10950))) + Expect(OSCtlplane.Spec.TLS.PodLevel.Enabled).Should(BeTrue()) + Expect(OSCtlplane.Spec.TLS.PodLevel.Internal.Ca.Duration.Duration.Hours()).Should(Equal(float64(87600))) + Expect(OSCtlplane.Spec.TLS.PodLevel.Internal.Cert.Duration.Duration.Hours()).Should(Equal(float64(10950))) + Expect(OSCtlplane.Spec.TLS.PodLevel.Libvirt.Ca.Duration.Duration.Hours()).Should(Equal(float64(87600))) + Expect(OSCtlplane.Spec.TLS.PodLevel.Libvirt.Cert.Duration.Duration.Hours()).Should(Equal(float64(43800))) + Expect(OSCtlplane.Spec.TLS.PodLevel.Ovn.Ca.Duration.Duration.Hours()).Should(Equal(float64(87600))) + Expect(OSCtlplane.Spec.TLS.PodLevel.Ovn.Cert.Duration.Duration.Hours()).Should(Equal(float64(10950))) + }) + }) + When("TLS - A TLSe OpenStackControlplane instance is created with customized internal ca duration", func() { + BeforeEach(func() { + spec := GetDefaultOpenStackControlPlaneSpec() + spec["tls"] = map[string]interface{}{ + "podLevel": map[string]interface{}{ + "internal": map[string]interface{}{ + "ca": map[string]interface{}{ + "duration": "100h", + }, + }, + }, + } + DeferCleanup( + th.DeleteInstance, + CreateOpenStackControlPlane(names.OpenStackControlplaneName, spec), + ) + }) + It("should have the TLS Spec fields set/defaulted", func() { + OSCtlplane := GetOpenStackControlPlane(names.OpenStackControlplaneName) + Expect(OSCtlplane.Spec.TLS.Ingress.Enabled).Should(BeTrue()) + Expect(OSCtlplane.Spec.TLS.Ingress.Ca.Duration.Duration.Hours()).Should(Equal(float64(87600))) + Expect(OSCtlplane.Spec.TLS.Ingress.Cert.Duration.Duration.Hours()).Should(Equal(float64(10950))) + Expect(OSCtlplane.Spec.TLS.PodLevel.Enabled).Should(BeTrue()) + Expect(OSCtlplane.Spec.TLS.PodLevel.Internal.Ca.Duration.Duration.Hours()).Should(Equal(float64(100))) + Expect(OSCtlplane.Spec.TLS.PodLevel.Internal.Cert.Duration.Duration.Hours()).Should(Equal(float64(10950))) + Expect(OSCtlplane.Spec.TLS.PodLevel.Libvirt.Ca.Duration.Duration.Hours()).Should(Equal(float64(87600))) + Expect(OSCtlplane.Spec.TLS.PodLevel.Libvirt.Cert.Duration.Duration.Hours()).Should(Equal(float64(43800))) + Expect(OSCtlplane.Spec.TLS.PodLevel.Ovn.Ca.Duration.Duration.Hours()).Should(Equal(float64(87600))) + Expect(OSCtlplane.Spec.TLS.PodLevel.Ovn.Cert.Duration.Duration.Hours()).Should(Equal(float64(10950))) + }) + }) + When("TLS - A TLSe OpenStackControlplane instance is created with customized internal cert duration", func() { + BeforeEach(func() { + spec := GetDefaultOpenStackControlPlaneSpec() + spec["tls"] = map[string]interface{}{ + "podLevel": map[string]interface{}{ + "internal": map[string]interface{}{ + "cert": map[string]interface{}{ + "duration": "10h", + }, + }, + }, + } + DeferCleanup( + th.DeleteInstance, + CreateOpenStackControlPlane(names.OpenStackControlplaneName, spec), + ) + }) + It("should have the TLS Spec fields set/defaulted", func() { + OSCtlplane := GetOpenStackControlPlane(names.OpenStackControlplaneName) + Expect(OSCtlplane.Spec.TLS.Ingress.Enabled).Should(BeTrue()) + Expect(OSCtlplane.Spec.TLS.Ingress.Ca.Duration.Duration.Hours()).Should(Equal(float64(87600))) + Expect(OSCtlplane.Spec.TLS.Ingress.Cert.Duration.Duration.Hours()).Should(Equal(float64(10950))) + Expect(OSCtlplane.Spec.TLS.PodLevel.Enabled).Should(BeTrue()) + Expect(OSCtlplane.Spec.TLS.PodLevel.Internal.Ca.Duration.Duration.Hours()).Should(Equal(float64(87600))) + Expect(OSCtlplane.Spec.TLS.PodLevel.Internal.Cert.Duration.Duration.Hours()).Should(Equal(float64(10))) + Expect(OSCtlplane.Spec.TLS.PodLevel.Libvirt.Ca.Duration.Duration.Hours()).Should(Equal(float64(87600))) + Expect(OSCtlplane.Spec.TLS.PodLevel.Libvirt.Cert.Duration.Duration.Hours()).Should(Equal(float64(43800))) + Expect(OSCtlplane.Spec.TLS.PodLevel.Ovn.Ca.Duration.Duration.Hours()).Should(Equal(float64(87600))) + Expect(OSCtlplane.Spec.TLS.PodLevel.Ovn.Cert.Duration.Duration.Hours()).Should(Equal(float64(10950))) + }) + }) + When("TLS - A TLSe OpenStackControlplane instance is created with an internal custom issuer", func() { + BeforeEach(func() { + spec := GetDefaultOpenStackControlPlaneSpec() + spec["tls"] = map[string]interface{}{ + "podLevel": map[string]interface{}{ + "internal": map[string]interface{}{ + "ca": map[string]interface{}{ + "customIssuer": "myissuer", + }, + }, + }, + } + + DeferCleanup( + th.DeleteInstance, + CreateOpenStackControlPlane(names.OpenStackControlplaneName, spec), + ) + }) + It("should have the TLS Spec fields set/defaulted", func() { + OSCtlplane := GetOpenStackControlPlane(names.OpenStackControlplaneName) + Expect(OSCtlplane.Spec.TLS.Ingress.Enabled).Should(BeTrue()) + Expect(OSCtlplane.Spec.TLS.Ingress.Ca.Duration.Duration.Hours()).Should(Equal(float64(87600))) + Expect(OSCtlplane.Spec.TLS.Ingress.Cert.Duration.Duration.Hours()).Should(Equal(float64(10950))) + Expect(OSCtlplane.Spec.TLS.PodLevel.Enabled).Should(BeTrue()) + Expect(*OSCtlplane.Spec.TLS.PodLevel.Internal.Ca.CustomIssuer).Should(Equal("myissuer")) + Expect(OSCtlplane.Spec.TLS.PodLevel.Internal.Ca.Duration.Duration.Hours()).Should(Equal(float64(87600))) + Expect(OSCtlplane.Spec.TLS.PodLevel.Internal.Cert.Duration.Duration.Hours()).Should(Equal(float64(10950))) + Expect(OSCtlplane.Spec.TLS.PodLevel.Libvirt.Ca.Duration.Duration.Hours()).Should(Equal(float64(87600))) + Expect(OSCtlplane.Spec.TLS.PodLevel.Libvirt.Cert.Duration.Duration.Hours()).Should(Equal(float64(43800))) + Expect(OSCtlplane.Spec.TLS.PodLevel.Ovn.Ca.Duration.Duration.Hours()).Should(Equal(float64(87600))) + Expect(OSCtlplane.Spec.TLS.PodLevel.Ovn.Cert.Duration.Duration.Hours()).Should(Equal(float64(10950))) + }) + }) + When("TLS - A TLSe OpenStackControlplane instance is created with an libvirt custom issuer", func() { + BeforeEach(func() { + spec := GetDefaultOpenStackControlPlaneSpec() + spec["tls"] = map[string]interface{}{ + "podLevel": map[string]interface{}{ + "libvirt": map[string]interface{}{ + "ca": map[string]interface{}{ + "customIssuer": "myissuer", + }, + "cert": map[string]interface{}{ + "duration": "43800h", // can we come up with a single default duration for certs? + }, + }, + }, + } + + DeferCleanup( + th.DeleteInstance, + CreateOpenStackControlPlane(names.OpenStackControlplaneName, spec), + ) + }) + It("should have the TLS Spec fields set/defaulted", func() { + OSCtlplane := GetOpenStackControlPlane(names.OpenStackControlplaneName) + Expect(OSCtlplane.Spec.TLS.Ingress.Enabled).Should(BeTrue()) + Expect(OSCtlplane.Spec.TLS.Ingress.Ca.Duration.Duration.Hours()).Should(Equal(float64(87600))) + Expect(OSCtlplane.Spec.TLS.Ingress.Cert.Duration.Duration.Hours()).Should(Equal(float64(10950))) + Expect(OSCtlplane.Spec.TLS.PodLevel.Enabled).Should(BeTrue()) + Expect(OSCtlplane.Spec.TLS.PodLevel.Internal.Ca.Duration.Duration.Hours()).Should(Equal(float64(87600))) + Expect(OSCtlplane.Spec.TLS.PodLevel.Internal.Cert.Duration.Duration.Hours()).Should(Equal(float64(10950))) + Expect(*OSCtlplane.Spec.TLS.PodLevel.Libvirt.Ca.CustomIssuer).Should(Equal("myissuer")) + Expect(OSCtlplane.Spec.TLS.PodLevel.Libvirt.Ca.Duration.Duration.Hours()).Should(Equal(float64(87600))) + Expect(OSCtlplane.Spec.TLS.PodLevel.Libvirt.Cert.Duration.Duration.Hours()).Should(Equal(float64(43800))) + Expect(OSCtlplane.Spec.TLS.PodLevel.Ovn.Ca.Duration.Duration.Hours()).Should(Equal(float64(87600))) + Expect(OSCtlplane.Spec.TLS.PodLevel.Ovn.Cert.Duration.Duration.Hours()).Should(Equal(float64(10950))) + }) + }) + When("TLS - A TLSe OpenStackControlplane instance is created with an ovn custom issuer", func() { + BeforeEach(func() { + spec := GetDefaultOpenStackControlPlaneSpec() + spec["tls"] = map[string]interface{}{ + "podLevel": map[string]interface{}{ + "ovn": map[string]interface{}{ + "ca": map[string]interface{}{ + "customIssuer": "myissuer", + }, + }, + }, + } + + DeferCleanup( + th.DeleteInstance, + CreateOpenStackControlPlane(names.OpenStackControlplaneName, spec), + ) + }) + It("should have the TLS Spec fields set/defaulted", func() { + OSCtlplane := GetOpenStackControlPlane(names.OpenStackControlplaneName) + Expect(OSCtlplane.Spec.TLS.Ingress.Enabled).Should(BeTrue()) + Expect(OSCtlplane.Spec.TLS.Ingress.Ca.Duration.Duration.Hours()).Should(Equal(float64(87600))) + Expect(OSCtlplane.Spec.TLS.Ingress.Cert.Duration.Duration.Hours()).Should(Equal(float64(10950))) + Expect(OSCtlplane.Spec.TLS.PodLevel.Enabled).Should(BeTrue()) + Expect(OSCtlplane.Spec.TLS.PodLevel.Internal.Ca.Duration.Duration.Hours()).Should(Equal(float64(87600))) + Expect(OSCtlplane.Spec.TLS.PodLevel.Internal.Cert.Duration.Duration.Hours()).Should(Equal(float64(10950))) + Expect(OSCtlplane.Spec.TLS.PodLevel.Libvirt.Ca.Duration.Duration.Hours()).Should(Equal(float64(87600))) + Expect(OSCtlplane.Spec.TLS.PodLevel.Libvirt.Cert.Duration.Duration.Hours()).Should(Equal(float64(43800))) + Expect(*OSCtlplane.Spec.TLS.PodLevel.Ovn.Ca.CustomIssuer).Should(Equal("myissuer")) + Expect(OSCtlplane.Spec.TLS.PodLevel.Ovn.Ca.Duration.Duration.Hours()).Should(Equal(float64(87600))) + Expect(OSCtlplane.Spec.TLS.PodLevel.Ovn.Cert.Duration.Duration.Hours()).Should(Equal(float64(10950))) + }) + }) + // + // Validate TLS input settings -END + // + When("A public TLS OpenStackControlplane instance is created", func() { BeforeEach(func() { spec := GetDefaultOpenStackControlPlaneSpec()