Move additional rackspace common code into module_utils/rax.py

This commit is contained in:
Matt Martz 2014-06-10 10:08:12 -05:00
parent f0ae6204e4
commit 07d80b5f1e
14 changed files with 30 additions and 352 deletions

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,
@ -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,

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,30 +113,15 @@ 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"""
def rax_dns_record(module, data=None, comment=None, loadbalancer=None,
name=None, server=None, state='present', ttl=7200):
changed = False
results = []
@ -301,7 +286,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:

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():