moved floating ip db access and sanity checking from network api into network manager
added floating ip get by fixed address added fixed_ip_get moved floating ip testing from osapi into the network tests where they belong Change-Id: I3ee53971206e37405a2adc2491412f7896e1af87
This commit is contained in:
@@ -80,8 +80,8 @@ class FloatingIPController(object):
|
||||
context = req.environ['nova.context']
|
||||
|
||||
try:
|
||||
# FIXME(ja) - why does self.network_api.list_floating_ips raise?
|
||||
floating_ips = self.network_api.list_floating_ips(context)
|
||||
get_floating_ips = self.network_api.get_floating_ips_by_project
|
||||
floating_ips = get_floating_ips(context)
|
||||
except exception.FloatingIpNotFoundForProject:
|
||||
floating_ips = []
|
||||
|
||||
@@ -92,7 +92,7 @@ class FloatingIPController(object):
|
||||
|
||||
try:
|
||||
address = self.network_api.allocate_floating_ip(context)
|
||||
ip = self.network_api.get_floating_ip_by_ip(context, address)
|
||||
ip = self.network_api.get_floating_ip_by_address(context, address)
|
||||
except rpc.RemoteError as ex:
|
||||
# NOTE(tr3buchet) - why does this block exist?
|
||||
if ex.exc_type == 'NoMoreFloatingIps':
|
||||
@@ -162,7 +162,8 @@ class Floating_ips(extensions.ExtensionDescriptor):
|
||||
msg = _("Address not specified")
|
||||
raise webob.exc.HTTPBadRequest(explanation=msg)
|
||||
|
||||
floating_ip = self.network_api.get_floating_ip_by_ip(context, address)
|
||||
floating_ip = self.network_api.get_floating_ip_by_address(context,
|
||||
address)
|
||||
if floating_ip.get('fixed_ip'):
|
||||
try:
|
||||
self.network_api.disassociate_floating_ip(context, address)
|
||||
|
||||
@@ -1521,8 +1521,8 @@ class API(base.Base):
|
||||
LOG.warning(_("multiple fixed_ips exist, using the first: %s"),
|
||||
fixed_ip_addrs[0])
|
||||
self.network_api.associate_floating_ip(context,
|
||||
floating_ip=address,
|
||||
fixed_ip=fixed_ip_addrs[0])
|
||||
floating_address=address,
|
||||
fixed_address=fixed_ip_addrs[0])
|
||||
|
||||
def get_instance_metadata(self, context, instance_id):
|
||||
"""Get all metadata associated with an instance."""
|
||||
|
||||
@@ -372,6 +372,11 @@ def fixed_ip_disassociate_all_by_timeout(context, host, time):
|
||||
return IMPL.fixed_ip_disassociate_all_by_timeout(context, host, time)
|
||||
|
||||
|
||||
def fixed_ip_get(context, id):
|
||||
"""Get fixed ip by id or raise if it does not exist."""
|
||||
return IMPL.fixed_ip_get(context, id)
|
||||
|
||||
|
||||
def fixed_ip_get_all(context):
|
||||
"""Get all defined fixed ips."""
|
||||
return IMPL.fixed_ip_get_all(context)
|
||||
|
||||
@@ -796,6 +796,25 @@ def fixed_ip_disassociate_all_by_timeout(_context, host, time):
|
||||
return result
|
||||
|
||||
|
||||
@require_context
|
||||
def fixed_ip_get(context, id, session=None):
|
||||
if not session:
|
||||
session = get_session()
|
||||
result = session.query(models.FixedIp).\
|
||||
filter_by(id=id).\
|
||||
filter_by(deleted=can_read_deleted(context)).\
|
||||
options(joinedload('floating_ips')).\
|
||||
options(joinedload('network')).\
|
||||
first()
|
||||
if not result:
|
||||
raise exception.FixedIpNotFound(id=id)
|
||||
|
||||
if is_user_context(context):
|
||||
authorize_project_context(context, result.instance.project_id)
|
||||
|
||||
return result
|
||||
|
||||
|
||||
@require_admin_context
|
||||
def fixed_ip_get_all(context, session=None):
|
||||
if not session:
|
||||
|
||||
@@ -539,8 +539,12 @@ class NoMoreFloatingIps(FloatingIpNotFound):
|
||||
message = _("Zero floating ips available.")
|
||||
|
||||
|
||||
class FloatingIpAlreadyInUse(NovaException):
|
||||
message = _("Floating ip %(address)s already in use by %(fixed_ip)s.")
|
||||
class FloatingIpAssociated(NovaException):
|
||||
message = _("Floating ip %(address)s is associated.")
|
||||
|
||||
|
||||
class FloatingIpNotAssociated(NovaException):
|
||||
message = _("Floating ip %(address)s is not associated.")
|
||||
|
||||
|
||||
class NoFloatingIpsDefined(NotFound):
|
||||
|
||||
@@ -34,17 +34,27 @@ class API(base.Base):
|
||||
"""API for interacting with the network manager."""
|
||||
|
||||
def get_floating_ip(self, context, id):
|
||||
rv = self.db.floating_ip_get(context, id)
|
||||
return dict(rv.iteritems())
|
||||
return rpc.call(context,
|
||||
FLAGS.network_topic,
|
||||
{'method': 'get_floating_ip',
|
||||
'args': {'id': id}})
|
||||
|
||||
def get_floating_ip_by_ip(self, context, address):
|
||||
res = self.db.floating_ip_get_by_address(context, address)
|
||||
return dict(res.iteritems())
|
||||
def get_floating_ip_by_address(self, context, address):
|
||||
return rpc.call(context,
|
||||
FLAGS.network_topic,
|
||||
{'method': 'get_floating_ip_by_address',
|
||||
'args': {'address': address}})
|
||||
|
||||
def list_floating_ips(self, context):
|
||||
ips = self.db.floating_ip_get_all_by_project(context,
|
||||
context.project_id)
|
||||
return ips
|
||||
def get_floating_ips_by_project(self, context):
|
||||
return rpc.call(context,
|
||||
FLAGS.network_topic,
|
||||
{'method': 'get_floating_ips_by_project'})
|
||||
|
||||
def get_floating_ips_by_fixed_address(self, context, fixed_address):
|
||||
return rpc.call(context,
|
||||
FLAGS.network_topic,
|
||||
{'method': 'get_floating_ips_by_fixed_address',
|
||||
'args': {'address': address}})
|
||||
|
||||
def get_floating_ips_by_fixed_address(self, context, fixed_address):
|
||||
return rpc.call(context,
|
||||
@@ -53,12 +63,13 @@ class API(base.Base):
|
||||
'args': {'fixed_address': fixed_address}})
|
||||
|
||||
def get_vifs_by_instance(self, context, instance_id):
|
||||
return rpc.call(context, FLAGS.network_topic,
|
||||
return rpc.call(context,
|
||||
FLAGS.network_topic,
|
||||
{'method': 'get_vifs_by_instance',
|
||||
'args': {'instance_id': instance_id}})
|
||||
|
||||
def allocate_floating_ip(self, context):
|
||||
"""Adds a floating ip to a project."""
|
||||
"""Adds a floating ip to a project. (allocates)"""
|
||||
# NOTE(vish): We don't know which network host should get the ip
|
||||
# when we allocate, so just send it to any one. This
|
||||
# will probably need to move into a network supervisor
|
||||
@@ -70,89 +81,33 @@ class API(base.Base):
|
||||
|
||||
def release_floating_ip(self, context, address,
|
||||
affect_auto_assigned=False):
|
||||
"""Removes floating ip with address from a project."""
|
||||
floating_ip = self.db.floating_ip_get_by_address(context, address)
|
||||
if floating_ip['fixed_ip']:
|
||||
raise exception.ApiError(_('Floating ip is in use. '
|
||||
'Disassociate it before releasing.'))
|
||||
if not affect_auto_assigned and floating_ip.get('auto_assigned'):
|
||||
return
|
||||
# NOTE(vish): We don't know which network host should get the ip
|
||||
# when we deallocate, so just send it to any one. This
|
||||
# will probably need to move into a network supervisor
|
||||
# at some point.
|
||||
"""Removes floating ip with address from a project. (deallocates)"""
|
||||
rpc.cast(context,
|
||||
FLAGS.network_topic,
|
||||
{'method': 'deallocate_floating_ip',
|
||||
'args': {'floating_address': floating_ip['address']}})
|
||||
'args': {'floating_address': address,
|
||||
'affect_auto_assigned': affect_auto_assigned}})
|
||||
|
||||
def associate_floating_ip(self, context, floating_ip, fixed_ip,
|
||||
def associate_floating_ip(self, context, floating_address, fixed_address,
|
||||
affect_auto_assigned=False):
|
||||
"""Associates a floating ip with a fixed ip.
|
||||
|
||||
ensures floating ip is allocated to the project in context
|
||||
|
||||
:param fixed_ip: is either fixed_ip object or a string fixed ip address
|
||||
:param floating_ip: is a string floating ip address
|
||||
"""
|
||||
# NOTE(tr3buchet): i don't like the "either or" argument type
|
||||
# funcationility but i've left it alone for now
|
||||
# TODO(tr3buchet): this function needs to be rewritten to move
|
||||
# the network related db lookups into the network host code
|
||||
if isinstance(fixed_ip, basestring):
|
||||
fixed_ip = self.db.fixed_ip_get_by_address(context, fixed_ip)
|
||||
floating_ip = self.db.floating_ip_get_by_address(context, floating_ip)
|
||||
if not affect_auto_assigned and floating_ip.get('auto_assigned'):
|
||||
return
|
||||
# Check if the floating ip address is allocated
|
||||
if floating_ip['project_id'] is None:
|
||||
raise exception.ApiError(_('Address (%s) is not allocated') %
|
||||
floating_ip['address'])
|
||||
# Check if the floating ip address is allocated to the same project
|
||||
if floating_ip['project_id'] != context.project_id:
|
||||
LOG.warn(_('Address (%(address)s) is not allocated to your '
|
||||
'project (%(project)s)'),
|
||||
{'address': floating_ip['address'],
|
||||
'project': context.project_id})
|
||||
raise exception.ApiError(_('Address (%(address)s) is not '
|
||||
'allocated to your project'
|
||||
'(%(project)s)') %
|
||||
{'address': floating_ip['address'],
|
||||
'project': context.project_id})
|
||||
|
||||
# If this address has been previously associated to a
|
||||
# different instance, disassociate the floating_ip
|
||||
if floating_ip['fixed_ip'] and floating_ip['fixed_ip'] is not fixed_ip:
|
||||
self.disassociate_floating_ip(context, floating_ip['address'])
|
||||
|
||||
# NOTE(vish): if we are multi_host, send to the instances host
|
||||
if fixed_ip['network']['multi_host']:
|
||||
host = fixed_ip['instance']['host']
|
||||
else:
|
||||
host = fixed_ip['network']['host']
|
||||
rpc.cast(context,
|
||||
self.db.queue_get_for(context, FLAGS.network_topic, host),
|
||||
FLAGS.network_topic,
|
||||
{'method': 'associate_floating_ip',
|
||||
'args': {'floating_address': floating_ip['address'],
|
||||
'fixed_address': fixed_ip['address']}})
|
||||
'args': {'floating_address': floating_address,
|
||||
'fixed_address': fixed_address,
|
||||
'affect_auto_assigned': affect_auto_assigned}})
|
||||
|
||||
def disassociate_floating_ip(self, context, address,
|
||||
affect_auto_assigned=False):
|
||||
"""Disassociates a floating ip from fixed ip it is associated with."""
|
||||
floating_ip = self.db.floating_ip_get_by_address(context, address)
|
||||
if not affect_auto_assigned and floating_ip.get('auto_assigned'):
|
||||
return
|
||||
if not floating_ip.get('fixed_ip'):
|
||||
raise exception.ApiError('Address is not associated.')
|
||||
# NOTE(vish): if we are multi_host, send to the instances host
|
||||
if floating_ip['fixed_ip']['network']['multi_host']:
|
||||
host = floating_ip['fixed_ip']['instance']['host']
|
||||
else:
|
||||
host = floating_ip['fixed_ip']['network']['host']
|
||||
rpc.call(context,
|
||||
self.db.queue_get_for(context, FLAGS.network_topic, host),
|
||||
rpc.cast(context,
|
||||
FLAGS.network_topic,
|
||||
{'method': 'disassociate_floating_ip',
|
||||
'args': {'floating_address': floating_ip['address']}})
|
||||
'args': {'address': address}})
|
||||
|
||||
def allocate_for_instance(self, context, instance, **kwargs):
|
||||
"""Allocates all network structures for an instance.
|
||||
|
||||
@@ -219,26 +219,26 @@ class FloatingIP(object):
|
||||
# call the next inherited class's allocate_for_instance()
|
||||
# which is currently the NetworkManager version
|
||||
# do this first so fixed ip is already allocated
|
||||
ips = super(FloatingIP, self).allocate_for_instance(context, **kwargs)
|
||||
nw_info = \
|
||||
super(FloatingIP, self).allocate_for_instance(context, **kwargs)
|
||||
if FLAGS.auto_assign_floating_ip:
|
||||
# allocate a floating ip (public_ip is just the address string)
|
||||
public_ip = self.allocate_floating_ip(context, project_id)
|
||||
# allocate a floating ip
|
||||
floating_address = self.allocate_floating_ip(context, project_id)
|
||||
# set auto_assigned column to true for the floating ip
|
||||
self.db.floating_ip_set_auto_assigned(context, public_ip)
|
||||
# get the floating ip object from public_ip string
|
||||
floating_ip = self.db.floating_ip_get_by_address(context,
|
||||
public_ip)
|
||||
self.db.floating_ip_set_auto_assigned(context, floating_address)
|
||||
|
||||
# get the first fixed_ip belonging to the instance
|
||||
fixed_ips = self.db.fixed_ip_get_by_instance(context, instance_id)
|
||||
fixed_ip = fixed_ips[0] if fixed_ips else None
|
||||
# get the first fixed address belonging to the instance
|
||||
for nw, info in nw_info:
|
||||
if info.get('ips'):
|
||||
fixed_address = info['ips'][0]['ip']
|
||||
break
|
||||
|
||||
# call to correct network host to associate the floating ip
|
||||
self.network_api.associate_floating_ip(context,
|
||||
floating_ip,
|
||||
fixed_ip,
|
||||
# associate the floating ip to fixed_ip
|
||||
self.associate_floating_ip(context,
|
||||
floating_address,
|
||||
fixed_address,
|
||||
affect_auto_assigned=True)
|
||||
return ips
|
||||
return nw_info
|
||||
|
||||
def deallocate_for_instance(self, context, **kwargs):
|
||||
"""Handles deallocating floating IP resources for an instance.
|
||||
@@ -258,21 +258,33 @@ class FloatingIP(object):
|
||||
# disassociate floating ips related to fixed_ip
|
||||
for floating_ip in fixed_ip.floating_ips:
|
||||
address = floating_ip['address']
|
||||
self.network_api.disassociate_floating_ip(context, address)
|
||||
self.disassociate_floating_ip(context, address, True)
|
||||
# deallocate if auto_assigned
|
||||
if floating_ip['auto_assigned']:
|
||||
self.network_api.release_floating_ip(context,
|
||||
address,
|
||||
True)
|
||||
self.release_floating_ip(context, address, True)
|
||||
|
||||
# call the next inherited class's deallocate_for_instance()
|
||||
# which is currently the NetworkManager version
|
||||
# call this after so floating IPs are handled first
|
||||
super(FloatingIP, self).deallocate_for_instance(context, **kwargs)
|
||||
|
||||
def _floating_ip_owned_by_project(self, context, floating_ip):
|
||||
"""Raises if floating ip does not belong to project"""
|
||||
if floating_ip['project_id'] != context.project_id:
|
||||
if floating_ip['project_id'] is None:
|
||||
LOG.warn(_('Address |%(address)s| is not allocated'),
|
||||
{'address': floating_ip['address']})
|
||||
raise exception.NotAuthorized()
|
||||
else:
|
||||
LOG.warn(_('Address |%(address)s| is not allocated to your '
|
||||
'project |%(project)s|'),
|
||||
{'address': floating_ip['address'],
|
||||
'project': context.project_id})
|
||||
raise exception.NotAuthorized()
|
||||
|
||||
def allocate_floating_ip(self, context, project_id):
|
||||
"""Gets an floating ip from the pool."""
|
||||
# NOTE(tr3buchet): all networks hosts in zone now use the same pool
|
||||
# NOTE(tr3buchet): all network hosts in zone now use the same pool
|
||||
LOG.debug("QUOTA: %s" % quota.allowed_floating_ips(context, 1))
|
||||
if quota.allowed_floating_ips(context, 1) < 1:
|
||||
LOG.warn(_('Quota exceeded for %s, tried to allocate '
|
||||
@@ -284,32 +296,146 @@ class FloatingIP(object):
|
||||
return self.db.floating_ip_allocate_address(context,
|
||||
project_id)
|
||||
|
||||
def associate_floating_ip(self, context, floating_address, fixed_address):
|
||||
"""Associates an floating ip to a fixed ip."""
|
||||
def deallocate_floating_ip(self, context, address,
|
||||
affect_auto_assigned=False):
|
||||
"""Returns an floating ip to the pool."""
|
||||
floating_ip = self.db.floating_ip_get_by_address(context, address)
|
||||
|
||||
# handle auto_assigned
|
||||
if not affect_auto_assigned and floating_ip.get('auto_assigned'):
|
||||
return
|
||||
|
||||
# make sure project ownz this floating ip (allocated)
|
||||
self._floating_ip_owned_by_project(context, floating_ip)
|
||||
|
||||
# make sure floating ip is not associated
|
||||
if floating_ip['fixed_ip_id']:
|
||||
floating_address = floating_ip['address']
|
||||
raise exception.FloatingIpAssociated(address=floating_address)
|
||||
|
||||
self.db.floating_ip_deallocate(context, address)
|
||||
|
||||
def associate_floating_ip(self, context, floating_address, fixed_address,
|
||||
affect_auto_assigned=False):
|
||||
"""Associates a floating ip with a fixed ip.
|
||||
|
||||
Makes sure everything makes sense then calls _associate_floating_ip,
|
||||
rpc'ing to correct host if i'm not it.
|
||||
"""
|
||||
floating_ip = self.db.floating_ip_get_by_address(context,
|
||||
floating_address)
|
||||
if floating_ip['fixed_ip']:
|
||||
raise exception.FloatingIpAlreadyInUse(
|
||||
address=floating_ip['address'],
|
||||
fixed_ip=floating_ip['fixed_ip']['address'])
|
||||
# handle auto_assigned
|
||||
if not affect_auto_assigned and floating_ip.get('auto_assigned'):
|
||||
return
|
||||
|
||||
# make sure project ownz this floating ip (allocated)
|
||||
self._floating_ip_owned_by_project(context, floating_ip)
|
||||
|
||||
# make sure floating ip isn't already associated
|
||||
if floating_ip['fixed_ip_id']:
|
||||
floating_address = floating_ip['address']
|
||||
raise exception.FloatingIpAssociated(address=floating_address)
|
||||
|
||||
fixed_ip = self.db.fixed_ip_get_by_address(context, fixed_address)
|
||||
|
||||
# send to correct host, unless i'm the correct host
|
||||
if fixed_ip['network']['multi_host']:
|
||||
instance = self.db.instance_get(context, fixed_ip['instance_id'])
|
||||
host = instance['host']
|
||||
else:
|
||||
host = fixed_ip['network']['host']
|
||||
LOG.info("%s", self.host)
|
||||
if host == self.host:
|
||||
# i'm the correct host
|
||||
self._associate_floating_ip(context, floating_address,
|
||||
fixed_address)
|
||||
else:
|
||||
# send to correct host
|
||||
rpc.cast(context,
|
||||
self.db.queue_get_for(context, FLAGS.network_topic, host),
|
||||
{'method': '_associate_floating_ip',
|
||||
'args': {'floating_address': floating_ip['address'],
|
||||
'fixed_address': fixed_ip['address']}})
|
||||
|
||||
def _associate_floating_ip(self, context, floating_address, fixed_address):
|
||||
"""Performs db and driver calls to associate floating ip & fixed ip"""
|
||||
# associate floating ip
|
||||
self.db.floating_ip_fixed_ip_associate(context,
|
||||
floating_address,
|
||||
fixed_address,
|
||||
self.host)
|
||||
# gogo driver time
|
||||
self.driver.bind_floating_ip(floating_address)
|
||||
self.driver.ensure_floating_forward(floating_address, fixed_address)
|
||||
|
||||
def disassociate_floating_ip(self, context, floating_address):
|
||||
"""Disassociates a floating ip."""
|
||||
fixed_address = self.db.floating_ip_disassociate(context,
|
||||
floating_address)
|
||||
self.driver.unbind_floating_ip(floating_address)
|
||||
self.driver.remove_floating_forward(floating_address, fixed_address)
|
||||
def disassociate_floating_ip(self, context, address,
|
||||
affect_auto_assigned=False):
|
||||
"""Disassociates a floating ip from its fixed ip.
|
||||
|
||||
def deallocate_floating_ip(self, context, floating_address):
|
||||
"""Returns an floating ip to the pool."""
|
||||
self.db.floating_ip_deallocate(context, floating_address)
|
||||
Makes sure everything makes sense then calls _disassociate_floating_ip,
|
||||
rpc'ing to correct host if i'm not it.
|
||||
"""
|
||||
floating_ip = self.db.floating_ip_get_by_address(context, address)
|
||||
|
||||
# handle auto assigned
|
||||
if not affect_auto_assigned and floating_ip.get('auto_assigned'):
|
||||
return
|
||||
|
||||
# make sure project ownz this floating ip (allocated)
|
||||
self._floating_ip_owned_by_project(context, floating_ip)
|
||||
|
||||
# make sure floating ip is associated
|
||||
if not floating_ip.get('fixed_ip_id'):
|
||||
floating_address = floating_ip['address']
|
||||
raise exception.FloatingIpNotAssociated(address=floating_address)
|
||||
|
||||
fixed_ip = self.db.fixed_ip_get(context, floating_ip['fixed_ip_id'])
|
||||
|
||||
# send to correct host, unless i'm the correct host
|
||||
if fixed_ip['network']['multi_host']:
|
||||
instance = self.db.instance_get(context, fixed_ip['instance_id'])
|
||||
host = instance['host']
|
||||
else:
|
||||
host = fixed_ip['network']['host']
|
||||
if host == self.host:
|
||||
# i'm the correct host
|
||||
self._disassociate_floating_ip(context, address)
|
||||
else:
|
||||
# send to correct host
|
||||
rpc.cast(context,
|
||||
self.db.queue_get_for(context, FLAGS.network_topic, host),
|
||||
{'method': '_disassociate_floating_ip',
|
||||
'args': {'address': address}})
|
||||
|
||||
def _disassociate_floating_ip(self, context, address):
|
||||
"""Performs db and driver calls to disassociate floating ip"""
|
||||
# disassociate floating ip
|
||||
fixed_address = self.db.floating_ip_disassociate(context, address)
|
||||
|
||||
# go go driver time
|
||||
self.driver.unbind_floating_ip(address)
|
||||
self.driver.remove_floating_forward(address, fixed_address)
|
||||
|
||||
def get_floating_ip(self, context, id):
|
||||
"""Returns a floating IP as a dict"""
|
||||
return dict(self.db.floating_ip_get(context, id).iteritems())
|
||||
|
||||
def get_floating_ip_by_address(self, context, address):
|
||||
"""Returns a floating IP as a dict"""
|
||||
return dict(self.db.floating_ip_get_by_address(context,
|
||||
address).iteritems())
|
||||
|
||||
def get_floating_ips_by_project(self, context):
|
||||
"""Returns the floating IPs allocated to a project"""
|
||||
ips = self.db.floating_ip_get_all_by_project(context,
|
||||
context.project_id)
|
||||
return [dict(ip.iteritems()) for ip in ips]
|
||||
|
||||
def get_floating_ips_by_fixed_address(self, context, fixed_address):
|
||||
"""Returns the floating IPs associated with a fixed_address"""
|
||||
floating_ips = self.db.floating_ip_get_by_fixed_address(context,
|
||||
fixed_address)
|
||||
return [floating_ip['address'] for floating_ip in floating_ips]
|
||||
|
||||
def get_floating_ips_by_fixed_address(self, context, fixed_address):
|
||||
"""Returns the floating IPs associated with a fixed_address"""
|
||||
@@ -414,11 +540,6 @@ class NetworkManager(manager.SchedulerDependentManager):
|
||||
# floating ips MUST override this or use the Mixin
|
||||
return []
|
||||
|
||||
def get_vifs_by_instance(self, context, instance_id):
|
||||
vifs = self.db.virtual_interface_get_by_instance(context,
|
||||
instance_id)
|
||||
return vifs
|
||||
|
||||
def get_instance_uuids_by_ip_filter(self, context, filters):
|
||||
fixed_ip_filter = filters.get('fixed_ip')
|
||||
ip_filter = re.compile(str(filters.get('ip')))
|
||||
@@ -946,6 +1067,11 @@ class NetworkManager(manager.SchedulerDependentManager):
|
||||
def _get_networks_by_uuids(self, context, network_uuids):
|
||||
return self.db.network_get_all_by_uuids(context, network_uuids)
|
||||
|
||||
def get_vifs_by_instance(self, context, instance_id):
|
||||
"""Returns the vifs associated with an instance"""
|
||||
vifs = self.db.virtual_interface_get_by_instance(context, instance_id)
|
||||
return [dict(vif.iteritems()) for vif in vifs]
|
||||
|
||||
|
||||
class FlatManager(NetworkManager):
|
||||
"""Basic network where no vlans are used.
|
||||
@@ -1004,7 +1130,7 @@ class FlatManager(NetworkManager):
|
||||
self.db.network_update(context, network_ref['id'], net)
|
||||
|
||||
|
||||
class FlatDHCPManager(FloatingIP, RPCAllocateFixedIP, NetworkManager):
|
||||
class FlatDHCPManager(RPCAllocateFixedIP, FloatingIP, NetworkManager):
|
||||
"""Flat networking with dhcp.
|
||||
|
||||
FlatDHCPManager will start up one dhcp server to give out addresses.
|
||||
|
||||
@@ -56,6 +56,7 @@ LOG = log.getLogger('nova.tests')
|
||||
|
||||
class skip_test(object):
|
||||
"""Decorator that skips a test."""
|
||||
# TODO(tr3buchet): remember forever what comstud did here
|
||||
def __init__(self, msg):
|
||||
self.message = msg
|
||||
|
||||
|
||||
@@ -130,24 +130,6 @@ class CloudTestCase(test.TestCase):
|
||||
result = self.cloud.release_address(self.context, address)
|
||||
self.assertEqual(result['releaseResponse'], ['Address released.'])
|
||||
|
||||
def test_release_address_still_associated(self):
|
||||
address = "10.10.10.10"
|
||||
fixed_ip = {'instance': {'id': 1}}
|
||||
floating_ip = {'id': 0,
|
||||
'address': address,
|
||||
'fixed_ip_id': 0,
|
||||
'fixed_ip': fixed_ip,
|
||||
'project_id': None,
|
||||
'auto_assigned': False}
|
||||
network_api = network.api.API()
|
||||
self.mox.StubOutWithMock(network_api.db, 'floating_ip_get_by_address')
|
||||
network_api.db.floating_ip_get_by_address(mox.IgnoreArg(),
|
||||
mox.IgnoreArg()).AndReturn(floating_ip)
|
||||
self.mox.ReplayAll()
|
||||
release = self.cloud.release_address
|
||||
# ApiError: Floating ip is in use. Disassociate it before releasing.
|
||||
self.assertRaises(exception.ApiError, release, self.context, address)
|
||||
|
||||
def test_associate_disassociate_address(self):
|
||||
"""Verifies associate runs cleanly without raising an exception"""
|
||||
address = "10.10.10.10"
|
||||
|
||||
@@ -36,12 +36,12 @@ def network_api_get_floating_ip(self, context, id):
|
||||
'fixed_ip': None}
|
||||
|
||||
|
||||
def network_api_get_floating_ip_by_ip(self, context, address):
|
||||
def network_api_get_floating_ip_by_address(self, context, address):
|
||||
return {'id': 1, 'address': '10.10.10.10',
|
||||
'fixed_ip': {'address': '10.0.0.1', 'instance_id': 1}},
|
||||
'fixed_ip': {'address': '10.0.0.1', 'instance_id': 1}}
|
||||
|
||||
|
||||
def network_api_list_floating_ips(self, context):
|
||||
def network_api_get_floating_ips_by_project(self, context):
|
||||
return [{'id': 1,
|
||||
'address': '10.10.10.10',
|
||||
'fixed_ip': {'address': '10.0.0.1', 'instance_id': 1}},
|
||||
@@ -57,11 +57,11 @@ def network_api_release(self, context, address):
|
||||
pass
|
||||
|
||||
|
||||
def compute_api_associate(self, context, instance_id, floating_ip):
|
||||
def compute_api_associate(self, context, instance_id, address):
|
||||
pass
|
||||
|
||||
|
||||
def network_api_associate(self, context, floating_ip, fixed_ip):
|
||||
def network_api_associate(self, context, floating_address, fixed_address):
|
||||
pass
|
||||
|
||||
|
||||
@@ -110,10 +110,10 @@ class FloatingIpTest(test.TestCase):
|
||||
super(FloatingIpTest, self).setUp()
|
||||
self.stubs.Set(network.api.API, "get_floating_ip",
|
||||
network_api_get_floating_ip)
|
||||
self.stubs.Set(network.api.API, "get_floating_ip_by_ip",
|
||||
network_api_get_floating_ip)
|
||||
self.stubs.Set(network.api.API, "list_floating_ips",
|
||||
network_api_list_floating_ips)
|
||||
self.stubs.Set(network.api.API, "get_floating_ip_by_address",
|
||||
network_api_get_floating_ip_by_address)
|
||||
self.stubs.Set(network.api.API, "get_floating_ips_by_project",
|
||||
network_api_get_floating_ips_by_project)
|
||||
self.stubs.Set(network.api.API, "release_floating_ip",
|
||||
network_api_release)
|
||||
self.stubs.Set(network.api.API, "disassociate_floating_ip",
|
||||
@@ -184,6 +184,7 @@ class FloatingIpTest(test.TestCase):
|
||||
self.assertEqual(res_dict['floating_ip']['ip'], '10.10.10.10')
|
||||
self.assertEqual(res_dict['floating_ip']['instance_id'], 1)
|
||||
|
||||
# test floating ip allocate/release(deallocate)
|
||||
def test_floating_ip_allocate_no_free_ips(self):
|
||||
def fake_call(*args, **kwargs):
|
||||
raise(rpc.RemoteError('NoMoreFloatingIps', '', ''))
|
||||
@@ -196,8 +197,16 @@ class FloatingIpTest(test.TestCase):
|
||||
self.assertEqual(res.status_int, 400)
|
||||
|
||||
def test_floating_ip_allocate(self):
|
||||
def fake1(*args, **kwargs):
|
||||
pass
|
||||
|
||||
def fake2(*args, **kwargs):
|
||||
return {'id': 1, 'address': '10.10.10.10'}
|
||||
|
||||
self.stubs.Set(network.api.API, "allocate_floating_ip",
|
||||
network_api_allocate)
|
||||
fake1)
|
||||
self.stubs.Set(network.api.API, "get_floating_ip_by_address",
|
||||
fake2)
|
||||
req = webob.Request.blank('/v1.1/123/os-floating-ips')
|
||||
req.method = 'POST'
|
||||
req.headers['Content-Type'] = 'application/json'
|
||||
@@ -212,50 +221,16 @@ class FloatingIpTest(test.TestCase):
|
||||
"fixed_ip": None}
|
||||
self.assertEqual(ip, expected)
|
||||
|
||||
def test_floating_ip_release_associated(self):
|
||||
self.disassociated = False
|
||||
|
||||
def get_floating_ip(ignore, context, id):
|
||||
return {'id': 1, 'address': '10.10.10.10',
|
||||
'fixed_ip': {'id': 1}}
|
||||
|
||||
def disassociate(ignore, context, floating_address):
|
||||
self.disassociated = True
|
||||
|
||||
self.stubs.Set(network.api.API, "get_floating_ip",
|
||||
get_floating_ip)
|
||||
self.stubs.Set(network.api.API, "disassociate_floating_ip",
|
||||
disassociate)
|
||||
def test_floating_ip_release(self):
|
||||
req = webob.Request.blank('/v1.1/123/os-floating-ips/1')
|
||||
req.method = 'DELETE'
|
||||
res = req.get_response(fakes.wsgi_app())
|
||||
self.assertEqual(res.status_int, 202)
|
||||
self.assertTrue(self.disassociated)
|
||||
|
||||
def test_floating_ip_release_disassociated(self):
|
||||
self.disassociated = False
|
||||
# test floating ip add/remove -> associate/disassociate
|
||||
|
||||
def fake_get_floating_ip(ignore, context, id):
|
||||
return {'id': 1, 'address': '10.10.10.10',
|
||||
'fixed_ip': None}
|
||||
|
||||
def fake_disassociate(ignore, context, floating_address):
|
||||
self.disassociated = True
|
||||
|
||||
self.stubs.Set(network.api.API, "get_floating_ip",
|
||||
fake_get_floating_ip)
|
||||
self.stubs.Set(network.api.API, "disassociate_floating_ip",
|
||||
fake_disassociate)
|
||||
req = webob.Request.blank('/v1.1/123/os-floating-ips/1')
|
||||
req.method = 'DELETE'
|
||||
res = req.get_response(fakes.wsgi_app())
|
||||
self.assertEqual(res.status_int, 202)
|
||||
self.assertFalse(self.disassociated)
|
||||
|
||||
def test_add_floating_ip_to_instance(self):
|
||||
self.stubs.Set(network.api.API, "associate_floating_ip",
|
||||
network_api_associate)
|
||||
body = dict(addFloatingIp=dict(address='11.0.0.1'))
|
||||
def test_floating_ip_associate(self):
|
||||
body = dict(addFloatingIp=dict(address=self.address))
|
||||
req = webob.Request.blank('/v1.1/123/servers/test_inst/action')
|
||||
req.method = "POST"
|
||||
req.body = json.dumps(body)
|
||||
@@ -264,79 +239,7 @@ class FloatingIpTest(test.TestCase):
|
||||
resp = req.get_response(fakes.wsgi_app())
|
||||
self.assertEqual(resp.status_int, 202)
|
||||
|
||||
def test_associate_floating_ip_to_instance_wrong_project_id(self):
|
||||
def fake_fixed_ip_get_by_address(ctx, address, session=None):
|
||||
return {'address': address, 'network': {'multi_host': None,
|
||||
'host': 'fake'}}
|
||||
self.stubs.Set(db.api, "fixed_ip_get_by_address",
|
||||
fake_fixed_ip_get_by_address)
|
||||
db.floating_ip_update(self.context, self.address, {'project_id': 'bad',
|
||||
'fixed_ip_id': 1})
|
||||
body = dict(addFloatingIp=dict(address=self.address))
|
||||
req = webob.Request.blank('/v1.1/123/servers/test_inst/action')
|
||||
req.method = "POST"
|
||||
req.body = json.dumps(body)
|
||||
req.headers["content-type"] = "application/json"
|
||||
resp = req.get_response(fakes.wsgi_app())
|
||||
self.assertEqual(resp.status_int, 401)
|
||||
|
||||
def test_associate_floating_ip_to_instance_no_project_id(self):
|
||||
def fake_fixed_ip_get_by_address(ctx, address, session=None):
|
||||
return {'address': address, 'network': {'multi_host': None,
|
||||
'host': 'fake'}}
|
||||
self.stubs.Set(db.api, "fixed_ip_get_by_address",
|
||||
fake_fixed_ip_get_by_address)
|
||||
db.floating_ip_update(self.context, self.address, {'project_id': None,
|
||||
'fixed_ip_id': 1})
|
||||
body = dict(addFloatingIp=dict(address=self.address))
|
||||
req = webob.Request.blank('/v1.1/123/servers/test_inst/action')
|
||||
req.method = "POST"
|
||||
req.body = json.dumps(body)
|
||||
req.headers["content-type"] = "application/json"
|
||||
resp = req.get_response(fakes.wsgi_app())
|
||||
self.assertEqual(resp.status_int, 400)
|
||||
|
||||
def test_add_associated_floating_ip_to_instance(self):
|
||||
def fake_fixed_ip_get_by_address(ctx, address, session=None):
|
||||
return {'address': address, 'network': {'multi_host': None,
|
||||
'host': 'fake'}}
|
||||
|
||||
self.disassociated = False
|
||||
|
||||
def fake_network_api_disassociate(local_self, ctx, floating_address):
|
||||
self.disassociated = True
|
||||
|
||||
db.floating_ip_update(self.context, self.address, {'project_id': '123',
|
||||
'fixed_ip_id': 1})
|
||||
self.stubs.Set(network.api.API, "disassociate_floating_ip",
|
||||
fake_network_api_disassociate)
|
||||
self.stubs.Set(db.api, "fixed_ip_get_by_address",
|
||||
fake_fixed_ip_get_by_address)
|
||||
|
||||
body = dict(addFloatingIp=dict(address=self.address))
|
||||
req = webob.Request.blank('/v1.1/123/servers/test_inst/action')
|
||||
req.method = "POST"
|
||||
req.body = json.dumps(body)
|
||||
req.headers["content-type"] = "application/json"
|
||||
|
||||
resp = req.get_response(fakes.wsgi_app())
|
||||
self.assertEqual(resp.status_int, 202)
|
||||
self.assertTrue(self.disassociated)
|
||||
|
||||
def test_remove_associated_floating_ip_from_instance(self):
|
||||
self.disassociated = False
|
||||
|
||||
def fake_get_floating_ip_by_ip(ignore, context, ip):
|
||||
return {'id': 1, 'address': '10.10.10.10',
|
||||
'fixed_ip': {'id': 1}}
|
||||
|
||||
def fake_disassociate(ignore, context, floating_address):
|
||||
self.disassociated = True
|
||||
|
||||
self.stubs.Set(network.api.API, "get_floating_ip_by_ip",
|
||||
fake_get_floating_ip_by_ip)
|
||||
self.stubs.Set(network.api.API, "disassociate_floating_ip",
|
||||
fake_disassociate)
|
||||
def test_floating_ip_disassociate(self):
|
||||
body = dict(removeFloatingIp=dict(address='10.10.10.10'))
|
||||
req = webob.Request.blank('/v1.1/123/servers/test_inst/action')
|
||||
req.method = "POST"
|
||||
@@ -345,31 +248,8 @@ class FloatingIpTest(test.TestCase):
|
||||
|
||||
resp = req.get_response(fakes.wsgi_app())
|
||||
self.assertEqual(resp.status_int, 202)
|
||||
self.assertTrue(self.disassociated)
|
||||
|
||||
def test_remove_disassociated_floating_ip_from_instance(self):
|
||||
self.disassociated = False
|
||||
|
||||
def fake_get_floating_ip_by_ip(ignore, context, ip):
|
||||
return {'id': 1, 'address': '10.10.10.10',
|
||||
'fixed_ip': None}
|
||||
|
||||
def fake_disassociate(ignore, context, floating_address):
|
||||
self.disassociated = True
|
||||
|
||||
self.stubs.Set(network.api.API, "get_floating_ip_by_ip",
|
||||
fake_get_floating_ip_by_ip)
|
||||
self.stubs.Set(network.api.API, "disassociate_floating_ip",
|
||||
fake_disassociate)
|
||||
body = dict(removeFloatingIp=dict(address='10.10.10.10'))
|
||||
req = webob.Request.blank('/v1.1/123/servers/test_inst/action')
|
||||
req.method = "POST"
|
||||
req.body = json.dumps(body)
|
||||
req.headers["content-type"] = "application/json"
|
||||
|
||||
resp = req.get_response(fakes.wsgi_app())
|
||||
self.assertEqual(resp.status_int, 202)
|
||||
self.assertFalse(self.disassociated)
|
||||
# these are a few bad param tests
|
||||
|
||||
def test_bad_address_param_in_remove_floating_ip(self):
|
||||
body = dict(removeFloatingIp=dict(badparam='11.0.0.1'))
|
||||
@@ -391,16 +271,6 @@ class FloatingIpTest(test.TestCase):
|
||||
resp = req.get_response(fakes.wsgi_app())
|
||||
self.assertEqual(resp.status_int, 400)
|
||||
|
||||
def test_bad_address_param_in_add_floating_ip(self):
|
||||
body = dict(addFloatingIp=dict(badparam='11.0.0.1'))
|
||||
req = webob.Request.blank('/v1.1/123/servers/test_inst/action')
|
||||
req.method = "POST"
|
||||
req.body = json.dumps(body)
|
||||
req.headers["content-type"] = "application/json"
|
||||
|
||||
resp = req.get_response(fakes.wsgi_app())
|
||||
self.assertEqual(resp.status_int, 400)
|
||||
|
||||
def test_missing_dict_param_in_add_floating_ip(self):
|
||||
body = dict(addFloatingIp='11.0.0.1')
|
||||
req = webob.Request.blank('/v1.1/123/servers/test_inst/action')
|
||||
|
||||
@@ -20,6 +20,8 @@ from nova import context
|
||||
from nova import db
|
||||
from nova import exception
|
||||
from nova import log as logging
|
||||
from nova import quota
|
||||
from nova import rpc
|
||||
from nova import test
|
||||
from nova.network import manager as network_manager
|
||||
from nova.tests import fake_network
|
||||
@@ -394,22 +396,203 @@ class VlanNetworkTestCase(test.TestCase):
|
||||
self.mox.ReplayAll()
|
||||
self.network.validate_networks(self.context, requested_networks)
|
||||
|
||||
def test_cant_associate_associated_floating_ip(self):
|
||||
def test_floating_ip_owned_by_project(self):
|
||||
ctxt = context.RequestContext('testuser', 'testproject',
|
||||
is_admin=False)
|
||||
|
||||
def fake_floating_ip_get_by_address(context, address):
|
||||
return {'address': '10.10.10.10',
|
||||
'fixed_ip': {'address': '10.0.0.1'}}
|
||||
self.stubs.Set(self.network.db, 'floating_ip_get_by_address',
|
||||
fake_floating_ip_get_by_address)
|
||||
# raises because floating_ip project_id is None
|
||||
floating_ip = {'address': '10.0.0.1',
|
||||
'project_id': None}
|
||||
self.assertRaises(exception.NotAuthorized,
|
||||
self.network._floating_ip_owned_by_project,
|
||||
ctxt,
|
||||
floating_ip)
|
||||
|
||||
self.assertRaises(exception.FloatingIpAlreadyInUse,
|
||||
# raises because floating_ip project_id is not equal to ctxt project_id
|
||||
floating_ip = {'address': '10.0.0.1',
|
||||
'project_id': ctxt.project_id + '1'}
|
||||
self.assertRaises(exception.NotAuthorized,
|
||||
self.network._floating_ip_owned_by_project,
|
||||
ctxt,
|
||||
floating_ip)
|
||||
|
||||
# does not raise (floating ip is owned by ctxt project)
|
||||
floating_ip = {'address': '10.0.0.1',
|
||||
'project_id': ctxt.project_id}
|
||||
self.network._floating_ip_owned_by_project(ctxt, floating_ip)
|
||||
|
||||
def test_allocate_floating_ip(self):
|
||||
ctxt = context.RequestContext('testuser', 'testproject',
|
||||
is_admin=False)
|
||||
|
||||
def fake1(*args, **kwargs):
|
||||
return {'address': '10.0.0.1'}
|
||||
|
||||
def fake2(*args, **kwargs):
|
||||
return 25
|
||||
|
||||
def fake3(*args, **kwargs):
|
||||
return 0
|
||||
|
||||
self.stubs.Set(self.network.db, 'floating_ip_allocate_address', fake1)
|
||||
|
||||
# this time should raise
|
||||
self.stubs.Set(self.network.db, 'floating_ip_count_by_project', fake2)
|
||||
self.assertRaises(quota.QuotaError,
|
||||
self.network.allocate_floating_ip,
|
||||
ctxt,
|
||||
ctxt.project_id)
|
||||
|
||||
# this time should not
|
||||
self.stubs.Set(self.network.db, 'floating_ip_count_by_project', fake3)
|
||||
self.network.allocate_floating_ip(ctxt, ctxt.project_id)
|
||||
|
||||
def test_deallocate_floating_ip(self):
|
||||
ctxt = context.RequestContext('testuser', 'testproject',
|
||||
is_admin=False)
|
||||
|
||||
def fake1(*args, **kwargs):
|
||||
pass
|
||||
|
||||
def fake2(*args, **kwargs):
|
||||
return {'address': '10.0.0.1', 'fixed_ip_id': 1}
|
||||
|
||||
def fake3(*args, **kwargs):
|
||||
return {'address': '10.0.0.1', 'fixed_ip_id': None}
|
||||
|
||||
self.stubs.Set(self.network.db, 'floating_ip_deallocate', fake1)
|
||||
self.stubs.Set(self.network, '_floating_ip_owned_by_project', fake1)
|
||||
|
||||
# this time should raise because floating ip is associated to fixed_ip
|
||||
self.stubs.Set(self.network.db, 'floating_ip_get_by_address', fake2)
|
||||
self.assertRaises(exception.FloatingIpAssociated,
|
||||
self.network.deallocate_floating_ip,
|
||||
ctxt,
|
||||
mox.IgnoreArg())
|
||||
|
||||
# this time should not raise
|
||||
self.stubs.Set(self.network.db, 'floating_ip_get_by_address', fake3)
|
||||
self.network.deallocate_floating_ip(ctxt, ctxt.project_id)
|
||||
|
||||
def test_associate_floating_ip(self):
|
||||
ctxt = context.RequestContext('testuser', 'testproject',
|
||||
is_admin=False)
|
||||
|
||||
def fake1(*args, **kwargs):
|
||||
pass
|
||||
|
||||
# floating ip that's already associated
|
||||
def fake2(*args, **kwargs):
|
||||
return {'address': '10.0.0.1',
|
||||
'fixed_ip_id': 1}
|
||||
|
||||
# floating ip that isn't associated
|
||||
def fake3(*args, **kwargs):
|
||||
return {'address': '10.0.0.1',
|
||||
'fixed_ip_id': None}
|
||||
|
||||
# fixed ip with remote host
|
||||
def fake4(*args, **kwargs):
|
||||
return {'address': '10.0.0.1',
|
||||
'network': {'multi_host': False, 'host': 'jibberjabber'}}
|
||||
|
||||
# fixed ip with local host
|
||||
def fake5(*args, **kwargs):
|
||||
return {'address': '10.0.0.1',
|
||||
'network': {'multi_host': False, 'host': 'testhost'}}
|
||||
|
||||
def fake6(*args, **kwargs):
|
||||
self.local = False
|
||||
|
||||
def fake7(*args, **kwargs):
|
||||
self.local = True
|
||||
|
||||
self.stubs.Set(self.network, '_floating_ip_owned_by_project', fake1)
|
||||
|
||||
# raises because floating_ip is already associated to a fixed_ip
|
||||
self.stubs.Set(self.network.db, 'floating_ip_get_by_address', fake2)
|
||||
self.assertRaises(exception.FloatingIpAssociated,
|
||||
self.network.associate_floating_ip,
|
||||
ctxt,
|
||||
mox.IgnoreArg(),
|
||||
mox.IgnoreArg())
|
||||
|
||||
self.stubs.Set(self.network.db, 'floating_ip_get_by_address', fake3)
|
||||
|
||||
# does not raise and makes call remotely
|
||||
self.local = True
|
||||
self.stubs.Set(self.network.db, 'fixed_ip_get_by_address', fake4)
|
||||
self.stubs.Set(rpc, 'cast', fake6)
|
||||
self.network.associate_floating_ip(ctxt, mox.IgnoreArg(),
|
||||
mox.IgnoreArg())
|
||||
self.assertFalse(self.local)
|
||||
|
||||
# does not raise and makes call locally
|
||||
self.local = False
|
||||
self.stubs.Set(self.network.db, 'fixed_ip_get_by_address', fake5)
|
||||
self.stubs.Set(self.network, '_associate_floating_ip', fake7)
|
||||
self.network.associate_floating_ip(ctxt, mox.IgnoreArg(),
|
||||
mox.IgnoreArg())
|
||||
self.assertTrue(self.local)
|
||||
|
||||
def test_disassociate_floating_ip(self):
|
||||
ctxt = context.RequestContext('testuser', 'testproject',
|
||||
is_admin=False)
|
||||
|
||||
def fake1(*args, **kwargs):
|
||||
pass
|
||||
|
||||
# floating ip that isn't associated
|
||||
def fake2(*args, **kwargs):
|
||||
return {'address': '10.0.0.1',
|
||||
'fixed_ip_id': None}
|
||||
|
||||
# floating ip that is associated
|
||||
def fake3(*args, **kwargs):
|
||||
return {'address': '10.0.0.1',
|
||||
'fixed_ip_id': 1}
|
||||
|
||||
# fixed ip with remote host
|
||||
def fake4(*args, **kwargs):
|
||||
return {'address': '10.0.0.1',
|
||||
'network': {'multi_host': False, 'host': 'jibberjabber'}}
|
||||
|
||||
# fixed ip with local host
|
||||
def fake5(*args, **kwargs):
|
||||
return {'address': '10.0.0.1',
|
||||
'network': {'multi_host': False, 'host': 'testhost'}}
|
||||
|
||||
def fake6(*args, **kwargs):
|
||||
self.local = False
|
||||
|
||||
def fake7(*args, **kwargs):
|
||||
self.local = True
|
||||
|
||||
self.stubs.Set(self.network, '_floating_ip_owned_by_project', fake1)
|
||||
|
||||
# raises because floating_ip is not associated to a fixed_ip
|
||||
self.stubs.Set(self.network.db, 'floating_ip_get_by_address', fake2)
|
||||
self.assertRaises(exception.FloatingIpNotAssociated,
|
||||
self.network.disassociate_floating_ip,
|
||||
ctxt,
|
||||
mox.IgnoreArg())
|
||||
|
||||
self.stubs.Set(self.network.db, 'floating_ip_get_by_address', fake3)
|
||||
|
||||
# does not raise and makes call remotely
|
||||
self.local = True
|
||||
self.stubs.Set(self.network.db, 'fixed_ip_get', fake4)
|
||||
self.stubs.Set(rpc, 'cast', fake6)
|
||||
self.network.disassociate_floating_ip(ctxt, mox.IgnoreArg())
|
||||
self.assertFalse(self.local)
|
||||
|
||||
# does not raise and makes call locally
|
||||
self.local = False
|
||||
self.stubs.Set(self.network.db, 'fixed_ip_get', fake5)
|
||||
self.stubs.Set(self.network, '_disassociate_floating_ip', fake7)
|
||||
self.network.disassociate_floating_ip(ctxt, mox.IgnoreArg())
|
||||
self.assertTrue(self.local)
|
||||
|
||||
def test_add_fixed_ip_instance_without_vpn_requested_networks(self):
|
||||
self.mox.StubOutWithMock(db, 'network_get')
|
||||
self.mox.StubOutWithMock(db, 'fixed_ip_associate_pool')
|
||||
|
||||
Reference in New Issue
Block a user