Add json-schema for v2.1 fixed-ips
This patch adds json-schema for v2.1 fixed-ips. The json-schame limits the input for actions reserve/unreserve. Also fixed the API sample file at same time and add parameter_type none. Co-Authored-By: Ken'ichi Ohmichi <ken1ohmichi@gmail.com> Change-Id: Id2d0416c3ccc2a50d3cb66bed8747082f98fb194 Closes-Bug: #1438480
This commit is contained in:
parent
739f471264
commit
8423a9cd15
@ -1,3 +1,3 @@
|
||||
{
|
||||
"reserve": "None"
|
||||
"reserve": null
|
||||
}
|
@ -1,3 +1,3 @@
|
||||
{
|
||||
"reserve": "None"
|
||||
"reserve": null
|
||||
}
|
@ -15,8 +15,10 @@
|
||||
import webob
|
||||
import webob.exc
|
||||
|
||||
from nova.api.openstack.compute.schemas.v3 import fixed_ips
|
||||
from nova.api.openstack import extensions
|
||||
from nova.api.openstack import wsgi
|
||||
from nova.api import validation
|
||||
from nova import exception
|
||||
from nova.i18n import _
|
||||
from nova import objects
|
||||
@ -60,6 +62,7 @@ class FixedIPController(wsgi.Controller):
|
||||
|
||||
@wsgi.response(202)
|
||||
@extensions.expected_errors((400, 404))
|
||||
@validation.schema(fixed_ips.reserve)
|
||||
@wsgi.action('reserve')
|
||||
def reserve(self, req, id, body):
|
||||
context = req.environ['nova.context']
|
||||
@ -69,6 +72,7 @@ class FixedIPController(wsgi.Controller):
|
||||
|
||||
@wsgi.response(202)
|
||||
@extensions.expected_errors((400, 404))
|
||||
@validation.schema(fixed_ips.unreserve)
|
||||
@wsgi.action('unreserve')
|
||||
def unreserve(self, req, id, body):
|
||||
context = req.environ['nova.context']
|
||||
|
36
nova/api/openstack/compute/schemas/v3/fixed_ips.py
Normal file
36
nova/api/openstack/compute/schemas/v3/fixed_ips.py
Normal file
@ -0,0 +1,36 @@
|
||||
# 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,
|
||||
}
|
@ -62,6 +62,11 @@ boolean = {
|
||||
}
|
||||
|
||||
|
||||
none = {
|
||||
'enum': ['None', None, {}]
|
||||
}
|
||||
|
||||
|
||||
positive_integer = {
|
||||
'type': ['integer', 'string'],
|
||||
'pattern': '^[0-9]*$', 'minimum': 1
|
||||
|
@ -1,3 +1,3 @@
|
||||
{
|
||||
"reserve": "%(reserve)s"
|
||||
"reserve": null
|
||||
}
|
||||
|
@ -1204,10 +1204,8 @@ class FixedIpJsonTest(ApiSampleTestBaseV2):
|
||||
|
||||
def test_fixed_ip_reserve(self):
|
||||
# Reserve a Fixed IP.
|
||||
project = {'reserve': None}
|
||||
response = self._do_post('os-fixed-ips/192.168.1.1/action',
|
||||
'fixedip-post-req',
|
||||
project)
|
||||
'fixedip-post-req', {})
|
||||
self.assertEqual(response.status_code, 202)
|
||||
self.assertEqual(response.content, "")
|
||||
|
||||
|
@ -1,3 +1,3 @@
|
||||
{
|
||||
"reserve": "%(reserve)s"
|
||||
"reserve": null
|
||||
}
|
||||
|
@ -80,10 +80,8 @@ class FixedIpTest(test_servers.ServersSampleBase):
|
||||
|
||||
def test_fixed_ip_reserve(self):
|
||||
# Reserve a Fixed IP.
|
||||
project = {'reserve': None}
|
||||
response = self._do_post('os-fixed-ips/192.168.1.1/action',
|
||||
'fixedip-post-req',
|
||||
project)
|
||||
'fixedip-post-req', {})
|
||||
self.assertEqual(response.status_code, 202)
|
||||
self.assertEqual(response.content, "")
|
||||
|
||||
|
@ -168,7 +168,7 @@ class FixedIpTestV21(test.NoDBTestCase):
|
||||
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)
|
||||
result = action(req, "192.168.1.1", body=body)
|
||||
|
||||
self._assert_equal(result or action, 202)
|
||||
self.assertEqual(fake_fixed_ips[0]['reserved'], True)
|
||||
@ -179,7 +179,7 @@ class FixedIpTestV21(test.NoDBTestCase):
|
||||
action = self._get_reserve_action()
|
||||
|
||||
self.assertRaises(webob.exc.HTTPNotFound, action, req,
|
||||
'10.0.0.1', body)
|
||||
'10.0.0.1', body=body)
|
||||
|
||||
def test_fixed_ip_reserve_invalid_ip_address(self):
|
||||
body = {'reserve': None}
|
||||
@ -187,7 +187,7 @@ class FixedIpTestV21(test.NoDBTestCase):
|
||||
action = self._get_reserve_action()
|
||||
|
||||
self.assertRaises(webob.exc.HTTPBadRequest,
|
||||
action, req, 'inv.ali.d.ip', body)
|
||||
action, req, 'inv.ali.d.ip', body=body)
|
||||
|
||||
def test_fixed_ip_reserve_deleted_ip(self):
|
||||
body = {'reserve': None}
|
||||
@ -195,14 +195,14 @@ class FixedIpTestV21(test.NoDBTestCase):
|
||||
|
||||
req = fakes.HTTPRequest.blank('%s/10.0.0.2/action' % self.url)
|
||||
self.assertRaises(webob.exc.HTTPNotFound, action, req,
|
||||
'10.0.0.2', body)
|
||||
'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)
|
||||
result = action(req, "192.168.1.1", body=body)
|
||||
|
||||
self._assert_equal(result or action, 202)
|
||||
self.assertEqual(fake_fixed_ips[0]['reserved'], False)
|
||||
@ -213,21 +213,21 @@ class FixedIpTestV21(test.NoDBTestCase):
|
||||
action = self._get_unreserve_action()
|
||||
|
||||
self.assertRaises(webob.exc.HTTPNotFound, action, req,
|
||||
'10.0.0.1', body)
|
||||
'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)
|
||||
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)
|
||||
'10.0.0.2', body=body)
|
||||
|
||||
|
||||
class FixedIpTestV2(FixedIpTestV21):
|
||||
|
@ -621,6 +621,47 @@ class NameTestCase(APIValidationTestCase):
|
||||
pass
|
||||
|
||||
|
||||
class NoneTypeTestCase(APIValidationTestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(NoneTypeTestCase, self).setUp()
|
||||
schema = {
|
||||
'type': 'object',
|
||||
'properties': {
|
||||
'foo': parameter_types.none
|
||||
}
|
||||
}
|
||||
|
||||
@validation.schema(request_body_schema=schema)
|
||||
def post(req, body):
|
||||
return 'Validation succeeded.'
|
||||
|
||||
self.post = post
|
||||
|
||||
def test_validate_none(self):
|
||||
self.assertEqual('Validation succeeded.',
|
||||
self.post(body={'foo': 'None'},
|
||||
req=FakeRequest()))
|
||||
self.assertEqual('Validation succeeded.',
|
||||
self.post(body={'foo': None},
|
||||
req=FakeRequest()))
|
||||
self.assertEqual('Validation succeeded.',
|
||||
self.post(body={'foo': {}},
|
||||
req=FakeRequest()))
|
||||
|
||||
def test_validate_none_fails(self):
|
||||
detail = ("Invalid input for field/attribute foo. Value: ."
|
||||
" '' is not one of ['None', None, {}]")
|
||||
self.check_validation_error(self.post, body={'foo': ''},
|
||||
expected_detail=detail)
|
||||
|
||||
detail = ("Invalid input for field/attribute foo. Value: "
|
||||
"{'key': 'val'}. {'key': 'val'} is not one of "
|
||||
"['None', None, {}]")
|
||||
self.check_validation_error(self.post, body={'foo': {'key': 'val'}},
|
||||
expected_detail=detail)
|
||||
|
||||
|
||||
class TcpUdpPortTestCase(APIValidationTestCase):
|
||||
|
||||
def setUp(self):
|
||||
|
Loading…
x
Reference in New Issue
Block a user