Merge "Add validation for podmanager API"
This commit is contained in:
commit
dea13b1036
@ -21,6 +21,7 @@ from six.moves import http_client
|
|||||||
from valence.common import exception
|
from valence.common import exception
|
||||||
from valence.common import utils
|
from valence.common import utils
|
||||||
from valence.controller import podmanagers
|
from valence.controller import podmanagers
|
||||||
|
from valence.validation import validator
|
||||||
|
|
||||||
|
|
||||||
LOG = logging.getLogger(__name__)
|
LOG = logging.getLogger(__name__)
|
||||||
@ -31,6 +32,7 @@ class PodManagersList(flask_restful.Resource):
|
|||||||
def get(self):
|
def get(self):
|
||||||
return utils.make_response(http_client.OK, podmanagers.get_podm_list())
|
return utils.make_response(http_client.OK, podmanagers.get_podm_list())
|
||||||
|
|
||||||
|
@validator.check_input('podmanager_schema')
|
||||||
def post(self):
|
def post(self):
|
||||||
values = flask.request.get_json()
|
values = flask.request.get_json()
|
||||||
return utils.make_response(http_client.OK,
|
return utils.make_response(http_client.OK,
|
||||||
|
@ -33,22 +33,6 @@ def _check_creation(values):
|
|||||||
:returns: improved values that could be inserted to db
|
:returns: improved values that could be inserted to db
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if not ('name' in values and
|
|
||||||
'url' in values and
|
|
||||||
'authentication' in values):
|
|
||||||
raise exception.BadRequest(detail="Incomplete parameters")
|
|
||||||
# check authentication's format and content
|
|
||||||
try:
|
|
||||||
if not (values['authentication'][0]['type'] and
|
|
||||||
values['authentication'][0]['auth_items']):
|
|
||||||
LOG.error("invalid authentication when creating podmanager")
|
|
||||||
raise exception.BadRequest(detail="invalid "
|
|
||||||
"authentication properties")
|
|
||||||
except KeyError:
|
|
||||||
LOG.error("Incomplete parameters when creating podmanager")
|
|
||||||
raise exception.BadRequest(detail="invalid "
|
|
||||||
"authentication properties")
|
|
||||||
|
|
||||||
pod_manager_list = get_podm_list()
|
pod_manager_list = get_podm_list()
|
||||||
names = [podm['name'] for podm in pod_manager_list]
|
names = [podm['name'] for podm in pod_manager_list]
|
||||||
urls = [podm['url'] for podm in pod_manager_list]
|
urls = [podm['url'] for podm in pod_manager_list]
|
||||||
|
@ -53,28 +53,6 @@ class TestPodManagers(unittest.TestCase):
|
|||||||
values['authentication'])
|
values['authentication'])
|
||||||
mock_get_podm_list.assert_called_once_with()
|
mock_get_podm_list.assert_called_once_with()
|
||||||
|
|
||||||
def test_check_creation_incomplete_parameters(self):
|
|
||||||
incomplete_values = {
|
|
||||||
'name': 'name',
|
|
||||||
'url': 'url'
|
|
||||||
}
|
|
||||||
self.assertRaises(BadRequest,
|
|
||||||
podmanagers._check_creation,
|
|
||||||
incomplete_values)
|
|
||||||
|
|
||||||
def test_check_creation_invalid_authentication(self):
|
|
||||||
invalid_authentication_values = {
|
|
||||||
"name": "podm_name",
|
|
||||||
"url": "https://10.0.0.2",
|
|
||||||
'authentication': {
|
|
||||||
"username": "username",
|
|
||||||
"password": "password"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
self.assertRaises(BadRequest,
|
|
||||||
podmanagers._check_creation,
|
|
||||||
invalid_authentication_values)
|
|
||||||
|
|
||||||
@mock.patch('valence.controller.podmanagers.get_podm_list')
|
@mock.patch('valence.controller.podmanagers.get_podm_list')
|
||||||
def test_check_creation_duplicate_Exception(self, mock_get_podm_list):
|
def test_check_creation_duplicate_Exception(self, mock_get_podm_list):
|
||||||
mock_get_podm_list.return_value = [
|
mock_get_podm_list.return_value = [
|
||||||
|
@ -1,9 +1,11 @@
|
|||||||
|
import copy
|
||||||
import json
|
import json
|
||||||
|
|
||||||
import mock
|
import mock
|
||||||
from oslotest import base
|
from oslotest import base
|
||||||
|
|
||||||
from valence.api import app as flask_app
|
from valence.api import app as flask_app
|
||||||
|
from valence.common import constants
|
||||||
from valence.tests.unit.fakes import flavor_fakes
|
from valence.tests.unit.fakes import flavor_fakes
|
||||||
|
|
||||||
|
|
||||||
@ -15,6 +17,11 @@ class TestApiValidation(base.BaseTestCase):
|
|||||||
app = flask_app.get_app()
|
app = flask_app.get_app()
|
||||||
app.config['TESTING'] = True
|
app.config['TESTING'] = True
|
||||||
self.app = app.test_client()
|
self.app = app.test_client()
|
||||||
|
|
||||||
|
|
||||||
|
class TestFlavorApi(TestApiValidation):
|
||||||
|
def setUp(self):
|
||||||
|
super(TestFlavorApi, self).setUp()
|
||||||
self.flavor = flavor_fakes.fake_flavor()
|
self.flavor = flavor_fakes.fake_flavor()
|
||||||
|
|
||||||
@mock.patch('valence.controller.flavors.create_flavor')
|
@mock.patch('valence.controller.flavors.create_flavor')
|
||||||
@ -48,3 +55,61 @@ class TestApiValidation(base.BaseTestCase):
|
|||||||
response = json.loads(response.data.decode())
|
response = json.loads(response.data.decode())
|
||||||
self.assertEqual(400, response['status'])
|
self.assertEqual(400, response['status'])
|
||||||
self.assertEqual('ValidationError', response['code'])
|
self.assertEqual('ValidationError', response['code'])
|
||||||
|
|
||||||
|
|
||||||
|
class TestPodmanagerApi(TestApiValidation):
|
||||||
|
|
||||||
|
@mock.patch('valence.controller.podmanagers.create_podm')
|
||||||
|
@mock.patch('valence.controller.podmanagers.get_podm_list')
|
||||||
|
@mock.patch('valence.controller.podmanagers.get_podm_status')
|
||||||
|
def test_podmanager_create(self, pstatus_mock, plist_mock, pcreate_mock):
|
||||||
|
pstatus_mock.return_value = constants.PODM_STATUS_ONLINE
|
||||||
|
plist_mock.return_value = []
|
||||||
|
values = {
|
||||||
|
"name": "podm_name",
|
||||||
|
"url": "https://10.240.212.123",
|
||||||
|
"authentication": [
|
||||||
|
{
|
||||||
|
"type": "basic",
|
||||||
|
"auth_items":
|
||||||
|
{
|
||||||
|
"username": "xxxxxxx",
|
||||||
|
"password": "xxxxxxx"
|
||||||
|
}
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
result = copy.deepcopy(values)
|
||||||
|
result['status'] = constants.PODM_STATUS_ONLINE
|
||||||
|
pcreate_mock.return_value = result
|
||||||
|
response = self.app.post('/v1/pod_managers',
|
||||||
|
content_type='application/json',
|
||||||
|
data=json.dumps(values))
|
||||||
|
self.assertEqual(200, response.status_code)
|
||||||
|
|
||||||
|
def test_check_creation_incomplete_parameters(self):
|
||||||
|
incomplete_values = {
|
||||||
|
'name': 'name',
|
||||||
|
'url': 'url'
|
||||||
|
}
|
||||||
|
response = self.app.post('/v1/pod_managers',
|
||||||
|
content_type='application/json',
|
||||||
|
data=json.dumps(incomplete_values))
|
||||||
|
response = json.loads(response.data.decode())
|
||||||
|
self.assertEqual(400, response['status'])
|
||||||
|
self.assertEqual('ValidationError', response['code'])
|
||||||
|
|
||||||
|
def test_check_creation_invalid_authentication(self):
|
||||||
|
invalid_auth_values = {
|
||||||
|
"name": "podm_name",
|
||||||
|
"url": "https://10.0.0.2",
|
||||||
|
'authentication': {
|
||||||
|
"username": "username",
|
||||||
|
"password": "password"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
response = self.app.post('/v1/pod_managers',
|
||||||
|
content_type='application/json',
|
||||||
|
data=json.dumps(invalid_auth_values))
|
||||||
|
response = json.loads(response.data.decode())
|
||||||
|
self.assertEqual(400, response['status'])
|
||||||
|
self.assertEqual('ValidationError', response['code'])
|
||||||
|
@ -32,6 +32,43 @@ flavor_schema = {
|
|||||||
'additionalProperties': False,
|
'additionalProperties': False,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
jsonschema.Draft4Validator.check_schema(flavor_schema)
|
jsonschema.Draft4Validator.check_schema(flavor_schema)
|
||||||
SCHEMAS = {'flavor_schema': flavor_schema}
|
|
||||||
|
podmanager_schema = {
|
||||||
|
'type': 'object',
|
||||||
|
'properties': {
|
||||||
|
'name': {'type': 'string'},
|
||||||
|
'url': {
|
||||||
|
'type': 'string',
|
||||||
|
'format': 'uri',
|
||||||
|
},
|
||||||
|
'authentication': {
|
||||||
|
'type': 'array',
|
||||||
|
'minItems': 1,
|
||||||
|
'items': {
|
||||||
|
'type': 'object',
|
||||||
|
'properties': {
|
||||||
|
'type': {'type': 'string'},
|
||||||
|
'auth_items': {
|
||||||
|
'type': 'object',
|
||||||
|
'properties': {
|
||||||
|
'username': {'type': 'string'},
|
||||||
|
'password': {'type': 'string'},
|
||||||
|
},
|
||||||
|
'required': ['username', 'password'],
|
||||||
|
'additionalProperties': False,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'required': ['type', 'auth_items'],
|
||||||
|
'additionalProperties': False,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'required': ['name', 'url', 'authentication'],
|
||||||
|
'additionalProperties': False,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
jsonschema.Draft4Validator.check_schema(podmanager_schema)
|
||||||
|
SCHEMAS = {'flavor_schema': flavor_schema,
|
||||||
|
'podmanager_schema': podmanager_schema, }
|
||||||
|
@ -49,5 +49,12 @@ class Validator(object):
|
|||||||
try:
|
try:
|
||||||
self.validator.validate(data)
|
self.validator.validate(data)
|
||||||
except jsonschema.ValidationError as e:
|
except jsonschema.ValidationError as e:
|
||||||
|
if len(e.path) > 0:
|
||||||
|
detail = (("Invalid input for field/attribute '%(path)s' "
|
||||||
|
"Value: '%(value)s'. %(message)s") %
|
||||||
|
{'path': e.path.pop(), 'value': e.instance,
|
||||||
|
'message': e.message})
|
||||||
|
else:
|
||||||
|
detail = e.message
|
||||||
LOG.exception("Failed to validate the input")
|
LOG.exception("Failed to validate the input")
|
||||||
raise exception.ValidationError(detail=e.message)
|
raise exception.ValidationError(detail=detail)
|
||||||
|
Loading…
Reference in New Issue
Block a user