Split nova floating-ip pool logic
The desires around getting a floating ip associated with a pool and getting a floating ip not associated with a pool is just different enough that following it as one set of nested ifs is tricky. Split the function into two, one for the pool and one for the non-pool logic.
This commit is contained in:
parent
6da266f64c
commit
10a50b4a61
1 changed files with 107 additions and 87 deletions
|
@ -193,21 +193,116 @@ def _delete_server(module, nova):
|
||||||
module.fail_json(msg = "Timed out waiting for server to get deleted, please check manually")
|
module.fail_json(msg = "Timed out waiting for server to get deleted, please check manually")
|
||||||
|
|
||||||
|
|
||||||
|
def _add_floating_ip_from_pool(module, nova, server, floating_ip_obj):
|
||||||
|
|
||||||
|
# empty dict and list
|
||||||
|
usable_floating_ips = {}
|
||||||
|
pools = []
|
||||||
|
|
||||||
|
# user specified
|
||||||
|
pools = module.params['floating_ip']['pools']
|
||||||
|
|
||||||
|
# get the list of all floating IPs. Mileage may
|
||||||
|
# vary according to Nova Compute configuration
|
||||||
|
# per cloud provider
|
||||||
|
all_floating_ips = floating_ip_obj.list()
|
||||||
|
|
||||||
|
# iterate through all pools of IP address. Empty
|
||||||
|
# string means all and is the default value
|
||||||
|
for pool in pools:
|
||||||
|
# temporary list per pool
|
||||||
|
pool_ips = []
|
||||||
|
# loop through all floating IPs
|
||||||
|
for f_ip in all_floating_ips:
|
||||||
|
# if not reserved and the correct pool, add
|
||||||
|
if f_ip.instance_id is None and (f_ip.pool == pool):
|
||||||
|
pool_ips.append(f_ip.ip)
|
||||||
|
# only need one
|
||||||
|
break
|
||||||
|
|
||||||
|
# if the list is empty, add for this pool
|
||||||
|
if not pool_ips:
|
||||||
|
try:
|
||||||
|
new_ip = nova.floating_ips.create(pool)
|
||||||
|
except Exception, e:
|
||||||
|
module.fail_json(msg = "Unable to create floating ip")
|
||||||
|
pool_ips.append(new_ip.ip)
|
||||||
|
# Add to the main list
|
||||||
|
usable_floating_ips[pool] = pool_ips
|
||||||
|
|
||||||
|
# finally, add ip(s) to instance for each pool
|
||||||
|
for pool in usable_floating_ips:
|
||||||
|
for ip in usable_floating_ips[pool]:
|
||||||
|
try:
|
||||||
|
server.add_floating_ip(ip)
|
||||||
|
# We only need to assign one ip - but there is an inherent
|
||||||
|
# race condition and some other cloud operation may have
|
||||||
|
# stolen an available floating ip
|
||||||
|
break
|
||||||
|
except Exception, e:
|
||||||
|
module.fail_json(msg = "Error attaching IP %s to instance %s: %s " % (ip, server.id, e.message))
|
||||||
|
|
||||||
|
|
||||||
|
def _add_floating_ip_no_pool(module, nova, server, floating_ip_obj):
|
||||||
|
|
||||||
|
usable_floating_ips = list()
|
||||||
|
|
||||||
|
# if there is a list of IP addresses, make that the list
|
||||||
|
if module.params['floating_ip'].has_key('ips'):
|
||||||
|
usable_floating_ips = module.params['floating_ip']['ips']
|
||||||
|
else:
|
||||||
|
# get the list of all floating IPs. Mileage may
|
||||||
|
# vary according to Nova Compute configuration
|
||||||
|
# per cloud provider
|
||||||
|
for f_ip in floating_ip_obj.list():
|
||||||
|
# if not reserved and the correct pool, add
|
||||||
|
if f_ip.instance_id is None:
|
||||||
|
usable_floating_ips.append(f_ip.ip)
|
||||||
|
|
||||||
|
if not usable_floating_ips:
|
||||||
|
try:
|
||||||
|
new_ip = nova.floating_ips.create()
|
||||||
|
except Exception, e:
|
||||||
|
module.fail_json(msg = "Unable to create floating ip")
|
||||||
|
usable_floating_ips.append(new_ip.ip)
|
||||||
|
|
||||||
|
# finally, add ip(s) to instance
|
||||||
|
for ip in usable_floating_ips:
|
||||||
|
try:
|
||||||
|
server.add_floating_ip(ip)
|
||||||
|
except Exception, e:
|
||||||
|
module.fail_json(msg = "Error attaching IP %s to instance %s: %s " % (ip, server.id, e.message))
|
||||||
|
|
||||||
|
|
||||||
|
def _add_floating_ip(module, nova, server):
|
||||||
|
# instantiate FloatingIPManager object
|
||||||
|
floating_ip_obj = floating_ips.FloatingIPManager(nova)
|
||||||
|
|
||||||
|
if module.params['floating_ip'].has_key('pools'):
|
||||||
|
_add_floating_ip_from_pool(module, nova, server, floating_ip_obj)
|
||||||
|
else:
|
||||||
|
_add_floating_ip_no_pool(module, nova, server, floating_ip_obj)
|
||||||
|
|
||||||
|
# this may look redundant, but if there is now a
|
||||||
|
# floating IP, then it needs to be obtained from
|
||||||
|
# a recent server object if the above code path exec'd
|
||||||
|
try:
|
||||||
|
server = nova.servers.get(server.id)
|
||||||
|
except Exception, e:
|
||||||
|
module.fail_json(msg = "Error in getting info from instance: %s " % e.message)
|
||||||
|
return server
|
||||||
|
|
||||||
|
|
||||||
def _create_server(module, nova):
|
def _create_server(module, nova):
|
||||||
# issue an error early on and not launch the instance
|
# issue an error early on and not launch the instance
|
||||||
if module.params['floating_ip'] != None:
|
if module.params['floating_ip'] is not None:
|
||||||
if module.params['floating_ip'].has_key('ips'):
|
if module.params['floating_ip'].has_key('ips'):
|
||||||
# can't specify "ips" and "auto" both
|
# can't specify "ips" and "auto" both
|
||||||
if module.params['floating_ip'].has_key('auto') and \
|
if module.params['floating_ip'].has_key('auto') and module.params['floating_ip']['auto']:
|
||||||
module.params['floating_ip']['auto'] is True:
|
module.fail_json(msg = "For floating_ips - you cannot specify both 'auto' and 'ips'!")
|
||||||
err_msg = "For floating_ips - "
|
|
||||||
err_msg += "you cannot specify both 'auto' and 'ips'!"
|
|
||||||
module.fail_json(msg = err_msg)
|
|
||||||
# can't specify "ips" and "pools" both
|
# can't specify "ips" and "pools" both
|
||||||
if module.params['floating_ip'].has_key('pools'):
|
if module.params['floating_ip'].has_key('pools'):
|
||||||
err_msg = "For floating_ips - "
|
module.fail_json(msg = "For floating_ips - you cannot specify both 'pools' and 'ips'!")
|
||||||
err_msg += "you cannot specify both 'ips' and 'pools'!"
|
|
||||||
module.fail_json(msg = err_msg)
|
|
||||||
|
|
||||||
bootargs = [module.params['name'], module.params['image_id'], module.params['flavor_id']]
|
bootargs = [module.params['name'], module.params['image_id'], module.params['flavor_id']]
|
||||||
bootkwargs = {
|
bootkwargs = {
|
||||||
|
@ -231,86 +326,11 @@ def _create_server(module, nova):
|
||||||
try:
|
try:
|
||||||
server = nova.servers.get(server.id)
|
server = nova.servers.get(server.id)
|
||||||
except Exception, e:
|
except Exception, e:
|
||||||
module.fail_json(msg = \
|
module.fail_json( msg = "Error in getting info from instance: %s" % e.message)
|
||||||
"Error in getting info from instance: %s"\
|
|
||||||
% e.message
|
|
||||||
)
|
|
||||||
if server.status == 'ACTIVE':
|
if server.status == 'ACTIVE':
|
||||||
# if floating_ip is specified, then attach
|
# if floating_ip is specified, then attach
|
||||||
if module.params['floating_ip'] != None:
|
if module.params['floating_ip'] is not None:
|
||||||
# instantiate FloatingIPManager object
|
server = _add_floating_ip(module, nova, server)
|
||||||
floating_ip_obj = floating_ips.FloatingIPManager(nova)
|
|
||||||
# empty dict and list
|
|
||||||
usable_floating_ips = {}
|
|
||||||
pools = []
|
|
||||||
|
|
||||||
# if floating_ip pools are defined, then make that
|
|
||||||
# the list of pools
|
|
||||||
if module.params['floating_ip'].has_key('pools'):
|
|
||||||
# user specified
|
|
||||||
pools = module.params['floating_ip']['pools']
|
|
||||||
else:
|
|
||||||
# otherwise all
|
|
||||||
pools = ['']
|
|
||||||
|
|
||||||
# if there is a list of IP addresses, make that the list
|
|
||||||
if module.params['floating_ip'].has_key('ips'):
|
|
||||||
usable_floating_ips[''] = \
|
|
||||||
module.params['floating_ip']['ips']
|
|
||||||
|
|
||||||
# if 'auto', then assign automatically, no pool needed
|
|
||||||
if module.params['floating_ip'].has_key('auto') and \
|
|
||||||
module.params['floating_ip']['auto'] is True:
|
|
||||||
# get the list of all floating IPs. Mileage may
|
|
||||||
# vary according to Nova Compute configuration
|
|
||||||
# per cloud provider
|
|
||||||
all_floating_ips = floating_ip_obj.list()
|
|
||||||
|
|
||||||
# iterate through all pools of IP address. Empty
|
|
||||||
# string means all and is the default value
|
|
||||||
for pool in pools:
|
|
||||||
# temporary list per pool
|
|
||||||
pool_ips = []
|
|
||||||
# loop through all floating IPs
|
|
||||||
for f_ip in all_floating_ips:
|
|
||||||
# if not reserved and the correct pool, add
|
|
||||||
if f_ip.instance_id == None and \
|
|
||||||
(f_ip.pool == pool or pool == ''):
|
|
||||||
pool_ips.append(f_ip.ip)
|
|
||||||
# one per pool
|
|
||||||
break
|
|
||||||
# if the list is empty, add for this pool
|
|
||||||
if len(pool_ips) == 0:
|
|
||||||
try:
|
|
||||||
new_ip = nova.floating_ips.create(pool)
|
|
||||||
except Exception, e:
|
|
||||||
module.fail_json(msg = \
|
|
||||||
"Unable to create \
|
|
||||||
floating ip")
|
|
||||||
pool_ips.append(new_ip.ip)
|
|
||||||
# Add to the main list
|
|
||||||
usable_floating_ips[pool] = pool_ips
|
|
||||||
|
|
||||||
# finally, add ip(s) to instance for each pool
|
|
||||||
for pool in usable_floating_ips:
|
|
||||||
for ip in usable_floating_ips[pool]:
|
|
||||||
try:
|
|
||||||
server.add_floating_ip(ip)
|
|
||||||
except Exception, e:
|
|
||||||
module.fail_json(msg = \
|
|
||||||
"Error attaching IP %s to \
|
|
||||||
instance %s: %s " % \
|
|
||||||
(ip, server.id, e.message))
|
|
||||||
|
|
||||||
# this may look redundant, but if there is now a
|
|
||||||
# floating IP, then it needs to be obtained from
|
|
||||||
# a recent server object if the above code path exec'd
|
|
||||||
try:
|
|
||||||
server = nova.servers.get(server.id)
|
|
||||||
except Exception, e:
|
|
||||||
module.fail_json(msg = \
|
|
||||||
"Error in getting info from \
|
|
||||||
instance: %s " % e.message)
|
|
||||||
|
|
||||||
private = [ x['addr'] for x in getattr(server, 'addresses').itervalues().next() if 'OS-EXT-IPS:type' in x and x['OS-EXT-IPS:type'] == 'fixed']
|
private = [ x['addr'] for x in getattr(server, 'addresses').itervalues().next() if 'OS-EXT-IPS:type' in x and x['OS-EXT-IPS:type'] == 'fixed']
|
||||||
public = [ x['addr'] for x in getattr(server, 'addresses').itervalues().next() if 'OS-EXT-IPS:type' in x and x['OS-EXT-IPS:type'] == 'floating']
|
public = [ x['addr'] for x in getattr(server, 'addresses').itervalues().next() if 'OS-EXT-IPS:type' in x and x['OS-EXT-IPS:type'] == 'floating']
|
||||||
|
|
Loading…
Reference in a new issue