Statistics
| Branch: | Tag: | Revision:

root / snf-astakos-app / astakos / im / management / commands / astakos-quota.py @ cb14cc6c

History | View | Annotate | Download (7.4 kB)

1 f557d10a Giorgos Korfiatis
# Copyright 2012, 2013 GRNET S.A. All rights reserved.
2 fc1e2f02 Sofia Papagiannaki
#
3 fc1e2f02 Sofia Papagiannaki
# Redistribution and use in source and binary forms, with or
4 fc1e2f02 Sofia Papagiannaki
# without modification, are permitted provided that the following
5 fc1e2f02 Sofia Papagiannaki
# conditions are met:
6 fc1e2f02 Sofia Papagiannaki
#
7 fc1e2f02 Sofia Papagiannaki
#   1. Redistributions of source code must retain the above
8 fc1e2f02 Sofia Papagiannaki
#      copyright notice, this list of conditions and the following
9 fc1e2f02 Sofia Papagiannaki
#      disclaimer.
10 fc1e2f02 Sofia Papagiannaki
#
11 fc1e2f02 Sofia Papagiannaki
#   2. Redistributions in binary form must reproduce the above
12 fc1e2f02 Sofia Papagiannaki
#      copyright notice, this list of conditions and the following
13 fc1e2f02 Sofia Papagiannaki
#      disclaimer in the documentation and/or other materials
14 fc1e2f02 Sofia Papagiannaki
#      provided with the distribution.
15 fc1e2f02 Sofia Papagiannaki
#
16 fc1e2f02 Sofia Papagiannaki
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
17 fc1e2f02 Sofia Papagiannaki
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 fc1e2f02 Sofia Papagiannaki
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 fc1e2f02 Sofia Papagiannaki
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
20 fc1e2f02 Sofia Papagiannaki
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 fc1e2f02 Sofia Papagiannaki
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 fc1e2f02 Sofia Papagiannaki
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23 fc1e2f02 Sofia Papagiannaki
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24 fc1e2f02 Sofia Papagiannaki
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 fc1e2f02 Sofia Papagiannaki
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26 fc1e2f02 Sofia Papagiannaki
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 fc1e2f02 Sofia Papagiannaki
# POSSIBILITY OF SUCH DAMAGE.
28 fc1e2f02 Sofia Papagiannaki
#
29 fc1e2f02 Sofia Papagiannaki
# The views and conclusions contained in the software and
30 fc1e2f02 Sofia Papagiannaki
# documentation are those of the authors and should not be
31 fc1e2f02 Sofia Papagiannaki
# interpreted as representing official policies, either expressed
32 fc1e2f02 Sofia Papagiannaki
# or implied, of GRNET S.A.
33 fc1e2f02 Sofia Papagiannaki
34 84a3f701 Giorgos Korfiatis
from optparse import make_option
35 84a3f701 Giorgos Korfiatis
from django.core.management.base import BaseCommand, CommandError
36 fc1e2f02 Sofia Papagiannaki
37 aa27f246 Giorgos Korfiatis
from astakos.im.models import AstakosUser
38 3adbd562 Giorgos Korfiatis
from astakos.im.quotas import set_user_quota, list_user_quotas
39 3c049f6d Giorgos Korfiatis
from astakos.im.functions import get_user_by_uuid
40 db8cfc97 Giorgos Korfiatis
from astakos.im.management.commands._common import is_uuid, is_email
41 b830f774 Giorgos Korfiatis
from snf_django.lib.db.transaction import commit_on_success_strict
42 fc1e2f02 Sofia Papagiannaki
43 9a06d96f Olga Brani
import logging
44 9a06d96f Olga Brani
logger = logging.getLogger(__name__)
45 9a06d96f Olga Brani
46 f557d10a Giorgos Korfiatis
47 84a3f701 Giorgos Korfiatis
class Command(BaseCommand):
48 140da2d1 Giorgos Korfiatis
    help = "Inspect quotaholder status"
49 5ce3ce4f Sofia Papagiannaki
50 84a3f701 Giorgos Korfiatis
    option_list = BaseCommand.option_list + (
51 f557d10a Giorgos Korfiatis
        make_option('--list',
52 f557d10a Giorgos Korfiatis
                    action='store_true',
53 f557d10a Giorgos Korfiatis
                    dest='list',
54 f557d10a Giorgos Korfiatis
                    default=False,
55 f557d10a Giorgos Korfiatis
                    help="List all quotas (default)"),
56 f557d10a Giorgos Korfiatis
        make_option('--verify',
57 84a3f701 Giorgos Korfiatis
                    action='store_true',
58 f557d10a Giorgos Korfiatis
                    dest='verify',
59 f557d10a Giorgos Korfiatis
                    default=False,
60 f557d10a Giorgos Korfiatis
                    help="Check if quotaholder is in sync with astakos"),
61 140da2d1 Giorgos Korfiatis
        make_option('--sync',
62 84a3f701 Giorgos Korfiatis
                    action='store_true',
63 140da2d1 Giorgos Korfiatis
                    dest='sync',
64 84a3f701 Giorgos Korfiatis
                    default=False,
65 140da2d1 Giorgos Korfiatis
                    help="Sync quotaholder"),
66 db8cfc97 Giorgos Korfiatis
        make_option('--user',
67 db8cfc97 Giorgos Korfiatis
                    metavar='<uuid or email>',
68 db8cfc97 Giorgos Korfiatis
                    dest='user',
69 db8cfc97 Giorgos Korfiatis
                    help="List quotas for a specified user"),
70 84a3f701 Giorgos Korfiatis
    )
71 84a3f701 Giorgos Korfiatis
72 3adbd562 Giorgos Korfiatis
    @commit_on_success_strict()
73 84a3f701 Giorgos Korfiatis
    def handle(self, *args, **options):
74 140da2d1 Giorgos Korfiatis
        sync = options['sync']
75 2ef1e2d7 Giorgos Korfiatis
        verify = options['verify']
76 db8cfc97 Giorgos Korfiatis
        user_ident = options['user']
77 2ef1e2d7 Giorgos Korfiatis
        list_only = not sync and not verify
78 2ef1e2d7 Giorgos Korfiatis
79 f557d10a Giorgos Korfiatis
80 db8cfc97 Giorgos Korfiatis
        if user_ident is not None:
81 3adbd562 Giorgos Korfiatis
            users = [self.get_user(user_ident)]
82 db8cfc97 Giorgos Korfiatis
        else:
83 3adbd562 Giorgos Korfiatis
            users = AstakosUser.objects.verified()
84 db8cfc97 Giorgos Korfiatis
85 3adbd562 Giorgos Korfiatis
        try:
86 3adbd562 Giorgos Korfiatis
            qh_limits, qh_quotas, astakos_i, diff_q = list_user_quotas(users)
87 3adbd562 Giorgos Korfiatis
        except BaseException as e:
88 3adbd562 Giorgos Korfiatis
            logger.exception(e)
89 3adbd562 Giorgos Korfiatis
            raise CommandError("Failed to compute quotas.")
90 3adbd562 Giorgos Korfiatis
91 3adbd562 Giorgos Korfiatis
        info = {}
92 3adbd562 Giorgos Korfiatis
        for user in users:
93 3adbd562 Giorgos Korfiatis
            info[user.uuid] = user.email
94 f557d10a Giorgos Korfiatis
95 2ef1e2d7 Giorgos Korfiatis
        if list_only:
96 0da5e49a Giorgos Korfiatis
            self.list_quotas(qh_quotas, astakos_i, info)
97 2ef1e2d7 Giorgos Korfiatis
        else:
98 2ef1e2d7 Giorgos Korfiatis
            if verify:
99 0da5e49a Giorgos Korfiatis
                self.print_verify(qh_limits, diff_q)
100 2ef1e2d7 Giorgos Korfiatis
            if sync:
101 3adbd562 Giorgos Korfiatis
                try:
102 3adbd562 Giorgos Korfiatis
                    set_user_quota(diff_q)
103 3adbd562 Giorgos Korfiatis
                except BaseException as e:
104 3adbd562 Giorgos Korfiatis
                    logger.exception(e)
105 3adbd562 Giorgos Korfiatis
                    raise CommandError("Failed to sync quotas.")
106 2ef1e2d7 Giorgos Korfiatis
                self.print_sync(diff_q)
107 f557d10a Giorgos Korfiatis
108 3adbd562 Giorgos Korfiatis
    def get_user(self, user_ident):
109 db8cfc97 Giorgos Korfiatis
        if is_uuid(user_ident):
110 db8cfc97 Giorgos Korfiatis
            try:
111 db8cfc97 Giorgos Korfiatis
                user = AstakosUser.objects.get(uuid=user_ident)
112 db8cfc97 Giorgos Korfiatis
            except AstakosUser.DoesNotExist:
113 db8cfc97 Giorgos Korfiatis
                raise CommandError('Not found user having uuid: %s' %
114 db8cfc97 Giorgos Korfiatis
                                   user_ident)
115 db8cfc97 Giorgos Korfiatis
        elif is_email(user_ident):
116 db8cfc97 Giorgos Korfiatis
            try:
117 db8cfc97 Giorgos Korfiatis
                user = AstakosUser.objects.get(username=user_ident)
118 db8cfc97 Giorgos Korfiatis
            except AstakosUser.DoesNotExist:
119 db8cfc97 Giorgos Korfiatis
                raise CommandError('Not found user having email: %s' %
120 db8cfc97 Giorgos Korfiatis
                                   user_ident)
121 db8cfc97 Giorgos Korfiatis
        else:
122 db8cfc97 Giorgos Korfiatis
            raise CommandError('Please specify user by uuid or email')
123 db8cfc97 Giorgos Korfiatis
124 cb0c401a Giorgos Korfiatis
        if not user.email_verified and sync:
125 cb0c401a Giorgos Korfiatis
            raise CommandError('User %s is not verified.' % user.uuid)
126 cb0c401a Giorgos Korfiatis
127 3adbd562 Giorgos Korfiatis
        return user
128 f557d10a Giorgos Korfiatis
129 0da5e49a Giorgos Korfiatis
    def list_quotas(self, qh_quotas, astakos_initial, info):
130 0da5e49a Giorgos Korfiatis
        labels = ('uuid', 'email', 'source', 'resource', 'initial', 'total', 'usage')
131 0da5e49a Giorgos Korfiatis
        columns = (36, 30, 20, 24, 12, 12, 12)
132 f557d10a Giorgos Korfiatis
133 f557d10a Giorgos Korfiatis
        line = ' '.join(l.rjust(w) for l, w in zip(labels, columns))
134 f557d10a Giorgos Korfiatis
        self.stdout.write(line + '\n')
135 f557d10a Giorgos Korfiatis
        sep = '-' * len(line)
136 f557d10a Giorgos Korfiatis
        self.stdout.write(sep + '\n')
137 f557d10a Giorgos Korfiatis
138 0da5e49a Giorgos Korfiatis
        for holder, holder_quotas in qh_quotas.iteritems():
139 7125062f Giorgos Korfiatis
            h_initial = astakos_initial.get(holder)
140 7125062f Giorgos Korfiatis
            email = info.get(holder, "")
141 0da5e49a Giorgos Korfiatis
            for source, source_quotas in holder_quotas.iteritems():
142 7125062f Giorgos Korfiatis
                s_initial = h_initial.get(source) if h_initial else None
143 0da5e49a Giorgos Korfiatis
                for resource, values in source_quotas.iteritems():
144 7125062f Giorgos Korfiatis
                    initial = s_initial.get(resource) if s_initial else None
145 7125062f Giorgos Korfiatis
                    initial = str(initial)
146 0da5e49a Giorgos Korfiatis
                    capacity = str(values['limit'])
147 480974e6 Giorgos Korfiatis
                    usage = str(values['usage'])
148 0da5e49a Giorgos Korfiatis
149 480974e6 Giorgos Korfiatis
                    fields = (holder, email, source, resource,
150 480974e6 Giorgos Korfiatis
                              initial, capacity, usage)
151 0da5e49a Giorgos Korfiatis
                    output = []
152 0da5e49a Giorgos Korfiatis
                    for field, width in zip(fields, columns):
153 0da5e49a Giorgos Korfiatis
                        s = field.rjust(width)
154 0da5e49a Giorgos Korfiatis
                        output.append(s)
155 0da5e49a Giorgos Korfiatis
156 0da5e49a Giorgos Korfiatis
                    line = ' '.join(output)
157 0da5e49a Giorgos Korfiatis
                    self.stdout.write(line + '\n')
158 f557d10a Giorgos Korfiatis
159 2ef1e2d7 Giorgos Korfiatis
    def print_sync(self, diff_quotas):
160 2ef1e2d7 Giorgos Korfiatis
        size = len(diff_quotas)
161 2ef1e2d7 Giorgos Korfiatis
        if size == 0:
162 2ef1e2d7 Giorgos Korfiatis
            self.stdout.write("No sync needed.\n")
163 2ef1e2d7 Giorgos Korfiatis
        else:
164 2ef1e2d7 Giorgos Korfiatis
            self.stdout.write("Synced %s users:\n" % size)
165 2ef1e2d7 Giorgos Korfiatis
            for holder in diff_quotas.keys():
166 2ef1e2d7 Giorgos Korfiatis
                user = get_user_by_uuid(holder)
167 2ef1e2d7 Giorgos Korfiatis
                self.stdout.write("%s (%s)\n" % (holder, user.username))
168 2ef1e2d7 Giorgos Korfiatis
169 f557d10a Giorgos Korfiatis
    def print_verify(self,
170 f557d10a Giorgos Korfiatis
                     qh_limits,
171 2ef1e2d7 Giorgos Korfiatis
                     diff_quotas):
172 62fda315 Giorgos Korfiatis
173 2ef1e2d7 Giorgos Korfiatis
            for holder, local in diff_quotas.iteritems():
174 f557d10a Giorgos Korfiatis
                registered = qh_limits.pop(holder, None)
175 2ef1e2d7 Giorgos Korfiatis
                user = get_user_by_uuid(holder)
176 3c049f6d Giorgos Korfiatis
                if registered is None:
177 2ef1e2d7 Giorgos Korfiatis
                    self.stdout.write(
178 2ef1e2d7 Giorgos Korfiatis
                        "No quotas for %s (%s) in quotaholder.\n" %
179 2ef1e2d7 Giorgos Korfiatis
                        (holder, user.username))
180 2ef1e2d7 Giorgos Korfiatis
                else:
181 2ef1e2d7 Giorgos Korfiatis
                    self.stdout.write("Quotas differ for %s (%s):\n" %
182 2ef1e2d7 Giorgos Korfiatis
                                      (holder, user.username))
183 3c049f6d Giorgos Korfiatis
                    self.stdout.write("Quotas according to quotaholder:\n")
184 3c049f6d Giorgos Korfiatis
                    self.stdout.write("%s\n" % (registered))
185 3c049f6d Giorgos Korfiatis
                    self.stdout.write("Quotas according to astakos:\n")
186 3c049f6d Giorgos Korfiatis
                    self.stdout.write("%s\n\n" % (local))
187 3c049f6d Giorgos Korfiatis
188 2ef1e2d7 Giorgos Korfiatis
            diffs = len(diff_quotas)
189 3c049f6d Giorgos Korfiatis
            if diffs:
190 3c049f6d Giorgos Korfiatis
                self.stdout.write("Quotas differ for %d users.\n" % (diffs))