From d75e8ad493b0fa0adb3a906886139f03959fa289 Mon Sep 17 00:00:00 2001 From: Tobias Wolf Date: Tue, 5 Nov 2024 19:54:47 +0100 Subject: [PATCH] Support creating the OSISM configuration after successful migration Fixes: #91 Signed-off-by: Tobias Wolf --- .gitignore | 3 + config.example.osism.yaml | 7 +- .../modules/osism_configuration/__init__.py | 3 + .../modules/osism_configuration/main.py | 135 ++++++++++++++++++ .../templates/configuration.yaml.j2 | 21 +++ .../templates/images.yaml.j2 | 4 + .../templates/secrets.yaml.j2 | 4 + 7 files changed, 171 insertions(+), 6 deletions(-) create mode 100644 src/rookify/modules/osism_configuration/__init__.py create mode 100644 src/rookify/modules/osism_configuration/main.py create mode 100644 src/rookify/modules/osism_configuration/templates/configuration.yaml.j2 create mode 100644 src/rookify/modules/osism_configuration/templates/images.yaml.j2 create mode 100644 src/rookify/modules/osism_configuration/templates/secrets.yaml.j2 diff --git a/.gitignore b/.gitignore index e103679..4cccc8f 100644 --- a/.gitignore +++ b/.gitignore @@ -88,6 +88,9 @@ cython_debug/ # Project specific data.pickle config.yaml +osism_configuration.yaml +osism_images.yaml +osism_secrets.yaml .ceph .k8s .ssh diff --git a/config.example.osism.yaml b/config.example.osism.yaml index cdd93ac..a9b4909 100644 --- a/config.example.osism.yaml +++ b/config.example.osism.yaml @@ -42,9 +42,4 @@ rook: migration_modules: - example -- migrate_osds -- migrate_osd_pools -- migrate_mds -- migrate_mds_pools -- migrate_rgws -- migrate_rgw_pools +- osism_configuration diff --git a/src/rookify/modules/osism_configuration/__init__.py b/src/rookify/modules/osism_configuration/__init__.py new file mode 100644 index 0000000..cd6ffb5 --- /dev/null +++ b/src/rookify/modules/osism_configuration/__init__.py @@ -0,0 +1,3 @@ +# -*- coding: utf-8 -*- + +from .main import OSISMConfigurationHandler as ModuleHandler # noqa diff --git a/src/rookify/modules/osism_configuration/main.py b/src/rookify/modules/osism_configuration/main.py new file mode 100644 index 0000000..b38b80c --- /dev/null +++ b/src/rookify/modules/osism_configuration/main.py @@ -0,0 +1,135 @@ +# -*- coding: utf-8 -*- + +import os +from os import path +from typing import Dict +from ..exception import ModuleException +from ..module import ModuleHandler + + +class OSISMConfigurationHandler(ModuleHandler): + CONFIGURATION_FILE_NAME = "osism_configuration.yaml" + IMAGES_FILE_NAME = "osism_images.yaml" + + REQUIRES = [ + "migrate_mons", + "migrate_osds", + "migrate_osd_pools", + "migrate_mds", + "migrate_mds_pools", + "migrate_mgrs", + "migrate_rgws", + "migrate_rgw_pools", + ] + + OSISM_CONFIGURATION_FILE_LOCATION = ( + "/opt/configuration/environments/rook/configuration.yml" + ) + + OSISM_IMAGES_FILE_LOCATION = "/opt/configuration/environments/rook/images.yml" + OSISM_SECRETS_FILE_LOCATION = "/opt/configuration/environments/rook/secrets.yml" + SECRETS_FILE_NAME = "osism_secrets.yaml" + + def preflight(self) -> None: + if not os.access("./", os.W_OK): + raise ModuleException( + "OSISM configuration can not be written to the current working directory: {0}".format( + path.abspath("./") + ) + ) + + def execute(self) -> None: + self._write_configuration_yaml() + self._write_images_yaml() + self._write_secrets_yaml() + + def get_readable_key_value_state(self) -> Dict[str, str]: + return {"OSISM configuration path": path.abspath("./")} + + def _write_configuration_yaml(self) -> None: + analyze_ceph_data = self.machine.get_preflight_state("AnalyzeCephHandler").data + rook_config = self._config["rook"] + + (rook_ceph_repository, rook_ceph_version) = rook_config["ceph"]["image"].split( + ":", 1 + ) + osd_hosts_list = [ + {"name": osd_host} + for osd_host in analyze_ceph_data["node"]["ls"]["osd"].keys() + ] + + create_rook_cluster_data = self.machine.get_preflight_state( + "CreateRookClusterHandler" + ) + + configuration_values = { + "ceph_repository": rook_ceph_repository, + "ceph_version": rook_ceph_version, + "cluster_name": rook_config["cluster"]["name"], + "cluster_namespace": rook_config["cluster"]["namespace"], + "osd_hosts_list": osd_hosts_list, + "mon_count": create_rook_cluster_data.mon_count, + "mgr_count": create_rook_cluster_data.mgr_count, + "mds_count": len(analyze_ceph_data["node"]["ls"]["mds"]), + } + + if len(rook_config["ceph"].get("public_network", "")) > 0: + configuration_values["public_network"] = rook_config["ceph"][ + "public_network" + ] + else: + self.logger.warn( + "Rook Ceph cluster will be configured without a public network and determine it automatically during runtime" + ) + + if len(rook_config["ceph"].get("cluster_network", "")) > 0: + configuration_values["cluster_network"] = rook_config["ceph"][ + "cluster_network" + ] + else: + self.logger.info( + "Rook Ceph cluster will be configured without a cluster network" + ) + + # Render cluster config from template + configuration = self.load_template( + "configuration.yaml.j2", **configuration_values + ) + + with open(OSISMConfigurationHandler.CONFIGURATION_FILE_NAME, "w") as fp: + fp.write(configuration.raw) + + self.logger.info( + "Generated '{0}' to be copied to '{1}'".format( + OSISMConfigurationHandler.CONFIGURATION_FILE_NAME, + OSISMConfigurationHandler.OSISM_CONFIGURATION_FILE_LOCATION, + ) + ) + + def _write_images_yaml(self) -> None: + # Render cluster config from template + images = self.load_template("images.yaml.j2") + + with open(OSISMConfigurationHandler.IMAGES_FILE_NAME, "w") as fp: + fp.write(images.raw) + + self.logger.info( + "Generated '{0}' to be copied to '{1}'".format( + OSISMConfigurationHandler.IMAGES_FILE_NAME, + OSISMConfigurationHandler.OSISM_IMAGES_FILE_LOCATION, + ) + ) + + def _write_secrets_yaml(self) -> None: + # Render cluster config from template + secrets = self.load_template("secrets.yaml.j2") + + with open(OSISMConfigurationHandler.SECRETS_FILE_NAME, "w") as fp: + fp.write(secrets.raw) + + self.logger.info( + "Generated '{0}' to be copied to '{1}'".format( + OSISMConfigurationHandler.SECRETS_FILE_NAME, + OSISMConfigurationHandler.OSISM_SECRETS_FILE_LOCATION, + ) + ) diff --git a/src/rookify/modules/osism_configuration/templates/configuration.yaml.j2 b/src/rookify/modules/osism_configuration/templates/configuration.yaml.j2 new file mode 100644 index 0000000..ccd77e9 --- /dev/null +++ b/src/rookify/modules/osism_configuration/templates/configuration.yaml.j2 @@ -0,0 +1,21 @@ +--- +rook_cluster_name: "{{ cluster_name }}" +rook_ceph_cluster_helm_release_name: "{{ cluster_name }}" +rook_ceph_cluster_helm_release_namespace: "{{ cluster_namespace }}" +rook_ceph_image: "{{ ceph_repository }}" +rook_ceph_image_tag: "{{ ceph_version }}" + +{% if public_network is defined %} +rook_network_public: "{{ public_network }}" +{% endif %} + +{% if cluster_network is defined %} +rook_network_cluster: "{{ cluster_network }}" +{% endif %} + +rook_storage_devicefilter: "^sd[b-c]" +rook_storage_nodes: {{ osd_hosts_list }} + +rook_mon_count: {{ mon_count }} +rook_mds_count: {{ mds_count }} +rook_mgr_count: {{ mgr_count }} diff --git a/src/rookify/modules/osism_configuration/templates/images.yaml.j2 b/src/rookify/modules/osism_configuration/templates/images.yaml.j2 new file mode 100644 index 0000000..601cb4d --- /dev/null +++ b/src/rookify/modules/osism_configuration/templates/images.yaml.j2 @@ -0,0 +1,4 @@ +--- +# Dummy variable to avoid error because ansible does not recognize the +# file as a good configuration file when no variable in it. +dummy: diff --git a/src/rookify/modules/osism_configuration/templates/secrets.yaml.j2 b/src/rookify/modules/osism_configuration/templates/secrets.yaml.j2 new file mode 100644 index 0000000..601cb4d --- /dev/null +++ b/src/rookify/modules/osism_configuration/templates/secrets.yaml.j2 @@ -0,0 +1,4 @@ +--- +# Dummy variable to avoid error because ansible does not recognize the +# file as a good configuration file when no variable in it. +dummy: