Merge extended server attributes extension response

As nova extensions has been deprecated already and goal is to
merge all scattered code into main controller side.
Currently schema and request/response extended code are there
among all extensions.

This commit merge the extended server attributes extension
resposne into server controller.

Partially implements: blueprint api-extensions-merge-stein

Change-Id: I82b11b8866ac82b05eae04351605d52fa8b91453
This commit is contained in:
ghanshyam 2018-08-15 12:29:44 +00:00 committed by Ghanshyam Mann
parent 67d3448136
commit 82b98ad951
6 changed files with 358 additions and 383 deletions

View File

@ -1,105 +0,0 @@
# Copyright 2012 OpenStack Foundation
#
# 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.
"""The Extended Server Attributes API extension."""
from nova.api.openstack import api_version_request
from nova.api.openstack import wsgi
from nova import compute
from nova.policies import extended_server_attributes as esa_policies
from nova.policies import servers as servers_policies
class ExtendedServerAttributesController(wsgi.Controller):
def __init__(self, *args, **kwargs):
super(ExtendedServerAttributesController, self).__init__(*args,
**kwargs)
self.compute_api = compute.API()
def _extend_server(self, context, server, instance, req):
key = "OS-EXT-SRV-ATTR:hypervisor_hostname"
server[key] = instance.node
properties = ['host', 'name']
if api_version_request.is_supported(req, min_version='2.3'):
# NOTE(mriedem): These will use the OS-EXT-SRV-ATTR prefix below
# and that's OK for microversion 2.3 which is being compatible
# with v2.0 for the ec2 API split out from Nova. After this,
# however, new microversions should not be using the
# OS-EXT-SRV-ATTR prefix.
properties += ['reservation_id', 'launch_index',
'hostname', 'kernel_id', 'ramdisk_id',
'root_device_name', 'user_data']
for attr in properties:
if attr == 'name':
key = "OS-EXT-SRV-ATTR:instance_%s" % attr
else:
# NOTE(mriedem): Nothing after microversion 2.3 should use the
# OS-EXT-SRV-ATTR prefix for the attribute key name.
key = "OS-EXT-SRV-ATTR:%s" % attr
server[key] = instance[attr]
def _server_host_status(self, context, server, instance, req):
host_status = self.compute_api.get_instance_host_status(instance)
server['host_status'] = host_status
@wsgi.extends
def show(self, req, resp_obj, id):
context = req.environ['nova.context']
authorize_extend = False
authorize_host_status = False
if context.can(esa_policies.BASE_POLICY_NAME, fatal=False):
authorize_extend = True
if (api_version_request.is_supported(req, min_version='2.16') and
context.can(servers_policies.SERVERS % 'show:host_status',
fatal=False)):
authorize_host_status = True
if authorize_extend or authorize_host_status:
server = resp_obj.obj['server']
db_instance = req.get_db_instance(server['id'])
# server['id'] is guaranteed to be in the cache due to
# the core API adding it in its 'show' method.
if authorize_extend:
self._extend_server(context, server, db_instance, req)
if authorize_host_status:
self._server_host_status(context, server, db_instance, req)
@wsgi.extends
def detail(self, req, resp_obj):
context = req.environ['nova.context']
authorize_extend = False
authorize_host_status = False
if context.can(esa_policies.BASE_POLICY_NAME, fatal=False):
authorize_extend = True
if (api_version_request.is_supported(req, min_version='2.16') and
context.can(servers_policies.SERVERS % 'show:host_status',
fatal=False)):
authorize_host_status = True
if authorize_extend or authorize_host_status:
servers = list(resp_obj.obj['servers'])
# NOTE(dinesh-bhor): Skipping fetching of instances from cache as
# servers list can be empty if invalid status is provided to the
# core API 'detail' method.
if servers:
instances = req.get_db_instances()
if authorize_host_status:
host_statuses = (
self.compute_api.get_instances_host_statuses(
instances.values()))
for server in servers:
if authorize_extend:
instance = instances[server['id']]
self._extend_server(context, server, instance, req)
if authorize_host_status:
server['host_status'] = host_statuses[server['id']]

View File

@ -34,7 +34,6 @@ from nova.api.openstack.compute import consoles
from nova.api.openstack.compute import create_backup
from nova.api.openstack.compute import deferred_delete
from nova.api.openstack.compute import evacuate
from nova.api.openstack.compute import extended_server_attributes
from nova.api.openstack.compute import extended_status
from nova.api.openstack.compute import extended_volumes
from nova.api.openstack.compute import extension_info
@ -267,7 +266,6 @@ security_group_rules_controller = functools.partial(_create_controller,
server_controller = functools.partial(_create_controller,
servers.ServersController,
[
extended_server_attributes.ExtendedServerAttributesController,
extended_status.ExtendedStatusController,
extended_volumes.ExtendedVolumesController,
hide_server_addresses.Controller,

View File

@ -719,7 +719,9 @@ class ServersController(wsgi.Controller):
return self._view_builder.show(req, instance,
extend_address=False,
show_AZ=False,
show_config_drive=False)
show_config_drive=False,
show_extended_attr=False,
show_host_status=False)
except exception.InstanceNotFound:
msg = _("Instance could not be found")
raise exc.HTTPNotFound(explanation=msg)
@ -985,7 +987,9 @@ class ServersController(wsgi.Controller):
view = self._view_builder.show(req, instance, extend_address=False,
show_AZ=False,
show_config_drive=False)
show_config_drive=False,
show_extended_attr=False,
show_host_status=False)
# Add on the admin_password attribute since the view doesn't do it
# unless instance passwords are disabled

View File

@ -22,10 +22,13 @@ from nova.api.openstack.compute.views import addresses as views_addresses
from nova.api.openstack.compute.views import flavors as views_flavors
from nova.api.openstack.compute.views import images as views_images
from nova import availability_zones as avail_zone
from nova import compute
from nova import context as nova_context
from nova import exception
from nova import objects
from nova.policies import extended_server_attributes as esa_policies
from nova.policies import flavor_extra_specs as fes_policies
from nova.policies import servers as servers_policies
from nova import utils
@ -61,6 +64,7 @@ class ViewBuilder(common.ViewBuilder):
self._address_builder = views_addresses.ViewBuilder()
self._image_builder = views_images.ViewBuilder()
self._flavor_builder = views_flavors.ViewBuilder()
self.compute_api = compute.API()
def create(self, request, instance):
"""View that should be returned when an instance is created."""
@ -78,7 +82,8 @@ class ViewBuilder(common.ViewBuilder):
},
}
def basic(self, request, instance, show_extra_specs=False):
def basic(self, request, instance, show_extra_specs=False,
show_extended_attr=None, show_host_status=None):
"""Generic, non-detailed view of an instance."""
return {
"server": {
@ -111,7 +116,8 @@ class ViewBuilder(common.ViewBuilder):
return sorted(list(set(self._show_expected_attrs + expected_attrs)))
def show(self, request, instance, extend_address=True,
show_extra_specs=None, show_AZ=True, show_config_drive=True):
show_extra_specs=None, show_AZ=True, show_config_drive=True,
show_extended_attr=None, show_host_status=None):
"""Detailed view of a single instance."""
ip_v4 = instance.get('access_ip_v4')
ip_v6 = instance.get('access_ip_v6')
@ -161,8 +167,8 @@ class ViewBuilder(common.ViewBuilder):
if server["server"]["status"] in self._progress_statuses:
server["server"]["progress"] = instance.get("progress", 0)
context = request.environ['nova.context']
if show_AZ:
context = request.environ['nova.context']
az = avail_zone.get_instance_availability_zone(context, instance)
# NOTE(mriedem): The OS-EXT-AZ prefix should not be used for new
# attributes after v2.1. They are only in v2.1 for backward compat
@ -172,6 +178,40 @@ class ViewBuilder(common.ViewBuilder):
if show_config_drive:
server["server"]["config_drive"] = instance["config_drive"]
if show_extended_attr is None:
show_extended_attr = context.can(
esa_policies.BASE_POLICY_NAME, fatal=False)
if show_extended_attr:
server["server"][
"OS-EXT-SRV-ATTR:hypervisor_hostname"] = instance.node
properties = ['host', 'name']
if api_version_request.is_supported(request, min_version='2.3'):
# NOTE(mriedem): These will use the OS-EXT-SRV-ATTR prefix
# below and that's OK for microversion 2.3 which is being
# compatible with v2.0 for the ec2 API split out from Nova.
# After this, however, new microversions should not be using
# the OS-EXT-SRV-ATTR prefix.
properties += ['reservation_id', 'launch_index',
'hostname', 'kernel_id', 'ramdisk_id',
'root_device_name', 'user_data']
for attr in properties:
if attr == 'name':
key = "OS-EXT-SRV-ATTR:instance_%s" % attr
else:
# NOTE(mriedem): Nothing after microversion 2.3 should use
# the OS-EXT-SRV-ATTR prefix for the attribute key name.
key = "OS-EXT-SRV-ATTR:%s" % attr
server["server"][key] = instance[attr]
if (api_version_request.is_supported(request, min_version='2.16')):
if show_host_status is None:
show_host_status = context.can(
servers_policies.SERVERS % 'show:host_status', fatal=False)
if show_host_status:
host_status = self.compute_api.get_instance_host_status(
instance)
server["server"]['host_status'] = host_status
if api_version_request.is_supported(request, min_version="2.9"):
server["server"]["locked"] = (True if instance["locked_by"]
else False)
@ -209,11 +249,20 @@ class ViewBuilder(common.ViewBuilder):
fatal=False)
else:
show_extra_specs = False
context = request.environ['nova.context']
show_extended_attr = context.can(
esa_policies.BASE_POLICY_NAME, fatal=False)
show_host_status = False
if (api_version_request.is_supported(request, min_version='2.16')):
show_host_status = context.can(
servers_policies.SERVERS % 'show:host_status', fatal=False)
return self._list_view(self.show, request, instances, coll_name,
show_extra_specs)
show_extra_specs,
show_extended_attr=show_extended_attr,
show_host_status=show_host_status)
def _list_view(self, func, request, servers, coll_name, show_extra_specs):
def _list_view(self, func, request, servers, coll_name, show_extra_specs,
show_extended_attr=None, show_host_status=None):
"""Provide a view for a list of servers.
:param func: Function used to format the server data
@ -221,10 +270,16 @@ class ViewBuilder(common.ViewBuilder):
:param servers: List of servers in dictionary format
:param coll_name: Name of collection, used to generate the next link
for a pagination query
:param show_extended_attr: If the server extended attributes should be
included in the response dict.
:param show_host_status: If the host status should be included in
the response dict.
:returns: Server data in dictionary format
"""
server_list = [func(request, server,
show_extra_specs=show_extra_specs)["server"]
show_extra_specs=show_extra_specs,
show_extended_attr=show_extended_attr,
show_host_status=show_host_status)["server"]
for server in servers]
servers_links = self._get_collection_links(request,
servers,

View File

@ -1,246 +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 mock
from oslo_config import cfg
from oslo_serialization import jsonutils
from nova.api.openstack import wsgi as os_wsgi
from nova import compute
from nova import exception
from nova import objects
from nova import test
from nova.tests.unit.api.openstack import fakes
NAME_FMT = cfg.CONF.instance_name_template
UUID1 = '00000000-0000-0000-0000-000000000001'
UUID2 = '00000000-0000-0000-0000-000000000002'
UUID3 = '00000000-0000-0000-0000-000000000003'
UUID4 = '00000000-0000-0000-0000-000000000004'
UUID5 = '00000000-0000-0000-0000-000000000005'
def fake_services(host):
service_list = [objects.Service(id=0, host=host, forced_down=True,
binary='nova-compute')]
return objects.ServiceList(objects=service_list)
def fake_compute_get(*args, **kwargs):
return fakes.stub_instance_obj(
None, 1, uuid=UUID3, host="host-fake",
node="node-fake",
reservation_id="r-1", launch_index=0,
kernel_id=UUID4, ramdisk_id=UUID5,
display_name="hostname-1",
root_device_name="/dev/vda",
user_data="userdata",
services=fake_services("host-fake"))
def fake_compute_get_all(*args, **kwargs):
inst_list = [
fakes.stub_instance_obj(
None, 1, uuid=UUID1, host="host-1", node="node-1",
reservation_id="r-1", launch_index=0,
kernel_id=UUID4, ramdisk_id=UUID5,
display_name="hostname-1",
root_device_name="/dev/vda",
user_data="userdata",
services=fake_services("host-1")),
fakes.stub_instance_obj(
None, 2, uuid=UUID2, host="host-2", node="node-2",
reservation_id="r-2", launch_index=1,
kernel_id=UUID4, ramdisk_id=UUID5,
display_name="hostname-2",
root_device_name="/dev/vda",
user_data="userdata",
services=fake_services("host-2")),
]
return objects.InstanceList(objects=inst_list)
class ExtendedServerAttributesTestV21(test.TestCase):
content_type = 'application/json'
prefix = 'OS-EXT-SRV-ATTR:'
fake_url = '/v2/fake'
wsgi_api_version = os_wsgi.DEFAULT_API_VERSION
def setUp(self):
super(ExtendedServerAttributesTestV21, self).setUp()
fakes.stub_out_nw_api(self)
fakes.stub_out_secgroup_api(self)
self.stub_out('nova.compute.api.API.get', fake_compute_get)
self.stub_out('nova.compute.api.API.get_all', fake_compute_get_all)
self.stub_out('nova.db.api.instance_get_by_uuid', fake_compute_get)
def _make_request(self, url):
req = fakes.HTTPRequest.blank(url)
req.headers['Accept'] = self.content_type
req.headers = {os_wsgi.API_VERSION_REQUEST_HEADER:
'compute %s' % self.wsgi_api_version}
res = req.get_response(
fakes.wsgi_app_v21())
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 assertServerAttributes(self, server, host, node, instance_name):
self.assertEqual(server.get('%shost' % self.prefix), host)
self.assertEqual(server.get('%sinstance_name' % self.prefix),
instance_name)
self.assertEqual(server.get('%shypervisor_hostname' % self.prefix),
node)
def test_show(self):
url = self.fake_url + '/servers/%s' % UUID3
res = self._make_request(url)
self.assertEqual(res.status_int, 200)
self.assertServerAttributes(self._get_server(res.body),
host='host-fake',
node='node-fake',
instance_name=NAME_FMT % 1)
def test_detail(self):
url = self.fake_url + '/servers/detail'
res = self._make_request(url)
self.assertEqual(res.status_int, 200)
for i, server in enumerate(self._get_servers(res.body)):
self.assertServerAttributes(server,
host='host-%s' % (i + 1),
node='node-%s' % (i + 1),
instance_name=NAME_FMT % (i + 1))
@mock.patch.object(compute.api.API, 'get_all')
def test_detail_empty_instance_list_invalid_status(self,
mock_get_all_method):
mock_get_all_method.return_value = objects.InstanceList(objects=[])
url = "%s%s" % (self.fake_url, '/servers/detail?status=invalid_status')
res = self._make_request(url)
# check status code 200 with empty instance list
self.assertEqual(200, res.status_int)
self.assertEqual(0, len(self._get_servers(res.body)))
def test_no_instance_passthrough_404(self):
def fake_compute_get(*args, **kwargs):
raise exception.InstanceNotFound(instance_id='fake')
self.stub_out('nova.compute.api.API.get', fake_compute_get)
url = self.fake_url + '/servers/70f6db34-de8d-4fbd-aafb-4065bdfa6115'
res = self._make_request(url)
self.assertEqual(res.status_int, 404)
class ExtendedServerAttributesTestV23(ExtendedServerAttributesTestV21):
wsgi_api_version = '2.3'
def assertServerAttributes(self, server, host, node, instance_name,
reservation_id, launch_index, kernel_id,
ramdisk_id, hostname, root_device_name,
user_data):
super(ExtendedServerAttributesTestV23, self).assertServerAttributes(
server, host, node, instance_name)
self.assertEqual(server.get('%sreservation_id' % self.prefix),
reservation_id)
self.assertEqual(server.get('%slaunch_index' % self.prefix),
launch_index)
self.assertEqual(server.get('%skernel_id' % self.prefix),
kernel_id)
self.assertEqual(server.get('%sramdisk_id' % self.prefix),
ramdisk_id)
self.assertEqual(server.get('%shostname' % self.prefix),
hostname)
self.assertEqual(server.get('%sroot_device_name' % self.prefix),
root_device_name)
self.assertEqual(server.get('%suser_data' % self.prefix),
user_data)
def test_show(self):
url = self.fake_url + '/servers/%s' % UUID3
res = self._make_request(url)
self.assertEqual(res.status_int, 200)
self.assertServerAttributes(self._get_server(res.body),
host='host-fake',
node='node-fake',
instance_name=NAME_FMT % 1,
reservation_id="r-1",
launch_index=0,
kernel_id=UUID4,
ramdisk_id=UUID5,
hostname="hostname-1",
root_device_name="/dev/vda",
user_data="userdata")
def test_detail(self):
url = self.fake_url + '/servers/detail'
res = self._make_request(url)
self.assertEqual(res.status_int, 200)
for i, server in enumerate(self._get_servers(res.body)):
self.assertServerAttributes(server,
host='host-%s' % (i + 1),
node='node-%s' % (i + 1),
instance_name=NAME_FMT % (i + 1),
reservation_id="r-%s" % (i + 1),
launch_index=i,
kernel_id=UUID4,
ramdisk_id=UUID5,
hostname="hostname-%s" % (i + 1),
root_device_name="/dev/vda",
user_data="userdata")
class ExtendedServerAttributesTestV216(ExtendedServerAttributesTestV21):
wsgi_api_version = '2.16'
def assertServerAttributes(self, server, host, node, instance_name,
host_status):
super(ExtendedServerAttributesTestV216, self).assertServerAttributes(
server, host, node, instance_name)
self.assertEqual(server.get('host_status'), host_status)
def test_show(self):
url = self.fake_url + '/servers/%s' % UUID3
res = self._make_request(url)
self.assertEqual(res.status_int, 200)
self.assertServerAttributes(self._get_server(res.body),
host='host-fake',
node='node-fake',
instance_name=NAME_FMT % 1,
host_status="DOWN")
def test_detail(self):
url = self.fake_url + '/servers/detail'
res = self._make_request(url)
self.assertEqual(res.status_int, 200)
for i, server in enumerate(self._get_servers(res.body)):
self.assertServerAttributes(server,
host='host-%s' % (i + 1),
node='node-%s' % (i + 1),
instance_name=NAME_FMT % (i + 1),
host_status="DOWN")

View File

@ -73,6 +73,9 @@ CONF = nova.conf.CONF
FAKE_UUID = fakes.FAKE_UUID
UUID1 = '00000000-0000-0000-0000-000000000001'
UUID2 = '00000000-0000-0000-0000-000000000002'
INSTANCE_IDS = {FAKE_UUID: 1}
FIELDS = instance_obj.INSTANCE_DEFAULT_FIELDS
@ -159,7 +162,7 @@ class ControllerTest(test.TestCase):
self.flags(use_ipv6=False)
fakes.stub_out_key_pair_funcs(self)
fake.stub_out_image_service(self)
return_server = fakes.fake_compute_get(availability_zone='nova')
return_server = fakes.fake_compute_get(id=2, availability_zone='nova')
return_servers = fakes.fake_compute_get_all()
# Server sort keys extension is enabled in v21 so sort data is passed
# to the instance API and the sorted DB API is invoked
@ -379,6 +382,9 @@ class ServersControllerTest(ControllerTest):
"accessIPv6": '',
"OS-EXT-AZ:availability_zone": "nova",
"config_drive": None,
"OS-EXT-SRV-ATTR:host": None,
"OS-EXT-SRV-ATTR:hypervisor_hostname": None,
"OS-EXT-SRV-ATTR:instance_name": "instance-00000002",
}
}
@ -395,8 +401,6 @@ class ServersControllerTest(ControllerTest):
image_bookmark,
flavor_bookmark,
progress=0)
expected_server['server']['name'] = 'server1'
expected_server['server']['metadata']['seq'] = '1'
self.assertThat(res_dict, matchers.DictMatches(expected_server))
def test_get_server_empty_az(self):
@ -411,15 +415,12 @@ class ServersControllerTest(ControllerTest):
image_bookmark = "http://localhost/fake/images/10"
flavor_bookmark = "http://localhost/fake/flavors/2"
self.mock_get.side_effect = fakes.fake_compute_get(
id=2, vm_state=vm_states.ACTIVE, progress=100,
availability_zone='nova')
req = self.req('/fake/servers/%s' % FAKE_UUID)
res_dict = self.controller.show(req, FAKE_UUID)
expected_server = self._get_server_data_dict(FAKE_UUID,
image_bookmark,
flavor_bookmark)
flavor_bookmark,
progress=0)
self.assertThat(res_dict, matchers.DictMatches(expected_server))
self.mock_get.assert_called_once_with(
req.environ['nova.context'], FAKE_UUID,
@ -427,21 +428,15 @@ class ServersControllerTest(ControllerTest):
'numa_topology'])
def test_get_server_with_id_image_ref_by_id(self):
image_ref = "10"
image_bookmark = "http://localhost/fake/images/10"
flavor_id = "1"
flavor_bookmark = "http://localhost/fake/flavors/2"
self.mock_get.side_effect = fakes.fake_compute_get(
id=2, vm_state=vm_states.ACTIVE, image_ref=image_ref,
flavor_id=flavor_id, progress=100,
availability_zone='nova')
req = self.req('/fake/servers/%s' % FAKE_UUID)
res_dict = self.controller.show(req, FAKE_UUID)
expected_server = self._get_server_data_dict(FAKE_UUID,
image_bookmark,
flavor_bookmark)
flavor_bookmark,
progress=0)
self.assertThat(res_dict, matchers.DictMatches(expected_server))
self.mock_get.assert_called_once_with(
@ -1435,9 +1430,104 @@ class ServersControllerTest(ControllerTest):
self.assertIn('servers', self.controller.detail(req))
class ServersControllerTestV23(ServersControllerTest):
wsgi_api_version = '2.3'
def setUp(self):
super(ServersControllerTestV23, self).setUp()
self.mock_get.side_effect = fakes.fake_compute_get(
id=2, uuid=FAKE_UUID,
node="node-fake",
reservation_id="r-1", launch_index=0,
kernel_id=UUID1, ramdisk_id=UUID2,
display_name="server2",
root_device_name="/dev/vda",
user_data="userdata",
metadata={"seq": "2"},
availability_zone='nova')
def _get_server_data_dict(self, uuid, image_bookmark, flavor_bookmark,
status="ACTIVE", progress=100):
server_dict = super(ServersControllerTestV23,
self)._get_server_data_dict(uuid,
image_bookmark,
flavor_bookmark,
status,
progress)
server_dict['server']["OS-EXT-SRV-ATTR:hostname"] = "server2"
server_dict['server'][
"OS-EXT-SRV-ATTR:hypervisor_hostname"] = "node-fake"
server_dict['server']["OS-EXT-SRV-ATTR:kernel_id"] = UUID1
server_dict['server']["OS-EXT-SRV-ATTR:launch_index"] = 0
server_dict['server']["OS-EXT-SRV-ATTR:ramdisk_id"] = UUID2
server_dict['server']["OS-EXT-SRV-ATTR:reservation_id"] = "r-1"
server_dict['server']["OS-EXT-SRV-ATTR:root_device_name"] = "/dev/vda"
server_dict['server']["OS-EXT-SRV-ATTR:user_data"] = "userdata"
return server_dict
def test_show(self):
image_bookmark = "http://localhost/fake/images/10"
flavor_bookmark = "http://localhost/fake/flavors/2"
req = self.req('/fake/servers/%s' % FAKE_UUID)
res_dict = self.controller.show(req, FAKE_UUID)
expected_server = self._get_server_data_dict(FAKE_UUID,
image_bookmark,
flavor_bookmark,
progress=0)
self.assertThat(res_dict, matchers.DictMatches(expected_server))
def test_detail(self):
def fake_get_all(context, search_opts=None,
limit=None, marker=None,
expected_attrs=None, sort_keys=None, sort_dirs=None):
obj_list = []
for i in range(2):
server = fakes.stub_instance_obj(context,
id=2, uuid=FAKE_UUID,
node="node-fake",
reservation_id="r-1", launch_index=0,
kernel_id=UUID1, ramdisk_id=UUID2,
display_name="server2",
root_device_name="/dev/vda",
user_data="userdata",
metadata={"seq": "2"},
availability_zone='nova')
obj_list.append(server)
return objects.InstanceList(objects=obj_list)
self.mock_get_all.side_effect = None
self.mock_get_all.return_value = fake_get_all(context)
req = self.req('/fake/servers/detail')
servers_list = self.controller.detail(req)
image_bookmark = "http://localhost/fake/images/10"
flavor_bookmark = "http://localhost/fake/flavors/2"
expected_server = self._get_server_data_dict(FAKE_UUID,
image_bookmark,
flavor_bookmark,
progress=0)
self.assertIn(expected_server['server'], servers_list['servers'])
class ServersControllerTestV29(ServersControllerTest):
wsgi_api_version = '2.9'
def setUp(self):
super(ServersControllerTestV29, self).setUp()
self.mock_get.side_effect = fakes.fake_compute_get(
id=2, uuid=FAKE_UUID,
node="node-fake",
reservation_id="r-1", launch_index=0,
kernel_id=UUID1, ramdisk_id=UUID2,
display_name="server2",
root_device_name="/dev/vda",
user_data="userdata",
metadata={"seq": "2"},
availability_zone='nova')
def _get_server_data_dict(self, uuid, image_bookmark, flavor_bookmark,
status="ACTIVE", progress=100):
server_dict = super(ServersControllerTestV29,
@ -1447,6 +1537,15 @@ class ServersControllerTestV29(ServersControllerTest):
status,
progress)
server_dict['server']['locked'] = False
server_dict['server']["OS-EXT-SRV-ATTR:hostname"] = "server2"
server_dict['server'][
"OS-EXT-SRV-ATTR:hypervisor_hostname"] = "node-fake"
server_dict['server']["OS-EXT-SRV-ATTR:kernel_id"] = UUID1
server_dict['server']["OS-EXT-SRV-ATTR:launch_index"] = 0
server_dict['server']["OS-EXT-SRV-ATTR:ramdisk_id"] = UUID2
server_dict['server']["OS-EXT-SRV-ATTR:reservation_id"] = "r-1"
server_dict['server']["OS-EXT-SRV-ATTR:root_device_name"] = "/dev/vda"
server_dict['server']["OS-EXT-SRV-ATTR:user_data"] = "userdata"
return server_dict
def _test_get_server_with_lock(self, locked_by):
@ -1454,6 +1553,13 @@ class ServersControllerTestV29(ServersControllerTest):
flavor_bookmark = "http://localhost/fake/flavors/2"
self.mock_get.side_effect = fakes.fake_compute_get(
id=2, locked_by=locked_by, uuid=FAKE_UUID,
node="node-fake",
reservation_id="r-1", launch_index=0,
kernel_id=UUID1, ramdisk_id=UUID2,
display_name="server2",
root_device_name="/dev/vda",
user_data="userdata",
metadata={"seq": "2"},
availability_zone='nova')
req = self.req('/fake/servers/%s' % FAKE_UUID)
@ -1484,7 +1590,16 @@ class ServersControllerTestV29(ServersControllerTest):
s2_locked):
self.mock_get_all.side_effect = None
self.mock_get_all.return_value = fake_instance_get_all_with_locked(
context, [s1_locked, s2_locked])
context, [s1_locked, s2_locked],
node="node-fake",
reservation_id="r-1", launch_index=0,
kernel_id=UUID1, ramdisk_id=UUID2,
display_name="server2",
root_device_name="/dev/vda",
user_data="userdata",
metadata={"seq": "2"},
availability_zone='nova')
req = self.req('/fake/servers/detail')
servers_list = self.controller.detail(req)
# Check that each returned server has the same 'locked' value
@ -1525,9 +1640,111 @@ class ServersControllerTestV29(ServersControllerTest):
self.assertNotIn(key, search_opts)
class ServersControllerTestV216(ServersControllerTest):
wsgi_api_version = '2.16'
def setUp(self):
super(ServersControllerTestV216, self).setUp()
self.mock_get.side_effect = fakes.fake_compute_get(
id=2, uuid=FAKE_UUID,
node="node-fake",
reservation_id="r-1", launch_index=0,
kernel_id=UUID1, ramdisk_id=UUID2,
display_name="server2",
root_device_name="/dev/vda",
user_data="userdata",
metadata={"seq": "2"},
availability_zone='nova')
self.useFixture(fixtures.MockPatchObject(
compute_api.API, 'get_instance_host_status',
return_value='UP')).mock
def _get_server_data_dict(self, uuid, image_bookmark, flavor_bookmark,
status="ACTIVE", progress=100):
server_dict = super(ServersControllerTestV216,
self)._get_server_data_dict(uuid,
image_bookmark,
flavor_bookmark,
status,
progress)
server_dict['server']['locked'] = False
server_dict['server']["host_status"] = "UP"
server_dict['server']["OS-EXT-SRV-ATTR:hostname"] = "server2"
server_dict['server'][
"OS-EXT-SRV-ATTR:hypervisor_hostname"] = "node-fake"
server_dict['server']["OS-EXT-SRV-ATTR:kernel_id"] = UUID1
server_dict['server']["OS-EXT-SRV-ATTR:launch_index"] = 0
server_dict['server']["OS-EXT-SRV-ATTR:ramdisk_id"] = UUID2
server_dict['server']["OS-EXT-SRV-ATTR:reservation_id"] = "r-1"
server_dict['server']["OS-EXT-SRV-ATTR:root_device_name"] = "/dev/vda"
server_dict['server']["OS-EXT-SRV-ATTR:user_data"] = "userdata"
return server_dict
def test_show(self):
image_bookmark = "http://localhost/fake/images/10"
flavor_bookmark = "http://localhost/fake/flavors/2"
req = self.req('/fake/servers/%s' % FAKE_UUID)
res_dict = self.controller.show(req, FAKE_UUID)
expected_server = self._get_server_data_dict(FAKE_UUID,
image_bookmark,
flavor_bookmark,
progress=0)
self.assertThat(res_dict, matchers.DictMatches(expected_server))
def test_detail(self):
def fake_get_all(context, search_opts=None,
limit=None, marker=None,
expected_attrs=None, sort_keys=None, sort_dirs=None):
obj_list = []
for i in range(2):
server = fakes.stub_instance_obj(context,
id=2, uuid=FAKE_UUID,
node="node-fake",
reservation_id="r-1", launch_index=0,
kernel_id=UUID1, ramdisk_id=UUID2,
display_name="server2",
root_device_name="/dev/vda",
user_data="userdata",
metadata={"seq": "2"},
availability_zone='nova')
obj_list.append(server)
return objects.InstanceList(objects=obj_list)
self.mock_get_all.side_effect = None
self.mock_get_all.return_value = fake_get_all(context)
req = self.req('/fake/servers/detail')
servers_list = self.controller.detail(req)
image_bookmark = "http://localhost/fake/images/10"
flavor_bookmark = "http://localhost/fake/flavors/2"
expected_server = self._get_server_data_dict(FAKE_UUID,
image_bookmark,
flavor_bookmark,
progress=0)
self.assertIn(expected_server['server'], servers_list['servers'])
class ServersControllerTestV219(ServersControllerTest):
wsgi_api_version = '2.19'
def setUp(self):
super(ServersControllerTestV219, self).setUp()
self.mock_get.side_effect = fakes.fake_compute_get(
id=2, uuid=FAKE_UUID,
node="node-fake",
reservation_id="r-1", launch_index=0,
kernel_id=UUID1, ramdisk_id=UUID2,
display_name="server2",
root_device_name="/dev/vda",
user_data="userdata",
metadata={"seq": "2"},
availability_zone='nova')
self.useFixture(fixtures.MockPatchObject(
compute_api.API, 'get_instance_host_status',
return_value='UP')).mock
def _get_server_data_dict(self, uuid, image_bookmark, flavor_bookmark,
status="ACTIVE", progress=100, description=None):
server_dict = super(ServersControllerTestV219,
@ -1538,6 +1755,17 @@ class ServersControllerTestV219(ServersControllerTest):
progress)
server_dict['server']['locked'] = False
server_dict['server']['description'] = description
server_dict['server']["host_status"] = "UP"
server_dict['server']["OS-EXT-SRV-ATTR:hostname"] = "server2"
server_dict['server'][
"OS-EXT-SRV-ATTR:hypervisor_hostname"] = "node-fake"
server_dict['server']["OS-EXT-SRV-ATTR:kernel_id"] = UUID1
server_dict['server']["OS-EXT-SRV-ATTR:launch_index"] = 0
server_dict['server']["OS-EXT-SRV-ATTR:ramdisk_id"] = UUID2
server_dict['server']["OS-EXT-SRV-ATTR:reservation_id"] = "r-1"
server_dict['server']["OS-EXT-SRV-ATTR:root_device_name"] = "/dev/vda"
server_dict['server']["OS-EXT-SRV-ATTR:user_data"] = "userdata"
return server_dict
def _test_get_server_with_description(self, description):
@ -1545,6 +1773,13 @@ class ServersControllerTestV219(ServersControllerTest):
flavor_bookmark = "http://localhost/fake/flavors/2"
self.mock_get.side_effect = fakes.fake_compute_get(
id=2, display_description=description, uuid=FAKE_UUID,
node="node-fake",
reservation_id="r-1", launch_index=0,
kernel_id=UUID1, ramdisk_id=UUID2,
display_name="server2",
root_device_name="/dev/vda",
user_data="userdata",
metadata={"seq": "2"},
availability_zone='nova')
req = self.req('/fake/servers/%s' % FAKE_UUID)
@ -2088,8 +2323,19 @@ class ServersControllerRebuildInstanceTest(ControllerTest):
body = self.controller._action_rebuild(self.req, FAKE_UUID,
body=body).obj
self.assertNotIn('OS-EXT-AZ:availability_zone', body['server'])
self.assertNotIn('config_drive', body['server'])
get_only_fields = ['OS-EXT-AZ:availability_zone', 'config_drive',
'OS-EXT-SRV-ATTR:host',
'OS-EXT-SRV-ATTR:hypervisor_hostname',
'OS-EXT-SRV-ATTR:instance_name',
'OS-EXT-SRV-ATTR:hostname'
'OS-EXT-SRV-ATTR:kernel_id',
'OS-EXT-SRV-ATTR:launch_index',
'OS-EXT-SRV-ATTR:ramdisk_id',
'OS-EXT-SRV-ATTR:reservation_id',
'OS-EXT-SRV-ATTR:root_device_name',
'OS-EXT-SRV-ATTR:user_data', 'host_status']
for field in get_only_fields:
self.assertNotIn(field, body['server'])
@mock.patch.object(compute_api.API, 'start')
def test_start(self, mock_start):
@ -2684,8 +2930,19 @@ class ServersControllerUpdateTest(ControllerTest):
body = {'server': {'name': 'server_test'}}
req = self._get_request(body)
res_dict = self.controller.update(req, FAKE_UUID, body=body)
self.assertNotIn('OS-EXT-AZ:availability_zone', res_dict['server'])
self.assertNotIn('config_drive', res_dict['server'])
get_only_fields = ['OS-EXT-AZ:availability_zone', 'config_drive',
'OS-EXT-SRV-ATTR:host',
'OS-EXT-SRV-ATTR:hypervisor_hostname',
'OS-EXT-SRV-ATTR:instance_name',
'OS-EXT-SRV-ATTR:hostname'
'OS-EXT-SRV-ATTR:kernel_id',
'OS-EXT-SRV-ATTR:launch_index',
'OS-EXT-SRV-ATTR:ramdisk_id',
'OS-EXT-SRV-ATTR:reservation_id',
'OS-EXT-SRV-ATTR:root_device_name',
'OS-EXT-SRV-ATTR:user_data', 'host_status']
for field in get_only_fields:
self.assertNotIn(field, res_dict['server'])
def test_update_server_name_too_long(self):
body = {'server': {'name': 'x' * 256}}
@ -5996,6 +6253,9 @@ class ServersViewBuilderTest(test.TestCase):
"accessIPv6": '',
"OS-EXT-AZ:availability_zone": "nova",
"config_drive": None,
"OS-EXT-SRV-ATTR:host": None,
"OS-EXT-SRV-ATTR:hypervisor_hostname": None,
"OS-EXT-SRV-ATTR:instance_name": "instance-00000001",
}
}
@ -6077,6 +6337,9 @@ class ServersViewBuilderTest(test.TestCase):
"accessIPv6": '',
"OS-EXT-AZ:availability_zone": "nova",
"config_drive": None,
"OS-EXT-SRV-ATTR:host": None,
"OS-EXT-SRV-ATTR:hypervisor_hostname": None,
"OS-EXT-SRV-ATTR:instance_name": "instance-00000001",
}
}
@ -6257,6 +6520,9 @@ class ServersViewBuilderTest(test.TestCase):
"accessIPv6": '',
"OS-EXT-AZ:availability_zone": "nova",
"config_drive": None,
"OS-EXT-SRV-ATTR:host": None,
"OS-EXT-SRV-ATTR:hypervisor_hostname": None,
"OS-EXT-SRV-ATTR:instance_name": "instance-00000001",
}
}
@ -6335,6 +6601,9 @@ class ServersViewBuilderTest(test.TestCase):
"accessIPv6": '',
"OS-EXT-AZ:availability_zone": "nova",
"config_drive": None,
"OS-EXT-SRV-ATTR:host": None,
"OS-EXT-SRV-ATTR:hypervisor_hostname": None,
"OS-EXT-SRV-ATTR:instance_name": "instance-00000001",
}
}