From 9980b9ad52a24998bc36fc191118a3d924b0a880 Mon Sep 17 00:00:00 2001 From: Artom Lifshitz Date: Wed, 11 Jan 2023 06:31:45 -0500 Subject: [PATCH] Microversion 2.94: FQDN in hostname Extend microversion 2.90 to allow FQDNs in the hostname parameter. Multi-create with --hostname continues to be refused, returning error 400 to the user. This simplifies the code by not needing to handle any sort of suffix or prefix mangling of the FQDN to handle multiple instances. No other changes are made - not Neutron integration, metadata API changes (the FQDN will appear as-is in places where the hostname currently appears), etc. Change-Id: I47e397dc6da8263762479cc8ae4f8777a6d9d811 Implements: bp/fqdn-in-hostname --- api-ref/source/parameters.yaml | 3 + api-ref/source/servers-actions.inc | 5 ++ api-ref/source/servers.inc | 5 ++ .../v2.94/server-action-rebuild-resp.json | 80 +++++++++++++++++ .../servers/v2.94/server-action-rebuild.json | 15 ++++ .../servers/v2.94/server-create-req.json | 30 +++++++ .../servers/v2.94/server-create-resp.json | 22 +++++ .../servers/v2.94/server-get-resp.json | 81 +++++++++++++++++ .../servers/v2.94/server-update-req.json | 8 ++ .../servers/v2.94/server-update-resp.json | 78 ++++++++++++++++ .../servers/v2.94/servers-details-resp.json | 88 +++++++++++++++++++ .../servers/v2.94/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 | 3 +- .../compute/rest_api_version_history.rst | 8 ++ nova/api/openstack/compute/schemas/servers.py | 14 +++ nova/api/openstack/compute/servers.py | 9 +- nova/conf/api.py | 7 +- .../v2.94/server-action-rebuild-resp.json.tpl | 80 +++++++++++++++++ .../v2.94/server-action-rebuild.json.tpl | 15 ++++ .../servers/v2.94/server-create-req.json.tpl | 21 +++++ .../servers/v2.94/server-create-resp.json.tpl | 22 +++++ .../servers/v2.94/server-get-resp.json.tpl | 81 +++++++++++++++++ .../servers/v2.94/server-update-req.json.tpl | 8 ++ .../servers/v2.94/server-update-resp.json.tpl | 78 ++++++++++++++++ .../v2.94/servers-details-resp.json.tpl | 88 +++++++++++++++++++ .../servers/v2.94/servers-list-resp.json.tpl | 24 +++++ .../api_sample_tests/test_servers.py | 45 ++++++++++ .../microversion-2-94-59649401d5763286.yaml | 22 +++++ 30 files changed, 960 insertions(+), 8 deletions(-) create mode 100644 doc/api_samples/servers/v2.94/server-action-rebuild-resp.json create mode 100644 doc/api_samples/servers/v2.94/server-action-rebuild.json create mode 100644 doc/api_samples/servers/v2.94/server-create-req.json create mode 100644 doc/api_samples/servers/v2.94/server-create-resp.json create mode 100644 doc/api_samples/servers/v2.94/server-get-resp.json create mode 100644 doc/api_samples/servers/v2.94/server-update-req.json create mode 100644 doc/api_samples/servers/v2.94/server-update-resp.json create mode 100644 doc/api_samples/servers/v2.94/servers-details-resp.json create mode 100644 doc/api_samples/servers/v2.94/servers-list-resp.json create mode 100644 nova/tests/functional/api_sample_tests/api_samples/servers/v2.94/server-action-rebuild-resp.json.tpl create mode 100644 nova/tests/functional/api_sample_tests/api_samples/servers/v2.94/server-action-rebuild.json.tpl create mode 100644 nova/tests/functional/api_sample_tests/api_samples/servers/v2.94/server-create-req.json.tpl create mode 100644 nova/tests/functional/api_sample_tests/api_samples/servers/v2.94/server-create-resp.json.tpl create mode 100644 nova/tests/functional/api_sample_tests/api_samples/servers/v2.94/server-get-resp.json.tpl create mode 100644 nova/tests/functional/api_sample_tests/api_samples/servers/v2.94/server-update-req.json.tpl create mode 100644 nova/tests/functional/api_sample_tests/api_samples/servers/v2.94/server-update-resp.json.tpl create mode 100644 nova/tests/functional/api_sample_tests/api_samples/servers/v2.94/servers-details-resp.json.tpl create mode 100644 nova/tests/functional/api_sample_tests/api_samples/servers/v2.94/servers-list-resp.json.tpl create mode 100644 releasenotes/notes/microversion-2-94-59649401d5763286.yaml diff --git a/api-ref/source/parameters.yaml b/api-ref/source/parameters.yaml index aba8185a4b7..e185dce29db 100644 --- a/api-ref/source/parameters.yaml +++ b/api-ref/source/parameters.yaml @@ -6382,6 +6382,9 @@ server_hostname_req: description: | The hostname to configure for the instance in the metadata service. + Starting with microversion 2.94, this can be a Fully Qualified Domain Name + (FQDN) of up to 255 characters in length. + .. note:: This information is published via the metadata service and requires diff --git a/api-ref/source/servers-actions.inc b/api-ref/source/servers-actions.inc index 3b8b68d4ff7..bb9953afa0f 100644 --- a/api-ref/source/servers-actions.inc +++ b/api-ref/source/servers-actions.inc @@ -604,6 +604,11 @@ Request .. literalinclude:: ../../doc/api_samples/servers/v2.90/server-action-rebuild.json :language: javascript +**Example Rebuild Server (rebuild Action) (v2.94)** + +.. literalinclude:: ../../doc/api_samples/servers/v2.94/server-action-rebuild.json + :language: javascript + Response -------- diff --git a/api-ref/source/servers.inc b/api-ref/source/servers.inc index fa199e211c2..e72d0641b98 100644 --- a/api-ref/source/servers.inc +++ b/api-ref/source/servers.inc @@ -448,6 +448,11 @@ Request .. literalinclude:: ../../doc/api_samples/servers/v2.90/server-create-req.json :language: javascript +**Example Create Server With FQDN in Hostname (v2.94)** + +.. literalinclude:: ../../doc/api_samples/servers/v2.94/server-create-req.json + :language: javascript + Response -------- diff --git a/doc/api_samples/servers/v2.94/server-action-rebuild-resp.json b/doc/api_samples/servers/v2.94/server-action-rebuild-resp.json new file mode 100644 index 00000000000..7eeb568ea41 --- /dev/null +++ b/doc/api_samples/servers/v2.94/server-action-rebuild-resp.json @@ -0,0 +1,80 @@ +{ + "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" + } + ] + }, + "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.94/server-action-rebuild.json b/doc/api_samples/servers/v2.94/server-action-rebuild.json new file mode 100644 index 00000000000..b5401ad9ca1 --- /dev/null +++ b/doc/api_samples/servers/v2.94/server-action-rebuild.json @@ -0,0 +1,15 @@ +{ + "rebuild" : { + "accessIPv4" : "1.2.3.4", + "accessIPv6" : "80fe::", + "OS-DCF:diskConfig": "AUTO", + "imageRef" : "70a599e0-31e7-49b7-b260-868f441e862b", + "name" : "foobar", + "adminPass" : "seekr3t", + "hostname": "custom-hostname.example.com", + "metadata" : { + "meta_var" : "meta_val" + }, + "user_data": "ZWNobyAiaGVsbG8gd29ybGQi" + } +} diff --git a/doc/api_samples/servers/v2.94/server-create-req.json b/doc/api_samples/servers/v2.94/server-create-req.json new file mode 100644 index 00000000000..c6d4ce56407 --- /dev/null +++ b/doc/api_samples/servers/v2.94/server-create-req.json @@ -0,0 +1,30 @@ +{ + "server" : { + "accessIPv4": "1.2.3.4", + "accessIPv6": "80fe::", + "name" : "new-server-test", + "imageRef" : "70a599e0-31e7-49b7-b260-868f441e862b", + "flavorRef" : "1", + "availability_zone": "us-west", + "OS-DCF:diskConfig": "AUTO", + "hostname": "custom-hostname.example.com", + "metadata" : { + "My Server Name" : "Apache1" + }, + "personality": [ + { + "path": "/etc/banner.txt", + "contents": "ICAgICAgDQoiQSBjbG91ZCBkb2VzIG5vdCBrbm93IHdoeSBp dCBtb3ZlcyBpbiBqdXN0IHN1Y2ggYSBkaXJlY3Rpb24gYW5k IGF0IHN1Y2ggYSBzcGVlZC4uLkl0IGZlZWxzIGFuIGltcHVs c2lvbi4uLnRoaXMgaXMgdGhlIHBsYWNlIHRvIGdvIG5vdy4g QnV0IHRoZSBza3kga25vd3MgdGhlIHJlYXNvbnMgYW5kIHRo ZSBwYXR0ZXJucyBiZWhpbmQgYWxsIGNsb3VkcywgYW5kIHlv dSB3aWxsIGtub3csIHRvbywgd2hlbiB5b3UgbGlmdCB5b3Vy c2VsZiBoaWdoIGVub3VnaCB0byBzZWUgYmV5b25kIGhvcml6 b25zLiINCg0KLVJpY2hhcmQgQmFjaA==" + } + ], + "security_groups": [ + { + "name": "default" + } + ], + "user_data" : "IyEvYmluL2Jhc2gKL2Jpbi9zdQplY2hvICJJIGFtIGluIHlvdSEiCg==" + }, + "OS-SCH-HNT:scheduler_hints": { + "same_host": "48e6a9f6-30af-47e0-bc04-acaed113bb4e" + } +} diff --git a/doc/api_samples/servers/v2.94/server-create-resp.json b/doc/api_samples/servers/v2.94/server-create-resp.json new file mode 100644 index 00000000000..f50e29dd8be --- /dev/null +++ b/doc/api_samples/servers/v2.94/server-create-resp.json @@ -0,0 +1,22 @@ +{ + "server": { + "OS-DCF:diskConfig": "AUTO", + "adminPass": "6NpUwoz2QDRN", + "id": "f5dc173b-6804-445a-a6d8-c705dad5b5eb", + "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" + } + ], + "security_groups": [ + { + "name": "default" + } + ] + } +} diff --git a/doc/api_samples/servers/v2.94/server-get-resp.json b/doc/api_samples/servers/v2.94/server-get-resp.json new file mode 100644 index 00000000000..0a05b2f9178 --- /dev/null +++ b/doc/api_samples/servers/v2.94/server-get-resp.json @@ -0,0 +1,81 @@ +{ + "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": "nova", + "OS-EXT-SRV-ATTR:hostname": "custom-hostname.example.com", + "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, + "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.94/server-update-req.json b/doc/api_samples/servers/v2.94/server-update-req.json new file mode 100644 index 00000000000..1743f05fc7c --- /dev/null +++ b/doc/api_samples/servers/v2.94/server-update-req.json @@ -0,0 +1,8 @@ +{ + "server": { + "accessIPv4": "4.3.2.1", + "accessIPv6": "80fe::", + "OS-DCF:diskConfig": "AUTO", + "hostname" : "new-server-hostname.example.com" + } +} diff --git a/doc/api_samples/servers/v2.94/server-update-resp.json b/doc/api_samples/servers/v2.94/server-update-resp.json new file mode 100644 index 00000000000..4aa834f9ec1 --- /dev/null +++ b/doc/api_samples/servers/v2.94/server-update-resp.json @@ -0,0 +1,78 @@ +{ + "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-hostname.example.com", + "OS-EXT-STS:power_state": 1, + "OS-EXT-STS:task_state": null, + "OS-EXT-STS:vm_state": "active", + "os-extended-volumes:volumes_attached": [], + "OS-SRV-USG:launched_at": "2013-09-23T13:37:00.880302", + "OS-SRV-USG:terminated_at": null, + "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.94/servers-details-resp.json b/doc/api_samples/servers/v2.94/servers-details-resp.json new file mode 100644 index 00000000000..54b63fa523e --- /dev/null +++ b/doc/api_samples/servers/v2.94/servers-details-resp.json @@ -0,0 +1,88 @@ +{ + "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": "nova", + "OS-EXT-SRV-ATTR:hostname": "custom-hostname.example.com", + "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, + "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.94/servers-list-resp.json b/doc/api_samples/servers/v2.94/servers-list-resp.json new file mode 100644 index 00000000000..742d54b170c --- /dev/null +++ b/doc/api_samples/servers/v2.94/servers-list-resp.json @@ -0,0 +1,24 @@ +{ + "servers": [ + { + "id": "22c91117-08de-4894-9aa9-6ef382400985", + "links": [ + { + "href": "http://openstack.example.com/v2/6f70656e737461636b20342065766572/servers/22c91117-08de-4894-9aa9-6ef382400985", + "rel": "self" + }, + { + "href": "http://openstack.example.com/6f70656e737461636b20342065766572/servers/22c91117-08de-4894-9aa9-6ef382400985", + "rel": "bookmark" + } + ], + "name": "new-server-test" + } + ], + "servers_links": [ + { + "href": "http://openstack.example.com/v2.1/6f70656e737461636b20342065766572/servers?limit=1&marker=22c91117-08de-4894-9aa9-6ef382400985", + "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 78678556bfd..f2ed6a83b05 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.93", + "version": "2.94", "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 59b67279b71..7b39c94ef77 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.93", + "version": "2.94", "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 02afdbd850c..dda3cbbc748 100644 --- a/nova/api/openstack/api_version_request.py +++ b/nova/api/openstack/api_version_request.py @@ -253,6 +253,7 @@ ``POST /os-keypairs`` and allow including @ and dot (.) characters in keypair name. * 2.93 - Add support for volume backed server rebuild. + * 2.94 - Allow FQDN in server hostname. """ # The minimum and maximum versions of the API supported @@ -261,7 +262,7 @@ # 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.93' +_MAX_API_VERSION = '2.94' 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 00403101981..d4df0e81ede 100644 --- a/nova/api/openstack/compute/rest_api_version_history.rst +++ b/nova/api/openstack/compute/rest_api_version_history.rst @@ -1229,3 +1229,11 @@ Add support for volume backed server rebuild. The end user will provide the image with the rebuild command and it will rebuild the volume with the new image similar to the result of rebuilding an ephemeral disk. + +2.94 +--------------------- + +The ``hostname`` parameter to the ``POST /servers`` (create server), ``PUT +/servers/{id}`` (update server) and ``POST /servers/{server_id}/action +(rebuild)`` (rebuild server) APIs is now allowed to be a Fully Qualified Domain +Name (FQDN). diff --git a/nova/api/openstack/compute/schemas/servers.py b/nova/api/openstack/compute/schemas/servers.py index 300411de40a..0869f834348 100644 --- a/nova/api/openstack/compute/schemas/servers.py +++ b/nova/api/openstack/compute/schemas/servers.py @@ -360,6 +360,11 @@ create_v290['properties']['server'][ 'properties']['hostname'] = parameter_types.hostname +# Support FQDN as hostname +create_v294 = copy.deepcopy(create_v290) +create_v294['properties']['server'][ + 'properties']['hostname'] = parameter_types.fqdn + update = { 'type': 'object', 'properties': { @@ -391,6 +396,11 @@ update_v290['properties']['server'][ 'properties']['hostname'] = parameter_types.hostname + +update_v294 = copy.deepcopy(update_v290) +update_v294['properties']['server'][ + 'properties']['hostname'] = parameter_types.fqdn + rebuild = { 'type': 'object', 'properties': { @@ -449,6 +459,10 @@ rebuild_v290['properties']['rebuild']['properties'][ 'hostname'] = parameter_types.hostname +rebuild_v294 = copy.deepcopy(rebuild_v290) +rebuild_v294['properties']['rebuild']['properties'][ + 'hostname'] = parameter_types.fqdn + resize = { 'type': 'object', diff --git a/nova/api/openstack/compute/servers.py b/nova/api/openstack/compute/servers.py index 946d5a70425..33e74456fd4 100644 --- a/nova/api/openstack/compute/servers.py +++ b/nova/api/openstack/compute/servers.py @@ -677,7 +677,8 @@ def _process_hosts_for_create( @validation.schema(schema_servers.create_v263, '2.63', '2.66') @validation.schema(schema_servers.create_v267, '2.67', '2.73') @validation.schema(schema_servers.create_v274, '2.74', '2.89') - @validation.schema(schema_servers.create_v290, '2.90') + @validation.schema(schema_servers.create_v290, '2.90', '2.93') + @validation.schema(schema_servers.create_v294, '2.94') def create(self, req, body): """Creates a new server for a given user.""" context = req.environ['nova.context'] @@ -906,7 +907,8 @@ def _delete(self, context, req, instance_uuid): @validation.schema(schema_servers.update_v20, '2.0', '2.0') @validation.schema(schema_servers.update, '2.1', '2.18') @validation.schema(schema_servers.update_v219, '2.19', '2.89') - @validation.schema(schema_servers.update_v290, '2.90') + @validation.schema(schema_servers.update_v290, '2.90', '2.93') + @validation.schema(schema_servers.update_v294, '2.94') def update(self, req, id, body): """Update server then pass on to version-specific controller.""" @@ -1147,7 +1149,8 @@ def _action_resize(self, req, id, body): @validation.schema(schema_servers.rebuild_v254, '2.54', '2.56') @validation.schema(schema_servers.rebuild_v257, '2.57', '2.62') @validation.schema(schema_servers.rebuild_v263, '2.63', '2.89') - @validation.schema(schema_servers.rebuild_v290, '2.90') + @validation.schema(schema_servers.rebuild_v290, '2.90', '2.93') + @validation.schema(schema_servers.rebuild_v294, '2.94') def _action_rebuild(self, req, id, body): """Rebuild an instance with the given attributes.""" rebuild_dict = body['rebuild'] diff --git a/nova/conf/api.py b/nova/conf/api.py index 5c8a367e8e9..58cbc4931ee 100644 --- a/nova/conf/api.py +++ b/nova/conf/api.py @@ -225,8 +225,11 @@ help=""" Domain name used to configure FQDN for instances. -Configure a fully-qualified domain name for instance hostnames. If unset, only -the hostname without a domain will be configured. +Configure a fully-qualified domain name for instance hostnames. The value is +suffixed to the instance hostname from the database to construct the hostname +that appears in the metadata API. To disable this behavior (for example in +order to correctly support microversion's 2.94 FQDN hostnames), set this to the +empty string. Possible values: diff --git a/nova/tests/functional/api_sample_tests/api_samples/servers/v2.94/server-action-rebuild-resp.json.tpl b/nova/tests/functional/api_sample_tests/api_samples/servers/v2.94/server-action-rebuild-resp.json.tpl new file mode 100644 index 00000000000..486433733d9 --- /dev/null +++ b/nova/tests/functional/api_sample_tests/api_samples/servers/v2.94/server-action-rebuild-resp.json.tpl @@ -0,0 +1,80 @@ +{ + "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" + } + ] + }, + "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.94/server-action-rebuild.json.tpl b/nova/tests/functional/api_sample_tests/api_samples/servers/v2.94/server-action-rebuild.json.tpl new file mode 100644 index 00000000000..3becc83fba6 --- /dev/null +++ b/nova/tests/functional/api_sample_tests/api_samples/servers/v2.94/server-action-rebuild.json.tpl @@ -0,0 +1,15 @@ +{ + "rebuild" : { + "accessIPv4" : "%(access_ip_v4)s", + "accessIPv6" : "%(access_ip_v6)s", + "OS-DCF:diskConfig": "AUTO", + "imageRef" : "%(uuid)s", + "name" : "%(name)s", + "adminPass" : "%(pass)s", + "hostname": "%(hostname)s", + "metadata" : { + "meta_var" : "meta_val" + }, + "user_data": "ZWNobyAiaGVsbG8gd29ybGQi" + } +} diff --git a/nova/tests/functional/api_sample_tests/api_samples/servers/v2.94/server-create-req.json.tpl b/nova/tests/functional/api_sample_tests/api_samples/servers/v2.94/server-create-req.json.tpl new file mode 100644 index 00000000000..f83c78fdc96 --- /dev/null +++ b/nova/tests/functional/api_sample_tests/api_samples/servers/v2.94/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": "custom-hostname.example.com" + } +} diff --git a/nova/tests/functional/api_sample_tests/api_samples/servers/v2.94/server-create-resp.json.tpl b/nova/tests/functional/api_sample_tests/api_samples/servers/v2.94/server-create-resp.json.tpl new file mode 100644 index 00000000000..4b30e0cfbdb --- /dev/null +++ b/nova/tests/functional/api_sample_tests/api_samples/servers/v2.94/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.94/server-get-resp.json.tpl b/nova/tests/functional/api_sample_tests/api_samples/servers/v2.94/server-get-resp.json.tpl new file mode 100644 index 00000000000..ae2088619ad --- /dev/null +++ b/nova/tests/functional/api_sample_tests/api_samples/servers/v2.94/server-get-resp.json.tpl @@ -0,0 +1,81 @@ +{ + "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": "nova", + "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, + "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.94/server-update-req.json.tpl b/nova/tests/functional/api_sample_tests/api_samples/servers/v2.94/server-update-req.json.tpl new file mode 100644 index 00000000000..bc4be64a8e6 --- /dev/null +++ b/nova/tests/functional/api_sample_tests/api_samples/servers/v2.94/server-update-req.json.tpl @@ -0,0 +1,8 @@ +{ + "server": { + "accessIPv4": "%(access_ip_v4)s", + "accessIPv6": "%(access_ip_v6)s", + "OS-DCF:diskConfig": "AUTO", + "hostname": "new-server-hostname.example.com" + } +} diff --git a/nova/tests/functional/api_sample_tests/api_samples/servers/v2.94/server-update-resp.json.tpl b/nova/tests/functional/api_sample_tests/api_samples/servers/v2.94/server-update-resp.json.tpl new file mode 100644 index 00000000000..2adc16df5e2 --- /dev/null +++ b/nova/tests/functional/api_sample_tests/api_samples/servers/v2.94/server-update-resp.json.tpl @@ -0,0 +1,78 @@ +{ + "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": "", + "OS-DCF:diskConfig": "AUTO", + "OS-EXT-AZ:availability_zone": "us-west", + "OS-EXT-SRV-ATTR:hostname": "new-server-hostname.example.com", + "OS-EXT-STS:power_state": 1, + "OS-EXT-STS:task_state": null, + "OS-EXT-STS:vm_state": "active", + "os-extended-volumes:volumes_attached": [], + "OS-SRV-USG:launched_at": "%(strtime)s", + "OS-SRV-USG:terminated_at": null, + "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.94/servers-details-resp.json.tpl b/nova/tests/functional/api_sample_tests/api_samples/servers/v2.94/servers-details-resp.json.tpl new file mode 100644 index 00000000000..f49d21e7a24 --- /dev/null +++ b/nova/tests/functional/api_sample_tests/api_samples/servers/v2.94/servers-details-resp.json.tpl @@ -0,0 +1,88 @@ +{ + "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": "nova", + "OS-EXT-SRV-ATTR:hostname": "custom-hostname.example.com", + "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, + "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.94/servers-list-resp.json.tpl b/nova/tests/functional/api_sample_tests/api_samples/servers/v2.94/servers-list-resp.json.tpl new file mode 100644 index 00000000000..9cdb3aa6447 --- /dev/null +++ b/nova/tests/functional/api_sample_tests/api_samples/servers/v2.94/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 aa07b88247b..7679c9b7340 100644 --- a/nova/tests/functional/api_sample_tests/test_servers.py +++ b/nova/tests/functional/api_sample_tests/test_servers.py @@ -618,6 +618,13 @@ class ServersSampleJson290Test(ServersSampleJsonTest): ADMIN_API = False +class ServersSampleJson294Test(ServersSampleJsonTest): + microversion = '2.94' + scenarios = [('v2_94', {'api_major_version': 'v2.1'})] + use_common_server_post = False + ADMIN_API = False + + class ServersUpdateSampleJsonTest(ServersSampleBase): # Many of the 'os_compute_api:servers:*' policies are admin-only, and we @@ -702,6 +709,44 @@ def test_server_rebuild(self): self._verify_response('server-action-rebuild-resp', subs, resp, 202) +class ServersUpdateSampleJson294Test(ServersUpdateSampleJsonTest): + microversion = '2.94' + scenarios = [('v2_94', {'api_major_version': 'v2.1'})] + ADMIN_API = False + + def test_update_server(self): + uuid = self._post_server() + subs = {} + subs['hostid'] = '[a-f0-9]+' + subs['access_ip_v4'] = '1.2.3.4' + subs['access_ip_v6'] = '80fe::' + subs['hostname'] = 'updated-hostname.example.com' + response = self._do_put('servers/%s' % uuid, + 'server-update-req', subs) + self._verify_response('server-update-resp', subs, response, 200) + + def test_server_rebuild(self): + uuid = self._post_server() + params = { + 'uuid': self.glance.auto_disk_config_enabled_image['id'], + 'name': 'foobar', + 'pass': 'seekr3t', + 'hostid': '[a-f0-9]+', + 'access_ip_v4': '1.2.3.4', + 'access_ip_v6': '80fe::', + 'hostname': 'updated-hostname.example.com', + } + + resp = self._do_post( + 'servers/%s/action' % uuid, + 'server-action-rebuild', + params, + ) + subs = params.copy() + del subs['uuid'] + self._verify_response('server-action-rebuild-resp', subs, resp, 202) + + class ServerSortKeysJsonTests(ServersSampleBase): sample_dir = 'servers-sort' diff --git a/releasenotes/notes/microversion-2-94-59649401d5763286.yaml b/releasenotes/notes/microversion-2-94-59649401d5763286.yaml new file mode 100644 index 00000000000..d0927e6f758 --- /dev/null +++ b/releasenotes/notes/microversion-2-94-59649401d5763286.yaml @@ -0,0 +1,22 @@ +--- +features: + - | + The 2.94 microversion has been added. This microversion extends + microversion 2.90 by allowing Fully Qualified Domain Names (FQDN) wherever + the ``hostname`` is able to be specified. This consists of creating an + instance (``POST /servers``), updating an instance + (``PUT /servers/{id}``), or rebuilding an instance + (``POST /servers/{server_id}/action (rebuild)``). When using an FQDN as the + instance hostname, the ``[api]dhcp_domain`` configuration option must be + set to the empty string in order for the correct FQDN to appear in the + ``hostname`` field in the metadata API. + +upgrade: + - | + In order to make use of microversion's 2.94 FQDN hostnames, the + ``[api]dhcp_domain`` config option must be set to the empty string. If + this is not done, the ``hostname`` field in the metadata API will be + incorrect, as it will include the value of ``[api]dhcp_domain`` appended to + the instance's FQDN. Note that simply not setting ``[api]dhcp_domain`` is + not enough, as it has a default value of ``novalocal``. It must explicitly + be set to the empty string.