Skip to content

Commit

Permalink
Update libs, drop itest (#211)
Browse files Browse the repository at this point in the history
* fetch-lib
* Remove buggy, unnecessary itest
* Fix tls test
  • Loading branch information
sed-i authored Jan 29, 2024
1 parent 950777a commit 08b1d45
Show file tree
Hide file tree
Showing 8 changed files with 469 additions and 270 deletions.
38 changes: 25 additions & 13 deletions lib/charms/observability_libs/v0/cert_handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@

LIBID = "b5cd5cd580f3428fa5f59a8876dcbe6a"
LIBAPI = 0
LIBPATCH = 8
LIBPATCH = 9


def is_ip_address(value: str) -> bool:
Expand Down Expand Up @@ -181,33 +181,40 @@ def _peer_relation(self) -> Optional[Relation]:
return self.charm.model.get_relation(self.peer_relation_name, None)

def _on_peer_relation_created(self, _):
"""Generate the private key and store it in a peer relation."""
# We're in "relation-created", so the relation should be there
"""Generate the CSR if the certificates relation is ready."""
self._generate_privkey()

# Just in case we already have a private key, do not overwrite it.
# Not sure how this could happen.
# TODO figure out how to go about key rotation.
if not self._private_key:
private_key = generate_private_key()
self._private_key = private_key.decode()

# Generate CSR here, in case peer events fired after tls-certificate relation events
# check cert relation is ready
if not (self.charm.model.get_relation(self.certificates_relation_name)):
# peer relation event happened to fire before tls-certificates events.
# Abort, and let the "certificates joined" observer create the CSR.
logger.info("certhandler waiting on certificates relation")
return

logger.debug("certhandler has peer and certs relation: proceeding to generate csr")
self._generate_csr()

def _on_certificates_relation_joined(self, _) -> None:
"""Generate the CSR and request the certificate creation."""
"""Generate the CSR if the peer relation is ready."""
self._generate_privkey()

# check peer relation is there
if not self._peer_relation:
# tls-certificates relation event happened to fire before peer events.
# Abort, and let the "peer joined" relation create the CSR.
logger.info("certhandler waiting on peer relation")
return

logger.debug("certhandler has peer and certs relation: proceeding to generate csr")
self._generate_csr()

def _generate_privkey(self):
# Generate priv key unless done already
# TODO figure out how to go about key rotation.
if not self._private_key:
private_key = generate_private_key()
self._private_key = private_key.decode()

def _on_config_changed(self, _):
# FIXME on config changed, the web_external_url may or may not change. But because every
# call to `generate_csr` appends a uuid, CSRs cannot be easily compared to one another.
Expand Down Expand Up @@ -237,7 +244,12 @@ def _generate_csr(
# In case we already have a csr, do not overwrite it by default.
if overwrite or renew or not self._csr:
private_key = self._private_key
assert private_key is not None # for type checker
if private_key is None:
# FIXME: raise this in a less nested scope by
# generating privkey and csr in the same method.
raise RuntimeError(
"private key unset. call _generate_privkey() before you call this method."
)
csr = generate_csr(
private_key=private_key.encode(),
subject=self.cert_subject,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ def setUp(self, *unused):
from math import ceil, floor
from typing import Callable, Dict, List, Optional, Union

from lightkube import ApiError, Client
from lightkube import ApiError, Client # pyright: ignore
from lightkube.core import exceptions
from lightkube.models.apps_v1 import StatefulSetSpec
from lightkube.models.core_v1 import (
Expand All @@ -133,7 +133,7 @@ def setUp(self, *unused):

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


_Decimal = Union[Decimal, float, str, int] # types that are potentially convertible to Decimal
Expand Down Expand Up @@ -322,7 +322,7 @@ def __init__(self, namespace: str, statefulset_name: str, container_name: str):
self.namespace = namespace
self.statefulset_name = statefulset_name
self.container_name = container_name
self.client = Client()
self.client = Client() # pyright: ignore

def _patched_delta(self, resource_reqs: ResourceRequirements) -> StatefulSet:
statefulset = self.client.get(
Expand Down Expand Up @@ -366,7 +366,7 @@ def is_patched(self, resource_reqs: ResourceRequirements) -> bool:
"""
return equals_canonically(self.get_templated(), resource_reqs)

def get_templated(self) -> ResourceRequirements:
def get_templated(self) -> Optional[ResourceRequirements]:
"""Returns the resource limits specified in the StatefulSet template."""
statefulset = self.client.get(
StatefulSet, name=self.statefulset_name, namespace=self.namespace
Expand All @@ -377,7 +377,7 @@ def get_templated(self) -> ResourceRequirements:
)
return podspec_tpl.resources

def get_actual(self, pod_name: str) -> ResourceRequirements:
def get_actual(self, pod_name: str) -> Optional[ResourceRequirements]:
"""Return the resource limits that are in effect for the container in the given pod."""
pod = self.client.get(Pod, name=pod_name, namespace=self.namespace)
podspec = self._get_container(
Expand Down Expand Up @@ -421,7 +421,7 @@ def apply(self, resource_reqs: ResourceRequirements) -> None:
class KubernetesComputeResourcesPatch(Object):
"""A utility for patching the Kubernetes compute resources set up by Juju."""

on = K8sResourcePatchEvents()
on = K8sResourcePatchEvents() # pyright: ignore

def __init__(
self,
Expand Down
28 changes: 17 additions & 11 deletions lib/charms/prometheus_k8s/v0/prometheus_scrape.py
Original file line number Diff line number Diff line change
Expand Up @@ -362,7 +362,7 @@ def _on_scrape_targets_changed(self, event):

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

PYDEPS = ["cosl"]

Expand All @@ -386,6 +386,7 @@ def _on_scrape_targets_changed(self, event):
"basic_auth",
"tls_config",
"authorization",
"params",
}
DEFAULT_JOB = {
"metrics_path": "/metrics",
Expand Down Expand Up @@ -764,7 +765,7 @@ def _validate_relation_by_interface_and_direction(
actual_relation_interface = relation.interface_name
if actual_relation_interface != expected_relation_interface:
raise RelationInterfaceMismatchError(
relation_name, expected_relation_interface, actual_relation_interface
relation_name, expected_relation_interface, actual_relation_interface or "None"
)

if expected_relation_role == RelationRole.provides:
Expand Down Expand Up @@ -857,7 +858,7 @@ class MonitoringEvents(ObjectEvents):
class MetricsEndpointConsumer(Object):
"""A Prometheus based Monitoring service."""

on = MonitoringEvents()
on = MonitoringEvents() # pyright: ignore

def __init__(self, charm: CharmBase, relation_name: str = DEFAULT_RELATION_NAME):
"""A Prometheus based Monitoring service.
Expand Down Expand Up @@ -1014,7 +1015,6 @@ def alerts(self) -> dict:
try:
scrape_metadata = json.loads(relation.data[relation.app]["scrape_metadata"])
identifier = JujuTopology.from_dict(scrape_metadata).identifier
alerts[identifier] = self._tool.apply_label_matchers(alert_rules) # type: ignore

except KeyError as e:
logger.debug(
Expand All @@ -1029,6 +1029,10 @@ def alerts(self) -> dict:
)
continue

# We need to append the relation info to the identifier. This is to allow for cases for there are two
# relations which eventually scrape the same application. Issue #551.
identifier = f"{identifier}_{relation.name}_{relation.id}"

alerts[identifier] = alert_rules

_, errmsg = self._tool.validate_alert_rules(alert_rules)
Expand Down Expand Up @@ -1294,7 +1298,7 @@ def _resolve_dir_against_charm_path(charm: CharmBase, *path_elements: str) -> st
class MetricsEndpointProvider(Object):
"""A metrics endpoint for Prometheus."""

on = MetricsEndpointProviderEvents()
on = MetricsEndpointProviderEvents() # pyright: ignore

def __init__(
self,
Expand Down Expand Up @@ -1836,14 +1840,16 @@ def _set_prometheus_data(self, event):
return

jobs = [] + _type_convert_stored(
self._stored.jobs
self._stored.jobs # pyright: ignore
) # list of scrape jobs, one per relation
for relation in self.model.relations[self._target_relation]:
targets = self._get_targets(relation)
if targets and relation.app:
jobs.append(self._static_scrape_job(targets, relation.app.name))

groups = [] + _type_convert_stored(self._stored.alert_rules) # list of alert rule groups
groups = [] + _type_convert_stored(
self._stored.alert_rules # pyright: ignore
) # list of alert rule groups
for relation in self.model.relations[self._alert_rules_relation]:
unit_rules = self._get_alert_rules(relation)
if unit_rules and relation.app:
Expand Down Expand Up @@ -1895,7 +1901,7 @@ def set_target_job_data(self, targets: dict, app_name: str, **kwargs) -> None:
jobs.append(updated_job)
relation.data[self._charm.app]["scrape_jobs"] = json.dumps(jobs)

if not _type_convert_stored(self._stored.jobs) == jobs:
if not _type_convert_stored(self._stored.jobs) == jobs: # pyright: ignore
self._stored.jobs = jobs

def _on_prometheus_targets_departed(self, event):
Expand Down Expand Up @@ -1947,7 +1953,7 @@ def remove_prometheus_jobs(self, job_name: str, unit_name: Optional[str] = ""):

relation.data[self._charm.app]["scrape_jobs"] = json.dumps(jobs)

if not _type_convert_stored(self._stored.jobs) == jobs:
if not _type_convert_stored(self._stored.jobs) == jobs: # pyright: ignore
self._stored.jobs = jobs

def _job_name(self, appname) -> str:
Expand Down Expand Up @@ -2126,7 +2132,7 @@ def set_alert_rule_data(self, name: str, unit_rules: dict, label_rules: bool = T
groups.append(updated_group)
relation.data[self._charm.app]["alert_rules"] = json.dumps({"groups": groups})

if not _type_convert_stored(self._stored.alert_rules) == groups:
if not _type_convert_stored(self._stored.alert_rules) == groups: # pyright: ignore
self._stored.alert_rules = groups

def _on_alert_rules_departed(self, event):
Expand Down Expand Up @@ -2176,7 +2182,7 @@ def remove_alert_rules(self, group_name: str, unit_name: str) -> None:
json.dumps({"groups": groups}) if groups else "{}"
)

if not _type_convert_stored(self._stored.alert_rules) == groups:
if not _type_convert_stored(self._stored.alert_rules) == groups: # pyright: ignore
self._stored.alert_rules = groups

def _get_alert_rules(self, relation) -> dict:
Expand Down
Loading

0 comments on commit 08b1d45

Please sign in to comment.