diff --git a/.envrc b/.envrc new file mode 100644 index 0000000..8cc1ae5 --- /dev/null +++ b/.envrc @@ -0,0 +1 @@ +unset SSH_AUTH_SOCK 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/Makefile b/Makefile index 641aa7b..4879eb4 100644 --- a/Makefile +++ b/Makefile @@ -34,7 +34,10 @@ help: ## Display this help message @echo -e '\n${COLOUR_RED}Usage: make ${COLOUR_END}' @cat $(MAKEFILE_LIST) | grep '^[a-zA-Z]' | \ awk -F ':.*?## ' 'NF==2 {printf " %-26s%s\n\n", $$1, "${COLOUR_GREEN}"$$2"${COLOUR_END}"}' - @echo -e '${COLOUR_RED}OSISM helperscript usage: make ${COLOUR_END}' + @echo -e '${COLOUR_RED}Container related commands${COLOUR_END}' + @cat $(MAKEFILE_LIST) | grep '^[a-zA-Z]' | \ + awk -F ':.*?#container# ' 'NF==2 {printf " %-26s%s\n\n", $$1, "${COLOUR_GREEN}"$$2"${COLOUR_END}"}' + @echo -e '${COLOUR_RED}OSISM helperscripts${COLOUR_END}' @cat $(MAKEFILE_LIST) | grep '^[a-zA-Z]' | \ awk -F ':.*?#osism# ' 'NF==2 {printf " %-26s%s\n\n", $$1, "${COLOUR_GREEN}"$$2"${COLOUR_END}"}' @@ -66,53 +69,55 @@ check-radoslib: ## Checks if radoslib is installed and if it contains the right ./scripts/check_local_rados_lib_installation.sh ${RADOSLIB_VERSION} .PHONY: build-local-rookify -build-local-rookify: ## This builds rookify into .venv/bin/rookify +build-local-rookify: setup ## This builds rookify into .venv/bin/rookify source .venv/bin/activate && pip install -e . -.PHONY: build-container -build-container: ## Build container from Dockerfile, add e.g. ROOKIFY_VERSION=0.0.1 to specify the version. Default value is 0.0.0.dev1 - ${CONTAINERCMD} build --build-arg ROOKIFY_VERSION=$(ROOKIFY_VERSION) --target rookify -t rookify:latest -f Dockerfile . - .PHONY: run-local-rookify -run-local-rookify: ## Runs rookify in the local development environment (requires setup-venv) - source ./.venv/bin/activate && pip install -e . && rookify - -.PHONY: run-rookify -run-rookify: ## Runs rookify in the container - docker exec -it rookify-dev /app/rookify/.venv/bin/rookify - -.PHONY: get-testbed-configs-for-rookify-testing -get-testbed-configs-for-rookify-testing: ## Gets the needed config (like .kube, /etc/ceph and so on) from the testbed - bash ./scripts/get_configs_from_testbed.sh +run-local-rookify: build-local-rookify ## Runs rookify in the local development environment (requires setup-venv) + ./.venv/bin/rookify .PHONY: run-tests-locally -run-tests-locally: ## Runs the tests in the tests directory. NB: check that your local setup is connected through vpn to the testbed! +run-tests-locally: setup-venv ## Runs the tests in the tests directory. NB: check that your local setup is connected through vpn to the testbed! .venv/bin/python -m pytest +## +# Add container related commands here (so they appear below the container header) +# Note: use #container# so command appear under header in menu +## + .PHONY: run-tests -run-tests: up ## Runs the tests in the container +run-tests: up #container# Runs the tests in the container ${CONTAINERCMD} exec -it rookify-dev bash -c "/app/rookify/.venv/bin/python -m pytest" +.PHONY: run-rookify +run-rookify: up #container# Runs rookify in the container + ${CONTAINERCMD} exec -it rookify-dev /app/rookify/.venv/bin/rookify + .PHONY: enter -enter: ## Enter the container +enter: up #container# Enter the container ${CONTAINERCMD} exec -it rookify-dev bash .PHONY: logs -logs: ## Logs the container +logs: #container# Logs the container ${CONTAINERCMD} logs -f rookify-dev .PHONY: down -down: ## Remove the containers as setup by docker-compose.yml +down: #container# Remove the containers as setup by docker-compose.yml ${CONTAINERCMD} compose down .PHONY: up -up: ## Sets up the container as specified in docker-compose.yml and opens a bash terminal +up: #container# Sets up the container as specified in docker-compose.yml and opens a bash terminal ${CONTAINERCMD} compose up -d +.PHONY: build-container +build-container: #container# Build container from Dockerfile only, add e.g. ROOKIFY_VERSION=0.0.1 to specify the version. Default value is 0.0.0.dev1 + ${CONTAINERCMD} build --build-arg ROOKIFY_VERSION=$(ROOKIFY_VERSION) --target rookify -t rookify:latest -f Dockerfile . + ## -# Add osism specific scripts below here (so they appear below helper header) +# Add osism specific scripts below here +# Note: use #osism# so command appear under header in menu ## .PHONY: get-config get-config: #osism# Gets configuration files from the OSISM testbed - ./scripts/osism/get_osism_configs_from_testbed.sh + ./scripts/osism/get_configs_from_testbed.sh diff --git a/README.md b/README.md index e2cbe8c..7c5e06b 100644 --- a/README.md +++ b/README.md @@ -14,11 +14,12 @@ Rookify is designed to facilitate a smooth and efficient transition for existing - A functioning Ceph cluster deployed via traditional methods. - __TODO:__ List supported methods - Access to a Kubernetes cluster with sufficient resources to host the migrated Ceph cluster. - - Kubernetes nodes should be rolled out at least on the OSD nodes + - Kubernetes nodes should be rolled out at least on the monitor nodes - Rook operator version 1.13 or higher installed in the Kubernetes cluster. - _local development enivornment_ requires radoslib version 2.0.0 installed ## Installation + 1. Clone the repository: ```bash git clone https://github.com/SovereignCloudStack/rookify @@ -29,24 +30,92 @@ git clone https://github.com/SovereignCloudStack/rookify cd rookify ``` -3. To install the local development environment +3. Check if your host has the correct "radoslib" library installed (if not: then install radoslib version 2.0.0): +```bash +make check-radoslib +``` + +4. To install the local development environment (_Note: This will install pre-commit in your local user context_): ```bash make setup ``` -4. To install the container-based environment +5. To install the container-based environment ```bash make build-container -docker run -ti --mount type=bind,source="$(pwd)",target=/app/rookify/src/,readonly --workdir=/app/rookify/src rookify:latest ``` ## Usage -__TODO__ -Type `make` to get a list of available development specific commands. +**NOTE**: for testing purposes the [OSISM Testbed](https://github.com/osism/testbed) is used. The `Makefile` and example configuration (`config.example.osism.yaml`) have built in helper functions and examples for this test setup. + +### Copy and adapt configuration files + +Choose one of the configuration-examples found in the root of the working directory and copy it to `config.yml`: + +``` +ls config.example.* +# there is a specific example config for the OSISM testbed: config.example.osism.yaml +cp config.example.yml config.yaml +``` + +_Adapt the config.yml to your need_: especially enter the correct paths for ssh-keys, kubernetes configuration and ceph configuration (all these configuration files need to be provided!). + +### Provide needed configuration files from target servers + +Copy the needed configuration-files from the servers that need to be migrated from ceph to rook. + +_Provide needed configuration files as written in the config.yml._ At least required are: +- ./ceph/ceph.conf (typically found in `/etc/ceph/` on a testbednode) +- ./ceph/ceph.admin.keyring (typically found in `/etc/ceph/` on a testbednode) +- kubernetes config of user (e.g. found in `~/.kube/config`) +- ssh key of the server (found at `./terraform/.id.rsa` in the `testbed` directory) + +Note: +- for the testbed there is a helper script to download the configs from the testbed. These helperscripts need correct `.ssh/config` entries to work (take a look at [scripts/osism/get_configs_from_testbed](osism/get_configs_from_testbed.sh) for an example). +- the helper scripts are merely there to help for testing with the [OSISM testbed](https://github.com/osism/testbed) and might not suit your purposes. + +### Run Rookify + +Now decide on how to run rookify. Either run it from within a container or locally: + +``` +run-local-rookify +# or +run-rookify +``` + +Then sit back and wait. Check the [troubleshooting](#troubleshooting) and [support](#support) sections if any issues occur. + +For other options you can also check the makefile: Type `make` to get a list of available commands. + +### Check status of migration + +Use `rookify --show-states` argument to let each module check for its state in the migration + +```bash +.venv/bin/rookify --show-states +ceph mon dump: Not analyzed yet +ceph osd dump: Not analyzed yet +OSD devices: Not analyzed yet +``` + +#### Troubleshooting + +**missing Ceph systemd targets:** +- please consult your distribution's documentation in case documented Ceph systemd unit services or targets are missing +- `cephadm install ceph-common ceph-base ceph-mon ceph-mgr ceph-mds radosgw` may help if supported + +**frozen state:** +- if the rookify process freezes, check your connections. In the OSISM testbed especially check the vpn-connection (in testbed repository try `make vpn-*`) + +**ssh-issues:** +- make sure the id-rsa keys are "clean" and do not contain unexpected strings like "\<\ +# IdentitiesOnly yes +# user dragon +# +# Host testbed-manager +# Hostname +# +# Host testbed-node-0 +# Hostname 192.168.16.10 +# +# Host testbed-node-1 +# Hostname 192.168.16.11 +# Host testbed-node-2 +# Hostname 192.168.16.12 +# + +# copy .kube to ./.k8s +scp -r testbed-manager:.kube ./.k8s + +# copy /etc/ceph/ from node1 to ./.k8s +ssh testbed-manager "docker cp cephclient:/etc/ceph /tmp/cephclientconfig" && scp -r testbed-manager:/tmp/cephclientconfig ./.ceph && ssh testbed-manager "rm -rf /tmp/cephclientconfig" diff --git a/src/rookify/config.schema.yaml b/src/rookify/config.schema.yaml index ae30c41..8f9da4f 100644 --- a/src/rookify/config.schema.yaml +++ b/src/rookify/config.schema.yaml @@ -10,6 +10,7 @@ logging: ceph: config: str() keyring: str() + systemd_file_name_templates: include("systemd_file_name_templates", required=False) ssh: private_key: str() @@ -39,3 +40,10 @@ migration_modules: list(str()) ssh_host: address: ip() user: str() +--- +systemd_file_name_templates: + mds: str(required=False) + mgr: str(required=False) + mon: str(required=False) + osd: str(required=False) + rgw: str(required=False) diff --git a/src/rookify/modules/ceph.py b/src/rookify/modules/ceph.py index ba16b87..0f180aa 100644 --- a/src/rookify/modules/ceph.py +++ b/src/rookify/modules/ceph.py @@ -16,6 +16,14 @@ def __init__(self, config: Dict[str, Any]): except rados.ObjectNotFound as err: raise ModuleException(f"Could not connect to ceph: {err}") + status_data = self.mon_command("status") + + self._fsid = status_data["fsid"] + + self._systemd_file_name_templates = config.get( + "systemd_file_name_templates", {} + ) + def __getattr__(self, name: str) -> Any: return getattr(self.__ceph, name) @@ -32,7 +40,43 @@ def _json_command(self, handler: Any, *args: Any) -> Any: return data - def get_osd_pool_configurations_from_osd_dump( + def get_systemd_mds_file_name(self, host: str) -> str: + return self._get_systemd_template_file_name( + self._systemd_file_name_templates.get("mds", "ceph-mds.target"), + host, + ) + + def get_systemd_mgr_file_name(self, host: str) -> str: + return self._get_systemd_template_file_name( + self._systemd_file_name_templates.get("mgr", "ceph-mgr.target"), + host, + ) + + def get_systemd_mon_file_name(self, host: str) -> str: + return self._get_systemd_template_file_name( + self._systemd_file_name_templates.get("mon", "ceph-mon.target"), + host, + ) + + def get_systemd_osd_file_name(self, host: str, osd_id: int) -> str: + file_name_template: str = self._systemd_file_name_templates.get( + "osd", "ceph-osd@{0:d}.service".format(osd_id) + ) + + return file_name_template.format(fsid=self._fsid, host=host, osd_id=osd_id) + + def get_systemd_rgw_file_name(self, host: str) -> str: + return self._get_systemd_template_file_name( + self._systemd_file_name_templates.get("mon", "ceph-radosgw.target"), + host, + ) + + def _get_systemd_template_file_name( + self, file_name_template: str, host: str + ) -> str: + return file_name_template.format(fsid=self._fsid, host=host) + + def get_osd_pool_configurations_from_map( self, dump_data: Dict[str, Any] ) -> Dict[str, Any]: osd_pools = {osd_pool["pool_name"]: osd_pool for osd_pool in dump_data["pools"]} diff --git a/src/rookify/modules/create_rook_resources/main.py b/src/rookify/modules/create_rook_resources/main.py index 2cceccd..b683cf9 100644 --- a/src/rookify/modules/create_rook_resources/main.py +++ b/src/rookify/modules/create_rook_resources/main.py @@ -36,7 +36,7 @@ def __create_configmap_definition(self) -> None: configmap_data = { "data": configmap_mon_list, "mapping": json.dumps({"node": mapping}), - "maxMonId": "{0:d}".format(len(state_data["mon"]["dump"]["mons"])), + "maxMonId": "{0:d}".format(len(state_data["report"]["monmap"]["mons"])), } configmap = kubernetes.client.V1ConfigMap( diff --git a/src/rookify/modules/migrate_mds/main.py b/src/rookify/modules/migrate_mds/main.py index 163bc56..d9f7694 100644 --- a/src/rookify/modules/migrate_mds/main.py +++ b/src/rookify/modules/migrate_mds/main.py @@ -83,7 +83,10 @@ def execute(self) -> None: def _disable_mds(self, mds_host: str) -> None: result = self.ssh.command( - mds_host, "sudo systemctl disable --now ceph-mds.target" + mds_host, + "sudo systemctl disable --now {0}".format( + self.ceph.get_systemd_mds_file_name(mds_host) + ), ) if result.failed: diff --git a/src/rookify/modules/migrate_mds_pools/main.py b/src/rookify/modules/migrate_mds_pools/main.py index bcae3b4..bd84cf5 100644 --- a/src/rookify/modules/migrate_mds_pools/main.py +++ b/src/rookify/modules/migrate_mds_pools/main.py @@ -16,8 +16,8 @@ def preflight(self) -> None: "MigrateMdsPoolsHandler", "pools", default_value={} ) - osd_pools = self.ceph.get_osd_pool_configurations_from_osd_dump( - state_data["osd"]["dump"] + osd_pools = self.ceph.get_osd_pool_configurations_from_map( + state_data["report"]["osdmap"] ) for mds_fs_data in state_data["fs"]["ls"]: diff --git a/src/rookify/modules/migrate_mgrs/main.py b/src/rookify/modules/migrate_mgrs/main.py index 8dce03e..9803975 100644 --- a/src/rookify/modules/migrate_mgrs/main.py +++ b/src/rookify/modules/migrate_mgrs/main.py @@ -44,7 +44,10 @@ def _migrate_mgr(self, mgr_host: str) -> None: self.logger.info("Migrating ceph-mgr daemon at host'{0}'".format(mgr_host)) result = self.ssh.command( - mgr_host, "sudo systemctl disable --now ceph-mgr.target" + mgr_host, + "sudo systemctl disable --now {0}".format( + self.ceph.get_systemd_mgr_file_name(mgr_host) + ), ) if result.failed: diff --git a/src/rookify/modules/migrate_monitors/__init__.py b/src/rookify/modules/migrate_monitors/__init__.py deleted file mode 100644 index 65c6808..0000000 --- a/src/rookify/modules/migrate_monitors/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -# -*- coding: utf-8 -*- - -from .main import MigrateMonitorsHandler as ModuleHandler # noqa diff --git a/src/rookify/modules/migrate_monitors/main.py b/src/rookify/modules/migrate_monitors/main.py deleted file mode 100644 index ac54483..0000000 --- a/src/rookify/modules/migrate_monitors/main.py +++ /dev/null @@ -1,10 +0,0 @@ -# -*- coding: utf-8 -*- - -from ..module import ModuleHandler - - -class MigrateMonitorsHandler(ModuleHandler): - REQUIRES = ["analyze_ceph"] - - def execute(self) -> None: - self.logger.info("MigrateMonitorsHandler ran successfully.") diff --git a/src/rookify/modules/migrate_mons/main.py b/src/rookify/modules/migrate_mons/main.py index 92e08a0..f3e425e 100644 --- a/src/rookify/modules/migrate_mons/main.py +++ b/src/rookify/modules/migrate_mons/main.py @@ -51,7 +51,10 @@ def _migrate_mon(self, mon: Dict[str, Any]) -> None: self.logger.info("Migrating ceph-mon daemon '{0}'".format(mon["name"])) result = self.ssh.command( - mon["name"], "sudo systemctl disable --now ceph-mon.target" + mon["name"], + "sudo systemctl disable --now {0}".format( + self.ceph.get_systemd_mon_file_name(mon["name"]) + ), ) if result.failed: diff --git a/src/rookify/modules/migrate_osd_pools/main.py b/src/rookify/modules/migrate_osd_pools/main.py index 406a0f5..6224da7 100644 --- a/src/rookify/modules/migrate_osd_pools/main.py +++ b/src/rookify/modules/migrate_osd_pools/main.py @@ -32,7 +32,7 @@ def _get_filtered_osd_pools_list(self) -> List[Dict[str, Any]]: state_data = self.machine.get_preflight_state("AnalyzeCephHandler").data - osd_pool_configurations = self.ceph.get_osd_pool_configurations_from_osd_dump( + osd_pool_configurations = self.ceph.get_osd_pool_configurations_from_map( state_data["report"]["osdmap"] ) diff --git a/src/rookify/modules/migrate_osds/main.py b/src/rookify/modules/migrate_osds/main.py index b6efb86..d2212b9 100644 --- a/src/rookify/modules/migrate_osds/main.py +++ b/src/rookify/modules/migrate_osds/main.py @@ -16,7 +16,8 @@ def _get_devices_of_hosts(self) -> Dict[str, Dict[str, str]]: osd_devices: Dict[str, Dict[str, str]] = {} osd_metadata = { - str(osd_data["id"]): osd_data for osd_data in state_data["osd_metadata"] + osd_data["id"]: osd_data + for osd_data in state_data["report"]["osd_metadata"] } for osd_host, osds in state_data["node"]["ls"]["osd"].items(): @@ -157,7 +158,9 @@ def migrate_osds(self, host: str, osd_ids: List[int]) -> None: result = self.ssh.command( host, - "sudo systemctl disable --now ceph-osd@{0:d}.service".format(osd_id), + "sudo systemctl disable --now {0}".format( + self.ceph.get_systemd_osd_file_name(host, osd_id) + ), ) if result.failed: diff --git a/src/rookify/modules/migrate_rgw_pools/main.py b/src/rookify/modules/migrate_rgw_pools/main.py index e3076e9..7e147c1 100644 --- a/src/rookify/modules/migrate_rgw_pools/main.py +++ b/src/rookify/modules/migrate_rgw_pools/main.py @@ -37,7 +37,7 @@ def preflight(self) -> None: else: zones[zone_name] = {"osd_pools": {}, "rgw_count": 1} - osd_pools = self.ceph.get_osd_pool_configurations_from_osd_dump( + osd_pools = self.ceph.get_osd_pool_configurations_from_map( state_data["report"]["osdmap"] ) diff --git a/src/rookify/modules/migrate_rgws/main.py b/src/rookify/modules/migrate_rgws/main.py index caf7309..aaa4e25 100644 --- a/src/rookify/modules/migrate_rgws/main.py +++ b/src/rookify/modules/migrate_rgws/main.py @@ -13,13 +13,19 @@ class MigrateRgwsHandler(ModuleHandler): def _get_rgw_daemon_hosts(self) -> List[str]: state_data = self.machine.get_preflight_state("AnalyzeCephHandler").data - rgw_daemons = state_data["report"]["servicemap"]["services"]["rgw"]["daemons"] + return self._get_rgw_daemon_hosts_of_map( + state_data["report"]["servicemap"]["services"]["rgw"]["daemons"] + ) + + def _get_rgw_daemon_hosts_of_map( + self, rgw_daemons_map: Dict[str, Any] + ) -> List[str]: rgw_daemon_hosts = [] - if "summary" in rgw_daemons: - del rgw_daemons["summary"] + if "summary" in rgw_daemons_map: + del rgw_daemons_map["summary"] - for rgw_daemon in rgw_daemons.values(): + for rgw_daemon in rgw_daemons_map.values(): if "metadata" not in rgw_daemon or "hostname" not in rgw_daemon["metadata"]: raise ModuleException( "Unexpected ceph-rgw daemon metadata: {0}".format(rgw_daemon) @@ -72,7 +78,10 @@ def _migrate_rgw(self, rgw_host: str) -> None: if is_migration_required: result = self.ssh.command( - rgw_host, "sudo systemctl disable --now ceph-radosgw.target" + rgw_host, + "sudo systemctl disable --now {0}".format( + self.ceph.get_systemd_rgw_file_name(rgw_host) + ), ) if result.failed: @@ -89,7 +98,11 @@ def _migrate_rgw(self, rgw_host: str) -> None: ) while True: - rgw_daemon_hosts = self._get_rgw_daemon_hosts() + ceph_status = self.ceph.mon_command("status") + + rgw_daemon_hosts = self._get_rgw_daemon_hosts_of_map( + ceph_status["servicemap"]["services"]["rgw"]["daemons"] + ) if rgw_host not in rgw_daemon_hosts: break 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: