Beispiel #1
0
    def allocate_floating_ip(self, context, project_id, auto_assigned=False,
                             pool=None):
        """Gets a floating ip from the pool."""
        # NOTE(tr3buchet): all network hosts in zone now use the same pool
        pool = pool or CONF.default_floating_pool
        use_quota = not auto_assigned

        # Check the quota; can't put this in the API because we get
        # called into from other places
        try:
            if use_quota:
                reservations = QUOTAS.reserve(context, floating_ips=1)
        except exception.OverQuota:
            LOG.warn(_("Quota exceeded for %s, tried to allocate "
                       "floating IP"), context.project_id)
            raise exception.FloatingIpLimitExceeded()

        try:
            floating_ip = self.db.floating_ip_allocate_address(
                context, project_id, pool, auto_assigned=auto_assigned)
            payload = dict(project_id=project_id, floating_ip=floating_ip)
            notifier.notify(context,
                            notifier.publisher_id("network"),
                            'network.floating_ip.allocate',
                            notifier.INFO, payload)

            # Commit the reservations
            if use_quota:
                QUOTAS.commit(context, reservations)
        except Exception:
            with excutils.save_and_reraise_exception():
                if use_quota:
                    QUOTAS.rollback(context, reservations)

        return floating_ip
Beispiel #2
0
    def allocate_floating_ip(self,
                             context,
                             project_id,
                             auto_assigned=False,
                             pool=None):
        """Gets a floating IP from the pool."""
        # NOTE(tr3buchet): all network hosts in zone now use the same pool
        pool = pool or CONF.default_floating_pool
        use_quota = not auto_assigned

        if not self._floating_ip_pool_exists(context, pool):
            raise exception.FloatingIpPoolNotFound()

        # Check the quota; can't put this in the API because we get
        # called into from other places
        try:
            if use_quota:
                objects.Quotas.check_deltas(context, {'floating_ips': 1},
                                            project_id)
        except exception.OverQuota:
            LOG.warning(
                _LW("Quota exceeded for %s, tried to allocate "
                    "floating IP"), context.project_id)
            raise exception.FloatingIpLimitExceeded()

        floating_ip = objects.FloatingIP.allocate_address(
            context, project_id, pool, auto_assigned=auto_assigned)

        # NOTE(melwitt): We recheck the quota after creating the object to
        # prevent users from allocating more resources than their allowed quota
        # in the event of a race. This is configurable because it can be
        # expensive if strict quota limits are not required in a deployment.
        if CONF.quota.recheck_quota and use_quota:
            try:
                objects.Quotas.check_deltas(context, {'floating_ips': 0},
                                            project_id)
            except exception.OverQuota:
                objects.FloatingIP.deallocate(context, floating_ip.address)
                LOG.warning(
                    _LW("Quota exceeded for %s, tried to allocate "
                        "floating IP"), context.project_id)
                raise exception.FloatingIpLimitExceeded()

        payload = dict(project_id=project_id, floating_ip=floating_ip)
        self.notifier.info(context, 'network.floating_ip.allocate', payload)

        return floating_ip
Beispiel #3
0
class FloatingIpTestV21(test.TestCase):
    floating_ip = "10.10.10.10"
    floating_ip_2 = "10.10.10.11"
    floating_ips = fips_v21
    validation_error = exception.ValidationError

    def _create_floating_ips(self, floating_ips=None):
        """Create a floating IP object."""
        if floating_ips is None:
            floating_ips = [self.floating_ip]
        elif not isinstance(floating_ips, (list, tuple)):
            floating_ips = [floating_ips]

        dict_ = {'pool': 'nova', 'host': 'fake_host'}
        return db.floating_ip_bulk_create(
            self.context,
            [dict(address=ip, **dict_) for ip in floating_ips],
        )

    def _delete_floating_ip(self):
        db.floating_ip_destroy(self.context, self.floating_ip)

    def setUp(self):
        super(FloatingIpTestV21, self).setUp()
        self.flags(use_neutron=False)
        self.stubs.Set(compute.api.API, "get", compute_api_get)
        self.stubs.Set(network.api.API, "get_floating_ip",
                       network_api_get_floating_ip)
        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",
                       network_api_disassociate)
        self.stubs.Set(network.api.API, "get_instance_id_by_floating_address",
                       get_instance_by_floating_ip_addr)
        self.stubs.Set(compute_utils, "get_nw_info_for_instance",
                       stub_nw_info(self))

        fake_network.stub_out_nw_api_get_instance_nw_info(self)
        self.stub_out('nova.db.instance_get', fake_instance_get)

        self.context = context.get_admin_context()
        self._create_floating_ips()

        self.ext_mgr = extensions.ExtensionManager()
        self.ext_mgr.extensions = {}
        self.controller = self.floating_ips.FloatingIPController()
        self.manager = self.floating_ips.\
                            FloatingIPActionController(self.ext_mgr)
        self.fake_req = fakes.HTTPRequest.blank('')

    def tearDown(self):
        self._delete_floating_ip()
        super(FloatingIpTestV21, self).tearDown()

    def test_floatingip_delete(self):
        fip_val = {'address': '1.1.1.1', 'fixed_ip_id': '192.168.1.2'}
        with test.nested(
                mock.patch.object(self.controller.network_api,
                                  'disassociate_floating_ip'),
                mock.patch.object(self.controller.network_api,
                                  'release_floating_ip'),
                mock.patch.object(self.controller.network_api,
                                  'get_instance_id_by_floating_address',
                                  return_value=None),
                mock.patch.object(self.controller.network_api,
                                  'get_floating_ip',
                                  return_value=fip_val)) as (disoc_fip,
                                                             rel_fip, _, _):
            self.controller.delete(self.fake_req, 1)
            self.assertTrue(disoc_fip.called)
            self.assertTrue(rel_fip.called)

    def _test_floatingip_delete_not_found(self,
                                          ex,
                                          expect_ex=webob.exc.HTTPNotFound):
        with mock.patch.object(self.controller.network_api,
                               'get_floating_ip',
                               side_effect=ex):
            self.assertRaises(expect_ex, self.controller.delete, self.fake_req,
                              1)

    def test_floatingip_delete_not_found_ip(self):
        ex = exception.FloatingIpNotFound(id=1)
        self._test_floatingip_delete_not_found(ex)

    def test_floatingip_delete_not_found(self):
        ex = exception.NotFound
        self._test_floatingip_delete_not_found(ex)

    def test_floatingip_delete_invalid_id(self):
        ex = exception.InvalidID(id=1)
        self._test_floatingip_delete_not_found(ex, webob.exc.HTTPBadRequest)

    def test_translate_floating_ip_view(self):
        floating_ip_address = self.floating_ip
        floating_ip = db.floating_ip_get_by_address(self.context,
                                                    floating_ip_address)
        # NOTE(vish): network_get uses the id not the address
        floating_ip = db.floating_ip_get(self.context, floating_ip['id'])
        floating_obj = objects.FloatingIP()
        objects.FloatingIP._from_db_object(self.context, floating_obj,
                                           floating_ip)

        view = self.floating_ips._translate_floating_ip_view(floating_obj)

        self.assertIn('floating_ip', view)
        self.assertTrue(view['floating_ip']['id'])
        self.assertEqual(view['floating_ip']['ip'], floating_obj.address)
        self.assertIsNone(view['floating_ip']['fixed_ip'])
        self.assertIsNone(view['floating_ip']['instance_id'])

    def test_translate_floating_ip_view_neutronesque(self):
        uuid = 'ca469a10-fa76-11e5-86aa-5e5517507c66'
        fixed_id = 'ae900cf4-fb73-11e5-86aa-5e5517507c66'
        floating_ip = objects.floating_ip.NeutronFloatingIP(
            id=uuid,
            address='1.2.3.4',
            pool='pool',
            context='ctxt',
            fixed_ip_id=fixed_id)
        view = self.floating_ips._translate_floating_ip_view(floating_ip)
        self.assertEqual(uuid, view['floating_ip']['id'])

    def test_translate_floating_ip_view_dict(self):
        floating_ip = {
            'id': 0,
            'address': '10.0.0.10',
            'pool': 'nova',
            'fixed_ip': None
        }
        view = self.floating_ips._translate_floating_ip_view(floating_ip)
        self.assertIn('floating_ip', view)

    def test_translate_floating_ip_view_obj(self):
        fip = objects.FixedIP(address='192.168.1.2', instance_uuid=FAKE_UUID)
        floater = self._build_floating_ip('10.0.0.2', fip)

        result = self.floating_ips._translate_floating_ip_view(floater)

        expected = self._build_expected(floater, fip.address,
                                        fip.instance_uuid)
        self._test_result(expected, result)

    def test_translate_floating_ip_bad_address(self):
        fip = objects.FixedIP(instance_uuid=FAKE_UUID)
        floater = self._build_floating_ip('10.0.0.2', fip)

        result = self.floating_ips._translate_floating_ip_view(floater)

        expected = self._build_expected(floater, None, fip.instance_uuid)
        self._test_result(expected, result)

    def test_translate_floating_ip_bad_instance_id(self):
        fip = objects.FixedIP(address='192.168.1.2')
        floater = self._build_floating_ip('10.0.0.2', fip)

        result = self.floating_ips._translate_floating_ip_view(floater)

        expected = self._build_expected(floater, fip.address, None)
        self._test_result(expected, result)

    def test_translate_floating_ip_bad_instance_and_address(self):
        fip = objects.FixedIP()
        floater = self._build_floating_ip('10.0.0.2', fip)

        result = self.floating_ips._translate_floating_ip_view(floater)

        expected = self._build_expected(floater, None, None)
        self._test_result(expected, result)

    def test_translate_floating_ip_null_fixed(self):
        floater = self._build_floating_ip('10.0.0.2', None)

        result = self.floating_ips._translate_floating_ip_view(floater)

        expected = self._build_expected(floater, None, None)
        self._test_result(expected, result)

    def test_translate_floating_ip_unset_fixed(self):
        floater = objects.FloatingIP(id=1, address='10.0.0.2', pool='foo')

        result = self.floating_ips._translate_floating_ip_view(floater)

        expected = self._build_expected(floater, None, None)
        self._test_result(expected, result)

    def test_translate_floating_ips_view(self):
        mock_trans = mock.Mock()
        mock_trans.return_value = {'floating_ip': 'foo'}
        self.floating_ips._translate_floating_ip_view = mock_trans
        fip1 = objects.FixedIP(address='192.168.1.2', instance_uuid=FAKE_UUID)
        fip2 = objects.FixedIP(address='192.168.1.3', instance_uuid=FAKE_UUID)

        floaters = [
            self._build_floating_ip('10.0.0.2', fip1),
            self._build_floating_ip('10.0.0.3', fip2)
        ]

        result = self.floating_ips._translate_floating_ips_view(floaters)

        called_floaters = [call[0][0] for call in mock_trans.call_args_list]
        self.assertTrue(
            any(
                obj_base.obj_equal_prims(floaters[0], f)
                for f in called_floaters),
            "_translate_floating_ip_view was not called with all "
            "floating ips")
        self.assertTrue(
            any(
                obj_base.obj_equal_prims(floaters[1], f)
                for f in called_floaters),
            "_translate_floating_ip_view was not called with all "
            "floating ips")
        expected_result = {'floating_ips': ['foo', 'foo']}
        self.assertEqual(expected_result, result)

    def test_floating_ips_list(self):
        res_dict = self.controller.index(self.fake_req)

        response = {
            'floating_ips': [{
                'instance_id': FAKE_UUID,
                'ip': '10.10.10.10',
                'pool': 'nova',
                'fixed_ip': '10.0.0.1',
                'id': 1
            }, {
                'instance_id': None,
                'ip': '10.10.10.11',
                'pool': 'nova',
                'fixed_ip': None,
                'id': 2
            }]
        }
        self.assertEqual(res_dict, response)

    def test_floating_ip_release_nonexisting(self):
        def fake_get_floating_ip(*args, **kwargs):
            raise exception.FloatingIpNotFound(id=id)

        self.stubs.Set(network.api.API, "get_floating_ip",
                       fake_get_floating_ip)

        ex = self.assertRaises(webob.exc.HTTPNotFound, self.controller.delete,
                               self.fake_req, '9876')
        self.assertIn("Floating IP not found for ID 9876", ex.explanation)

    def test_floating_ip_release_race_cond(self):
        def fake_get_floating_ip(*args, **kwargs):
            return {'fixed_ip_id': 1, 'address': self.floating_ip}

        def fake_get_instance_by_floating_ip_addr(*args, **kwargs):
            return 'test-inst'

        def fake_disassociate_floating_ip(*args, **kwargs):
            raise exception.FloatingIpNotAssociated(args[3])

        self.stubs.Set(network.api.API, "get_floating_ip",
                       fake_get_floating_ip)
        self.stubs.Set(self.floating_ips, "get_instance_by_floating_ip_addr",
                       fake_get_instance_by_floating_ip_addr)
        self.stubs.Set(self.floating_ips, "disassociate_floating_ip",
                       fake_disassociate_floating_ip)

        delete = self.controller.delete
        res = delete(self.fake_req, '9876')
        # NOTE: on v2.1, http status code is set as wsgi_code of API
        # method instead of status_int in a response object.
        if isinstance(self.controller, fips_v21.FloatingIPController):
            status_int = delete.wsgi_code
        else:
            status_int = res.status_int
        self.assertEqual(status_int, 202)

    def test_floating_ip_show(self):
        res_dict = self.controller.show(self.fake_req, 1)

        self.assertEqual(res_dict['floating_ip']['id'], 1)
        self.assertEqual(res_dict['floating_ip']['ip'], '10.10.10.10')
        self.assertIsNone(res_dict['floating_ip']['instance_id'])

    def test_floating_ip_show_not_found(self):
        def fake_get_floating_ip(*args, **kwargs):
            raise exception.FloatingIpNotFound(id='fake')

        self.stubs.Set(network.api.API, "get_floating_ip",
                       fake_get_floating_ip)

        ex = self.assertRaises(webob.exc.HTTPNotFound, self.controller.show,
                               self.fake_req, '9876')
        self.assertIn("Floating IP not found for ID 9876", ex.explanation)

    def test_show_associated_floating_ip(self):
        def get_floating_ip(self, context, id):
            return {
                'id': 1,
                'address': '10.10.10.10',
                'pool': 'nova',
                'fixed_ip': {
                    'address': '10.0.0.1',
                    'instance_uuid': FAKE_UUID,
                    'instance': {
                        'uuid': FAKE_UUID
                    }
                }
            }

        self.stubs.Set(network.api.API, "get_floating_ip", get_floating_ip)

        res_dict = self.controller.show(self.fake_req, 1)

        self.assertEqual(res_dict['floating_ip']['id'], 1)
        self.assertEqual(res_dict['floating_ip']['ip'], '10.10.10.10')
        self.assertEqual(res_dict['floating_ip']['fixed_ip'], '10.0.0.1')
        self.assertEqual(res_dict['floating_ip']['instance_id'], FAKE_UUID)

    def test_recreation_of_floating_ip(self):
        self._delete_floating_ip()
        self._create_floating_ips()

    def test_floating_ip_in_bulk_creation(self):
        self._delete_floating_ip()

        self._create_floating_ips([self.floating_ip, self.floating_ip_2])
        all_ips = db.floating_ip_get_all(self.context)
        ip_list = [ip['address'] for ip in all_ips]
        self.assertIn(self.floating_ip, ip_list)
        self.assertIn(self.floating_ip_2, ip_list)

    def test_fail_floating_ip_in_bulk_creation(self):
        self.assertRaises(exception.FloatingIpExists,
                          self._create_floating_ips,
                          [self.floating_ip, self.floating_ip_2])
        all_ips = db.floating_ip_get_all(self.context)
        ip_list = [ip['address'] for ip in all_ips]
        self.assertIn(self.floating_ip, ip_list)
        self.assertNotIn(self.floating_ip_2, ip_list)

    def test_floating_ip_allocate_no_free_ips(self):
        def fake_allocate(*args, **kwargs):
            raise exception.NoMoreFloatingIps()

        self.stubs.Set(network.api.API, "allocate_floating_ip", fake_allocate)

        ex = self.assertRaises(webob.exc.HTTPNotFound, self.controller.create,
                               self.fake_req)

        self.assertIn('No more floating IPs', ex.explanation)

    def test_floating_ip_allocate_no_free_ips_pool(self):
        def fake_allocate(*args, **kwargs):
            raise exception.NoMoreFloatingIps()

        self.stubs.Set(network.api.API, "allocate_floating_ip", fake_allocate)

        ex = self.assertRaises(webob.exc.HTTPNotFound, self.controller.create,
                               self.fake_req, {'pool': 'non_existent_pool'})

        self.assertIn('No more floating IPs in pool non_existent_pool',
                      ex.explanation)

    @mock.patch.object(
        network.api.API,
        'allocate_floating_ip',
        side_effect=exception.FloatingIpBadRequest(
            'Bad floatingip request: Network '
            'c8f0e88f-ae41-47cb-be6c-d8256ba80576 does not contain any '
            'IPv4 subnet'))
    def test_floating_ip_allocate_no_ipv4_subnet(self, allocate_mock):
        ex = self.assertRaises(webob.exc.HTTPBadRequest,
                               self.controller.create, self.fake_req,
                               {'pool': 'non_existent_pool'})
        self.assertIn("does not contain any IPv4 subnet", six.text_type(ex))

    @mock.patch('nova.network.api.API.allocate_floating_ip',
                side_effect=exception.FloatingIpLimitExceeded())
    def test_floating_ip_allocate_over_quota(self, allocate_mock):
        ex = self.assertRaises(webob.exc.HTTPForbidden, self.controller.create,
                               self.fake_req)

        self.assertIn('IP allocation over quota', ex.explanation)

    @mock.patch('nova.network.api.API.allocate_floating_ip',
                side_effect=exception.FloatingIpLimitExceeded())
    def test_floating_ip_allocate_quota_exceed_in_pool(self, allocate_mock):
        ex = self.assertRaises(webob.exc.HTTPForbidden, self.controller.create,
                               self.fake_req, {'pool': 'non_existent_pool'})

        self.assertIn('IP allocation over quota in pool non_existent_pool.',
                      ex.explanation)

    @mock.patch('nova.network.api.API.allocate_floating_ip',
                side_effect=exception.FloatingIpPoolNotFound())
    def test_floating_ip_create_with_unknown_pool(self, allocate_mock):
        ex = self.assertRaises(webob.exc.HTTPNotFound, self.controller.create,
                               self.fake_req, {'pool': 'non_existent_pool'})

        self.assertIn('Floating IP pool not found.', ex.explanation)

    def test_floating_ip_allocate(self):
        def fake1(*args, **kwargs):
            pass

        def fake2(*args, **kwargs):
            return {'id': 1, 'address': '10.10.10.10', 'pool': 'nova'}

        self.stubs.Set(network.api.API, "allocate_floating_ip", fake1)
        self.stubs.Set(network.api.API, "get_floating_ip_by_address", fake2)

        res_dict = self.controller.create(self.fake_req)

        ip = res_dict['floating_ip']

        expected = {
            "id": 1,
            "instance_id": None,
            "ip": "10.10.10.10",
            "fixed_ip": None,
            "pool": 'nova'
        }
        self.assertEqual(ip, expected)

    def test_floating_ip_release(self):
        self.controller.delete(self.fake_req, 1)

    def _test_floating_ip_associate(self, fixed_address):
        def fake_associate_floating_ip(*args, **kwargs):
            self.assertEqual(fixed_address, kwargs['fixed_address'])

        self.stubs.Set(network.api.API, "associate_floating_ip",
                       fake_associate_floating_ip)
        body = dict(addFloatingIp=dict(address=self.floating_ip))

        rsp = self.manager._add_floating_ip(self.fake_req,
                                            TEST_INST,
                                            body=body)
        self.assertEqual(202, rsp.status_int)

    def test_floating_ip_associate(self):
        self._test_floating_ip_associate(fixed_address='192.168.1.100')

    @mock.patch.object(network.model.NetworkInfo, 'fixed_ips')
    def test_associate_floating_ip_v4v6_fixed_ip(self, fixed_ips_mock):
        fixed_address = '192.168.1.100'
        fixed_ips_mock.return_value = [{
            'address': 'fc00:2001:db8::100'
        }, {
            'address': ''
        }, {
            'address': fixed_address
        }]
        self._test_floating_ip_associate(fixed_address=fixed_address)

    @mock.patch.object(network.model.NetworkInfo,
                       'fixed_ips',
                       return_value=[{
                           'address': 'fc00:2001:db8::100'
                       }])
    def test_associate_floating_ip_v6_fixed_ip(self, fixed_ips_mock):
        body = dict(addFloatingIp=dict(address=self.floating_ip))
        self.assertRaises(webob.exc.HTTPBadRequest,
                          self.manager._add_floating_ip,
                          self.fake_req,
                          TEST_INST,
                          body=body)

    def test_floating_ip_associate_invalid_instance(self):
        def fake_get(self, context, id, expected_attrs=None):
            raise exception.InstanceNotFound(instance_id=id)

        self.stubs.Set(compute.api.API, "get", fake_get)

        body = dict(addFloatingIp=dict(address=self.floating_ip))

        self.assertRaises(webob.exc.HTTPNotFound,
                          self.manager._add_floating_ip,
                          self.fake_req,
                          'test_inst',
                          body=body)

    def test_associate_not_allocated_floating_ip_to_instance(self):
        def fake_associate_floating_ip(self,
                                       context,
                                       instance,
                                       floating_address,
                                       fixed_address,
                                       affect_auto_assigned=False):
            raise exception.FloatingIpNotFoundForAddress(
                address=floating_address)

        self.stubs.Set(network.api.API, "associate_floating_ip",
                       fake_associate_floating_ip)
        floating_ip = '10.10.10.11'
        body = dict(addFloatingIp=dict(address=floating_ip))
        ex = self.assertRaises(webob.exc.HTTPNotFound,
                               self.manager._add_floating_ip,
                               self.fake_req,
                               TEST_INST,
                               body=body)

        self.assertIn("floating IP not found", ex.explanation)

    @mock.patch.object(network.api.API,
                       'associate_floating_ip',
                       side_effect=exception.Forbidden)
    def test_associate_floating_ip_forbidden(self, associate_mock):
        body = dict(addFloatingIp=dict(address='10.10.10.11'))
        self.assertRaises(webob.exc.HTTPForbidden,
                          self.manager._add_floating_ip,
                          self.fake_req,
                          TEST_INST,
                          body=body)

    def test_associate_floating_ip_bad_address_key(self):
        body = dict(addFloatingIp=dict(bad_address='10.10.10.11'))
        req = fakes.HTTPRequest.blank('/v2/fake/servers/test_inst/action')
        self.assertRaises(self.validation_error,
                          self.manager._add_floating_ip,
                          req,
                          'test_inst',
                          body=body)

    def test_associate_floating_ip_bad_addfloatingip_key(self):
        body = dict(bad_addFloatingIp=dict(address='10.10.10.11'))
        req = fakes.HTTPRequest.blank('/v2/fake/servers/test_inst/action')
        self.assertRaises(self.validation_error,
                          self.manager._add_floating_ip,
                          req,
                          'test_inst',
                          body=body)

    def test_floating_ip_disassociate(self):
        def get_instance_by_floating_ip_addr(self, context, address):
            if address == '10.10.10.10':
                return TEST_INST

        self.stubs.Set(network.api.API, "get_instance_id_by_floating_address",
                       get_instance_by_floating_ip_addr)

        body = dict(removeFloatingIp=dict(address='10.10.10.10'))

        rsp = self.manager._remove_floating_ip(self.fake_req,
                                               TEST_INST,
                                               body=body)
        self.assertEqual(202, rsp.status_int)

    def test_floating_ip_disassociate_missing(self):
        body = dict(removeFloatingIp=dict(address='10.10.10.10'))

        self.assertRaises(webob.exc.HTTPConflict,
                          self.manager._remove_floating_ip,
                          self.fake_req,
                          'test_inst',
                          body=body)

    def test_floating_ip_associate_non_existent_ip(self):
        def fake_network_api_associate(self,
                                       context,
                                       instance,
                                       floating_address=None,
                                       fixed_address=None):
            floating_ips = ["10.10.10.10", "10.10.10.11"]
            if floating_address not in floating_ips:
                raise exception.FloatingIpNotFoundForAddress(
                    address=floating_address)

        self.stubs.Set(network.api.API, "associate_floating_ip",
                       fake_network_api_associate)

        body = dict(addFloatingIp=dict(address='1.1.1.1'))
        self.assertRaises(webob.exc.HTTPNotFound,
                          self.manager._add_floating_ip,
                          self.fake_req,
                          TEST_INST,
                          body=body)

    def test_floating_ip_disassociate_non_existent_ip(self):
        def network_api_get_floating_ip_by_address(self, context,
                                                   floating_address):
            floating_ips = ["10.10.10.10", "10.10.10.11"]
            if floating_address not in floating_ips:
                raise exception.FloatingIpNotFoundForAddress(
                    address=floating_address)

        self.stubs.Set(network.api.API, "get_floating_ip_by_address",
                       network_api_get_floating_ip_by_address)

        body = dict(removeFloatingIp=dict(address='1.1.1.1'))
        self.assertRaises(webob.exc.HTTPNotFound,
                          self.manager._remove_floating_ip,
                          self.fake_req,
                          TEST_INST,
                          body=body)

    def test_floating_ip_disassociate_wrong_instance_uuid(self):
        def get_instance_by_floating_ip_addr(self, context, address):
            if address == '10.10.10.10':
                return TEST_INST

        self.stubs.Set(network.api.API, "get_instance_id_by_floating_address",
                       get_instance_by_floating_ip_addr)

        wrong_uuid = 'aaaaaaaa-ffff-ffff-ffff-aaaaaaaaaaaa'
        body = dict(removeFloatingIp=dict(address='10.10.10.10'))

        self.assertRaises(webob.exc.HTTPConflict,
                          self.manager._remove_floating_ip,
                          self.fake_req,
                          wrong_uuid,
                          body=body)

    def test_floating_ip_disassociate_wrong_instance_id(self):
        def get_instance_by_floating_ip_addr(self, context, address):
            if address == '10.10.10.10':
                return WRONG_INST

        self.stubs.Set(network.api.API, "get_instance_id_by_floating_address",
                       get_instance_by_floating_ip_addr)

        body = dict(removeFloatingIp=dict(address='10.10.10.10'))

        self.assertRaises(webob.exc.HTTPConflict,
                          self.manager._remove_floating_ip,
                          self.fake_req,
                          TEST_INST,
                          body=body)

    def test_floating_ip_disassociate_auto_assigned(self):
        def fake_get_floating_ip_addr_auto_assigned(self, context, address):
            return {
                'id': 1,
                'address': '10.10.10.10',
                'pool': 'nova',
                'fixed_ip_id': 10,
                'auto_assigned': 1
            }

        def get_instance_by_floating_ip_addr(self, context, address):
            if address == '10.10.10.10':
                return TEST_INST

        def network_api_disassociate(self, context, instance,
                                     floating_address):
            raise exception.CannotDisassociateAutoAssignedFloatingIP()

        self.stubs.Set(network.api.API, "get_floating_ip_by_address",
                       fake_get_floating_ip_addr_auto_assigned)
        self.stubs.Set(network.api.API, "get_instance_id_by_floating_address",
                       get_instance_by_floating_ip_addr)
        self.stubs.Set(network.api.API, "disassociate_floating_ip",
                       network_api_disassociate)
        body = dict(removeFloatingIp=dict(address='10.10.10.10'))
        self.assertRaises(webob.exc.HTTPForbidden,
                          self.manager._remove_floating_ip,
                          self.fake_req,
                          TEST_INST,
                          body=body)

    def test_floating_ip_disassociate_map_authorization_exc(self):
        def fake_get_floating_ip_addr_auto_assigned(self, context, address):
            return {
                'id': 1,
                'address': '10.10.10.10',
                'pool': 'nova',
                'fixed_ip_id': 10,
                'auto_assigned': 1
            }

        def get_instance_by_floating_ip_addr(self, context, address):
            if address == '10.10.10.10':
                return TEST_INST

        def network_api_disassociate(self, context, instance, address):
            raise exception.Forbidden()

        self.stubs.Set(network.api.API, "get_floating_ip_by_address",
                       fake_get_floating_ip_addr_auto_assigned)
        self.stubs.Set(network.api.API, "get_instance_id_by_floating_address",
                       get_instance_by_floating_ip_addr)
        self.stubs.Set(network.api.API, "disassociate_floating_ip",
                       network_api_disassociate)
        body = dict(removeFloatingIp=dict(address='10.10.10.10'))
        self.assertRaises(webob.exc.HTTPForbidden,
                          self.manager._remove_floating_ip,
                          self.fake_req,
                          TEST_INST,
                          body=body)


# 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'))

        self.assertRaises(self.validation_error,
                          self.manager._remove_floating_ip,
                          self.fake_req,
                          TEST_INST,
                          body=body)

    def test_missing_dict_param_in_remove_floating_ip(self):
        body = dict(removeFloatingIp='11.0.0.1')

        self.assertRaises(self.validation_error,
                          self.manager._remove_floating_ip,
                          self.fake_req,
                          TEST_INST,
                          body=body)

    def test_missing_dict_param_in_add_floating_ip(self):
        body = dict(addFloatingIp='11.0.0.1')

        self.assertRaises(self.validation_error,
                          self.manager._add_floating_ip,
                          self.fake_req,
                          TEST_INST,
                          body=body)

    def _build_floating_ip(self, address, fixed_ip):
        floating = objects.FloatingIP(id=1,
                                      address=address,
                                      pool='foo',
                                      fixed_ip=fixed_ip)
        return floating

    def _build_expected(self, floating_ip, fixed_ip, instance_id):
        return {
            'floating_ip': {
                'id': floating_ip.id,
                'ip': floating_ip.address,
                'pool': floating_ip.pool,
                'fixed_ip': fixed_ip,
                'instance_id': instance_id
            }
        }

    def _test_result(self, expected, actual):
        expected_fl = expected['floating_ip']
        actual_fl = actual['floating_ip']

        self.assertEqual(expected_fl, actual_fl)
Beispiel #4
0
class FloatingIpTest(test.TestCase):
    floating_ip = "10.10.10.10"
    floating_ip_2 = "10.10.10.11"

    def _create_floating_ips(self, floating_ips=None):
        """Create a floating ip object."""
        if floating_ips is None:
            floating_ips = [self.floating_ip]
        elif not isinstance(floating_ips, (list, tuple)):
            floating_ips = [floating_ips]

        def make_ip_dict(ip):
            """Shortcut for creating floating ip dict."""
            return

        dict_ = {'pool': 'nova', 'host': 'fake_host'}
        return db.floating_ip_bulk_create(
            self.context,
            [dict(address=ip, **dict_) for ip in floating_ips],
        )

    def _delete_floating_ip(self):
        db.floating_ip_destroy(self.context, self.floating_ip)

    def _get_fake_fip_request(self, act=''):
        return fakes.HTTPRequest.blank('/v2/fake/os-floating-ips/%s' % act)

    def _get_fake_server_request(self):
        return fakes.HTTPRequest.blank('/v2/fake/servers/test_inst/action')

    def _get_fake_response(self, req, init_only):
        return req.get_response(fakes.wsgi_app(init_only=(init_only, )))

    def setUp(self):
        super(FloatingIpTest, self).setUp()
        self.stubs.Set(compute.api.API, "get", compute_api_get)
        self.stubs.Set(network.api.API, "get_floating_ip",
                       network_api_get_floating_ip)
        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",
                       network_api_disassociate)
        self.stubs.Set(network.api.API, "get_instance_id_by_floating_address",
                       get_instance_by_floating_ip_addr)
        self.stubs.Set(compute_utils, "get_nw_info_for_instance",
                       stub_nw_info(self.stubs))

        fake_network.stub_out_nw_api_get_instance_nw_info(self.stubs)
        self.stubs.Set(db, 'instance_get', fake_instance_get)

        self.context = context.get_admin_context()
        self._create_floating_ips()

        self.ext_mgr = extensions.ExtensionManager()
        self.ext_mgr.extensions = {}
        self.controller = floating_ips.FloatingIPController()
        self.manager = floating_ips.FloatingIPActionController(self.ext_mgr)

        self.flags(osapi_compute_extension=[
            'nova.api.openstack.compute.contrib.select_extensions'
        ],
                   osapi_compute_ext_list=['Floating_ips'])

    def tearDown(self):
        self._delete_floating_ip()
        super(FloatingIpTest, self).tearDown()

    def test_floatingip_delete(self):
        req = self._get_fake_fip_request('1')
        fip_val = {'address': '1.1.1.1', 'fixed_ip_id': '192.168.1.2'}
        with contextlib.nested(
                mock.patch.object(self.controller.network_api,
                                  'disassociate_floating_ip'),
                mock.patch.object(self.controller.network_api,
                                  'release_floating_ip'),
                mock.patch.object(self.controller.network_api,
                                  'get_instance_id_by_floating_address',
                                  return_value=None),
                mock.patch.object(self.controller.network_api,
                                  'get_floating_ip',
                                  return_value=fip_val)) as (disoc_fip,
                                                             rel_fip, _, _):
            self.controller.delete(req, 1)
            self.assertTrue(disoc_fip.called)
            self.assertTrue(rel_fip.called)

    def test_translate_floating_ip_view(self):
        floating_ip_address = self.floating_ip
        floating_ip = db.floating_ip_get_by_address(self.context,
                                                    floating_ip_address)
        # NOTE(vish): network_get uses the id not the address
        floating_ip = db.floating_ip_get(self.context, floating_ip['id'])
        view = floating_ips._translate_floating_ip_view(floating_ip)
        self.assertIn('floating_ip', view)
        self.assertTrue(view['floating_ip']['id'])
        self.assertEqual(view['floating_ip']['ip'], self.floating_ip)
        self.assertIsNone(view['floating_ip']['fixed_ip'])
        self.assertIsNone(view['floating_ip']['instance_id'])

    def test_translate_floating_ip_view_dict(self):
        floating_ip = {
            'id': 0,
            'address': '10.0.0.10',
            'pool': 'nova',
            'fixed_ip': None
        }
        view = floating_ips._translate_floating_ip_view(floating_ip)
        self.assertIn('floating_ip', view)

    def test_floating_ips_list(self):
        req = self._get_fake_fip_request()
        res_dict = self.controller.index(req)

        response = {
            'floating_ips': [{
                'instance_id': FAKE_UUID,
                'ip': '10.10.10.10',
                'pool': 'nova',
                'fixed_ip': '10.0.0.1',
                'id': 1
            }, {
                'instance_id': None,
                'ip': '10.10.10.11',
                'pool': 'nova',
                'fixed_ip': None,
                'id': 2
            }]
        }
        self.assertEqual(res_dict, response)

    def test_floating_ip_release_nonexisting(self):
        def fake_get_floating_ip(*args, **kwargs):
            raise exception.FloatingIpNotFound(id=id)

        self.stubs.Set(network.api.API, "get_floating_ip",
                       fake_get_floating_ip)

        req = self._get_fake_fip_request('9876')
        req.method = 'DELETE'
        res = self._get_fake_response(req, 'os-floating-ips')
        self.assertEqual(res.status_int, 404)
        expected_msg = ('{"itemNotFound": {"message": "Floating ip not found '
                        'for id 9876", "code": 404}}')
        self.assertEqual(res.body, expected_msg)

    def test_floating_ip_release_race_cond(self):
        def fake_get_floating_ip(*args, **kwargs):
            return {'fixed_ip_id': 1, 'address': self.floating_ip}

        def fake_get_instance_by_floating_ip_addr(*args, **kwargs):
            return 'test-inst'

        def fake_disassociate_floating_ip(*args, **kwargs):
            raise exception.FloatingIpNotAssociated(args[3])

        self.stubs.Set(network.api.API, "get_floating_ip",
                       fake_get_floating_ip)
        self.stubs.Set(floating_ips, "get_instance_by_floating_ip_addr",
                       fake_get_instance_by_floating_ip_addr)
        self.stubs.Set(floating_ips, "disassociate_floating_ip",
                       fake_disassociate_floating_ip)

        req = self._get_fake_fip_request('1')
        req.method = 'DELETE'
        res = self._get_fake_response(req, 'os-floating-ips')
        self.assertEqual(res.status_int, 202)

    def test_floating_ip_show(self):
        req = self._get_fake_fip_request('1')
        res_dict = self.controller.show(req, 1)

        self.assertEqual(res_dict['floating_ip']['id'], 1)
        self.assertEqual(res_dict['floating_ip']['ip'], '10.10.10.10')
        self.assertIsNone(res_dict['floating_ip']['instance_id'])

    def test_floating_ip_show_not_found(self):
        def fake_get_floating_ip(*args, **kwargs):
            raise exception.FloatingIpNotFound(id='fake')

        self.stubs.Set(network.api.API, "get_floating_ip",
                       fake_get_floating_ip)

        req = self._get_fake_fip_request('9876')
        res = self._get_fake_response(req, 'os-floating-ips')
        self.assertEqual(res.status_int, 404)
        expected_msg = ('{"itemNotFound": {"message": "Floating ip not found '
                        'for id 9876", "code": 404}}')
        self.assertEqual(res.body, expected_msg)

    def test_show_associated_floating_ip(self):
        def get_floating_ip(self, context, id):
            return {
                'id': 1,
                'address': '10.10.10.10',
                'pool': 'nova',
                'fixed_ip': {
                    'address': '10.0.0.1',
                    'instance_uuid': FAKE_UUID,
                    'instance': {
                        'uuid': FAKE_UUID
                    }
                }
            }

        self.stubs.Set(network.api.API, "get_floating_ip", get_floating_ip)

        req = self._get_fake_fip_request('1')
        res_dict = self.controller.show(req, 1)

        self.assertEqual(res_dict['floating_ip']['id'], 1)
        self.assertEqual(res_dict['floating_ip']['ip'], '10.10.10.10')
        self.assertEqual(res_dict['floating_ip']['fixed_ip'], '10.0.0.1')
        self.assertEqual(res_dict['floating_ip']['instance_id'], FAKE_UUID)

    def test_recreation_of_floating_ip(self):
        self._delete_floating_ip()
        self._create_floating_ips()

    def test_floating_ip_in_bulk_creation(self):
        self._delete_floating_ip()

        self._create_floating_ips([self.floating_ip, self.floating_ip_2])
        all_ips = db.floating_ip_get_all(self.context)
        ip_list = [ip['address'] for ip in all_ips]
        self.assertIn(self.floating_ip, ip_list)
        self.assertIn(self.floating_ip_2, ip_list)

    def test_fail_floating_ip_in_bulk_creation(self):
        self.assertRaises(exception.FloatingIpExists,
                          self._create_floating_ips,
                          [self.floating_ip, self.floating_ip_2])
        all_ips = db.floating_ip_get_all(self.context)
        ip_list = [ip['address'] for ip in all_ips]
        self.assertIn(self.floating_ip, ip_list)
        self.assertNotIn(self.floating_ip_2, ip_list)

    def test_floating_ip_allocate_no_free_ips(self):
        def fake_allocate(*args, **kwargs):
            raise exception.NoMoreFloatingIps()

        self.stubs.Set(network.api.API, "allocate_floating_ip", fake_allocate)

        req = self._get_fake_fip_request()
        ex = self.assertRaises(webob.exc.HTTPNotFound, self.controller.create,
                               req)

        self.assertIn('No more floating ips', ex.explanation)

    def test_floating_ip_allocate_no_free_ips_pool(self):
        def fake_allocate(*args, **kwargs):
            raise exception.NoMoreFloatingIps()

        self.stubs.Set(network.api.API, "allocate_floating_ip", fake_allocate)

        req = self._get_fake_fip_request()
        ex = self.assertRaises(webob.exc.HTTPNotFound, self.controller.create,
                               req, {'pool': 'non_existent_pool'})

        self.assertIn('No more floating ips in pool non_existent_pool',
                      ex.explanation)

    @mock.patch('nova.network.api.API.allocate_floating_ip',
                side_effect=exception.FloatingIpLimitExceeded())
    def test_floating_ip_allocate_over_quota(self, allocate_mock):
        req = self._get_fake_fip_request()
        ex = self.assertRaises(webob.exc.HTTPForbidden, self.controller.create,
                               req)

        self.assertIn('IP allocation over quota', ex.explanation)

    @mock.patch('nova.network.api.API.allocate_floating_ip',
                side_effect=exception.FloatingIpLimitExceeded())
    def test_floating_ip_allocate_quota_exceed_in_pool(self, allocate_mock):
        req = self._get_fake_fip_request()
        ex = self.assertRaises(webob.exc.HTTPForbidden, self.controller.create,
                               req, {'pool': 'non_existent_pool'})

        self.assertIn('IP allocation over quota in pool non_existent_pool.',
                      ex.explanation)

    @mock.patch('nova.network.api.API.allocate_floating_ip',
                side_effect=exception.FloatingIpPoolNotFound())
    def test_floating_ip_create_with_unknown_pool(self, allocate_mock):
        req = self._get_fake_fip_request()
        ex = self.assertRaises(webob.exc.HTTPNotFound, self.controller.create,
                               req, {'pool': 'non_existent_pool'})

        self.assertIn('Floating ip pool not found.', ex.explanation)

    def test_floating_ip_allocate(self):
        def fake1(*args, **kwargs):
            pass

        def fake2(*args, **kwargs):
            return {'id': 1, 'address': '10.10.10.10', 'pool': 'nova'}

        self.stubs.Set(network.api.API, "allocate_floating_ip", fake1)
        self.stubs.Set(network.api.API, "get_floating_ip_by_address", fake2)

        req = self._get_fake_fip_request()
        res_dict = self.controller.create(req)

        ip = res_dict['floating_ip']

        expected = {
            "id": 1,
            "instance_id": None,
            "ip": "10.10.10.10",
            "fixed_ip": None,
            "pool": 'nova'
        }
        self.assertEqual(ip, expected)

    def test_floating_ip_release(self):
        req = self._get_fake_fip_request('1')
        self.controller.delete(req, 1)

    def test_floating_ip_associate(self):
        fixed_address = '192.168.1.100'

        def fake_associate_floating_ip(*args, **kwargs):
            self.assertEqual(fixed_address, kwargs['fixed_address'])

        self.stubs.Set(network.api.API, "associate_floating_ip",
                       fake_associate_floating_ip)
        body = dict(addFloatingIp=dict(address=self.floating_ip))

        req = self._get_fake_server_request()
        rsp = self.manager._add_floating_ip(req, 'test_inst', body)
        self.assertEqual(202, rsp.status_int)

    def test_floating_ip_associate_invalid_instance(self):
        def fake_get(self,
                     context,
                     id,
                     expected_attrs=None,
                     want_objects=False):
            raise exception.InstanceNotFound(instance_id=id)

        self.stubs.Set(compute.api.API, "get", fake_get)

        body = dict(addFloatingIp=dict(address=self.floating_ip))

        req = self._get_fake_server_request()
        self.assertRaises(webob.exc.HTTPNotFound,
                          self.manager._add_floating_ip, req, 'test_inst',
                          body)

    def test_not_extended_floating_ip_associate_fixed(self):
        # Check that fixed_address is ignored if os-extended-floating-ips
        # is not loaded
        fixed_address_requested = '192.168.1.101'
        fixed_address_allocated = '192.168.1.100'

        def fake_associate_floating_ip(*args, **kwargs):
            self.assertEqual(fixed_address_allocated, kwargs['fixed_address'])

        self.stubs.Set(network.api.API, "associate_floating_ip",
                       fake_associate_floating_ip)
        body = dict(addFloatingIp=dict(address=self.floating_ip,
                                       fixed_address=fixed_address_requested))

        req = self._get_fake_server_request()
        rsp = self.manager._add_floating_ip(req, 'test_inst', body)
        self.assertEqual(202, rsp.status_int)

    def test_associate_not_allocated_floating_ip_to_instance(self):
        def fake_associate_floating_ip(self,
                                       context,
                                       instance,
                                       floating_address,
                                       fixed_address,
                                       affect_auto_assigned=False):
            raise exception.FloatingIpNotFoundForAddress(
                address=floating_address)

        self.stubs.Set(network.api.API, "associate_floating_ip",
                       fake_associate_floating_ip)
        floating_ip = '10.10.10.11'
        body = dict(addFloatingIp=dict(address=floating_ip))
        req = self._get_fake_server_request()
        req.method = "POST"
        req.body = jsonutils.dumps(body)
        req.headers["content-type"] = "application/json"
        resp = self._get_fake_response(req, 'servers')
        res_dict = jsonutils.loads(resp.body)
        self.assertEqual(resp.status_int, 404)
        self.assertEqual(res_dict['itemNotFound']['message'],
                         "floating ip not found")

    @mock.patch.object(network.api.API,
                       'associate_floating_ip',
                       side_effect=exception.Forbidden)
    def test_associate_floating_ip_forbidden(self, associate_mock):
        body = dict(addFloatingIp=dict(address='10.10.10.11'))
        req = self._get_fake_server_request()
        self.assertRaises(webob.exc.HTTPForbidden,
                          self.manager._add_floating_ip, req, 'test_inst',
                          body)

    def test_associate_floating_ip_bad_address_key(self):
        body = dict(addFloatingIp=dict(bad_address='10.10.10.11'))
        req = fakes.HTTPRequest.blank('/v2/fake/servers/test_inst/action')
        self.assertRaises(webob.exc.HTTPBadRequest,
                          self.manager._add_floating_ip, req, 'test_inst',
                          body)

    def test_associate_floating_ip_bad_addfloatingip_key(self):
        body = dict(bad_addFloatingIp=dict(address='10.10.10.11'))
        req = fakes.HTTPRequest.blank('/v2/fake/servers/test_inst/action')
        self.assertRaises(webob.exc.HTTPBadRequest,
                          self.manager._add_floating_ip, req, 'test_inst',
                          body)

    def test_floating_ip_disassociate(self):
        def get_instance_by_floating_ip_addr(self, context, address):
            if address == '10.10.10.10':
                return 'test_inst'

        self.stubs.Set(network.api.API, "get_instance_id_by_floating_address",
                       get_instance_by_floating_ip_addr)

        body = dict(removeFloatingIp=dict(address='10.10.10.10'))

        req = self._get_fake_server_request()
        rsp = self.manager._remove_floating_ip(req, 'test_inst', body)
        self.assertEqual(202, rsp.status_int)

    def test_floating_ip_disassociate_missing(self):
        body = dict(removeFloatingIp=dict(address='10.10.10.10'))

        req = self._get_fake_server_request()
        self.assertRaises(webob.exc.HTTPUnprocessableEntity,
                          self.manager._remove_floating_ip, req, 'test_inst',
                          body)

    def test_floating_ip_associate_non_existent_ip(self):
        def fake_network_api_associate(self,
                                       context,
                                       instance,
                                       floating_address=None,
                                       fixed_address=None):
            floating_ips = ["10.10.10.10", "10.10.10.11"]
            if floating_address not in floating_ips:
                raise exception.FloatingIpNotFoundForAddress(
                    address=floating_address)

        self.stubs.Set(network.api.API, "associate_floating_ip",
                       fake_network_api_associate)

        body = dict(addFloatingIp=dict(address='1.1.1.1'))
        req = self._get_fake_server_request()
        self.assertRaises(webob.exc.HTTPNotFound,
                          self.manager._add_floating_ip, req, 'test_inst',
                          body)

    def test_floating_ip_disassociate_non_existent_ip(self):
        def network_api_get_floating_ip_by_address(self, context,
                                                   floating_address):
            floating_ips = ["10.10.10.10", "10.10.10.11"]
            if floating_address not in floating_ips:
                raise exception.FloatingIpNotFoundForAddress(
                    address=floating_address)

        self.stubs.Set(network.api.API, "get_floating_ip_by_address",
                       network_api_get_floating_ip_by_address)

        body = dict(removeFloatingIp=dict(address='1.1.1.1'))
        req = self._get_fake_server_request()
        self.assertRaises(webob.exc.HTTPNotFound,
                          self.manager._remove_floating_ip, req, 'test_inst',
                          body)

    def test_floating_ip_disassociate_wrong_instance_uuid(self):
        def get_instance_by_floating_ip_addr(self, context, address):
            if address == '10.10.10.10':
                return 'test_inst'

        self.stubs.Set(network.api.API, "get_instance_id_by_floating_address",
                       get_instance_by_floating_ip_addr)

        wrong_uuid = 'aaaaaaaa-ffff-ffff-ffff-aaaaaaaaaaaa'
        body = dict(removeFloatingIp=dict(address='10.10.10.10'))

        req = self._get_fake_server_request()
        self.assertRaises(webob.exc.HTTPUnprocessableEntity,
                          self.manager._remove_floating_ip, req, wrong_uuid,
                          body)

    def test_floating_ip_disassociate_wrong_instance_id(self):
        def get_instance_by_floating_ip_addr(self, context, address):
            if address == '10.10.10.10':
                return 'wrong_inst'

        self.stubs.Set(network.api.API, "get_instance_id_by_floating_address",
                       get_instance_by_floating_ip_addr)

        body = dict(removeFloatingIp=dict(address='10.10.10.10'))

        req = self._get_fake_server_request()
        self.assertRaises(webob.exc.HTTPUnprocessableEntity,
                          self.manager._remove_floating_ip, req, 'test_inst',
                          body)

    def test_floating_ip_disassociate_auto_assigned(self):
        def fake_get_floating_ip_addr_auto_assigned(self, context, address):
            return {
                'id': 1,
                'address': '10.10.10.10',
                'pool': 'nova',
                'fixed_ip_id': 10,
                'auto_assigned': 1
            }

        def get_instance_by_floating_ip_addr(self, context, address):
            if address == '10.10.10.10':
                return 'test_inst'

        def network_api_disassociate(self, context, instance,
                                     floating_address):
            raise exception.CannotDisassociateAutoAssignedFloatingIP()

        self.stubs.Set(network.api.API, "get_floating_ip_by_address",
                       fake_get_floating_ip_addr_auto_assigned)
        self.stubs.Set(network.api.API, "get_instance_id_by_floating_address",
                       get_instance_by_floating_ip_addr)
        self.stubs.Set(network.api.API, "disassociate_floating_ip",
                       network_api_disassociate)
        body = dict(removeFloatingIp=dict(address='10.10.10.10'))
        req = self._get_fake_server_request()
        self.assertRaises(webob.exc.HTTPForbidden,
                          self.manager._remove_floating_ip, req, 'test_inst',
                          body)

    def test_floating_ip_disassociate_map_authorization_exc(self):
        def fake_get_floating_ip_addr_auto_assigned(self, context, address):
            return {
                'id': 1,
                'address': '10.10.10.10',
                'pool': 'nova',
                'fixed_ip_id': 10,
                'auto_assigned': 1
            }

        def get_instance_by_floating_ip_addr(self, context, address):
            if address == '10.10.10.10':
                return 'test_inst'

        def network_api_disassociate(self, context, instance, address):
            raise exception.Forbidden()

        self.stubs.Set(network.api.API, "get_floating_ip_by_address",
                       fake_get_floating_ip_addr_auto_assigned)
        self.stubs.Set(network.api.API, "get_instance_id_by_floating_address",
                       get_instance_by_floating_ip_addr)
        self.stubs.Set(network.api.API, "disassociate_floating_ip",
                       network_api_disassociate)
        body = dict(removeFloatingIp=dict(address='10.10.10.10'))
        req = self._get_fake_server_request()
        self.assertRaises(webob.exc.HTTPForbidden,
                          self.manager._remove_floating_ip, req, 'test_inst',
                          body)


# 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'))

        req = self._get_fake_server_request()
        self.assertRaises(webob.exc.HTTPBadRequest,
                          self.manager._remove_floating_ip, req, 'test_inst',
                          body)

    def test_missing_dict_param_in_remove_floating_ip(self):
        body = dict(removeFloatingIp='11.0.0.1')

        req = self._get_fake_server_request()
        self.assertRaises(webob.exc.HTTPBadRequest,
                          self.manager._remove_floating_ip, req, 'test_inst',
                          body)

    def test_missing_dict_param_in_add_floating_ip(self):
        body = dict(addFloatingIp='11.0.0.1')

        req = self._get_fake_server_request()
        self.assertRaises(webob.exc.HTTPBadRequest,
                          self.manager._add_floating_ip, req, 'test_inst',
                          body)
Beispiel #5
0
class FloatingIpTestV21(test.TestCase):
    floating_ip = "10.10.10.10"
    floating_ip_2 = "10.10.10.11"
    floating_ips = fips_v21
    validation_error = exception.ValidationError

    def _create_floating_ips(self, floating_ips=None):
        """Create a floating ip object."""
        if floating_ips is None:
            floating_ips = [self.floating_ip]
        elif not isinstance(floating_ips, (list, tuple)):
            floating_ips = [floating_ips]

        def make_ip_dict(ip):
            """Shortcut for creating floating ip dict."""
            return

        dict_ = {'pool': 'nova', 'host': 'fake_host'}
        return db.floating_ip_bulk_create(
            self.context, [dict(address=ip, **dict_) for ip in floating_ips],
        )

    def _delete_floating_ip(self):
        db.floating_ip_destroy(self.context, self.floating_ip)

    def setUp(self):
        super(FloatingIpTestV21, self).setUp()
        self.stubs.Set(compute.api.API, "get",
                       compute_api_get)
        self.stubs.Set(network.api.API, "get_floating_ip",
                       network_api_get_floating_ip)
        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",
                       network_api_disassociate)
        self.stubs.Set(network.api.API, "get_instance_id_by_floating_address",
                       get_instance_by_floating_ip_addr)
        self.stubs.Set(compute_utils, "get_nw_info_for_instance",
                       stub_nw_info(self.stubs))

        fake_network.stub_out_nw_api_get_instance_nw_info(self.stubs)
        self.stubs.Set(db, 'instance_get',
                       fake_instance_get)

        self.context = context.get_admin_context()
        self._create_floating_ips()

        self.ext_mgr = extensions.ExtensionManager()
        self.ext_mgr.extensions = {}
        self.controller = self.floating_ips.FloatingIPController()
        self.manager = self.floating_ips.\
                            FloatingIPActionController(self.ext_mgr)
        self.fake_req = fakes.HTTPRequest.blank('')

    def tearDown(self):
        self._delete_floating_ip()
        super(FloatingIpTestV21, self).tearDown()

    def test_floatingip_delete(self):
        fip_val = {'address': '1.1.1.1', 'fixed_ip_id': '192.168.1.2'}
        with contextlib.nested(
            mock.patch.object(self.controller.network_api,
                              'disassociate_floating_ip'),
            mock.patch.object(self.controller.network_api,
                              'release_floating_ip'),
            mock.patch.object(self.controller.network_api,
                             'get_instance_id_by_floating_address',
                              return_value=None),
            mock.patch.object(self.controller.network_api,
                              'get_floating_ip',
                              return_value=fip_val)) as (
                disoc_fip, rel_fip, _, _):
            self.controller.delete(self.fake_req, 1)
            self.assertTrue(disoc_fip.called)
            self.assertTrue(rel_fip.called)

    def _test_floatingip_delete_not_found(self, ex,
                                          expect_ex=webob.exc.HTTPNotFound):
        with contextlib.nested(
            mock.patch.object(self.controller.network_api,
                              'get_floating_ip',
                              side_effect=ex)
            ):
            self.assertRaises(expect_ex,
                              self.controller.delete, self.fake_req, 1)

    def test_floatingip_delete_not_found_ip(self):
        ex = exception.FloatingIpNotFound(id=1)
        self._test_floatingip_delete_not_found(ex)

    def test_floatingip_delete_not_found(self):
        ex = exception.NotFound
        self._test_floatingip_delete_not_found(ex)

    def test_floatingip_delete_invalid_id(self):
        ex = exception.InvalidID(id=1)
        self._test_floatingip_delete_not_found(ex, webob.exc.HTTPBadRequest)

    def test_translate_floating_ip_view(self):
        floating_ip_address = self.floating_ip
        floating_ip = db.floating_ip_get_by_address(self.context,
                                                    floating_ip_address)
        # NOTE(vish): network_get uses the id not the address
        floating_ip = db.floating_ip_get(self.context, floating_ip['id'])
        view = self.floating_ips._translate_floating_ip_view(floating_ip)
        self.assertIn('floating_ip', view)
        self.assertTrue(view['floating_ip']['id'])
        self.assertEqual(view['floating_ip']['ip'], self.floating_ip)
        self.assertIsNone(view['floating_ip']['fixed_ip'])
        self.assertIsNone(view['floating_ip']['instance_id'])

    def test_translate_floating_ip_view_dict(self):
        floating_ip = {'id': 0, 'address': '10.0.0.10', 'pool': 'nova',
                       'fixed_ip': None}
        view = self.floating_ips._translate_floating_ip_view(floating_ip)
        self.assertIn('floating_ip', view)

    def test_floating_ips_list(self):
        res_dict = self.controller.index(self.fake_req)

        response = {'floating_ips': [{'instance_id': FAKE_UUID,
                                      'ip': '10.10.10.10',
                                      'pool': 'nova',
                                      'fixed_ip': '10.0.0.1',
                                      'id': 1},
                                     {'instance_id': None,
                                      'ip': '10.10.10.11',
                                      'pool': 'nova',
                                      'fixed_ip': None,
                                      'id': 2}]}
        self.assertEqual(res_dict, response)

    def test_floating_ip_release_nonexisting(self):
        def fake_get_floating_ip(*args, **kwargs):
            raise exception.FloatingIpNotFound(id=id)

        self.stubs.Set(network.api.API, "get_floating_ip",
                       fake_get_floating_ip)

        ex = self.assertRaises(webob.exc.HTTPNotFound,
                               self.controller.delete, self.fake_req, '9876')
        self.assertIn("Floating ip not found for id 9876", ex.explanation)

    def test_floating_ip_release_race_cond(self):
        def fake_get_floating_ip(*args, **kwargs):
            return {'fixed_ip_id': 1, 'address': self.floating_ip}

        def fake_get_instance_by_floating_ip_addr(*args, **kwargs):
            return 'test-inst'

        def fake_disassociate_floating_ip(*args, **kwargs):
            raise exception.FloatingIpNotAssociated(args[3])

        self.stubs.Set(network.api.API, "get_floating_ip",
                fake_get_floating_ip)
        self.stubs.Set(self.floating_ips, "get_instance_by_floating_ip_addr",
                fake_get_instance_by_floating_ip_addr)
        self.stubs.Set(self.floating_ips, "disassociate_floating_ip",
                fake_disassociate_floating_ip)

        res = self.controller.delete(self.fake_req, '9876')
        # NOTE: on v2.1, http status code is set as wsgi_code of API
        # method instead of status_int in a response object.
        if isinstance(self.controller,
                      fips_v21.FloatingIPController):
            status_int = self.controller.delete.wsgi_code
        else:
            status_int = res.status_int
        self.assertEqual(status_int, 202)

    def test_floating_ip_show(self):
        res_dict = self.controller.show(self.fake_req, 1)

        self.assertEqual(res_dict['floating_ip']['id'], 1)
        self.assertEqual(res_dict['floating_ip']['ip'], '10.10.10.10')
        self.assertIsNone(res_dict['floating_ip']['instance_id'])

    def test_floating_ip_show_not_found(self):
        def fake_get_floating_ip(*args, **kwargs):
            raise exception.FloatingIpNotFound(id='fake')

        self.stubs.Set(network.api.API, "get_floating_ip",
                       fake_get_floating_ip)

        ex = self.assertRaises(webob.exc.HTTPNotFound,
                               self.controller.show, self.fake_req, '9876')
        self.assertIn("Floating ip not found for id 9876", ex.explanation)

    def test_show_associated_floating_ip(self):
        def get_floating_ip(self, context, id):
            return {'id': 1, 'address': '10.10.10.10', 'pool': 'nova',
                    'fixed_ip': {'address': '10.0.0.1',
                                 'instance_uuid': FAKE_UUID,
                                 'instance': {'uuid': FAKE_UUID}}}

        self.stubs.Set(network.api.API, "get_floating_ip", get_floating_ip)

        res_dict = self.controller.show(self.fake_req, 1)

        self.assertEqual(res_dict['floating_ip']['id'], 1)
        self.assertEqual(res_dict['floating_ip']['ip'], '10.10.10.10')
        self.assertEqual(res_dict['floating_ip']['fixed_ip'], '10.0.0.1')
        self.assertEqual(res_dict['floating_ip']['instance_id'], FAKE_UUID)

    def test_recreation_of_floating_ip(self):
        self._delete_floating_ip()
        self._create_floating_ips()

    def test_floating_ip_in_bulk_creation(self):
        self._delete_floating_ip()

        self._create_floating_ips([self.floating_ip, self.floating_ip_2])
        all_ips = db.floating_ip_get_all(self.context)
        ip_list = [ip['address'] for ip in all_ips]
        self.assertIn(self.floating_ip, ip_list)
        self.assertIn(self.floating_ip_2, ip_list)

    def test_fail_floating_ip_in_bulk_creation(self):
        self.assertRaises(exception.FloatingIpExists,
                          self._create_floating_ips,
                          [self.floating_ip, self.floating_ip_2])
        all_ips = db.floating_ip_get_all(self.context)
        ip_list = [ip['address'] for ip in all_ips]
        self.assertIn(self.floating_ip, ip_list)
        self.assertNotIn(self.floating_ip_2, ip_list)

    def test_floating_ip_allocate_no_free_ips(self):
        def fake_allocate(*args, **kwargs):
            raise exception.NoMoreFloatingIps()

        self.stubs.Set(network.api.API, "allocate_floating_ip", fake_allocate)

        ex = self.assertRaises(webob.exc.HTTPNotFound,
                               self.controller.create, self.fake_req)

        self.assertIn('No more floating ips', ex.explanation)

    def test_floating_ip_allocate_no_free_ips_pool(self):
        def fake_allocate(*args, **kwargs):
            raise exception.NoMoreFloatingIps()

        self.stubs.Set(network.api.API, "allocate_floating_ip", fake_allocate)

        ex = self.assertRaises(webob.exc.HTTPNotFound,
                               self.controller.create, self.fake_req,
                               {'pool': 'non_existent_pool'})

        self.assertIn('No more floating ips in pool non_existent_pool',
                      ex.explanation)

    @mock.patch('nova.network.api.API.allocate_floating_ip',
                side_effect=exception.FloatingIpLimitExceeded())
    def test_floating_ip_allocate_over_quota(self, allocate_mock):
        ex = self.assertRaises(webob.exc.HTTPForbidden,
                               self.controller.create, self.fake_req)

        self.assertIn('IP allocation over quota', ex.explanation)

    @mock.patch('nova.network.api.API.allocate_floating_ip',
                side_effect=exception.FloatingIpLimitExceeded())
    def test_floating_ip_allocate_quota_exceed_in_pool(self, allocate_mock):
        ex = self.assertRaises(webob.exc.HTTPForbidden,
                               self.controller.create, self.fake_req,
                               {'pool': 'non_existent_pool'})

        self.assertIn('IP allocation over quota in pool non_existent_pool.',
                      ex.explanation)

    @mock.patch('nova.network.api.API.allocate_floating_ip',
                side_effect=exception.FloatingIpPoolNotFound())
    def test_floating_ip_create_with_unknown_pool(self, allocate_mock):
        ex = self.assertRaises(webob.exc.HTTPNotFound,
                               self.controller.create, self.fake_req,
                               {'pool': 'non_existent_pool'})

        self.assertIn('Floating ip pool not found.', ex.explanation)

    def test_floating_ip_allocate(self):
        def fake1(*args, **kwargs):
            pass

        def fake2(*args, **kwargs):
            return {'id': 1, 'address': '10.10.10.10', 'pool': 'nova'}

        self.stubs.Set(network.api.API, "allocate_floating_ip",
                       fake1)
        self.stubs.Set(network.api.API, "get_floating_ip_by_address",
                       fake2)

        res_dict = self.controller.create(self.fake_req)

        ip = res_dict['floating_ip']

        expected = {
            "id": 1,
            "instance_id": None,
            "ip": "10.10.10.10",
            "fixed_ip": None,
            "pool": 'nova'}
        self.assertEqual(ip, expected)

    def test_floating_ip_release(self):
        self.controller.delete(self.fake_req, 1)

    def test_floating_ip_associate(self):
        fixed_address = '192.168.1.100'

        def fake_associate_floating_ip(*args, **kwargs):
            self.assertEqual(fixed_address, kwargs['fixed_address'])

        self.stubs.Set(network.api.API, "associate_floating_ip",
                       fake_associate_floating_ip)
        body = dict(addFloatingIp=dict(address=self.floating_ip))

        rsp = self.manager._add_floating_ip(self.fake_req, TEST_INST,
                                            body=body)
        self.assertEqual(202, rsp.status_int)

    def test_floating_ip_associate_invalid_instance(self):

        def fake_get(self, context, id, expected_attrs=None,
                     want_objects=False):
            raise exception.InstanceNotFound(instance_id=id)

        self.stubs.Set(compute.api.API, "get", fake_get)

        body = dict(addFloatingIp=dict(address=self.floating_ip))

        self.assertRaises(webob.exc.HTTPNotFound,
                          self.manager._add_floating_ip, self.fake_req,
                          'test_inst', body=body)

    def test_associate_not_allocated_floating_ip_to_instance(self):
        def fake_associate_floating_ip(self, context, instance,
                              floating_address, fixed_address,
                              affect_auto_assigned=False):
            raise exception.FloatingIpNotFoundForAddress(
                address=floating_address)
        self.stubs.Set(network.api.API, "associate_floating_ip",
                       fake_associate_floating_ip)
        floating_ip = '10.10.10.11'
        body = dict(addFloatingIp=dict(address=floating_ip))
        ex = self.assertRaises(webob.exc.HTTPNotFound,
                               self.manager._add_floating_ip,
                               self.fake_req, TEST_INST, body=body)

        self.assertIn("floating ip not found", ex.explanation)

    @mock.patch.object(network.api.API, 'associate_floating_ip',
                       side_effect=exception.Forbidden)
    def test_associate_floating_ip_forbidden(self, associate_mock):
        body = dict(addFloatingIp=dict(address='10.10.10.11'))
        self.assertRaises(webob.exc.HTTPForbidden,
                          self.manager._add_floating_ip, self.fake_req,
                          TEST_INST, body=body)

    def test_associate_floating_ip_bad_address_key(self):
        body = dict(addFloatingIp=dict(bad_address='10.10.10.11'))
        req = fakes.HTTPRequest.blank('/v2/fake/servers/test_inst/action')
        self.assertRaises(self.validation_error,
                          self.manager._add_floating_ip, req, 'test_inst',
                          body=body)

    def test_associate_floating_ip_bad_addfloatingip_key(self):
        body = dict(bad_addFloatingIp=dict(address='10.10.10.11'))
        req = fakes.HTTPRequest.blank('/v2/fake/servers/test_inst/action')
        self.assertRaises(self.validation_error,
                          self.manager._add_floating_ip, req, 'test_inst',
                          body=body)

    def test_floating_ip_disassociate(self):
        def get_instance_by_floating_ip_addr(self, context, address):
            if address == '10.10.10.10':
                return TEST_INST

        self.stubs.Set(network.api.API, "get_instance_id_by_floating_address",
                       get_instance_by_floating_ip_addr)

        body = dict(removeFloatingIp=dict(address='10.10.10.10'))

        rsp = self.manager._remove_floating_ip(self.fake_req, TEST_INST,
                                               body=body)
        self.assertEqual(202, rsp.status_int)

    def test_floating_ip_disassociate_missing(self):
        body = dict(removeFloatingIp=dict(address='10.10.10.10'))

        self.assertRaises(webob.exc.HTTPConflict,
                          self.manager._remove_floating_ip,
                          self.fake_req, 'test_inst', body=body)

    def test_floating_ip_associate_non_existent_ip(self):
        def fake_network_api_associate(self, context, instance,
                                             floating_address=None,
                                             fixed_address=None):
            floating_ips = ["10.10.10.10", "10.10.10.11"]
            if floating_address not in floating_ips:
                    raise exception.FloatingIpNotFoundForAddress(
                            address=floating_address)

        self.stubs.Set(network.api.API, "associate_floating_ip",
                       fake_network_api_associate)

        body = dict(addFloatingIp=dict(address='1.1.1.1'))
        self.assertRaises(webob.exc.HTTPNotFound,
                          self.manager._add_floating_ip,
                          self.fake_req, TEST_INST, body=body)

    def test_floating_ip_disassociate_non_existent_ip(self):
        def network_api_get_floating_ip_by_address(self, context,
                                                         floating_address):
            floating_ips = ["10.10.10.10", "10.10.10.11"]
            if floating_address not in floating_ips:
                    raise exception.FloatingIpNotFoundForAddress(
                            address=floating_address)

        self.stubs.Set(network.api.API, "get_floating_ip_by_address",
                       network_api_get_floating_ip_by_address)

        body = dict(removeFloatingIp=dict(address='1.1.1.1'))
        self.assertRaises(webob.exc.HTTPNotFound,
                          self.manager._remove_floating_ip,
                          self.fake_req, TEST_INST, body=body)

    def test_floating_ip_disassociate_wrong_instance_uuid(self):
        def get_instance_by_floating_ip_addr(self, context, address):
            if address == '10.10.10.10':
                return TEST_INST

        self.stubs.Set(network.api.API, "get_instance_id_by_floating_address",
                       get_instance_by_floating_ip_addr)

        wrong_uuid = 'aaaaaaaa-ffff-ffff-ffff-aaaaaaaaaaaa'
        body = dict(removeFloatingIp=dict(address='10.10.10.10'))

        self.assertRaises(webob.exc.HTTPConflict,
                          self.manager._remove_floating_ip,
                          self.fake_req, wrong_uuid, body=body)

    def test_floating_ip_disassociate_wrong_instance_id(self):
        def get_instance_by_floating_ip_addr(self, context, address):
            if address == '10.10.10.10':
                return WRONG_INST

        self.stubs.Set(network.api.API, "get_instance_id_by_floating_address",
                       get_instance_by_floating_ip_addr)

        body = dict(removeFloatingIp=dict(address='10.10.10.10'))

        self.assertRaises(webob.exc.HTTPConflict,
                          self.manager._remove_floating_ip,
                          self.fake_req, TEST_INST, body=body)

    def test_floating_ip_disassociate_auto_assigned(self):
        def fake_get_floating_ip_addr_auto_assigned(self, context, address):
            return {'id': 1, 'address': '10.10.10.10', 'pool': 'nova',
            'fixed_ip_id': 10, 'auto_assigned': 1}

        def get_instance_by_floating_ip_addr(self, context, address):
            if address == '10.10.10.10':
                return TEST_INST

        def network_api_disassociate(self, context, instance,
                                     floating_address):
            raise exception.CannotDisassociateAutoAssignedFloatingIP()

        self.stubs.Set(network.api.API, "get_floating_ip_by_address",
                       fake_get_floating_ip_addr_auto_assigned)
        self.stubs.Set(network.api.API, "get_instance_id_by_floating_address",
                       get_instance_by_floating_ip_addr)
        self.stubs.Set(network.api.API, "disassociate_floating_ip",
                       network_api_disassociate)
        body = dict(removeFloatingIp=dict(address='10.10.10.10'))
        self.assertRaises(webob.exc.HTTPForbidden,
                          self.manager._remove_floating_ip,
                          self.fake_req, TEST_INST, body=body)

    def test_floating_ip_disassociate_map_authorization_exc(self):
        def fake_get_floating_ip_addr_auto_assigned(self, context, address):
            return {'id': 1, 'address': '10.10.10.10', 'pool': 'nova',
            'fixed_ip_id': 10, 'auto_assigned': 1}

        def get_instance_by_floating_ip_addr(self, context, address):
            if address == '10.10.10.10':
                return TEST_INST

        def network_api_disassociate(self, context, instance, address):
            raise exception.Forbidden()

        self.stubs.Set(network.api.API, "get_floating_ip_by_address",
                       fake_get_floating_ip_addr_auto_assigned)
        self.stubs.Set(network.api.API, "get_instance_id_by_floating_address",
                       get_instance_by_floating_ip_addr)
        self.stubs.Set(network.api.API, "disassociate_floating_ip",
                       network_api_disassociate)
        body = dict(removeFloatingIp=dict(address='10.10.10.10'))
        self.assertRaises(webob.exc.HTTPForbidden,
                          self.manager._remove_floating_ip,
                          self.fake_req, TEST_INST, body=body)

# 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'))

        self.assertRaises(self.validation_error,
                          self.manager._remove_floating_ip, self.fake_req,
                          TEST_INST, body=body)

    def test_missing_dict_param_in_remove_floating_ip(self):
        body = dict(removeFloatingIp='11.0.0.1')

        self.assertRaises(self.validation_error,
                          self.manager._remove_floating_ip, self.fake_req,
                          TEST_INST, body=body)

    def test_missing_dict_param_in_add_floating_ip(self):
        body = dict(addFloatingIp='11.0.0.1')

        self.assertRaises(self.validation_error,
                          self.manager._add_floating_ip, self.fake_req,
                          TEST_INST, body=body)