version request url move to the dir of module
Change-Id: If6819e3131144c5630539d76bafd42b101e06a91
This commit is contained in:
parent
8453642b1e
commit
a5e1284138
@ -37,7 +37,7 @@ paste.app_factory = venus.api.v1.router:APIRouter.factory
|
|||||||
pipeline = faultwrap osvenusversionapp
|
pipeline = faultwrap osvenusversionapp
|
||||||
|
|
||||||
[app:osvenusversionapp]
|
[app:osvenusversionapp]
|
||||||
paste.app_factory = venus.api.versions:Versions.factory
|
paste.app_factory = venus.modules.version.versions:Versions.factory
|
||||||
|
|
||||||
##########
|
##########
|
||||||
# Shared #
|
# Shared #
|
||||||
|
@ -81,10 +81,10 @@ class APIRouter(base_wsgi.Router):
|
|||||||
mapper = ProjectMapper()
|
mapper = ProjectMapper()
|
||||||
self.resources = {}
|
self.resources = {}
|
||||||
self._setup_routes(mapper, ext_mgr)
|
self._setup_routes(mapper, ext_mgr)
|
||||||
self._setup_ext_routes(mapper, ext_mgr)
|
# self._setup_ext_routes(mapper, ext_mgr)
|
||||||
self._setup_extensions(ext_mgr)
|
# self._setup_extensions(ext_mgr)
|
||||||
for url in mapper.matchlist:
|
for url in mapper.matchlist:
|
||||||
LOG.debug('URL methid: s% register: %s ',
|
LOG.debug('URL method: %s register: %s ',
|
||||||
url.conditions, url.routepath)
|
url.conditions, url.routepath)
|
||||||
|
|
||||||
super(APIRouter, self).__init__(mapper)
|
super(APIRouter, self).__init__(mapper)
|
||||||
|
@ -20,9 +20,9 @@ from oslo_log import log as logging
|
|||||||
|
|
||||||
from venus.api import extensions
|
from venus.api import extensions
|
||||||
import venus.api.openstack
|
import venus.api.openstack
|
||||||
from venus.api import versions
|
|
||||||
from venus.modules.custom_config import controller as custom_config
|
from venus.modules.custom_config import controller as custom_config
|
||||||
from venus.modules.search import controller as search
|
from venus.modules.search import controller as search
|
||||||
|
from venus.modules.version import versions
|
||||||
|
|
||||||
|
|
||||||
LOG = logging.getLogger(__name__)
|
LOG = logging.getLogger(__name__)
|
||||||
|
0
venus/modules/version/__init__.py
Normal file
0
venus/modules/version/__init__.py
Normal file
@ -1,245 +1,242 @@
|
|||||||
# Copyright 2020 Inspur
|
# Copyright 2020 Inspur
|
||||||
#
|
#
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
# 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
|
# not use this file except in compliance with the License. You may obtain
|
||||||
# a copy of the License at
|
# a copy of the License at
|
||||||
#
|
#
|
||||||
# http://www.apache.org/licenses/LICENSE-2.0
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
#
|
#
|
||||||
# Unless required by applicable law or agreed to in writing, software
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
# License for the specific language governing permissions and limitations
|
# License for the specific language governing permissions and limitations
|
||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
import datetime
|
import datetime
|
||||||
|
|
||||||
from lxml import etree
|
from lxml import etree
|
||||||
from oslo_config import cfg
|
|
||||||
|
from venus.api.openstack import wsgi
|
||||||
from venus.api.openstack import wsgi
|
from venus.api.v1.views import versions as views_versions
|
||||||
from venus.api.v1.views import versions as views_versions
|
from venus.api import xmlutil
|
||||||
from venus.api import xmlutil
|
from venus.conf import CONF
|
||||||
|
|
||||||
|
|
||||||
CONF = cfg.CONF
|
_KNOWN_VERSIONS = {
|
||||||
|
"v1.0": {
|
||||||
|
"id": "v1.0",
|
||||||
_KNOWN_VERSIONS = {
|
"status": "SUPPORTED",
|
||||||
"v1.0": {
|
"updated": "2014-06-28T12:20:21Z",
|
||||||
"id": "v1.0",
|
"links": [
|
||||||
"status": "SUPPORTED",
|
{
|
||||||
"updated": "2014-06-28T12:20:21Z",
|
"rel": "describedby",
|
||||||
"links": [
|
"type": "text/html",
|
||||||
{
|
"href": "http://docs.openstack.org/",
|
||||||
"rel": "describedby",
|
},
|
||||||
"type": "text/html",
|
],
|
||||||
"href": "http://docs.openstack.org/",
|
"media-types": [
|
||||||
},
|
{
|
||||||
],
|
"base": "application/xml",
|
||||||
"media-types": [
|
"type": "application/vnd.openstack.venus+xml;version=1",
|
||||||
{
|
},
|
||||||
"base": "application/xml",
|
{
|
||||||
"type": "application/vnd.openstack.venus+xml;version=1",
|
"base": "application/json",
|
||||||
},
|
"type": "application/vnd.openstack.venus+json;version=1",
|
||||||
{
|
}
|
||||||
"base": "application/json",
|
],
|
||||||
"type": "application/vnd.openstack.venus+json;version=1",
|
}
|
||||||
}
|
}
|
||||||
],
|
|
||||||
}
|
|
||||||
}
|
def get_supported_versions():
|
||||||
|
versions = {}
|
||||||
|
|
||||||
def get_supported_versions():
|
if CONF.enable_v1_api:
|
||||||
versions = {}
|
versions['v1.0'] = _KNOWN_VERSIONS['v1.0']
|
||||||
|
|
||||||
if CONF.enable_v1_api:
|
return versions
|
||||||
versions['v1.0'] = _KNOWN_VERSIONS['v1.0']
|
|
||||||
|
|
||||||
return versions
|
class MediaTypesTemplateElement(xmlutil.TemplateElement):
|
||||||
|
def will_render(self, datum):
|
||||||
|
return 'media-types' in datum
|
||||||
class MediaTypesTemplateElement(xmlutil.TemplateElement):
|
|
||||||
def will_render(self, datum):
|
|
||||||
return 'media-types' in datum
|
def make_version(elem):
|
||||||
|
elem.set('id')
|
||||||
|
elem.set('status')
|
||||||
def make_version(elem):
|
elem.set('updated')
|
||||||
elem.set('id')
|
|
||||||
elem.set('status')
|
mts = MediaTypesTemplateElement('media-types')
|
||||||
elem.set('updated')
|
elem.append(mts)
|
||||||
|
|
||||||
mts = MediaTypesTemplateElement('media-types')
|
mt = xmlutil.sub_template_element(mts, 'media-type',
|
||||||
elem.append(mts)
|
selector='media-types')
|
||||||
|
mt.set('base')
|
||||||
mt = xmlutil.sub_template_element(mts, 'media-type',
|
mt.set('type')
|
||||||
selector='media-types')
|
|
||||||
mt.set('base')
|
xmlutil.make_links(elem, 'links')
|
||||||
mt.set('type')
|
|
||||||
|
|
||||||
xmlutil.make_links(elem, 'links')
|
version_nsmap = {None: xmlutil.XMLNS_COMMON_V10, 'atom': xmlutil.XMLNS_ATOM}
|
||||||
|
|
||||||
|
|
||||||
version_nsmap = {None: xmlutil.XMLNS_COMMON_V10, 'atom': xmlutil.XMLNS_ATOM}
|
class VersionTemplate(xmlutil.TemplateBuilder):
|
||||||
|
def construct(self):
|
||||||
|
root = xmlutil.TemplateElement('version', selector='version')
|
||||||
class VersionTemplate(xmlutil.TemplateBuilder):
|
make_version(root)
|
||||||
def construct(self):
|
return xmlutil.MasterTemplate(root, 1, nsmap=version_nsmap)
|
||||||
root = xmlutil.TemplateElement('version', selector='version')
|
|
||||||
make_version(root)
|
|
||||||
return xmlutil.MasterTemplate(root, 1, nsmap=version_nsmap)
|
class VersionsTemplate(xmlutil.TemplateBuilder):
|
||||||
|
def construct(self):
|
||||||
|
root = xmlutil.TemplateElement('versions')
|
||||||
class VersionsTemplate(xmlutil.TemplateBuilder):
|
elem = xmlutil.sub_template_element(root, 'version',
|
||||||
def construct(self):
|
selector='versions')
|
||||||
root = xmlutil.TemplateElement('versions')
|
make_version(elem)
|
||||||
elem = xmlutil.sub_template_element(root, 'version',
|
return xmlutil.MasterTemplate(root, 1, nsmap=version_nsmap)
|
||||||
selector='versions')
|
|
||||||
make_version(elem)
|
|
||||||
return xmlutil.MasterTemplate(root, 1, nsmap=version_nsmap)
|
class ChoicesTemplate(xmlutil.TemplateBuilder):
|
||||||
|
def construct(self):
|
||||||
|
root = xmlutil.TemplateElement('choices')
|
||||||
class ChoicesTemplate(xmlutil.TemplateBuilder):
|
elem = xmlutil.sub_template_element(root, 'version',
|
||||||
def construct(self):
|
selector='choices')
|
||||||
root = xmlutil.TemplateElement('choices')
|
make_version(elem)
|
||||||
elem = xmlutil.sub_template_element(root, 'version',
|
return xmlutil.MasterTemplate(root, 1, nsmap=version_nsmap)
|
||||||
selector='choices')
|
|
||||||
make_version(elem)
|
|
||||||
return xmlutil.MasterTemplate(root, 1, nsmap=version_nsmap)
|
class AtomSerializer(wsgi.XMLDictSerializer):
|
||||||
|
|
||||||
|
NSMAP = {None: xmlutil.XMLNS_ATOM}
|
||||||
class AtomSerializer(wsgi.XMLDictSerializer):
|
|
||||||
|
def __init__(self, metadata=None, xmlns=None):
|
||||||
NSMAP = {None: xmlutil.XMLNS_ATOM}
|
super(AtomSerializer, self).__init__(metadata, xmlns)
|
||||||
|
self.metadata = metadata or {}
|
||||||
def __init__(self, metadata=None, xmlns=None):
|
if not xmlns:
|
||||||
super(AtomSerializer, self).__init__(metadata, xmlns)
|
self.xmlns = wsgi.XML_NS_ATOM
|
||||||
self.metadata = metadata or {}
|
else:
|
||||||
if not xmlns:
|
self.xmlns = xmlns
|
||||||
self.xmlns = wsgi.XML_NS_ATOM
|
|
||||||
else:
|
def _get_most_recent_update(self, versions):
|
||||||
self.xmlns = xmlns
|
recent = None
|
||||||
|
for version in versions:
|
||||||
def _get_most_recent_update(self, versions):
|
updated = datetime.datetime.strptime(version['updated'],
|
||||||
recent = None
|
'%Y-%m-%dT%H:%M:%SZ')
|
||||||
for version in versions:
|
if not recent:
|
||||||
updated = datetime.datetime.strptime(version['updated'],
|
recent = updated
|
||||||
'%Y-%m-%dT%H:%M:%SZ')
|
elif updated > recent:
|
||||||
if not recent:
|
recent = updated
|
||||||
recent = updated
|
|
||||||
elif updated > recent:
|
return recent.strftime('%Y-%m-%dT%H:%M:%SZ')
|
||||||
recent = updated
|
|
||||||
|
def _get_base_url(self, link_href):
|
||||||
return recent.strftime('%Y-%m-%dT%H:%M:%SZ')
|
# Make sure no trailing /
|
||||||
|
link_href = link_href.rstrip('/')
|
||||||
def _get_base_url(self, link_href):
|
return link_href.rsplit('/', 1)[0] + '/'
|
||||||
# Make sure no trailing /
|
|
||||||
link_href = link_href.rstrip('/')
|
def _create_feed(self, versions, feed_title, feed_id):
|
||||||
return link_href.rsplit('/', 1)[0] + '/'
|
feed = etree.Element('feed', nsmap=self.NSMAP)
|
||||||
|
title = etree.SubElement(feed, 'title')
|
||||||
def _create_feed(self, versions, feed_title, feed_id):
|
title.set('type', 'text')
|
||||||
feed = etree.Element('feed', nsmap=self.NSMAP)
|
title.text = feed_title
|
||||||
title = etree.SubElement(feed, 'title')
|
|
||||||
title.set('type', 'text')
|
# Set this updated to the most recently updated version
|
||||||
title.text = feed_title
|
recent = self._get_most_recent_update(versions)
|
||||||
|
etree.SubElement(feed, 'updated').text = recent
|
||||||
# Set this updated to the most recently updated version
|
|
||||||
recent = self._get_most_recent_update(versions)
|
etree.SubElement(feed, 'id').text = feed_id
|
||||||
etree.SubElement(feed, 'updated').text = recent
|
|
||||||
|
link = etree.SubElement(feed, 'link')
|
||||||
etree.SubElement(feed, 'id').text = feed_id
|
link.set('rel', 'self')
|
||||||
|
link.set('href', feed_id)
|
||||||
link = etree.SubElement(feed, 'link')
|
|
||||||
link.set('rel', 'self')
|
author = etree.SubElement(feed, 'author')
|
||||||
link.set('href', feed_id)
|
etree.SubElement(author, 'name').text = 'Rackspace'
|
||||||
|
etree.SubElement(author, 'uri').text = 'http://www.rackspace.com/'
|
||||||
author = etree.SubElement(feed, 'author')
|
|
||||||
etree.SubElement(author, 'name').text = 'Rackspace'
|
for version in versions:
|
||||||
etree.SubElement(author, 'uri').text = 'http://www.rackspace.com/'
|
feed.append(self._create_version_entry(version))
|
||||||
|
|
||||||
for version in versions:
|
return feed
|
||||||
feed.append(self._create_version_entry(version))
|
|
||||||
|
def _create_version_entry(self, version):
|
||||||
return feed
|
entry = etree.Element('entry')
|
||||||
|
etree.SubElement(entry, 'id').text = version['links'][0]['href']
|
||||||
def _create_version_entry(self, version):
|
title = etree.SubElement(entry, 'title')
|
||||||
entry = etree.Element('entry')
|
title.set('type', 'text')
|
||||||
etree.SubElement(entry, 'id').text = version['links'][0]['href']
|
title.text = 'Version %s' % version['id']
|
||||||
title = etree.SubElement(entry, 'title')
|
etree.SubElement(entry, 'updated').text = version['updated']
|
||||||
title.set('type', 'text')
|
|
||||||
title.text = 'Version %s' % version['id']
|
for link in version['links']:
|
||||||
etree.SubElement(entry, 'updated').text = version['updated']
|
link_elem = etree.SubElement(entry, 'link')
|
||||||
|
link_elem.set('rel', link['rel'])
|
||||||
for link in version['links']:
|
link_elem.set('href', link['href'])
|
||||||
link_elem = etree.SubElement(entry, 'link')
|
if 'type' in link:
|
||||||
link_elem.set('rel', link['rel'])
|
link_elem.set('type', link['type'])
|
||||||
link_elem.set('href', link['href'])
|
|
||||||
if 'type' in link:
|
content = etree.SubElement(entry, 'content')
|
||||||
link_elem.set('type', link['type'])
|
content.set('type', 'text')
|
||||||
|
content.text = 'Version %s %s (%s)' % (version['id'],
|
||||||
content = etree.SubElement(entry, 'content')
|
version['status'],
|
||||||
content.set('type', 'text')
|
version['updated'])
|
||||||
content.text = 'Version %s %s (%s)' % (version['id'],
|
return entry
|
||||||
version['status'],
|
|
||||||
version['updated'])
|
|
||||||
return entry
|
class VersionsAtomSerializer(AtomSerializer):
|
||||||
|
def default(self, data):
|
||||||
|
versions = data['versions']
|
||||||
class VersionsAtomSerializer(AtomSerializer):
|
feed_id = self._get_base_url(versions[0]['links'][0]['href'])
|
||||||
def default(self, data):
|
feed = self._create_feed(versions, 'Available API Versions', feed_id)
|
||||||
versions = data['versions']
|
return self._to_xml(feed)
|
||||||
feed_id = self._get_base_url(versions[0]['links'][0]['href'])
|
|
||||||
feed = self._create_feed(versions, 'Available API Versions', feed_id)
|
|
||||||
return self._to_xml(feed)
|
class VersionAtomSerializer(AtomSerializer):
|
||||||
|
def default(self, data):
|
||||||
|
version = data['version']
|
||||||
class VersionAtomSerializer(AtomSerializer):
|
feed_id = version['links'][0]['href']
|
||||||
def default(self, data):
|
feed = self._create_feed([version], 'About This Version', feed_id)
|
||||||
version = data['version']
|
return self._to_xml(feed)
|
||||||
feed_id = version['links'][0]['href']
|
|
||||||
feed = self._create_feed([version], 'About This Version', feed_id)
|
|
||||||
return self._to_xml(feed)
|
class Versions(wsgi.Resource):
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
class Versions(wsgi.Resource):
|
super(Versions, self).__init__(None)
|
||||||
|
|
||||||
def __init__(self):
|
@wsgi.serializers(xml=VersionsTemplate,
|
||||||
super(Versions, self).__init__(None)
|
atom=VersionsAtomSerializer)
|
||||||
|
def index(self, req):
|
||||||
@wsgi.serializers(xml=VersionsTemplate,
|
"""Return all versions."""
|
||||||
atom=VersionsAtomSerializer)
|
builder = views_versions.get_view_builder(req)
|
||||||
def index(self, req):
|
return builder.build_versions(get_supported_versions())
|
||||||
"""Return all versions."""
|
|
||||||
builder = views_versions.get_view_builder(req)
|
@wsgi.serializers(xml=ChoicesTemplate)
|
||||||
return builder.build_versions(get_supported_versions())
|
@wsgi.response(300)
|
||||||
|
def multi(self, req):
|
||||||
@wsgi.serializers(xml=ChoicesTemplate)
|
"""Return multiple choices."""
|
||||||
@wsgi.response(300)
|
builder = views_versions.get_view_builder(req)
|
||||||
def multi(self, req):
|
return builder.build_choices(get_supported_versions(), req)
|
||||||
"""Return multiple choices."""
|
|
||||||
builder = views_versions.get_view_builder(req)
|
def get_action_args(self, request_environment):
|
||||||
return builder.build_choices(get_supported_versions(), req)
|
"""Parse dictionary created by routes library."""
|
||||||
|
args = {}
|
||||||
def get_action_args(self, request_environment):
|
if request_environment['PATH_INFO'] == '/':
|
||||||
"""Parse dictionary created by routes library."""
|
args['action'] = 'index'
|
||||||
args = {}
|
else:
|
||||||
if request_environment['PATH_INFO'] == '/':
|
args['action'] = 'multi'
|
||||||
args['action'] = 'index'
|
|
||||||
else:
|
return args
|
||||||
args['action'] = 'multi'
|
|
||||||
|
|
||||||
return args
|
class VenusVersion(object):
|
||||||
|
@wsgi.serializers(xml=VersionTemplate,
|
||||||
|
atom=VersionAtomSerializer)
|
||||||
class VenusVersion(object):
|
def show(self, req):
|
||||||
@wsgi.serializers(xml=VersionTemplate,
|
builder = views_versions.get_view_builder(req)
|
||||||
atom=VersionAtomSerializer)
|
if 'v1' in builder.base_url:
|
||||||
def show(self, req):
|
return builder.build_version(_KNOWN_VERSIONS['v1.0'])
|
||||||
builder = views_versions.get_view_builder(req)
|
|
||||||
if 'v1' in builder.base_url:
|
|
||||||
return builder.build_version(_KNOWN_VERSIONS['v1.0'])
|
def create_resource():
|
||||||
|
return wsgi.Resource(VenusVersion())
|
||||||
|
|
||||||
def create_resource():
|
|
||||||
return wsgi.Resource(VenusVersion())
|
|
Loading…
Reference in New Issue
Block a user