Revision f8cac8c7

b/snf-astakos-app/astakos/im/functions.py
42 42
from django.db.models import Q
43 43

  
44 44
from synnefo_branding.utils import render_to_string
45
from synnefo.util.keypath import set_path
45 46

  
46 47
from synnefo.lib import join_urls
47 48
from astakos.im.models import AstakosUser, Invitation, ProjectMembership, \
......
1178 1179
    usage = {}
1179 1180
    for user in users:
1180 1181
        uuid = user.uuid
1181
        usage[uuid] = len(apps_d.get(uuid, []))
1182
        set_path(usage,
1183
                 [uuid, user.base_project.uuid, quotas.PENDING_APP_RESOURCE],
1184
                 len(apps_d.get(uuid, [])), createpath=True)
1182 1185
    return usage
1183 1186

  
1184 1187

  
b/snf-astakos-app/astakos/im/management/commands/reconcile-resources-astakos.py
32 32
# or implied, of GRNET S.A.
33 33

  
34 34
from optparse import make_option
35
from datetime import datetime
35 36

  
36 37
from django.core.management.base import BaseCommand, CommandError
37 38
from django.db import transaction
38 39

  
40
from snf_django.utils import reconcile
39 41
from snf_django.management.utils import pprint_table
40 42
from astakos.im.models import Component, AstakosUser
41
from astakos.im.quotas import service_get_quotas, SYSTEM
43
from astakos.im import quotas
42 44
from astakos.im.functions import count_pending_app
43 45
import astakos.quotaholder_app.callpoint as qh
44 46
import astakos.quotaholder_app.exception as qh_exception
......
56 58
        make_option("--userid", dest="userid",
57 59
                    default=None,
58 60
                    help="Reconcile resources only for this user"),
61
        make_option("--project",
62
                    help="Reconcile resources only for this project"),
59 63
        make_option("--fix", dest="fix",
60 64
                    default=False,
61 65
                    action="store_true",
......
72 76
        write = self.stderr.write
73 77
        force = options['force']
74 78
        userid = options['userid']
79
        project = options['project']
80

  
81
        RESOURCES = [quotas.PENDING_APP_RESOURCE]
75 82

  
76 83
        try:
77 84
            astakos = Component.objects.get(name="astakos")
......
79 86
            raise CommandError("Component 'astakos' not found.")
80 87

  
81 88
        query = [userid] if userid is not None else None
82
        qh_holdings = service_get_quotas(astakos, query)
89
        qh_holdings = quotas.service_get_quotas(astakos, query)
90
        query = [project] if project is not None else None
91
        qh_project_holdings = quotas.service_get_project_quotas(astakos, query)
83 92

  
84 93
        if userid is None:
85
            users = AstakosUser.objects.accepted()
94
            users = AstakosUser.objects.accepted().select_related(
95
                'base_project')
86 96
        else:
87 97
            try:
88 98
                user = AstakosUser.objects.get(uuid=userid)
......
94 104

  
95 105
        db_holdings = count_pending_app(users)
96 106

  
97
        pending_exists = False
98
        unknown_user_exists = False
99
        unsynced = []
100
        for user in users:
101
            uuid = user.uuid
102
            db_value = db_holdings.get(uuid, 0)
103
            try:
104
                qh_all = qh_holdings[uuid]
105
            except KeyError:
106
                write("User '%s' does not exist in Quotaholder!\n" % uuid)
107
                unknown_user_exists = True
108
                continue
109

  
110
            # Assuming only one source
111
            system_qh = qh_all.get(SYSTEM, {})
112
            # Assuming only one resource
113
            resource = 'astakos.pending_app'
114
            try:
115
                qh_values = system_qh[resource]
116
                qh_value = qh_values['usage']
117
                qh_pending = qh_values['pending']
118
            except KeyError:
119
                write("Resource '%s' does not exist in Quotaholder"
120
                      " for user '%s'!\n" % (resource, uuid))
121
                continue
122
            if qh_pending:
123
                write("Pending commission. User '%s', resource '%s'.\n" %
124
                      (uuid, resource))
125
                pending_exists = True
126
                continue
127
            if db_value != qh_value:
128
                data = (uuid, resource, db_value, qh_value)
129
                unsynced.append(data)
130

  
131
        headers = ("User", "Resource", "Astakos", "Quotaholder")
107
        db_project_holdings = {}
108
        for user, user_holdings in db_holdings.iteritems():
109
            db_project_holdings.update(user_holdings)
110

  
111
        unsynced_users, users_pending, users_unknown =\
112
            reconcile.check_users(self.stderr, RESOURCES,
113
                                  db_holdings, qh_holdings)
114

  
115
        unsynced_projects, projects_pending, projects_unknown =\
116
            reconcile.check_projects(self.stderr, RESOURCES,
117
                                     db_project_holdings, qh_project_holdings)
118
        pending_exists = users_pending or projects_pending
119
        unknown_exists = users_unknown or projects_unknown
120

  
121
        headers = ("Type", "Holder", "Source", "Resource",
122
                   "Astakos", "Quotaholder")
123
        unsynced = unsynced_users + unsynced_projects
132 124
        if unsynced:
133 125
            pprint_table(self.stdout, unsynced, headers)
134 126
            if options["fix"]:
135
                provisions = map(create_provision, unsynced)
127
                user_provisions = create_user_provisions(unsynced_users)
128
                project_provisions = create_project_provisions(
129
                    unsynced_projects)
130
                provisions = user_provisions + project_provisions
131
                name = ("client: reconcile-resources-astakos, time: %s"
132
                        % datetime.now())
136 133
                try:
137 134
                    s = qh.issue_commission('astakos', provisions,
138
                                            name='RECONCILE', force=force)
135
                                            name=name, force=force)
139 136
                except qh_exception.NoCapacityError:
140 137
                    write("Reconciling failed because a limit has been "
141 138
                          "reached. Use --force to ignore the check.\n")
......
147 144
        if pending_exists:
148 145
            write("Found pending commissions. "
149 146
                  "This is probably a bug. Please report.\n")
150
        elif not (unsynced or unknown_user_exists):
147
        elif not (unsynced or unknown_exists):
151 148
            write("Everything in sync.\n")
152 149

  
153 150

  
154
def create_provision(provision_info):
155
    user, resource, db_value, qh_value = provision_info
156
    return (user, SYSTEM, resource), (db_value - qh_value)
151
def create_user_provisions(provision_list):
152
    provisions = []
153
    for _, holder, source, resource, db_value, qh_value in provision_list:
154
        value = db_value - qh_value
155
        provisions.append(
156
            quotas.mk_user_provision(holder, source, resource, value))
157
    return provisions
158

  
159

  
160
def create_project_provisions(provision_list):
161
    provisions = []
162
    for _, holder, _, resource, db_value, qh_value in provision_list:
163
        value = db_value - qh_value
164
        provisions.append(
165
            quotas.mk_project_provision(holder, resource, value))
166
    return provisions

Also available in: Unified diff