Skip to content

Commit

Permalink
chore: update charm libraries (#487)
Browse files Browse the repository at this point in the history
Co-authored-by: Github Actions <[email protected]>
  • Loading branch information
observability-noctua-bot and Github Actions authored Jun 6, 2023
1 parent 72224ba commit 78707ec
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 35 deletions.
46 changes: 24 additions & 22 deletions lib/charms/grafana_k8s/v0/grafana_dashboard.py
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,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 = 30
LIBPATCH = 31

logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -955,7 +955,7 @@ def restore(self, snapshot):
"""Restore grafana source information."""
self.error_message = snapshot["error_message"]
self.valid = snapshot["valid"]
self.errors = json.loads(snapshot["errors"])
self.errors = json.loads(str(snapshot["errors"]))


class GrafanaProviderEvents(ObjectEvents):
Expand All @@ -968,7 +968,7 @@ class GrafanaDashboardProvider(Object):
"""An API to provide Grafana dashboards to a Grafana charm."""

_stored = StoredState()
on = GrafanaProviderEvents()
on = GrafanaProviderEvents() # pyright: ignore

def __init__(
self,
Expand Down Expand Up @@ -1072,7 +1072,7 @@ def add_dashboard(self, content: str, inject_dropdowns: bool = True) -> None:
"""
# Update of storage must be done irrespective of leadership, so
# that the stored state is there when this unit becomes leader.
stored_dashboard_templates = self._stored.dashboard_templates # type: Any
stored_dashboard_templates: Any = self._stored.dashboard_templates # pyright: ignore

encoded_dashboard = _encode_dashboard_content(content)

Expand All @@ -1093,7 +1093,7 @@ def remove_non_builtin_dashboards(self) -> None:
"""Remove all dashboards to the relation added via :method:`add_dashboard`."""
# Update of storage must be done irrespective of leadership, so
# that the stored state is there when this unit becomes leader.
stored_dashboard_templates = self._stored.dashboard_templates # type: Any
stored_dashboard_templates: Any = self._stored.dashboard_templates # pyright: ignore

for dashboard_id in list(stored_dashboard_templates.keys()):
if dashboard_id.startswith("prog:"):
Expand All @@ -1120,7 +1120,7 @@ def _update_all_dashboards_from_dir(
# Ensure we do not leave outdated dashboards by removing from stored all
# the encoded dashboards that start with "file/".
if self._dashboards_path:
stored_dashboard_templates = self._stored.dashboard_templates # type: Any
stored_dashboard_templates: Any = self._stored.dashboard_templates # pyright: ignore

for dashboard_id in list(stored_dashboard_templates.keys()):
if dashboard_id.startswith("file:"):
Expand Down Expand Up @@ -1174,7 +1174,7 @@ def _reinitialize_dashboard_data(self, inject_dropdowns: bool = True) -> None:
e.grafana_dashboards_absolute_path,
e.message,
)
stored_dashboard_templates = self._stored.dashboard_templates # type: Any
stored_dashboard_templates: Any = self._stored.dashboard_templates # pyright: ignore

for dashboard_id in list(stored_dashboard_templates.keys()):
if dashboard_id.startswith("file:"):
Expand Down Expand Up @@ -1212,16 +1212,18 @@ def _on_grafana_dashboard_relation_changed(self, event: RelationChangedEvent) ->
valid = bool(data.get("valid", True))
errors = data.get("errors", [])
if valid and not errors:
self.on.dashboard_status_changed.emit(valid=valid)
self.on.dashboard_status_changed.emit(valid=valid) # pyright: ignore
else:
self.on.dashboard_status_changed.emit(valid=valid, errors=errors)
self.on.dashboard_status_changed.emit( # pyright: ignore
valid=valid, errors=errors
)

def _upset_dashboards_on_relation(self, relation: Relation) -> None:
"""Update the dashboards in the relation data bucket."""
# It's completely ridiculous to add a UUID, but if we don't have some
# pseudo-random value, this never makes it across 'juju set-state'
stored_data = {
"templates": _type_convert_stored(self._stored.dashboard_templates),
"templates": _type_convert_stored(self._stored.dashboard_templates), # pyright: ignore
"uuid": str(uuid.uuid4()),
}

Expand Down Expand Up @@ -1256,7 +1258,7 @@ def dashboard_templates(self) -> List:
class GrafanaDashboardConsumer(Object):
"""A consumer object for working with Grafana Dashboards."""

on = GrafanaDashboardEvents()
on = GrafanaDashboardEvents() # pyright: ignore
_stored = StoredState()

def __init__(
Expand Down Expand Up @@ -1348,13 +1350,13 @@ def _on_grafana_dashboard_relation_changed(self, event: RelationChangedEvent) ->
changes = self._render_dashboards_and_signal_changed(event.relation)

if changes:
self.on.dashboards_changed.emit()
self.on.dashboards_changed.emit() # pyright: ignore

def _on_grafana_peer_changed(self, _: RelationChangedEvent) -> None:
"""Emit dashboard events on peer events so secondary charm data updates."""
if self._charm.unit.is_leader():
return
self.on.dashboards_changed.emit()
self.on.dashboards_changed.emit() # pyright: ignore

def update_dashboards(self, relation: Optional[Relation] = None) -> None:
"""Re-establish dashboards on one or more relations.
Expand Down Expand Up @@ -1401,7 +1403,7 @@ def _render_dashboards_and_signal_changed(self, relation: Relation) -> bool: #
"""
other_app = relation.app

raw_data = relation.data[other_app].get("dashboards", {}) # type: ignore
raw_data = relation.data[other_app].get("dashboards", "") # pyright: ignore

if not raw_data:
logger.warning(
Expand Down Expand Up @@ -1509,20 +1511,20 @@ def _render_dashboards_and_signal_changed(self, relation: Relation) -> bool: #

def _manage_dashboard_uid(self, dashboard: str, template: dict) -> str:
"""Add an uid to the dashboard if it is not present."""
dashboard = json.loads(dashboard)
dashboard_dict = json.loads(dashboard)

if not dashboard.get("uid", None) and "dashboard_alt_uid" in template:
dashboard["uid"] = template["dashboard_alt_uid"]
if not dashboard_dict.get("uid", None) and "dashboard_alt_uid" in template:
dashboard_dict["uid"] = template["dashboard_alt_uid"]

return json.dumps(dashboard)
return json.dumps(dashboard_dict)

def _remove_all_dashboards_for_relation(self, relation: Relation) -> None:
"""If an errored dashboard is in stored data, remove it and trigger a deletion."""
if self._get_stored_dashboards(relation.id):
stored_dashboards = self.get_peer_data("dashboards")
stored_dashboards.pop(str(relation.id))
self.set_peer_data("dashboards", stored_dashboards)
self.on.dashboards_changed.emit()
self.on.dashboards_changed.emit() # pyright: ignore

def _to_external_object(self, relation_id, dashboard):
return {
Expand Down Expand Up @@ -1604,7 +1606,7 @@ class GrafanaDashboardAggregator(Object):
"""

_stored = StoredState()
on = GrafanaProviderEvents()
on = GrafanaProviderEvents() # pyright: ignore

def __init__(
self,
Expand Down Expand Up @@ -1669,7 +1671,7 @@ def _update_remote_grafana(self, _: Optional[RelationEvent] = None) -> None:
"""Push dashboards to the downstream Grafana relation."""
# It's still ridiculous to add a UUID here, but needed
stored_data = {
"templates": _type_convert_stored(self._stored.dashboard_templates),
"templates": _type_convert_stored(self._stored.dashboard_templates), # pyright: ignore
"uuid": str(uuid.uuid4()),
}

Expand All @@ -1690,7 +1692,7 @@ def remove_dashboards(self, event: RelationBrokenEvent) -> None:
del self._stored.dashboard_templates[id] # type: ignore

stored_data = {
"templates": _type_convert_stored(self._stored.dashboard_templates),
"templates": _type_convert_stored(self._stored.dashboard_templates), # pyright: ignore
"uuid": str(uuid.uuid4()),
}

Expand Down
24 changes: 14 additions & 10 deletions lib/charms/grafana_k8s/v0/grafana_source.py
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,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 = 15
LIBPATCH = 16

logger = logging.getLogger(__name__)

Expand All @@ -169,7 +169,7 @@ def __init__(self, *args):
RELATION_INTERFACE_NAME = "grafana_datasource"


def _type_convert_stored(obj):
def _type_convert_stored(obj) -> Union[dict, list]:
"""Convert Stored* to their appropriate types, recursively."""
if isinstance(obj, StoredList):
return list(map(_type_convert_stored, obj))
Expand Down Expand Up @@ -467,7 +467,7 @@ def _set_unit_details(self, _: Union[BoundEvent, RelationEvent, Relation]):
class GrafanaSourceConsumer(Object):
"""A consumer object for working with Grafana datasources."""

on = GrafanaSourceEvents()
on = GrafanaSourceEvents() # pyright: ignore
_stored = StoredState()

def __init__(
Expand Down Expand Up @@ -532,14 +532,14 @@ def _on_grafana_source_relation_changed(self, event: Optional[CharmEvents] = Non

self.set_peer_data("sources", sources)

self.on.sources_changed.emit()
self.on.sources_changed.emit() # pyright: ignore

def _on_grafana_peer_changed(self, _: RelationChangedEvent) -> None:
"""Emit source events on peer events so secondary charm data updates."""
if self._charm.unit.is_leader():
return
self.on.sources_changed.emit()
self.on.sources_to_delete_changed.emit()
self.on.sources_changed.emit() # pyright: ignore
self.on.sources_to_delete_changed.emit() # pyright: ignore

def _get_source_config(self, rel: Relation):
"""Generate configuration from data stored in relation data by providers."""
Expand Down Expand Up @@ -610,7 +610,7 @@ def _on_grafana_source_relation_departed(self, event: RelationDepartedEvent) ->
removed_source = self._remove_source_from_datastore(event)

if removed_source:
self.on.sources_to_delete_changed.emit()
self.on.sources_to_delete_changed.emit() # pyright: ignore

def _remove_source_from_datastore(self, event: RelationDepartedEvent) -> bool:
"""Remove the grafana-source from the datastore.
Expand Down Expand Up @@ -658,7 +658,7 @@ def upgrade_keys(self) -> None:
return

self._set_default_data()
sources = _type_convert_stored(self._stored.sources)
sources: dict = _type_convert_stored(self._stored.sources) # pyright: ignore
for rel_id in sources.keys():
for i in range(len(sources[rel_id])):
sources[rel_id][i].update(
Expand All @@ -673,10 +673,14 @@ def upgrade_keys(self) -> None:
self.set_peer_data("sources", sources)

if self._stored.sources_to_delete: # type: ignore
old_sources_to_delete = _type_convert_stored(self._stored.sources_to_delete)
old_sources_to_delete = _type_convert_stored(
self._stored.sources_to_delete # pyright: ignore
)
self._stored.sources_to_delete = set()
peer_sources_to_delete = set(self.get_peer_data("sources_to_delete"))
sources_to_delete = set.union(old_sources_to_delete, peer_sources_to_delete)
sources_to_delete = set.union(
old_sources_to_delete, peer_sources_to_delete # pyright: ignore
)
self.set_peer_data("sources_to_delete", sources_to_delete)

def update_sources(self, relation: Optional[Relation] = None) -> None:
Expand Down
15 changes: 12 additions & 3 deletions lib/charms/traefik_k8s/v1/ingress_per_unit.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ def _on_ingress_revoked(self, event: IngressPerUnitRevokedForUnitEvent):

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

log = logging.getLogger(__name__)

Expand Down Expand Up @@ -113,6 +113,7 @@ def _on_ingress_revoked(self, event: IngressPerUnitRevokedForUnitEvent):
"port": {"type": "string"},
"mode": {"type": "string"},
"strip-prefix": {"type": "string"},
"redirect-https": {"type": "string"},
},
"required": ["model", "name", "host", "port"],
}
Expand Down Expand Up @@ -152,6 +153,7 @@ def _on_ingress_revoked(self, event: IngressPerUnitRevokedForUnitEvent):
"port": int,
"mode": Optional[Literal["tcp", "http"]],
"strip-prefix": Optional[bool],
"redirect-https": Optional[bool],
},
total=False,
)
Expand Down Expand Up @@ -483,13 +485,14 @@ def _get_requirer_unit_data(self, relation: Relation, remote_unit: Unit) -> Requ

databag = relation.data[remote_unit]
remote_data: Dict[str, Union[int, str]] = {}
for k in ("port", "host", "model", "name", "mode", "strip-prefix"):
for k in ("port", "host", "model", "name", "mode", "strip-prefix", "redirect-https"):
v = databag.get(k)
if v is not None:
remote_data[k] = v
_validate_data(remote_data, INGRESS_REQUIRES_UNIT_SCHEMA)
remote_data["port"] = int(remote_data["port"])
remote_data["strip-prefix"] = bool(remote_data.get("strip-prefix", False))
remote_data["strip-prefix"] = bool(remote_data.get("strip-prefix", "false") == "true")
remote_data["redirect-https"] = bool(remote_data.get("redirect-https", "false") == "true")
return typing.cast(RequirerData, remote_data)

def _provider_app_data(self, relation: Relation) -> ProviderApplicationData:
Expand Down Expand Up @@ -659,6 +662,7 @@ def __init__(
mode: Literal["tcp", "http"] = "http",
listen_to: Literal["only-this-unit", "all-units", "both"] = "only-this-unit",
strip_prefix: bool = False,
redirect_https: bool = False,
):
"""Constructor for IngressPerUnitRequirer.
Expand Down Expand Up @@ -687,6 +691,7 @@ def __init__(
"all": this unit will receive both event types (which means it
will be notified *twice* of changes to this unit's ingress!).
strip_prefix: remove prefixes from the URL path.
redirect_https: redirect incoming requests to HTTPS
"""
super().__init__(charm, relation_name)
self._stored.set_default(current_urls=None) # type: ignore
Expand All @@ -697,6 +702,7 @@ def __init__(
self._port = port
self._mode = mode
self._strip_prefix = strip_prefix
self._redirect_https = redirect_https

self.listen_to = listen_to

Expand Down Expand Up @@ -789,6 +795,9 @@ def provide_ingress_requirements(self, *, host: Optional[str] = None, port: int)
if self._strip_prefix:
data["strip-prefix"] = "true"

if self._redirect_https:
data["redirect-https"] = "true"

_validate_data(data, INGRESS_REQUIRES_UNIT_SCHEMA)
self.relation.data[self.unit].update(data)

Expand Down

0 comments on commit 78707ec

Please sign in to comment.