Add API validation schema for cloudpipe api

Add API schema to validation, require project_id need to be uuid formate.

Partially implements blueprint v2-on-v3-api
Change-Id: I9d95229d9391b419fe633b5b9e6f06f68289d3a0
This commit is contained in:
Eli Qiao 2014-10-17 16:58:00 +08:00
parent 660588bf56
commit 6120c2a2d3
6 changed files with 52 additions and 21 deletions

View File

@ -1,5 +1,5 @@
{
"cloudpipe": {
"project_id": "cloudpipe-059f21e3-c20e-4efc-9e7a-eba2ab3c6f9a"
"project_id": "059f21e3-c20e-4efc-9e7a-eba2ab3c6f9a"
}
}
}

View File

@ -4,10 +4,10 @@
"created_at": "2012-11-27T17:18:01Z",
"instance_id": "27deecdb-baa3-4a26-9c82-32994b815b01",
"internal_ip": "192.168.0.3",
"project_id": "cloudpipe-fa1765bd-a352-49c7-a6b7-8ee108a3cb0c",
"project_id": "fa1765bd-a352-49c7-a6b7-8ee108a3cb0c",
"public_ip": "127.0.0.1",
"public_port": 22,
"state": "down"
}
]
}
}

View File

@ -110,6 +110,7 @@ class CloudpipeController(wsgi.Controller):
return rv
@extensions.expected_errors((400, 403))
@validation.schema(cloudpipe.create)
def create(self, req, body):
"""Create a new cloudpipe instance, if none exists.

View File

@ -15,6 +15,21 @@
from nova.api.validation import parameter_types
create = {
'type': 'object',
'properties': {
'cloudpipe': {
'type': 'object',
'properties': {
'project_id': parameter_types.project_id,
},
'additionalProperties': False,
},
},
'required': ['cloudpipe'],
'additionalProperties': False,
}
update = {
'type': 'object',
'properties': {

View File

@ -13,13 +13,15 @@
# License for the specific language governing permissions and limitations
# under the License.
import uuid as uuid_lib
from lxml import etree
from oslo.config import cfg
from oslo.utils import timeutils
from webob import exc
from nova.api.openstack.compute.contrib import cloudpipe as cloudpipe_v2
from nova.api.openstack.compute.contrib import cloudpipe as cloudpipe_v21
from nova.api.openstack.compute.plugins.v3 import cloudpipe as cloudpipe_v21
from nova.api.openstack import wsgi
from nova.compute import utils as compute_utils
from nova import exception
@ -33,11 +35,15 @@ CONF = cfg.CONF
CONF.import_opt('vpn_image_id', 'nova.cloudpipe.pipelib')
project_id = str(uuid_lib.uuid4().hex)
uuid = str(uuid_lib.uuid4())
def fake_vpn_instance():
return {
'id': 7, 'image_ref': CONF.vpn_image_id, 'vm_state': 'active',
'created_at': timeutils.parse_strtime('1981-10-20T00:00:00.000000'),
'uuid': 7777, 'project_id': 'other',
'uuid': uuid, 'project_id': project_id,
}
@ -75,15 +81,15 @@ class CloudpipeTestV21(test.NoDBTestCase):
compute_api_get_all)
req = fakes.HTTPRequest.blank(self.url)
res_dict = self.controller.index(req)
response = {'cloudpipes': [{'project_id': 'other',
'instance_id': 7777,
response = {'cloudpipes': [{'project_id': project_id,
'instance_id': uuid,
'created_at': '1981-10-20T00:00:00Z'}]}
self.assertEqual(res_dict, response)
def test_cloudpipe_list(self):
def network_api_get(context, network_id):
self.assertEqual(context.project_id, 'other')
self.assertEqual(context.project_id, project_id)
return {'vpn_public_address': '127.0.0.1',
'vpn_public_port': 22}
@ -98,12 +104,12 @@ class CloudpipeTestV21(test.NoDBTestCase):
compute_api_get_all)
req = fakes.HTTPRequest.blank(self.url)
res_dict = self.controller.index(req)
response = {'cloudpipes': [{'project_id': 'other',
response = {'cloudpipes': [{'project_id': project_id,
'internal_ip': '192.168.1.100',
'public_ip': '127.0.0.1',
'public_port': 22,
'state': 'running',
'instance_id': 7777,
'instance_id': uuid,
'created_at': '1981-10-20T00:00:00Z'}]}
self.assertThat(res_dict, matchers.DictMatches(response))
@ -113,11 +119,11 @@ class CloudpipeTestV21(test.NoDBTestCase):
self.stubs.Set(self.controller.cloudpipe, 'launch_vpn_instance',
launch_vpn_instance)
body = {'cloudpipe': {'project_id': 1}}
body = {'cloudpipe': {'project_id': project_id}}
req = fakes.HTTPRequest.blank(self.url)
res_dict = self.controller.create(req, body)
res_dict = self.controller.create(req, body=body)
response = {'instance_id': 7777}
response = {'instance_id': uuid}
self.assertEqual(res_dict, response)
def test_cloudpipe_create_no_networks(self):
@ -126,10 +132,10 @@ class CloudpipeTestV21(test.NoDBTestCase):
self.stubs.Set(self.controller.cloudpipe, 'launch_vpn_instance',
launch_vpn_instance)
body = {'cloudpipe': {'project_id': 1}}
body = {'cloudpipe': {'project_id': project_id}}
req = fakes.HTTPRequest.blank(self.url)
self.assertRaises(exc.HTTPBadRequest,
self.controller.create, req, body)
self.controller.create, req, body=body)
def test_cloudpipe_create_already_running(self):
def launch_vpn_instance(*args, **kwargs):
@ -139,16 +145,25 @@ class CloudpipeTestV21(test.NoDBTestCase):
launch_vpn_instance)
self.stubs.Set(self.controller.compute_api, "get_all",
compute_api_get_all)
body = {'cloudpipe': {'project_id': 1}}
body = {'cloudpipe': {'project_id': project_id}}
req = fakes.HTTPRequest.blank(self.url)
res_dict = self.controller.create(req, body)
response = {'instance_id': 7777}
res_dict = self.controller.create(req, body=body)
response = {'instance_id': uuid}
self.assertEqual(res_dict, response)
def test_cloudpipe_create_with_bad_project_id_failed(self):
body = {'cloudpipe': {'project_id': 'bad.project.id'}}
req = fakes.HTTPRequest.blank(self.url)
self.assertRaises(exception.ValidationError,
self.controller.create, req, body=body)
class CloudpipeTestV2(CloudpipeTestV21):
cloudpipe = cloudpipe_v2
def test_cloudpipe_create_with_bad_project_id_failed(self):
pass
class CloudpipesXMLSerializerTestV2(test.NoDBTestCase):
def test_default_serializer(self):

View File

@ -46,13 +46,13 @@ class CloudPipeSampleTest(api_sample_base.ApiSampleTestBaseV3):
network_api_get)
def generalize_subs(self, subs, vanilla_regexes):
subs['project_id'] = 'cloudpipe-[0-9a-f-]+'
subs['project_id'] = '[0-9a-f-]+'
return subs
def test_cloud_pipe_create(self):
# Get api samples of cloud pipe extension creation.
self.flags(vpn_image_id=fake.get_valid_image_id())
project = {'project_id': 'cloudpipe-' + str(uuid_lib.uuid4())}
project = {'project_id': str(uuid_lib.uuid4().hex)}
response = self._do_post('os-cloudpipe', 'cloud-pipe-create-req',
project)
subs = self._get_regexes()