Merge ~mthaddon/charm-k8s-discourse/+git/charm-k8s-discourse:redis-relation into charm-k8s-discourse:master
- Git
- lp:~mthaddon/charm-k8s-discourse/+git/charm-k8s-discourse
- redis-relation
- Merge into master
Status: | Merged |
---|---|
Approved by: | Tom Haddon |
Approved revision: | 8635ad01c30596a19ce219a4a470c96e81ed218b |
Merged at revision: | ab22995f6d560f85d94adec0d2a9d4d1b8813221 |
Proposed branch: | ~mthaddon/charm-k8s-discourse/+git/charm-k8s-discourse:redis-relation |
Merge into: | charm-k8s-discourse:master |
Diff against target: |
506 lines (+173/-38) 12 files modified
Makefile (+2/-2) README.md (+7/-16) config.yaml (+4/-4) lib/charms/redis_k8s/v0/redis.py (+97/-0) metadata.yaml (+4/-1) src/charm.py (+42/-7) tests/unit/fixtures/config_valid_complete.yaml (+4/-3) tests/unit/fixtures/config_valid_no_saml_fingerprint.yaml (+1/-0) tests/unit/fixtures/config_valid_no_saml_target_url.yaml (+1/-0) tests/unit/fixtures/config_valid_no_tls.yaml (+4/-3) tests/unit/fixtures/config_valid_with_tls.yaml (+1/-0) tests/unit/test_charm.py (+6/-2) |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Joel Sing (community) | +1 | Approve | |
🤖 prod-jenkaas-is (community) | continuous-integration | Approve | |
Canonical IS Reviewers | Pending | ||
Review via email: mp+402637@code.launchpad.net |
Commit message
Add a redis relation, using the new redis-k8s library, but continue to support static redis config as well
Description of the change
🤖 Canonical IS Merge Bot (canonical-is-mergebot) wrote : | # |
🤖 prod-jenkaas-is (prod-jenkaas-is) wrote : | # |
A CI job is currently in progress. A follow up comment will be added when it completes.
🤖 prod-jenkaas-is (prod-jenkaas-is) wrote : | # |
FAILED: Continuous integration, rev:74fc0f5f551
https:/
Executed test runs:
FAILURE: https:/
None: https:/
Click here to trigger a rebuild:
https:/
🤖 prod-jenkaas-is (prod-jenkaas-is) wrote : | # |
A CI job is currently in progress. A follow up comment will be added when it completes.
🤖 prod-jenkaas-is (prod-jenkaas-is) wrote : | # |
FAILED: Continuous integration, rev:08af48d0f81
https:/
Executed test runs:
FAILURE: https:/
None: https:/
Click here to trigger a rebuild:
https:/
🤖 prod-jenkaas-is (prod-jenkaas-is) wrote : | # |
A CI job is currently in progress. A follow up comment will be added when it completes.
🤖 prod-jenkaas-is (prod-jenkaas-is) wrote : | # |
PASSED: Continuous integration, rev:2ef40686420
https:/
Executed test runs:
SUCCESS: https:/
None: https:/
Click here to trigger a rebuild:
https:/
Joel Sing (jsing) wrote : | # |
LGTM - see various minor comments inline.
🤖 Canonical IS Merge Bot (canonical-is-mergebot) wrote : | # |
Change successfully merged at revision ab22995f6d560f8
Preview Diff
1 | diff --git a/Makefile b/Makefile |
2 | index 95aa3b7..6a7bbe1 100644 |
3 | --- a/Makefile |
4 | +++ b/Makefile |
5 | @@ -12,7 +12,7 @@ lint: blacken |
6 | |
7 | # We actually use the build directory created by charmcraft, |
8 | # but the .charm file makes a much more convenient sentinel. |
9 | -unittest: discourse.charm |
10 | +unittest: discourse-k8s.charm |
11 | @tox -e unit |
12 | |
13 | test: lint unittest |
14 | @@ -21,7 +21,7 @@ clean: |
15 | @echo "Cleaning files" |
16 | @git clean -fXd |
17 | |
18 | -discourse.charm: src/*.py requirements.txt |
19 | +discourse-k8s.charm: src/*.py requirements.txt |
20 | charmcraft build |
21 | |
22 | build-image: |
23 | diff --git a/README.md b/README.md |
24 | index 09898e4..b49813d 100644 |
25 | --- a/README.md |
26 | +++ b/README.md |
27 | @@ -15,22 +15,13 @@ Discourse than the one currently deployed. |
28 | For details on using Kubernetes with Juju [see here](https://juju.is/docs/kubernetes), and for |
29 | details on using Juju with MicroK8s for easy local testing [see here](https://juju.is/docs/microk8s-cloud). |
30 | |
31 | -To get started with a test environment, first deploy Redis in an IaaS model: |
32 | - |
33 | - juju deploy cs:~redis-charmers/redis # Note the deployed IP as ${REDIS_IP} |
34 | - |
35 | -Now deploy the Discourse and PostgreSQL charms within a Juju Kubernetes model |
36 | -as follows: |
37 | - |
38 | - juju deploy cs:~postgresql-charmers/postgresql-k8s postgresql |
39 | - juju deploy cs:~discourse-charmers/discourse-k8s discourse \ |
40 | - --config redis_host=${REDIS_IP} \ |
41 | - --config developer_emails="user@foo.internal" \ |
42 | - --config external_hostname="foo.internal" \ |
43 | - --config smtp_address="127.0.0.1" \ |
44 | - --config smtp_domain="foo.internal" |
45 | - juju add-relation discourse postgresql:db-admin |
46 | - juju expose discourse |
47 | +To deploy into a Juju K8s model: |
48 | + |
49 | + juju deploy postgresql-k8s |
50 | + juju deploy redis-k8s |
51 | + juju deploy discourse-k8s |
52 | + juju relate discourse-k8s postgresql-k8s:db-admin |
53 | + juju relate discourse-k8s redis-k8s |
54 | |
55 | Once the deployment is completed and the "discourse" workload state in `juju |
56 | status` has changed to "active" you can visit http://{$discourse_ip}:3000 in a |
57 | diff --git a/config.yaml b/config.yaml |
58 | index a55dafd..85f0677 100644 |
59 | --- a/config.yaml |
60 | +++ b/config.yaml |
61 | @@ -18,7 +18,7 @@ options: |
62 | external_hostname: |
63 | type: string |
64 | description: "External hostname this discourse instance should respond to" |
65 | - default: "" |
66 | + default: "foo.internal" |
67 | enable_cors: |
68 | type: boolean |
69 | description: "Enable Cross-origin Resource Sharing (CORS) at the application level (required for SSO)" |
70 | @@ -30,15 +30,15 @@ options: |
71 | developer_emails: |
72 | type: string |
73 | description: "Comma delimited list of email addresses that should have developer level access" |
74 | - default: "" |
75 | + default: "user@foo.internal" |
76 | smtp_domain: |
77 | type: string |
78 | description: "Hostname that email sent by this discourse should appear to come from" |
79 | - default: "" |
80 | + default: "foo.internal" |
81 | smtp_address: |
82 | type: string |
83 | description: "Hostname / IP that should be used to send SMTP mail" |
84 | - default: "" |
85 | + default: "127.0.0.1" |
86 | smtp_port: |
87 | type: int |
88 | description: "Port to use when connecting to SMTP server" |
89 | diff --git a/lib/charms/redis_k8s/v0/redis.py b/lib/charms/redis_k8s/v0/redis.py |
90 | new file mode 100644 |
91 | index 0000000..70787b6 |
92 | --- /dev/null |
93 | +++ b/lib/charms/redis_k8s/v0/redis.py |
94 | @@ -0,0 +1,97 @@ |
95 | +"""Library for the redis relation. |
96 | + |
97 | +This library contains the Requires and Provides classes for handling the |
98 | +redis interface. |
99 | + |
100 | +Import `RedisRequires` in your charm by adding the following to `src/charm.py`: |
101 | +``` |
102 | +from charms.redis_k8s.v0.redis import RedisRequires |
103 | + |
104 | +# In your charm's `__init__` method. |
105 | +self.redis = RedisRequires(self, self._stored) |
106 | +``` |
107 | +And then wherever you need to reference the relation data: |
108 | +``` |
109 | +for redis_unit in self._stored.redis_relation: |
110 | + redis_host = self._stored.redis_relation[redis_unit]["hostname"] |
111 | + redis_port = self._stored.redis_relation[redis_unit]["port"] |
112 | +``` |
113 | +""" |
114 | +import logging |
115 | + |
116 | +from ops.charm import CharmEvents |
117 | +from ops.framework import EventBase, EventSource, Object |
118 | + |
119 | +# The unique Charmhub library identifier, never change it |
120 | +LIBID = "fe18a608cec5465fa5153e419abcad7b" |
121 | + |
122 | +# Increment this major API version when introducing breaking changes |
123 | +LIBAPI = 0 |
124 | + |
125 | +# Increment this PATCH version before using `charmcraft publish-lib` or reset |
126 | +# to 0 if you are raising the major API version |
127 | +LIBPATCH = 1 |
128 | + |
129 | +logger = logging.getLogger(__name__) |
130 | + |
131 | + |
132 | +class RedisRelationUpdatedEvent(EventBase): |
133 | + pass |
134 | + |
135 | + |
136 | +class RedisRelationCharmEvents(CharmEvents): |
137 | + redis_relation_updated = EventSource(RedisRelationUpdatedEvent) |
138 | + |
139 | + |
140 | +class RedisRequires(Object): |
141 | + def __init__(self, charm, _stored): |
142 | + # Define a constructor that takes the charm and it's StoredState |
143 | + super().__init__(charm, "redis") |
144 | + self.framework.observe(charm.on.redis_relation_changed, self._on_relation_changed) |
145 | + self.framework.observe(charm.on.redis_relation_broken, self._on_relation_broken) |
146 | + self._stored = _stored |
147 | + self.charm = charm |
148 | + |
149 | + def _on_relation_changed(self, event): |
150 | + if not event.unit: |
151 | + return |
152 | + |
153 | + hostname = event.relation.data[event.unit].get("hostname") |
154 | + port = event.relation.data[event.unit].get("port") |
155 | + # Store some data from the relation in local state |
156 | + self._stored.redis_relation[event.relation.id] = {"hostname": hostname, "port": port} |
157 | + |
158 | + # Trigger an event that our charm can react to. |
159 | + self.charm.on.redis_relation_updated.emit() |
160 | + |
161 | + def _on_relation_broken(self, event): |
162 | + # Remove the unit data from local state |
163 | + self._stored.redis_relation.pop(event.relation.id, None) |
164 | + |
165 | + # Trigger an event that our charm can react to. |
166 | + self.charm.on.redis_relation_updated.emit() |
167 | + |
168 | + |
169 | +class RedisProvides(Object): |
170 | + def __init__(self, charm, port): |
171 | + super().__init__(charm, "redis") |
172 | + self.framework.observe(charm.on.redis_relation_changed, self._on_relation_changed) |
173 | + self._port = port |
174 | + |
175 | + def _on_relation_changed(self, event): |
176 | + if not self.model.unit.is_leader(): |
177 | + logger.debug("Relation changes ignored by non-leader") |
178 | + return |
179 | + |
180 | + event.relation.data[self.model.unit]['hostname'] = str(self._bind_address(event)) |
181 | + event.relation.data[self.model.unit]['port'] = str(self._port) |
182 | + # The reactive Redis charm exposes also 'password'. When tackling |
183 | + # https://github.com/canonical/redis-operator/issues/7 add 'password' |
184 | + # field so that it matches the exposed interface information from it. |
185 | + # event.relation.data[self.unit]['password'] = '' |
186 | + |
187 | + def _bind_address(self, event): |
188 | + relation = self.model.get_relation(event.relation.name, event.relation.id) |
189 | + if address := self.model.get_binding(relation).network.bind_address: |
190 | + return address |
191 | + return self.app.name |
192 | diff --git a/metadata.yaml b/metadata.yaml |
193 | index 82e1aa8..0c8beb2 100644 |
194 | --- a/metadata.yaml |
195 | +++ b/metadata.yaml |
196 | @@ -1,4 +1,5 @@ |
197 | -name: discourse |
198 | +name: discourse-k8s |
199 | +display-name: Discourse |
200 | summary: Discourse is the 100% open source discussion platform built for the next decade of the Internet. |
201 | description: | |
202 | Discourse is the 100% open source discussion platform built for the next decade of the Internet. |
203 | @@ -15,6 +16,8 @@ series: |
204 | - kubernetes |
205 | min-juju-version: 2.8.0 |
206 | requires: |
207 | + redis: |
208 | + interface: redis |
209 | db: |
210 | interface: pgsql |
211 | limit: 1 |
212 | diff --git a/src/charm.py b/src/charm.py |
213 | index d8f210b..0ef9f01 100755 |
214 | --- a/src/charm.py |
215 | +++ b/src/charm.py |
216 | @@ -2,7 +2,13 @@ |
217 | # Copyright 2020 Canonical Ltd. |
218 | # See LICENSE file for licensing details. |
219 | |
220 | +import logging |
221 | + |
222 | import ops.lib |
223 | +from charms.redis_k8s.v0.redis import ( |
224 | + RedisRelationCharmEvents, |
225 | + RedisRequires, |
226 | +) |
227 | from ops.charm import CharmBase |
228 | from ops.main import main |
229 | from ops.framework import StoredState |
230 | @@ -10,6 +16,9 @@ from ops.framework import StoredState |
231 | from ops.model import ActiveStatus, BlockedStatus, MaintenanceStatus, WaitingStatus |
232 | |
233 | |
234 | +logger = logging.getLogger(__name__) |
235 | + |
236 | + |
237 | pgsql = ops.lib.use("pgsql", 1, "postgresql-charmers@lists.launchpad.net") |
238 | |
239 | THROTTLE_LEVELS = { |
240 | @@ -52,7 +61,7 @@ def create_discourse_pod_config(config): |
241 | 'DISCOURSE_SMTP_USER_NAME': config['smtp_username'], |
242 | 'DISCOURSE_SMTP_PASSWORD': config['smtp_password'], |
243 | 'DISCOURSE_REDIS_HOST': config['redis_host'], |
244 | - 'DISCOURSE_REDIS_PORT': 6379, |
245 | + 'DISCOURSE_REDIS_PORT': config['redis_port'], |
246 | 'DISCOURSE_ENABLE_CORS': config['enable_cors'], |
247 | 'DISCOURSE_CORS_ORIGIN': config['cors_origin'], |
248 | 'DISCOURSE_REFRESH_MAXMIND_DB_DURING_PRECOMPILE_DAYS': "0", |
249 | @@ -161,7 +170,7 @@ def get_pod_spec(app_name, config): |
250 | return pod_spec |
251 | |
252 | |
253 | -def check_for_config_problems(config): |
254 | +def check_for_config_problems(config, stored): |
255 | """Check if there are issues with the juju config. |
256 | |
257 | - Primarily looks for missing config options using check_for_missing_config_fields() |
258 | @@ -169,7 +178,7 @@ def check_for_config_problems(config): |
259 | - Returns a list of errors if any were found. |
260 | """ |
261 | errors = [] |
262 | - missing_fields = check_for_missing_config_fields(config) |
263 | + missing_fields = check_for_missing_config_fields(config, stored) |
264 | |
265 | if missing_fields: |
266 | errors.append('Required configuration missing: {}'.format(" ".join(missing_fields))) |
267 | @@ -183,7 +192,7 @@ def check_for_config_problems(config): |
268 | return errors |
269 | |
270 | |
271 | -def check_for_missing_config_fields(config): |
272 | +def check_for_missing_config_fields(config, stored): |
273 | """Check for missing fields in juju config. |
274 | |
275 | - Returns a list of required fields that are either not present |
276 | @@ -194,13 +203,18 @@ def check_for_missing_config_fields(config): |
277 | needed_fields = [ |
278 | 'db_name', |
279 | 'smtp_address', |
280 | - 'redis_host', |
281 | 'cors_origin', |
282 | 'developer_emails', |
283 | 'smtp_domain', |
284 | 'discourse_image', |
285 | 'external_hostname', |
286 | ] |
287 | + # See if Redis connection information has been provided via a relation. |
288 | + redis_hostname = None |
289 | + for redis_unit in stored.redis_relation: |
290 | + redis_hostname = stored.redis_relation[redis_unit]["hostname"] |
291 | + if not redis_hostname: |
292 | + needed_fields.append("redis_host") |
293 | for key in needed_fields: |
294 | if not config.get(key): |
295 | missing_fields.append(key) |
296 | @@ -209,6 +223,7 @@ def check_for_missing_config_fields(config): |
297 | |
298 | |
299 | class DiscourseCharm(CharmBase): |
300 | + on = RedisRelationCharmEvents() |
301 | stored = StoredState() |
302 | |
303 | def __init__(self, *args): |
304 | @@ -220,7 +235,13 @@ class DiscourseCharm(CharmBase): |
305 | super().__init__(*args) |
306 | |
307 | self.stored.set_default( |
308 | - db_name=None, db_user=None, db_password=None, db_host=None, has_db_relation=False, has_db_credentials=False |
309 | + db_name=None, |
310 | + db_user=None, |
311 | + db_password=None, |
312 | + db_host=None, |
313 | + has_db_relation=False, |
314 | + has_db_credentials=False, |
315 | + redis_relation={}, |
316 | ) |
317 | self.framework.observe(self.on.leader_elected, self.configure_pod) |
318 | self.framework.observe(self.on.config_changed, self.configure_pod) |
319 | @@ -230,6 +251,9 @@ class DiscourseCharm(CharmBase): |
320 | self.framework.observe(self.db.on.database_relation_joined, self.on_database_relation_joined) |
321 | self.framework.observe(self.db.on.master_changed, self.on_database_changed) |
322 | |
323 | + self.redis = RedisRequires(self, self.stored) |
324 | + self.framework.observe(self.on.redis_relation_updated, self.configure_pod) |
325 | + |
326 | def check_config_is_valid(self, config): |
327 | """Check that the provided config is valid. |
328 | |
329 | @@ -238,7 +262,7 @@ class DiscourseCharm(CharmBase): |
330 | - Sets model status as appropriate. |
331 | """ |
332 | valid_config = True |
333 | - errors = check_for_config_problems(config) |
334 | + errors = check_for_config_problems(config, self.stored) |
335 | |
336 | # Set status if we have a bad config. |
337 | if errors: |
338 | @@ -266,6 +290,15 @@ class DiscourseCharm(CharmBase): |
339 | |
340 | - Configures pod using pod_spec generated from config. |
341 | """ |
342 | + # Get redis connection information from config but allow overriding |
343 | + # via a relation. |
344 | + redis_hostname = self.config["redis_host"] |
345 | + redis_port = 6379 |
346 | + for redis_unit in self.stored.redis_relation: |
347 | + redis_hostname = self.stored.redis_relation[redis_unit]["hostname"] |
348 | + redis_port = self.stored.redis_relation[redis_unit]["port"] |
349 | + logging.debug("Got redis connection details from relation of %s:%s", redis_hostname, redis_port) |
350 | + |
351 | # Set our status while we get configured. |
352 | self.model.unit.status = MaintenanceStatus('Configuring pod') |
353 | |
354 | @@ -282,6 +315,8 @@ class DiscourseCharm(CharmBase): |
355 | config["db_user"] = self.stored.db_user |
356 | config["db_password"] = self.stored.db_password |
357 | config["db_host"] = self.stored.db_host |
358 | + config["redis_host"] = redis_hostname |
359 | + config["redis_port"] = redis_port |
360 | # Get our spec definition. |
361 | if self.check_config_is_valid(config): |
362 | # Get pod spec using our app name and config |
363 | diff --git a/tests/unit/fixtures/config_valid_complete.yaml b/tests/unit/fixtures/config_valid_complete.yaml |
364 | index 7815983..946388d 100644 |
365 | --- a/tests/unit/fixtures/config_valid_complete.yaml |
366 | +++ b/tests/unit/fixtures/config_valid_complete.yaml |
367 | @@ -12,6 +12,7 @@ config: |
368 | image_user: 'someuser' |
369 | max_body_size: 25 |
370 | redis_host: 10.9.89.197 |
371 | + redis_port: 6379 |
372 | smtp_address: 167.89.123.58 |
373 | smtp_authentication: login |
374 | smtp_domain: example.com |
375 | @@ -51,7 +52,7 @@ pod_config: |
376 | pod_spec: |
377 | version: 3 |
378 | containers: |
379 | - - name: discourse |
380 | + - name: discourse-k8s |
381 | envConfig: |
382 | DISCOURSE_CORS_ORIGIN: '*' |
383 | DISCOURSE_DEVELOPER_EMAILS: some.person@example.com |
384 | @@ -100,14 +101,14 @@ pod_spec: |
385 | nginx.ingress.kubernetes.io/session-cookie-max-age: '3600' |
386 | nginx.ingress.kubernetes.io/session-cookie-name: 'DISCOURSE_AFFINITY' |
387 | nginx.ingress.kubernetes.io/session-cookie-samesite: 'Lax' |
388 | - name: discourse-ingress |
389 | + name: discourse-k8s-ingress |
390 | spec: |
391 | rules: |
392 | - host: discourse.local |
393 | http: |
394 | paths: |
395 | - backend: |
396 | - serviceName: discourse |
397 | + serviceName: discourse-k8s |
398 | servicePort: 3000 |
399 | path: '/' |
400 | tls: |
401 | diff --git a/tests/unit/fixtures/config_valid_no_saml_fingerprint.yaml b/tests/unit/fixtures/config_valid_no_saml_fingerprint.yaml |
402 | index 4f7365a..cc76606 100644 |
403 | --- a/tests/unit/fixtures/config_valid_no_saml_fingerprint.yaml |
404 | +++ b/tests/unit/fixtures/config_valid_no_saml_fingerprint.yaml |
405 | @@ -11,6 +11,7 @@ config: |
406 | image_pass: '' |
407 | image_user: '' |
408 | redis_host: 10.9.89.197 |
409 | + redis_port: 6379 |
410 | smtp_address: 167.89.123.58 |
411 | smtp_authentication: login |
412 | smtp_domain: example.com |
413 | diff --git a/tests/unit/fixtures/config_valid_no_saml_target_url.yaml b/tests/unit/fixtures/config_valid_no_saml_target_url.yaml |
414 | index 2f31a4f..1364998 100644 |
415 | --- a/tests/unit/fixtures/config_valid_no_saml_target_url.yaml |
416 | +++ b/tests/unit/fixtures/config_valid_no_saml_target_url.yaml |
417 | @@ -11,6 +11,7 @@ config: |
418 | image_pass: '' |
419 | image_user: '' |
420 | redis_host: 10.9.89.197 |
421 | + redis_port: 6379 |
422 | smtp_address: 167.89.123.58 |
423 | smtp_authentication: login |
424 | smtp_domain: example.com |
425 | diff --git a/tests/unit/fixtures/config_valid_no_tls.yaml b/tests/unit/fixtures/config_valid_no_tls.yaml |
426 | index 1f7e021..8179e1a 100644 |
427 | --- a/tests/unit/fixtures/config_valid_no_tls.yaml |
428 | +++ b/tests/unit/fixtures/config_valid_no_tls.yaml |
429 | @@ -12,6 +12,7 @@ config: |
430 | image_user: '' |
431 | max_body_size: 20 |
432 | redis_host: 10.9.89.197 |
433 | + redis_port: 6379 |
434 | smtp_address: 167.89.123.58 |
435 | smtp_authentication: login |
436 | smtp_domain: example.com |
437 | @@ -51,7 +52,7 @@ pod_config: |
438 | pod_spec: |
439 | version: 3 |
440 | containers: |
441 | - - name: discourse |
442 | + - name: discourse-k8s |
443 | envConfig: |
444 | DISCOURSE_CORS_ORIGIN: '*' |
445 | DISCOURSE_DEVELOPER_EMAILS: some.person@example.com |
446 | @@ -99,13 +100,13 @@ pod_spec: |
447 | nginx.ingress.kubernetes.io/session-cookie-name: 'DISCOURSE_AFFINITY' |
448 | nginx.ingress.kubernetes.io/session-cookie-samesite: 'Lax' |
449 | nginx.ingress.kubernetes.io/ssl-redirect: 'false' |
450 | - name: discourse-ingress |
451 | + name: discourse-k8s-ingress |
452 | spec: |
453 | rules: |
454 | - host: discourse.local |
455 | http: |
456 | paths: |
457 | - backend: |
458 | - serviceName: discourse |
459 | + serviceName: discourse-k8s |
460 | servicePort: 3000 |
461 | path: '/' |
462 | diff --git a/tests/unit/fixtures/config_valid_with_tls.yaml b/tests/unit/fixtures/config_valid_with_tls.yaml |
463 | index 8e9e225..a4eff75 100644 |
464 | --- a/tests/unit/fixtures/config_valid_with_tls.yaml |
465 | +++ b/tests/unit/fixtures/config_valid_with_tls.yaml |
466 | @@ -11,6 +11,7 @@ config: |
467 | image_pass: 'discourse123' |
468 | image_user: 'discourse_role' |
469 | redis_host: 10.9.89.197 |
470 | + redis_port: 6379 |
471 | smtp_address: 167.89.123.58 |
472 | smtp_authentication: login |
473 | smtp_domain: example.com |
474 | diff --git a/tests/unit/test_charm.py b/tests/unit/test_charm.py |
475 | index 20fe84e..40da7db 100644 |
476 | --- a/tests/unit/test_charm.py |
477 | +++ b/tests/unit/test_charm.py |
478 | @@ -56,7 +56,7 @@ class TestDiscourseK8sCharmHooksDisabled(unittest.TestCase): |
479 | if config_key.startswith('config_valid_'): |
480 | config_valid = self.harness.charm.check_config_is_valid(self.configs[config_key]['config']) |
481 | pod_config = create_discourse_pod_config(self.configs[config_key]['config']) |
482 | - self.assertEqual(config_valid, True, 'Valid config is not recognized as valid') |
483 | + self.assertEqual(config_valid, True, 'Valid config {} is not recognized as valid'.format(config_key)) |
484 | self.assertEqual( |
485 | pod_config, |
486 | self.configs[config_key]['pod_config'], |
487 | @@ -77,7 +77,9 @@ class TestDiscourseK8sCharmHooksDisabled(unittest.TestCase): |
488 | for config_key in self.configs: |
489 | if config_key.startswith('config_invalid_'): |
490 | config_valid = self.harness.charm.check_config_is_valid(self.configs[config_key]['config']) |
491 | - missing_fields = check_for_missing_config_fields(self.configs[config_key]['config']) |
492 | + stored = SimpleNamespace() |
493 | + stored.redis_relation = {} |
494 | + missing_fields = check_for_missing_config_fields(self.configs[config_key]['config'], stored) |
495 | self.assertEqual(config_valid, False, 'Invalid config is not recognized as invalid') |
496 | self.assertEqual( |
497 | missing_fields, |
498 | @@ -91,6 +93,8 @@ class TestDiscourseK8sCharmHooksDisabled(unittest.TestCase): |
499 | test_config['db_user'] = 'discourse_m' |
500 | test_config['db_password'] = 'a_real_password' |
501 | test_config['db_host'] = '10.9.89.237' |
502 | + test_config['redis_host'] = '10.9.89.197' |
503 | + test_config['redis_port'] = 6379 |
504 | db_event = SimpleNamespace() |
505 | db_event.master = SimpleNamespace() |
506 | db_event.master.user = 'discourse_m' |
This merge proposal is being monitored by mergebot. Change the status to Approved to merge.