show flavor info in server details

Add a new microversion to change the flavor field in the server
details to display a subset of the flavor information instead of
just a link to the original flavor.

This is more reliable since it shows the actual instance size, while
the flavor may have been deleted/recreated in the meantime or the
flavor extra-specs may have been modified.

Implements: blueprint instance-flavor-api
Change-Id: If646149efb7eec8c90bf7d07c39ff4c495349941
This commit is contained in:
Chris Friesen 2017-02-13 09:55:01 -06:00 committed by Matt Riedemann
parent 31d2e465e3
commit 90636e0f33
31 changed files with 1103 additions and 25 deletions

View File

@ -1988,6 +1988,15 @@ extra_specs:
in: body
required: true
type: object
extra_specs_2_47:
min_version: 2.47
description: |
A dictionary of the flavor's extra-specs key-and-value pairs. This will
only be included if the user is allowed by policy to index flavor
extra_specs.
in: body
required: false
type: object
fault:
description: |
A fault object. Only displayed in the failed response.
@ -2092,6 +2101,13 @@ flavor_cpus:
type: integer
description: |
The number of virtual CPUs that will be allocated to the server.
flavor_cpus_2_47:
min_version: 2.47
in: body
required: true
type: integer
description: |
The number of virtual CPUs that were allocated to the server.
flavor_disabled:
in: body
required: false
@ -2110,6 +2126,13 @@ flavor_disk:
select the compute host based on the virtual image size. Therefore,
0 should only be used for volume booted instances or for testing
purposes.
flavor_disk_2_47:
min_version: 2.47
in: body
required: true
type: integer
description: |
The size of the root disk that was created in GiB.
flavor_ephem_disk:
in: body
required: true
@ -2119,6 +2142,13 @@ flavor_ephem_disk:
GiB. Ephemeral disks may be written over on server state
changes. So should only be used as a scratch space for
applications that are aware of its limitations. Defaults to 0.
flavor_ephem_disk_2_47:
min_version: 2.47
in: body
required: true
type: integer
description: |
The size of the ephemeral disk that was created, in GiB.
flavor_ephem_disk_in:
in: body
required: false
@ -2136,6 +2166,13 @@ flavor_extra_spec_key2:
in: body
required: true
type: string
flavor_extra_spec_key_2_47:
description: |
The extra spec key of a flavor.
in: body
required: true
type: string
min_version: 2.47
flavor_extra_spec_value:
description: |
The extra spec value of a flavor. It appears in the os-extra-specs'
@ -2144,6 +2181,13 @@ flavor_extra_spec_value:
in: body
required: true
type: string
flavor_extra_spec_value_2_47:
description: |
The extra spec value of a flavor.
in: body
required: true
type: string
min_version: 2.47
flavor_id_body:
description: |
The ID of the flavor. While people often make this look like
@ -2151,6 +2195,14 @@ flavor_id_body:
in: body
required: true
type: string
flavor_id_body_2_46:
description: |
The ID of the flavor. While people often make this look like
an int, this is really a string.
in: body
required: true
type: string
max_version: 2.46
flavor_id_body_create:
description: |
The ID of the flavor. While people often make this look like an int, this
@ -2172,6 +2224,16 @@ flavor_is_public_in:
in: body
required: false
type: boolean
flavor_links_2_46:
description: |
Links to the flavor resource. See `API Guide / Links and
References
<http://developer.openstack.org/api-guide/compute/links_and_references.html>`_
for more info.
in: body
required: true
type: array
max_version: 2.46
flavor_name:
description: |
The display name of a flavor.
@ -2184,12 +2246,26 @@ flavor_name_optional:
in: body
required: false
type: string
flavor_original_name:
description: |
The display name of a flavor.
in: body
required: true
type: string
min_version: 2.47
flavor_ram:
description: |
The amount of RAM a flavor has, in MiB.
in: body
required: true
type: integer
flavor_ram_2_47:
description: |
The amount of RAM a flavor has, in MiB.
in: body
required: true
type: integer
min_version: 2.47
flavor_rxtx_factor:
description: |
The receive / transmit factor (as a float) that will be set on
@ -2208,9 +2284,13 @@ flavor_rxtx_factor_in:
type: float
flavor_server:
description: |
The ID and links for the flavor for your server instance. A flavor is a combination
of memory, disk size, and CPUs. This can be empty object in case flavor information
is not present in the system.
Before microversion 2.47 this contains the ID and links for the flavor
used to boot the server instance. This can be an empty object in case
flavor information is no longer present in the system.
As of microversion 2.47 this contains a subset of the actual flavor
information used to create the server instance, represented as a nested
dictionary.
in: body
required: true
type: object
@ -2221,6 +2301,13 @@ flavor_swap:
in: body
required: true
type: integer
flavor_swap_2_47:
description: |
The size of a dedicated swap disk that was allocated, in MiB.
in: body
required: true
type: integer
min_version: 2.47
flavor_swap_in:
description: |
The size of a dedicated swap disk that will be allocated, in

View File

@ -486,9 +486,9 @@ Request
- preserve_ephemeral: preserve_ephemeral
- description: server_description
**Example Rebuild Server (rebuild Action) (v2.26)**
**Example Rebuild Server (rebuild Action) (v2.47)**
.. literalinclude:: ../../doc/api_samples/servers/v2.26/server-action-rebuild.json
.. literalinclude:: ../../doc/api_samples/servers/v2.47/server-action-rebuild.json
:language: javascript
Response
@ -503,9 +503,18 @@ Response
- addresses: addresses_obj
- adminPass: adminPass_response
- created: created
- flavor: flavor
- flavor.id: flavor_id_body
- flavor.links: links
- flavor: flavor_server
- flavor.id: flavor_id_body_2_46
- flavor.links: flavor_links_2_46
- flavor.vcpus: flavor_cpus_2_47
- flavor.ram: flavor_ram_2_47
- flavor.disk: flavor_disk_2_47
- flavor.ephemeral: flavor_ephem_disk_2_47
- flavor.swap: flavor_swap_2_47
- flavor.original_name: flavor_original_name
- flavor.extra_specs: extra_specs_2_47
- flavor.extra_specs.key: flavor_extra_spec_key_2_47
- flavor.extra_specs.value: flavor_extra_spec_value_2_47
- hostId: hostId
- id: server_id
- image: image
@ -524,9 +533,9 @@ Response
- description: server_description_resp
- tags: tags
**Example Rebuild Server (rebuild Action) (v2.26)**
**Example Rebuild Server (rebuild Action) (v2.47)**
.. literalinclude:: ../../doc/api_samples/servers/v2.26/server-action-rebuild-resp.json
.. literalinclude:: ../../doc/api_samples/servers/v2.47/server-action-rebuild-resp.json
:language: javascript
Remove (Disassociate) Floating Ip (removeFloatingIp Action) (DEPRECATED)

View File

@ -502,6 +502,17 @@ Response
- addresses: addresses
- created: created
- flavor: flavor_server
- flavor.id: flavor_id_body_2_46
- flavor.links: flavor_links_2_46
- flavor.vcpus: flavor_cpus_2_47
- flavor.ram: flavor_ram_2_47
- flavor.disk: flavor_disk_2_47
- flavor.ephemeral: flavor_ephem_disk_2_47
- flavor.swap: flavor_swap_2_47
- flavor.original_name: flavor_original_name
- flavor.extra_specs: extra_specs_2_47
- flavor.extra_specs.key: flavor_extra_spec_key_2_47
- flavor.extra_specs.value: flavor_extra_spec_value_2_47
- hostId: hostId
- id: server_id
- image: image
@ -542,9 +553,9 @@ Response
- OS-EXT-SRV-ATTR:user_data: server_user_data
- locked: locked
**Example List Servers Detailed**
**Example List Servers Detailed (2.47)**
.. literalinclude:: /../../doc/api_samples/servers/servers-details-resp.json
.. literalinclude:: /../../doc/api_samples/servers/v2.47/servers-details-resp.json
:language: javascript
@ -590,6 +601,17 @@ Response
- addresses: addresses
- created: created
- flavor: flavor_server
- flavor.id: flavor_id_body_2_46
- flavor.links: flavor_links_2_46
- flavor.vcpus: flavor_cpus_2_47
- flavor.ram: flavor_ram_2_47
- flavor.disk: flavor_disk_2_47
- flavor.ephemeral: flavor_ephem_disk_2_47
- flavor.swap: flavor_swap_2_47
- flavor.original_name: flavor_original_name
- flavor.extra_specs: extra_specs_2_47
- flavor.extra_specs.key: flavor_extra_spec_key_2_47
- flavor.extra_specs.value: flavor_extra_spec_value_2_47
- hostId: hostId
- id: server_id
- image: image
@ -631,9 +653,9 @@ Response
- OS-EXT-SRV-ATTR:user_data: server_user_data
- locked: locked
**Example Show Server Details**
**Example Show Server Details (2.47)**
.. literalinclude:: ../../doc/api_samples/servers/server-get-resp.json
.. literalinclude:: ../../doc/api_samples/servers/v2.47/server-get-resp.json
:language: javascript
Update Server
@ -660,9 +682,9 @@ Request
- OS-DCF:diskConfig: OS-DCF:diskConfig
- description: server_description
**Example Update server name**
**Example Update server name (2.47)**
.. literalinclude:: ../../doc/api_samples/servers/server-update-req.json
.. literalinclude:: ../../doc/api_samples/servers/v2.47/server-update-req.json
:language: javascript
..
@ -688,6 +710,17 @@ Response
- addresses: addresses
- created: created
- flavor: flavor_server
- flavor.id: flavor_id_body_2_46
- flavor.links: flavor_links_2_46
- flavor.vcpus: flavor_cpus_2_47
- flavor.ram: flavor_ram_2_47
- flavor.disk: flavor_disk_2_47
- flavor.ephemeral: flavor_ephem_disk_2_47
- flavor.swap: flavor_swap_2_47
- flavor.original_name: flavor_original_name
- flavor.extra_specs: extra_specs_2_47
- flavor.extra_specs.key: flavor_extra_spec_key_2_47
- flavor.extra_specs.value: flavor_extra_spec_value_2_47
- hostId: hostId
- id: server_id
- image: image
@ -724,9 +757,9 @@ Response
- OS-EXT-SRV-ATTR:user_data: server_user_data
- locked: locked
**Example Update server name**
**Example Update server name (2.47)**
.. literalinclude:: ../../doc/api_samples/servers/server-update-resp.json
.. literalinclude:: ../../doc/api_samples/servers/v2.47/server-update-resp.json
:language: javascript
Delete Server

View File

@ -0,0 +1,59 @@
{
"server": {
"accessIPv4": "1.2.3.4",
"accessIPv6": "80fe::",
"addresses": {
"private": [
{
"addr": "192.168.0.3",
"version": 4
}
]
},
"adminPass": "seekr3t",
"created": "2013-11-14T06:29:00Z",
"flavor": {
"disk": 1,
"ephemeral": 0,
"extra_specs": {},
"original_name": "m1.tiny",
"ram": 512,
"swap": 0,
"vcpus": 1
},
"hostId": "28d8d56f0e3a77e20891f455721cbb68032e017045e20aa5dfc6cb66",
"id": "a0a80a94-3d81-4a10-822a-daa0cf9e870b",
"image": {
"id": "70a599e0-31e7-49b7-b260-868f441e862b",
"links": [
{
"href": "http://openstack.example.com/6f70656e737461636b20342065766572/images/70a599e0-31e7-49b7-b260-868f441e862b",
"rel": "bookmark"
}
]
},
"links": [
{
"href": "http://openstack.example.com/v2/6f70656e737461636b20342065766572/servers/a0a80a94-3d81-4a10-822a-daa0cf9e870b",
"rel": "self"
},
{
"href": "http://openstack.example.com/6f70656e737461636b20342065766572/servers/a0a80a94-3d81-4a10-822a-daa0cf9e870b",
"rel": "bookmark"
}
],
"locked": false,
"metadata": {
"meta_var": "meta_val"
},
"name": "foobar",
"description" : null,
"progress": 0,
"status": "ACTIVE",
"OS-DCF:diskConfig": "AUTO",
"tags": [],
"tenant_id": "6f70656e737461636b20342065766572",
"updated": "2013-11-14T06:29:02Z",
"user_id": "fake"
}
}

View File

@ -0,0 +1,19 @@
{
"rebuild" : {
"imageRef" : "70a599e0-31e7-49b7-b260-868f441e862b",
"accessIPv4" : "1.2.3.4",
"accessIPv6" : "80fe::",
"adminPass" : "seekr3t",
"metadata" : {
"meta_var" : "meta_val"
},
"name" : "foobar",
"OS-DCF:diskConfig": "AUTO",
"personality" : [
{
"path" : "/etc/banner.txt",
"contents" : "ICAgICAgDQoiQSBjbG91ZCBkb2VzIG5vdCBrbm93IHdoeSBp dCBtb3ZlcyBpbiBqdXN0IHN1Y2ggYSBkaXJlY3Rpb24gYW5k IGF0IHN1Y2ggYSBzcGVlZC4uLkl0IGZlZWxzIGFuIGltcHVs c2lvbi4uLnRoaXMgaXMgdGhlIHBsYWNlIHRvIGdvIG5vdy4g QnV0IHRoZSBza3kga25vd3MgdGhlIHJlYXNvbnMgYW5kIHRo ZSBwYXR0ZXJucyBiZWhpbmQgYWxsIGNsb3VkcywgYW5kIHlv dSB3aWxsIGtub3csIHRvbywgd2hlbiB5b3UgbGlmdCB5b3Vy c2VsZiBoaWdoIGVub3VnaCB0byBzZWUgYmV5b25kIGhvcml6 b25zLiINCg0KLVJpY2hhcmQgQmFjaA=="
}
]
}
}

View File

@ -0,0 +1,30 @@
{
"server" : {
"accessIPv4": "1.2.3.4",
"accessIPv6": "80fe::",
"name" : "new-server-test",
"imageRef" : "70a599e0-31e7-49b7-b260-868f441e862b",
"flavorRef" : "6",
"availability_zone": "nova",
"OS-DCF:diskConfig": "AUTO",
"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==",
"networks": "auto"
},
"OS-SCH-HNT:scheduler_hints": {
"same_host": "[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}"
}
}

View File

@ -0,0 +1,22 @@
{
"server": {
"OS-DCF:diskConfig": "AUTO",
"adminPass": "S5wqy9sPYUvU",
"id": "97108291-2fd7-4dc2-a909-eaae0306a6a9",
"links": [
{
"href": "http://openstack.example.com/v2.1/6f70656e737461636b20342065766572/servers/97108291-2fd7-4dc2-a909-eaae0306a6a9",
"rel": "self"
},
{
"href": "http://openstack.example.com/6f70656e737461636b20342065766572/servers/97108291-2fd7-4dc2-a909-eaae0306a6a9",
"rel": "bookmark"
}
],
"security_groups": [
{
"name": "default"
}
]
}
}

View File

@ -0,0 +1,98 @@
{
"server": {
"OS-DCF:diskConfig": "AUTO",
"OS-EXT-AZ:availability_zone": "nova",
"OS-EXT-SRV-ATTR:host": "compute",
"OS-EXT-SRV-ATTR:hostname": "new-server-test",
"OS-EXT-SRV-ATTR:hypervisor_hostname": "fake-mini",
"OS-EXT-SRV-ATTR:instance_name": "instance-00000001",
"OS-EXT-SRV-ATTR:kernel_id": "",
"OS-EXT-SRV-ATTR:launch_index": 0,
"OS-EXT-SRV-ATTR:ramdisk_id": "",
"OS-EXT-SRV-ATTR:reservation_id": "r-ov3q80zj",
"OS-EXT-SRV-ATTR:root_device_name": "/dev/sda",
"OS-EXT-SRV-ATTR:user_data": "IyEvYmluL2Jhc2gKL2Jpbi9zdQplY2hvICJJIGFtIGluIHlvdSEiCg==",
"OS-EXT-STS:power_state": 1,
"OS-EXT-STS:task_state": null,
"OS-EXT-STS:vm_state": "active",
"OS-SRV-USG:launched_at": "2017-02-14T19:23:59.895661",
"OS-SRV-USG:terminated_at": null,
"accessIPv4": "1.2.3.4",
"accessIPv6": "80fe::",
"addresses": {
"private": [
{
"OS-EXT-IPS-MAC:mac_addr": "aa:bb:cc:dd:ee:ff",
"OS-EXT-IPS:type": "fixed",
"addr": "192.168.0.3",
"version": 4
}
]
},
"config_drive": "",
"created": "2017-02-14T19:23:58Z",
"description": null,
"flavor": {
"disk": 1,
"ephemeral": 0,
"extra_specs": {
"hw:cpu_model": "SandyBridge",
"hw:mem_page_size": "2048",
"hw:cpu_policy": "dedicated"
},
"original_name": "m1.tiny.specs",
"ram": 512,
"swap": 0,
"vcpus": 1
},
"hostId": "2091634baaccdc4c5a1d57069c833e402921df696b7f970791b12ec6",
"host_status": "UP",
"id": "9168b536-cd40-4630-b43f-b259807c6e87",
"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/9168b536-cd40-4630-b43f-b259807c6e87",
"rel": "self"
},
{
"href": "http://openstack.example.com/6f70656e737461636b20342065766572/servers/9168b536-cd40-4630-b43f-b259807c6e87",
"rel": "bookmark"
}
],
"locked": false,
"metadata": {
"My Server Name": "Apache1"
},
"name": "new-server-test",
"os-extended-volumes:volumes_attached": [
{
"delete_on_termination": false,
"id": "volume_id1"
},
{
"delete_on_termination": false,
"id": "volume_id2"
}
],
"progress": 0,
"security_groups": [
{
"name": "default"
}
],
"status": "ACTIVE",
"tags": [],
"tenant_id": "6f70656e737461636b20342065766572",
"updated": "2017-02-14T19:24:00Z",
"user_id": "fake"
}
}

View File

@ -0,0 +1,8 @@
{
"server": {
"accessIPv4": "1.2.3.4",
"accessIPv6": "80fe::",
"OS-DCF:diskConfig": "AUTO",
"name" : "new-server-test"
}
}

View File

@ -0,0 +1,58 @@
{
"server": {
"OS-DCF:diskConfig": "AUTO",
"accessIPv4": "1.2.3.4",
"accessIPv6": "80fe::",
"addresses": {
"private": [
{
"addr": "192.168.0.3",
"version": 4
}
]
},
"created": "2012-12-02T02:11:57Z",
"description": null,
"flavor": {
"disk": 1,
"ephemeral": 0,
"extra_specs": {},
"original_name": "m1.tiny",
"ram": 512,
"swap": 0,
"vcpus": 1
},
"hostId": "6e84af987b4e7ec1c039b16d21f508f4a505672bd94fb0218b668d07",
"id": "324dfb7d-f4a9-419a-9a19-237df04b443b",
"image": {
"id": "70a599e0-31e7-49b7-b260-868f441e862b",
"links": [
{
"href": "http://openstack.example.com/6f70656e737461636b20342065766572/images/70a599e0-31e7-49b7-b260-868f441e862b",
"rel": "bookmark"
}
]
},
"links": [
{
"href": "http://openstack.example.com/v2/6f70656e737461636b20342065766572/servers/324dfb7d-f4a9-419a-9a19-237df04b443b",
"rel": "self"
},
{
"href": "http://openstack.example.com/6f70656e737461636b20342065766572/servers/324dfb7d-f4a9-419a-9a19-237df04b443b",
"rel": "bookmark"
}
],
"locked": false,
"metadata": {
"My Server Name": "Apache1"
},
"name": "new-server-test",
"progress": 0,
"status": "ACTIVE",
"tags": [],
"tenant_id": "6f70656e737461636b20342065766572",
"updated": "2012-12-02T02:11:58Z",
"user_id": "fake"
}
}

View File

@ -0,0 +1,100 @@
{
"servers": [
{
"OS-DCF:diskConfig": "AUTO",
"OS-EXT-AZ:availability_zone": "nova",
"OS-EXT-SRV-ATTR:host": "compute",
"OS-EXT-SRV-ATTR:hostname": "new-server-test",
"OS-EXT-SRV-ATTR:hypervisor_hostname": "fake-mini",
"OS-EXT-SRV-ATTR:instance_name": "instance-00000001",
"OS-EXT-SRV-ATTR:kernel_id": "",
"OS-EXT-SRV-ATTR:launch_index": 0,
"OS-EXT-SRV-ATTR:ramdisk_id": "",
"OS-EXT-SRV-ATTR:reservation_id": "r-iffothgx",
"OS-EXT-SRV-ATTR:root_device_name": "/dev/sda",
"OS-EXT-SRV-ATTR:user_data": "IyEvYmluL2Jhc2gKL2Jpbi9zdQplY2hvICJJIGFtIGluIHlvdSEiCg==",
"OS-EXT-STS:power_state": 1,
"OS-EXT-STS:task_state": null,
"OS-EXT-STS:vm_state": "active",
"OS-SRV-USG:launched_at": "2017-02-14T19:24:43.891568",
"OS-SRV-USG:terminated_at": null,
"accessIPv4": "1.2.3.4",
"accessIPv6": "80fe::",
"addresses": {
"private": [
{
"OS-EXT-IPS-MAC:mac_addr": "aa:bb:cc:dd:ee:ff",
"OS-EXT-IPS:type": "fixed",
"addr": "192.168.0.3",
"version": 4
}
]
},
"config_drive": "",
"created": "2017-02-14T19:24:42Z",
"description": null,
"flavor": {
"disk": 1,
"ephemeral": 0,
"extra_specs": {
"hw:cpu_model": "SandyBridge",
"hw:mem_page_size": "2048",
"hw:cpu_policy": "dedicated"
},
"original_name": "m1.tiny.specs",
"ram": 512,
"swap": 0,
"vcpus": 1
},
"hostId": "2091634baaccdc4c5a1d57069c833e402921df696b7f970791b12ec6",
"host_status": "UP",
"id": "764e369e-a874-4401-b7ce-43e4760888da",
"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/764e369e-a874-4401-b7ce-43e4760888da",
"rel": "self"
},
{
"href": "http://openstack.example.com/6f70656e737461636b20342065766572/servers/764e369e-a874-4401-b7ce-43e4760888da",
"rel": "bookmark"
}
],
"locked": false,
"metadata": {
"My Server Name": "Apache1"
},
"name": "new-server-test",
"os-extended-volumes:volumes_attached": [
{
"delete_on_termination": false,
"id": "volume_id1"
},
{
"delete_on_termination": false,
"id": "volume_id2"
}
],
"progress": 0,
"security_groups": [
{
"name": "default"
}
],
"status": "ACTIVE",
"tags": [],
"tenant_id": "6f70656e737461636b20342065766572",
"updated": "2017-02-14T19:24:43Z",
"user_id": "fake"
}
]
}

View File

@ -0,0 +1,18 @@
{
"servers": [
{
"id": "6e3a87e6-a133-452e-86e1-a31291c1b1c8",
"links": [
{
"href": "http://openstack.example.com/v2.1/6f70656e737461636b20342065766572/servers/6e3a87e6-a133-452e-86e1-a31291c1b1c8",
"rel": "self"
},
{
"href": "http://openstack.example.com/6f70656e737461636b20342065766572/servers/6e3a87e6-a133-452e-86e1-a31291c1b1c8",
"rel": "bookmark"
}
],
"name": "new-server-test"
}
]
}

View File

@ -19,7 +19,7 @@
}
],
"status": "CURRENT",
"version": "2.46",
"version": "2.47",
"min_version": "2.1",
"updated": "2013-07-23T11:33:21Z"
}

View File

@ -22,7 +22,7 @@
}
],
"status": "CURRENT",
"version": "2.46",
"version": "2.47",
"min_version": "2.1",
"updated": "2013-07-23T11:33:21Z"
}

View File

@ -110,6 +110,10 @@ REST_API_VERSION_HISTORY = """REST API Version History:
json dict in the response body with an image_id key and uuid
value.
* 2.46 - Return ``X-OpenStack-Request-ID`` header on requests.
* 2.47 - When displaying server details, display the flavor as a dict
rather than a link. If the user is prevented from retrieving
the flavor extra-specs by policy, simply omit the field from
the output.
"""
# The minimum and maximum versions of the API supported
@ -118,7 +122,7 @@ REST_API_VERSION_HISTORY = """REST API Version History:
# Note(cyeoh): This only applies for the v2.1 API once microversions
# support is fully merged. It does not affect the V2 API.
_MIN_API_VERSION = "2.1"
_MAX_API_VERSION = "2.46"
_MAX_API_VERSION = "2.47"
DEFAULT_API_VERSION = _MIN_API_VERSION
# Almost all proxy APIs which related to network, images and baremetal

View File

@ -545,3 +545,14 @@ user documentation.
to be consistent with the rest of OpenStack. This is a signaling
only microversion, as these header settings happen well before
microversion processing.
2.47
----
Replace the ``flavor`` name/ref with the actual flavor details from the embedded
flavor object when displaying server details. Requests made with microversion
>= 2.47 will no longer return the flavor ID/link but instead will return a
subset of the flavor details. If the user is prevented by policy from
indexing extra-specs, then the ``extra_specs`` field will not be included in the
flavor information.

View File

@ -448,7 +448,6 @@ class ServersController(wsgi.Controller):
@validation.schema(schema_server_create_v242, '2.42')
def create(self, req, body):
"""Creates a new server for a given user."""
context = req.environ['nova.context']
server_dict = body['server']
password = self._get_server_admin_password(server_dict)

View File

@ -27,6 +27,7 @@ from nova import context as nova_context
from nova import exception
from nova import objects
from nova.objects import base as obj_base
from nova.policies import flavor_extra_specs as fes_policies
from nova import utils
@ -244,12 +245,30 @@ class ViewBuilder(common.ViewBuilder):
else:
return ""
def _get_flavor_dict(self, request, instance_type):
flavordict = {
"vcpus": instance_type.vcpus,
"ram": instance_type.memory_mb,
"disk": instance_type.root_gb,
"ephemeral": instance_type.ephemeral_gb,
"swap": instance_type.swap,
"original_name": instance_type.name
}
context = request.environ['nova.context']
if context.can(fes_policies.POLICY_ROOT % 'index', fatal=False):
flavordict['extra_specs'] = instance_type.extra_specs
return flavordict
def _get_flavor(self, request, instance):
instance_type = instance.get_flavor()
if not instance_type:
LOG.warning("Instance has had its instance_type removed "
"from the DB", instance=instance)
return {}
if api_version_request.is_supported(request, min_version="2.47"):
return self._get_flavor_dict(request, instance_type)
flavor_id = instance_type["flavorid"]
flavor_bookmark = self._flavor_builder._get_bookmark_link(request,
flavor_id,

View File

@ -0,0 +1,59 @@
{
"server": {
"accessIPv4": "%(access_ip_v4)s",
"accessIPv6": "%(access_ip_v6)s",
"addresses": {
"private": [
{
"addr": "%(ip)s",
"version": 4
}
]
},
"adminPass": "%(password)s",
"created": "%(isotime)s",
"flavor": {
"disk": 1,
"ephemeral": 0,
"extra_specs": {},
"original_name": "m1.tiny",
"ram": 512,
"swap": 0,
"vcpus": 1
},
"hostId": "%(hostid)s",
"id": "%(uuid)s",
"image": {
"id": "%(uuid)s",
"links": [
{
"href": "%(compute_endpoint)s/images/%(uuid)s",
"rel": "bookmark"
}
]
},
"links": [
{
"href": "%(versioned_compute_endpoint)s/servers/%(uuid)s",
"rel": "self"
},
{
"href": "%(compute_endpoint)s/servers/%(uuid)s",
"rel": "bookmark"
}
],
"locked": false,
"metadata": {
"meta_var": "meta_val"
},
"name": "%(name)s",
"description": null,
"progress": 0,
"OS-DCF:diskConfig": "AUTO",
"status": "ACTIVE",
"tags": [],
"tenant_id": "6f70656e737461636b20342065766572",
"updated": "%(isotime)s",
"user_id": "fake"
}
}

View File

@ -0,0 +1,19 @@
{
"rebuild" : {
"accessIPv4" : "%(access_ip_v4)s",
"accessIPv6" : "%(access_ip_v6)s",
"OS-DCF:diskConfig": "AUTO",
"imageRef" : "%(uuid)s",
"name" : "%(name)s",
"adminPass" : "%(pass)s",
"metadata" : {
"meta_var" : "meta_val"
},
"personality": [
{
"path": "/etc/banner.txt",
"contents": "ICAgICAgDQoiQSBjbG91ZCBkb2VzIG5vdCBrbm93IHdoeSBp dCBtb3ZlcyBpbiBqdXN0IHN1Y2ggYSBkaXJlY3Rpb24gYW5k IGF0IHN1Y2ggYSBzcGVlZC4uLkl0IGZlZWxzIGFuIGltcHVs c2lvbi4uLnRoaXMgaXMgdGhlIHBsYWNlIHRvIGdvIG5vdy4g QnV0IHRoZSBza3kga25vd3MgdGhlIHJlYXNvbnMgYW5kIHRo ZSBwYXR0ZXJucyBiZWhpbmQgYWxsIGNsb3VkcywgYW5kIHlv dSB3aWxsIGtub3csIHRvbywgd2hlbiB5b3UgbGlmdCB5b3Vy c2VsZiBoaWdoIGVub3VnaCB0byBzZWUgYmV5b25kIGhvcml6 b25zLiINCg0KLVJpY2hhcmQgQmFjaA=="
}
]
}
}

View File

@ -0,0 +1,30 @@
{
"server" : {
"accessIPv4": "%(access_ip_v4)s",
"accessIPv6": "%(access_ip_v6)s",
"name" : "%(name)s",
"imageRef" : "%(image_id)s",
"flavorRef" : "6",
"availability_zone": "nova",
"OS-DCF:diskConfig": "AUTO",
"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" : "%(user_data)s",
"networks": "auto"
},
"OS-SCH-HNT:scheduler_hints": {
"same_host": "%(uuid)s"
}
}

View 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"
}
]
}
}

View File

@ -0,0 +1,92 @@
{
"server": {
"accessIPv4": "%(access_ip_v4)s",
"accessIPv6": "%(access_ip_v6)s",
"addresses": {
"private": [
{
"addr": "%(ip)s",
"OS-EXT-IPS-MAC:mac_addr": "aa:bb:cc:dd:ee:ff",
"OS-EXT-IPS:type": "fixed",
"version": 4
}
]
},
"created": "%(isotime)s",
"description": null,
"host_status": "UP",
"locked": false,
"tags": [],
"flavor": {
"disk": 1,
"ephemeral": 0,
"extra_specs": {
"hw:cpu_model": "SandyBridge",
"hw:mem_page_size": "2048",
"hw:cpu_policy": "dedicated"
},
"original_name": "m1.tiny.specs",
"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:host": "%(compute_host)s",
"OS-EXT-SRV-ATTR:hostname": "%(hostname)s",
"OS-EXT-SRV-ATTR:hypervisor_hostname": "%(hypervisor_hostname)s",
"OS-EXT-SRV-ATTR:instance_name": "%(instance_name)s",
"OS-EXT-SRV-ATTR:kernel_id": "",
"OS-EXT-SRV-ATTR:launch_index": 0,
"OS-EXT-SRV-ATTR:ramdisk_id": "",
"OS-EXT-SRV-ATTR:reservation_id": "%(reservation_id)s",
"OS-EXT-SRV-ATTR:root_device_name": "/dev/sda",
"OS-EXT-SRV-ATTR:user_data": "%(user_data)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"
}
],
"status": "ACTIVE",
"tenant_id": "6f70656e737461636b20342065766572",
"updated": "%(isotime)s",
"user_id": "fake"
}
}

View File

@ -0,0 +1,8 @@
{
"server": {
"accessIPv4": "%(access_ip_v4)s",
"accessIPv6": "%(access_ip_v6)s",
"OS-DCF:diskConfig": "AUTO",
"name" : "new-server-test"
}
}

View File

@ -0,0 +1,58 @@
{
"server": {
"OS-DCF:diskConfig": "AUTO",
"accessIPv4": "%(access_ip_v4)s",
"accessIPv6": "%(access_ip_v6)s",
"addresses": {
"private": [
{
"addr": "192.168.0.3",
"version": 4
}
]
},
"created": "%(isotime)s",
"description": 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"
}
]
},
"links": [
{
"href": "%(versioned_compute_endpoint)s/servers/%(id)s",
"rel": "self"
},
{
"href": "%(compute_endpoint)s/servers/%(id)s",
"rel": "bookmark"
}
],
"locked": false,
"metadata": {
"My Server Name": "Apache1"
},
"name": "new-server-test",
"progress": 0,
"status": "ACTIVE",
"tags": [],
"tenant_id": "6f70656e737461636b20342065766572",
"updated": "%(isotime)s",
"user_id": "fake"
}
}

View File

@ -0,0 +1,94 @@
{
"servers": [
{
"accessIPv4": "%(access_ip_v4)s",
"accessIPv6": "%(access_ip_v6)s",
"addresses": {
"private": [
{
"addr": "%(ip)s",
"OS-EXT-IPS-MAC:mac_addr": "aa:bb:cc:dd:ee:ff",
"OS-EXT-IPS:type": "fixed",
"version": 4
}
]
},
"created": "%(isotime)s",
"description": null,
"host_status": "UP",
"locked": false,
"tags": [],
"flavor": {
"disk": 1,
"ephemeral": 0,
"extra_specs": {
"hw:cpu_model": "SandyBridge",
"hw:mem_page_size": "2048",
"hw:cpu_policy": "dedicated"
},
"original_name": "m1.tiny.specs",
"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",
"OS-DCF:diskConfig": "AUTO",
"OS-EXT-AZ:availability_zone": "nova",
"OS-EXT-SRV-ATTR:host": "%(compute_host)s",
"OS-EXT-SRV-ATTR:hostname": "%(hostname)s",
"OS-EXT-SRV-ATTR:hypervisor_hostname": "%(hypervisor_hostname)s",
"OS-EXT-SRV-ATTR:instance_name": "%(instance_name)s",
"OS-EXT-SRV-ATTR:kernel_id": "",
"OS-EXT-SRV-ATTR:launch_index": 0,
"OS-EXT-SRV-ATTR:ramdisk_id": "",
"OS-EXT-SRV-ATTR:reservation_id": "%(reservation_id)s",
"OS-EXT-SRV-ATTR:root_device_name": "/dev/sda",
"OS-EXT-SRV-ATTR:user_data": "%(user_data)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"
}
],
"status": "ACTIVE",
"tenant_id": "6f70656e737461636b20342065766572",
"updated": "%(isotime)s",
"user_id": "fake"
}
]
}

View File

@ -0,0 +1,18 @@
{
"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"
}
]
}

View File

@ -85,10 +85,14 @@ class ServersSampleBase(api_sample_base.ApiSampleTestBaseV21):
class ServersSampleJsonTest(ServersSampleBase):
# This controls whether or not we use the common server API sample
# for server post req/resp.
use_common_server_post = True
microversion = None
def test_servers_post(self):
return self._post_server()
return self._post_server(
use_common_server_api_samples=self.use_common_server_post)
def test_servers_get(self):
self.stub_out('nova.db.block_device_mapping_get_all_by_instance_uuids',
@ -202,6 +206,30 @@ class ServersSampleJson242Test(ServersSampleBase):
self._post_server(use_common_server_api_samples=False)
class ServersSampleJson247Test(ServersSampleJsonTest):
microversion = '2.47'
scenarios = [('v2_47', {'api_major_version': 'v2.1'})]
use_common_server_post = False
def test_server_rebuild(self):
uuid = self._post_server()
image = fake.get_valid_image_id()
params = {
'uuid': image,
'name': 'foobar',
'pass': 'seekr3t',
'hostid': '[a-f0-9]+',
'access_ip_v4': '1.2.3.4',
'access_ip_v6': '80fe::',
}
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 ServersUpdateSampleJsonTest(ServersSampleBase):
def test_update_server(self):
@ -215,6 +243,11 @@ class ServersUpdateSampleJsonTest(ServersSampleBase):
self._verify_response('server-update-resp', subs, response, 200)
class ServersUpdateSampleJson247Test(ServersUpdateSampleJsonTest):
microversion = '2.47'
scenarios = [('v2_47', {'api_major_version': 'v2.1'})]
class ServerSortKeysJsonTests(ServersSampleBase):
sample_dir = 'servers-sort'

View File

@ -61,12 +61,15 @@ class ServersPreSchedulingTestCase(test.TestCase):
create_resp = self.api.api_post('servers', body)
get_resp = self.api.api_get('servers/%s' %
create_resp.body['server']['id'])
flavor_get_resp = self.api.api_get('flavors/%s' %
body['server']['flavorRef'])
server = get_resp.body['server']
# Validate a few things
self.assertEqual('foo', server['name'])
self.assertEqual(image_ref, server['image']['id'])
self.assertEqual('1', server['flavor']['id'])
self.assertEqual(flavor_get_resp.body['flavor']['name'],
server['flavor']['original_name'])
self.assertEqual('', server['hostId'])
self.assertIsNone(None, server['OS-SRV-USG:launched_at'])
self.assertIsNone(None, server['OS-SRV-USG:terminated_at'])
@ -89,11 +92,14 @@ class ServersPreSchedulingTestCase(test.TestCase):
create_resp = self.api.api_post('servers', body)
get_resp = self.api.api_get('servers/%s' %
create_resp.body['server']['id'])
flavor_get_resp = self.api.api_get('flavors/%s' %
body['server']['flavorRef'])
server = get_resp.body['server']
# Just validate some basics
self.assertEqual('foo', server['name'])
self.assertEqual(image_ref, server['image']['id'])
self.assertEqual('1', server['flavor']['id'])
self.assertEqual(flavor_get_resp.body['flavor']['name'],
server['flavor']['original_name'])
self.assertEqual('', server['hostId'])
self.assertIsNone(None, server['OS-SRV-USG:launched_at'])
self.assertIsNone(None, server['OS-SRV-USG:terminated_at'])

View File

@ -1662,6 +1662,64 @@ class ServerControllerTestV238(ControllerTest):
self._test_invalid_status(False)
class ServerControllerTestV247(ControllerTest):
"""Server controller test for microversion 2.47
The intent here is simply to verify that when showing server details
after microversion 2.47 that the flavor is shown as a dict of flavor
information rather than as dict of id/links. The existence of the
'extra_specs' key is controlled by policy.
"""
wsgi_api_version = '2.47'
@mock.patch.object(objects.TagList, 'get_by_resource_id')
def test_get_all_server_details(self, mock_get_by_resource_id):
# Fake out tags on the instances
mock_get_by_resource_id.return_value = objects.TagList()
expected_flavor = {
'disk': 20,
'ephemeral': 0,
'extra_specs': {},
'original_name': u'm1.small',
'ram': 2048,
'swap': 0,
'vcpus': 1}
req = fakes.HTTPRequest.blank('/fake/servers/detail',
version=self.wsgi_api_version)
res_dict = self.controller.detail(req)
for i, s in enumerate(res_dict['servers']):
self.assertEqual(s['flavor'], expected_flavor)
@mock.patch.object(objects.TagList, 'get_by_resource_id')
def test_get_all_server_details_no_extra_spec(self,
mock_get_by_resource_id):
# Fake out tags on the instances
mock_get_by_resource_id.return_value = objects.TagList()
# Set the policy so we don't have permission to index
# flavor extra-specs but are able to get server details.
servers_rule = 'os_compute_api:servers:detail'
extraspec_rule = 'os_compute_api:os-flavor-extra-specs:index'
self.policy.set_rules({
extraspec_rule: 'rule:admin_api',
servers_rule: '@'})
expected_flavor = {
'disk': 20,
'ephemeral': 0,
'original_name': u'm1.small',
'ram': 2048,
'swap': 0,
'vcpus': 1}
req = fakes.HTTPRequest.blank('/fake/servers/detail',
version=self.wsgi_api_version)
res_dict = self.controller.detail(req)
for i, s in enumerate(res_dict['servers']):
self.assertEqual(s['flavor'], expected_flavor)
class ServersControllerDeleteTest(ControllerTest):
def setUp(self):

View File

@ -0,0 +1,7 @@
---
features:
- A new 2.47 microversion was added to the Compute API. Users specifying
this microversion or later will see the "flavor" information displayed as
a dict when displaying server details via the `servers` REST API endpoint.
If the user is prevented by policy from indexing extra-specs, then the
"extra_specs" field will not be included in the flavor information.