mirror of
https://github.com/ansible-collections/community.general.git
synced 2025-08-02 12:14:25 -07:00
Merge pull request #8500 from sivel/rax-de-dupe
rax: Move additional shared code into module utils
This commit is contained in:
commit
d0205b2878
17 changed files with 232 additions and 400 deletions
|
@ -25,11 +25,13 @@ import shlex
|
||||||
from ansible import errors
|
from ansible import errors
|
||||||
from ansible import utils
|
from ansible import utils
|
||||||
from ansible import constants as C
|
from ansible import constants as C
|
||||||
|
from ansible import __version__
|
||||||
|
|
||||||
REPLACER = "#<<INCLUDE_ANSIBLE_MODULE_COMMON>>"
|
REPLACER = "#<<INCLUDE_ANSIBLE_MODULE_COMMON>>"
|
||||||
REPLACER_ARGS = "\"<<INCLUDE_ANSIBLE_MODULE_ARGS>>\""
|
REPLACER_ARGS = "\"<<INCLUDE_ANSIBLE_MODULE_ARGS>>\""
|
||||||
REPLACER_COMPLEX = "\"<<INCLUDE_ANSIBLE_MODULE_COMPLEX_ARGS>>\""
|
REPLACER_COMPLEX = "\"<<INCLUDE_ANSIBLE_MODULE_COMPLEX_ARGS>>\""
|
||||||
REPLACER_WINDOWS = "# POWERSHELL_COMMON"
|
REPLACER_WINDOWS = "# POWERSHELL_COMMON"
|
||||||
|
REPLACER_VERSION = "\"<<ANSIBLE_VERSION>>\""
|
||||||
|
|
||||||
class ModuleReplacer(object):
|
class ModuleReplacer(object):
|
||||||
|
|
||||||
|
@ -156,6 +158,7 @@ class ModuleReplacer(object):
|
||||||
encoded_complex = repr(complex_args_json)
|
encoded_complex = repr(complex_args_json)
|
||||||
|
|
||||||
# these strings should be part of the 'basic' snippet which is required to be included
|
# these strings should be part of the 'basic' snippet which is required to be included
|
||||||
|
module_data = module_data.replace(REPLACER_VERSION, repr(__version__))
|
||||||
module_data = module_data.replace(REPLACER_ARGS, encoded_args)
|
module_data = module_data.replace(REPLACER_ARGS, encoded_args)
|
||||||
module_data = module_data.replace(REPLACER_COMPLEX, encoded_complex)
|
module_data = module_data.replace(REPLACER_COMPLEX, encoded_complex)
|
||||||
|
|
||||||
|
|
|
@ -29,6 +29,8 @@
|
||||||
|
|
||||||
# == BEGIN DYNAMICALLY INSERTED CODE ==
|
# == BEGIN DYNAMICALLY INSERTED CODE ==
|
||||||
|
|
||||||
|
ANSIBLE_VERSION = "<<ANSIBLE_VERSION>>"
|
||||||
|
|
||||||
MODULE_ARGS = "<<INCLUDE_ANSIBLE_MODULE_ARGS>>"
|
MODULE_ARGS = "<<INCLUDE_ANSIBLE_MODULE_ARGS>>"
|
||||||
MODULE_COMPLEX_ARGS = "<<INCLUDE_ANSIBLE_MODULE_COMPLEX_ARGS>>"
|
MODULE_COMPLEX_ARGS = "<<INCLUDE_ANSIBLE_MODULE_COMPLEX_ARGS>>"
|
||||||
|
|
||||||
|
|
|
@ -1,32 +1,197 @@
|
||||||
# This code is part of Ansible, but is an independent component.
|
# This code is part of Ansible, but is an independent component.
|
||||||
# This particular file snippet, and this file snippet only, is BSD licensed.
|
# This particular file snippet, and this file snippet only, is BSD licensed.
|
||||||
# Modules you write using this snippet, which is embedded dynamically by Ansible
|
# Modules you write using this snippet, which is embedded dynamically by
|
||||||
# still belong to the author of the module, and may assign their own license
|
# Ansible still belong to the author of the module, and may assign their own
|
||||||
# to the complete work.
|
# license to the complete work.
|
||||||
#
|
#
|
||||||
# Copyright (c), Michael DeHaan <michael.dehaan@gmail.com>, 2012-2013
|
# Copyright (c), Michael DeHaan <michael.dehaan@gmail.com>, 2012-2013
|
||||||
# All rights reserved.
|
# All rights reserved.
|
||||||
#
|
#
|
||||||
# Redistribution and use in source and binary forms, with or without modification,
|
# Redistribution and use in source and binary forms, with or without
|
||||||
# are permitted provided that the following conditions are met:
|
# modification, are permitted provided that the following conditions are met:
|
||||||
#
|
#
|
||||||
# * Redistributions of source code must retain the above copyright
|
# * Redistributions of source code must retain the above copyright
|
||||||
# notice, this list of conditions and the following disclaimer.
|
# notice, this list of conditions and the following disclaimer.
|
||||||
# * Redistributions in binary form must reproduce the above copyright notice,
|
# * Redistributions in binary form must reproduce the above copyright
|
||||||
# this list of conditions and the following disclaimer in the documentation
|
# notice, this list of conditions and the following disclaimer in the
|
||||||
# and/or other materials provided with the distribution.
|
# documentation and/or other materials provided with the distribution.
|
||||||
#
|
#
|
||||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
# IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||||
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
# USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
# POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
from uuid import UUID
|
||||||
|
|
||||||
|
|
||||||
|
FINAL_STATUSES = ('ACTIVE', 'ERROR')
|
||||||
|
VOLUME_STATUS = ('available', 'attaching', 'creating', 'deleting', 'in-use',
|
||||||
|
'error', 'error_deleting')
|
||||||
|
|
||||||
|
CLB_ALGORITHMS = ['RANDOM', 'LEAST_CONNECTIONS', 'ROUND_ROBIN',
|
||||||
|
'WEIGHTED_LEAST_CONNECTIONS', 'WEIGHTED_ROUND_ROBIN']
|
||||||
|
CLB_PROTOCOLS = ['DNS_TCP', 'DNS_UDP', 'FTP', 'HTTP', 'HTTPS', 'IMAPS',
|
||||||
|
'IMAPv4', 'LDAP', 'LDAPS', 'MYSQL', 'POP3', 'POP3S', 'SMTP',
|
||||||
|
'TCP', 'TCP_CLIENT_FIRST', 'UDP', 'UDP_STREAM', 'SFTP']
|
||||||
|
|
||||||
|
NON_CALLABLES = (basestring, bool, dict, int, list, type(None))
|
||||||
|
PUBLIC_NET_ID = "00000000-0000-0000-0000-000000000000"
|
||||||
|
SERVICE_NET_ID = "11111111-1111-1111-1111-111111111111"
|
||||||
|
|
||||||
|
|
||||||
|
def rax_slugify(value):
|
||||||
|
"""Prepend a key with rax_ and normalize the key name"""
|
||||||
|
return 'rax_%s' % (re.sub('[^\w-]', '_', value).lower().lstrip('_'))
|
||||||
|
|
||||||
|
|
||||||
|
def rax_clb_node_to_dict(obj):
|
||||||
|
"""Function to convert a CLB Node object to a dict"""
|
||||||
|
if not obj:
|
||||||
|
return {}
|
||||||
|
node = obj.to_dict()
|
||||||
|
node['id'] = obj.id
|
||||||
|
node['weight'] = obj.weight
|
||||||
|
return node
|
||||||
|
|
||||||
|
|
||||||
|
def rax_to_dict(obj, obj_type='standard'):
|
||||||
|
"""Generic function to convert a pyrax object to a dict
|
||||||
|
|
||||||
|
obj_type values:
|
||||||
|
standard
|
||||||
|
clb
|
||||||
|
server
|
||||||
|
|
||||||
|
"""
|
||||||
|
instance = {}
|
||||||
|
for key in dir(obj):
|
||||||
|
value = getattr(obj, key)
|
||||||
|
if obj_type == 'clb' and key == 'nodes':
|
||||||
|
instance[key] = []
|
||||||
|
for node in value:
|
||||||
|
instance[key].append(rax_clb_node_to_dict(node))
|
||||||
|
elif (isinstance(value, list) and len(value) > 0 and
|
||||||
|
not isinstance(value[0], NON_CALLABLES)):
|
||||||
|
instance[key] = []
|
||||||
|
for item in value:
|
||||||
|
instance[key].append(rax_to_dict(item))
|
||||||
|
elif (isinstance(value, NON_CALLABLES) and not key.startswith('_')):
|
||||||
|
if obj_type == 'server':
|
||||||
|
key = rax_slugify(key)
|
||||||
|
instance[key] = value
|
||||||
|
|
||||||
|
if obj_type == 'server':
|
||||||
|
for attr in ['id', 'accessIPv4', 'name', 'status']:
|
||||||
|
instance[attr] = instance.get(rax_slugify(attr))
|
||||||
|
|
||||||
|
return instance
|
||||||
|
|
||||||
|
|
||||||
|
def rax_find_image(module, rax_module, image):
|
||||||
|
cs = rax_module.cloudservers
|
||||||
|
try:
|
||||||
|
UUID(image)
|
||||||
|
except ValueError:
|
||||||
|
try:
|
||||||
|
image = cs.images.find(human_id=image)
|
||||||
|
except(cs.exceptions.NotFound,
|
||||||
|
cs.exceptions.NoUniqueMatch):
|
||||||
|
try:
|
||||||
|
image = cs.images.find(name=image)
|
||||||
|
except (cs.exceptions.NotFound,
|
||||||
|
cs.exceptions.NoUniqueMatch):
|
||||||
|
module.fail_json(msg='No matching image found (%s)' %
|
||||||
|
image)
|
||||||
|
|
||||||
|
return rax_module.utils.get_id(image)
|
||||||
|
|
||||||
|
|
||||||
|
def rax_find_volume(module, rax_module, name):
|
||||||
|
cbs = rax_module.cloud_blockstorage
|
||||||
|
try:
|
||||||
|
UUID(name)
|
||||||
|
volume = cbs.get(name)
|
||||||
|
except ValueError:
|
||||||
|
try:
|
||||||
|
volume = cbs.find(name=name)
|
||||||
|
except rax_module.exc.NotFound:
|
||||||
|
volume = None
|
||||||
|
except Exception, e:
|
||||||
|
module.fail_json(msg='%s' % e)
|
||||||
|
return volume
|
||||||
|
|
||||||
|
|
||||||
|
def rax_find_network(module, rax_module, network):
|
||||||
|
cnw = rax_module.cloud_networks
|
||||||
|
try:
|
||||||
|
UUID(network)
|
||||||
|
except ValueError:
|
||||||
|
if network.lower() == 'public':
|
||||||
|
return cnw.get_server_networks(PUBLIC_NET_ID)
|
||||||
|
elif network.lower() == 'private':
|
||||||
|
return cnw.get_server_networks(SERVICE_NET_ID)
|
||||||
|
else:
|
||||||
|
try:
|
||||||
|
network_obj = cnw.find_network_by_label(network)
|
||||||
|
except (rax_module.exceptions.NetworkNotFound,
|
||||||
|
rax_module.exceptions.NetworkLabelNotUnique):
|
||||||
|
module.fail_json(msg='No matching network found (%s)' %
|
||||||
|
network)
|
||||||
|
else:
|
||||||
|
return cnw.get_server_networks(network_obj)
|
||||||
|
else:
|
||||||
|
return cnw.get_server_networks(network)
|
||||||
|
|
||||||
|
|
||||||
|
def rax_find_server(module, rax_module, server):
|
||||||
|
cs = rax_module.cloudservers
|
||||||
|
try:
|
||||||
|
UUID(server)
|
||||||
|
server = cs.servers.get(server)
|
||||||
|
except ValueError:
|
||||||
|
servers = cs.servers.list(search_opts=dict(name='^%s$' % server))
|
||||||
|
if not servers:
|
||||||
|
module.fail_json(msg='No Server was matched by name, '
|
||||||
|
'try using the Server ID instead')
|
||||||
|
if len(servers) > 1:
|
||||||
|
module.fail_json(msg='Multiple servers matched by name, '
|
||||||
|
'try using the Server ID instead')
|
||||||
|
|
||||||
|
# We made it this far, grab the first and hopefully only server
|
||||||
|
# in the list
|
||||||
|
server = servers[0]
|
||||||
|
return server
|
||||||
|
|
||||||
|
|
||||||
|
def rax_find_loadbalancer(module, rax_module, loadbalancer):
|
||||||
|
clb = rax_module.cloud_loadbalancers
|
||||||
|
try:
|
||||||
|
UUID(loadbalancer)
|
||||||
|
found = clb.get(loadbalancer)
|
||||||
|
except:
|
||||||
|
for lb in clb.list():
|
||||||
|
if loadbalancer == lb.name:
|
||||||
|
found.append(lb)
|
||||||
|
|
||||||
|
if not found:
|
||||||
|
module.fail_json(msg='No loadbalancer was matched')
|
||||||
|
|
||||||
|
if len(found) > 1:
|
||||||
|
module.fail_json(msg='Multiple loadbalancers matched')
|
||||||
|
|
||||||
|
# We made it this far, grab the first and hopefully only item
|
||||||
|
# in the list
|
||||||
|
found = found[0]
|
||||||
|
|
||||||
|
return found
|
||||||
|
|
||||||
import os
|
|
||||||
|
|
||||||
def rax_argument_spec():
|
def rax_argument_spec():
|
||||||
return dict(
|
return dict(
|
||||||
|
@ -48,6 +213,9 @@ def rax_required_together():
|
||||||
|
|
||||||
|
|
||||||
def setup_rax_module(module, rax_module):
|
def setup_rax_module(module, rax_module):
|
||||||
|
rax_module.USER_AGENT = 'ansible/%s %s' % (ANSIBLE_VERSION,
|
||||||
|
rax_module.USER_AGENT)
|
||||||
|
|
||||||
api_key = module.params.get('api_key')
|
api_key = module.params.get('api_key')
|
||||||
auth_endpoint = module.params.get('auth_endpoint')
|
auth_endpoint = module.params.get('auth_endpoint')
|
||||||
credentials = module.params.get('credentials')
|
credentials = module.params.get('credentials')
|
||||||
|
@ -102,4 +270,7 @@ def setup_rax_module(module, rax_module):
|
||||||
except Exception, e:
|
except Exception, e:
|
||||||
module.fail_json(msg='%s' % e.message)
|
module.fail_json(msg='%s' % e.message)
|
||||||
|
|
||||||
|
rax_module.USER_AGENT = 'ansible/%s %s' % (ANSIBLE_VERSION,
|
||||||
|
rax_module.USER_AGENT)
|
||||||
|
|
||||||
return rax_module
|
return rax_module
|
||||||
|
|
|
@ -194,44 +194,12 @@ EXAMPLES = '''
|
||||||
register: rax
|
register: rax
|
||||||
'''
|
'''
|
||||||
|
|
||||||
import os
|
|
||||||
import re
|
|
||||||
import time
|
|
||||||
|
|
||||||
from uuid import UUID
|
|
||||||
from types import NoneType
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
import pyrax
|
import pyrax
|
||||||
HAS_PYRAX = True
|
HAS_PYRAX = True
|
||||||
except ImportError:
|
except ImportError:
|
||||||
HAS_PYRAX = False
|
HAS_PYRAX = False
|
||||||
|
|
||||||
ACTIVE_STATUSES = ('ACTIVE', 'BUILD', 'HARD_REBOOT', 'MIGRATING', 'PASSWORD',
|
|
||||||
'REBOOT', 'REBUILD', 'RESCUE', 'RESIZE', 'REVERT_RESIZE')
|
|
||||||
FINAL_STATUSES = ('ACTIVE', 'ERROR')
|
|
||||||
NON_CALLABLES = (basestring, bool, dict, int, list, NoneType)
|
|
||||||
PUBLIC_NET_ID = "00000000-0000-0000-0000-000000000000"
|
|
||||||
SERVICE_NET_ID = "11111111-1111-1111-1111-111111111111"
|
|
||||||
|
|
||||||
|
|
||||||
def rax_slugify(value):
|
|
||||||
return 'rax_%s' % (re.sub('[^\w-]', '_', value).lower().lstrip('_'))
|
|
||||||
|
|
||||||
|
|
||||||
def server_to_dict(obj):
|
|
||||||
instance = {}
|
|
||||||
for key in dir(obj):
|
|
||||||
value = getattr(obj, key)
|
|
||||||
if (isinstance(value, NON_CALLABLES) and not key.startswith('_')):
|
|
||||||
key = rax_slugify(key)
|
|
||||||
instance[key] = value
|
|
||||||
|
|
||||||
for attr in ['id', 'accessIPv4', 'name', 'status']:
|
|
||||||
instance[attr] = instance.get(rax_slugify(attr))
|
|
||||||
|
|
||||||
return instance
|
|
||||||
|
|
||||||
|
|
||||||
def create(module, names=[], flavor=None, image=None, meta={}, key_name=None,
|
def create(module, names=[], flavor=None, image=None, meta={}, key_name=None,
|
||||||
files={}, wait=True, wait_timeout=300, disk_config=None,
|
files={}, wait=True, wait_timeout=300, disk_config=None,
|
||||||
|
@ -251,7 +219,7 @@ def create(module, names=[], flavor=None, image=None, meta={}, key_name=None,
|
||||||
except Exception, e:
|
except Exception, e:
|
||||||
module.fail_json(msg='Failed to load %s' % user_data)
|
module.fail_json(msg='Failed to load %s' % user_data)
|
||||||
|
|
||||||
# Handle the file contents
|
# Handle the file contents
|
||||||
for rpath in files.keys():
|
for rpath in files.keys():
|
||||||
lpath = os.path.expanduser(files[rpath])
|
lpath = os.path.expanduser(files[rpath])
|
||||||
try:
|
try:
|
||||||
|
@ -299,7 +267,7 @@ def create(module, names=[], flavor=None, image=None, meta={}, key_name=None,
|
||||||
server.get()
|
server.get()
|
||||||
except:
|
except:
|
||||||
server.status == 'ERROR'
|
server.status == 'ERROR'
|
||||||
instance = server_to_dict(server)
|
instance = rax_to_dict(server, 'server')
|
||||||
if server.status == 'ACTIVE' or not wait:
|
if server.status == 'ACTIVE' or not wait:
|
||||||
success.append(instance)
|
success.append(instance)
|
||||||
elif server.status == 'ERROR':
|
elif server.status == 'ERROR':
|
||||||
|
@ -307,7 +275,7 @@ def create(module, names=[], flavor=None, image=None, meta={}, key_name=None,
|
||||||
elif wait:
|
elif wait:
|
||||||
timeout.append(instance)
|
timeout.append(instance)
|
||||||
|
|
||||||
untouched = [server_to_dict(s) for s in existing]
|
untouched = [rax_to_dict(s, 'server') for s in existing]
|
||||||
instances = success + untouched
|
instances = success + untouched
|
||||||
|
|
||||||
results = {
|
results = {
|
||||||
|
@ -354,7 +322,7 @@ def delete(module, instance_ids=[], wait=True, wait_timeout=300, kept=[]):
|
||||||
else:
|
else:
|
||||||
changed = True
|
changed = True
|
||||||
|
|
||||||
instance = server_to_dict(server)
|
instance = rax_to_dict(server, 'server')
|
||||||
instances[instance['id']] = instance
|
instances[instance['id']] = instance
|
||||||
|
|
||||||
# If requested, wait for server deletion
|
# If requested, wait for server deletion
|
||||||
|
@ -384,7 +352,7 @@ def delete(module, instance_ids=[], wait=True, wait_timeout=300, kept=[]):
|
||||||
success = filter(lambda s: s['status'] in ('', 'DELETED'),
|
success = filter(lambda s: s['status'] in ('', 'DELETED'),
|
||||||
instances.values())
|
instances.values())
|
||||||
|
|
||||||
instances = [server_to_dict(s) for s in kept]
|
instances = [rax_to_dict(s, 'server') for s in kept]
|
||||||
|
|
||||||
results = {
|
results = {
|
||||||
'changed': changed,
|
'changed': changed,
|
||||||
|
@ -451,48 +419,13 @@ def cloudservers(module, state=None, name=None, flavor=None, image=None,
|
||||||
state = 'present'
|
state = 'present'
|
||||||
was_absent = True
|
was_absent = True
|
||||||
|
|
||||||
# Check if the provided image is a UUID and if not, search for an
|
|
||||||
# appropriate image using human_id and name
|
|
||||||
if image:
|
if image:
|
||||||
try:
|
image = rax_find_image(module, pyrax, image)
|
||||||
UUID(image)
|
|
||||||
except ValueError:
|
|
||||||
try:
|
|
||||||
image = cs.images.find(human_id=image)
|
|
||||||
except(cs.exceptions.NotFound,
|
|
||||||
cs.exceptions.NoUniqueMatch):
|
|
||||||
try:
|
|
||||||
image = cs.images.find(name=image)
|
|
||||||
except (cs.exceptions.NotFound,
|
|
||||||
cs.exceptions.NoUniqueMatch):
|
|
||||||
module.fail_json(msg='No matching image found (%s)' %
|
|
||||||
image)
|
|
||||||
|
|
||||||
image = pyrax.utils.get_id(image)
|
|
||||||
|
|
||||||
# Check if the provided network is a UUID and if not, search for an
|
|
||||||
# appropriate network using label
|
|
||||||
nics = []
|
nics = []
|
||||||
if networks:
|
if networks:
|
||||||
for network in networks:
|
for network in networks:
|
||||||
try:
|
nics.extend(rax_find_network(module, pyrax, network))
|
||||||
UUID(network)
|
|
||||||
except ValueError:
|
|
||||||
if network.lower() == 'public':
|
|
||||||
nics.extend(cnw.get_server_networks(PUBLIC_NET_ID))
|
|
||||||
elif network.lower() == 'private':
|
|
||||||
nics.extend(cnw.get_server_networks(SERVICE_NET_ID))
|
|
||||||
else:
|
|
||||||
try:
|
|
||||||
network_obj = cnw.find_network_by_label(network)
|
|
||||||
except (pyrax.exceptions.NetworkNotFound,
|
|
||||||
pyrax.exceptions.NetworkLabelNotUnique):
|
|
||||||
module.fail_json(msg='No matching network found (%s)' %
|
|
||||||
network)
|
|
||||||
else:
|
|
||||||
nics.extend(cnw.get_server_networks(network_obj))
|
|
||||||
else:
|
|
||||||
nics.extend(cnw.get_server_networks(network))
|
|
||||||
|
|
||||||
# act on the state
|
# act on the state
|
||||||
if state == 'present':
|
if state == 'present':
|
||||||
|
@ -568,7 +501,7 @@ def cloudservers(module, state=None, name=None, flavor=None, image=None,
|
||||||
instances = []
|
instances = []
|
||||||
instance_ids = []
|
instance_ids = []
|
||||||
for server in servers:
|
for server in servers:
|
||||||
instances.append(server_to_dict(server))
|
instances.append(rax_to_dict(server, 'server'))
|
||||||
instance_ids.append(server.id)
|
instance_ids.append(server.id)
|
||||||
module.exit_json(changed=False, action=None,
|
module.exit_json(changed=False, action=None,
|
||||||
instances=instances,
|
instances=instances,
|
||||||
|
@ -623,7 +556,7 @@ def cloudservers(module, state=None, name=None, flavor=None, image=None,
|
||||||
if len(servers) >= count:
|
if len(servers) >= count:
|
||||||
instances = []
|
instances = []
|
||||||
for server in servers:
|
for server in servers:
|
||||||
instances.append(server_to_dict(server))
|
instances.append(rax_to_dict(server, 'server'))
|
||||||
|
|
||||||
instance_ids = [i['id'] for i in instances]
|
instance_ids = [i['id'] for i in instances]
|
||||||
module.exit_json(changed=False, action=None,
|
module.exit_json(changed=False, action=None,
|
||||||
|
@ -774,5 +707,5 @@ def main():
|
||||||
from ansible.module_utils.basic import *
|
from ansible.module_utils.basic import *
|
||||||
from ansible.module_utils.rax import *
|
from ansible.module_utils.rax import *
|
||||||
|
|
||||||
### invoke the module
|
# invoke the module
|
||||||
main()
|
main()
|
||||||
|
|
|
@ -99,21 +99,12 @@ EXAMPLES = '''
|
||||||
register: my_volume
|
register: my_volume
|
||||||
'''
|
'''
|
||||||
|
|
||||||
import sys
|
|
||||||
|
|
||||||
from uuid import UUID
|
|
||||||
from types import NoneType
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
import pyrax
|
import pyrax
|
||||||
HAS_PYRAX = True
|
HAS_PYRAX = True
|
||||||
except ImportError:
|
except ImportError:
|
||||||
HAS_PYRAX = False
|
HAS_PYRAX = False
|
||||||
|
|
||||||
NON_CALLABLES = (basestring, bool, dict, int, list, NoneType)
|
|
||||||
VOLUME_STATUS = ('available', 'attaching', 'creating', 'deleting', 'in-use',
|
|
||||||
'error', 'error_deleting')
|
|
||||||
|
|
||||||
|
|
||||||
def cloud_block_storage(module, state, name, description, meta, size,
|
def cloud_block_storage(module, state, name, description, meta, size,
|
||||||
snapshot_id, volume_type, wait, wait_timeout):
|
snapshot_id, volume_type, wait, wait_timeout):
|
||||||
|
@ -135,16 +126,7 @@ def cloud_block_storage(module, state, name, description, meta, size,
|
||||||
'typically indicates an invalid region or an '
|
'typically indicates an invalid region or an '
|
||||||
'incorrectly capitalized region name.')
|
'incorrectly capitalized region name.')
|
||||||
|
|
||||||
try:
|
volume = rax_find_volume(module, pyrax, name)
|
||||||
UUID(name)
|
|
||||||
volume = cbs.get(name)
|
|
||||||
except ValueError:
|
|
||||||
try:
|
|
||||||
volume = cbs.find(name=name)
|
|
||||||
except pyrax.exc.NotFound:
|
|
||||||
pass
|
|
||||||
except Exception, e:
|
|
||||||
module.fail_json(msg='%s' % e)
|
|
||||||
|
|
||||||
if state == 'present':
|
if state == 'present':
|
||||||
if not volume:
|
if not volume:
|
||||||
|
|
|
@ -81,19 +81,12 @@ EXAMPLES = '''
|
||||||
register: my_volume
|
register: my_volume
|
||||||
'''
|
'''
|
||||||
|
|
||||||
import sys
|
|
||||||
|
|
||||||
from uuid import UUID
|
|
||||||
from types import NoneType
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
import pyrax
|
import pyrax
|
||||||
HAS_PYRAX = True
|
HAS_PYRAX = True
|
||||||
except ImportError:
|
except ImportError:
|
||||||
HAS_PYRAX = False
|
HAS_PYRAX = False
|
||||||
|
|
||||||
NON_CALLABLES = (basestring, bool, dict, int, list, NoneType)
|
|
||||||
|
|
||||||
|
|
||||||
def cloud_block_storage_attachments(module, state, volume, server, device,
|
def cloud_block_storage_attachments(module, state, volume, server, device,
|
||||||
wait, wait_timeout):
|
wait, wait_timeout):
|
||||||
|
@ -113,34 +106,13 @@ def cloud_block_storage_attachments(module, state, volume, server, device,
|
||||||
changed = False
|
changed = False
|
||||||
instance = {}
|
instance = {}
|
||||||
|
|
||||||
try:
|
volume = rax_find_volume(module, pyrax, volume)
|
||||||
UUID(volume)
|
|
||||||
volume = cbs.get(volume)
|
|
||||||
except ValueError:
|
|
||||||
try:
|
|
||||||
volume = cbs.find(name=volume)
|
|
||||||
except Exception, e:
|
|
||||||
module.fail_json(msg='%s' % e)
|
|
||||||
|
|
||||||
if not volume:
|
if not volume:
|
||||||
module.fail_json(msg='No matching storage volumes were found')
|
module.fail_json(msg='No matching storage volumes were found')
|
||||||
|
|
||||||
if state == 'present':
|
if state == 'present':
|
||||||
try:
|
server = rax_find_server(module, pyrax, server)
|
||||||
UUID(server)
|
|
||||||
server = cs.servers.get(server)
|
|
||||||
except ValueError:
|
|
||||||
servers = cs.servers.list(search_opts=dict(name='^%s$' % server))
|
|
||||||
if not servers:
|
|
||||||
module.fail_json(msg='No Server was matched by name, '
|
|
||||||
'try using the Server ID instead')
|
|
||||||
if len(servers) > 1:
|
|
||||||
module.fail_json(msg='Multiple servers matched by name, '
|
|
||||||
'try using the Server ID instead')
|
|
||||||
|
|
||||||
# We made it this far, grab the first and hopefully only server
|
|
||||||
# in the list
|
|
||||||
server = servers[0]
|
|
||||||
|
|
||||||
if (volume.attachments and
|
if (volume.attachments and
|
||||||
volume.attachments[0]['server_id'] == server.id):
|
volume.attachments[0]['server_id'] == server.id):
|
||||||
|
@ -176,21 +148,7 @@ def cloud_block_storage_attachments(module, state, volume, server, device,
|
||||||
module.exit_json(**result)
|
module.exit_json(**result)
|
||||||
|
|
||||||
elif state == 'absent':
|
elif state == 'absent':
|
||||||
try:
|
server = rax_find_server(module, pyrax, server)
|
||||||
UUID(server)
|
|
||||||
server = cs.servers.get(server)
|
|
||||||
except ValueError:
|
|
||||||
servers = cs.servers.list(search_opts=dict(name='^%s$' % server))
|
|
||||||
if not servers:
|
|
||||||
module.fail_json(msg='No Server was matched by name, '
|
|
||||||
'try using the Server ID instead')
|
|
||||||
if len(servers) > 1:
|
|
||||||
module.fail_json(msg='Multiple servers matched by name, '
|
|
||||||
'try using the Server ID instead')
|
|
||||||
|
|
||||||
# We made it this far, grab the first and hopefully only server
|
|
||||||
# in the list
|
|
||||||
server = servers[0]
|
|
||||||
|
|
||||||
if (volume.attachments and
|
if (volume.attachments and
|
||||||
volume.attachments[0]['server_id'] == server.id):
|
volume.attachments[0]['server_id'] == server.id):
|
||||||
|
|
|
@ -130,7 +130,6 @@ EXAMPLES = '''
|
||||||
register: my_lb
|
register: my_lb
|
||||||
'''
|
'''
|
||||||
|
|
||||||
from types import NoneType
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
import pyrax
|
import pyrax
|
||||||
|
@ -138,42 +137,6 @@ try:
|
||||||
except ImportError:
|
except ImportError:
|
||||||
HAS_PYRAX = False
|
HAS_PYRAX = False
|
||||||
|
|
||||||
NON_CALLABLES = (basestring, bool, dict, int, list, NoneType)
|
|
||||||
ALGORITHMS = ['RANDOM', 'LEAST_CONNECTIONS', 'ROUND_ROBIN',
|
|
||||||
'WEIGHTED_LEAST_CONNECTIONS', 'WEIGHTED_ROUND_ROBIN']
|
|
||||||
PROTOCOLS = ['DNS_TCP', 'DNS_UDP', 'FTP', 'HTTP', 'HTTPS', 'IMAPS', 'IMAPv4',
|
|
||||||
'LDAP', 'LDAPS', 'MYSQL', 'POP3', 'POP3S', 'SMTP', 'TCP',
|
|
||||||
'TCP_CLIENT_FIRST', 'UDP', 'UDP_STREAM', 'SFTP']
|
|
||||||
|
|
||||||
|
|
||||||
def node_to_dict(obj):
|
|
||||||
node = obj.to_dict()
|
|
||||||
node['id'] = obj.id
|
|
||||||
return node
|
|
||||||
|
|
||||||
|
|
||||||
def to_dict(obj):
|
|
||||||
instance = {}
|
|
||||||
for key in dir(obj):
|
|
||||||
value = getattr(obj, key)
|
|
||||||
if key == 'virtual_ips':
|
|
||||||
instance[key] = []
|
|
||||||
for vip in value:
|
|
||||||
vip_dict = {}
|
|
||||||
for vip_key, vip_value in vars(vip).iteritems():
|
|
||||||
if isinstance(vip_value, NON_CALLABLES):
|
|
||||||
vip_dict[vip_key] = vip_value
|
|
||||||
instance[key].append(vip_dict)
|
|
||||||
elif key == 'nodes':
|
|
||||||
instance[key] = []
|
|
||||||
for node in value:
|
|
||||||
instance[key].append(node_to_dict(node))
|
|
||||||
elif (isinstance(value, NON_CALLABLES) and
|
|
||||||
not key.startswith('_')):
|
|
||||||
instance[key] = value
|
|
||||||
|
|
||||||
return instance
|
|
||||||
|
|
||||||
|
|
||||||
def cloud_load_balancer(module, state, name, meta, algorithm, port, protocol,
|
def cloud_load_balancer(module, state, name, meta, algorithm, port, protocol,
|
||||||
vip_type, timeout, wait, wait_timeout, vip_id):
|
vip_type, timeout, wait, wait_timeout, vip_id):
|
||||||
|
@ -252,7 +215,7 @@ def cloud_load_balancer(module, state, name, meta, algorithm, port, protocol,
|
||||||
pyrax.utils.wait_for_build(balancer, interval=5, attempts=attempts)
|
pyrax.utils.wait_for_build(balancer, interval=5, attempts=attempts)
|
||||||
|
|
||||||
balancer.get()
|
balancer.get()
|
||||||
instance = to_dict(balancer)
|
instance = rax_to_dict(balancer, 'clb')
|
||||||
|
|
||||||
result = dict(changed=changed, balancer=instance)
|
result = dict(changed=changed, balancer=instance)
|
||||||
|
|
||||||
|
@ -275,7 +238,7 @@ def cloud_load_balancer(module, state, name, meta, algorithm, port, protocol,
|
||||||
except Exception, e:
|
except Exception, e:
|
||||||
module.fail_json(msg='%s' % e.message)
|
module.fail_json(msg='%s' % e.message)
|
||||||
|
|
||||||
instance = to_dict(balancer)
|
instance = rax_to_dict(balancer, 'clb')
|
||||||
|
|
||||||
if wait:
|
if wait:
|
||||||
attempts = wait_timeout / 5
|
attempts = wait_timeout / 5
|
||||||
|
@ -291,11 +254,12 @@ def main():
|
||||||
argument_spec = rax_argument_spec()
|
argument_spec = rax_argument_spec()
|
||||||
argument_spec.update(
|
argument_spec.update(
|
||||||
dict(
|
dict(
|
||||||
algorithm=dict(choices=ALGORITHMS, default='LEAST_CONNECTIONS'),
|
algorithm=dict(choices=CLB_ALGORITHMS,
|
||||||
|
default='LEAST_CONNECTIONS'),
|
||||||
meta=dict(type='dict', default={}),
|
meta=dict(type='dict', default={}),
|
||||||
name=dict(),
|
name=dict(),
|
||||||
port=dict(type='int', default=80),
|
port=dict(type='int', default=80),
|
||||||
protocol=dict(choices=PROTOCOLS, default='HTTP'),
|
protocol=dict(choices=CLB_PROTOCOLS, default='HTTP'),
|
||||||
state=dict(default='present', choices=['present', 'absent']),
|
state=dict(default='present', choices=['present', 'absent']),
|
||||||
timeout=dict(type='int', default=30),
|
timeout=dict(type='int', default=30),
|
||||||
type=dict(choices=['PUBLIC', 'SERVICENET'], default='PUBLIC'),
|
type=dict(choices=['PUBLIC', 'SERVICENET'], default='PUBLIC'),
|
||||||
|
|
|
@ -120,8 +120,6 @@ EXAMPLES = '''
|
||||||
credentials: /path/to/credentials
|
credentials: /path/to/credentials
|
||||||
'''
|
'''
|
||||||
|
|
||||||
import os
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
import pyrax
|
import pyrax
|
||||||
HAS_PYRAX = True
|
HAS_PYRAX = True
|
||||||
|
@ -167,20 +165,6 @@ def _get_primary_nodes(lb):
|
||||||
return nodes
|
return nodes
|
||||||
|
|
||||||
|
|
||||||
def _node_to_dict(node):
|
|
||||||
"""Return a dictionary containing node details"""
|
|
||||||
if not node:
|
|
||||||
return {}
|
|
||||||
return {
|
|
||||||
'address': node.address,
|
|
||||||
'condition': node.condition,
|
|
||||||
'id': node.id,
|
|
||||||
'port': node.port,
|
|
||||||
'type': node.type,
|
|
||||||
'weight': node.weight,
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
argument_spec = rax_argument_spec()
|
argument_spec = rax_argument_spec()
|
||||||
argument_spec.update(
|
argument_spec.update(
|
||||||
|
@ -241,7 +225,7 @@ def main():
|
||||||
|
|
||||||
node = _get_node(lb, node_id, address, port)
|
node = _get_node(lb, node_id, address, port)
|
||||||
|
|
||||||
result = _node_to_dict(node)
|
result = rax_clb_node_to_dict(node)
|
||||||
|
|
||||||
if state == 'absent':
|
if state == 'absent':
|
||||||
if not node: # Removing a non-existent node
|
if not node: # Removing a non-existent node
|
||||||
|
|
|
@ -66,25 +66,12 @@ EXAMPLES = '''
|
||||||
register: rax_dns
|
register: rax_dns
|
||||||
'''
|
'''
|
||||||
|
|
||||||
from types import NoneType
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
import pyrax
|
import pyrax
|
||||||
HAS_PYRAX = True
|
HAS_PYRAX = True
|
||||||
except ImportError:
|
except ImportError:
|
||||||
HAS_PYRAX = False
|
HAS_PYRAX = False
|
||||||
|
|
||||||
NON_CALLABLES = (basestring, bool, dict, int, list, NoneType)
|
|
||||||
|
|
||||||
|
|
||||||
def to_dict(obj):
|
|
||||||
instance = {}
|
|
||||||
for key in dir(obj):
|
|
||||||
value = getattr(obj, key)
|
|
||||||
if (isinstance(value, NON_CALLABLES) and not key.startswith('_')):
|
|
||||||
instance[key] = value
|
|
||||||
return instance
|
|
||||||
|
|
||||||
|
|
||||||
def rax_dns(module, comment, email, name, state, ttl):
|
def rax_dns(module, comment, email, name, state, ttl):
|
||||||
changed = False
|
changed = False
|
||||||
|
@ -144,7 +131,7 @@ def rax_dns(module, comment, email, name, state, ttl):
|
||||||
except Exception, e:
|
except Exception, e:
|
||||||
module.fail_json(msg='%s' % e.message)
|
module.fail_json(msg='%s' % e.message)
|
||||||
|
|
||||||
module.exit_json(changed=changed, domain=to_dict(domain))
|
module.exit_json(changed=changed, domain=rax_to_dict(domain))
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
|
|
|
@ -113,65 +113,30 @@ EXAMPLES = '''
|
||||||
register: ptr_record
|
register: ptr_record
|
||||||
'''
|
'''
|
||||||
|
|
||||||
from uuid import UUID
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
import pyrax
|
import pyrax
|
||||||
HAS_PYRAX = True
|
HAS_PYRAX = True
|
||||||
except ImportError:
|
except ImportError:
|
||||||
HAS_PYRAX = False
|
HAS_PYRAX = False
|
||||||
|
|
||||||
NON_CALLABLES = (basestring, bool, dict, int, list, type(None))
|
|
||||||
|
|
||||||
|
|
||||||
def to_dict(obj):
|
|
||||||
instance = {}
|
|
||||||
for key in dir(obj):
|
|
||||||
value = getattr(obj, key)
|
|
||||||
if (isinstance(value, NON_CALLABLES) and not key.startswith('_')):
|
|
||||||
instance[key] = value
|
|
||||||
return instance
|
|
||||||
|
|
||||||
|
|
||||||
def rax_dns_record_ptr(module, data=None, comment=None, loadbalancer=None,
|
def rax_dns_record_ptr(module, data=None, comment=None, loadbalancer=None,
|
||||||
name=None, server=None, state='present', ttl=7200):
|
name=None, server=None, state='present', ttl=7200):
|
||||||
"""Function for manipulating DNS PTR records"""
|
|
||||||
|
|
||||||
changed = False
|
changed = False
|
||||||
results = []
|
results = []
|
||||||
|
|
||||||
cs = pyrax.cloudservers
|
|
||||||
clb = pyrax.cloud_loadbalancers
|
|
||||||
dns = pyrax.cloud_dns
|
dns = pyrax.cloud_dns
|
||||||
|
|
||||||
if not cs or not clb or not dns:
|
if not dns:
|
||||||
module.fail_json(msg='Failed to instantiate client. This '
|
module.fail_json(msg='Failed to instantiate client. This '
|
||||||
'typically indicates an invalid region or an '
|
'typically indicates an invalid region or an '
|
||||||
'incorrectly capitalized region name.')
|
'incorrectly capitalized region name.')
|
||||||
|
|
||||||
if loadbalancer:
|
if loadbalancer:
|
||||||
try:
|
item = rax_find_loadbalancer(module, pyrax, loadbalancer)
|
||||||
UUID(loadbalancer)
|
|
||||||
found = [clb.get(loadbalancer)]
|
|
||||||
except:
|
|
||||||
for lb in clb.list():
|
|
||||||
if loadbalancer == lb.name:
|
|
||||||
found.append(lb)
|
|
||||||
|
|
||||||
if len(found) != 1:
|
|
||||||
module.fail_json(msg='Could not match a loadbalancer with %s' %
|
|
||||||
loadbalancer)
|
|
||||||
elif server:
|
elif server:
|
||||||
try:
|
item = rax_find_server(module, pyrax, server)
|
||||||
UUID(server)
|
|
||||||
found = [cs.servers.get(server)]
|
|
||||||
except:
|
|
||||||
found = cs.servers.list(search_opts=dict(name='^%s$' % server))
|
|
||||||
if len(found) != 1:
|
|
||||||
module.fail_json(msg='Could not match a server with %s' %
|
|
||||||
server)
|
|
||||||
|
|
||||||
item = found[0]
|
|
||||||
if state == 'present':
|
if state == 'present':
|
||||||
current = dns.list_ptr_records(item)
|
current = dns.list_ptr_records(item)
|
||||||
for record in current:
|
for record in current:
|
||||||
|
@ -184,10 +149,10 @@ def rax_dns_record_ptr(module, data=None, comment=None, loadbalancer=None,
|
||||||
module.fail_json(msg='%s' % e.message)
|
module.fail_json(msg='%s' % e.message)
|
||||||
record.ttl = ttl
|
record.ttl = ttl
|
||||||
record.name = name
|
record.name = name
|
||||||
results.append(to_dict(record))
|
results.append(rax_to_dict(record))
|
||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
results.append(to_dict(record))
|
results.append(rax_to_dict(record))
|
||||||
break
|
break
|
||||||
|
|
||||||
if not results:
|
if not results:
|
||||||
|
@ -205,7 +170,7 @@ def rax_dns_record_ptr(module, data=None, comment=None, loadbalancer=None,
|
||||||
current = dns.list_ptr_records(item)
|
current = dns.list_ptr_records(item)
|
||||||
for record in current:
|
for record in current:
|
||||||
if record.data == data:
|
if record.data == data:
|
||||||
results.append(to_dict(record))
|
results.append(rax_to_dict(record))
|
||||||
break
|
break
|
||||||
|
|
||||||
if results:
|
if results:
|
||||||
|
@ -301,7 +266,7 @@ def rax_dns_record(module, comment=None, data=None, domain=None, name=None,
|
||||||
except Exception, e:
|
except Exception, e:
|
||||||
module.fail_json(msg='%s' % e.message)
|
module.fail_json(msg='%s' % e.message)
|
||||||
|
|
||||||
module.exit_json(changed=changed, record=to_dict(record))
|
module.exit_json(changed=changed, record=rax_to_dict(record))
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
|
|
|
@ -55,30 +55,12 @@ EXAMPLES = '''
|
||||||
ansible_ssh_host: "{{ rax_accessipv4 }}"
|
ansible_ssh_host: "{{ rax_accessipv4 }}"
|
||||||
'''
|
'''
|
||||||
|
|
||||||
from types import NoneType
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
import pyrax
|
import pyrax
|
||||||
HAS_PYRAX = True
|
HAS_PYRAX = True
|
||||||
except ImportError:
|
except ImportError:
|
||||||
HAS_PYRAX = False
|
HAS_PYRAX = False
|
||||||
|
|
||||||
NON_CALLABLES = (basestring, bool, dict, int, list, NoneType)
|
|
||||||
|
|
||||||
|
|
||||||
def rax_slugify(value):
|
|
||||||
return 'rax_%s' % (re.sub('[^\w-]', '_', value).lower().lstrip('_'))
|
|
||||||
|
|
||||||
|
|
||||||
def pyrax_object_to_dict(obj):
|
|
||||||
instance = {}
|
|
||||||
for key in dir(obj):
|
|
||||||
value = getattr(obj, key)
|
|
||||||
if (isinstance(value, NON_CALLABLES) and not key.startswith('_')):
|
|
||||||
key = rax_slugify(key)
|
|
||||||
instance[key] = value
|
|
||||||
return instance
|
|
||||||
|
|
||||||
|
|
||||||
def rax_facts(module, address, name, server_id):
|
def rax_facts(module, address, name, server_id):
|
||||||
changed = False
|
changed = False
|
||||||
|
@ -120,7 +102,7 @@ def rax_facts(module, address, name, server_id):
|
||||||
module.fail_json(msg='Multiple servers found matching provided '
|
module.fail_json(msg='Multiple servers found matching provided '
|
||||||
'search parameters')
|
'search parameters')
|
||||||
elif len(servers) == 1:
|
elif len(servers) == 1:
|
||||||
ansible_facts = pyrax_object_to_dict(servers[0])
|
ansible_facts = rax_to_dict(servers[0], 'server')
|
||||||
|
|
||||||
module.exit_json(changed=changed, ansible_facts=ansible_facts)
|
module.exit_json(changed=changed, ansible_facts=ansible_facts)
|
||||||
|
|
||||||
|
|
|
@ -139,8 +139,6 @@ EXAMPLES = '''
|
||||||
file_for: ""
|
file_for: ""
|
||||||
'''
|
'''
|
||||||
|
|
||||||
from ansible import __version__
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
import pyrax
|
import pyrax
|
||||||
HAS_PYRAX = True
|
HAS_PYRAX = True
|
||||||
|
@ -149,7 +147,6 @@ except ImportError, e:
|
||||||
|
|
||||||
EXIT_DICT = dict(success=True)
|
EXIT_DICT = dict(success=True)
|
||||||
META_PREFIX = 'x-container-meta-'
|
META_PREFIX = 'x-container-meta-'
|
||||||
USER_AGENT = "Ansible/%s via pyrax" % __version__
|
|
||||||
|
|
||||||
|
|
||||||
def _get_container(module, cf, container):
|
def _get_container(module, cf, container):
|
||||||
|
@ -321,8 +318,6 @@ def cloudfiles(module, container_, state, meta_, clear_meta, typ, ttl, public,
|
||||||
'typically indicates an invalid region or an '
|
'typically indicates an invalid region or an '
|
||||||
'incorrectly capitalized region name.')
|
'incorrectly capitalized region name.')
|
||||||
|
|
||||||
cf.user_agent = USER_AGENT
|
|
||||||
|
|
||||||
if typ == "container":
|
if typ == "container":
|
||||||
container(cf, module, container_, state, meta_, clear_meta, ttl,
|
container(cf, module, container_, state, meta_, clear_meta, ttl,
|
||||||
public, private, web_index, web_error)
|
public, private, web_index, web_error)
|
||||||
|
|
|
@ -183,8 +183,6 @@ EXAMPLES = '''
|
||||||
rax_files_objects: container=testcont type=meta
|
rax_files_objects: container=testcont type=meta
|
||||||
'''
|
'''
|
||||||
|
|
||||||
import os
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
import pyrax
|
import pyrax
|
||||||
HAS_PYRAX = True
|
HAS_PYRAX = True
|
||||||
|
|
|
@ -47,8 +47,6 @@ EXAMPLES = '''
|
||||||
register: rackspace_identity
|
register: rackspace_identity
|
||||||
'''
|
'''
|
||||||
|
|
||||||
from types import NoneType
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
import pyrax
|
import pyrax
|
||||||
HAS_PYRAX = True
|
HAS_PYRAX = True
|
||||||
|
@ -56,9 +54,6 @@ except ImportError:
|
||||||
HAS_PYRAX = False
|
HAS_PYRAX = False
|
||||||
|
|
||||||
|
|
||||||
NON_CALLABLES = (basestring, bool, dict, int, list, NoneType)
|
|
||||||
|
|
||||||
|
|
||||||
def cloud_identity(module, state, identity):
|
def cloud_identity(module, state, identity):
|
||||||
for arg in (state, identity):
|
for arg in (state, identity):
|
||||||
if not arg:
|
if not arg:
|
||||||
|
@ -70,10 +65,8 @@ def cloud_identity(module, state, identity):
|
||||||
)
|
)
|
||||||
changed = False
|
changed = False
|
||||||
|
|
||||||
for key, value in vars(identity).iteritems():
|
instance.update(rax_to_dict(identity))
|
||||||
if (isinstance(value, NON_CALLABLES) and
|
instance['services'] = instance.get('services', {}).keys()
|
||||||
not key.startswith('_')):
|
|
||||||
instance[key] = value
|
|
||||||
|
|
||||||
if state == 'present':
|
if state == 'present':
|
||||||
if not identity.authenticated:
|
if not identity.authenticated:
|
||||||
|
|
|
@ -84,25 +84,12 @@ EXAMPLES = '''
|
||||||
register: keypair
|
register: keypair
|
||||||
'''
|
'''
|
||||||
|
|
||||||
from types import NoneType
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
import pyrax
|
import pyrax
|
||||||
HAS_PYRAX = True
|
HAS_PYRAX = True
|
||||||
except ImportError:
|
except ImportError:
|
||||||
HAS_PYRAX = False
|
HAS_PYRAX = False
|
||||||
|
|
||||||
NON_CALLABLES = (basestring, bool, dict, int, list, NoneType)
|
|
||||||
|
|
||||||
|
|
||||||
def to_dict(obj):
|
|
||||||
instance = {}
|
|
||||||
for key in dir(obj):
|
|
||||||
value = getattr(obj, key)
|
|
||||||
if (isinstance(value, NON_CALLABLES) and not key.startswith('_')):
|
|
||||||
instance[key] = value
|
|
||||||
return instance
|
|
||||||
|
|
||||||
|
|
||||||
def rax_keypair(module, name, public_key, state):
|
def rax_keypair(module, name, public_key, state):
|
||||||
changed = False
|
changed = False
|
||||||
|
@ -149,7 +136,7 @@ def rax_keypair(module, name, public_key, state):
|
||||||
except Exception, e:
|
except Exception, e:
|
||||||
module.fail_json(msg='%s' % e.message)
|
module.fail_json(msg='%s' % e.message)
|
||||||
|
|
||||||
module.exit_json(changed=changed, keypair=to_dict(keypair))
|
module.exit_json(changed=changed, keypair=rax_to_dict(keypair))
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
|
|
|
@ -118,34 +118,12 @@ EXAMPLES = '''
|
||||||
register: asg
|
register: asg
|
||||||
'''
|
'''
|
||||||
|
|
||||||
import os
|
|
||||||
|
|
||||||
from uuid import UUID
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
import pyrax
|
import pyrax
|
||||||
HAS_PYRAX = True
|
HAS_PYRAX = True
|
||||||
except ImportError:
|
except ImportError:
|
||||||
HAS_PYRAX = False
|
HAS_PYRAX = False
|
||||||
|
|
||||||
NON_CALLABLES = (basestring, bool, dict, int, list, type(None))
|
|
||||||
PUBLIC_NET_ID = "00000000-0000-0000-0000-000000000000"
|
|
||||||
SERVICE_NET_ID = "11111111-1111-1111-1111-111111111111"
|
|
||||||
|
|
||||||
|
|
||||||
def asg_to_dict(obj):
|
|
||||||
instance = {}
|
|
||||||
for key in dir(obj):
|
|
||||||
value = getattr(obj, key)
|
|
||||||
if key == 'policies' and isinstance(value, list):
|
|
||||||
policies = []
|
|
||||||
for policy in value:
|
|
||||||
policies.append(asg_to_dict(policy))
|
|
||||||
instance[key] = policies
|
|
||||||
elif (isinstance(value, NON_CALLABLES) and not key.startswith('_')):
|
|
||||||
instance[key] = value
|
|
||||||
return instance
|
|
||||||
|
|
||||||
|
|
||||||
def rax_asg(module, cooldown=300, disk_config=None, files={}, flavor=None,
|
def rax_asg(module, cooldown=300, disk_config=None, files={}, flavor=None,
|
||||||
image=None, key_name=None, loadbalancers=[], meta={},
|
image=None, key_name=None, loadbalancers=[], meta={},
|
||||||
|
@ -172,48 +150,13 @@ def rax_asg(module, cooldown=300, disk_config=None, files={}, flavor=None,
|
||||||
elif not isinstance(v, basestring):
|
elif not isinstance(v, basestring):
|
||||||
meta[k] = '%s' % v
|
meta[k] = '%s' % v
|
||||||
|
|
||||||
# Check if the provided image is a UUID and if not, search for an
|
|
||||||
# appropriate image using human_id and name
|
|
||||||
if image:
|
if image:
|
||||||
try:
|
image = rax_find_image(module, pyrax, image)
|
||||||
UUID(image)
|
|
||||||
except ValueError:
|
|
||||||
try:
|
|
||||||
image = cs.images.find(human_id=image)
|
|
||||||
except(cs.exceptions.NotFound,
|
|
||||||
cs.exceptions.NoUniqueMatch):
|
|
||||||
try:
|
|
||||||
image = cs.images.find(name=image)
|
|
||||||
except (cs.exceptions.NotFound,
|
|
||||||
cs.exceptions.NoUniqueMatch):
|
|
||||||
module.fail_json(msg='No matching image found (%s)' %
|
|
||||||
image)
|
|
||||||
|
|
||||||
image = pyrax.utils.get_id(image)
|
|
||||||
|
|
||||||
# Check if the provided network is a UUID and if not, search for an
|
|
||||||
# appropriate network using label
|
|
||||||
nics = []
|
nics = []
|
||||||
if networks:
|
if networks:
|
||||||
for network in networks:
|
for network in networks:
|
||||||
try:
|
nics.extend(rax_find_network(module, pyrax, network))
|
||||||
UUID(network)
|
|
||||||
except ValueError:
|
|
||||||
if network.lower() == 'public':
|
|
||||||
nics.extend(cnw.get_server_networks(PUBLIC_NET_ID))
|
|
||||||
elif network.lower() == 'private':
|
|
||||||
nics.extend(cnw.get_server_networks(SERVICE_NET_ID))
|
|
||||||
else:
|
|
||||||
try:
|
|
||||||
network_obj = cnw.find_network_by_label(network)
|
|
||||||
except (pyrax.exceptions.NetworkNotFound,
|
|
||||||
pyrax.exceptions.NetworkLabelNotUnique):
|
|
||||||
module.fail_json(msg='No matching network found '
|
|
||||||
'(%s)' % network)
|
|
||||||
else:
|
|
||||||
nics.extend(cnw.get_server_networks(network_obj))
|
|
||||||
else:
|
|
||||||
nics.extend(cnw.get_server_networks(network))
|
|
||||||
|
|
||||||
for nic in nics:
|
for nic in nics:
|
||||||
# pyrax is currently returning net-id, but we need uuid
|
# pyrax is currently returning net-id, but we need uuid
|
||||||
|
@ -322,7 +265,7 @@ def rax_asg(module, cooldown=300, disk_config=None, files={}, flavor=None,
|
||||||
|
|
||||||
sg.get()
|
sg.get()
|
||||||
|
|
||||||
module.exit_json(changed=changed, autoscale_group=asg_to_dict(sg))
|
module.exit_json(changed=changed, autoscale_group=rax_to_dict(sg))
|
||||||
|
|
||||||
else:
|
else:
|
||||||
try:
|
try:
|
||||||
|
@ -334,7 +277,7 @@ def rax_asg(module, cooldown=300, disk_config=None, files={}, flavor=None,
|
||||||
except Exception, e:
|
except Exception, e:
|
||||||
module.fail_json(msg='%s' % e.message)
|
module.fail_json(msg='%s' % e.message)
|
||||||
|
|
||||||
module.exit_json(changed=changed, autoscale_group=asg_to_dict(sg))
|
module.exit_json(changed=changed, autoscale_group=rax_to_dict(sg))
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
|
|
|
@ -118,27 +118,12 @@ EXAMPLES = '''
|
||||||
register: asp_webhook
|
register: asp_webhook
|
||||||
'''
|
'''
|
||||||
|
|
||||||
from uuid import UUID
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
import pyrax
|
import pyrax
|
||||||
HAS_PYRAX = True
|
HAS_PYRAX = True
|
||||||
except ImportError:
|
except ImportError:
|
||||||
HAS_PYRAX = False
|
HAS_PYRAX = False
|
||||||
|
|
||||||
NON_CALLABLES = (basestring, bool, dict, int, list, type(None))
|
|
||||||
PUBLIC_NET_ID = "00000000-0000-0000-0000-000000000000"
|
|
||||||
SERVICE_NET_ID = "11111111-1111-1111-1111-111111111111"
|
|
||||||
|
|
||||||
|
|
||||||
def to_dict(obj):
|
|
||||||
instance = {}
|
|
||||||
for key in dir(obj):
|
|
||||||
value = getattr(obj, key)
|
|
||||||
if (isinstance(value, NON_CALLABLES) and not key.startswith('_')):
|
|
||||||
instance[key] = value
|
|
||||||
return instance
|
|
||||||
|
|
||||||
|
|
||||||
def rax_asp(module, at=None, change=0, cron=None, cooldown=300,
|
def rax_asp(module, at=None, change=0, cron=None, cooldown=300,
|
||||||
desired_capacity=0, is_percent=False, name=None,
|
desired_capacity=0, is_percent=False, name=None,
|
||||||
|
@ -220,7 +205,7 @@ def rax_asp(module, at=None, change=0, cron=None, cooldown=300,
|
||||||
|
|
||||||
policy.get()
|
policy.get()
|
||||||
|
|
||||||
module.exit_json(changed=changed, autoscale_policy=to_dict(policy))
|
module.exit_json(changed=changed, autoscale_policy=rax_to_dict(policy))
|
||||||
|
|
||||||
else:
|
else:
|
||||||
try:
|
try:
|
||||||
|
@ -235,7 +220,7 @@ def rax_asp(module, at=None, change=0, cron=None, cooldown=300,
|
||||||
except Exception, e:
|
except Exception, e:
|
||||||
module.fail_json(msg='%s' % e.message)
|
module.fail_json(msg='%s' % e.message)
|
||||||
|
|
||||||
module.exit_json(changed=changed, autoscale_policy=to_dict(policy))
|
module.exit_json(changed=changed, autoscale_policy=rax_to_dict(policy))
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue