Merge lp:~niedbalski/charms/trusty/rabbitmq-server/fix-1442443 into lp:charms/trusty/rabbitmq-server

Proposed by Jorge Niedbalski
Status: Superseded
Proposed branch: lp:~niedbalski/charms/trusty/rabbitmq-server/fix-1442443
Merge into: lp:charms/trusty/rabbitmq-server
Diff against target: 746 lines (+373/-168)
11 files modified
config.yaml (+7/-1)
hooks/rabbit_utils.py (+37/-39)
hooks/rabbitmq_context.py (+125/-0)
hooks/rabbitmq_server_relations.py (+7/-113)
hooks/ssl_utils.py (+55/-0)
templates/rabbitmq.config (+25/-11)
tests/00_setup.sh (+3/-0)
tests/50_test_cluster_partition.py (+31/-0)
unit_tests/test_rabbit_utils.py (+1/-1)
unit_tests/test_rabbitmq_context.py (+79/-0)
unit_tests/test_rabbitmq_server_relations.py (+3/-3)
To merge this branch: bzr merge lp:~niedbalski/charms/trusty/rabbitmq-server/fix-1442443
Reviewer Review Type Date Requested Status
Billy Olsen Needs Fixing
OpenStack Charmers Pending
Review via email: mp+255770@code.launchpad.net

This proposal has been superseded by a proposal from 2015-04-10.

Description of the change

- Added the cluster_partition_handling option fixes LP: #1442443
- Refactored the ssl handling code.
- Added a generic config loader

To post a comment you must log in.
Revision history for this message
Billy Olsen (billy-olsen) wrote :

Jorge,

I think some of the refactor in here is a definite improvement and makes things cleaner, thanks! I've got a few inline comments included, but the biggest thing is that the rabbitmq-server charm now has a /next and /trunk branch to match the rest of the flow of the openstack charms (since this has recently come under ownership of the ~openstack-charmers team). Can you retarget for /next?

Also, I think the README file should be updated with some discussions regarding high availability.

I'll run through some tests on this but wanted to drop some feedback now.

review: Needs Fixing
Revision history for this message
uosci-testing-bot (uosci-testing-bot) wrote :

charm_lint_check #3202 rabbitmq-server for niedbalski mp255770
    LINT OK: passed

Build: http://10.245.162.77:8080/job/charm_lint_check/3202/

Revision history for this message
uosci-testing-bot (uosci-testing-bot) wrote :

charm_unit_test #2990 rabbitmq-server for niedbalski mp255770
    UNIT OK: passed

Build: http://10.245.162.77:8080/job/charm_unit_test/2990/

Revision history for this message
uosci-testing-bot (uosci-testing-bot) wrote :

charm_amulet_test #3019 rabbitmq-server for niedbalski mp255770
    AMULET FAIL: amulet-test failed

AMULET Results (max last 2 lines):
make: *** [functional_test] Error 1
ERROR:root:Make target returned non-zero.

Full amulet test output: http://paste.ubuntu.com/10789138/
Build: http://10.245.162.77:8080/job/charm_amulet_test/3019/

89. By Liam Young

[gnuoy,trivial] Pre-release charmhelper sync

90. By James Page

[wolsen,r=james-page] Fixup SSL tests to not fail when certs expire!

91. By Jorge Niedbalski

Rebase commit

92. By Jorge Niedbalski

Rebase

93. By Jorge Niedbalski

addressing @dosaboy comments

94. By Jorge Niedbalski

addressing @dosaboy comments

95. By Jorge Niedbalski

addressing @dosaboy comments

96. By Jorge Niedbalski

addressing comments

97. By Jorge Niedbalski

Addressed @beisner comments

98. By Jorge Niedbalski

Addressed @beisner comments

Unmerged revisions

98. By Jorge Niedbalski

Addressed @beisner comments

97. By Jorge Niedbalski

Addressed @beisner comments

96. By Jorge Niedbalski

addressing comments

95. By Jorge Niedbalski

addressing @dosaboy comments

94. By Jorge Niedbalski

addressing @dosaboy comments

93. By Jorge Niedbalski

addressing @dosaboy comments

92. By Jorge Niedbalski

Rebase

91. By Jorge Niedbalski

Rebase commit

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'config.yaml'
--- config.yaml 2015-03-03 06:05:14 +0000
+++ config.yaml 2015-04-10 02:40:31 +0000
@@ -8,7 +8,7 @@
8 type: string8 type: string
9 default: "off"9 default: "off"
10 description: |10 description: |
11 Enable SSL connections on rabbitmq, valid values are 'off', 'on', 'only'. If ssl_key, 11 Enable SSL connections on rabbitmq, valid values are 'off', 'on', 'only'. If ssl_key,
12 ssl_cert, ssl_ca are provided then then those values will be used. Otherwise12 ssl_cert, ssl_ca are provided then then those values will be used. Otherwise
13 the service will act as its own certificate authority and pass its ca cert to clients.13 the service will act as its own certificate authority and pass its ca cert to clients.
14 For HA or clustered rabbits ssl key/cert must be provided.14 For HA or clustered rabbits ssl key/cert must be provided.
@@ -92,6 +92,12 @@
92 description: |92 description: |
93 When set to true the 'ha-mode: all' policy is applied to all the exchages93 When set to true the 'ha-mode: all' policy is applied to all the exchages
94 that match the expression '^(?!amq\.).*'94 that match the expression '^(?!amq\.).*'
95 cluster-partition-handling:
96 type: string
97 default: ignore
98 description: |
99 How to respond to cluster partitions.
100 See http://www.rabbitmq.com/partitions.html for further details.
95 rbd-size:101 rbd-size:
96 type: string102 type: string
97 default: 5G103 default: 5G
98104
=== modified file 'hooks/rabbit_utils.py'
--- hooks/rabbit_utils.py 2015-03-24 20:17:01 +0000
+++ hooks/rabbit_utils.py 2015-04-10 02:40:31 +0000
@@ -1,6 +1,4 @@
1import os1import os
2import pwd
3import grp
4import re2import re
5import socket3import socket
6import sys4import sys
@@ -8,6 +6,13 @@
8import glob6import glob
9import tempfile7import tempfile
108
9from rabbitmq_context import (
10 RabbitMQSSLContext,
11 RabbitMQClusterContext
12)
13
14from charmhelpers.core.templating import render
15
11from charmhelpers.contrib.openstack.utils import (16from charmhelpers.contrib.openstack.utils import (
12 get_hostname,17 get_hostname,
13)18)
@@ -30,8 +35,6 @@
30 cmp_pkgrevno35 cmp_pkgrevno
31)36)
3237
33from charmhelpers.core.templating import render
34
35from charmhelpers.contrib.peerstorage import (38from charmhelpers.contrib.peerstorage import (
36 peer_store,39 peer_store,
37 peer_retrieve40 peer_retrieve
@@ -57,7 +60,10 @@
57# the charm doesn't concern itself with template specifics etc.60# the charm doesn't concern itself with template specifics etc.
58CONFIG_FILES = OrderedDict([61CONFIG_FILES = OrderedDict([
59 (RABBITMQ_CONF, {62 (RABBITMQ_CONF, {
60 'hook_contexts': None,63 'hook_contexts': [
64 RabbitMQSSLContext(),
65 RabbitMQClusterContext(),
66 ],
61 'services': ['rabbitmq-server']67 'services': ['rabbitmq-server']
62 }),68 }),
63 (ENV_CONF, {69 (ENV_CONF, {
@@ -71,6 +77,32 @@
71])77])
7278
7379
80class ConfigRenderer():
81
82 def __init__(self, config):
83 self.config_data = {}
84
85 for config_path, data in config.items():
86 if 'hook_contexts' in data and data['hook_contexts']:
87 ctxt = {}
88 for svc_context in data['hook_contexts']:
89 ctxt.update(svc_context())
90 self.config_data[config_path] = ctxt
91
92 def write(self, config_path):
93 data = self.config_data.get(config_path, None)
94 if data:
95 log("writing config file: %s , data: %s" % (config_path,
96 str(data)), level='DEBUG')
97
98 render(os.path.basename(config_path), config_path,
99 data, perms=0o644)
100
101 def write_all(self):
102 for service in self.config_data.keys():
103 self.write(service)
104
105
74class RabbitmqError(Exception):106class RabbitmqError(Exception):
75 pass107 pass
76108
@@ -390,40 +422,6 @@
390def disable_plugin(plugin):422def disable_plugin(plugin):
391 _manage_plugin(plugin, 'disable')423 _manage_plugin(plugin, 'disable')
392424
393ssl_key_file = "/etc/rabbitmq/rabbit-server-privkey.pem"
394ssl_cert_file = "/etc/rabbitmq/rabbit-server-cert.pem"
395ssl_ca_file = "/etc/rabbitmq/rabbit-server-ca.pem"
396
397
398def enable_ssl(ssl_key, ssl_cert, ssl_port,
399 ssl_ca=None, ssl_only=False, ssl_client=None):
400 uid = pwd.getpwnam("root").pw_uid
401 gid = grp.getgrnam("rabbitmq").gr_gid
402
403 for contents, path in (
404 (ssl_key, ssl_key_file),
405 (ssl_cert, ssl_cert_file),
406 (ssl_ca, ssl_ca_file)):
407 if not contents:
408 continue
409 with open(path, 'w') as fh:
410 fh.write(contents)
411 os.chmod(path, 0o640)
412 os.chown(path, uid, gid)
413
414 data = {
415 "ssl_port": ssl_port,
416 "ssl_cert_file": ssl_cert_file,
417 "ssl_key_file": ssl_key_file,
418 "ssl_client": ssl_client,
419 "ssl_ca_file": "",
420 "ssl_only": ssl_only}
421
422 if ssl_ca:
423 data["ssl_ca_file"] = ssl_ca_file
424
425 render(os.path.basename(RABBITMQ_CONF), RABBITMQ_CONF, data, perms=0o644)
426
427425
428def execute(cmd, die=False, echo=False):426def execute(cmd, die=False, echo=False):
429 """ Executes a command427 """ Executes a command
430428
=== added file 'hooks/rabbitmq_context.py'
--- hooks/rabbitmq_context.py 1970-01-01 00:00:00 +0000
+++ hooks/rabbitmq_context.py 2015-04-10 02:40:31 +0000
@@ -0,0 +1,125 @@
1from charmhelpers.contrib.ssl.service import ServiceCA
2
3from charmhelpers.core.hookenv import (
4 open_port,
5 close_port,
6 config,
7 log,
8 ERROR,
9)
10
11import sys
12import pwd
13import grp
14import os
15import base64
16
17import ssl_utils
18
19ssl_key_file = "/etc/rabbitmq/rabbit-server-privkey.pem"
20ssl_cert_file = "/etc/rabbitmq/rabbit-server-cert.pem"
21ssl_ca_file = "/etc/rabbitmq/rabbit-server-ca.pem"
22
23
24def convert_from_base64(v):
25 # Rabbit originally supported pem encoded key/cert in config, play
26 # nice on upgrades as we now expect base64 encoded key/cert/ca.
27 if not v:
28 return v
29 if v.startswith('-----BEGIN'):
30 return v
31 try:
32 return base64.b64decode(v)
33 except TypeError:
34 return v
35
36
37class RabbitMQSSLContext(object):
38
39 def enable_ssl(self, ssl_key, ssl_cert, ssl_port,
40 ssl_ca=None, ssl_only=False, ssl_client=None):
41
42 uid = pwd.getpwnam("root").pw_uid
43 gid = grp.getgrnam("rabbitmq").gr_gid
44
45 for contents, path in (
46 (ssl_key, ssl_key_file),
47 (ssl_cert, ssl_cert_file),
48 (ssl_ca, ssl_ca_file)):
49
50 if not contents:
51 continue
52
53 with open(path, 'w') as fh:
54 fh.write(contents)
55
56 os.chmod(path, 0o640)
57 os.chown(path, uid, gid)
58
59 data = {
60 "ssl_port": ssl_port,
61 "ssl_cert_file": ssl_cert_file,
62 "ssl_key_file": ssl_key_file,
63 "ssl_client": ssl_client,
64 "ssl_ca_file": "",
65 "ssl_only": ssl_only
66 }
67
68 if ssl_ca:
69 data["ssl_ca_file"] = ssl_ca_file
70
71 return data
72
73 def __call__(self):
74 """
75 The legacy config support adds some additional complications.
76
77 ssl_enabled = True, ssl = off -> ssl enabled
78 ssl_enabled = False, ssl = on -> ssl enabled
79 """
80 ssl_mode, external_ca = ssl_utils.get_ssl_mode()
81
82 ctxt = {
83 'ssl_mode': ssl_mode,
84 }
85
86 if ssl_mode == 'off':
87 close_port(config('ssl_port'))
88 ssl_utils.reconfigure_client_ssl()
89 return ctxt
90
91 ssl_key = convert_from_base64(config('ssl_key'))
92 ssl_cert = convert_from_base64(config('ssl_cert'))
93 ssl_ca = convert_from_base64(config('ssl_ca'))
94 ssl_port = config('ssl_port')
95
96 # If external managed certs then we need all the fields.
97 if (
98 ssl_mode in ('on', 'only') and
99 any((ssl_key, ssl_cert)) and
100 not all((ssl_key, ssl_cert))
101 ):
102 log('If ssl_key or ssl_cert are specified both are required.',
103 level=ERROR)
104 sys.exit(1)
105
106 if not external_ca:
107 ssl_cert, ssl_key, ssl_ca = ServiceCA.get_service_cert()
108
109 ctxt.update(self.enable_ssl(
110 ssl_key, ssl_cert, ssl_port, ssl_ca,
111 ssl_only=(ssl_mode == "only"), ssl_client=False
112 ))
113
114 ssl_utils.reconfigure_client_ssl(True)
115 open_port(ssl_port)
116
117 return ctxt
118
119
120class RabbitMQClusterContext(object):
121
122 def __call__(self):
123 return {
124 'cluster_partition_handling': config('cluster-partition-handling'),
125 }
0126
=== modified file 'hooks/rabbitmq_server_relations.py'
--- hooks/rabbitmq_server_relations.py 2015-03-06 06:39:19 +0000
+++ hooks/rabbitmq_server_relations.py 2015-04-10 02:40:31 +0000
@@ -1,5 +1,5 @@
1#!/usr/bin/python1#!/usr/bin/python
2import base642
3import os3import os
4import shutil4import shutil
5import sys5import sys
@@ -8,6 +8,8 @@
8import socket8import socket
99
10import rabbit_utils as rabbit10import rabbit_utils as rabbit
11import ssl_utils
12
11from lib.utils import (13from lib.utils import (
12 chown, chmod,14 chown, chmod,
13 is_newer,15 is_newer,
@@ -46,7 +48,6 @@
46 related_units,48 related_units,
47 service_name,49 service_name,
48 local_unit,50 local_unit,
49 relations_of_type,
50 config,51 config,
51 unit_get,52 unit_get,
52 is_relation_made,53 is_relation_made,
@@ -61,7 +62,6 @@
61 service_restart,62 service_restart,
62)63)
63from charmhelpers.contrib.charmsupport import nrpe64from charmhelpers.contrib.charmsupport import nrpe
64from charmhelpers.contrib.ssl.service import ServiceCA
6565
66from charmhelpers.contrib.peerstorage import (66from charmhelpers.contrib.peerstorage import (
67 peer_echo,67 peer_echo,
@@ -176,7 +176,7 @@
176 get_address_in_network(config('access-network'),176 get_address_in_network(config('access-network'),
177 unit_get('private-address'))177 unit_get('private-address'))
178178
179 configure_client_ssl(relation_settings)179 ssl_utils.configure_client_ssl(relation_settings)
180180
181 if is_clustered():181 if is_clustered():
182 relation_settings['clustered'] = 'true'182 relation_settings['clustered'] = 'true'
@@ -302,19 +302,6 @@
302 service_restart('rabbitmq-server')302 service_restart('rabbitmq-server')
303303
304304
305@hooks.hook('cluster-relation-departed')
306def cluster_departed():
307 if is_relation_made('ha') and \
308 config('ha-vip-only') is False:
309 log('hacluster relation is present, skipping native '
310 'rabbitmq cluster config.')
311 return
312 if not is_newer():
313 log('cluster_joined: Relation lesser.')
314 return
315 rabbit.break_cluster()
316
317
318@hooks.hook('ha-relation-joined')305@hooks.hook('ha-relation-joined')
319def ha_joined():306def ha_joined():
320 corosync_bindiface = config('ha-bindiface')307 corosync_bindiface = config('ha-bindiface')
@@ -526,103 +513,10 @@
526MAN_PLUGIN = 'rabbitmq_management'513MAN_PLUGIN = 'rabbitmq_management'
527514
528515
529def configure_client_ssl(relation_data):
530 """Configure client with ssl
531 """
532 ssl_mode, external_ca = _get_ssl_mode()
533 if ssl_mode == 'off':
534 return
535 relation_data['ssl_port'] = config('ssl_port')
536 if external_ca:
537 if config('ssl_ca'):
538 relation_data['ssl_ca'] = base64.b64encode(
539 config('ssl_ca'))
540 return
541 ca = ServiceCA.get_ca()
542 relation_data['ssl_ca'] = base64.b64encode(ca.get_ca_bundle())
543
544
545def _get_ssl_mode():
546 ssl_mode = config('ssl')
547 external_ca = False
548 # Legacy config boolean option
549 ssl_on = config('ssl_enabled')
550 if ssl_mode == 'off' and ssl_on is False:
551 ssl_mode = 'off'
552 elif ssl_mode == 'off' and ssl_on:
553 ssl_mode = 'on'
554 ssl_key = config('ssl_key')
555 ssl_cert = config('ssl_cert')
556 if all((ssl_key, ssl_cert)):
557 external_ca = True
558 return ssl_mode, external_ca
559
560
561def _convert_from_base64(v):
562 # Rabbit originally supported pem encoded key/cert in config, play
563 # nice on upgrades as we now expect base64 encoded key/cert/ca.
564 if not v:
565 return v
566 if v.startswith('-----BEGIN'):
567 return v
568 try:
569 return base64.b64decode(v)
570 except TypeError:
571 return v
572
573
574def reconfigure_client_ssl(ssl_enabled=False):
575 ssl_config_keys = set(('ssl_key', 'ssl_cert', 'ssl_ca'))
576 for rid in relation_ids('amqp'):
577 rdata = relation_get(rid=rid, unit=os.environ['JUJU_UNIT_NAME'])
578 if not ssl_enabled and ssl_config_keys.intersection(rdata):
579 # No clean way to remove entirely, but blank them.
580 relation_set(relation_id=rid, ssl_key='', ssl_cert='', ssl_ca='')
581 elif ssl_enabled and not ssl_config_keys.intersection(rdata):
582 configure_client_ssl(rdata)
583 relation_set(relation_id=rid, **rdata)
584
585
586def configure_rabbit_ssl():
587 """
588 The legacy config support adds some additional complications.
589
590 ssl_enabled = True, ssl = off -> ssl enabled
591 ssl_enabled = False, ssl = on -> ssl enabled
592 """
593 ssl_mode, external_ca = _get_ssl_mode()
594
595 if ssl_mode == 'off':
596 if os.path.exists(rabbit.RABBITMQ_CONF):
597 os.remove(rabbit.RABBITMQ_CONF)
598 close_port(config('ssl_port'))
599 reconfigure_client_ssl()
600 return
601 ssl_key = _convert_from_base64(config('ssl_key'))
602 ssl_cert = _convert_from_base64(config('ssl_cert'))
603 ssl_ca = _convert_from_base64(config('ssl_ca'))
604 ssl_port = config('ssl_port')
605
606 # If external managed certs then we need all the fields.
607 if (ssl_mode in ('on', 'only') and any((ssl_key, ssl_cert)) and
608 not all((ssl_key, ssl_cert))):
609 log('If ssl_key or ssl_cert are specified both are required.',
610 level=ERROR)
611 sys.exit(1)
612
613 if not external_ca:
614 ssl_cert, ssl_key, ssl_ca = ServiceCA.get_service_cert()
615
616 rabbit.enable_ssl(
617 ssl_key, ssl_cert, ssl_port, ssl_ca,
618 ssl_only=(ssl_mode == "only"), ssl_client=False)
619 reconfigure_client_ssl(True)
620 open_port(ssl_port)
621
622
623@hooks.hook('config-changed')516@hooks.hook('config-changed')
624@restart_on_change(rabbit.restart_map())517@restart_on_change(rabbit.restart_map())
625def config_changed():518def config_changed():
519
626 if config('prefer-ipv6'):520 if config('prefer-ipv6'):
627 rabbit.assert_charm_supports_ipv6()521 rabbit.assert_charm_supports_ipv6()
628522
@@ -652,9 +546,9 @@
652 rabbit.disable_plugin(MAN_PLUGIN)546 rabbit.disable_plugin(MAN_PLUGIN)
653 close_port(55672)547 close_port(55672)
654548
655 configure_rabbit_ssl()
656
657 rabbit.set_all_mirroring_queues(config('mirroring-queues'))549 rabbit.set_all_mirroring_queues(config('mirroring-queues'))
550 rabbit.ConfigRenderer(
551 rabbit.CONFIG_FILES).write_all()
658552
659 if is_relation_made("ha"):553 if is_relation_made("ha"):
660 ha_is_active_active = config("ha-vip-only")554 ha_is_active_active = config("ha-vip-only")
661555
=== added file 'hooks/ssl_utils.py'
--- hooks/ssl_utils.py 1970-01-01 00:00:00 +0000
+++ hooks/ssl_utils.py 2015-04-10 02:40:31 +0000
@@ -0,0 +1,55 @@
1from charmhelpers.contrib.ssl.service import ServiceCA
2
3from charmhelpers.core.hookenv import (
4 config,
5 relation_ids,
6 relation_set,
7 relation_get,
8)
9
10import base64
11import os
12
13
14def get_ssl_mode():
15 ssl_mode = config('ssl')
16 external_ca = False
17 # Legacy config boolean option
18 ssl_on = config('ssl_enabled')
19 if ssl_mode == 'off' and ssl_on is False:
20 ssl_mode = 'off'
21 elif ssl_mode == 'off' and ssl_on:
22 ssl_mode = 'on'
23 ssl_key = config('ssl_key')
24 ssl_cert = config('ssl_cert')
25 if all((ssl_key, ssl_cert)):
26 external_ca = True
27 return ssl_mode, external_ca
28
29
30def configure_client_ssl(relation_data):
31 """Configure client with ssl
32 """
33 ssl_mode, external_ca = get_ssl_mode()
34 if ssl_mode == 'off':
35 return
36 relation_data['ssl_port'] = config('ssl_port')
37 if external_ca:
38 if config('ssl_ca'):
39 relation_data['ssl_ca'] = base64.b64encode(
40 config('ssl_ca'))
41 return
42 ca = ServiceCA.get_ca()
43 relation_data['ssl_ca'] = base64.b64encode(ca.get_ca_bundle())
44
45
46def reconfigure_client_ssl(ssl_enabled=False):
47 ssl_config_keys = set(('ssl_key', 'ssl_cert', 'ssl_ca'))
48 for rid in relation_ids('amqp'):
49 rdata = relation_get(rid=rid, unit=os.environ['JUJU_UNIT_NAME'])
50 if not ssl_enabled and ssl_config_keys.intersection(rdata):
51 # No clean way to remove entirely, but blank them.
52 relation_set(relation_id=rid, ssl_key='', ssl_cert='', ssl_ca='')
53 elif ssl_enabled and not ssl_config_keys.intersection(rdata):
54 configure_client_ssl(rdata)
55 relation_set(relation_id=rid, **rdata)
056
=== modified file 'templates/rabbitmq.config'
--- templates/rabbitmq.config 2014-05-23 08:13:05 +0000
+++ templates/rabbitmq.config 2015-04-10 02:40:31 +0000
@@ -1,21 +1,35 @@
1[1[
2 {rabbit, [ 2 {rabbit, [
3{% if ssl_only %} 3{% if ssl_only %}
4 {tcp_listeners, []},4 {tcp_listeners, []},
5{% else %}5{% else %}
6 {tcp_listeners, [5672]},6 {tcp_listeners, [5672]},
7{% endif %}7{% endif %}
8 {ssl_listeners, [{{ ssl_port }}]},8{% if ssl_port %}
9 {ssl_listeners, [{{ ssl_port }}]},
10{% endif %}
11{% if ssl_mode == "on" %}
9 {ssl_options, [12 {ssl_options, [
10 {verify, verify_peer},13 {verify, verify_peer},
11{% if ssl_client %} 14{% if ssl_client %}
12 {fail_if_no_peer_cert, true}, 15 {fail_if_no_peer_cert, true},
13{% else %}16{% else %}
14 {fail_if_no_peer_cert, false},17 {fail_if_no_peer_cert, false},
15{% endif %}{% if ssl_ca_file %} 18{% endif %}
16 {cacertfile, "{{ ssl_ca_file }}"}, {% endif %}19 {% if ssl_ca_file %}
17 {certfile, "{{ ssl_cert_file }}"},20 {cacertfile, "{{ ssl_ca_file }}"},
18 {keyfile, "{{ ssl_key_file }}"}21 {% endif %}
19 ]}22 {% if ssl_cert_file %}
23 {certfile, "{{ ssl_cert_file }}"},
24 {% endif %}
25 {% if ssl_key_file %}
26 {keyfile, "{{ ssl_key_file }}"}
27 {% endif %}
28 ]},
29{% endif %}
30
31 {% if cluster_partition_handling %}
32 {cluster_partition_handling, {{ cluster_partition_handling }}}
33 {% endif %}
20 ]}34 ]}
21].
22\ No newline at end of file35\ No newline at end of file
36].
2337
=== modified file 'tests/00_setup.sh'
--- tests/00_setup.sh 2015-03-12 16:42:09 +0000
+++ tests/00_setup.sh 2015-04-10 02:40:31 +0000
@@ -15,4 +15,7 @@
15# Install any additional python packages, or software here.15# Install any additional python packages, or software here.
16sudo apt-get install -y python python-pika python3-requests python3-setuptools16sudo apt-get install -y python python-pika python3-requests python3-setuptools
1717
18# Set http proxy if amulet is using one.
19[[ -n "$AMULET_HTTP_PROXY" ]] && export http_proxy="$AMULET_HTTP_PROXY" && https_proxy="$AMULET_HTTP_PROXY"
20
18sudo easy_install3 python3-pika21sudo easy_install3 python3-pika
1922
=== added file 'tests/50_test_cluster_partition.py'
--- tests/50_test_cluster_partition.py 1970-01-01 00:00:00 +0000
+++ tests/50_test_cluster_partition.py 2015-04-10 02:40:31 +0000
@@ -0,0 +1,31 @@
1#!/usr/bin/python
2#
3# This Amulet test deploys rabbitmq-server
4#
5# Note: We use python2, because pika doesn't support python3
6import amulet
7
8# The number of seconds to wait for the environment to setup.
9seconds = 1200
10d = amulet.Deployment(series="trusty")
11
12d.add('rabbitmq-server', units=1)
13# Create a configuration.
14configuration = {'cluster-partition-handling': "autoheal"}
15d.configure('rabbitmq-server', configuration)
16
17d.expose('rabbitmq-server')
18try:
19 d.setup(timeout=seconds)
20 d.sentry.wait(seconds)
21except amulet.helpers.TimeoutError:
22 message = 'The environment did not setup in %d seconds.' % seconds
23 amulet.raise_status(amulet.SKIP, msg=message)
24except:
25 raise
26
27rabbit_unit = d.sentry.unit['rabbitmq-server/0']
28output, code = rabbit_unit.run("grep autoheal /etc/rabbitmq/rabbitmq.conf")
29
30if code != 0 or output == "":
31 amulet.raise_status(amulet.FAIL, msg=message)
032
=== modified file 'unit_tests/test_rabbit_utils.py'
--- unit_tests/test_rabbit_utils.py 2014-10-08 15:57:57 +0000
+++ unit_tests/test_rabbit_utils.py 2015-04-10 02:40:31 +0000
@@ -4,8 +4,8 @@
4import tempfile4import tempfile
5import sys5import sys
66
7import rabbit_utils
7sys.modules['MySQLdb'] = mock.Mock()8sys.modules['MySQLdb'] = mock.Mock()
8import rabbit_utils
99
1010
11class UtilsTests(unittest.TestCase):11class UtilsTests(unittest.TestCase):
1212
=== added file 'unit_tests/test_rabbitmq_context.py'
--- unit_tests/test_rabbitmq_context.py 1970-01-01 00:00:00 +0000
+++ unit_tests/test_rabbitmq_context.py 2015-04-10 02:40:31 +0000
@@ -0,0 +1,79 @@
1import rabbitmq_context
2
3import mock
4import unittest
5
6
7class TestRabbitMQSSLContext(unittest.TestCase):
8
9 @mock.patch("rabbitmq_context.config")
10 @mock.patch("rabbitmq_context.close_port")
11 @mock.patch("rabbitmq_context.ssl_utils.reconfigure_client_ssl")
12 @mock.patch("rabbitmq_context.ssl_utils.get_ssl_mode")
13 def test_context_ssl_off(self, get_ssl_mode, reconfig_ssl, close_port,
14 config):
15 get_ssl_mode.return_value = ("off", "off")
16 self.assertEqual(rabbitmq_context.RabbitMQSSLContext().__call__(), {
17 "ssl_mode": "off"
18 })
19
20 close_port.assert_called_once()
21 reconfig_ssl.assert_called_once()
22
23 @mock.patch("rabbitmq_context.open_port")
24 @mock.patch("rabbitmq_context.os.chmod")
25 @mock.patch("rabbitmq_context.os.chown")
26 @mock.patch("rabbitmq_context.pwd.getpwnam")
27 @mock.patch("rabbitmq_context.grp.getgrnam")
28 @mock.patch("rabbitmq_context.config")
29 @mock.patch("rabbitmq_context.close_port")
30 @mock.patch("rabbitmq_context.ssl_utils.reconfigure_client_ssl")
31 @mock.patch("rabbitmq_context.ssl_utils.get_ssl_mode")
32 def test_context_ssl_on(self, get_ssl_mode, reconfig_ssl, close_port,
33 config, gr, pw, chown, chmod, open_port):
34
35 get_ssl_mode.return_value = ("on", "on")
36
37 def config_get(n):
38 return None
39
40 config.side_effect = config_get
41
42 def pw(name):
43 class Uid(object):
44 pw_uid = 1
45 gr_gid = 100
46 return Uid()
47
48 pw.side_effect = pw
49 gr.side_effect = pw
50
51 m = mock.mock_open()
52 with mock.patch('rabbitmq_context.open', m, create=True):
53 self.assertEqual(
54 rabbitmq_context.RabbitMQSSLContext().__call__(), {
55 "ssl_port": None,
56 "ssl_cert_file": "/etc/rabbitmq/rabbit-server-cert.pem",
57 "ssl_key_file": '/etc/rabbitmq/rabbit-server-privkey.pem',
58 "ssl_client": False,
59 "ssl_ca_file": "",
60 "ssl_only": False,
61 "ssl_mode": "on",
62 })
63
64 reconfig_ssl.assert_called_once()
65 open_port.assert_called_once()
66
67
68class TestRabbitMQClusterContext(unittest.TestCase):
69
70 @mock.patch("rabbitmq_context.config")
71 def test_context_ssl_off(self, config):
72 config.return_value = "ignore"
73
74 self.assertEqual(
75 rabbitmq_context.RabbitMQClusterContext().__call__(), {
76 'cluster_partition_handling': "ignore"
77 })
78
79 config.assert_called_once_with("cluster-partition-handling")
080
=== modified file 'unit_tests/test_rabbitmq_server_relations.py'
--- unit_tests/test_rabbitmq_server_relations.py 2015-01-23 08:23:05 +0000
+++ unit_tests/test_rabbitmq_server_relations.py 2015-04-10 02:40:31 +0000
@@ -2,7 +2,7 @@
2from testtools import TestCase2from testtools import TestCase
3from mock import patch, MagicMock3from mock import patch, MagicMock
44
5os.environ['JUJU_UNIT_NAME'] = 'UNIT_TEST/0'5os.environ['JUJU_UNIT_NAME'] = 'UNIT_TEST/0' # noqa - needed for import
6import rabbitmq_server_relations6import rabbitmq_server_relations
77
88
@@ -37,7 +37,7 @@
37 @patch('rabbitmq_server_relations.relation_set')37 @patch('rabbitmq_server_relations.relation_set')
38 @patch('apt_pkg.Cache')38 @patch('apt_pkg.Cache')
39 @patch('rabbitmq_server_relations.is_clustered')39 @patch('rabbitmq_server_relations.is_clustered')
40 @patch('rabbitmq_server_relations.configure_client_ssl')40 @patch('rabbitmq_server_relations.ssl_utils.configure_client_ssl')
41 @patch('rabbitmq_server_relations.unit_get')41 @patch('rabbitmq_server_relations.unit_get')
42 @patch('rabbitmq_server_relations.relation_get')42 @patch('rabbitmq_server_relations.relation_get')
43 @patch('rabbitmq_server_relations.is_elected_leader')43 @patch('rabbitmq_server_relations.is_elected_leader')
@@ -87,7 +87,7 @@
87 @patch('rabbitmq_server_relations.relation_set')87 @patch('rabbitmq_server_relations.relation_set')
88 @patch('apt_pkg.Cache')88 @patch('apt_pkg.Cache')
89 @patch('rabbitmq_server_relations.is_clustered')89 @patch('rabbitmq_server_relations.is_clustered')
90 @patch('rabbitmq_server_relations.configure_client_ssl')90 @patch('rabbitmq_server_relations.ssl_utils.configure_client_ssl')
91 @patch('rabbitmq_server_relations.unit_get')91 @patch('rabbitmq_server_relations.unit_get')
92 @patch('rabbitmq_server_relations.relation_get')92 @patch('rabbitmq_server_relations.relation_get')
93 @patch('rabbitmq_server_relations.is_elected_leader')93 @patch('rabbitmq_server_relations.is_elected_leader')

Subscribers

People subscribed via source and target branches