From 9f20805a3d9c9cecdd5fce4ff7b311c1c3655c23 Mon Sep 17 00:00:00 2001 From: beierlm Date: Fri, 25 Aug 2023 23:03:24 +0200 Subject: [PATCH] Revert "Integrate MON and Grafana" This reverts commit 87b620ace4933f30db8c4834862a57d56f9a07a6. Reason for revert: Grafana-k8s requires Juju 3.1 and we are not ready to change Juju versions at this time Change-Id: I645f1a8bd71b48f5d139420dbe7d879c88c6a2c7 Signed-off-by: Mark Beierl --- installers/charm/osm-mon/actions.yaml | 25 -- installers/charm/osm-mon/config.yaml | 3 + installers/charm/osm-mon/requirements.txt | 1 - installers/charm/osm-mon/src/charm.py | 74 +---- .../osm-mon/src/grafana_datasource_handler.py | 120 -------- .../osm-mon/tests/integration/test_charm.py | 66 ++--- .../integration/test_datasource_actions.py | 272 ------------------ .../charm/osm-mon/tests/unit/test_charm.py | 56 ---- 8 files changed, 33 insertions(+), 584 deletions(-) delete mode 100644 installers/charm/osm-mon/src/grafana_datasource_handler.py delete mode 100644 installers/charm/osm-mon/tests/integration/test_datasource_actions.py diff --git a/installers/charm/osm-mon/actions.yaml b/installers/charm/osm-mon/actions.yaml index 4f1a1576..0d73468f 100644 --- a/installers/charm/osm-mon/actions.yaml +++ b/installers/charm/osm-mon/actions.yaml @@ -24,28 +24,3 @@ get-debug-mode-information: description: Get information to debug the container - -create-datasource: - description: Create a new prometheus datasource. - params: - name: - type: string - description: The name of the datasource. - url: - type: string - description: URL to prometheus. - required: [name, url] - additionalProperties: false - -list-datasources: - description: List datasources. - additionalProperties: false - -delete-datasource: - description: Delete a given datasource. - params: - name: - type: string - description: The name of the datasource. - required: [name] - additionalProperties: false diff --git a/installers/charm/osm-mon/config.yaml b/installers/charm/osm-mon/config.yaml index 8f1d91f0..cb2eb99c 100644 --- a/installers/charm/osm-mon/config.yaml +++ b/installers/charm/osm-mon/config.yaml @@ -59,12 +59,15 @@ options: grafana-url: description: Grafana URL type: string + default: http://grafana:3000 grafana-user: description: Grafana user type: string + default: admin grafana-password: description: Grafana password type: string + default: admin keystone-enabled: description: MON will use Keystone backend type: boolean diff --git a/installers/charm/osm-mon/requirements.txt b/installers/charm/osm-mon/requirements.txt index 44e5b92d..398d4ad3 100644 --- a/installers/charm/osm-mon/requirements.txt +++ b/installers/charm/osm-mon/requirements.txt @@ -20,5 +20,4 @@ ops < 2.2 lightkube lightkube-models -requests # git+https://github.com/charmed-osm/config-validator/ diff --git a/installers/charm/osm-mon/src/charm.py b/installers/charm/osm-mon/src/charm.py index 620a9bb1..12c5dcda 100755 --- a/installers/charm/osm-mon/src/charm.py +++ b/installers/charm/osm-mon/src/charm.py @@ -29,7 +29,6 @@ See more: https://charmhub.io/osm import logging from typing import Any, Dict -from urllib.parse import urlparse from charms.data_platform_libs.v0.data_interfaces import DatabaseRequires from charms.kafka_k8s.v0.kafka import KafkaRequires, _KafkaAvailableEvent @@ -48,11 +47,6 @@ from ops.framework import EventSource, StoredState from ops.main import main from ops.model import ActiveStatus, Container -from grafana_datasource_handler import ( - DatasourceConfig, - GrafanaConfig, - GrafanaDataSourceHandler, -) from legacy_interfaces import KeystoneClient, PrometheusClient HOSTPATHS = [ @@ -167,47 +161,6 @@ class OsmMonCharm(CharmBase): } event.set_results(debug_info) - def _on_create_datasource_action(self, event: ActionEvent) -> None: - """Handler for the create-datasource action event.""" - url = event.params["url"] - if not self._is_valid_url(url): - event.fail(f"Invalid datasource url '{url}'") - return - grafana_config = self._get_grafana_config() - datasource_config = DatasourceConfig(event.params["name"], url) - response = GrafanaDataSourceHandler.create_datasource(grafana_config, datasource_config) - logger.debug(response) - if response.is_success: - event.set_results(response.results) - return - event.fail(response.message) - - def _on_list_datasources_action(self, event: ActionEvent) -> None: - """Handler for the list-datasource action event.""" - grafana_config = self._get_grafana_config() - response = GrafanaDataSourceHandler.list_datasources(grafana_config) - logger.debug(response) - if response.is_success: - event.set_results(response.results) - return - event.fail(response.message) - - def _on_delete_datasource_action(self, event: ActionEvent) -> None: - """Handler for the delete-datasource action event.""" - datasource_name = event.params["name"] - grafana_config = self._get_grafana_config() - response = GrafanaDataSourceHandler.delete_datasource(grafana_config, datasource_name) - logger.debug(response) - if not response.is_success: - event.fail(response.message) - - def _get_grafana_config(self) -> GrafanaConfig: - return GrafanaConfig( - self.config.get("grafana-user", ""), - self.config.get("grafana-password", ""), - self.config.get("grafana-url", ""), - ) - # --------------------------------------------------------------------------- # Validation and configuration and more # --------------------------------------------------------------------------- @@ -226,9 +179,6 @@ class OsmMonCharm(CharmBase): self.on["mongodb"].relation_broken: self._on_required_relation_broken, # Action events self.on.get_debug_mode_information_action: self._on_get_debug_mode_information_action, - self.on.create_datasource_action: self._on_create_datasource_action, - self.on.list_datasources_action: self._on_list_datasources_action, - self.on.delete_datasource_action: self._on_delete_datasource_action, } for relation in [self.on[rel_name] for rel_name in ["prometheus", "keystone"]]: event_handler_mapping[relation.relation_changed] = self._on_config_changed @@ -250,24 +200,6 @@ class OsmMonCharm(CharmBase): CharmError: if charm configuration is invalid. """ logger.debug("validating charm config") - missing_configs = [] - grafana_configs = ["grafana-url", "grafana-user", "grafana-password"] - for config in grafana_configs: - if not self.config.get(config): - missing_configs.append(config) - - if missing_configs: - config_str = ", ".join(missing_configs) - error_msg = f"need {config_str} config" - logger.warning(error_msg) - raise CharmError(error_msg) - - grafana_url = self.config["grafana-url"] - if not self._is_valid_url(grafana_url): - raise CharmError(f"Invalid value for grafana-url config: '{grafana_url}'") - - def _is_valid_url(self, url) -> bool: - return urlparse(url).hostname is not None def _check_relations(self) -> None: """Validate charm relations. @@ -322,9 +254,9 @@ class OsmMonCharm(CharmBase): "OSMMON_PROMETHEUS_URL": f"http://{self.prometheus_client.hostname}:{self.prometheus_client.port}", "OSMMON_PROMETHEUS_USER": self.prometheus_client.user, "OSMMON_PROMETHEUS_PASSWORD": self.prometheus_client.password, - "OSMMON_GRAFANA_URL": self.config.get("grafana-url", ""), - "OSMMON_GRAFANA_USER": self.config.get("grafana-user", ""), - "OSMMON_GRAFANA_PASSWORD": self.config.get("grafana-password", ""), + "OSMMON_GRAFANA_URL": self.config["grafana-url"], + "OSMMON_GRAFANA_USER": self.config["grafana-user"], + "OSMMON_GRAFANA_PASSWORD": self.config["grafana-password"], "OSMMON_KEYSTONE_ENABLED": self.config["keystone-enabled"], "OSMMON_KEYSTONE_URL": self.keystone_client.host, "OSMMON_KEYSTONE_DOMAIN_NAME": self.keystone_client.user_domain_name, diff --git a/installers/charm/osm-mon/src/grafana_datasource_handler.py b/installers/charm/osm-mon/src/grafana_datasource_handler.py deleted file mode 100644 index 9cd6acb0..00000000 --- a/installers/charm/osm-mon/src/grafana_datasource_handler.py +++ /dev/null @@ -1,120 +0,0 @@ -#!/usr/bin/env python3 -# Copyright 2022 Canonical Ltd. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. -# -# For those usages not covered by the Apache License, Version 2.0 please -# contact: legal@canonical.com -# -# To get in touch with the maintainers, please contact: -# osm-charmers@lists.launchpad.net -# -# -# Learn more at: https://juju.is/docs/sdk - -"""Module to handle Grafana datasource operations.""" - -import json -import logging -from dataclasses import dataclass - -import requests -from requests.auth import HTTPBasicAuth - -logger = logging.getLogger(__name__) - - -@dataclass -class GrafanaConfig: - """Values needed to make grafana API calls.""" - - user: str - password: str - url: str - - -@dataclass -class DatasourceConfig: - """Information about the datasource to create.""" - - name: str - url: str - - -@dataclass -class DatasourceResponse: - """Return value used by GrafanaDataSourceHandler operations.""" - - is_success: bool - message: str - results: dict - - -class GrafanaDataSourceHandler: - """Handle grafana datasource pperations.""" - - @staticmethod - def create_datasource( - grafana_config: GrafanaConfig, datasource_config: DatasourceConfig - ) -> DatasourceResponse: - """Calls the Grafana API to create a new prometheus datasource.""" - try: - auth = HTTPBasicAuth(grafana_config.user, grafana_config.password) - url = grafana_config.url + "/api/datasources" - datasource_data = { - "name": datasource_config.name, - "type": "prometheus", - "url": datasource_config.url, - "access": "proxy", - "readOnly": False, - "basicAuth": False, - } - response = requests.post(url, json=datasource_data, auth=auth) - response_content = response.json() - results = {"datasource-name": response_content.get("name")} - return DatasourceResponse( - response.ok, response_content.get("message"), results=results - ) - except Exception as e: - logger.debug(f"Exception processing request for creating datasource: {e}") - return DatasourceResponse(False, str(e), results={}) - - @staticmethod - def list_datasources(grafana_config: GrafanaConfig) -> DatasourceResponse: - """Calls the Grafana API to get a list of datasources.""" - try: - auth = HTTPBasicAuth(grafana_config.user, grafana_config.password) - url = grafana_config.url + "/api/datasources" - response = requests.get(url, auth=auth) - response_content = response.json() - results = {"datasources": json.dumps(response_content)} - message = response_content.get("message") if not response.ok else "" - return DatasourceResponse(response.ok, message=message, results=results) - except Exception as e: - logger.debug(f"Exception processing request to list datasources: {e}") - return DatasourceResponse(False, str(e), results={}) - - @staticmethod - def delete_datasource( - grafana_config: GrafanaConfig, datasource_name: str - ) -> DatasourceResponse: - """Calls the Grafana API to delete a given datasource by name.""" - try: - auth = HTTPBasicAuth(grafana_config.user, grafana_config.password) - url = grafana_config.url + f"/api/datasources/name/{datasource_name}" - response = requests.delete(url, auth=auth) - response_content = response.json() - return DatasourceResponse(response.ok, response_content.get("message"), results={}) - except Exception as e: - logger.debug(f"Exception processing request for deleting datasource: {e}") - return DatasourceResponse(False, str(e), results={}) diff --git a/installers/charm/osm-mon/tests/integration/test_charm.py b/installers/charm/osm-mon/tests/integration/test_charm.py index e14e191e..caf8deda 100644 --- a/installers/charm/osm-mon/tests/integration/test_charm.py +++ b/installers/charm/osm-mon/tests/integration/test_charm.py @@ -52,7 +52,7 @@ APPS = [KAFKA_APP, ZOOKEEPER_APP, KEYSTONE_APP, MONGO_DB_APP, MARIADB_APP, PROME @pytest.mark.abort_on_fail -async def test_mon_and_other_charms_are_idle(ops_test: OpsTest): +async def test_mon_is_deployed(ops_test: OpsTest): charm = await ops_test.build_charm(".") resources = {"mon-image": METADATA["resources"]["mon-image"]["upstream-source"]} @@ -71,40 +71,11 @@ async def test_mon_and_other_charms_are_idle(ops_test: OpsTest): await ops_test.run(*shlex.split(cmd), check=True) async with ops_test.fast_forward(): - await ops_test.model.wait_for_idle(apps=APPS) - - -@pytest.mark.abort_on_fail -async def test_mon_is_blocked_due_to_missing_grafana_config(ops_test: OpsTest): + await ops_test.model.wait_for_idle( + apps=APPS, + ) assert ops_test.model.applications[MON_APP].status == "blocked" unit = ops_test.model.applications[MON_APP].units[0] - assert ( - unit.workload_status_message == "need grafana-url, grafana-user, grafana-password config" - ) - - await ops_test.model.applications[MON_APP].set_config({"grafana-url": "new_value"}) - async with ops_test.fast_forward(): - await ops_test.model.wait_for_idle(apps=[MON_APP], status="blocked") - assert unit.workload_status_message == "need grafana-user, grafana-password config" - - await ops_test.model.applications[MON_APP].set_config({"grafana-password": "new_value"}) - async with ops_test.fast_forward(): - await ops_test.model.wait_for_idle(apps=[MON_APP], status="blocked") - assert unit.workload_status_message == "need grafana-user config" - - await ops_test.model.applications[MON_APP].set_config({"grafana-user": "new_value"}) - async with ops_test.fast_forward(): - await ops_test.model.wait_for_idle(apps=[MON_APP], status="blocked") - - assert unit.workload_status_message == "Invalid value for grafana-url config: 'new_value'" - await ops_test.model.applications[MON_APP].set_config({"grafana-url": "http://valid:92"}) - - -@pytest.mark.abort_on_fail -async def test_mon_is_blocked_due_to_missing_relations(ops_test: OpsTest): - async with ops_test.fast_forward(): - await ops_test.model.wait_for_idle(apps=[MON_APP], status="blocked") - unit = ops_test.model.applications[MON_APP].units[0] assert unit.workload_status_message == "need kafka, mongodb, prometheus, keystone relations" logger.info("Adding relations for other components") @@ -120,7 +91,10 @@ async def test_mon_is_blocked_due_to_missing_relations(ops_test: OpsTest): await ops_test.model.add_relation(MON_APP, PROMETHEUS_APP) async with ops_test.fast_forward(): - await ops_test.model.wait_for_idle(apps=APPS, status="active") + await ops_test.model.wait_for_idle( + apps=APPS, + status="active", + ) @pytest.mark.abort_on_fail @@ -155,13 +129,19 @@ async def test_mon_blocks_without_relation(ops_test: OpsTest, relation_to_remove assert unit.workload_status_message == f"need {relation_to_remove} relation" await ops_test.model.add_relation(MON_APP, relation_to_remove) async with ops_test.fast_forward(): - await ops_test.model.wait_for_idle(apps=APPS, status="active") + await ops_test.model.wait_for_idle( + apps=APPS, + status="active", + ) @pytest.mark.abort_on_fail async def test_mon_action_debug_mode_disabled(ops_test: OpsTest): async with ops_test.fast_forward(): - await ops_test.model.wait_for_idle(apps=APPS, status="active") + await ops_test.model.wait_for_idle( + apps=APPS, + status="active", + ) logger.info("Running action 'get-debug-mode-information'") action = ( await ops_test.model.applications[MON_APP] @@ -207,7 +187,9 @@ async def test_mon_integration_vca(ops_test: OpsTest): ), ) async with ops_test.fast_forward(): - await ops_test.model.wait_for_idle(apps=[VCA_APP]) + await ops_test.model.wait_for_idle( + apps=[VCA_APP], + ) controllers = (Path.home() / ".local/share/juju/controllers.yaml").read_text() accounts = (Path.home() / ".local/share/juju/accounts.yaml").read_text() public_key = (Path.home() / ".local/share/juju/ssh/juju_id_rsa.pub").read_text() @@ -220,7 +202,13 @@ async def test_mon_integration_vca(ops_test: OpsTest): } ) async with ops_test.fast_forward(): - await ops_test.model.wait_for_idle(apps=APPS + [VCA_APP], status="active") + await ops_test.model.wait_for_idle( + apps=APPS + [VCA_APP], + status="active", + ) await ops_test.model.add_relation(MON_APP, VCA_APP) async with ops_test.fast_forward(): - await ops_test.model.wait_for_idle(apps=APPS + [VCA_APP], status="active") + await ops_test.model.wait_for_idle( + apps=APPS + [VCA_APP], + status="active", + ) diff --git a/installers/charm/osm-mon/tests/integration/test_datasource_actions.py b/installers/charm/osm-mon/tests/integration/test_datasource_actions.py deleted file mode 100644 index 71d0706f..00000000 --- a/installers/charm/osm-mon/tests/integration/test_datasource_actions.py +++ /dev/null @@ -1,272 +0,0 @@ -#!/usr/bin/env python3 -# Copyright 2022 Canonical Ltd. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. -# -# For those usages not covered by the Apache License, Version 2.0 please -# contact: legal@canonical.com -# -# To get in touch with the maintainers, please contact: -# osm-charmers@lists.launchpad.net -# -# Learn more about testing at: https://juju.is/docs/sdk/testing - -import asyncio -import json -import logging -from pathlib import Path - -import pytest -import yaml -from pytest_operator.plugin import OpsTest - -logger = logging.getLogger(__name__) - -METADATA = yaml.safe_load(Path("./metadata.yaml").read_text()) -MON_APP = METADATA["name"] -GRAFANA_CHARM = "grafana-k8s" -GRAFANA_APP = "grafana" -DS_NAME = "osm_prometheus" -DS_URL = "http://prometheus:9090" - - -async def _run_action_create_datasource(ops_test: OpsTest, name: str, url: str): - action = ( - await ops_test.model.applications[MON_APP] - .units[0] - .run_action( - action_name="create-datasource", - name=name, - url=url, - ) - ) - return await action.wait() - - -async def _run_action_list_datasources(ops_test: OpsTest): - action = ( - await ops_test.model.applications[MON_APP] - .units[0] - .run_action(action_name="list-datasources") - ) - return await action.wait() - - -async def _run_action_delete_datasource(ops_test: OpsTest, name: str): - action = ( - await ops_test.model.applications[MON_APP] - .units[0] - .run_action(action_name="delete-datasource", name=name) - ) - return await action.wait() - - -@pytest.mark.abort_on_fail -async def test_mon_and_grafana_are_idle(ops_test: OpsTest): - charm = await ops_test.build_charm(".") - resources = {"mon-image": METADATA["resources"]["mon-image"]["upstream-source"]} - - await asyncio.gather( - ops_test.model.deploy( - charm, resources=resources, application_name=MON_APP, series="jammy" - ), - ops_test.model.deploy(GRAFANA_CHARM, application_name=GRAFANA_APP, channel="stable"), - ) - async with ops_test.fast_forward(): - await ops_test.model.wait_for_idle(apps=[GRAFANA_APP], status="active") - await ops_test.model.wait_for_idle(apps=[MON_APP], status="blocked") - - -@pytest.mark.abort_on_fail -async def test_mon_cannot_create_datasource_grafana_url_is_not_set(ops_test: OpsTest): - action = await _run_action_create_datasource(ops_test, DS_NAME, DS_URL) - assert action.status == "failed" - assert "Invalid URL" in action.message - - -@pytest.mark.abort_on_fail -async def test_mon_cannot_list_datasources_grafana_url_is_not_set(ops_test: OpsTest): - action = await _run_action_list_datasources(ops_test) - assert action.status == "failed" - assert "Invalid URL" in action.message - - -@pytest.mark.abort_on_fail -async def test_mon_cannot_delete_datasource_grafana_url_is_not_set(ops_test: OpsTest): - action = await _run_action_delete_datasource(ops_test, "prometheus") - assert action.status == "failed" - assert "Invalid URL" in action.message - - -@pytest.mark.abort_on_fail -async def test_mon_cannot_create_datasource_due_to_invalid_grafana_password(ops_test: OpsTest): - await ops_test.model.applications[MON_APP].set_config( - {"grafana-url": f"http://{GRAFANA_APP}:3000", "grafana-user": "admin"} - ) - async with ops_test.fast_forward(): - await ops_test.model.wait_for_idle(apps=[MON_APP], status="blocked") - - action = await _run_action_create_datasource(ops_test, DS_NAME, DS_URL) - assert action.status == "failed" - assert action.message == "invalid username or password" - - -@pytest.mark.abort_on_fail -async def test_mon_cannot_create_datasource_invalid_url_fails(ops_test: OpsTest): - await ops_test.model.applications[MON_APP].set_config( - {"grafana-url": f"http://{GRAFANA_APP}:3000"} - ) - async with ops_test.fast_forward(): - await ops_test.model.wait_for_idle(apps=[MON_APP], status="blocked") - - action = await _run_action_create_datasource(ops_test, DS_NAME, "prometheus:9090") - assert action.status == "failed" - assert action.message == "Invalid datasource url 'prometheus:9090'" - - -async def _get_grafana_admin_password(ops_test: OpsTest): - action = ( - await ops_test.model.applications[GRAFANA_APP].units[0].run_action("get-admin-password") - ) - admin_password = (await action.wait()).results["admin-password"] - logger.info(f"Password obtained from {GRAFANA_APP} : {admin_password}") - assert admin_password != "Admin password has been changed by an administrator" - return admin_password - - -@pytest.mark.abort_on_fail -async def test_grafana_password_is_set_in_mon_config(ops_test: OpsTest): - admin_password = await _get_grafana_admin_password(ops_test) - - default_password = None - grafana_password_in_mon = ( - (await ops_test.model.applications[MON_APP].get_config()) - .get("grafana-password") - .get("value") - ) - assert grafana_password_in_mon == default_password - - await ops_test.model.applications[MON_APP].set_config({"grafana-password": admin_password}) - - async with ops_test.fast_forward(): - await ops_test.model.wait_for_idle(apps=[GRAFANA_APP], status="active") - await ops_test.model.wait_for_idle(apps=[MON_APP], status="blocked") - - grafana_password_in_mon = ( - (await ops_test.model.applications[MON_APP].get_config()) - .get("grafana-password") - .get("value") - ) - assert grafana_password_in_mon == admin_password - - -@pytest.mark.abort_on_fail -async def test_mon_create_datasource_successfully(ops_test: OpsTest): - action = await _run_action_create_datasource(ops_test, DS_NAME, DS_URL) - assert action.status == "completed" - assert action.results["datasource-name"] == DS_NAME - - -@pytest.mark.abort_on_fail -async def test_mon_list_datasources_returns_osm_prometheus(ops_test: OpsTest): - action = await _run_action_list_datasources(ops_test) - assert action.status == "completed" - datasources = json.loads(action.results.get("datasources")) - assert len(datasources) == 1 - assert datasources[0].get("name") == DS_NAME - assert datasources[0].get("type") == "prometheus" - - -@pytest.mark.abort_on_fail -async def test_mon_create_datasource_that_already_exists_returns_error_message(ops_test: OpsTest): - action = await _run_action_create_datasource(ops_test, DS_NAME, DS_URL) - assert action.status == "failed" - assert action.message == "data source with the same name already exists" - - -@pytest.mark.abort_on_fail -async def test_mon_delete_existing_datasource_returns_success_message(ops_test: OpsTest): - action = await _run_action_delete_datasource(ops_test, DS_NAME) - assert action.status == "completed" - - -@pytest.mark.abort_on_fail -async def test_mon_list_datasources_is_empty(ops_test: OpsTest): - action = await _run_action_list_datasources(ops_test) - assert action.status == "completed" - datasources = json.loads(action.results.get("datasources")) - assert len(datasources) == 0 - - -@pytest.mark.abort_on_fail -async def test_mon_delete_non_existing_datasource_returns_error_message(ops_test: OpsTest): - action = await _run_action_delete_datasource(ops_test, DS_NAME) - assert action.status == "failed" - assert action.message == "Data source not found" - - -@pytest.mark.abort_on_fail -async def test_mon_create_datasource_incorrect_grafana_host_fails(ops_test: OpsTest): - await ops_test.model.applications[MON_APP].set_config( - {"grafana-url": f"http://{GRAFANA_APP}-k8s:3000"} - ) - async with ops_test.fast_forward(): - await ops_test.model.wait_for_idle(apps=[MON_APP], status="blocked") - action = await _run_action_create_datasource(ops_test, DS_NAME, DS_URL) - assert action.status == "failed" - assert f"Failed to resolve '{GRAFANA_APP}-k8s'" in action.message - - -@pytest.mark.abort_on_fail -async def test_mon_list_datasources_incorrect_grafana_host_fails(ops_test: OpsTest): - action = await _run_action_list_datasources(ops_test) - assert action.status == "failed" - assert f"Failed to resolve '{GRAFANA_APP}-k8s'" in action.message - - -@pytest.mark.abort_on_fail -async def test_mon_delete_datasource_incorrect_grafana_host_fails(ops_test: OpsTest): - action = await _run_action_delete_datasource(ops_test, DS_NAME) - assert action.status == "failed" - assert f"Failed to resolve '{GRAFANA_APP}-k8s'" in action.message - - -@pytest.mark.abort_on_fail -async def test_mon_incorrect_grafana_port_returns_timeout_message(ops_test: OpsTest): - await ops_test.model.applications[MON_APP].set_config( - {"grafana-url": f"http://{GRAFANA_APP}:3001"} - ) - async with ops_test.fast_forward(): - await ops_test.model.wait_for_idle(apps=[MON_APP], status="blocked") - action = await _run_action_create_datasource(ops_test, DS_NAME, DS_URL) - assert action.status == "failed" - assert f"Connection to {GRAFANA_APP} timed out" in action.message - - -@pytest.mark.abort_on_fail -async def test_mon_list_datasources_incorrect_user_fails(ops_test: OpsTest): - await ops_test.model.applications[MON_APP].set_config( - {"grafana-url": f"http://{GRAFANA_APP}:3000", "grafana-user": "some_user"} - ) - async with ops_test.fast_forward(): - await ops_test.model.wait_for_idle(apps=[MON_APP], status="blocked") - action = await _run_action_list_datasources(ops_test) - assert action.status == "failed" - assert action.message == "invalid username or password" - - -@pytest.mark.abort_on_fail -async def test_mon_delete_datasource_incorrect_user_fails(ops_test: OpsTest): - action = await _run_action_delete_datasource(ops_test, DS_NAME) - assert action.status == "failed" - assert action.message == "invalid username or password" diff --git a/installers/charm/osm-mon/tests/unit/test_charm.py b/installers/charm/osm-mon/tests/unit/test_charm.py index 441eddbf..33598fe6 100644 --- a/installers/charm/osm-mon/tests/unit/test_charm.py +++ b/installers/charm/osm-mon/tests/unit/test_charm.py @@ -42,27 +42,7 @@ def harness(mocker: MockerFixture): harness.cleanup() -def _set_grafana_config(harness: Harness): - harness.update_config( - { - "grafana-url": "http://prometheus:1234", - "grafana-user": "user", - "grafana-password": "password", - } - ) - - -def test_default_grafana_config_is_invalid_charm_is_blocked(harness: Harness): - harness.charm.on.config_changed.emit() - assert type(harness.charm.unit.status) == BlockedStatus - assert ( - "need grafana-url, grafana-user, grafana-password config" - == harness.charm.unit.status.message - ) - - def test_missing_relations(harness: Harness): - _set_grafana_config(harness) harness.charm.on.config_changed.emit() assert type(harness.charm.unit.status) == BlockedStatus assert all( @@ -71,48 +51,12 @@ def test_missing_relations(harness: Harness): ) -def test_grafana_url_without_schema_block_status(harness: Harness): - harness.update_config( - {"grafana-url": "foo.com", "grafana-user": "user", "grafana-password": "password"} - ) - assert type(harness.charm.unit.status) == BlockedStatus - assert "Invalid value for grafana-url config: 'foo.com'" == harness.charm.unit.status.message - - -def test_grafana_url_with_port_without_schema_block_status(harness: Harness): - harness.update_config( - {"grafana-url": "foo.com:9090", "grafana-user": "user", "grafana-password": "password"} - ) - assert type(harness.charm.unit.status) == BlockedStatus - assert ( - "Invalid value for grafana-url config: 'foo.com:9090'" == harness.charm.unit.status.message - ) - - -def test_grafana_url_without_port_is_valid(harness: Harness): - _add_relations(harness) - harness.update_config( - {"grafana-url": "http://foo", "grafana-user": "user", "grafana-password": "password"} - ) - assert harness.charm.unit.status == ActiveStatus() - - -def test_grafana_url_with_port_is_valid(harness: Harness): - _add_relations(harness) - harness.update_config( - {"grafana-url": "http://foo:90", "grafana-user": "user", "grafana-password": "password"} - ) - assert harness.charm.unit.status == ActiveStatus() - - def test_ready(harness: Harness): - _set_grafana_config(harness) _add_relations(harness) assert harness.charm.unit.status == ActiveStatus() def test_container_stops_after_relation_broken(harness: Harness): - _set_grafana_config(harness) harness.charm.on[container_name].pebble_ready.emit(container_name) container = harness.charm.unit.get_container(container_name) relation_ids = _add_relations(harness) -- 2.25.1