mirror of
https://github.com/ansible-collections/community.general.git
synced 2024-09-14 20:13:21 +02:00
Remove rabbitmq content (#13)
This content has been moved to: https://github.com/ansible-collections/rabbitmq
This commit is contained in:
parent
1f06a02043
commit
5d47ab7096
54 changed files with 0 additions and 3854 deletions
|
@ -1,56 +0,0 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Copyright: (c) 2016, Jorge Rodriguez <jorge.rodriguez@tiriel.eu>
|
||||
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||
|
||||
|
||||
class ModuleDocFragment(object):
|
||||
# Parameters for RabbitMQ modules
|
||||
DOCUMENTATION = r'''
|
||||
options:
|
||||
login_user:
|
||||
description:
|
||||
- RabbitMQ user for connection.
|
||||
type: str
|
||||
default: guest
|
||||
login_password:
|
||||
description:
|
||||
- RabbitMQ password for connection.
|
||||
type: str
|
||||
login_host:
|
||||
description:
|
||||
- RabbitMQ host for connection.
|
||||
type: str
|
||||
default: localhost
|
||||
login_port:
|
||||
description:
|
||||
- RabbitMQ management API port.
|
||||
type: str
|
||||
default: '15672'
|
||||
login_protocol:
|
||||
description:
|
||||
- RabbitMQ management API protocol.
|
||||
type: str
|
||||
choices: [ http , https ]
|
||||
default: http
|
||||
ca_cert:
|
||||
description:
|
||||
- CA certificate to verify SSL connection to management API.
|
||||
type: path
|
||||
aliases: [ cacert ]
|
||||
client_cert:
|
||||
description:
|
||||
- Client certificate to send on SSL connections to management API.
|
||||
type: path
|
||||
aliases: [ cert ]
|
||||
client_key:
|
||||
description:
|
||||
- Private key matching the client certificate.
|
||||
type: path
|
||||
aliases: [ key ]
|
||||
vhost:
|
||||
description:
|
||||
- RabbitMQ virtual host.
|
||||
type: str
|
||||
default: "/"
|
||||
'''
|
|
@ -1,189 +0,0 @@
|
|||
# (c) 2018, John Imison <john+github@imison.net>
|
||||
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||
|
||||
from __future__ import (absolute_import, division, print_function)
|
||||
__metaclass__ = type
|
||||
|
||||
DOCUMENTATION = '''
|
||||
lookup: rabbitmq
|
||||
author: John Imison <@Im0>
|
||||
short_description: Retrieve messages from an AMQP/AMQPS RabbitMQ queue.
|
||||
description:
|
||||
- This lookup uses a basic get to retrieve all, or a limited number C(count), messages from a RabbitMQ queue.
|
||||
options:
|
||||
url:
|
||||
description:
|
||||
- An URI connection string to connect to the AMQP/AMQPS RabbitMQ server.
|
||||
- For more information refer to the URI spec U(https://www.rabbitmq.com/uri-spec.html).
|
||||
required: True
|
||||
queue:
|
||||
description:
|
||||
- The queue to get messages from.
|
||||
required: True
|
||||
count:
|
||||
description:
|
||||
- How many messages to collect from the queue.
|
||||
- If not set, defaults to retrieving all the messages from the queue.
|
||||
requirements:
|
||||
- The python pika package U(https://pypi.org/project/pika/).
|
||||
notes:
|
||||
- This lookup implements BlockingChannel.basic_get to get messages from a RabbitMQ server.
|
||||
- After retrieving a message from the server, receipt of the message is acknowledged and the message on the server is deleted.
|
||||
- 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.
|
||||
- More information about pika can be found at U(https://pika.readthedocs.io/en/stable/).
|
||||
- This plugin is tested against RabbitMQ. Other AMQP 0.9.1 protocol based servers may work but not tested/guaranteed.
|
||||
- Assigning the return messages to a variable under C(vars) may result in unexpected results as the lookup is evaluated every time the
|
||||
variable is referenced.
|
||||
- Currently this plugin only handles text based messages from a queue. Unexpected results may occur when retrieving binary data.
|
||||
'''
|
||||
|
||||
|
||||
EXAMPLES = """
|
||||
- name: Get all messages off a queue
|
||||
debug:
|
||||
msg: "{{ lookup('rabbitmq', url='amqp://guest:guest@192.168.0.10:5672/%2F', queue='hello') }}"
|
||||
|
||||
|
||||
# If you are intending on using the returned messages as a variable in more than
|
||||
# one task (eg. debug, template), it is recommended to set_fact.
|
||||
|
||||
- name: Get 2 messages off a queue and set a fact for re-use
|
||||
set_fact:
|
||||
messages: "{{ lookup('rabbitmq', url='amqp://guest:guest@192.168.0.10:5672/%2F', queue='hello', count=2) }}"
|
||||
|
||||
- name: Dump out contents of the messages
|
||||
debug:
|
||||
var: messages
|
||||
|
||||
"""
|
||||
|
||||
RETURN = """
|
||||
_list:
|
||||
description:
|
||||
- A list of dictionaries with keys and value from the queue.
|
||||
type: list
|
||||
contains:
|
||||
content_type:
|
||||
description: The content_type on the message in the queue.
|
||||
type: str
|
||||
delivery_mode:
|
||||
description: The delivery_mode on the message in the queue.
|
||||
type: str
|
||||
delivery_tag:
|
||||
description: The delivery_tag on the message in the queue.
|
||||
type: str
|
||||
exchange:
|
||||
description: The exchange the message came from.
|
||||
type: str
|
||||
message_count:
|
||||
description: The message_count for the message on the queue.
|
||||
type: str
|
||||
msg:
|
||||
description: The content of the message.
|
||||
type: str
|
||||
redelivered:
|
||||
description: The redelivered flag. True if the message has been delivered before.
|
||||
type: bool
|
||||
routing_key:
|
||||
description: The routing_key on the message in the queue.
|
||||
type: str
|
||||
headers:
|
||||
description: The headers for the message returned from the queue.
|
||||
type: dict
|
||||
json:
|
||||
description: If application/json is specified in content_type, json will be loaded into variables.
|
||||
type: dict
|
||||
|
||||
"""
|
||||
|
||||
import json
|
||||
|
||||
from ansible.errors import AnsibleError, AnsibleParserError
|
||||
from ansible.plugins.lookup import LookupBase
|
||||
from ansible.module_utils._text import to_native, to_text
|
||||
from ansible.utils.display import Display
|
||||
|
||||
try:
|
||||
import pika
|
||||
from pika import spec
|
||||
HAS_PIKA = True
|
||||
except ImportError:
|
||||
HAS_PIKA = False
|
||||
|
||||
display = Display()
|
||||
|
||||
|
||||
class LookupModule(LookupBase):
|
||||
|
||||
def run(self, terms, variables=None, url=None, queue=None, count=None):
|
||||
if not HAS_PIKA:
|
||||
raise AnsibleError('pika python package is required for rabbitmq lookup.')
|
||||
if not url:
|
||||
raise AnsibleError('URL is required for rabbitmq lookup.')
|
||||
if not queue:
|
||||
raise AnsibleError('Queue is required for rabbitmq lookup.')
|
||||
|
||||
display.vvv(u"terms:%s : variables:%s url:%s queue:%s count:%s" % (terms, variables, url, queue, count))
|
||||
|
||||
try:
|
||||
parameters = pika.URLParameters(url)
|
||||
except Exception as e:
|
||||
raise AnsibleError("URL malformed: %s" % to_native(e))
|
||||
|
||||
try:
|
||||
connection = pika.BlockingConnection(parameters)
|
||||
except Exception as e:
|
||||
raise AnsibleError("Connection issue: %s" % to_native(e))
|
||||
|
||||
try:
|
||||
conn_channel = connection.channel()
|
||||
except pika.exceptions.AMQPChannelError as e:
|
||||
try:
|
||||
connection.close()
|
||||
except pika.exceptions.AMQPConnectionError as ie:
|
||||
raise AnsibleError("Channel and connection closing issues: %s / %s" % to_native(e), to_native(ie))
|
||||
raise AnsibleError("Channel issue: %s" % to_native(e))
|
||||
|
||||
ret = []
|
||||
idx = 0
|
||||
|
||||
while True:
|
||||
method_frame, properties, body = conn_channel.basic_get(queue=queue)
|
||||
if method_frame:
|
||||
display.vvv(u"%s, %s, %s " % (method_frame, properties, to_text(body)))
|
||||
|
||||
# TODO: In the future consider checking content_type and handle text/binary data differently.
|
||||
msg_details = dict({
|
||||
'msg': to_text(body),
|
||||
'message_count': method_frame.message_count,
|
||||
'routing_key': method_frame.routing_key,
|
||||
'delivery_tag': method_frame.delivery_tag,
|
||||
'redelivered': method_frame.redelivered,
|
||||
'exchange': method_frame.exchange,
|
||||
'delivery_mode': properties.delivery_mode,
|
||||
'content_type': properties.content_type,
|
||||
'headers': properties.headers
|
||||
})
|
||||
if properties.content_type == 'application/json':
|
||||
try:
|
||||
msg_details['json'] = json.loads(msg_details['msg'])
|
||||
except ValueError as e:
|
||||
raise AnsibleError("Unable to decode JSON for message %s: %s" % (method_frame.delivery_tag, to_native(e)))
|
||||
|
||||
ret.append(msg_details)
|
||||
conn_channel.basic_ack(method_frame.delivery_tag)
|
||||
idx += 1
|
||||
if method_frame.message_count == 0 or idx == count:
|
||||
break
|
||||
# If we didn't get a method_frame, exit.
|
||||
else:
|
||||
break
|
||||
|
||||
if connection.is_closed:
|
||||
return [ret]
|
||||
else:
|
||||
try:
|
||||
connection.close()
|
||||
except pika.exceptions.AMQPConnectionError:
|
||||
pass
|
||||
return [ret]
|
|
@ -1,220 +0,0 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Copyright: (c) 2016, Jorge Rodriguez <jorge.rodriguez@tiriel.eu>
|
||||
# Copyright: (c) 2018, John Imison <john+github@imison.net>
|
||||
#
|
||||
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||
|
||||
from __future__ import absolute_import, division, print_function
|
||||
__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
|
||||
try:
|
||||
import pika
|
||||
import pika.exceptions
|
||||
from pika import spec
|
||||
HAS_PIKA = True
|
||||
except ImportError:
|
||||
PIKA_IMP_ERR = traceback.format_exc()
|
||||
HAS_PIKA = False
|
||||
|
||||
|
||||
def rabbitmq_argument_spec():
|
||||
return dict(
|
||||
login_user=dict(type='str', default='guest'),
|
||||
login_password=dict(type='str', default='guest', no_log=True),
|
||||
login_host=dict(type='str', default='localhost'),
|
||||
login_port=dict(type='str', default='15672'),
|
||||
login_protocol=dict(type='str', default='http', choices=['http', 'https']),
|
||||
ca_cert=dict(type='path', aliases=['cacert']),
|
||||
client_cert=dict(type='path', aliases=['cert']),
|
||||
client_key=dict(type='path', aliases=['key']),
|
||||
vhost=dict(type='str', default='/'),
|
||||
)
|
||||
|
||||
|
||||
# notification/rabbitmq_basic_publish.py
|
||||
class RabbitClient():
|
||||
def __init__(self, module):
|
||||
self.module = module
|
||||
self.params = module.params
|
||||
self.check_required_library()
|
||||
self.check_host_params()
|
||||
self.url = self.params['url']
|
||||
self.proto = self.params['proto']
|
||||
self.username = self.params['username']
|
||||
self.password = self.params['password']
|
||||
self.host = self.params['host']
|
||||
self.port = self.params['port']
|
||||
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):
|
||||
if not HAS_PIKA:
|
||||
self.module.fail_json(msg=missing_required_lib("pika"), exception=PIKA_IMP_ERR)
|
||||
|
||||
def check_host_params(self):
|
||||
# Fail if url is specified and other conflicting parameters have been specified
|
||||
if self.params['url'] is not None and any(self.params[k] is not None for k in ['proto', 'host', 'port', 'password', 'username', 'vhost']):
|
||||
self.module.fail_json(msg="url and proto, host, port, vhost, username or password cannot be specified at the same time.")
|
||||
|
||||
# Fail if url not specified and there is a missing parameter to build the url
|
||||
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(
|
||||
url=dict(type='str'),
|
||||
proto=dict(type='str', choices=['amqp', 'amqps']),
|
||||
host=dict(type='str'),
|
||||
port=dict(type='int'),
|
||||
username=dict(type='str'),
|
||||
password=dict(type='str', no_log=True),
|
||||
vhost=dict(type='str'),
|
||||
queue=dict(type='str')
|
||||
)
|
||||
|
||||
''' Consider some file size limits here '''
|
||||
def _read_file(self, path):
|
||||
try:
|
||||
with open(path, "rb") as file_handle:
|
||||
return file_handle.read()
|
||||
except IOError as e:
|
||||
self.module.fail_json(msg="Unable to open file %s: %s" % (path, to_native(e)))
|
||||
|
||||
@staticmethod
|
||||
def _check_file_mime_type(path):
|
||||
mime = MimeTypes()
|
||||
return mime.guess_type(path)
|
||||
|
||||
def build_url(self):
|
||||
self.url = '{0}://{1}:{2}@{3}:{4}/{5}'.format(self.proto,
|
||||
self.username,
|
||||
self.password,
|
||||
self.host,
|
||||
self.port,
|
||||
self.vhost)
|
||||
|
||||
def connect_to_rabbitmq(self):
|
||||
"""
|
||||
Function to connect to rabbitmq using username and password
|
||||
"""
|
||||
try:
|
||||
parameters = pika.URLParameters(self.url)
|
||||
except Exception as e:
|
||||
self.module.fail_json(msg="URL malformed: %s" % to_native(e))
|
||||
|
||||
try:
|
||||
self.connection = pika.BlockingConnection(parameters)
|
||||
except Exception as e:
|
||||
self.module.fail_json(msg="Connection issue: %s" % to_native(e))
|
||||
|
||||
try:
|
||||
self.conn_channel = self.connection.channel()
|
||||
except pika.exceptions.AMQPChannelError as e:
|
||||
self.close_connection()
|
||||
self.module.fail_json(msg="Channel issue: %s" % to_native(e))
|
||||
|
||||
def close_connection(self):
|
||||
try:
|
||||
self.connection.close()
|
||||
except pika.exceptions.AMQPConnectionError:
|
||||
pass
|
||||
|
||||
def basic_publish(self):
|
||||
self.content_type = self.params.get("content_type")
|
||||
|
||||
if self.params.get("body") is not None:
|
||||
args = dict(
|
||||
body=self.params.get("body"),
|
||||
exchange=self.params.get("exchange"),
|
||||
routing_key=self.params.get("routing_key"),
|
||||
properties=pika.BasicProperties(content_type=self.content_type, delivery_mode=1, headers=self.headers))
|
||||
|
||||
# If src (file) is defined and content_type is left as default, do a mime lookup on the file
|
||||
if self.params.get("src") is not None and self.content_type == 'text/plain':
|
||||
self.content_type = RabbitClient._check_file_mime_type(self.params.get("src"))[0]
|
||||
self.headers.update(
|
||||
filename=os.path.basename(self.params.get("src"))
|
||||
)
|
||||
|
||||
args = dict(
|
||||
body=self._read_file(self.params.get("src")),
|
||||
exchange=self.params.get("exchange"),
|
||||
routing_key=self.params.get("routing_key"),
|
||||
properties=pika.BasicProperties(content_type=self.content_type,
|
||||
delivery_mode=1,
|
||||
headers=self.headers
|
||||
))
|
||||
elif self.params.get("src") is not None:
|
||||
args = dict(
|
||||
body=self._read_file(self.params.get("src")),
|
||||
exchange=self.params.get("exchange"),
|
||||
routing_key=self.params.get("routing_key"),
|
||||
properties=pika.BasicProperties(content_type=self.content_type,
|
||||
delivery_mode=1,
|
||||
headers=self.headers
|
||||
))
|
||||
|
||||
try:
|
||||
# If queue is not defined, RabbitMQ will return the queue name of the automatically generated queue.
|
||||
if self.queue is None:
|
||||
result = self.conn_channel.queue_declare(durable=self.params.get("durable"),
|
||||
exclusive=self.params.get("exclusive"),
|
||||
auto_delete=self.params.get("auto_delete"))
|
||||
self.conn_channel.confirm_delivery()
|
||||
self.queue = result.method.queue
|
||||
else:
|
||||
self.conn_channel.queue_declare(queue=self.queue,
|
||||
durable=self.params.get("durable"),
|
||||
exclusive=self.params.get("exclusive"),
|
||||
auto_delete=self.params.get("auto_delete"))
|
||||
self.conn_channel.confirm_delivery()
|
||||
except Exception as e:
|
||||
self.module.fail_json(msg="Queue declare issue: %s" % to_native(e))
|
||||
|
||||
# https://github.com/ansible/ansible/blob/devel/lib/ansible/module_utils/cloudstack.py#L150
|
||||
if args['routing_key'] is None:
|
||||
args['routing_key'] = self.queue
|
||||
|
||||
if args['exchange'] is None:
|
||||
args['exchange'] = ''
|
||||
|
||||
try:
|
||||
self.conn_channel.basic_publish(**args)
|
||||
return True
|
||||
except pika.exceptions.UnroutableError:
|
||||
return False
|
|
@ -1,297 +0,0 @@
|
|||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Copyright: (c) 2015, Manuel Sousa <manuel.sousa@gmail.com>
|
||||
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||
|
||||
from __future__ import absolute_import, division, print_function
|
||||
__metaclass__ = type
|
||||
|
||||
ANSIBLE_METADATA = {
|
||||
'metadata_version': '1.1',
|
||||
'status': ['preview'],
|
||||
'supported_by': 'community'
|
||||
}
|
||||
|
||||
DOCUMENTATION = '''
|
||||
---
|
||||
module: rabbitmq_binding
|
||||
author: Manuel Sousa (@manuel-sousa)
|
||||
|
||||
short_description: Manage rabbitMQ bindings
|
||||
description:
|
||||
- This module uses rabbitMQ REST APIs to create / delete bindings.
|
||||
requirements: [ "requests >= 1.0.0" ]
|
||||
options:
|
||||
state:
|
||||
description:
|
||||
- Whether the bindings should be present or absent.
|
||||
choices: [ "present", "absent" ]
|
||||
default: present
|
||||
name:
|
||||
description:
|
||||
- source exchange to create binding on.
|
||||
required: true
|
||||
aliases: [ "src", "source" ]
|
||||
destination:
|
||||
description:
|
||||
- destination exchange or queue for the binding.
|
||||
required: true
|
||||
aliases: [ "dst", "dest" ]
|
||||
destination_type:
|
||||
description:
|
||||
- Either queue or exchange.
|
||||
required: true
|
||||
choices: [ "queue", "exchange" ]
|
||||
aliases: [ "type", "dest_type" ]
|
||||
routing_key:
|
||||
description:
|
||||
- routing key for the binding.
|
||||
default: "#"
|
||||
arguments:
|
||||
description:
|
||||
- extra arguments for exchange. If defined this argument is a key/value dictionary
|
||||
required: false
|
||||
default: {}
|
||||
extends_documentation_fragment:
|
||||
- community.general.rabbitmq
|
||||
|
||||
'''
|
||||
|
||||
EXAMPLES = '''
|
||||
# Bind myQueue to directExchange with routing key info
|
||||
- rabbitmq_binding:
|
||||
name: directExchange
|
||||
destination: myQueue
|
||||
type: queue
|
||||
routing_key: info
|
||||
|
||||
# Bind directExchange to topicExchange with routing key *.info
|
||||
- rabbitmq_binding:
|
||||
name: topicExchange
|
||||
destination: topicExchange
|
||||
type: exchange
|
||||
routing_key: '*.info'
|
||||
'''
|
||||
|
||||
import json
|
||||
import traceback
|
||||
|
||||
REQUESTS_IMP_ERR = None
|
||||
try:
|
||||
import requests
|
||||
HAS_REQUESTS = True
|
||||
except ImportError:
|
||||
REQUESTS_IMP_ERR = traceback.format_exc()
|
||||
HAS_REQUESTS = False
|
||||
|
||||
from ansible.module_utils.six.moves.urllib import parse as urllib_parse
|
||||
from ansible.module_utils.basic import AnsibleModule, missing_required_lib
|
||||
from ansible_collections.community.general.plugins.module_utils.rabbitmq import rabbitmq_argument_spec
|
||||
|
||||
|
||||
class RabbitMqBinding(object):
|
||||
def __init__(self, module):
|
||||
"""
|
||||
:param module:
|
||||
"""
|
||||
self.module = module
|
||||
self.name = self.module.params['name']
|
||||
self.login_user = self.module.params['login_user']
|
||||
self.login_password = self.module.params['login_password']
|
||||
self.login_host = self.module.params['login_host']
|
||||
self.login_port = self.module.params['login_port']
|
||||
self.login_protocol = self.module.params['login_protocol']
|
||||
self.vhost = self.module.params['vhost']
|
||||
self.destination = self.module.params['destination']
|
||||
self.destination_type = 'q' if self.module.params['destination_type'] == 'queue' else 'e'
|
||||
self.routing_key = self.module.params['routing_key']
|
||||
self.arguments = self.module.params['arguments']
|
||||
self.verify = self.module.params['ca_cert']
|
||||
self.cert = self.module.params['client_cert']
|
||||
self.key = self.module.params['client_key']
|
||||
self.props = urllib_parse.quote(self.routing_key) if self.routing_key != '' else '~'
|
||||
self.base_url = '{0}://{1}:{2}/api/bindings'.format(self.login_protocol,
|
||||
self.login_host,
|
||||
self.login_port)
|
||||
self.url = '{0}/{1}/e/{2}/{3}/{4}/{5}'.format(self.base_url,
|
||||
urllib_parse.quote(self.vhost, safe=''),
|
||||
urllib_parse.quote(self.name, safe=''),
|
||||
self.destination_type,
|
||||
urllib_parse.quote(self.destination, safe=''),
|
||||
self.props)
|
||||
self.result = {
|
||||
'changed': False,
|
||||
'name': self.module.params['name'],
|
||||
}
|
||||
self.authentication = (
|
||||
self.login_user,
|
||||
self.login_password
|
||||
)
|
||||
self.request = requests
|
||||
self.http_check_states = {
|
||||
200: True,
|
||||
404: False,
|
||||
}
|
||||
self.http_actionable_states = {
|
||||
201: True,
|
||||
204: True,
|
||||
}
|
||||
self.api_result = self.request.get(self.url, auth=self.authentication, verify=self.verify, cert=(self.cert, self.key))
|
||||
|
||||
def run(self):
|
||||
"""
|
||||
:return:
|
||||
"""
|
||||
self.check_presence()
|
||||
self.check_mode()
|
||||
self.action_mode()
|
||||
|
||||
def check_presence(self):
|
||||
"""
|
||||
:return:
|
||||
"""
|
||||
if self.check_should_throw_fail():
|
||||
self.fail()
|
||||
|
||||
def change_required(self):
|
||||
"""
|
||||
:return:
|
||||
"""
|
||||
if self.module.params['state'] == 'present':
|
||||
if not self.is_present():
|
||||
return True
|
||||
elif self.module.params['state'] == 'absent':
|
||||
if self.is_present():
|
||||
return True
|
||||
return False
|
||||
|
||||
def is_present(self):
|
||||
"""
|
||||
:return:
|
||||
"""
|
||||
return self.http_check_states.get(self.api_result.status_code, False)
|
||||
|
||||
def check_mode(self):
|
||||
"""
|
||||
:return:
|
||||
"""
|
||||
if self.module.check_mode:
|
||||
result = self.result
|
||||
result['changed'] = self.change_required()
|
||||
result['details'] = self.api_result.json() if self.is_present() else self.api_result.text
|
||||
result['arguments'] = self.module.params['arguments']
|
||||
self.module.exit_json(**result)
|
||||
|
||||
def check_reply_is_correct(self):
|
||||
"""
|
||||
:return:
|
||||
"""
|
||||
if self.api_result.status_code in self.http_check_states:
|
||||
return True
|
||||
return False
|
||||
|
||||
def check_should_throw_fail(self):
|
||||
"""
|
||||
:return:
|
||||
"""
|
||||
if not self.is_present():
|
||||
if not self.check_reply_is_correct():
|
||||
return True
|
||||
return False
|
||||
|
||||
def action_mode(self):
|
||||
"""
|
||||
:return:
|
||||
"""
|
||||
result = self.result
|
||||
if self.change_required():
|
||||
if self.module.params['state'] == 'present':
|
||||
self.create()
|
||||
if self.module.params['state'] == 'absent':
|
||||
self.remove()
|
||||
if self.action_should_throw_fail():
|
||||
self.fail()
|
||||
result['changed'] = True
|
||||
result['destination'] = self.module.params['destination']
|
||||
self.module.exit_json(**result)
|
||||
else:
|
||||
result['changed'] = False
|
||||
self.module.exit_json(**result)
|
||||
|
||||
def action_reply_is_correct(self):
|
||||
"""
|
||||
:return:
|
||||
"""
|
||||
if self.api_result.status_code in self.http_actionable_states:
|
||||
return True
|
||||
return False
|
||||
|
||||
def action_should_throw_fail(self):
|
||||
"""
|
||||
:return:
|
||||
"""
|
||||
if not self.action_reply_is_correct():
|
||||
return True
|
||||
return False
|
||||
|
||||
def create(self):
|
||||
"""
|
||||
:return:
|
||||
"""
|
||||
self.url = '{0}/{1}/e/{2}/{3}/{4}'.format(self.base_url,
|
||||
urllib_parse.quote(self.vhost, safe=''),
|
||||
urllib_parse.quote(self.name, safe=''),
|
||||
self.destination_type,
|
||||
urllib_parse.quote(self.destination, safe=''))
|
||||
self.api_result = self.request.post(self.url,
|
||||
auth=self.authentication,
|
||||
verify=self.verify,
|
||||
cert=(self.cert, self.key),
|
||||
headers={"content-type": "application/json"},
|
||||
data=json.dumps({
|
||||
'routing_key': self.routing_key,
|
||||
'arguments': self.arguments
|
||||
}))
|
||||
|
||||
def remove(self):
|
||||
"""
|
||||
:return:
|
||||
"""
|
||||
self.api_result = self.request.delete(self.url, auth=self.authentication, verify=self.verify, cert=(self.cert, self.key))
|
||||
|
||||
def fail(self):
|
||||
"""
|
||||
:return:
|
||||
"""
|
||||
self.module.fail_json(
|
||||
msg="Unexpected reply from API",
|
||||
status=self.api_result.status_code,
|
||||
details=self.api_result.text
|
||||
)
|
||||
|
||||
|
||||
def main():
|
||||
|
||||
argument_spec = rabbitmq_argument_spec()
|
||||
argument_spec.update(
|
||||
dict(
|
||||
state=dict(default='present', choices=['present', 'absent'], type='str'),
|
||||
name=dict(required=True, aliases=["src", "source"], type='str'),
|
||||
destination=dict(required=True, aliases=["dst", "dest"], type='str'),
|
||||
destination_type=dict(required=True, aliases=["type", "dest_type"], choices=["queue", "exchange"],
|
||||
type='str'),
|
||||
routing_key=dict(default='#', type='str'),
|
||||
arguments=dict(default=dict(), type='dict')
|
||||
)
|
||||
)
|
||||
module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=True)
|
||||
|
||||
if not HAS_REQUESTS:
|
||||
module.fail_json(msg=missing_required_lib("requests"), exception=REQUESTS_IMP_ERR)
|
||||
|
||||
RabbitMqBinding(module).run()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
|
@ -1,208 +0,0 @@
|
|||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Copyright: (c) 2015, Manuel Sousa <manuel.sousa@gmail.com>
|
||||
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||
|
||||
from __future__ import absolute_import, division, print_function
|
||||
__metaclass__ = type
|
||||
|
||||
|
||||
ANSIBLE_METADATA = {'metadata_version': '1.1',
|
||||
'status': ['preview'],
|
||||
'supported_by': 'community'}
|
||||
|
||||
|
||||
DOCUMENTATION = '''
|
||||
---
|
||||
module: rabbitmq_exchange
|
||||
author: Manuel Sousa (@manuel-sousa)
|
||||
|
||||
short_description: Manage rabbitMQ exchanges
|
||||
description:
|
||||
- This module uses rabbitMQ Rest API to create/delete exchanges
|
||||
requirements: [ "requests >= 1.0.0" ]
|
||||
options:
|
||||
name:
|
||||
description:
|
||||
- Name of the exchange to create
|
||||
required: true
|
||||
state:
|
||||
description:
|
||||
- Whether the exchange should be present or absent
|
||||
choices: [ "present", "absent" ]
|
||||
required: false
|
||||
default: present
|
||||
durable:
|
||||
description:
|
||||
- whether exchange is durable or not
|
||||
required: false
|
||||
type: bool
|
||||
default: yes
|
||||
exchange_type:
|
||||
description:
|
||||
- type for the exchange
|
||||
required: false
|
||||
choices: [ "fanout", "direct", "headers", "topic" ]
|
||||
aliases: [ "type" ]
|
||||
default: direct
|
||||
auto_delete:
|
||||
description:
|
||||
- if the exchange should delete itself after all queues/exchanges unbound from it
|
||||
required: false
|
||||
type: bool
|
||||
default: no
|
||||
internal:
|
||||
description:
|
||||
- exchange is available only for other exchanges
|
||||
required: false
|
||||
type: bool
|
||||
default: no
|
||||
arguments:
|
||||
description:
|
||||
- extra arguments for exchange. If defined this argument is a key/value dictionary
|
||||
required: false
|
||||
default: {}
|
||||
extends_documentation_fragment:
|
||||
- community.general.rabbitmq
|
||||
|
||||
'''
|
||||
|
||||
EXAMPLES = '''
|
||||
# Create direct exchange
|
||||
- rabbitmq_exchange:
|
||||
name: directExchange
|
||||
|
||||
# Create topic exchange on vhost
|
||||
- rabbitmq_exchange:
|
||||
name: topicExchange
|
||||
type: topic
|
||||
vhost: myVhost
|
||||
'''
|
||||
|
||||
import json
|
||||
import traceback
|
||||
|
||||
REQUESTS_IMP_ERR = None
|
||||
try:
|
||||
import requests
|
||||
HAS_REQUESTS = True
|
||||
except ImportError:
|
||||
REQUESTS_IMP_ERR = traceback.format_exc()
|
||||
HAS_REQUESTS = False
|
||||
|
||||
from ansible.module_utils.basic import AnsibleModule, missing_required_lib
|
||||
from ansible.module_utils.six.moves.urllib import parse as urllib_parse
|
||||
from ansible_collections.community.general.plugins.module_utils.rabbitmq import rabbitmq_argument_spec
|
||||
|
||||
|
||||
def main():
|
||||
|
||||
argument_spec = rabbitmq_argument_spec()
|
||||
argument_spec.update(
|
||||
dict(
|
||||
state=dict(default='present', choices=['present', 'absent'], type='str'),
|
||||
name=dict(required=True, type='str'),
|
||||
durable=dict(default=True, type='bool'),
|
||||
auto_delete=dict(default=False, type='bool'),
|
||||
internal=dict(default=False, type='bool'),
|
||||
exchange_type=dict(default='direct', aliases=['type'], type='str'),
|
||||
arguments=dict(default=dict(), type='dict')
|
||||
)
|
||||
)
|
||||
module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=True)
|
||||
|
||||
url = "%s://%s:%s/api/exchanges/%s/%s" % (
|
||||
module.params['login_protocol'],
|
||||
module.params['login_host'],
|
||||
module.params['login_port'],
|
||||
urllib_parse.quote(module.params['vhost'], ''),
|
||||
urllib_parse.quote(module.params['name'], '')
|
||||
)
|
||||
|
||||
if not HAS_REQUESTS:
|
||||
module.fail_json(msg=missing_required_lib("requests"), exception=REQUESTS_IMP_ERR)
|
||||
|
||||
result = dict(changed=False, name=module.params['name'])
|
||||
|
||||
# Check if exchange already exists
|
||||
r = requests.get(url, auth=(module.params['login_user'], module.params['login_password']),
|
||||
verify=module.params['ca_cert'], cert=(module.params['client_cert'], module.params['client_key']))
|
||||
|
||||
if r.status_code == 200:
|
||||
exchange_exists = True
|
||||
response = r.json()
|
||||
elif r.status_code == 404:
|
||||
exchange_exists = False
|
||||
response = r.text
|
||||
else:
|
||||
module.fail_json(
|
||||
msg="Invalid response from RESTAPI when trying to check if exchange exists",
|
||||
details=r.text
|
||||
)
|
||||
|
||||
if module.params['state'] == 'present':
|
||||
change_required = not exchange_exists
|
||||
else:
|
||||
change_required = exchange_exists
|
||||
|
||||
# Check if attributes change on existing exchange
|
||||
if not change_required and r.status_code == 200 and module.params['state'] == 'present':
|
||||
if not (
|
||||
response['durable'] == module.params['durable'] and
|
||||
response['auto_delete'] == module.params['auto_delete'] and
|
||||
response['internal'] == module.params['internal'] and
|
||||
response['type'] == module.params['exchange_type']
|
||||
):
|
||||
module.fail_json(
|
||||
msg="RabbitMQ RESTAPI doesn't support attribute changes for existing exchanges"
|
||||
)
|
||||
|
||||
# Exit if check_mode
|
||||
if module.check_mode:
|
||||
result['changed'] = change_required
|
||||
result['details'] = response
|
||||
result['arguments'] = module.params['arguments']
|
||||
module.exit_json(**result)
|
||||
|
||||
# Do changes
|
||||
if change_required:
|
||||
if module.params['state'] == 'present':
|
||||
r = requests.put(
|
||||
url,
|
||||
auth=(module.params['login_user'], module.params['login_password']),
|
||||
headers={"content-type": "application/json"},
|
||||
data=json.dumps({
|
||||
"durable": module.params['durable'],
|
||||
"auto_delete": module.params['auto_delete'],
|
||||
"internal": module.params['internal'],
|
||||
"type": module.params['exchange_type'],
|
||||
"arguments": module.params['arguments']
|
||||
}),
|
||||
verify=module.params['ca_cert'],
|
||||
cert=(module.params['client_cert'], module.params['client_key'])
|
||||
)
|
||||
elif module.params['state'] == 'absent':
|
||||
r = requests.delete(url, auth=(module.params['login_user'], module.params['login_password']),
|
||||
verify=module.params['ca_cert'], cert=(module.params['client_cert'], module.params['client_key']))
|
||||
|
||||
# RabbitMQ 3.6.7 changed this response code from 204 to 201
|
||||
if r.status_code == 204 or r.status_code == 201:
|
||||
result['changed'] = True
|
||||
module.exit_json(**result)
|
||||
else:
|
||||
module.fail_json(
|
||||
msg="Error creating exchange",
|
||||
status=r.status_code,
|
||||
details=r.text
|
||||
)
|
||||
|
||||
else:
|
||||
module.exit_json(
|
||||
changed=False,
|
||||
name=module.params['name']
|
||||
)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
|
@ -1,156 +0,0 @@
|
|||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Copyright: (c) 2013, Chatham Financial <oss@chathamfinancial.com>
|
||||
# Copyright: (c) 2017, Juergen Kirschbaum <jk@jk-itc.de>
|
||||
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||
|
||||
from __future__ import absolute_import, division, print_function
|
||||
__metaclass__ = type
|
||||
|
||||
|
||||
ANSIBLE_METADATA = {'metadata_version': '1.1',
|
||||
'status': ['preview'],
|
||||
'supported_by': 'community'}
|
||||
|
||||
|
||||
DOCUMENTATION = '''
|
||||
---
|
||||
module: rabbitmq_global_parameter
|
||||
short_description: Manage RabbitMQ global parameters
|
||||
description:
|
||||
- Manage dynamic, cluster-wide global parameters for RabbitMQ
|
||||
author: "Juergen Kirschbaum (@jgkirschbaum)"
|
||||
options:
|
||||
name:
|
||||
description:
|
||||
- Name of the global parameter being set
|
||||
required: true
|
||||
default: null
|
||||
value:
|
||||
description:
|
||||
- Value of the global parameter, as a JSON term
|
||||
required: false
|
||||
default: null
|
||||
node:
|
||||
description:
|
||||
- erlang node name of the rabbit we wish to configure
|
||||
required: false
|
||||
default: rabbit
|
||||
state:
|
||||
description:
|
||||
- Specify if user is to be added or removed
|
||||
required: false
|
||||
default: present
|
||||
choices: [ 'present', 'absent']
|
||||
'''
|
||||
|
||||
EXAMPLES = '''
|
||||
# Set the global parameter 'cluster_name' to a value of 'mq-cluster' (in quotes)
|
||||
- rabbitmq_global_parameter:
|
||||
name: cluster_name
|
||||
value: "{{ 'mq-cluster' | to_json }}"
|
||||
state: present
|
||||
'''
|
||||
|
||||
RETURN = '''
|
||||
name:
|
||||
description: name of the global parameter being set
|
||||
returned: success
|
||||
type: str
|
||||
sample: "cluster_name"
|
||||
value:
|
||||
description: value of the global parameter, as a JSON term
|
||||
returned: changed
|
||||
type: str
|
||||
sample: "the-cluster-name"
|
||||
'''
|
||||
|
||||
import json
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
|
||||
|
||||
class RabbitMqGlobalParameter(object):
|
||||
def __init__(self, module, name, value, node):
|
||||
self.module = module
|
||||
self.name = name
|
||||
self.value = value
|
||||
self.node = node
|
||||
|
||||
self._value = None
|
||||
|
||||
self._rabbitmqctl = module.get_bin_path('rabbitmqctl', True)
|
||||
|
||||
def _exec(self, args, run_in_check_mode=False):
|
||||
if not self.module.check_mode or (self.module.check_mode and run_in_check_mode):
|
||||
cmd = [self._rabbitmqctl, '-q', '-n', self.node]
|
||||
rc, out, err = self.module.run_command(cmd + args, check_rc=True)
|
||||
return out.splitlines()
|
||||
return list()
|
||||
|
||||
def get(self):
|
||||
global_parameters = self._exec(['list_global_parameters'], True)
|
||||
|
||||
for param_item in global_parameters:
|
||||
name, value = param_item.split('\t')
|
||||
|
||||
if name == self.name:
|
||||
self._value = json.loads(value)
|
||||
return True
|
||||
return False
|
||||
|
||||
def set(self):
|
||||
self._exec(['set_global_parameter',
|
||||
self.name,
|
||||
json.dumps(self.value)])
|
||||
|
||||
def delete(self):
|
||||
self._exec(['clear_global_parameter', self.name])
|
||||
|
||||
def has_modifications(self):
|
||||
return self.value != self._value
|
||||
|
||||
|
||||
def main():
|
||||
arg_spec = dict(
|
||||
name=dict(type='str', required=True),
|
||||
value=dict(type='str', default=None),
|
||||
state=dict(default='present', choices=['present', 'absent']),
|
||||
node=dict(type='str', default='rabbit')
|
||||
)
|
||||
module = AnsibleModule(
|
||||
argument_spec=arg_spec,
|
||||
supports_check_mode=True
|
||||
)
|
||||
|
||||
name = module.params['name']
|
||||
value = module.params['value']
|
||||
if isinstance(value, str):
|
||||
value = json.loads(value)
|
||||
state = module.params['state']
|
||||
node = module.params['node']
|
||||
|
||||
result = dict(changed=False)
|
||||
rabbitmq_global_parameter = RabbitMqGlobalParameter(module, name, value, node)
|
||||
|
||||
if rabbitmq_global_parameter.get():
|
||||
if state == 'absent':
|
||||
rabbitmq_global_parameter.delete()
|
||||
result['changed'] = True
|
||||
else:
|
||||
if rabbitmq_global_parameter.has_modifications():
|
||||
rabbitmq_global_parameter.set()
|
||||
result['changed'] = True
|
||||
elif state == 'present':
|
||||
rabbitmq_global_parameter.set()
|
||||
result['changed'] = True
|
||||
|
||||
result['name'] = name
|
||||
result['value'] = value
|
||||
result['state'] = state
|
||||
|
||||
module.exit_json(**result)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
|
@ -1,154 +0,0 @@
|
|||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Copyright: (c) 2013, Chatham Financial <oss@chathamfinancial.com>
|
||||
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||
|
||||
from __future__ import absolute_import, division, print_function
|
||||
__metaclass__ = type
|
||||
|
||||
|
||||
ANSIBLE_METADATA = {'metadata_version': '1.1',
|
||||
'status': ['preview'],
|
||||
'supported_by': 'community'}
|
||||
|
||||
|
||||
DOCUMENTATION = '''
|
||||
---
|
||||
module: rabbitmq_parameter
|
||||
short_description: Manage RabbitMQ parameters
|
||||
description:
|
||||
- Manage dynamic, cluster-wide parameters for RabbitMQ
|
||||
author: Chris Hoffman (@chrishoffman)
|
||||
options:
|
||||
component:
|
||||
description:
|
||||
- Name of the component of which the parameter is being set
|
||||
required: true
|
||||
name:
|
||||
description:
|
||||
- Name of the parameter being set
|
||||
required: true
|
||||
value:
|
||||
description:
|
||||
- Value of the parameter, as a JSON term
|
||||
vhost:
|
||||
description:
|
||||
- vhost to apply access privileges.
|
||||
default: /
|
||||
node:
|
||||
description:
|
||||
- erlang node name of the rabbit we wish to configure
|
||||
default: rabbit
|
||||
state:
|
||||
description:
|
||||
- Specify if user is to be added or removed
|
||||
default: present
|
||||
choices: [ 'present', 'absent']
|
||||
'''
|
||||
|
||||
EXAMPLES = """
|
||||
# Set the federation parameter 'local_username' to a value of 'guest' (in quotes)
|
||||
- rabbitmq_parameter:
|
||||
component: federation
|
||||
name: local-username
|
||||
value: '"guest"'
|
||||
state: present
|
||||
"""
|
||||
import json
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
|
||||
|
||||
class RabbitMqParameter(object):
|
||||
def __init__(self, module, component, name, value, vhost, node):
|
||||
self.module = module
|
||||
self.component = component
|
||||
self.name = name
|
||||
self.value = value
|
||||
self.vhost = vhost
|
||||
self.node = node
|
||||
|
||||
self._value = None
|
||||
|
||||
self._rabbitmqctl = module.get_bin_path('rabbitmqctl', True)
|
||||
|
||||
def _exec(self, args, run_in_check_mode=False):
|
||||
if not self.module.check_mode or (self.module.check_mode and run_in_check_mode):
|
||||
cmd = [self._rabbitmqctl, '-q', '-n', self.node]
|
||||
rc, out, err = self.module.run_command(cmd + args, check_rc=True)
|
||||
return out.strip().splitlines()
|
||||
return list()
|
||||
|
||||
def get(self):
|
||||
parameters = [param for param in self._exec(['list_parameters', '-p', self.vhost], True) if param.strip()]
|
||||
|
||||
for param_item in parameters:
|
||||
component, name, value = param_item.split('\t')
|
||||
|
||||
if component == self.component and name == self.name:
|
||||
self._value = json.loads(value)
|
||||
return True
|
||||
return False
|
||||
|
||||
def set(self):
|
||||
self._exec(['set_parameter',
|
||||
'-p',
|
||||
self.vhost,
|
||||
self.component,
|
||||
self.name,
|
||||
json.dumps(self.value)])
|
||||
|
||||
def delete(self):
|
||||
self._exec(['clear_parameter', '-p', self.vhost, self.component, self.name])
|
||||
|
||||
def has_modifications(self):
|
||||
return self.value != self._value
|
||||
|
||||
|
||||
def main():
|
||||
arg_spec = dict(
|
||||
component=dict(required=True),
|
||||
name=dict(required=True),
|
||||
value=dict(default=None),
|
||||
vhost=dict(default='/'),
|
||||
state=dict(default='present', choices=['present', 'absent']),
|
||||
node=dict(default='rabbit')
|
||||
)
|
||||
module = AnsibleModule(
|
||||
argument_spec=arg_spec,
|
||||
supports_check_mode=True
|
||||
)
|
||||
|
||||
component = module.params['component']
|
||||
name = module.params['name']
|
||||
value = module.params['value']
|
||||
if isinstance(value, str):
|
||||
value = json.loads(value)
|
||||
vhost = module.params['vhost']
|
||||
state = module.params['state']
|
||||
node = module.params['node']
|
||||
|
||||
result = dict(changed=False)
|
||||
rabbitmq_parameter = RabbitMqParameter(module, component, name, value, vhost, node)
|
||||
|
||||
if rabbitmq_parameter.get():
|
||||
if state == 'absent':
|
||||
rabbitmq_parameter.delete()
|
||||
result['changed'] = True
|
||||
else:
|
||||
if rabbitmq_parameter.has_modifications():
|
||||
rabbitmq_parameter.set()
|
||||
result['changed'] = True
|
||||
elif state == 'present':
|
||||
rabbitmq_parameter.set()
|
||||
result['changed'] = True
|
||||
|
||||
result['component'] = component
|
||||
result['name'] = name
|
||||
result['vhost'] = vhost
|
||||
result['state'] = state
|
||||
module.exit_json(**result)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
|
@ -1,178 +0,0 @@
|
|||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Copyright: (c) 2013, Chatham Financial <oss@chathamfinancial.com>
|
||||
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||
|
||||
from __future__ import absolute_import, division, print_function
|
||||
__metaclass__ = type
|
||||
|
||||
|
||||
ANSIBLE_METADATA = {
|
||||
'metadata_version': '1.1',
|
||||
'status': ['preview'],
|
||||
'supported_by': 'community'
|
||||
}
|
||||
|
||||
|
||||
DOCUMENTATION = '''
|
||||
---
|
||||
module: rabbitmq_plugin
|
||||
short_description: Manage RabbitMQ plugins
|
||||
description:
|
||||
- This module can be used to enable or disable RabbitMQ plugins.
|
||||
author:
|
||||
- Chris Hoffman (@chrishoffman)
|
||||
options:
|
||||
names:
|
||||
description:
|
||||
- Comma-separated list of plugin names. Also, accepts plugin name.
|
||||
required: true
|
||||
aliases: [name]
|
||||
new_only:
|
||||
description:
|
||||
- Only enable missing plugins.
|
||||
- Does not disable plugins that are not in the names list.
|
||||
type: bool
|
||||
default: "no"
|
||||
state:
|
||||
description:
|
||||
- Specify if plugins are to be enabled or disabled.
|
||||
default: enabled
|
||||
choices: [enabled, disabled]
|
||||
prefix:
|
||||
description:
|
||||
- Specify a custom install prefix to a Rabbit.
|
||||
'''
|
||||
|
||||
EXAMPLES = '''
|
||||
- name: Enables the rabbitmq_management plugin
|
||||
rabbitmq_plugin:
|
||||
names: rabbitmq_management
|
||||
state: enabled
|
||||
|
||||
- name: Enable multiple rabbitmq plugins
|
||||
rabbitmq_plugin:
|
||||
names: rabbitmq_management,rabbitmq_management_visualiser
|
||||
state: enabled
|
||||
|
||||
- name: Disable plugin
|
||||
rabbitmq_plugin:
|
||||
names: rabbitmq_management
|
||||
state: disabled
|
||||
|
||||
- name: Enable every plugin in list with existing plugins
|
||||
rabbitmq_plugin:
|
||||
names: rabbitmq_management,rabbitmq_management_visualiser,rabbitmq_shovel,rabbitmq_shovel_management
|
||||
state: enabled
|
||||
new_only: 'yes'
|
||||
'''
|
||||
|
||||
RETURN = '''
|
||||
enabled:
|
||||
description: list of plugins enabled during task run
|
||||
returned: always
|
||||
type: list
|
||||
sample: ["rabbitmq_management"]
|
||||
disabled:
|
||||
description: list of plugins disabled during task run
|
||||
returned: always
|
||||
type: list
|
||||
sample: ["rabbitmq_management"]
|
||||
'''
|
||||
|
||||
import os
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
|
||||
|
||||
class RabbitMqPlugins(object):
|
||||
|
||||
def __init__(self, module):
|
||||
self.module = module
|
||||
bin_path = ''
|
||||
if module.params['prefix']:
|
||||
if os.path.isdir(os.path.join(module.params['prefix'], 'bin')):
|
||||
bin_path = os.path.join(module.params['prefix'], 'bin')
|
||||
elif os.path.isdir(os.path.join(module.params['prefix'], 'sbin')):
|
||||
bin_path = os.path.join(module.params['prefix'], 'sbin')
|
||||
else:
|
||||
# No such path exists.
|
||||
module.fail_json(msg="No binary folder in prefix %s" % module.params['prefix'])
|
||||
|
||||
self._rabbitmq_plugins = os.path.join(bin_path, "rabbitmq-plugins")
|
||||
else:
|
||||
self._rabbitmq_plugins = module.get_bin_path('rabbitmq-plugins', True)
|
||||
|
||||
def _exec(self, args, run_in_check_mode=False):
|
||||
if not self.module.check_mode or (self.module.check_mode and run_in_check_mode):
|
||||
cmd = [self._rabbitmq_plugins]
|
||||
rc, out, err = self.module.run_command(cmd + args, check_rc=True)
|
||||
return out.splitlines()
|
||||
return list()
|
||||
|
||||
def get_all(self):
|
||||
list_output = self._exec(['list', '-E', '-m'], True)
|
||||
plugins = []
|
||||
for plugin in list_output:
|
||||
if not plugin:
|
||||
break
|
||||
plugins.append(plugin)
|
||||
|
||||
return plugins
|
||||
|
||||
def enable(self, name):
|
||||
self._exec(['enable', name])
|
||||
|
||||
def disable(self, name):
|
||||
self._exec(['disable', name])
|
||||
|
||||
|
||||
def main():
|
||||
arg_spec = dict(
|
||||
names=dict(required=True, aliases=['name']),
|
||||
new_only=dict(default='no', type='bool'),
|
||||
state=dict(default='enabled', choices=['enabled', 'disabled']),
|
||||
prefix=dict(required=False, default=None)
|
||||
)
|
||||
module = AnsibleModule(
|
||||
argument_spec=arg_spec,
|
||||
supports_check_mode=True
|
||||
)
|
||||
|
||||
result = dict()
|
||||
names = module.params['names'].split(',')
|
||||
new_only = module.params['new_only']
|
||||
state = module.params['state']
|
||||
|
||||
rabbitmq_plugins = RabbitMqPlugins(module)
|
||||
enabled_plugins = rabbitmq_plugins.get_all()
|
||||
|
||||
enabled = []
|
||||
disabled = []
|
||||
if state == 'enabled':
|
||||
if not new_only:
|
||||
for plugin in enabled_plugins:
|
||||
if " " in plugin:
|
||||
continue
|
||||
if plugin not in names:
|
||||
rabbitmq_plugins.disable(plugin)
|
||||
disabled.append(plugin)
|
||||
|
||||
for name in names:
|
||||
if name not in enabled_plugins:
|
||||
rabbitmq_plugins.enable(name)
|
||||
enabled.append(name)
|
||||
else:
|
||||
for plugin in enabled_plugins:
|
||||
if plugin in names:
|
||||
rabbitmq_plugins.disable(plugin)
|
||||
disabled.append(plugin)
|
||||
|
||||
result['changed'] = len(enabled) > 0 or len(disabled) > 0
|
||||
result['enabled'] = enabled
|
||||
result['disabled'] = disabled
|
||||
module.exit_json(**result)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
|
@ -1,245 +0,0 @@
|
|||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Copyright: (c) 2013, John Dewey <john@dewey.ws>
|
||||
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||
|
||||
from __future__ import absolute_import, division, print_function
|
||||
__metaclass__ = type
|
||||
|
||||
|
||||
ANSIBLE_METADATA = {'metadata_version': '1.1',
|
||||
'status': ['preview'],
|
||||
'supported_by': 'community'}
|
||||
|
||||
|
||||
DOCUMENTATION = '''
|
||||
---
|
||||
module: rabbitmq_policy
|
||||
short_description: Manage the state of policies in RabbitMQ
|
||||
description:
|
||||
- Manage the state of a policy in RabbitMQ.
|
||||
author: John Dewey (@retr0h)
|
||||
options:
|
||||
name:
|
||||
description:
|
||||
- The name of the policy to manage.
|
||||
required: true
|
||||
vhost:
|
||||
description:
|
||||
- The name of the vhost to apply to.
|
||||
default: /
|
||||
apply_to:
|
||||
description:
|
||||
- What the policy applies to. Requires RabbitMQ 3.2.0 or later.
|
||||
default: all
|
||||
choices: [all, exchanges, queues]
|
||||
pattern:
|
||||
description:
|
||||
- A regex of queues to apply the policy to. Required when
|
||||
C(state=present). This option is no longer required as of Ansible 2.9.
|
||||
required: false
|
||||
default: null
|
||||
tags:
|
||||
description:
|
||||
- A dict or string describing the policy. Required when
|
||||
C(state=present). This option is no longer required as of Ansible 2.9.
|
||||
required: false
|
||||
default: null
|
||||
priority:
|
||||
description:
|
||||
- The priority of the policy.
|
||||
default: 0
|
||||
node:
|
||||
description:
|
||||
- Erlang node name of the rabbit we wish to configure.
|
||||
default: rabbit
|
||||
state:
|
||||
description:
|
||||
- The state of the policy.
|
||||
default: present
|
||||
choices: [present, absent]
|
||||
'''
|
||||
|
||||
EXAMPLES = '''
|
||||
- name: ensure the default vhost contains the HA policy via a dict
|
||||
rabbitmq_policy:
|
||||
name: HA
|
||||
pattern: .*
|
||||
args:
|
||||
tags:
|
||||
ha-mode: all
|
||||
|
||||
- name: ensure the default vhost contains the HA policy
|
||||
rabbitmq_policy:
|
||||
name: HA
|
||||
pattern: .*
|
||||
tags:
|
||||
ha-mode: all
|
||||
'''
|
||||
|
||||
import json
|
||||
import re
|
||||
from distutils.version import LooseVersion as Version
|
||||
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
|
||||
|
||||
class RabbitMqPolicy(object):
|
||||
|
||||
def __init__(self, module, name):
|
||||
self._module = module
|
||||
self._name = name
|
||||
self._vhost = module.params['vhost']
|
||||
self._pattern = module.params['pattern']
|
||||
self._apply_to = module.params['apply_to']
|
||||
self._tags = module.params['tags']
|
||||
self._priority = module.params['priority']
|
||||
self._node = module.params['node']
|
||||
self._rabbitmqctl = module.get_bin_path('rabbitmqctl', True)
|
||||
|
||||
self._version = self._rabbit_version()
|
||||
|
||||
def _exec(self,
|
||||
args,
|
||||
run_in_check_mode=False,
|
||||
split_lines=True,
|
||||
add_vhost=True):
|
||||
if (not self._module.check_mode
|
||||
or (self._module.check_mode and run_in_check_mode)):
|
||||
cmd = [self._rabbitmqctl, '-q', '-n', self._node]
|
||||
|
||||
if add_vhost:
|
||||
args.insert(1, '-p')
|
||||
args.insert(2, self._vhost)
|
||||
|
||||
rc, out, err = self._module.run_command(cmd + args, check_rc=True)
|
||||
if split_lines:
|
||||
return out.splitlines()
|
||||
|
||||
return out
|
||||
return list()
|
||||
|
||||
def _rabbit_version(self):
|
||||
status = self._exec(['status'], True, False, False)
|
||||
|
||||
# 3.7.x erlang style output
|
||||
version_match = re.search('{rabbit,".*","(?P<version>.*)"}', status)
|
||||
if version_match:
|
||||
return Version(version_match.group('version'))
|
||||
|
||||
# 3.8.x style ouput
|
||||
version_match = re.search('RabbitMQ version: (?P<version>.*)', status)
|
||||
if version_match:
|
||||
return Version(version_match.group('version'))
|
||||
|
||||
return None
|
||||
|
||||
def _list_policies(self):
|
||||
if self._version and self._version >= Version('3.7.9'):
|
||||
# Remove first header line from policies list for version > 3.7.9
|
||||
return self._exec(['list_policies'], True)[1:]
|
||||
|
||||
return self._exec(['list_policies'], True)
|
||||
|
||||
def has_modifications(self):
|
||||
if self._pattern is None or self._tags is None:
|
||||
self._module.fail_json(
|
||||
msg=('pattern and tags are required for '
|
||||
'state=present'))
|
||||
|
||||
if self._version and self._version >= Version('3.7.0'):
|
||||
# Change fields order in rabbitmqctl output in version 3.7
|
||||
return not any(
|
||||
self._policy_check(policy, apply_to_fno=3, pattern_fno=2)
|
||||
for policy in self._list_policies())
|
||||
else:
|
||||
return not any(
|
||||
self._policy_check(policy) for policy in self._list_policies())
|
||||
|
||||
def should_be_deleted(self):
|
||||
return any(
|
||||
self._policy_check_by_name(policy)
|
||||
for policy in self._list_policies())
|
||||
|
||||
def set(self):
|
||||
args = ['set_policy']
|
||||
args.append(self._name)
|
||||
args.append(self._pattern)
|
||||
args.append(json.dumps(self._tags))
|
||||
args.append('--priority')
|
||||
args.append(self._priority)
|
||||
if self._apply_to != 'all':
|
||||
args.append('--apply-to')
|
||||
args.append(self._apply_to)
|
||||
return self._exec(args)
|
||||
|
||||
def clear(self):
|
||||
return self._exec(['clear_policy', self._name])
|
||||
|
||||
def _policy_check(self,
|
||||
policy,
|
||||
name_fno=1,
|
||||
apply_to_fno=2,
|
||||
pattern_fno=3,
|
||||
tags_fno=4,
|
||||
priority_fno=5):
|
||||
if not policy:
|
||||
return False
|
||||
|
||||
policy_data = policy.split('\t')
|
||||
|
||||
policy_name = policy_data[name_fno]
|
||||
apply_to = policy_data[apply_to_fno]
|
||||
pattern = policy_data[pattern_fno].replace('\\\\', '\\')
|
||||
tags = json.loads(policy_data[tags_fno])
|
||||
priority = policy_data[priority_fno]
|
||||
|
||||
return (policy_name == self._name and apply_to == self._apply_to
|
||||
and tags == self._tags and priority == self._priority
|
||||
and pattern == self._pattern)
|
||||
|
||||
def _policy_check_by_name(self, policy):
|
||||
if not policy:
|
||||
return False
|
||||
|
||||
policy_name = policy.split('\t')[1]
|
||||
|
||||
return policy_name == self._name
|
||||
|
||||
|
||||
def main():
|
||||
arg_spec = dict(
|
||||
name=dict(required=True),
|
||||
vhost=dict(default='/'),
|
||||
pattern=dict(required=False, default=None),
|
||||
apply_to=dict(default='all', choices=['all', 'exchanges', 'queues']),
|
||||
tags=dict(type='dict', required=False, default=None),
|
||||
priority=dict(default='0'),
|
||||
node=dict(default='rabbit'),
|
||||
state=dict(default='present', choices=['present', 'absent']),
|
||||
)
|
||||
|
||||
module = AnsibleModule(
|
||||
argument_spec=arg_spec,
|
||||
supports_check_mode=True
|
||||
)
|
||||
|
||||
name = module.params['name']
|
||||
state = module.params['state']
|
||||
rabbitmq_policy = RabbitMqPolicy(module, name)
|
||||
|
||||
result = dict(changed=False, name=name, state=state)
|
||||
|
||||
if state == 'present' and rabbitmq_policy.has_modifications():
|
||||
rabbitmq_policy.set()
|
||||
result['changed'] = True
|
||||
elif state == 'absent' and rabbitmq_policy.should_be_deleted():
|
||||
rabbitmq_policy.clear()
|
||||
result['changed'] = True
|
||||
|
||||
module.exit_json(**result)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
|
@ -1,256 +0,0 @@
|
|||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Copyright: (c) 2015, Manuel Sousa <manuel.sousa@gmail.com>
|
||||
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||
|
||||
from __future__ import absolute_import, division, print_function
|
||||
__metaclass__ = type
|
||||
|
||||
|
||||
ANSIBLE_METADATA = {'metadata_version': '1.1',
|
||||
'status': ['preview'],
|
||||
'supported_by': 'community'}
|
||||
|
||||
|
||||
DOCUMENTATION = '''
|
||||
---
|
||||
module: rabbitmq_queue
|
||||
author: Manuel Sousa (@manuel-sousa)
|
||||
|
||||
short_description: Manage rabbitMQ queues
|
||||
description:
|
||||
- This module uses rabbitMQ Rest API to create/delete queues
|
||||
requirements: [ "requests >= 1.0.0" ]
|
||||
options:
|
||||
name:
|
||||
description:
|
||||
- Name of the queue
|
||||
required: true
|
||||
state:
|
||||
description:
|
||||
- Whether the queue should be present or absent
|
||||
choices: [ "present", "absent" ]
|
||||
default: present
|
||||
durable:
|
||||
description:
|
||||
- whether queue is durable or not
|
||||
type: bool
|
||||
default: 'yes'
|
||||
auto_delete:
|
||||
description:
|
||||
- if the queue should delete itself after all queues/queues unbound from it
|
||||
type: bool
|
||||
default: 'no'
|
||||
message_ttl:
|
||||
description:
|
||||
- How long a message can live in queue before it is discarded (milliseconds)
|
||||
default: forever
|
||||
auto_expires:
|
||||
description:
|
||||
- How long a queue can be unused before it is automatically deleted (milliseconds)
|
||||
default: forever
|
||||
max_length:
|
||||
description:
|
||||
- How many messages can the queue contain before it starts rejecting
|
||||
default: no limit
|
||||
dead_letter_exchange:
|
||||
description:
|
||||
- Optional name of an exchange to which messages will be republished if they
|
||||
- are rejected or expire
|
||||
dead_letter_routing_key:
|
||||
description:
|
||||
- Optional replacement routing key to use when a message is dead-lettered.
|
||||
- Original routing key will be used if unset
|
||||
max_priority:
|
||||
description:
|
||||
- Maximum number of priority levels for the queue to support.
|
||||
- If not set, the queue will not support message priorities.
|
||||
- Larger numbers indicate higher priority.
|
||||
arguments:
|
||||
description:
|
||||
- extra arguments for queue. If defined this argument is a key/value dictionary
|
||||
default: {}
|
||||
extends_documentation_fragment:
|
||||
- community.general.rabbitmq
|
||||
|
||||
'''
|
||||
|
||||
EXAMPLES = '''
|
||||
# Create a queue
|
||||
- rabbitmq_queue:
|
||||
name: myQueue
|
||||
|
||||
# Create a queue on remote host
|
||||
- rabbitmq_queue:
|
||||
name: myRemoteQueue
|
||||
login_user: user
|
||||
login_password: secret
|
||||
login_host: remote.example.org
|
||||
'''
|
||||
|
||||
import json
|
||||
import traceback
|
||||
|
||||
REQUESTS_IMP_ERR = None
|
||||
try:
|
||||
import requests
|
||||
HAS_REQUESTS = True
|
||||
except ImportError:
|
||||
REQUESTS_IMP_ERR = traceback.format_exc()
|
||||
HAS_REQUESTS = False
|
||||
|
||||
from ansible.module_utils.basic import AnsibleModule, missing_required_lib
|
||||
from ansible.module_utils.six.moves.urllib import parse as urllib_parse
|
||||
from ansible_collections.community.general.plugins.module_utils.rabbitmq import rabbitmq_argument_spec
|
||||
|
||||
|
||||
def main():
|
||||
|
||||
argument_spec = rabbitmq_argument_spec()
|
||||
argument_spec.update(
|
||||
dict(
|
||||
state=dict(default='present', choices=['present', 'absent'], type='str'),
|
||||
name=dict(required=True, type='str'),
|
||||
durable=dict(default=True, type='bool'),
|
||||
auto_delete=dict(default=False, type='bool'),
|
||||
message_ttl=dict(default=None, type='int'),
|
||||
auto_expires=dict(default=None, type='int'),
|
||||
max_length=dict(default=None, type='int'),
|
||||
dead_letter_exchange=dict(default=None, type='str'),
|
||||
dead_letter_routing_key=dict(default=None, type='str'),
|
||||
arguments=dict(default=dict(), type='dict'),
|
||||
max_priority=dict(default=None, type='int')
|
||||
)
|
||||
)
|
||||
module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=True)
|
||||
|
||||
url = "%s://%s:%s/api/queues/%s/%s" % (
|
||||
module.params['login_protocol'],
|
||||
module.params['login_host'],
|
||||
module.params['login_port'],
|
||||
urllib_parse.quote(module.params['vhost'], ''),
|
||||
module.params['name']
|
||||
)
|
||||
|
||||
if not HAS_REQUESTS:
|
||||
module.fail_json(msg=missing_required_lib("requests"), exception=REQUESTS_IMP_ERR)
|
||||
|
||||
result = dict(changed=False, name=module.params['name'])
|
||||
|
||||
# Check if queue already exists
|
||||
r = requests.get(url, auth=(module.params['login_user'], module.params['login_password']),
|
||||
verify=module.params['ca_cert'], cert=(module.params['client_cert'], module.params['client_key']))
|
||||
|
||||
if r.status_code == 200:
|
||||
queue_exists = True
|
||||
response = r.json()
|
||||
elif r.status_code == 404:
|
||||
queue_exists = False
|
||||
response = r.text
|
||||
else:
|
||||
module.fail_json(
|
||||
msg="Invalid response from RESTAPI when trying to check if queue exists",
|
||||
details=r.text
|
||||
)
|
||||
|
||||
if module.params['state'] == 'present':
|
||||
change_required = not queue_exists
|
||||
else:
|
||||
change_required = queue_exists
|
||||
|
||||
# Check if attributes change on existing queue
|
||||
if not change_required and r.status_code == 200 and module.params['state'] == 'present':
|
||||
if not (
|
||||
response['durable'] == module.params['durable'] and
|
||||
response['auto_delete'] == module.params['auto_delete'] and
|
||||
(
|
||||
('x-message-ttl' in response['arguments'] and response['arguments']['x-message-ttl'] == module.params['message_ttl']) or
|
||||
('x-message-ttl' not in response['arguments'] and module.params['message_ttl'] is None)
|
||||
) and
|
||||
(
|
||||
('x-expires' in response['arguments'] and response['arguments']['x-expires'] == module.params['auto_expires']) or
|
||||
('x-expires' not in response['arguments'] and module.params['auto_expires'] is None)
|
||||
) and
|
||||
(
|
||||
('x-max-length' in response['arguments'] and response['arguments']['x-max-length'] == module.params['max_length']) or
|
||||
('x-max-length' not in response['arguments'] and module.params['max_length'] is None)
|
||||
) and
|
||||
(
|
||||
('x-dead-letter-exchange' in response['arguments'] and
|
||||
response['arguments']['x-dead-letter-exchange'] == module.params['dead_letter_exchange']) or
|
||||
('x-dead-letter-exchange' not in response['arguments'] and module.params['dead_letter_exchange'] is None)
|
||||
) and
|
||||
(
|
||||
('x-dead-letter-routing-key' in response['arguments'] and
|
||||
response['arguments']['x-dead-letter-routing-key'] == module.params['dead_letter_routing_key']) or
|
||||
('x-dead-letter-routing-key' not in response['arguments'] and module.params['dead_letter_routing_key'] is None)
|
||||
) and
|
||||
(
|
||||
('x-max-priority' in response['arguments'] and
|
||||
response['arguments']['x-max-priority'] == module.params['max_priority']) or
|
||||
('x-max-priority' not in response['arguments'] and module.params['max_priority'] is None)
|
||||
)
|
||||
):
|
||||
module.fail_json(
|
||||
msg="RabbitMQ RESTAPI doesn't support attribute changes for existing queues",
|
||||
)
|
||||
|
||||
# Copy parameters to arguments as used by RabbitMQ
|
||||
for k, v in {
|
||||
'message_ttl': 'x-message-ttl',
|
||||
'auto_expires': 'x-expires',
|
||||
'max_length': 'x-max-length',
|
||||
'dead_letter_exchange': 'x-dead-letter-exchange',
|
||||
'dead_letter_routing_key': 'x-dead-letter-routing-key',
|
||||
'max_priority': 'x-max-priority'
|
||||
}.items():
|
||||
if module.params[k] is not None:
|
||||
module.params['arguments'][v] = module.params[k]
|
||||
|
||||
# Exit if check_mode
|
||||
if module.check_mode:
|
||||
result['changed'] = change_required
|
||||
result['details'] = response
|
||||
result['arguments'] = module.params['arguments']
|
||||
module.exit_json(**result)
|
||||
|
||||
# Do changes
|
||||
if change_required:
|
||||
if module.params['state'] == 'present':
|
||||
r = requests.put(
|
||||
url,
|
||||
auth=(module.params['login_user'], module.params['login_password']),
|
||||
headers={"content-type": "application/json"},
|
||||
data=json.dumps({
|
||||
"durable": module.params['durable'],
|
||||
"auto_delete": module.params['auto_delete'],
|
||||
"arguments": module.params['arguments']
|
||||
}),
|
||||
verify=module.params['ca_cert'],
|
||||
cert=(module.params['client_cert'], module.params['client_key'])
|
||||
)
|
||||
elif module.params['state'] == 'absent':
|
||||
r = requests.delete(url, auth=(module.params['login_user'], module.params['login_password']),
|
||||
verify=module.params['ca_cert'], cert=(module.params['client_cert'], module.params['client_key']))
|
||||
|
||||
# RabbitMQ 3.6.7 changed this response code from 204 to 201
|
||||
if r.status_code == 204 or r.status_code == 201:
|
||||
result['changed'] = True
|
||||
module.exit_json(**result)
|
||||
else:
|
||||
module.fail_json(
|
||||
msg="Error creating queue",
|
||||
status=r.status_code,
|
||||
details=r.text
|
||||
)
|
||||
|
||||
else:
|
||||
module.exit_json(
|
||||
changed=False,
|
||||
name=module.params['name']
|
||||
)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
|
@ -1,321 +0,0 @@
|
|||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Copyright: (c) 2013, Chatham Financial <oss@chathamfinancial.com>
|
||||
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||
|
||||
from __future__ import absolute_import, division, print_function
|
||||
__metaclass__ = type
|
||||
|
||||
|
||||
ANSIBLE_METADATA = {'metadata_version': '1.1',
|
||||
'status': ['preview'],
|
||||
'supported_by': 'community'}
|
||||
|
||||
|
||||
DOCUMENTATION = '''
|
||||
---
|
||||
module: rabbitmq_user
|
||||
short_description: Manage RabbitMQ users
|
||||
description:
|
||||
- Add or remove users to RabbitMQ and assign permissions
|
||||
author: Chris Hoffman (@chrishoffman)
|
||||
options:
|
||||
user:
|
||||
description:
|
||||
- Name of user to add
|
||||
required: true
|
||||
aliases: [username, name]
|
||||
password:
|
||||
description:
|
||||
- Password of user to add.
|
||||
- To change the password of an existing user, you must also specify
|
||||
C(update_password=always).
|
||||
tags:
|
||||
description:
|
||||
- User tags specified as comma delimited
|
||||
permissions:
|
||||
description:
|
||||
- a list of dicts, each dict contains vhost, configure_priv, write_priv, and read_priv,
|
||||
and represents a permission rule for that vhost.
|
||||
- This option should be preferable when you care about all permissions of the user.
|
||||
- You should use vhost, configure_priv, write_priv, and read_priv options instead
|
||||
if you care about permissions for just some vhosts.
|
||||
default: []
|
||||
vhost:
|
||||
description:
|
||||
- vhost to apply access privileges.
|
||||
- This option will be ignored when permissions option is used.
|
||||
default: /
|
||||
node:
|
||||
description:
|
||||
- erlang node name of the rabbit we wish to configure
|
||||
default: rabbit
|
||||
configure_priv:
|
||||
description:
|
||||
- Regular expression to restrict configure actions on a resource
|
||||
for the specified vhost.
|
||||
- By default all actions are restricted.
|
||||
- This option will be ignored when permissions option is used.
|
||||
default: ^$
|
||||
write_priv:
|
||||
description:
|
||||
- Regular expression to restrict configure actions on a resource
|
||||
for the specified vhost.
|
||||
- By default all actions are restricted.
|
||||
- This option will be ignored when permissions option is used.
|
||||
default: ^$
|
||||
read_priv:
|
||||
description:
|
||||
- Regular expression to restrict configure actions on a resource
|
||||
for the specified vhost.
|
||||
- By default all actions are restricted.
|
||||
- This option will be ignored when permissions option is used.
|
||||
default: ^$
|
||||
force:
|
||||
description:
|
||||
- Deletes and recreates the user.
|
||||
type: bool
|
||||
default: 'no'
|
||||
state:
|
||||
description:
|
||||
- Specify if user is to be added or removed
|
||||
default: present
|
||||
choices: [present, absent]
|
||||
update_password:
|
||||
description:
|
||||
- C(on_create) will only set the password for newly created users. C(always) will update passwords if they differ.
|
||||
required: false
|
||||
default: on_create
|
||||
choices: [ on_create, always ]
|
||||
'''
|
||||
|
||||
EXAMPLES = '''
|
||||
# Add user to server and assign full access control on / vhost.
|
||||
# The user might have permission rules for other vhost but you don't care.
|
||||
- rabbitmq_user:
|
||||
user: joe
|
||||
password: changeme
|
||||
vhost: /
|
||||
configure_priv: .*
|
||||
read_priv: .*
|
||||
write_priv: .*
|
||||
state: present
|
||||
|
||||
# Add user to server and assign full access control on / vhost.
|
||||
# The user doesn't have permission rules for other vhosts
|
||||
- rabbitmq_user:
|
||||
user: joe
|
||||
password: changeme
|
||||
permissions:
|
||||
- vhost: /
|
||||
configure_priv: .*
|
||||
read_priv: .*
|
||||
write_priv: .*
|
||||
state: present
|
||||
'''
|
||||
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
from ansible.module_utils.common.collections import count
|
||||
|
||||
|
||||
class RabbitMqUser(object):
|
||||
def __init__(self, module, username, password, tags, permissions,
|
||||
node, bulk_permissions=False):
|
||||
self.module = module
|
||||
self.username = username
|
||||
self.password = password
|
||||
self.node = node
|
||||
if not tags:
|
||||
self.tags = list()
|
||||
else:
|
||||
self.tags = tags.split(',')
|
||||
|
||||
self.permissions = permissions
|
||||
self.bulk_permissions = bulk_permissions
|
||||
|
||||
self._tags = None
|
||||
self._permissions = []
|
||||
self._rabbitmqctl = module.get_bin_path('rabbitmqctl', True)
|
||||
|
||||
def _exec(self, args, run_in_check_mode=False, check_rc=True):
|
||||
if not self.module.check_mode or run_in_check_mode:
|
||||
cmd = [self._rabbitmqctl, '-q']
|
||||
if self.node:
|
||||
cmd.extend(['-n', self.node])
|
||||
rc, out, err = self.module.run_command(cmd + args, check_rc=check_rc)
|
||||
return out.splitlines()
|
||||
return list()
|
||||
|
||||
def get(self):
|
||||
users = self._exec(['list_users'], True)
|
||||
|
||||
for user_tag in users:
|
||||
if '\t' not in user_tag:
|
||||
continue
|
||||
|
||||
user, tags = user_tag.split('\t')
|
||||
|
||||
if user == self.username:
|
||||
for c in ['[', ']', ' ']:
|
||||
tags = tags.replace(c, '')
|
||||
|
||||
if tags != '':
|
||||
self._tags = tags.split(',')
|
||||
else:
|
||||
self._tags = list()
|
||||
|
||||
self._permissions = self._get_permissions()
|
||||
return True
|
||||
return False
|
||||
|
||||
def _get_permissions(self):
|
||||
"""Get permissions of the user from RabbitMQ."""
|
||||
perms_out = [perm for perm in self._exec(['list_user_permissions', self.username], True) if perm.strip()]
|
||||
|
||||
perms_list = list()
|
||||
for perm in perms_out:
|
||||
vhost, configure_priv, write_priv, read_priv = perm.split('\t')
|
||||
if not self.bulk_permissions:
|
||||
if vhost == self.permissions[0]['vhost']:
|
||||
perms_list.append(dict(vhost=vhost, configure_priv=configure_priv,
|
||||
write_priv=write_priv, read_priv=read_priv))
|
||||
break
|
||||
else:
|
||||
perms_list.append(dict(vhost=vhost, configure_priv=configure_priv,
|
||||
write_priv=write_priv, read_priv=read_priv))
|
||||
return perms_list
|
||||
|
||||
def check_password(self):
|
||||
return self._exec(['authenticate_user', self.username, self.password],
|
||||
run_in_check_mode=True, check_rc=False)
|
||||
|
||||
def add(self):
|
||||
if self.password is not None:
|
||||
self._exec(['add_user', self.username, self.password])
|
||||
else:
|
||||
self._exec(['add_user', self.username, ''])
|
||||
self._exec(['clear_password', self.username])
|
||||
|
||||
def delete(self):
|
||||
self._exec(['delete_user', self.username])
|
||||
|
||||
def change_password(self):
|
||||
if self.password is not None:
|
||||
self._exec(['change_password', self.username, self.password])
|
||||
else:
|
||||
self._exec(['clear_password', self.username])
|
||||
|
||||
def set_tags(self):
|
||||
self._exec(['set_user_tags', self.username] + self.tags)
|
||||
|
||||
def set_permissions(self):
|
||||
permissions_to_clear = [permission for permission in self._permissions if permission not in self.permissions]
|
||||
permissions_to_add = [permission for permission in self.permissions if permission not in self._permissions]
|
||||
for permission in permissions_to_clear:
|
||||
cmd = 'clear_permissions -p {vhost} {username}'.format(username=self.username,
|
||||
vhost=permission['vhost'])
|
||||
self._exec(cmd.split(' '))
|
||||
for permission in permissions_to_add:
|
||||
cmd = ('set_permissions -p {vhost} {username} {configure_priv} {write_priv} {read_priv}'
|
||||
.format(username=self.username, **permission))
|
||||
self._exec(cmd.split(' '))
|
||||
|
||||
def has_tags_modifications(self):
|
||||
return set(self.tags) != set(self._tags)
|
||||
|
||||
def has_permissions_modifications(self):
|
||||
def to_permission_tuple(vhost_permission_dict):
|
||||
return vhost_permission_dict['vhost'], vhost_permission_dict
|
||||
|
||||
def permission_dict(vhost_permission_list):
|
||||
return dict(map(to_permission_tuple, vhost_permission_list))
|
||||
|
||||
return permission_dict(self._permissions) != permission_dict(self.permissions)
|
||||
|
||||
|
||||
def main():
|
||||
arg_spec = dict(
|
||||
user=dict(required=True, aliases=['username', 'name']),
|
||||
password=dict(default=None, no_log=True),
|
||||
tags=dict(default=None),
|
||||
permissions=dict(default=list(), type='list'),
|
||||
vhost=dict(default='/'),
|
||||
configure_priv=dict(default='^$'),
|
||||
write_priv=dict(default='^$'),
|
||||
read_priv=dict(default='^$'),
|
||||
force=dict(default='no', type='bool'),
|
||||
state=dict(default='present', choices=['present', 'absent']),
|
||||
node=dict(default='rabbit'),
|
||||
update_password=dict(default='on_create', choices=['on_create', 'always'])
|
||||
)
|
||||
module = AnsibleModule(
|
||||
argument_spec=arg_spec,
|
||||
supports_check_mode=True
|
||||
)
|
||||
|
||||
username = module.params['user']
|
||||
password = module.params['password']
|
||||
tags = module.params['tags']
|
||||
permissions = module.params['permissions']
|
||||
vhost = module.params['vhost']
|
||||
configure_priv = module.params['configure_priv']
|
||||
write_priv = module.params['write_priv']
|
||||
read_priv = module.params['read_priv']
|
||||
force = module.params['force']
|
||||
state = module.params['state']
|
||||
node = module.params['node']
|
||||
update_password = module.params['update_password']
|
||||
|
||||
if permissions:
|
||||
vhosts = map(lambda permission: permission.get('vhost', '/'), permissions)
|
||||
if any(map(lambda count: count > 1, count(vhosts).values())):
|
||||
module.fail_json(msg="Error parsing permissions: You can't have two permission dicts for the same vhost")
|
||||
bulk_permissions = True
|
||||
else:
|
||||
perm = {
|
||||
'vhost': vhost,
|
||||
'configure_priv': configure_priv,
|
||||
'write_priv': write_priv,
|
||||
'read_priv': read_priv
|
||||
}
|
||||
permissions.append(perm)
|
||||
bulk_permissions = False
|
||||
|
||||
rabbitmq_user = RabbitMqUser(module, username, password, tags, permissions,
|
||||
node, bulk_permissions=bulk_permissions)
|
||||
|
||||
result = dict(changed=False, user=username, state=state)
|
||||
if rabbitmq_user.get():
|
||||
if state == 'absent':
|
||||
rabbitmq_user.delete()
|
||||
result['changed'] = True
|
||||
else:
|
||||
if force:
|
||||
rabbitmq_user.delete()
|
||||
rabbitmq_user.add()
|
||||
rabbitmq_user.get()
|
||||
result['changed'] = True
|
||||
elif update_password == 'always':
|
||||
if not rabbitmq_user.check_password():
|
||||
rabbitmq_user.change_password()
|
||||
result['changed'] = True
|
||||
|
||||
if rabbitmq_user.has_tags_modifications():
|
||||
rabbitmq_user.set_tags()
|
||||
result['changed'] = True
|
||||
|
||||
if rabbitmq_user.has_permissions_modifications():
|
||||
rabbitmq_user.set_permissions()
|
||||
result['changed'] = True
|
||||
elif state == 'present':
|
||||
rabbitmq_user.add()
|
||||
rabbitmq_user.set_tags()
|
||||
rabbitmq_user.set_permissions()
|
||||
result['changed'] = True
|
||||
|
||||
module.exit_json(**result)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
|
@ -1,144 +0,0 @@
|
|||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Copyright: (c) 2013, Chatham Financial <oss@chathamfinancial.com>
|
||||
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||
|
||||
from __future__ import absolute_import, division, print_function
|
||||
__metaclass__ = type
|
||||
|
||||
|
||||
ANSIBLE_METADATA = {'metadata_version': '1.1',
|
||||
'status': ['preview'],
|
||||
'supported_by': 'community'}
|
||||
|
||||
|
||||
DOCUMENTATION = '''
|
||||
---
|
||||
module: rabbitmq_vhost
|
||||
short_description: Manage the state of a virtual host in RabbitMQ
|
||||
description:
|
||||
- Manage the state of a virtual host in RabbitMQ
|
||||
author: Chris Hoffman (@chrishoffman)
|
||||
options:
|
||||
name:
|
||||
description:
|
||||
- The name of the vhost to manage
|
||||
required: true
|
||||
aliases: [vhost]
|
||||
node:
|
||||
description:
|
||||
- erlang node name of the rabbit we wish to configure
|
||||
default: rabbit
|
||||
tracing:
|
||||
description:
|
||||
- Enable/disable tracing for a vhost
|
||||
type: bool
|
||||
default: 'no'
|
||||
aliases: [trace]
|
||||
state:
|
||||
description:
|
||||
- The state of vhost
|
||||
default: present
|
||||
choices: [present, absent]
|
||||
'''
|
||||
|
||||
EXAMPLES = '''
|
||||
# Ensure that the vhost /test exists.
|
||||
- rabbitmq_vhost:
|
||||
name: /test
|
||||
state: present
|
||||
'''
|
||||
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
|
||||
|
||||
class RabbitMqVhost(object):
|
||||
def __init__(self, module, name, tracing, node):
|
||||
self.module = module
|
||||
self.name = name
|
||||
self.tracing = tracing
|
||||
self.node = node
|
||||
|
||||
self._tracing = False
|
||||
self._rabbitmqctl = module.get_bin_path('rabbitmqctl', True)
|
||||
|
||||
def _exec(self, args, run_in_check_mode=False):
|
||||
if not self.module.check_mode or (self.module.check_mode and run_in_check_mode):
|
||||
cmd = [self._rabbitmqctl, '-q', '-n', self.node]
|
||||
rc, out, err = self.module.run_command(cmd + args, check_rc=True)
|
||||
return out.splitlines()
|
||||
return list()
|
||||
|
||||
def get(self):
|
||||
vhosts = self._exec(['list_vhosts', 'name', 'tracing'], True)
|
||||
|
||||
for vhost in vhosts:
|
||||
if '\t' not in vhost:
|
||||
continue
|
||||
|
||||
name, tracing = vhost.split('\t')
|
||||
if name == self.name:
|
||||
self._tracing = self.module.boolean(tracing)
|
||||
return True
|
||||
return False
|
||||
|
||||
def add(self):
|
||||
return self._exec(['add_vhost', self.name])
|
||||
|
||||
def delete(self):
|
||||
return self._exec(['delete_vhost', self.name])
|
||||
|
||||
def set_tracing(self):
|
||||
if self.tracing != self._tracing:
|
||||
if self.tracing:
|
||||
self._enable_tracing()
|
||||
else:
|
||||
self._disable_tracing()
|
||||
return True
|
||||
return False
|
||||
|
||||
def _enable_tracing(self):
|
||||
return self._exec(['trace_on', '-p', self.name])
|
||||
|
||||
def _disable_tracing(self):
|
||||
return self._exec(['trace_off', '-p', self.name])
|
||||
|
||||
|
||||
def main():
|
||||
arg_spec = dict(
|
||||
name=dict(required=True, aliases=['vhost']),
|
||||
tracing=dict(default='off', aliases=['trace'], type='bool'),
|
||||
state=dict(default='present', choices=['present', 'absent']),
|
||||
node=dict(default='rabbit'),
|
||||
)
|
||||
|
||||
module = AnsibleModule(
|
||||
argument_spec=arg_spec,
|
||||
supports_check_mode=True
|
||||
)
|
||||
|
||||
name = module.params['name']
|
||||
tracing = module.params['tracing']
|
||||
state = module.params['state']
|
||||
node = module.params['node']
|
||||
result = dict(changed=False, name=name, state=state)
|
||||
rabbitmq_vhost = RabbitMqVhost(module, name, tracing, node)
|
||||
|
||||
if rabbitmq_vhost.get():
|
||||
if state == 'absent':
|
||||
rabbitmq_vhost.delete()
|
||||
result['changed'] = True
|
||||
else:
|
||||
if rabbitmq_vhost.set_tracing():
|
||||
result['changed'] = True
|
||||
elif state == 'present':
|
||||
rabbitmq_vhost.add()
|
||||
rabbitmq_vhost.set_tracing()
|
||||
result['changed'] = True
|
||||
|
||||
module.exit_json(**result)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
|
@ -1,172 +0,0 @@
|
|||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Copyright: (c) 2018, Hiroyuki Matsuo <h.matsuo.engineer@gmail.com>
|
||||
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||
|
||||
from __future__ import absolute_import, division, print_function
|
||||
__metaclass__ = type
|
||||
|
||||
|
||||
ANSIBLE_METADATA = {'metadata_version': '1.1',
|
||||
'status': ['preview'],
|
||||
'supported_by': 'community'}
|
||||
|
||||
DOCUMENTATION = '''
|
||||
---
|
||||
module: rabbitmq_vhost_limits
|
||||
author: Hiroyuki Matsuo (@h-matsuo)
|
||||
|
||||
short_description: Manage the state of virtual host limits in RabbitMQ
|
||||
description:
|
||||
- This module sets/clears certain limits on a virtual host.
|
||||
- The configurable limits are I(max_connections) and I(max-queues).
|
||||
|
||||
options:
|
||||
max_connections:
|
||||
description:
|
||||
- Max number of concurrent client connections.
|
||||
- Negative value means "no limit".
|
||||
- Ignored when the I(state) is C(absent).
|
||||
default: -1
|
||||
max_queues:
|
||||
description:
|
||||
- Max number of queues.
|
||||
- Negative value means "no limit".
|
||||
- Ignored when the I(state) is C(absent).
|
||||
default: -1
|
||||
node:
|
||||
description:
|
||||
- Name of the RabbitMQ Erlang node to manage.
|
||||
state:
|
||||
description:
|
||||
- Specify whether the limits are to be set or cleared.
|
||||
- If set to C(absent), the limits of both I(max_connections) and I(max-queues) will be cleared.
|
||||
default: present
|
||||
choices: [present, absent]
|
||||
vhost:
|
||||
description:
|
||||
- Name of the virtual host to manage.
|
||||
default: /
|
||||
'''
|
||||
|
||||
EXAMPLES = '''
|
||||
# Limit both of the max number of connections and queues on the vhost '/'.
|
||||
- rabbitmq_vhost_limits:
|
||||
vhost: /
|
||||
max_connections: 64
|
||||
max_queues: 256
|
||||
state: present
|
||||
|
||||
# Limit the max number of connections on the vhost '/'.
|
||||
# This task implicitly clears the max number of queues limit using default value: -1.
|
||||
- rabbitmq_vhost_limits:
|
||||
vhost: /
|
||||
max_connections: 64
|
||||
state: present
|
||||
|
||||
# Clear the limits on the vhost '/'.
|
||||
- rabbitmq_vhost_limits:
|
||||
vhost: /
|
||||
state: absent
|
||||
'''
|
||||
|
||||
RETURN = ''' # '''
|
||||
|
||||
|
||||
import json
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
|
||||
|
||||
class RabbitMqVhostLimits(object):
|
||||
def __init__(self, module):
|
||||
self._module = module
|
||||
self._max_connections = module.params['max_connections']
|
||||
self._max_queues = module.params['max_queues']
|
||||
self._node = module.params['node']
|
||||
self._state = module.params['state']
|
||||
self._vhost = module.params['vhost']
|
||||
self._rabbitmqctl = module.get_bin_path('rabbitmqctl', True)
|
||||
|
||||
def _exec(self, args):
|
||||
cmd = [self._rabbitmqctl, '-q', '-p', self._vhost]
|
||||
if self._node is not None:
|
||||
cmd.extend(['-n', self._node])
|
||||
rc, out, err = self._module.run_command(cmd + args, check_rc=True)
|
||||
return dict(rc=rc, out=out.splitlines(), err=err.splitlines())
|
||||
|
||||
def list(self):
|
||||
exec_result = self._exec(['list_vhost_limits'])
|
||||
vhost_limits = exec_result['out'][0]
|
||||
max_connections = None
|
||||
max_queues = None
|
||||
if vhost_limits:
|
||||
vhost_limits = json.loads(vhost_limits)
|
||||
if 'max-connections' in vhost_limits:
|
||||
max_connections = vhost_limits['max-connections']
|
||||
if 'max-queues' in vhost_limits:
|
||||
max_queues = vhost_limits['max-queues']
|
||||
return dict(
|
||||
max_connections=max_connections,
|
||||
max_queues=max_queues
|
||||
)
|
||||
|
||||
def set(self):
|
||||
if self._module.check_mode:
|
||||
return
|
||||
json_str = '{{"max-connections": {0}, "max-queues": {1}}}'.format(self._max_connections, self._max_queues)
|
||||
self._exec(['set_vhost_limits', json_str])
|
||||
|
||||
def clear(self):
|
||||
if self._module.check_mode:
|
||||
return
|
||||
self._exec(['clear_vhost_limits'])
|
||||
|
||||
|
||||
def main():
|
||||
arg_spec = dict(
|
||||
max_connections=dict(default=-1, type='int'),
|
||||
max_queues=dict(default=-1, type='int'),
|
||||
node=dict(default=None, type='str'),
|
||||
state=dict(default='present', choices=['present', 'absent'], type='str'),
|
||||
vhost=dict(default='/', type='str')
|
||||
)
|
||||
|
||||
module = AnsibleModule(
|
||||
argument_spec=arg_spec,
|
||||
supports_check_mode=True
|
||||
)
|
||||
|
||||
max_connections = module.params['max_connections']
|
||||
max_queues = module.params['max_queues']
|
||||
node = module.params['node']
|
||||
state = module.params['state']
|
||||
vhost = module.params['vhost']
|
||||
|
||||
module_result = dict(changed=False)
|
||||
rabbitmq_vhost_limits = RabbitMqVhostLimits(module)
|
||||
current_status = rabbitmq_vhost_limits.list()
|
||||
|
||||
if state == 'present':
|
||||
wanted_status = dict(
|
||||
max_connections=max_connections,
|
||||
max_queues=max_queues
|
||||
)
|
||||
else: # state == 'absent'
|
||||
wanted_status = dict(
|
||||
max_connections=None,
|
||||
max_queues=None
|
||||
)
|
||||
|
||||
if current_status != wanted_status:
|
||||
module_result['changed'] = True
|
||||
if state == 'present':
|
||||
rabbitmq_vhost_limits.set()
|
||||
else: # state == 'absent'
|
||||
rabbitmq_vhost_limits.clear()
|
||||
|
||||
module.exit_json(**module_result)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
|
@ -1,209 +0,0 @@
|
|||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# (c) 2018, John Imison <john+github@imison.net>
|
||||
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||
|
||||
from __future__ import absolute_import, division, print_function
|
||||
__metaclass__ = type
|
||||
|
||||
|
||||
ANSIBLE_METADATA = {'metadata_version': '1.1',
|
||||
'status': ['preview'],
|
||||
'supported_by': 'community'}
|
||||
|
||||
|
||||
DOCUMENTATION = '''
|
||||
---
|
||||
module: rabbitmq_publish
|
||||
short_description: Publish a message to a RabbitMQ queue.
|
||||
description:
|
||||
- Publish a message on a RabbitMQ queue using a blocking connection.
|
||||
options:
|
||||
url:
|
||||
description:
|
||||
- An URL connection string to connect to the RabbitMQ server.
|
||||
- I(url) and I(host)/I(port)/I(user)/I(pass)/I(vhost) are mutually exclusive, use either or but not both.
|
||||
proto:
|
||||
description:
|
||||
- The protocol to use.
|
||||
choices: [amqps, amqp]
|
||||
host:
|
||||
description:
|
||||
- The RabbitMQ server hostname or IP.
|
||||
port:
|
||||
description:
|
||||
- The RabbitMQ server port.
|
||||
username:
|
||||
description:
|
||||
- The RabbitMQ username.
|
||||
password:
|
||||
description:
|
||||
- The RabbitMQ password.
|
||||
vhost:
|
||||
description:
|
||||
- The virtual host to target.
|
||||
- If default vhost is required, use C('%2F').
|
||||
queue:
|
||||
description:
|
||||
- The queue to publish a message to. If no queue is specified, RabbitMQ will return a random queue name.
|
||||
exchange:
|
||||
description:
|
||||
- The exchange to publish a message to.
|
||||
routing_key:
|
||||
description:
|
||||
- The routing key.
|
||||
body:
|
||||
description:
|
||||
- The body of the message.
|
||||
- A C(body) cannot be provided if a C(src) is specified.
|
||||
src:
|
||||
description:
|
||||
- A file to upload to the queue. Automatic mime type detection is attempted if content_type is not defined (left as default).
|
||||
- A C(src) cannot be provided if a C(body) is specified.
|
||||
- The filename is added to the headers of the posted message to RabbitMQ. Key being the C(filename), value is the filename.
|
||||
aliases: ['file']
|
||||
content_type:
|
||||
description:
|
||||
- The content type of the body.
|
||||
default: text/plain
|
||||
durable:
|
||||
description:
|
||||
- Set the queue to be durable.
|
||||
default: False
|
||||
type: bool
|
||||
exclusive:
|
||||
description:
|
||||
- Set the queue to be exclusive.
|
||||
default: False
|
||||
type: bool
|
||||
auto_delete:
|
||||
description:
|
||||
- Set the queue to auto delete.
|
||||
default: False
|
||||
type: bool
|
||||
headers:
|
||||
description:
|
||||
- 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.
|
||||
certfile:
|
||||
description:
|
||||
- Client certificate to establish SSL connection.
|
||||
- If this option is specified, also I(cafile) and I(keyfile) must be specified.
|
||||
keyfile:
|
||||
description:
|
||||
- Client key to establish SSL connection.
|
||||
- If this option is specified, also I(cafile) and I(certfile) must be specified.
|
||||
|
||||
|
||||
|
||||
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 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)"
|
||||
'''
|
||||
|
||||
EXAMPLES = '''
|
||||
- name: Publish a message to a queue with headers
|
||||
rabbitmq_publish:
|
||||
url: "amqp://guest:guest@192.168.0.32:5672/%2F"
|
||||
queue: 'test'
|
||||
body: "Hello world from ansible module rabbitmq_publish"
|
||||
content_type: "text/plain"
|
||||
headers:
|
||||
myHeader: myHeaderValue
|
||||
|
||||
|
||||
- name: Publish a file to a queue
|
||||
rabbitmq_publish:
|
||||
url: "amqp://guest:guest@192.168.0.32:5672/%2F"
|
||||
queue: 'images'
|
||||
file: 'path/to/logo.gif'
|
||||
|
||||
- name: RabbitMQ auto generated queue
|
||||
rabbitmq_publish:
|
||||
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 = '''
|
||||
result:
|
||||
description:
|
||||
- Contains the status I(msg), content type I(content_type) and the queue name I(queue).
|
||||
returned: success
|
||||
type: dict
|
||||
sample: |
|
||||
'result': { 'content_type': 'text/plain', 'msg': 'Successfully published to queue test', 'queue': 'test' }
|
||||
'''
|
||||
|
||||
try:
|
||||
import pika
|
||||
HAS_PIKA = True
|
||||
except ImportError:
|
||||
HAS_PIKA = False
|
||||
|
||||
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
from ansible.module_utils._text import to_native, to_text
|
||||
from ansible_collections.community.general.plugins.module_utils.rabbitmq import RabbitClient
|
||||
|
||||
|
||||
def main():
|
||||
argument_spec = RabbitClient.rabbitmq_argument_spec()
|
||||
argument_spec.update(
|
||||
exchange=dict(type='str', default=''),
|
||||
routing_key=dict(type='str', required=False),
|
||||
body=dict(type='str', required=False),
|
||||
src=dict(aliases=['file'], type='path', required=False),
|
||||
content_type=dict(default="text/plain", type='str'),
|
||||
durable=dict(default=False, type='bool'),
|
||||
exclusive=dict(default=False, type='bool'),
|
||||
auto_delete=dict(default=False, type='bool'),
|
||||
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
|
||||
)
|
||||
|
||||
rabbitmq = RabbitClient(module)
|
||||
|
||||
if rabbitmq.basic_publish():
|
||||
rabbitmq.close_connection()
|
||||
module.exit_json(changed=True, result={"msg": "Successfully published to queue %s" % rabbitmq.queue,
|
||||
"queue": rabbitmq.queue,
|
||||
"content_type": rabbitmq.content_type})
|
||||
else:
|
||||
rabbitmq.close_connection()
|
||||
module.fail_json(changed=False, msg="Unsuccessful publishing to queue %s" % rabbitmq.queue)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
|
@ -1 +0,0 @@
|
|||
./messaging/rabbitmq/rabbitmq_binding.py
|
|
@ -1 +0,0 @@
|
|||
./messaging/rabbitmq/rabbitmq_exchange.py
|
|
@ -1 +0,0 @@
|
|||
./messaging/rabbitmq/rabbitmq_global_parameter.py
|
|
@ -1 +0,0 @@
|
|||
./messaging/rabbitmq/rabbitmq_parameter.py
|
|
@ -1 +0,0 @@
|
|||
./messaging/rabbitmq/rabbitmq_plugin.py
|
|
@ -1 +0,0 @@
|
|||
./messaging/rabbitmq/rabbitmq_policy.py
|
|
@ -1 +0,0 @@
|
|||
./notification/rabbitmq_publish.py
|
|
@ -1 +0,0 @@
|
|||
./messaging/rabbitmq/rabbitmq_queue.py
|
|
@ -1 +0,0 @@
|
|||
./messaging/rabbitmq/rabbitmq_user.py
|
|
@ -1 +0,0 @@
|
|||
./messaging/rabbitmq/rabbitmq_vhost.py
|
|
@ -1 +0,0 @@
|
|||
./messaging/rabbitmq/rabbitmq_vhost_limits.py
|
|
@ -1,6 +0,0 @@
|
|||
destructive
|
||||
shippable/posix/group1
|
||||
skip/aix
|
||||
skip/osx
|
||||
skip/freebsd
|
||||
skip/rhel
|
|
@ -1,2 +0,0 @@
|
|||
dependencies:
|
||||
- setup_rabbitmq
|
|
@ -1,3 +0,0 @@
|
|||
---
|
||||
- import_tasks: tests.yml
|
||||
when: ansible_distribution == 'Ubuntu'
|
|
@ -1,132 +0,0 @@
|
|||
---
|
||||
- name: Add test requisites
|
||||
block:
|
||||
- name: Add exchange
|
||||
rabbitmq_exchange:
|
||||
name: "{{ item }}"
|
||||
type: direct
|
||||
with_items:
|
||||
- exchange-foo
|
||||
- exchange-bar
|
||||
|
||||
- name: Add queue
|
||||
rabbitmq_queue:
|
||||
name: queue-foo
|
||||
|
||||
- name: Test add binding in check mode
|
||||
block:
|
||||
- name: Add binding
|
||||
rabbitmq_binding:
|
||||
source: exchange-foo
|
||||
destination: queue-foo
|
||||
type: queue
|
||||
check_mode: true
|
||||
register: add_binding
|
||||
|
||||
- name: Check that binding succeeds with a change
|
||||
assert:
|
||||
that:
|
||||
- add_binding.changed == true
|
||||
|
||||
- name: Test add binding
|
||||
block:
|
||||
- name: Add binding
|
||||
rabbitmq_binding:
|
||||
source: exchange-foo
|
||||
destination: queue-foo
|
||||
type: queue
|
||||
register: add_binding
|
||||
|
||||
- name: Check that binding succeeds with a change
|
||||
assert:
|
||||
that:
|
||||
- add_binding.changed == true
|
||||
|
||||
- name: Test add binding idempotence
|
||||
block:
|
||||
- name: Add binding
|
||||
rabbitmq_binding:
|
||||
source: exchange-foo
|
||||
destination: queue-foo
|
||||
type: queue
|
||||
register: add_binding
|
||||
|
||||
- name: Check that binding succeeds without a change
|
||||
assert:
|
||||
that:
|
||||
- add_binding.changed == false
|
||||
|
||||
- name: Test remove binding in check mode
|
||||
block:
|
||||
- name: Remove binding
|
||||
rabbitmq_binding:
|
||||
source: exchange-foo
|
||||
destination: queue-foo
|
||||
type: queue
|
||||
state: absent
|
||||
check_mode: true
|
||||
register: remove_binding
|
||||
|
||||
- name: Check that binding succeeds with a change
|
||||
assert:
|
||||
that:
|
||||
- remove_binding.changed == true
|
||||
|
||||
- name: Test remove binding
|
||||
block:
|
||||
- name: Remove binding
|
||||
rabbitmq_binding:
|
||||
source: exchange-foo
|
||||
destination: queue-foo
|
||||
type: queue
|
||||
state: absent
|
||||
register: remove_binding
|
||||
|
||||
- name: Check that binding succeeds with a change
|
||||
assert:
|
||||
that:
|
||||
- remove_binding.changed == true
|
||||
|
||||
- name: Test remove binding idempotence
|
||||
block:
|
||||
- name: Remove binding
|
||||
rabbitmq_binding:
|
||||
source: exchange-foo
|
||||
destination: queue-foo
|
||||
type: queue
|
||||
state: absent
|
||||
register: remove_binding
|
||||
|
||||
- name: Check that binding succeeds with a change
|
||||
assert:
|
||||
that:
|
||||
- remove_binding.changed == false
|
||||
|
||||
- name: Test add exchange to exchange binding
|
||||
block:
|
||||
- name: Add binding
|
||||
rabbitmq_binding:
|
||||
source: exchange-foo
|
||||
destination: exchange-bar
|
||||
type: exchange
|
||||
register: add_binding
|
||||
|
||||
- name: Check that binding succeeds with a change
|
||||
assert:
|
||||
that:
|
||||
- add_binding.changed == true
|
||||
|
||||
- name: Test remove exchange to exchange binding
|
||||
block:
|
||||
- name: Remove binding
|
||||
rabbitmq_binding:
|
||||
source: exchange-foo
|
||||
destination: exchange-bar
|
||||
type: exchange
|
||||
state: absent
|
||||
register: remove_binding
|
||||
|
||||
- name: Check that binding succeeds with a change
|
||||
assert:
|
||||
that:
|
||||
- remove_binding.changed == true
|
|
@ -1,6 +0,0 @@
|
|||
destructive
|
||||
shippable/posix/group1
|
||||
skip/aix
|
||||
skip/osx
|
||||
skip/freebsd
|
||||
skip/rhel
|
|
@ -1,2 +0,0 @@
|
|||
dependencies:
|
||||
- setup_rabbitmq
|
|
@ -1,2 +0,0 @@
|
|||
- import_tasks: tests.yml
|
||||
when: ansible_distribution == 'Ubuntu'
|
|
@ -1,71 +0,0 @@
|
|||
- block:
|
||||
- set_fact:
|
||||
plugin_name: rabbitmq_top
|
||||
|
||||
- name: Enable plugin
|
||||
rabbitmq_plugin:
|
||||
name: "{{ plugin_name }}"
|
||||
state: enabled
|
||||
new_only: True
|
||||
register: result
|
||||
|
||||
- name: Get rabbitmq-plugins output
|
||||
shell: "rabbitmq-plugins list | grep {{ plugin_name }}"
|
||||
register: cli_result
|
||||
|
||||
- name: Check that the plugin is enabled
|
||||
assert:
|
||||
that:
|
||||
- result is changed
|
||||
- result is success
|
||||
- '"{{ plugin_name }}" in result.enabled'
|
||||
- result.disabled == []
|
||||
- '"[E" in cli_result.stdout'
|
||||
|
||||
- name: Enable plugin (idempotency)
|
||||
rabbitmq_plugin:
|
||||
name: "{{ plugin_name }}"
|
||||
state: enabled
|
||||
new_only: True
|
||||
register: result
|
||||
|
||||
- name: Check idempotency
|
||||
assert:
|
||||
that:
|
||||
- result is not changed
|
||||
|
||||
- name: Disable plugin
|
||||
rabbitmq_plugin:
|
||||
name: "{{ plugin_name }}"
|
||||
state: disabled
|
||||
register: result
|
||||
|
||||
- name: Get rabbitmq-plugins output
|
||||
shell: "rabbitmq-plugins list | grep {{ plugin_name }}"
|
||||
register: cli_result
|
||||
|
||||
- name: Check that the plugin is disabled
|
||||
assert:
|
||||
that:
|
||||
- result is changed
|
||||
- result is success
|
||||
- result.enabled == []
|
||||
- '"{{ plugin_name }}" in result.disabled'
|
||||
- '"[E" not in cli_result.stdout'
|
||||
|
||||
- name: Disable plugin (idempotency)
|
||||
rabbitmq_plugin:
|
||||
name: "{{ plugin_name }}"
|
||||
state: disabled
|
||||
register: result
|
||||
|
||||
- name: Check idempotency
|
||||
assert:
|
||||
that:
|
||||
- result is not changed
|
||||
|
||||
always:
|
||||
- name: Disable plugin
|
||||
rabbitmq_plugin:
|
||||
name: "{{ plugin_name }}"
|
||||
state: disabled
|
|
@ -1,6 +0,0 @@
|
|||
destructive
|
||||
shippable/posix/group1
|
||||
skip/aix
|
||||
skip/osx
|
||||
skip/freebsd
|
||||
skip/rhel
|
Binary file not shown.
Before Width: | Height: | Size: 43 B |
|
@ -1,3 +0,0 @@
|
|||
dependencies:
|
||||
- setup_rabbitmq
|
||||
- setup_remote_tmp_dir
|
|
@ -1,5 +0,0 @@
|
|||
# Rabbitmq lookup
|
||||
- include: ubuntu.yml
|
||||
when:
|
||||
- ansible_distribution == 'Ubuntu'
|
||||
- ansible_distribution_release != 'trusty'
|
|
@ -1,171 +0,0 @@
|
|||
- name: Install requests and pika
|
||||
pip:
|
||||
name: requests,pika<1.0.0
|
||||
state: present
|
||||
|
||||
- name: RabbitMQ basic publish test
|
||||
rabbitmq_publish:
|
||||
url: "amqp://guest:guest@localhost:5672/%2F"
|
||||
queue: 'publish_test'
|
||||
body: "Hello world from ansible module rabbitmq_publish"
|
||||
content_type: "text/plain"
|
||||
register: rabbit_basic_output1
|
||||
|
||||
- assert:
|
||||
that:
|
||||
- "rabbit_basic_output1 is not failed"
|
||||
- "'publish_test' in rabbit_basic_output1.result.msg"
|
||||
- "'publish_test' in rabbit_basic_output1.result.queue"
|
||||
- "'text/plain' in rabbit_basic_output1.result.content_type"
|
||||
|
||||
|
||||
# Testing random queue
|
||||
- name: Publish to random queue
|
||||
rabbitmq_publish:
|
||||
url: "amqp://guest:guest@localhost:5672/%2F"
|
||||
body: "RANDOM QUEUE POST"
|
||||
content_type: "text/plain"
|
||||
register: rabbit_random_queue_output
|
||||
|
||||
- assert:
|
||||
that:
|
||||
- "rabbit_random_queue_output is not failed"
|
||||
- "'amq.gen' in rabbit_random_queue_output.result.msg"
|
||||
- "'amq.gen' in rabbit_random_queue_output.result.queue"
|
||||
- "'text/plain' in rabbit_random_queue_output.result.content_type"
|
||||
|
||||
- name: Copy binary to remote
|
||||
copy:
|
||||
src: "{{ role_path }}/files/image.gif"
|
||||
dest: "{{ remote_tmp_dir }}/image.gif"
|
||||
|
||||
- name: Publish binary to a queue
|
||||
rabbitmq_publish:
|
||||
url: "amqp://guest:guest@localhost:5672/%2F"
|
||||
queue: publish_test
|
||||
src: "{{ remote_tmp_dir }}/image.gif"
|
||||
register: rabbitmq_publish_file
|
||||
|
||||
- assert:
|
||||
that:
|
||||
- "rabbitmq_publish_file is not failed"
|
||||
- "'publish_test' in rabbitmq_publish_file.result.queue"
|
||||
- "'image/gif' in rabbitmq_publish_file.result.content_type"
|
||||
|
||||
- name: Raise error for src and body defined
|
||||
rabbitmq_publish:
|
||||
url: "amqp://guest:guest@localhost:5672/%2F"
|
||||
queue: 'publish_test'
|
||||
src: "{{ remote_tmp_dir }}/image.gif"
|
||||
body: blah
|
||||
register: rabbit_basic_fail_output1
|
||||
ignore_errors: yes
|
||||
|
||||
- assert:
|
||||
that:
|
||||
- "rabbit_basic_fail_output1 is failed"
|
||||
- "'parameters are mutually exclusive' in rabbit_basic_fail_output1.msg"
|
||||
|
||||
- name: Publish a file that does not exist
|
||||
rabbitmq_publish:
|
||||
url: "amqp://guest:guest@localhost:5672/%2F"
|
||||
queue: 'publish_test'
|
||||
src: 'aaaaaaajax-loader.gif'
|
||||
register: file_missing_fail
|
||||
ignore_errors: yes
|
||||
|
||||
- assert:
|
||||
that:
|
||||
- "file_missing_fail is failed"
|
||||
- "'Unable to open file' in file_missing_fail.msg"
|
||||
|
||||
- name: Publish with proto/host/port/user/pass
|
||||
rabbitmq_publish:
|
||||
proto: amqp
|
||||
host: localhost
|
||||
port: 5672
|
||||
username: guest
|
||||
password: guest
|
||||
vhost: '%2F'
|
||||
queue: publish_test
|
||||
body: Testing with proto/host/port/username/password/vhost
|
||||
register: host_port_output
|
||||
|
||||
- assert:
|
||||
that:
|
||||
- "host_port_output is not failed"
|
||||
|
||||
- name: Publish with host/port/user but missing proto
|
||||
rabbitmq_publish:
|
||||
host: localhost
|
||||
port: 5672
|
||||
username: guest
|
||||
password: guest
|
||||
vhost: '%2F'
|
||||
queue: publish_test
|
||||
body: Testing with proto/host/port/username/password/vhost
|
||||
ignore_errors: yes
|
||||
register: host_port_missing_proto_output
|
||||
|
||||
- assert:
|
||||
that:
|
||||
- "host_port_missing_proto_output is failed"
|
||||
- "'Connection parameters must be passed via' in host_port_missing_proto_output.msg"
|
||||
|
||||
- name: Publish with proto/host/port/user and url
|
||||
rabbitmq_publish:
|
||||
url: "amqp://guest:guest@localhost:5672/%2F"
|
||||
proto: amqp
|
||||
host: localhost
|
||||
port: 5672
|
||||
username: guest
|
||||
password: guest
|
||||
vhost: '%2F'
|
||||
queue: publish_test
|
||||
body: Testing with proto/host/port/username/password/vhost
|
||||
ignore_errors: yes
|
||||
register: host_and_url_output
|
||||
|
||||
- assert:
|
||||
that:
|
||||
- "host_and_url_output is failed"
|
||||
- "'cannot be specified at the same time' in host_and_url_output.msg"
|
||||
|
||||
- name: Publish headers to queue
|
||||
rabbitmq_publish:
|
||||
url: "amqp://guest:guest@localhost:5672/%2F"
|
||||
queue: 'publish_test'
|
||||
body: blah
|
||||
headers:
|
||||
myHeader: Value1
|
||||
secondHeader: Value2
|
||||
register: test_headers1
|
||||
ignore_errors: yes
|
||||
|
||||
- name: Publish headers with file
|
||||
rabbitmq_publish:
|
||||
url: "amqp://guest:guest@localhost:5672/%2F"
|
||||
queue: 'publish_test'
|
||||
src: "{{ remote_tmp_dir }}/image.gif"
|
||||
headers:
|
||||
myHeader: Value1
|
||||
secondHeader: Value2
|
||||
register: test_headers2
|
||||
ignore_errors: yes
|
||||
|
||||
- name: Collect all messages off the publish queue
|
||||
set_fact:
|
||||
messages: "{{ lookup('rabbitmq', url='amqp://guest:guest@localhost:5672/%2F', queue='publish_test') }}"
|
||||
|
||||
- name: Check contents of published messages
|
||||
assert:
|
||||
that:
|
||||
- messages|length == 5
|
||||
- "'Hello world from ansible module rabbitmq_publish' in messages[0]['msg']"
|
||||
- "'text/plain' in messages[0]['content_type']"
|
||||
- "'image/gif' in messages[1]['content_type']"
|
||||
- "'image.gif' in messages[1]['headers']['filename']"
|
||||
- "'Testing with proto/host/port/username/password/vhost' in messages[2]['msg']"
|
||||
# - messages[3]['headers']['myHeader'] is defined
|
||||
# - messages[4]['headers']['filename'] is defined
|
||||
# - messages[4]['headers']['secondHeader'] is defined
|
|
@ -1,6 +0,0 @@
|
|||
destructive
|
||||
shippable/posix/group1
|
||||
skip/aix
|
||||
skip/osx
|
||||
skip/freebsd
|
||||
skip/rhel
|
|
@ -1,2 +0,0 @@
|
|||
dependencies:
|
||||
- setup_rabbitmq
|
|
@ -1,10 +0,0 @@
|
|||
---
|
||||
|
||||
- when: ansible_distribution == 'Ubuntu'
|
||||
block:
|
||||
|
||||
- import_tasks: tests.yml
|
||||
|
||||
- import_tasks: tests.yml
|
||||
environment:
|
||||
RABBITMQ_NODENAME: test
|
|
@ -1,137 +0,0 @@
|
|||
---
|
||||
|
||||
- name: Test add user in check mode
|
||||
block:
|
||||
- name: Add user
|
||||
rabbitmq_user: user=joe password=changeme
|
||||
check_mode: true
|
||||
register: add_user
|
||||
|
||||
- name: Check that user adding succeeds with a change
|
||||
assert:
|
||||
that:
|
||||
- add_user.changed == true
|
||||
|
||||
- name: Test add user
|
||||
block:
|
||||
- name: Add user
|
||||
rabbitmq_user: user=joe password=changeme
|
||||
register: add_user
|
||||
|
||||
- name: Check that user adding succeeds with a change
|
||||
assert:
|
||||
that:
|
||||
- add_user.changed == true
|
||||
|
||||
- name: Test add user idempotence
|
||||
block:
|
||||
- name: Add user
|
||||
rabbitmq_user: user=joe password=changeme
|
||||
register: add_user
|
||||
|
||||
- name: Check that user adding succeeds without a change
|
||||
assert:
|
||||
that:
|
||||
- add_user.changed == false
|
||||
|
||||
- name: Test change user permissions in check mode
|
||||
block:
|
||||
- name: Add user with permissions
|
||||
rabbitmq_user: user=joe password=changeme vhost=/ configure_priv=.* read_priv=.* write_priv=.*
|
||||
check_mode: true
|
||||
register: add_user
|
||||
|
||||
- name: Check that changing permissions succeeds with a change
|
||||
assert:
|
||||
that:
|
||||
- add_user.changed == true
|
||||
|
||||
- name: Test change user permissions
|
||||
block:
|
||||
- name: Add user with permissions
|
||||
rabbitmq_user: user=joe password=changeme vhost=/ configure_priv=.* read_priv=.* write_priv=.*
|
||||
register: add_user
|
||||
|
||||
- name: Check that changing permissions succeeds with a change
|
||||
assert:
|
||||
that:
|
||||
- add_user.changed == true
|
||||
|
||||
- name: Test change user permissions idempotence
|
||||
block:
|
||||
- name: Add user with permissions
|
||||
rabbitmq_user: user=joe password=changeme vhost=/ configure_priv=.* read_priv=.* write_priv=.*
|
||||
register: add_user
|
||||
|
||||
- name: Check that changing permissions succeeds without a change
|
||||
assert:
|
||||
that:
|
||||
- add_user.changed == false
|
||||
|
||||
- name: Test add user tags in check mode
|
||||
block:
|
||||
- name: Add user with tags
|
||||
rabbitmq_user: user=joe password=changeme vhost=/ configure_priv=.* read_priv=.* write_priv=.* tags=management,administrator
|
||||
check_mode: true
|
||||
register: add_user
|
||||
|
||||
- name: Check that adding tags succeeds with a change
|
||||
assert:
|
||||
that:
|
||||
- add_user.changed == true
|
||||
|
||||
- name: Test add user tags
|
||||
block:
|
||||
- name: Add user with tags
|
||||
rabbitmq_user: user=joe password=changeme vhost=/ configure_priv=.* read_priv=.* write_priv=.* tags=management,administrator
|
||||
register: add_user
|
||||
|
||||
- name: Check that adding tags succeeds with a change
|
||||
assert:
|
||||
that:
|
||||
- add_user.changed == true
|
||||
|
||||
- name: Test add user tags idempotence
|
||||
block:
|
||||
- name: Add user with tags
|
||||
rabbitmq_user: user=joe password=changeme vhost=/ configure_priv=.* read_priv=.* write_priv=.* tags=administrator,management
|
||||
register: add_user
|
||||
|
||||
- name: Check that adding tags succeeds without a change
|
||||
assert:
|
||||
that:
|
||||
- add_user.changed == false
|
||||
|
||||
- name: Test remove user in check mode
|
||||
block:
|
||||
- name: Remove user
|
||||
rabbitmq_user: user=joe state=absent
|
||||
check_mode: true
|
||||
register: remove_user
|
||||
|
||||
- name: Check that user removing succeeds with a change
|
||||
assert:
|
||||
that:
|
||||
- remove_user.changed == true
|
||||
|
||||
- name: Test remove user
|
||||
block:
|
||||
- name: Remove user
|
||||
rabbitmq_user: user=joe state=absent
|
||||
register: remove_user
|
||||
|
||||
- name: Check that user removing succeeds with a change
|
||||
assert:
|
||||
that:
|
||||
- remove_user.changed == true
|
||||
|
||||
- name: Test remove user idempotence
|
||||
block:
|
||||
- name: Remove user
|
||||
rabbitmq_user: user=joe state=absent
|
||||
register: remove_user
|
||||
|
||||
- name: Check that user removing succeeds without a change
|
||||
assert:
|
||||
that:
|
||||
- remove_user.changed == false
|
|
@ -1,6 +0,0 @@
|
|||
destructive
|
||||
shippable/posix/group1
|
||||
skip/aix
|
||||
skip/osx
|
||||
skip/freebsd
|
||||
skip/rhel
|
|
@ -1,2 +0,0 @@
|
|||
dependencies:
|
||||
- setup_rabbitmq
|
|
@ -1,2 +0,0 @@
|
|||
- import_tasks: tests.yml
|
||||
when: ansible_distribution == 'Ubuntu'
|
|
@ -1,121 +0,0 @@
|
|||
- block:
|
||||
- set_fact:
|
||||
vhost_name: /test
|
||||
|
||||
- name: Add host
|
||||
rabbitmq_vhost:
|
||||
name: "{{ vhost_name }}"
|
||||
state: present
|
||||
register: result
|
||||
|
||||
- name: Check that the host was created successfuly
|
||||
shell: "rabbitmqctl list_vhosts name tracing | grep {{ vhost_name }}"
|
||||
register: ctl_result
|
||||
|
||||
- name: Check that the host is added
|
||||
assert:
|
||||
that:
|
||||
- result is changed
|
||||
- result is success
|
||||
- '"false" in ctl_result.stdout' # value for tracing, false is disabled
|
||||
|
||||
- name: Add host (idempotency)
|
||||
rabbitmq_vhost:
|
||||
name: "{{ vhost_name }}"
|
||||
state: present
|
||||
register: result
|
||||
|
||||
- name: Check idempotency
|
||||
assert:
|
||||
that:
|
||||
- result is not changed
|
||||
|
||||
- name: Enable tracing
|
||||
rabbitmq_vhost:
|
||||
name: "{{ vhost_name }}"
|
||||
tracing: yes
|
||||
register: result
|
||||
|
||||
- name: Get rabbitmqctl output
|
||||
shell: "rabbitmqctl list_vhosts name tracing | grep {{ vhost_name }}"
|
||||
register: ctl_result
|
||||
|
||||
- name: Check that tracing is enabled
|
||||
assert:
|
||||
that:
|
||||
- result is changed
|
||||
- result is success
|
||||
- '"true" in ctl_result.stdout' # value for tracing, true is enabled
|
||||
|
||||
- name: Enable tracing (idempotency)
|
||||
rabbitmq_vhost:
|
||||
name: "{{ vhost_name }}"
|
||||
tracing: yes
|
||||
register: result
|
||||
|
||||
- name: Check idempotency
|
||||
assert:
|
||||
that:
|
||||
- result is not changed
|
||||
|
||||
- name: Disable tracing
|
||||
rabbitmq_vhost:
|
||||
name: "{{ vhost_name }}"
|
||||
tracing: no
|
||||
register: result
|
||||
|
||||
- name: Get rabbitmqctl output
|
||||
shell: "rabbitmqctl list_vhosts name tracing | grep {{ vhost_name }}"
|
||||
register: ctl_result
|
||||
|
||||
- name: Check that tracing is disabled
|
||||
assert:
|
||||
that:
|
||||
- result is changed
|
||||
- result is success
|
||||
- '"false" in ctl_result.stdout' # value for tracing, false is disabled
|
||||
|
||||
- name: Disable tracing (idempotency)
|
||||
rabbitmq_vhost:
|
||||
name: "{{ vhost_name }}"
|
||||
tracing: no
|
||||
register: result
|
||||
|
||||
- name: Check idempotency
|
||||
assert:
|
||||
that:
|
||||
- result is not changed
|
||||
|
||||
- name: Remove host
|
||||
rabbitmq_vhost:
|
||||
name: "{{ vhost_name }}"
|
||||
state: absent
|
||||
register: result
|
||||
|
||||
- name: Get rabbitmqctl output
|
||||
shell: "rabbitmqctl list_vhosts name tracing | grep {{ vhost_name }}"
|
||||
register: ctl_result
|
||||
failed_when: ctl_result.rc == 0
|
||||
|
||||
- name: Check that the host is removed
|
||||
assert:
|
||||
that:
|
||||
- result is changed
|
||||
- result is success
|
||||
|
||||
- name: Remove host (idempotency)
|
||||
rabbitmq_vhost:
|
||||
name: "{{ vhost_name }}"
|
||||
state: absent
|
||||
register: result
|
||||
|
||||
- name: Check idempotency
|
||||
assert:
|
||||
that:
|
||||
- result is not changed
|
||||
|
||||
always:
|
||||
- name: Remove host
|
||||
rabbitmq_vhost:
|
||||
name: "{{ vhost_name }}"
|
||||
state: absent
|
|
@ -1,6 +0,0 @@
|
|||
destructive
|
||||
shippable/posix/group1
|
||||
skip/aix
|
||||
skip/osx
|
||||
skip/freebsd
|
||||
skip/rhel
|
|
@ -1,2 +0,0 @@
|
|||
dependencies:
|
||||
- setup_rabbitmq
|
|
@ -1,5 +0,0 @@
|
|||
# Rabbitmq lookup
|
||||
- include: ubuntu.yml
|
||||
when:
|
||||
- ansible_distribution == 'Ubuntu'
|
||||
- ansible_distribution_release != 'trusty'
|
|
@ -1,163 +0,0 @@
|
|||
---
|
||||
|
||||
- name: Test setting virtual host limits in check mode
|
||||
block:
|
||||
- name: Set virtual host limits in check mode
|
||||
rabbitmq_vhost_limits:
|
||||
vhost: /
|
||||
max_connections: 64
|
||||
max_queues: 256
|
||||
state: present
|
||||
check_mode: true
|
||||
register: module_result
|
||||
|
||||
- name: Check that the module's result is correct
|
||||
assert:
|
||||
that:
|
||||
- module_result is changed
|
||||
- module_result is success
|
||||
|
||||
- name: Get a list of configured virtual host limits
|
||||
shell: "rabbitmqctl list_vhost_limits"
|
||||
register: shell_result
|
||||
|
||||
- name: Check that the check mode does not make any changes
|
||||
assert:
|
||||
that:
|
||||
- shell_result is success
|
||||
- "'\"max-connections\":64' not in shell_result.stdout"
|
||||
- "'\"max-queues\":256' not in shell_result.stdout"
|
||||
|
||||
- name: Test setting virtual host limits
|
||||
block:
|
||||
- name: Set virtual host limits
|
||||
rabbitmq_vhost_limits:
|
||||
vhost: /
|
||||
max_connections: 64
|
||||
max_queues: 256
|
||||
state: present
|
||||
register: module_result
|
||||
|
||||
- name: Check that the module's result is correct
|
||||
assert:
|
||||
that:
|
||||
- module_result is changed
|
||||
- module_result is success
|
||||
|
||||
- name: Get a list of configured virtual host limits
|
||||
shell: "rabbitmqctl list_vhost_limits"
|
||||
register: shell_result
|
||||
|
||||
- name: Check that the virtual host limits are actually set
|
||||
assert:
|
||||
that:
|
||||
- shell_result is success
|
||||
- "'\"max-connections\":64' in shell_result.stdout"
|
||||
- "'\"max-queues\":256' in shell_result.stdout"
|
||||
|
||||
- name: Test setting virtual host limits (idempotence)
|
||||
block:
|
||||
- name: Set virtual host limits (idempotence)
|
||||
rabbitmq_vhost_limits:
|
||||
vhost: /
|
||||
max_connections: 64
|
||||
max_queues: 256
|
||||
state: present
|
||||
register: module_result
|
||||
|
||||
- name: Check the idempotence
|
||||
assert:
|
||||
that:
|
||||
- module_result is not changed
|
||||
- module_result is success
|
||||
|
||||
- name: Test changing virtual host limits
|
||||
block:
|
||||
- name: Change virtual host limits
|
||||
rabbitmq_vhost_limits:
|
||||
vhost: /
|
||||
max_connections: 32
|
||||
state: present
|
||||
register: module_result
|
||||
|
||||
- name: Check that the module's result is correct
|
||||
assert:
|
||||
that:
|
||||
- module_result is changed
|
||||
- module_result is success
|
||||
|
||||
- name: Get a list of configured virtual host limits
|
||||
shell: "rabbitmqctl list_vhost_limits"
|
||||
register: shell_result
|
||||
|
||||
- name: Check that the virtual host limits are actually set
|
||||
assert:
|
||||
that:
|
||||
- shell_result is success
|
||||
- "'\"max-connections\":32' in shell_result.stdout"
|
||||
- "'\"max-queues\":-1' in shell_result.stdout"
|
||||
|
||||
- name: Test clearing virtual host limits in check mode
|
||||
block:
|
||||
- name: Clear virtual host limits in check mode
|
||||
rabbitmq_vhost_limits:
|
||||
vhost: /
|
||||
state: absent
|
||||
check_mode: true
|
||||
register: module_result
|
||||
|
||||
- name: Check that the module's result is correct
|
||||
assert:
|
||||
that:
|
||||
- module_result is changed
|
||||
- module_result is success
|
||||
|
||||
- name: Get a list of configured virtual host limits
|
||||
shell: "rabbitmqctl list_vhost_limits"
|
||||
register: shell_result
|
||||
|
||||
- name: Check that the check mode does not make any changes
|
||||
assert:
|
||||
that:
|
||||
- shell_result is success
|
||||
- "'\"max-connections\":32' in shell_result.stdout"
|
||||
- "'\"max-queues\":-1' in shell_result.stdout"
|
||||
|
||||
- name: Test clearing virtual host limits
|
||||
block:
|
||||
- name: Clear virtual host limits
|
||||
rabbitmq_vhost_limits:
|
||||
vhost: /
|
||||
state: absent
|
||||
register: module_result
|
||||
|
||||
- name: Check that the module's result is correct
|
||||
assert:
|
||||
that:
|
||||
- module_result is changed
|
||||
- module_result is success
|
||||
|
||||
- name: Get a list of configured virtual host limits
|
||||
shell: "rabbitmqctl list_vhost_limits"
|
||||
register: shell_result
|
||||
|
||||
- name: Check that the virtual host limits are actually cleared
|
||||
assert:
|
||||
that:
|
||||
- shell_result is success
|
||||
- "'\"max-connections\":' not in shell_result.stdout"
|
||||
- "'\"max-queues\":' not in shell_result.stdout"
|
||||
|
||||
- name: Test clearing virtual host limits (idempotence)
|
||||
block:
|
||||
- name: Clear virtual host limits (idempotence)
|
||||
rabbitmq_vhost_limits:
|
||||
vhost: /
|
||||
state: absent
|
||||
register: module_result
|
||||
|
||||
- name: Check the idempotence
|
||||
assert:
|
||||
that:
|
||||
- module_result is not changed
|
||||
- module_result is success
|
|
@ -1,8 +0,0 @@
|
|||
listeners.ssl.default = 5671
|
||||
|
||||
ssl_options.cacertfile = /tls/ca_certificate.pem
|
||||
ssl_options.certfile = /tls/server_certificate.pem
|
||||
ssl_options.keyfile = /tls/server_key.pem
|
||||
ssl_options.password = bunnies
|
||||
ssl_options.verify = verify_peer
|
||||
ssl_options.fail_if_no_peer_cert = false
|
|
@ -988,26 +988,6 @@ plugins/modules/identity/keycloak/keycloak_clienttemplate.py validate-modules:pa
|
|||
plugins/modules/identity/onepassword_info.py validate-modules:parameter-list-no-elements
|
||||
plugins/modules/identity/opendj/opendj_backendprop.py validate-modules:doc-missing-type
|
||||
plugins/modules/identity/opendj/opendj_backendprop.py validate-modules:parameter-type-not-in-doc
|
||||
plugins/modules/messaging/rabbitmq/rabbitmq_binding.py validate-modules:doc-default-does-not-match-spec
|
||||
plugins/modules/messaging/rabbitmq/rabbitmq_binding.py validate-modules:parameter-type-not-in-doc
|
||||
plugins/modules/messaging/rabbitmq/rabbitmq_exchange.py validate-modules:doc-choices-do-not-match-spec
|
||||
plugins/modules/messaging/rabbitmq/rabbitmq_exchange.py validate-modules:doc-default-does-not-match-spec
|
||||
plugins/modules/messaging/rabbitmq/rabbitmq_exchange.py validate-modules:parameter-type-not-in-doc
|
||||
plugins/modules/messaging/rabbitmq/rabbitmq_global_parameter.py validate-modules:doc-missing-type
|
||||
plugins/modules/messaging/rabbitmq/rabbitmq_global_parameter.py validate-modules:parameter-type-not-in-doc
|
||||
plugins/modules/messaging/rabbitmq/rabbitmq_parameter.py validate-modules:doc-missing-type
|
||||
plugins/modules/messaging/rabbitmq/rabbitmq_plugin.py validate-modules:doc-missing-type
|
||||
plugins/modules/messaging/rabbitmq/rabbitmq_policy.py validate-modules:doc-default-does-not-match-spec
|
||||
plugins/modules/messaging/rabbitmq/rabbitmq_policy.py validate-modules:doc-missing-type
|
||||
plugins/modules/messaging/rabbitmq/rabbitmq_policy.py validate-modules:parameter-type-not-in-doc
|
||||
plugins/modules/messaging/rabbitmq/rabbitmq_queue.py validate-modules:doc-default-does-not-match-spec
|
||||
plugins/modules/messaging/rabbitmq/rabbitmq_queue.py validate-modules:doc-default-incompatible-type
|
||||
plugins/modules/messaging/rabbitmq/rabbitmq_queue.py validate-modules:parameter-type-not-in-doc
|
||||
plugins/modules/messaging/rabbitmq/rabbitmq_user.py validate-modules:doc-missing-type
|
||||
plugins/modules/messaging/rabbitmq/rabbitmq_user.py validate-modules:parameter-list-no-elements
|
||||
plugins/modules/messaging/rabbitmq/rabbitmq_user.py validate-modules:parameter-type-not-in-doc
|
||||
plugins/modules/messaging/rabbitmq/rabbitmq_vhost.py validate-modules:doc-missing-type
|
||||
plugins/modules/messaging/rabbitmq/rabbitmq_vhost_limits.py validate-modules:parameter-type-not-in-doc
|
||||
plugins/modules/monitoring/airbrake_deployment.py validate-modules:doc-default-does-not-match-spec
|
||||
plugins/modules/monitoring/airbrake_deployment.py validate-modules:doc-missing-type
|
||||
plugins/modules/monitoring/bigpanda.py validate-modules:doc-default-does-not-match-spec
|
||||
|
@ -2806,7 +2786,6 @@ plugins/modules/notification/pushover.py validate-modules:doc-choices-do-not-mat
|
|||
plugins/modules/notification/pushover.py validate-modules:doc-default-does-not-match-spec
|
||||
plugins/modules/notification/pushover.py validate-modules:doc-missing-type
|
||||
plugins/modules/notification/pushover.py validate-modules:parameter-type-not-in-doc
|
||||
plugins/modules/notification/rabbitmq_publish.py validate-modules:parameter-type-not-in-doc
|
||||
plugins/modules/notification/rocketchat.py validate-modules:no-default-for-required-parameter
|
||||
plugins/modules/notification/rocketchat.py validate-modules:parameter-list-no-elements
|
||||
plugins/modules/notification/rocketchat.py validate-modules:parameter-type-not-in-doc
|
||||
|
@ -3490,8 +3469,6 @@ plugins/doc_fragments/proxysql.py future-import-boilerplate
|
|||
plugins/doc_fragments/proxysql.py metaclass-boilerplate
|
||||
plugins/doc_fragments/purestorage.py future-import-boilerplate
|
||||
plugins/doc_fragments/purestorage.py metaclass-boilerplate
|
||||
plugins/doc_fragments/rabbitmq.py future-import-boilerplate
|
||||
plugins/doc_fragments/rabbitmq.py metaclass-boilerplate
|
||||
plugins/doc_fragments/rackspace.py future-import-boilerplate
|
||||
plugins/doc_fragments/rackspace.py metaclass-boilerplate
|
||||
plugins/doc_fragments/scaleway.py future-import-boilerplate
|
||||
|
@ -3589,8 +3566,6 @@ tests/unit/modules/cloud/xenserver/FakeXenAPI.py future-import-boilerplate
|
|||
tests/unit/modules/cloud/xenserver/FakeXenAPI.py metaclass-boilerplate
|
||||
tests/unit/modules/conftest.py future-import-boilerplate
|
||||
tests/unit/modules/conftest.py metaclass-boilerplate
|
||||
tests/unit/modules/messaging/rabbitmq/test_rabbitmq_user.py future-import-boilerplate
|
||||
tests/unit/modules/messaging/rabbitmq/test_rabbitmq_user.py metaclass-boilerplate
|
||||
tests/unit/modules/monitoring/test_circonus_annotation.py future-import-boilerplate
|
||||
tests/unit/modules/monitoring/test_circonus_annotation.py metaclass-boilerplate
|
||||
tests/unit/modules/monitoring/test_icinga2_feature.py future-import-boilerplate
|
||||
|
|
|
@ -1,134 +0,0 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
from ansible_collections.community.general.plugins.modules.messaging.rabbitmq import rabbitmq_user
|
||||
from ansible_collections.community.general.tests.unit.compat.mock import patch
|
||||
from ansible_collections.community.general.tests.unit.modules.utils import AnsibleExitJson, AnsibleFailJson, ModuleTestCase, set_module_args
|
||||
|
||||
|
||||
class TestRabbitMQUserModule(ModuleTestCase):
|
||||
def setUp(self):
|
||||
super(TestRabbitMQUserModule, self).setUp()
|
||||
self.module = rabbitmq_user
|
||||
|
||||
def tearDown(self):
|
||||
super(TestRabbitMQUserModule, self).tearDown()
|
||||
|
||||
def _assert(self, exc, attribute, expected_value, msg=""):
|
||||
value = exc.message[attribute] if hasattr(exc, attribute) else exc.args[0][attribute]
|
||||
assert value == expected_value, msg
|
||||
|
||||
def test_without_required_parameters(self):
|
||||
"""Failure must occurs when all parameters are missing"""
|
||||
with self.assertRaises(AnsibleFailJson):
|
||||
set_module_args({})
|
||||
self.module.main()
|
||||
|
||||
def test_permissions_with_same_vhost(self):
|
||||
set_module_args({
|
||||
'user': 'someuser',
|
||||
'password': 'somepassword',
|
||||
'state': 'present',
|
||||
'permissions': [{'vhost': '/'}, {'vhost': '/'}],
|
||||
})
|
||||
with patch('ansible.module_utils.basic.AnsibleModule.get_bin_path') as get_bin_path:
|
||||
get_bin_path.return_value = '/rabbitmqctl'
|
||||
try:
|
||||
self.module.main()
|
||||
except AnsibleFailJson as e:
|
||||
self._assert(e, 'failed', True)
|
||||
self._assert(e, 'msg',
|
||||
"Error parsing permissions: You can't have two permission dicts for the same vhost")
|
||||
|
||||
@patch('ansible.module_utils.basic.AnsibleModule.get_bin_path')
|
||||
@patch('ansible_collections.community.general.plugins.modules.messaging.rabbitmq.rabbitmq_user.RabbitMqUser.get')
|
||||
@patch('ansible_collections.community.general.plugins.modules.messaging.rabbitmq.rabbitmq_user.RabbitMqUser.check_password')
|
||||
@patch('ansible_collections.community.general.plugins.modules.messaging.rabbitmq.rabbitmq_user.RabbitMqUser.has_tags_modifications')
|
||||
@patch('ansible_collections.community.general.plugins.modules.messaging.rabbitmq.rabbitmq_user.RabbitMqUser.has_permissions_modifications')
|
||||
def test_password_changes_only_when_needed(self, has_permissions_modifications, has_tags_modifications,
|
||||
check_password, get, get_bin_path):
|
||||
set_module_args({
|
||||
'user': 'someuser',
|
||||
'password': 'somepassword',
|
||||
'state': 'present',
|
||||
'update_password': 'always',
|
||||
})
|
||||
get.return_value = True
|
||||
get_bin_path.return_value = '/rabbitmqctl'
|
||||
check_password.return_value = True
|
||||
has_tags_modifications.return_value = False
|
||||
has_permissions_modifications.return_value = False
|
||||
try:
|
||||
self.module.main()
|
||||
except AnsibleExitJson as e:
|
||||
self._assert(e, 'changed', False)
|
||||
self._assert(e, 'state', 'present')
|
||||
|
||||
@patch('ansible.module_utils.basic.AnsibleModule.get_bin_path')
|
||||
@patch('ansible_collections.community.general.plugins.modules.messaging.rabbitmq.rabbitmq_user.RabbitMqUser._exec')
|
||||
@patch('ansible_collections.community.general.plugins.modules.messaging.rabbitmq.rabbitmq_user.RabbitMqUser._get_permissions')
|
||||
@patch('ansible_collections.community.general.plugins.modules.messaging.rabbitmq.rabbitmq_user.RabbitMqUser.has_tags_modifications')
|
||||
def test_same_permissions_not_changing(self, has_tags_modifications, _get_permissions, _exec, get_bin_path):
|
||||
set_module_args({
|
||||
'user': 'someuser',
|
||||
'password': 'somepassword',
|
||||
'state': 'present',
|
||||
'permissions': [{'vhost': '/', 'configure_priv': '.*', 'write_priv': '.*', 'read_priv': '.*'}],
|
||||
})
|
||||
_get_permissions.return_value = [{'vhost': '/', 'configure_priv': '.*', 'write_priv': '.*', 'read_priv': '.*'}]
|
||||
_exec.return_value = ['someuser\t[]']
|
||||
get_bin_path.return_value = '/rabbitmqctl'
|
||||
has_tags_modifications.return_value = False
|
||||
try:
|
||||
self.module.main()
|
||||
except AnsibleExitJson as e:
|
||||
self._assert(e, 'changed', False)
|
||||
self._assert(e, 'state', 'present')
|
||||
|
||||
@patch('ansible.module_utils.basic.AnsibleModule.get_bin_path')
|
||||
@patch('ansible_collections.community.general.plugins.modules.messaging.rabbitmq.rabbitmq_user.RabbitMqUser._exec')
|
||||
@patch('ansible_collections.community.general.plugins.modules.messaging.rabbitmq.rabbitmq_user.RabbitMqUser._get_permissions')
|
||||
@patch('ansible_collections.community.general.plugins.modules.messaging.rabbitmq.rabbitmq_user.RabbitMqUser.set_permissions')
|
||||
@patch('ansible_collections.community.general.plugins.modules.messaging.rabbitmq.rabbitmq_user.RabbitMqUser.has_tags_modifications')
|
||||
def test_permissions_are_fixed(self, has_tags_modifications, set_permissions, _get_permissions, _exec, get_bin_path):
|
||||
set_module_args({
|
||||
'user': 'someuser',
|
||||
'password': 'somepassword',
|
||||
'state': 'present',
|
||||
'permissions': [{'vhost': '/', 'configure_priv': '.*', 'write_priv': '.*', 'read_priv': '.*'}],
|
||||
})
|
||||
set_permissions.return_value = None
|
||||
_get_permissions.return_value = []
|
||||
_exec.return_value = ['someuser\t[]']
|
||||
get_bin_path.return_value = '/rabbitmqctl'
|
||||
has_tags_modifications.return_value = False
|
||||
try:
|
||||
self.module.main()
|
||||
except AnsibleExitJson as e:
|
||||
self._assert(e, 'changed', True)
|
||||
self._assert(e, 'state', 'present')
|
||||
assert set_permissions.call_count == 1
|
||||
|
||||
@patch('ansible.module_utils.basic.AnsibleModule.get_bin_path')
|
||||
@patch('ansible_collections.community.general.plugins.modules.messaging.rabbitmq.rabbitmq_user.RabbitMqUser._exec')
|
||||
@patch('ansible_collections.community.general.plugins.modules.messaging.rabbitmq.rabbitmq_user.RabbitMqUser._get_permissions')
|
||||
@patch('ansible_collections.community.general.plugins.modules.messaging.rabbitmq.rabbitmq_user.RabbitMqUser.set_permissions')
|
||||
@patch('ansible_collections.community.general.plugins.modules.messaging.rabbitmq.rabbitmq_user.RabbitMqUser.has_tags_modifications')
|
||||
def test_permissions_are_fixed_with_different_host(self, has_tags_modifications, set_permissions, _get_permissions,
|
||||
_exec, get_bin_path):
|
||||
set_module_args({
|
||||
'user': 'someuser',
|
||||
'password': 'somepassword',
|
||||
'state': 'present',
|
||||
'permissions': [{'vhost': '/', 'configure_priv': '.*', 'write_priv': '.*', 'read_priv': '.*'}],
|
||||
})
|
||||
set_permissions.return_value = None
|
||||
_get_permissions.return_value = [{'vhost': 'monitoring', 'configure_priv': '.*', 'write_priv': '.*', 'read_priv': '.*'}]
|
||||
_exec.return_value = ['someuser\t[]']
|
||||
get_bin_path.return_value = '/rabbitmqctl'
|
||||
has_tags_modifications.return_value = False
|
||||
try:
|
||||
self.module.main()
|
||||
except AnsibleExitJson as e:
|
||||
self._assert(e, 'changed', True)
|
||||
self._assert(e, 'state', 'present')
|
||||
assert set_permissions.call_count == 1
|
Loading…
Reference in a new issue