rabbitmq_publish SSL certificate implementation (#62036)

* Implementing ability to specify certificates.

* Changelog fragment for rabbitmq_publish certificate checking

* Fixing version_added

* Reducing line size.

* Minor documentation updates.

* Update to add missing space.

Co-Authored-By: Felix Fontein <felix@fontein.de>
This commit is contained in:
John Imison 2019-11-21 07:09:06 +11:00 committed by John R Barker
parent 60d49c410d
commit 5bd06ee16e
3 changed files with 57 additions and 2 deletions

View file

@ -0,0 +1,2 @@
minor_changes:
- rabbitmq_publish - Support for connecting with SSL certificates.

View file

@ -10,9 +10,11 @@ __metaclass__ = type
from ansible.module_utils._text import to_native
from ansible.module_utils.basic import missing_required_lib
from ansible.module_utils.six.moves.urllib import parse as urllib_parse
from mimetypes import MimeTypes
import os
import json
import traceback
PIKA_IMP_ERR = None
@ -56,10 +58,16 @@ class RabbitClient():
self.vhost = self.params['vhost']
self.queue = self.params['queue']
self.headers = self.params['headers']
self.cafile = self.params['cafile']
self.certfile = self.params['certfile']
self.keyfile = self.params['keyfile']
if self.host is not None:
self.build_url()
if self.cafile is not None:
self.append_ssl_certs()
self.connect_to_rabbitmq()
def check_required_library(self):
@ -75,6 +83,17 @@ class RabbitClient():
if self.params['url'] is None and any(self.params[k] is None for k in ['proto', 'host', 'port', 'password', 'username', 'vhost']):
self.module.fail_json(msg="Connection parameters must be passed via url, or, proto, host, port, vhost, username or password.")
def append_ssl_certs(self):
ssl_options = {}
if self.cafile:
ssl_options['cafile'] = self.cafile
if self.certfile:
ssl_options['certfile'] = self.certfile
if self.keyfile:
ssl_options['keyfile'] = self.keyfile
self.url = self.url + '?ssl_options=' + urllib_parse.quote(json.dumps(ssl_options))
@staticmethod
def rabbitmq_argument_spec():
return dict(

View file

@ -88,13 +88,32 @@ options:
- A dictionary of headers to post with the message.
default: {}
type: dict
cafile:
description:
- CA file used during connection to the RabbitMQ server over SSL.
- If this option is specified, also I(certfile) and I(keyfile) must be specified.
version_added: '2.10'
certfile:
description:
- Client certificate to establish SSL connection.
- If this option is specified, also I(cafile) and I(keyfile) must be specified.
version_added: '2.10'
keyfile:
description:
- Client key to establish SSL connection.
- If this option is specified, also I(cafile) and I(certfile) must be specified.
version_added: '2.10'
requirements: [ pika ]
notes:
- This module requires the pika python library U(https://pika.readthedocs.io/).
- Pika is a pure-Python implementation of the AMQP 0-9-1 protocol that tries to stay fairly independent of the underlying network support library.
- This plugin is tested against RabbitMQ. Other AMQP 0.9.1 protocol based servers may work but not tested/guaranteed.
- This module is tested against RabbitMQ. Other AMQP 0.9.1 protocol based servers may work but not tested/guaranteed.
- The certificate authentication was tested with certificates created
via U(https://www.rabbitmq.com/ssl.html#automated-certificate-generation) and RabbitMQ
configuration variables C(ssl_options.verify = verify_peer) & C(ssl_options.fail_if_no_peer_cert = true).
author: "John Imison (@Im0)"
'''
@ -120,6 +139,17 @@ EXAMPLES = '''
url: "amqp://guest:guest@192.168.0.32:5672/%2F"
body: "Hello world random queue from ansible module rabbitmq_publish"
content_type: "text/plain"
- name: Publish with certs
rabbitmq_publish:
url: "amqps://guest:guest@192.168.0.32:5671/%2F"
body: "Hello test queue from ansible module rabbitmq_publish via SSL certs"
queue: 'test'
content_type: "text/plain"
cafile: 'ca_certificate.pem'
certfile: 'client_certificate.pem'
keyfile: 'client_key.pem'
'''
RETURN = '''
@ -155,11 +185,15 @@ def main():
durable=dict(default=False, type='bool'),
exclusive=dict(default=False, type='bool'),
auto_delete=dict(default=False, type='bool'),
headers=dict(default={}, type='dict')
headers=dict(default={}, type='dict'),
cafile=dict(type='str', required=False),
certfile=dict(type='str', required=False),
keyfile=dict(type='str', required=False),
)
module = AnsibleModule(
argument_spec=argument_spec,
mutually_exclusive=[['body', 'src']],
required_together=[['cafile', 'certfile', 'keyfile']],
supports_check_mode=False
)