Merge ~arturo-seijas/postgresql-charm:fix-enabling-extensions into postgresql-charm:master

Proposed by Arturo Enrique Seijas Fernández
Status: Merged
Approved by: Tom Haddon
Approved revision: 83be85035e2d26101362a2e916a351361943fddb
Merged at revision: 06b06260a39efa096fa8ca5e2ad2a182455c14bf
Proposed branch: ~arturo-seijas/postgresql-charm:fix-enabling-extensions
Merge into: postgresql-charm:master
Diff against target: 110 lines (+61/-10)
2 files modified
reactive/postgresql/client.py (+10/-10)
unit_tests/test_client.py (+51/-0)
Reviewer Review Type Date Requested Status
Tom Haddon Approve
Canonical IS Reviewers Pending
Review via email: mp+429280@code.launchpad.net

Commit message

Fix DB extensions installation when schema is specified

Description of the change

Fixes a bug preventing the database extensions to be installed when the target schema is also specified, in the format extension:schema

To post a comment you must log in.
Revision history for this message
🤖 Canonical IS Merge Bot (canonical-is-mergebot) wrote :

This merge proposal is being monitored by mergebot. Change the status to Approved to merge.

Revision history for this message
Tom Haddon (mthaddon) wrote :

Looks great to me, thanks.

review: Approve
Revision history for this message
🤖 Canonical IS Merge Bot (canonical-is-mergebot) wrote :

Change successfully merged at revision 06b06260a39efa096fa8ca5e2ad2a182455c14bf

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/reactive/postgresql/client.py b/reactive/postgresql/client.py
2index d80f771..9df9db3 100644
3--- a/reactive/postgresql/client.py
4+++ b/reactive/postgresql/client.py
5@@ -15,7 +15,6 @@
6 # along with this program. If not, see <http://www.gnu.org/licenses/>.
7 import json
8 from itertools import chain
9-import re
10
11 from charmhelpers.core import hookenv, host
12 from charms import leadership
13@@ -27,7 +26,7 @@ from reactive.postgresql import helpers
14 from reactive.postgresql import replication
15 from reactive.postgresql import postgresql
16 from reactive.postgresql.service import incoming_addresses
17-from relations.pgsql.requires import ConnectionString
18+from relations import pgsql
19
20 from everyhook import everyhook
21
22@@ -283,7 +282,7 @@ def relinfo_to_cs(relinfo):
23 )
24 if not all(d.values()):
25 return None
26- return ConnectionString(**d)
27+ return pgsql.requires.ConnectionString(**d)
28
29
30 def ping_standbys():
31@@ -335,14 +334,15 @@ def ensure_db_relation_resources(rel):
32 # Create requested extensions. We never drop extensions, as there
33 # may be dependent objects.
34 if "extensions" in master:
35- extensions = list(filter(None, master.get("extensions", "").split(",")))
36- # Convert to the (extension, schema) tuple expected by
37+ extensions_list = list(filter(None, master.get("extensions", "").split(",")))
38+ # Convert to the (extension, schema) tuple defaulting schema to public, as expected by
39 # postgresql.ensure_extensions
40- for i in range(0, len(extensions)):
41- m = re.search(r"^\s*([^(\s]+)\s*(?:\((\w+)\))?", extensions[i])
42- if m is None:
43- raise RuntimeError("Invalid extension {}".format(extensions[i]))
44- extensions[i] = (m.group(1), m.group(2) or "public")
45+ extensions = []
46+ for ext in extensions_list:
47+ ext_sch = ext.split(":")
48+ if(len(ext_sch) < 2):
49+ ext_sch.append("public")
50+ extensions.append(tuple(ext_sch))
51 postgresql.ensure_extensions(con, extensions)
52
53 con.commit() # Don't throw away our changes.
54diff --git a/unit_tests/test_client.py b/unit_tests/test_client.py
55new file mode 100644
56index 0000000..d569a26
57--- /dev/null
58+++ b/unit_tests/test_client.py
59@@ -0,0 +1,51 @@
60+# Copyright 2022 Canonical Ltd.
61+#
62+# This file is part of the PostgreSQL Charm for Juju.
63+#
64+# This program is free software: you can redistribute it and/or modify
65+# it under the terms of the GNU General Public License version 3, as
66+# published by the Free Software Foundation.
67+#
68+# This program is distributed in the hope that it will be useful, but
69+# WITHOUT ANY WARRANTY; without even the implied warranties of
70+# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
71+# PURPOSE. See the GNU General Public License for more details.
72+#
73+# You should have received a copy of the GNU General Public License
74+# along with this program. If not, see <http://www.gnu.org/licenses/>.
75+import os
76+import sys
77+import unittest
78+from charmhelpers.core import hookenv
79+from unittest.mock import ANY, Mock, patch
80+
81+ROOT = os.path.abspath(os.path.join(os.path.dirname(__file__), os.pardir))
82+sys.path.insert(1, ROOT)
83+sys.path.insert(2, os.path.join(ROOT, 'lib'))
84+sys.path.insert(3, os.path.join(ROOT, 'lib', 'testdeps'))
85+
86+from reactive.postgresql import client
87+from reactive.postgresql import postgresql
88+
89+
90+class TestClient(unittest.TestCase):
91+ @patch.object(hookenv, "config")
92+ @patch.object(postgresql, "connect")
93+ @patch.object(postgresql, "ensure_database")
94+ @patch.object(postgresql, "ensure_user")
95+ @patch.object(postgresql, "grant_database_privileges")
96+ @patch("psycopg2.connect")
97+ def test_ensure_db_relation_resources(self, *_):
98+ rel = Mock()
99+ rel.local = {
100+ "database": "exampledb",
101+ "extensions": "ext1:public,ext2,ext3:schema1",
102+ "password": "whatever",
103+ "schema_user": "someuser",
104+ "schema_password": "somepwd",
105+ "user": "sampleuser",
106+ }
107+ expected_extensions = [("ext1", "public"), ("ext2", "public"), ("ext3", "schema1")]
108+ with patch.object(postgresql, "ensure_extensions") as mock_ensure_extensions:
109+ client.ensure_db_relation_resources(rel)
110+ mock_ensure_extensions.assert_any_call(ANY, expected_extensions)

Subscribers

People subscribed via source and target branches