diff options
author | Zuul <zuul@review.opendev.org> | 2021-08-29 08:39:44 +0000 |
---|---|---|
committer | Gerrit Code Review <review@openstack.org> | 2021-08-29 08:39:44 +0000 |
commit | d5f22c6652b6323f44d717074243623a6a1d381e (patch) | |
tree | 23019c604f9e0e9e923fbd8f24b8f7c757b66e7c | |
parent | 244a75fd6b79ff33e93442eb8ff0d48392818b21 (diff) | |
parent | ec44fc89997624c692635d5fae8fba4ca5d9aa02 (diff) | |
download | cinder-d5f22c6652b6323f44d717074243623a6a1d381e.tar.gz |
Merge "Expose volume & snapshot use_quota field"
43 files changed, 733 insertions, 60 deletions
diff --git a/api-ref/source/v3/parameters.yaml b/api-ref/source/v3/parameters.yaml index 3551f3301..cf806829d 100644 --- a/api-ref/source/v3/parameters.yaml +++ b/api-ref/source/v3/parameters.yaml @@ -214,6 +214,18 @@ detail: in: query required: false type: boolean +filter_consumes_quota: + description: | + Filters results by ``consumes_quota`` field. Resources that don't use + quotas are usually temporary internal resources created to perform an + operation. Default is to not filter by it. Filtering by this option may + not be always possible in a cloud, see + :ref:`List Resource Filters <resource-filters>` to determine whether this + filter is available in your cloud. + in: query + required: false + type: boolean + min_version: 3.65 filter_created_at: description: | Filters reuslts by a time that resources are created at with time @@ -841,6 +853,15 @@ consumer: in: body required: false type: string +consumes_quota: + description: | + Whether this resource consumes quota or not. Resources that not counted + for quota usage are usually temporary internal resources created to perform + an operation. + in: body + required: false + type: boolean + min_version: 3.65 container: description: | The container name or null. diff --git a/api-ref/source/v3/resource-filters.inc b/api-ref/source/v3/resource-filters.inc index b5064e965..37f662c75 100644 --- a/api-ref/source/v3/resource-filters.inc +++ b/api-ref/source/v3/resource-filters.inc @@ -1,5 +1,7 @@ .. -*- rst -*- +.. _resource-filters: + Resource Filters (resource_filters) =================================== diff --git a/api-ref/source/v3/samples/snapshots/snapshot-create-response.json b/api-ref/source/v3/samples/snapshots/snapshot-create-response.json index 8819dd94a..e19e407c8 100644 --- a/api-ref/source/v3/samples/snapshots/snapshot-create-response.json +++ b/api-ref/source/v3/samples/snapshots/snapshot-create-response.json @@ -12,4 +12,4 @@ "updated_at": null, "volume_id": "d291b81c-6e40-4525-8231-90aa1588121e" } -}
\ No newline at end of file +} diff --git a/api-ref/source/v3/samples/snapshots/snapshot-show-response.json b/api-ref/source/v3/samples/snapshots/snapshot-show-response.json index da7e68da1..b4979f368 100644 --- a/api-ref/source/v3/samples/snapshots/snapshot-show-response.json +++ b/api-ref/source/v3/samples/snapshots/snapshot-show-response.json @@ -14,4 +14,4 @@ "updated_at": null, "volume_id": "b72c48f1-64b7-4cd8-9745-b12e0be82d37" } -}
\ No newline at end of file +} diff --git a/api-ref/source/v3/samples/snapshots/snapshot-update-response.json b/api-ref/source/v3/samples/snapshots/snapshot-update-response.json index 5d9c9bb4d..d69a8aedc 100644 --- a/api-ref/source/v3/samples/snapshots/snapshot-update-response.json +++ b/api-ref/source/v3/samples/snapshots/snapshot-update-response.json @@ -12,4 +12,4 @@ "updated_at": null, "volume_id": "070c942d-9909-42e9-a467-7a781f150c58" } -}
\ No newline at end of file +} diff --git a/api-ref/source/v3/samples/snapshots/snapshots-list-detailed-response.json b/api-ref/source/v3/samples/snapshots/snapshots-list-detailed-response.json index 9c452f387..a73af2094 100644 --- a/api-ref/source/v3/samples/snapshots/snapshots-list-detailed-response.json +++ b/api-ref/source/v3/samples/snapshots/snapshots-list-detailed-response.json @@ -16,4 +16,4 @@ "volume_id": "7acd675e-4e06-4653-af9f-2ecd546342d6" } ] -}
\ No newline at end of file +} diff --git a/api-ref/source/v3/samples/snapshots/v3.65/snapshot-create-response.json b/api-ref/source/v3/samples/snapshots/v3.65/snapshot-create-response.json new file mode 100644 index 000000000..b38d66242 --- /dev/null +++ b/api-ref/source/v3/samples/snapshots/v3.65/snapshot-create-response.json @@ -0,0 +1,18 @@ +{ + "snapshot": { + "created_at": "2019-03-11T16:24:34.469003", + "description": "Daily backup", + "id": "b36476e5-d18b-47f9-ac69-4818cb43ee21", + "metadata": { + "key": "v3" + }, + "name": "snap-001", + "size": 10, + "status": "creating", + "updated_at": null, + "volume_id": "d291b81c-6e40-4525-8231-90aa1588121e", + "group_snapshot_id": null, + "user_id": "c853ca26-e8ea-4797-8a52-ee124a013d0e", + "consumes_quota": true + } +} diff --git a/api-ref/source/v3/samples/snapshots/v3.65/snapshot-show-response.json b/api-ref/source/v3/samples/snapshots/v3.65/snapshot-show-response.json new file mode 100644 index 000000000..69be72e98 --- /dev/null +++ b/api-ref/source/v3/samples/snapshots/v3.65/snapshot-show-response.json @@ -0,0 +1,20 @@ +{ + "snapshot": { + "created_at": "2019-03-12T04:42:00.809352", + "description": "Daily backup", + "id": "4a584cae-e4ce-429b-9154-d4c9eb8fda4c", + "metadata": { + "key": "v3" + }, + "name": "snap-001", + "os-extended-snapshot-attributes:progress": "0%", + "os-extended-snapshot-attributes:project_id": "89afd400-b646-4bbc-b12b-c0a4d63e5bd3", + "size": 10, + "status": "creating", + "updated_at": null, + "volume_id": "b72c48f1-64b7-4cd8-9745-b12e0be82d37", + "group_snapshot_id": null, + "user_id": "c853ca26-e8ea-4797-8a52-ee124a013d0e", + "consumes_quota": true + } +} diff --git a/api-ref/source/v3/samples/snapshots/v3.65/snapshot-update-response.json b/api-ref/source/v3/samples/snapshots/v3.65/snapshot-update-response.json new file mode 100644 index 000000000..c097889d2 --- /dev/null +++ b/api-ref/source/v3/samples/snapshots/v3.65/snapshot-update-response.json @@ -0,0 +1,18 @@ +{ + "snapshot": { + "created_at": "2019-03-12T04:53:53.426591", + "description": "This is yet, another snapshot.", + "id": "43666194-8e72-451a-b7bb-54fef763b2b8", + "metadata": { + "key": "v3" + }, + "name": "snap-002", + "size": 10, + "status": "creating", + "updated_at": null, + "volume_id": "070c942d-9909-42e9-a467-7a781f150c58", + "group_snapshot_id": null, + "user_id": "c853ca26-e8ea-4797-8a52-ee124a013d0e", + "consumes_quota": true + } +} diff --git a/api-ref/source/v3/samples/snapshots/v3.65/snapshots-list-detailed-response.json b/api-ref/source/v3/samples/snapshots/v3.65/snapshots-list-detailed-response.json new file mode 100644 index 000000000..7c9e8d476 --- /dev/null +++ b/api-ref/source/v3/samples/snapshots/v3.65/snapshots-list-detailed-response.json @@ -0,0 +1,22 @@ +{ + "snapshots": [ + { + "created_at": "2019-03-11T16:24:36.464445", + "description": "Daily backup", + "id": "d0083dc5-8795-4c1a-bc9c-74f70006c205", + "metadata": { + "key": "v3" + }, + "name": "snap-001", + "os-extended-snapshot-attributes:progress": "0%", + "os-extended-snapshot-attributes:project_id": "89afd400-b646-4bbc-b12b-c0a4d63e5bd3", + "size": 10, + "status": "creating", + "updated_at": null, + "volume_id": "7acd675e-4e06-4653-af9f-2ecd546342d6", + "group_snapshot_id": null, + "user_id": "c853ca26-e8ea-4797-8a52-ee124a013d0e", + "consumes_quota": true + } + ] +} diff --git a/api-ref/source/v3/samples/versions/version-show-response.json b/api-ref/source/v3/samples/versions/version-show-response.json index 5e34efae7..1d79bf38f 100644 --- a/api-ref/source/v3/samples/versions/version-show-response.json +++ b/api-ref/source/v3/samples/versions/version-show-response.json @@ -21,8 +21,8 @@ ], "min_version": "3.0", "status": "CURRENT", - "updated": "2021-05-30T00:00:00Z", - "version": "3.64" + "updated": "2021-08-25T00:00:00Z", + "version": "3.65" } ] } diff --git a/api-ref/source/v3/samples/versions/versions-response.json b/api-ref/source/v3/samples/versions/versions-response.json index 529ca5d21..dd7b843d1 100644 --- a/api-ref/source/v3/samples/versions/versions-response.json +++ b/api-ref/source/v3/samples/versions/versions-response.json @@ -21,8 +21,8 @@ ], "min_version": "3.0", "status": "CURRENT", - "updated": "2021-05-30T00:00:00Z", - "version": "3.64" + "updated": "2021-08-25T00:00:00Z", + "version": "3.65" } ] } diff --git a/api-ref/source/v3/samples/volumes/v3.65/volume-create-response.json b/api-ref/source/v3/samples/volumes/v3.65/volume-create-response.json new file mode 100644 index 000000000..4dc4775ff --- /dev/null +++ b/api-ref/source/v3/samples/volumes/v3.65/volume-create-response.json @@ -0,0 +1,41 @@ +{ + "volume": { + "attachments": [], + "availability_zone": "nova", + "bootable": "false", + "consistencygroup_id": null, + "created_at": "2018-11-28T06:21:12.715987", + "description": null, + "encrypted": false, + "id": "2b955850-f177-45f7-9f49-ecb2c256d161", + "links": [ + { + "href": "http://127.0.0.1:33951/v3/89afd400-b646-4bbc-b12b-c0a4d63e5bd3/volumes/2b955850-f177-45f7-9f49-ecb2c256d161", + "rel": "self" + }, + { + "href": "http://127.0.0.1:33951/89afd400-b646-4bbc-b12b-c0a4d63e5bd3/volumes/2b955850-f177-45f7-9f49-ecb2c256d161", + "rel": "bookmark" + } + ], + "metadata": {}, + "migration_status": null, + "multiattach": false, + "name": null, + "replication_status": null, + "size": 10, + "snapshot_id": null, + "source_volid": null, + "status": "creating", + "updated_at": null, + "user_id": "c853ca26-e8ea-4797-8a52-ee124a013d0e", + "volume_type": "__DEFAULT__", + "group_id": null, + "provider_id": null, + "service_uuid": null, + "shared_targets": true, + "cluster_name": null, + "volume_type_id": "5fed9d7c-401d-46e2-8e80-f30c70cb7e1d", + "consumes_quota": true + } +} diff --git a/api-ref/source/v3/samples/volumes/v3.65/volume-show-response.json b/api-ref/source/v3/samples/volumes/v3.65/volume-show-response.json new file mode 100644 index 000000000..690bb228b --- /dev/null +++ b/api-ref/source/v3/samples/volumes/v3.65/volume-show-response.json @@ -0,0 +1,45 @@ +{ + "volume": { + "attachments": [], + "availability_zone": "nova", + "bootable": "false", + "consistencygroup_id": null, + "created_at": "2018-11-29T06:50:07.770785", + "description": null, + "encrypted": false, + "id": "f7223234-1afc-4d19-bfa3-d19deb6235ef", + "links": [ + { + "href": "http://127.0.0.1:45839/v3/89afd400-b646-4bbc-b12b-c0a4d63e5bd3/volumes/f7223234-1afc-4d19-bfa3-d19deb6235ef", + "rel": "self" + }, + { + "href": "http://127.0.0.1:45839/89afd400-b646-4bbc-b12b-c0a4d63e5bd3/volumes/f7223234-1afc-4d19-bfa3-d19deb6235ef", + "rel": "bookmark" + } + ], + "metadata": {}, + "migration_status": null, + "multiattach": false, + "name": null, + "os-vol-host-attr:host": null, + "os-vol-mig-status-attr:migstat": null, + "os-vol-mig-status-attr:name_id": null, + "os-vol-tenant-attr:tenant_id": "89afd400-b646-4bbc-b12b-c0a4d63e5bd3", + "replication_status": null, + "size": 10, + "snapshot_id": null, + "source_volid": null, + "status": "creating", + "updated_at": null, + "user_id": "c853ca26-e8ea-4797-8a52-ee124a013d0e", + "volume_type": "__DEFAULT__", + "provider_id": null, + "group_id": null, + "service_uuid": null, + "shared_targets": true, + "cluster_name": null, + "volume_type_id": "5fed9d7c-401d-46e2-8e80-f30c70cb7e1d", + "consumes_quota": true + } +} diff --git a/api-ref/source/v3/samples/volumes/v3.65/volume-update-response.json b/api-ref/source/v3/samples/volumes/v3.65/volume-update-response.json new file mode 100644 index 000000000..3d8f20926 --- /dev/null +++ b/api-ref/source/v3/samples/volumes/v3.65/volume-update-response.json @@ -0,0 +1,43 @@ +{ + "volume": { + "attachments": [], + "availability_zone": "nova", + "bootable": "false", + "consistencygroup_id": null, + "created_at": "2018-11-29T06:59:23.679903", + "description": "This is yet, another volume.", + "encrypted": false, + "id": "8b2459d1-0059-4e14-a89f-dfa73a452af6", + "links": [ + { + "href": "http://127.0.0.1:41467/v3/89afd400-b646-4bbc-b12b-c0a4d63e5bd3/volumes/8b2459d1-0059-4e14-a89f-dfa73a452af6", + "rel": "self" + }, + { + "href": "http://127.0.0.1:41467/89afd400-b646-4bbc-b12b-c0a4d63e5bd3/volumes/8b2459d1-0059-4e14-a89f-dfa73a452af6", + "rel": "bookmark" + } + ], + "metadata": { + "name": "metadata0" + }, + "migration_status": null, + "multiattach": false, + "name": "vol-003", + "replication_status": null, + "size": 10, + "snapshot_id": null, + "source_volid": null, + "status": "creating", + "updated_at": null, + "user_id": "c853ca26-e8ea-4797-8a52-ee124a013d0e", + "volume_type": "__DEFAULT__", + "group_id": null, + "provider_id": null, + "service_uuid": null, + "shared_targets": true, + "cluster_name": null, + "volume_type_id": "5fed9d7c-401d-46e2-8e80-f30c70cb7e1d", + "consumes_quota": true + } +} diff --git a/api-ref/source/v3/samples/volumes/v3.65/volumes-list-detailed-response.json b/api-ref/source/v3/samples/volumes/v3.65/volumes-list-detailed-response.json new file mode 100644 index 000000000..ceaa39c79 --- /dev/null +++ b/api-ref/source/v3/samples/volumes/v3.65/volumes-list-detailed-response.json @@ -0,0 +1,47 @@ +{ + "volumes": [ + { + "attachments": [], + "availability_zone": "nova", + "bootable": "false", + "consistencygroup_id": null, + "created_at": "2018-11-28T06:25:15.288987", + "description": null, + "encrypted": false, + "id": "cb49b381-9012-40cb-b8ee-80c19a4801b5", + "links": [ + { + "href": "http://127.0.0.1:43543/v3/89afd400-b646-4bbc-b12b-c0a4d63e5bd3/volumes/cb49b381-9012-40cb-b8ee-80c19a4801b5", + "rel": "self" + }, + { + "href": "http://127.0.0.1:43543/89afd400-b646-4bbc-b12b-c0a4d63e5bd3/volumes/cb49b381-9012-40cb-b8ee-80c19a4801b5", + "rel": "bookmark" + } + ], + "metadata": {}, + "migration_status": null, + "multiattach": false, + "name": null, + "os-vol-host-attr:host": null, + "os-vol-mig-status-attr:migstat": null, + "os-vol-mig-status-attr:name_id": null, + "os-vol-tenant-attr:tenant_id": "89afd400-b646-4bbc-b12b-c0a4d63e5bd3", + "replication_status": null, + "size": 10, + "snapshot_id": null, + "source_volid": null, + "status": "creating", + "updated_at": null, + "user_id": "c853ca26-e8ea-4797-8a52-ee124a013d0e", + "volume_type": "__DEFAULT__", + "volume_type_id": "5fed9d7c-401d-46e2-8e80-f30c70cb7e1d", + "provider_id": null, + "group_id": null, + "service_uuid": null, + "shared_targets": true, + "cluster_name": null, + "consumes_quota": true + } + ] +} diff --git a/api-ref/source/v3/samples/volumes/volume-create-response.json b/api-ref/source/v3/samples/volumes/volume-create-response.json index 30feb2ac6..4bd8a6e0f 100644 --- a/api-ref/source/v3/samples/volumes/volume-create-response.json +++ b/api-ref/source/v3/samples/volumes/volume-create-response.json @@ -31,4 +31,4 @@ "user_id": "c853ca26-e8ea-4797-8a52-ee124a013d0e", "volume_type": "__DEFAULT__" } -}
\ No newline at end of file +} diff --git a/api-ref/source/v3/samples/volumes/volume-show-response.json b/api-ref/source/v3/samples/volumes/volume-show-response.json index 186411e90..faf9be288 100644 --- a/api-ref/source/v3/samples/volumes/volume-show-response.json +++ b/api-ref/source/v3/samples/volumes/volume-show-response.json @@ -35,4 +35,4 @@ "user_id": "c853ca26-e8ea-4797-8a52-ee124a013d0e", "volume_type": "__DEFAULT__" } -}
\ No newline at end of file +} diff --git a/api-ref/source/v3/samples/volumes/volume-update-response.json b/api-ref/source/v3/samples/volumes/volume-update-response.json index 4a587f679..a41d41fba 100644 --- a/api-ref/source/v3/samples/volumes/volume-update-response.json +++ b/api-ref/source/v3/samples/volumes/volume-update-response.json @@ -33,4 +33,4 @@ "user_id": "c853ca26-e8ea-4797-8a52-ee124a013d0e", "volume_type": "__DEFAULT__" } -}
\ No newline at end of file +} diff --git a/api-ref/source/v3/volumes-v3-snapshots.inc b/api-ref/source/v3/volumes-v3-snapshots.inc index c7a63793f..f3d660857 100644 --- a/api-ref/source/v3/volumes-v3-snapshots.inc +++ b/api-ref/source/v3/volumes-v3-snapshots.inc @@ -67,6 +67,7 @@ Request - offset: offset - marker: marker - with_count: with_count + - consumes_quota: filter_consumes_quota Response Parameters @@ -89,11 +90,12 @@ Response Parameters - updated_at: updated_at - snapshots_links: links_snap - group_snapshot_id: group_snapshot_id_3_14 + - consumes_quota: consumes_quota -Response Example (v3.41) +Response Example (v3.65) ------------------------ -.. literalinclude:: ./samples/snapshots/v3.41/snapshots-list-detailed-response.json +.. literalinclude:: ./samples/snapshots/v3.65/snapshots-list-detailed-response.json :language: javascript @@ -149,11 +151,12 @@ Response Parameters - size: size - updated_at: updated_at - group_snapshot_id: group_snapshot_id_3_14 + - consumes_quota: consumes_quota -Response Example (v3.41) +Response Example (v3.65) ------------------------ -.. literalinclude:: ./samples/snapshots/v3.41/snapshot-create-response.json +.. literalinclude:: ./samples/snapshots/v3.65/snapshot-create-response.json :language: javascript @@ -189,6 +192,7 @@ Request - limit: limit - offset: offset - marker: marker + - consumes_quota: filter_consumes_quota - with_count: with_count @@ -388,11 +392,12 @@ Response Parameters - metadata: metadata - updated_at: updated_at - group_snapshot_id: group_snapshot_id_3_14 + - consumes_quota: consumes_quota -Response Example (v3.41) +Response Example (v3.65) ------------------------ -.. literalinclude:: ./samples/snapshots/v3.41/snapshot-show-response.json +.. literalinclude:: ./samples/snapshots/v3.65/snapshot-show-response.json :language: javascript @@ -446,11 +451,12 @@ Response Parameters - user_id: user_id_min - metadata: metadata - group_snapshot_id: group_snapshot_id_3_14 + - consumes_quota: consumes_quota -Response Example (v3.41) +Response Example (v3.65) ------------------------ -.. literalinclude:: ./samples/snapshots/v3.41/snapshot-update-response.json +.. literalinclude:: ./samples/snapshots/v3.65/snapshot-update-response.json :language: javascript diff --git a/api-ref/source/v3/volumes-v3-volumes.inc b/api-ref/source/v3/volumes-v3-volumes.inc index f40b38606..2d7d8f4d3 100644 --- a/api-ref/source/v3/volumes-v3-volumes.inc +++ b/api-ref/source/v3/volumes-v3-volumes.inc @@ -98,6 +98,7 @@ Request - with_count: with_count - created_at: filter_created_at - updated_at: filter_updated_at + - consumes_quota: filter_consumes_quota Response Parameters @@ -140,13 +141,14 @@ Response Parameters - service_uuid: service_uuid - shared_targets: shared_targets - cluster_name: cluster_name + - consumes_quota: consumes_quota - count: count -Response Example (v3.63) +Response Example (v3.65) ------------------------ -.. literalinclude:: ./samples/volumes/v3.63/volumes-list-detailed-response.json +.. literalinclude:: ./samples/volumes/v3.65/volumes-list-detailed-response.json :language: javascript @@ -258,11 +260,12 @@ Response Parameters - service_uuid: service_uuid - shared_targets: shared_targets - cluster_name: cluster_name + - consumes_quota: consumes_quota -Response Example (v3.63) +Response Example (v3.65) ------------------------ -.. literalinclude:: ./samples/volumes/v3.63/volume-create-response.json +.. literalinclude:: ./samples/volumes/v3.65/volume-create-response.json :language: javascript @@ -301,6 +304,7 @@ Request - marker: marker - with_count: with_count - created_at: filter_created_at + - consumes_quota: filter_consumes_quota - updated_at: filter_updated_at @@ -394,12 +398,13 @@ Response Parameters - cluster_name: cluster_name - provider_id: provider_id - group_id: group_id_optional + - consumes_quota: consumes_quota -Response Example (v3.63) +Response Example (v3.65) ------------------------ -.. literalinclude:: ./samples/volumes/v3.63/volume-show-response.json +.. literalinclude:: ./samples/volumes/v3.65/volume-show-response.json :language: javascript @@ -473,12 +478,13 @@ Response Parameters - service_uuid: service_uuid - shared_targets: shared_targets - cluster_name: cluster_name + - consumes_quota: consumes_quota -Response Example (v3.63) +Response Example (v3.65) ------------------------ -.. literalinclude:: ./samples/volumes/v3.63/volume-update-response.json +.. literalinclude:: ./samples/volumes/v3.65/volume-update-response.json :language: javascript diff --git a/cinder/api/common.py b/cinder/api/common.py index 432052786..7479237ee 100644 --- a/cinder/api/common.py +++ b/cinder/api/common.py @@ -49,7 +49,8 @@ LOG = logging.getLogger(__name__) _FILTERS_COLLECTION = None ATTRIBUTE_CONVERTERS = {'name~': 'display_name~', - 'description~': 'display_description~'} + 'description~': 'display_description~', + 'consumes_quota': 'use_quota'} METADATA_TYPES = enum.Enum('METADATA_TYPES', 'user image') diff --git a/cinder/api/microversions.py b/cinder/api/microversions.py index e72c76c07..909dcd875 100644 --- a/cinder/api/microversions.py +++ b/cinder/api/microversions.py @@ -167,6 +167,8 @@ VOLUME_TYPE_ID_IN_VOLUME_DETAIL = '3.63' ENCRYPTION_KEY_ID_IN_DETAILS = '3.64' +USE_QUOTA = '3.65' + def get_mv_header(version): """Gets a formatted HTTP microversion header. diff --git a/cinder/api/openstack/api_version_request.py b/cinder/api/openstack/api_version_request.py index b6597346d..7f0769e9b 100644 --- a/cinder/api/openstack/api_version_request.py +++ b/cinder/api/openstack/api_version_request.py @@ -148,14 +148,17 @@ REST_API_VERSION_HISTORY = """ ("GET /v3/{project_id}/volumes/detail") and volume-show ("GET /v3/{project_id}/volumes/{volume_id}") calls. * 3.64 - Include 'encryption_key_id' in volume and backup details + * 3.65 - Include 'consumes_quota' in volume and snapshot details + - Accept 'consumes_quota' filter in volume and snapshot list + operation. """ # The minimum and maximum versions of the API supported # The default api version request is defined to be the # minimum version of the API supported. _MIN_API_VERSION = "3.0" -_MAX_API_VERSION = "3.64" -UPDATED = "2021-05-30T00:00:00Z" +_MAX_API_VERSION = "3.65" +UPDATED = "2021-08-25T00:00:00Z" # NOTE(cyeoh): min and max versions declared as functions so we can diff --git a/cinder/api/v3/snapshots.py b/cinder/api/v3/snapshots.py index 9debfcebc..d5c1a47ba 100644 --- a/cinder/api/v3/snapshots.py +++ b/cinder/api/v3/snapshots.py @@ -53,16 +53,24 @@ class SnapshotsController(snapshots_v2.SnapshotsController): LOG.debug('Could not evaluate value %s, assuming string', search_opts['metadata']) + if 'use_quota' in search_opts: + search_opts['use_quota'] = utils.get_bool_param('use_quota', + search_opts) + + MV_ADDED_FILTERS = ( + (mv.get_prior_version(mv.SNAPSHOT_LIST_METADATA_FILTER), 'metadata'), + # REST API receives consumes_quota, but process_general_filtering + # transforms it into use_quota + (mv.get_prior_version(mv.USE_QUOTA), 'use_quota'), + ) + @common.process_general_filtering('snapshot') def _process_snapshot_filtering(self, context=None, filters=None, req_version=None): """Formats allowed filters""" - - # if the max version is less than SNAPSHOT_LIST_METADATA_FILTER - # metadata based filtering is not supported - if req_version.matches( - None, mv.get_prior_version(mv.SNAPSHOT_LIST_METADATA_FILTER)): - filters.pop('metadata', None) + for version, field in self.MV_ADDED_FILTERS: + if req_version.matches(None, version): + filters.pop(field, None) # Filter out invalid options allowed_search_options = self._get_snapshot_filter_options() diff --git a/cinder/api/v3/views/snapshots.py b/cinder/api/v3/views/snapshots.py index 857df059c..cd09f9cd5 100644 --- a/cinder/api/v3/views/snapshots.py +++ b/cinder/api/v3/views/snapshots.py @@ -27,9 +27,11 @@ class ViewBuilder(views_v2.ViewBuilder): req_version = request.api_version_request # Add group_snapshot_id if min version is greater than or equal # to GROUP_SNAPSHOTS. + snap = snapshot_ref['snapshot'] if req_version.matches(mv.GROUP_SNAPSHOTS, None): - snapshot_ref['snapshot']['group_snapshot_id'] = ( - snapshot.get('group_snapshot_id')) + snap['group_snapshot_id'] = snapshot.get('group_snapshot_id') if req_version.matches(mv.SNAPSHOT_LIST_USER_ID, None): - snapshot_ref['snapshot']['user_id'] = snapshot.get('user_id') + snap['user_id'] = snapshot.get('user_id') + if req_version.matches(mv.USE_QUOTA): + snap['consumes_quota'] = snapshot.get('use_quota') return snapshot_ref diff --git a/cinder/api/v3/views/volumes.py b/cinder/api/v3/views/volumes.py index ed171c7bd..ded603a4f 100644 --- a/cinder/api/v3/views/volumes.py +++ b/cinder/api/v3/views/volumes.py @@ -77,6 +77,9 @@ class ViewBuilder(views_v2.ViewBuilder): encryption_key_id != cinder_constants.FIXED_KEY_ID): volume_ref['volume']['encryption_key_id'] = encryption_key_id + if req_version.matches(mv.USE_QUOTA): + volume_ref['volume']['consumes_quota'] = volume.get('use_quota') + return volume_ref def _list_view(self, func, request, volumes, volume_count, diff --git a/cinder/api/v3/volumes.py b/cinder/api/v3/volumes.py index e5c5f18ef..0d2841c4f 100644 --- a/cinder/api/v3/volumes.py +++ b/cinder/api/v3/volumes.py @@ -80,18 +80,23 @@ class VolumeController(volumes_v2.VolumeController): return webob.Response(status_int=HTTPStatus.ACCEPTED) + MV_ADDED_FILTERS = ( + (mv.get_prior_version(mv.VOLUME_LIST_GLANCE_METADATA), + 'glance_metadata'), + (mv.get_prior_version(mv.VOLUME_LIST_GROUP), 'group_id'), + (mv.get_prior_version(mv.VOLUME_TIME_COMPARISON_FILTER), 'created_at'), + (mv.get_prior_version(mv.VOLUME_TIME_COMPARISON_FILTER), 'updated_at'), + # REST API receives consumes_quota, but process_general_filtering + # transforms it into use_quota + (mv.get_prior_version(mv.USE_QUOTA), 'use_quota'), + ) + @common.process_general_filtering('volume') def _process_volume_filtering(self, context=None, filters=None, req_version=None): - if req_version.matches(None, mv.MESSAGES): - filters.pop('glance_metadata', None) - - if req_version.matches(None, mv.BACKUP_UPDATE): - filters.pop('group_id', None) - - if req_version.matches(None, mv.SUPPORT_TRANSFER_PAGINATION): - filters.pop('created_at', None) - filters.pop('updated_at', None) + for version, field in self.MV_ADDED_FILTERS: + if req_version.matches(None, version): + filters.pop(field, None) api_utils.remove_invalid_filter_options( context, filters, @@ -155,6 +160,9 @@ class VolumeController(volumes_v2.VolumeController): if 'name' in filters: filters['display_name'] = filters.pop('name') + if 'use_quota' in filters: + filters['use_quota'] = utils.get_bool_param('use_quota', filters) + self._handle_time_comparison_filters(filters) strict = req.api_version_request.matches( diff --git a/cinder/tests/functional/api_sample_tests/samples/snapshots/v3.65/snapshot-create-response.json.tpl b/cinder/tests/functional/api_sample_tests/samples/snapshots/v3.65/snapshot-create-response.json.tpl new file mode 100644 index 000000000..e2f6f55de --- /dev/null +++ b/cinder/tests/functional/api_sample_tests/samples/snapshots/v3.65/snapshot-create-response.json.tpl @@ -0,0 +1,18 @@ +{ + "snapshot": { + "created_at": "%(strtime)s", + "description": "Daily backup", + "id": "%(uuid)s", + "metadata": { + "key": "v3" + }, + "name": "snap-001", + "size": 10, + "status": "creating", + "updated_at": null, + "volume_id": "%(uuid)s", + "group_snapshot_id": null, + "user_id": "%(uuid)s", + "consumes_quota": true + } +} diff --git a/cinder/tests/functional/api_sample_tests/samples/snapshots/v3.65/snapshot-show-response.json.tpl b/cinder/tests/functional/api_sample_tests/samples/snapshots/v3.65/snapshot-show-response.json.tpl new file mode 100644 index 000000000..2656017af --- /dev/null +++ b/cinder/tests/functional/api_sample_tests/samples/snapshots/v3.65/snapshot-show-response.json.tpl @@ -0,0 +1,20 @@ +{ + "snapshot": { + "created_at": "%(strtime)s", + "description": "Daily backup", + "id": "%(uuid)s", + "metadata": { + "key": "v3" + }, + "name": "snap-001", + "os-extended-snapshot-attributes:progress": "0%", + "os-extended-snapshot-attributes:project_id": "%(uuid)s", + "size": 10, + "status": "creating", + "updated_at": null, + "volume_id": "%(uuid)s", + "group_snapshot_id": null, + "user_id": "%(uuid)s", + "consumes_quota": true + } +} diff --git a/cinder/tests/functional/api_sample_tests/samples/snapshots/v3.65/snapshot-update-response.json.tpl b/cinder/tests/functional/api_sample_tests/samples/snapshots/v3.65/snapshot-update-response.json.tpl new file mode 100644 index 000000000..fb5285c6e --- /dev/null +++ b/cinder/tests/functional/api_sample_tests/samples/snapshots/v3.65/snapshot-update-response.json.tpl @@ -0,0 +1,18 @@ +{ + "snapshot": { + "created_at": "%(strtime)s", + "description": "This is yet, another snapshot.", + "id": "%(uuid)s", + "metadata": { + "key": "v3" + }, + "name": "snap-002", + "size": 10, + "status": "creating", + "updated_at": null, + "volume_id": "%(uuid)s", + "group_snapshot_id": null, + "user_id": "%(uuid)s", + "consumes_quota": true + } +} diff --git a/cinder/tests/functional/api_sample_tests/samples/snapshots/v3.65/snapshots-list-detailed-response.json.tpl b/cinder/tests/functional/api_sample_tests/samples/snapshots/v3.65/snapshots-list-detailed-response.json.tpl new file mode 100644 index 000000000..a521bc85c --- /dev/null +++ b/cinder/tests/functional/api_sample_tests/samples/snapshots/v3.65/snapshots-list-detailed-response.json.tpl @@ -0,0 +1,22 @@ +{ + "snapshots": [ + { + "created_at": "%(strtime)s", + "description": "Daily backup", + "id": "%(uuid)s", + "metadata": { + "key": "v3" + }, + "name": "snap-001", + "os-extended-snapshot-attributes:progress": "0%", + "os-extended-snapshot-attributes:project_id": "%(uuid)s", + "size": 10, + "status": "creating", + "updated_at": null, + "volume_id": "%(uuid)s", + "group_snapshot_id": null, + "user_id": "%(uuid)s", + "consumes_quota": true + } + ] +} diff --git a/cinder/tests/functional/api_sample_tests/samples/volumes/v3.65/volume-create-response.json.tpl b/cinder/tests/functional/api_sample_tests/samples/volumes/v3.65/volume-create-response.json.tpl new file mode 100644 index 000000000..ecfa16b1f --- /dev/null +++ b/cinder/tests/functional/api_sample_tests/samples/volumes/v3.65/volume-create-response.json.tpl @@ -0,0 +1,41 @@ +{ + "volume": { + "attachments": [], + "availability_zone": "nova", + "bootable": "false", + "consistencygroup_id": null, + "created_at": "%(strtime)s", + "description": null, + "encrypted": false, + "id": "%(uuid)s", + "links": [ + { + "href": "%(host)s/v3/89afd400-b646-4bbc-b12b-c0a4d63e5bd3/volumes/%(uuid)s", + "rel": "self" + }, + { + "href": "%(host)s/89afd400-b646-4bbc-b12b-c0a4d63e5bd3/volumes/%(uuid)s", + "rel": "bookmark" + } + ], + "metadata": {}, + "migration_status": null, + "multiattach": false, + "name": null, + "replication_status": null, + "size": 10, + "snapshot_id": null, + "source_volid": null, + "status": "creating", + "updated_at": null, + "user_id": "%(uuid)s", + "volume_type": "__DEFAULT__", + "group_id": null, + "provider_id": null, + "service_uuid": null, + "shared_targets": true, + "cluster_name": null, + "volume_type_id": "%(uuid)s", + "consumes_quota": true + } +} diff --git a/cinder/tests/functional/api_sample_tests/samples/volumes/v3.65/volume-show-response.json.tpl b/cinder/tests/functional/api_sample_tests/samples/volumes/v3.65/volume-show-response.json.tpl new file mode 100644 index 000000000..4fc2ab447 --- /dev/null +++ b/cinder/tests/functional/api_sample_tests/samples/volumes/v3.65/volume-show-response.json.tpl @@ -0,0 +1,45 @@ +{ + "volume": { + "attachments": [], + "availability_zone": "nova", + "bootable": "false", + "consistencygroup_id": null, + "created_at": "%(strtime)s", + "description": null, + "encrypted": false, + "id": "%(uuid)s", + "links": [ + { + "href": "%(host)s/v3/89afd400-b646-4bbc-b12b-c0a4d63e5bd3/volumes/%(uuid)s", + "rel": "self" + }, + { + "href": "%(host)s/89afd400-b646-4bbc-b12b-c0a4d63e5bd3/volumes/%(uuid)s", + "rel": "bookmark" + } + ], + "metadata": {}, + "migration_status": null, + "multiattach": false, + "name": null, + "os-vol-host-attr:host": null, + "os-vol-mig-status-attr:migstat": null, + "os-vol-mig-status-attr:name_id": null, + "os-vol-tenant-attr:tenant_id": "%(uuid)s", + "replication_status": null, + "size": 10, + "snapshot_id": null, + "source_volid": null, + "status": "creating", + "updated_at": null, + "user_id": "%(uuid)s", + "volume_type": "__DEFAULT__", + "provider_id": null, + "group_id": null, + "service_uuid": null, + "shared_targets": true, + "cluster_name": null, + "volume_type_id": "%(uuid)s", + "consumes_quota": true + } +} diff --git a/cinder/tests/functional/api_sample_tests/samples/volumes/v3.65/volume-update-response.json.tpl b/cinder/tests/functional/api_sample_tests/samples/volumes/v3.65/volume-update-response.json.tpl new file mode 100644 index 000000000..bc2723504 --- /dev/null +++ b/cinder/tests/functional/api_sample_tests/samples/volumes/v3.65/volume-update-response.json.tpl @@ -0,0 +1,43 @@ +{ + "volume": { + "attachments": [], + "availability_zone": "nova", + "bootable": "false", + "consistencygroup_id": null, + "created_at": "%(strtime)s", + "description": "This is yet, another volume.", + "encrypted": false, + "id": "%(uuid)s", + "links": [ + { + "href": "%(host)s/v3/89afd400-b646-4bbc-b12b-c0a4d63e5bd3/volumes/%(uuid)s", + "rel": "self" + }, + { + "href": "%(host)s/89afd400-b646-4bbc-b12b-c0a4d63e5bd3/volumes/%(uuid)s", + "rel": "bookmark" + } + ], + "metadata": { + "name": "metadata0" + }, + "migration_status": null, + "multiattach": false, + "name": "vol-003", + "replication_status": null, + "size": 10, + "snapshot_id": null, + "source_volid": null, + "status": "creating", + "updated_at": null, + "user_id": "%(uuid)s", + "volume_type": "__DEFAULT__", + "group_id": null, + "provider_id": null, + "service_uuid": null, + "shared_targets": true, + "cluster_name": null, + "volume_type_id": "%(uuid)s", + "consumes_quota": true + } +} diff --git a/cinder/tests/functional/api_sample_tests/samples/volumes/v3.65/volumes-list-detailed-response.json.tpl b/cinder/tests/functional/api_sample_tests/samples/volumes/v3.65/volumes-list-detailed-response.json.tpl new file mode 100644 index 000000000..3aff1e884 --- /dev/null +++ b/cinder/tests/functional/api_sample_tests/samples/volumes/v3.65/volumes-list-detailed-response.json.tpl @@ -0,0 +1,47 @@ +{ + "volumes": [ + { + "attachments": [], + "availability_zone": "nova", + "bootable": "false", + "consistencygroup_id": null, + "created_at": "%(strtime)s", + "description": null, + "encrypted": false, + "id": "%(uuid)s", + "links": [ + { + "href": "%(host)s/v3/89afd400-b646-4bbc-b12b-c0a4d63e5bd3/volumes/%(uuid)s", + "rel": "self" + }, + { + "href": "%(host)s/89afd400-b646-4bbc-b12b-c0a4d63e5bd3/volumes/%(uuid)s", + "rel": "bookmark" + } + ], + "metadata": {}, + "migration_status": null, + "multiattach": false, + "name": null, + "os-vol-host-attr:host": null, + "os-vol-mig-status-attr:migstat": null, + "os-vol-mig-status-attr:name_id": null, + "os-vol-tenant-attr:tenant_id": "%(uuid)s", + "replication_status": null, + "size": 10, + "snapshot_id": null, + "source_volid": null, + "status": "creating", + "updated_at": null, + "user_id": "%(uuid)s", + "volume_type": "%(name)s", + "volume_type_id": "%(uuid)s", + "service_uuid": null, + "provider_id": null, + "group_id": null, + "shared_targets": true, + "cluster_name": null, + "consumes_quota": true + } + ] +} diff --git a/cinder/tests/functional/api_sample_tests/test_snapshots.py b/cinder/tests/functional/api_sample_tests/test_snapshots.py index abec1251a..14200ff01 100644 --- a/cinder/tests/functional/api_sample_tests/test_snapshots.py +++ b/cinder/tests/functional/api_sample_tests/test_snapshots.py @@ -39,7 +39,8 @@ class SnapshotBaseTest(test_base.VolumesSampleBase): @test_base.VolumesSampleBase.use_versions( mv.BASE_VERSION, # 3.0 mv.GROUP_SNAPSHOTS, # 3.14 - mv.SNAPSHOT_LIST_USER_ID) # 3.41 + mv.SNAPSHOT_LIST_USER_ID, # 3.41 + mv.USE_QUOTA) # 3.65 class SnapshotDetailTests(SnapshotBaseTest): """Test snapshot details returned for operations with different MVs. diff --git a/cinder/tests/functional/api_sample_tests/test_volumes.py b/cinder/tests/functional/api_sample_tests/test_volumes.py index a80d3ef1c..24ef1d5da 100644 --- a/cinder/tests/functional/api_sample_tests/test_volumes.py +++ b/cinder/tests/functional/api_sample_tests/test_volumes.py @@ -22,7 +22,8 @@ from cinder.tests.functional import api_samples_test_base as test_base mv.VOLUME_DETAIL_PROVIDER_ID, # 3.21 mv.VOLUME_SHARED_TARGETS_AND_SERVICE_FIELDS, # 3.48 mv.VOLUME_CLUSTER_NAME, # 3.61 - mv.VOLUME_TYPE_ID_IN_VOLUME_DETAIL) # 3.63 + mv.VOLUME_TYPE_ID_IN_VOLUME_DETAIL, # 3.63 + mv.USE_QUOTA) # 3.65 class VolumeDetailTests(test_base.VolumesSampleBase): """Test volume details returned for operations with different MVs. diff --git a/cinder/tests/unit/api/test_common.py b/cinder/tests/unit/api/test_common.py index ecd389340..e18bb24cc 100644 --- a/cinder/tests/unit/api/test_common.py +++ b/cinder/tests/unit/api/test_common.py @@ -487,12 +487,13 @@ class GeneralFiltersTest(test.TestCase): 'expected': ["name", "status", "metadata", "bootable", "migration_status", "availability_zone", "group_id", - "size", "created_at", "updated_at"]}, + "size", "created_at", "updated_at", + "consumes_quota"]}, {'resource': 'backup', 'expected': ["name", "status", "volume_id"]}, {'resource': 'snapshot', 'expected': ["name", "status", "volume_id", "metadata", - "availability_zone"]}, + "availability_zone", "consumes_quota"]}, {'resource': 'group_snapshot', 'expected': ["name", "status", "group_id"]}, {'resource': 'attachment', diff --git a/cinder/tests/unit/api/v3/test_snapshots.py b/cinder/tests/unit/api/v3/test_snapshots.py index d984c8c53..473ae5b89 100644 --- a/cinder/tests/unit/api/v3/test_snapshots.py +++ b/cinder/tests/unit/api/v3/test_snapshots.py @@ -115,6 +115,28 @@ class SnapshotApiTest(test.TestCase): self.assertNotIn('group_snapshot_id', resp_dict['snapshot']) self.assertNotIn('user_id', resp_dict['snapshot']) + @ddt.data( + (True, True, mv.USE_QUOTA), + (True, False, mv.USE_QUOTA), + (False, True, mv.get_prior_version(mv.USE_QUOTA)), + (False, False, mv.get_prior_version(mv.USE_QUOTA)), + ) + @ddt.unpack + def test_snapshot_show_with_use_quota(self, present, value, microversion): + volume = test_utils.create_volume(self.ctx, host='test_host1', + cluster_name='cluster1', + availability_zone='nova1') + snapshot = test_utils.create_snapshot(self.ctx, volume.id, + use_quota=value) + + url = '/v3/snapshots?%s' % snapshot.id + req = fakes.HTTPRequest.blank(url, version=microversion) + res_dict = self.controller.show(req, snapshot.id)['snapshot'] + if present: + self.assertIs(value, res_dict['consumes_quota']) + else: + self.assertNotIn('consumes_quota', res_dict) + def test_snapshot_show_invalid_id(self): snapshot_id = INVALID_UUID req = fakes.HTTPRequest.blank('/v3/snapshots/%s' % snapshot_id) @@ -133,25 +155,28 @@ class SnapshotApiTest(test.TestCase): body = {"snapshot": snap} self.controller.create(req, body=body) - @ddt.data(('host', 'test_host1', True), ('cluster_name', 'cluster1', True), - ('availability_zone', 'nova1', False)) + @ddt.data(('host', 'test_host1', True, mv.RESOURCE_FILTER), + ('cluster_name', 'cluster1', True, mv.RESOURCE_FILTER), + ('availability_zone', 'nova1', False, mv.RESOURCE_FILTER), + ('consumes_quota', 'true', False, mv.USE_QUOTA)) @ddt.unpack def test_snapshot_list_with_filter(self, filter_name, filter_value, - is_admin_user): + is_admin_user, microversion): volume1 = test_utils.create_volume(self.ctx, host='test_host1', cluster_name='cluster1', availability_zone='nova1') volume2 = test_utils.create_volume(self.ctx, host='test_host2', cluster_name='cluster2', availability_zone='nova2') - snapshot1 = test_utils.create_snapshot(self.ctx, volume1.id) - test_utils.create_snapshot(self.ctx, volume2.id) + snapshot1 = test_utils.create_snapshot(self.ctx, volume1.id, + use_quota=True) + test_utils.create_snapshot(self.ctx, volume2.id, use_quota=False) url = '/v3/snapshots?%s=%s' % (filter_name, filter_value) # Generic filtering is introduced since '3,31' and we add # 'availability_zone' support by using generic filtering. req = fakes.HTTPRequest.blank(url, use_admin_context=is_admin_user, - version=mv.RESOURCE_FILTER) + version=microversion) res_dict = self.controller.detail(req) self.assertEqual(1, len(res_dict['snapshots'])) diff --git a/cinder/tests/unit/api/v3/test_volumes.py b/cinder/tests/unit/api/v3/test_volumes.py index c2f787021..18e313527 100644 --- a/cinder/tests/unit/api/v3/test_volumes.py +++ b/cinder/tests/unit/api/v3/test_volumes.py @@ -343,6 +343,45 @@ class VolumeApiTest(test.TestCase): volumes = res_dict['volumes'] self.assertEqual(2, len(volumes)) + @ddt.data(('true', 0), ('false', 1)) + @ddt.unpack + def test_volume_list_with_quota_filter(self, use_quota, expected_index): + volumes = (test_utils.create_volume(self.ctxt, host='test_host1', + cluster_name='cluster1', + volume_type_id=None, + use_quota=True, + availability_zone='nova1'), + test_utils.create_volume(self.ctxt, host='test_host2', + cluster_name='cluster2', + volume_type_id=None, + use_quota=False, + availability_zone='nova2')) + req = fakes.HTTPRequest.blank( + '/v3/volumes?consumes_quota=%s' % use_quota, version=mv.USE_QUOTA) + res_dict = self.controller.detail(req) + self.assertEqual(1, len(res_dict['volumes'])) + self.assertEqual(volumes[expected_index].id, + res_dict['volumes'][0]['id']) + + def test_volume_list_without_quota_filter(self): + num_vols = 4 + vol_ids = set() + # Half of the volumes will use quota, the other half won't + for i in range(num_vols): + vol = test_utils.create_volume(self.ctxt, + use_quota=bool(i % 2), + host='test_host', + cluster_name='cluster', + volume_type_id=None, + availability_zone='nova1') + vol_ids.add(vol.id) + req = fakes.HTTPRequest.blank('/v3/volumes', version=mv.USE_QUOTA) + res_dict = self.controller.detail(req) + + res_vol_ids = {v['id'] for v in res_dict['volumes']} + self.assertEqual(num_vols, len(res_vol_ids)) + self.assertEqual(vol_ids, res_vol_ids) + def _fake_volumes_summary_request(self, version=mv.VOLUME_SUMMARY, all_tenant=False, @@ -900,6 +939,27 @@ class VolumeApiTest(test.TestCase): else: self.assertNotIn('encryption_key_id', volume_details) + @ddt.data( + (True, True, mv.USE_QUOTA), + (True, False, mv.USE_QUOTA), + (False, True, mv.get_prior_version(mv.USE_QUOTA)), + (False, False, mv.get_prior_version(mv.USE_QUOTA)), + ) + @ddt.unpack + def test_volume_show_with_use_quota(self, present, value, microversion): + volume = test_utils.create_volume(self.ctxt, + volume_type_id=None, + use_quota=value) + + req = fakes.HTTPRequest.blank('/v3/volumes/%s' % volume.id, + version=microversion) + volume_details = self.controller.show(req, volume.id)['volume'] + + if present: + self.assertIs(value, volume_details['consumes_quota']) + else: + self.assertNotIn('consumes_quota', volume_details) + def _fake_create_volume(self, size=1): vol = { 'display_name': 'fake_volume1', diff --git a/etc/cinder/resource_filters.json b/etc/cinder/resource_filters.json index 967361e69..e9335ab14 100644 --- a/etc/cinder/resource_filters.json +++ b/etc/cinder/resource_filters.json @@ -1,10 +1,11 @@ { "volume": ["name", "status", "metadata", "bootable", "migration_status", "availability_zone", - "group_id", "size", "created_at", "updated_at"], + "group_id", "size", "created_at", "updated_at", + "consumes_quota"], "backup": ["name", "status", "volume_id"], "snapshot": ["name", "status", "volume_id", "metadata", - "availability_zone"], + "availability_zone", "consumes_quota"], "group": ["name"], "group_snapshot": ["name", "status", "group_id"], "attachment": ["volume_id", "status", "instance_id", "attach_status"], diff --git a/releasenotes/notes/mv-use_quota-b8e010f8f68a1eaa.yaml b/releasenotes/notes/mv-use_quota-b8e010f8f68a1eaa.yaml new file mode 100644 index 000000000..e5c494e81 --- /dev/null +++ b/releasenotes/notes/mv-use_quota-b8e010f8f68a1eaa.yaml @@ -0,0 +1,14 @@ +--- +features: + - | + Starting with API microversion 3.65, a ``consumes_quota`` field + is included in the response body of volumes and snapshots to indicate + whether the volume is using quota or not. + + Additionally, ``consumes_quota`` can be used as a listing filter for + volumes and snapshots. Its availability is controlled by its inclusion in + ``etc/cinder/resource_filters.json``, where it is included by default. The + default listing behavior is not to use this filter. + + Only temporary resources created internally by cinder will have the value + set to ``false``. |