Fix lp:855115 -- Issue with disassociating floating ips.
This commit is contained in:
		@@ -386,6 +386,10 @@ class Executor(wsgi.Application):
 | 
			
		||||
            LOG.debug(_('InvalidPortRange raised: %s'), unicode(ex),
 | 
			
		||||
                     context=context)
 | 
			
		||||
            return self._error(req, context, type(ex).__name__, unicode(ex))
 | 
			
		||||
        except exception.NotAuthorized as ex:
 | 
			
		||||
            LOG.info(_('NotAuthorized raised: %s'), unicode(ex),
 | 
			
		||||
                    context=context)
 | 
			
		||||
            return self._error(req, context, type(ex).__name__, unicode(ex))
 | 
			
		||||
        except Exception as ex:
 | 
			
		||||
            extra = {'environment': req.environ}
 | 
			
		||||
            LOG.exception(_('Unexpected error raised: %s'), unicode(ex),
 | 
			
		||||
 
 | 
			
		||||
@@ -144,6 +144,8 @@ class Floating_ips(extensions.ExtensionDescriptor):
 | 
			
		||||
                                                   address)
 | 
			
		||||
        except exception.ApiError, e:
 | 
			
		||||
            raise webob.exc.HTTPBadRequest(explanation=e.message)
 | 
			
		||||
        except exception.NotAuthorized, e:
 | 
			
		||||
            raise webob.exc.HTTPUnauthorized()
 | 
			
		||||
 | 
			
		||||
        return webob.Response(status_int=202)
 | 
			
		||||
 | 
			
		||||
@@ -162,7 +164,10 @@ class Floating_ips(extensions.ExtensionDescriptor):
 | 
			
		||||
 | 
			
		||||
        floating_ip = self.network_api.get_floating_ip_by_ip(context, address)
 | 
			
		||||
        if floating_ip.get('fixed_ip'):
 | 
			
		||||
            try:
 | 
			
		||||
                self.network_api.disassociate_floating_ip(context, address)
 | 
			
		||||
            except exception.NotAuthorized, e:
 | 
			
		||||
                raise webob.exc.HTTPUnauthorized()
 | 
			
		||||
 | 
			
		||||
        return webob.Response(status_int=202)
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -533,7 +533,6 @@ def floating_ip_fixed_ip_associate(context, floating_address,
 | 
			
		||||
                                   fixed_address, host):
 | 
			
		||||
    session = get_session()
 | 
			
		||||
    with session.begin():
 | 
			
		||||
        # TODO(devcamcar): How to ensure floating_id belongs to user?
 | 
			
		||||
        floating_ip_ref = floating_ip_get_by_address(context,
 | 
			
		||||
                                                     floating_address,
 | 
			
		||||
                                                     session=session)
 | 
			
		||||
@@ -549,7 +548,6 @@ def floating_ip_fixed_ip_associate(context, floating_address,
 | 
			
		||||
def floating_ip_deallocate(context, address):
 | 
			
		||||
    session = get_session()
 | 
			
		||||
    with session.begin():
 | 
			
		||||
        # TODO(devcamcar): How to ensure floating id belongs to user?
 | 
			
		||||
        floating_ip_ref = floating_ip_get_by_address(context,
 | 
			
		||||
                                                     address,
 | 
			
		||||
                                                     session=session)
 | 
			
		||||
@@ -563,7 +561,6 @@ def floating_ip_deallocate(context, address):
 | 
			
		||||
def floating_ip_destroy(context, address):
 | 
			
		||||
    session = get_session()
 | 
			
		||||
    with session.begin():
 | 
			
		||||
        # TODO(devcamcar): Ensure address belongs to user.
 | 
			
		||||
        floating_ip_ref = floating_ip_get_by_address(context,
 | 
			
		||||
                                                     address,
 | 
			
		||||
                                                     session=session)
 | 
			
		||||
@@ -574,8 +571,6 @@ def floating_ip_destroy(context, address):
 | 
			
		||||
def floating_ip_disassociate(context, address):
 | 
			
		||||
    session = get_session()
 | 
			
		||||
    with session.begin():
 | 
			
		||||
        # TODO(devcamcar): Ensure address belongs to user.
 | 
			
		||||
        #                  Does get_floating_ip_by_address handle this?
 | 
			
		||||
        floating_ip_ref = floating_ip_get_by_address(context,
 | 
			
		||||
                                                     address,
 | 
			
		||||
                                                     session=session)
 | 
			
		||||
@@ -644,7 +639,6 @@ def floating_ip_get_all_by_project(context, project_id):
 | 
			
		||||
 | 
			
		||||
@require_context
 | 
			
		||||
def floating_ip_get_by_address(context, address, session=None):
 | 
			
		||||
    # TODO(devcamcar): Ensure the address belongs to user.
 | 
			
		||||
    if not session:
 | 
			
		||||
        session = get_session()
 | 
			
		||||
 | 
			
		||||
@@ -653,8 +647,15 @@ def floating_ip_get_by_address(context, address, session=None):
 | 
			
		||||
                filter_by(address=address).\
 | 
			
		||||
                filter_by(deleted=can_read_deleted(context)).\
 | 
			
		||||
                first()
 | 
			
		||||
 | 
			
		||||
    if not result:
 | 
			
		||||
        raise exception.FloatingIpNotFoundForAddress(address=address)
 | 
			
		||||
 | 
			
		||||
    # If the floating IP has a project ID set, check to make sure
 | 
			
		||||
    # the non-admin user has access.
 | 
			
		||||
    if result.project_id and is_user_context(context):
 | 
			
		||||
        authorize_project_context(context, result.project_id)
 | 
			
		||||
 | 
			
		||||
    return result
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -278,7 +278,7 @@ class FloatingIpTest(test.TestCase):
 | 
			
		||||
        req.body = json.dumps(body)
 | 
			
		||||
        req.headers["content-type"] = "application/json"
 | 
			
		||||
        resp = req.get_response(fakes.wsgi_app())
 | 
			
		||||
        self.assertEqual(resp.status_int, 400)
 | 
			
		||||
        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):
 | 
			
		||||
 
 | 
			
		||||
@@ -447,6 +447,52 @@ class VlanNetworkTestCase(test.TestCase):
 | 
			
		||||
        self.network.add_fixed_ip_to_instance(self.context, 1, HOST,
 | 
			
		||||
                                              networks[0]['id'])
 | 
			
		||||
 | 
			
		||||
    def test_ip_association_and_allocation_of_other_project(self):
 | 
			
		||||
        """Makes sure that we cannot deallocaate or disassociate
 | 
			
		||||
        a public ip of other project"""
 | 
			
		||||
 | 
			
		||||
        context1 = context.RequestContext('user', 'project1')
 | 
			
		||||
        context2 = context.RequestContext('user', 'project2')
 | 
			
		||||
 | 
			
		||||
        address = '1.2.3.4'
 | 
			
		||||
        float_addr = db.floating_ip_create(context1.elevated(),
 | 
			
		||||
                {'address': address,
 | 
			
		||||
                 'project_id': context1.project_id})
 | 
			
		||||
 | 
			
		||||
        instance = db.instance_create(context1,
 | 
			
		||||
                {'project_id': 'project1'})
 | 
			
		||||
 | 
			
		||||
        fix_addr = db.fixed_ip_associate_pool(context1.elevated(),
 | 
			
		||||
                1, instance['id'])
 | 
			
		||||
 | 
			
		||||
        # Associate the IP with non-admin user context
 | 
			
		||||
        self.assertRaises(exception.NotAuthorized,
 | 
			
		||||
                          self.network.associate_floating_ip,
 | 
			
		||||
                          context2,
 | 
			
		||||
                          float_addr,
 | 
			
		||||
                          fix_addr)
 | 
			
		||||
 | 
			
		||||
        # Deallocate address from other project
 | 
			
		||||
        self.assertRaises(exception.NotAuthorized,
 | 
			
		||||
                          self.network.deallocate_floating_ip,
 | 
			
		||||
                          context2,
 | 
			
		||||
                          float_addr)
 | 
			
		||||
 | 
			
		||||
        # Now Associates the address to the actual project
 | 
			
		||||
        self.network.associate_floating_ip(context1, float_addr, fix_addr)
 | 
			
		||||
 | 
			
		||||
        # Now try dis-associating from other project
 | 
			
		||||
        self.assertRaises(exception.NotAuthorized,
 | 
			
		||||
                          self.network.disassociate_floating_ip,
 | 
			
		||||
                          context2,
 | 
			
		||||
                          float_addr)
 | 
			
		||||
 | 
			
		||||
        # Clean up the ip addresses
 | 
			
		||||
        self.network.deallocate_floating_ip(context1, float_addr)
 | 
			
		||||
        self.network.deallocate_fixed_ip(context1, fix_addr)
 | 
			
		||||
        db.floating_ip_destroy(context1.elevated(), float_addr)
 | 
			
		||||
        db.fixed_ip_disassociate(context1.elevated(), fix_addr)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class CommonNetworkTestCase(test.TestCase):
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user