Skip to content

Commit c3005d3

Browse files
authored
[DPE-6259] pgbackrest config perms (#1038)
* Remove read access to pgbackrest conf file * Update libs * Set extra user roles config for the test app * Fix data-int base * Set channel and series in ne rel tests
1 parent f502532 commit c3005d3

File tree

7 files changed

+60
-37
lines changed

7 files changed

+60
-37
lines changed

lib/charms/data_platform_libs/v0/data_interfaces.py

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -331,7 +331,7 @@ def _on_topic_requested(self, event: TopicRequestedEvent):
331331

332332
# Increment this PATCH version before using `charmcraft publish-lib` or reset
333333
# to 0 if you are raising the major API version
334-
LIBPATCH = 48
334+
LIBPATCH = 49
335335

336336
PYDEPS = ["ops>=2.0.0"]
337337

@@ -3527,16 +3527,20 @@ def __init__(
35273527
self.consumer_group_prefix = consumer_group_prefix or ""
35283528
self.mtls_cert = mtls_cert
35293529

3530+
@staticmethod
3531+
def is_topic_value_acceptable(topic_value: str) -> bool:
3532+
"""Check whether the given Kafka topic value is acceptable."""
3533+
return "*" not in topic_value[:3]
3534+
35303535
@property
35313536
def topic(self):
35323537
"""Topic to use in Kafka."""
35333538
return self._topic
35343539

35353540
@topic.setter
35363541
def topic(self, value):
3537-
# Avoid wildcards
3538-
if value == "*":
3539-
raise ValueError(f"Error on topic '{value}', cannot be a wildcard.")
3542+
if not self.is_topic_value_acceptable(value):
3543+
raise ValueError(f"Error on topic '{value}', unacceptable value.")
35403544
self._topic = value
35413545

35423546
def set_mtls_cert(self, relation_id: int, mtls_cert: str) -> None:

lib/charms/glauth_k8s/v0/ldap.py

Lines changed: 23 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,7 @@ def _on_ldap_requested(self, event: LdapRequestedEvent) -> None:
147147

148148
# Increment this PATCH version before using `charmcraft publish-lib` or reset
149149
# to 0 if you are raising the major API version
150-
LIBPATCH = 10
150+
LIBPATCH = 11
151151

152152
PYDEPS = ["pydantic"]
153153

@@ -256,13 +256,11 @@ def load(
256256
cls,
257257
charm: CharmBase,
258258
label: str,
259-
*,
260-
content: Optional[dict[str, str]] = None,
261-
) -> "Secret":
259+
) -> Optional["Secret"]:
262260
try:
263261
secret = charm.model.get_secret(label=label)
264262
except SecretNotFoundError:
265-
secret = charm.app.add_secret(label=label, content=content)
263+
return None
266264

267265
return Secret(secret)
268266

@@ -411,7 +409,8 @@ def _on_relation_broken(self, event: RelationBrokenEvent) -> None:
411409
self.charm,
412410
label=BIND_ACCOUNT_SECRET_LABEL_TEMPLATE.substitute(relation_id=event.relation.id),
413411
)
414-
secret.remove()
412+
if secret:
413+
secret.remove()
415414

416415
def get_bind_password(self, relation_id: int) -> Optional[str]:
417416
"""Retrieve the bind account password for a given integration."""
@@ -490,15 +489,27 @@ def _on_ldap_relation_changed(self, event: RelationChangedEvent) -> None:
490489
"""Handle the event emitted when the LDAP related information is ready."""
491490
provider_app = event.relation.app
492491

493-
if not event.relation.data.get(provider_app):
492+
if not (provider_data := event.relation.data.get(provider_app)):
494493
return
495494

496-
self.on.ldap_ready.emit(event.relation)
495+
provider_data = dict(provider_data)
496+
if self._load_provider_data(provider_data):
497+
self.on.ldap_ready.emit(event.relation)
497498

498499
def _on_ldap_relation_broken(self, event: RelationBrokenEvent) -> None:
499500
"""Handle the event emitted when the LDAP integration is broken."""
500501
self.on.ldap_unavailable.emit(event.relation)
501502

503+
def _load_provider_data(self, provider_data: dict) -> Optional[LdapProviderData]:
504+
if secret_id := provider_data.get("bind_password_secret"):
505+
secret = self.charm.model.get_secret(id=secret_id)
506+
provider_data["bind_password"] = secret.get_content().get("password")
507+
508+
try:
509+
return LdapProviderData(**provider_data)
510+
except ValidationError:
511+
return None
512+
502513
def consume_ldap_relation_data(
503514
self,
504515
/,
@@ -513,10 +524,10 @@ def consume_ldap_relation_data(
513524
return None
514525

515526
provider_data = dict(relation.data.get(relation.app))
516-
if secret_id := provider_data.get("bind_password_secret"):
517-
secret = self.charm.model.get_secret(id=secret_id)
518-
provider_data["bind_password"] = secret.get_content().get("password")
519-
return LdapProviderData(**provider_data) if provider_data else None
527+
if not provider_data:
528+
return None
529+
530+
return self._load_provider_data(provider_data)
520531

521532
def _is_relation_active(self, relation: Relation) -> bool:
522533
"""Whether the relation is active based on contained data."""

lib/charms/tempo_coordinator_k8s/v0/charm_tracing.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -313,10 +313,10 @@ def _remove_stale_otel_sdk_packages():
313313

314314
import opentelemetry
315315
import ops
316-
from opentelemetry.exporter.otlp.proto.common._internal.trace_encoder import (
316+
from opentelemetry.exporter.otlp.proto.common._internal.trace_encoder import ( # type: ignore
317317
encode_spans # type: ignore
318318
)
319-
from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter
319+
from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter # type: ignore
320320
from opentelemetry.sdk.resources import Resource
321321
from opentelemetry.sdk.trace import ReadableSpan, Span, TracerProvider
322322
from opentelemetry.sdk.trace.export import (
@@ -348,7 +348,7 @@ def _remove_stale_otel_sdk_packages():
348348
# Increment this PATCH version before using `charmcraft publish-lib` or reset
349349
# to 0 if you are raising the major API version
350350

351-
LIBPATCH = 8
351+
LIBPATCH = 9
352352

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

src/backups.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1265,7 +1265,7 @@ def _render_pgbackrest_conf_file(self) -> bool:
12651265
process_max=max(os.cpu_count() - 2, 1),
12661266
)
12671267
# Render pgBackRest config file.
1268-
self.charm._patroni.render_file(f"{PGBACKREST_CONF_PATH}/pgbackrest.conf", rendered, 0o644)
1268+
self.charm._patroni.render_file(f"{PGBACKREST_CONF_PATH}/pgbackrest.conf", rendered, 0o640)
12691269

12701270
# Render the logrotate configuration file.
12711271
with open("templates/pgbackrest.logrotate.j2") as file:

tests/integration/new_relations/test_new_relations_1.py

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,8 @@ async def test_deploy_charms(ops_test: OpsTest, charm):
5858
application_name=APPLICATION_APP_NAME,
5959
num_units=2,
6060
base=CHARM_BASE,
61-
channel="edge",
61+
channel="latest/edge",
62+
config={"extra_user_roles": "CREATEDB,CREATEROLE"},
6263
),
6364
ops_test.model.deploy(
6465
charm,
@@ -261,7 +262,7 @@ async def test_two_applications_doesnt_share_the_same_relation_data(ops_test: Op
261262
await ops_test.model.deploy(
262263
APPLICATION_APP_NAME,
263264
application_name=another_application_app_name,
264-
channel="edge",
265+
channel="latest/edge",
265266
base=CHARM_BASE,
266267
)
267268
await ops_test.model.wait_for_idle(apps=all_app_names, status="active")
@@ -490,7 +491,11 @@ async def test_admin_role(ops_test: OpsTest):
490491
all_app_names = [DATA_INTEGRATOR_APP_NAME]
491492
all_app_names.extend(APP_NAMES)
492493
async with ops_test.fast_forward():
493-
await ops_test.model.deploy(DATA_INTEGRATOR_APP_NAME, base=CHARM_BASE)
494+
await ops_test.model.deploy(
495+
DATA_INTEGRATOR_APP_NAME,
496+
channel="latest/edge",
497+
series="jammy",
498+
)
494499
await ops_test.model.wait_for_idle(apps=[DATA_INTEGRATOR_APP_NAME], status="blocked")
495500
await ops_test.model.applications[DATA_INTEGRATOR_APP_NAME].set_config({
496501
"database-name": DATA_INTEGRATOR_APP_NAME.replace("-", "_"),
@@ -579,10 +584,12 @@ async def test_invalid_extra_user_roles(ops_test: OpsTest):
579584

580585
another_data_integrator_app_name = f"another-{DATA_INTEGRATOR_APP_NAME}"
581586
data_integrator_apps_names = [DATA_INTEGRATOR_APP_NAME, another_data_integrator_app_name]
587+
# Base is ignored
582588
await ops_test.model.deploy(
583589
DATA_INTEGRATOR_APP_NAME,
584590
application_name=another_data_integrator_app_name,
585-
base=CHARM_BASE,
591+
channel="latest/edge",
592+
series="jammy",
586593
)
587594
await ops_test.model.wait_for_idle(
588595
apps=[another_data_integrator_app_name], status="blocked"

tests/integration/new_relations/test_relations_coherence.py

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import logging
55
import secrets
66
import string
7+
from asyncio import gather
78

89
import psycopg2
910
import pytest
@@ -26,23 +27,23 @@
2627
async def test_relations(ops_test: OpsTest, charm):
2728
"""Test that check relation data."""
2829
async with ops_test.fast_forward():
29-
await ops_test.model.deploy(
30-
charm,
31-
application_name=DATABASE_APP_NAME,
32-
num_units=1,
33-
base=CHARM_BASE,
34-
config={"profile": "testing"},
30+
await gather(
31+
ops_test.model.deploy(
32+
charm,
33+
application_name=DATABASE_APP_NAME,
34+
num_units=1,
35+
base=CHARM_BASE,
36+
config={"profile": "testing"},
37+
),
38+
# Creating first time relation with user role
39+
# Base is ignored
40+
ops_test.model.deploy(DATA_INTEGRATOR_APP_NAME, series="jammy"),
3541
)
36-
await ops_test.model.wait_for_idle(apps=[DATABASE_APP_NAME], status="active", timeout=3000)
37-
38-
# Creating first time relation with user role
39-
await ops_test.model.deploy(DATA_INTEGRATOR_APP_NAME, base=CHARM_BASE)
4042
await ops_test.model.applications[DATA_INTEGRATOR_APP_NAME].set_config({
4143
"database-name": DATA_INTEGRATOR_APP_NAME.replace("-", "_"),
4244
})
43-
await ops_test.model.wait_for_idle(apps=[DATA_INTEGRATOR_APP_NAME], status="blocked")
4445
await ops_test.model.add_relation(DATA_INTEGRATOR_APP_NAME, DATABASE_APP_NAME)
45-
await ops_test.model.wait_for_idle(apps=APP_NAMES, status="active")
46+
await ops_test.model.wait_for_idle(apps=APP_NAMES, status="active", timeout=1500)
4647

4748
connection_string = await build_connection_string(
4849
ops_test,

tests/unit/test_backups.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1776,7 +1776,7 @@ def test_render_pgbackrest_conf_file(harness, tls_ca_chain_filename):
17761776
call(
17771777
"/var/snap/charmed-postgresql/current/etc/pgbackrest/pgbackrest.conf",
17781778
expected_content,
1779-
0o644,
1779+
0o640,
17801780
),
17811781
call(
17821782
"/etc/logrotate.d/pgbackrest.logrotate",

0 commit comments

Comments
 (0)