Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Grafana Datasource support and Dashboards #34

Merged
merged 9 commits into from
Feb 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
756 changes: 756 additions & 0 deletions lib/charms/grafana_k8s/v0/grafana_source.py

Large diffs are not rendered by default.

22 changes: 18 additions & 4 deletions lib/charms/loki_k8s/v1/loki_push_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@
Subsequently, a Loki charm may instantiate the `LokiPushApiProvider` in its constructor as
follows:

from charms.loki_k8s.v0.loki_push_api import LokiPushApiProvider
from charms.loki_k8s.v1.loki_push_api import LokiPushApiProvider
from loki_server import LokiServer
...

Expand Down Expand Up @@ -167,7 +167,7 @@ def __init__(self, *args):
sends logs).

```python
from charms.loki_k8s.v0.loki_push_api import LokiPushApiConsumer
from charms.loki_k8s.v1.loki_push_api import LokiPushApiConsumer

class LokiClientCharm(CharmBase):

Expand Down Expand Up @@ -518,7 +518,7 @@ def _alert_rules_error(self, event):

# Increment this PATCH version before using `charmcraft publish-lib` or reset
# to 0 if you are raising the major API version
LIBPATCH = 2
LIBPATCH = 3

logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -2089,7 +2089,21 @@ def _download_and_push_promtail_to_workload(
- "binsha": sha256 sum of unpacked promtail binary
container: container into which promtail is to be uploaded.
"""
with request.urlopen(promtail_info["url"]) as r:
# Check for Juju proxy variables and fall back to standard ones if not set
proxies: Optional[Dict[str, str]] = {}
if proxies and os.environ.get("JUJU_CHARM_HTTP_PROXY"):
proxies.update({"http": os.environ["JUJU_CHARM_HTTP_PROXY"]})
if proxies and os.environ.get("JUJU_CHARM_HTTPS_PROXY"):
proxies.update({"https": os.environ["JUJU_CHARM_HTTPS_PROXY"]})
if proxies and os.environ.get("JUJU_CHARM_NO_PROXY"):
proxies.update({"no_proxy": os.environ["JUJU_CHARM_NO_PROXY"]})
else:
proxies = None

proxy_handler = request.ProxyHandler(proxies)
opener = request.build_opener(proxy_handler)

with opener.open(promtail_info["url"]) as r:
file_bytes = r.read()
file_path = os.path.join(BINARY_DIR, promtail_info["filename"] + ".gz")
with open(file_path, "wb") as f:
Expand Down
7 changes: 6 additions & 1 deletion lib/charms/mimir_coordinator_k8s/v0/mimir_cluster.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
DEFAULT_ENDPOINT_NAME = "mimir-cluster"

LIBAPI = 0
LIBPATCH = 3
LIBPATCH = 2

BUILTIN_JUJU_KEYS = {"ingress-address", "private-address", "egress-subnets"}

Expand Down Expand Up @@ -283,6 +283,11 @@ def gather_addresses(self) -> Set[str]:
data.update(address_set)

return data

def get_datasource_address(self) -> Optional[str]:
addresses_by_role = self.gather_addresses_by_role()
if address_set := addresses_by_role.get("ruler", None):
return address_set.pop()

def gather_topology(self) -> List[Dict[str,str]]:
data = []
Expand Down
4 changes: 2 additions & 2 deletions lib/charms/observability_libs/v1/cert_handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -323,7 +323,7 @@ def private_key(self) -> Optional[str]:

@property
def private_key_secret_id(self) -> Optional[str]:
"""Private key secret id."""
"""ID of the Juju Secret for the Private key."""
return self._retrieve_secret_id("private-key-secret-id")

@property
Expand Down Expand Up @@ -351,7 +351,7 @@ def ca_cert(self) -> Optional[str]:

@property
def ca_server_cert_secret_id(self) -> Optional[str]:
"""CA, servert cert secret id."""
"""CA server cert secret id."""
return self._retrieve_secret_id("secret-id")

@property
Expand Down
16 changes: 5 additions & 11 deletions lib/charms/tempo_k8s/v1/charm_tracing.py
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@
# Increment this PATCH version before using `charmcraft publish-lib` or reset
# to 0 if you are raising the major API version

LIBPATCH = 1
LIBPATCH = 2

PYDEPS = ["opentelemetry-exporter-otlp-proto-http>=1.21.0"]

Expand Down Expand Up @@ -200,15 +200,12 @@
return tracer.get()
except LookupError:
try:
logger.debug("tracer was not found in context variable, looking up in default context")
ctx: Context = copy_context()
if context_tracer := _get_tracer_from_context(ctx):
return context_tracer.get()
else:
logger.debug("Couldn't find context var for tracer: span will be skipped")
return None
except LookupError as err:
logger.debug(f"Couldn't find tracer: span will be skipped, err: {err}")
return None


Expand All @@ -219,7 +216,6 @@
with tracer.start_as_current_span(name) as span:
yield cast(Span, span)
else:
logger.debug("tracer not found")
yield None


Expand All @@ -243,9 +239,9 @@
tracing_endpoint = tracing_endpoint_getter(self)

if tracing_endpoint is None:
logger.warning(
f"{charm}.{getattr(tracing_endpoint_getter, '__qualname__', str(tracing_endpoint_getter))} "
f"returned None; continuing with tracing DISABLED."
logger.debug(
"Charm tracing is disabled. Tracing endpoint is not defined - "
"tracing is not available or relation is not set."
)
return
elif not isinstance(tracing_endpoint, str):
Expand All @@ -266,15 +262,14 @@

if server_cert is None:
logger.warning(
f"{charm}.{server_cert_getter} returned None; continuing with INSECURE connection."
f"{charm}.{server_cert_getter} returned None; sending traces over INSECURE connection."
Dismissed Show dismissed Hide dismissed
)
return
elif not Path(server_cert).is_absolute():
raise ValueError(
f"{charm}.{server_cert_getter} should return a valid tls cert absolute path (string | Path)); "
f"got {server_cert} instead."
)
logger.debug("Certificate successfully retrieved.") # todo: some more validation?
return server_cert


Expand All @@ -300,7 +295,6 @@

original_event_context = framework._event_context

logging.debug("Initializing opentelemetry tracer...")
_service_name = service_name or self.app.name

resource = Resource.create(
Expand Down
16 changes: 10 additions & 6 deletions lib/charms/tempo_k8s/v1/tracing.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Copyright 2022 Pietro Pasotti
# Copyright 2024 Canonical Ltd.
# See LICENSE file for licensing details.
"""## Overview.

Expand Down Expand Up @@ -93,7 +93,7 @@ def __init__(self, *args):

# Increment this PATCH version before using `charmcraft publish-lib` or reset
# to 0 if you are raising the major API version
LIBPATCH = 2
LIBPATCH = 3

PYDEPS = ["pydantic>=2"]

Expand Down Expand Up @@ -151,8 +151,12 @@ def load(cls, databag: MutableMapping):
try:
return cls.parse_raw(json.dumps(data)) # type: ignore
except pydantic.ValidationError as e:
msg = f"failed to validate databag: {databag}"
logger.error(msg, exc_info=True)
if not data:
# databag is empty; this is usually expected
raise DataValidationError("empty databag")

msg = f"failed to validate databag contents: {data!r} as {cls}"
logger.debug(msg, exc_info=True)
raise DataValidationError(msg) from e

def dump(self, databag: Optional[MutableMapping] = None, clear: bool = True):
Expand Down Expand Up @@ -194,8 +198,8 @@ class TracingProviderAppData(DatabagModel): # noqa: D101


class _AutoSnapshotEvent(RelationEvent):
__args__ = () # type: Tuple[str, ...]
__optional_kwargs__ = {} # type: Dict[str, Any]
__args__: Tuple[str, ...] = ()
__optional_kwargs__: Dict[str, Any] = {}

@classmethod
def __attrs__(cls):
Expand Down
Loading
Loading