Skip to content

Commit f3b7667

Browse files
authored
[MISC] Enable RBAC in tests (#861)
* Enable RBAC * Bump cosl * Add trust * Bump libs
1 parent c9f6554 commit f3b7667

File tree

9 files changed

+158
-128
lines changed

9 files changed

+158
-128
lines changed

concierge.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ providers:
88
addons:
99
- dns
1010
- hostpath-storage
11+
- rbac
1112
host:
1213
snaps:
1314
jhack:

lib/charms/grafana_k8s/v0/grafana_dashboard.py

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -219,7 +219,7 @@ def __init__(self, *args):
219219
# Increment this PATCH version before using `charmcraft publish-lib` or reset
220220
# to 0 if you are raising the major API version
221221

222-
LIBPATCH = 39
222+
LIBPATCH = 42
223223

224224
PYDEPS = ["cosl >= 0.0.50"]
225225

@@ -417,8 +417,7 @@ def __init__(
417417
self.expected_relation_interface = expected_relation_interface
418418
self.actual_relation_interface = actual_relation_interface
419419
self.message = (
420-
"The '{}' relation has '{}' as "
421-
"interface rather than the expected '{}'".format(
420+
"The '{}' relation has '{}' as " "interface rather than the expected '{}'".format(
422421
relation_name, actual_relation_interface, expected_relation_interface
423422
)
424423
)
@@ -634,7 +633,10 @@ def _replace_template_fields( # noqa: C901
634633
deletions = []
635634
for tmpl in dict_content["templating"]["list"]:
636635
if tmpl["name"] and tmpl["name"] in used_replacements:
637-
deletions.append(tmpl)
636+
# it might happen that existing template var name is the same as the one we insert (i.e prometheusds or lokids)
637+
# in that case, we want to pop the existing one only.
638+
if tmpl not in DATASOURCE_TEMPLATE_DROPDOWNS:
639+
deletions.append(tmpl)
638640

639641
for d in deletions:
640642
dict_content["templating"]["list"].remove(d)
@@ -962,6 +964,13 @@ def _replace_uid(
962964
"Processed dashboard '%s': kept original uid '%s'", dashboard_path, original_uid
963965
)
964966

967+
@classmethod
968+
def _add_tags(cls, dashboard_dict: dict, charm_name: str):
969+
tags: List[str] = dashboard_dict.get("tags", [])
970+
if not any(tag.startswith("charm: ") for tag in tags):
971+
tags.append(f"charm: {charm_name}")
972+
dashboard_dict["tags"] = tags
973+
965974
@classmethod
966975
def load_dashboards_from_dir(
967976
cls,
@@ -1004,6 +1013,8 @@ def _is_dashboard(p: Path) -> bool:
10041013
charm_name=charm_name,
10051014
)
10061015

1016+
cls._add_tags(dashboard_dict=dashboard_dict, charm_name=charm_name)
1017+
10071018
id = "file:{}".format(path.stem)
10081019
dashboard_templates[id] = cls._content_to_dashboard_object(
10091020
charm_name=charm_name,
@@ -1601,7 +1612,7 @@ def _render_dashboards_and_signal_changed(self, relation: Relation) -> bool: #
16011612

16021613
if not coerced_data == stored_data:
16031614
stored_dashboards = self.get_peer_data("dashboards")
1604-
stored_dashboards[relation.id] = stored_data
1615+
stored_dashboards[str(relation.id)] = stored_data
16051616
self.set_peer_data("dashboards", stored_dashboards)
16061617
return True
16071618
return None # type: ignore

lib/charms/prometheus_k8s/v0/prometheus_scrape.py

Lines changed: 48 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -340,8 +340,8 @@ def _on_scrape_targets_changed(self, event):
340340

341341
import yaml
342342
from cosl import JujuTopology
343-
from cosl.rules import AlertRules
344-
from ops.charm import CharmBase, RelationRole
343+
from cosl.rules import AlertRules, generic_alert_groups
344+
from ops.charm import CharmBase, RelationJoinedEvent, RelationRole
345345
from ops.framework import (
346346
BoundEvent,
347347
EventBase,
@@ -362,7 +362,7 @@ def _on_scrape_targets_changed(self, event):
362362

363363
# Increment this PATCH version before using `charmcraft publish-lib` or reset
364364
# to 0 if you are raising the major API version
365-
LIBPATCH = 48
365+
LIBPATCH = 50
366366

367367
PYDEPS = ["cosl"]
368368

@@ -1309,6 +1309,8 @@ def __init__(
13091309
refresh_event: Optional[Union[BoundEvent, List[BoundEvent]]] = None,
13101310
external_url: str = "",
13111311
lookaside_jobs_callable: Optional[Callable] = None,
1312+
*,
1313+
forward_alert_rules: bool = True,
13121314
):
13131315
"""Construct a metrics provider for a Prometheus charm.
13141316
@@ -1411,6 +1413,7 @@ def __init__(
14111413
files. Defaults to "./prometheus_alert_rules",
14121414
resolved relative to the directory hosting the charm entry file.
14131415
The alert rules are automatically updated on charm upgrade.
1416+
forward_alert_rules: a boolean flag to toggle forwarding of charmed alert rules.
14141417
refresh_event: an optional bound event or list of bound events which
14151418
will be observed to re-set scrape job data (IP address and others)
14161419
external_url: an optional argument that represents an external url that
@@ -1449,6 +1452,7 @@ def __init__(
14491452

14501453
self._charm = charm
14511454
self._alert_rules_path = alert_rules_path
1455+
self._forward_alert_rules = forward_alert_rules
14521456
self._relation_name = relation_name
14531457
# sanitize job configurations to the supported subset of parameters
14541458
jobs = [] if jobs is None else jobs
@@ -1530,7 +1534,11 @@ def set_scrape_job_spec(self, _=None):
15301534
return
15311535

15321536
alert_rules = AlertRules(query_type="promql", topology=self.topology)
1533-
alert_rules.add_path(self._alert_rules_path, recursive=True)
1537+
if self._forward_alert_rules:
1538+
alert_rules.add_path(self._alert_rules_path, recursive=True)
1539+
alert_rules.add(
1540+
generic_alert_groups.application_rules, group_name_prefix=self.topology.identifier
1541+
)
15341542
alert_rules_as_dict = alert_rules.as_dict()
15351543

15361544
for relation in self._charm.model.relations[self._relation_name]:
@@ -1776,6 +1784,9 @@ def __init__(
17761784
relation_names: Optional[dict] = None,
17771785
relabel_instance=True,
17781786
resolve_addresses=False,
1787+
path_to_own_alert_rules: Optional[str] = None,
1788+
*,
1789+
forward_alert_rules: bool = True,
17791790
):
17801791
"""Construct a `MetricsEndpointAggregator`.
17811792
@@ -1795,6 +1806,8 @@ def __init__(
17951806
resolve_addresses: A boolean flag indiccating if the aggregator
17961807
should attempt to perform DNS lookups of targets and append
17971808
a `dns_name` label
1809+
path_to_own_alert_rules: Optionally supply a path for alert rule files
1810+
forward_alert_rules: a boolean flag to toggle forwarding of charmed alert rules
17981811
"""
17991812
self._charm = charm
18001813

@@ -1807,15 +1820,21 @@ def __init__(
18071820
self._alert_rules_relation = relation_names.get("alert_rules", "prometheus-rules")
18081821

18091822
super().__init__(charm, self._prometheus_relation)
1823+
self.topology = JujuTopology.from_charm(charm)
1824+
18101825
self._stored.set_default(jobs=[], alert_rules=[])
18111826

18121827
self._relabel_instance = relabel_instance
18131828
self._resolve_addresses = resolve_addresses
18141829

1830+
self._forward_alert_rules = forward_alert_rules
1831+
18151832
# manage Prometheus charm relation events
18161833
prometheus_events = self._charm.on[self._prometheus_relation]
18171834
self.framework.observe(prometheus_events.relation_joined, self._set_prometheus_data)
18181835

1836+
self.path_to_own_alert_rules = path_to_own_alert_rules
1837+
18191838
# manage list of Prometheus scrape jobs from related scrape targets
18201839
target_events = self._charm.on[self._target_relation]
18211840
self.framework.observe(target_events.relation_changed, self._on_prometheus_targets_changed)
@@ -1828,7 +1847,7 @@ def __init__(
18281847
self.framework.observe(alert_rule_events.relation_changed, self._on_alert_rules_changed)
18291848
self.framework.observe(alert_rule_events.relation_departed, self._on_alert_rules_departed)
18301849

1831-
def _set_prometheus_data(self, event):
1850+
def _set_prometheus_data(self, event: Optional[RelationJoinedEvent] = None):
18321851
"""Ensure every new Prometheus instances is updated.
18331852
18341853
Any time a new Prometheus unit joins the relation with
@@ -1838,6 +1857,7 @@ def _set_prometheus_data(self, event):
18381857
if not self._charm.unit.is_leader():
18391858
return
18401859

1860+
# Gather the scrape jobs
18411861
jobs = [] + _type_convert_stored(
18421862
self._stored.jobs # pyright: ignore
18431863
) # list of scrape jobs, one per relation
@@ -1846,6 +1866,7 @@ def _set_prometheus_data(self, event):
18461866
if targets and relation.app:
18471867
jobs.append(self._static_scrape_job(targets, relation.app.name))
18481868

1869+
# Gather the alert rules
18491870
groups = [] + _type_convert_stored(
18501871
self._stored.alert_rules # pyright: ignore
18511872
) # list of alert rule groups
@@ -1856,9 +1877,23 @@ def _set_prometheus_data(self, event):
18561877
rules = self._label_alert_rules(unit_rules, appname)
18571878
group = {"name": self.group_name(appname), "rules": rules}
18581879
groups.append(group)
1859-
1860-
event.relation.data[self._charm.app]["scrape_jobs"] = json.dumps(jobs)
1861-
event.relation.data[self._charm.app]["alert_rules"] = json.dumps({"groups": groups})
1880+
alert_rules = AlertRules(query_type="promql", topology=self.topology)
1881+
# Add alert rules from file
1882+
if self.path_to_own_alert_rules:
1883+
alert_rules.add_path(self.path_to_own_alert_rules, recursive=True)
1884+
# Add generic alert rules
1885+
alert_rules.add(
1886+
generic_alert_groups.application_rules, group_name_prefix=self.topology.identifier
1887+
)
1888+
groups.extend(alert_rules.as_dict()["groups"])
1889+
1890+
# Set scrape jobs and alert rules in relation data
1891+
relations = [event.relation] if event else self.model.relations[self._prometheus_relation]
1892+
for rel in relations:
1893+
rel.data[self._charm.app]["scrape_jobs"] = json.dumps(jobs) # type: ignore
1894+
rel.data[self._charm.app]["alert_rules"] = json.dumps( # type: ignore
1895+
{"groups": groups if self._forward_alert_rules else []}
1896+
)
18621897

18631898
def _on_prometheus_targets_changed(self, event):
18641899
"""Update scrape jobs in response to scrape target changes.
@@ -2129,7 +2164,9 @@ def set_alert_rule_data(self, name: str, unit_rules: dict, label_rules: bool = T
21292164

21302165
if updated_group["name"] not in [g["name"] for g in groups]:
21312166
groups.append(updated_group)
2132-
relation.data[self._charm.app]["alert_rules"] = json.dumps({"groups": groups})
2167+
relation.data[self._charm.app]["alert_rules"] = json.dumps(
2168+
{"groups": groups if self._forward_alert_rules else []}
2169+
)
21332170

21342171
if not _type_convert_stored(self._stored.alert_rules) == groups: # pyright: ignore
21352172
self._stored.alert_rules = groups
@@ -2177,8 +2214,8 @@ def remove_alert_rules(self, group_name: str, unit_name: str) -> None:
21772214
changed_group["rules"] = rules_kept # type: ignore
21782215
groups.append(changed_group)
21792216

2180-
relation.data[self._charm.app]["alert_rules"] = (
2181-
json.dumps({"groups": groups}) if groups else "{}"
2217+
relation.data[self._charm.app]["alert_rules"] = json.dumps(
2218+
{"groups": groups if self._forward_alert_rules else []}
21822219
)
21832220

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

lib/charms/rolling_ops/v0/rollingops.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -63,13 +63,14 @@ def _on_trigger_restart(self, event):
6363
juju run-action some-charm/0 some-charm/1 <... some-charm/n> restart
6464
```
6565
66-
Note that all units that plan to restart must receive the action and emit the aquire
66+
Note that all units that plan to restart must receive the action and emit the acquire
6767
event. Any units that do not run their acquire handler will be left out of the rolling
6868
restart. (An operator might take advantage of this fact to recover from a failed rolling
6969
operation without restarting workloads that were able to successfully restart -- simply
7070
omit the successful units from a subsequent run-action call.)
7171
7272
"""
73+
7374
import logging
7475
from enum import Enum
7576
from typing import AnyStr, Callable, Optional
@@ -88,7 +89,7 @@ def _on_trigger_restart(self, event):
8889

8990
# Increment this PATCH version before using `charmcraft publish-lib` or reset
9091
# to 0 if you are raising the major API version
91-
LIBPATCH = 7
92+
LIBPATCH = 8
9293

9394

9495
class LockNoRelationError(Exception):
@@ -149,7 +150,6 @@ class Lock:
149150
"""
150151

151152
def __init__(self, manager, unit=None):
152-
153153
self.relation = manager.model.relations[manager.name][0]
154154
if not self.relation:
155155
# TODO: defer caller in this case (probably just fired too soon).
@@ -246,7 +246,7 @@ def __init__(self, manager):
246246

247247
# Gather all the units.
248248
relation = manager.model.relations[manager.name][0]
249-
units = [unit for unit in relation.units]
249+
units = list(relation.units)
250250

251251
# Plus our unit ...
252252
units.append(manager.model.unit)

0 commit comments

Comments
 (0)