Merge pull request #5404 from sivel/rax-improvements
rax module: improvements
This commit is contained in:
parent
1e6926b9ab
commit
7520bac8ce
1 changed files with 112 additions and 49 deletions
|
@ -26,6 +26,13 @@ options:
|
|||
api_key:
|
||||
description:
|
||||
- Rackspace API key (overrides I(credentials))
|
||||
auto_increment:
|
||||
description:
|
||||
- Whether or not to increment a single number with the name of the
|
||||
created servers. Only applicable when used with the I(group) attribute
|
||||
or meta key.
|
||||
default: yes
|
||||
version_added: 1.5
|
||||
count:
|
||||
description:
|
||||
- number of instances to launch
|
||||
|
@ -147,6 +154,26 @@ EXAMPLES = '''
|
|||
networks:
|
||||
- private
|
||||
- public
|
||||
register: rax
|
||||
|
||||
- name: Build an exact count of cloud servers with incremented names
|
||||
hosts: local
|
||||
gather_facts: False
|
||||
tasks:
|
||||
- name: Server build requests
|
||||
local_action:
|
||||
module: rax
|
||||
credentials: ~/.raxpub
|
||||
name: test%03d.example.org
|
||||
flavor: performance1-1
|
||||
image: ubuntu-1204-lts-precise-pangolin
|
||||
state: present
|
||||
count: 10
|
||||
count_offset: 10
|
||||
exact_count: yes
|
||||
group: test
|
||||
wait: yes
|
||||
register: rax
|
||||
'''
|
||||
|
||||
import sys
|
||||
|
@ -199,7 +226,7 @@ def create(module, names, flavor, image, meta, key_name, files,
|
|||
lpath = os.path.expanduser(files[rpath])
|
||||
try:
|
||||
fileobj = open(lpath, 'r')
|
||||
files[rpath] = fileobj
|
||||
files[rpath] = fileobj.read()
|
||||
except Exception, e:
|
||||
module.fail_json(msg='Failed to load %s' % lpath)
|
||||
try:
|
||||
|
@ -347,7 +374,8 @@ def delete(module, instance_ids, wait, wait_timeout):
|
|||
|
||||
def cloudservers(module, state, name, flavor, image, meta, key_name, files,
|
||||
wait, wait_timeout, disk_config, count, group,
|
||||
instance_ids, exact_count, networks, count_offset):
|
||||
instance_ids, exact_count, networks, count_offset,
|
||||
auto_increment):
|
||||
cs = pyrax.cloudservers
|
||||
cnw = pyrax.cloud_networks
|
||||
servers = []
|
||||
|
@ -358,6 +386,15 @@ def cloudservers(module, state, name, flavor, image, meta, key_name, files,
|
|||
elif 'group' in meta and group is None:
|
||||
group = meta['group']
|
||||
|
||||
# When using state=absent with group, the absent block won't match the
|
||||
# names properly. Use the exact_count functionality to decrease the count
|
||||
# to the desired level
|
||||
was_absent = False
|
||||
if group is not None and state == 'absent':
|
||||
exact_count = True
|
||||
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:
|
||||
|
@ -416,27 +453,43 @@ def cloudservers(module, state, name, flavor, image, meta, key_name, files,
|
|||
module.fail_json(msg='"group" must be provided when using '
|
||||
'"exact_count"')
|
||||
else:
|
||||
numbers = set()
|
||||
if auto_increment:
|
||||
numbers = set()
|
||||
|
||||
try:
|
||||
name % 0
|
||||
except TypeError, e:
|
||||
if e.message.startswith('not all'):
|
||||
name = '%s%%d' % name
|
||||
try:
|
||||
name % 0
|
||||
except TypeError, e:
|
||||
if e.message.startswith('not all'):
|
||||
name = '%s%%d' % name
|
||||
else:
|
||||
module.fail_json(msg=e.message)
|
||||
|
||||
pattern = re.sub(r'%\d+[sd]', r'(\d+)', name)
|
||||
for server in cs.servers.list():
|
||||
if server.metadata.get('group') == group:
|
||||
servers.append(server)
|
||||
match = re.search(pattern, server.name)
|
||||
if match:
|
||||
number = int(match.group(1))
|
||||
numbers.add(number)
|
||||
|
||||
number_range = xrange(count_offset, count_offset + count)
|
||||
available_numbers = list(set(number_range)
|
||||
.difference(numbers))
|
||||
else:
|
||||
for server in cs.servers.list():
|
||||
if server.metadata.get('group') == group:
|
||||
servers.append(server)
|
||||
|
||||
# If state was absent but the count was changed,
|
||||
# assume we only wanted to remove that number of instances
|
||||
if was_absent:
|
||||
diff = len(servers) - count
|
||||
if diff < 0:
|
||||
count = 0
|
||||
else:
|
||||
module.fail_json(msg=e.message)
|
||||
count = diff
|
||||
|
||||
pattern = re.sub(r'%\d+[sd]', r'(\d+)', name)
|
||||
for server in cs.servers.list():
|
||||
if server.metadata.get('group') == group:
|
||||
servers.append(server)
|
||||
match = re.search(pattern, server.name)
|
||||
if match:
|
||||
number = int(match.group(1))
|
||||
numbers.add(number)
|
||||
|
||||
number_range = xrange(count_offset, count_offset + count)
|
||||
available_numbers = list(set(number_range).difference(numbers))
|
||||
if len(servers) > count:
|
||||
state = 'absent'
|
||||
del servers[:count]
|
||||
|
@ -445,45 +498,52 @@ def cloudservers(module, state, name, flavor, image, meta, key_name, files,
|
|||
instance_ids.append(server.id)
|
||||
delete(module, instance_ids, wait, wait_timeout)
|
||||
elif len(servers) < count:
|
||||
names = []
|
||||
numbers_to_use = available_numbers[:count - len(servers)]
|
||||
for number in numbers_to_use:
|
||||
names.append(name % number)
|
||||
if auto_increment:
|
||||
names = []
|
||||
name_slice = count - len(servers)
|
||||
numbers_to_use = available_numbers[:name_slice]
|
||||
for number in numbers_to_use:
|
||||
names.append(name % number)
|
||||
else:
|
||||
names = [name] * (count - len(servers))
|
||||
else:
|
||||
module.exit_json(changed=False, action=None, instances=[],
|
||||
success=[], error=[], timeout=[],
|
||||
instance_ids={'instances': [],
|
||||
'success': [], 'error': [],
|
||||
'timeout': []})
|
||||
|
||||
else:
|
||||
if group is not None:
|
||||
numbers = set()
|
||||
if auto_increment:
|
||||
numbers = set()
|
||||
|
||||
try:
|
||||
name % 0
|
||||
except TypeError, e:
|
||||
if e.message.startswith('not all'):
|
||||
name = '%s%%d' % name
|
||||
else:
|
||||
module.fail_json(msg=e.message)
|
||||
try:
|
||||
name % 0
|
||||
except TypeError, e:
|
||||
if e.message.startswith('not all'):
|
||||
name = '%s%%d' % name
|
||||
else:
|
||||
module.fail_json(msg=e.message)
|
||||
|
||||
pattern = re.sub(r'%\d+[sd]', r'(\d+)', name)
|
||||
for server in cs.servers.list():
|
||||
if server.metadata.get('group') == group:
|
||||
servers.append(server)
|
||||
match = re.search(pattern, server.name)
|
||||
if match:
|
||||
number = int(match.group(1))
|
||||
numbers.add(number)
|
||||
pattern = re.sub(r'%\d+[sd]', r'(\d+)', name)
|
||||
for server in cs.servers.list():
|
||||
if server.metadata.get('group') == group:
|
||||
servers.append(server)
|
||||
match = re.search(pattern, server.name)
|
||||
if match:
|
||||
number = int(match.group(1))
|
||||
numbers.add(number)
|
||||
|
||||
number_range = xrange(count_offset,
|
||||
count_offset + count + len(numbers))
|
||||
available_numbers = list(set(number_range).difference(numbers))
|
||||
names = []
|
||||
numbers_to_use = available_numbers[:count]
|
||||
for number in numbers_to_use:
|
||||
names.append(name % number)
|
||||
number_range = xrange(count_offset,
|
||||
count_offset + count + len(numbers))
|
||||
available_numbers = list(set(number_range)
|
||||
.difference(numbers))
|
||||
names = []
|
||||
numbers_to_use = available_numbers[:count]
|
||||
for number in numbers_to_use:
|
||||
names.append(name % number)
|
||||
else:
|
||||
names = [name] * count
|
||||
else:
|
||||
search_opts = {
|
||||
'name': name,
|
||||
|
@ -552,6 +612,7 @@ def main():
|
|||
argument_spec = rax_argument_spec()
|
||||
argument_spec.update(
|
||||
dict(
|
||||
auto_increment=dict(choices=BOOLEANS, default=True, type='bool'),
|
||||
count=dict(default=1, type='int'),
|
||||
count_offset=dict(default=1, type='int'),
|
||||
disk_config=dict(default='auto', choices=['auto', 'manual']),
|
||||
|
@ -584,6 +645,7 @@ def main():
|
|||
'please remove "service: cloudservers" from your '
|
||||
'playbook pertaining to the "rax" module')
|
||||
|
||||
auto_increment = module.params.get('auto_increment')
|
||||
count = module.params.get('count')
|
||||
count_offset = module.params.get('count_offset')
|
||||
disk_config = module.params.get('disk_config').upper()
|
||||
|
@ -605,7 +667,8 @@ def main():
|
|||
|
||||
cloudservers(module, state, name, flavor, image, meta, key_name, files,
|
||||
wait, wait_timeout, disk_config, count, group,
|
||||
instance_ids, exact_count, networks, count_offset)
|
||||
instance_ids, exact_count, networks, count_offset,
|
||||
auto_increment)
|
||||
|
||||
|
||||
# import module snippets
|
||||
|
|
Loading…
Reference in a new issue