Convert v3 ExtendedAvailabilityZone api to v2.1

This patch changes v3 ExtendedAvailabilityZone API to v2.1
and makes v2 unit tests share between v2 and v2.1.

The differences between v2 and v3 are described on the wiki page
https://wiki.openstack.org/wiki/NovaAPIv2tov3.

Partially implements blueprint v2-on-v3-api

Change-Id: I49baff38b7a9dabd40550267c2119fe84137594f
This commit is contained in:
Haiwei Xu 2014-09-01 11:16:18 +09:00
parent 680c4430e6
commit be605e9996
11 changed files with 39 additions and 178 deletions

View File

@ -49,7 +49,7 @@
"accessIPv4": "",
"accessIPv6": "",
"config_drive": "",
"os-extended-availability-zone:availability_zone": "nova",
"OS-EXT-AZ:availability_zone": "nova",
"OS-EXT-SRV-ATTR:host": "b8b357f7100d4391828f2177c922ef93",
"OS-EXT-SRV-ATTR:hypervisor_hostname": "fake-mini",
"OS-EXT-SRV-ATTR:instance_name": "instance-00000001",

View File

@ -50,7 +50,7 @@
"accessIPv4": "",
"accessIPv6": "",
"config_drive": "",
"os-extended-availability-zone:availability_zone": "nova",
"OS-EXT-AZ:availability_zone": "nova",
"OS-EXT-SRV-ATTR:host": "c3f14e9812ad496baf92ccfb3c61e15f",
"OS-EXT-SRV-ATTR:hypervisor_hostname": "fake-mini",
"OS-EXT-SRV-ATTR:instance_name": "instance-00000001",

View File

@ -46,7 +46,7 @@
"My Server Name": "Apache1"
},
"name": "new-server-test",
"os-extended-availability-zone:availability_zone": "nova",
"OS-EXT-AZ:availability_zone": "nova",
"progress": 0,
"status": "ACTIVE",
"tenant_id": "openstack",

View File

@ -47,7 +47,7 @@
"My Server Name": "Apache1"
},
"name": "new-server-test",
"os-extended-availability-zone:availability_zone": "nova",
"OS-EXT-AZ:availability_zone": "nova",
"progress": 0,
"status": "ACTIVE",
"tenant_id": "openstack",

View File

@ -22,11 +22,12 @@ from nova import availability_zones as avail_zone
ALIAS = "os-extended-availability-zone"
authorize = extensions.soft_extension_authorizer('compute',
'v3:' + ALIAS)
PREFIX = "OS-EXT-AZ"
class ExtendedAZController(wsgi.Controller):
def _extend_server(self, context, server, instance):
key = "%s:availability_zone" % ExtendedAvailabilityZone.alias
key = "%s:availability_zone" % PREFIX
az = avail_zone.get_instance_availability_zone(context, instance)
if not az and instance.get('availability_zone'):
# Likely hasn't reached a viable compute node yet so give back the

View File

@ -74,12 +74,13 @@ def fake_get_no_host_availability_zone(context, host):
return None
class ExtendedAvailabilityZoneTest(test.TestCase):
class ExtendedAvailabilityZoneTestV21(test.TestCase):
content_type = 'application/json'
prefix = 'OS-EXT-AZ:'
base_url = '/v3/servers/'
def setUp(self):
super(ExtendedAvailabilityZoneTest, self).setUp()
super(ExtendedAvailabilityZoneTestV21, self).setUp()
availability_zones.reset_cache()
fakes.stub_out_nw_api(self.stubs)
self.stubs.Set(compute.api.API, 'get', fake_compute_get)
@ -89,15 +90,10 @@ class ExtendedAvailabilityZoneTest(test.TestCase):
return_server = fakes.fake_instance_get()
self.stubs.Set(db, 'instance_get_by_uuid', return_server)
self.flags(
osapi_compute_extension=[
'nova.api.openstack.compute.contrib.select_extensions'],
osapi_compute_ext_list=['Extended_availability_zone'])
def _make_request(self, url):
req = webob.Request.blank(url)
req.headers['Accept'] = self.content_type
res = req.get_response(fakes.wsgi_app(init_only=('servers',)))
res = req.get_response(fakes.wsgi_app_v3(init_only=None))
return res
def _get_server(self, body):
@ -115,7 +111,7 @@ class ExtendedAvailabilityZoneTest(test.TestCase):
self.stubs.Set(availability_zones, 'get_host_availability_zone',
fake_get_no_host_availability_zone)
url = '/v2/fake/servers/%s' % UUID3
url = self.base_url + UUID3
res = self._make_request(url)
self.assertEqual(res.status_int, 200)
@ -126,21 +122,21 @@ class ExtendedAvailabilityZoneTest(test.TestCase):
self.stubs.Set(availability_zones, 'get_host_availability_zone',
fake_get_no_host_availability_zone)
url = '/v2/fake/servers/%s' % UUID3
url = self.base_url + UUID3
res = self._make_request(url)
self.assertEqual(res.status_int, 200)
self.assertAvailabilityZone(self._get_server(res.body), 'fakeaz')
def test_show(self):
url = '/v2/fake/servers/%s' % UUID3
url = self.base_url + UUID3
res = self._make_request(url)
self.assertEqual(res.status_int, 200)
self.assertAvailabilityZone(self._get_server(res.body), 'get-host')
def test_detail(self):
url = '/v2/fake/servers/detail'
url = self.base_url + 'detail'
res = self._make_request(url)
self.assertEqual(res.status_int, 200)
@ -153,13 +149,32 @@ class ExtendedAvailabilityZoneTest(test.TestCase):
raise exception.InstanceNotFound(instance_id='fake')
self.stubs.Set(compute.api.API, 'get', fake_compute_get)
url = '/v2/fake/servers/70f6db34-de8d-4fbd-aafb-4065bdfa6115'
url = self.base_url + '70f6db34-de8d-4fbd-aafb-4065bdfa6115'
res = self._make_request(url)
self.assertEqual(res.status_int, 404)
class ExtendedAvailabilityZoneXmlTest(ExtendedAvailabilityZoneTest):
class ExtendedAvailabilityZoneTestV2(ExtendedAvailabilityZoneTestV21):
base_url = '/v2/fake/servers/'
def setUp(self):
super(ExtendedAvailabilityZoneTestV2, self).setUp()
self.flags(
osapi_compute_extension=[
'nova.api.openstack.compute.contrib.select_extensions'],
osapi_compute_ext_list=['Extended_availability_zone'])
def _make_request(self, url):
req = webob.Request.blank(url)
req.headers['Accept'] = self.content_type
res = req.get_response(fakes.wsgi_app(init_only=('servers',)))
return res
class ExtendedAvailabilityZoneXmlTestV2(ExtendedAvailabilityZoneTestV2):
content_type = 'application/xml'
prefix = '{%s}' % extended_availability_zone.\
Extended_availability_zone.namespace

View File

@ -1,155 +0,0 @@
# 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.
import webob
from nova.api.openstack.compute.plugins.v3 import extended_availability_zone
from nova import availability_zones
from nova import compute
from nova.compute import vm_states
from nova import db
from nova import exception
from nova import objects
from nova.objects import instance as instance_obj
from nova.openstack.common import jsonutils
from nova import test
from nova.tests.api.openstack import fakes
from nova.tests import fake_instance
UUID1 = '00000000-0000-0000-0000-000000000001'
UUID2 = '00000000-0000-0000-0000-000000000002'
UUID3 = '00000000-0000-0000-0000-000000000003'
def fake_compute_get_az(*args, **kwargs):
inst = fakes.stub_instance(1, uuid=UUID3, host="get-host",
vm_state=vm_states.ACTIVE,
availability_zone='fakeaz')
return fake_instance.fake_instance_obj(args[1], **inst)
def fake_compute_get_empty(*args, **kwargs):
inst = fakes.stub_instance(1, uuid=UUID3, host="",
vm_state=vm_states.ACTIVE,
availability_zone='fakeaz')
return fake_instance.fake_instance_obj(args[1], **inst)
def fake_compute_get(*args, **kwargs):
inst = fakes.stub_instance(1, uuid=UUID3, host="get-host",
vm_state=vm_states.ACTIVE)
return fake_instance.fake_instance_obj(args[1], **inst)
def fake_compute_get_all(*args, **kwargs):
inst1 = fakes.stub_instance(1, uuid=UUID1, host="all-host",
vm_state=vm_states.ACTIVE)
inst2 = fakes.stub_instance(2, uuid=UUID2, host="all-host",
vm_state=vm_states.ACTIVE)
db_list = [inst1, inst2]
fields = instance_obj.INSTANCE_DEFAULT_FIELDS
return instance_obj._make_instance_list(args[1],
objects.InstanceList(),
db_list, fields)
def fake_get_host_availability_zone(context, host):
return host
def fake_get_no_host_availability_zone(context, host):
return None
class ExtendedAvailabilityZoneTest(test.TestCase):
content_type = 'application/json'
prefix = '%s:' % extended_availability_zone.ExtendedAvailabilityZone.alias
def setUp(self):
super(ExtendedAvailabilityZoneTest, self).setUp()
availability_zones.reset_cache()
fakes.stub_out_nw_api(self.stubs)
self.stubs.Set(compute.api.API, 'get', fake_compute_get)
self.stubs.Set(compute.api.API, 'get_all', fake_compute_get_all)
self.stubs.Set(availability_zones, 'get_host_availability_zone',
fake_get_host_availability_zone)
return_server = fakes.fake_instance_get()
self.stubs.Set(db, 'instance_get_by_uuid', return_server)
def _make_request(self, url):
req = webob.Request.blank(url)
req.headers['Accept'] = self.content_type
res = req.get_response(
fakes.wsgi_app_v3(init_only=('servers',
'os-extended-availability-zone')))
return res
def _get_server(self, body):
return jsonutils.loads(body).get('server')
def _get_servers(self, body):
return jsonutils.loads(body).get('servers')
def assertAvailabilityZone(self, server, az):
self.assertEqual(server.get('%savailability_zone' % self.prefix),
az)
def test_show_no_host_az(self):
self.stubs.Set(compute.api.API, 'get', fake_compute_get_az)
self.stubs.Set(availability_zones, 'get_host_availability_zone',
fake_get_no_host_availability_zone)
url = '/v3/servers/%s' % UUID3
res = self._make_request(url)
self.assertEqual(res.status_int, 200)
self.assertAvailabilityZone(self._get_server(res.body), 'fakeaz')
def test_show_empty_host_az(self):
self.stubs.Set(compute.api.API, 'get', fake_compute_get_empty)
self.stubs.Set(availability_zones, 'get_host_availability_zone',
fake_get_no_host_availability_zone)
url = '/v3/servers/%s' % UUID3
res = self._make_request(url)
self.assertEqual(res.status_int, 200)
self.assertAvailabilityZone(self._get_server(res.body), 'fakeaz')
def test_show(self):
url = '/v3/servers/%s' % UUID3
res = self._make_request(url)
self.assertEqual(res.status_int, 200)
self.assertAvailabilityZone(self._get_server(res.body), 'get-host')
def test_detail(self):
url = '/v3/servers/detail'
res = self._make_request(url)
self.assertEqual(res.status_int, 200)
for i, server in enumerate(self._get_servers(res.body)):
self.assertAvailabilityZone(server, 'all-host')
def test_no_instance_passthrough_404(self):
def fake_compute_get(*args, **kwargs):
raise exception.InstanceNotFound(instance_id='fake')
self.stubs.Set(compute.api.API, 'get', fake_compute_get)
url = '/v3/servers/70f6db34-de8d-4fbd-aafb-4065bdfa6115'
res = self._make_request(url)
self.assertEqual(res.status_int, 404)

View File

@ -49,7 +49,7 @@
},
"name": "new-server-test",
"config_drive": "",
"os-extended-availability-zone:availability_zone": "nova",
"OS-EXT-AZ:availability_zone": "nova",
"OS-EXT-SRV-ATTR:host": "%(compute_host)s",
"OS-EXT-SRV-ATTR:hypervisor_hostname": "%(hypervisor_hostname)s",
"OS-EXT-SRV-ATTR:instance_name": "instance-00000001",

View File

@ -50,7 +50,7 @@
},
"name": "new-server-test",
"config_drive": "",
"os-extended-availability-zone:availability_zone": "nova",
"OS-EXT-AZ:availability_zone": "nova",
"OS-EXT-SRV-ATTR:host": "%(compute_host)s",
"OS-EXT-SRV-ATTR:hypervisor_hostname": "%(hypervisor_hostname)s",
"OS-EXT-SRV-ATTR:instance_name": "instance-00000001",

View File

@ -2,7 +2,7 @@
"server": {
"updated": "%(isotime)s",
"created": "%(isotime)s",
"os-extended-availability-zone:availability_zone": "nova",
"OS-EXT-AZ:availability_zone": "nova",
"addresses": {
"private": [
{

View File

@ -3,7 +3,7 @@
{
"updated": "%(isotime)s",
"created": "%(isotime)s",
"os-extended-availability-zone:availability_zone": "nova",
"OS-EXT-AZ:availability_zone": "nova",
"addresses": {
"private": [
{