From 7bed4c4bef56d1e3b5e23c340accedfadadbf7b6 Mon Sep 17 00:00:00 2001 From: Matt Verran Date: Sat, 13 Sep 2025 12:00:14 +0100 Subject: [PATCH] Cloudkitty initial fix: db connections to 2 and risk level fix: pep8 issues fix: add imports for requires and risk fix: organise imports Signed-off-by: Matt Verran --- .../sunbeam/features/rating/README.md | 30 ++++++ .../sunbeam/features/rating/__init__.py | 0 .../sunbeam/features/rating/feature.py | 99 +++++++++++++++++++ 3 files changed, 129 insertions(+) create mode 100644 sunbeam-python/sunbeam/features/rating/README.md create mode 100644 sunbeam-python/sunbeam/features/rating/__init__.py create mode 100644 sunbeam-python/sunbeam/features/rating/feature.py diff --git a/sunbeam-python/sunbeam/features/rating/README.md b/sunbeam-python/sunbeam/features/rating/README.md new file mode 100644 index 000000000..74cd3723a --- /dev/null +++ b/sunbeam-python/sunbeam/features/rating/README.md @@ -0,0 +1,30 @@ +# Cloudkitty service + +This feature provides Rating (billing) service for Sunbeam. It's based on [Cloudkitty](https://docs.openstack.org/cloudkitty/latest/), rating solution for OpenStack. + +## Installation + +To enable the Rating service, you need an already bootstraped Sunbeam instance. Then, you can install the feature with: + +```bash +sunbeam enable rating +``` + +## Contents + +This feature will install the following services: +- Cloudkitty: Rating service for OpenStack [charm](https://opendev.org/openstack/sunbeam-charms/src/branch/main/charms/cloudkitty-k8s) [ROCK](https://github.com/canonical/ubuntu-openstack-rocks/tree/main/rocks/cloudkitty-consolidated) +- MySQL Router for Cloudkitty [charm](https://github.com/canonical/mysql-router-k8s-operator) [ROCK](https://github.com/canonical/charmed-mysql-rock) +- MySQL Instance in the case of a multi-mysql installation (for large deployments) [charm](https://github.com/canonical/mysql-k8s-operator) [ROCK](https://github.com/canonical/charmed-mysql-rock) + +Services are constituted of charms, i.e. operator code, and ROCKs, the corresponding OCI images. + +The Cloudkitty charm currently supports Storage V1, Gnocchi and Ceilometer telemetry with other options to be enhanced at a later date. + +## Removal + +To remove the feature, run: + +```bash +sunbeam disable rating +``` diff --git a/sunbeam-python/sunbeam/features/rating/__init__.py b/sunbeam-python/sunbeam/features/rating/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/sunbeam-python/sunbeam/features/rating/feature.py b/sunbeam-python/sunbeam/features/rating/feature.py new file mode 100644 index 000000000..abf3ae9e3 --- /dev/null +++ b/sunbeam-python/sunbeam/features/rating/feature.py @@ -0,0 +1,99 @@ +# SPDX-FileCopyrightText: 2023 - Canonical Ltd +# SPDX-License-Identifier: Apache-2.0 + +import logging + +import click +from packaging.version import Version + +from sunbeam.core.common import RiskLevel +from sunbeam.core.deployment import Deployment +from sunbeam.core.manifest import CharmManifest, FeatureConfig, SoftwareConfig +from sunbeam.features.interface.v1.base import FeatureRequirement +from sunbeam.features.interface.v1.openstack import ( + OpenStackControlPlaneFeature, + TerraformPlanLocation, +) +from sunbeam.utils import click_option_show_hints, pass_method_obj +from sunbeam.versions import OPENSTACK_CHANNEL + +LOG = logging.getLogger(__name__) + + +class RatingFeature(OpenStackControlPlaneFeature): + version = Version("0.0.1") + requires = {FeatureRequirement("telemetry")} + risk_availability = RiskLevel.BETA + + name = "rating" + tf_plan_location = TerraformPlanLocation.SUNBEAM_TERRAFORM_REPO + + def default_software_overrides(self) -> SoftwareConfig: + """Feature software configuration.""" + return SoftwareConfig( + charms={"cloudkitty-k8s": CharmManifest(channel=OPENSTACK_CHANNEL)} + ) + + def manifest_attributes_tfvar_map(self) -> dict: + """Manifest attributes terraformvars map.""" + return { + self.tfplan: { + "charms": { + "cloudkitty-k8s": { + "channel": "cloudkitty-channel", + "revision": "cloudkitty-revision", + "config": "cloudkitty-config", + } + } + } + } + + def set_application_names(self, deployment: Deployment) -> list: + """Application names handled by the terraform plan.""" + apps = ["cloudkitty", "cloudkitty-mysql-router"] + if self.get_database_topology(deployment) == "multi": + apps.extend(["cloudkitty-mysql"]) + + return apps + + def set_tfvars_on_enable( + self, deployment: Deployment, config: FeatureConfig + ) -> dict: + """Set terraform variables to enable the application.""" + return { + "enable-cloudkitty": True, + **self.add_horizon_plugin_to_tfvars(deployment, "cloudkitty"), + } + + def set_tfvars_on_disable(self, deployment: Deployment) -> dict: + """Set terraform variables to disable the application.""" + return { + "enable-cloudkitty": False, + **self.remove_horizon_plugin_from_tfvars(deployment, "cloudkitty"), + } + + def set_tfvars_on_resize( + self, deployment: Deployment, config: FeatureConfig + ) -> dict: + """Set terraform variables to resize the application.""" + return {} + + def get_database_charm_processes(self) -> dict[str, dict[str, int]]: + """Returns the database processes accessing this service.""" + return { + "cloudkitty": {"cloudkitty-k8s": 2}, + } + + @click.command() + @click_option_show_hints + @pass_method_obj + def enable_cmd(self, deployment: Deployment, show_hints: bool) -> None: + """Enable Rating service.""" + self.enable_feature(deployment, FeatureConfig(), show_hints) + + @click.command() + @click_option_show_hints + @pass_method_obj + def disable_cmd(self, deployment: Deployment, show_hints: bool) -> None: + """Disable Rating service.""" + self.disable_feature(deployment, show_hints)