Commit 8a931304 authored by Christos Stavrakakis's avatar Christos Stavrakakis
Browse files

Merge branch 'devel-0.12' into devel-0.13

Conflicts:
	snf-cyclades-app/synnefo/plankton/backend.py
parents a7b49bfe 6f68df8a
...@@ -64,7 +64,7 @@ from synnefo.db.models import (Flavor, VirtualMachine, VirtualMachineMetadata, ...@@ -64,7 +64,7 @@ from synnefo.db.models import (Flavor, VirtualMachine, VirtualMachineMetadata,
from synnefo.db.pools import EmptyPool from synnefo.db.pools import EmptyPool
from synnefo.lib.astakos import get_user from synnefo.lib.astakos import get_user
from synnefo.plankton.backend import ImageBackend from synnefo.plankton.backend import ImageBackend, NotAllowedError
from synnefo.settings import MAX_CIDR_BLOCK from synnefo.settings import MAX_CIDR_BLOCK
...@@ -408,6 +408,10 @@ def api_method(http_method=None, atom_allowed=False): ...@@ -408,6 +408,10 @@ def api_method(http_method=None, atom_allowed=False):
except VirtualMachine.BuildingError: except VirtualMachine.BuildingError:
fault = BuildInProgress('Server is being built.') fault = BuildInProgress('Server is being built.')
return render_fault(request, fault) return render_fault(request, fault)
except NotAllowedError:
# Image Backend Unathorized
fault = Forbidden('Request not allowed.')
return render_fault(request, fault)
except Fault, fault: except Fault, fault:
if fault.code >= 500: if fault.code >= 500:
log.exception('API fault') log.exception('API fault')
......
...@@ -54,11 +54,12 @@ import json ...@@ -54,11 +54,12 @@ import json
import warnings import warnings
from operator import itemgetter from operator import itemgetter
from time import gmtime, strftime, time from time import gmtime, strftime
from functools import wraps
from django.conf import settings from django.conf import settings
from pithos.backends.base import NotAllowedError from pithos.backends.base import NotAllowedError as PithosNotAllowedError
PLANKTON_DOMAIN = 'plankton' PLANKTON_DOMAIN = 'plankton'
...@@ -86,6 +87,10 @@ class BackendException(Exception): ...@@ -86,6 +87,10 @@ class BackendException(Exception):
pass pass
class NotAllowedError(BackendException):
pass
from pithos.backends.util import PithosBackendPool from pithos.backends.util import PithosBackendPool
POOL_SIZE = 8 POOL_SIZE = 8
_pithos_backend_pool = \ _pithos_backend_pool = \
...@@ -98,6 +103,16 @@ def get_pithos_backend(): ...@@ -98,6 +103,16 @@ def get_pithos_backend():
return _pithos_backend_pool.pool_get() return _pithos_backend_pool.pool_get()
def handle_backend_exceptions(func):
@wraps(func)
def wrapper(*args, **kwargs):
try:
return func(*args, **kwargs)
except PithosNotAllowedError:
raise NotAllowedError()
return wrapper
class ImageBackend(object): class ImageBackend(object):
"""A wrapper arround the pithos backend to simplify image handling.""" """A wrapper arround the pithos backend to simplify image handling."""
...@@ -109,6 +124,7 @@ class ImageBackend(object): ...@@ -109,6 +124,7 @@ class ImageBackend(object):
self.backend = get_pithos_backend() self.backend = get_pithos_backend()
warnings.filters = original_filters # Restore warnings warnings.filters = original_filters # Restore warnings
@handle_backend_exceptions
def _get_image(self, location): def _get_image(self, location):
def format_timestamp(t): def format_timestamp(t):
return strftime('%Y-%m-%d %H:%M:%S', gmtime(t)) return strftime('%Y-%m-%d %H:%M:%S', gmtime(t))
...@@ -159,6 +175,7 @@ class ImageBackend(object): ...@@ -159,6 +175,7 @@ class ImageBackend(object):
return image return image
@handle_backend_exceptions
def _get_meta(self, location, version=None): def _get_meta(self, location, version=None):
account, container, object = split_location(location) account, container, object = split_location(location)
try: try:
...@@ -167,12 +184,14 @@ class ImageBackend(object): ...@@ -167,12 +184,14 @@ class ImageBackend(object):
except NameError: except NameError:
return None return None
@handle_backend_exceptions
def _get_permissions(self, location): def _get_permissions(self, location):
account, container, object = split_location(location) account, container, object = split_location(location)
action, path, permissions = self.backend.get_object_permissions( action, path, permissions = self.backend.get_object_permissions(
self.user, account, container, object) self.user, account, container, object)
return permissions return permissions
@handle_backend_exceptions
def _store(self, f, size=None): def _store(self, f, size=None):
"""Breaks data into blocks and stores them in the backend""" """Breaks data into blocks and stores them in the backend"""
...@@ -193,6 +212,7 @@ class ImageBackend(object): ...@@ -193,6 +212,7 @@ class ImageBackend(object):
return hashmap, bytes return hashmap, bytes
@handle_backend_exceptions
def _update(self, location, size, hashmap, meta, permissions): def _update(self, location, size, hashmap, meta, permissions):
account, container, object = split_location(location) account, container, object = split_location(location)
self.backend.update_object_hashmap(self.user, account, container, self.backend.update_object_hashmap(self.user, account, container,
...@@ -200,6 +220,7 @@ class ImageBackend(object): ...@@ -200,6 +220,7 @@ class ImageBackend(object):
permissions=permissions) permissions=permissions)
self._update_meta(location, meta, replace=True) self._update_meta(location, meta, replace=True)
@handle_backend_exceptions
def _update_meta(self, location, meta, replace=False): def _update_meta(self, location, meta, replace=False):
account, container, object = split_location(location) account, container, object = split_location(location)
...@@ -213,11 +234,13 @@ class ImageBackend(object): ...@@ -213,11 +234,13 @@ class ImageBackend(object):
self.backend.update_object_meta(self.user, account, container, object, self.backend.update_object_meta(self.user, account, container, object,
PLANKTON_DOMAIN, prefixed, replace) PLANKTON_DOMAIN, prefixed, replace)
@handle_backend_exceptions
def _update_permissions(self, location, permissions): def _update_permissions(self, location, permissions):
account, container, object = split_location(location) account, container, object = split_location(location)
self.backend.update_object_permissions(self.user, account, container, self.backend.update_object_permissions(self.user, account, container,
object, permissions) object, permissions)
@handle_backend_exceptions
def add_user(self, image_id, user): def add_user(self, image_id, user):
image = self.get_image(image_id) image = self.get_image(image_id)
assert image, "Image not found" assert image, "Image not found"
...@@ -232,11 +255,13 @@ class ImageBackend(object): ...@@ -232,11 +255,13 @@ class ImageBackend(object):
def close(self): def close(self):
self.backend.close() self.backend.close()
@handle_backend_exceptions
def delete(self, image_id): def delete(self, image_id):
image = self.get_image(image_id) image = self.get_image(image_id)
account, container, object = split_location(image['location']) account, container, object = split_location(image['location'])
self.backend.delete_object(self.user, account, container, object) self.backend.delete_object(self.user, account, container, object)
@handle_backend_exceptions
def get_data(self, location): def get_data(self, location):
account, container, object = split_location(location) account, container, object = split_location(location)
size, hashmap = self.backend.get_object_hashmap(self.user, account, size, hashmap = self.backend.get_object_hashmap(self.user, account,
...@@ -245,6 +270,7 @@ class ImageBackend(object): ...@@ -245,6 +270,7 @@ class ImageBackend(object):
assert len(data) == size assert len(data) == size
return data return data
@handle_backend_exceptions
def get_image(self, image_id): def get_image(self, image_id):
try: try:
account, container, object = self.backend.get_uuid(self.user, account, container, object = self.backend.get_uuid(self.user,
...@@ -255,6 +281,7 @@ class ImageBackend(object): ...@@ -255,6 +281,7 @@ class ImageBackend(object):
location = get_location(account, container, object) location = get_location(account, container, object)
return self._get_image(location) return self._get_image(location)
@handle_backend_exceptions
def _iter(self, public=False, filters=None, shared_from=None): def _iter(self, public=False, filters=None, shared_from=None):
filters = filters or {} filters = filters or {}
...@@ -301,7 +328,7 @@ class ImageBackend(object): ...@@ -301,7 +328,7 @@ class ImageBackend(object):
def iter_shared(self, filters=None, member=None): def iter_shared(self, filters=None, member=None):
"""Iter over images shared to member""" """Iter over images shared to member"""
return self._iter(filters=filters) return self._iter(filters=filters, shared_from=member)
def list(self, filters=None, params={}): def list(self, filters=None, params={}):
"""Return all images available to the user""" """Return all images available to the user"""
...@@ -326,6 +353,7 @@ class ImageBackend(object): ...@@ -326,6 +353,7 @@ class ImageBackend(object):
permissions = self._get_permissions(image['location']) permissions = self._get_permissions(image['location'])
return [user for user in permissions.get('read', []) if user != '*'] return [user for user in permissions.get('read', []) if user != '*']
@handle_backend_exceptions
def put(self, name, f, params): def put(self, name, f, params):
assert 'checksum' not in params, "Passing a checksum is not supported" assert 'checksum' not in params, "Passing a checksum is not supported"
assert 'id' not in params, "Passing an ID is not supported" assert 'id' not in params, "Passing an ID is not supported"
...@@ -353,6 +381,7 @@ class ImageBackend(object): ...@@ -353,6 +381,7 @@ class ImageBackend(object):
self._update(location, size, hashmap, meta, permissions) self._update(location, size, hashmap, meta, permissions)
return self._get_image(location) return self._get_image(location)
@handle_backend_exceptions
def register(self, name, location, params): def register(self, name, location, params):
assert 'id' not in params, "Passing an ID is not supported" assert 'id' not in params, "Passing an ID is not supported"
assert location.startswith('pithos://'), "Invalid location" assert location.startswith('pithos://'), "Invalid location"
...@@ -392,6 +421,7 @@ class ImageBackend(object): ...@@ -392,6 +421,7 @@ class ImageBackend(object):
self._update_permissions(location, permissions) self._update_permissions(location, permissions)
return self._get_image(location) return self._get_image(location)
@handle_backend_exceptions
def remove_user(self, image_id, user): def remove_user(self, image_id, user):
image = self.get_image(image_id) image = self.get_image(image_id)
assert image, "Image not found" assert image, "Image not found"
...@@ -404,6 +434,7 @@ class ImageBackend(object): ...@@ -404,6 +434,7 @@ class ImageBackend(object):
return # User did not have access anyway return # User did not have access anyway
self._update_permissions(location, permissions) self._update_permissions(location, permissions)
@handle_backend_exceptions
def replace_users(self, image_id, users): def replace_users(self, image_id, users):
image = self.get_image(image_id) image = self.get_image(image_id)
assert image, "Image not found" assert image, "Image not found"
...@@ -415,6 +446,7 @@ class ImageBackend(object): ...@@ -415,6 +446,7 @@ class ImageBackend(object):
permissions['read'].append('*') permissions['read'].append('*')
self._update_permissions(location, permissions) self._update_permissions(location, permissions)
@handle_backend_exceptions
def update(self, image_id, params): def update(self, image_id, params):
image = self.get_image(image_id) image = self.get_image(image_id)
assert image, "Image not found" assert image, "Image not found"
...@@ -437,4 +469,3 @@ class ImageBackend(object): ...@@ -437,4 +469,3 @@ class ImageBackend(object):
self._update_meta(location, meta) self._update_meta(location, meta)
return self.get_image(image_id) return self.get_image(image_id)
...@@ -31,8 +31,6 @@ ...@@ -31,8 +31,6 @@
# interpreted as representing official policies, either expressed # interpreted as representing official policies, either expressed
# or implied, of GRNET S.A. # or implied, of GRNET S.A.
import datetime
from functools import wraps from functools import wraps
from logging import getLogger from logging import getLogger
from traceback import format_exc from traceback import format_exc
...@@ -42,9 +40,8 @@ from django.http import (HttpResponse, HttpResponseBadRequest, ...@@ -42,9 +40,8 @@ from django.http import (HttpResponse, HttpResponseBadRequest,
HttpResponseServerError, HttpResponseForbidden) HttpResponseServerError, HttpResponseForbidden)
from synnefo.lib.astakos import get_user from synnefo.lib.astakos import get_user
from synnefo.plankton.backend import ImageBackend, BackendException from synnefo.plankton.backend import (ImageBackend, BackendException,
NotAllowedError)
from pithos.backends.base import NotAllowedError
log = getLogger('synnefo.plankton') log = getLogger('synnefo.plankton')
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment