Merge "Remove '/os-tenant-networks' REST API"
This commit is contained in:
commit
bf10180e64
|
@ -1,10 +1,8 @@
|
|||
.. -*- rst -*-
|
||||
.. NOTE(gmann): These APIs are deprecated so do not update this
|
||||
file even body, example or parameters are not complete.
|
||||
|
||||
===================================================
|
||||
====================================================
|
||||
Project networks (os-tenant-networks) (DEPRECATED)
|
||||
===================================================
|
||||
====================================================
|
||||
|
||||
.. warning::
|
||||
|
||||
|
@ -57,7 +55,8 @@ through the ``policy.json`` file.
|
|||
|
||||
Normal response codes: 200
|
||||
|
||||
Error response codes: badRequest(400), unauthorized(401), forbidden(403), conflict(409), serviceUnavailable(503)
|
||||
Error response codes: badRequest(400), unauthorized(401), forbidden(403),
|
||||
conflict(409), gone(410), serviceUnavailable(503)
|
||||
|
||||
**Example Create Project Network: JSON request**
|
||||
|
||||
|
@ -121,7 +120,8 @@ can change these permissions through the ``policy.json`` file.
|
|||
|
||||
Normal response codes: 202
|
||||
|
||||
Error response codes: unauthorized(401), forbidden(403), itemNotFound(404), conflict(409)
|
||||
Error response codes: unauthorized(401), forbidden(403), itemNotFound(404),
|
||||
conflict(409), gone(410)
|
||||
|
||||
Request
|
||||
-------
|
||||
|
|
|
@ -1,14 +1,9 @@
|
|||
{
|
||||
"networks": [
|
||||
{
|
||||
"cidr": "10.0.0.0/29",
|
||||
"id": "616fb98f-46ca-475e-917e-2563e5a8cd19",
|
||||
"label": "test_0"
|
||||
},
|
||||
{
|
||||
"cidr": "10.0.0.8/29",
|
||||
"id": "616fb98f-46ca-475e-917e-2563e5a8cd20",
|
||||
"label": "test_1"
|
||||
"cidr": "None",
|
||||
"id": "3cb9bc59-5699-4588-a4b1-b87f96708bc6",
|
||||
"label": "private"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
@ -441,6 +441,12 @@ API endpoints as below::
|
|||
release. On deployments newer than this, some endpoints of the API will
|
||||
return HTTP 410 (Gone) regadless of the requested microversion.
|
||||
|
||||
.. versionchanged:: 21.0.0
|
||||
|
||||
The ``os-tenant-networks`` API was partially removed in the 21.0.0 (Ussuri)
|
||||
release. On deployments newer than this, some endpoints of the API will
|
||||
return HTTP 410 (Gone) regadless of the requested microversion.
|
||||
|
||||
2.37
|
||||
----
|
||||
|
||||
|
|
|
@ -1,44 +0,0 @@
|
|||
# Copyright 2015 NEC 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
|
||||
|
||||
create = {
|
||||
'type': 'object',
|
||||
'properties': {
|
||||
'network': {
|
||||
'type': 'object',
|
||||
'properties': {
|
||||
'label': {
|
||||
'type': 'string', 'maxLength': 255
|
||||
},
|
||||
'ipam': parameter_types.boolean,
|
||||
'cidr': parameter_types.cidr,
|
||||
'cidr_v6': parameter_types.cidr,
|
||||
'vlan_start': parameter_types.positive_integer_with_empty_str,
|
||||
'network_size':
|
||||
parameter_types.positive_integer_with_empty_str,
|
||||
'num_networks': parameter_types.positive_integer_with_empty_str
|
||||
},
|
||||
'required': ['label'],
|
||||
'oneOf': [
|
||||
{'required': ['cidr']},
|
||||
{'required': ['cidr_v6']}
|
||||
],
|
||||
'additionalProperties': False,
|
||||
},
|
||||
},
|
||||
'required': ['network'],
|
||||
'additionalProperties': False,
|
||||
}
|
|
@ -13,24 +13,17 @@
|
|||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
|
||||
import netaddr
|
||||
import netaddr.core as netexc
|
||||
from oslo_log import log as logging
|
||||
import six
|
||||
from webob import exc
|
||||
|
||||
from nova.api.openstack.api_version_request \
|
||||
import MAX_PROXY_API_SUPPORT_VERSION
|
||||
from nova.api.openstack.compute.schemas import tenant_networks as schema
|
||||
from nova.api.openstack import wsgi
|
||||
from nova.api import validation
|
||||
import nova.conf
|
||||
from nova import context as nova_context
|
||||
from nova import exception
|
||||
from nova.i18n import _
|
||||
import nova.network
|
||||
from nova import objects
|
||||
from nova.policies import tenant_networks as tn_policies
|
||||
from nova import quota
|
||||
|
||||
|
@ -97,86 +90,13 @@ class TenantNetworkController(wsgi.Controller):
|
|||
raise exc.HTTPNotFound(explanation=msg)
|
||||
return {'network': network_dict(network)}
|
||||
|
||||
@wsgi.Controller.api_version("2.1", MAX_PROXY_API_SUPPORT_VERSION)
|
||||
@wsgi.expected_errors((403, 404, 409))
|
||||
@wsgi.response(202)
|
||||
@wsgi.expected_errors(410)
|
||||
def delete(self, req, id):
|
||||
context = req.environ['nova.context']
|
||||
context.can(tn_policies.BASE_POLICY_NAME)
|
||||
raise exc.HTTPGone()
|
||||
|
||||
try:
|
||||
self.network_api.disassociate(context, id)
|
||||
self.network_api.delete(context, id)
|
||||
except exception.PolicyNotAuthorized as e:
|
||||
raise exc.HTTPForbidden(explanation=six.text_type(e))
|
||||
except exception.NetworkInUse as e:
|
||||
raise exc.HTTPConflict(explanation=e.format_message())
|
||||
except exception.NetworkNotFound:
|
||||
msg = _("Network not found")
|
||||
raise exc.HTTPNotFound(explanation=msg)
|
||||
|
||||
@wsgi.Controller.api_version("2.1", MAX_PROXY_API_SUPPORT_VERSION)
|
||||
@wsgi.expected_errors((400, 403, 409, 503))
|
||||
@validation.schema(schema.create)
|
||||
@wsgi.expected_errors(410)
|
||||
def create(self, req, body):
|
||||
context = req.environ["nova.context"]
|
||||
context.can(tn_policies.BASE_POLICY_NAME)
|
||||
|
||||
network = body["network"]
|
||||
keys = ["cidr", "cidr_v6", "ipam", "vlan_start", "network_size",
|
||||
"num_networks"]
|
||||
kwargs = {k: network.get(k) for k in keys}
|
||||
|
||||
label = network["label"]
|
||||
|
||||
if kwargs["cidr"]:
|
||||
try:
|
||||
net = netaddr.IPNetwork(kwargs["cidr"])
|
||||
if net.size < 4:
|
||||
msg = _("Requested network does not contain "
|
||||
"enough (2+) usable hosts")
|
||||
raise exc.HTTPBadRequest(explanation=msg)
|
||||
except netexc.AddrConversionError:
|
||||
msg = _("Address could not be converted.")
|
||||
raise exc.HTTPBadRequest(explanation=msg)
|
||||
|
||||
try:
|
||||
if CONF.enable_network_quota:
|
||||
objects.Quotas.check_deltas(context, {'networks': 1},
|
||||
context.project_id)
|
||||
except exception.OverQuota:
|
||||
msg = _("Quota exceeded, too many networks.")
|
||||
raise exc.HTTPForbidden(explanation=msg)
|
||||
|
||||
kwargs['project_id'] = context.project_id
|
||||
|
||||
try:
|
||||
networks = self.network_api.create(context,
|
||||
label=label, **kwargs)
|
||||
except exception.PolicyNotAuthorized as e:
|
||||
raise exc.HTTPForbidden(explanation=six.text_type(e))
|
||||
except exception.CidrConflict as e:
|
||||
raise exc.HTTPConflict(explanation=e.format_message())
|
||||
except Exception:
|
||||
msg = _("Create networks failed")
|
||||
LOG.exception(msg, extra=network)
|
||||
raise exc.HTTPServiceUnavailable(explanation=msg)
|
||||
|
||||
# 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 CONF.enable_network_quota:
|
||||
try:
|
||||
objects.Quotas.check_deltas(context, {'networks': 0},
|
||||
context.project_id)
|
||||
except exception.OverQuota:
|
||||
self.network_api.delete(context,
|
||||
network_dict(networks[0])['id'])
|
||||
msg = _("Quota exceeded, too many networks.")
|
||||
raise exc.HTTPForbidden(explanation=msg)
|
||||
|
||||
return {"network": network_dict(networks[0])}
|
||||
raise exc.HTTPGone()
|
||||
|
||||
|
||||
def _network_count(context, project_id):
|
||||
|
|
|
@ -250,13 +250,6 @@ non_negative_integer = {
|
|||
'pattern': '^[0-9]*$', 'minimum': 0, 'minLength': 1
|
||||
}
|
||||
|
||||
# This only be used by nova-network specific APIs. It will be removed when
|
||||
# those API removed.
|
||||
positive_integer_with_empty_str = {
|
||||
'type': ['integer', 'string'],
|
||||
'pattern': '^[0-9]*$', 'minimum': 1,
|
||||
}
|
||||
|
||||
hostname = {
|
||||
'type': 'string', 'minLength': 1, 'maxLength': 255,
|
||||
# NOTE: 'host' is defined in "services" table, and that
|
||||
|
|
|
@ -34,22 +34,10 @@ deprecated.""",
|
|||
'method': 'GET',
|
||||
'path': '/os-tenant-networks'
|
||||
},
|
||||
|
||||
{
|
||||
'method': 'POST',
|
||||
'path': '/os-tenant-networks'
|
||||
},
|
||||
|
||||
{
|
||||
'method': 'GET',
|
||||
'path': '/os-tenant-networks/{network_id}'
|
||||
},
|
||||
|
||||
{
|
||||
'method': 'DELETE',
|
||||
'path': '/os-tenant-networks/{network_id}'
|
||||
}
|
||||
|
||||
]),
|
||||
]
|
||||
|
||||
|
|
|
@ -1,14 +1,9 @@
|
|||
{
|
||||
"networks": [
|
||||
{
|
||||
"cidr": "10.0.0.0/29",
|
||||
"id": "%(id)s",
|
||||
"label": "test_0"
|
||||
},
|
||||
{
|
||||
"cidr": "10.0.0.8/29",
|
||||
"id": "%(id)s",
|
||||
"label": "test_1"
|
||||
"cidr": "None",
|
||||
"id": "%(uuid)s",
|
||||
"label": "private"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
@ -1,9 +0,0 @@
|
|||
{
|
||||
"network": {
|
||||
"label": "public",
|
||||
"cidr": "172.0.0.0/24",
|
||||
"vlan_start": 1,
|
||||
"num_networks": 1,
|
||||
"network_size": 255
|
||||
}
|
||||
}
|
|
@ -1,7 +0,0 @@
|
|||
{
|
||||
"network": {
|
||||
"cidr": "172.0.0.0/24",
|
||||
"id": "%(id)s",
|
||||
"label": "public"
|
||||
}
|
||||
}
|
|
@ -13,52 +13,24 @@
|
|||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
|
||||
from oslo_serialization import jsonutils
|
||||
|
||||
import nova.conf
|
||||
from nova.tests import fixtures as nova_fixtures
|
||||
from nova.tests.functional.api_sample_tests import api_sample_base
|
||||
|
||||
CONF = nova.conf.CONF
|
||||
|
||||
|
||||
# TODO(stephenfin): Remove the parts of this test that are nova-network only
|
||||
class TenantNetworksJsonTests(api_sample_base.ApiSampleTestBaseV21):
|
||||
USE_NEUTRON = False # partially nova-net only
|
||||
ADMIN_API = True
|
||||
sample_dir = "os-tenant-networks"
|
||||
|
||||
def setUp(self):
|
||||
super(TenantNetworksJsonTests, self).setUp()
|
||||
CONF.set_override("enable_network_quota", True)
|
||||
self.useFixture(nova_fixtures.RegisterNetworkQuota())
|
||||
|
||||
def fake(*args, **kwargs):
|
||||
pass
|
||||
|
||||
self.stub_out("nova.quota.QUOTAS.reserve", fake)
|
||||
self.stub_out("nova.quota.QUOTAS.commit", fake)
|
||||
self.stub_out("nova.quota.QUOTAS.rollback", fake)
|
||||
self.stub_out("nova.quota.QuotaEngine.reserve", fake)
|
||||
self.stub_out("nova.quota.QuotaEngine.commit", fake)
|
||||
self.stub_out("nova.quota.QuotaEngine.rollback", fake)
|
||||
|
||||
# TODO(stephenfin): Rework this to work with neutron
|
||||
def test_list_networks(self):
|
||||
response = self._do_get('os-tenant-networks')
|
||||
self._verify_response('networks-list-res', {}, response, 200)
|
||||
|
||||
# TODO(stephenfin): Remove this API since it's nova-network only
|
||||
def test_create_network(self):
|
||||
response = self._do_post('os-tenant-networks', "networks-post-req", {})
|
||||
self._verify_response('networks-post-res', {}, response, 200)
|
||||
self.api.api_post('os-tenant-networks', {},
|
||||
check_response_status=[410])
|
||||
|
||||
# TODO(stephenfin): Remove this API since it's nova-network only
|
||||
def test_delete_network(self):
|
||||
response = self._do_post('os-tenant-networks', "networks-post-req", {})
|
||||
net = jsonutils.loads(response.content)
|
||||
response = self._do_delete('os-tenant-networks/%s' %
|
||||
net["network"]["id"])
|
||||
self.assertEqual(202, response.status_code)
|
||||
self.assertEqual("", response.text)
|
||||
self.api.api_delete('os-tenant-networks/1',
|
||||
check_response_status=[410])
|
||||
|
|
|
@ -64,15 +64,14 @@ def fake_network_api_get_all(context):
|
|||
class TenantNetworksTestV21(test.NoDBTestCase):
|
||||
ctrlr = networks_v21.TenantNetworkController
|
||||
validation_error = exception.ValidationError
|
||||
use_neutron = False
|
||||
|
||||
def setUp(self):
|
||||
# TODO(stephenfin): We should probably use NeutronFixture here
|
||||
super(TenantNetworksTestV21, self).setUp()
|
||||
# os-tenant-networks only supports Neutron when listing networks or
|
||||
# showing details about a network, create and delete operations
|
||||
# result in a 503 and 500 response, respectively.
|
||||
self.flags(enable_network_quota=True,
|
||||
use_neutron=self.use_neutron)
|
||||
self.flags(enable_network_quota=True)
|
||||
self.useFixture(nova_fixtures.RegisterNetworkQuota())
|
||||
self.controller = self.ctrlr()
|
||||
self.req = fakes.HTTPRequest.blank('')
|
||||
|
@ -83,63 +82,6 @@ class TenantNetworksTestV21(test.NoDBTestCase):
|
|||
CONF.set_override("use_neutron_default_nets", self.original_value,
|
||||
group='api')
|
||||
|
||||
def _fake_network_api_create(self, context, **kwargs):
|
||||
self.assertEqual(context.project_id, kwargs['project_id'])
|
||||
return NETWORKS
|
||||
|
||||
@mock.patch('nova.network.api.API.disassociate')
|
||||
@mock.patch('nova.network.api.API.delete')
|
||||
def _test_network_delete_exception(self, delete_ex, disassociate_ex, expex,
|
||||
delete_mock, disassociate_mock):
|
||||
ctxt = self.req.environ['nova.context']
|
||||
|
||||
if delete_mock:
|
||||
delete_mock.side_effect = delete_ex
|
||||
if disassociate_ex:
|
||||
disassociate_mock.side_effect = disassociate_ex
|
||||
|
||||
if self.use_neutron:
|
||||
expex = webob.exc.HTTPInternalServerError
|
||||
self.assertRaises(expex, self.controller.delete, self.req, 1)
|
||||
|
||||
if not self.use_neutron:
|
||||
disassociate_mock.assert_called_once_with(ctxt, 1)
|
||||
if not disassociate_ex:
|
||||
delete_mock.assert_called_once_with(ctxt, 1)
|
||||
|
||||
def test_network_delete_exception_network_not_found(self):
|
||||
ex = exception.NetworkNotFound(network_id=1)
|
||||
expex = webob.exc.HTTPNotFound
|
||||
self._test_network_delete_exception(None, ex, expex)
|
||||
|
||||
def test_network_delete_exception_policy_failed(self):
|
||||
ex = exception.PolicyNotAuthorized(action='dummy')
|
||||
expex = webob.exc.HTTPForbidden
|
||||
self._test_network_delete_exception(ex, None, expex)
|
||||
|
||||
def test_network_delete_exception_network_in_use(self):
|
||||
ex = exception.NetworkInUse(network_id=1)
|
||||
expex = webob.exc.HTTPConflict
|
||||
self._test_network_delete_exception(ex, None, expex)
|
||||
|
||||
@mock.patch('nova.network.api.API.delete')
|
||||
@mock.patch('nova.network.api.API.disassociate')
|
||||
def test_network_delete(self, disassociate_mock, delete_mock):
|
||||
ctxt = self.req.environ['nova.context']
|
||||
|
||||
delete_method = self.controller.delete
|
||||
res = delete_method(self.req, 1)
|
||||
# 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, networks_v21.TenantNetworkController):
|
||||
status_int = delete_method.wsgi_code
|
||||
else:
|
||||
status_int = res.status_int
|
||||
self.assertEqual(202, status_int)
|
||||
|
||||
disassociate_mock.assert_called_once_with(ctxt, 1)
|
||||
delete_mock.assert_called_once_with(ctxt, 1)
|
||||
|
||||
def test_network_show(self):
|
||||
with mock.patch.object(self.controller.network_api, 'get',
|
||||
return_value=NETWORKS[0]):
|
||||
|
@ -173,155 +115,6 @@ class TenantNetworksTestV21(test.NoDBTestCase):
|
|||
def test_network_index_without_default_net(self):
|
||||
self._test_network_index(default_net=False)
|
||||
|
||||
@mock.patch('nova.objects.Quotas.check_deltas')
|
||||
@mock.patch('nova.network.api.API.create')
|
||||
def test_network_create(self, create_mock, check_mock):
|
||||
create_mock.side_effect = self._fake_network_api_create
|
||||
|
||||
body = copy.deepcopy(NETWORKS[0])
|
||||
del body['id']
|
||||
body = {'network': body}
|
||||
res = self.controller.create(self.req, body=body)
|
||||
|
||||
self.assertEqual(NETWORKS[0], res['network'])
|
||||
|
||||
@mock.patch('nova.objects.Quotas.check_deltas')
|
||||
@mock.patch('nova.network.api.API.delete')
|
||||
@mock.patch('nova.network.api.API.create')
|
||||
def test_network_create_quota_error_during_recheck(self, create_mock,
|
||||
delete_mock,
|
||||
check_mock):
|
||||
create_mock.side_effect = self._fake_network_api_create
|
||||
ctxt = self.req.environ['nova.context']
|
||||
|
||||
# Simulate a race where the first check passes and the recheck fails.
|
||||
check_mock.side_effect = [None, exception.OverQuota(overs='networks')]
|
||||
|
||||
body = copy.deepcopy(NETWORKS[0])
|
||||
del body['id']
|
||||
body = {'network': body}
|
||||
self.assertRaises(webob.exc.HTTPForbidden,
|
||||
self.controller.create, self.req, body=body)
|
||||
|
||||
self.assertEqual(2, check_mock.call_count)
|
||||
call1 = mock.call(ctxt, {'networks': 1}, ctxt.project_id)
|
||||
call2 = mock.call(ctxt, {'networks': 0}, ctxt.project_id)
|
||||
check_mock.assert_has_calls([call1, call2])
|
||||
|
||||
# Verify we removed the network that was added after the first quota
|
||||
# check passed.
|
||||
delete_mock.assert_called_once_with(ctxt, NETWORKS[0]['id'])
|
||||
|
||||
@mock.patch('nova.objects.Quotas.check_deltas')
|
||||
@mock.patch('nova.network.api.API.create')
|
||||
def test_network_create_no_quota_recheck(self, create_mock, check_mock):
|
||||
create_mock.side_effect = self._fake_network_api_create
|
||||
ctxt = self.req.environ['nova.context']
|
||||
# Disable recheck_quota.
|
||||
self.flags(recheck_quota=False, group='quota')
|
||||
|
||||
body = copy.deepcopy(NETWORKS[0])
|
||||
del body['id']
|
||||
body = {'network': body}
|
||||
self.controller.create(self.req, body=body)
|
||||
|
||||
# check_deltas should have been called only once.
|
||||
check_mock.assert_called_once_with(ctxt, {'networks': 1},
|
||||
ctxt.project_id)
|
||||
|
||||
@mock.patch('nova.objects.Quotas.check_deltas')
|
||||
def test_network_create_quota_error(self, check_mock):
|
||||
ctxt = self.req.environ['nova.context']
|
||||
|
||||
check_mock.side_effect = exception.OverQuota(overs='networks')
|
||||
body = {'network': {"cidr": "10.20.105.0/24",
|
||||
"label": "new net 1"}}
|
||||
self.assertRaises(webob.exc.HTTPForbidden,
|
||||
self.controller.create, self.req, body=body)
|
||||
check_mock.assert_called_once_with(ctxt, {'networks': 1},
|
||||
ctxt.project_id)
|
||||
|
||||
@mock.patch('nova.objects.Quotas.check_deltas')
|
||||
@mock.patch('nova.network.api.API.create')
|
||||
def _test_network_create_exception(self, ex, expex, create_mock,
|
||||
check_mock):
|
||||
ctxt = self.req.environ['nova.context']
|
||||
|
||||
create_mock.side_effect = ex
|
||||
body = {'network': {"cidr": "10.20.105.0/24",
|
||||
"label": "new net 1"}}
|
||||
if self.use_neutron:
|
||||
expex = webob.exc.HTTPServiceUnavailable
|
||||
self.assertRaises(expex, self.controller.create, self.req, body=body)
|
||||
check_mock.assert_called_once_with(ctxt, {'networks': 1},
|
||||
ctxt.project_id)
|
||||
|
||||
def test_network_create_exception_policy_failed(self):
|
||||
ex = exception.PolicyNotAuthorized(action='dummy')
|
||||
expex = webob.exc.HTTPForbidden
|
||||
self._test_network_create_exception(ex, expex)
|
||||
|
||||
def test_network_create_exception_conflictcidr(self):
|
||||
ex = exception.CidrConflict(cidr='dummy', other='dummy')
|
||||
expex = webob.exc.HTTPConflict
|
||||
self._test_network_create_exception(ex, expex)
|
||||
|
||||
def test_network_create_exception_service_unavailable(self):
|
||||
ex = Exception
|
||||
expex = webob.exc.HTTPServiceUnavailable
|
||||
self._test_network_create_exception(ex, expex)
|
||||
|
||||
def test_network_create_empty_body(self):
|
||||
self.assertRaises(exception.ValidationError,
|
||||
self.controller.create, self.req, body={})
|
||||
|
||||
def test_network_create_without_cidr(self):
|
||||
body = {'network': {"label": "new net 1"}}
|
||||
self.assertRaises(self.validation_error,
|
||||
self.controller.create, self.req, body=body)
|
||||
|
||||
def test_network_create_bad_format_cidr(self):
|
||||
body = {'network': {"cidr": "123",
|
||||
"label": "new net 1"}}
|
||||
self.assertRaises(self.validation_error,
|
||||
self.controller.create, self.req, body=body)
|
||||
|
||||
def test_network_create_empty_network(self):
|
||||
body = {'network': {}}
|
||||
self.assertRaises(self.validation_error,
|
||||
self.controller.create, self.req, body=body)
|
||||
|
||||
def test_network_create_without_label(self):
|
||||
body = {'network': {"cidr": "10.20.105.0/24"}}
|
||||
self.assertRaises(self.validation_error,
|
||||
self.controller.create, self.req, body=body)
|
||||
|
||||
|
||||
class TenantNeutronNetworksTestV21(TenantNetworksTestV21):
|
||||
use_neutron = True
|
||||
|
||||
def test_network_create(self):
|
||||
self.assertRaises(
|
||||
webob.exc.HTTPServiceUnavailable,
|
||||
super(TenantNeutronNetworksTestV21, self).test_network_create)
|
||||
|
||||
def test_network_create_quota_error_during_recheck(self):
|
||||
self.assertRaises(
|
||||
webob.exc.HTTPServiceUnavailable,
|
||||
super(TenantNeutronNetworksTestV21, self)
|
||||
.test_network_create_quota_error_during_recheck)
|
||||
|
||||
def test_network_create_no_quota_recheck(self):
|
||||
self.assertRaises(
|
||||
webob.exc.HTTPServiceUnavailable,
|
||||
super(TenantNeutronNetworksTestV21, self)
|
||||
.test_network_create_no_quota_recheck)
|
||||
|
||||
def test_network_delete(self):
|
||||
self.assertRaises(
|
||||
webob.exc.HTTPInternalServerError,
|
||||
super(TenantNeutronNetworksTestV21, self).test_network_delete)
|
||||
|
||||
|
||||
class TenantNetworksEnforcementV21(test.NoDBTestCase):
|
||||
|
||||
|
@ -330,18 +123,6 @@ class TenantNetworksEnforcementV21(test.NoDBTestCase):
|
|||
self.controller = networks_v21.TenantNetworkController()
|
||||
self.req = fakes.HTTPRequest.blank('')
|
||||
|
||||
def test_create_policy_failed(self):
|
||||
rule_name = 'os_compute_api:os-tenant-networks'
|
||||
self.policy.set_rules({rule_name: "project:non_fake"})
|
||||
exc = self.assertRaises(
|
||||
exception.PolicyNotAuthorized,
|
||||
self.controller.create,
|
||||
self.req, body={'network': {'label': 'test',
|
||||
'cidr': '10.0.0.0/32'}})
|
||||
self.assertEqual(
|
||||
"Policy doesn't allow %s to be performed." % rule_name,
|
||||
exc.format_message())
|
||||
|
||||
def test_index_policy_failed(self):
|
||||
rule_name = 'os_compute_api:os-tenant-networks'
|
||||
self.policy.set_rules({rule_name: "project:non_fake"})
|
||||
|
@ -353,17 +134,6 @@ class TenantNetworksEnforcementV21(test.NoDBTestCase):
|
|||
"Policy doesn't allow %s to be performed." % rule_name,
|
||||
exc.format_message())
|
||||
|
||||
def test_delete_policy_failed(self):
|
||||
rule_name = 'os_compute_api:os-tenant-networks'
|
||||
self.policy.set_rules({rule_name: "project:non_fake"})
|
||||
exc = self.assertRaises(
|
||||
exception.PolicyNotAuthorized,
|
||||
self.controller.delete,
|
||||
self.req, fakes.FAKE_UUID)
|
||||
self.assertEqual(
|
||||
"Policy doesn't allow %s to be performed." % rule_name,
|
||||
exc.format_message())
|
||||
|
||||
def test_show_policy_failed(self):
|
||||
rule_name = 'os_compute_api:os-tenant-networks'
|
||||
self.policy.set_rules({rule_name: "project:non_fake"})
|
||||
|
@ -388,7 +158,3 @@ class TenantNetworksDeprecationTest(test.NoDBTestCase):
|
|||
self.controller.index, self.req)
|
||||
self.assertRaises(exception.VersionNotFoundForAPIMethod,
|
||||
self.controller.show, self.req, fakes.FAKE_UUID)
|
||||
self.assertRaises(exception.VersionNotFoundForAPIMethod,
|
||||
self.controller.delete, self.req, fakes.FAKE_UUID)
|
||||
self.assertRaises(exception.VersionNotFoundForAPIMethod,
|
||||
self.controller.create, self.req, {})
|
||||
|
|
|
@ -17,6 +17,8 @@ upgrade:
|
|||
* ``POST /os-networks/{id} (disassociate)``
|
||||
* ``POST /os-networks/{id} (disassociate_host)``
|
||||
* ``POST /os-networks/{id} (disassociate_project)``
|
||||
* ``POST /os-tenant-networks``
|
||||
* ``DELETE /os-tenant-networks``
|
||||
|
||||
The following policies have also been removed.
|
||||
|
||||
|
|
Loading…
Reference in New Issue