Merge ~tcuthbert/charm-k8s-wordpress:additional_hostnames into charm-k8s-wordpress:master

Proposed by Thomas Cuthbert
Status: Merged
Approved by: Tom Haddon
Approved revision: 53bdaaed6f436eb14f45d46edcbb233f498c116b
Merged at revision: 15142081bbd9396aa0b66ba97fbaec1ae8033877
Proposed branch: ~tcuthbert/charm-k8s-wordpress:additional_hostnames
Merge into: charm-k8s-wordpress:master
Diff against target: 173 lines (+94/-0)
4 files modified
config.yaml (+4/-0)
src/charm.py (+30/-0)
tests/unit/test_charm.py (+59/-0)
tests/unit/test_wordpress.py (+1/-0)
Reviewer Review Type Date Requested Status
Tom Haddon Approve
Canonical IS Reviewers Pending
Review via email: mp+395661@code.launchpad.net

Commit message

Support sites with multiple hostnames ie fridge.u.c / ubuntu-news.org

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 :

Added some comments inline.

Revision history for this message
Thomas Cuthbert (tcuthbert) wrote :

comments inline

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

LGTM, thx

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

Change successfully merged at revision 15142081bbd9396aa0b66ba97fbaec1ae8033877

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
diff --git a/config.yaml b/config.yaml
index b0ee33b..acb10d3 100644
--- a/config.yaml
+++ b/config.yaml
@@ -37,6 +37,10 @@ options:
37 type: string37 type: string
38 description: "MySQL database user's password"38 description: "MySQL database user's password"
39 default: "wordpress"39 default: "wordpress"
40 additional_hostnames:
41 type: string
42 description: "Space separated list of aditional hostnames for the site."
43 default: ""
40 container_config:44 container_config:
41 type: string45 type: string
42 description: >46 description: >
diff --git a/src/charm.py b/src/charm.py
index 3dcb33e..19fe468 100755
--- a/src/charm.py
+++ b/src/charm.py
@@ -2,6 +2,7 @@
22
3import io3import io
4import logging4import logging
5import re
5import subprocess6import subprocess
6from pprint import pprint7from pprint import pprint
7from yaml import safe_load8from yaml import safe_load
@@ -87,6 +88,11 @@ def gather_wordpress_secrets():
87 return rv88 return rv
8889
8990
91def juju_setting_to_list(config_string, split_char=" "):
92 "Transforms Juju setting strings into a list, defaults to splitting on whitespace."
93 return config_string.split(split_char)
94
95
90class WordpressInitialiseEvent(EventBase):96class WordpressInitialiseEvent(EventBase):
91 """Custom event for signalling Wordpress initialisation.97 """Custom event for signalling Wordpress initialisation.
9298
@@ -281,6 +287,20 @@ class WordpressCharm(CharmBase):
281 },287 },
282 }288 }
283289
290 if self.model.config["additional_hostnames"]:
291 additional_hostnames = juju_setting_to_list(self.model.config["additional_hostnames"])
292 rules = resources["kubernetesResources"]["ingressResources"][0]["spec"]["rules"]
293 for hostname in additional_hostnames:
294 rule = {
295 "host": hostname,
296 "http": {
297 "paths": [
298 {"path": "/", "backend": {"serviceName": self.app.name, "servicePort": 80}}
299 ]
300 },
301 }
302 rules.append(rule)
303
284 ingress = resources["kubernetesResources"]["ingressResources"][0]304 ingress = resources["kubernetesResources"]["ingressResources"][0]
285 if self.model.config["tls_secret_name"]:305 if self.model.config["tls_secret_name"]:
286 ingress["spec"]["tls"] = [306 ingress["spec"]["tls"] = [
@@ -365,6 +385,16 @@ class WordpressCharm(CharmBase):
365 self.model.unit.status = BlockedStatus(message)385 self.model.unit.status = BlockedStatus(message)
366 is_valid = False386 is_valid = False
367387
388 if config["additional_hostnames"]:
389 additional_hostnames = juju_setting_to_list(config["additional_hostnames"])
390 valid_domain_name_pattern = re.compile(r"^([a-z0-9]+(-[a-z0-9]+)*\.)+[a-z]{2,}$")
391 valid = [re.match(valid_domain_name_pattern, h) for h in additional_hostnames]
392 if not all(valid):
393 message = "Invalid additional hostnames supplied: {}".format(config["additional_hostnames"])
394 logger.info(message)
395 self.model.unit.status = BlockedStatus(message)
396 is_valid = False
397
368 return is_valid398 return is_valid
369399
370 def get_service_ip(self):400 def get_service_ip(self):
diff --git a/tests/unit/test_charm.py b/tests/unit/test_charm.py
index 7f6dc54..155e908 100644
--- a/tests/unit/test_charm.py
+++ b/tests/unit/test_charm.py
@@ -98,6 +98,21 @@ class TestWordpressCharm(unittest.TestCase):
98 self.assertIsInstance(self.harness.charm.unit.status, BlockedStatus)98 self.assertIsInstance(self.harness.charm.unit.status, BlockedStatus)
99 self.assertEqual(self.harness.charm.unit.status.message, expected_msg)99 self.assertEqual(self.harness.charm.unit.status.message, expected_msg)
100 self.assertLogs(expected_msg, level="INFO")100 self.assertLogs(expected_msg, level="INFO")
101 self.harness.update_config(copy.deepcopy(self.test_model_config))
102
103 # Test for empty additional hostnames string.
104 self.harness.update_config({"additional_hostnames": ""})
105 want_true = self.harness.charm.is_valid_config()
106 self.assertTrue(want_true)
107
108 # Test for invalid additional hostnames.
109 invalid_additional_hostnames = "forgot-my-tld invalid+character.com"
110 expected_msg = "Invalid additional hostnames supplied: {}".format(invalid_additional_hostnames)
111 self.harness.update_config({"additional_hostnames": invalid_additional_hostnames})
112 self.harness.charm.is_valid_config()
113 self.assertIsInstance(self.harness.charm.unit.status, BlockedStatus)
114 self.assertEqual(self.harness.charm.unit.status.message, expected_msg)
115 self.assertLogs(expected_msg, level="INFO")
101116
102 @mock.patch("charm._leader_set")117 @mock.patch("charm._leader_set")
103 @mock.patch("charm._leader_get")118 @mock.patch("charm._leader_get")
@@ -151,6 +166,28 @@ class TestWordpressCharm(unittest.TestCase):
151 }166 }
152 ]167 ]
153 },168 },
169 },
170 {
171 'host': 'cool-newsite.org',
172 'http': {
173 'paths': [
174 {
175 'path': '/',
176 'backend': {'serviceName': 'wordpress', 'servicePort': 80},
177 }
178 ]
179 },
180 },
181 {
182 'host': 'blog.test.com',
183 'http': {
184 'paths': [
185 {
186 'path': '/',
187 'backend': {'serviceName': 'wordpress', 'servicePort': 80},
188 }
189 ]
190 },
154 }191 }
155 ],192 ],
156 'tls': [{'hosts': ['blog.example.com'], 'secretName': 'blog-example-com-tls'}],193 'tls': [{'hosts': ['blog.example.com'], 'secretName': 'blog-example-com-tls'}],
@@ -185,6 +222,28 @@ class TestWordpressCharm(unittest.TestCase):
185 }222 }
186 ]223 ]
187 },224 },
225 },
226 {
227 'host': 'cool-newsite.org',
228 'http': {
229 'paths': [
230 {
231 'path': '/',
232 'backend': {'serviceName': 'wordpress', 'servicePort': 80},
233 }
234 ]
235 },
236 },
237 {
238 'host': 'blog.test.com',
239 'http': {
240 'paths': [
241 {
242 'path': '/',
243 'backend': {'serviceName': 'wordpress', 'servicePort': 80},
244 }
245 ]
246 },
188 }247 }
189 ],248 ],
190 },249 },
diff --git a/tests/unit/test_wordpress.py b/tests/unit/test_wordpress.py
index 47cf8be..6083481 100644
--- a/tests/unit/test_wordpress.py
+++ b/tests/unit/test_wordpress.py
@@ -17,6 +17,7 @@ TEST_MODEL_CONFIG = {
17 "db_name": "wordpress",17 "db_name": "wordpress",
18 "db_user": "admin",18 "db_user": "admin",
19 "db_password": "letmein123",19 "db_password": "letmein123",
20 "additional_hostnames": "cool-newsite.org blog.test.com",
20 "wp_plugin_openid_team_map": True,21 "wp_plugin_openid_team_map": True,
21 "wp_plugin_akismet_key": "somerandomstring",22 "wp_plugin_akismet_key": "somerandomstring",
22 "container_config": "test-key: test",23 "container_config": "test-key: test",

Subscribers

People subscribed via source and target branches