Microversion 2.94: FQDN in hostname
Extend microversion 2.90 to allow FQDNs in the hostname parameter. Multi-create with --hostname continues to be refused, returning error 400 to the user. This simplifies the code by not needing to handle any sort of suffix or prefix mangling of the FQDN to handle multiple instances. No other changes are made - not Neutron integration, metadata API changes (the FQDN will appear as-is in places where the hostname currently appears), etc. Change-Id: I47e397dc6da8263762479cc8ae4f8777a6d9d811 Implements: bp/fqdn-in-hostname
This commit is contained in:
parent
8e3ffb851b
commit
9980b9ad52
@ -6382,6 +6382,9 @@ server_hostname_req:
|
||||
description: |
|
||||
The hostname to configure for the instance in the metadata service.
|
||||
|
||||
Starting with microversion 2.94, this can be a Fully Qualified Domain Name
|
||||
(FQDN) of up to 255 characters in length.
|
||||
|
||||
.. note::
|
||||
|
||||
This information is published via the metadata service and requires
|
||||
|
@ -604,6 +604,11 @@ Request
|
||||
.. literalinclude:: ../../doc/api_samples/servers/v2.90/server-action-rebuild.json
|
||||
:language: javascript
|
||||
|
||||
**Example Rebuild Server (rebuild Action) (v2.94)**
|
||||
|
||||
.. literalinclude:: ../../doc/api_samples/servers/v2.94/server-action-rebuild.json
|
||||
:language: javascript
|
||||
|
||||
Response
|
||||
--------
|
||||
|
||||
|
@ -448,6 +448,11 @@ Request
|
||||
.. literalinclude:: ../../doc/api_samples/servers/v2.90/server-create-req.json
|
||||
:language: javascript
|
||||
|
||||
**Example Create Server With FQDN in Hostname (v2.94)**
|
||||
|
||||
.. literalinclude:: ../../doc/api_samples/servers/v2.94/server-create-req.json
|
||||
:language: javascript
|
||||
|
||||
Response
|
||||
--------
|
||||
|
||||
|
@ -0,0 +1,80 @@
|
||||
{
|
||||
"server": {
|
||||
"OS-DCF:diskConfig": "AUTO",
|
||||
"OS-EXT-AZ:availability_zone": "us-west",
|
||||
"OS-EXT-SRV-ATTR:hostname": "updated-hostname.example.com",
|
||||
"OS-EXT-STS:power_state": 1,
|
||||
"OS-EXT-STS:task_state": null,
|
||||
"OS-EXT-STS:vm_state": "active",
|
||||
"OS-SRV-USG:launched_at": "2021-08-19T15:16:22.177882",
|
||||
"OS-SRV-USG:terminated_at": null,
|
||||
"accessIPv4": "1.2.3.4",
|
||||
"accessIPv6": "80fe::",
|
||||
"addresses": {
|
||||
"private": [
|
||||
{
|
||||
"OS-EXT-IPS-MAC:mac_addr": "00:0c:29:0d:11:74",
|
||||
"OS-EXT-IPS:type": "fixed",
|
||||
"addr": "192.168.1.30",
|
||||
"version": 4
|
||||
}
|
||||
]
|
||||
},
|
||||
"adminPass": "seekr3t",
|
||||
"config_drive": "",
|
||||
"created": "2019-04-23T17:10:22Z",
|
||||
"description": null,
|
||||
"flavor": {
|
||||
"disk": 1,
|
||||
"ephemeral": 0,
|
||||
"extra_specs": {},
|
||||
"original_name": "m1.tiny",
|
||||
"ram": 512,
|
||||
"swap": 0,
|
||||
"vcpus": 1
|
||||
},
|
||||
"hostId": "2091634baaccdc4c5a1d57069c833e402921df696b7f970791b12ec6",
|
||||
"id": "0c37a84a-c757-4f22-8c7f-0bf8b6970886",
|
||||
"image": {
|
||||
"id": "70a599e0-31e7-49b7-b260-868f441e862b",
|
||||
"links": [
|
||||
{
|
||||
"href": "http://openstack.example.com/6f70656e737461636b20342065766572/images/70a599e0-31e7-49b7-b260-868f441e862b",
|
||||
"rel": "bookmark"
|
||||
}
|
||||
]
|
||||
},
|
||||
"key_name": null,
|
||||
"links": [
|
||||
{
|
||||
"href": "http://openstack.example.com/v2.1/6f70656e737461636b20342065766572/servers/0c37a84a-c757-4f22-8c7f-0bf8b6970886",
|
||||
"rel": "self"
|
||||
},
|
||||
{
|
||||
"href": "http://openstack.example.com/6f70656e737461636b20342065766572/servers/0c37a84a-c757-4f22-8c7f-0bf8b6970886",
|
||||
"rel": "bookmark"
|
||||
}
|
||||
],
|
||||
"locked": false,
|
||||
"locked_reason": null,
|
||||
"metadata": {
|
||||
"meta_var": "meta_val"
|
||||
},
|
||||
"name": "foobar",
|
||||
"os-extended-volumes:volumes_attached": [],
|
||||
"progress": 0,
|
||||
"security_groups": [
|
||||
{
|
||||
"name": "default"
|
||||
}
|
||||
],
|
||||
"server_groups": [],
|
||||
"status": "ACTIVE",
|
||||
"tags": [],
|
||||
"tenant_id": "6f70656e737461636b20342065766572",
|
||||
"trusted_image_certificates": null,
|
||||
"updated": "2019-04-23T17:10:24Z",
|
||||
"user_data": "ZWNobyAiaGVsbG8gd29ybGQi",
|
||||
"user_id": "fake"
|
||||
}
|
||||
}
|
15
doc/api_samples/servers/v2.94/server-action-rebuild.json
Normal file
15
doc/api_samples/servers/v2.94/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.example.com",
|
||||
"metadata" : {
|
||||
"meta_var" : "meta_val"
|
||||
},
|
||||
"user_data": "ZWNobyAiaGVsbG8gd29ybGQi"
|
||||
}
|
||||
}
|
30
doc/api_samples/servers/v2.94/server-create-req.json
Normal file
30
doc/api_samples/servers/v2.94/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.example.com",
|
||||
"metadata" : {
|
||||
"My Server Name" : "Apache1"
|
||||
},
|
||||
"personality": [
|
||||
{
|
||||
"path": "/etc/banner.txt",
|
||||
"contents": "ICAgICAgDQoiQSBjbG91ZCBkb2VzIG5vdCBrbm93IHdoeSBp dCBtb3ZlcyBpbiBqdXN0IHN1Y2ggYSBkaXJlY3Rpb24gYW5k IGF0IHN1Y2ggYSBzcGVlZC4uLkl0IGZlZWxzIGFuIGltcHVs c2lvbi4uLnRoaXMgaXMgdGhlIHBsYWNlIHRvIGdvIG5vdy4g QnV0IHRoZSBza3kga25vd3MgdGhlIHJlYXNvbnMgYW5kIHRo ZSBwYXR0ZXJucyBiZWhpbmQgYWxsIGNsb3VkcywgYW5kIHlv dSB3aWxsIGtub3csIHRvbywgd2hlbiB5b3UgbGlmdCB5b3Vy c2VsZiBoaWdoIGVub3VnaCB0byBzZWUgYmV5b25kIGhvcml6 b25zLiINCg0KLVJpY2hhcmQgQmFjaA=="
|
||||
}
|
||||
],
|
||||
"security_groups": [
|
||||
{
|
||||
"name": "default"
|
||||
}
|
||||
],
|
||||
"user_data" : "IyEvYmluL2Jhc2gKL2Jpbi9zdQplY2hvICJJIGFtIGluIHlvdSEiCg=="
|
||||
},
|
||||
"OS-SCH-HNT:scheduler_hints": {
|
||||
"same_host": "48e6a9f6-30af-47e0-bc04-acaed113bb4e"
|
||||
}
|
||||
}
|
22
doc/api_samples/servers/v2.94/server-create-resp.json
Normal file
22
doc/api_samples/servers/v2.94/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.94/server-get-resp.json
Normal file
81
doc/api_samples/servers/v2.94/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.example.com",
|
||||
"OS-EXT-STS:power_state": 1,
|
||||
"OS-EXT-STS:task_state": null,
|
||||
"OS-EXT-STS:vm_state": "active",
|
||||
"os-extended-volumes:volumes_attached": [
|
||||
{"id": "volume_id1", "delete_on_termination": false},
|
||||
{"id": "volume_id2", "delete_on_termination": false}
|
||||
],
|
||||
"OS-SRV-USG:launched_at": "2013-09-23T13:37:00.880302",
|
||||
"OS-SRV-USG:terminated_at": null,
|
||||
"progress": 0,
|
||||
"security_groups": [
|
||||
{
|
||||
"name": "default"
|
||||
}
|
||||
],
|
||||
"server_groups": [],
|
||||
"status": "ACTIVE",
|
||||
"tags": [],
|
||||
"tenant_id": "6f70656e737461636b20342065766572",
|
||||
"trusted_image_certificates": null,
|
||||
"updated": "2013-09-03T04:01:33Z",
|
||||
"user_id": "fake"
|
||||
}
|
||||
}
|
8
doc/api_samples/servers/v2.94/server-update-req.json
Normal file
8
doc/api_samples/servers/v2.94/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.example.com"
|
||||
}
|
||||
}
|
78
doc/api_samples/servers/v2.94/server-update-resp.json
Normal file
78
doc/api_samples/servers/v2.94/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.example.com",
|
||||
"OS-EXT-STS:power_state": 1,
|
||||
"OS-EXT-STS:task_state": null,
|
||||
"OS-EXT-STS:vm_state": "active",
|
||||
"os-extended-volumes:volumes_attached": [],
|
||||
"OS-SRV-USG:launched_at": "2013-09-23T13:37:00.880302",
|
||||
"OS-SRV-USG:terminated_at": null,
|
||||
"progress": 0,
|
||||
"security_groups": [
|
||||
{
|
||||
"name": "default"
|
||||
}
|
||||
],
|
||||
"server_groups": [],
|
||||
"status": "ACTIVE",
|
||||
"tags": [],
|
||||
"tenant_id": "6f70656e737461636b20342065766572",
|
||||
"trusted_image_certificates": null,
|
||||
"updated": "2013-09-03T04:01:33Z",
|
||||
"user_id": "fake"
|
||||
}
|
||||
}
|
88
doc/api_samples/servers/v2.94/servers-details-resp.json
Normal file
88
doc/api_samples/servers/v2.94/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.example.com",
|
||||
"OS-EXT-STS:power_state": 1,
|
||||
"OS-EXT-STS:task_state": null,
|
||||
"OS-EXT-STS:vm_state": "active",
|
||||
"os-extended-volumes:volumes_attached": [
|
||||
{"id": "volume_id1", "delete_on_termination": false},
|
||||
{"id": "volume_id2", "delete_on_termination": false}
|
||||
],
|
||||
"OS-SRV-USG:launched_at": "2013-09-23T13:53:12.774549",
|
||||
"OS-SRV-USG:terminated_at": null,
|
||||
"progress": 0,
|
||||
"security_groups": [
|
||||
{
|
||||
"name": "default"
|
||||
}
|
||||
],
|
||||
"status": "ACTIVE",
|
||||
"tags": [],
|
||||
"tenant_id": "6f70656e737461636b20342065766572",
|
||||
"trusted_image_certificates": null,
|
||||
"updated": "2013-09-03T04:01:32Z",
|
||||
"user_id": "fake"
|
||||
}
|
||||
],
|
||||
"servers_links": [
|
||||
{
|
||||
"href": "http://openstack.example.com/v2.1/6f70656e737461636b20342065766572/servers/detail?limit=1&marker=f5dc173b-6804-445a-a6d8-c705dad5b5eb",
|
||||
"rel": "next"
|
||||
}
|
||||
]
|
||||
}
|
24
doc/api_samples/servers/v2.94/servers-list-resp.json
Normal file
24
doc/api_samples/servers/v2.94/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",
|
||||
"version": "2.93",
|
||||
"version": "2.94",
|
||||
"min_version": "2.1",
|
||||
"updated": "2013-07-23T11:33:21Z"
|
||||
}
|
||||
|
@ -22,7 +22,7 @@
|
||||
}
|
||||
],
|
||||
"status": "CURRENT",
|
||||
"version": "2.93",
|
||||
"version": "2.94",
|
||||
"min_version": "2.1",
|
||||
"updated": "2013-07-23T11:33:21Z"
|
||||
}
|
||||
|
@ -253,6 +253,7 @@ REST_API_VERSION_HISTORY = """REST API Version History:
|
||||
``POST /os-keypairs`` and allow including @ and dot (.) characters
|
||||
in keypair name.
|
||||
* 2.93 - Add support for volume backed server rebuild.
|
||||
* 2.94 - Allow FQDN in server hostname.
|
||||
"""
|
||||
|
||||
# The minimum and maximum versions of the API supported
|
||||
@ -261,7 +262,7 @@ 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.93'
|
||||
_MAX_API_VERSION = '2.94'
|
||||
DEFAULT_API_VERSION = _MIN_API_VERSION
|
||||
|
||||
# Almost all proxy APIs which are related to network, images and baremetal
|
||||
|
@ -1229,3 +1229,11 @@ Add support for volume backed server rebuild. The end user will provide the
|
||||
image with the rebuild command and it will rebuild the volume with the new
|
||||
image similar to the result of rebuilding an ephemeral disk.
|
||||
|
||||
|
||||
2.94
|
||||
---------------------
|
||||
|
||||
The ``hostname`` parameter to the ``POST /servers`` (create server), ``PUT
|
||||
/servers/{id}`` (update server) and ``POST /servers/{server_id}/action
|
||||
(rebuild)`` (rebuild server) APIs is now allowed to be a Fully Qualified Domain
|
||||
Name (FQDN).
|
||||
|
@ -360,6 +360,11 @@ create_v290 = copy.deepcopy(create_v274)
|
||||
create_v290['properties']['server'][
|
||||
'properties']['hostname'] = parameter_types.hostname
|
||||
|
||||
# Support FQDN as hostname
|
||||
create_v294 = copy.deepcopy(create_v290)
|
||||
create_v294['properties']['server'][
|
||||
'properties']['hostname'] = parameter_types.fqdn
|
||||
|
||||
update = {
|
||||
'type': 'object',
|
||||
'properties': {
|
||||
@ -391,6 +396,11 @@ update_v290 = copy.deepcopy(update_v219)
|
||||
update_v290['properties']['server'][
|
||||
'properties']['hostname'] = parameter_types.hostname
|
||||
|
||||
|
||||
update_v294 = copy.deepcopy(update_v290)
|
||||
update_v294['properties']['server'][
|
||||
'properties']['hostname'] = parameter_types.fqdn
|
||||
|
||||
rebuild = {
|
||||
'type': 'object',
|
||||
'properties': {
|
||||
@ -449,6 +459,10 @@ rebuild_v290 = copy.deepcopy(rebuild_v263)
|
||||
rebuild_v290['properties']['rebuild']['properties'][
|
||||
'hostname'] = parameter_types.hostname
|
||||
|
||||
rebuild_v294 = copy.deepcopy(rebuild_v290)
|
||||
rebuild_v294['properties']['rebuild']['properties'][
|
||||
'hostname'] = parameter_types.fqdn
|
||||
|
||||
|
||||
resize = {
|
||||
'type': 'object',
|
||||
|
@ -677,7 +677,8 @@ class ServersController(wsgi.Controller):
|
||||
@validation.schema(schema_servers.create_v263, '2.63', '2.66')
|
||||
@validation.schema(schema_servers.create_v267, '2.67', '2.73')
|
||||
@validation.schema(schema_servers.create_v274, '2.74', '2.89')
|
||||
@validation.schema(schema_servers.create_v290, '2.90')
|
||||
@validation.schema(schema_servers.create_v290, '2.90', '2.93')
|
||||
@validation.schema(schema_servers.create_v294, '2.94')
|
||||
def create(self, req, body):
|
||||
"""Creates a new server for a given user."""
|
||||
context = req.environ['nova.context']
|
||||
@ -906,7 +907,8 @@ class ServersController(wsgi.Controller):
|
||||
@validation.schema(schema_servers.update_v20, '2.0', '2.0')
|
||||
@validation.schema(schema_servers.update, '2.1', '2.18')
|
||||
@validation.schema(schema_servers.update_v219, '2.19', '2.89')
|
||||
@validation.schema(schema_servers.update_v290, '2.90')
|
||||
@validation.schema(schema_servers.update_v290, '2.90', '2.93')
|
||||
@validation.schema(schema_servers.update_v294, '2.94')
|
||||
def update(self, req, id, body):
|
||||
"""Update server then pass on to version-specific controller."""
|
||||
|
||||
@ -1147,7 +1149,8 @@ class ServersController(wsgi.Controller):
|
||||
@validation.schema(schema_servers.rebuild_v254, '2.54', '2.56')
|
||||
@validation.schema(schema_servers.rebuild_v257, '2.57', '2.62')
|
||||
@validation.schema(schema_servers.rebuild_v263, '2.63', '2.89')
|
||||
@validation.schema(schema_servers.rebuild_v290, '2.90')
|
||||
@validation.schema(schema_servers.rebuild_v290, '2.90', '2.93')
|
||||
@validation.schema(schema_servers.rebuild_v294, '2.94')
|
||||
def _action_rebuild(self, req, id, body):
|
||||
"""Rebuild an instance with the given attributes."""
|
||||
rebuild_dict = body['rebuild']
|
||||
|
@ -225,8 +225,11 @@ service.
|
||||
help="""
|
||||
Domain name used to configure FQDN for instances.
|
||||
|
||||
Configure a fully-qualified domain name for instance hostnames. If unset, only
|
||||
the hostname without a domain will be configured.
|
||||
Configure a fully-qualified domain name for instance hostnames. The value is
|
||||
suffixed to the instance hostname from the database to construct the hostname
|
||||
that appears in the metadata API. To disable this behavior (for example in
|
||||
order to correctly support microversion's 2.94 FQDN hostnames), set this to the
|
||||
empty string.
|
||||
|
||||
Possible values:
|
||||
|
||||
|
@ -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"
|
||||
}
|
||||
}
|
@ -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"
|
||||
}
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
{
|
||||
"server" : {
|
||||
"accessIPv4": "%(access_ip_v4)s",
|
||||
"accessIPv6": "%(access_ip_v6)s",
|
||||
"name" : "new-server-test",
|
||||
"imageRef" : "%(image_id)s",
|
||||
"flavorRef" : "1",
|
||||
"OS-DCF:diskConfig": "AUTO",
|
||||
"metadata" : {
|
||||
"My Server Name" : "Apache1"
|
||||
},
|
||||
"security_groups": [
|
||||
{
|
||||
"name": "default"
|
||||
}
|
||||
],
|
||||
"user_data" : "%(user_data)s",
|
||||
"networks": "auto",
|
||||
"hostname": "custom-hostname.example.com"
|
||||
}
|
||||
}
|
@ -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"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
@ -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"
|
||||
}
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
{
|
||||
"server": {
|
||||
"accessIPv4": "%(access_ip_v4)s",
|
||||
"accessIPv6": "%(access_ip_v6)s",
|
||||
"OS-DCF:diskConfig": "AUTO",
|
||||
"hostname": "new-server-hostname.example.com"
|
||||
}
|
||||
}
|
@ -0,0 +1,78 @@
|
||||
{
|
||||
"server": {
|
||||
"accessIPv4": "%(access_ip_v4)s",
|
||||
"accessIPv6": "%(access_ip_v6)s",
|
||||
"addresses": {
|
||||
"private": [
|
||||
{
|
||||
"addr": "%(ip)s",
|
||||
"OS-EXT-IPS-MAC:mac_addr": "00:0c:29:0d:11:74",
|
||||
"OS-EXT-IPS:type": "fixed",
|
||||
"version": 4
|
||||
}
|
||||
]
|
||||
},
|
||||
"created": "%(isotime)s",
|
||||
"description": null,
|
||||
"locked": false,
|
||||
"locked_reason": null,
|
||||
"flavor": {
|
||||
"disk": 1,
|
||||
"ephemeral": 0,
|
||||
"extra_specs": {},
|
||||
"original_name": "m1.tiny",
|
||||
"ram": 512,
|
||||
"swap": 0,
|
||||
"vcpus": 1
|
||||
},
|
||||
"hostId": "%(hostid)s",
|
||||
"id": "%(id)s",
|
||||
"image": {
|
||||
"id": "%(uuid)s",
|
||||
"links": [
|
||||
{
|
||||
"href": "%(compute_endpoint)s/images/%(uuid)s",
|
||||
"rel": "bookmark"
|
||||
}
|
||||
]
|
||||
},
|
||||
"key_name": null,
|
||||
"links": [
|
||||
{
|
||||
"href": "%(versioned_compute_endpoint)s/servers/%(uuid)s",
|
||||
"rel": "self"
|
||||
},
|
||||
{
|
||||
"href": "%(compute_endpoint)s/servers/%(uuid)s",
|
||||
"rel": "bookmark"
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"My Server Name": "Apache1"
|
||||
},
|
||||
"name": "new-server-test",
|
||||
"config_drive": "",
|
||||
"OS-DCF:diskConfig": "AUTO",
|
||||
"OS-EXT-AZ:availability_zone": "us-west",
|
||||
"OS-EXT-SRV-ATTR:hostname": "new-server-hostname.example.com",
|
||||
"OS-EXT-STS:power_state": 1,
|
||||
"OS-EXT-STS:task_state": null,
|
||||
"OS-EXT-STS:vm_state": "active",
|
||||
"os-extended-volumes:volumes_attached": [],
|
||||
"OS-SRV-USG:launched_at": "%(strtime)s",
|
||||
"OS-SRV-USG:terminated_at": null,
|
||||
"progress": 0,
|
||||
"security_groups": [
|
||||
{
|
||||
"name": "default"
|
||||
}
|
||||
],
|
||||
"server_groups": [],
|
||||
"status": "ACTIVE",
|
||||
"tags": [],
|
||||
"tenant_id": "6f70656e737461636b20342065766572",
|
||||
"trusted_image_certificates": null,
|
||||
"updated": "%(isotime)s",
|
||||
"user_id": "fake"
|
||||
}
|
||||
}
|
@ -0,0 +1,88 @@
|
||||
{
|
||||
"servers": [
|
||||
{
|
||||
"accessIPv4": "%(access_ip_v4)s",
|
||||
"accessIPv6": "%(access_ip_v6)s",
|
||||
"addresses": {
|
||||
"private": [
|
||||
{
|
||||
"addr": "%(ip)s",
|
||||
"OS-EXT-IPS-MAC:mac_addr": "00:0c:29:0d:11:74",
|
||||
"OS-EXT-IPS:type": "fixed",
|
||||
"version": 4
|
||||
}
|
||||
]
|
||||
},
|
||||
"created": "%(isotime)s",
|
||||
"description": "",
|
||||
"flavor": {
|
||||
"disk": 1,
|
||||
"ephemeral": 0,
|
||||
"extra_specs": {},
|
||||
"original_name": "m1.tiny",
|
||||
"ram": 512,
|
||||
"swap": 0,
|
||||
"vcpus": 1
|
||||
},
|
||||
"hostId": "%(hostid)s",
|
||||
"id": "%(id)s",
|
||||
"image": {
|
||||
"id": "%(uuid)s",
|
||||
"links": [
|
||||
{
|
||||
"href": "%(compute_endpoint)s/images/%(uuid)s",
|
||||
"rel": "bookmark"
|
||||
}
|
||||
]
|
||||
},
|
||||
"key_name": null,
|
||||
"links": [
|
||||
{
|
||||
"href": "%(versioned_compute_endpoint)s/servers/%(uuid)s",
|
||||
"rel": "self"
|
||||
},
|
||||
{
|
||||
"href": "%(compute_endpoint)s/servers/%(id)s",
|
||||
"rel": "bookmark"
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"My Server Name": "Apache1"
|
||||
},
|
||||
"name": "new-server-test",
|
||||
"config_drive": "%(cdrive)s",
|
||||
"locked": false,
|
||||
"locked_reason": "",
|
||||
"OS-DCF:diskConfig": "AUTO",
|
||||
"OS-EXT-AZ:availability_zone": "nova",
|
||||
"OS-EXT-SRV-ATTR:hostname": "custom-hostname.example.com",
|
||||
"OS-EXT-STS:power_state": 1,
|
||||
"OS-EXT-STS:task_state": null,
|
||||
"OS-EXT-STS:vm_state": "active",
|
||||
"os-extended-volumes:volumes_attached": [
|
||||
{"id": "volume_id1", "delete_on_termination": false},
|
||||
{"id": "volume_id2", "delete_on_termination": false}
|
||||
],
|
||||
"OS-SRV-USG:launched_at": "%(strtime)s",
|
||||
"OS-SRV-USG:terminated_at": null,
|
||||
"progress": 0,
|
||||
"security_groups": [
|
||||
{
|
||||
"name": "default"
|
||||
}
|
||||
],
|
||||
"status": "ACTIVE",
|
||||
"tags": [],
|
||||
"tenant_id": "6f70656e737461636b20342065766572",
|
||||
"trusted_image_certificates": null,
|
||||
"updated": "%(isotime)s",
|
||||
"user_id": "fake"
|
||||
}
|
||||
],
|
||||
"servers_links": [
|
||||
{
|
||||
"href": "%(versioned_compute_endpoint)s/servers/detail?limit=1&marker=%(id)s",
|
||||
"rel": "next"
|
||||
}
|
||||
]
|
||||
}
|
@ -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"
|
||||
}
|
||||
]
|
||||
}
|
@ -618,6 +618,13 @@ class ServersSampleJson290Test(ServersSampleJsonTest):
|
||||
ADMIN_API = False
|
||||
|
||||
|
||||
class ServersSampleJson294Test(ServersSampleJsonTest):
|
||||
microversion = '2.94'
|
||||
scenarios = [('v2_94', {'api_major_version': 'v2.1'})]
|
||||
use_common_server_post = False
|
||||
ADMIN_API = False
|
||||
|
||||
|
||||
class ServersUpdateSampleJsonTest(ServersSampleBase):
|
||||
|
||||
# Many of the 'os_compute_api:servers:*' policies are admin-only, and we
|
||||
@ -702,6 +709,44 @@ class ServersUpdateSampleJson290Test(ServersUpdateSampleJsonTest):
|
||||
self._verify_response('server-action-rebuild-resp', subs, resp, 202)
|
||||
|
||||
|
||||
class ServersUpdateSampleJson294Test(ServersUpdateSampleJsonTest):
|
||||
microversion = '2.94'
|
||||
scenarios = [('v2_94', {'api_major_version': 'v2.1'})]
|
||||
ADMIN_API = False
|
||||
|
||||
def test_update_server(self):
|
||||
uuid = self._post_server()
|
||||
subs = {}
|
||||
subs['hostid'] = '[a-f0-9]+'
|
||||
subs['access_ip_v4'] = '1.2.3.4'
|
||||
subs['access_ip_v6'] = '80fe::'
|
||||
subs['hostname'] = 'updated-hostname.example.com'
|
||||
response = self._do_put('servers/%s' % uuid,
|
||||
'server-update-req', subs)
|
||||
self._verify_response('server-update-resp', subs, response, 200)
|
||||
|
||||
def test_server_rebuild(self):
|
||||
uuid = self._post_server()
|
||||
params = {
|
||||
'uuid': self.glance.auto_disk_config_enabled_image['id'],
|
||||
'name': 'foobar',
|
||||
'pass': 'seekr3t',
|
||||
'hostid': '[a-f0-9]+',
|
||||
'access_ip_v4': '1.2.3.4',
|
||||
'access_ip_v6': '80fe::',
|
||||
'hostname': 'updated-hostname.example.com',
|
||||
}
|
||||
|
||||
resp = self._do_post(
|
||||
'servers/%s/action' % uuid,
|
||||
'server-action-rebuild',
|
||||
params,
|
||||
)
|
||||
subs = params.copy()
|
||||
del subs['uuid']
|
||||
self._verify_response('server-action-rebuild-resp', subs, resp, 202)
|
||||
|
||||
|
||||
class ServerSortKeysJsonTests(ServersSampleBase):
|
||||
sample_dir = 'servers-sort'
|
||||
|
||||
|
22
releasenotes/notes/microversion-2-94-59649401d5763286.yaml
Normal file
22
releasenotes/notes/microversion-2-94-59649401d5763286.yaml
Normal file
@ -0,0 +1,22 @@
|
||||
---
|
||||
features:
|
||||
- |
|
||||
The 2.94 microversion has been added. This microversion extends
|
||||
microversion 2.90 by allowing Fully Qualified Domain Names (FQDN) wherever
|
||||
the ``hostname`` is able to be specified. This consists of creating an
|
||||
instance (``POST /servers``), updating an instance
|
||||
(``PUT /servers/{id}``), or rebuilding an instance
|
||||
(``POST /servers/{server_id}/action (rebuild)``). When using an FQDN as the
|
||||
instance hostname, the ``[api]dhcp_domain`` configuration option must be
|
||||
set to the empty string in order for the correct FQDN to appear in the
|
||||
``hostname`` field in the metadata API.
|
||||
|
||||
upgrade:
|
||||
- |
|
||||
In order to make use of microversion's 2.94 FQDN hostnames, the
|
||||
``[api]dhcp_domain`` config option must be set to the empty string. If
|
||||
this is not done, the ``hostname`` field in the metadata API will be
|
||||
incorrect, as it will include the value of ``[api]dhcp_domain`` appended to
|
||||
the instance's FQDN. Note that simply not setting ``[api]dhcp_domain`` is
|
||||
not enough, as it has a default value of ``novalocal``. It must explicitly
|
||||
be set to the empty string.
|
Loading…
x
Reference in New Issue
Block a user