Fix get information about multiple VNF instances
When getting information about multiple VNF instances with invalid attribute selector or invalid attribute-based filtering parameters, tacker return a response with HTTP Code 200 and all information about VNF instances. However, according to the specification file, the HTTP code 400 Bad Request shall be returned. To fix this bug, this patch adds a new check for this api`s parameters. If it contains unsupported parameters, the HTTP code 400 Bad Request will be returned. Closes-Bug: #1938108 Change-Id: I3cca6d6fa664dd8f88791516042892369e4972a2
This commit is contained in:
parent
ef982945d9
commit
3bb8791f18
@ -14,6 +14,7 @@
|
||||
# under the License.
|
||||
|
||||
from functools import cmp_to_key
|
||||
from functools import wraps
|
||||
import netaddr
|
||||
from oslo_config import cfg
|
||||
import oslo_i18n
|
||||
@ -30,6 +31,30 @@ from tacker import wsgi
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def validate_supported_params(supported_params):
|
||||
"""Decorator for Restful API methods which specifies supported parameters.
|
||||
|
||||
If there are unsupported parameters in the request parameters, the http
|
||||
code 400 Bad Request will be returned and the user will be told which
|
||||
parameters in the request are not supported.
|
||||
"""
|
||||
def decorator(f):
|
||||
@wraps(f)
|
||||
def wrapped(*args, **kwargs):
|
||||
request = kwargs.get('request')
|
||||
if not request:
|
||||
request = args[1]
|
||||
params = set(request.params.keys())
|
||||
unsupported_params = params - supported_params
|
||||
if unsupported_params:
|
||||
msg = _("Not supported parameters: %s") \
|
||||
% ','.join(unsupported_params)
|
||||
raise exc.HTTPBadRequest(explanation=msg)
|
||||
return f(*args, **kwargs)
|
||||
return wrapped
|
||||
return decorator
|
||||
|
||||
|
||||
def get_filters(request, attr_info, skips=None):
|
||||
"""Extract the filters from the request string.
|
||||
|
||||
|
@ -39,6 +39,7 @@ from http import client as http_client
|
||||
from urllib import parse
|
||||
|
||||
from tacker._i18n import _
|
||||
from tacker.api import api_common
|
||||
from tacker.api.schemas import vnf_lcm
|
||||
from tacker.api import validation
|
||||
from tacker.api.views import vnf_lcm as vnf_lcm_view
|
||||
@ -562,7 +563,8 @@ class VnfLcmController(wsgi.Controller):
|
||||
return self._view_builder.show(vnf_instance)
|
||||
|
||||
@wsgi.response(http_client.OK)
|
||||
@wsgi.expected_errors((http_client.FORBIDDEN))
|
||||
@wsgi.expected_errors((http_client.FORBIDDEN, http_client.BAD_REQUEST))
|
||||
@api_common.validate_supported_params({'filter'})
|
||||
def index(self, request):
|
||||
context = request.environ['tacker.context']
|
||||
context.can(vnf_lcm_policies.VNFLCM % 'index')
|
||||
|
@ -2013,6 +2013,53 @@ class TestController(base.TestCase):
|
||||
self.assertRaises(exceptions.ValidationError,
|
||||
self.controller.index, req)
|
||||
|
||||
@mock.patch.object(objects.VnfInstanceList, "get_by_filters")
|
||||
@ddt.data(
|
||||
{'attribute_not_exist': 'some_value'},
|
||||
{'all_fields': {}},
|
||||
{'fields': {}},
|
||||
{'exclude_fields': {}},
|
||||
{'exclude_default': {}},
|
||||
{'nextpage_opaque_marker': 1},
|
||||
{'attribute_not_exist': 'some_value', 'filter': {}},
|
||||
{'attribute_not_exist': 'some_value', 'fields': {}}
|
||||
)
|
||||
def test_index_not_supported_params_1(self, params,
|
||||
mock_vnf_list):
|
||||
"""Test not supported params in request."""
|
||||
query = urllib.parse.urlencode(params)
|
||||
req = fake_request.HTTPRequest.blank(
|
||||
'/vnflcm/v1/vnf_instances?' + query)
|
||||
self.assertRaises(webob.exc.HTTPBadRequest,
|
||||
self.controller.index, req)
|
||||
|
||||
@mock.patch.object(objects.VnfInstanceList, "get_by_filters")
|
||||
@ddt.data(
|
||||
{'attribute_not_exist': 'some_value'},
|
||||
{'all_fields': {}},
|
||||
{'fields': {}},
|
||||
{'exclude_fields': {}},
|
||||
{'exclude_default': {}},
|
||||
{'nextpage_opaque_marker': 1},
|
||||
{'attribute_not_exist': 'some_value', 'filter': {}},
|
||||
{'attribute_not_exist': 'some_value', 'fields': {}}
|
||||
)
|
||||
def test_index_not_supported_params_2(self, params,
|
||||
mock_vnf_list):
|
||||
query = urllib.parse.urlencode(params)
|
||||
req = fake_request.HTTPRequest.blank(
|
||||
f'/vnf_instances?{query}')
|
||||
req.headers['Content-Type'] = 'application/json'
|
||||
req.method = 'GET'
|
||||
params = set(params)
|
||||
supported_params = {'filter'}
|
||||
unsupported_params = params - supported_params
|
||||
msg = _("Not supported parameters: %s") \
|
||||
% ','.join(unsupported_params)
|
||||
res = '{"title": "Bad Request", "status": 400, "detail": "%s"}' % msg
|
||||
resp = req.get_response(self.app)
|
||||
self.assertEqual(res, resp.text)
|
||||
|
||||
@mock.patch.object(TackerManager, 'get_service_plugins',
|
||||
return_value={'VNFM': FakeVNFMPlugin()})
|
||||
@mock.patch.object(objects.VnfLcmOpOcc, "get_by_id")
|
||||
|
Loading…
Reference in New Issue
Block a user