From 91ba288fe3afdf7eb79733a48de3125b96139813 Mon Sep 17 00:00:00 2001 From: Oded Viner <61982127+OdedViner@users.noreply.github.com> Date: Wed, 24 Jul 2024 18:39:44 +0300 Subject: [PATCH] Version details for DR operators (#9956) * Version details for all DR components Signed-off-by: oviner --- ocs_ci/framework/__init__.py | 27 ++++++++ ocs_ci/ocs/constants.py | 1 + ocs_ci/ocs/resources/ocs.py | 17 ++++- ocs_ci/ocs/utils.py | 73 ++++++++++++++++++++- ocs_ci/utility/utils.py | 6 +- ocs_ci/utility/version.py | 119 +++++++++++++++++++++++++++++++++++ tests/conftest.py | 5 ++ 7 files changed, 243 insertions(+), 5 deletions(-) diff --git a/ocs_ci/framework/__init__.py b/ocs_ci/framework/__init__.py index 18e73ffbf34..4e61f85c14f 100644 --- a/ocs_ci/framework/__init__.py +++ b/ocs_ci/framework/__init__.py @@ -451,6 +451,33 @@ def switch_to_cluster_by_cluster_type(self, cluster_type, num_of_cluster=0): self.get_cluster_type_indices_list(cluster_type)[num_of_cluster] ) + class RunWithConfigContext(object): + def __init__(self, config_index): + self.original_config_index = config.cur_index + self.config_index = config_index + + def __enter__(self): + config.switch_ctx(self.config_index) + return self + + def __exit__(self, exc_type, exc_value, exc_traceback): + config.switch_ctx(self.original_config_index) + + class RunWithAcmConfigContext(RunWithConfigContext): + def __init__(self): + from ocs_ci.ocs.utils import get_all_acm_indexes + + acm_index = get_all_acm_indexes()[0] + super().__init__(acm_index) + + class RunWithPrimaryConfigContext(RunWithConfigContext): + def __init__(self): + from ocs_ci.ocs.utils import get_primary_cluster_config + + primary_config = get_primary_cluster_config() + primary_index = primary_config.MULTICLUSTER.get("multicluster_index") + super().__init__(primary_index) + config = MultiClusterConfig() diff --git a/ocs_ci/ocs/constants.py b/ocs_ci/ocs/constants.py index 1c381ff24ea..4a1486306c5 100644 --- a/ocs_ci/ocs/constants.py +++ b/ocs_ci/ocs/constants.py @@ -250,6 +250,7 @@ TEST_FILES_BUCKET = "ocsci-test-files" ROOK_REPOSITORY = "https://github.com/rook/rook.git" OPENSHIFT_STORAGE_NAMESPACE = "openshift-storage" +OPENSHIFT_NAMESPACE = "openshift" OPENSHIFT_STORAGE_CLIENT_NAMESPACE = "openshift-storage-client" OPENSHIFT_STORAGE_EXTENDED_NAMESPACE = "openshift-storage-extended" OPENSHIFT_STORAGE_CLIENT_NAMESPACE = "openshift-storage-client" diff --git a/ocs_ci/ocs/resources/ocs.py b/ocs_ci/ocs/resources/ocs.py index aff3600ce5e..d98b342595c 100644 --- a/ocs_ci/ocs/resources/ocs.py +++ b/ocs_ci/ocs/resources/ocs.py @@ -194,6 +194,19 @@ def __setstate__(self, d): def get_version_info(namespace=None): + """ + Get OCS versions and DR operator versions + + Args: + namespace (str): the CSVs namespace + + Returns: + dict: the ocs versions and DR operator versions + + """ + # Importing here to avoid circular dependency + from ocs_ci.ocs.utils import get_dr_operator_versions + operator_selector = get_selector_for_ocs_operator() subscription_plan_approval = config.DEPLOYMENT.get("subscription_plan_approval") package_manifest = PackageManifest( @@ -205,7 +218,9 @@ def get_version_info(namespace=None): csv_name = package_manifest.get_current_csv(channel) csv_pre = CSV(resource_name=csv_name, namespace=namespace) info = get_images(csv_pre.get()) - return info + dr_operator_versions = get_dr_operator_versions() + versions = {**info, **dr_operator_versions} + return versions def get_ocs_csv(): diff --git a/ocs_ci/ocs/utils.py b/ocs_ci/ocs/utils.py index b532e6f4073..6c5e551bad2 100644 --- a/ocs_ci/ocs/utils.py +++ b/ocs_ci/ocs/utils.py @@ -31,7 +31,21 @@ from ocs_ci.utility import templating, version from ocs_ci.utility.prometheus import PrometheusAPI from ocs_ci.utility.retry import retry -from ocs_ci.utility.utils import create_directory_path, mirror_image, run_cmd +from ocs_ci.utility.utils import ( + create_directory_path, + mirror_image, + run_cmd, + get_oadp_version, + get_acm_version, +) +from ocs_ci.utility.version import ( + get_dr_hub_operator_version, + get_dr_cluster_operator_version, + get_odf_multicluster_orchestrator_version, + get_ocp_gitops_operator_version, + get_submariner_operator_version, + get_volsync_operator_version, +) log = logging.getLogger(__name__) @@ -1681,3 +1695,60 @@ def collect_pod_container_rpm_package(dir_name): go_log_file_name = f"{package_log_dir_path}/{pod_obj.name}-{container_name}-go-version.log" with open(go_log_file_name, "w") as f: f.write(go_output) + + +def is_dr_scenario(): + """ + Check if it is RDR or MDR setup + + Returns: + bool: return True if it is rdr or mdr setup otherwise False + + """ + return ocsci_config.MULTICLUSTER.get("multicluster_mode") in ( + "metro-dr", + "regional-dr", + ) + + +def get_dr_operator_versions(): + """ + Get all DR operator versions on hub and primary clusters + + Returns: + dict: return operator name as key and version as value + + """ + versions_dic = dict() + if is_dr_scenario(): + with ocsci_config.RunWithAcmConfigContext(): + acm_operator_version = get_acm_version() + if acm_operator_version: + versions_dic["acm_version"] = acm_operator_version + ocp_dr_hub_operator_version = get_dr_hub_operator_version() + if ocp_dr_hub_operator_version: + versions_dic["dr_hub_version"] = ocp_dr_hub_operator_version + odf_multicluster_orchestrator_version = ( + get_odf_multicluster_orchestrator_version() + ) + if odf_multicluster_orchestrator_version: + versions_dic[ + "odf_multicluster_orchestrator_version" + ] = odf_multicluster_orchestrator_version + with ocsci_config.RunWithPrimaryConfigContext(): + oadp_operator_version = get_oadp_version() + if oadp_operator_version: + versions_dic["oadp_version"] = oadp_operator_version + ocp_dr_cluster_operator_version = get_dr_cluster_operator_version() + if ocp_dr_cluster_operator_version: + versions_dic["dr_cluster_version"] = ocp_dr_cluster_operator_version + gitops_operator_version = get_ocp_gitops_operator_version() + if gitops_operator_version: + versions_dic["gitops_version"] = gitops_operator_version + volsync_operator_version = get_volsync_operator_version() + if volsync_operator_version: + versions_dic["volsync_version"] = volsync_operator_version + submariner_operator_version = get_submariner_operator_version() + if submariner_operator_version: + versions_dic["submariner_version"] = submariner_operator_version + return versions_dic diff --git a/ocs_ci/utility/utils.py b/ocs_ci/utility/utils.py index 5a29ef65dee..ce9232345b1 100644 --- a/ocs_ci/utility/utils.py +++ b/ocs_ci/utility/utils.py @@ -4825,7 +4825,7 @@ def add_time_report_to_email(session, soup): summary_tag.insert_after(time_div) -def get_oadp_version(namespace=constants.ACM_HUB_BACKUP_NAMESPACE): +def get_oadp_version(namespace=constants.OADP_NAMESPACE): """ Returns: str: returns version string @@ -4840,7 +4840,7 @@ def get_oadp_version(namespace=constants.ACM_HUB_BACKUP_NAMESPACE): return csv["spec"]["version"] -def get_acm_version(): +def get_acm_version(namespace=constants.ACM_HUB_NAMESPACE): """ Get ACM version from CSV @@ -4851,7 +4851,7 @@ def get_acm_version(): from ocs_ci.ocs.resources.csv import get_csvs_start_with_prefix csv_list = get_csvs_start_with_prefix( - "advanced-cluster-management", namespace=constants.ACM_HUB_NAMESPACE + "advanced-cluster-management", namespace=namespace ) for csv in csv_list: if "advanced-cluster-management" in csv["metadata"]["name"]: diff --git a/ocs_ci/utility/version.py b/ocs_ci/utility/version.py index 93093504a49..98c8da04059 100644 --- a/ocs_ci/utility/version.py +++ b/ocs_ci/utility/version.py @@ -9,6 +9,7 @@ from ocs_ci.framework import config from ocs_ci.ocs import defaults from ocs_ci.ocs.exceptions import WrongVersionExpression +from ocs_ci.ocs import constants def get_semantic_version( @@ -172,3 +173,121 @@ def get_previous_version(version, count=1): new_minor = version.minor - count previous_version = f"{version.major}.{new_minor}" return previous_version + + +def get_dr_hub_operator_version(namespace=constants.OPENSHIFT_NAMESPACE): + """ + Get DR Hub Operator Version + + Returns: + str: returns version string + + """ + # Importing here to avoid circular dependency + from ocs_ci.ocs.resources.csv import get_csvs_start_with_prefix + + csv_list = get_csvs_start_with_prefix( + constants.ACM_ODR_HUB_OPERATOR_RESOURCE, namespace=namespace + ) + for csv in csv_list: + if constants.ACM_ODR_HUB_OPERATOR_RESOURCE in csv["metadata"]["name"]: + # extract version string + return csv["spec"]["version"] + + +def get_dr_cluster_operator_version(namespace=constants.OPENSHIFT_NAMESPACE): + """ + Get DR Cluster Operator Version + + Returns: + str: returns version string + + """ + # Importing here to avoid circular dependency + from ocs_ci.ocs.resources.csv import get_csvs_start_with_prefix + + csv_list = get_csvs_start_with_prefix("odr-cluster-operator", namespace=namespace) + for csv in csv_list: + if "odr-cluster-operator" in csv["metadata"]["name"]: + # extract version string + return csv["spec"]["version"] + + +def get_odf_multicluster_orchestrator_version(namespace=constants.ACM_HUB_NAMESPACE): + """ + Get ODF Multicluster Orchestrator Version + + Returns: + str: returns version string + + """ + # Importing here to avoid circular dependency + from ocs_ci.ocs.resources.csv import get_csvs_start_with_prefix + + csv_list = get_csvs_start_with_prefix( + constants.ACM_ODF_MULTICLUSTER_ORCHESTRATOR_RESOURCE, + namespace=namespace, + ) + for csv in csv_list: + if ( + constants.ACM_ODF_MULTICLUSTER_ORCHESTRATOR_RESOURCE + in csv["metadata"]["name"] + ): + # extract version string + return csv["spec"]["version"] + + +def get_ocp_gitops_operator_version(namespace=constants.OPENSHIFT_NAMESPACE): + """ + Get OCP Gitops Operator Version + + Returns: + str: returns version string + + """ + # Importing here to avoid circular dependency + from ocs_ci.ocs.resources.csv import get_csvs_start_with_prefix + + csv_list = get_csvs_start_with_prefix( + constants.GITOPS_OPERATOR_NAME, namespace=namespace + ) + for csv in csv_list: + if constants.GITOPS_OPERATOR_NAME in csv["metadata"]["name"]: + # extract version string + return csv["spec"]["version"] + + +def get_submariner_operator_version(namespace=constants.SUBMARINER_OPERATOR_NAMESPACE): + """ + Get Submariner Operator Version + + Returns: + str: returns version string + + """ + # Importing here to avoid circular dependency + from ocs_ci.ocs.resources.csv import get_csvs_start_with_prefix + + csv_list = get_csvs_start_with_prefix("submariner", namespace=namespace) + for csv in csv_list: + if "submariner" in csv["metadata"]["name"]: + # extract version string + return csv["spec"]["version"] + + +def get_volsync_operator_version(namespace=constants.SUBMARINER_OPERATOR_NAMESPACE): + """ + Get VolSync Operator Version + + Returns: + str: returns version string + + """ + # Importing here to avoid circular dependency + from ocs_ci.ocs.resources.csv import get_csvs_start_with_prefix + + csv_list = get_csvs_start_with_prefix("volsync", namespace=namespace) + for csv in csv_list: + if "volsync" in csv["metadata"]["name"]: + # extract version string + return csv["spec"]["version"] diff --git a/tests/conftest.py b/tests/conftest.py index 8e0e39af156..fc2db0c5ba6 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -65,6 +65,7 @@ setup_ceph_toolbox, collect_ocs_logs, collect_pod_container_rpm_package, + get_dr_operator_versions, ) from ocs_ci.ocs.resources.deployment import Deployment from ocs_ci.ocs.resources.job import get_job_obj @@ -174,6 +175,7 @@ from ocs_ci.ocs.longevity import start_app_workload from ocs_ci.utility.decorators import switch_to_default_cluster_index_at_last + log = logging.getLogger(__name__) @@ -1594,6 +1596,9 @@ def additional_testsuite_properties(record_testsuite_property, pytestconfig): # add markers as separated property markers = ocsci_config.RUN["cli_params"].get("-m", "").replace(" ", "-") record_testsuite_property("rp_markers", markers) + dr_operator_versions = get_dr_operator_versions() + for dr_operator_name, dr_operator_version in dr_operator_versions.items(): + record_testsuite_property(f"rp_{dr_operator_name}", dr_operator_version) @pytest.fixture(scope="session")