Add schema validation for Share Snapshot list API

Introduces JSON schema validation for the share snapshot list
(index) API across supported microversions. It defines request
query and response body schemas for versions 2.0 through 2.79,
covering pagination, sorting, filtering, and count parameters.

Prepares the groundwork for full controller validation, which
will include request body schemas for create and update
operations in a follow-up

Change-Id: I308d942ae460e881cf37f95f393c799c75d5bd62
Signed-off-by: Marco Wehrhahn <marco.wehrhahn@gmail.com>
This commit is contained in:
Marco Wehrhahn
2025-10-18 17:59:17 -04:00
parent 40107f9616
commit e07ea29033
2 changed files with 158 additions and 0 deletions

View File

@@ -0,0 +1,149 @@
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import copy
from oslo_config import cfg
from manila.api.validation import parameter_types
from manila.api.validation import response_types
CONF = cfg.CONF
# Base list snapshots query (v2.0+)
index_request_query = {
'type': 'object',
'properties': {
# Pagination
'limit': parameter_types.single_param(
parameter_types.non_negative_integer
),
'offset': parameter_types.single_param(
parameter_types.non_negative_integer
),
# Sorting
'sort_key': parameter_types.single_param({
'type': 'string',
'minLength': 1,
'maxLength': 255,
}),
'sort_dir': parameter_types.single_param({
'type': 'string',
'default': 'desc',
'description': 'Sort direction',
}),
# Project Scoping
'project_id': parameter_types.single_param({
'type': 'string',
'minLength': 1,
'maxLength': 255,
}),
# Admin only
'all_tenants': {
**parameter_types.boolean,
'enum': [1, 0],
'description': (
"Set 1 to list resources for all projects;"
"set 0 to list resources only for the current project"
)},
# Basic filters
'name': parameter_types.single_param({
'type': 'string',
'minLength': 1,
'maxLength': 255,
}),
'description': parameter_types.single_param({
'type': 'string',
'minLength': 1,
'maxLength': 255,
}),
'status': parameter_types.single_param({
'type': 'string',
'minLength': 1,
'maxLength': 255,
}),
'share_id': parameter_types.single_param({
'type': 'string',
'minLength': 1,
'maxLength': 255,
}),
'size': parameter_types.single_param(
parameter_types.non_negative_integer,
),
},
'required': [],
'additionalProperties': True,
}
# >= v2.36: like filters for name~/description~
index_request_query_v236 = copy.copy(index_request_query)
index_request_query_v236['properties'].update({
'name~': parameter_types.single_param({
'type': 'string',
'minLength': 1,
'maxLength': 255,
}),
'description~': parameter_types.single_param({
'type': 'string',
'minLength': 1,
'maxLength': 255
}),
})
# >= v2.73: metadata filter
index_request_query_v273 = copy.copy(index_request_query_v236)
index_request_query_v273['properties'].update({
'metadata': parameter_types.single_param({
'type': 'string',
'minLength': 1,
'maxLength': 4096,
}),
})
# >= v2.79: with_count flag added on top
index_request_query_v279 = copy.copy(index_request_query_v273)
index_request_query_v279['properties'].update({
'with_count': parameter_types.single_param({
**parameter_types.boolean,
'default': False,
'description': "Show count in share snapshot list API response"
}),
})
_snapshot_response = {
'type': 'object',
'properties': {
'id': {'type': ['string', 'integer'],
'description': "The UUID of the snapshot."},
'links': response_types.links,
'name': {'type': ['string', 'null'],
'description': "The user-defined name of the snapshot."},
},
'required': ['id', 'links', 'name'],
'additionalProperties': False,
}
index_response_body = {
'type': 'object',
'properties': {
'snapshots': {
'type': 'array',
'items': _snapshot_response,
},
'share_snapshots_links': response_types.collection_links,
# >= v2.79 when with_count=True
'count': {'type': 'integer', 'minimum': 0},
},
'required': ['snapshots'],
'additionalProperties': False,
}

View File

@@ -25,8 +25,10 @@ from webob import exc
from manila.api import common
from manila.api.openstack import api_version_request as api_version
from manila.api.openstack import wsgi
from manila.api.schemas import share_snapshots as schema
from manila.api.v1 import share_snapshots
from manila.api.v2 import metadata
from manila.api import validation
from manila.api.views import share_snapshots as snapshot_views
from manila.common import constants
from manila.db import api as db_api
@@ -333,6 +335,13 @@ class ShareSnapshotsController(share_snapshots.ShareSnapshotMixin,
return self._access_list(req, snapshot_id)
@wsgi.Controller.api_version("2.0")
@validation.request_query_schema(schema.index_request_query, "2.0", "2.35")
@validation.request_query_schema(
schema.index_request_query_v236, "2.36", "2.72")
@validation.request_query_schema(
schema.index_request_query_v273, "2.73", "2.78")
@validation.request_query_schema(schema.index_request_query_v279, "2.79")
@validation.response_body_schema(schema.index_response_body)
def index(self, req):
"""Returns a summary list of shares."""
if req.api_version_request < api_version.APIVersionRequest("2.36"):