api: Add support for 'hostname' parameter
Add microversion 2.90, which allows allows users to configure the hostname that will be exposed via the nova metadata service when creating their instance. Change-Id: I95047c1689ac14fa73eba48e19dc438988b78aad Signed-off-by: Stephen Finucane <stephenfin@redhat.com>
This commit is contained in:
parent
982d459c65
commit
5e2c31ab78
api-ref/source
doc/api_samples
servers/v2.90
server-action-rebuild-resp.jsonserver-action-rebuild.jsonserver-create-req.jsonserver-create-resp.jsonserver-get-resp.jsonserver-update-req.jsonserver-update-resp.jsonservers-details-resp.jsonservers-list-resp.json
versions
nova
api
openstack
validation
compute
exception.pypolicies
tests
functional/api_sample_tests
api_samples/servers/v2.90
server-action-rebuild-resp.json.tplserver-action-rebuild.json.tplserver-create-req.json.tplserver-create-resp.json.tplserver-get-resp.json.tplserver-update-req.json.tplserver-update-resp.json.tplservers-details-resp.json.tplservers-list-resp.json.tpl
test_servers.pyunit
releasenotes/notes
@ -737,8 +737,10 @@ hostname_query_server:
|
|||||||
description: |
|
description: |
|
||||||
Filter the server list result by the host name of server.
|
Filter the server list result by the host name of server.
|
||||||
|
|
||||||
This parameter is only valid when specified by administrators.
|
This parameter is only valid when specified by administrators until
|
||||||
If non-admin users specify this parameter, it is ignored.
|
microversion 2.90, after which it can be specified by all users.
|
||||||
|
If non-admin users specify this parameter before microversion 2.90, it is
|
||||||
|
ignored.
|
||||||
in: query
|
in: query
|
||||||
required: false
|
required: false
|
||||||
type: string
|
type: string
|
||||||
@ -6330,21 +6332,36 @@ server_host_create:
|
|||||||
required: false
|
required: false
|
||||||
type: string
|
type: string
|
||||||
min_version: 2.74
|
min_version: 2.74
|
||||||
server_hostname:
|
server_hostname: &server_hostname
|
||||||
in: body
|
in: body
|
||||||
required: false
|
required: false
|
||||||
type: string
|
type: string
|
||||||
description: |
|
description: |
|
||||||
The hostname set on the instance when it is booted.
|
The hostname of the instance reported in the metadata service.
|
||||||
By default, it appears in the response for administrative users only.
|
This parameter only appears in responses for administrators until
|
||||||
|
microversion 2.90, after which it is shown for all users.
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
|
||||||
|
This information is published via the metadata service and requires
|
||||||
|
application such as ``cloud-init`` to propogate it through to the
|
||||||
|
instance.
|
||||||
min_version: 2.3
|
min_version: 2.3
|
||||||
server_hostname_update_rebuild:
|
server_hostname_req:
|
||||||
in: body
|
in: body
|
||||||
required: false
|
required: false
|
||||||
type: string
|
type: string
|
||||||
description: |
|
description: |
|
||||||
The hostname set on the instance when it is booted.
|
The hostname to configure for the instance in the metadata service.
|
||||||
By default, it appears in the response for administrative users only.
|
|
||||||
|
.. note::
|
||||||
|
|
||||||
|
This information is published via the metadata service and requires
|
||||||
|
application such as ``cloud-init`` to propogate it through to the
|
||||||
|
instance.
|
||||||
|
min_version: 2.90
|
||||||
|
server_hostname_update_rebuild:
|
||||||
|
<<: *server_hostname
|
||||||
min_version: 2.75
|
min_version: 2.75
|
||||||
# This is the hypervisor_hostname in a POST (create instance) request body.
|
# This is the hypervisor_hostname in a POST (create instance) request body.
|
||||||
server_hypervisor_hostname_create:
|
server_hypervisor_hostname_create:
|
||||||
|
@ -22,6 +22,7 @@ into a server since Mitaka release.
|
|||||||
|
|
||||||
You can get an RDP, serial, SPICE, or VNC console for a server.
|
You can get an RDP, serial, SPICE, or VNC console for a server.
|
||||||
|
|
||||||
|
|
||||||
Add (Associate) Floating Ip (addFloatingIp Action) (DEPRECATED)
|
Add (Associate) Floating Ip (addFloatingIp Action) (DEPRECATED)
|
||||||
================================================================
|
================================================================
|
||||||
|
|
||||||
@ -469,6 +470,7 @@ Response
|
|||||||
|
|
||||||
If successful, this method does not return content in the response body.
|
If successful, this method does not return content in the response body.
|
||||||
|
|
||||||
|
|
||||||
.. _reboot:
|
.. _reboot:
|
||||||
|
|
||||||
Reboot Server (reboot Action)
|
Reboot Server (reboot Action)
|
||||||
@ -582,12 +584,18 @@ Request
|
|||||||
- key_name: key_name_rebuild_req
|
- key_name: key_name_rebuild_req
|
||||||
- user_data: user_data_rebuild_req
|
- user_data: user_data_rebuild_req
|
||||||
- trusted_image_certificates: server_trusted_image_certificates_rebuild_req
|
- trusted_image_certificates: server_trusted_image_certificates_rebuild_req
|
||||||
|
- hostname: server_hostname_req
|
||||||
|
|
||||||
**Example Rebuild Server (rebuild Action) (v2.63)**
|
**Example Rebuild Server (rebuild Action) (v2.63)**
|
||||||
|
|
||||||
.. literalinclude:: ../../doc/api_samples/servers/v2.63/server-action-rebuild.json
|
.. literalinclude:: ../../doc/api_samples/servers/v2.63/server-action-rebuild.json
|
||||||
:language: javascript
|
:language: javascript
|
||||||
|
|
||||||
|
**Example Rebuild Server (rebuild Action) (v2.90)**
|
||||||
|
|
||||||
|
.. literalinclude:: ../../doc/api_samples/servers/v2.90/server-action-rebuild.json
|
||||||
|
:language: javascript
|
||||||
|
|
||||||
Response
|
Response
|
||||||
--------
|
--------
|
||||||
|
|
||||||
@ -662,6 +670,7 @@ Response
|
|||||||
.. literalinclude:: ../../doc/api_samples/servers/v2.75/server-action-rebuild-resp.json
|
.. literalinclude:: ../../doc/api_samples/servers/v2.75/server-action-rebuild-resp.json
|
||||||
:language: javascript
|
:language: javascript
|
||||||
|
|
||||||
|
|
||||||
Remove (Disassociate) Floating Ip (removeFloatingIp Action) (DEPRECATED)
|
Remove (Disassociate) Floating Ip (removeFloatingIp Action) (DEPRECATED)
|
||||||
=========================================================================
|
=========================================================================
|
||||||
|
|
||||||
@ -791,6 +800,7 @@ Response
|
|||||||
.. literalinclude:: ../../doc/api_samples/os-rescue/server-rescue.json
|
.. literalinclude:: ../../doc/api_samples/os-rescue/server-rescue.json
|
||||||
:language: javascript
|
:language: javascript
|
||||||
|
|
||||||
|
|
||||||
Resize Server (resize Action)
|
Resize Server (resize Action)
|
||||||
=============================
|
=============================
|
||||||
|
|
||||||
|
@ -368,7 +368,6 @@ Request
|
|||||||
|
|
||||||
.. rest_parameters:: parameters.yaml
|
.. rest_parameters:: parameters.yaml
|
||||||
|
|
||||||
|
|
||||||
- server: server
|
- server: server
|
||||||
- flavorRef: flavorRef
|
- flavorRef: flavorRef
|
||||||
- name: server_name
|
- name: server_name
|
||||||
@ -404,6 +403,7 @@ Request
|
|||||||
- security_groups: security_groups
|
- security_groups: security_groups
|
||||||
- user_data: user_data
|
- user_data: user_data
|
||||||
- description: server_description
|
- description: server_description
|
||||||
|
- hostname: server_hostname_req
|
||||||
- tags: server_tags_create
|
- tags: server_tags_create
|
||||||
- trusted_image_certificates: server_trusted_image_certificates_create_req
|
- trusted_image_certificates: server_trusted_image_certificates_create_req
|
||||||
- host: server_host_create
|
- host: server_host_create
|
||||||
@ -443,6 +443,11 @@ Request
|
|||||||
.. literalinclude:: ../../doc/api_samples/servers/v2.74/server-create-req-with-host-and-node.json
|
.. literalinclude:: ../../doc/api_samples/servers/v2.74/server-create-req-with-host-and-node.json
|
||||||
:language: javascript
|
:language: javascript
|
||||||
|
|
||||||
|
**Example Create Server With Hostname (v2.90)**
|
||||||
|
|
||||||
|
.. literalinclude:: ../../doc/api_samples/servers/v2.90/server-create-req.json
|
||||||
|
:language: javascript
|
||||||
|
|
||||||
Response
|
Response
|
||||||
--------
|
--------
|
||||||
|
|
||||||
@ -633,8 +638,15 @@ Response
|
|||||||
- OS-DCF:diskConfig: disk_config
|
- OS-DCF:diskConfig: disk_config
|
||||||
- OS-EXT-AZ:availability_zone: OS-EXT-AZ:availability_zone
|
- OS-EXT-AZ:availability_zone: OS-EXT-AZ:availability_zone
|
||||||
- OS-EXT-SRV-ATTR:host: OS-EXT-SRV-ATTR:host
|
- OS-EXT-SRV-ATTR:host: OS-EXT-SRV-ATTR:host
|
||||||
|
- OS-EXT-SRV-ATTR:hostname: server_hostname
|
||||||
- OS-EXT-SRV-ATTR:hypervisor_hostname: OS-EXT-SRV-ATTR:hypervisor_hostname
|
- OS-EXT-SRV-ATTR:hypervisor_hostname: OS-EXT-SRV-ATTR:hypervisor_hostname
|
||||||
- OS-EXT-SRV-ATTR:instance_name: OS-EXT-SRV-ATTR:instance_name
|
- OS-EXT-SRV-ATTR:instance_name: OS-EXT-SRV-ATTR:instance_name
|
||||||
|
- OS-EXT-SRV-ATTR:kernel_id: server_kernel_id
|
||||||
|
- OS-EXT-SRV-ATTR:launch_index: server_launch_index
|
||||||
|
- OS-EXT-SRV-ATTR:ramdisk_id: server_ramdisk_id
|
||||||
|
- OS-EXT-SRV-ATTR:reservation_id: server_reservation_id
|
||||||
|
- OS-EXT-SRV-ATTR:root_device_name: server_root_device_name
|
||||||
|
- OS-EXT-SRV-ATTR:user_data: server_user_data
|
||||||
- OS-EXT-STS:power_state: OS-EXT-STS:power_state
|
- OS-EXT-STS:power_state: OS-EXT-STS:power_state
|
||||||
- OS-EXT-STS:task_state: OS-EXT-STS:task_state
|
- OS-EXT-STS:task_state: OS-EXT-STS:task_state
|
||||||
- OS-EXT-STS:vm_state: OS-EXT-STS:vm_state
|
- OS-EXT-STS:vm_state: OS-EXT-STS:vm_state
|
||||||
@ -656,13 +668,6 @@ Response
|
|||||||
- security_groups: security_groups_obj_optional
|
- security_groups: security_groups_obj_optional
|
||||||
- security_group.name: name
|
- security_group.name: name
|
||||||
- servers_links: servers_links
|
- servers_links: servers_links
|
||||||
- OS-EXT-SRV-ATTR:hostname: server_hostname
|
|
||||||
- OS-EXT-SRV-ATTR:reservation_id: server_reservation_id
|
|
||||||
- OS-EXT-SRV-ATTR:launch_index: server_launch_index
|
|
||||||
- OS-EXT-SRV-ATTR:kernel_id: server_kernel_id
|
|
||||||
- OS-EXT-SRV-ATTR:ramdisk_id: server_ramdisk_id
|
|
||||||
- OS-EXT-SRV-ATTR:root_device_name: server_root_device_name
|
|
||||||
- OS-EXT-SRV-ATTR:user_data: server_user_data
|
|
||||||
- locked: locked
|
- locked: locked
|
||||||
- host_status: host_status
|
- host_status: host_status
|
||||||
- description: server_description_resp
|
- description: server_description_resp
|
||||||
@ -757,8 +762,15 @@ Response
|
|||||||
- OS-DCF:diskConfig: disk_config
|
- OS-DCF:diskConfig: disk_config
|
||||||
- OS-EXT-AZ:availability_zone: OS-EXT-AZ:availability_zone
|
- OS-EXT-AZ:availability_zone: OS-EXT-AZ:availability_zone
|
||||||
- OS-EXT-SRV-ATTR:host: OS-EXT-SRV-ATTR:host
|
- OS-EXT-SRV-ATTR:host: OS-EXT-SRV-ATTR:host
|
||||||
|
- OS-EXT-SRV-ATTR:hostname: server_hostname
|
||||||
- OS-EXT-SRV-ATTR:hypervisor_hostname: OS-EXT-SRV-ATTR:hypervisor_hostname
|
- OS-EXT-SRV-ATTR:hypervisor_hostname: OS-EXT-SRV-ATTR:hypervisor_hostname
|
||||||
- OS-EXT-SRV-ATTR:instance_name: OS-EXT-SRV-ATTR:instance_name
|
- OS-EXT-SRV-ATTR:instance_name: OS-EXT-SRV-ATTR:instance_name
|
||||||
|
- OS-EXT-SRV-ATTR:kernel_id: server_kernel_id
|
||||||
|
- OS-EXT-SRV-ATTR:launch_index: server_launch_index
|
||||||
|
- OS-EXT-SRV-ATTR:ramdisk_id: server_ramdisk_id
|
||||||
|
- OS-EXT-SRV-ATTR:reservation_id: server_reservation_id
|
||||||
|
- OS-EXT-SRV-ATTR:root_device_name: server_root_device_name
|
||||||
|
- OS-EXT-SRV-ATTR:user_data: server_user_data
|
||||||
- OS-EXT-STS:power_state: OS-EXT-STS:power_state
|
- OS-EXT-STS:power_state: OS-EXT-STS:power_state
|
||||||
- OS-EXT-STS:task_state: OS-EXT-STS:task_state
|
- OS-EXT-STS:task_state: OS-EXT-STS:task_state
|
||||||
- OS-EXT-STS:vm_state: OS-EXT-STS:vm_state
|
- OS-EXT-STS:vm_state: OS-EXT-STS:vm_state
|
||||||
@ -779,13 +791,6 @@ Response
|
|||||||
- progress: progress
|
- progress: progress
|
||||||
- security_groups: security_groups_obj_optional
|
- security_groups: security_groups_obj_optional
|
||||||
- security_group.name: name
|
- security_group.name: name
|
||||||
- OS-EXT-SRV-ATTR:hostname: server_hostname
|
|
||||||
- OS-EXT-SRV-ATTR:reservation_id: server_reservation_id
|
|
||||||
- OS-EXT-SRV-ATTR:launch_index: server_launch_index
|
|
||||||
- OS-EXT-SRV-ATTR:kernel_id: server_kernel_id
|
|
||||||
- OS-EXT-SRV-ATTR:ramdisk_id: server_ramdisk_id
|
|
||||||
- OS-EXT-SRV-ATTR:root_device_name: server_root_device_name
|
|
||||||
- OS-EXT-SRV-ATTR:user_data: server_user_data
|
|
||||||
- locked: locked
|
- locked: locked
|
||||||
- host_status: host_status
|
- host_status: host_status
|
||||||
- description: server_description_resp
|
- description: server_description_resp
|
||||||
@ -830,10 +835,13 @@ Request
|
|||||||
- accessIPv4: accessIPv4_in
|
- accessIPv4: accessIPv4_in
|
||||||
- accessIPv6: accessIPv6_in
|
- accessIPv6: accessIPv6_in
|
||||||
- name: server_name_optional
|
- name: server_name_optional
|
||||||
|
- hostname: server_hostname_req
|
||||||
- OS-DCF:diskConfig: OS-DCF:diskConfig
|
- OS-DCF:diskConfig: OS-DCF:diskConfig
|
||||||
- description: server_description
|
- description: server_description
|
||||||
|
|
||||||
.. note:: You can specify parameters to update independently.
|
.. note::
|
||||||
|
|
||||||
|
You can specify parameters to update independently.
|
||||||
e.g. ``name`` only, ``description`` only, ``name`` and ``description``, etc.
|
e.g. ``name`` only, ``description`` only, ``name`` and ``description``, etc.
|
||||||
|
|
||||||
**Example Update Server (2.63)**
|
**Example Update Server (2.63)**
|
||||||
@ -889,18 +897,18 @@ Response
|
|||||||
- config_drive: config_drive_resp_update_rebuild
|
- config_drive: config_drive_resp_update_rebuild
|
||||||
- OS-EXT-AZ:availability_zone: OS-EXT-AZ:availability_zone_update_rebuild
|
- OS-EXT-AZ:availability_zone: OS-EXT-AZ:availability_zone_update_rebuild
|
||||||
- OS-EXT-SRV-ATTR:host: OS-EXT-SRV-ATTR:host_update_rebuild
|
- OS-EXT-SRV-ATTR:host: OS-EXT-SRV-ATTR:host_update_rebuild
|
||||||
|
- OS-EXT-SRV-ATTR:hostname: server_hostname_update_rebuild
|
||||||
- OS-EXT-SRV-ATTR:hypervisor_hostname: OS-EXT-SRV-ATTR:hypervisor_hostname_update_rebuild
|
- OS-EXT-SRV-ATTR:hypervisor_hostname: OS-EXT-SRV-ATTR:hypervisor_hostname_update_rebuild
|
||||||
- OS-EXT-SRV-ATTR:instance_name: OS-EXT-SRV-ATTR:instance_name_update_rebuild
|
- OS-EXT-SRV-ATTR:instance_name: OS-EXT-SRV-ATTR:instance_name_update_rebuild
|
||||||
|
- OS-EXT-SRV-ATTR:kernel_id: server_kernel_id_update_rebuild
|
||||||
|
- OS-EXT-SRV-ATTR:launch_index: server_launch_index_update_rebuild
|
||||||
|
- OS-EXT-SRV-ATTR:ramdisk_id: server_ramdisk_id_update_rebuild
|
||||||
|
- OS-EXT-SRV-ATTR:reservation_id: server_reservation_id_update_rebuild
|
||||||
|
- OS-EXT-SRV-ATTR:root_device_name: server_root_device_name_update_rebuild
|
||||||
|
- OS-EXT-SRV-ATTR:user_data: server_user_data_update
|
||||||
- OS-EXT-STS:power_state: OS-EXT-STS:power_state_update_rebuild
|
- OS-EXT-STS:power_state: OS-EXT-STS:power_state_update_rebuild
|
||||||
- OS-EXT-STS:task_state: OS-EXT-STS:task_state_update_rebuild
|
- OS-EXT-STS:task_state: OS-EXT-STS:task_state_update_rebuild
|
||||||
- OS-EXT-STS:vm_state: OS-EXT-STS:vm_state_update_rebuild
|
- OS-EXT-STS:vm_state: OS-EXT-STS:vm_state_update_rebuild
|
||||||
- OS-EXT-SRV-ATTR:hostname: server_hostname_update_rebuild
|
|
||||||
- OS-EXT-SRV-ATTR:reservation_id: server_reservation_id_update_rebuild
|
|
||||||
- OS-EXT-SRV-ATTR:launch_index: server_launch_index_update_rebuild
|
|
||||||
- OS-EXT-SRV-ATTR:kernel_id: server_kernel_id_update_rebuild
|
|
||||||
- OS-EXT-SRV-ATTR:ramdisk_id: server_ramdisk_id_update_rebuild
|
|
||||||
- OS-EXT-SRV-ATTR:root_device_name: server_root_device_name_update_rebuild
|
|
||||||
- OS-EXT-SRV-ATTR:user_data: server_user_data_update
|
|
||||||
- os-extended-volumes:volumes_attached: os-extended-volumes:volumes_attached_update_rebuild
|
- os-extended-volumes:volumes_attached: os-extended-volumes:volumes_attached_update_rebuild
|
||||||
- os-extended-volumes:volumes_attached.id: os-extended-volumes:volumes_attached.id_update_rebuild
|
- os-extended-volumes:volumes_attached.id: os-extended-volumes:volumes_attached.id_update_rebuild
|
||||||
- os-extended-volumes:volumes_attached.delete_on_termination: os-extended-volumes:volumes_attached.delete_on_termination_update_rebuild
|
- os-extended-volumes:volumes_attached.delete_on_termination: os-extended-volumes:volumes_attached.delete_on_termination_update_rebuild
|
||||||
|
@ -0,0 +1,80 @@
|
|||||||
|
{
|
||||||
|
"server": {
|
||||||
|
"OS-DCF:diskConfig": "AUTO",
|
||||||
|
"OS-EXT-AZ:availability_zone": "us-west",
|
||||||
|
"OS-EXT-SRV-ATTR:hostname": "updated-hostname",
|
||||||
|
"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"
|
||||||
|
}
|
||||||
|
}
|
15
doc/api_samples/servers/v2.90/server-action-rebuild.json
Normal file
15
doc/api_samples/servers/v2.90/server-action-rebuild.json
Normal file
@ -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",
|
||||||
|
"metadata" : {
|
||||||
|
"meta_var" : "meta_val"
|
||||||
|
},
|
||||||
|
"user_data": "ZWNobyAiaGVsbG8gd29ybGQi"
|
||||||
|
}
|
||||||
|
}
|
30
doc/api_samples/servers/v2.90/server-create-req.json
Normal file
30
doc/api_samples/servers/v2.90/server-create-req.json
Normal file
@ -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",
|
||||||
|
"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"
|
||||||
|
}
|
||||||
|
}
|
22
doc/api_samples/servers/v2.90/server-create-resp.json
Normal file
22
doc/api_samples/servers/v2.90/server-create-resp.json
Normal file
@ -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"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
81
doc/api_samples/servers/v2.90/server-get-resp.json
Normal file
81
doc/api_samples/servers/v2.90/server-get-resp.json
Normal file
@ -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",
|
||||||
|
"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"
|
||||||
|
}
|
||||||
|
}
|
8
doc/api_samples/servers/v2.90/server-update-req.json
Normal file
8
doc/api_samples/servers/v2.90/server-update-req.json
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"server": {
|
||||||
|
"accessIPv4": "4.3.2.1",
|
||||||
|
"accessIPv6": "80fe::",
|
||||||
|
"OS-DCF:diskConfig": "AUTO",
|
||||||
|
"hostname" : "new-server-hostname"
|
||||||
|
}
|
||||||
|
}
|
78
doc/api_samples/servers/v2.90/server-update-resp.json
Normal file
78
doc/api_samples/servers/v2.90/server-update-resp.json
Normal file
@ -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",
|
||||||
|
"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"
|
||||||
|
}
|
||||||
|
}
|
88
doc/api_samples/servers/v2.90/servers-details-resp.json
Normal file
88
doc/api_samples/servers/v2.90/servers-details-resp.json
Normal file
@ -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",
|
||||||
|
"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"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
24
doc/api_samples/servers/v2.90/servers-list-resp.json
Normal file
24
doc/api_samples/servers/v2.90/servers-list-resp.json
Normal file
@ -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"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
@ -19,7 +19,7 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"status": "CURRENT",
|
"status": "CURRENT",
|
||||||
"version": "2.89",
|
"version": "2.90",
|
||||||
"min_version": "2.1",
|
"min_version": "2.1",
|
||||||
"updated": "2013-07-23T11:33:21Z"
|
"updated": "2013-07-23T11:33:21Z"
|
||||||
}
|
}
|
||||||
|
@ -22,7 +22,7 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"status": "CURRENT",
|
"status": "CURRENT",
|
||||||
"version": "2.89",
|
"version": "2.90",
|
||||||
"min_version": "2.1",
|
"min_version": "2.1",
|
||||||
"updated": "2013-07-23T11:33:21Z"
|
"updated": "2013-07-23T11:33:21Z"
|
||||||
}
|
}
|
||||||
|
@ -243,7 +243,10 @@ REST_API_VERSION_HISTORY = """REST API Version History:
|
|||||||
* 2.89 - Add ``attachment_id``, ``bdm_uuid`` and remove ``id`` from the
|
* 2.89 - Add ``attachment_id``, ``bdm_uuid`` and remove ``id`` from the
|
||||||
responses of ``GET /servers/{server_id}/os-volume_attachments``
|
responses of ``GET /servers/{server_id}/os-volume_attachments``
|
||||||
and ``GET /servers/{server_id}/os-volume_attachments/{volume_id}``
|
and ``GET /servers/{server_id}/os-volume_attachments/{volume_id}``
|
||||||
|
* 2.90 - Add support for requesting a specific hostname when creating,
|
||||||
|
updating or rebuilding an instance. The
|
||||||
|
``OS-EXT-SRV-ATTR:hostname`` attribute is now returned in various
|
||||||
|
server responses regardless of policy configuration.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# The minimum and maximum versions of the API supported
|
# The minimum and maximum versions of the API supported
|
||||||
@ -252,7 +255,7 @@ REST_API_VERSION_HISTORY = """REST API Version History:
|
|||||||
# Note(cyeoh): This only applies for the v2.1 API once microversions
|
# Note(cyeoh): This only applies for the v2.1 API once microversions
|
||||||
# support is fully merged. It does not affect the V2 API.
|
# support is fully merged. It does not affect the V2 API.
|
||||||
_MIN_API_VERSION = '2.1'
|
_MIN_API_VERSION = '2.1'
|
||||||
_MAX_API_VERSION = '2.89'
|
_MAX_API_VERSION = '2.90'
|
||||||
DEFAULT_API_VERSION = _MIN_API_VERSION
|
DEFAULT_API_VERSION = _MIN_API_VERSION
|
||||||
|
|
||||||
# Almost all proxy APIs which are related to network, images and baremetal
|
# Almost all proxy APIs which are related to network, images and baremetal
|
||||||
|
@ -1180,11 +1180,25 @@ has been removed in favour of including this field in the primary ``GET
|
|||||||
|
|
||||||
.. _microversion 2.89:
|
.. _microversion 2.89:
|
||||||
|
|
||||||
2.89 (Maximum in Xena)
|
2.89
|
||||||
----------------------
|
----
|
||||||
|
|
||||||
``attachment_id`` and ``bdm_uuid`` are now included in the responses for ``GET
|
``attachment_id`` and ``bdm_uuid`` are now included in the responses for ``GET
|
||||||
/servers/{server_id}/os-volume_attachments`` and ``GET
|
/servers/{server_id}/os-volume_attachments`` and ``GET
|
||||||
/servers/{server_id}/os-volume_attachments/{volume_id}``. Additionally the
|
/servers/{server_id}/os-volume_attachments/{volume_id}``. Additionally the
|
||||||
``id`` field is dropped from the response as it duplicates the ``volumeId``
|
``id`` field is dropped from the response as it duplicates the ``volumeId``
|
||||||
field.
|
field.
|
||||||
|
|
||||||
|
.. _microversion 2.90:
|
||||||
|
|
||||||
|
2.90 (Maximum in Xena)
|
||||||
|
----------------------
|
||||||
|
|
||||||
|
The ``POST /servers`` (create server), ``PUT /servers/{id}`` (update server)
|
||||||
|
and ``POST /servers/{server_id}/action (rebuild)`` (rebuild server) APIs now
|
||||||
|
accept a ``hostname`` parameter, allowing users to configure a hostname when
|
||||||
|
creating the instance. When specified, this will replace the auto-generated
|
||||||
|
hostname based on the display name.
|
||||||
|
|
||||||
|
In addition, the ``OS-EXT-SRV-ATTR:hostname`` field for all server
|
||||||
|
responses is now visible to all users. Previously this was an admin-only field.
|
||||||
|
@ -355,6 +355,10 @@ create_v274['properties']['server'][
|
|||||||
create_v274['properties']['server'][
|
create_v274['properties']['server'][
|
||||||
'properties']['hypervisor_hostname'] = parameter_types.fqdn
|
'properties']['hypervisor_hostname'] = parameter_types.fqdn
|
||||||
|
|
||||||
|
# Add hostname in server
|
||||||
|
create_v290 = copy.deepcopy(create_v274)
|
||||||
|
create_v290['properties']['server'][
|
||||||
|
'properties']['hostname'] = parameter_types.hostname
|
||||||
|
|
||||||
update = {
|
update = {
|
||||||
'type': 'object',
|
'type': 'object',
|
||||||
@ -383,6 +387,10 @@ update_v219['properties']['server'][
|
|||||||
'properties']['description'] = parameter_types.description
|
'properties']['description'] = parameter_types.description
|
||||||
|
|
||||||
|
|
||||||
|
update_v290 = copy.deepcopy(update_v219)
|
||||||
|
update_v290['properties']['server'][
|
||||||
|
'properties']['hostname'] = parameter_types.hostname
|
||||||
|
|
||||||
rebuild = {
|
rebuild = {
|
||||||
'type': 'object',
|
'type': 'object',
|
||||||
'properties': {
|
'properties': {
|
||||||
@ -437,6 +445,10 @@ rebuild_v263 = copy.deepcopy(rebuild_v257)
|
|||||||
rebuild_v263['properties']['rebuild']['properties'][
|
rebuild_v263['properties']['rebuild']['properties'][
|
||||||
'trusted_image_certificates'] = parameter_types.trusted_certs
|
'trusted_image_certificates'] = parameter_types.trusted_certs
|
||||||
|
|
||||||
|
rebuild_v290 = copy.deepcopy(rebuild_v263)
|
||||||
|
rebuild_v290['properties']['rebuild']['properties'][
|
||||||
|
'hostname'] = parameter_types.hostname
|
||||||
|
|
||||||
|
|
||||||
resize = {
|
resize = {
|
||||||
'type': 'object',
|
'type': 'object',
|
||||||
|
@ -665,7 +665,8 @@ class ServersController(wsgi.Controller):
|
|||||||
@validation.schema(schema_servers.create_v257, '2.57', '2.62')
|
@validation.schema(schema_servers.create_v257, '2.57', '2.62')
|
||||||
@validation.schema(schema_servers.create_v263, '2.63', '2.66')
|
@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_v267, '2.67', '2.73')
|
||||||
@validation.schema(schema_servers.create_v274, '2.74')
|
@validation.schema(schema_servers.create_v274, '2.74', '2.89')
|
||||||
|
@validation.schema(schema_servers.create_v290, '2.90')
|
||||||
def create(self, req, body):
|
def create(self, req, body):
|
||||||
"""Creates a new server for a given user."""
|
"""Creates a new server for a given user."""
|
||||||
context = req.environ['nova.context']
|
context = req.environ['nova.context']
|
||||||
@ -675,6 +676,9 @@ class ServersController(wsgi.Controller):
|
|||||||
description = name
|
description = name
|
||||||
if api_version_request.is_supported(req, min_version='2.19'):
|
if api_version_request.is_supported(req, min_version='2.19'):
|
||||||
description = server_dict.get('description')
|
description = server_dict.get('description')
|
||||||
|
hostname = None
|
||||||
|
if api_version_request.is_supported(req, min_version='2.90'):
|
||||||
|
hostname = server_dict.get('hostname')
|
||||||
|
|
||||||
# Arguments to be passed to instance create function
|
# Arguments to be passed to instance create function
|
||||||
create_kwargs = {}
|
create_kwargs = {}
|
||||||
@ -772,6 +776,7 @@ class ServersController(wsgi.Controller):
|
|||||||
image_uuid,
|
image_uuid,
|
||||||
display_name=name,
|
display_name=name,
|
||||||
display_description=description,
|
display_description=description,
|
||||||
|
hostname=hostname,
|
||||||
availability_zone=availability_zone,
|
availability_zone=availability_zone,
|
||||||
forced_host=host, forced_node=node,
|
forced_host=host, forced_node=node,
|
||||||
metadata=server_dict.get('metadata', {}),
|
metadata=server_dict.get('metadata', {}),
|
||||||
@ -815,6 +820,7 @@ class ServersController(wsgi.Controller):
|
|||||||
exception.MismatchVolumeAZException,
|
exception.MismatchVolumeAZException,
|
||||||
exception.MultiplePortsNotApplicable,
|
exception.MultiplePortsNotApplicable,
|
||||||
exception.InvalidFixedIpAndMaxCountRequest,
|
exception.InvalidFixedIpAndMaxCountRequest,
|
||||||
|
exception.AmbiguousHostnameForMultipleInstances,
|
||||||
exception.InstanceUserDataMalformed,
|
exception.InstanceUserDataMalformed,
|
||||||
exception.PortNotFound,
|
exception.PortNotFound,
|
||||||
exception.FixedIpAlreadyInUse,
|
exception.FixedIpAlreadyInUse,
|
||||||
@ -888,7 +894,8 @@ class ServersController(wsgi.Controller):
|
|||||||
@wsgi.expected_errors(404)
|
@wsgi.expected_errors(404)
|
||||||
@validation.schema(schema_servers.update_v20, '2.0', '2.0')
|
@validation.schema(schema_servers.update_v20, '2.0', '2.0')
|
||||||
@validation.schema(schema_servers.update, '2.1', '2.18')
|
@validation.schema(schema_servers.update, '2.1', '2.18')
|
||||||
@validation.schema(schema_servers.update_v219, '2.19')
|
@validation.schema(schema_servers.update_v219, '2.19', '2.89')
|
||||||
|
@validation.schema(schema_servers.update_v290, '2.90')
|
||||||
def update(self, req, id, body):
|
def update(self, req, id, body):
|
||||||
"""Update server then pass on to version-specific controller."""
|
"""Update server then pass on to version-specific controller."""
|
||||||
|
|
||||||
@ -911,11 +918,14 @@ class ServersController(wsgi.Controller):
|
|||||||
# This is allowed to be None (remove description)
|
# This is allowed to be None (remove description)
|
||||||
update_dict['display_description'] = server['description']
|
update_dict['display_description'] = server['description']
|
||||||
|
|
||||||
|
if 'hostname' in server:
|
||||||
|
update_dict['hostname'] = server['hostname']
|
||||||
|
|
||||||
helpers.translate_attributes(helpers.UPDATE, server, update_dict)
|
helpers.translate_attributes(helpers.UPDATE, server, update_dict)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
instance = self.compute_api.update_instance(ctxt, instance,
|
instance = self.compute_api.update_instance(
|
||||||
update_dict)
|
ctxt, instance, update_dict)
|
||||||
|
|
||||||
# NOTE(gmann): Starting from microversion 2.75, PUT and Rebuild
|
# NOTE(gmann): Starting from microversion 2.75, PUT and Rebuild
|
||||||
# API response will show all attributes like GET /servers API.
|
# API response will show all attributes like GET /servers API.
|
||||||
@ -1134,7 +1144,8 @@ class ServersController(wsgi.Controller):
|
|||||||
@validation.schema(schema_servers.rebuild_v219, '2.19', '2.53')
|
@validation.schema(schema_servers.rebuild_v219, '2.19', '2.53')
|
||||||
@validation.schema(schema_servers.rebuild_v254, '2.54', '2.56')
|
@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_v257, '2.57', '2.62')
|
||||||
@validation.schema(schema_servers.rebuild_v263, '2.63')
|
@validation.schema(schema_servers.rebuild_v263, '2.63', '2.89')
|
||||||
|
@validation.schema(schema_servers.rebuild_v290, '2.90')
|
||||||
def _action_rebuild(self, req, id, body):
|
def _action_rebuild(self, req, id, body):
|
||||||
"""Rebuild an instance with the given attributes."""
|
"""Rebuild an instance with the given attributes."""
|
||||||
rebuild_dict = body['rebuild']
|
rebuild_dict = body['rebuild']
|
||||||
@ -1158,8 +1169,10 @@ class ServersController(wsgi.Controller):
|
|||||||
|
|
||||||
helpers.translate_attributes(helpers.REBUILD, rebuild_dict, kwargs)
|
helpers.translate_attributes(helpers.REBUILD, rebuild_dict, kwargs)
|
||||||
|
|
||||||
if (api_version_request.is_supported(req, min_version='2.54') and
|
if (
|
||||||
'key_name' in rebuild_dict):
|
api_version_request.is_supported(req, min_version='2.54') and
|
||||||
|
'key_name' in rebuild_dict
|
||||||
|
):
|
||||||
kwargs['key_name'] = rebuild_dict.get('key_name')
|
kwargs['key_name'] = rebuild_dict.get('key_name')
|
||||||
|
|
||||||
# If user_data is not specified, we don't include it in kwargs because
|
# If user_data is not specified, we don't include it in kwargs because
|
||||||
@ -1171,17 +1184,25 @@ class ServersController(wsgi.Controller):
|
|||||||
|
|
||||||
# Skip policy check for 'rebuild:trusted_certs' if no trusted
|
# Skip policy check for 'rebuild:trusted_certs' if no trusted
|
||||||
# certificate IDs were provided.
|
# certificate IDs were provided.
|
||||||
if ((api_version_request.is_supported(req, min_version='2.63')) and
|
if (
|
||||||
|
api_version_request.is_supported(req, min_version='2.63') and
|
||||||
# Note that this is different from server create since with
|
# Note that this is different from server create since with
|
||||||
# rebuild a user can unset/reset the trusted certs by
|
# rebuild a user can unset/reset the trusted certs by
|
||||||
# specifying trusted_image_certificates=None, similar to
|
# specifying trusted_image_certificates=None, similar to
|
||||||
# key_name.
|
# key_name.
|
||||||
('trusted_image_certificates' in rebuild_dict)):
|
'trusted_image_certificates' in rebuild_dict
|
||||||
|
):
|
||||||
kwargs['trusted_certs'] = rebuild_dict.get(
|
kwargs['trusted_certs'] = rebuild_dict.get(
|
||||||
'trusted_image_certificates')
|
'trusted_image_certificates')
|
||||||
context.can(server_policies.SERVERS % 'rebuild:trusted_certs',
|
context.can(server_policies.SERVERS % 'rebuild:trusted_certs',
|
||||||
target=target)
|
target=target)
|
||||||
|
|
||||||
|
if (
|
||||||
|
api_version_request.is_supported(req, min_version='2.90') and
|
||||||
|
'hostname' in rebuild_dict
|
||||||
|
):
|
||||||
|
kwargs['hostname'] = rebuild_dict['hostname']
|
||||||
|
|
||||||
for request_attribute, instance_attribute in attr_map.items():
|
for request_attribute, instance_attribute in attr_map.items():
|
||||||
try:
|
try:
|
||||||
if request_attribute == 'name':
|
if request_attribute == 'name':
|
||||||
@ -1380,6 +1401,8 @@ class ServersController(wsgi.Controller):
|
|||||||
'created_at', 'launched_at', 'terminated_at',
|
'created_at', 'launched_at', 'terminated_at',
|
||||||
'power_state', 'task_state', 'vm_state', 'progress',
|
'power_state', 'task_state', 'vm_state', 'progress',
|
||||||
'user_id',)
|
'user_id',)
|
||||||
|
if api_version_request.is_supported(req, min_version='2.90'):
|
||||||
|
opt_list += ('hostname',)
|
||||||
return opt_list
|
return opt_list
|
||||||
|
|
||||||
def _get_instance(self, context, instance_uuid):
|
def _get_instance(self, context, instance_uuid):
|
||||||
|
@ -313,6 +313,7 @@ class ViewBuilder(common.ViewBuilder):
|
|||||||
show_extended_attr = context.can(
|
show_extended_attr = context.can(
|
||||||
esa_policies.BASE_POLICY_NAME, fatal=False,
|
esa_policies.BASE_POLICY_NAME, fatal=False,
|
||||||
target={'project_id': instance.project_id})
|
target={'project_id': instance.project_id})
|
||||||
|
|
||||||
if show_extended_attr:
|
if show_extended_attr:
|
||||||
properties = ['host', 'name', 'node']
|
properties = ['host', 'name', 'node']
|
||||||
if api_version_request.is_supported(request, min_version='2.3'):
|
if api_version_request.is_supported(request, min_version='2.3'):
|
||||||
@ -342,6 +343,7 @@ class ViewBuilder(common.ViewBuilder):
|
|||||||
# the OS-EXT-SRV-ATTR prefix for the attribute key name.
|
# the OS-EXT-SRV-ATTR prefix for the attribute key name.
|
||||||
key = "OS-EXT-SRV-ATTR:%s" % attr
|
key = "OS-EXT-SRV-ATTR:%s" % attr
|
||||||
server["server"][key] = getattr(instance, attr)
|
server["server"][key] = getattr(instance, attr)
|
||||||
|
|
||||||
if show_extended_status:
|
if show_extended_status:
|
||||||
# NOTE(gmann): Removed 'locked_by' from extended status
|
# NOTE(gmann): Removed 'locked_by' from extended status
|
||||||
# to make it same as V2. If needed it can be added with
|
# to make it same as V2. If needed it can be added with
|
||||||
@ -352,6 +354,7 @@ class ViewBuilder(common.ViewBuilder):
|
|||||||
# compat with v2.0.
|
# compat with v2.0.
|
||||||
key = "%s:%s" % ('OS-EXT-STS', state)
|
key = "%s:%s" % ('OS-EXT-STS', state)
|
||||||
server["server"][key] = instance[state]
|
server["server"][key] = instance[state]
|
||||||
|
|
||||||
if show_extended_volumes:
|
if show_extended_volumes:
|
||||||
# NOTE(mriedem): The os-extended-volumes prefix should not be used
|
# NOTE(mriedem): The os-extended-volumes prefix should not be used
|
||||||
# for new attributes after v2.1. They are only in v2.1 for backward
|
# for new attributes after v2.1. They are only in v2.1 for backward
|
||||||
@ -364,7 +367,8 @@ class ViewBuilder(common.ViewBuilder):
|
|||||||
self._add_volumes_attachments(server["server"],
|
self._add_volumes_attachments(server["server"],
|
||||||
bdms,
|
bdms,
|
||||||
add_delete_on_termination)
|
add_delete_on_termination)
|
||||||
if (api_version_request.is_supported(request, min_version='2.16')):
|
|
||||||
|
if api_version_request.is_supported(request, min_version='2.16'):
|
||||||
if show_host_status is None:
|
if show_host_status is None:
|
||||||
unknown_only = self._get_host_status_unknown_only(
|
unknown_only = self._get_host_status_unknown_only(
|
||||||
context, instance)
|
context, instance)
|
||||||
@ -404,6 +408,13 @@ class ViewBuilder(common.ViewBuilder):
|
|||||||
trusted_certs = instance.trusted_certs.ids
|
trusted_certs = instance.trusted_certs.ids
|
||||||
server["server"]["trusted_image_certificates"] = trusted_certs
|
server["server"]["trusted_image_certificates"] = trusted_certs
|
||||||
|
|
||||||
|
if api_version_request.is_supported(request, min_version='2.90'):
|
||||||
|
# API 2.90 made this field visible to non-admins, but we only show
|
||||||
|
# it if it's not already added
|
||||||
|
if not show_extended_attr:
|
||||||
|
server["server"]["OS-EXT-SRV-ATTR:hostname"] = \
|
||||||
|
instance.hostname
|
||||||
|
|
||||||
if show_server_groups:
|
if show_server_groups:
|
||||||
server['server']['server_groups'] = self._get_server_groups(
|
server['server']['server_groups'] = self._get_server_groups(
|
||||||
context,
|
context,
|
||||||
|
@ -245,6 +245,38 @@ non_negative_integer = {
|
|||||||
'pattern': '^[0-9]*$', 'minimum': 0, 'minLength': 1
|
'pattern': '^[0-9]*$', 'minimum': 0, 'minLength': 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# A host-specific or leaf label.
|
||||||
|
#
|
||||||
|
# This is based on the specifications from two RFCs, RFCC 952 and RFC 1123.
|
||||||
|
#
|
||||||
|
# From RFC 952:
|
||||||
|
#
|
||||||
|
# A "name" (Net, Host, Gateway, or Domain name) is a text string up to 24
|
||||||
|
# characters drawn from the alphabet (A-Z), digits (0-9), minus sign (-), and
|
||||||
|
# period (.). Note that periods are only allowed when they serve to delimit
|
||||||
|
# components of "domain style names". (See RFC-921, "Domain Name System
|
||||||
|
# Implementation Schedule", for background). No blank or space characters are
|
||||||
|
# permitted as part of a name. No distinction is made between upper and lower
|
||||||
|
# case. The first character must be an alpha character. The last character
|
||||||
|
# must not be a minus sign or period. [...] Single character names or
|
||||||
|
# nicknames are not allowed.
|
||||||
|
#
|
||||||
|
# From RFC 1123, which revises RFC 952:
|
||||||
|
#
|
||||||
|
# The syntax of a legal Internet host name was specified in RFC-952 [DNS:4].
|
||||||
|
# One aspect of host name syntax is hereby changed: the restriction on the
|
||||||
|
# first character is relaxed to allow either a letter or a digit. Host
|
||||||
|
# software MUST support this more liberal syntax.
|
||||||
|
#
|
||||||
|
# Host software MUST handle host names of up to 63 characters and SHOULD
|
||||||
|
# handle host names of up to 255 characters.
|
||||||
|
hostname = {
|
||||||
|
'type': 'string',
|
||||||
|
'minLength': 2,
|
||||||
|
'maxLength': 63,
|
||||||
|
'pattern': '^[a-zA-Z0-9]+[a-zA-Z0-9-]*[a-zA-Z0-9]+$',
|
||||||
|
}
|
||||||
|
|
||||||
fqdn = {
|
fqdn = {
|
||||||
'type': 'string', 'minLength': 1, 'maxLength': 255,
|
'type': 'string', 'minLength': 1, 'maxLength': 255,
|
||||||
# NOTE: 'host' is defined in "services" table, and that
|
# NOTE: 'host' is defined in "services" table, and that
|
||||||
|
@ -999,7 +999,7 @@ class API:
|
|||||||
|
|
||||||
def _validate_and_build_base_options(
|
def _validate_and_build_base_options(
|
||||||
self, context, flavor, boot_meta, image_href, image_id, kernel_id,
|
self, context, flavor, boot_meta, image_href, image_id, kernel_id,
|
||||||
ramdisk_id, display_name, display_description, key_name,
|
ramdisk_id, display_name, display_description, hostname, key_name,
|
||||||
key_data, security_groups, availability_zone, user_data, metadata,
|
key_data, security_groups, availability_zone, user_data, metadata,
|
||||||
access_ip_v4, access_ip_v6, requested_networks, config_drive,
|
access_ip_v4, access_ip_v6, requested_networks, config_drive,
|
||||||
auto_disk_config, reservation_id, max_count,
|
auto_disk_config, reservation_id, max_count,
|
||||||
@ -1091,6 +1091,7 @@ class API:
|
|||||||
'ephemeral_gb': flavor['ephemeral_gb'],
|
'ephemeral_gb': flavor['ephemeral_gb'],
|
||||||
'display_name': display_name,
|
'display_name': display_name,
|
||||||
'display_description': display_description,
|
'display_description': display_description,
|
||||||
|
'hostname': hostname,
|
||||||
'user_data': user_data,
|
'user_data': user_data,
|
||||||
'key_name': key_name,
|
'key_name': key_name,
|
||||||
'key_data': key_data,
|
'key_data': key_data,
|
||||||
@ -1500,7 +1501,7 @@ class API:
|
|||||||
def _create_instance(self, context, flavor,
|
def _create_instance(self, context, flavor,
|
||||||
image_href, kernel_id, ramdisk_id,
|
image_href, kernel_id, ramdisk_id,
|
||||||
min_count, max_count,
|
min_count, max_count,
|
||||||
display_name, display_description,
|
display_name, display_description, hostname,
|
||||||
key_name, key_data, security_groups,
|
key_name, key_data, security_groups,
|
||||||
availability_zone, user_data, metadata, injected_files,
|
availability_zone, user_data, metadata, injected_files,
|
||||||
admin_password, access_ip_v4, access_ip_v6,
|
admin_password, access_ip_v4, access_ip_v6,
|
||||||
@ -1550,7 +1551,7 @@ class API:
|
|||||||
) = self._validate_and_build_base_options(
|
) = self._validate_and_build_base_options(
|
||||||
context, flavor, boot_meta, image_href, image_id,
|
context, flavor, boot_meta, image_href, image_id,
|
||||||
kernel_id, ramdisk_id, display_name, display_description,
|
kernel_id, ramdisk_id, display_name, display_description,
|
||||||
key_name, key_data, security_groups, availability_zone,
|
hostname, key_name, key_data, security_groups, availability_zone,
|
||||||
user_data, metadata, access_ip_v4, access_ip_v6,
|
user_data, metadata, access_ip_v4, access_ip_v6,
|
||||||
requested_networks, config_drive, auto_disk_config,
|
requested_networks, config_drive, auto_disk_config,
|
||||||
reservation_id, max_count, supports_port_resource_request,
|
reservation_id, max_count, supports_port_resource_request,
|
||||||
@ -1586,8 +1587,8 @@ class API:
|
|||||||
flavor, metadata, injected_files,
|
flavor, metadata, injected_files,
|
||||||
block_device_mapping.root_bdm(), validate_numa=False)
|
block_device_mapping.root_bdm(), validate_numa=False)
|
||||||
|
|
||||||
instance_group = self._get_requested_instance_group(context,
|
instance_group = self._get_requested_instance_group(
|
||||||
filter_properties)
|
context, filter_properties)
|
||||||
|
|
||||||
tags = self._create_tag_list_obj(context, tags)
|
tags = self._create_tag_list_obj(context, tags)
|
||||||
|
|
||||||
@ -1903,24 +1904,21 @@ class API:
|
|||||||
if 'display_name' not in instance or instance.display_name is None:
|
if 'display_name' not in instance or instance.display_name is None:
|
||||||
instance.display_name = 'Server %s' % instance.uuid
|
instance.display_name = 'Server %s' % instance.uuid
|
||||||
|
|
||||||
|
# only set the hostname if the user hasn't already requested one
|
||||||
|
if 'hostname' not in instance or not instance.hostname:
|
||||||
# if we're booting multiple instances, we need to add an indexing
|
# if we're booting multiple instances, we need to add an indexing
|
||||||
# suffix to both instance.hostname and instance.display_name. This is
|
# suffix to both instance.hostname and instance.display_name.
|
||||||
# not necessary for a single instance.
|
# This is not necessary for a single instance.
|
||||||
if num_instances == 1:
|
hostname = utils.sanitize_hostname(instance.display_name)
|
||||||
default_hostname = 'Server-%s' % instance.uuid
|
if not hostname:
|
||||||
instance.hostname = utils.sanitize_hostname(
|
hostname = f'Server-{instance.uuid}'
|
||||||
instance.display_name, default_hostname)
|
|
||||||
elif num_instances > 1:
|
elif num_instances > 1:
|
||||||
old_display_name = instance.display_name
|
hostname = f'{hostname}-{index + 1}'
|
||||||
new_display_name = '%s-%d' % (old_display_name, index + 1)
|
|
||||||
|
|
||||||
if utils.sanitize_hostname(old_display_name) == "":
|
instance.hostname = hostname
|
||||||
instance.hostname = 'Server-%s' % instance.uuid
|
|
||||||
else:
|
|
||||||
instance.hostname = utils.sanitize_hostname(
|
|
||||||
new_display_name)
|
|
||||||
|
|
||||||
instance.display_name = new_display_name
|
if num_instances > 1:
|
||||||
|
instance.display_name = f'{instance.display_name}-{index + 1}'
|
||||||
|
|
||||||
def _populate_instance_for_create(
|
def _populate_instance_for_create(
|
||||||
self, context, instance, image, index, security_groups, flavor,
|
self, context, instance, image, index, security_groups, flavor,
|
||||||
@ -2029,7 +2027,7 @@ class API:
|
|||||||
self, context, flavor,
|
self, context, flavor,
|
||||||
image_href, kernel_id=None, ramdisk_id=None,
|
image_href, kernel_id=None, ramdisk_id=None,
|
||||||
min_count=None, max_count=None,
|
min_count=None, max_count=None,
|
||||||
display_name=None, display_description=None,
|
display_name=None, display_description=None, hostname=None,
|
||||||
key_name=None, key_data=None, security_groups=None,
|
key_name=None, key_data=None, security_groups=None,
|
||||||
availability_zone=None, forced_host=None, forced_node=None,
|
availability_zone=None, forced_host=None, forced_node=None,
|
||||||
user_data=None, metadata=None, injected_files=None,
|
user_data=None, metadata=None, injected_files=None,
|
||||||
@ -2054,6 +2052,9 @@ class API:
|
|||||||
self._check_multiple_instances_with_neutron_ports(
|
self._check_multiple_instances_with_neutron_ports(
|
||||||
requested_networks)
|
requested_networks)
|
||||||
|
|
||||||
|
if hostname and max_count is not None and max_count > 1:
|
||||||
|
raise exception.AmbiguousHostnameForMultipleInstances()
|
||||||
|
|
||||||
if availability_zone and forced_host is None:
|
if availability_zone and forced_host is None:
|
||||||
azs = availability_zones.get_availability_zones(
|
azs = availability_zones.get_availability_zones(
|
||||||
context.elevated(), self.host_api, get_only_available=True)
|
context.elevated(), self.host_api, get_only_available=True)
|
||||||
@ -2068,7 +2069,7 @@ class API:
|
|||||||
context, flavor,
|
context, flavor,
|
||||||
image_href, kernel_id, ramdisk_id,
|
image_href, kernel_id, ramdisk_id,
|
||||||
min_count, max_count,
|
min_count, max_count,
|
||||||
display_name, display_description,
|
display_name, display_description, hostname,
|
||||||
key_name, key_data, security_groups,
|
key_name, key_data, security_groups,
|
||||||
availability_zone, user_data, metadata,
|
availability_zone, user_data, metadata,
|
||||||
injected_files, admin_password,
|
injected_files, admin_password,
|
||||||
@ -3483,6 +3484,9 @@ class API:
|
|||||||
instance.trusted_certs = self._retrieve_trusted_certs_object(
|
instance.trusted_certs = self._retrieve_trusted_certs_object(
|
||||||
context, trusted_certs, rebuild=True)
|
context, trusted_certs, rebuild=True)
|
||||||
|
|
||||||
|
if 'hostname' in kwargs:
|
||||||
|
instance.hostname = kwargs.pop('hostname')
|
||||||
|
|
||||||
image_id, image = self._get_image(context, image_href)
|
image_id, image = self._get_image(context, image_href)
|
||||||
self._check_auto_disk_config(image=image,
|
self._check_auto_disk_config(image=image,
|
||||||
auto_disk_config=auto_disk_config)
|
auto_disk_config=auto_disk_config)
|
||||||
|
@ -501,6 +501,10 @@ class MultiplePortsNotApplicable(Invalid):
|
|||||||
msg_fmt = _("Failed to launch instances: %(reason)s")
|
msg_fmt = _("Failed to launch instances: %(reason)s")
|
||||||
|
|
||||||
|
|
||||||
|
class AmbiguousHostnameForMultipleInstances(Invalid):
|
||||||
|
msg_fmt = _("Unable to allocate a single hostname to multiple instances")
|
||||||
|
|
||||||
|
|
||||||
class InvalidFixedIpAndMaxCountRequest(Invalid):
|
class InvalidFixedIpAndMaxCountRequest(Invalid):
|
||||||
msg_fmt = _("Failed to launch instances: %(reason)s")
|
msg_fmt = _("Failed to launch instances: %(reason)s")
|
||||||
|
|
||||||
|
@ -42,6 +42,10 @@ This rule will control the visibility for a set of servers attributes:
|
|||||||
Microvision 2.75 added the above attributes in the ``PUT /servers/{server_id}``
|
Microvision 2.75 added the above attributes in the ``PUT /servers/{server_id}``
|
||||||
and ``POST /servers/{server_id}/action (rebuild)`` API responses which are
|
and ``POST /servers/{server_id}/action (rebuild)`` API responses which are
|
||||||
also controlled by this policy rule, like the ``GET /servers*`` APIs.
|
also controlled by this policy rule, like the ``GET /servers*`` APIs.
|
||||||
|
|
||||||
|
Microversion 2.90 made the ``OS-EXT-SRV-ATTR:hostname`` attribute available to
|
||||||
|
all users, so this policy has no effect on that field for microversions 2.90
|
||||||
|
and greater.
|
||||||
""",
|
""",
|
||||||
operations=[
|
operations=[
|
||||||
{
|
{
|
||||||
|
80
nova/tests/functional/api_sample_tests/api_samples/servers/v2.90/server-action-rebuild-resp.json.tpl
Normal file
80
nova/tests/functional/api_sample_tests/api_samples/servers/v2.90/server-action-rebuild-resp.json.tpl
Normal file
@ -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"
|
||||||
|
}
|
||||||
|
}
|
15
nova/tests/functional/api_sample_tests/api_samples/servers/v2.90/server-action-rebuild.json.tpl
Normal file
15
nova/tests/functional/api_sample_tests/api_samples/servers/v2.90/server-action-rebuild.json.tpl
Normal file
@ -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"
|
||||||
|
}
|
||||||
|
}
|
21
nova/tests/functional/api_sample_tests/api_samples/servers/v2.90/server-create-req.json.tpl
Normal file
21
nova/tests/functional/api_sample_tests/api_samples/servers/v2.90/server-create-req.json.tpl
Normal file
@ -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"
|
||||||
|
}
|
||||||
|
}
|
22
nova/tests/functional/api_sample_tests/api_samples/servers/v2.90/server-create-resp.json.tpl
Normal file
22
nova/tests/functional/api_sample_tests/api_samples/servers/v2.90/server-create-resp.json.tpl
Normal file
@ -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"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
81
nova/tests/functional/api_sample_tests/api_samples/servers/v2.90/server-get-resp.json.tpl
Normal file
81
nova/tests/functional/api_sample_tests/api_samples/servers/v2.90/server-get-resp.json.tpl
Normal file
@ -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"
|
||||||
|
}
|
||||||
|
}
|
8
nova/tests/functional/api_sample_tests/api_samples/servers/v2.90/server-update-req.json.tpl
Normal file
8
nova/tests/functional/api_sample_tests/api_samples/servers/v2.90/server-update-req.json.tpl
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"server": {
|
||||||
|
"accessIPv4": "%(access_ip_v4)s",
|
||||||
|
"accessIPv6": "%(access_ip_v6)s",
|
||||||
|
"OS-DCF:diskConfig": "AUTO",
|
||||||
|
"hostname": "new-server-hostname"
|
||||||
|
}
|
||||||
|
}
|
78
nova/tests/functional/api_sample_tests/api_samples/servers/v2.90/server-update-resp.json.tpl
Normal file
78
nova/tests/functional/api_sample_tests/api_samples/servers/v2.90/server-update-resp.json.tpl
Normal file
@ -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",
|
||||||
|
"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"
|
||||||
|
}
|
||||||
|
}
|
88
nova/tests/functional/api_sample_tests/api_samples/servers/v2.90/servers-details-resp.json.tpl
Normal file
88
nova/tests/functional/api_sample_tests/api_samples/servers/v2.90/servers-details-resp.json.tpl
Normal file
@ -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",
|
||||||
|
"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"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
24
nova/tests/functional/api_sample_tests/api_samples/servers/v2.90/servers-list-resp.json.tpl
Normal file
24
nova/tests/functional/api_sample_tests/api_samples/servers/v2.90/servers-list-resp.json.tpl
Normal file
@ -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"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
@ -596,9 +596,6 @@ class ServersSampleJson274Test(ServersSampleBase):
|
|||||||
def _setup_compute_service(self):
|
def _setup_compute_service(self):
|
||||||
return self.start_service('compute', host='openstack-node-01')
|
return self.start_service('compute', host='openstack-node-01')
|
||||||
|
|
||||||
def setUp(self):
|
|
||||||
super(ServersSampleJson274Test, self).setUp()
|
|
||||||
|
|
||||||
def test_servers_post_with_only_host(self):
|
def test_servers_post_with_only_host(self):
|
||||||
self._post_server(use_common_server_api_samples=False,
|
self._post_server(use_common_server_api_samples=False,
|
||||||
sample_name='server-create-req-with-only-host')
|
sample_name='server-create-req-with-only-host')
|
||||||
@ -612,6 +609,15 @@ class ServersSampleJson274Test(ServersSampleBase):
|
|||||||
sample_name='server-create-req-with-host-and-node')
|
sample_name='server-create-req-with-host-and-node')
|
||||||
|
|
||||||
|
|
||||||
|
class ServersSampleJson290Test(ServersSampleJsonTest):
|
||||||
|
microversion = '2.90'
|
||||||
|
scenarios = [('v2_90', {'api_major_version': 'v2.1'})]
|
||||||
|
use_common_server_post = False
|
||||||
|
|
||||||
|
# we want to show that the non-admin response includes the hostname
|
||||||
|
ADMIN_API = False
|
||||||
|
|
||||||
|
|
||||||
class ServersUpdateSampleJsonTest(ServersSampleBase):
|
class ServersUpdateSampleJsonTest(ServersSampleBase):
|
||||||
|
|
||||||
# Many of the 'os_compute_api:servers:*' policies are admin-only, and we
|
# Many of the 'os_compute_api:servers:*' policies are admin-only, and we
|
||||||
@ -634,7 +640,7 @@ class ServersUpdateSampleJson247Test(ServersUpdateSampleJsonTest):
|
|||||||
scenarios = [('v2_47', {'api_major_version': 'v2.1'})]
|
scenarios = [('v2_47', {'api_major_version': 'v2.1'})]
|
||||||
|
|
||||||
|
|
||||||
class ServersSampleJson275Test(ServersUpdateSampleJsonTest):
|
class ServersUpdateSampleJson275Test(ServersUpdateSampleJsonTest):
|
||||||
microversion = '2.75'
|
microversion = '2.75'
|
||||||
scenarios = [('v2_75', {'api_major_version': 'v2.1'})]
|
scenarios = [('v2_75', {'api_major_version': 'v2.1'})]
|
||||||
|
|
||||||
@ -656,6 +662,46 @@ class ServersSampleJson275Test(ServersUpdateSampleJsonTest):
|
|||||||
self._verify_response('server-action-rebuild-resp', subs, resp, 202)
|
self._verify_response('server-action-rebuild-resp', subs, resp, 202)
|
||||||
|
|
||||||
|
|
||||||
|
class ServersUpdateSampleJson289Test(ServersUpdateSampleJsonTest):
|
||||||
|
microversion = '2.90'
|
||||||
|
scenarios = [('v2_90', {'api_major_version': 'v2.1'})]
|
||||||
|
|
||||||
|
# we want to show that the non-admin response includes the hostname
|
||||||
|
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'
|
||||||
|
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',
|
||||||
|
}
|
||||||
|
|
||||||
|
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):
|
class ServerSortKeysJsonTests(ServersSampleBase):
|
||||||
sample_dir = 'servers-sort'
|
sample_dir = 'servers-sort'
|
||||||
|
|
||||||
|
@ -2845,6 +2845,67 @@ class ServersControllerTestV283(ControllerTest):
|
|||||||
self.assertEqual(uuids.fake, servers[0]['id'])
|
self.assertEqual(uuids.fake, servers[0]['id'])
|
||||||
|
|
||||||
|
|
||||||
|
class ServersControllerTestV290(ControllerTest):
|
||||||
|
filters = ['hostname']
|
||||||
|
|
||||||
|
def test_get_servers_by_new_filter_for_non_admin(self):
|
||||||
|
def fake_get_all(context, search_opts=None, **kwargs):
|
||||||
|
self.assertIsNotNone(search_opts)
|
||||||
|
for f in self.filters:
|
||||||
|
self.assertIn(f, search_opts)
|
||||||
|
return objects.InstanceList(
|
||||||
|
objects=[fakes.stub_instance_obj(100, uuid=uuids.fake)])
|
||||||
|
|
||||||
|
self.mock_get_all.side_effect = fake_get_all
|
||||||
|
|
||||||
|
query_str = '&'.join('%s=test_value' % f for f in self.filters)
|
||||||
|
req = fakes.HTTPRequest.blank(
|
||||||
|
self.path_with_query % query_str, version='2.90')
|
||||||
|
servers = self.controller.index(req)['servers']
|
||||||
|
|
||||||
|
self.assertEqual(1, len(servers))
|
||||||
|
self.assertEqual(uuids.fake, servers[0]['id'])
|
||||||
|
|
||||||
|
def test_get_servers_new_filters_for_non_admin_old_version(self):
|
||||||
|
def fake_get_all(context, search_opts=None, **kwargs):
|
||||||
|
self.assertIsNotNone(search_opts)
|
||||||
|
for f in self.filters:
|
||||||
|
self.assertNotIn(f, search_opts)
|
||||||
|
return objects.InstanceList(objects=[])
|
||||||
|
|
||||||
|
# Without policy edition, test will fail and admin filter will work.
|
||||||
|
self.policy.set_rules({'os_compute_api:servers:index': ''})
|
||||||
|
self.mock_get_all.side_effect = fake_get_all
|
||||||
|
|
||||||
|
query_str = '&'.join('%s=test_value' % f for f in self.filters)
|
||||||
|
req = fakes.HTTPRequest.blank(
|
||||||
|
self.path_with_query % query_str, version='2.89')
|
||||||
|
servers = self.controller.index(req)['servers']
|
||||||
|
|
||||||
|
self.assertEqual(0, len(servers))
|
||||||
|
|
||||||
|
def test_get_servers_by_node_fail_non_admin(self):
|
||||||
|
def fake_get_all(context, search_opts=None, **kwargs):
|
||||||
|
self.assertIsNotNone(search_opts)
|
||||||
|
self.assertNotIn('node', search_opts)
|
||||||
|
return objects.InstanceList(
|
||||||
|
objects=[fakes.stub_instance_obj(100, uuid=uuids.fake)])
|
||||||
|
|
||||||
|
self.mock_get_all.side_effect = fake_get_all
|
||||||
|
self.policy.set_rules({
|
||||||
|
'os_compute_api:servers:index': '',
|
||||||
|
'os_compute_api:servers:allow_all_filters': 'role:admin',
|
||||||
|
})
|
||||||
|
|
||||||
|
query_str = "node=node1"
|
||||||
|
req = fakes.HTTPRequest.blank(
|
||||||
|
self.path_with_query % query_str, version='2.90')
|
||||||
|
servers = self.controller.index(req)['servers']
|
||||||
|
|
||||||
|
self.assertEqual(1, len(servers))
|
||||||
|
self.assertEqual(uuids.fake, servers[0]['id'])
|
||||||
|
|
||||||
|
|
||||||
class ServersControllerDeleteTest(ControllerTest):
|
class ServersControllerDeleteTest(ControllerTest):
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
@ -3609,6 +3670,11 @@ class ServersControllerRebuildTestV263(ControllerTest):
|
|||||||
server = self.controller._action_rebuild(
|
server = self.controller._action_rebuild(
|
||||||
self.req, FAKE_UUID, body=self.body).obj['server']
|
self.req, FAKE_UUID, body=self.body).obj['server']
|
||||||
|
|
||||||
|
# TODO(stephenfin): This is a lie. We call '_get_server' immediately
|
||||||
|
# after making the call to 'nova.compute.api.API().rebuild_server' in
|
||||||
|
# '_action_rebuild', which means all we're testing here is the value
|
||||||
|
# returned by 'mock_get' above. Drop it in favour of testing the calls
|
||||||
|
# to the API itself
|
||||||
if certs:
|
if certs:
|
||||||
self.assertEqual(certs, server['trusted_image_certificates'])
|
self.assertEqual(certs, server['trusted_image_certificates'])
|
||||||
else:
|
else:
|
||||||
@ -3761,6 +3827,69 @@ class ServersControllerRebuildTestV271(ControllerTest):
|
|||||||
self.assertEqual([], server['server_groups'])
|
self.assertEqual([], server['server_groups'])
|
||||||
|
|
||||||
|
|
||||||
|
class ServersControllerRebuildTestV290(ControllerTest):
|
||||||
|
microversion = '2.90'
|
||||||
|
image_uuid = nova_fixtures.GlanceFixture.image3['id']
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
super().setUp()
|
||||||
|
|
||||||
|
mock_rebuild = mock.patch(
|
||||||
|
'nova.compute.api.API.rebuild', return_value=None)
|
||||||
|
self.mock_rebuild = mock_rebuild.start()
|
||||||
|
self.addCleanup(mock_rebuild.stop)
|
||||||
|
|
||||||
|
def _get_request(self, body=None):
|
||||||
|
req = fakes.HTTPRequest.blank(
|
||||||
|
self.path_action % FAKE_UUID,
|
||||||
|
use_admin_context=True,
|
||||||
|
)
|
||||||
|
req.method = 'POST'
|
||||||
|
req.content_type = 'application/json'
|
||||||
|
req.body = jsonutils.dump_as_bytes(body)
|
||||||
|
req.api_version_request = api_version_request.APIVersionRequest(
|
||||||
|
self.microversion)
|
||||||
|
|
||||||
|
return req
|
||||||
|
|
||||||
|
def test_rebuild_server_with_hostname(self):
|
||||||
|
body = {
|
||||||
|
'rebuild': {
|
||||||
|
'imageRef': self.image_uuid,
|
||||||
|
'hostname': 'new-hostname',
|
||||||
|
}
|
||||||
|
}
|
||||||
|
req = self._get_request(body)
|
||||||
|
|
||||||
|
# There's nothing to check here from the return value since the
|
||||||
|
# 'rebuild' API is a cast and we immediately fetch the instance from
|
||||||
|
# the database after this cast...which returns a mocked Instance
|
||||||
|
self.controller._action_rebuild(
|
||||||
|
req, FAKE_UUID, body=body,
|
||||||
|
).obj['server']
|
||||||
|
|
||||||
|
# ...so instead we check the call to the API itself
|
||||||
|
self.mock_rebuild.assert_called_once()
|
||||||
|
self.assertIn('hostname', self.mock_rebuild.call_args[0][1])
|
||||||
|
|
||||||
|
def test_rebuild_server_with_hostname_old_version(self):
|
||||||
|
"""Tests that trying to rebuild with hostname before 2.90 fails."""
|
||||||
|
body = {
|
||||||
|
'rebuild': {
|
||||||
|
'imageRef': self.image_uuid,
|
||||||
|
'hostname': 'new-hostname',
|
||||||
|
}
|
||||||
|
}
|
||||||
|
req = self._get_request(body)
|
||||||
|
req.api_version_request = api_version_request.APIVersionRequest('2.89')
|
||||||
|
|
||||||
|
ex = self.assertRaises(
|
||||||
|
exception.ValidationError,
|
||||||
|
self.controller._action_rebuild,
|
||||||
|
req, FAKE_UUID, body=body)
|
||||||
|
self.assertIn('hostname', str(ex))
|
||||||
|
|
||||||
|
|
||||||
class _ServersControllerUpdateTest(ControllerTest):
|
class _ServersControllerUpdateTest(ControllerTest):
|
||||||
|
|
||||||
microversion = None
|
microversion = None
|
||||||
@ -3970,6 +4099,47 @@ class ServersControllerUpdateTestV271(_ServersControllerUpdateTest):
|
|||||||
self.assertEqual([], res_dict['server']['server_groups'])
|
self.assertEqual([], res_dict['server']['server_groups'])
|
||||||
|
|
||||||
|
|
||||||
|
class ServersControllerUpdateTestV290(_ServersControllerUpdateTest):
|
||||||
|
|
||||||
|
microversion = '2.90'
|
||||||
|
|
||||||
|
def test_update_server_with_hostname(self):
|
||||||
|
body = {'server': {'hostname': 'my-hostname'}}
|
||||||
|
req = self._get_request(body)
|
||||||
|
res_dict = self.controller.update(req, FAKE_UUID, body=body)
|
||||||
|
|
||||||
|
self.assertEqual(res_dict['server']['id'], FAKE_UUID)
|
||||||
|
self.assertEqual(
|
||||||
|
res_dict['server']["OS-EXT-SRV-ATTR:hostname"], 'my-hostname')
|
||||||
|
|
||||||
|
def test_update_server_with_hostname__too_long(self):
|
||||||
|
body = {'server': {'hostname': 'a' * 64}}
|
||||||
|
req = self._get_request(body)
|
||||||
|
self.assertRaises(
|
||||||
|
exception.ValidationError, self.controller.update,
|
||||||
|
req, FAKE_UUID, body=body)
|
||||||
|
|
||||||
|
def test_update_server_with_hostname__invalid_fqdn(self):
|
||||||
|
# only hostnames are allowed, not FQDN
|
||||||
|
body = {'server': {'hostname': 'hostname.example.com'}}
|
||||||
|
req = self._get_request(body)
|
||||||
|
self.assertRaises(
|
||||||
|
exception.ValidationError, self.controller.update,
|
||||||
|
req, FAKE_UUID, body=body)
|
||||||
|
|
||||||
|
def test_update_server_with_hostname_old_version(self):
|
||||||
|
"""Tests that trying to update with hostname before 2.90 fails."""
|
||||||
|
body = {'server': {'hostname': 'new-hostname'}}
|
||||||
|
req = self._get_request(body)
|
||||||
|
req.api_version_request = api_version_request.APIVersionRequest('2.89')
|
||||||
|
|
||||||
|
ex = self.assertRaises(
|
||||||
|
exception.ValidationError,
|
||||||
|
self.controller.update,
|
||||||
|
req, FAKE_UUID, body=body)
|
||||||
|
self.assertIn('hostname', str(ex))
|
||||||
|
|
||||||
|
|
||||||
class ServersControllerTriggerCrashDumpTest(ControllerTest):
|
class ServersControllerTriggerCrashDumpTest(ControllerTest):
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
@ -7049,6 +7219,52 @@ class ServersControllerCreateTestV274(ServersControllerCreateTest):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class ServersControllerCreateTestV290(ServersControllerCreateTest):
|
||||||
|
|
||||||
|
def _generate_req(self, hostname=None, api_version='2.90'):
|
||||||
|
if hostname:
|
||||||
|
self.body['server']['hostname'] = hostname
|
||||||
|
self.req.body = jsonutils.dump_as_bytes(self.body)
|
||||||
|
self.req.api_version_request = \
|
||||||
|
api_version_request.APIVersionRequest(api_version)
|
||||||
|
|
||||||
|
def test_create_instance_with_hostname(self):
|
||||||
|
self._generate_req(hostname='test-hostname')
|
||||||
|
self.controller.create(self.req, body=self.body).obj['server']
|
||||||
|
|
||||||
|
def test_create_instance_with_hostname_invalid(self):
|
||||||
|
self._generate_req(hostname='example.com')
|
||||||
|
|
||||||
|
ex = self.assertRaises(
|
||||||
|
exception.ValidationError,
|
||||||
|
self.controller.create,
|
||||||
|
self.req, body=self.body)
|
||||||
|
self.assertIn('Invalid input for field/attribute hostname.', str(ex))
|
||||||
|
|
||||||
|
def test_create_instance_with_hostname_old_version(self):
|
||||||
|
self._generate_req(hostname='hostname', api_version='2.89')
|
||||||
|
|
||||||
|
ex = self.assertRaises(
|
||||||
|
exception.ValidationError,
|
||||||
|
self.controller.create,
|
||||||
|
self.req, body=self.body)
|
||||||
|
self.assertIn("'hostname' was unexpected", str(ex))
|
||||||
|
|
||||||
|
@mock.patch.object(
|
||||||
|
compute_api.API, 'create',
|
||||||
|
side_effect=exception.AmbiguousHostnameForMultipleInstances())
|
||||||
|
def test_create_multiple_instances_with_hostname(self, mock_create):
|
||||||
|
self.body['server']['hostname'] = 'hostname'
|
||||||
|
self.body['server']['max_count'] = 2
|
||||||
|
self.req.body = jsonutils.dump_as_bytes(self.body)
|
||||||
|
self.req.api_version_request = \
|
||||||
|
api_version_request.APIVersionRequest('2.90')
|
||||||
|
self.assertRaises(
|
||||||
|
webob.exc.HTTPBadRequest,
|
||||||
|
self.controller.create,
|
||||||
|
self.req, body=self.body)
|
||||||
|
|
||||||
|
|
||||||
class ServersControllerCreateTestWithMock(test.TestCase):
|
class ServersControllerCreateTestWithMock(test.TestCase):
|
||||||
image_uuid = '76fa36fc-c930-4bf3-8c8a-ea2a2420deb6'
|
image_uuid = '76fa36fc-c930-4bf3-8c8a-ea2a2420deb6'
|
||||||
flavor_ref = 'http://localhost/123/flavors/3'
|
flavor_ref = 'http://localhost/123/flavors/3'
|
||||||
|
@ -355,6 +355,14 @@ class _ComputeAPIUnitTestMixIn(object):
|
|||||||
self.compute_api.create, self.context, 'fake_flavor', 'image_id',
|
self.compute_api.create, self.context, 'fake_flavor', 'image_id',
|
||||||
max_count=2, requested_networks=requested_networks)
|
max_count=2, requested_networks=requested_networks)
|
||||||
|
|
||||||
|
def test_specified_hostname_and_multiple_instances(self):
|
||||||
|
# Tests that if hostname is specified then there is only one instance
|
||||||
|
# request allowed (i.e max_count == 1)
|
||||||
|
self.assertRaises(
|
||||||
|
exception.AmbiguousHostnameForMultipleInstances,
|
||||||
|
self.compute_api.create, self.context, 'fake_flavor', 'image_id',
|
||||||
|
max_count=2, hostname='foo')
|
||||||
|
|
||||||
# TODO(huaqiang): Remove in Wallaby
|
# TODO(huaqiang): Remove in Wallaby
|
||||||
@mock.patch('nova.compute.api.API._check_requested_networks',
|
@mock.patch('nova.compute.api.API._check_requested_networks',
|
||||||
new=mock.Mock(return_value=1))
|
new=mock.Mock(return_value=1))
|
||||||
@ -4856,8 +4864,7 @@ class _ComputeAPIUnitTestMixIn(object):
|
|||||||
volume_types)
|
volume_types)
|
||||||
self.assertEqual(bdms[0].volume_type, volume_types[0]['name'])
|
self.assertEqual(bdms[0].volume_type, volume_types[0]['name'])
|
||||||
|
|
||||||
def _test_provision_instances_with_cinder_error(self,
|
def _test_provision_instances_with_cinder_error(self, expected_exception):
|
||||||
expected_exception):
|
|
||||||
@mock.patch('nova.compute.utils.check_num_instances_quota')
|
@mock.patch('nova.compute.utils.check_num_instances_quota')
|
||||||
@mock.patch.object(objects.Instance, 'create')
|
@mock.patch.object(objects.Instance, 'create')
|
||||||
@mock.patch.object(objects.RequestSpec, 'from_components')
|
@mock.patch.object(objects.RequestSpec, 'from_components')
|
||||||
@ -7185,11 +7192,11 @@ class ComputeAPIUnitTestCase(_ComputeAPIUnitTestMixIn, test.NoDBTestCase):
|
|||||||
self.compute_api._validate_and_build_base_options(
|
self.compute_api._validate_and_build_base_options(
|
||||||
self.context, flavor, boot_meta, uuids.image_href,
|
self.context, flavor, boot_meta, uuids.image_href,
|
||||||
mock.sentinel.image_id, kernel_id, ramdisk_id,
|
mock.sentinel.image_id, kernel_id, ramdisk_id,
|
||||||
'fake-display-name', 'fake-description', key_name,
|
'fake-display-name', 'fake-description', 'fake-hostname',
|
||||||
key_data, requested_secgroups, 'fake-az', user_data,
|
key_name, key_data, requested_secgroups, 'fake-az',
|
||||||
metadata, access_ip_v4, access_ip_v6, requested_networks,
|
user_data, metadata, access_ip_v4, access_ip_v6,
|
||||||
config_drive, auto_disk_config, reservation_id, max_count,
|
requested_networks, config_drive, auto_disk_config,
|
||||||
supports_port_resource_request
|
reservation_id, max_count, supports_port_resource_request,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
# Assert the neutron security group API get method was called once
|
# Assert the neutron security group API get method was called once
|
||||||
|
16
releasenotes/notes/microversion-2-90-59fb6d4ec420b9f4.yaml
Normal file
16
releasenotes/notes/microversion-2-90-59fb6d4ec420b9f4.yaml
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
---
|
||||||
|
features:
|
||||||
|
- |
|
||||||
|
The 2.90 microversion has been added. This microversion allows users to
|
||||||
|
specify a requested hostname to be configured for the instance metadata
|
||||||
|
when creating an instance (``POST /servers``), updating an instance
|
||||||
|
(``PUT /servers/{id}``), or rebuilding an instance
|
||||||
|
(``POST /servers/{server_id}/action (rebuild)``). When specified, this
|
||||||
|
hostname replaces the hostname that nova auto-generates from the instance
|
||||||
|
display name. As with the auto-generated hostnames, a service such as
|
||||||
|
``cloud-init`` can automatically configure the hostname in the guest OS
|
||||||
|
using this information retrieved from the metadata service.
|
||||||
|
|
||||||
|
In addition, starting with the 2.90 microversion, the
|
||||||
|
``OS-EXT-SRV-ATTR:hostname`` field is now returned for all users.
|
||||||
|
Previously this was restricted to admin users.
|
Loading…
x
Reference in New Issue
Block a user