Commit 7e73b5d3 authored by Sofia Papagiannaki's avatar Sofia Papagiannaki
Browse files

Integration with updated quotaholder component

parent 05bc5328
......@@ -45,7 +45,7 @@ from astakos.im.api.backends.errors import (
ItemNotExists, ItemExists, MissingIdentifier, MultipleItemsExist
)
from astakos.im.util import reserved_email, model_to_dict
from astakos.im.endpoints.quotaholder import get_quota
from astakos.im.endpoints.qh import get_quota
import logging
......@@ -219,9 +219,7 @@ class DjangoBackend(BaseBackend):
@safe
def get_resource_usage(self, user_id):
user = self._lookup_user(user_id)
r = get_quota((user,))
print '>>>', r
c, data = r
c, data = get_quota((user,))
resources = []
append = resources.append
for t in data:
......
# Copyright 2011-2012 GRNET S.A. All rights reserved.
#
# Redistribution and use in source and binary forms, with or
# without modification, are permitted provided that the following
# conditions are met:
#
# 1. Redistributions of source code must retain the above
# copyright notice, this list of conditions and the following
# disclaimer.
#
# 2. Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following
# disclaimer in the documentation and/or other materials
# provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#
# The views and conclusions contained in the software and
# documentation are those of the authors and should not be
# interpreted as representing official policies, either expressed
# or implied, of GRNET S.A.
from django.db import IntegrityError, transaction
from django.core.exceptions import ObjectDoesNotExist
from functools import wraps
from smtplib import SMTPException
from astakos.im.models import (
AstakosUser, AstakosGroup, GroupKind, Resource, Service, RESOURCE_SEPARATOR
)
from astakos.im.api.backends.base import BaseBackend, SuccessResult, FailureResult
from astakos.im.api.backends.errors import (
ItemNotExists, ItemExists, MissingIdentifier, MultipleItemsExist
)
from astakos.im.util import reserved_email, model_to_dict
from astakos.im.endpoints.quotaholder import get_quota
import logging
logger = logging.getLogger(__name__)
DEFAULT_CONTENT_TYPE = None
def safe(func):
"""Decorator function for views that implement an API method."""
@transaction.commit_manually
@wraps(func)
def wrapper(self, *args, **kwargs):
logger.debug('%s %s %s' % (func, args, kwargs))
try:
data = func(self, *args, **kwargs) or ()
except Exception, e:
logger.exception(e)
transaction.rollback()
return FailureResult(getattr(e, 'message', e))
else:
transaction.commit()
return SuccessResult(data)
return wrapper
class DjangoBackend(BaseBackend):
def _lookup_object(self, model, **kwargs):
"""
Returns an object of the specific model matching the given lookup
parameters.
"""
if not kwargs:
raise MissingIdentifier
try:
return model.objects.get(**kwargs)
except model.DoesNotExist:
raise ItemNotExists(model._meta.verbose_name, **kwargs)
except model.MultipleObjectsReturned:
raise MultipleItemsExist(model._meta.verbose_name, **kwargs)
def _lookup_user(self, id):
"""
Returns an AstakosUser having this id.
"""
if not isinstance(id, int):
raise TypeError('User id should be of type int')
return self._lookup_object(AstakosUser, id=id)
def _lookup_service(self, id):
"""
Returns an Service having this id.
"""
if not isinstance(id, int):
raise TypeError('Service id should be of type int')
return self._lookup_object(Service, id=id)
def _list(self, model, filter=()):
q = model.objects.all()
if filter:
q = q.filter(id__in=filter)
return map(lambda o: model_to_dict(o, exclude=[]), q)
def _create_object(self, model, **kwargs):
o = model.objects.create(**kwargs)
o.save()
return o
def _update_object(self, model, id, save=True, **kwargs):
o = self._lookup_object(model, id=id)
if kwargs:
o.__dict__.update(kwargs)
if save:
o.save()
return o
@safe
def update_user(self, user_id, renew_token=False, **kwargs):
user = self._update_object(AstakosUser, user_id, save=False, **kwargs)
if renew_token:
user.renew_token()
if kwargs or renew_token:
user.save()
@safe
def create_user(self, **kwargs):
policies = kwargs.pop('policies', ())
permissions = kwargs.pop('permissions', ())
groups = kwargs.pop('groups', ())
password = kwargs.pop('password', None)
u = self._create_object(AstakosUser, **kwargs)
if password:
u.set_password(password)
u.permissions = permissions
u.policies = policies
u.extended_groups = groups
return self._list(AstakosUser, filter=(u.id,))
@safe
def add_policies(self, user_id, update=False, policies=()):
user = self._lookup_user(user_id)
rejected = []
append = rejected.append
for p in policies:
service = p.get('service')
resource = p.get('resource')
uplimit = p.get('uplimit')
try:
user.add_policy(service, resource, uplimit, update)
except (ObjectDoesNotExist, IntegrityError), e:
append((service, resource, e))
return rejected
@safe
def remove_policies(self, user_id, policies=()):
user = self._lookup_user(user_id)
if not user:
return user_id
rejected = []
append = rejected.append
for p in policies:
service = p.get('service')
resource = p.get('resource')
try:
user.delete_policy(service, resource)
except ObjectDoesNotExist, e:
append((service, resource, e))
return rejected
@safe
def add_permissions(self, user_id, permissions=()):
user = self._lookup_user(user_id)
rejected = []
append = rejected.append
for p in permissions:
try:
user.add_permission(p)
except IntegrityError, e:
append((p, e))
return rejected
@safe
def remove_permissions(self, user_id, permissions=()):
user = self._lookup_user(user_id)
rejected = []
append = rejected.append
for p in permissions:
try:
user.remove_permission(p)
except (ObjectDoesNotExist, IntegrityError), e:
append((p, e))
return rejected
@safe
def invite_users(self, senderid, recipients=()):
user = self._lookup_user(senderid)
rejected = []
append = rejected.append
for r in recipients:
try:
user.invite(r.get('email'), r.get('realname'))
except (IntegrityError, SMTPException), e:
append((email, e))
return rejected
@safe
def list_users(self, filter=()):
return self._list(AstakosUser, filter=filter)
@safe
def get_resource_usage(self, user_id):
user = self._lookup_user(user_id)
c, data = get_quota((user,))
resources = []
append = resources.append
for t in data:
t = (i if i else 0 for i in t)
(entity, name, quantity, capacity, importLimit, exportLimit,
imported, exported, returned, released, flags) = t
service, sep, resource = name.partition(RESOURCE_SEPARATOR)
resource = Resource.objects.select_related().get(
service__name=service, name=resource)
d = dict(name=name,
description=resource.desc,
unit=resource.unit or '',
maxValue=quantity + capacity,
currValue=quantity + imported - released - exported + returned)
append(d)
return resources
@safe
def list_resources(self, filter=()):
return self._list(Resource, filter=filter)
@safe
def create_service(self, **kwargs):
resources = kwargs.pop('resources', ())
s = self._create_object(Service, **kwargs)
s.resources = resources
return self._list(Service, filter=(s.id,))
@safe
def remove_services(self, ids=()):
# TODO return information for unknown ids
q = Service.objects.filter(id__in=ids)
q.delete()
@safe
def update_service(self, service_id, renew_token=False, **kwargs):
s = self._update_object(Service, service_id, save=False, **kwargs)
if renew_token:
s.renew_token()
if kwargs or renew_token:
s.save()
@safe
def add_resources(self, service_id, update=False, resources=()):
s = self._lookup_service(service_id)
rejected = []
append = rejected.append
for r in resources:
try:
rr = r.copy()
resource_id = rr.pop('id', None)
if update:
if not resource_id:
raise MissingIdentifier
resource = self._update_object(Resource, resource_id, **rr)
else:
resource = self._create_object(Resource, service=s, **rr)
except Exception, e:
append((r, e))
return rejected
@safe
def remove_resources(self, service_id, ids=()):
# TODO return information for unknown ids
q = Resource.objects.filter(service__id=service_id,
id__in=ids)
q.delete()
@safe
def create_group(self, **kwargs):
policies = kwargs.pop('policies', ())
permissions = kwargs.pop('permissions', ())
members = kwargs.pop('members', ())
owners = kwargs.pop('owners', ())
kwargs['kind'] = self._lookup_object(
GroupKind, name=kwargs.get('kind', 'course')
)
g = self._create_object(AstakosGroup, **kwargs)
g.permissions = permissions
g.policies = policies
# g.members = members
g.owners = owners
return self._list(AstakosGroup, filter=(g.id,))
\ No newline at end of file
from commissioning.api.specificator import (
from commissioning.specificator import (
CanonifyException, SpecifyException,
Specificator, Null, Integer, Text,
Tuple, ListOf, Dict, Args)
......
......@@ -43,7 +43,7 @@ from django.utils.translation import ugettext as _
from astakos.im.settings import QUOTA_HOLDER_URL, LOGGING_LEVEL
if QUOTA_HOLDER_URL:
from commissioning.clients.quotaholder import QuotaholderHTTP
from quotaholder.clients.kamaki import quotaholder_client
ENTITY_KEY = '1'
......@@ -54,20 +54,20 @@ logger = logging.getLogger(__name__)
inf = float('inf')
def call(func_name):
"""Decorator function for QuotaholderHTTP client calls."""
"""Decorator function for Quotaholder client calls."""
def decorator(payload_func):
@wraps(payload_func)
def wrapper(entities=(), client=None, **kwargs):
if not entities:
return ()
return client, ()
if not QUOTA_HOLDER_URL:
return ()
return client, ()
c = client or QuotaholderHTTP(QUOTA_HOLDER_URL)
c = client or quotaholder_client(QUOTA_HOLDER_URL)
func = c.__dict__.get(func_name)
if not func:
return c,
return c, ()
data = payload_func(entities, client, **kwargs)
if not data:
......@@ -287,7 +287,7 @@ def timeline_charge(entity, resource, after, before, details, charge_type):
m = 'charge type %s not supported' % charge_type
raise ValueError(m)
quotaholder = QuotaholderHTTP(QUOTA_HOLDER_URL)
quotaholder = quotaholder_client(QUOTA_HOLDER_URL)
timeline = quotaholder.get_timeline(
context={},
after=after,
......
......@@ -35,7 +35,7 @@ from django.core.management.base import BaseCommand, CommandError
from django.db.utils import IntegrityError
from astakos.im.models import AstakosUser, Resource
from astakos.im.endpoints.quotaholder import register_users, register_resources
from astakos.im.endpoints.qh import register_users, register_resources
import logging
logger = logging.getLogger(__name__)
......
......@@ -57,7 +57,7 @@ from django.db.models import Q
from astakos.im.settings import (DEFAULT_USER_LEVEL, INVITATIONS_PER_LEVEL,
AUTH_TOKEN_DURATION, BILLING_FIELDS,
EMAILCHANGE_ACTIVATION_DAYS, LOGGING_LEVEL)
from astakos.im.endpoints.quotaholder import (register_users, send_quota,
from astakos.im.endpoints.qh import (register_users, send_quota,
register_resources)
from astakos.im.endpoints.aquarium.producer import report_user_event
from astakos.im.functions import send_invitation
......
......@@ -36,7 +36,7 @@ from celery.schedules import crontab
from functools import wraps
from astakos.im.endpoints.quotaholder import send_quota
from astakos.im.endpoints.qh import send_quota
from astakos.im.endpoints.aquarium.producer import (report_credits_event,
report_user_event
)
......
......@@ -85,7 +85,7 @@ from astakos.im.functions import (send_feedback, SendMailError,
switch_account_to_shibboleth,
send_group_creation_notification,
SendNotificationError)
from astakos.im.endpoints.quotaholder import timeline_charge
from astakos.im.endpoints.qh import timeline_charge
from astakos.im.settings import (COOKIE_NAME, COOKIE_DOMAIN, LOGOUT_NEXT,
LOGGING_LEVEL, PAGINATE_BY)
from astakos.im.tasks import request_billing
......
......@@ -81,9 +81,10 @@ INSTALL_REQUIRES = [
'recaptcha-client>=1.0.5',
'django-ratelimit==0.1',
'commissioning',
'quotaholder',
'celery',
'requests',
'inflect',
'inflect'
#TODO add commissioning
]
......
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