Skip to content

Commit 11da642

Browse files
[LDAP] Define sync pebble service
1 parent 13b8279 commit 11da642

File tree

2 files changed

+86
-14
lines changed

2 files changed

+86
-14
lines changed

src/charm.py

Lines changed: 70 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
from datetime import datetime
1717
from pathlib import Path
1818
from typing import Literal, get_args
19+
from urllib.parse import urlparse
1920

2021
import psycopg2
2122
from charms.data_platform_libs.v0.data_interfaces import DataPeerData, DataPeerUnitData
@@ -73,6 +74,7 @@
7374
APP_SCOPE,
7475
BACKUP_USER,
7576
DATABASE_DEFAULT_NAME,
77+
DATABASE_PORT,
7678
METRICS_PORT,
7779
MONITORING_PASSWORD_KEY,
7880
MONITORING_SNAP_SERVICE,
@@ -1316,6 +1318,42 @@ def _restart_services_after_reboot(self):
13161318
self._patroni.start_patroni()
13171319
self.backup.start_stop_pgbackrest_service()
13181320

1321+
def _restart_metrics_service(self) -> None:
1322+
"""Restart the monitoring service if the password was rotated."""
1323+
cache = snap.SnapCache()
1324+
postgres_snap = cache[POSTGRESQL_SNAP_NAME]
1325+
1326+
try:
1327+
snap_password = postgres_snap.get("exporter.password")
1328+
except snap.SnapError:
1329+
logger.warning("Early exit: Trying to reset metrics service with no configuration set")
1330+
return None
1331+
1332+
if snap_password != self.get_secret(APP_SCOPE, MONITORING_PASSWORD_KEY):
1333+
self._setup_exporter()
1334+
1335+
def _restart_ldap_sync_service(self) -> None:
1336+
"""Restart the LDAP sync service in case any configuration changed."""
1337+
if not self._patroni.member_started:
1338+
logger.debug("Restart LDAP sync early exit: Patroni has not started yet")
1339+
return
1340+
1341+
cache = snap.SnapCache()
1342+
postgres_snap = cache[POSTGRESQL_SNAP_NAME]
1343+
sync_service = postgres_snap.services["ldap-sync"]
1344+
1345+
if not self.is_primary and sync_service["active"]:
1346+
logger.debug("Stopping LDAP sync service. It must only run in the primary")
1347+
postgres_snap.stop(services=["ldap-sync"])
1348+
1349+
if self.is_primary and not self.is_ldap_enabled:
1350+
logger.debug("Stopping LDAP sync service")
1351+
postgres_snap.stop(services=["ldap-sync"])
1352+
return
1353+
1354+
if self.is_primary and self.is_ldap_enabled:
1355+
self._setup_ldap_sync()
1356+
13191357
def _setup_exporter(self) -> None:
13201358
"""Set up postgresql_exporter options."""
13211359
cache = snap.SnapCache()
@@ -1339,6 +1377,36 @@ def _setup_exporter(self) -> None:
13391377
postgres_snap.restart(services=[MONITORING_SNAP_SERVICE])
13401378
self.unit_peer_data.update({"exporter-started": "True"})
13411379

1380+
def _setup_ldap_sync(self) -> None:
1381+
"""Set up postgresql_ldap_sync options."""
1382+
cache = snap.SnapCache()
1383+
postgres_snap = cache[POSTGRESQL_SNAP_NAME]
1384+
1385+
ldap_params = self.get_ldap_parameters()
1386+
ldap_url = urlparse(ldap_params["ldapurl"])
1387+
ldap_host = ldap_url.hostname
1388+
ldap_port = ldap_url.port
1389+
1390+
ldap_base_dn = ldap_params["ldapbasedn"]
1391+
ldap_bind_username = ldap_params["ldapbinddn"]
1392+
ldap_bind_password = ldap_params["ldapbindpasswd"]
1393+
1394+
postgres_snap.set({
1395+
"ldap-sync.ldap_host": ldap_host,
1396+
"ldap-sync.ldap_port": ldap_port,
1397+
"ldap-sync.ldap_base_dn": ldap_base_dn,
1398+
"ldap-sync.ldap_bind_username": ldap_bind_username,
1399+
"ldap-sync.ldap_bind_password": ldap_bind_password,
1400+
"ldap-sync.postgres_host": "127.0.0.1",
1401+
"ldap-sync.postgres_port": DATABASE_PORT,
1402+
"ldap-sync.postgres_database": DATABASE_DEFAULT_NAME,
1403+
"ldap-sync.postgres_username": USER,
1404+
"ldap-sync.postgres_password": self._get_password(),
1405+
})
1406+
1407+
logger.debug("Starting LDAP sync service")
1408+
postgres_snap.restart(services=["ldap-sync"])
1409+
13421410
def _start_primary(self, event: StartEvent) -> None:
13431411
"""Bootstrap the cluster."""
13441412
# Set some information needed by Patroni to bootstrap the cluster.
@@ -1985,20 +2053,8 @@ def update_config(self, is_creating_backup: bool = False, no_peers: bool = False
19852053
})
19862054

19872055
self._handle_postgresql_restart_need(enable_tls)
1988-
1989-
# Restart the monitoring service if the password was rotated
1990-
cache = snap.SnapCache()
1991-
postgres_snap = cache[POSTGRESQL_SNAP_NAME]
1992-
1993-
try:
1994-
snap_password = postgres_snap.get("exporter.password")
1995-
except snap.SnapError:
1996-
logger.warning(
1997-
"Early exit update_config: Trying to reset metrics service with no configuration set"
1998-
)
1999-
return True
2000-
if snap_password != self.get_secret(APP_SCOPE, MONITORING_PASSWORD_KEY):
2001-
self._setup_exporter()
2056+
self._restart_metrics_service()
2057+
self._restart_ldap_sync_service()
20022058

20032059
return True
20042060

tests/unit/test_charm.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1274,6 +1274,12 @@ def test_update_config(harness):
12741274
patch(
12751275
"charm.PostgresqlOperatorCharm._handle_postgresql_restart_need"
12761276
) as _handle_postgresql_restart_need,
1277+
patch(
1278+
"charm.PostgresqlOperatorCharm._restart_metrics_service"
1279+
) as _restart_metrics_service,
1280+
patch(
1281+
"charm.PostgresqlOperatorCharm._restart_ldap_sync_service"
1282+
) as _restart_ldap_sync_service,
12771283
patch("charm.Patroni.bulk_update_parameters_controller_by_patroni"),
12781284
patch("charm.Patroni.member_started", new_callable=PropertyMock) as _member_started,
12791285
patch(
@@ -1313,10 +1319,14 @@ def test_update_config(harness):
13131319
no_peers=False,
13141320
)
13151321
_handle_postgresql_restart_need.assert_called_once_with(False)
1322+
_restart_ldap_sync_service.assert_called_once()
1323+
_restart_metrics_service.assert_called_once()
13161324
assert "tls" not in harness.get_relation_data(rel_id, harness.charm.unit.name)
13171325

13181326
# Test with TLS files available.
13191327
_handle_postgresql_restart_need.reset_mock()
1328+
_restart_ldap_sync_service.reset_mock()
1329+
_restart_metrics_service.reset_mock()
13201330
harness.update_relation_data(
13211331
rel_id, harness.charm.unit.name, {"tls": ""}
13221332
) # Mock some data in the relation to test that it change.
@@ -1338,6 +1348,8 @@ def test_update_config(harness):
13381348
no_peers=False,
13391349
)
13401350
_handle_postgresql_restart_need.assert_called_once()
1351+
_restart_ldap_sync_service.assert_called_once()
1352+
_restart_metrics_service.assert_called_once()
13411353
assert "tls" not in harness.get_relation_data(
13421354
rel_id, harness.charm.unit.name
13431355
) # The "tls" flag is set in handle_postgresql_restart_need.
@@ -1347,6 +1359,8 @@ def test_update_config(harness):
13471359
rel_id, harness.charm.unit.name, {"tls": ""}
13481360
) # Mock some data in the relation to test that it change.
13491361
_handle_postgresql_restart_need.reset_mock()
1362+
_restart_ldap_sync_service.reset_mock()
1363+
_restart_metrics_service.reset_mock()
13501364
harness.charm.update_config()
13511365
_handle_postgresql_restart_need.assert_not_called()
13521366
assert harness.get_relation_data(rel_id, harness.charm.unit.name)["tls"] == "enabled"
@@ -1357,6 +1371,8 @@ def test_update_config(harness):
13571371
) # Mock some data in the relation to test that it doesn't change.
13581372
harness.charm.update_config()
13591373
_handle_postgresql_restart_need.assert_not_called()
1374+
_restart_ldap_sync_service.assert_not_called()
1375+
_restart_metrics_service.assert_not_called()
13601376
assert "tls" not in harness.get_relation_data(rel_id, harness.charm.unit.name)
13611377

13621378

0 commit comments

Comments
 (0)