summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTelles Nobrega <tenobreg@redhat.com>2018-12-06 16:42:55 -0300
committerTelles Nobrega <tellesnobrega@gmail.com>2019-01-09 15:52:22 -0300
commit7105a891c23ca066d87f68e07a7098ea692ca112 (patch)
tree447b05df432a28e981a1efe3f7c9bbc2695628b0
parentbe47e5c134c42a465ecf0143758017a3de9bcdfa (diff)
APIv2 - Fix 500 on malformed query string on
In order to improve return information to clients we are adding a check to verify parameters before each call and return a more appropriate message to the users. Change-Id: I9923601d0903e415a3fe30bec9bdc8fc34b91ff6 Story: #2004506 Task: #28228
Notes
Notes (review): Code-Review+2: Jeremy Freudberg <jeremyfreudberg@gmail.com> Code-Review+2: Luigi Toscano <ltoscano@redhat.com> Workflow+1: Luigi Toscano <ltoscano@redhat.com> Verified+2: Zuul Submitted-by: Zuul Submitted-at: Wed, 09 Jan 2019 22:20:40 +0000 Reviewed-on: https://review.openstack.org/623300 Project: openstack/sahara Branch: refs/heads/master
-rw-r--r--sahara/api/v2/cluster_templates.py6
-rw-r--r--sahara/api/v2/clusters.py6
-rw-r--r--sahara/api/v2/data_sources.py5
-rw-r--r--sahara/api/v2/images.py7
-rw-r--r--sahara/api/v2/job_binaries.py6
-rw-r--r--sahara/api/v2/job_templates.py6
-rw-r--r--sahara/api/v2/job_types.py2
-rw-r--r--sahara/api/v2/jobs.py5
-rw-r--r--sahara/api/v2/node_group_templates.py6
-rw-r--r--sahara/api/v2/plugins.py4
-rw-r--r--sahara/service/validation.py19
-rw-r--r--sahara/utils/api.py12
12 files changed, 84 insertions, 0 deletions
diff --git a/sahara/api/v2/cluster_templates.py b/sahara/api/v2/cluster_templates.py
index fd9f7d4..449a2cc 100644
--- a/sahara/api/v2/cluster_templates.py
+++ b/sahara/api/v2/cluster_templates.py
@@ -29,6 +29,7 @@ rest = u.RestV2('cluster-templates', __name__)
29@v.check_exists(api.get_cluster_template, 'marker') 29@v.check_exists(api.get_cluster_template, 'marker')
30@v.validate(None, v.validate_pagination_limit, 30@v.validate(None, v.validate_pagination_limit,
31 v.validate_sorting_cluster_templates) 31 v.validate_sorting_cluster_templates)
32@v.validate_request_params(['plugin_name', 'hadoop_version', 'name'])
32def cluster_templates_list(): 33def cluster_templates_list():
33 result = api.get_cluster_templates(**u.get_request_args().to_dict()) 34 result = api.get_cluster_templates(**u.get_request_args().to_dict())
34 for ct in result: 35 for ct in result:
@@ -40,6 +41,7 @@ def cluster_templates_list():
40@acl.enforce("data-processing:cluster-templates:create") 41@acl.enforce("data-processing:cluster-templates:create")
41@v.validate(ct_schema.CLUSTER_TEMPLATE_SCHEMA_V2, 42@v.validate(ct_schema.CLUSTER_TEMPLATE_SCHEMA_V2,
42 v_ct.check_cluster_template_create) 43 v_ct.check_cluster_template_create)
44@v.validate_request_params([])
43def cluster_templates_create(data): 45def cluster_templates_create(data):
44 # renaming hadoop_version -> plugin_version 46 # renaming hadoop_version -> plugin_version
45 # this can be removed once APIv1 is deprecated 47 # this can be removed once APIv1 is deprecated
@@ -53,6 +55,7 @@ def cluster_templates_create(data):
53@rest.get('/cluster-templates/<cluster_template_id>') 55@rest.get('/cluster-templates/<cluster_template_id>')
54@acl.enforce("data-processing:cluster-templates:get") 56@acl.enforce("data-processing:cluster-templates:get")
55@v.check_exists(api.get_cluster_template, 'cluster_template_id') 57@v.check_exists(api.get_cluster_template, 'cluster_template_id')
58@v.validate_request_params([])
56def cluster_templates_get(cluster_template_id): 59def cluster_templates_get(cluster_template_id):
57 result = u.to_wrapped_dict_no_render( 60 result = u.to_wrapped_dict_no_render(
58 api.get_cluster_template, cluster_template_id) 61 api.get_cluster_template, cluster_template_id)
@@ -65,6 +68,7 @@ def cluster_templates_get(cluster_template_id):
65@v.check_exists(api.get_cluster_template, 'cluster_template_id') 68@v.check_exists(api.get_cluster_template, 'cluster_template_id')
66@v.validate(ct_schema.CLUSTER_TEMPLATE_UPDATE_SCHEMA_V2, 69@v.validate(ct_schema.CLUSTER_TEMPLATE_UPDATE_SCHEMA_V2,
67 v_ct.check_cluster_template_update) 70 v_ct.check_cluster_template_update)
71@v.validate_request_params([])
68def cluster_templates_update(cluster_template_id, data): 72def cluster_templates_update(cluster_template_id, data):
69 if data.get('plugin_version', None): 73 if data.get('plugin_version', None):
70 data['hadoop_version'] = data['plugin_version'] 74 data['hadoop_version'] = data['plugin_version']
@@ -79,6 +83,7 @@ def cluster_templates_update(cluster_template_id, data):
79@acl.enforce("data-processing:cluster-templates:delete") 83@acl.enforce("data-processing:cluster-templates:delete")
80@v.check_exists(api.get_cluster_template, 'cluster_template_id') 84@v.check_exists(api.get_cluster_template, 'cluster_template_id')
81@v.validate(None, v_ct.check_cluster_template_usage) 85@v.validate(None, v_ct.check_cluster_template_usage)
86@v.validate_request_params([])
82def cluster_templates_delete(cluster_template_id): 87def cluster_templates_delete(cluster_template_id):
83 api.terminate_cluster_template(cluster_template_id) 88 api.terminate_cluster_template(cluster_template_id)
84 return u.render() 89 return u.render()
@@ -97,6 +102,7 @@ def _cluster_template_export_helper(template):
97@rest.get('/cluster-templates/<cluster_template_id>/export') 102@rest.get('/cluster-templates/<cluster_template_id>/export')
98@acl.enforce("data-processing:cluster-templates:get") 103@acl.enforce("data-processing:cluster-templates:get")
99@v.check_exists(api.get_cluster_template, 'cluster_template_id') 104@v.check_exists(api.get_cluster_template, 'cluster_template_id')
105@v.validate_request_params([])
100def cluster_template_export(cluster_template_id): 106def cluster_template_export(cluster_template_id):
101 content = u.to_wrapped_dict_no_render( 107 content = u.to_wrapped_dict_no_render(
102 api.export_cluster_template, cluster_template_id) 108 api.export_cluster_template, cluster_template_id)
diff --git a/sahara/api/v2/clusters.py b/sahara/api/v2/clusters.py
index 3d63817..9e38595 100644
--- a/sahara/api/v2/clusters.py
+++ b/sahara/api/v2/clusters.py
@@ -31,6 +31,7 @@ rest = u.RestV2('clusters', __name__)
31@acl.enforce("data-processing:clusters:get_all") 31@acl.enforce("data-processing:clusters:get_all")
32@v.check_exists(api.get_cluster, 'marker') 32@v.check_exists(api.get_cluster, 'marker')
33@v.validate(None, v.validate_pagination_limit) 33@v.validate(None, v.validate_pagination_limit)
34@v.validate_request_params(['plugin_name', 'hadoop_version', 'name'])
34def clusters_list(): 35def clusters_list():
35 result = api.get_clusters(**u.get_request_args().to_dict()) 36 result = api.get_clusters(**u.get_request_args().to_dict())
36 for c in result: 37 for c in result:
@@ -42,6 +43,7 @@ def clusters_list():
42@acl.enforce("data-processing:clusters:create") 43@acl.enforce("data-processing:clusters:create")
43@v.validate(v_c_schema.CLUSTER_SCHEMA_V2, 44@v.validate(v_c_schema.CLUSTER_SCHEMA_V2,
44 v_c.check_one_or_multiple_clusters_create) 45 v_c.check_one_or_multiple_clusters_create)
46@v.validate_request_params([])
45def clusters_create(data): 47def clusters_create(data):
46 # renaming hadoop_version -> plugin_version 48 # renaming hadoop_version -> plugin_version
47 # this can be removed once APIv1 is deprecated 49 # this can be removed once APIv1 is deprecated
@@ -62,6 +64,7 @@ def clusters_create(data):
62@acl.enforce("data-processing:clusters:scale") 64@acl.enforce("data-processing:clusters:scale")
63@v.check_exists(api.get_cluster, 'cluster_id') 65@v.check_exists(api.get_cluster, 'cluster_id')
64@v.validate(v_c_schema.CLUSTER_SCALING_SCHEMA_V2, v_c_s.check_cluster_scaling) 66@v.validate(v_c_schema.CLUSTER_SCALING_SCHEMA_V2, v_c_s.check_cluster_scaling)
67@v.validate_request_params([])
65def clusters_scale(cluster_id, data): 68def clusters_scale(cluster_id, data):
66 result = u.to_wrapped_dict_no_render( 69 result = u.to_wrapped_dict_no_render(
67 api.scale_cluster, cluster_id, data) 70 api.scale_cluster, cluster_id, data)
@@ -72,6 +75,7 @@ def clusters_scale(cluster_id, data):
72@rest.get('/clusters/<cluster_id>') 75@rest.get('/clusters/<cluster_id>')
73@acl.enforce("data-processing:clusters:get") 76@acl.enforce("data-processing:clusters:get")
74@v.check_exists(api.get_cluster, 'cluster_id') 77@v.check_exists(api.get_cluster, 'cluster_id')
78@v.validate_request_params([])
75def clusters_get(cluster_id): 79def clusters_get(cluster_id):
76 data = u.get_request_args() 80 data = u.get_request_args()
77 show_events = six.text_type( 81 show_events = six.text_type(
@@ -86,6 +90,7 @@ def clusters_get(cluster_id):
86@acl.enforce("data-processing:clusters:modify") 90@acl.enforce("data-processing:clusters:modify")
87@v.check_exists(api.get_cluster, 'cluster_id') 91@v.check_exists(api.get_cluster, 'cluster_id')
88@v.validate(v_c_schema.CLUSTER_UPDATE_SCHEMA, v_c.check_cluster_update) 92@v.validate(v_c_schema.CLUSTER_UPDATE_SCHEMA, v_c.check_cluster_update)
93@v.validate_request_params([])
89def clusters_update(cluster_id, data): 94def clusters_update(cluster_id, data):
90 result = u.to_wrapped_dict_no_render( 95 result = u.to_wrapped_dict_no_render(
91 api.update_cluster, cluster_id, data) 96 api.update_cluster, cluster_id, data)
@@ -97,6 +102,7 @@ def clusters_update(cluster_id, data):
97@acl.enforce("data-processing:clusters:delete") 102@acl.enforce("data-processing:clusters:delete")
98@v.check_exists(api.get_cluster, 'cluster_id') 103@v.check_exists(api.get_cluster, 'cluster_id')
99@v.validate(v_c_schema.CLUSTER_DELETE_SCHEMA_V2, v_c.check_cluster_delete) 104@v.validate(v_c_schema.CLUSTER_DELETE_SCHEMA_V2, v_c.check_cluster_delete)
105@v.validate_request_params([])
100def clusters_delete(cluster_id): 106def clusters_delete(cluster_id):
101 data = u.request_data() 107 data = u.request_data()
102 force = data.get('force', False) 108 force = data.get('force', False)
diff --git a/sahara/api/v2/data_sources.py b/sahara/api/v2/data_sources.py
index 2781bc3..0284584 100644
--- a/sahara/api/v2/data_sources.py
+++ b/sahara/api/v2/data_sources.py
@@ -29,6 +29,7 @@ rest = u.RestV2('data-sources', __name__)
29@v.check_exists(api.get_data_source, 'marker') 29@v.check_exists(api.get_data_source, 'marker')
30@v.validate(None, v.validate_pagination_limit, 30@v.validate(None, v.validate_pagination_limit,
31 v.validate_sorting_data_sources) 31 v.validate_sorting_data_sources)
32@v.validate_request_params(['type'])
32def data_sources_list(): 33def data_sources_list():
33 result = api.get_data_sources(**u.get_request_args().to_dict()) 34 result = api.get_data_sources(**u.get_request_args().to_dict())
34 return u.render(res=result, name='data_sources') 35 return u.render(res=result, name='data_sources')
@@ -37,6 +38,7 @@ def data_sources_list():
37@rest.post('/data-sources') 38@rest.post('/data-sources')
38@acl.enforce("data-processing:data-sources:register") 39@acl.enforce("data-processing:data-sources:register")
39@v.validate(v_d_s_schema.DATA_SOURCE_SCHEMA, v_d_s.check_data_source_create) 40@v.validate(v_d_s_schema.DATA_SOURCE_SCHEMA, v_d_s.check_data_source_create)
41@v.validate_request_params([])
40def data_source_register(data): 42def data_source_register(data):
41 return u.render(api.register_data_source(data).to_wrapped_dict()) 43 return u.render(api.register_data_source(data).to_wrapped_dict())
42 44
@@ -44,6 +46,7 @@ def data_source_register(data):
44@rest.get('/data-sources/<data_source_id>') 46@rest.get('/data-sources/<data_source_id>')
45@acl.enforce("data-processing:data-sources:get") 47@acl.enforce("data-processing:data-sources:get")
46@v.check_exists(api.get_data_source, 'data_source_id') 48@v.check_exists(api.get_data_source, 'data_source_id')
49@v.validate_request_params([])
47def data_source_get(data_source_id): 50def data_source_get(data_source_id):
48 return u.to_wrapped_dict(api.get_data_source, data_source_id) 51 return u.to_wrapped_dict(api.get_data_source, data_source_id)
49 52
@@ -51,6 +54,7 @@ def data_source_get(data_source_id):
51@rest.delete('/data-sources/<data_source_id>') 54@rest.delete('/data-sources/<data_source_id>')
52@acl.enforce("data-processing:data-sources:delete") 55@acl.enforce("data-processing:data-sources:delete")
53@v.check_exists(api.get_data_source, 'data_source_id') 56@v.check_exists(api.get_data_source, 'data_source_id')
57@v.validate_request_params([])
54def data_source_delete(data_source_id): 58def data_source_delete(data_source_id):
55 api.delete_data_source(data_source_id) 59 api.delete_data_source(data_source_id)
56 return u.render() 60 return u.render()
@@ -60,5 +64,6 @@ def data_source_delete(data_source_id):
60@acl.enforce("data-processing:data-sources:modify") 64@acl.enforce("data-processing:data-sources:modify")
61@v.check_exists(api.get_data_source, 'data_source_id') 65@v.check_exists(api.get_data_source, 'data_source_id')
62@v.validate(v_d_s_schema.DATA_SOURCE_UPDATE_SCHEMA) 66@v.validate(v_d_s_schema.DATA_SOURCE_UPDATE_SCHEMA)
67@v.validate_request_params([])
63def data_source_update(data_source_id, data): 68def data_source_update(data_source_id, data):
64 return u.to_wrapped_dict(api.data_source_update, data_source_id, data) 69 return u.to_wrapped_dict(api.data_source_update, data_source_id, data)
diff --git a/sahara/api/v2/images.py b/sahara/api/v2/images.py
index 1d3d6f9..1cced90 100644
--- a/sahara/api/v2/images.py
+++ b/sahara/api/v2/images.py
@@ -25,6 +25,7 @@ rest = u.RestV2('images', __name__)
25 25
26@rest.get('/images') 26@rest.get('/images')
27@acl.enforce("data-processing:images:get_all") 27@acl.enforce("data-processing:images:get_all")
28@v.validate_request_params(['name', 'tags', 'username'])
28def images_list(): 29def images_list():
29 tags = u.get_request_args().getlist('tags') 30 tags = u.get_request_args().getlist('tags')
30 name = u.get_request_args().get('name', None) 31 name = u.get_request_args().get('name', None)
@@ -34,6 +35,7 @@ def images_list():
34@rest.get('/images/<image_id>') 35@rest.get('/images/<image_id>')
35@acl.enforce("data-processing:images:get") 36@acl.enforce("data-processing:images:get")
36@v.check_exists(api.get_image, id='image_id') 37@v.check_exists(api.get_image, id='image_id')
38@v.validate_request_params([])
37def images_get(image_id): 39def images_get(image_id):
38 return u.render(api.get_registered_image(id=image_id).wrapped_dict) 40 return u.render(api.get_registered_image(id=image_id).wrapped_dict)
39 41
@@ -42,6 +44,7 @@ def images_get(image_id):
42@acl.enforce("data-processing:images:register") 44@acl.enforce("data-processing:images:register")
43@v.check_exists(api.get_image, id='image_id') 45@v.check_exists(api.get_image, id='image_id')
44@v.validate(v_images.image_register_schema, v_images.check_image_register) 46@v.validate(v_images.image_register_schema, v_images.check_image_register)
47@v.validate_request_params([])
45def images_set(image_id, data): 48def images_set(image_id, data):
46 return u.render(api.register_image(image_id, **data).wrapped_dict) 49 return u.render(api.register_image(image_id, **data).wrapped_dict)
47 50
@@ -49,6 +52,7 @@ def images_set(image_id, data):
49@rest.delete('/images/<image_id>') 52@rest.delete('/images/<image_id>')
50@acl.enforce("data-processing:images:unregister") 53@acl.enforce("data-processing:images:unregister")
51@v.check_exists(api.get_image, id='image_id') 54@v.check_exists(api.get_image, id='image_id')
55@v.validate_request_params([])
52def images_unset(image_id): 56def images_unset(image_id):
53 api.unregister_image(image_id) 57 api.unregister_image(image_id)
54 return u.render() 58 return u.render()
@@ -57,6 +61,7 @@ def images_unset(image_id):
57@rest.get('/images/<image_id>/tags') 61@rest.get('/images/<image_id>/tags')
58@acl.enforce("data-processing:images:get_tags") 62@acl.enforce("data-processing:images:get_tags")
59@v.check_exists(api.get_image, id='image_id') 63@v.check_exists(api.get_image, id='image_id')
64@v.validate_request_params([])
60def image_tags_get(image_id): 65def image_tags_get(image_id):
61 return u.render(api.get_image_tags(image_id)) 66 return u.render(api.get_image_tags(image_id))
62 67
@@ -65,6 +70,7 @@ def image_tags_get(image_id):
65@acl.enforce("data-processing:images:set_tags") 70@acl.enforce("data-processing:images:set_tags")
66@v.check_exists(api.get_image, id='image_id') 71@v.check_exists(api.get_image, id='image_id')
67@v.validate(v_images.image_tags_schema, v_images.check_tags) 72@v.validate(v_images.image_tags_schema, v_images.check_tags)
73@v.validate_request_params([])
68def image_tags_update(image_id, data): 74def image_tags_update(image_id, data):
69 return u.render(api.set_image_tags(image_id, **data).wrapped_dict) 75 return u.render(api.set_image_tags(image_id, **data).wrapped_dict)
70 76
@@ -72,6 +78,7 @@ def image_tags_update(image_id, data):
72@rest.delete('/images/<image_id>/tags') 78@rest.delete('/images/<image_id>/tags')
73@acl.enforce("data-processing:images:remove_tags") 79@acl.enforce("data-processing:images:remove_tags")
74@v.check_exists(api.get_image, id='image_id') 80@v.check_exists(api.get_image, id='image_id')
81@v.validate_request_params([])
75def image_tags_delete(image_id): 82def image_tags_delete(image_id):
76 api.remove_image_tags(image_id) 83 api.remove_image_tags(image_id)
77 return u.render() 84 return u.render()
diff --git a/sahara/api/v2/job_binaries.py b/sahara/api/v2/job_binaries.py
index ac201fc..3e9e486 100644
--- a/sahara/api/v2/job_binaries.py
+++ b/sahara/api/v2/job_binaries.py
@@ -27,6 +27,7 @@ rest = u.RestV2('job-binaries', __name__)
27@rest.post('/job-binaries') 27@rest.post('/job-binaries')
28@acl.enforce("data-processing:job-binaries:create") 28@acl.enforce("data-processing:job-binaries:create")
29@v.validate(v_j_b_schema.JOB_BINARY_SCHEMA, v_j_b.check_job_binary) 29@v.validate(v_j_b_schema.JOB_BINARY_SCHEMA, v_j_b.check_job_binary)
30@v.validate_request_params([])
30def job_binary_create(data): 31def job_binary_create(data):
31 return u.render(api.create_job_binary(data).to_wrapped_dict()) 32 return u.render(api.create_job_binary(data).to_wrapped_dict())
32 33
@@ -36,6 +37,7 @@ def job_binary_create(data):
36@v.check_exists(api.get_job_binary, 'marker') 37@v.check_exists(api.get_job_binary, 'marker')
37@v.validate(None, v.validate_pagination_limit, 38@v.validate(None, v.validate_pagination_limit,
38 v.validate_sorting_job_binaries) 39 v.validate_sorting_job_binaries)
40@v.validate_request_params(['name'])
39def job_binary_list(): 41def job_binary_list():
40 result = api.get_job_binaries(**u.get_request_args().to_dict()) 42 result = api.get_job_binaries(**u.get_request_args().to_dict())
41 return u.render(res=result, name='binaries') 43 return u.render(res=result, name='binaries')
@@ -44,6 +46,7 @@ def job_binary_list():
44@rest.get('/job-binaries/<job_binary_id>') 46@rest.get('/job-binaries/<job_binary_id>')
45@acl.enforce("data-processing:job-binaries:get") 47@acl.enforce("data-processing:job-binaries:get")
46@v.check_exists(api.get_job_binary, 'job_binary_id') 48@v.check_exists(api.get_job_binary, 'job_binary_id')
49@v.validate_request_params([])
47def job_binary_get(job_binary_id): 50def job_binary_get(job_binary_id):
48 return u.to_wrapped_dict(api.get_job_binary, job_binary_id) 51 return u.to_wrapped_dict(api.get_job_binary, job_binary_id)
49 52
@@ -51,6 +54,7 @@ def job_binary_get(job_binary_id):
51@rest.delete('/job-binaries/<job_binary_id>') 54@rest.delete('/job-binaries/<job_binary_id>')
52@acl.enforce("data-processing:job-binaries:delete") 55@acl.enforce("data-processing:job-binaries:delete")
53@v.check_exists(api.get_job_binary, id='job_binary_id') 56@v.check_exists(api.get_job_binary, id='job_binary_id')
57@v.validate_request_params([])
54def job_binary_delete(job_binary_id): 58def job_binary_delete(job_binary_id):
55 api.delete_job_binary(job_binary_id) 59 api.delete_job_binary(job_binary_id)
56 return u.render() 60 return u.render()
@@ -59,6 +63,7 @@ def job_binary_delete(job_binary_id):
59@rest.get('/job-binaries/<job_binary_id>/data') 63@rest.get('/job-binaries/<job_binary_id>/data')
60@acl.enforce("data-processing:job-binaries:get_data") 64@acl.enforce("data-processing:job-binaries:get_data")
61@v.check_exists(api.get_job_binary, 'job_binary_id') 65@v.check_exists(api.get_job_binary, 'job_binary_id')
66@v.validate_request_params([])
62def job_binary_data(job_binary_id): 67def job_binary_data(job_binary_id):
63 data = api.get_job_binary_data(job_binary_id) 68 data = api.get_job_binary_data(job_binary_id)
64 if type(data) == dict: 69 if type(data) == dict:
@@ -69,6 +74,7 @@ def job_binary_data(job_binary_id):
69@rest.patch('/job-binaries/<job_binary_id>') 74@rest.patch('/job-binaries/<job_binary_id>')
70@acl.enforce("data-processing:job-binaries:modify") 75@acl.enforce("data-processing:job-binaries:modify")
71@v.validate(v_j_b_schema.JOB_BINARY_UPDATE_SCHEMA, v_j_b.check_job_binary) 76@v.validate(v_j_b_schema.JOB_BINARY_UPDATE_SCHEMA, v_j_b.check_job_binary)
77@v.validate_request_params([])
72def job_binary_update(job_binary_id, data): 78def job_binary_update(job_binary_id, data):
73 return u.render(api.update_job_binary(job_binary_id, 79 return u.render(api.update_job_binary(job_binary_id,
74 data).to_wrapped_dict()) 80 data).to_wrapped_dict())
diff --git a/sahara/api/v2/job_templates.py b/sahara/api/v2/job_templates.py
index c1e268e..dcdf9c5 100644
--- a/sahara/api/v2/job_templates.py
+++ b/sahara/api/v2/job_templates.py
@@ -29,6 +29,7 @@ rest = u.RestV2('job-templates', __name__)
29@v.check_exists(api.get_job_templates, 'marker') 29@v.check_exists(api.get_job_templates, 'marker')
30@v.validate(None, v.validate_pagination_limit, 30@v.validate(None, v.validate_pagination_limit,
31 v.validate_sorting_jobs) 31 v.validate_sorting_jobs)
32@v.validate_request_params(['type', 'name'])
32def job_templates_list(): 33def job_templates_list():
33 result = api.get_job_templates(**u.get_request_args().to_dict()) 34 result = api.get_job_templates(**u.get_request_args().to_dict())
34 return u.render(res=result, name='job_templates') 35 return u.render(res=result, name='job_templates')
@@ -37,6 +38,7 @@ def job_templates_list():
37@rest.post('/job-templates') 38@rest.post('/job-templates')
38@acl.enforce("data-processing:job-templates:create") 39@acl.enforce("data-processing:job-templates:create")
39@v.validate(v_j_schema.JOB_SCHEMA, v_j.check_mains_libs, v_j.check_interface) 40@v.validate(v_j_schema.JOB_SCHEMA, v_j.check_mains_libs, v_j.check_interface)
41@v.validate_request_params([])
40def job_templates_create(data): 42def job_templates_create(data):
41 return u.render({'job_template': api.create_job_template(data).to_dict()}) 43 return u.render({'job_template': api.create_job_template(data).to_dict()})
42 44
@@ -44,6 +46,7 @@ def job_templates_create(data):
44@rest.get('/job-templates/<job_templates_id>') 46@rest.get('/job-templates/<job_templates_id>')
45@acl.enforce("data-processing:job-templates:get") 47@acl.enforce("data-processing:job-templates:get")
46@v.check_exists(api.get_job_templates, id='job_templates_id') 48@v.check_exists(api.get_job_templates, id='job_templates_id')
49@v.validate_request_params([])
47def job_templates_get(job_templates_id): 50def job_templates_get(job_templates_id):
48 return u.render({'job_template': api.get_job_template( 51 return u.render({'job_template': api.get_job_template(
49 job_templates_id).to_dict()}) 52 job_templates_id).to_dict()})
@@ -53,6 +56,7 @@ def job_templates_get(job_templates_id):
53@acl.enforce("data-processing:jobs:modify") 56@acl.enforce("data-processing:jobs:modify")
54@v.check_exists(api.get_job_templates, id='job_templates_id') 57@v.check_exists(api.get_job_templates, id='job_templates_id')
55@v.validate(v_j_schema.JOB_UPDATE_SCHEMA) 58@v.validate(v_j_schema.JOB_UPDATE_SCHEMA)
59@v.validate_request_params([])
56def job_templates_update(job_templates_id, data): 60def job_templates_update(job_templates_id, data):
57 return u.render({'job_template': api.update_job_template( 61 return u.render({'job_template': api.update_job_template(
58 job_templates_id, data).to_dict()}) 62 job_templates_id, data).to_dict()})
@@ -61,6 +65,7 @@ def job_templates_update(job_templates_id, data):
61@rest.delete('/job-templates/<job_templates_id>') 65@rest.delete('/job-templates/<job_templates_id>')
62@acl.enforce("data-processing:jobs:delete") 66@acl.enforce("data-processing:jobs:delete")
63@v.check_exists(api.get_job_templates, id='job_templates_id') 67@v.check_exists(api.get_job_templates, id='job_templates_id')
68@v.validate_request_params([])
64def job_templates_delete(job_templates_id): 69def job_templates_delete(job_templates_id):
65 api.delete_job_template(job_templates_id) 70 api.delete_job_template(job_templates_id)
66 return u.render() 71 return u.render()
@@ -69,5 +74,6 @@ def job_templates_delete(job_templates_id):
69@rest.get('/job-templates/config-hints/<job_type>') 74@rest.get('/job-templates/config-hints/<job_type>')
70@acl.enforce("data-processing:jobs:get_config_hints") 75@acl.enforce("data-processing:jobs:get_config_hints")
71@v.check_exists(api.get_job_config_hints, job_type='job_type') 76@v.check_exists(api.get_job_config_hints, job_type='job_type')
77@v.validate_request_params([])
72def job_config_hints_get(job_type): 78def job_config_hints_get(job_type):
73 return u.render(api.get_job_config_hints(job_type)) 79 return u.render(api.get_job_config_hints(job_type))
diff --git a/sahara/api/v2/job_types.py b/sahara/api/v2/job_types.py
index aa9ef9e..5c81416 100644
--- a/sahara/api/v2/job_types.py
+++ b/sahara/api/v2/job_types.py
@@ -15,6 +15,7 @@
15 15
16from sahara.api import acl 16from sahara.api import acl
17from sahara.service.api.v2 import job_types as api 17from sahara.service.api.v2 import job_types as api
18from sahara.service import validation as v
18import sahara.utils.api as u 19import sahara.utils.api as u
19 20
20 21
@@ -23,6 +24,7 @@ rest = u.RestV2('job-types', __name__)
23 24
24@rest.get('/job-types') 25@rest.get('/job-types')
25@acl.enforce("data-processing:job-types:get_all") 26@acl.enforce("data-processing:job-types:get_all")
27@v.validate_request_params(['type', 'plugin_name', 'hadoop_version'])
26def job_types_get(): 28def job_types_get():
27 # We want to use flat=False with to_dict() so that 29 # We want to use flat=False with to_dict() so that
28 # the value of each arg is given as a list. This supports 30 # the value of each arg is given as a list. This supports
diff --git a/sahara/api/v2/jobs.py b/sahara/api/v2/jobs.py
index 3c4dcfc..a9e41d4 100644
--- a/sahara/api/v2/jobs.py
+++ b/sahara/api/v2/jobs.py
@@ -31,6 +31,7 @@ rest = u.RestV2('jobs', __name__)
31@v.check_exists(api.get_job_execution, 'marker') 31@v.check_exists(api.get_job_execution, 'marker')
32@v.validate(None, v.validate_pagination_limit, 32@v.validate(None, v.validate_pagination_limit,
33 v.validate_sorting_job_executions) 33 v.validate_sorting_job_executions)
34@v.validate_request_params(['status'])
34def jobs_list(): 35def jobs_list():
35 result = api.job_execution_list(**u.get_request_args().to_dict()) 36 result = api.job_execution_list(**u.get_request_args().to_dict())
36 # APIv2: renaming oozie_job_id -> engine_job_id 37 # APIv2: renaming oozie_job_id -> engine_job_id
@@ -44,6 +45,7 @@ def jobs_list():
44@rest.post('/jobs') 45@rest.post('/jobs')
45@acl.enforce("data-processing:jobs:execute") 46@acl.enforce("data-processing:jobs:execute")
46@v.validate(v_j_e_schema.JOB_EXEC_SCHEMA_V2, v_j_e.check_job_execution) 47@v.validate(v_j_e_schema.JOB_EXEC_SCHEMA_V2, v_j_e.check_job_execution)
48@v.validate_request_params([])
47def jobs_execute(data): 49def jobs_execute(data):
48 result = {'job': api.execute_job(data)} 50 result = {'job': api.execute_job(data)}
49 dict.update(result['job'], 51 dict.update(result['job'],
@@ -55,6 +57,7 @@ def jobs_execute(data):
55@rest.get('/jobs/<job_id>') 57@rest.get('/jobs/<job_id>')
56@acl.enforce("data-processing:job-executions:get") 58@acl.enforce("data-processing:job-executions:get")
57@v.check_exists(api.get_job_execution, id='job_id') 59@v.check_exists(api.get_job_execution, id='job_id')
60@v.validate_request_params([])
58def jobs_get(job_id): 61def jobs_get(job_id):
59 data = u.get_request_args() 62 data = u.get_request_args()
60 refresh_status = six.text_type( 63 refresh_status = six.text_type(
@@ -69,6 +72,7 @@ def jobs_get(job_id):
69@v.check_exists(api.get_job_execution, id='job_id') 72@v.check_exists(api.get_job_execution, id='job_id')
70@v.validate( 73@v.validate(
71 v_j_e_schema.JOB_EXEC_UPDATE_SCHEMA, v_j_e.check_job_execution_update) 74 v_j_e_schema.JOB_EXEC_UPDATE_SCHEMA, v_j_e.check_job_execution_update)
75@v.validate_request_params([])
72def jobs_update(job_id, data): 76def jobs_update(job_id, data):
73 result = {'job': api.update_job_execution(job_id, data)} 77 result = {'job': api.update_job_execution(job_id, data)}
74 result['job'].pop('oozie_job_id', force=True) 78 result['job'].pop('oozie_job_id', force=True)
@@ -79,6 +83,7 @@ def jobs_update(job_id, data):
79@acl.enforce("data-processing:job-executions:delete") 83@acl.enforce("data-processing:job-executions:delete")
80@v.check_exists(api.get_job_execution, id='job_id') 84@v.check_exists(api.get_job_execution, id='job_id')
81@v.validate(None, v_j_e.check_job_execution_delete) 85@v.validate(None, v_j_e.check_job_execution_delete)
86@v.validate_request_params([])
82def jobs_delete(job_id): 87def jobs_delete(job_id):
83 api.delete_job_execution(job_id) 88 api.delete_job_execution(job_id)
84 return u.render() 89 return u.render()
diff --git a/sahara/api/v2/node_group_templates.py b/sahara/api/v2/node_group_templates.py
index c0b20d0..17e0c83 100644
--- a/sahara/api/v2/node_group_templates.py
+++ b/sahara/api/v2/node_group_templates.py
@@ -30,6 +30,7 @@ rest = u.RestV2('node-group-templates', __name__)
30@v.check_exists(api.get_node_group_template, 'marker') 30@v.check_exists(api.get_node_group_template, 'marker')
31@v.validate(None, v.validate_pagination_limit, 31@v.validate(None, v.validate_pagination_limit,
32 v.validate_sorting_node_group_templates) 32 v.validate_sorting_node_group_templates)
33@v.validate_request_params(['plugin_name', 'hadoop_version', 'name'])
33def node_group_templates_list(): 34def node_group_templates_list():
34 result = api.get_node_group_templates(**u.get_request_args().to_dict()) 35 result = api.get_node_group_templates(**u.get_request_args().to_dict())
35 for ngt in result: 36 for ngt in result:
@@ -41,6 +42,7 @@ def node_group_templates_list():
41@acl.enforce("data-processing:node-group-templates:create") 42@acl.enforce("data-processing:node-group-templates:create")
42@v.validate(ngt_schema.NODE_GROUP_TEMPLATE_SCHEMA_V2, 43@v.validate(ngt_schema.NODE_GROUP_TEMPLATE_SCHEMA_V2,
43 v_ngt.check_node_group_template_create) 44 v_ngt.check_node_group_template_create)
45@v.validate_request_params([])
44def node_group_templates_create(data): 46def node_group_templates_create(data):
45 # renaming hadoop_version -> plugin_version 47 # renaming hadoop_version -> plugin_version
46 # this can be removed once APIv1 is deprecated 48 # this can be removed once APIv1 is deprecated
@@ -54,6 +56,7 @@ def node_group_templates_create(data):
54@rest.get('/node-group-templates/<node_group_template_id>') 56@rest.get('/node-group-templates/<node_group_template_id>')
55@acl.enforce("data-processing:node-group-templates:get") 57@acl.enforce("data-processing:node-group-templates:get")
56@v.check_exists(api.get_node_group_template, 'node_group_template_id') 58@v.check_exists(api.get_node_group_template, 'node_group_template_id')
59@v.validate_request_params([])
57def node_group_templates_get(node_group_template_id): 60def node_group_templates_get(node_group_template_id):
58 result = u.to_wrapped_dict_no_render( 61 result = u.to_wrapped_dict_no_render(
59 api.get_node_group_template, node_group_template_id) 62 api.get_node_group_template, node_group_template_id)
@@ -66,6 +69,7 @@ def node_group_templates_get(node_group_template_id):
66@v.check_exists(api.get_node_group_template, 'node_group_template_id') 69@v.check_exists(api.get_node_group_template, 'node_group_template_id')
67@v.validate(ngt_schema.NODE_GROUP_TEMPLATE_UPDATE_SCHEMA_V2, 70@v.validate(ngt_schema.NODE_GROUP_TEMPLATE_UPDATE_SCHEMA_V2,
68 v_ngt.check_node_group_template_update) 71 v_ngt.check_node_group_template_update)
72@v.validate_request_params([])
69def node_group_templates_update(node_group_template_id, data): 73def node_group_templates_update(node_group_template_id, data):
70 if data.get('plugin_version', None): 74 if data.get('plugin_version', None):
71 data['hadoop_version'] = data['plugin_version'] 75 data['hadoop_version'] = data['plugin_version']
@@ -80,6 +84,7 @@ def node_group_templates_update(node_group_template_id, data):
80@acl.enforce("data-processing:node-group-templates:delete") 84@acl.enforce("data-processing:node-group-templates:delete")
81@v.check_exists(api.get_node_group_template, 'node_group_template_id') 85@v.check_exists(api.get_node_group_template, 'node_group_template_id')
82@v.validate(None, v_ngt.check_node_group_template_usage) 86@v.validate(None, v_ngt.check_node_group_template_usage)
87@v.validate_request_params([])
83def node_group_templates_delete(node_group_template_id): 88def node_group_templates_delete(node_group_template_id):
84 api.terminate_node_group_template(node_group_template_id) 89 api.terminate_node_group_template(node_group_template_id)
85 return u.render() 90 return u.render()
@@ -100,6 +105,7 @@ def _node_group_template_export_helper(template):
100@rest.get('/node-group-templates/<node_group_template_id>/export') 105@rest.get('/node-group-templates/<node_group_template_id>/export')
101@acl.enforce("data-processing:node-group-templates:get") 106@acl.enforce("data-processing:node-group-templates:get")
102@v.check_exists(api.get_node_group_template, 'node_group_template_id') 107@v.check_exists(api.get_node_group_template, 'node_group_template_id')
108@v.validate_request_params([])
103def node_group_template_export(node_group_template_id): 109def node_group_template_export(node_group_template_id):
104 content = u.to_wrapped_dict_no_render( 110 content = u.to_wrapped_dict_no_render(
105 api.export_node_group_template, node_group_template_id) 111 api.export_node_group_template, node_group_template_id)
diff --git a/sahara/api/v2/plugins.py b/sahara/api/v2/plugins.py
index f6f9434..e9ef4d8 100644
--- a/sahara/api/v2/plugins.py
+++ b/sahara/api/v2/plugins.py
@@ -25,6 +25,7 @@ rest = u.RestV2('plugins', __name__)
25 25
26@rest.get('/plugins') 26@rest.get('/plugins')
27@acl.enforce("data-processing:plugins:get_all") 27@acl.enforce("data-processing:plugins:get_all")
28@v.validate_request_params([])
28def plugins_list(): 29def plugins_list():
29 return u.render(plugins=[p.dict for p in api.get_plugins()]) 30 return u.render(plugins=[p.dict for p in api.get_plugins()])
30 31
@@ -32,6 +33,7 @@ def plugins_list():
32@rest.get('/plugins/<plugin_name>') 33@rest.get('/plugins/<plugin_name>')
33@acl.enforce("data-processing:plugins:get") 34@acl.enforce("data-processing:plugins:get")
34@v.check_exists(api.get_plugin, plugin_name='plugin_name') 35@v.check_exists(api.get_plugin, plugin_name='plugin_name')
36@v.validate_request_params([])
35def plugins_get(plugin_name): 37def plugins_get(plugin_name):
36 return u.render(api.get_plugin(plugin_name).wrapped_dict) 38 return u.render(api.get_plugin(plugin_name).wrapped_dict)
37 39
@@ -39,6 +41,7 @@ def plugins_get(plugin_name):
39@rest.get('/plugins/<plugin_name>/<version>') 41@rest.get('/plugins/<plugin_name>/<version>')
40@acl.enforce("data-processing:plugins:get_version") 42@acl.enforce("data-processing:plugins:get_version")
41@v.check_exists(api.get_plugin, plugin_name='plugin_name', version='version') 43@v.check_exists(api.get_plugin, plugin_name='plugin_name', version='version')
44@v.validate_request_params([])
42def plugins_get_version(plugin_name, version): 45def plugins_get_version(plugin_name, version):
43 return u.render(api.get_plugin(plugin_name, version).wrapped_dict) 46 return u.render(api.get_plugin(plugin_name, version).wrapped_dict)
44 47
@@ -47,5 +50,6 @@ def plugins_get_version(plugin_name, version):
47@acl.enforce("data-processing:plugins:patch") 50@acl.enforce("data-processing:plugins:patch")
48@v.check_exists(api.get_plugin, plugin_name='plugin_name') 51@v.check_exists(api.get_plugin, plugin_name='plugin_name')
49@v.validate(v_p.plugin_update_validation_jsonschema(), v_p.check_plugin_update) 52@v.validate(v_p.plugin_update_validation_jsonschema(), v_p.check_plugin_update)
53@v.validate_request_params([])
50def plugins_update(plugin_name, data): 54def plugins_update(plugin_name, data):
51 return u.render(api.update_plugin(plugin_name, data).wrapped_dict) 55 return u.render(api.update_plugin(plugin_name, data).wrapped_dict)
diff --git a/sahara/service/validation.py b/sahara/service/validation.py
index d0e9a10..038d60a 100644
--- a/sahara/service/validation.py
+++ b/sahara/service/validation.py
@@ -198,3 +198,22 @@ def check_exists(get_func, *id_prop, **get_args):
198 return handler 198 return handler
199 199
200 return decorator 200 return decorator
201
202
203def validate_request_params(supported_params):
204 def decorator(func):
205 @functools.wraps(func)
206 def handler(*args, **kwargs):
207 pagination_params = ['marker', 'limit', 'sort_by']
208 func_name = func.__name__
209 params = u.get_request_args()
210 for param in params.keys():
211 if (param not in supported_params and
212 param not in pagination_params):
213 return u.invalid_param_error(
214 400,
215 'The only valid params for %s are %s and %s' % (
216 func_name, supported_params, pagination_params))
217 return func(*args, **kwargs)
218 return handler
219 return decorator
diff --git a/sahara/utils/api.py b/sahara/utils/api.py
index 847264f..5be0d98 100644
--- a/sahara/utils/api.py
+++ b/sahara/utils/api.py
@@ -288,6 +288,18 @@ def render_error_message(error_code, error_message, error_name):
288 return resp 288 return resp
289 289
290 290
291def invalid_param_error(status_code, descr, exc=None):
292 LOG.error("Request aborted with status code {code} and "
293 "message '{message}'".format(code=status_code, message=descr))
294
295 if exc is not None:
296 LOG.error(traceback.format_exc())
297
298 error_code = "INVALID_PARAMS_ON_REQUEST"
299
300 return render_error_message(status_code, descr, error_code)
301
302
291def internal_error(status_code, descr, exc=None): 303def internal_error(status_code, descr, exc=None):
292 LOG.error("Request aborted with status code {code} and " 304 LOG.error("Request aborted with status code {code} and "
293 "message '{message}'".format(code=status_code, message=descr)) 305 "message '{message}'".format(code=status_code, message=descr))