Pecan: /v2.0/ views response with resources

The legacy framework return a list of resources as the response to:

GET /v2.0/

Current pecan 2.0 controller seems return the same as root controller
content. This patch will make it return the same response as legacy
framework

Change-Id: Icae8c1b417d4d5a65a98eeafe80a26886aa254a3
This commit is contained in:
tonytan4ever 2016-09-01 10:52:40 -04:00 committed by Kevin Benton
parent 87cb9d8552
commit 5da865c1a8
4 changed files with 34 additions and 11 deletions

View File

@ -35,6 +35,10 @@ SUBNET = 'subnet'
SUBNETS = '%ss' % SUBNET
SUBNETPOOL = 'subnetpool'
SUBNETPOOLS = '%ss' % SUBNETPOOL
CORE_RESOURCES = {'network': 'networks',
'subnet': 'subnets',
'subnetpool': 'subnetpools',
'port': 'ports'}
# Note: a default of ATTR_NOT_SPECIFIED indicates that an
# attribute is not required, but will be generated by the plugin
# if it is not specified. Particularly, a value of ATTR_NOT_SPECIFIED

View File

@ -34,10 +34,7 @@ from neutron.quota import resource_registry
from neutron import wsgi
RESOURCES = {'network': 'networks',
'subnet': 'subnets',
'subnetpool': 'subnetpools',
'port': 'ports'}
RESOURCES = attributes.CORE_RESOURCES
SUB_RESOURCES = {}
COLLECTION_ACTIONS = ['index', 'create']
MEMBER_ACTIONS = ['show', 'update', 'delete']

View File

@ -18,8 +18,11 @@ from oslo_config import cfg
from oslo_log import log
import pecan
from pecan import request
import six
import six.moves.urllib.parse as urlparse
from neutron._i18n import _LW
from neutron.api.v2 import attributes
from neutron.api.views import versions as versions_view
from neutron import manager
from neutron.pecan_wsgi.controllers import extensions as ext_ctrl
@ -83,8 +86,18 @@ class V2Controller(object):
@utils.expose(generic=True)
def index(self):
builder = versions_view.get_view_builder(pecan.request)
return dict(version=builder.build(self.version_info))
if not pecan.request.path_url.endswith('/'):
pecan.abort(404)
layout = []
for name, collection in six.iteritems(attributes.CORE_RESOURCES):
href = urlparse.urljoin(pecan.request.path_url, collection)
resource = {'name': name,
'collection': collection,
'links': [{'rel': 'self',
'href': href}]}
layout.append(resource)
return {'resources': layout}
@utils.when(index, method='HEAD')
@utils.when(index, method='POST')

View File

@ -90,24 +90,33 @@ class TestRootController(test_functional.PecanFunctionalTest):
class TestV2Controller(TestRootController):
base_url = '/v2.0'
base_url = '/v2.0/'
def test_get(self):
"""Verify current version info are returned."""
response = self.app.get(self.base_url)
self.assertEqual(response.status_int, 200)
json_body = jsonutils.loads(response.body)
self.assertEqual('v2.0', json_body['version']['id'])
self.assertEqual('CURRENT', json_body['version']['status'])
self.assertIn('resources', json_body)
self.assertIsInstance(json_body['resources'], list)
for r in json_body['resources']:
self.assertIn("links", r)
self.assertIn("name", r)
self.assertIn("collection", r)
self.assertIn(self.base_url, r['links'][0]['href'])
def test_get_no_trailing_slash(self):
response = self.app.get(self.base_url[:-1], expect_errors=True)
self.assertEqual(response.status_int, 404)
def test_routing_successs(self):
"""Test dispatch to controller for existing resource."""
response = self.app.get('%s/ports.json' % self.base_url)
response = self.app.get('%sports.json' % self.base_url)
self.assertEqual(response.status_int, 200)
def test_routing_failure(self):
"""Test dispatch to controller for non-existing resource."""
response = self.app.get('%s/idonotexist.json' % self.base_url,
response = self.app.get('%sidonotexist.json' % self.base_url,
expect_errors=True)
self.assertEqual(response.status_int, 404)