mirror of
https://github.com/ansible-collections/community.general.git
synced 2026-05-08 22:33:25 +00:00
Relocating extras into lib/ansible/modules/ after merge
This commit is contained in:
committed by
Matt Clay
parent
c65ba07d2c
commit
011ea55a8f
0
lib/ansible/modules/messaging/__init__.py
Normal file
0
lib/ansible/modules/messaging/__init__.py
Normal file
233
lib/ansible/modules/messaging/rabbitmq_binding.py
Normal file
233
lib/ansible/modules/messaging/rabbitmq_binding.py
Normal file
@@ -0,0 +1,233 @@
|
||||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# (c) 2015, Manuel Sousa <manuel.sousa@gmail.com>
|
||||
#
|
||||
# This file is part of Ansible
|
||||
#
|
||||
# Ansible is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# Ansible is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
|
||||
ANSIBLE_METADATA = {'status': ['preview'],
|
||||
'supported_by': 'community',
|
||||
'version': '1.0'}
|
||||
|
||||
DOCUMENTATION = '''
|
||||
---
|
||||
module: rabbitmq_binding
|
||||
author: "Manuel Sousa (@manuel-sousa)"
|
||||
version_added: "2.0"
|
||||
|
||||
short_description: This module manages rabbitMQ bindings
|
||||
description:
|
||||
- This module uses rabbitMQ Rest API to create/delete bindings
|
||||
requirements: [ "requests >= 1.0.0" ]
|
||||
options:
|
||||
state:
|
||||
description:
|
||||
- Whether the exchange should be present or absent
|
||||
- Only present implemented atm
|
||||
choices: [ "present", "absent" ]
|
||||
required: false
|
||||
default: present
|
||||
name:
|
||||
description:
|
||||
- source exchange to create binding on
|
||||
required: true
|
||||
aliases: [ "src", "source" ]
|
||||
login_user:
|
||||
description:
|
||||
- rabbitMQ user for connection
|
||||
required: false
|
||||
default: guest
|
||||
login_password:
|
||||
description:
|
||||
- rabbitMQ password for connection
|
||||
required: false
|
||||
default: false
|
||||
login_host:
|
||||
description:
|
||||
- rabbitMQ host for connection
|
||||
required: false
|
||||
default: localhost
|
||||
login_port:
|
||||
description:
|
||||
- rabbitMQ management api port
|
||||
required: false
|
||||
default: 15672
|
||||
vhost:
|
||||
description:
|
||||
- rabbitMQ virtual host
|
||||
- default vhost is /
|
||||
required: false
|
||||
default: "/"
|
||||
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 is #
|
||||
required: false
|
||||
default: "#"
|
||||
arguments:
|
||||
description:
|
||||
- extra arguments for exchange. If defined this argument is a key/value dictionary
|
||||
required: false
|
||||
default: {}
|
||||
'''
|
||||
|
||||
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 requests
|
||||
import urllib
|
||||
import json
|
||||
|
||||
def main():
|
||||
module = AnsibleModule(
|
||||
argument_spec = dict(
|
||||
state = dict(default='present', choices=['present', 'absent'], type='str'),
|
||||
name = dict(required=True, aliases=[ "src", "source" ], type='str'),
|
||||
login_user = dict(default='guest', type='str'),
|
||||
login_password = dict(default='guest', type='str', no_log=True),
|
||||
login_host = dict(default='localhost', type='str'),
|
||||
login_port = dict(default='15672', type='str'),
|
||||
vhost = dict(default='/', 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')
|
||||
),
|
||||
supports_check_mode = True
|
||||
)
|
||||
|
||||
if module.params['destination_type'] == "queue":
|
||||
dest_type="q"
|
||||
else:
|
||||
dest_type="e"
|
||||
|
||||
if module.params['routing_key'] == "":
|
||||
props = "~"
|
||||
else:
|
||||
props = urllib.quote(module.params['routing_key'],'')
|
||||
|
||||
url = "http://%s:%s/api/bindings/%s/e/%s/%s/%s/%s" % (
|
||||
module.params['login_host'],
|
||||
module.params['login_port'],
|
||||
urllib.quote(module.params['vhost'],''),
|
||||
urllib.quote(module.params['name'],''),
|
||||
dest_type,
|
||||
urllib.quote(module.params['destination'],''),
|
||||
props
|
||||
)
|
||||
|
||||
# Check if exchange already exists
|
||||
r = requests.get( url, auth=(module.params['login_user'],module.params['login_password']))
|
||||
|
||||
if r.status_code==200:
|
||||
binding_exists = True
|
||||
response = r.json()
|
||||
elif r.status_code==404:
|
||||
binding_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 binding_exists
|
||||
else:
|
||||
change_required = binding_exists
|
||||
|
||||
# Exit if check_mode
|
||||
if module.check_mode:
|
||||
module.exit_json(
|
||||
changed= change_required,
|
||||
name = module.params['name'],
|
||||
details = response,
|
||||
arguments = module.params['arguments']
|
||||
)
|
||||
|
||||
# Do changes
|
||||
if change_required:
|
||||
if module.params['state'] == 'present':
|
||||
url = "http://%s:%s/api/bindings/%s/e/%s/%s/%s" % (
|
||||
module.params['login_host'],
|
||||
module.params['login_port'],
|
||||
urllib.quote(module.params['vhost'],''),
|
||||
urllib.quote(module.params['name'],''),
|
||||
dest_type,
|
||||
urllib.quote(module.params['destination'],'')
|
||||
)
|
||||
|
||||
r = requests.post(
|
||||
url,
|
||||
auth = (module.params['login_user'],module.params['login_password']),
|
||||
headers = { "content-type": "application/json"},
|
||||
data = json.dumps({
|
||||
"routing_key": module.params['routing_key'],
|
||||
"arguments": module.params['arguments']
|
||||
})
|
||||
)
|
||||
elif module.params['state'] == 'absent':
|
||||
r = requests.delete( url, auth = (module.params['login_user'],module.params['login_password']))
|
||||
|
||||
if r.status_code == 204 or r.status_code == 201:
|
||||
module.exit_json(
|
||||
changed = True,
|
||||
name = module.params['name'],
|
||||
destination = module.params['destination']
|
||||
)
|
||||
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']
|
||||
)
|
||||
|
||||
# import module snippets
|
||||
from ansible.module_utils.basic import *
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
228
lib/ansible/modules/messaging/rabbitmq_exchange.py
Normal file
228
lib/ansible/modules/messaging/rabbitmq_exchange.py
Normal file
@@ -0,0 +1,228 @@
|
||||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# (c) 2015, Manuel Sousa <manuel.sousa@gmail.com>
|
||||
#
|
||||
# This file is part of Ansible
|
||||
#
|
||||
# Ansible is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# Ansible is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
|
||||
ANSIBLE_METADATA = {'status': ['preview'],
|
||||
'supported_by': 'community',
|
||||
'version': '1.0'}
|
||||
|
||||
DOCUMENTATION = '''
|
||||
---
|
||||
module: rabbitmq_exchange
|
||||
author: "Manuel Sousa (@manuel-sousa)"
|
||||
version_added: "2.0"
|
||||
|
||||
short_description: This module manages 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
|
||||
- Only present implemented atm
|
||||
choices: [ "present", "absent" ]
|
||||
required: false
|
||||
default: present
|
||||
login_user:
|
||||
description:
|
||||
- rabbitMQ user for connection
|
||||
required: false
|
||||
default: guest
|
||||
login_password:
|
||||
description:
|
||||
- rabbitMQ password for connection
|
||||
required: false
|
||||
default: false
|
||||
login_host:
|
||||
description:
|
||||
- rabbitMQ host for connection
|
||||
required: false
|
||||
default: localhost
|
||||
login_port:
|
||||
description:
|
||||
- rabbitMQ management api port
|
||||
required: false
|
||||
default: 15672
|
||||
vhost:
|
||||
description:
|
||||
- rabbitMQ virtual host
|
||||
required: false
|
||||
default: "/"
|
||||
durable:
|
||||
description:
|
||||
- whether exchange is durable or not
|
||||
required: false
|
||||
choices: [ "yes", "no" ]
|
||||
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
|
||||
choices: [ "yes", "no" ]
|
||||
default: no
|
||||
internal:
|
||||
description:
|
||||
- exchange is available only for other exchanges
|
||||
required: false
|
||||
choices: [ "yes", "no" ]
|
||||
default: no
|
||||
arguments:
|
||||
description:
|
||||
- extra arguments for exchange. If defined this argument is a key/value dictionary
|
||||
required: false
|
||||
default: {}
|
||||
'''
|
||||
|
||||
EXAMPLES = '''
|
||||
# Create direct exchange
|
||||
- rabbitmq_exchange:
|
||||
name: directExchange
|
||||
|
||||
# Create topic exchange on vhost
|
||||
- rabbitmq_exchange:
|
||||
name: topicExchange
|
||||
type: topic
|
||||
vhost: myVhost
|
||||
'''
|
||||
|
||||
import requests
|
||||
import urllib
|
||||
import json
|
||||
|
||||
def main():
|
||||
module = AnsibleModule(
|
||||
argument_spec = dict(
|
||||
state = dict(default='present', choices=['present', 'absent'], type='str'),
|
||||
name = dict(required=True, type='str'),
|
||||
login_user = dict(default='guest', type='str'),
|
||||
login_password = dict(default='guest', type='str', no_log=True),
|
||||
login_host = dict(default='localhost', type='str'),
|
||||
login_port = dict(default='15672', type='str'),
|
||||
vhost = dict(default='/', 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')
|
||||
),
|
||||
supports_check_mode = True
|
||||
)
|
||||
|
||||
url = "http://%s:%s/api/exchanges/%s/%s" % (
|
||||
module.params['login_host'],
|
||||
module.params['login_port'],
|
||||
urllib.quote(module.params['vhost'],''),
|
||||
urllib.quote(module.params['name'],'')
|
||||
)
|
||||
|
||||
# Check if exchange already exists
|
||||
r = requests.get( url, auth=(module.params['login_user'],module.params['login_password']))
|
||||
|
||||
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:
|
||||
module.exit_json(
|
||||
changed= change_required,
|
||||
name = module.params['name'],
|
||||
details = response,
|
||||
arguments = module.params['arguments']
|
||||
)
|
||||
|
||||
# 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']
|
||||
})
|
||||
)
|
||||
elif module.params['state'] == 'absent':
|
||||
r = requests.delete( url, auth = (module.params['login_user'],module.params['login_password']))
|
||||
|
||||
if r.status_code == 204:
|
||||
module.exit_json(
|
||||
changed = True,
|
||||
name = module.params['name']
|
||||
)
|
||||
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']
|
||||
)
|
||||
|
||||
# import module snippets
|
||||
from ansible.module_utils.basic import *
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
166
lib/ansible/modules/messaging/rabbitmq_parameter.py
Normal file
166
lib/ansible/modules/messaging/rabbitmq_parameter.py
Normal file
@@ -0,0 +1,166 @@
|
||||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# (c) 2013, Chatham Financial <oss@chathamfinancial.com>
|
||||
#
|
||||
# This file is part of Ansible
|
||||
#
|
||||
# Ansible is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# Ansible is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
ANSIBLE_METADATA = {'status': ['preview'],
|
||||
'supported_by': 'community',
|
||||
'version': '1.0'}
|
||||
|
||||
DOCUMENTATION = '''
|
||||
---
|
||||
module: rabbitmq_parameter
|
||||
short_description: Adds or removes parameters to RabbitMQ
|
||||
description:
|
||||
- Manage dynamic, cluster-wide parameters for RabbitMQ
|
||||
version_added: "1.1"
|
||||
author: '"Chris Hoffman (@chrishoffman)"'
|
||||
options:
|
||||
component:
|
||||
description:
|
||||
- Name of the component of which the parameter is being set
|
||||
required: true
|
||||
default: null
|
||||
name:
|
||||
description:
|
||||
- Name of the parameter being set
|
||||
required: true
|
||||
default: null
|
||||
value:
|
||||
description:
|
||||
- Value of the parameter, as a JSON term
|
||||
required: false
|
||||
default: null
|
||||
vhost:
|
||||
description:
|
||||
- vhost to apply access privileges.
|
||||
required: false
|
||||
default: /
|
||||
node:
|
||||
description:
|
||||
- erlang node name of the rabbit we wish to configure
|
||||
required: false
|
||||
default: rabbit
|
||||
version_added: "1.2"
|
||||
state:
|
||||
description:
|
||||
- Specify if user is to be added or removed
|
||||
required: false
|
||||
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
|
||||
"""
|
||||
|
||||
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.splitlines()
|
||||
return list()
|
||||
|
||||
def get(self):
|
||||
parameters = self._exec(['list_parameters', '-p', self.vhost], True)
|
||||
|
||||
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']
|
||||
|
||||
rabbitmq_parameter = RabbitMqParameter(module, component, name, value, vhost, node)
|
||||
|
||||
changed = False
|
||||
if rabbitmq_parameter.get():
|
||||
if state == 'absent':
|
||||
rabbitmq_parameter.delete()
|
||||
changed = True
|
||||
else:
|
||||
if rabbitmq_parameter.has_modifications():
|
||||
rabbitmq_parameter.set()
|
||||
changed = True
|
||||
elif state == 'present':
|
||||
rabbitmq_parameter.set()
|
||||
changed = True
|
||||
|
||||
module.exit_json(changed=changed, component=component, name=name, vhost=vhost, state=state)
|
||||
|
||||
# import module snippets
|
||||
from ansible.module_utils.basic import *
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
158
lib/ansible/modules/messaging/rabbitmq_plugin.py
Normal file
158
lib/ansible/modules/messaging/rabbitmq_plugin.py
Normal file
@@ -0,0 +1,158 @@
|
||||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# (c) 2013, Chatham Financial <oss@chathamfinancial.com>
|
||||
#
|
||||
# This file is part of Ansible
|
||||
#
|
||||
# Ansible is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# Ansible is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
ANSIBLE_METADATA = {'status': ['preview'],
|
||||
'supported_by': 'community',
|
||||
'version': '1.0'}
|
||||
|
||||
DOCUMENTATION = '''
|
||||
---
|
||||
module: rabbitmq_plugin
|
||||
short_description: Adds or removes plugins to RabbitMQ
|
||||
description:
|
||||
- Enables or disables RabbitMQ plugins
|
||||
version_added: "1.1"
|
||||
author: '"Chris Hoffman (@chrishoffman)"'
|
||||
options:
|
||||
names:
|
||||
description:
|
||||
- Comma-separated list of plugin names
|
||||
required: true
|
||||
default: null
|
||||
aliases: [name]
|
||||
new_only:
|
||||
description:
|
||||
- Only enable missing plugins
|
||||
- Does not disable plugins that are not in the names list
|
||||
required: false
|
||||
default: "no"
|
||||
choices: [ "yes", "no" ]
|
||||
state:
|
||||
description:
|
||||
- Specify if plugins are to be enabled or disabled
|
||||
required: false
|
||||
default: enabled
|
||||
choices: [enabled, disabled]
|
||||
prefix:
|
||||
description:
|
||||
- Specify a custom install prefix to a Rabbit
|
||||
required: false
|
||||
version_added: "1.3"
|
||||
default: null
|
||||
'''
|
||||
|
||||
EXAMPLES = '''
|
||||
# Enables the rabbitmq_management plugin
|
||||
- rabbitmq_plugin:
|
||||
names: rabbitmq_management
|
||||
state: enabled
|
||||
'''
|
||||
|
||||
import os
|
||||
|
||||
class RabbitMqPlugins(object):
|
||||
def __init__(self, module):
|
||||
self.module = module
|
||||
|
||||
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.
|
||||
raise Exception("No binary folder in prefix %s" %
|
||||
module.params['prefix'])
|
||||
|
||||
self._rabbitmq_plugins = 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
|
||||
)
|
||||
|
||||
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 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)
|
||||
|
||||
changed = len(enabled) > 0 or len(disabled) > 0
|
||||
module.exit_json(changed=changed, enabled=enabled, disabled=disabled)
|
||||
|
||||
# import module snippets
|
||||
from ansible.module_utils.basic import *
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
180
lib/ansible/modules/messaging/rabbitmq_policy.py
Normal file
180
lib/ansible/modules/messaging/rabbitmq_policy.py
Normal file
@@ -0,0 +1,180 @@
|
||||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# (c) 2013, John Dewey <john@dewey.ws>
|
||||
#
|
||||
# This file is part of Ansible
|
||||
#
|
||||
# Ansible is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# Ansible is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
|
||||
ANSIBLE_METADATA = {'status': ['preview'],
|
||||
'supported_by': 'community',
|
||||
'version': '1.0'}
|
||||
|
||||
DOCUMENTATION = '''
|
||||
---
|
||||
module: rabbitmq_policy
|
||||
short_description: Manage the state of policies in RabbitMQ.
|
||||
description:
|
||||
- Manage the state of a virtual host in RabbitMQ.
|
||||
version_added: "1.5"
|
||||
author: "John Dewey (@retr0h)"
|
||||
options:
|
||||
name:
|
||||
description:
|
||||
- The name of the policy to manage.
|
||||
required: true
|
||||
default: null
|
||||
vhost:
|
||||
description:
|
||||
- The name of the vhost to apply to.
|
||||
required: false
|
||||
default: /
|
||||
apply_to:
|
||||
description:
|
||||
- What the policy applies to. Requires RabbitMQ 3.2.0 or later.
|
||||
required: false
|
||||
default: all
|
||||
choices: [all, exchanges, queues]
|
||||
version_added: "2.1"
|
||||
pattern:
|
||||
description:
|
||||
- A regex of queues to apply the policy to.
|
||||
required: true
|
||||
default: null
|
||||
tags:
|
||||
description:
|
||||
- A dict or string describing the policy.
|
||||
required: true
|
||||
default: null
|
||||
priority:
|
||||
description:
|
||||
- The priority of the policy.
|
||||
required: false
|
||||
default: 0
|
||||
node:
|
||||
description:
|
||||
- Erlang node name of the rabbit we wish to configure.
|
||||
required: false
|
||||
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
|
||||
'''
|
||||
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)
|
||||
|
||||
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]
|
||||
args.insert(1, '-p')
|
||||
args.insert(2, self._vhost)
|
||||
rc, out, err = self._module.run_command(cmd + args, check_rc=True)
|
||||
return out.splitlines()
|
||||
return list()
|
||||
|
||||
def list(self):
|
||||
policies = self._exec(['list_policies'], True)
|
||||
|
||||
for policy in policies:
|
||||
policy_name = policy.split('\t')[1]
|
||||
if policy_name == self._name:
|
||||
return True
|
||||
return False
|
||||
|
||||
def set(self):
|
||||
import json
|
||||
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 main():
|
||||
arg_spec = dict(
|
||||
name=dict(required=True),
|
||||
vhost=dict(default='/'),
|
||||
pattern=dict(required=True),
|
||||
apply_to=dict(default='all', choices=['all', 'exchanges', 'queues']),
|
||||
tags=dict(type='dict', required=True),
|
||||
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)
|
||||
|
||||
changed = False
|
||||
if rabbitmq_policy.list():
|
||||
if state == 'absent':
|
||||
rabbitmq_policy.clear()
|
||||
changed = True
|
||||
else:
|
||||
changed = False
|
||||
elif state == 'present':
|
||||
rabbitmq_policy.set()
|
||||
changed = True
|
||||
|
||||
module.exit_json(changed=changed, name=name, state=state)
|
||||
|
||||
# import module snippets
|
||||
from ansible.module_utils.basic import *
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
274
lib/ansible/modules/messaging/rabbitmq_queue.py
Normal file
274
lib/ansible/modules/messaging/rabbitmq_queue.py
Normal file
@@ -0,0 +1,274 @@
|
||||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# (c) 2015, Manuel Sousa <manuel.sousa@gmail.com>
|
||||
#
|
||||
# This file is part of Ansible
|
||||
#
|
||||
# Ansible is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# Ansible is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
|
||||
ANSIBLE_METADATA = {'status': ['preview'],
|
||||
'supported_by': 'community',
|
||||
'version': '1.0'}
|
||||
|
||||
DOCUMENTATION = '''
|
||||
---
|
||||
module: rabbitmq_queue
|
||||
author: "Manuel Sousa (@manuel-sousa)"
|
||||
version_added: "2.0"
|
||||
|
||||
short_description: This module manages 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 to create
|
||||
required: true
|
||||
state:
|
||||
description:
|
||||
- Whether the queue should be present or absent
|
||||
- Only present implemented atm
|
||||
choices: [ "present", "absent" ]
|
||||
required: false
|
||||
default: present
|
||||
login_user:
|
||||
description:
|
||||
- rabbitMQ user for connection
|
||||
required: false
|
||||
default: guest
|
||||
login_password:
|
||||
description:
|
||||
- rabbitMQ password for connection
|
||||
required: false
|
||||
default: false
|
||||
login_host:
|
||||
description:
|
||||
- rabbitMQ host for connection
|
||||
required: false
|
||||
default: localhost
|
||||
login_port:
|
||||
description:
|
||||
- rabbitMQ management api port
|
||||
required: false
|
||||
default: 15672
|
||||
vhost:
|
||||
description:
|
||||
- rabbitMQ virtual host
|
||||
required: false
|
||||
default: "/"
|
||||
durable:
|
||||
description:
|
||||
- whether queue is durable or not
|
||||
required: false
|
||||
choices: [ "yes", "no" ]
|
||||
default: yes
|
||||
auto_delete:
|
||||
description:
|
||||
- if the queue should delete itself after all queues/queues unbound from it
|
||||
required: false
|
||||
choices: [ "yes", "no" ]
|
||||
default: no
|
||||
message_ttl:
|
||||
description:
|
||||
- How long a message can live in queue before it is discarded (milliseconds)
|
||||
required: False
|
||||
default: forever
|
||||
auto_expires:
|
||||
description:
|
||||
- How long a queue can be unused before it is automatically deleted (milliseconds)
|
||||
required: false
|
||||
default: forever
|
||||
max_length:
|
||||
description:
|
||||
- How many messages can the queue contain before it starts rejecting
|
||||
required: false
|
||||
default: no limit
|
||||
dead_letter_exchange:
|
||||
description:
|
||||
- Optional name of an exchange to which messages will be republished if they
|
||||
- are rejected or expire
|
||||
required: false
|
||||
default: None
|
||||
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
|
||||
required: false
|
||||
default: None
|
||||
arguments:
|
||||
description:
|
||||
- extra arguments for queue. If defined this argument is a key/value dictionary
|
||||
required: false
|
||||
default: {}
|
||||
'''
|
||||
|
||||
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 requests
|
||||
import urllib
|
||||
import json
|
||||
|
||||
def main():
|
||||
module = AnsibleModule(
|
||||
argument_spec = dict(
|
||||
state = dict(default='present', choices=['present', 'absent'], type='str'),
|
||||
name = dict(required=True, type='str'),
|
||||
login_user = dict(default='guest', type='str'),
|
||||
login_password = dict(default='guest', type='str', no_log=True),
|
||||
login_host = dict(default='localhost', type='str'),
|
||||
login_port = dict(default='15672', type='str'),
|
||||
vhost = dict(default='/', 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')
|
||||
),
|
||||
supports_check_mode = True
|
||||
)
|
||||
|
||||
url = "http://%s:%s/api/queues/%s/%s" % (
|
||||
module.params['login_host'],
|
||||
module.params['login_port'],
|
||||
urllib.quote(module.params['vhost'],''),
|
||||
module.params['name']
|
||||
)
|
||||
|
||||
# Check if queue already exists
|
||||
r = requests.get( url, auth=(module.params['login_user'],module.params['login_password']))
|
||||
|
||||
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 )
|
||||
)
|
||||
):
|
||||
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'
|
||||
}.items():
|
||||
if module.params[k]:
|
||||
module.params['arguments'][v] = module.params[k]
|
||||
|
||||
# Exit if check_mode
|
||||
if module.check_mode:
|
||||
module.exit_json(
|
||||
changed= change_required,
|
||||
name = module.params['name'],
|
||||
details = response,
|
||||
arguments = module.params['arguments']
|
||||
)
|
||||
|
||||
# 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']
|
||||
})
|
||||
)
|
||||
elif module.params['state'] == 'absent':
|
||||
r = requests.delete( url, auth = (module.params['login_user'],module.params['login_password']))
|
||||
|
||||
if r.status_code == 204:
|
||||
module.exit_json(
|
||||
changed = True,
|
||||
name = module.params['name']
|
||||
)
|
||||
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']
|
||||
)
|
||||
|
||||
# import module snippets
|
||||
from ansible.module_utils.basic import *
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
314
lib/ansible/modules/messaging/rabbitmq_user.py
Normal file
314
lib/ansible/modules/messaging/rabbitmq_user.py
Normal file
@@ -0,0 +1,314 @@
|
||||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# (c) 2013, Chatham Financial <oss@chathamfinancial.com>
|
||||
#
|
||||
# This file is part of Ansible
|
||||
#
|
||||
# Ansible is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# Ansible is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
ANSIBLE_METADATA = {'status': ['preview'],
|
||||
'supported_by': 'community',
|
||||
'version': '1.0'}
|
||||
|
||||
DOCUMENTATION = '''
|
||||
---
|
||||
module: rabbitmq_user
|
||||
short_description: Adds or removes users to RabbitMQ
|
||||
description:
|
||||
- Add or remove users to RabbitMQ and assign permissions
|
||||
version_added: "1.1"
|
||||
author: '"Chris Hoffman (@chrishoffman)"'
|
||||
options:
|
||||
user:
|
||||
description:
|
||||
- Name of user to add
|
||||
required: true
|
||||
default: null
|
||||
aliases: [username, name]
|
||||
password:
|
||||
description:
|
||||
- Password of user to add.
|
||||
- To change the password of an existing user, you must also specify
|
||||
C(force=yes).
|
||||
required: false
|
||||
default: null
|
||||
tags:
|
||||
description:
|
||||
- User tags specified as comma delimited
|
||||
required: false
|
||||
default: null
|
||||
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.
|
||||
required: false
|
||||
default: []
|
||||
vhost:
|
||||
description:
|
||||
- vhost to apply access privileges.
|
||||
- This option will be ignored when permissions option is used.
|
||||
required: false
|
||||
default: /
|
||||
node:
|
||||
description:
|
||||
- erlang node name of the rabbit we wish to configure
|
||||
required: false
|
||||
default: rabbit
|
||||
version_added: "1.2"
|
||||
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.
|
||||
required: false
|
||||
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.
|
||||
required: false
|
||||
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.
|
||||
required: false
|
||||
default: ^$
|
||||
force:
|
||||
description:
|
||||
- Deletes and recreates the user.
|
||||
required: false
|
||||
default: "no"
|
||||
choices: [ "yes", "no" ]
|
||||
state:
|
||||
description:
|
||||
- Specify if user is to be added or removed
|
||||
required: false
|
||||
default: present
|
||||
choices: [present, absent]
|
||||
'''
|
||||
|
||||
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
|
||||
'''
|
||||
|
||||
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):
|
||||
if not self.module.check_mode or (self.module.check_mode and run_in_check_mode):
|
||||
cmd = [self._rabbitmqctl, '-q']
|
||||
if self.node is not None:
|
||||
cmd.extend(['-n', self.node])
|
||||
rc, out, err = self.module.run_command(cmd + args, check_rc=True)
|
||||
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):
|
||||
perms_out = self._exec(['list_user_permissions', self.username], True)
|
||||
|
||||
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 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 set_tags(self):
|
||||
self._exec(['set_user_tags', self.username] + self.tags)
|
||||
|
||||
def set_permissions(self):
|
||||
for permission in self._permissions:
|
||||
if permission not in self.permissions:
|
||||
cmd = ['clear_permissions', '-p']
|
||||
cmd.append(permission['vhost'])
|
||||
cmd.append(self.username)
|
||||
self._exec(cmd)
|
||||
for permission in self.permissions:
|
||||
if permission not in self._permissions:
|
||||
cmd = ['set_permissions', '-p']
|
||||
cmd.append(permission['vhost'])
|
||||
cmd.append(self.username)
|
||||
cmd.append(permission['configure_priv'])
|
||||
cmd.append(permission['write_priv'])
|
||||
cmd.append(permission['read_priv'])
|
||||
self._exec(cmd)
|
||||
|
||||
def has_tags_modifications(self):
|
||||
return set(self.tags) != set(self._tags)
|
||||
|
||||
def has_permissions_modifications(self):
|
||||
return self._permissions != self.permissions
|
||||
|
||||
def main():
|
||||
arg_spec = dict(
|
||||
user=dict(required=True, aliases=['username', 'name']),
|
||||
password=dict(default=None),
|
||||
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=None)
|
||||
)
|
||||
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']
|
||||
|
||||
bulk_permissions = True
|
||||
if permissions == []:
|
||||
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)
|
||||
|
||||
changed = False
|
||||
if rabbitmq_user.get():
|
||||
if state == 'absent':
|
||||
rabbitmq_user.delete()
|
||||
changed = True
|
||||
else:
|
||||
if force:
|
||||
rabbitmq_user.delete()
|
||||
rabbitmq_user.add()
|
||||
rabbitmq_user.get()
|
||||
changed = True
|
||||
|
||||
if rabbitmq_user.has_tags_modifications():
|
||||
rabbitmq_user.set_tags()
|
||||
changed = True
|
||||
|
||||
if rabbitmq_user.has_permissions_modifications():
|
||||
rabbitmq_user.set_permissions()
|
||||
changed = True
|
||||
elif state == 'present':
|
||||
rabbitmq_user.add()
|
||||
rabbitmq_user.set_tags()
|
||||
rabbitmq_user.set_permissions()
|
||||
changed = True
|
||||
|
||||
module.exit_json(changed=changed, user=username, state=state)
|
||||
|
||||
# import module snippets
|
||||
from ansible.module_utils.basic import *
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
155
lib/ansible/modules/messaging/rabbitmq_vhost.py
Normal file
155
lib/ansible/modules/messaging/rabbitmq_vhost.py
Normal file
@@ -0,0 +1,155 @@
|
||||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# (c) 2013, Chatham Financial <oss@chathamfinancial.com>
|
||||
#
|
||||
# This file is part of Ansible
|
||||
#
|
||||
# Ansible is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# Ansible is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
|
||||
ANSIBLE_METADATA = {'status': ['preview'],
|
||||
'supported_by': 'community',
|
||||
'version': '1.0'}
|
||||
|
||||
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
|
||||
version_added: "1.1"
|
||||
author: '"Chris Hoffman (@choffman)"'
|
||||
options:
|
||||
name:
|
||||
description:
|
||||
- The name of the vhost to manage
|
||||
required: true
|
||||
default: null
|
||||
aliases: [vhost]
|
||||
node:
|
||||
description:
|
||||
- erlang node name of the rabbit we wish to configure
|
||||
required: false
|
||||
default: rabbit
|
||||
version_added: "1.2"
|
||||
tracing:
|
||||
description:
|
||||
- Enable/disable tracing for a vhost
|
||||
default: "no"
|
||||
choices: [ "yes", "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
|
||||
'''
|
||||
|
||||
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:
|
||||
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']
|
||||
|
||||
rabbitmq_vhost = RabbitMqVhost(module, name, tracing, node)
|
||||
|
||||
changed = False
|
||||
if rabbitmq_vhost.get():
|
||||
if state == 'absent':
|
||||
rabbitmq_vhost.delete()
|
||||
changed = True
|
||||
else:
|
||||
if rabbitmq_vhost.set_tracing():
|
||||
changed = True
|
||||
elif state == 'present':
|
||||
rabbitmq_vhost.add()
|
||||
rabbitmq_vhost.set_tracing()
|
||||
changed = True
|
||||
|
||||
module.exit_json(changed=changed, name=name, state=state)
|
||||
|
||||
# import module snippets
|
||||
from ansible.module_utils.basic import *
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
Reference in New Issue
Block a user