Revert "Integrate MON and Prometheus"
[osm/devops.git] / installers / charm / osm-mon / lib / charms / observability_libs / v0 / juju_topology.py
diff --git a/installers/charm/osm-mon/lib/charms/observability_libs/v0/juju_topology.py b/installers/charm/osm-mon/lib/charms/observability_libs/v0/juju_topology.py
deleted file mode 100644 (file)
index 26204cf..0000000
+++ /dev/null
@@ -1,313 +0,0 @@
-# Copyright 2023 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.
-
-"""## Overview.
-
-This document explains how to use the `JujuTopology` class to
-create and consume topology information from Juju in a consistent manner.
-
-The goal of the Juju topology is to uniquely identify a piece
-of software running across any of your Juju-managed deployments.
-This is achieved by combining the following four elements:
-
-- Model name
-- Model UUID
-- Application name
-- Unit identifier
-
-
-For a more in-depth description of the concept, as well as a
-walk-through of it's use-case in observability, see
-[this blog post](https://juju.is/blog/model-driven-observability-part-2-juju-topology-metrics)
-on the Juju blog.
-
-## Library Usage
-
-This library may be used to create and consume `JujuTopology` objects.
-The `JujuTopology` class provides three ways to create instances:
-
-### Using the `from_charm` method
-
-Enables instantiation by supplying the charm as an argument. When
-creating topology objects for the current charm, this is the recommended
-approach.
-
-```python
-topology = JujuTopology.from_charm(self)
-```
-
-### Using the `from_dict` method
-
-Allows for instantion using a dictionary of relation data, like the
-`scrape_metadata` from Prometheus or the labels of an alert rule. When
-creating topology objects for remote charms, this is the recommended
-approach.
-
-```python
-scrape_metadata = json.loads(relation.data[relation.app].get("scrape_metadata", "{}"))
-topology = JujuTopology.from_dict(scrape_metadata)
-```
-
-### Using the class constructor
-
-Enables instantiation using whatever values you want. While this
-is useful in some very specific cases, this is almost certainly not
-what you are looking for as setting these values manually may
-result in observability metrics which do not uniquely identify a
-charm in order to provide accurate usage reporting, alerting,
-horizontal scaling, or other use cases.
-
-```python
-topology = JujuTopology(
-    model="some-juju-model",
-    model_uuid="00000000-0000-0000-0000-000000000001",
-    application="fancy-juju-application",
-    unit="fancy-juju-application/0",
-    charm_name="fancy-juju-application-k8s",
-)
-```
-
-"""
-from collections import OrderedDict
-from typing import Dict, List, Optional
-from uuid import UUID
-
-# The unique Charmhub library identifier, never change it
-LIBID = "bced1658f20f49d28b88f61f83c2d232"
-
-LIBAPI = 0
-LIBPATCH = 6
-
-
-class InvalidUUIDError(Exception):
-    """Invalid UUID was provided."""
-
-    def __init__(self, uuid: str):
-        self.message = "'{}' is not a valid UUID.".format(uuid)
-        super().__init__(self.message)
-
-
-class JujuTopology:
-    """JujuTopology is used for storing, generating and formatting juju topology information.
-
-    DEPRECATED: This class is deprecated. Use `pip install cosl` and
-    `from cosl.juju_topology import JujuTopology` instead.
-    """
-
-    def __init__(
-        self,
-        model: str,
-        model_uuid: str,
-        application: str,
-        unit: Optional[str] = None,
-        charm_name: Optional[str] = None,
-    ):
-        """Build a JujuTopology object.
-
-        A `JujuTopology` object is used for storing and transforming
-        Juju topology information. This information is used to
-        annotate Prometheus scrape jobs and alert rules. Such
-        annotation when applied to scrape jobs helps in identifying
-        the source of the scrapped metrics. On the other hand when
-        applied to alert rules topology information ensures that
-        evaluation of alert expressions is restricted to the source
-        (charm) from which the alert rules were obtained.
-
-        Args:
-            model: a string name of the Juju model
-            model_uuid: a globally unique string identifier for the Juju model
-            application: an application name as a string
-            unit: a unit name as a string
-            charm_name: name of charm as a string
-        """
-        if not self.is_valid_uuid(model_uuid):
-            raise InvalidUUIDError(model_uuid)
-
-        self._model = model
-        self._model_uuid = model_uuid
-        self._application = application
-        self._charm_name = charm_name
-        self._unit = unit
-
-    def is_valid_uuid(self, uuid):
-        """Validate the supplied UUID against the Juju Model UUID pattern.
-
-        Args:
-            uuid: string that needs to be checked if it is valid v4 UUID.
-
-        Returns:
-            True if parameter is a valid v4 UUID, False otherwise.
-        """
-        try:
-            return str(UUID(uuid, version=4)) == uuid
-        except (ValueError, TypeError):
-            return False
-
-    @classmethod
-    def from_charm(cls, charm):
-        """Creates a JujuTopology instance by using the model data available on a charm object.
-
-        Args:
-            charm: a `CharmBase` object for which the `JujuTopology` will be constructed
-        Returns:
-            a `JujuTopology` object.
-        """
-        return cls(
-            model=charm.model.name,
-            model_uuid=charm.model.uuid,
-            application=charm.model.app.name,
-            unit=charm.model.unit.name,
-            charm_name=charm.meta.name,
-        )
-
-    @classmethod
-    def from_dict(cls, data: dict):
-        """Factory method for creating `JujuTopology` children from a dictionary.
-
-        Args:
-            data: a dictionary with five keys providing topology information. The keys are
-                - "model"
-                - "model_uuid"
-                - "application"
-                - "unit"
-                - "charm_name"
-                `unit` and `charm_name` may be empty, but will result in more limited
-                labels. However, this allows us to support charms without workloads.
-
-        Returns:
-            a `JujuTopology` object.
-        """
-        return cls(
-            model=data["model"],
-            model_uuid=data["model_uuid"],
-            application=data["application"],
-            unit=data.get("unit", ""),
-            charm_name=data.get("charm_name", ""),
-        )
-
-    def as_dict(
-        self,
-        *,
-        remapped_keys: Optional[Dict[str, str]] = None,
-        excluded_keys: Optional[List[str]] = None,
-    ) -> OrderedDict:
-        """Format the topology information into an ordered dict.
-
-        Keeping the dictionary ordered is important to be able to
-        compare dicts without having to resort to deep comparisons.
-
-        Args:
-            remapped_keys: A dictionary mapping old key names to new key names,
-                which will be substituted when invoked.
-            excluded_keys: A list of key names to exclude from the returned dict.
-            uuid_length: The length to crop the UUID to.
-        """
-        ret = OrderedDict(
-            [
-                ("model", self.model),
-                ("model_uuid", self.model_uuid),
-                ("application", self.application),
-                ("unit", self.unit),
-                ("charm_name", self.charm_name),
-            ]
-        )
-        if excluded_keys:
-            ret = OrderedDict({k: v for k, v in ret.items() if k not in excluded_keys})
-
-        if remapped_keys:
-            ret = OrderedDict(
-                (remapped_keys.get(k), v) if remapped_keys.get(k) else (k, v) for k, v in ret.items()  # type: ignore
-            )
-
-        return ret
-
-    @property
-    def identifier(self) -> str:
-        """Format the topology information into a terse string.
-
-        This crops the model UUID, making it unsuitable for comparisons against
-        anything but other identifiers. Mainly to be used as a display name or file
-        name where long strings might become an issue.
-
-        >>> JujuTopology( \
-              model = "a-model", \
-              model_uuid = "00000000-0000-4000-8000-000000000000", \
-              application = "some-app", \
-              unit = "some-app/1" \
-            ).identifier
-        'a-model_00000000_some-app'
-        """
-        parts = self.as_dict(
-            excluded_keys=["unit", "charm_name"],
-        )
-
-        parts["model_uuid"] = self.model_uuid_short
-        values = parts.values()
-
-        return "_".join([str(val) for val in values]).replace("/", "_")
-
-    @property
-    def label_matcher_dict(self) -> Dict[str, str]:
-        """Format the topology information into a dict with keys having 'juju_' as prefix.
-
-        Relabelled topology never includes the unit as it would then only match
-        the leader unit (ie. the unit that produced the dict).
-        """
-        items = self.as_dict(
-            remapped_keys={"charm_name": "charm"},
-            excluded_keys=["unit"],
-        ).items()
-
-        return {"juju_{}".format(key): value for key, value in items if value}
-
-    @property
-    def label_matchers(self) -> str:
-        """Format the topology information into a promql/logql label matcher string.
-
-        Topology label matchers should never include the unit as it
-        would then only match the leader unit (ie. the unit that
-        produced the matchers).
-        """
-        items = self.label_matcher_dict.items()
-        return ", ".join(['{}="{}"'.format(key, value) for key, value in items if value])
-
-    @property
-    def model(self) -> str:
-        """Getter for the juju model value."""
-        return self._model
-
-    @property
-    def model_uuid(self) -> str:
-        """Getter for the juju model uuid value."""
-        return self._model_uuid
-
-    @property
-    def model_uuid_short(self) -> str:
-        """Getter for the juju model value, truncated to the first eight letters."""
-        return self._model_uuid[:8]
-
-    @property
-    def application(self) -> str:
-        """Getter for the juju application value."""
-        return self._application
-
-    @property
-    def charm_name(self) -> Optional[str]:
-        """Getter for the juju charm name value."""
-        return self._charm_name
-
-    @property
-    def unit(self) -> Optional[str]:
-        """Getter for the juju unit value."""
-        return self._unit