Skip to content

Commit

Permalink
chore: update charm libraries
Browse files Browse the repository at this point in the history
  • Loading branch information
observability-noctua-bot committed May 8, 2024
1 parent 23c37dc commit b059024
Show file tree
Hide file tree
Showing 5 changed files with 182 additions and 79 deletions.
36 changes: 20 additions & 16 deletions lib/charms/hydra/v0/oauth.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,21 +48,14 @@ def _set_client_config(self):
```
"""

import inspect
import json
import logging
import re
from dataclasses import asdict, dataclass, field
from dataclasses import asdict, dataclass, field, fields
from typing import Dict, List, Mapping, Optional

import jsonschema
from ops.charm import (
CharmBase,
RelationBrokenEvent,
RelationChangedEvent,
RelationCreatedEvent,
RelationDepartedEvent,
)
from ops.charm import CharmBase, RelationBrokenEvent, RelationChangedEvent, RelationCreatedEvent
from ops.framework import EventBase, EventSource, Handle, Object, ObjectEvents
from ops.model import Relation, Secret, TooManyRelatedAppsError

Expand All @@ -74,12 +67,20 @@ def _set_client_config(self):

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

PYDEPS = ["jsonschema"]


logger = logging.getLogger(__name__)

DEFAULT_RELATION_NAME = "oauth"
ALLOWED_GRANT_TYPES = ["authorization_code", "refresh_token", "client_credentials"]
ALLOWED_GRANT_TYPES = [
"authorization_code",
"refresh_token",
"client_credentials",
"urn:ietf:params:oauth:grant-type:device_code",
]
ALLOWED_CLIENT_AUTHN_METHODS = ["client_secret_basic", "client_secret_post"]
CLIENT_SECRET_FIELD = "secret"

Expand Down Expand Up @@ -295,7 +296,7 @@ class OauthProviderConfig:
@classmethod
def from_dict(cls, dic: Dict) -> "OauthProviderConfig":
"""Generate OauthProviderConfig instance from dict."""
return cls(**{k: v for k, v in dic.items() if k in inspect.signature(cls).parameters})
return cls(**{k: v for k, v in dic.items() if k in [f.name for f in fields(cls)]})


class OAuthInfoChangedEvent(EventBase):
Expand All @@ -315,6 +316,7 @@ def snapshot(self) -> Dict:

def restore(self, snapshot: Dict) -> None:
"""Restore event."""
super().restore(snapshot)
self.client_id = snapshot["client_id"]
self.client_secret_id = snapshot["client_secret_id"]

Expand Down Expand Up @@ -454,7 +456,9 @@ def is_client_created(self, relation_id: Optional[int] = None) -> bool:
and "client_secret_id" in relation.data[relation.app]
)

def get_provider_info(self, relation_id: Optional[int] = None) -> OauthProviderConfig:
def get_provider_info(
self, relation_id: Optional[int] = None
) -> Optional[OauthProviderConfig]:
"""Get the provider information from the databag."""
if len(self.model.relations) == 0:
return None
Expand Down Expand Up @@ -647,8 +651,8 @@ def __init__(self, charm: CharmBase, relation_name: str = DEFAULT_RELATION_NAME)
self._get_client_config_from_relation_data,
)
self.framework.observe(
events.relation_departed,
self._on_relation_departed,
events.relation_broken,
self._on_relation_broken,
)

def _get_client_config_from_relation_data(self, event: RelationChangedEvent) -> None:
Expand Down Expand Up @@ -696,7 +700,7 @@ def _get_client_config_from_relation_data(self, event: RelationChangedEvent) ->
def _get_secret_label(self, relation: Relation) -> str:
return f"client_secret_{relation.id}"

def _on_relation_departed(self, event: RelationDepartedEvent) -> None:
def _on_relation_broken(self, event: RelationBrokenEvent) -> None:
# Workaround for https://github.com/canonical/operator/issues/888
self._pop_relation_data(event.relation.id)

Expand Down
34 changes: 13 additions & 21 deletions lib/charms/observability_libs/v0/cert_handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,18 +40,18 @@
from typing import List, Optional, Union, cast

try:
from charms.tls_certificates_interface.v3.tls_certificates import ( # type: ignore
from charms.tls_certificates_interface.v2.tls_certificates import ( # type: ignore
AllCertificatesInvalidatedEvent,
CertificateAvailableEvent,
CertificateExpiringEvent,
CertificateInvalidatedEvent,
TLSCertificatesRequiresV3,
TLSCertificatesRequiresV2,
generate_csr,
generate_private_key,
)
except ImportError as e:
raise ImportError(
"failed to import charms.tls_certificates_interface.v3.tls_certificates; "
"failed to import charms.tls_certificates_interface.v2.tls_certificates; "
"Either the library itself is missing (please get it through charmcraft fetch-lib) "
"or one of its dependencies is unmet."
) from e
Expand All @@ -67,7 +67,7 @@

LIBID = "b5cd5cd580f3428fa5f59a8876dcbe6a"
LIBAPI = 0
LIBPATCH = 12
LIBPATCH = 13


def is_ip_address(value: str) -> bool:
Expand Down Expand Up @@ -132,7 +132,7 @@ def __init__(
self.peer_relation_name = peer_relation_name
self.certificates_relation_name = certificates_relation_name

self.certificates = TLSCertificatesRequiresV3(self.charm, self.certificates_relation_name)
self.certificates = TLSCertificatesRequiresV2(self.charm, self.certificates_relation_name)

self.framework.observe(
self.charm.on.config_changed,
Expand Down Expand Up @@ -289,7 +289,7 @@ def _generate_csr(
if clear_cert:
self._ca_cert = ""
self._server_cert = ""
self._chain = ""
self._chain = []

def _on_certificate_available(self, event: CertificateAvailableEvent) -> None:
"""Get the certificate from the event and store it in a peer relation.
Expand All @@ -311,7 +311,7 @@ def _on_certificate_available(self, event: CertificateAvailableEvent) -> None:
if event_csr == self._csr:
self._ca_cert = event.ca
self._server_cert = event.certificate
self._chain = event.chain_as_pem()
self._chain = event.chain
self.on.cert_changed.emit() # pyright: ignore

@property
Expand Down Expand Up @@ -382,29 +382,21 @@ def _server_cert(self, value: str):
rel.data[self.charm.unit].update({"certificate": value})

@property
def _chain(self) -> str:
def _chain(self) -> List[str]:
if self._peer_relation:
if chain := self._peer_relation.data[self.charm.unit].get("chain", ""):
chain = json.loads(chain)

# In a previous version of this lib, chain used to be a list.
# Convert the List[str] to str, per
# https://github.com/canonical/tls-certificates-interface/pull/141
if isinstance(chain, list):
chain = "\n\n".join(reversed(chain))

return cast(str, chain)
return ""
if chain := self._peer_relation.data[self.charm.unit].get("chain", []):
return cast(list, json.loads(cast(str, chain)))
return []

@_chain.setter
def _chain(self, value: str):
def _chain(self, value: List[str]):
# Caller must guard. We want the setter to fail loudly. Failure must have a side effect.
rel = self._peer_relation
assert rel is not None # For type checker
rel.data[self.charm.unit].update({"chain": json.dumps(value)})

@property
def chain(self) -> str:
def chain(self) -> List[str]:
"""Return the ca chain."""
return self._chain

Expand Down
6 changes: 3 additions & 3 deletions lib/charms/prometheus_k8s/v0/prometheus_scrape.py
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ def __init__(self, *args):
- `scrape_timeout`
- `proxy_url`
- `relabel_configs`
- `metrics_relabel_configs`
- `metric_relabel_configs`
- `sample_limit`
- `label_limit`
- `label_name_length_limit`
Expand Down 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 = 46
LIBPATCH = 47

PYDEPS = ["cosl"]

Expand All @@ -377,7 +377,7 @@ def _on_scrape_targets_changed(self, event):
"scrape_timeout",
"proxy_url",
"relabel_configs",
"metrics_relabel_configs",
"metric_relabel_configs",
"sample_limit",
"label_limit",
"label_name_length_limit",
Expand Down
20 changes: 14 additions & 6 deletions lib/charms/tempo_k8s/v2/tracing.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,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 = 3
LIBPATCH = 4

PYDEPS = ["pydantic"]

Expand Down Expand Up @@ -308,6 +308,9 @@ class TracingProviderAppData(DatabagModel): # noqa: D101
external_url: Optional[str] = None
"""Server url. If an ingress is present, it will be the ingress address."""

internal_scheme: Optional[str] = None
"""Scheme for internal communication. If it is present, it will be protocol accepted by the provider."""


class TracingRequirerAppData(DatabagModel): # noqa: D101
"""Application databag model for the tracing requirer."""
Expand Down Expand Up @@ -495,6 +498,7 @@ def __init__(
host: str,
external_url: Optional[str] = None,
relation_name: str = DEFAULT_RELATION_NAME,
internal_scheme: Optional[Literal["http", "https"]] = "http",
):
"""Initialize.
Expand Down Expand Up @@ -525,6 +529,7 @@ def __init__(
self._host = host
self._external_url = external_url
self._relation_name = relation_name
self._internal_scheme = internal_scheme
self.framework.observe(
self._charm.on[relation_name].relation_joined, self._on_relation_event
)
Expand Down Expand Up @@ -590,10 +595,11 @@ def publish_receivers(self, receivers: Sequence[RawReceiver]):
try:
TracingProviderAppData(
host=self._host,
external_url=self._external_url,
external_url=f"http://{self._external_url}" if self._external_url else None,
receivers=[
Receiver(port=port, protocol=protocol) for protocol, port in receivers
],
internal_scheme=self._internal_scheme,
).dump(relation.data[self._charm.app])

except ModelError as e:
Expand Down Expand Up @@ -822,11 +828,13 @@ def _get_endpoint(
receiver = receivers[0]
# if there's an external_url argument (v2.5+), use that. Otherwise, we use the tempo local fqdn
if app_data.external_url:
url = app_data.external_url
url = f"{app_data.external_url}:{receiver.port}"
else:
# FIXME: if we don't get an external url but only a
# hostname, we don't know what scheme we need to be using. ASSUME HTTP
url = f"http://{app_data.host}:{receiver.port}"
if app_data.internal_scheme:
url = f"{app_data.internal_scheme}://{app_data.host}:{receiver.port}"
else:
# if we didn't receive a scheme (old provider), we assume HTTP is used
url = f"http://{app_data.host}:{receiver.port}"

if receiver.protocol.endswith("grpc"):
# TCP protocols don't want an http/https scheme prefix
Expand Down
Loading

0 comments on commit b059024

Please sign in to comment.