Skip to content

Commit 85f92e9

Browse files
Fix scale up with S3 and TLS relations (#480)
Signed-off-by: Marcelo Henrique Neppel <[email protected]>
1 parent 1d35a66 commit 85f92e9

File tree

2 files changed

+71
-3
lines changed

2 files changed

+71
-3
lines changed

src/backups.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,22 @@ def _are_backup_settings_ok(self) -> Tuple[bool, Optional[str]]:
9696

9797
return True, None
9898

99+
@property
100+
def _can_initialise_stanza(self) -> bool:
101+
"""Validates whether this unit can initialise a stanza."""
102+
# Don't allow stanza initialisation if this unit hasn't started the database
103+
# yet and either hasn't joined the peer relation yet or hasn't configured TLS
104+
# yet while other unit already has TLS enabled.
105+
if not self.charm._patroni.member_started and (
106+
(len(self.charm._peers.data.keys()) == 2)
107+
or (
108+
"tls" not in self.charm.unit_peer_data
109+
and any("tls" in unit_data for _, unit_data in self.charm._peers.data.items())
110+
)
111+
):
112+
return False
113+
return True
114+
99115
def _can_unit_perform_backup(self) -> Tuple[bool, Optional[str]]:
100116
"""Validates whether this unit can perform a backup."""
101117
if self.charm.is_blocked:
@@ -512,6 +528,11 @@ def _on_s3_credential_changed(self, event: CredentialsChangedEvent):
512528
logger.debug("Cannot set pgBackRest configurations, missing configurations.")
513529
return
514530

531+
if not self._can_initialise_stanza:
532+
logger.debug("Cannot initialise stanza yet.")
533+
event.defer()
534+
return
535+
515536
# Verify the s3 relation only on the primary.
516537
if not self.charm.is_primary:
517538
return

tests/unit/test_backups.py

Lines changed: 50 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,39 @@ def test_are_backup_settings_ok(harness):
7373
)
7474

7575

76+
def test_can_initialise_stanza(harness):
77+
with patch("charm.Patroni.member_started", new_callable=PropertyMock) as _member_started:
78+
# Test when Patroni or PostgreSQL hasn't started yet
79+
# and the unit hasn't joined the peer relation yet.
80+
_member_started.return_value = False
81+
tc.assertEqual(
82+
harness.charm.backup._can_initialise_stanza,
83+
False,
84+
)
85+
86+
# Test when the unit hasn't configured TLS yet while other unit already has TLS enabled.
87+
harness.add_relation_unit(
88+
harness.model.get_relation(PEER).id, f"{harness.charm.app.name}/1"
89+
)
90+
with harness.hooks_disabled():
91+
harness.update_relation_data(
92+
harness.model.get_relation(PEER).id,
93+
f"{harness.charm.app.name}/1",
94+
{"tls": "enabled"},
95+
)
96+
tc.assertEqual(
97+
harness.charm.backup._can_initialise_stanza,
98+
False,
99+
)
100+
101+
# Test when everything is ok to initialise the stanza.
102+
_member_started.return_value = True
103+
tc.assertEqual(
104+
harness.charm.backup._can_initialise_stanza,
105+
True,
106+
)
107+
108+
76109
@patch_network_get(private_address="1.1.1.1")
77110
def test_can_unit_perform_backup(harness):
78111
with (
@@ -926,6 +959,9 @@ def test_on_s3_credential_changed(harness):
926959
patch(
927960
"charm.PostgresqlOperatorCharm.is_primary", new_callable=PropertyMock
928961
) as _is_primary,
962+
patch(
963+
"charm.PostgreSQLBackups._can_initialise_stanza", new_callable=PropertyMock
964+
) as _can_initialise_stanza,
929965
patch(
930966
"charm.PostgreSQLBackups._render_pgbackrest_conf_file"
931967
) as _render_pgbackrest_conf_file,
@@ -953,31 +989,42 @@ def test_on_s3_credential_changed(harness):
953989
{"cluster_initialised": "True"},
954990
)
955991
_render_pgbackrest_conf_file.return_value = False
956-
_is_primary.return_value = False
957992
harness.charm.backup.s3_client.on.credentials_changed.emit(
958993
relation=harness.model.get_relation(S3_PARAMETERS_RELATION, s3_rel_id)
959994
)
960995
_defer.assert_not_called()
961996
_render_pgbackrest_conf_file.assert_called_once()
997+
_can_initialise_stanza.assert_not_called()
962998
_create_bucket_if_not_exists.assert_not_called()
963999
_can_use_s3_repository.assert_not_called()
9641000
_initialise_stanza.assert_not_called()
9651001

1002+
# Test when it's not possible to initialise the stanza in this unit.
1003+
_render_pgbackrest_conf_file.return_value = True
1004+
_can_initialise_stanza.return_value = False
1005+
harness.charm.backup.s3_client.on.credentials_changed.emit(
1006+
relation=harness.model.get_relation(S3_PARAMETERS_RELATION, s3_rel_id)
1007+
)
1008+
_defer.assert_called_once()
1009+
_can_initialise_stanza.assert_called_once()
1010+
_is_primary.assert_not_called()
1011+
9661012
# Test that followers will not initialise the bucket
9671013
harness.charm.unit.status = ActiveStatus()
9681014
_render_pgbackrest_conf_file.reset_mock()
1015+
_can_initialise_stanza.return_value = True
1016+
_is_primary.return_value = False
9691017
with harness.hooks_disabled():
9701018
harness.update_relation_data(
9711019
peer_rel_id,
9721020
harness.charm.app.name,
9731021
{"cluster_initialised": "True"},
9741022
)
975-
_render_pgbackrest_conf_file.return_value = True
976-
9771023
harness.charm.backup.s3_client.on.credentials_changed.emit(
9781024
relation=harness.model.get_relation(S3_PARAMETERS_RELATION, s3_rel_id)
9791025
)
9801026
_render_pgbackrest_conf_file.assert_called_once()
1027+
_is_primary.assert_called_once()
9811028
_create_bucket_if_not_exists.assert_not_called()
9821029
tc.assertIsInstance(harness.charm.unit.status, ActiveStatus)
9831030
_can_use_s3_repository.assert_not_called()

0 commit comments

Comments
 (0)