api: Remove dead fields from flavors response

Change-Id: I65be4f2e522c9f73a28b8837d7937a371d3e73d3
Signed-off-by: Stephen Finucane <stephenfin@redhat.com>
This commit is contained in:
Stephen Finucane
2025-06-20 15:10:19 +01:00
parent e73a0bc84b
commit b95a2c5219
27 changed files with 831 additions and 35 deletions
+10 -11
View File
@@ -46,9 +46,9 @@ Response
- description: flavor_description_resp - description: flavor_description_resp
- links: links - links: links
**Example List Flavors (v2.55)** **Example List Flavors (v2.102)**
.. literalinclude:: ../../doc/api_samples/flavors/v2.55/flavors-list-resp.json .. literalinclude:: ../../doc/api_samples/flavors/v2.102/flavors-list-resp.json
:language: javascript :language: javascript
Create Flavor Create Flavor
@@ -92,9 +92,9 @@ Request
- rxtx_factor: flavor_rxtx_factor_in - rxtx_factor: flavor_rxtx_factor_in
- os-flavor-access:is_public: flavor_is_public_in - os-flavor-access:is_public: flavor_is_public_in
**Example Create Flavor (v2.55)** **Example Create Flavor (v2.102)**
.. literalinclude:: ../../doc/api_samples/flavor-manage/v2.55/flavor-create-post-req.json .. literalinclude:: ../../doc/api_samples/flavor-manage/v2.102/flavor-create-post-req.json
:language: javascript :language: javascript
Response Response
@@ -117,10 +117,9 @@ Response
- os-flavor-access:is_public: flavor_is_public - os-flavor-access:is_public: flavor_is_public
- extra_specs: extra_specs_2_61 - extra_specs: extra_specs_2_61
**Example Create Flavor (v2.102)**
**Example Create Flavor (v2.75)** .. literalinclude:: ../../doc/api_samples/flavor-manage/v2.102/flavor-create-post-resp.json
.. literalinclude:: ../../doc/api_samples/flavor-manage/v2.75/flavor-create-post-resp.json
:language: javascript :language: javascript
List Flavors With Details List Flavors With Details
@@ -168,9 +167,9 @@ Response
- os-flavor-access:is_public: flavor_is_public - os-flavor-access:is_public: flavor_is_public
- extra_specs: extra_specs_2_61 - extra_specs: extra_specs_2_61
**Example List Flavors With Details (v2.75)** **Example List Flavors With Details (v2.102)**
.. literalinclude:: ../../doc/api_samples/flavors/v2.75/flavors-detail-resp.json .. literalinclude:: ../../doc/api_samples/flavors/v2.102/flavors-detail-resp.json
:language: javascript :language: javascript
Show Flavor Details Show Flavor Details
@@ -211,9 +210,9 @@ Response
- os-flavor-access:is_public: flavor_is_public - os-flavor-access:is_public: flavor_is_public
- extra_specs: extra_specs_2_61 - extra_specs: extra_specs_2_61
**Example Show Flavor Details (v2.75)** **Example Show Flavor Details (v2.102)**
.. literalinclude:: ../../doc/api_samples/flavors/v2.75/flavor-get-resp.json .. literalinclude:: ../../doc/api_samples/flavors/v2.102/flavor-get-resp.json
:language: javascript :language: javascript
Update Flavor Description Update Flavor Description
+3
View File
@@ -3059,6 +3059,7 @@ flavor_disabled:
This is an artifact of the legacy v2 API and will always be set to This is an artifact of the legacy v2 API and will always be set to
``false``. There is currently no way to disable a flavor and set this to ``false``. There is currently no way to disable a flavor and set this to
``true``. ``true``.
max_version: 2.101
flavor_disk: flavor_disk:
in: body in: body
required: true required: true
@@ -3221,6 +3222,7 @@ flavor_rxtx_factor:
in: body in: body
required: true required: true
type: float type: float
max_version: 2.101
flavor_rxtx_factor_in: flavor_rxtx_factor_in:
description: | description: |
The receive / transmit factor (as a float) that will be set on The receive / transmit factor (as a float) that will be set on
@@ -3229,6 +3231,7 @@ flavor_rxtx_factor_in:
in: body in: body
required: false required: false
type: float type: float
max_version: 2.101
flavor_server: flavor_server:
description: | description: |
Before microversion 2.47 this contains the ID and links for the flavor Before microversion 2.47 this contains the ID and links for the flavor
@@ -0,0 +1,10 @@
{
"flavor": {
"name": "test_flavor",
"ram": 1024,
"vcpus": 2,
"disk": 10,
"id": "10",
"description": "test description"
}
}
@@ -0,0 +1,24 @@
{
"flavor": {
"OS-FLV-EXT-DATA:ephemeral": 0,
"description": "test description",
"disk": 10,
"extra_specs": {},
"id": "10",
"links": [
{
"href": "http://openstack.example.com/v2.1/6f70656e737461636b20342065766572/flavors/10",
"rel": "self"
},
{
"href": "http://openstack.example.com/6f70656e737461636b20342065766572/flavors/10",
"rel": "bookmark"
}
],
"name": "test_flavor",
"os-flavor-access:is_public": true,
"ram": 1024,
"swap": 0,
"vcpus": 2
}
}
@@ -0,0 +1,5 @@
{
"flavor": {
"description": "updated description"
}
}
@@ -0,0 +1,24 @@
{
"flavor": {
"OS-FLV-EXT-DATA:ephemeral": 0,
"description": "updated description",
"disk": 1,
"extra_specs": {},
"id": "1",
"links": [
{
"href": "http://openstack.example.com/v2.1/6f70656e737461636b20342065766572/flavors/1",
"rel": "self"
},
{
"href": "http://openstack.example.com/6f70656e737461636b20342065766572/flavors/1",
"rel": "bookmark"
}
],
"name": "m1.tiny",
"os-flavor-access:is_public": true,
"ram": 512,
"swap": 0,
"vcpus": 1
}
}
@@ -0,0 +1,27 @@
{
"flavor": {
"OS-FLV-EXT-DATA:ephemeral": 0,
"description": "test description",
"disk": 20,
"extra_specs": {
"hw:cpu_policy": "shared",
"hw:numa_nodes": "1"
},
"id": "7",
"links": [
{
"href": "http://openstack.example.com/v2.1/6f70656e737461636b20342065766572/flavors/7",
"rel": "self"
},
{
"href": "http://openstack.example.com/6f70656e737461636b20342065766572/flavors/7",
"rel": "bookmark"
}
],
"name": "m1.small.description",
"os-flavor-access:is_public": true,
"ram": 2048,
"swap": 0,
"vcpus": 1
}
}
@@ -0,0 +1,163 @@
{
"flavors": [
{
"OS-FLV-EXT-DATA:ephemeral": 0,
"description": null,
"disk": 1,
"extra_specs": {},
"id": "1",
"links": [
{
"href": "http://openstack.example.com/v2.1/6f70656e737461636b20342065766572/flavors/1",
"rel": "self"
},
{
"href": "http://openstack.example.com/6f70656e737461636b20342065766572/flavors/1",
"rel": "bookmark"
}
],
"name": "m1.tiny",
"os-flavor-access:is_public": true,
"ram": 512,
"swap": 0,
"vcpus": 1
},
{
"OS-FLV-EXT-DATA:ephemeral": 0,
"description": null,
"disk": 20,
"extra_specs": {},
"id": "2",
"links": [
{
"href": "http://openstack.example.com/v2.1/6f70656e737461636b20342065766572/flavors/2",
"rel": "self"
},
{
"href": "http://openstack.example.com/6f70656e737461636b20342065766572/flavors/2",
"rel": "bookmark"
}
],
"name": "m1.small",
"os-flavor-access:is_public": true,
"ram": 2048,
"swap": 0,
"vcpus": 1
},
{
"OS-FLV-EXT-DATA:ephemeral": 0,
"description": null,
"disk": 40,
"extra_specs": {},
"id": "3",
"links": [
{
"href": "http://openstack.example.com/v2.1/6f70656e737461636b20342065766572/flavors/3",
"rel": "self"
},
{
"href": "http://openstack.example.com/6f70656e737461636b20342065766572/flavors/3",
"rel": "bookmark"
}
],
"name": "m1.medium",
"os-flavor-access:is_public": true,
"ram": 4096,
"swap": 0,
"vcpus": 2
},
{
"OS-FLV-EXT-DATA:ephemeral": 0,
"description": null,
"disk": 80,
"extra_specs": {},
"id": "4",
"links": [
{
"href": "http://openstack.example.com/v2.1/6f70656e737461636b20342065766572/flavors/4",
"rel": "self"
},
{
"href": "http://openstack.example.com/6f70656e737461636b20342065766572/flavors/4",
"rel": "bookmark"
}
],
"name": "m1.large",
"os-flavor-access:is_public": true,
"ram": 8192,
"swap": 0,
"vcpus": 4
},
{
"OS-FLV-EXT-DATA:ephemeral": 0,
"description": null,
"disk": 160,
"extra_specs": {},
"id": "5",
"links": [
{
"href": "http://openstack.example.com/v2.1/6f70656e737461636b20342065766572/flavors/5",
"rel": "self"
},
{
"href": "http://openstack.example.com/6f70656e737461636b20342065766572/flavors/5",
"rel": "bookmark"
}
],
"name": "m1.xlarge",
"os-flavor-access:is_public": true,
"ram": 16384,
"swap": 0,
"vcpus": 8
},
{
"OS-FLV-EXT-DATA:ephemeral": 0,
"description": null,
"disk": 1,
"extra_specs": {
"hw:numa_nodes": "1"
},
"id": "6",
"links": [
{
"href": "http://openstack.example.com/v2.1/6f70656e737461636b20342065766572/flavors/6",
"rel": "self"
},
{
"href": "http://openstack.example.com/6f70656e737461636b20342065766572/flavors/6",
"rel": "bookmark"
}
],
"name": "m1.tiny.specs",
"os-flavor-access:is_public": true,
"ram": 512,
"swap": 0,
"vcpus": 1
},
{
"OS-FLV-EXT-DATA:ephemeral": 0,
"description": "test description",
"disk": 20,
"extra_specs": {
"hw:cpu_policy": "shared",
"hw:numa_nodes": "1"
},
"id": "7",
"links": [
{
"href": "http://openstack.example.com/v2.1/6f70656e737461636b20342065766572/flavors/7",
"rel": "self"
},
{
"href": "http://openstack.example.com/6f70656e737461636b20342065766572/flavors/7",
"rel": "bookmark"
}
],
"name": "m1.small.description",
"os-flavor-access:is_public": true,
"ram": 2048,
"swap": 0,
"vcpus": 1
}
]
}
@@ -0,0 +1,109 @@
{
"flavors": [
{
"description": null,
"id": "1",
"links": [
{
"href": "http://openstack.example.com/v2.1/6f70656e737461636b20342065766572/flavors/1",
"rel": "self"
},
{
"href": "http://openstack.example.com/6f70656e737461636b20342065766572/flavors/1",
"rel": "bookmark"
}
],
"name": "m1.tiny"
},
{
"description": null,
"id": "2",
"links": [
{
"href": "http://openstack.example.com/v2.1/6f70656e737461636b20342065766572/flavors/2",
"rel": "self"
},
{
"href": "http://openstack.example.com/6f70656e737461636b20342065766572/flavors/2",
"rel": "bookmark"
}
],
"name": "m1.small"
},
{
"description": null,
"id": "3",
"links": [
{
"href": "http://openstack.example.com/v2.1/6f70656e737461636b20342065766572/flavors/3",
"rel": "self"
},
{
"href": "http://openstack.example.com/6f70656e737461636b20342065766572/flavors/3",
"rel": "bookmark"
}
],
"name": "m1.medium"
},
{
"description": null,
"id": "4",
"links": [
{
"href": "http://openstack.example.com/v2.1/6f70656e737461636b20342065766572/flavors/4",
"rel": "self"
},
{
"href": "http://openstack.example.com/6f70656e737461636b20342065766572/flavors/4",
"rel": "bookmark"
}
],
"name": "m1.large"
},
{
"description": null,
"id": "5",
"links": [
{
"href": "http://openstack.example.com/v2.1/6f70656e737461636b20342065766572/flavors/5",
"rel": "self"
},
{
"href": "http://openstack.example.com/6f70656e737461636b20342065766572/flavors/5",
"rel": "bookmark"
}
],
"name": "m1.xlarge"
},
{
"description": null,
"id": "6",
"links": [
{
"href": "http://openstack.example.com/v2.1/6f70656e737461636b20342065766572/flavors/6",
"rel": "self"
},
{
"href": "http://openstack.example.com/6f70656e737461636b20342065766572/flavors/6",
"rel": "bookmark"
}
],
"name": "m1.tiny.specs"
},
{
"description": "test description",
"id": "7",
"links": [
{
"href": "http://openstack.example.com/v2.1/6f70656e737461636b20342065766572/flavors/7",
"rel": "self"
},
{
"href": "http://openstack.example.com/6f70656e737461636b20342065766572/flavors/7",
"rel": "bookmark"
}
],
"name": "m1.small.description"
}
]
}
+3 -1
View File
@@ -281,7 +281,9 @@ REST_API_VERSION_HISTORY = """REST API Version History:
* 2.101 - Attaching a volume via * 2.101 - Attaching a volume via
``POST /servers/{server_id}/os-volume_attachments`` returns HTTP ``POST /servers/{server_id}/os-volume_attachments`` returns HTTP
202 Accepted instead of HTTP 200 and a volumeAttachment response. 202 Accepted instead of HTTP 200 and a volumeAttachment response.
* 2.102 - Add support for filtering flavors by name. * 2.102 - Add support for filtering flavors by name. Remove the deprecated
``rxtx_factor`` and ``OS-FLV-DISABLED:disabled`` fields and
filters from various flavors APIs.
""" """
# The minimum and maximum versions of the API supported # The minimum and maximum versions of the API supported
+10 -5
View File
@@ -58,11 +58,13 @@ class FlavorsController(wsgi.Controller):
@wsgi.expected_errors((400, 409)) @wsgi.expected_errors((400, 409))
@validation.schema(schema.create_v20, '2.0', '2.0') @validation.schema(schema.create_v20, '2.0', '2.0')
@validation.schema(schema.create, '2.1', '2.54') @validation.schema(schema.create, '2.1', '2.54')
@validation.schema(schema.create_v255, '2.55') @validation.schema(schema.create_v255, '2.55', '2.101')
@validation.schema(schema.create_v2102, '2.102')
@validation.response_body_schema(schema.create_response, '2.0', '2.54') @validation.response_body_schema(schema.create_response, '2.0', '2.54')
@validation.response_body_schema(schema.create_response_v255, '2.55', '2.60') # noqa: E501 @validation.response_body_schema(schema.create_response_v255, '2.55', '2.60') # noqa: E501
@validation.response_body_schema(schema.create_response_v261, '2.61', '2.74') # noqa: E501 @validation.response_body_schema(schema.create_response_v261, '2.61', '2.74') # noqa: E501
@validation.response_body_schema(schema.create_response_v275, '2.75') @validation.response_body_schema(schema.create_response_v275, '2.75', '2.101') # noqa: E501
@validation.response_body_schema(schema.create_response_v2102, '2.102')
def create(self, req, body): def create(self, req, body):
context = req.environ['nova.context'] context = req.environ['nova.context']
context.can(fm_policies.POLICY_ROOT % 'create', target={}) context.can(fm_policies.POLICY_ROOT % 'create', target={})
@@ -114,7 +116,8 @@ class FlavorsController(wsgi.Controller):
@validation.schema(schema.update, '2.55') @validation.schema(schema.update, '2.55')
@validation.response_body_schema(schema.update_response, '2.55', '2.60') @validation.response_body_schema(schema.update_response, '2.55', '2.60')
@validation.response_body_schema(schema.update_response_v261, '2.61', '2.74') # noqa: E501 @validation.response_body_schema(schema.update_response_v261, '2.61', '2.74') # noqa: E501
@validation.response_body_schema(schema.update_response_v275, '2.75') @validation.response_body_schema(schema.update_response_v275, '2.75', '2.101') # noqa: E501
@validation.response_body_schema(schema.update_response_v2102, '2.102')
def update(self, req, id, body): def update(self, req, id, body):
# Validate the policy. # Validate the policy.
context = req.environ['nova.context'] context = req.environ['nova.context']
@@ -152,7 +155,8 @@ class FlavorsController(wsgi.Controller):
@validation.query_schema(schema.index_query_v2102, '2.102') @validation.query_schema(schema.index_query_v2102, '2.102')
@validation.response_body_schema(schema.detail_response, '2.0', '2.54') @validation.response_body_schema(schema.detail_response, '2.0', '2.54')
@validation.response_body_schema(schema.detail_response_v255, '2.55', '2.60') # noqa: E501 @validation.response_body_schema(schema.detail_response_v255, '2.55', '2.60') # noqa: E501
@validation.response_body_schema(schema.detail_response_v261, '2.61') @validation.response_body_schema(schema.detail_response_v261, '2.61', '2.101') # noqa: E501
@validation.response_body_schema(schema.detail_response_v2102, '2.102')
def detail(self, req): def detail(self, req):
"""Return all flavors in detail.""" """Return all flavors in detail."""
context = req.environ['nova.context'] context = req.environ['nova.context']
@@ -171,7 +175,8 @@ class FlavorsController(wsgi.Controller):
@validation.response_body_schema(schema.show_response, '2.0', '2.54') @validation.response_body_schema(schema.show_response, '2.0', '2.54')
@validation.response_body_schema(schema.show_response_v255, '2.55', '2.60') @validation.response_body_schema(schema.show_response_v255, '2.55', '2.60')
@validation.response_body_schema(schema.show_response_v261, '2.61', '2.74') @validation.response_body_schema(schema.show_response_v261, '2.61', '2.74')
@validation.response_body_schema(schema.show_response_v275, '2.75') @validation.response_body_schema(schema.show_response_v275, '2.75', '2.101') # noqa: E501
@validation.response_body_schema(schema.show_response_v2102, '2.102')
def show(self, req, id): def show(self, req, id):
"""Return data about the given flavor id.""" """Return data about the given flavor id."""
context = req.environ['nova.context'] context = req.environ['nova.context']
+22 -3
View File
@@ -75,13 +75,11 @@ create = {
'additionalProperties': False, 'additionalProperties': False,
} }
create_v20 = copy.deepcopy(create) create_v20 = copy.deepcopy(create)
create_v20['properties']['flavor']['properties']['name'] = ( create_v20['properties']['flavor']['properties']['name'] = (
parameter_types.name_with_leading_trailing_spaces parameter_types.name_with_leading_trailing_spaces
) )
# 2.55 adds an optional description field with a max length of 65535 since the # 2.55 adds an optional description field with a max length of 65535 since the
# backing database column is a TEXT column which is 64KiB. # backing database column is a TEXT column which is 64KiB.
_flavor_description = { _flavor_description = {
@@ -89,11 +87,12 @@ _flavor_description = {
'pattern': parameter_types.valid_description_regex, 'pattern': parameter_types.valid_description_regex,
} }
create_v255 = copy.deepcopy(create) create_v255 = copy.deepcopy(create)
create_v255['properties']['flavor']['properties']['description'] = ( create_v255['properties']['flavor']['properties']['description'] = (
_flavor_description) _flavor_description)
create_v2102 = copy.deepcopy(create_v255)
del create_v2102['properties']['flavor']['properties']['rxtx_factor']
update = { update = {
'type': 'object', 'type': 'object',
@@ -142,6 +141,8 @@ index_query_v275['additionalProperties'] = False
index_query_v2102 = copy.deepcopy(index_query_v275) index_query_v2102 = copy.deepcopy(index_query_v275)
index_query_v2102['properties']['name'] = parameter_types.multi_params( index_query_v2102['properties']['name'] = parameter_types.multi_params(
{'type': 'string'}) {'type': 'string'})
index_query_v2102['properties']['sort_key']['items']['enum'].remove(
'rxtx_factor')
# TODO(stephenfin): Remove additionalProperties in a future API version # TODO(stephenfin): Remove additionalProperties in a future API version
show_query = { show_query = {
@@ -239,6 +240,12 @@ _flavor_v275 = copy.deepcopy(_flavor_v261)
# we completely overwrite this since the new variant is much simpler # we completely overwrite this since the new variant is much simpler
_flavor_v275['properties']['swap'] = {'type': 'integer'} _flavor_v275['properties']['swap'] = {'type': 'integer'}
_flavor_v2102 = copy.deepcopy(_flavor_v275)
del _flavor_v2102['properties']['rxtx_factor']
del _flavor_v2102['properties']['OS-FLV-DISABLED:disabled']
_flavor_v2102['required'].remove('rxtx_factor')
_flavor_v2102['required'].remove('OS-FLV-DISABLED:disabled')
_flavors_links = { _flavors_links = {
'type': 'array', 'type': 'array',
'items': { 'items': {
@@ -274,6 +281,9 @@ create_response_v261['properties']['flavor'] = copy.deepcopy(_flavor_v261)
create_response_v275 = copy.deepcopy(create_response_v261) create_response_v275 = copy.deepcopy(create_response_v261)
create_response_v275['properties']['flavor'] = copy.deepcopy(_flavor_v275) create_response_v275['properties']['flavor'] = copy.deepcopy(_flavor_v275)
create_response_v2102 = copy.deepcopy(create_response_v261)
create_response_v2102['properties']['flavor'] = copy.deepcopy(_flavor_v2102)
# NOTE(stephenfin): update is only available from 2.55 and the response is # NOTE(stephenfin): update is only available from 2.55 and the response is
# identical to the create and show response from that point forward # identical to the create and show response from that point forward
update_response = { update_response = {
@@ -291,6 +301,9 @@ update_response_v261['properties']['flavor'] = copy.deepcopy(_flavor_v261)
update_response_v275 = copy.deepcopy(update_response_v261) update_response_v275 = copy.deepcopy(update_response_v261)
update_response_v275['properties']['flavor'] = copy.deepcopy(_flavor_v275) update_response_v275['properties']['flavor'] = copy.deepcopy(_flavor_v275)
update_response_v2102 = copy.deepcopy(update_response_v261)
update_response_v2102['properties']['flavor'] = copy.deepcopy(_flavor_v2102)
index_response = { index_response = {
'type': 'object', 'type': 'object',
'properties': { 'properties': {
@@ -329,6 +342,9 @@ detail_response_v261['properties']['flavors']['items'] = _flavor_v261
detail_response_v275 = copy.deepcopy(detail_response_v261) detail_response_v275 = copy.deepcopy(detail_response_v261)
detail_response_v275['properties']['flavors']['items'] = _flavor_v275 detail_response_v275['properties']['flavors']['items'] = _flavor_v275
detail_response_v2102 = copy.deepcopy(detail_response_v261)
detail_response_v2102['properties']['flavors']['items'] = _flavor_v2102
show_response = { show_response = {
'type': 'object', 'type': 'object',
'properties': { 'properties': {
@@ -346,3 +362,6 @@ show_response_v261['properties']['flavor'] = copy.deepcopy(_flavor_v261)
show_response_v275 = copy.deepcopy(show_response_v261) show_response_v275 = copy.deepcopy(show_response_v261)
show_response_v275['properties']['flavor'] = copy.deepcopy(_flavor_v275) show_response_v275['properties']['flavor'] = copy.deepcopy(_flavor_v275)
show_response_v2102 = copy.deepcopy(show_response_v261)
show_response_v2102['properties']['flavor'] = copy.deepcopy(_flavor_v2102)
@@ -68,6 +68,10 @@ class ViewBuilder(common.ViewBuilder):
if api_version_request.is_supported(request, '2.75'): if api_version_request.is_supported(request, '2.75'):
flavor_dict['flavor']['swap'] = flavor["swap"] or 0 flavor_dict['flavor']['swap'] = flavor["swap"] or 0
if api_version_request.is_supported(request, '2.102'):
del flavor_dict['flavor']['OS-FLV-DISABLED:disabled']
del flavor_dict['flavor']['rxtx_factor']
return flavor_dict return flavor_dict
def index(self, request, flavors): def index(self, request, flavors):
@@ -0,0 +1,10 @@
{
"flavor": {
"name": "%(flavor_name)s",
"ram": 1024,
"vcpus": 2,
"disk": 10,
"id": "%(flavor_id)s",
"description": "test description"
}
}
@@ -0,0 +1,24 @@
{
"flavor": {
"disk": 10,
"id": "%(flavor_id)s",
"links": [
{
"href": "%(versioned_compute_endpoint)s/flavors/%(flavor_id)s",
"rel": "self"
},
{
"href": "%(compute_endpoint)s/flavors/%(flavor_id)s",
"rel": "bookmark"
}
],
"name": "%(flavor_name)s",
"os-flavor-access:is_public": true,
"ram": 1024,
"vcpus": 2,
"OS-FLV-EXT-DATA:ephemeral": 0,
"swap": 0,
"description": "test description",
"extra_specs": {}
}
}
@@ -0,0 +1,5 @@
{
"flavor": {
"description": "updated description"
}
}
@@ -0,0 +1,24 @@
{
"flavor": {
"disk": 1,
"OS-FLV-EXT-DATA:ephemeral": 0,
"os-flavor-access:is_public": true,
"id": "1",
"links": [
{
"href": "http://openstack.example.com/v2.1/6f70656e737461636b20342065766572/flavors/1",
"rel": "self"
},
{
"href": "http://openstack.example.com/6f70656e737461636b20342065766572/flavors/1",
"rel": "bookmark"
}
],
"name": "m1.tiny",
"ram": 512,
"swap": 0,
"vcpus": 1,
"description": "updated description",
"extra_specs": {}
}
}
@@ -0,0 +1,27 @@
{
"flavor": {
"disk": 20,
"OS-FLV-EXT-DATA:ephemeral": 0,
"id": "%(flavorid)s",
"links": [
{
"href": "%(versioned_compute_endpoint)s/flavors/%(flavorid)s",
"rel": "self"
},
{
"href": "%(compute_endpoint)s/flavors/%(flavorid)s",
"rel": "bookmark"
}
],
"name": "m1.small.description",
"os-flavor-access:is_public": true,
"ram": 2048,
"swap": 0,
"vcpus": 1,
"description": "test description",
"extra_specs": {
"hw:cpu_policy": "shared",
"hw:numa_nodes": "1"
}
}
}
@@ -0,0 +1,163 @@
{
"flavors": [
{
"disk": 1,
"OS-FLV-EXT-DATA:ephemeral": 0,
"id": "1",
"links": [
{
"href": "%(versioned_compute_endpoint)s/flavors/1",
"rel": "self"
},
{
"href": "%(compute_endpoint)s/flavors/1",
"rel": "bookmark"
}
],
"name": "m1.tiny",
"os-flavor-access:is_public": true,
"ram": 512,
"swap": 0,
"vcpus": 1,
"description": null,
"extra_specs": {}
},
{
"disk": 20,
"OS-FLV-EXT-DATA:ephemeral": 0,
"id": "2",
"links": [
{
"href": "%(versioned_compute_endpoint)s/flavors/2",
"rel": "self"
},
{
"href": "%(compute_endpoint)s/flavors/2",
"rel": "bookmark"
}
],
"name": "m1.small",
"os-flavor-access:is_public": true,
"ram": 2048,
"swap": 0,
"vcpus": 1,
"description": null,
"extra_specs": {}
},
{
"disk": 40,
"OS-FLV-EXT-DATA:ephemeral": 0,
"id": "3",
"links": [
{
"href": "%(versioned_compute_endpoint)s/flavors/3",
"rel": "self"
},
{
"href": "%(compute_endpoint)s/flavors/3",
"rel": "bookmark"
}
],
"name": "m1.medium",
"os-flavor-access:is_public": true,
"ram": 4096,
"swap": 0,
"vcpus": 2,
"description": null,
"extra_specs": {}
},
{
"disk": 80,
"OS-FLV-EXT-DATA:ephemeral": 0,
"id": "4",
"links": [
{
"href": "%(versioned_compute_endpoint)s/flavors/4",
"rel": "self"
},
{
"href": "%(compute_endpoint)s/flavors/4",
"rel": "bookmark"
}
],
"name": "m1.large",
"os-flavor-access:is_public": true,
"ram": 8192,
"swap": 0,
"vcpus": 4,
"description": null,
"extra_specs": {}
},
{
"disk": 160,
"OS-FLV-EXT-DATA:ephemeral": 0,
"id": "5",
"links": [
{
"href": "%(versioned_compute_endpoint)s/flavors/5",
"rel": "self"
},
{
"href": "%(compute_endpoint)s/flavors/5",
"rel": "bookmark"
}
],
"name": "m1.xlarge",
"os-flavor-access:is_public": true,
"ram": 16384,
"swap": 0,
"vcpus": 8,
"description": null,
"extra_specs": {}
},
{
"disk": 1,
"OS-FLV-EXT-DATA:ephemeral": 0,
"id": "6",
"links": [
{
"href": "%(versioned_compute_endpoint)s/flavors/6",
"rel": "self"
},
{
"href": "%(compute_endpoint)s/flavors/6",
"rel": "bookmark"
}
],
"name": "m1.tiny.specs",
"os-flavor-access:is_public": true,
"ram": 512,
"swap": 0,
"vcpus": 1,
"description": null,
"extra_specs": {
"hw:numa_nodes": "1"
}
},
{
"disk": 20,
"OS-FLV-EXT-DATA:ephemeral": 0,
"id": "%(flavorid)s",
"links": [
{
"href": "%(versioned_compute_endpoint)s/flavors/%(flavorid)s",
"rel": "self"
},
{
"href": "%(compute_endpoint)s/flavors/%(flavorid)s",
"rel": "bookmark"
}
],
"name": "m1.small.description",
"os-flavor-access:is_public": true,
"ram": 2048,
"swap": 0,
"vcpus": 1,
"description": "test description",
"extra_specs": {
"hw:cpu_policy": "shared",
"hw:numa_nodes": "1"
}
}
]
}
@@ -0,0 +1,109 @@
{
"flavors": [
{
"description": null,
"id": "1",
"links": [
{
"href": "http://openstack.example.com/v2.1/6f70656e737461636b20342065766572/flavors/1",
"rel": "self"
},
{
"href": "http://openstack.example.com/6f70656e737461636b20342065766572/flavors/1",
"rel": "bookmark"
}
],
"name": "m1.tiny"
},
{
"description": null,
"id": "2",
"links": [
{
"href": "http://openstack.example.com/v2.1/6f70656e737461636b20342065766572/flavors/2",
"rel": "self"
},
{
"href": "http://openstack.example.com/6f70656e737461636b20342065766572/flavors/2",
"rel": "bookmark"
}
],
"name": "m1.small"
},
{
"description": null,
"id": "3",
"links": [
{
"href": "http://openstack.example.com/v2.1/6f70656e737461636b20342065766572/flavors/3",
"rel": "self"
},
{
"href": "http://openstack.example.com/6f70656e737461636b20342065766572/flavors/3",
"rel": "bookmark"
}
],
"name": "m1.medium"
},
{
"description": null,
"id": "4",
"links": [
{
"href": "http://openstack.example.com/v2.1/6f70656e737461636b20342065766572/flavors/4",
"rel": "self"
},
{
"href": "http://openstack.example.com/6f70656e737461636b20342065766572/flavors/4",
"rel": "bookmark"
}
],
"name": "m1.large"
},
{
"description": null,
"id": "5",
"links": [
{
"href": "http://openstack.example.com/v2.1/6f70656e737461636b20342065766572/flavors/5",
"rel": "self"
},
{
"href": "http://openstack.example.com/6f70656e737461636b20342065766572/flavors/5",
"rel": "bookmark"
}
],
"name": "m1.xlarge"
},
{
"description": null,
"id": "6",
"links": [
{
"href": "http://openstack.example.com/v2.1/6f70656e737461636b20342065766572/flavors/6",
"rel": "self"
},
{
"href": "http://openstack.example.com/6f70656e737461636b20342065766572/flavors/6",
"rel": "bookmark"
}
],
"name": "m1.tiny.specs"
},
{
"description": "test description",
"id": "7",
"links": [
{
"href": "http://openstack.example.com/v2.1/6f70656e737461636b20342065766572/flavors/7",
"rel": "self"
},
{
"href": "http://openstack.example.com/6f70656e737461636b20342065766572/flavors/7",
"rel": "bookmark"
}
],
"name": "m1.small.description"
}
]
}
@@ -39,7 +39,7 @@ class FlavorManageSampleJsonTests(api_sample_base.ApiSampleTestBaseV21):
self.assertEqual('', response.text) self.assertEqual('', response.text)
class FlavorManageSampleJsonTests2_55(FlavorManageSampleJsonTests): class FlavorManageSampleJsonTests255(FlavorManageSampleJsonTests):
microversion = '2.55' microversion = '2.55'
scenarios = [('v2_55', {'api_major_version': 'v2.1'})] scenarios = [('v2_55', {'api_major_version': 'v2.1'})]
@@ -48,6 +48,11 @@ class FlavorManageSampleJsonTests2_55(FlavorManageSampleJsonTests):
self._verify_response("flavor-update-resp", {}, response, 200) self._verify_response("flavor-update-resp", {}, response, 200)
class FlavorManageSampleJsonTests2_75(FlavorManageSampleJsonTests2_55): class FlavorManageSampleJsonTests275(FlavorManageSampleJsonTests255):
microversion = '2.75' microversion = '2.75'
scenarios = [('v2_75', {'api_major_version': 'v2.1'})] scenarios = [('v2_75', {'api_major_version': 'v2.1'})]
class FlavorManageSampleJsonTests2102(FlavorManageSampleJsonTests255):
microversion = '2.102'
scenarios = [('v2_102', {'api_major_version': 'v2.1'})]
@@ -82,12 +82,12 @@ class FlavorsSampleJsonTest(api_sample_base.ApiSampleTestBaseV21):
self.assertEqual(400, response.status_code) self.assertEqual(400, response.status_code)
class FlavorsSampleJsonTest2_55(FlavorsSampleJsonTest): class FlavorsSampleJsonTest255(FlavorsSampleJsonTest):
microversion = '2.55' microversion = '2.55'
scenarios = [('v2_55', {'api_major_version': 'v2.1'})] scenarios = [('v2_55', {'api_major_version': 'v2.1'})]
def setUp(self): def setUp(self):
super(FlavorsSampleJsonTest2_55, self).setUp() super().setUp()
# Get the existing flavors created by DefaultFlavorsFixture. # Get the existing flavors created by DefaultFlavorsFixture.
ctxt = nova_context.get_admin_context() ctxt = nova_context.get_admin_context()
flavors = objects.FlavorList.get_all(ctxt) flavors = objects.FlavorList.get_all(ctxt)
@@ -104,12 +104,12 @@ class FlavorsSampleJsonTest2_55(FlavorsSampleJsonTest):
self.subs = {'flavorid': new_flavor_id} self.subs = {'flavorid': new_flavor_id}
class FlavorsSampleJsonTest2_61(FlavorsSampleJsonTest): class FlavorsSampleJsonTest261(FlavorsSampleJsonTest):
microversion = '2.61' microversion = '2.61'
scenarios = [('v2_61', {'api_major_version': 'v2.1'})] scenarios = [('v2_61', {'api_major_version': 'v2.1'})]
def setUp(self): def setUp(self):
super(FlavorsSampleJsonTest2_61, self).setUp() super().setUp()
# Get the existing flavors created by DefaultFlavorsFixture. # Get the existing flavors created by DefaultFlavorsFixture.
ctxt = nova_context.get_admin_context() ctxt = nova_context.get_admin_context()
flavors = objects.FlavorList.get_all(ctxt) flavors = objects.FlavorList.get_all(ctxt)
@@ -130,9 +130,17 @@ class FlavorsSampleJsonTest2_61(FlavorsSampleJsonTest):
self.subs = {'flavorid': new_flavor_id} self.subs = {'flavorid': new_flavor_id}
class FlavorsSampleJsonTest2_75(FlavorsSampleJsonTest2_61): class FlavorsSampleJsonTest275(FlavorsSampleJsonTest261):
microversion = '2.75' microversion = '2.75'
scenarios = [('v2_75', {'api_major_version': 'v2.1'})] scenarios = [('v2_75', {'api_major_version': 'v2.1'})]
def test_flavors_list(self): def test_flavors_list(self):
pass pass
class FlavorsSampleJsonTest2102(FlavorsSampleJsonTest261):
microversion = '2.102'
scenarios = [('v2_102', {'api_major_version': 'v2.1'})]
sort_keys = FlavorsSampleJsonTest.sort_keys
sort_keys.remove('rxtx_factor')
+8 -4
View File
@@ -334,7 +334,7 @@ class InstanceHelperMixin:
return api.post_aggregate(body)['id'] return api.post_aggregate(body)['id']
def _build_flavor(self, id=None, name=None, memory_mb=2048, vcpu=2, def _build_flavor(self, id=None, name=None, memory_mb=2048, vcpu=2,
disk=10, ephemeral=10, swap=0, rxtx_factor=1.0, disk=10, ephemeral=10, swap=0, rxtx_factor=None,
is_public=True): is_public=True):
"""Build a request for the flavor create API. """Build a request for the flavor create API.
@@ -353,7 +353,7 @@ class InstanceHelperMixin:
name = ''.join( name = ''.join(
random.choice(string.ascii_lowercase) for i in range(20)) random.choice(string.ascii_lowercase) for i in range(20))
return { body = {
"flavor": { "flavor": {
"id": id, "id": id,
"name": name, "name": name,
@@ -362,13 +362,17 @@ class InstanceHelperMixin:
"disk": disk, "disk": disk,
"OS-FLV-EXT-DATA:ephemeral": ephemeral, "OS-FLV-EXT-DATA:ephemeral": ephemeral,
"swap": swap, "swap": swap,
"rxtx_factor": rxtx_factor,
"os-flavor-access:is_public": is_public, "os-flavor-access:is_public": is_public,
} }
} }
if rxtx_factor is not None:
body["rxtx_factor"] = rxtx_factor
return body
def _create_flavor(self, id=None, name=None, memory_mb=2048, vcpu=2, def _create_flavor(self, id=None, name=None, memory_mb=2048, vcpu=2,
disk=10, ephemeral=10, swap=0, rxtx_factor=1.0, disk=10, ephemeral=10, swap=0, rxtx_factor=None,
is_public=True, extra_spec=None): is_public=True, extra_spec=None):
"""Build and submit a request to the flavor create API. """Build and submit a request to the flavor create API.
@@ -17,6 +17,8 @@ from nova.tests.functional.notification_sample_tests \
class TestFlavorNotificationSample( class TestFlavorNotificationSample(
notification_sample_base.NotificationSampleTestBase): notification_sample_base.NotificationSampleTestBase):
MAX_MICROVERSION = '2.1'
def test_flavor_create(self): def test_flavor_create(self):
body = { body = {
"flavor": { "flavor": {
@@ -47,6 +47,8 @@ class FlavorsTestV21(test.TestCase):
expect_description = False expect_description = False
# Flag to tell the test if a extra_specs should be expected in a response. # Flag to tell the test if a extra_specs should be expected in a response.
expect_extra_specs = False expect_extra_specs = False
# Flag to tell the test if legacy fields should be omitted from responses.
omit_legacy_fields = False
def setUp(self): def setUp(self):
super().setUp() super().setUp()
@@ -67,6 +69,9 @@ class FlavorsTestV21(test.TestCase):
expected['description'] = flavor.description expected['description'] = flavor.description
if self.expect_extra_specs: if self.expect_extra_specs:
expected['extra_specs'] = flavor.extra_specs expected['extra_specs'] = flavor.extra_specs
if self.omit_legacy_fields:
expected.pop('rxtx_factor', None)
expected.pop('OS-FLV-DISABLED:disabled', None)
@mock.patch('nova.objects.Flavor.get_by_flavor_id', @mock.patch('nova.objects.Flavor.get_by_flavor_id',
side_effect=return_flavor_not_found) side_effect=return_flavor_not_found)
@@ -249,7 +254,7 @@ class FlavorsTestV21(test.TestCase):
self.assertThat({'limit': ['1'], 'marker': ['1']}, self.assertThat({'limit': ['1'], 'marker': ['1']},
matchers.DictMatches(params)) matchers.DictMatches(params))
def test_get_flavor_with_limit(self): def test_get_flavor_list_with_limit(self):
req = self._build_request('/flavors?limit=2') req = self._build_request('/flavors?limit=2')
response = self.controller.index(req) response = self.controller.index(req)
response_list = response["flavors"] response_list = response["flavors"]
@@ -298,7 +303,7 @@ class FlavorsTestV21(test.TestCase):
self.assertThat({'limit': ['2'], 'marker': ['2']}, self.assertThat({'limit': ['2'], 'marker': ['2']},
matchers.DictMatches(params)) matchers.DictMatches(params))
def test_get_flavor_with_default_limit(self): def test_get_flavor_list_with_default_limit(self):
self.stub_out('nova.api.openstack.common.get_limit_and_marker', self.stub_out('nova.api.openstack.common.get_limit_and_marker',
fake_get_limit_and_marker) fake_get_limit_and_marker)
self.flags(max_limit=1, group='api') self.flags(max_limit=1, group='api')
@@ -547,6 +552,9 @@ class FlavorsTestV21(test.TestCase):
if 'detail' in url and self.expect_extra_specs: if 'detail' in url and self.expect_extra_specs:
expected_resp[0]['extra_specs'] = ( expected_resp[0]['extra_specs'] = (
fakes.FLAVORS['2'].extra_specs) fakes.FLAVORS['2'].extra_specs)
if self.omit_legacy_fields:
expected_resp[0].pop('rxtx_factor', None)
expected_resp[0].pop('OS-FLV-DISABLED:disabled', None)
params = { params = {
'limit': 1, 'limit': 1,
'marker': 1, 'marker': 1,
@@ -609,6 +617,9 @@ class FlavorsTestV21(test.TestCase):
if 'detail' in url and self.expect_extra_specs: if 'detail' in url and self.expect_extra_specs:
expected_resp[0]['extra_specs'] = ( expected_resp[0]['extra_specs'] = (
fakes.FLAVORS['2'].extra_specs) fakes.FLAVORS['2'].extra_specs)
if self.omit_legacy_fields:
expected_resp[0].pop('rxtx_factor', None)
expected_resp[0].pop('OS-FLV-DISABLED:disabled', None)
req = req or self._build_request(url + '&limit=1&marker=1') req = req or self._build_request(url + '&limit=1&marker=1')
result = controller_list(req) result = controller_list(req)
self.assertEqual(expected_resp, result['flavors']) self.assertEqual(expected_resp, result['flavors'])
@@ -856,6 +867,7 @@ class FlavorsTestV275(FlavorsTestV261):
class FlavorsTestV2102(FlavorsTestV275): class FlavorsTestV2102(FlavorsTestV275):
microversion = '2.102' microversion = '2.102'
omit_legacy_fields = True
def test_list_flavors_with_name_filter_old_version(self): def test_list_flavors_with_name_filter_old_version(self):
req = fakes.HTTPRequestV21.blank( req = fakes.HTTPRequestV21.blank(
@@ -901,7 +913,6 @@ class FlavorsTestV2102(FlavorsTestV275):
expected = { expected = {
'flavors': [ 'flavors': [
{ {
'OS-FLV-DISABLED:disabled': fakes.FLAVORS['2'].disabled,
'OS-FLV-EXT-DATA:ephemeral': 'OS-FLV-EXT-DATA:ephemeral':
fakes.FLAVORS['2'].ephemeral_gb, fakes.FLAVORS['2'].ephemeral_gb,
'description': fakes.FLAVORS['2'].description, 'description': fakes.FLAVORS['2'].description,
@@ -921,7 +932,6 @@ class FlavorsTestV2102(FlavorsTestV275):
'name': fakes.FLAVORS['2'].name, 'name': fakes.FLAVORS['2'].name,
'os-flavor-access:is_public': True, 'os-flavor-access:is_public': True,
'ram': fakes.FLAVORS['2'].memory_mb, 'ram': fakes.FLAVORS['2'].memory_mb,
'rxtx_factor': '',
'swap': fakes.FLAVORS['2'].swap, 'swap': fakes.FLAVORS['2'].swap,
'vcpus': fakes.FLAVORS['2'].vcpus, 'vcpus': fakes.FLAVORS['2'].vcpus,
}, },
@@ -929,6 +939,10 @@ class FlavorsTestV2102(FlavorsTestV275):
} }
self.assertEqual(expected, actual) self.assertEqual(expected, actual)
def test_list_detail_flavors_with_additional_filter_old_version(self):
self.omit_legacy_fields = False
super().test_list_detail_flavors_with_additional_filter_old_version()
class DisabledFlavorsWithRealDBTestV21(test.TestCase): class DisabledFlavorsWithRealDBTestV21(test.TestCase):
"""Tests that disabled flavors should not be shown nor listed.""" """Tests that disabled flavors should not be shown nor listed."""
@@ -5,3 +5,7 @@ features:
flavors by name, e.g.:: flavors by name, e.g.::
GET /flavors?name=gpu GET /flavors?name=gpu
In addition, the ``rxtx_factor`` and ``OS-FLV-DISABLED:disabled`` fields
have been removed from all flavors responses, while the ``rxtx_factor``
field can no longer be provided when creating a server.
+3
View File
@@ -86,6 +86,9 @@ commands =
[testenv:functional{,-py310,-py311,-py312,-py313}] [testenv:functional{,-py310,-py311,-py312,-py313}]
description = description =
Run functional tests. Run functional tests.
passenv =
{[testenv]passenv}
GENERATE_SAMPLES
setenv = setenv =
{[testenv]setenv} {[testenv]setenv}
# we do not have any greenlet leaks in functional tests so enforce that # we do not have any greenlet leaks in functional tests so enforce that