From c98c8d84eec6e65f1b67ae1ab8278d9c507a1a76 Mon Sep 17 00:00:00 2001 From: Rajesh Tailor Date: Wed, 3 Jan 2024 18:52:03 +0530 Subject: [PATCH] Add support for showing requested az in output As of now, the server show and server list --long output shows the availability zone, that is, the AZ to which the host of the instance belongs. There is no way to tell from this information if the instance create request included an AZ or not. This change adds a new api microversion to add support for including availability zone requested during instance create in server show and server list --long responses. Change-Id: If4cf09c1006a3f56d243b9c00712bb24d2a796d3 --- api-ref/source/parameters.yaml | 12 +++ api-ref/source/servers.inc | 12 +++ .../servers/v2.96/server-get-resp.json | 83 +++++++++++++++++ .../servers/v2.96/servers-details-resp.json | 89 ++++++++++++++++++ .../servers/v2.96/servers-list-resp.json | 24 +++++ .../versions/v21-version-get-resp.json | 2 +- .../versions/versions-get-resp.json | 2 +- nova/api/openstack/api_version_request.py | 4 +- .../compute/rest_api_version_history.rst | 8 ++ nova/api/openstack/compute/views/servers.py | 35 ++++++- nova/objects/request_spec.py | 20 +++- .../servers/v2.96/server-create-req.json.tpl | 21 +++++ .../servers/v2.96/server-create-resp.json.tpl | 22 +++++ .../v2.96/server-details-resp.json.tpl | 82 +++++++++++++++++ .../servers/v2.96/server-get-resp.json.tpl | 84 +++++++++++++++++ .../servers/v2.96/server-list-resp.json.tpl | 25 +++++ .../v2.96/servers-details-resp.json.tpl | 91 +++++++++++++++++++ .../servers/v2.96/servers-list-resp.json.tpl | 24 +++++ .../api_sample_tests/test_servers.py | 6 ++ nova/tests/unit/objects/test_objects.py | 2 +- .../microversion-2-96-ca56e1e5a4ee4e02.yaml | 7 ++ 21 files changed, 647 insertions(+), 8 deletions(-) create mode 100644 doc/api_samples/servers/v2.96/server-get-resp.json create mode 100644 doc/api_samples/servers/v2.96/servers-details-resp.json create mode 100644 doc/api_samples/servers/v2.96/servers-list-resp.json create mode 100644 nova/tests/functional/api_sample_tests/api_samples/servers/v2.96/server-create-req.json.tpl create mode 100644 nova/tests/functional/api_sample_tests/api_samples/servers/v2.96/server-create-resp.json.tpl create mode 100644 nova/tests/functional/api_sample_tests/api_samples/servers/v2.96/server-details-resp.json.tpl create mode 100644 nova/tests/functional/api_sample_tests/api_samples/servers/v2.96/server-get-resp.json.tpl create mode 100644 nova/tests/functional/api_sample_tests/api_samples/servers/v2.96/server-list-resp.json.tpl create mode 100644 nova/tests/functional/api_sample_tests/api_samples/servers/v2.96/servers-details-resp.json.tpl create mode 100644 nova/tests/functional/api_sample_tests/api_samples/servers/v2.96/servers-list-resp.json.tpl create mode 100644 releasenotes/notes/microversion-2-96-ca56e1e5a4ee4e02.yaml diff --git a/api-ref/source/parameters.yaml b/api-ref/source/parameters.yaml index 6200bd94604d..90c508ce8ca7 100644 --- a/api-ref/source/parameters.yaml +++ b/api-ref/source/parameters.yaml @@ -5695,6 +5695,18 @@ personality: required: false type: array max_version: 2.56 +pinned_availability_zone: + description: | + This is the availability zone requested during server creation. + Also when cross_az_attach option is false and booting an instance from + volume, the instance can be pinned to AZ and in that case, instance will + be scheduled on host belonging to pinned AZ. + Also when default_schedule_zone config option set to specific AZ, in that + case, instance would be pinned to that specific AZ, and instance will be + scheduled on host belonging to pinned AZ. + in: body + type: string + min_version: 2.96 policies: description: | A list of exactly one policy name to associate with the server group. The diff --git a/api-ref/source/servers.inc b/api-ref/source/servers.inc index e72d0641b980..b1653c433956 100644 --- a/api-ref/source/servers.inc +++ b/api-ref/source/servers.inc @@ -669,6 +669,7 @@ Response - fault.created: fault_created - fault.message: fault_message - fault.details: fault_details + - pinned_availability_zone: pinned_availability_zone - progress: progress - security_groups: security_groups_obj_optional - security_group.name: name @@ -680,6 +681,11 @@ Response - trusted_image_certificates: server_trusted_image_certificates_resp - locked_reason: locked_reason_resp +**Example List Servers Detailed (2.96)** + +.. literalinclude:: /../../doc/api_samples/servers/v2.96/servers-details-resp.json + :language: javascript + **Example List Servers Detailed (2.73)** .. literalinclude:: /../../doc/api_samples/servers/v2.73/servers-details-resp.json @@ -793,6 +799,7 @@ Response - fault.created: fault_created - fault.message: fault_message - fault.details: fault_details + - pinned_availability_zone: pinned_availability_zone - progress: progress - security_groups: security_groups_obj_optional - security_group.name: name @@ -804,6 +811,11 @@ Response - server_groups: server_groups_2_71 - locked_reason: locked_reason_resp +**Example Show Server Details (2.96)** + +.. literalinclude:: ../../doc/api_samples/servers/v2.96/server-get-resp.json + :language: javascript + **Example Show Server Details (2.73)** .. literalinclude:: ../../doc/api_samples/servers/v2.73/server-get-resp.json diff --git a/doc/api_samples/servers/v2.96/server-get-resp.json b/doc/api_samples/servers/v2.96/server-get-resp.json new file mode 100644 index 000000000000..7638f9b90d2a --- /dev/null +++ b/doc/api_samples/servers/v2.96/server-get-resp.json @@ -0,0 +1,83 @@ +{ + "server": { + "accessIPv4": "1.2.3.4", + "accessIPv6": "80fe::", + "addresses": { + "private": [ + { + "addr": "192.168.1.30", + "OS-EXT-IPS-MAC:mac_addr": "00:0c:29:0d:11:74", + "OS-EXT-IPS:type": "fixed", + "version": 4 + } + ] + }, + "created": "2013-09-03T04:01:32Z", + "description": null, + "locked": false, + "locked_reason": null, + "flavor": { + "disk": 1, + "ephemeral": 0, + "extra_specs": {}, + "original_name": "m1.tiny", + "ram": 512, + "swap": 0, + "vcpus": 1 + }, + "hostId": "92154fab69d5883ba2c8622b7e65f745dd33257221c07af363c51b29", + "id": "0e44cc9c-e052-415d-afbf-469b0d384170", + "image": { + "id": "70a599e0-31e7-49b7-b260-868f441e862b", + "links": [ + { + "href": "http://openstack.example.com/6f70656e737461636b20342065766572/images/70a599e0-31e7-49b7-b260-868f441e862b", + "rel": "bookmark" + } + ] + }, + "key_name": null, + "links": [ + { + "href": "http://openstack.example.com/v2/6f70656e737461636b20342065766572/servers/0e44cc9c-e052-415d-afbf-469b0d384170", + "rel": "self" + }, + { + "href": "http://openstack.example.com/6f70656e737461636b20342065766572/servers/0e44cc9c-e052-415d-afbf-469b0d384170", + "rel": "bookmark" + } + ], + "metadata": { + "My Server Name": "Apache1" + }, + "name": "new-server-test", + "config_drive": "", + "OS-DCF:diskConfig": "AUTO", + "OS-EXT-AZ:availability_zone": "us-west", + "OS-EXT-SRV-ATTR:hostname": "new-server-test", + "OS-EXT-STS:power_state": 1, + "OS-EXT-STS:task_state": null, + "OS-EXT-STS:vm_state": "active", + "os-extended-volumes:volumes_attached": [ + {"id": "volume_id1", "delete_on_termination": false}, + {"id": "volume_id2", "delete_on_termination": false} + ], + "OS-SRV-USG:launched_at": "2013-09-23T13:37:00.880302", + "OS-SRV-USG:terminated_at": null, + "pinned_availability_zone": "us-west", + "progress": 0, + "security_groups": [ + { + "name": "default" + } + ], + "server_groups": [], + "status": "ACTIVE", + "tags": [], + "tenant_id": "6f70656e737461636b20342065766572", + "trusted_image_certificates": null, + "updated": "2013-09-03T04:01:33Z", + "user_id": "fake" + } +} + diff --git a/doc/api_samples/servers/v2.96/servers-details-resp.json b/doc/api_samples/servers/v2.96/servers-details-resp.json new file mode 100644 index 000000000000..6c39476fda76 --- /dev/null +++ b/doc/api_samples/servers/v2.96/servers-details-resp.json @@ -0,0 +1,89 @@ +{ + "servers": [ + { + "accessIPv4": "1.2.3.4", + "accessIPv6": "80fe::", + "addresses": { + "private": [ + { + "addr": "192.168.1.30", + "OS-EXT-IPS-MAC:mac_addr": "00:0c:29:0d:11:74", + "OS-EXT-IPS:type": "fixed", + "version": 4 + } + ] + }, + "created": "2013-09-03T04:01:32Z", + "description": "", + "flavor": { + "disk": 1, + "ephemeral": 0, + "extra_specs": {}, + "original_name": "m1.tiny", + "ram": 512, + "swap": 0, + "vcpus": 1 + }, + "hostId": "bcf92836fc9ed4203a75cb0337afc7f917d2be504164b995c2334b25", + "id": "f5dc173b-6804-445a-a6d8-c705dad5b5eb", + "image": { + "id": "70a599e0-31e7-49b7-b260-868f441e862b", + "links": [ + { + "href": "http://openstack.example.com/6f70656e737461636b20342065766572/images/70a599e0-31e7-49b7-b260-868f441e862b", + "rel": "bookmark" + } + ] + }, + "key_name": null, + "links": [ + { + "href": "http://openstack.example.com/v2/6f70656e737461636b20342065766572/servers/f5dc173b-6804-445a-a6d8-c705dad5b5eb", + "rel": "self" + }, + { + "href": "http://openstack.example.com/6f70656e737461636b20342065766572/servers/f5dc173b-6804-445a-a6d8-c705dad5b5eb", + "rel": "bookmark" + } + ], + "metadata": { + "My Server Name": "Apache1" + }, + "name": "new-server-test", + "config_drive": "", + "locked": false, + "locked_reason": "", + "OS-DCF:diskConfig": "AUTO", + "OS-EXT-AZ:availability_zone": "us-west", + "OS-EXT-SRV-ATTR:hostname": "new-server-test", + "OS-EXT-STS:power_state": 1, + "OS-EXT-STS:task_state": null, + "OS-EXT-STS:vm_state": "active", + "os-extended-volumes:volumes_attached": [ + {"id": "volume_id1", "delete_on_termination": false}, + {"id": "volume_id2", "delete_on_termination": false} + ], + "OS-SRV-USG:launched_at": "2013-09-23T13:53:12.774549", + "OS-SRV-USG:terminated_at": null, + "pinned_availability_zone": "us-west", + "progress": 0, + "security_groups": [ + { + "name": "default" + } + ], + "status": "ACTIVE", + "tags": [], + "tenant_id": "6f70656e737461636b20342065766572", + "trusted_image_certificates": null, + "updated": "2013-09-03T04:01:32Z", + "user_id": "fake" + } + ], + "servers_links": [ + { + "href": "http://openstack.example.com/v2.1/6f70656e737461636b20342065766572/servers/detail?limit=1&marker=f5dc173b-6804-445a-a6d8-c705dad5b5eb", + "rel": "next" + } + ] +} diff --git a/doc/api_samples/servers/v2.96/servers-list-resp.json b/doc/api_samples/servers/v2.96/servers-list-resp.json new file mode 100644 index 000000000000..3932f907b989 --- /dev/null +++ b/doc/api_samples/servers/v2.96/servers-list-resp.json @@ -0,0 +1,24 @@ +{ + "servers": [ + { + "id": "3cfb801c-f03c-45ce-834b-d097b34e9534", + "links": [ + { + "href": "http://openstack.example.com/v2/6f70656e737461636b20342065766572/servers/3cfb801c-f03c-45ce-834b-d097b34e9534", + "rel": "self" + }, + { + "href": "http://openstack.example.com/6f70656e737461636b20342065766572/servers/3cfb801c-f03c-45ce-834b-d097b34e9534", + "rel": "bookmark" + } + ], + "name": "new-server-test" + } + ], + "servers_links": [ + { + "href": "http://openstack.example.com/v2.1/6f70656e737461636b20342065766572/servers?limit=1&marker=3cfb801c-f03c-45ce-834b-d097b34e9534", + "rel": "next" + } + ] +} diff --git a/doc/api_samples/versions/v21-version-get-resp.json b/doc/api_samples/versions/v21-version-get-resp.json index 3f285e601774..e1b7acede1c3 100644 --- a/doc/api_samples/versions/v21-version-get-resp.json +++ b/doc/api_samples/versions/v21-version-get-resp.json @@ -19,7 +19,7 @@ } ], "status": "CURRENT", - "version": "2.95", + "version": "2.96", "min_version": "2.1", "updated": "2013-07-23T11:33:21Z" } diff --git a/doc/api_samples/versions/versions-get-resp.json b/doc/api_samples/versions/versions-get-resp.json index 749fd4674f26..d36325e9b623 100644 --- a/doc/api_samples/versions/versions-get-resp.json +++ b/doc/api_samples/versions/versions-get-resp.json @@ -22,7 +22,7 @@ } ], "status": "CURRENT", - "version": "2.95", + "version": "2.96", "min_version": "2.1", "updated": "2013-07-23T11:33:21Z" } diff --git a/nova/api/openstack/api_version_request.py b/nova/api/openstack/api_version_request.py index 718ac7e8e66f..841b2211f8ec 100644 --- a/nova/api/openstack/api_version_request.py +++ b/nova/api/openstack/api_version_request.py @@ -255,6 +255,8 @@ REST_API_VERSION_HISTORY = """REST API Version History: * 2.93 - Add support for volume backed server rebuild. * 2.94 - Allow FQDN in server hostname. * 2.95 - Evacuate will now stop instance at destination. + * 2.96 - Add support for returning pinned_availability_zone in + ``server show`` and ``server list --long`` responses. """ # The minimum and maximum versions of the API supported @@ -263,7 +265,7 @@ REST_API_VERSION_HISTORY = """REST API Version History: # Note(cyeoh): This only applies for the v2.1 API once microversions # support is fully merged. It does not affect the V2 API. _MIN_API_VERSION = '2.1' -_MAX_API_VERSION = '2.95' +_MAX_API_VERSION = '2.96' DEFAULT_API_VERSION = _MIN_API_VERSION # Almost all proxy APIs which are related to network, images and baremetal diff --git a/nova/api/openstack/compute/rest_api_version_history.rst b/nova/api/openstack/compute/rest_api_version_history.rst index f44e2c7d00a3..956bd1e0e366 100644 --- a/nova/api/openstack/compute/rest_api_version_history.rst +++ b/nova/api/openstack/compute/rest_api_version_history.rst @@ -1247,3 +1247,11 @@ Any evacuated instances will be now stopped at destination. This requires minimum nova release 27.0.0, OpenStack release 2023.1 Antelope. Operators can still use previous microversion for older behavior. + +.. _microversion 2.96: + +2.96 +---- + +The ``server show`` and ``server list --long`` responses now include the +pinned availability zone as well. diff --git a/nova/api/openstack/compute/views/servers.py b/nova/api/openstack/compute/views/servers.py index 8e7b8d301978..6dfd16624f37 100644 --- a/nova/api/openstack/compute/views/servers.py +++ b/nova/api/openstack/compute/views/servers.py @@ -14,6 +14,8 @@ # License for the specific language governing permissions and limitations # under the License. +import collections + from oslo_log import log as logging from oslo_serialization import jsonutils @@ -94,7 +96,7 @@ class ViewBuilder(common.ViewBuilder): def basic(self, request, instance, show_extra_specs=False, show_extended_attr=None, show_host_status=None, show_sec_grp=None, bdms=None, cell_down_support=False, - show_user_data=False): + show_user_data=False, provided_az=None): """Generic, non-detailed view of an instance.""" if cell_down_support and 'display_name' not in instance: # NOTE(tssurya): If the microversion is >= 2.69, this boolean will @@ -218,13 +220,26 @@ class ViewBuilder(common.ViewBuilder): unknown_only = True return unknown_only + def _get_pinned_az(self, context, instance, provided_az): + pinned_az = '' + if provided_az is not None: + pinned_az = provided_az + else: + try: + req_spec = objects.RequestSpec.get_by_instance_uuid( + context, instance.uuid) + pinned_az = req_spec.availability_zone + except exception.RequestSpecNotFound: + pinned_az = '' + return pinned_az + def show(self, request, instance, extend_address=True, show_extra_specs=None, show_AZ=True, show_config_drive=True, show_extended_attr=None, show_host_status=None, show_keypair=True, show_srv_usg=True, show_sec_grp=True, show_extended_status=True, show_extended_volumes=True, bdms=None, cell_down_support=False, show_server_groups=False, - show_user_data=True): + show_user_data=True, provided_az=None): """Detailed view of a single instance.""" if show_extra_specs is None: # detail will pre-calculate this for us. If we're doing show, @@ -291,6 +306,9 @@ class ViewBuilder(common.ViewBuilder): # attributes after v2.1. They are only in v2.1 for backward compat # with v2.0. server["server"]["OS-EXT-AZ:availability_zone"] = az or '' + if api_version_request.is_supported(request, min_version='2.96'): + pinned_az = self._get_pinned_az(context, instance, provided_az) + server['server']['pinned_availability_zone'] = pinned_az if show_config_drive: server["server"]["config_drive"] = instance["config_drive"] @@ -498,12 +516,23 @@ class ViewBuilder(common.ViewBuilder): down. :returns: Server data in dictionary format """ + req_specs = None + req_specs_dict = collections.defaultdict(str) + if api_version_request.is_supported(request, min_version='2.96'): + context = request.environ['nova.context'] + instance_uuids = [s.uuid for s in servers] + req_specs = objects.RequestSpec.get_by_instance_uuids( + context, instance_uuids) + req_specs_dict = {req.instance_uuid: req.availability_zone + for req in req_specs} + server_list = [func(request, server, show_extra_specs=show_extra_specs, show_extended_attr=show_extended_attr, show_host_status=show_host_status, show_sec_grp=show_sec_grp, bdms=bdms, - cell_down_support=cell_down_support)["server"] + cell_down_support=cell_down_support, + provided_az=req_specs_dict[server.uuid])["server"] for server in servers # Filter out the fake marker instance created by the # fill_virtual_interface_list online data migration. diff --git a/nova/objects/request_spec.py b/nova/objects/request_spec.py index 48d69cbdb4bd..f068a212e4bf 100644 --- a/nova/objects/request_spec.py +++ b/nova/objects/request_spec.py @@ -59,7 +59,8 @@ class RequestSpec(base.NovaObject): # Version 1.12: Added requested_resources # Version 1.13: Added request_level_params # Version 1.14: Added requested_networks - VERSION = '1.14' + # Version 1.15: Added get_by_instance_uuids() + VERSION = '1.15' fields = { 'id': fields.IntegerField(), @@ -782,6 +783,23 @@ class RequestSpec(base.NovaObject): db_spec = cls._get_by_instance_uuid_from_db(context, instance_uuid) return cls._from_db_object(context, cls(), db_spec) + @staticmethod + @api_db_api.context_manager.reader + def _get_by_instance_uuids_from_db(context, instance_uuids): + db_specs = context.session.query(api_models.RequestSpec).filter( + api_models.RequestSpec.instance_uuid.in_(instance_uuids)).all() + return db_specs + + @base.remotable_classmethod + def get_by_instance_uuids(cls, context, instance_uuids): + req_specs = [] + if not instance_uuids: + return req_specs + db_specs = cls._get_by_instance_uuids_from_db(context, instance_uuids) + for db_spec in db_specs: + req_specs.append(cls._from_db_object(context, cls(), db_spec)) + return req_specs + @staticmethod @api_db_api.context_manager.writer def _create_in_db(context, updates): diff --git a/nova/tests/functional/api_sample_tests/api_samples/servers/v2.96/server-create-req.json.tpl b/nova/tests/functional/api_sample_tests/api_samples/servers/v2.96/server-create-req.json.tpl new file mode 100644 index 000000000000..286c9ed4aed2 --- /dev/null +++ b/nova/tests/functional/api_sample_tests/api_samples/servers/v2.96/server-create-req.json.tpl @@ -0,0 +1,21 @@ +{ + "server" : { + "accessIPv4": "%(access_ip_v4)s", + "accessIPv6": "%(access_ip_v6)s", + "name" : "new-server-test", + "imageRef" : "%(image_id)s", + "flavorRef" : "1", + "OS-DCF:diskConfig": "AUTO", + "metadata" : { + "My Server Name" : "Apache1" + }, + "security_groups": [ + { + "name": "default" + } + ], + "user_data" : "%(user_data)s", + "networks": "auto", + "hostname": "new-server-test" + } +} diff --git a/nova/tests/functional/api_sample_tests/api_samples/servers/v2.96/server-create-resp.json.tpl b/nova/tests/functional/api_sample_tests/api_samples/servers/v2.96/server-create-resp.json.tpl new file mode 100644 index 000000000000..4b30e0cfbdb8 --- /dev/null +++ b/nova/tests/functional/api_sample_tests/api_samples/servers/v2.96/server-create-resp.json.tpl @@ -0,0 +1,22 @@ +{ + "server": { + "OS-DCF:diskConfig": "AUTO", + "adminPass": "%(password)s", + "id": "%(id)s", + "links": [ + { + "href": "%(versioned_compute_endpoint)s/servers/%(uuid)s", + "rel": "self" + }, + { + "href": "%(compute_endpoint)s/servers/%(uuid)s", + "rel": "bookmark" + } + ], + "security_groups": [ + { + "name": "default" + } + ] + } +} diff --git a/nova/tests/functional/api_sample_tests/api_samples/servers/v2.96/server-details-resp.json.tpl b/nova/tests/functional/api_sample_tests/api_samples/servers/v2.96/server-details-resp.json.tpl new file mode 100644 index 000000000000..fd4131164e6d --- /dev/null +++ b/nova/tests/functional/api_sample_tests/api_samples/servers/v2.96/server-details-resp.json.tpl @@ -0,0 +1,82 @@ +{ + "server": { + "accessIPv4": "%(access_ip_v4)s", + "accessIPv6": "%(access_ip_v6)s", + "addresses": { + "private": [ + { + "addr": "%(ip)s", + "OS-EXT-IPS-MAC:mac_addr": "00:0c:29:0d:11:74", + "OS-EXT-IPS:type": "fixed", + "version": 4 + } + ] + }, + "created": "%(isotime)s", + "description": null, + "locked": false, + "locked_reason": null, + "flavor": { + "disk": 1, + "ephemeral": 0, + "extra_specs": {}, + "original_name": "m1.tiny", + "ram": 512, + "swap": 0, + "vcpus": 1 + }, + "hostId": "%(hostid)s", + "id": "%(id)s", + "image": { + "id": "%(uuid)s", + "links": [ + { + "href": "%(compute_endpoint)s/images/%(uuid)s", + "rel": "bookmark" + } + ] + }, + "key_name": null, + "links": [ + { + "href": "%(versioned_compute_endpoint)s/servers/%(uuid)s", + "rel": "self" + }, + { + "href": "%(compute_endpoint)s/servers/%(uuid)s", + "rel": "bookmark" + } + ], + "metadata": { + "My Server Name": "Apache1" + }, + "name": "new-server-test", + "config_drive": "%(cdrive)s", + "OS-DCF:diskConfig": "AUTO", + "OS-EXT-AZ:availability_zone": "us-west", + "OS-EXT-SRV-ATTR:hostname": "%(hostname)s", + "OS-EXT-STS:power_state": 1, + "OS-EXT-STS:task_state": null, + "OS-EXT-STS:vm_state": "active", + "os-extended-volumes:volumes_attached": [ + {"id": "volume_id1", "delete_on_termination": false}, + {"id": "volume_id2", "delete_on_termination": false} + ], + "OS-SRV-USG:launched_at": "%(strtime)s", + "OS-SRV-USG:terminated_at": null, + "pinned_availability_zone": "us-west", + "progress": 0, + "security_groups": [ + { + "name": "default" + } + ], + "server_groups": [], + "status": "ACTIVE", + "tags": [], + "tenant_id": "6f70656e737461636b20342065766572", + "trusted_image_certificates": null, + "updated": "%(isotime)s", + "user_id": "fake" + } +} diff --git a/nova/tests/functional/api_sample_tests/api_samples/servers/v2.96/server-get-resp.json.tpl b/nova/tests/functional/api_sample_tests/api_samples/servers/v2.96/server-get-resp.json.tpl new file mode 100644 index 000000000000..01064104831a --- /dev/null +++ b/nova/tests/functional/api_sample_tests/api_samples/servers/v2.96/server-get-resp.json.tpl @@ -0,0 +1,84 @@ + +{ + "server": { + "accessIPv4": "%(access_ip_v4)s", + "accessIPv6": "%(access_ip_v6)s", + "addresses": { + "private": [ + { + "addr": "%(ip)s", + "OS-EXT-IPS-MAC:mac_addr": "00:0c:29:0d:11:74", + "OS-EXT-IPS:type": "fixed", + "version": 4 + } + ] + }, + "created": "%(isotime)s", + "description": null, + "locked": false, + "locked_reason": null, + "flavor": { + "disk": 1, + "ephemeral": 0, + "extra_specs": {}, + "original_name": "m1.tiny", + "ram": 512, + "swap": 0, + "vcpus": 1 + }, + "hostId": "%(hostid)s", + "id": "%(id)s", + "image": { + "id": "%(uuid)s", + "links": [ + { + "href": "%(compute_endpoint)s/images/%(uuid)s", + "rel": "bookmark" + } + ] + }, + "key_name": null, + "links": [ + { + "href": "%(versioned_compute_endpoint)s/servers/%(uuid)s", + "rel": "self" + }, + { + "href": "%(compute_endpoint)s/servers/%(uuid)s", + "rel": "bookmark" + } + ], + "metadata": { + "My Server Name": "Apache1" + }, + "name": "new-server-test", + "config_drive": "%(cdrive)s", + "OS-DCF:diskConfig": "AUTO", + "OS-EXT-AZ:availability_zone": "us-west", + "OS-EXT-SRV-ATTR:hostname": "%(hostname)s", + "OS-EXT-STS:power_state": 1, + "OS-EXT-STS:task_state": null, + "OS-EXT-STS:vm_state": "active", + "os-extended-volumes:volumes_attached": [ + {"id": "volume_id1", "delete_on_termination": false}, + {"id": "volume_id2", "delete_on_termination": false} + ], + "OS-SRV-USG:launched_at": "%(strtime)s", + "OS-SRV-USG:terminated_at": null, + "pinned_availability_zone": "us-west", + "progress": 0, + "security_groups": [ + { + "name": "default" + } + ], + "server_groups": [], + "status": "ACTIVE", + "tags": [], + "tenant_id": "6f70656e737461636b20342065766572", + "trusted_image_certificates": null, + "updated": "%(isotime)s", + "user_id": "fake" + } +} + diff --git a/nova/tests/functional/api_sample_tests/api_samples/servers/v2.96/server-list-resp.json.tpl b/nova/tests/functional/api_sample_tests/api_samples/servers/v2.96/server-list-resp.json.tpl new file mode 100644 index 000000000000..42a21fff8527 --- /dev/null +++ b/nova/tests/functional/api_sample_tests/api_samples/servers/v2.96/server-list-resp.json.tpl @@ -0,0 +1,25 @@ +{ + "servers": [ + { + "id": "%(id)s", + "links": [ + { + "href": "%(versioned_compute_endpoint)s/servers/%(id)s", + "rel": "self" + }, + { + "href": "%(compute_endpoint)s/servers/%(id)s", + "rel": "bookmark" + } + ], + "name": "new-server-test" + } + ], + "servers_links": [ + { + "href": "%(versioned_compute_endpoint)s/servers?limit=1&marker=%(id)s", + "rel": "next" + } + ] +} + diff --git a/nova/tests/functional/api_sample_tests/api_samples/servers/v2.96/servers-details-resp.json.tpl b/nova/tests/functional/api_sample_tests/api_samples/servers/v2.96/servers-details-resp.json.tpl new file mode 100644 index 000000000000..45e2f8d29823 --- /dev/null +++ b/nova/tests/functional/api_sample_tests/api_samples/servers/v2.96/servers-details-resp.json.tpl @@ -0,0 +1,91 @@ + +{ + "servers": [ + { + "accessIPv4": "%(access_ip_v4)s", + "accessIPv6": "%(access_ip_v6)s", + "addresses": { + "private": [ + { + "addr": "%(ip)s", + "OS-EXT-IPS-MAC:mac_addr": "00:0c:29:0d:11:74", + "OS-EXT-IPS:type": "fixed", + "version": 4 + } + ] + }, + "created": "%(isotime)s", + "description": "", + "flavor": { + "disk": 1, + "ephemeral": 0, + "extra_specs": {}, + "original_name": "m1.tiny", + "ram": 512, + "swap": 0, + "vcpus": 1 + }, + "hostId": "%(hostid)s", + "id": "%(id)s", + "image": { + "id": "%(uuid)s", + "links": [ + { + "href": "%(compute_endpoint)s/images/%(uuid)s", + "rel": "bookmark" + } + ] + }, + "key_name": null, + "links": [ + { + "href": "%(versioned_compute_endpoint)s/servers/%(uuid)s", + "rel": "self" + }, + { + "href": "%(compute_endpoint)s/servers/%(id)s", + "rel": "bookmark" + } + ], + "metadata": { + "My Server Name": "Apache1" + }, + "name": "new-server-test", + "config_drive": "%(cdrive)s", + "locked": false, + "locked_reason": "", + "OS-DCF:diskConfig": "AUTO", + "OS-EXT-AZ:availability_zone": "us-west", + "OS-EXT-SRV-ATTR:hostname": "new-server-test", + "OS-EXT-STS:power_state": 1, + "OS-EXT-STS:task_state": null, + "OS-EXT-STS:vm_state": "active", + "os-extended-volumes:volumes_attached": [ + {"id": "volume_id1", "delete_on_termination": false}, + {"id": "volume_id2", "delete_on_termination": false} + ], + "OS-SRV-USG:launched_at": "%(strtime)s", + "OS-SRV-USG:terminated_at": null, + "pinned_availability_zone": "us-west", + "progress": 0, + "security_groups": [ + { + "name": "default" + } + ], + "status": "ACTIVE", + "tags": [], + "tenant_id": "6f70656e737461636b20342065766572", + "trusted_image_certificates": null, + "updated": "%(isotime)s", + "user_id": "fake" + } + ], + "servers_links": [ + { + "href": "%(versioned_compute_endpoint)s/servers/detail?limit=1&marker=%(id)s", + "rel": "next" + } + ] +} + diff --git a/nova/tests/functional/api_sample_tests/api_samples/servers/v2.96/servers-list-resp.json.tpl b/nova/tests/functional/api_sample_tests/api_samples/servers/v2.96/servers-list-resp.json.tpl new file mode 100644 index 000000000000..9cdb3aa64475 --- /dev/null +++ b/nova/tests/functional/api_sample_tests/api_samples/servers/v2.96/servers-list-resp.json.tpl @@ -0,0 +1,24 @@ +{ + "servers": [ + { + "id": "%(id)s", + "links": [ + { + "href": "%(versioned_compute_endpoint)s/servers/%(id)s", + "rel": "self" + }, + { + "href": "%(compute_endpoint)s/servers/%(id)s", + "rel": "bookmark" + } + ], + "name": "new-server-test" + } + ], + "servers_links": [ + { + "href": "%(versioned_compute_endpoint)s/servers?limit=1&marker=%(id)s", + "rel": "next" + } + ] +} diff --git a/nova/tests/functional/api_sample_tests/test_servers.py b/nova/tests/functional/api_sample_tests/test_servers.py index 7679c9b73400..e81853866fbb 100644 --- a/nova/tests/functional/api_sample_tests/test_servers.py +++ b/nova/tests/functional/api_sample_tests/test_servers.py @@ -625,6 +625,12 @@ class ServersSampleJson294Test(ServersSampleJsonTest): ADMIN_API = False +class ServersSampleJson296Test(ServersSampleJsonTest): + microversion = '2.96' + scenarios = [('v2_96', {'api_major_version': 'v2.1'})] + ADMIN_API = False + + class ServersUpdateSampleJsonTest(ServersSampleBase): # Many of the 'os_compute_api:servers:*' policies are admin-only, and we diff --git a/nova/tests/unit/objects/test_objects.py b/nova/tests/unit/objects/test_objects.py index 9c177277cf18..fde7b7dcef55 100644 --- a/nova/tests/unit/objects/test_objects.py +++ b/nova/tests/unit/objects/test_objects.py @@ -1155,7 +1155,7 @@ object_data = { 'QuotasNoOp': '1.3-d1593cf969c81846bc8192255ea95cce', 'RequestGroup': '1.3-0458d350a8ec9d0673f9be5640a990ce', 'RequestLevelParams': '1.1-3a718a0ae0bfdec669e7108631b3f313', - 'RequestSpec': '1.14-2cdbda368ca07e10905dc5fe96908a58', + 'RequestSpec': '1.15-c1c9d34236d87a37c008dcf8926199fa', 'Resource': '1.0-d8a2abbb380da583b995fd118f6a8953', 'ResourceList': '1.0-4a53826625cc280e15fae64a575e0879', 'ResourceMetadata': '1.0-77509ea1ea0dd750d5864b9bd87d3f9d', diff --git a/releasenotes/notes/microversion-2-96-ca56e1e5a4ee4e02.yaml b/releasenotes/notes/microversion-2-96-ca56e1e5a4ee4e02.yaml new file mode 100644 index 000000000000..4758e3620d3e --- /dev/null +++ b/releasenotes/notes/microversion-2-96-ca56e1e5a4ee4e02.yaml @@ -0,0 +1,7 @@ +--- +features: + - | + The 2.96 microversion has been added. This microversion adds + pinned_availability_zone in `server show` and `server list --long` + responses. +