diff --git a/api-ref/source/parameters.yaml b/api-ref/source/parameters.yaml index 1f444bc2b6c2..efc046fe7649 100644 --- a/api-ref/source/parameters.yaml +++ b/api-ref/source/parameters.yaml @@ -3994,6 +3994,13 @@ image_progress: in: body required: true type: integer +image_properties: + description: | + The image properties key/value pairs. + in: body + required: true + type: object + min_version: 2.98 image_server: description: | The server booted from image. diff --git a/api-ref/source/servers-actions.inc b/api-ref/source/servers-actions.inc index 7a33990dbe26..f318f0ed9f0d 100644 --- a/api-ref/source/servers-actions.inc +++ b/api-ref/source/servers-actions.inc @@ -637,6 +637,7 @@ Response - image: image - image.id: image_id_body - image.links: links + - image.properties: image_properties - links: server_links - metadata: metadata_object - name: server_name @@ -678,6 +679,11 @@ Response - security_group.name: name_update_rebuild - host_status: host_status_update_rebuild +**Example Rebuild Server (rebuild Action) (v2.98)** + +.. literalinclude:: ../../doc/api_samples/servers/v2.98/server-action-rebuild-resp.json + :language: javascript + **Example Rebuild Server (rebuild Action) (v2.75)** .. literalinclude:: ../../doc/api_samples/servers/v2.75/server-action-rebuild-resp.json diff --git a/api-ref/source/servers.inc b/api-ref/source/servers.inc index b1653c433956..c64ea7515f62 100644 --- a/api-ref/source/servers.inc +++ b/api-ref/source/servers.inc @@ -681,6 +681,11 @@ Response - trusted_image_certificates: server_trusted_image_certificates_resp - locked_reason: locked_reason_resp +**Example List Servers Detailed (2.98)** + +.. literalinclude:: /../../doc/api_samples/servers/v2.98/servers-details-resp.json + :language: javascript + **Example List Servers Detailed (2.96)** .. literalinclude:: /../../doc/api_samples/servers/v2.96/servers-details-resp.json @@ -811,6 +816,11 @@ Response - server_groups: server_groups_2_71 - locked_reason: locked_reason_resp +**Example Show Server Details (2.98)** + +.. literalinclude:: ../../doc/api_samples/servers/v2.98/server-get-resp.json + :language: javascript + **Example Show Server Details (2.96)** .. literalinclude:: ../../doc/api_samples/servers/v2.96/server-get-resp.json diff --git a/doc/api_samples/servers/v2.98/server-action-rebuild-resp.json b/doc/api_samples/servers/v2.98/server-action-rebuild-resp.json new file mode 100644 index 000000000000..21e1680bdf00 --- /dev/null +++ b/doc/api_samples/servers/v2.98/server-action-rebuild-resp.json @@ -0,0 +1,91 @@ +{ + "server": { + "OS-DCF:diskConfig": "AUTO", + "OS-EXT-AZ:availability_zone": "us-west", + "OS-EXT-SRV-ATTR:hostname": "updated-hostname.example.com", + "OS-EXT-STS:power_state": 1, + "OS-EXT-STS:task_state": null, + "OS-EXT-STS:vm_state": "active", + "OS-SRV-USG:launched_at": "2021-08-19T15:16:22.177882", + "OS-SRV-USG:terminated_at": null, + "accessIPv4": "1.2.3.4", + "accessIPv6": "80fe::", + "addresses": { + "private": [ + { + "OS-EXT-IPS-MAC:mac_addr": "00:0c:29:0d:11:74", + "OS-EXT-IPS:type": "fixed", + "addr": "192.168.1.30", + "version": 4 + } + ] + }, + "adminPass": "seekr3t", + "config_drive": "", + "created": "2019-04-23T17:10:22Z", + "description": null, + "flavor": { + "disk": 1, + "ephemeral": 0, + "extra_specs": {}, + "original_name": "m1.tiny", + "ram": 512, + "swap": 0, + "vcpus": 1 + }, + "hostId": "2091634baaccdc4c5a1d57069c833e402921df696b7f970791b12ec6", + "id": "0c37a84a-c757-4f22-8c7f-0bf8b6970886", + "image": { + "id": "70a599e0-31e7-49b7-b260-868f441e862b", + "links": [ + { + "href": "http://openstack.example.com/6f70656e737461636b20342065766572/images/70a599e0-31e7-49b7-b260-868f441e862b", + "rel": "bookmark" + } + ], + "properties": { + "architecture": "x86_64", + "auto_disk_config": "True", + "base_image_ref": "70a599e0-31e7-49b7-b260-868f441e862b", + "container_format": "ova", + "disk_format": "vhd", + "kernel_id": "nokernel", + "min_disk": "1", + "min_ram": "0", + "ramdisk_id": "nokernel" + } + }, + "key_name": null, + "links": [ + { + "href": "http://openstack.example.com/v2.1/6f70656e737461636b20342065766572/servers/0c37a84a-c757-4f22-8c7f-0bf8b6970886", + "rel": "self" + }, + { + "href": "http://openstack.example.com/6f70656e737461636b20342065766572/servers/0c37a84a-c757-4f22-8c7f-0bf8b6970886", + "rel": "bookmark" + } + ], + "locked": false, + "locked_reason": null, + "metadata": { + "meta_var": "meta_val" + }, + "name": "foobar", + "os-extended-volumes:volumes_attached": [], + "progress": 0, + "security_groups": [ + { + "name": "default" + } + ], + "server_groups": [], + "status": "ACTIVE", + "tags": [], + "tenant_id": "6f70656e737461636b20342065766572", + "trusted_image_certificates": null, + "updated": "2019-04-23T17:10:24Z", + "user_data": "ZWNobyAiaGVsbG8gd29ybGQi", + "user_id": "fake" + } +} diff --git a/doc/api_samples/servers/v2.98/server-get-resp.json b/doc/api_samples/servers/v2.98/server-get-resp.json new file mode 100644 index 000000000000..252d30d407a8 --- /dev/null +++ b/doc/api_samples/servers/v2.98/server-get-resp.json @@ -0,0 +1,94 @@ +{ + "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" + } + ], + "properties": { + "architecture": "x86_64", + "auto_disk_config": "True", + "base_image_ref": "70a599e0-31e7-49b7-b260-868f441e862b", + "container_format": "ova", + "disk_format": "vhd", + "kernel_id": "nokernel", + "min_disk": "1", + "min_ram": "0", + "ramdisk_id": "nokernel" + } + }, + "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.98/servers-details-resp.json b/doc/api_samples/servers/v2.98/servers-details-resp.json new file mode 100644 index 000000000000..7555549621bb --- /dev/null +++ b/doc/api_samples/servers/v2.98/servers-details-resp.json @@ -0,0 +1,100 @@ +{ + "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" + } + ], + "properties": { + "architecture": "x86_64", + "auto_disk_config": "True", + "base_image_ref": "70a599e0-31e7-49b7-b260-868f441e862b", + "container_format": "ova", + "disk_format": "vhd", + "kernel_id": "nokernel", + "min_disk": "1", + "min_ram": "0", + "ramdisk_id": "nokernel" + } + }, + "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.98/servers-list-resp.json b/doc/api_samples/servers/v2.98/servers-list-resp.json new file mode 100644 index 000000000000..3932f907b989 --- /dev/null +++ b/doc/api_samples/servers/v2.98/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 197144bc28bb..0f7713fe29db 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.97", + "version": "2.98", "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 cdb5504f3d43..50f7be5071be 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.97", + "version": "2.98", "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 a90b1afad197..765dfeb2bd3d 100644 --- a/nova/api/openstack/api_version_request.py +++ b/nova/api/openstack/api_version_request.py @@ -265,6 +265,9 @@ REST_API_VERSION_HISTORY = """REST API Version History: attachment. ``DELETE /servers/{server_id}/shares/{share_id} which delete an attachment. + * 2.98 - Add support for returning embedded image properties in + ``server show`` and ``server list --long`` and in the ``server + rebuild`` responses. """ # The minimum and maximum versions of the API supported @@ -273,7 +276,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.97' +_MAX_API_VERSION = '2.98' 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 374e218265a5..c9f4a41f870a 100644 --- a/nova/api/openstack/compute/rest_api_version_history.rst +++ b/nova/api/openstack/compute/rest_api_version_history.rst @@ -1268,3 +1268,14 @@ display shares. For detailed insights and usage instructions, please refer to the `manage-shares documentation`_. .. _manage-shares documentation: https://docs.openstack.org/nova/latest/admin/manage-shares.html + +.. _microversion 2.98: + +2.98 +---- + +Add support for including image properties as new ``properties`` subkey +under the struct at the existing ``image`` key in the response for +``GET /servers/{server_id}`` (server show), ``GET /servers/detail`` +(list server --long) and in the rebuild case of +``POST /server/{server_id}/action`` (server rebuild) API response. diff --git a/nova/api/openstack/compute/schemas/servers.py b/nova/api/openstack/compute/schemas/servers.py index 906005b4a36f..a6635762ed00 100644 --- a/nova/api/openstack/compute/schemas/servers.py +++ b/nova/api/openstack/compute/schemas/servers.py @@ -1230,3 +1230,17 @@ rebuild_response_v296['properties']['server']['properties'].update({ rebuild_response_v296['properties']['server']['required'].append( 'pinned_availability_zone' ) +rebuild_response_v298 = copy.deepcopy(rebuild_response_v296) +rebuild_response_v298['properties']['server']['properties']['image'][ + 'oneOf'][1]['properties'].update({ + 'properties': { + 'type': 'object', + 'patternProperties': { + '^[a-zA-Z0-9_:. ]{1,255}$': { + 'type': 'string', + 'max_Length': 255, + }, + }, + 'additionalProperties': False, + }, +}) diff --git a/nova/api/openstack/compute/servers.py b/nova/api/openstack/compute/servers.py index e7b8266e50e8..93f76d348083 100644 --- a/nova/api/openstack/compute/servers.py +++ b/nova/api/openstack/compute/servers.py @@ -1188,7 +1188,9 @@ class ServersController(wsgi.Controller): @validation.response_body_schema( schema.rebuild_response_v275, '2.75', '2.95') @validation.response_body_schema( - schema.rebuild_response_v296, '2.96') + schema.rebuild_response_v296, '2.96', '2.97') + @validation.response_body_schema( + schema.rebuild_response_v298, '2.98') def _action_rebuild(self, req, id, body): """Rebuild an instance with the given attributes.""" rebuild_dict = body['rebuild'] diff --git a/nova/api/openstack/compute/views/servers.py b/nova/api/openstack/compute/views/servers.py index 6dfd16624f37..b910a1c356ce 100644 --- a/nova/api/openstack/compute/views/servers.py +++ b/nova/api/openstack/compute/views/servers.py @@ -584,13 +584,26 @@ class ViewBuilder(common.ViewBuilder): bookmark = self._image_builder._get_bookmark_link(request, image_id, "images") - return { + image = { "id": image_id, "links": [{ "rel": "bookmark", "href": bookmark, }], } + + if api_version_request.is_supported(request, min_version='2.98'): + image_props = {} + for key, value in instance.system_metadata.items(): + if key.startswith(utils.SM_IMAGE_PROP_PREFIX): + # remove prefix 'image_' at start of key, so that + # key 'image_' becomes '' + k = key.partition('_')[2] + image_props[k] = value + + image['properties'] = image_props + + return image else: return "" diff --git a/nova/tests/functional/api_sample_tests/api_samples/servers/v2.98/server-action-rebuild-resp.json.tpl b/nova/tests/functional/api_sample_tests/api_samples/servers/v2.98/server-action-rebuild-resp.json.tpl new file mode 100644 index 000000000000..653e75b0869a --- /dev/null +++ b/nova/tests/functional/api_sample_tests/api_samples/servers/v2.98/server-action-rebuild-resp.json.tpl @@ -0,0 +1,92 @@ +{ + "server": { + "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-SRV-USG:launched_at": "%(strtime)s", + "OS-SRV-USG:terminated_at": null, + "accessIPv4": "1.2.3.4", + "accessIPv6": "80fe::", + "addresses": { + "private": [ + { + "OS-EXT-IPS-MAC:mac_addr": "00:0c:29:0d:11:74", + "OS-EXT-IPS:type": "fixed", + "addr": "192.168.1.30", + "version": 4 + } + ] + }, + "adminPass": "seekr3t", + "config_drive": "", + "created": "%(isotime)s", + "description": null, + "flavor": { + "disk": 1, + "ephemeral": 0, + "extra_specs": {}, + "original_name": "m1.tiny", + "ram": 512, + "swap": 0, + "vcpus": 1 + }, + "hostId": "2091634baaccdc4c5a1d57069c833e402921df696b7f970791b12ec6", + "id": "%(id)s", + "image": { + "id": "%(uuid)s", + "links": [ + { + "href": "%(compute_endpoint)s/images/%(uuid)s", + "rel": "bookmark" + } + ], + "properties": { + "architecture": "x86_64", + "auto_disk_config": "True", + "base_image_ref": "%(uuid)s", + "container_format": "ova", + "disk_format": "vhd", + "kernel_id": "nokernel", + "min_disk": "1", + "min_ram": "0", + "ramdisk_id": "nokernel" + } + }, + "key_name": null, + "links": [ + { + "href": "%(versioned_compute_endpoint)s/servers/%(uuid)s", + "rel": "self" + }, + { + "href": "%(compute_endpoint)s/servers/%(id)s", + "rel": "bookmark" + } + ], + "locked": false, + "locked_reason": null, + "metadata": { + "meta_var": "meta_val" + }, + "name": "foobar", + "os-extended-volumes:volumes_attached": [], + "progress": 0, + "security_groups": [ + { + "name": "default" + } + ], + "server_groups": [], + "status": "ACTIVE", + "tags": [], + "tenant_id": "6f70656e737461636b20342065766572", + "trusted_image_certificates": null, + "updated": "%(isotime)s", + "user_data": "ZWNobyAiaGVsbG8gd29ybGQi", + "user_id": "fake" + } +} + diff --git a/nova/tests/functional/api_sample_tests/api_samples/servers/v2.98/server-create-req.json.tpl b/nova/tests/functional/api_sample_tests/api_samples/servers/v2.98/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.98/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.98/server-create-resp.json.tpl b/nova/tests/functional/api_sample_tests/api_samples/servers/v2.98/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.98/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.98/server-details-resp.json.tpl b/nova/tests/functional/api_sample_tests/api_samples/servers/v2.98/server-details-resp.json.tpl new file mode 100644 index 000000000000..38dbefebdba5 --- /dev/null +++ b/nova/tests/functional/api_sample_tests/api_samples/servers/v2.98/server-details-resp.json.tpl @@ -0,0 +1,93 @@ +{ + "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" + } + ], + "properties": { + "architecture": "x86_64", + "auto_disk_config": "True", + "base_image_ref": "%(uuid)s", + "container_format": "ova", + "disk_format": "vhd", + "kernel_id": "nokernel", + "min_disk": "1", + "min_ram": "0", + "ramdisk_id": "nokernel" + } + }, + "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.98/server-get-resp.json.tpl b/nova/tests/functional/api_sample_tests/api_samples/servers/v2.98/server-get-resp.json.tpl new file mode 100644 index 000000000000..1d9678524a9e --- /dev/null +++ b/nova/tests/functional/api_sample_tests/api_samples/servers/v2.98/server-get-resp.json.tpl @@ -0,0 +1,95 @@ + +{ + "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" + } + ], + "properties": { + "architecture": "x86_64", + "auto_disk_config": "True", + "base_image_ref": "%(uuid)s", + "container_format": "ova", + "disk_format": "vhd", + "kernel_id": "nokernel", + "min_disk": "1", + "min_ram": "0", + "ramdisk_id": "nokernel" + } + }, + "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.98/server-list-resp.json.tpl b/nova/tests/functional/api_sample_tests/api_samples/servers/v2.98/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.98/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.98/servers-details-resp.json.tpl b/nova/tests/functional/api_sample_tests/api_samples/servers/v2.98/servers-details-resp.json.tpl new file mode 100644 index 000000000000..fa1c6bbd1702 --- /dev/null +++ b/nova/tests/functional/api_sample_tests/api_samples/servers/v2.98/servers-details-resp.json.tpl @@ -0,0 +1,102 @@ + +{ + "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" + } + ], + "properties": { + "architecture": "x86_64", + "auto_disk_config": "True", + "base_image_ref": "%(uuid)s", + "container_format": "ova", + "disk_format": "vhd", + "kernel_id": "nokernel", + "min_disk": "1", + "min_ram": "0", + "ramdisk_id": "nokernel" + } + }, + "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.98/servers-list-resp.json.tpl b/nova/tests/functional/api_sample_tests/api_samples/servers/v2.98/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.98/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 e81853866fbb..23565ed42ad7 100644 --- a/nova/tests/functional/api_sample_tests/test_servers.py +++ b/nova/tests/functional/api_sample_tests/test_servers.py @@ -631,6 +631,12 @@ class ServersSampleJson296Test(ServersSampleJsonTest): ADMIN_API = False +class ServerSampleJson298Test(ServersSampleJsonTest): + microversion = '2.98' + scenarios = [('v2_98', {'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/api/openstack/compute/test_servers.py b/nova/tests/unit/api/openstack/compute/test_servers.py index 2fe6ee0f4543..e2bbc6399e3a 100644 --- a/nova/tests/unit/api/openstack/compute/test_servers.py +++ b/nova/tests/unit/api/openstack/compute/test_servers.py @@ -2818,6 +2818,10 @@ class ServersControllerTestV290(ControllerTest): self.assertEqual(uuids.fake, servers[0]['id']) +class ServersControllerTestV298(ServersControllerTestV290): + microversion = '2.98' + + class ServersControllerDeleteTest(ControllerTest): def setUp(self): diff --git a/releasenotes/notes/image-props-in-server-show-e28886d164774343.yaml b/releasenotes/notes/image-props-in-server-show-e28886d164774343.yaml new file mode 100644 index 000000000000..1d0e4d630159 --- /dev/null +++ b/releasenotes/notes/image-props-in-server-show-e28886d164774343.yaml @@ -0,0 +1,9 @@ +--- +features: + - | + The 2.98 microversion has been added. This microversion adds support for + including image properties as new ``properties`` subkey under the struct at + the existing ``image`` key in the response for ``GET /servers/{server_id}`` + (server show) and ``GET /servers/detail`` (list server --long) APIs. + Also the same is included in rebuild case of + ``POST /server/{server_id}/action`` (server rebuild) API response.