Skip to content

Commit ee3fb46

Browse files
[DPE-7521] Fix HBA rules for Landscape related through PgBouncer (#946)
* Fix HBA rules for Landscape related through PgBouncer Signed-off-by: Marcelo Henrique Neppel <[email protected]> * Update comment Signed-off-by: Marcelo Henrique Neppel <[email protected]> * Order users and databases Signed-off-by: Marcelo Henrique Neppel <[email protected]> * Add unit test for relations_user_databases_map property Signed-off-by: Marcelo Henrique Neppel <[email protected]> * Fix typo Signed-off-by: Marcelo Henrique Neppel <[email protected]> --------- Signed-off-by: Marcelo Henrique Neppel <[email protected]>
1 parent 394aec8 commit ee3fb46

File tree

2 files changed

+75
-6
lines changed

2 files changed

+75
-6
lines changed

src/charm.py

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2157,16 +2157,29 @@ def relations_user_databases_map(self) -> dict:
21572157
if not self.is_cluster_initialised or not self._patroni.member_started:
21582158
return {USER: "all", REPLICATION_USER: "all", REWIND_USER: "all"}
21592159
user_database_map = {}
2160-
for user in self.postgresql.list_users_from_relation(
2161-
current_host=self.is_connectivity_enabled
2160+
for user in sorted(
2161+
self.postgresql.list_users_from_relation(current_host=self.is_connectivity_enabled)
21622162
):
21632163
user_database_map[user] = ",".join(
2164-
self.postgresql.list_accessible_databases_for_user(
2165-
user, current_host=self.is_connectivity_enabled
2164+
sorted(
2165+
self.postgresql.list_accessible_databases_for_user(
2166+
user, current_host=self.is_connectivity_enabled
2167+
)
21662168
)
21672169
)
2168-
# Add "landscape" superuser by default to the list when the "db-admin" relation is present.
2169-
if any(True for relation in self.client_relations if relation.name == "db-admin"):
2170+
# Add "landscape" superuser by default to the list when the "db-admin" relation is present
2171+
# or when the "database" relation has "extra-user-roles" set to "SUPERUSER" (which may mean
2172+
# that PgBouncer is related to the database and there is the possibility that Landscape
2173+
# is related to it).
2174+
if any(
2175+
True
2176+
for relation in self.client_relations
2177+
if relation.name == "db-admin" # Possibly Landscape relation.
2178+
or (
2179+
relation.name == "database"
2180+
and relation.data[relation.app].get("extra-user-roles") == "SUPERUSER"
2181+
) # PgBouncer (which may be related to Landscape).
2182+
):
21702183
user_database_map["landscape"] = "all"
21712184
if self.postgresql.list_access_groups(current_host=self.is_connectivity_enabled) != set(
21722185
ACCESS_GROUPS

tests/unit/test_charm.py

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2916,3 +2916,59 @@ def test_get_ldap_parameters(harness):
29162916
harness.charm.get_ldap_parameters()
29172917
_get_relation_data.assert_called_once()
29182918
_get_relation_data.reset_mock()
2919+
2920+
2921+
def test_relations_user_databases_map(harness):
2922+
with (
2923+
patch("charm.PostgresqlOperatorCharm.postgresql") as _postgresql,
2924+
patch("charm.Patroni.member_started", new_callable=PropertyMock) as _member_started,
2925+
patch(
2926+
"charm.PostgresqlOperatorCharm.is_cluster_initialised", new_callable=PropertyMock
2927+
) as _is_cluster_initialised,
2928+
):
2929+
# Initial empty results from the functions used in the property that's being tested.
2930+
_postgresql.list_users_from_relation.return_value = set()
2931+
_postgresql.list_accessible_databases_for_user.return_value = set()
2932+
_postgresql.list_access_groups.return_value = {
2933+
"identity_access",
2934+
"internal_access",
2935+
"relation_access",
2936+
}
2937+
2938+
# Test when the cluster isn't initialised yet.
2939+
_is_cluster_initialised.return_value = False
2940+
_member_started.return_value = True
2941+
assert harness.charm.relations_user_databases_map == {
2942+
"operator": "all",
2943+
"replication": "all",
2944+
"rewind": "all",
2945+
}
2946+
2947+
# Test when the cluster is initialised but the cluster member hasn't started yet.
2948+
_is_cluster_initialised.return_value = True
2949+
_member_started.return_value = False
2950+
assert harness.charm.relations_user_databases_map == {
2951+
"operator": "all",
2952+
"replication": "all",
2953+
"rewind": "all",
2954+
}
2955+
2956+
# Test when there are no relation users in the database.
2957+
_member_started.return_value = True
2958+
assert harness.charm.relations_user_databases_map == {}
2959+
2960+
# Test when there are relation users in the database.
2961+
_postgresql.list_users_from_relation.return_value = {"user1", "user2"}
2962+
_postgresql.list_accessible_databases_for_user.side_effect = [{"db1", "db2"}, {"db3"}]
2963+
assert harness.charm.relations_user_databases_map == {"user1": "db1,db2", "user2": "db3"}
2964+
2965+
# Test when the access groups where not created yet.
2966+
_postgresql.list_accessible_databases_for_user.side_effect = [{"db1", "db2"}, {"db3"}]
2967+
_postgresql.list_access_groups.return_value = set()
2968+
assert harness.charm.relations_user_databases_map == {
2969+
"user1": "db1,db2",
2970+
"user2": "db3",
2971+
"operator": "all",
2972+
"replication": "all",
2973+
"rewind": "all",
2974+
}

0 commit comments

Comments
 (0)