Merge "api: Restrict additional query string arguments"
This commit is contained in:
@@ -283,7 +283,8 @@ REST_API_VERSION_HISTORY = """REST API Version History:
|
||||
202 Accepted instead of HTTP 200 and a volumeAttachment response.
|
||||
* 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.
|
||||
filters from various flavors APIs and restrict additional query
|
||||
string parameters for all APIs.
|
||||
"""
|
||||
|
||||
# The minimum and maximum versions of the API supported
|
||||
|
||||
@@ -50,7 +50,8 @@ class AggregateController(wsgi.Controller):
|
||||
self.conductor_tasks = conductor.ComputeTaskAPI()
|
||||
|
||||
@wsgi.expected_errors(())
|
||||
@validation.query_schema(schema.index_query)
|
||||
@validation.query_schema(schema.index_query, '2.1', '2.101')
|
||||
@validation.query_schema(schema.index_query_v2102, '2.102')
|
||||
@validation.response_body_schema(schema.index_response, '2.1', '2.40')
|
||||
@validation.response_body_schema(schema.index_response_v241, '2.41')
|
||||
def index(self, req):
|
||||
@@ -100,7 +101,8 @@ class AggregateController(wsgi.Controller):
|
||||
return agg
|
||||
|
||||
@wsgi.expected_errors((400, 404))
|
||||
@validation.query_schema(schema.show_query)
|
||||
@validation.query_schema(schema.show_query, '2.1', '2.101')
|
||||
@validation.query_schema(schema.show_query_v2102, '2.102')
|
||||
@validation.response_body_schema(schema.show_response, '2.1', '2.40')
|
||||
@validation.response_body_schema(schema.show_response_v241, '2.41')
|
||||
def show(self, req, id):
|
||||
|
||||
@@ -65,7 +65,7 @@ class AssistedVolumeSnapshotsController(wsgi.Controller):
|
||||
@wsgi.response(204)
|
||||
@wsgi.expected_errors((400, 404))
|
||||
@validation.query_schema(schema.delete_query, '2.0', '2.74')
|
||||
@validation.query_schema(schema.delete_query_275, '2.75')
|
||||
@validation.query_schema(schema.delete_query_v275, '2.75')
|
||||
@validation.response_body_schema(schema.delete_response)
|
||||
def delete(self, req, id):
|
||||
"""Delete a snapshot."""
|
||||
|
||||
@@ -65,7 +65,8 @@ class InterfaceAttachmentController(wsgi.Controller):
|
||||
self.network_api = neutron.API()
|
||||
|
||||
@wsgi.expected_errors((404, 501))
|
||||
@validation.query_schema(schema.index_query)
|
||||
@validation.query_schema(schema.index_query, '2.1', '2.101')
|
||||
@validation.query_schema(schema.index_query_v2102, '2.102')
|
||||
@validation.response_body_schema(schema.index_response, '2.1', '2.69')
|
||||
@validation.response_body_schema(schema.index_response_v270, '2.70')
|
||||
def index(self, req, server_id):
|
||||
@@ -110,7 +111,8 @@ class InterfaceAttachmentController(wsgi.Controller):
|
||||
return {'interfaceAttachments': results}
|
||||
|
||||
@wsgi.expected_errors((403, 404))
|
||||
@validation.query_schema(schema.show_query)
|
||||
@validation.query_schema(schema.show_query, '2.1', '2.101')
|
||||
@validation.query_schema(schema.show_query_v2102, '2.102')
|
||||
@validation.response_body_schema(schema.show_response, '2.1', '2.69')
|
||||
@validation.response_body_schema(schema.show_response_v270, '2.70')
|
||||
def show(self, req, server_id, id):
|
||||
|
||||
@@ -106,7 +106,8 @@ class AvailabilityZoneController(wsgi.Controller):
|
||||
return {'availabilityZoneInfo': result}
|
||||
|
||||
@wsgi.expected_errors(())
|
||||
@validation.query_schema(schema.index_query)
|
||||
@validation.query_schema(schema.index_query, '2.1', '2.101')
|
||||
@validation.query_schema(schema.index_query_v2102, '2.102')
|
||||
@validation.response_body_schema(schema.index_response)
|
||||
def index(self, req):
|
||||
"""Returns a summary list of availability zone."""
|
||||
@@ -116,7 +117,8 @@ class AvailabilityZoneController(wsgi.Controller):
|
||||
return self._describe_availability_zones(context)
|
||||
|
||||
@wsgi.expected_errors(())
|
||||
@validation.query_schema(schema.detail_query)
|
||||
@validation.query_schema(schema.detail_query, '2.1', '2.101')
|
||||
@validation.query_schema(schema.detail_query_v2102, '2.102')
|
||||
@validation.response_body_schema(schema.detail_response)
|
||||
def detail(self, req):
|
||||
"""Returns a detailed list of availability zone."""
|
||||
|
||||
@@ -856,7 +856,8 @@ EXTENSION_LIST_LEGACY_V2_COMPATIBLE = sorted(
|
||||
class ExtensionInfoController(wsgi.Controller):
|
||||
|
||||
@wsgi.expected_errors(())
|
||||
@validation.query_schema(schema.index_query)
|
||||
@validation.query_schema(schema.index_query, '2.1', '2.101')
|
||||
@validation.query_schema(schema.index_query_v2102, '2.102')
|
||||
@validation.response_body_schema(schema.index_response)
|
||||
def index(self, req):
|
||||
context = req.environ['nova.context']
|
||||
@@ -870,7 +871,8 @@ class ExtensionInfoController(wsgi.Controller):
|
||||
return dict(extensions=EXTENSION_LIST)
|
||||
|
||||
@wsgi.expected_errors(404)
|
||||
@validation.query_schema(schema.show_query)
|
||||
@validation.query_schema(schema.show_query, '2.1', '2.101')
|
||||
@validation.query_schema(schema.show_query_v2102, '2.102')
|
||||
@validation.response_body_schema(schema.show_response)
|
||||
def show(self, req, id):
|
||||
context = req.environ['nova.context']
|
||||
|
||||
@@ -42,7 +42,8 @@ class FlavorAccessController(wsgi.Controller):
|
||||
"""The flavor access API controller for the OpenStack API."""
|
||||
|
||||
@wsgi.expected_errors(404)
|
||||
@validation.query_schema(schema.index_query)
|
||||
@validation.query_schema(schema.index_query, '2.1', '2.101')
|
||||
@validation.query_schema(schema.index_query_v2102, '2.102')
|
||||
@validation.response_body_schema(schema.index_response)
|
||||
def index(self, req, flavor_id):
|
||||
context = req.environ['nova.context']
|
||||
|
||||
@@ -171,7 +171,8 @@ class FlavorsController(wsgi.Controller):
|
||||
req, limited_flavors, include_extra_specs=include_extra_specs)
|
||||
|
||||
@wsgi.expected_errors(404)
|
||||
@validation.query_schema(schema.show_query)
|
||||
@validation.query_schema(schema.show_query, '2.0', '2.101')
|
||||
@validation.query_schema(schema.show_query_v2102, '2.102')
|
||||
@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_v261, '2.61', '2.74')
|
||||
|
||||
@@ -55,7 +55,8 @@ class FlavorExtraSpecsController(wsgi.Controller):
|
||||
validators.validate(name, value)
|
||||
|
||||
@wsgi.expected_errors(404)
|
||||
@validation.query_schema(schema.index_query)
|
||||
@validation.query_schema(schema.index_query, '2.1', '2.101')
|
||||
@validation.query_schema(schema.index_query_v2102, '2.102')
|
||||
@validation.response_body_schema(schema.index_response)
|
||||
def index(self, req, flavor_id):
|
||||
"""Returns the list of extra specs for a given flavor."""
|
||||
@@ -108,7 +109,8 @@ class FlavorExtraSpecsController(wsgi.Controller):
|
||||
return body
|
||||
|
||||
@wsgi.expected_errors(404)
|
||||
@validation.query_schema(schema.show_query)
|
||||
@validation.query_schema(schema.show_query, '2.1', '2.101')
|
||||
@validation.query_schema(schema.show_query_v2102, '2.102')
|
||||
@validation.response_body_schema(schema.show_response)
|
||||
def show(self, req, flavor_id, id):
|
||||
"""Return a single extra spec item."""
|
||||
|
||||
@@ -139,7 +139,8 @@ class InstanceActionsController(wsgi.Controller):
|
||||
return actions_dict
|
||||
|
||||
@wsgi.expected_errors(404)
|
||||
@validation.query_schema(schema.show_query)
|
||||
@validation.query_schema(schema.show_query, '2.1', '2.101')
|
||||
@validation.query_schema(schema.show_query_v2102, '2.102')
|
||||
@validation.response_body_schema(schema.show_response, "2.1", "2.50")
|
||||
@validation.response_body_schema(schema.show_response_v251, "2.51", "2.57")
|
||||
@validation.response_body_schema(schema.show_response_v258, "2.58", "2.61")
|
||||
|
||||
@@ -35,7 +35,8 @@ class InstanceUsageAuditLogController(wsgi.Controller):
|
||||
self.host_api = compute.HostAPI()
|
||||
|
||||
@wsgi.expected_errors(())
|
||||
@validation.query_schema(schema.index_query)
|
||||
@validation.query_schema(schema.index_query, '2.1', '2.101')
|
||||
@validation.query_schema(schema.index_query_v2102, '2.102')
|
||||
@validation.response_body_schema(schema.index_response)
|
||||
def index(self, req):
|
||||
context = req.environ['nova.context']
|
||||
@@ -44,7 +45,8 @@ class InstanceUsageAuditLogController(wsgi.Controller):
|
||||
return {'instance_usage_audit_logs': task_log}
|
||||
|
||||
@wsgi.expected_errors(400)
|
||||
@validation.query_schema(schema.show_query)
|
||||
@validation.query_schema(schema.show_query, '2.1', '2.101')
|
||||
@validation.query_schema(schema.show_query_v2102, '2.102')
|
||||
@validation.response_body_schema(schema.show_response)
|
||||
def show(self, req, id):
|
||||
context = req.environ['nova.context']
|
||||
|
||||
@@ -35,7 +35,8 @@ class IPsController(wsgi.Controller):
|
||||
self._compute_api = compute.API()
|
||||
|
||||
@wsgi.expected_errors(404)
|
||||
@validation.query_schema(schema.index_query)
|
||||
@validation.query_schema(schema.index_query, '2.1', '2.101')
|
||||
@validation.query_schema(schema.index_query_v2102, '2.102')
|
||||
@validation.response_body_schema(schema.index_response)
|
||||
def index(self, req, server_id):
|
||||
context = req.environ["nova.context"]
|
||||
@@ -46,7 +47,8 @@ class IPsController(wsgi.Controller):
|
||||
return self._view_builder.index(req, networks)
|
||||
|
||||
@wsgi.expected_errors(404)
|
||||
@validation.query_schema(schema.show_query)
|
||||
@validation.query_schema(schema.show_query, '2.1', '2.101')
|
||||
@validation.query_schema(schema.show_query_v2102, '2.102')
|
||||
@validation.response_body_schema(schema.show_response)
|
||||
def show(self, req, server_id, id):
|
||||
context = req.environ["nova.context"]
|
||||
|
||||
@@ -118,9 +118,9 @@ class KeypairController(wsgi.Controller):
|
||||
|
||||
@wsgi.response(202, '2.0', '2.1')
|
||||
@wsgi.response(204, '2.2')
|
||||
@validation.query_schema(schema.delete_query_schema_v20, '2.0', '2.9')
|
||||
@validation.query_schema(schema.delete_query_schema_v210, '2.10', '2.74')
|
||||
@validation.query_schema(schema.delete_query_schema_v275, '2.75')
|
||||
@validation.query_schema(schema.delete_query_v20, '2.0', '2.9')
|
||||
@validation.query_schema(schema.delete_query_v210, '2.10', '2.74')
|
||||
@validation.query_schema(schema.delete_query_v275, '2.75')
|
||||
@validation.response_body_schema(schema.delete_response)
|
||||
@wsgi.expected_errors(404)
|
||||
def delete(self, req, id):
|
||||
@@ -143,9 +143,9 @@ class KeypairController(wsgi.Controller):
|
||||
except exception.KeypairNotFound as exc:
|
||||
raise webob.exc.HTTPNotFound(explanation=exc.format_message())
|
||||
|
||||
@validation.query_schema(schema.show_query_schema_v20, '2.0', '2.9')
|
||||
@validation.query_schema(schema.show_query_schema_v210, '2.10', '2.74')
|
||||
@validation.query_schema(schema.show_query_schema_v275, '2.75')
|
||||
@validation.query_schema(schema.show_query_v20, '2.0', '2.9')
|
||||
@validation.query_schema(schema.show_query_v210, '2.10', '2.74')
|
||||
@validation.query_schema(schema.show_query_v275, '2.75')
|
||||
@validation.response_body_schema(schema.show_response, '2.0', '2.1')
|
||||
@validation.response_body_schema(schema.show_response_v22, '2.2')
|
||||
@wsgi.expected_errors(404)
|
||||
@@ -174,10 +174,10 @@ class KeypairController(wsgi.Controller):
|
||||
raise webob.exc.HTTPNotFound(explanation=exc.format_message())
|
||||
return self._view_builder.show(keypair, key_type=key_type)
|
||||
|
||||
@validation.query_schema(schema.index_query_schema_v20, '2.0', '2.9')
|
||||
@validation.query_schema(schema.index_query_schema_v210, '2.10', '2.34')
|
||||
@validation.query_schema(schema.index_query_schema_v235, '2.35', '2.74')
|
||||
@validation.query_schema(schema.index_query_schema_v275, '2.75')
|
||||
@validation.query_schema(schema.index_query_v20, '2.0', '2.9')
|
||||
@validation.query_schema(schema.index_query_v210, '2.10', '2.34')
|
||||
@validation.query_schema(schema.index_query_v235, '2.35', '2.74')
|
||||
@validation.query_schema(schema.index_query_v275, '2.75')
|
||||
@validation.response_body_schema(schema.index_response, '2.0', '2.1')
|
||||
@validation.response_body_schema(schema.index_response_v22, '2.2', '2.34')
|
||||
@validation.response_body_schema(schema.index_response_v235, '2.35')
|
||||
|
||||
@@ -87,7 +87,8 @@ class QuotaClassSetsController(wsgi.Controller):
|
||||
return []
|
||||
|
||||
@wsgi.expected_errors(())
|
||||
@validation.query_schema(schema.show_query)
|
||||
@validation.query_schema(schema.show_query, '2.1', '2.101')
|
||||
@validation.query_schema(schema.show_query_v2102, '2.102')
|
||||
@validation.response_body_schema(schema.show_response, '2.1', '2.49')
|
||||
@validation.response_body_schema(schema.show_response_v250, '2.50', '2.56') # noqa: E501
|
||||
@validation.response_body_schema(schema.show_response_v257, '2.57')
|
||||
|
||||
@@ -125,19 +125,21 @@ set_metadata = {
|
||||
'additionalProperties': False,
|
||||
}
|
||||
|
||||
# TODO(stephenfin): Remove additionalProperties in a future API version
|
||||
index_query = {
|
||||
'type': 'object',
|
||||
'properties': {},
|
||||
'additionalProperties': True,
|
||||
}
|
||||
index_query_v2102 = copy.deepcopy(index_query)
|
||||
index_query_v2102['additionalProperties'] = False
|
||||
|
||||
# TODO(stephenfin): Remove additionalProperties in a future API version
|
||||
show_query = {
|
||||
'type': 'object',
|
||||
'properties': {},
|
||||
'additionalProperties': True,
|
||||
}
|
||||
show_query_v2102 = copy.deepcopy(show_query)
|
||||
show_query_v2102['additionalProperties'] = False
|
||||
|
||||
_aggregate_response = {
|
||||
'type': 'object',
|
||||
|
||||
@@ -65,8 +65,8 @@ delete_query = {
|
||||
'additionalProperties': True
|
||||
}
|
||||
|
||||
delete_query_275 = copy.deepcopy(delete_query)
|
||||
delete_query_275['additionalProperties'] = False
|
||||
delete_query_v275 = copy.deepcopy(delete_query)
|
||||
delete_query_v275['additionalProperties'] = False
|
||||
|
||||
create_response = {
|
||||
'type': 'object',
|
||||
|
||||
@@ -16,7 +16,6 @@ import copy
|
||||
|
||||
from nova.api.validation import parameter_types
|
||||
|
||||
|
||||
create = {
|
||||
'type': 'object',
|
||||
'properties': {
|
||||
@@ -50,20 +49,24 @@ create = {
|
||||
create_v249 = copy.deepcopy(create)
|
||||
create_v249['properties']['interfaceAttachment']['properties']['tag'] = parameter_types.tag # noqa: E501
|
||||
|
||||
# TODO(stephenfin): Remove additionalProperties in a future API version
|
||||
index_query = {
|
||||
'type': 'object',
|
||||
'properties': {},
|
||||
'additionalProperties': True,
|
||||
}
|
||||
|
||||
# TODO(stephenfin): Remove additionalProperties in a future API version
|
||||
index_query_v2102 = copy.deepcopy(index_query)
|
||||
index_query_v2102['additionalProperties'] = False
|
||||
|
||||
show_query = {
|
||||
'type': 'object',
|
||||
'properties': {},
|
||||
'additionalProperties': True,
|
||||
}
|
||||
|
||||
show_query_v2102 = copy.deepcopy(show_query)
|
||||
show_query_v2102['additionalProperties'] = False
|
||||
|
||||
_interface_attachment = {
|
||||
'type': 'object',
|
||||
'properties': {
|
||||
|
||||
@@ -14,15 +14,23 @@
|
||||
|
||||
import copy
|
||||
|
||||
|
||||
# TODO(stephenfin): Remove additionalProperties in a future API version
|
||||
index_query = {
|
||||
'type': 'object',
|
||||
'properties': {},
|
||||
'additionalProperties': True,
|
||||
}
|
||||
|
||||
detail_query = index_query
|
||||
index_query_v2102 = copy.deepcopy(index_query)
|
||||
index_query_v2102['additionalProperties'] = False
|
||||
|
||||
detail_query = {
|
||||
'type': 'object',
|
||||
'properties': {},
|
||||
'additionalProperties': True,
|
||||
}
|
||||
|
||||
detail_query_v2102 = copy.deepcopy(detail_query)
|
||||
detail_query_v2102['additionalProperties'] = False
|
||||
|
||||
index_response = {
|
||||
'type': 'object',
|
||||
|
||||
@@ -10,19 +10,23 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
# TODO(stephenfin): Remove additionalProperties in a future API version
|
||||
import copy
|
||||
|
||||
index_query = {
|
||||
'type': 'object',
|
||||
'properties': {},
|
||||
'additionalProperties': True,
|
||||
}
|
||||
index_query_v2102 = copy.deepcopy(index_query)
|
||||
index_query_v2102['additionalProperties'] = False
|
||||
|
||||
# TODO(stephenfin): Remove additionalProperties in a future API version
|
||||
show_query = {
|
||||
'type': 'object',
|
||||
'properties': {},
|
||||
'additionalProperties': True,
|
||||
}
|
||||
show_query_v2102 = copy.deepcopy(show_query)
|
||||
show_query_v2102['additionalProperties'] = False
|
||||
|
||||
_extension_obj = {
|
||||
'type': 'object',
|
||||
|
||||
@@ -16,7 +16,6 @@ import copy
|
||||
|
||||
from nova.api.validation import parameter_types
|
||||
|
||||
|
||||
add_tenant_access = {
|
||||
'type': 'object',
|
||||
'properties': {
|
||||
@@ -55,13 +54,15 @@ remove_tenant_access = {
|
||||
'additionalProperties': False,
|
||||
}
|
||||
|
||||
# TODO(stephenfin): Remove additionalProperties in a future API version
|
||||
index_query = {
|
||||
'type': 'object',
|
||||
'properties': {},
|
||||
'additionalProperties': True,
|
||||
}
|
||||
|
||||
index_query_v2102 = copy.deepcopy(index_query)
|
||||
index_query_v2102['additionalProperties'] = False
|
||||
|
||||
_common_response = {
|
||||
'type': 'object',
|
||||
'properties': {
|
||||
|
||||
@@ -144,13 +144,15 @@ index_query_v2102['properties']['name'] = parameter_types.multi_params(
|
||||
index_query_v2102['properties']['sort_key']['items']['enum'].remove(
|
||||
'rxtx_factor')
|
||||
|
||||
# TODO(stephenfin): Remove additionalProperties in a future API version
|
||||
show_query = {
|
||||
'type': 'object',
|
||||
'properties': {},
|
||||
'additionalProperties': True,
|
||||
}
|
||||
|
||||
show_query_v2102 = copy.deepcopy(show_query)
|
||||
show_query_v2102['additionalProperties'] = False
|
||||
|
||||
_flavor_basic = {
|
||||
'type': 'object',
|
||||
'properties': {
|
||||
|
||||
@@ -39,20 +39,24 @@ update.update({
|
||||
'maxProperties': 1
|
||||
})
|
||||
|
||||
# TODO(stephenfin): Remove additionalProperties in a future API version
|
||||
index_query = {
|
||||
'type': 'object',
|
||||
'properties': {},
|
||||
'additionalProperties': True,
|
||||
}
|
||||
|
||||
# TODO(stephenfin): Remove additionalProperties in a future API version
|
||||
index_query_v2102 = copy.deepcopy(index_query)
|
||||
index_query_v2102['additionalProperties'] = False
|
||||
|
||||
show_query = {
|
||||
'type': 'object',
|
||||
'properties': {},
|
||||
'additionalProperties': True,
|
||||
}
|
||||
|
||||
show_query_v2102 = copy.deepcopy(show_query)
|
||||
show_query_v2102['additionalProperties'] = False
|
||||
|
||||
index_response = {
|
||||
'type': 'object',
|
||||
'properties': {
|
||||
|
||||
@@ -10,13 +10,17 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
# TODO(stephenfin): Remove additionalProperties in a future API version
|
||||
import copy
|
||||
|
||||
index_query = {
|
||||
'type': 'object',
|
||||
'properties': {},
|
||||
'additionalProperties': True,
|
||||
}
|
||||
|
||||
index_query_v2102 = copy.deepcopy(index_query)
|
||||
index_query_v2102['additionalProperties'] = False
|
||||
|
||||
index_response = {
|
||||
'type': 'object',
|
||||
'properties': {
|
||||
|
||||
@@ -49,6 +49,9 @@ show_query = {
|
||||
'additionalProperties': True,
|
||||
}
|
||||
|
||||
show_query_v2102 = copy.deepcopy(show_query)
|
||||
show_query_v2102['additionalProperties'] = False
|
||||
|
||||
index_response = {
|
||||
'type': 'object',
|
||||
'properties': {
|
||||
|
||||
@@ -10,18 +10,26 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import copy
|
||||
|
||||
index_query = {
|
||||
'type': 'object',
|
||||
'properties': {},
|
||||
'additionalProperties': True,
|
||||
}
|
||||
|
||||
index_query_v2102 = copy.deepcopy(index_query)
|
||||
index_query_v2102['additionalProperties'] = False
|
||||
|
||||
show_query = {
|
||||
'type': 'object',
|
||||
'properties': {},
|
||||
'additionalProperties': True,
|
||||
}
|
||||
|
||||
show_query_v2102 = copy.deepcopy(show_query)
|
||||
show_query_v2102['additionalProperties'] = False
|
||||
|
||||
_instance_usage_audit_log_response = {
|
||||
'type': 'object',
|
||||
'properties': {
|
||||
|
||||
@@ -12,20 +12,24 @@
|
||||
|
||||
import copy
|
||||
|
||||
# TODO(stephenfin): Remove additionalProperties in a future API version
|
||||
index_query = {
|
||||
'type': 'object',
|
||||
'properties': {},
|
||||
'additionalProperties': True,
|
||||
}
|
||||
|
||||
# TODO(stephenfin): Remove additionalProperties in a future API version
|
||||
index_query_v2102 = copy.deepcopy(index_query)
|
||||
index_query_v2102['additionalProperties'] = False
|
||||
|
||||
show_query = {
|
||||
'type': 'object',
|
||||
'properties': {},
|
||||
'additionalProperties': True,
|
||||
}
|
||||
|
||||
show_query_v2102 = copy.deepcopy(show_query)
|
||||
show_query_v2102['additionalProperties'] = False
|
||||
|
||||
_ip_address = {
|
||||
'type': 'object',
|
||||
'properties': {
|
||||
|
||||
@@ -89,35 +89,33 @@ create_v292['properties']['keypair']['properties']['name'] = (
|
||||
parameter_types.keypair_name_special_chars_v292)
|
||||
create_v292['properties']['keypair']['required'] = ['name', 'public_key']
|
||||
|
||||
index_query_schema_v20 = {
|
||||
index_query_v20 = {
|
||||
'type': 'object',
|
||||
'properties': {},
|
||||
'additionalProperties': True
|
||||
}
|
||||
|
||||
index_query_schema_v210 = {
|
||||
index_query_v210 = {
|
||||
'type': 'object',
|
||||
'properties': {
|
||||
'user_id': parameter_types.multi_params({'type': 'string'})
|
||||
},
|
||||
'additionalProperties': True
|
||||
}
|
||||
|
||||
index_query_schema_v235 = copy.deepcopy(index_query_schema_v210)
|
||||
index_query_schema_v235['properties'].update(
|
||||
index_query_v235 = copy.deepcopy(index_query_v210)
|
||||
index_query_v235['properties'].update(
|
||||
parameter_types.pagination_parameters)
|
||||
index_query_v275 = copy.deepcopy(index_query_v235)
|
||||
index_query_v275['additionalProperties'] = False
|
||||
|
||||
show_query_schema_v20 = index_query_schema_v20
|
||||
show_query_schema_v210 = index_query_schema_v210
|
||||
delete_query_schema_v20 = index_query_schema_v20
|
||||
delete_query_schema_v210 = index_query_schema_v210
|
||||
show_query_v20 = index_query_v20
|
||||
show_query_v210 = index_query_v210
|
||||
show_query_v275 = copy.deepcopy(show_query_v210)
|
||||
show_query_v275['additionalProperties'] = False
|
||||
|
||||
index_query_schema_v275 = copy.deepcopy(index_query_schema_v235)
|
||||
index_query_schema_v275['additionalProperties'] = False
|
||||
show_query_schema_v275 = copy.deepcopy(show_query_schema_v210)
|
||||
show_query_schema_v275['additionalProperties'] = False
|
||||
delete_query_schema_v275 = copy.deepcopy(delete_query_schema_v210)
|
||||
delete_query_schema_v275['additionalProperties'] = False
|
||||
delete_query_v20 = index_query_v20
|
||||
delete_query_v210 = index_query_v210
|
||||
delete_query_v275 = copy.deepcopy(delete_query_v210)
|
||||
delete_query_v275['additionalProperties'] = False
|
||||
|
||||
create_response = {
|
||||
'type': 'object',
|
||||
|
||||
@@ -17,7 +17,6 @@ import copy
|
||||
from nova.api.validation import parameter_types
|
||||
from nova.api.validation import response_types
|
||||
|
||||
|
||||
index_query_v20 = {
|
||||
'type': 'object',
|
||||
'properties': {
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
# 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 nova.api.openstack.compute.schemas import quota_sets
|
||||
@@ -45,13 +46,15 @@ del update_v257['properties']['quota_class_set']['properties'][
|
||||
del update_v257['properties']['quota_class_set']['properties'][
|
||||
'injected_file_path_bytes']
|
||||
|
||||
# TODO(stephenfin): Remove additionalProperties in a future API version
|
||||
show_query = {
|
||||
'type': 'object',
|
||||
'properties': {},
|
||||
'additionalProperties': True,
|
||||
}
|
||||
|
||||
show_query_v2102 = copy.deepcopy(show_query)
|
||||
show_query_v2102['additionalProperties'] = False
|
||||
|
||||
_quota_response = {
|
||||
'type': 'object',
|
||||
'properties': {
|
||||
|
||||
@@ -101,15 +101,17 @@ detail_query_v275 = copy.deepcopy(show_query_v275)
|
||||
update_query = copy.deepcopy(show_query)
|
||||
update_query_v275 = copy.deepcopy(show_query_v275)
|
||||
|
||||
# TODO(stephenfin): Remove additionalProperties in a future API version
|
||||
delete_query = copy.deepcopy(show_query)
|
||||
delete_query_v275 = copy.deepcopy(show_query_v275)
|
||||
|
||||
defaults_query = {
|
||||
'type': 'object',
|
||||
'properties': {},
|
||||
'additionalProperties': True,
|
||||
}
|
||||
|
||||
delete_query = copy.deepcopy(show_query)
|
||||
delete_query_v275 = copy.deepcopy(show_query_v275)
|
||||
defaults_query_v2102 = copy.deepcopy(defaults_query)
|
||||
defaults_query_v2102['additionalProperties'] = False
|
||||
|
||||
_quota_response = {
|
||||
'type': 'object',
|
||||
|
||||
@@ -94,13 +94,15 @@ index_query = {
|
||||
'additionalProperties': True
|
||||
}
|
||||
|
||||
# TODO(stephenfin): Remove additionalProperties in a future API version
|
||||
index_server_query = {
|
||||
'type': 'object',
|
||||
'properties': {},
|
||||
'additionalProperties': True,
|
||||
}
|
||||
|
||||
index_server_query_v2102 = copy.deepcopy(index_server_query)
|
||||
index_server_query_v2102['additionalProperties'] = False
|
||||
|
||||
# TODO(stephenfin): Remove additionalProperties in a future API version
|
||||
add_security_group = {
|
||||
'type': 'object',
|
||||
|
||||
@@ -10,12 +10,15 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
# TODO(stephenfin): Remove additionalProperties in a future API version
|
||||
import copy
|
||||
|
||||
index_query = {
|
||||
'type': 'object',
|
||||
'properties': {},
|
||||
'additionalProperties': True,
|
||||
}
|
||||
index_query_v2102 = copy.deepcopy(index_query)
|
||||
index_query_v2102['additionalProperties'] = False
|
||||
|
||||
# NOTE(stephenfin): We could define all available response types for the
|
||||
# various virt drivers, but we'd need to be able to do this (accurately) for
|
||||
|
||||
@@ -99,6 +99,9 @@ show_query = {
|
||||
'additionalProperties': True,
|
||||
}
|
||||
|
||||
show_query_v2102 = copy.deepcopy(show_query)
|
||||
show_query_v2102['additionalProperties'] = False
|
||||
|
||||
_server_group_response = {
|
||||
'type': 'object',
|
||||
'properties': {
|
||||
|
||||
@@ -51,20 +51,23 @@ update_all = {
|
||||
'additionalProperties': False,
|
||||
}
|
||||
|
||||
# TODO(stephenfin): Remove additionalProperties in a future API version
|
||||
index_query = {
|
||||
'type': 'object',
|
||||
'properties': {},
|
||||
'additionalProperties': True,
|
||||
}
|
||||
index_query_v2102 = copy.deepcopy(index_query)
|
||||
index_query_v2102['additionalProperties'] = False
|
||||
|
||||
# TODO(stephenfin): Remove additionalProperties in a future API version
|
||||
show_query = {
|
||||
'type': 'object',
|
||||
'properties': {},
|
||||
'additionalProperties': True,
|
||||
}
|
||||
|
||||
show_query_v2102 = copy.deepcopy(show_query)
|
||||
show_query_v2102['additionalProperties'] = False
|
||||
|
||||
index_response = {
|
||||
'type': 'object',
|
||||
'properties': {
|
||||
|
||||
@@ -17,6 +17,23 @@ import copy
|
||||
|
||||
from nova.api.validation import parameter_types
|
||||
|
||||
index_query = {
|
||||
'type': 'object',
|
||||
'properties': {},
|
||||
'additionalProperties': True,
|
||||
}
|
||||
|
||||
index_query_v2102 = copy.deepcopy(index_query)
|
||||
index_query_v2102['additionalProperties'] = False
|
||||
|
||||
show_query = {
|
||||
'type': 'object',
|
||||
'properties': {},
|
||||
'additionalProperties': True,
|
||||
}
|
||||
|
||||
show_query_v2102 = copy.deepcopy(show_query)
|
||||
show_query_v2102['additionalProperties'] = False
|
||||
|
||||
force_complete = {
|
||||
'type': 'object',
|
||||
@@ -29,20 +46,6 @@ force_complete = {
|
||||
'additionalProperties': False,
|
||||
}
|
||||
|
||||
# TODO(stephenfin): Remove additionalProperties in a future API version
|
||||
index_query = {
|
||||
'type': 'object',
|
||||
'properties': {},
|
||||
'additionalProperties': True,
|
||||
}
|
||||
|
||||
# TODO(stephenfin): Remove additionalProperties in a future API version
|
||||
show_query = {
|
||||
'type': 'object',
|
||||
'properties': {},
|
||||
'additionalProperties': True,
|
||||
}
|
||||
|
||||
force_complete_response = {
|
||||
'type': 'null',
|
||||
}
|
||||
|
||||
@@ -10,13 +10,17 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
# TODO(stephenfin): Remove additionalProperties in a future API version
|
||||
import copy
|
||||
|
||||
index_query = {
|
||||
'type': 'object',
|
||||
'properties': {},
|
||||
'additionalProperties': True,
|
||||
}
|
||||
|
||||
index_query_v2102 = copy.deepcopy(index_query)
|
||||
index_query_v2102['additionalProperties'] = False
|
||||
|
||||
index_response = {
|
||||
'type': 'object',
|
||||
'properties': {
|
||||
|
||||
@@ -10,6 +10,8 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import copy
|
||||
|
||||
from nova.api.validation import parameter_types
|
||||
from nova.objects import instance
|
||||
|
||||
@@ -32,20 +34,24 @@ update = {
|
||||
"type": "null",
|
||||
}
|
||||
|
||||
# TODO(stephenfin): Remove additionalProperties in a future API version
|
||||
index_query = {
|
||||
'type': 'object',
|
||||
'properties': {},
|
||||
'additionalProperties': True,
|
||||
}
|
||||
|
||||
# TODO(stephenfin): Remove additionalProperties in a future API version
|
||||
index_query_v2102 = copy.deepcopy(index_query)
|
||||
index_query_v2102['additionalProperties'] = False
|
||||
|
||||
show_query = {
|
||||
'type': 'object',
|
||||
'properties': {},
|
||||
'additionalProperties': True,
|
||||
}
|
||||
|
||||
show_query_v2102 = copy.deepcopy(show_query)
|
||||
show_query_v2102['additionalProperties'] = False
|
||||
|
||||
show_response = {'type': 'null'}
|
||||
|
||||
index_response = {
|
||||
|
||||
@@ -10,12 +10,15 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
# TODO(stephenfin): Remove additionalProperties in a future API version
|
||||
query_params_v21 = {
|
||||
import copy
|
||||
|
||||
index_query = {
|
||||
'type': 'object',
|
||||
'properties': {},
|
||||
'additionalProperties': True,
|
||||
}
|
||||
index_query_v2102 = copy.deepcopy(index_query)
|
||||
index_query_v2102['additionalProperties'] = False
|
||||
|
||||
index_response = {
|
||||
'type': 'object',
|
||||
|
||||
@@ -619,7 +619,7 @@ VALID_SORT_KEYS_V275['enum'] = list(
|
||||
set(VALID_SORT_KEYS_V273["enum"]) - set(SERVER_LIST_IGNORE_SORT_KEY_V273)
|
||||
)
|
||||
|
||||
query_params_v21 = {
|
||||
index_query = {
|
||||
'type': 'object',
|
||||
'properties': {
|
||||
'user_id': parameter_types.common_query_param,
|
||||
@@ -692,38 +692,38 @@ query_params_v21 = {
|
||||
# Update the joined-table fields to the list so it will not be
|
||||
# stripped in later process, thus can be handled later in api
|
||||
# to raise HTTP 400.
|
||||
query_params_v21['properties'].update(
|
||||
index_query['properties'].update(
|
||||
JOINED_TABLE_QUERY_PARAMS_SERVERS)
|
||||
|
||||
query_params_v21['properties'].update(
|
||||
index_query['properties'].update(
|
||||
parameter_types.pagination_parameters)
|
||||
|
||||
query_params_v226 = copy.deepcopy(query_params_v21)
|
||||
query_params_v226['properties'].update({
|
||||
index_query_v226 = copy.deepcopy(index_query)
|
||||
index_query_v226['properties'].update({
|
||||
'tags': parameter_types.common_query_regex_param,
|
||||
'tags-any': parameter_types.common_query_regex_param,
|
||||
'not-tags': parameter_types.common_query_regex_param,
|
||||
'not-tags-any': parameter_types.common_query_regex_param,
|
||||
})
|
||||
|
||||
query_params_v266 = copy.deepcopy(query_params_v226)
|
||||
query_params_v266['properties'].update({
|
||||
index_query_v266 = copy.deepcopy(index_query_v226)
|
||||
index_query_v266['properties'].update({
|
||||
'changes-before': parameter_types.multi_params(
|
||||
{'type': 'string', 'format': 'date-time'}
|
||||
),
|
||||
})
|
||||
|
||||
query_params_v273 = copy.deepcopy(query_params_v266)
|
||||
query_params_v273['properties'].update({
|
||||
index_query_v273 = copy.deepcopy(index_query_v266)
|
||||
index_query_v273['properties'].update({
|
||||
'sort_key': parameter_types.multi_params(VALID_SORT_KEYS_V273),
|
||||
'locked': parameter_types.common_query_param,
|
||||
})
|
||||
|
||||
query_params_v275 = copy.deepcopy(query_params_v273)
|
||||
query_params_v275['properties'].update({
|
||||
index_query_v275 = copy.deepcopy(index_query_v273)
|
||||
index_query_v275['properties'].update({
|
||||
'sort_key': parameter_types.multi_params(VALID_SORT_KEYS_V275),
|
||||
})
|
||||
query_params_v275['additionalProperties'] = False
|
||||
index_query_v275['additionalProperties'] = False
|
||||
|
||||
show_query = {
|
||||
'type': 'object',
|
||||
@@ -731,6 +731,9 @@ show_query = {
|
||||
'additionalProperties': True,
|
||||
}
|
||||
|
||||
show_query_v2102 = copy.deepcopy(show_query)
|
||||
show_query_v2102['additionalProperties'] = False
|
||||
|
||||
_server_status = {
|
||||
'type': 'string',
|
||||
'enum': [
|
||||
|
||||
@@ -68,7 +68,6 @@ update_v253 = {
|
||||
'additionalProperties': False
|
||||
}
|
||||
|
||||
|
||||
index_query = {
|
||||
'type': 'object',
|
||||
'properties': {
|
||||
|
||||
@@ -12,6 +12,8 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import copy
|
||||
|
||||
from nova.api.validation import parameter_types
|
||||
|
||||
create = {
|
||||
@@ -52,6 +54,9 @@ show_query = {
|
||||
'additionalProperties': True
|
||||
}
|
||||
|
||||
show_query_v2102 = copy.deepcopy(show_query)
|
||||
show_query_v2102['additionalProperties'] = False
|
||||
|
||||
_snapshot_response = {
|
||||
'type': 'object',
|
||||
'properties': {
|
||||
|
||||
@@ -10,14 +10,15 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
# TODO(stephenfin): Remove additionalProperties in a future API version
|
||||
# NOTE(stephenfin): We would like to change additionalProperties to false, but
|
||||
# these APIs are unversioned so we can't
|
||||
|
||||
show_query = {
|
||||
'type': 'object',
|
||||
'properties': {},
|
||||
'additionalProperties': True,
|
||||
}
|
||||
|
||||
# TODO(stephenfin): Remove additionalProperties in a future API version
|
||||
multi_query = {
|
||||
'type': 'object',
|
||||
'properties': {},
|
||||
|
||||
@@ -14,6 +14,33 @@ import copy
|
||||
|
||||
from nova.api.validation import parameter_types
|
||||
|
||||
index_query = {
|
||||
'type': 'object',
|
||||
'properties': {
|
||||
'limit': parameter_types.multi_params(
|
||||
parameter_types.non_negative_integer),
|
||||
'offset': parameter_types.multi_params(
|
||||
parameter_types.non_negative_integer)
|
||||
},
|
||||
# NOTE(gmann): This is kept True to keep backward compatibility.
|
||||
# As of now Schema validation stripped out the additional parameters and
|
||||
# does not raise 400. In microversion 2.75, we have blocked the additional
|
||||
# parameters.
|
||||
'additionalProperties': True
|
||||
}
|
||||
|
||||
index_query_v275 = copy.deepcopy(index_query)
|
||||
index_query_v275['additionalProperties'] = False
|
||||
|
||||
show_query = {
|
||||
'type': 'object',
|
||||
'properties': {},
|
||||
'additionalProperties': True,
|
||||
}
|
||||
|
||||
show_query_v2102 = copy.deepcopy(show_query)
|
||||
show_query_v2102['additionalProperties'] = False
|
||||
|
||||
create = {
|
||||
'type': 'object',
|
||||
'properties': {
|
||||
@@ -76,31 +103,6 @@ update_v285 = {
|
||||
'additionalProperties': False,
|
||||
}
|
||||
|
||||
index_query = {
|
||||
'type': 'object',
|
||||
'properties': {
|
||||
'limit': parameter_types.multi_params(
|
||||
parameter_types.non_negative_integer),
|
||||
'offset': parameter_types.multi_params(
|
||||
parameter_types.non_negative_integer)
|
||||
},
|
||||
# NOTE(gmann): This is kept True to keep backward compatibility.
|
||||
# As of now Schema validation stripped out the additional parameters and
|
||||
# does not raise 400. In microversion 2.75, we have blocked the additional
|
||||
# parameters.
|
||||
'additionalProperties': True
|
||||
}
|
||||
|
||||
index_query_v275 = copy.deepcopy(index_query)
|
||||
index_query_v275['additionalProperties'] = False
|
||||
|
||||
# TODO(stephenfin): Remove additionalProperties in a future API version
|
||||
show_query = {
|
||||
'type': 'object',
|
||||
'properties': {},
|
||||
'additionalProperties': True,
|
||||
}
|
||||
|
||||
_volume_attachment_response = {
|
||||
'type': 'object',
|
||||
'properties': {
|
||||
|
||||
@@ -12,6 +12,8 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import copy
|
||||
|
||||
from nova.api.validation import parameter_types
|
||||
from nova.api.validation import response_types
|
||||
|
||||
@@ -58,14 +60,23 @@ index_query = {
|
||||
'additionalProperties': True
|
||||
}
|
||||
|
||||
index_query_v275 = copy.deepcopy(index_query)
|
||||
index_query_v275['additionalProperties'] = False
|
||||
|
||||
detail_query = index_query
|
||||
|
||||
detail_query_v2102 = copy.deepcopy(detail_query)
|
||||
detail_query_v2102['additionalProperties'] = False
|
||||
|
||||
show_query = {
|
||||
'type': 'object',
|
||||
'properties': {},
|
||||
'additionalProperties': True
|
||||
}
|
||||
|
||||
show_query_v2102 = copy.deepcopy(show_query)
|
||||
show_query_v2102['additionalProperties'] = False
|
||||
|
||||
_volume_response = {
|
||||
'type': 'object',
|
||||
'properties': {
|
||||
|
||||
@@ -366,7 +366,8 @@ class ServerSecurityGroupController(
|
||||
):
|
||||
|
||||
@wsgi.expected_errors(404)
|
||||
@validation.query_schema(schema.index_server_query)
|
||||
@validation.query_schema(schema.index_server_query, '2.1', '2.101')
|
||||
@validation.query_schema(schema.index_server_query_v2102, '2.102')
|
||||
@validation.response_body_schema(schema.index_server_response)
|
||||
def index(self, req, server_id):
|
||||
"""Returns a list of security groups for the given instance."""
|
||||
|
||||
@@ -35,7 +35,8 @@ class ServerDiagnosticsController(wsgi.Controller):
|
||||
self.compute_api = compute.API()
|
||||
|
||||
@wsgi.expected_errors((400, 404, 409, 501))
|
||||
@validation.query_schema(schema.index_query)
|
||||
@validation.query_schema(schema.index_query, '2.1', '2.101')
|
||||
@validation.query_schema(schema.index_query_v2102, '2.102')
|
||||
@validation.response_body_schema(schema.index_response, '2.1', '2.47')
|
||||
@validation.response_body_schema(schema.index_response_v248, '2.48')
|
||||
def index(self, req, server_id):
|
||||
|
||||
@@ -131,7 +131,8 @@ class ServerGroupController(wsgi.Controller):
|
||||
return server_group
|
||||
|
||||
@wsgi.expected_errors(404)
|
||||
@validation.query_schema(schema.show_query)
|
||||
@validation.query_schema(schema.show_query, '2.1', '2.101')
|
||||
@validation.query_schema(schema.show_query_v2102, '2.102')
|
||||
@validation.response_body_schema(schema.show_response, '2.1', '2.12')
|
||||
@validation.response_body_schema(schema.show_response_v213, '2.13', '2.14')
|
||||
@validation.response_body_schema(schema.show_response_v215, '2.15', '2.63')
|
||||
|
||||
@@ -49,7 +49,8 @@ class ServerMetadataController(wsgi.Controller):
|
||||
return meta_dict
|
||||
|
||||
@wsgi.expected_errors(404)
|
||||
@validation.query_schema(schema.index_query)
|
||||
@validation.query_schema(schema.index_query, '2.1', '2.101')
|
||||
@validation.query_schema(schema.index_query_v2102, '2.102')
|
||||
@validation.response_body_schema(schema.index_response)
|
||||
def index(self, req, server_id):
|
||||
"""Returns the list of metadata for a given instance."""
|
||||
@@ -126,7 +127,8 @@ class ServerMetadataController(wsgi.Controller):
|
||||
state_error, 'update metadata', server.uuid)
|
||||
|
||||
@wsgi.expected_errors(404)
|
||||
@validation.query_schema(schema.show_query)
|
||||
@validation.query_schema(schema.show_query, '2.1', '2.101')
|
||||
@validation.query_schema(schema.show_query_v2102, '2.102')
|
||||
@validation.response_body_schema(schema.show_response)
|
||||
def show(self, req, server_id, id):
|
||||
"""Return a single metadata item."""
|
||||
|
||||
@@ -119,7 +119,8 @@ class ServerMigrationsController(wsgi.Controller):
|
||||
|
||||
@wsgi.api_version("2.23")
|
||||
@wsgi.expected_errors(404)
|
||||
@validation.query_schema(schema.index_query)
|
||||
@validation.query_schema(schema.index_query, '2.23', '2.101')
|
||||
@validation.query_schema(schema.index_query_v2102, '2.102')
|
||||
@validation.response_body_schema(schema.index_response_v223, '2.23', '2.58') # noqa: E501
|
||||
@validation.response_body_schema(schema.index_response_v259, '2.59', '2.79') # noqa: E501
|
||||
@validation.response_body_schema(schema.index_response_v280, '2.80')
|
||||
@@ -148,7 +149,8 @@ class ServerMigrationsController(wsgi.Controller):
|
||||
|
||||
@wsgi.api_version("2.23")
|
||||
@wsgi.expected_errors(404)
|
||||
@validation.query_schema(schema.show_query)
|
||||
@validation.query_schema(schema.show_query, '2.23', '2.101')
|
||||
@validation.query_schema(schema.show_query_v2102, '2.102')
|
||||
@validation.response_body_schema(schema.show_response_v223, '2.23', '2.58')
|
||||
@validation.response_body_schema(schema.show_response_v259, '2.59', '2.79') # noqa: E501
|
||||
@validation.response_body_schema(schema.show_response_v280, '2.80')
|
||||
|
||||
@@ -33,7 +33,8 @@ class ServerPasswordController(wsgi.Controller):
|
||||
self.compute_api = compute.API()
|
||||
|
||||
@wsgi.expected_errors(404)
|
||||
@validation.query_schema(schema.index_query)
|
||||
@validation.query_schema(schema.index_query, '2.1', '2.101')
|
||||
@validation.query_schema(schema.index_query_v2102, '2.102')
|
||||
@validation.response_body_schema(schema.index_response)
|
||||
def index(self, req, server_id):
|
||||
context = req.environ['nova.context']
|
||||
|
||||
@@ -28,7 +28,8 @@ class ServerTopologyController(wsgi.Controller):
|
||||
|
||||
@wsgi.api_version("2.78")
|
||||
@wsgi.expected_errors(404)
|
||||
@validation.query_schema(schema.query_params_v21)
|
||||
@validation.query_schema(schema.index_query, '2.78', '2.101')
|
||||
@validation.query_schema(schema.index_query_v2102, '2.102')
|
||||
@validation.response_body_schema(schema.index_response)
|
||||
def index(self, req, server_id):
|
||||
context = req.environ["nova.context"]
|
||||
|
||||
@@ -114,11 +114,11 @@ class ServersController(wsgi.Controller):
|
||||
self.compute_api = compute.API()
|
||||
|
||||
@wsgi.expected_errors((400, 403))
|
||||
@validation.query_schema(schema.query_params_v21, '2.1', '2.25')
|
||||
@validation.query_schema(schema.query_params_v226, '2.26', '2.65')
|
||||
@validation.query_schema(schema.query_params_v266, '2.66', '2.72')
|
||||
@validation.query_schema(schema.query_params_v273, '2.73', '2.74')
|
||||
@validation.query_schema(schema.query_params_v275, '2.75')
|
||||
@validation.query_schema(schema.index_query, '2.1', '2.25')
|
||||
@validation.query_schema(schema.index_query_v226, '2.26', '2.65')
|
||||
@validation.query_schema(schema.index_query_v266, '2.66', '2.72')
|
||||
@validation.query_schema(schema.index_query_v273, '2.73', '2.74')
|
||||
@validation.query_schema(schema.index_query_v275, '2.75')
|
||||
@validation.response_body_schema(schema.index_response, '2.1', '2.68')
|
||||
@validation.response_body_schema(schema.index_response_v269, '2.69')
|
||||
def index(self, req):
|
||||
@@ -132,11 +132,11 @@ class ServersController(wsgi.Controller):
|
||||
return servers
|
||||
|
||||
@wsgi.expected_errors((400, 403))
|
||||
@validation.query_schema(schema.query_params_v21, '2.1', '2.25')
|
||||
@validation.query_schema(schema.query_params_v226, '2.26', '2.65')
|
||||
@validation.query_schema(schema.query_params_v266, '2.66', '2.72')
|
||||
@validation.query_schema(schema.query_params_v273, '2.73', '2.74')
|
||||
@validation.query_schema(schema.query_params_v275, '2.75')
|
||||
@validation.query_schema(schema.index_query, '2.1', '2.25')
|
||||
@validation.query_schema(schema.index_query_v226, '2.26', '2.65')
|
||||
@validation.query_schema(schema.index_query_v266, '2.66', '2.72')
|
||||
@validation.query_schema(schema.index_query_v273, '2.73', '2.74')
|
||||
@validation.query_schema(schema.index_query_v275, '2.75')
|
||||
@validation.response_body_schema(schema.detail_response, '2.1', '2.2')
|
||||
@validation.response_body_schema(schema.detail_response_v23, '2.3', '2.8')
|
||||
@validation.response_body_schema(schema.detail_response_v29, '2.9', '2.15')
|
||||
@@ -474,7 +474,8 @@ class ServersController(wsgi.Controller):
|
||||
return objects.NetworkRequestList(objects=networks)
|
||||
|
||||
@wsgi.expected_errors(404)
|
||||
@validation.query_schema(schema.show_query)
|
||||
@validation.query_schema(schema.show_query, '2.1', '2.101')
|
||||
@validation.query_schema(schema.show_query_v2102, '2.102')
|
||||
@validation.response_body_schema(schema.show_response, '2.0', '2.2')
|
||||
@validation.response_body_schema(schema.show_response_v23, '2.3', '2.8')
|
||||
@validation.response_body_schema(schema.show_response_v29, '2.9', '2.15')
|
||||
|
||||
@@ -106,17 +106,14 @@ class AggregateTestCaseV21(test.NoDBTestCase):
|
||||
set_metadata = 'self.controller._set_metadata'
|
||||
bad_request = exception.ValidationError
|
||||
|
||||
def _set_up(self):
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
self.controller = aggregates_v21.AggregateController()
|
||||
self.req = fakes.HTTPRequest.blank('/v2.1/os-aggregates',
|
||||
use_admin_context=True)
|
||||
self.user_req = fakes.HTTPRequest.blank('/v2.1/os-aggregates')
|
||||
self.context = self.req.environ['nova.context']
|
||||
|
||||
def setUp(self):
|
||||
super(AggregateTestCaseV21, self).setUp()
|
||||
self._set_up()
|
||||
|
||||
def test_index(self):
|
||||
def _list_aggregates(context):
|
||||
if context is None:
|
||||
@@ -130,6 +127,15 @@ class AggregateTestCaseV21(test.NoDBTestCase):
|
||||
self._assert_agg_data(AGGREGATE_LIST, _make_agg_list(result))
|
||||
self.assertTrue(mock_list.called)
|
||||
|
||||
def test_index_invalid_query_params(self):
|
||||
req = fakes.HTTPRequest.blank(
|
||||
'/v2/os-aggregates?unknown=1',
|
||||
use_admin_context=True,
|
||||
version='2.102')
|
||||
self.assertRaises(
|
||||
exception.ValidationError, self.controller.index, req
|
||||
)
|
||||
|
||||
def test_create(self):
|
||||
with mock.patch.object(self.controller.api, 'create_aggregate',
|
||||
return_value=AGGREGATE) as mock_create:
|
||||
@@ -293,6 +299,15 @@ class AggregateTestCaseV21(test.NoDBTestCase):
|
||||
self._assert_agg_data(AGGREGATE, _make_agg_obj(aggregate))
|
||||
mock_get.assert_called_once_with(self.context, '1')
|
||||
|
||||
def test_show_invalid_query_params(self):
|
||||
req = fakes.HTTPRequest.blank(
|
||||
'/v2/os-aggregates/1?unknown=1',
|
||||
use_admin_context=True,
|
||||
version='2.102')
|
||||
self.assertRaises(
|
||||
exception.ValidationError, self.controller.show, req, '1'
|
||||
)
|
||||
|
||||
def test_show_with_bad_aggregate(self):
|
||||
side_effect = exception.AggregateNotFound(aggregate_id='2')
|
||||
with mock.patch.object(self.controller.api, 'get_aggregate',
|
||||
|
||||
@@ -184,6 +184,29 @@ class InterfaceAttachTestsV21(test.NoDBTestCase):
|
||||
self.attachments.show, self.req, FAKE_UUID1,
|
||||
FAKE_PORT_ID1)
|
||||
|
||||
def test_show_invalid_query_params(self):
|
||||
req = fakes.HTTPRequest.blank(
|
||||
f'/servers/{FAKE_UUID1}/os-interface/{FAKE_PORT_ID1}?invalid=1',
|
||||
use_admin_context=True, version='2.102')
|
||||
self.assertRaises(
|
||||
exception.ValidationError,
|
||||
self.attachments.show,
|
||||
req,
|
||||
FAKE_UUID1,
|
||||
FAKE_PORT_ID1,
|
||||
)
|
||||
|
||||
def test_index_invalid_query_params(self):
|
||||
req = fakes.HTTPRequest.blank(
|
||||
f'/servers/{FAKE_UUID1}/os-interface?invalid=1',
|
||||
use_admin_context=True, version='2.102')
|
||||
self.assertRaises(
|
||||
exception.ValidationError,
|
||||
self.attachments.index,
|
||||
req,
|
||||
FAKE_UUID1,
|
||||
)
|
||||
|
||||
def test_delete(self):
|
||||
self.stub_out('nova.compute.api.API.detach_interface',
|
||||
fake_detach_interface)
|
||||
|
||||
@@ -128,6 +128,14 @@ class AvailabilityZoneApiTestV21(test.NoDBTestCase):
|
||||
self.assertFalse(zones[1]['zoneState']['available'])
|
||||
self.assertIsNone(zones[1]['hosts'])
|
||||
|
||||
def test_availability_zone_index_invalid_query_params(self):
|
||||
req = fakes.HTTPRequest.blank('?invalid=1', version='2.102')
|
||||
self.assertRaises(
|
||||
exception.ValidationError,
|
||||
self.controller.index,
|
||||
req,
|
||||
)
|
||||
|
||||
def test_availability_zone_detail(self):
|
||||
req = fakes.HTTPRequest.blank('')
|
||||
resp_dict = self.controller.detail(req)
|
||||
@@ -191,6 +199,14 @@ class AvailabilityZoneApiTestV21(test.NoDBTestCase):
|
||||
self.assertThat(resp_dict,
|
||||
matchers.DictMatches(expected_response))
|
||||
|
||||
def test_availability_zone_detail_invalid_query_params(self):
|
||||
req = fakes.HTTPRequest.blank('?invalid=1', version='2.102')
|
||||
self.assertRaises(
|
||||
exception.ValidationError,
|
||||
self.controller.index,
|
||||
req,
|
||||
)
|
||||
|
||||
|
||||
class ServersControllerCreateTestV21(test.TestCase):
|
||||
base_url = '/v2.1'
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
import webob
|
||||
|
||||
from nova.api.openstack.compute import extension_info
|
||||
from nova import exception
|
||||
from nova import test
|
||||
from nova.tests.unit.api.openstack import fakes
|
||||
|
||||
@@ -25,7 +26,24 @@ class ExtensionInfoV21Test(test.NoDBTestCase):
|
||||
super(ExtensionInfoV21Test, self).setUp()
|
||||
self.controller = extension_info.ExtensionInfoController()
|
||||
|
||||
def test_extension_info_show_servers_not_present(self):
|
||||
def test_extension_info_index_invalid_query_params(self):
|
||||
req = fakes.HTTPRequest.blank('?invalid=1', version='2.102')
|
||||
self.assertRaises(
|
||||
exception.ValidationError,
|
||||
self.controller.index,
|
||||
req,
|
||||
)
|
||||
|
||||
def test_extension_info_show_extension_not_present(self):
|
||||
req = fakes.HTTPRequest.blank('/extensions/servers')
|
||||
self.assertRaises(webob.exc.HTTPNotFound, self.controller.show,
|
||||
req, 'servers')
|
||||
|
||||
def test_extension_info_show_invalid_query_params(self):
|
||||
req = fakes.HTTPRequest.blank('?invalid=1', version='2.102')
|
||||
self.assertRaises(
|
||||
exception.ValidationError,
|
||||
self.controller.show,
|
||||
req,
|
||||
'servers',
|
||||
)
|
||||
|
||||
@@ -839,8 +839,7 @@ class FlavorsTestV275(FlavorsTestV261):
|
||||
@mock.patch('nova.objects.Flavor.get_by_flavor_id')
|
||||
def test_show_flavor_default_swap_value_old_version(self, mock_get):
|
||||
mock_get.return_value = self.FLAVOR_WITH_NO_SWAP
|
||||
req = fakes.HTTPRequestV21.blank(
|
||||
'/flavors/detail?limit=1', version='2.74')
|
||||
req = fakes.HTTPRequestV21.blank('/flavors/1', version='2.74')
|
||||
response = self.controller.show(req, 1)
|
||||
response_list = response["flavor"]
|
||||
self.assertEqual(response_list['swap'], "")
|
||||
@@ -859,7 +858,7 @@ class FlavorsTestV275(FlavorsTestV261):
|
||||
def test_show_flavor_default_swap_value(self, mock_get):
|
||||
mock_get.return_value = self.FLAVOR_WITH_NO_SWAP
|
||||
req = fakes.HTTPRequestV21.blank(
|
||||
'/flavors/detail?limit=1', version=self.microversion)
|
||||
'/flavors/1', version=self.microversion)
|
||||
response = self.controller.show(req, 1)
|
||||
response_list = response["flavor"]
|
||||
self.assertEqual(response_list['swap'], 0)
|
||||
@@ -943,6 +942,33 @@ class FlavorsTestV2102(FlavorsTestV275):
|
||||
self.omit_legacy_fields = False
|
||||
super().test_list_detail_flavors_with_additional_filter_old_version()
|
||||
|
||||
def test_list_flavor_invalid_query_params(self):
|
||||
req = fakes.HTTPRequest.blank(
|
||||
'/flavors?unknown=1',
|
||||
use_admin_context=True,
|
||||
version='2.102')
|
||||
self.assertRaises(
|
||||
exception.ValidationError, self.controller.index, req
|
||||
)
|
||||
|
||||
def test_detail_flavor_invalid_query_params(self):
|
||||
req = fakes.HTTPRequest.blank(
|
||||
'/flavors/detail?unknown=1',
|
||||
use_admin_context=True,
|
||||
version='2.102')
|
||||
self.assertRaises(
|
||||
exception.ValidationError, self.controller.detail, req
|
||||
)
|
||||
|
||||
def test_show_flavor_invalid_query_params(self):
|
||||
req = fakes.HTTPRequest.blank(
|
||||
'/flavors/123?unknown=1',
|
||||
use_admin_context=True,
|
||||
version='2.102')
|
||||
self.assertRaises(
|
||||
exception.ValidationError, self.controller.show, req, '123'
|
||||
)
|
||||
|
||||
|
||||
class DisabledFlavorsWithRealDBTestV21(test.TestCase):
|
||||
"""Tests that disabled flavors should not be shown nor listed."""
|
||||
|
||||
@@ -8,4 +8,6 @@ features:
|
||||
|
||||
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.
|
||||
field can no longer be provided when creating a server. Finally, all APIs
|
||||
now reject unknown query string parameters with a HTTP 400 (Bad Request)
|
||||
error, building upon work first started in microversion 2.75.
|
||||
|
||||
Reference in New Issue
Block a user