Validate swift params for swift type function creation
Check the swift related params before sending request to Swift. Change-Id: I29866eeb95f8b6e465d781ed02d2d499413dff54 Story: 2003482 Task: 24882
This commit is contained in:
parent
5f7ba972b6
commit
ffbd3ba111
|
@ -201,8 +201,15 @@ class FunctionsController(rest.RestController):
|
||||||
data = kwargs['package'].file.read()
|
data = kwargs['package'].file.read()
|
||||||
elif source == constants.SWIFT_FUNCTION:
|
elif source == constants.SWIFT_FUNCTION:
|
||||||
swift_info = values['code'].get('swift', {})
|
swift_info = values['code'].get('swift', {})
|
||||||
self._check_swift(swift_info.get('container'),
|
|
||||||
swift_info.get('object'))
|
if not (swift_info.get('container') and swift_info.get('object')):
|
||||||
|
raise exc.InputException("Both container and object must be "
|
||||||
|
"provided for swift type function.")
|
||||||
|
|
||||||
|
self._check_swift(
|
||||||
|
swift_info.get('container'),
|
||||||
|
swift_info.get('object')
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
create_trust = False
|
create_trust = False
|
||||||
values['entry'] = None
|
values['entry'] = None
|
||||||
|
@ -341,11 +348,15 @@ class FunctionsController(rest.RestController):
|
||||||
when function is updating.
|
when function is updating.
|
||||||
"""
|
"""
|
||||||
values = {}
|
values = {}
|
||||||
for key in UPDATE_ALLOWED:
|
|
||||||
if kwargs.get(key) is not None:
|
try:
|
||||||
if key == "code":
|
for key in UPDATE_ALLOWED:
|
||||||
kwargs[key] = json.loads(kwargs[key])
|
if kwargs.get(key) is not None:
|
||||||
values.update({key: kwargs[key]})
|
if key == "code":
|
||||||
|
kwargs[key] = json.loads(kwargs[key])
|
||||||
|
values.update({key: kwargs[key]})
|
||||||
|
except Exception as e:
|
||||||
|
raise exc.InputException("Invalid input, %s" % str(e))
|
||||||
|
|
||||||
LOG.info('Update function %s, params: %s', id, values)
|
LOG.info('Update function %s, params: %s', id, values)
|
||||||
ctx = context.get_ctx()
|
ctx = context.get_ctx()
|
||||||
|
@ -416,10 +427,29 @@ class FunctionsController(rest.RestController):
|
||||||
values.pop('package')
|
values.pop('package')
|
||||||
|
|
||||||
# Swift type function
|
# Swift type function
|
||||||
if pre_source == constants.SWIFT_FUNCTION:
|
if (pre_source == constants.SWIFT_FUNCTION and
|
||||||
swift_info = values['code'].get('swift', {})
|
"swift" in values.get('code', {})):
|
||||||
self._check_swift(swift_info.get('container'),
|
swift_info = values['code']["swift"]
|
||||||
swift_info.get('object'))
|
|
||||||
|
if not (swift_info.get('container') or
|
||||||
|
swift_info.get('object')):
|
||||||
|
raise exc.InputException(
|
||||||
|
"Either container or object must be provided for "
|
||||||
|
"swift type function update."
|
||||||
|
)
|
||||||
|
|
||||||
|
new_swift_info = pre_func.code['swift']
|
||||||
|
new_swift_info.update(swift_info)
|
||||||
|
|
||||||
|
self._check_swift(
|
||||||
|
new_swift_info.get('container'),
|
||||||
|
new_swift_info.get('object')
|
||||||
|
)
|
||||||
|
|
||||||
|
values['code'] = {
|
||||||
|
"source": pre_source,
|
||||||
|
"swift": new_swift_info
|
||||||
|
}
|
||||||
|
|
||||||
# Delete allocated resources in orchestrator and etcd.
|
# Delete allocated resources in orchestrator and etcd.
|
||||||
self.engine_client.delete_function(id)
|
self.engine_client.delete_function(id)
|
||||||
|
|
|
@ -102,6 +102,25 @@ class TestFunctionController(base.APITest):
|
||||||
)
|
)
|
||||||
self._assertDictContainsSubset(resp.json, body)
|
self._assertDictContainsSubset(resp.json, body)
|
||||||
|
|
||||||
|
def test_post_swift_not_enough_params(self):
|
||||||
|
body = {
|
||||||
|
'name': 'swift_function',
|
||||||
|
'code': json.dumps(
|
||||||
|
{
|
||||||
|
"source": "swift",
|
||||||
|
"swift": {"container": "fake-container"}
|
||||||
|
}
|
||||||
|
),
|
||||||
|
'runtime_id': self.runtime_id,
|
||||||
|
}
|
||||||
|
resp = self.app.post(
|
||||||
|
'/v1/functions',
|
||||||
|
params=body,
|
||||||
|
expect_errors=True
|
||||||
|
)
|
||||||
|
|
||||||
|
self.assertEqual(400, resp.status_int)
|
||||||
|
|
||||||
@mock.patch('qinling.utils.openstack.keystone.get_swiftclient')
|
@mock.patch('qinling.utils.openstack.keystone.get_swiftclient')
|
||||||
@mock.patch('qinling.context.AuthHook.before')
|
@mock.patch('qinling.context.AuthHook.before')
|
||||||
def test_post_swift_size_exceed(self, mock_auth, mock_client):
|
def test_post_swift_size_exceed(self, mock_auth, mock_client):
|
||||||
|
@ -242,6 +261,78 @@ class TestFunctionController(base.APITest):
|
||||||
|
|
||||||
self.assertEqual(400, resp.status_int)
|
self.assertEqual(400, resp.status_int)
|
||||||
|
|
||||||
|
@mock.patch('qinling.rpc.EngineClient.delete_function')
|
||||||
|
@mock.patch('qinling.utils.etcd_util.delete_function')
|
||||||
|
@mock.patch('qinling.utils.openstack.swift.check_object')
|
||||||
|
@mock.patch('qinling.context.AuthHook.before')
|
||||||
|
def test_put_swift_function(self, mock_auth, mock_check, mock_etcd_delete,
|
||||||
|
mock_func_delete):
|
||||||
|
self.override_config('auth_enable', True, group='pecan')
|
||||||
|
mock_check.return_value = True
|
||||||
|
|
||||||
|
db_func = self.create_function(
|
||||||
|
runtime_id=self.runtime_id,
|
||||||
|
code={
|
||||||
|
"source": "swift",
|
||||||
|
"swift": {"container": "fake-container", "object": "fake-obj"}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
body = {
|
||||||
|
'code': json.dumps(
|
||||||
|
{
|
||||||
|
"source": "swift",
|
||||||
|
"swift": {"object": "new-obj"}
|
||||||
|
}
|
||||||
|
),
|
||||||
|
}
|
||||||
|
resp = self.app.put_json('/v1/functions/%s' % db_func.id, body)
|
||||||
|
|
||||||
|
self.assertEqual(200, resp.status_int)
|
||||||
|
swift_info = {
|
||||||
|
'code': {
|
||||||
|
"source": "swift",
|
||||||
|
"swift": {"container": "fake-container", "object": "new-obj"}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
self._assertDictContainsSubset(resp.json, swift_info)
|
||||||
|
|
||||||
|
@mock.patch('qinling.rpc.EngineClient.delete_function')
|
||||||
|
@mock.patch('qinling.utils.etcd_util.delete_function')
|
||||||
|
@mock.patch('qinling.utils.openstack.swift.check_object')
|
||||||
|
@mock.patch('qinling.context.AuthHook.before')
|
||||||
|
def test_put_swift_function_without_source(self, mock_auth, mock_check,
|
||||||
|
mock_etcd_delete,
|
||||||
|
mock_func_delete):
|
||||||
|
self.override_config('auth_enable', True, group='pecan')
|
||||||
|
mock_check.return_value = True
|
||||||
|
|
||||||
|
db_func = self.create_function(
|
||||||
|
runtime_id=self.runtime_id,
|
||||||
|
code={
|
||||||
|
"source": "swift",
|
||||||
|
"swift": {"container": "fake-container", "object": "fake-obj"}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
body = {
|
||||||
|
'code': json.dumps(
|
||||||
|
{
|
||||||
|
"swift": {"object": "new-obj"}
|
||||||
|
}
|
||||||
|
),
|
||||||
|
}
|
||||||
|
resp = self.app.put_json('/v1/functions/%s' % db_func.id, body)
|
||||||
|
|
||||||
|
self.assertEqual(200, resp.status_int)
|
||||||
|
swift_info = {
|
||||||
|
'code': {
|
||||||
|
"source": "swift",
|
||||||
|
"swift": {"container": "fake-container", "object": "new-obj"}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
self._assertDictContainsSubset(resp.json, swift_info)
|
||||||
|
|
||||||
def test_put_cpu_with_type_error(self):
|
def test_put_cpu_with_type_error(self):
|
||||||
db_func = self.create_function(runtime_id=self.runtime_id)
|
db_func = self.create_function(runtime_id=self.runtime_id)
|
||||||
|
|
||||||
|
|
|
@ -182,7 +182,7 @@ class DbTestCase(BaseTest):
|
||||||
|
|
||||||
return runtime
|
return runtime
|
||||||
|
|
||||||
def create_function(self, runtime_id=None):
|
def create_function(self, runtime_id=None, code=None):
|
||||||
if not runtime_id:
|
if not runtime_id:
|
||||||
runtime_id = self.create_runtime().id
|
runtime_id = self.create_runtime().id
|
||||||
|
|
||||||
|
@ -190,7 +190,7 @@ class DbTestCase(BaseTest):
|
||||||
{
|
{
|
||||||
'name': self.rand_name('function', prefix=self.prefix),
|
'name': self.rand_name('function', prefix=self.prefix),
|
||||||
'runtime_id': runtime_id,
|
'runtime_id': runtime_id,
|
||||||
'code': {"source": "package", "md5sum": "fake_md5"},
|
'code': code or {"source": "package", "md5sum": "fake_md5"},
|
||||||
'entry': 'main.main',
|
'entry': 'main.main',
|
||||||
# 'auth_enable' is disabled by default, we create runtime for
|
# 'auth_enable' is disabled by default, we create runtime for
|
||||||
# default tenant.
|
# default tenant.
|
||||||
|
|
Loading…
Reference in New Issue