The 'check_exists' applied to all API calls

* 404 is now returned instead of 500 in all API calls;
* direct calls to nova client moved from api/v10 to service/api
* utils/api has been updated to avoid implicit magic.

Partailly implements blueprint savanna-rest-api-1-0-validation

Change-Id: Id1e64b03920c59bc96da6c8f709bd1beccb59d76
This commit is contained in:
Sergey Lukjanov 2013-06-25 16:31:00 +04:00
parent 3ea5c7776d
commit 7c324982f2
3 changed files with 64 additions and 41 deletions

View File

@ -15,8 +15,8 @@
from savanna.openstack.common import log as logging
from savanna.service import api
from savanna.service import validation as v
import savanna.utils.api as u
from savanna.utils.openstack import nova
LOG = logging.getLogger(__name__)
@ -36,16 +36,19 @@ def clusters_create(data):
@rest.get('/clusters/<cluster_id>')
@v.check_exists(api.get_cluster, 'cluster_id')
def clusters_get(cluster_id):
return u.render(api.get_cluster(id=cluster_id).wrapped_dict)
@rest.put('/clusters/<cluster_id>')
def clusters_update(_cluster_id):
@v.check_exists(api.get_cluster, 'cluster_id')
def clusters_update(cluster_id):
return _not_implemented()
@rest.delete('/clusters/<cluster_id>')
@v.check_exists(api.get_cluster, 'cluster_id')
def clusters_delete(cluster_id):
api.terminate_cluster(id=cluster_id)
return u.render()
@ -65,17 +68,20 @@ def cluster_templates_create(data):
@rest.get('/cluster-templates/<cluster_template_id>')
@v.check_exists(api.get_cluster_template, 'cluster_template_id')
def cluster_templates_get(cluster_template_id):
return u.render(
api.get_cluster_template(id=cluster_template_id).wrapped_dict)
@rest.put('/cluster-templates/<cluster_template_id>')
def cluster_templates_update(_cluster_template_id):
@v.check_exists(api.get_cluster_template, 'cluster_template_id')
def cluster_templates_update(cluster_template_id):
return _not_implemented()
@rest.delete('/cluster-templates/<cluster_template_id>')
@v.check_exists(api.get_cluster_template, 'cluster_template_id')
def cluster_templates_delete(cluster_template_id):
api.terminate_cluster_template(id=cluster_template_id)
return u.render()
@ -95,17 +101,20 @@ def node_group_templates_create(data):
@rest.get('/node-group-templates/<node_group_template_id>')
@v.check_exists(api.get_node_group_template, 'node_group_template_id')
def node_group_templates_get(node_group_template_id):
return u.render(
api.get_node_group_template(id=node_group_template_id).wrapped_dict)
@rest.put('/node-group-templates/<node_group_template_id>')
def node_group_templates_update(_node_group_template_id):
@v.check_exists(api.get_node_group_template, 'node_group_template_id')
def node_group_templates_update(node_group_template_id):
return _not_implemented()
@rest.delete('/node-group-templates/<node_group_template_id>')
@v.check_exists(api.get_node_group_template, 'node_group_template_id')
def node_group_templates_delete(node_group_template_id):
api.terminate_node_group_template(id=node_group_template_id)
return u.render()
@ -119,16 +128,19 @@ def plugins_list():
@rest.get('/plugins/<plugin_name>')
@v.check_exists(api.get_plugin, plugin_name='plugin_name')
def plugins_get(plugin_name):
return u.render(api.get_plugin(plugin_name).wrapped_dict)
@rest.get('/plugins/<plugin_name>/<version>')
@v.check_exists(api.get_plugin, plugin_name='plugin_name', version='version')
def plugins_get_version(plugin_name, version):
return u.render(api.get_plugin(plugin_name, version).wrapped_dict)
@rest.post_file('/plugins/<plugin_name>/<version>/convert-config')
@v.check_exists(api.get_plugin, plugin_name='plugin_name', version='version')
def plugins_convert_to_cluster_template(plugin_name, version, data):
return u.render(
api.convert_to_cluster_template(plugin_name, version, data))
@ -137,47 +149,40 @@ def plugins_convert_to_cluster_template(plugin_name, version, data):
## Image Registry ops
@rest.get('/images')
def images_list(request):
tags = request.args.getlist('tags')
return u.render(
images=[i.dict for i in nova.client().images.list_registered(tags)])
def _render_image(image_id, novaclient):
return u.render(novaclient.images.get(image_id).wrapped_dict)
def images_list():
tags = u.get_request_args().getlist('tags')
return u.render(images=[i.dict for i in api.get_images(tags)])
@rest.get('/images/<image_id>')
@v.check_exists(api.get_image, id='image_id')
def images_get(image_id):
return _render_image(image_id, nova.client())
return u.render(api.get_image(id=image_id).wrapped_dict)
@rest.post('/images/<image_id>')
@v.check_exists(api.get_image, id='image_id')
def images_set(image_id, data):
novaclient = nova.client()
novaclient.images.set_description(image_id, **data)
return _render_image(image_id, novaclient)
return u.render(api.register_image(image_id, **data).wrapped_dict)
@rest.delete('/images/<image_id>')
@v.check_exists(api.get_image, id='image_id')
def images_unset(image_id):
novaclient = nova.client()
novaclient.images.unset_description(image_id)
api.unregister_image(image_id)
return u.render()
@rest.post('/images/<image_id>/tag')
@v.check_exists(api.get_image, id='image_id')
def image_tags_add(image_id, data):
novaclient = nova.client()
novaclient.images.tag(image_id, **data)
return _render_image(image_id, novaclient)
return u.render(api.add_image_tags(image_id, **data).wrapped_dict)
@rest.post('/images/<image_id>/untag')
@v.check_exists(api.get_image, id='image_id')
def image_tags_delete(image_id, data):
novaclient = nova.client()
novaclient.images.untag(image_id, **data)
return _render_image(image_id, novaclient)
return u.render(api.remove_image_tags(image_id, **data).wrapped_dict)
def _not_implemented():

View File

@ -173,3 +173,27 @@ def get_image(**kwargs):
return nova.client().images.get(kwargs['id'])
else:
return nova.client().images.find(**kwargs)
def register_image(image_id, username, description=None):
client = nova.client()
client.images.set_description(image_id, username, description)
return client.images.get(image_id)
def unregister_image(image_id):
client = nova.client()
client.images.unset_description(image_id)
return client.images.get(image_id)
def add_image_tags(image_id, tags):
client = nova.client()
client.images.tag(image_id, tags)
return client.images.get(image_id)
def remove_image_tags(image_id, tags):
client = nova.client()
client.images.untag(image_id, tags)
return client.images.get(image_id)

View File

@ -13,7 +13,6 @@
# See the License for the specific language governing permissions and
# limitations under the License.
import inspect
import mimetypes
import traceback
@ -76,33 +75,24 @@ class Rest(flask.Blueprint):
ctx = context.Context(
flask.request.headers['X-User-Id'],
flask.request.headers['X-Tenant-Id'],
flask.request.headers[
'X-Auth-Token'],
flask.request.headers['X-Auth-Token'],
flask.request.headers)
context.set_ctx(ctx)
# set func implicit args
args = inspect.getargspec(func).args
if 'ctx' in args:
kwargs['ctx'] = ctx
if 'request' in args:
kwargs['request'] = flask.request
if flask.request.method in ['POST', 'PUT'] and 'data' in args:
if flask.request.method in ['POST', 'PUT']:
kwargs['data'] = request_data()
return func(**kwargs)
try:
return func(**kwargs)
except Exception, e:
return internal_error(500, 'Exception in REST API call', e)
f_rule = "/<tenant_id>" + rule
self.add_url_rule(f_rule, endpoint, handler, **options)
ext_rule = f_rule + '.<resp_type>'
self.add_url_rule(ext_rule, endpoint, handler, **options)
try:
return func
except Exception, e:
return internal_error(500, 'Exception in API call', e)
return func
return decorator
@ -203,6 +193,10 @@ def request_data():
return flask.request.parsed_data
def get_request_args():
return flask.request.args
def abort_and_log(status_code, descr, exc=None):
LOG.error("Request aborted with status code %s and message '%s'",
status_code, descr)