Ports ips api to v3 API

Port the core ips api to the V3 API as plugins along
with the corresponding tests for the ips and servers API.

Partially implements blueprint v3-api-core-as-extensions

Change-Id: I6e9f8ab71745791e6bc18999810f39764cd40116
This commit is contained in:
Chris Yeoh
2013-05-09 18:54:22 +09:30
parent 783b0e836d
commit 39b8641fc4
5 changed files with 5943 additions and 1 deletions

View File

@@ -0,0 +1,116 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright 2011 OpenStack Foundation
# 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 webob import exc
import nova
from nova.api.openstack import common
from nova.api.openstack.compute.views import addresses as view_addresses
from nova.api.openstack import extensions
from nova.api.openstack import wsgi
from nova.api.openstack import xmlutil
def make_network(elem):
elem.set('id', 0)
ip = xmlutil.SubTemplateElement(elem, 'ip', selector=1)
ip.set('version')
ip.set('addr')
network_nsmap = {None: xmlutil.XMLNS_V11}
class NetworkTemplate(xmlutil.TemplateBuilder):
def construct(self):
sel = xmlutil.Selector(xmlutil.get_items, 0)
root = xmlutil.TemplateElement('network', selector=sel)
make_network(root)
return xmlutil.MasterTemplate(root, 1, nsmap=network_nsmap)
class AddressesTemplate(xmlutil.TemplateBuilder):
def construct(self):
root = xmlutil.TemplateElement('addresses', selector='addresses')
elem = xmlutil.SubTemplateElement(root, 'network',
selector=xmlutil.get_items)
make_network(elem)
return xmlutil.MasterTemplate(root, 1, nsmap=network_nsmap)
class IPsController(wsgi.Controller):
"""The servers addresses API controller for the OpenStack API."""
_view_builder_class = view_addresses.ViewBuilder
def __init__(self, **kwargs):
super(IPsController, self).__init__(**kwargs)
self._compute_api = nova.compute.API()
def _get_instance(self, context, server_id):
try:
instance = self._compute_api.get(context, server_id)
except nova.exception.NotFound:
msg = _("Instance does not exist")
raise exc.HTTPNotFound(explanation=msg)
return instance
def create(self, req, server_id, body):
raise exc.HTTPNotImplemented()
def delete(self, req, server_id, id):
raise exc.HTTPNotImplemented()
@wsgi.serializers(xml=AddressesTemplate)
def index(self, req, server_id):
context = req.environ["nova.context"]
instance = self._get_instance(context, server_id)
networks = common.get_networks_for_instance(context, instance)
return self._view_builder.index(networks)
@wsgi.serializers(xml=NetworkTemplate)
def show(self, req, server_id, id):
context = req.environ["nova.context"]
instance = self._get_instance(context, server_id)
networks = common.get_networks_for_instance(context, instance)
if id not in networks:
msg = _("Instance is not a member of specified network")
raise exc.HTTPNotFound(explanation=msg)
return self._view_builder.show(networks[id], id)
class IPs(extensions.V3APIExtensionBase):
"""Server addresses."""
name = "ips"
alias = "ips"
namespace = "http://docs.openstack.org/compute/core/ips/v3"
version = 1
def get_resources(self):
parent = {'member_name': 'server',
'collection_name': 'servers'}
resources = [
extensions.ResourceExtension(
'ips', IPsController(), parent=parent, member_name='ip')]
return resources
def get_controller_extensions(self):
return []

View File

@@ -1492,7 +1492,7 @@ class ServersController(wsgi.Controller):
def _get_server_search_options(self):
"""Return server search options allowed by non-admin."""
return ('reservation_id', 'name', 'status', 'image', 'flavor',
'changes-since', 'all_tenants')
'ip', 'changes-since', 'all_tenants')
def remove_invalid_options(context, search_options, allowed_search_options):

File diff suppressed because it is too large Load Diff

View File

@@ -334,6 +334,18 @@ class HTTPRequest(os_wsgi.Request):
return out
class HTTPRequestV3(os_wsgi.Request):
@classmethod
def blank(cls, *args, **kwargs):
kwargs['base_url'] = 'http://localhost/v3'
use_admin_context = kwargs.pop('use_admin_context', False)
out = os_wsgi.Request.blank(*args, **kwargs)
out.environ['nova.context'] = FakeRequestContext('fake_user', 'fake',
is_admin=use_admin_context)
return out
class TestRouter(wsgi.Router):
def __init__(self, controller, mapper=None):
if not mapper:

View File

@@ -58,6 +58,7 @@ nova.api.v3.extensions =
extension_info = nova.api.openstack.compute.plugins.v3.extension_info:ExtensionInfo
servers = nova.api.openstack.compute.plugins.v3.servers:Servers
keypairs = nova.api.openstack.compute.plugins.v3.keypairs:Keypairs
ips = nova.api.openstack.compute.plugins.v3.ips:IPs
nova.api.v3.extensions.server.create =
keypairs_create = nova.api.openstack.compute.plugins.v3.keypairs:Keypairs