diff --git a/apis/bases/core.openstack.org_openstackcontrolplanes.yaml b/apis/bases/core.openstack.org_openstackcontrolplanes.yaml index 6bd5672b6..96a213139 100644 --- a/apis/bases/core.openstack.org_openstackcontrolplanes.yaml +++ b/apis/bases/core.openstack.org_openstackcontrolplanes.yaml @@ -17476,6 +17476,10 @@ spec: type: string telemetryNodeExporterImage: type: string + testTempestImage: + type: string + testTobikoImage: + type: string type: object deployedOVNVersion: type: string diff --git a/apis/bases/core.openstack.org_openstackversions.yaml b/apis/bases/core.openstack.org_openstackversions.yaml index b48b8431a..a8a837853 100644 --- a/apis/bases/core.openstack.org_openstackversions.yaml +++ b/apis/bases/core.openstack.org_openstackversions.yaml @@ -201,6 +201,10 @@ spec: type: string telemetryNodeExporterImage: type: string + testTempestImage: + type: string + testTobikoImage: + type: string type: object targetVersion: type: string @@ -394,6 +398,10 @@ spec: type: string telemetryNodeExporterImage: type: string + testTempestImage: + type: string + testTobikoImage: + type: string type: object type: object containerImages: @@ -560,6 +568,10 @@ spec: type: string telemetryNodeExporterImage: type: string + testTempestImage: + type: string + testTobikoImage: + type: string type: object deployedVersion: type: string diff --git a/apis/core/v1beta1/conditions.go b/apis/core/v1beta1/conditions.go index 2dc3f1fa1..322b6b532 100644 --- a/apis/core/v1beta1/conditions.go +++ b/apis/core/v1beta1/conditions.go @@ -140,6 +140,9 @@ const ( // OpenStackControlPlaneExposeBarbicanReadyCondition Status=True condition which indicates if Barbican is exposed via a route OpenStackControlPlaneExposeBarbicanReadyCondition condition.Type = "OpenStackControlPlaneExposeBarbicanReady" + + // OpenStackControlPlaneTestCMReadyCondition Status=True condition which indicates if Test operator CM is ready + OpenStackControlPlaneTestCMReadyCondition condition.Type = "OpenStackControlPlaneTestCMReadyCondition" ) // Common Messages used by API objects. @@ -429,6 +432,15 @@ const ( // OpenStackControlPlaneCAReadyErrorMessage OpenStackControlPlaneCustomTLSReadyErrorMessage = "OpenStackControlPlane custom TLS cert secret %s error occured %s" + + // OpenStackControlPlaneTestCMReadyErrorMessage + OpenStackControlPlaneTestCMReadyErrorMessage = "OpenStackControlPlane Test Operator CM error occured %s" + + // OpenStackControlPlaneTestCMReadyMessage + OpenStackControlPlaneTestCMReadyMessage = "OpenStackControlPlane Test Operator CM is available" + + // OpenStackControlPlaneTestCMWaitingMessage + OpenStackControlPlaneTestCMWaitingMessage = "OpenStackControlPlane Test Operator CM is waiting for %s" ) // Version Conditions used by API objects. diff --git a/apis/core/v1beta1/openstackversion_types.go b/apis/core/v1beta1/openstackversion_types.go index 49b403507..de473d59b 100644 --- a/apis/core/v1beta1/openstackversion_types.go +++ b/apis/core/v1beta1/openstackversion_types.go @@ -145,6 +145,8 @@ type ContainerTemplate struct { SwiftObjectImage *string `json:"swiftObjectImage,omitempty"` SwiftProxyImage *string `json:"swiftProxyImage,omitempty"` TelemetryNodeExporterImage *string `json:"telemetryNodeExporterImage,omitempty"` + TestTempestImage *string `json:"testTempestImage,omitempty"` + TestTobikoImage *string `json:"testTobikoImage,omitempty"` } // OpenStackVersionStatus defines the observed state of OpenStackVersion diff --git a/apis/core/v1beta1/zz_generated.deepcopy.go b/apis/core/v1beta1/zz_generated.deepcopy.go index 5e8d1a0a0..35064a6d2 100644 --- a/apis/core/v1beta1/zz_generated.deepcopy.go +++ b/apis/core/v1beta1/zz_generated.deepcopy.go @@ -598,6 +598,16 @@ func (in *ContainerTemplate) DeepCopyInto(out *ContainerTemplate) { *out = new(string) **out = **in } + if in.TestTempestImage != nil { + in, out := &in.TestTempestImage, &out.TestTempestImage + *out = new(string) + **out = **in + } + if in.TestTobikoImage != nil { + in, out := &in.TestTobikoImage, &out.TestTobikoImage + *out = new(string) + **out = **in + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ContainerTemplate. diff --git a/cmd/csv-merger/csv-merger.go b/cmd/csv-merger/csv-merger.go index 2b9d22346..e01bf7201 100644 --- a/cmd/csv-merger/csv-merger.go +++ b/cmd/csv-merger/csv-merger.go @@ -96,6 +96,7 @@ var ( octaviaCsv = flag.String("octavia-csv", "", "Octavia CSV filename") designateCsv = flag.String("designate-csv", "", "Designate CSV filename") barbicanCsv = flag.String("barbican-csv", "", "Barbican CSV filename") + testCsv = flag.String("test-csv", "", "Test Operator CSV filename") csvOverrides = flag.String("csv-overrides", "", "CSV like string with punctual changes that will be recursively applied (if possible)") importEnvFiles = flag.String("import-env-files", "", "Comma separated list of file names to read default operator ENVs from. Used for inter-bundle ENV merging.") exportEnvFile = flag.String("export-env-file", "", "Name the external file to write operator ENVs to. Used for inter-bundle ENV merging.") @@ -144,6 +145,7 @@ func main() { *octaviaCsv, *designateCsv, *barbicanCsv, + *testCsv, } csvVersion := os.Getenv("CSV_VERSION") diff --git a/config/crd/bases/core.openstack.org_openstackcontrolplanes.yaml b/config/crd/bases/core.openstack.org_openstackcontrolplanes.yaml index 6bd5672b6..96a213139 100644 --- a/config/crd/bases/core.openstack.org_openstackcontrolplanes.yaml +++ b/config/crd/bases/core.openstack.org_openstackcontrolplanes.yaml @@ -17476,6 +17476,10 @@ spec: type: string telemetryNodeExporterImage: type: string + testTempestImage: + type: string + testTobikoImage: + type: string type: object deployedOVNVersion: type: string diff --git a/config/crd/bases/core.openstack.org_openstackversions.yaml b/config/crd/bases/core.openstack.org_openstackversions.yaml index b48b8431a..a8a837853 100644 --- a/config/crd/bases/core.openstack.org_openstackversions.yaml +++ b/config/crd/bases/core.openstack.org_openstackversions.yaml @@ -201,6 +201,10 @@ spec: type: string telemetryNodeExporterImage: type: string + testTempestImage: + type: string + testTobikoImage: + type: string type: object targetVersion: type: string @@ -394,6 +398,10 @@ spec: type: string telemetryNodeExporterImage: type: string + testTempestImage: + type: string + testTobikoImage: + type: string type: object type: object containerImages: @@ -560,6 +568,10 @@ spec: type: string telemetryNodeExporterImage: type: string + testTempestImage: + type: string + testTobikoImage: + type: string type: object deployedVersion: type: string diff --git a/controllers/core/openstackcontrolplane_controller.go b/controllers/core/openstackcontrolplane_controller.go index b9efde702..b259c329d 100644 --- a/controllers/core/openstackcontrolplane_controller.go +++ b/controllers/core/openstackcontrolplane_controller.go @@ -438,6 +438,13 @@ func (r *OpenStackControlPlaneReconciler) reconcileNormal(ctx context.Context, i return ctrlResult, nil } + ctrlResult, err = openstack.ReconcileTest(ctx, instance, version, helper) + if err != nil { + return ctrl.Result{}, err + } else if (ctrlResult != ctrl.Result{}) { + return ctrlResult, nil + } + return ctrl.Result{}, nil } diff --git a/hack/bundle-cache-data.sh b/hack/bundle-cache-data.sh index fc4495110..229c78f19 100755 --- a/hack/bundle-cache-data.sh +++ b/hack/bundle-cache-data.sh @@ -65,6 +65,7 @@ bin/csv-merger \ --octavia-csv=$CSV_DIR/octavia-operator.clusterserviceversion.yaml \ --designate-csv=$CSV_DIR/designate-operator.clusterserviceversion.yaml \ --barbican-csv=$CSV_DIR/barbican-operator.clusterserviceversion.yaml \ + --test-csv=$CSV_DIR/test-operator.clusterserviceversion.yaml \ --base-csv=config/manifests/bases/openstack-operator.clusterserviceversion.yaml | tee "$EXTRACT_DIR/out.yaml" # cleanup our temporary dir used for extraction diff --git a/hack/export_related_images.sh b/hack/export_related_images.sh index 2fa7e566a..9defd7979 100755 --- a/hack/export_related_images.sh +++ b/hack/export_related_images.sh @@ -79,4 +79,6 @@ export RELATED_IMAGE_EDPM_NEUTRON_METADATA_AGENT_IMAGE_URL_DEFAULT=quay.io/podif export RELATED_IMAGE_EDPM_NEUTRON_OVN_AGENT_IMAGE_URL_DEFAULT=quay.io/podified-antelope-centos9/openstack-neutron-ovn-agent:current-podified export RELATED_IMAGE_EDPM_NEUTRON_SRIOV_AGENT_IMAGE_URL_DEFAULT=quay.io/podified-antelope-centos9/openstack-neutron-sriov-agent:current-podified export RELATED_IMAGE_EDPM_OVN_BGP_AGENT_IMAGE_URL_DEFAULT=quay.io/podified-antelope-centos9/openstack-ovn-bgp-agent:current-podified -export RELATED_IMAGE_EDPM_NODE_EXPORTER_IMAGE_URL_DEFAULT=quay.io/prometheus/node-exporter:v1.5.0 +export RELATED_IMAGE_EDPM_NODE_EXPORTER_IMAGE_URL_DEFAULT=quay.io/prometheus/node-exporter:v1.5 +export RELATED_IMAGE_TEST_TEMPEST_IMAGE_URL_DEFAULT=quay.io/podified-antelope-centos9/openstack-tempest-all:current-podified +export RELATED_IMAGE_TEST_TOBIKO_IMAGE_URL_DEFAULT=quay.io/podified-antelope-centos9/openstack-tobiko:current-podified diff --git a/pkg/openstack/test.go b/pkg/openstack/test.go new file mode 100644 index 000000000..0475ec9fe --- /dev/null +++ b/pkg/openstack/test.go @@ -0,0 +1,77 @@ +package openstack + +import ( + "context" + "time" + + "github.com/openstack-k8s-operators/lib-common/modules/common/condition" + "github.com/openstack-k8s-operators/lib-common/modules/common/configmap" + "github.com/openstack-k8s-operators/lib-common/modules/common/helper" + "github.com/openstack-k8s-operators/lib-common/modules/common/util" + + corev1beta1 "github.com/openstack-k8s-operators/openstack-operator/apis/core/v1beta1" + k8s_errors "k8s.io/apimachinery/pkg/api/errors" + ctrl "sigs.k8s.io/controller-runtime" +) + +const ( + // config map generated by Keyston operator containing clouds.yaml + CloudsConfigMap = "openstack-config" + TestOperatorConfigMap = "test-operator-config" + + TempestImageKey = "tempest-image" + TobikoImageKey = "tobiko-image" + CloudsKey = "clouds-secret-name" +) + +func ReconcileTest(ctx context.Context, instance *corev1beta1.OpenStackControlPlane, version *corev1beta1.OpenStackVersion, helper *helper.Helper) (ctrl.Result, error) { + customData := map[string]string{ + TempestImageKey: *version.Status.ContainerImages.TestTempestImage, + TobikoImageKey: *version.Status.ContainerImages.TestTobikoImage, + CloudsKey: CloudsConfigMap, + } + + _, _, err := configmap.GetConfigMapAndHashWithName(ctx, helper, CloudsConfigMap, instance.Namespace) + if err != nil { + if k8s_errors.IsNotFound(err) { + instance.Status.Conditions.Set(condition.FalseCondition( + corev1beta1.OpenStackControlPlaneTestCMReadyCondition, + condition.ErrorReason, + condition.SeverityWarning, + corev1beta1.OpenStackControlPlaneTestCMWaitingMessage, + CloudsConfigMap)) + + timeout := time.Second * 10 + return ctrl.Result{RequeueAfter: timeout}, nil + } + } + + cms := []util.Template{ + { + Name: TestOperatorConfigMap, + Namespace: instance.Namespace, + InstanceType: instance.Kind, + Labels: nil, + ConfigOptions: nil, + CustomData: customData, + }, + } + + if err := configmap.EnsureConfigMaps(ctx, helper, instance, cms, nil); err != nil { + instance.Status.Conditions.Set(condition.FalseCondition( + corev1beta1.OpenStackControlPlaneTestCMReadyCondition, + condition.ErrorReason, + condition.SeverityWarning, + corev1beta1.OpenStackControlPlaneTestCMReadyErrorMessage, + err.Error())) + + return ctrl.Result{}, err + } + + instance.Status.Conditions.Set(condition.TrueCondition( + corev1beta1.OpenStackControlPlaneTestCMReadyCondition, + corev1beta1.OpenStackControlPlaneTestCMReadyMessage, + )) + + return ctrl.Result{}, nil +} diff --git a/pkg/openstack/version.go b/pkg/openstack/version.go index f92f3d698..d70536341 100644 --- a/pkg/openstack/version.go +++ b/pkg/openstack/version.go @@ -153,6 +153,8 @@ func GetContainerImages(defaults *corev1beta1.ContainerDefaults, instance corev1 SwiftObjectImage: getImg(instance.Spec.CustomContainerImages.SwiftObjectImage, defaults.SwiftObjectImage), SwiftProxyImage: getImg(instance.Spec.CustomContainerImages.SwiftProxyImage, defaults.SwiftProxyImage), TelemetryNodeExporterImage: getImg(instance.Spec.CustomContainerImages.TelemetryNodeExporterImage, defaults.TelemetryNodeExporterImage), + TestTempestImage: getImg(instance.Spec.CustomContainerImages.TestTempestImage, defaults.TestTempestImage), + TestTobikoImage: getImg(instance.Spec.CustomContainerImages.TestTobikoImage, defaults.TestTobikoImage), }} if containerImages.CinderVolumeImages == nil { containerImages.CinderVolumeImages = make(map[string]*string)