Merge "Remove support for /os-fixed-ips REST API"

This commit is contained in:
Zuul
2018-06-26 21:01:35 +00:00
committed by Gerrit Code Review
15 changed files with 31 additions and 554 deletions

View File

@@ -60,7 +60,6 @@ the `API guide <http://developer.openstack.org/api-guide/compute/index.html>`_.
.. include:: images.inc
.. include:: os-baremetal-nodes.inc
.. include:: os-tenant-network.inc
.. include:: os-fixed-ips.inc
.. include:: os-floating-ip-dns.inc
.. include:: os-floating-ip-pools.inc
.. include:: os-floating-ips.inc
@@ -81,3 +80,4 @@ Compute API in the past, but no longer exist.
.. include:: os-cloudpipe.inc
.. include:: os-fping.inc
.. include:: os-virtual-interfaces.inc
.. include:: os-fixed-ips.inc

View File

@@ -6,9 +6,9 @@
.. warning::
These APIs are proxy calls to the Network service. Nova has
deprecated all the proxy APIs and users should use the native APIs
instead. These will fail with a 404 starting from microversion 2.36.
These APIs only work with **nova-network** which is deprecated.
These will fail with a 404 starting from microversion 2.36.
They were removed in the 18.0.0 Rocky release.
Shows data for a fixed IP, such as host name, CIDR, and address. Also,
reserves and releases a fixed IP address.
@@ -22,7 +22,8 @@ Shows details for a fixed IP address.
Normal response codes: 200
Error response codes: badRequest(400), unauthorized(401), forbidden(403), itemNotFound(404)
Error response codes: badRequest(400), unauthorized(401), forbidden(403),
itemNotFound(404), gone(410)
Request
-------
@@ -61,7 +62,8 @@ To release a fixed IP address, specify ``unreserve`` in the request body.
Normal response codes: 202
Error response codes: badRequest(400), unauthorized(401), forbidden(403), itemNotFound(404)
Error response codes: badRequest(400), unauthorized(401), forbidden(403),
itemNotFound(404), gone(410)
Request
-------

View File

@@ -12,96 +12,23 @@
# License for the specific language governing permissions and limitations
# under the License.
import webob
import webob.exc
from webob import exc
from nova.api.openstack.api_version_request \
import MAX_PROXY_API_SUPPORT_VERSION
from nova.api.openstack.compute.schemas import fixed_ips
from nova.api.openstack import wsgi
from nova.api import validation
from nova import exception
from nova.i18n import _
from nova import objects
from nova.policies import fixed_ips as fi_policies
class FixedIPController(wsgi.Controller):
@wsgi.Controller.api_version('2.1', '2.3')
def _fill_reserved_status(self, req, fixed_ip, fixed_ip_info):
# NOTE(mriedem): To be backwards compatible, < 2.4 version does not
# show anything about reserved status.
pass
@wsgi.Controller.api_version('2.4') # noqa
def _fill_reserved_status(self, req, fixed_ip, fixed_ip_info):
fixed_ip_info['fixed_ip']['reserved'] = fixed_ip.reserved
@wsgi.Controller.api_version("2.1", MAX_PROXY_API_SUPPORT_VERSION)
@wsgi.expected_errors((400, 404))
@wsgi.expected_errors((410))
def show(self, req, id):
"""Return data about the given fixed IP."""
context = req.environ['nova.context']
context.can(fi_policies.BASE_POLICY_NAME)
raise exc.HTTPGone()
attrs = ['network', 'instance']
try:
fixed_ip = objects.FixedIP.get_by_address(context, id,
expected_attrs=attrs)
except exception.FixedIpNotFoundForAddress as ex:
raise webob.exc.HTTPNotFound(explanation=ex.format_message())
except exception.FixedIpInvalid as ex:
raise webob.exc.HTTPBadRequest(explanation=ex.format_message())
fixed_ip_info = {"fixed_ip": {}}
if fixed_ip is None:
msg = _("Fixed IP %s has been deleted") % id
raise webob.exc.HTTPNotFound(explanation=msg)
fixed_ip_info['fixed_ip']['cidr'] = str(fixed_ip.network.cidr)
fixed_ip_info['fixed_ip']['address'] = str(fixed_ip.address)
if fixed_ip.instance:
fixed_ip_info['fixed_ip']['hostname'] = fixed_ip.instance.hostname
fixed_ip_info['fixed_ip']['host'] = fixed_ip.instance.host
else:
fixed_ip_info['fixed_ip']['hostname'] = None
fixed_ip_info['fixed_ip']['host'] = None
self._fill_reserved_status(req, fixed_ip, fixed_ip_info)
return fixed_ip_info
@wsgi.Controller.api_version("2.1", MAX_PROXY_API_SUPPORT_VERSION)
@wsgi.response(202)
@wsgi.expected_errors((400, 404))
@validation.schema(fixed_ips.reserve)
@wsgi.expected_errors((410))
@wsgi.action('reserve')
def reserve(self, req, id, body):
context = req.environ['nova.context']
context.can(fi_policies.BASE_POLICY_NAME)
raise exc.HTTPGone()
return self._set_reserved(context, id, True)
@wsgi.Controller.api_version("2.1", MAX_PROXY_API_SUPPORT_VERSION)
@wsgi.response(202)
@wsgi.expected_errors((400, 404))
@validation.schema(fixed_ips.unreserve)
@wsgi.expected_errors((410))
@wsgi.action('unreserve')
def unreserve(self, req, id, body):
context = req.environ['nova.context']
context.can(fi_policies.BASE_POLICY_NAME)
return self._set_reserved(context, id, False)
def _set_reserved(self, context, address, reserved):
try:
fixed_ip = objects.FixedIP.get_by_address(context, address)
fixed_ip.reserved = reserved
fixed_ip.save()
except exception.FixedIpNotFoundForAddress:
msg = _("Fixed IP %s not found") % address
raise webob.exc.HTTPNotFound(explanation=msg)
except exception.FixedIpInvalid:
msg = _("Fixed IP %s not valid") % address
raise webob.exc.HTTPBadRequest(explanation=msg)
raise exc.HTTPGone()

View File

@@ -1,36 +0,0 @@
# Copyright 2015 Intel Corporation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
from nova.api.validation import parameter_types
reserve = {
'type': 'object',
'properties': {
'reserve': parameter_types.none,
},
'required': ['reserve'],
'additionalProperties': False,
}
unreserve = {
'type': 'object',
'properties': {
'unreserve': parameter_types.none,
},
'required': ['unreserve'],
'additionalProperties': False,
}

View File

@@ -36,7 +36,6 @@ from nova.policies import extended_server_attributes
from nova.policies import extended_status
from nova.policies import extended_volumes
from nova.policies import extensions
from nova.policies import fixed_ips
from nova.policies import flavor_access
from nova.policies import flavor_extra_specs
from nova.policies import flavor_manage
@@ -112,7 +111,6 @@ def list_rules():
extended_status.list_rules(),
extended_volumes.list_rules(),
extensions.list_rules(),
fixed_ips.list_rules(),
flavor_access.list_rules(),
flavor_extra_specs.list_rules(),
flavor_manage.list_rules(),

View File

@@ -1,49 +0,0 @@
# Copyright 2016 Cloudbase Solutions Srl
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
from oslo_policy import policy
from nova.policies import base
BASE_POLICY_NAME = 'os_compute_api:os-fixed-ips'
fixed_ips_policies = [
policy.DocumentedRuleDefault(
BASE_POLICY_NAME,
base.RULE_ADMIN_API,
"""Show details for, reserve and unreserve a fixed IP address.
These APIs are only available with nova-network which is deprecated.""",
[
{
'method': 'GET',
'path': '/os-fixed-ips/{fixed_ip}'
},
{
'method': 'POST',
'path': '/os-fixed-ips/{fixed_ip}/action (reserve)'
},
{
'method': 'POST',
'path': '/os-fixed-ips/{fixed_ip}/action (unreserve)'
}
]),
]
def list_rules():
return fixed_ips_policies

View File

@@ -1,8 +0,0 @@
{
"fixed_ip": {
"cidr": "%(cidr)s",
"hostname": "%(hostname)s",
"host": "%(host)s",
"address": "%(address)s"
}
}

View File

@@ -1,9 +0,0 @@
{
"fixed_ip": {
"cidr": "%(cidr)s",
"hostname": "%(hostname)s",
"host": "%(host)s",
"address": "%(address)s",
"reserved": %(reserved)s
}
}

View File

@@ -12,100 +12,22 @@
# License for the specific language governing permissions and limitations
# under the License.
from nova import exception
from nova.tests.functional.api_sample_tests import test_servers
from nova.tests.unit.objects import test_network
from nova.tests.unit import utils as test_utils
from nova.tests import uuidsentinel as uuids
from nova.tests.functional.api import client as api_client
from nova.tests.functional import api_samples_test_base
class FixedIpTest(test_servers.ServersSampleBase):
sample_dir = "os-fixed-ips"
microversion = None
def setUp(self):
super(FixedIpTest, self).setUp()
self.api.microversion = self.microversion
instance = dict(test_utils.get_test_instance(),
hostname='compute.host.pvt', host='host')
fake_fixed_ips = [{'id': 1,
'address': '192.168.1.1',
'network_id': 1,
'virtual_interface_id': 1,
'instance_uuid': uuids.instance_1,
'allocated': False,
'leased': False,
'reserved': False,
'created_at': None,
'deleted_at': None,
'updated_at': None,
'deleted': None,
'instance': instance,
'network': test_network.fake_network,
'host': None},
{'id': 2,
'address': '192.168.1.2',
'network_id': 1,
'virtual_interface_id': 2,
'instance_uuid': uuids.instance_2,
'allocated': False,
'leased': False,
'reserved': False,
'created_at': None,
'deleted_at': None,
'updated_at': None,
'deleted': None,
'instance': instance,
'network': test_network.fake_network,
'host': None},
]
def fake_fixed_ip_get_by_address(context, address,
columns_to_join=None):
for fixed_ip in fake_fixed_ips:
if fixed_ip['address'] == address:
return fixed_ip
raise exception.FixedIpNotFoundForAddress(address=address)
def fake_fixed_ip_update(context, address, values):
fixed_ip = fake_fixed_ip_get_by_address(context, address)
if fixed_ip is None:
raise exception.FixedIpNotFoundForAddress(address=address)
else:
for key in values:
fixed_ip[key] = values[key]
self.stub_out("nova.db.fixed_ip_get_by_address",
fake_fixed_ip_get_by_address)
self.stub_out("nova.db.fixed_ip_update", fake_fixed_ip_update)
class FixedIpTest(api_samples_test_base.ApiSampleTestBase):
api_major_version = 'v2'
def test_fixed_ip_reserve(self):
# Reserve a Fixed IP.
response = self._do_post('os-fixed-ips/192.168.1.1/action',
'fixedip-post-req', {})
self.assertEqual(202, response.status_code)
self.assertEqual("", response.text)
def _test_get_fixed_ip(self, **kwargs):
# Return data about the given fixed ip.
response = self._do_get('os-fixed-ips/192.168.1.1')
project = {'cidr': '192.168.1.0/24',
'hostname': 'compute.host.pvt',
'host': 'host',
'address': '192.168.1.1'}
project.update(**kwargs)
self._verify_response('fixedips-get-resp', project, response, 200)
ex = self.assertRaises(api_client.OpenStackApiException,
self.api.api_post,
'/os-fixed-ips/192.168.1.1/action',
{"reserve": None})
self.assertEqual(410, ex.response.status_code)
def test_get_fixed_ip(self):
self._test_get_fixed_ip()
class FixedIpV24Test(FixedIpTest):
microversion = '2.4'
# NOTE(gmann): microversion tests do not need to run for v2 API
# so defining scenarios only for v2.4 which will run the original tests
# by appending '(v2_4)' in test_id.
scenarios = [('v2_4', {'api_major_version': 'v2.1'})]
def test_get_fixed_ip(self):
self._test_get_fixed_ip(reserved='False')
ex = self.assertRaises(api_client.OpenStackApiException,
self.api.api_get, '/os-fixed-ips/192.168.1.1')
self.assertEqual(410, ex.response.status_code)

View File

@@ -1,265 +0,0 @@
# Copyright 2012 IBM Corp.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import webob
from nova.api.openstack import api_version_request
from nova.api.openstack.compute import fixed_ips as fixed_ips_v21
from nova.api.openstack import wsgi as os_wsgi
from nova import context
from nova import exception
from nova import test
from nova.tests.unit.api.openstack import fakes
from nova.tests.unit.objects import test_network
from nova.tests import uuidsentinel as uuids
fake_fixed_ips = [{'id': 1,
'address': '192.168.1.1',
'network_id': 1,
'virtual_interface_id': 1,
'instance_uuid': uuids.instance_1,
'allocated': False,
'leased': False,
'reserved': False,
'host': None,
'instance': None,
'network': test_network.fake_network,
'created_at': None,
'updated_at': None,
'deleted_at': None,
'deleted': False},
{'id': 2,
'address': '192.168.1.2',
'network_id': 1,
'virtual_interface_id': 2,
'instance_uuid': uuids.instance_2,
'allocated': False,
'leased': False,
'reserved': False,
'host': None,
'instance': None,
'network': test_network.fake_network,
'created_at': None,
'updated_at': None,
'deleted_at': None,
'deleted': False},
{'id': 3,
'address': '10.0.0.2',
'network_id': 1,
'virtual_interface_id': 3,
'instance_uuid': uuids.instance_3,
'allocated': False,
'leased': False,
'reserved': False,
'host': None,
'instance': None,
'network': test_network.fake_network,
'created_at': None,
'updated_at': None,
'deleted_at': None,
'deleted': True},
]
def fake_fixed_ip_get_by_address(context, address, columns_to_join=None):
if address == 'inv.ali.d.ip':
msg = "Invalid fixed IP Address %s in request" % address
raise exception.FixedIpInvalid(msg)
for fixed_ip in fake_fixed_ips:
if fixed_ip['address'] == address and not fixed_ip['deleted']:
return fixed_ip
raise exception.FixedIpNotFoundForAddress(address=address)
def fake_fixed_ip_update(context, address, values):
fixed_ip = fake_fixed_ip_get_by_address(context, address)
if fixed_ip is None:
raise exception.FixedIpNotFoundForAddress(address=address)
else:
for key in values:
fixed_ip[key] = values[key]
class FakeModel(object):
"""Stubs out for model."""
def __init__(self, values):
self.values = values
def __getattr__(self, name):
return self.values[name]
def __getitem__(self, key):
if key in self.values:
return self.values[key]
else:
raise NotImplementedError()
def __repr__(self):
return '<FakeModel: %s>' % self.values
def fake_network_get_all(context):
network = {'id': 1,
'cidr': "192.168.1.0/24"}
return [FakeModel(network)]
class FixedIpTestV21(test.NoDBTestCase):
fixed_ips = fixed_ips_v21
url = '/v2/fake/os-fixed-ips'
wsgi_api_version = os_wsgi.DEFAULT_API_VERSION
def setUp(self):
super(FixedIpTestV21, self).setUp()
self.stub_out("nova.db.fixed_ip_get_by_address",
fake_fixed_ip_get_by_address)
self.stub_out("nova.db.fixed_ip_update", fake_fixed_ip_update)
self.context = context.get_admin_context()
self.controller = self.fixed_ips.FixedIPController()
def _assert_equal(self, ret, exp):
self.assertEqual(ret.wsgi_code, exp)
def _get_reserve_action(self):
return self.controller.reserve
def _get_unreserve_action(self):
return self.controller.unreserve
def _get_reserved_status(self, address):
return {}
def test_fixed_ips_get(self):
req = fakes.HTTPRequest.blank('%s/192.168.1.1' % self.url)
req.api_version_request = api_version_request.APIVersionRequest(
self.wsgi_api_version)
res_dict = self.controller.show(req, '192.168.1.1')
response = {'fixed_ip': {'cidr': '192.168.1.0/24',
'hostname': None,
'host': None,
'address': '192.168.1.1'}}
response['fixed_ip'].update(self._get_reserved_status('192.168.1.1'))
self.assertEqual(response, res_dict, self.wsgi_api_version)
def test_fixed_ips_get_bad_ip_fail(self):
req = fakes.HTTPRequest.blank('%s/10.0.0.1' % self.url)
self.assertRaises(webob.exc.HTTPNotFound, self.controller.show, req,
'10.0.0.1')
def test_fixed_ips_get_invalid_ip_address(self):
req = fakes.HTTPRequest.blank('%s/inv.ali.d.ip' % self.url)
self.assertRaises(webob.exc.HTTPBadRequest, self.controller.show, req,
'inv.ali.d.ip')
def test_fixed_ips_get_deleted_ip_fail(self):
req = fakes.HTTPRequest.blank('%s/10.0.0.2' % self.url)
self.assertRaises(webob.exc.HTTPNotFound, self.controller.show, req,
'10.0.0.2')
def test_fixed_ip_reserve(self):
fake_fixed_ips[0]['reserved'] = False
body = {'reserve': None}
req = fakes.HTTPRequest.blank('%s/192.168.1.1/action' % self.url)
action = self._get_reserve_action()
result = action(req, "192.168.1.1", body=body)
self._assert_equal(result or action, 202)
self.assertTrue(fake_fixed_ips[0]['reserved'])
def test_fixed_ip_reserve_bad_ip(self):
body = {'reserve': None}
req = fakes.HTTPRequest.blank('%s/10.0.0.1/action' % self.url)
action = self._get_reserve_action()
self.assertRaises(webob.exc.HTTPNotFound, action, req,
'10.0.0.1', body=body)
def test_fixed_ip_reserve_invalid_ip_address(self):
body = {'reserve': None}
req = fakes.HTTPRequest.blank('%s/inv.ali.d.ip/action' % self.url)
action = self._get_reserve_action()
self.assertRaises(webob.exc.HTTPBadRequest,
action, req, 'inv.ali.d.ip', body=body)
def test_fixed_ip_reserve_deleted_ip(self):
body = {'reserve': None}
action = self._get_reserve_action()
req = fakes.HTTPRequest.blank('%s/10.0.0.2/action' % self.url)
self.assertRaises(webob.exc.HTTPNotFound, action, req,
'10.0.0.2', body=body)
def test_fixed_ip_unreserve(self):
fake_fixed_ips[0]['reserved'] = True
body = {'unreserve': None}
req = fakes.HTTPRequest.blank('%s/192.168.1.1/action' % self.url)
action = self._get_unreserve_action()
result = action(req, "192.168.1.1", body=body)
self._assert_equal(result or action, 202)
self.assertFalse(fake_fixed_ips[0]['reserved'])
def test_fixed_ip_unreserve_bad_ip(self):
body = {'unreserve': None}
req = fakes.HTTPRequest.blank('%s/10.0.0.1/action' % self.url)
action = self._get_unreserve_action()
self.assertRaises(webob.exc.HTTPNotFound, action, req,
'10.0.0.1', body=body)
def test_fixed_ip_unreserve_invalid_ip_address(self):
body = {'unreserve': None}
req = fakes.HTTPRequest.blank('%s/inv.ali.d.ip/action' % self.url)
action = self._get_unreserve_action()
self.assertRaises(webob.exc.HTTPBadRequest,
action, req, 'inv.ali.d.ip', body=body)
def test_fixed_ip_unreserve_deleted_ip(self):
body = {'unreserve': None}
req = fakes.HTTPRequest.blank('%s/10.0.0.2/action' % self.url)
action = self._get_unreserve_action()
self.assertRaises(webob.exc.HTTPNotFound, action, req,
'10.0.0.2', body=body)
class FixedIpTestV24(FixedIpTestV21):
wsgi_api_version = '2.4'
def _get_reserved_status(self, address):
for fixed_ip in fake_fixed_ips:
if address == fixed_ip['address']:
return {'reserved': fixed_ip['reserved']}
self.fail('Invalid address: %s' % address)
class FixedIpDeprecationTest(test.NoDBTestCase):
def setUp(self):
super(FixedIpDeprecationTest, self).setUp()
self.req = fakes.HTTPRequest.blank('', version='2.36')
self.controller = fixed_ips_v21.FixedIPController()
def test_all_apis_return_not_found(self):
self.assertRaises(exception.VersionNotFoundForAPIMethod,
self.controller.show, self.req, fakes.FAKE_UUID)
self.assertRaises(exception.VersionNotFoundForAPIMethod,
self.controller.reserve, self.req, fakes.FAKE_UUID, {})
self.assertRaises(exception.VersionNotFoundForAPIMethod,
self.controller.unreserve, self.req, fakes.FAKE_UUID, {})

View File

@@ -39,7 +39,6 @@ policy_data = """
"os_compute_api:ips:index": "",
"os_compute_api:ips:show": "",
"os_compute_api:extensions": "",
"os_compute_api:os-fixed-ips": "",
"os_compute_api:os-flavor-access:remove_tenant_access": "",
"os_compute_api:os-flavor-access:add_tenant_access": "",
"os_compute_api:os-flavor-extra-specs:index": "",

View File

@@ -302,7 +302,6 @@ class RealRolePolicyTestCase(test.NoDBTestCase):
"os_compute_api:os-cells:sync_instances",
"os_compute_api:os-evacuate",
"os_compute_api:os-extended-server-attributes",
"os_compute_api:os-fixed-ips",
"os_compute_api:os-flavor-access:remove_tenant_access",
"os_compute_api:os-flavor-access:add_tenant_access",
"os_compute_api:os-flavor-extra-specs:create",

View File

@@ -9,6 +9,9 @@ upgrade:
* ``GET /os-fping``
* ``GET /os-fping/{server_id}``
* ``GET /servers/{server_id}/os-virtual-interfaces``
* ``GET /os-fixed-ips/{fixed_ip}``
* ``POST /os-fixed-ips/{fixed_ip}/action (reserve)``
* ``POST /os-fixed-ips/{fixed_ip}/action (unreserve)``
In addition, the following configuration options have been removed.