Merge pull request #8500 from sivel/rax-de-dupe

rax: Move additional shared code into module utils
This commit is contained in:
Michael DeHaan 2014-08-08 12:33:35 -04:00
commit d0205b2878
17 changed files with 232 additions and 400 deletions

View file

@ -25,11 +25,13 @@ import shlex
from ansible import errors
from ansible import utils
from ansible import constants as C
from ansible import __version__
REPLACER = "#<<INCLUDE_ANSIBLE_MODULE_COMMON>>"
REPLACER_ARGS = "\"<<INCLUDE_ANSIBLE_MODULE_ARGS>>\""
REPLACER_COMPLEX = "\"<<INCLUDE_ANSIBLE_MODULE_COMPLEX_ARGS>>\""
REPLACER_WINDOWS = "# POWERSHELL_COMMON"
REPLACER_VERSION = "\"<<ANSIBLE_VERSION>>\""
class ModuleReplacer(object):
@ -156,6 +158,7 @@ class ModuleReplacer(object):
encoded_complex = repr(complex_args_json)
# 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_COMPLEX, encoded_complex)

View file

@ -29,6 +29,8 @@
# == BEGIN DYNAMICALLY INSERTED CODE ==
ANSIBLE_VERSION = "<<ANSIBLE_VERSION>>"
MODULE_ARGS = "<<INCLUDE_ANSIBLE_MODULE_ARGS>>"
MODULE_COMPLEX_ARGS = "<<INCLUDE_ANSIBLE_MODULE_COMPLEX_ARGS>>"

View file

@ -1,32 +1,197 @@
# This code is part of Ansible, but is an independent component.
# This particular file snippet, and this file snippet only, is BSD licensed.
# Modules you write using this snippet, which is embedded dynamically by Ansible
# still belong to the author of the module, and may assign their own license
# to the complete work.
# Modules you write using this snippet, which is embedded dynamically by
# Ansible still belong to the author of the module, and may assign their own
# license to the complete work.
#
# Copyright (c), Michael DeHaan <michael.dehaan@gmail.com>, 2012-2013
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without modification,
# are permitted provided that the following conditions are met:
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
# * Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
# IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 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.
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# 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():
return dict(
@ -48,6 +213,9 @@ def rax_required_together():
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')
auth_endpoint = module.params.get('auth_endpoint')
credentials = module.params.get('credentials')
@ -102,4 +270,7 @@ def setup_rax_module(module, rax_module):
except Exception, e:
module.fail_json(msg='%s' % e.message)
rax_module.USER_AGENT = 'ansible/%s %s' % (ANSIBLE_VERSION,
rax_module.USER_AGENT)
return rax_module

View file

@ -194,44 +194,12 @@ EXAMPLES = '''
register: rax
'''
import os
import re
import time
from uuid import UUID
from types import NoneType
try:
import pyrax
HAS_PYRAX = True
except ImportError:
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,
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:
module.fail_json(msg='Failed to load %s' % user_data)
# Handle the file contents
# Handle the file contents
for rpath in files.keys():
lpath = os.path.expanduser(files[rpath])
try:
@ -299,7 +267,7 @@ def create(module, names=[], flavor=None, image=None, meta={}, key_name=None,
server.get()
except:
server.status == 'ERROR'
instance = server_to_dict(server)
instance = rax_to_dict(server, 'server')
if server.status == 'ACTIVE' or not wait:
success.append(instance)
elif server.status == 'ERROR':
@ -307,7 +275,7 @@ def create(module, names=[], flavor=None, image=None, meta={}, key_name=None,
elif wait:
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
results = {
@ -354,7 +322,7 @@ def delete(module, instance_ids=[], wait=True, wait_timeout=300, kept=[]):
else:
changed = True
instance = server_to_dict(server)
instance = rax_to_dict(server, 'server')
instances[instance['id']] = instance
# 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'),
instances.values())
instances = [server_to_dict(s) for s in kept]
instances = [rax_to_dict(s, 'server') for s in kept]
results = {
'changed': changed,
@ -451,48 +419,13 @@ def cloudservers(module, state=None, name=None, flavor=None, image=None,
state = 'present'
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:
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)
image = rax_find_image(module, pyrax, 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 = []
if networks:
for network in networks:
try:
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))
nics.extend(rax_find_network(module, pyrax, network))
# act on the state
if state == 'present':
@ -568,7 +501,7 @@ def cloudservers(module, state=None, name=None, flavor=None, image=None,
instances = []
instance_ids = []
for server in servers:
instances.append(server_to_dict(server))
instances.append(rax_to_dict(server, 'server'))
instance_ids.append(server.id)
module.exit_json(changed=False, action=None,
instances=instances,
@ -623,7 +556,7 @@ def cloudservers(module, state=None, name=None, flavor=None, image=None,
if len(servers) >= count:
instances = []
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]
module.exit_json(changed=False, action=None,
@ -774,5 +707,5 @@ def main():
from ansible.module_utils.basic import *
from ansible.module_utils.rax import *
### invoke the module
# invoke the module
main()

View file

@ -99,21 +99,12 @@ EXAMPLES = '''
register: my_volume
'''
import sys
from uuid import UUID
from types import NoneType
try:
import pyrax
HAS_PYRAX = True
except ImportError:
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,
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 '
'incorrectly capitalized region name.')
try:
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)
volume = rax_find_volume(module, pyrax, name)
if state == 'present':
if not volume:

View file

@ -81,19 +81,12 @@ EXAMPLES = '''
register: my_volume
'''
import sys
from uuid import UUID
from types import NoneType
try:
import pyrax
HAS_PYRAX = True
except ImportError:
HAS_PYRAX = False
NON_CALLABLES = (basestring, bool, dict, int, list, NoneType)
def cloud_block_storage_attachments(module, state, volume, server, device,
wait, wait_timeout):
@ -113,34 +106,13 @@ def cloud_block_storage_attachments(module, state, volume, server, device,
changed = False
instance = {}
try:
UUID(volume)
volume = cbs.get(volume)
except ValueError:
try:
volume = cbs.find(name=volume)
except Exception, e:
module.fail_json(msg='%s' % e)
volume = rax_find_volume(module, pyrax, volume)
if not volume:
module.fail_json(msg='No matching storage volumes were found')
if state == 'present':
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]
server = rax_find_server(module, pyrax, server)
if (volume.attachments and
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)
elif state == 'absent':
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]
server = rax_find_server(module, pyrax, server)
if (volume.attachments and
volume.attachments[0]['server_id'] == server.id):

View file

@ -130,7 +130,6 @@ EXAMPLES = '''
register: my_lb
'''
from types import NoneType
try:
import pyrax
@ -138,42 +137,6 @@ try:
except ImportError:
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,
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)
balancer.get()
instance = to_dict(balancer)
instance = rax_to_dict(balancer, 'clb')
result = dict(changed=changed, balancer=instance)
@ -275,7 +238,7 @@ def cloud_load_balancer(module, state, name, meta, algorithm, port, protocol,
except Exception, e:
module.fail_json(msg='%s' % e.message)
instance = to_dict(balancer)
instance = rax_to_dict(balancer, 'clb')
if wait:
attempts = wait_timeout / 5
@ -291,11 +254,12 @@ def main():
argument_spec = rax_argument_spec()
argument_spec.update(
dict(
algorithm=dict(choices=ALGORITHMS, default='LEAST_CONNECTIONS'),
algorithm=dict(choices=CLB_ALGORITHMS,
default='LEAST_CONNECTIONS'),
meta=dict(type='dict', default={}),
name=dict(),
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']),
timeout=dict(type='int', default=30),
type=dict(choices=['PUBLIC', 'SERVICENET'], default='PUBLIC'),

View file

@ -120,8 +120,6 @@ EXAMPLES = '''
credentials: /path/to/credentials
'''
import os
try:
import pyrax
HAS_PYRAX = True
@ -167,20 +165,6 @@ def _get_primary_nodes(lb):
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():
argument_spec = rax_argument_spec()
argument_spec.update(
@ -241,7 +225,7 @@ def main():
node = _get_node(lb, node_id, address, port)
result = _node_to_dict(node)
result = rax_clb_node_to_dict(node)
if state == 'absent':
if not node: # Removing a non-existent node

View file

@ -66,25 +66,12 @@ EXAMPLES = '''
register: rax_dns
'''
from types import NoneType
try:
import pyrax
HAS_PYRAX = True
except ImportError:
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):
changed = False
@ -144,7 +131,7 @@ def rax_dns(module, comment, email, name, state, ttl):
except Exception, e:
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():

View file

@ -113,65 +113,30 @@ EXAMPLES = '''
register: ptr_record
'''
from uuid import UUID
try:
import pyrax
HAS_PYRAX = True
except ImportError:
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,
name=None, server=None, state='present', ttl=7200):
"""Function for manipulating DNS PTR records"""
changed = False
results = []
cs = pyrax.cloudservers
clb = pyrax.cloud_loadbalancers
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 '
'typically indicates an invalid region or an '
'incorrectly capitalized region name.')
if loadbalancer:
try:
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)
item = rax_find_loadbalancer(module, pyrax, loadbalancer)
elif server:
try:
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 = rax_find_server(module, pyrax, server)
item = found[0]
if state == 'present':
current = dns.list_ptr_records(item)
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)
record.ttl = ttl
record.name = name
results.append(to_dict(record))
results.append(rax_to_dict(record))
break
else:
results.append(to_dict(record))
results.append(rax_to_dict(record))
break
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)
for record in current:
if record.data == data:
results.append(to_dict(record))
results.append(rax_to_dict(record))
break
if results:
@ -301,7 +266,7 @@ def rax_dns_record(module, comment=None, data=None, domain=None, name=None,
except Exception, e:
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():

View file

@ -55,30 +55,12 @@ EXAMPLES = '''
ansible_ssh_host: "{{ rax_accessipv4 }}"
'''
from types import NoneType
try:
import pyrax
HAS_PYRAX = True
except ImportError:
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):
changed = False
@ -120,7 +102,7 @@ def rax_facts(module, address, name, server_id):
module.fail_json(msg='Multiple servers found matching provided '
'search parameters')
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)

View file

@ -139,8 +139,6 @@ EXAMPLES = '''
file_for: ""
'''
from ansible import __version__
try:
import pyrax
HAS_PYRAX = True
@ -149,7 +147,6 @@ except ImportError, e:
EXIT_DICT = dict(success=True)
META_PREFIX = 'x-container-meta-'
USER_AGENT = "Ansible/%s via pyrax" % __version__
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 '
'incorrectly capitalized region name.')
cf.user_agent = USER_AGENT
if typ == "container":
container(cf, module, container_, state, meta_, clear_meta, ttl,
public, private, web_index, web_error)

View file

@ -183,8 +183,6 @@ EXAMPLES = '''
rax_files_objects: container=testcont type=meta
'''
import os
try:
import pyrax
HAS_PYRAX = True

View file

@ -47,8 +47,6 @@ EXAMPLES = '''
register: rackspace_identity
'''
from types import NoneType
try:
import pyrax
HAS_PYRAX = True
@ -56,9 +54,6 @@ except ImportError:
HAS_PYRAX = False
NON_CALLABLES = (basestring, bool, dict, int, list, NoneType)
def cloud_identity(module, state, identity):
for arg in (state, identity):
if not arg:
@ -70,10 +65,8 @@ def cloud_identity(module, state, identity):
)
changed = False
for key, value in vars(identity).iteritems():
if (isinstance(value, NON_CALLABLES) and
not key.startswith('_')):
instance[key] = value
instance.update(rax_to_dict(identity))
instance['services'] = instance.get('services', {}).keys()
if state == 'present':
if not identity.authenticated:

View file

@ -84,25 +84,12 @@ EXAMPLES = '''
register: keypair
'''
from types import NoneType
try:
import pyrax
HAS_PYRAX = True
except ImportError:
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):
changed = False
@ -149,7 +136,7 @@ def rax_keypair(module, name, public_key, state):
except Exception, e:
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():

View file

@ -118,34 +118,12 @@ EXAMPLES = '''
register: asg
'''
import os
from uuid import UUID
try:
import pyrax
HAS_PYRAX = True
except ImportError:
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,
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):
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:
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)
image = rax_find_image(module, pyrax, 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 = []
if networks:
for network in networks:
try:
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))
nics.extend(rax_find_network(module, pyrax, network))
for nic in nics:
# 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()
module.exit_json(changed=changed, autoscale_group=asg_to_dict(sg))
module.exit_json(changed=changed, autoscale_group=rax_to_dict(sg))
else:
try:
@ -334,7 +277,7 @@ def rax_asg(module, cooldown=300, disk_config=None, files={}, flavor=None,
except Exception, e:
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():

View file

@ -118,27 +118,12 @@ EXAMPLES = '''
register: asp_webhook
'''
from uuid import UUID
try:
import pyrax
HAS_PYRAX = True
except ImportError:
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,
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()
module.exit_json(changed=changed, autoscale_policy=to_dict(policy))
module.exit_json(changed=changed, autoscale_policy=rax_to_dict(policy))
else:
try:
@ -235,7 +220,7 @@ def rax_asp(module, at=None, change=0, cron=None, cooldown=300,
except Exception, e:
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():