From 74c030b25a3cc360760d47010a52ca991de83a02 Mon Sep 17 00:00:00 2001 From: Jiri Podivin Date: Fri, 14 Jun 2024 16:34:14 +0200 Subject: [PATCH] Introducing spec level validation of dataplane/controlplane TLS consistency Verifies that TLS settings for nodeset are consistent with those of existing control plane, if there is one and only one. If there are multiple control planes the process will result in error, same if it isn't possible to retrieve list of control planes. Tests are included Signed-off-by: Jiri Podivin --- .../openstackdataplanenodeset_types.go | 48 ++++ ...openstackdataplanedeployment_controller.go | 11 + tests/functional/dataplane/base_test.go | 32 +++ ...tackdataplanedeployment_controller_test.go | 212 +++++++++++++++++- tests/functional/dataplane/service_test.go | 66 ++++++ tests/functional/dataplane/suite_test.go | 16 +- .../00-controlplane-create.yaml | 190 ++++++++++++++++ .../00-dataplane-create.yaml | 2 +- 8 files changed, 569 insertions(+), 8 deletions(-) create mode 100644 tests/functional/dataplane/service_test.go create mode 100644 tests/kuttl/tests/dataplane-deploy-global-service-test/00-controlplane-create.yaml diff --git a/apis/dataplane/v1beta1/openstackdataplanenodeset_types.go b/apis/dataplane/v1beta1/openstackdataplanenodeset_types.go index 83e3a9bb5..e350efb85 100644 --- a/apis/dataplane/v1beta1/openstackdataplanenodeset_types.go +++ b/apis/dataplane/v1beta1/openstackdataplanenodeset_types.go @@ -17,9 +17,11 @@ limitations under the License. package v1beta1 import ( + "context" "fmt" "golang.org/x/exp/slices" + "sigs.k8s.io/controller-runtime/pkg/client" infranetworkv1 "github.com/openstack-k8s-operators/infra-operator/apis/network/v1beta1" condition "github.com/openstack-k8s-operators/lib-common/modules/common/condition" @@ -290,3 +292,49 @@ func (r *OpenStackDataPlaneNodeSetSpec) duplicateNodeCheck(nodeSetList *OpenStac return } + +// Compare TLS settings of control plane and data plane +// if control plane name is specified attempt to retrieve it +// otherwise get any control plane in the namespace +func (r *OpenStackDataPlaneNodeSetSpec) ValidateTLS(namespace string, reconcilerClient client.Client, ctx context.Context) error { + var err error + controlPlanes := openstackv1.OpenStackControlPlaneList{} + opts := client.ListOptions{ + Namespace: namespace, + } + + // Attempt to get list of all ControlPlanes fail if that isn't possible + if err = reconcilerClient.List(ctx, &controlPlanes, &opts); err != nil { + return err + } + // Verify TLS status of control plane only if there is a single one + // report error if there are multiple, or proceed if there are none + if len(controlPlanes.Items) > 1 { + err = fmt.Errorf("multiple control planes found in the namespace %s", namespace) + } else if len(controlPlanes.Items) == 1 { + controlPlane := controlPlanes.Items[0] + fieldErr := r.TLSMatch(controlPlane) + if fieldErr != nil { + err = fmt.Errorf("%s", fieldErr.Error()) + } + } + + return err +} + +// Do TLS flags match in control plane ingress, pods and data plane +func (r *OpenStackDataPlaneNodeSetSpec) TLSMatch(controlPlane openstackv1.OpenStackControlPlane) *field.Error { + + if controlPlane.Spec.TLS.Ingress.Enabled != r.TLSEnabled || controlPlane.Spec.TLS.PodLevel.Enabled != r.TLSEnabled { + + return field.Forbidden( + field.NewPath("spec.tlsEnabled"), + fmt.Sprintf( + "TLS settings on Data Plane node set and Control Plane %s do not match, Node set: %t Control Plane Ingress: %t Control Plane PodLevel: %t", + controlPlane.Name, + r.TLSEnabled, + controlPlane.Spec.TLS.Ingress.Enabled, + controlPlane.Spec.TLS.PodLevel.Enabled)) + } + return nil +} diff --git a/controllers/dataplane/openstackdataplanedeployment_controller.go b/controllers/dataplane/openstackdataplanedeployment_controller.go index 170e25ec7..54d66508b 100644 --- a/controllers/dataplane/openstackdataplanedeployment_controller.go +++ b/controllers/dataplane/openstackdataplanedeployment_controller.go @@ -62,6 +62,7 @@ func (r *OpenStackDataPlaneDeploymentReconciler) GetLogger(ctx context.Context) //+kubebuilder:rbac:groups=discovery.k8s.io,resources=endpointslices,verbs=get;list;watch;create;update;patch;delete; //+kubebuilder:rbac:groups=cert-manager.io,resources=issuers,verbs=get;list;watch; //+kubebuilder:rbac:groups=cert-manager.io,resources=certificates,verbs=get;list;watch;create;update;patch;delete; +//+kubebuilder:rbac:groups=core.openstack.org,resources=openstackcontrolplanes,verbs=get;list;watch; // Reconcile is part of the main kubernetes reconciliation loop which aims to // move the current state of the cluster closer to the desired state. @@ -183,6 +184,16 @@ func (r *OpenStackDataPlaneDeploymentReconciler) Reconcile(ctx context.Context, // Error reading the object - requeue the request. return ctrl.Result{}, err } + if err = nodeSetInstance.Spec.ValidateTLS(instance.GetNamespace(), r.Client, ctx); err != nil { + Log.Info("error while comparing TLS settings of nodeset %s with control plane: %w", nodeSet, err) + instance.Status.Conditions.MarkFalse( + dataplanev1.SetupReadyCondition, + condition.ErrorReason, + condition.SeverityError, + dataplanev1.DataPlaneNodeSetErrorMessage, + err.Error()) + return ctrl.Result{}, err + } nodeSets.Items = append(nodeSets.Items, *nodeSetInstance) } diff --git a/tests/functional/dataplane/base_test.go b/tests/functional/dataplane/base_test.go index 509a9a23f..ba1e23239 100644 --- a/tests/functional/dataplane/base_test.go +++ b/tests/functional/dataplane/base_test.go @@ -344,6 +344,38 @@ func DefaultDataplaneGlobalService(name types.NamespacedName) map[string]interfa } } +// Create simple OpenStackControlPlane +func CreateOpenStackControlPlane(name types.NamespacedName, tlsEnabled bool) *unstructured.Unstructured { + + raw := map[string]interface{}{ + "apiVersion": "core.openstack.org/v1beta1", + "kind": "OpenStackControlPlane", + "metadata": map[string]interface{}{ + "name": name.Name, + "namespace": name.Namespace, + }, + "spec": map[string]interface{}{ + "secret": "osp-secret", + "storageClass": "local-storage", + "tls": map[string]interface{}{ + "ingress": map[string]interface{}{ + "enabled": tlsEnabled, + "ca": map[string]interface{}{ + "duration": "100h", + }, + "cert": map[string]interface{}{ + "duration": "10h", + }, + }, + "podLevel": map[string]interface{}{ + "enabled": tlsEnabled, + }, + }, + }, + } + return th.CreateUnstructured(raw) +} + // Get resources // Retrieve OpenStackDataPlaneDeployment and check for errors diff --git a/tests/functional/dataplane/openstackdataplanedeployment_controller_test.go b/tests/functional/dataplane/openstackdataplanedeployment_controller_test.go index 556851ccf..4e5b1734c 100644 --- a/tests/functional/dataplane/openstackdataplanedeployment_controller_test.go +++ b/tests/functional/dataplane/openstackdataplanedeployment_controller_test.go @@ -18,6 +18,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/types" + "k8s.io/utils/ptr" ) var _ = Describe("Dataplane Deployment Test", func() { @@ -36,6 +37,7 @@ var _ = Describe("Dataplane Deployment Test", func() { var dataplaneServiceName types.NamespacedName var dataplaneUpdateServiceName types.NamespacedName var dataplaneGlobalServiceName types.NamespacedName + var controlPlaneName types.NamespacedName BeforeEach(func() { dnsMasqName = types.NamespacedName{ @@ -98,7 +100,11 @@ var _ = Describe("Dataplane Deployment Test", func() { Name: "global-service", Namespace: namespace, } - err := os.Setenv("OPERATOR_SERVICES", "../../../config/services") + controlPlaneName = types.NamespacedName{ + Name: "mock-control-plane", + Namespace: namespace, + } + err := os.Setenv("OPERATOR_SERVICES", "../../config/services") Expect(err).NotTo(HaveOccurred()) }) @@ -719,4 +725,208 @@ var _ = Describe("Dataplane Deployment Test", func() { ) }) }) + + When("A user sets TLSEnabled to true with control plane TLS disabled", func() { + BeforeEach(func() { + CreateSSHSecret(dataplaneSSHSecretName) + DeferCleanup(th.DeleteInstance, th.CreateSecret(neutronOvnMetadataSecretName, map[string][]byte{ + "fake_keys": []byte("blih"), + })) + DeferCleanup(th.DeleteInstance, th.CreateSecret(novaNeutronMetadataSecretName, map[string][]byte{ + "fake_keys": []byte("blih"), + })) + DeferCleanup(th.DeleteInstance, th.CreateSecret(novaCellComputeConfigSecretName, map[string][]byte{ + "fake_keys": []byte("blih"), + })) + DeferCleanup(th.DeleteInstance, th.CreateSecret(novaMigrationSSHKey, map[string][]byte{ + "ssh-privatekey": []byte("fake-ssh-private-key"), + "ssh-publickey": []byte("fake-ssh-public-key"), + })) + DeferCleanup(th.DeleteInstance, th.CreateSecret(ceilometerConfigSecretName, map[string][]byte{ + "fake_keys": []byte("blih"), + })) + // DefaultDataPlanenodeSetSpec comes with two mock services, one marked for deployment on all nodesets + DeferCleanup(th.DeleteInstance, CreateDataplaneService(dataplaneServiceName, false)) + DeferCleanup(th.DeleteInstance, CreateDataplaneService(dataplaneGlobalServiceName, true)) + + DeferCleanup(th.DeleteService, dataplaneServiceName) + DeferCleanup(th.DeleteService, dataplaneGlobalServiceName) + DeferCleanup(th.DeleteInstance, CreateNetConfig(dataplaneNetConfigName, DefaultNetConfigSpec())) + DeferCleanup(th.DeleteInstance, CreateDNSMasq(dnsMasqName, DefaultDNSMasqSpec())) + SimulateDNSMasqComplete(dnsMasqName) + DeferCleanup(th.DeleteInstance, CreateDataplaneNodeSet(dataplaneNodeSetName, DefaultDataPlaneNodeSetSpec(dataplaneNodeSetName.Name))) + DeferCleanup(th.DeleteInstance, CreateDataplaneDeployment(dataplaneDeploymentName, DefaultDataPlaneDeploymentSpec())) + SimulateIPSetComplete(dataplaneNodeName) + SimulateDNSDataComplete(dataplaneNodeSetName) + + DeferCleanup(th.DeleteInstance, CreateOpenStackControlPlane(controlPlaneName, false)) + }) + + It("Should have Spec fields initialized", func() { + dataplaneDeploymentInstance := GetDataplaneDeployment(dataplaneDeploymentName) + expectedSpec := dataplanev1.OpenStackDataPlaneDeploymentSpec{ + NodeSets: []string{"edpm-compute-nodeset"}, + AnsibleTags: "", + AnsibleLimit: "", + AnsibleSkipTags: "", + DeploymentRequeueTime: 15, + ServicesOverride: nil, + BackoffLimit: ptr.To(int32(6)), + } + Expect(dataplaneDeploymentInstance.Spec).Should(Equal(expectedSpec)) + }) + + It("should have ready condiction set to false and input condition set to unknown", func() { + + nodeSet := dataplanev1.OpenStackDataPlaneNodeSet{} + baremetal := baremetalv1.OpenStackBaremetalSet{ + ObjectMeta: metav1.ObjectMeta{ + Name: nodeSet.Name, + Namespace: nodeSet.Namespace, + }, + } + // Create config map for OVN service + ovnConfigMapName := types.NamespacedName{ + Namespace: namespace, + Name: "ovncontroller-config", + } + mapData := map[string]interface{}{ + "ovsdb-config": "test-ovn-config", + } + th.CreateConfigMap(ovnConfigMapName, mapData) + + nodeSet = *GetDataplaneNodeSet(dataplaneNodeSetName) + + // Set baremetal provisioning conditions to True + Eventually(func(g Gomega) { + // OpenStackBaremetalSet has the same name as OpenStackDataPlaneNodeSet + g.Expect(th.K8sClient.Get(th.Ctx, dataplaneNodeSetName, &baremetal)).To(Succeed()) + baremetal.Status.Conditions.MarkTrue( + condition.ReadyCondition, + condition.ReadyMessage) + g.Expect(th.K8sClient.Status().Update(th.Ctx, &baremetal)).To(Succeed()) + + }, th.Timeout, th.Interval).Should(Succeed()) + + th.ExpectCondition( + dataplaneDeploymentName, + ConditionGetterFunc(DataplaneDeploymentConditionGetter), + condition.ReadyCondition, + corev1.ConditionFalse, + ) + th.ExpectCondition( + dataplaneDeploymentName, + ConditionGetterFunc(DataplaneDeploymentConditionGetter), + condition.InputReadyCondition, + corev1.ConditionUnknown, + ) + }) + + }) + + When("A user sets TLSEnabled to true with control plane TLS enabled", func() { + BeforeEach(func() { + CreateSSHSecret(dataplaneSSHSecretName) + DeferCleanup(th.DeleteInstance, th.CreateSecret(neutronOvnMetadataSecretName, map[string][]byte{ + "fake_keys": []byte("blih"), + })) + DeferCleanup(th.DeleteInstance, th.CreateSecret(novaNeutronMetadataSecretName, map[string][]byte{ + "fake_keys": []byte("blih"), + })) + DeferCleanup(th.DeleteInstance, th.CreateSecret(novaCellComputeConfigSecretName, map[string][]byte{ + "fake_keys": []byte("blih"), + })) + DeferCleanup(th.DeleteInstance, th.CreateSecret(novaMigrationSSHKey, map[string][]byte{ + "ssh-privatekey": []byte("fake-ssh-private-key"), + "ssh-publickey": []byte("fake-ssh-public-key"), + })) + DeferCleanup(th.DeleteInstance, th.CreateSecret(ceilometerConfigSecretName, map[string][]byte{ + "fake_keys": []byte("blih"), + })) + // DefaultDataPlanenodeSetSpec comes with two mock services, one marked for deployment on all nodesets + DeferCleanup(th.DeleteInstance, CreateDataplaneService(dataplaneServiceName, false)) + DeferCleanup(th.DeleteInstance, CreateDataplaneService(dataplaneUpdateServiceName, false)) + CreateDataplaneService(dataplaneGlobalServiceName, true) + + DeferCleanup(th.DeleteService, dataplaneServiceName) + DeferCleanup(th.DeleteService, dataplaneGlobalServiceName) + DeferCleanup(th.DeleteInstance, CreateNetConfig(dataplaneNetConfigName, DefaultNetConfigSpec())) + DeferCleanup(th.DeleteInstance, CreateDNSMasq(dnsMasqName, DefaultDNSMasqSpec())) + SimulateDNSMasqComplete(dnsMasqName) + DeferCleanup(th.DeleteInstance, CreateDataplaneNodeSet(dataplaneNodeSetName, DefaultDataPlaneNodeSetSpec(dataplaneNodeSetName.Name))) + DeferCleanup(th.DeleteInstance, CreateDataplaneDeployment(dataplaneDeploymentName, DefaultDataPlaneDeploymentSpec())) + SimulateIPSetComplete(dataplaneNodeName) + SimulateDNSDataComplete(dataplaneNodeSetName) + + DeferCleanup(th.DeleteInstance, CreateOpenStackControlPlane(controlPlaneName, true)) + }) + + It("Should have Spec fields initialized", func() { + dataplaneDeploymentInstance := GetDataplaneDeployment(dataplaneDeploymentName) + expectedSpec := dataplanev1.OpenStackDataPlaneDeploymentSpec{ + NodeSets: []string{"edpm-compute-nodeset"}, + AnsibleTags: "", + AnsibleLimit: "", + AnsibleSkipTags: "", + DeploymentRequeueTime: 15, + ServicesOverride: nil, + BackoffLimit: ptr.To(int32(6)), + } + Expect(dataplaneDeploymentInstance.Spec).Should(Equal(expectedSpec)) + }) + + It("should have ready condiction set to false, input condition set to true and nodeset setup ready condition set to true", func() { + + nodeSet := dataplanev1.OpenStackDataPlaneNodeSet{} + baremetal := baremetalv1.OpenStackBaremetalSet{ + ObjectMeta: metav1.ObjectMeta{ + Name: nodeSet.Name, + Namespace: nodeSet.Namespace, + }, + } + // Create config map for OVN service + ovnConfigMapName := types.NamespacedName{ + Namespace: namespace, + Name: "ovncontroller-config", + } + mapData := map[string]interface{}{ + "ovsdb-config": "test-ovn-config", + } + th.CreateConfigMap(ovnConfigMapName, mapData) + + nodeSet = *GetDataplaneNodeSet(dataplaneNodeSetName) + + // Set baremetal provisioning conditions to True + Eventually(func(g Gomega) { + // OpenStackBaremetalSet has the same name as OpenStackDataPlaneNodeSet + g.Expect(th.K8sClient.Get(th.Ctx, dataplaneNodeSetName, &baremetal)).To(Succeed()) + baremetal.Status.Conditions.MarkTrue( + condition.ReadyCondition, + condition.ReadyMessage) + g.Expect(th.K8sClient.Status().Update(th.Ctx, &baremetal)).To(Succeed()) + + }, th.Timeout, th.Interval).Should(Succeed()) + + th.ExpectCondition( + dataplaneNodeSetName, + ConditionGetterFunc(DataplaneConditionGetter), + dataplanev1.SetupReadyCondition, + corev1.ConditionTrue, + ) + th.ExpectCondition( + dataplaneDeploymentName, + ConditionGetterFunc(DataplaneDeploymentConditionGetter), + condition.ReadyCondition, + corev1.ConditionFalse, + ) + th.ExpectCondition( + dataplaneDeploymentName, + ConditionGetterFunc(DataplaneDeploymentConditionGetter), + condition.InputReadyCondition, + corev1.ConditionTrue, + ) + }) + + }) + }) diff --git a/tests/functional/dataplane/service_test.go b/tests/functional/dataplane/service_test.go new file mode 100644 index 000000000..c1d5d9b2a --- /dev/null +++ b/tests/functional/dataplane/service_test.go @@ -0,0 +1,66 @@ +/* +Copyright 2023. + +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 functional + +import ( + "os" + + . "github.com/onsi/ginkgo/v2" //revive:disable:dot-imports + . "github.com/onsi/gomega" //revive:disable:dot-imports + "k8s.io/apimachinery/pkg/types" +) + +var _ = Describe("OpenstackDataplaneService Test", func() { + var dataplaneServiceName types.NamespacedName + BeforeEach(func() { + dataplaneServiceName = types.NamespacedName{ + Namespace: namespace, + Name: "configure-network", + } + }) + + When("A defined service resource is created", func() { + BeforeEach(func() { + os.Unsetenv("OPERATOR_SERVICES") + CreateDataplaneService(dataplaneServiceName, false) + DeferCleanup(th.DeleteService, dataplaneServiceName) + }) + + It("spec fields are set up", func() { + service := GetService(dataplaneServiceName) + Expect(service.Spec.Secrets).To(BeEmpty()) + Expect(service.Spec.Playbook).To(BeEmpty()) + Expect(service.Spec.ConfigMaps).To(BeEmpty()) + Expect(service.Spec.DeployOnAllNodeSets).To(BeFalse()) + }) + }) + + When("A defined service resource for all nodes is created", func() { + BeforeEach(func() { + os.Unsetenv("OPERATOR_SERVICES") + CreateDataplaneService(dataplaneServiceName, true) + DeferCleanup(th.DeleteService, dataplaneServiceName) + }) + + It("spec fields are set up", func() { + service := GetService(dataplaneServiceName) + Expect(service.Spec.Secrets).To(BeEmpty()) + Expect(service.Spec.Playbook).To(BeEmpty()) + Expect(service.Spec.ConfigMaps).To(BeEmpty()) + Expect(service.Spec.DeployOnAllNodeSets).To(BeTrue()) + }) + }) +}) diff --git a/tests/functional/dataplane/suite_test.go b/tests/functional/dataplane/suite_test.go index bb56410aa..412e8630e 100644 --- a/tests/functional/dataplane/suite_test.go +++ b/tests/functional/dataplane/suite_test.go @@ -26,6 +26,9 @@ import ( "github.com/google/uuid" . "github.com/onsi/ginkgo/v2" //revive:disable:dot-imports . "github.com/onsi/gomega" //revive:disable:dot-imports + openstackv1 "github.com/openstack-k8s-operators/openstack-operator/apis/core/v1beta1" + dataplanev1 "github.com/openstack-k8s-operators/openstack-operator/apis/dataplane/v1beta1" + dataplanecontrollers "github.com/openstack-k8s-operators/openstack-operator/controllers/dataplane" "k8s.io/client-go/kubernetes" "k8s.io/client-go/kubernetes/scheme" ctrl "sigs.k8s.io/controller-runtime" @@ -44,9 +47,6 @@ import ( infrav1 "github.com/openstack-k8s-operators/infra-operator/apis/network/v1beta1" aee "github.com/openstack-k8s-operators/openstack-ansibleee-operator/api/v1beta1" baremetalv1 "github.com/openstack-k8s-operators/openstack-baremetal-operator/api/v1beta1" - openstackv1 "github.com/openstack-k8s-operators/openstack-operator/apis/core/v1beta1" - dataplanev1 "github.com/openstack-k8s-operators/openstack-operator/apis/dataplane/v1beta1" - dataplanecontrollers "github.com/openstack-k8s-operators/openstack-operator/controllers/dataplane" //revive:disable-next-line:dot-imports . "github.com/openstack-k8s-operators/lib-common/modules/common/test/helpers" @@ -79,7 +79,7 @@ const ( func TestAPIs(t *testing.T) { RegisterFailHandler(Fail) - RunSpecs(t, "DataPlane Controller Suite") + RunSpecs(t, "Controller Suite") } var _ = BeforeSuite(func() { @@ -98,6 +98,9 @@ var _ = BeforeSuite(func() { infraCRDs, err := test.GetCRDDirFromModule( "github.com/openstack-k8s-operators/infra-operator/apis", gomod, "bases") Expect(err).ShouldNot(HaveOccurred()) + openstackCRDs, err := test.GetCRDDirFromModule( + "github.com/openstack-k8s-operators/openstack-operator/apis", gomod, "bases") + Expect(err).ShouldNot(HaveOccurred()) By("bootstrapping test environment") testEnv = &envtest.Environment{ @@ -106,6 +109,7 @@ var _ = BeforeSuite(func() { aeeCRDs, baremetalCRDs, infraCRDs, + openstackCRDs, }, WebhookInstallOptions: envtest.WebhookInstallOptions{ Paths: []string{filepath.Join("..", "..", "..", "config", "webhook")}, @@ -125,7 +129,7 @@ var _ = BeforeSuite(func() { // NOTE(gibi): Need to add all API schemas our operator can own. // Keep this in synch with SetupWithManager, otherwise the reconciler loop // will silently not start in the test env. - err = dataplanev1.AddToScheme(scheme.Scheme) + err = openstackv1.AddToScheme(scheme.Scheme) Expect(err).NotTo(HaveOccurred()) err = aee.AddToScheme(scheme.Scheme) Expect(err).NotTo(HaveOccurred()) @@ -143,7 +147,7 @@ var _ = BeforeSuite(func() { Expect(err).NotTo(HaveOccurred()) //+kubebuilder:scaffold:scheme - logger = ctrl.Log.WithName("---DataPlane Test---") + logger = ctrl.Log.WithName("---Test---") k8sClient, err = client.New(cfg, client.Options{Scheme: scheme.Scheme}) Expect(err).NotTo(HaveOccurred()) diff --git a/tests/kuttl/tests/dataplane-deploy-global-service-test/00-controlplane-create.yaml b/tests/kuttl/tests/dataplane-deploy-global-service-test/00-controlplane-create.yaml new file mode 100644 index 000000000..da7b47f8f --- /dev/null +++ b/tests/kuttl/tests/dataplane-deploy-global-service-test/00-controlplane-create.yaml @@ -0,0 +1,190 @@ +apiVersion: core.openstack.org/v1beta1 +kind: OpenStackControlPlane +metadata: + name: openstack-basic +spec: + secret: osp-secret + storageClass: local-storage + keystone: + template: + databaseInstance: openstack + secret: osp-secret + galera: + templates: + openstack: + storageClass: local-storage + storageRequest: 500M + secret: osp-secret + replicas: 1 + openstack-cell1: + storageClass: local-storage + storageRequest: 500M + secret: osp-secret + replicas: 1 + rabbitmq: + templates: + rabbitmq: + replicas: 1 + rabbitmq-cell1: + replicas: 1 + memcached: + templates: + memcached: + replicas: 1 + barbican: + template: + databaseInstance: openstack + secret: osp-secret + barbicanAPI: + replicas: 1 + barbicanWorker: + replicas: 1 + barbicanKeystoneListener: + replicas: 1 + placement: + template: + databaseInstance: openstack + secret: osp-secret + glance: + template: + secret: osp-secret + databaseInstance: openstack + storageClass: "" + storageRequest: 10G + keystoneEndpoint: default + glanceAPIs: + default: + type: single + replicas: 1 + cinder: + template: + databaseInstance: openstack + secret: osp-secret + cinderAPI: + replicas: 1 + cinderScheduler: + replicas: 1 + cinderBackup: + replicas: 0 # backend needs to be configured + cinderVolumes: + volume1: + replicas: 0 # backend needs to be configured + manila: + template: + manilaAPI: + replicas: 1 + manilaScheduler: + replicas: 1 + manilaShares: + share1: + replicas: 1 + ovn: + template: + ovnDBCluster: + ovndbcluster-nb: + replicas: 1 + dbType: NB + storageRequest: 10G + ovndbcluster-sb: + replicas: 1 + dbType: SB + storageRequest: 10G + ovnNorthd: + replicas: 1 + ovnController: {} + neutron: + template: + databaseInstance: openstack + secret: osp-secret + horizon: + template: + replicas: 1 + secret: osp-secret + nova: + template: + secret: osp-secret + heat: + enabled: false + template: + databaseInstance: openstack + heatAPI: + replicas: 1 + heatEngine: + replicas: 1 + secret: osp-secret + ironic: + enabled: false + template: + databaseInstance: openstack + ironicAPI: + replicas: 1 + ironicConductors: + - replicas: 1 + storageRequest: 10G + ironicInspector: + replicas: 1 + ironicNeutronAgent: + replicas: 1 + secret: osp-secret + telemetry: + enabled: true + template: + metricStorage: + enabled: false + monitoringStack: + alertingEnabled: true + scrapeInterval: 30s + storage: + strategy: persistent + retention: 24h + persistent: + pvcStorageRequest: 20G + autoscaling: + enabled: false + aodh: + passwordSelectors: + databaseAccount: aodh + databaseInstance: openstack + secret: osp-secret + heatInstance: heat + ceilometer: + enabled: true + secret: osp-secret + logging: + enabled: false + network: internalapi + ipaddr: 172.17.0.80 + port: 10514 + cloNamespace: openshift-logging + swift: + enabled: true + template: + swiftRing: + ringReplicas: 1 + swiftStorage: + replicas: 1 + swiftProxy: + replicas: 1 + octavia: + enabled: false + template: + databaseInstance: openstack + octaviaAPI: + replicas: 1 + secret: osp-secret + designate: + template: + databaseInstance: openstack + secret: osp-secret + designateAPI: + replicas: 1 + designateCentral: + replicas: 0 # backend needs to be configured + designateWorker: + replicas: 0 # backend needs to be configured + designateProducer: + replicas: 0 # backend needs to be configured + designateMdns: + replicas: 0 # backend needs to be configured + designateBackendbind9: + replicas: 0 # backend needs to be configured diff --git a/tests/kuttl/tests/dataplane-deploy-global-service-test/00-dataplane-create.yaml b/tests/kuttl/tests/dataplane-deploy-global-service-test/00-dataplane-create.yaml index b3d048c89..aaeb523ed 100644 --- a/tests/kuttl/tests/dataplane-deploy-global-service-test/00-dataplane-create.yaml +++ b/tests/kuttl/tests/dataplane-deploy-global-service-test/00-dataplane-create.yaml @@ -141,7 +141,7 @@ spec: memReqs: gbReq: {} preProvisioned: true - tlsEnabled: false + tlsEnabled: true services: - download-cache - bootstrap