Statistics
| Branch: | Tag: | Revision:

root / snf-pithos-app / pithos / api / management / commands / reconcile-resources-pithos.py @ eb83c485

History | View | Annotate | Download (6.1 kB)

1 eb83c485 Sofia Papagiannaki
# Copyright 2012, 2013 GRNET S.A. All rights reserved.
2 d1e7d2b4 Sofia Papagiannaki
#
3 d1e7d2b4 Sofia Papagiannaki
# Redistribution and use in source and binary forms, with or
4 d1e7d2b4 Sofia Papagiannaki
# without modification, are permitted provided that the following
5 d1e7d2b4 Sofia Papagiannaki
# conditions are met:
6 d1e7d2b4 Sofia Papagiannaki
#
7 d1e7d2b4 Sofia Papagiannaki
#   1. Redistributions of source code must retain the above
8 d1e7d2b4 Sofia Papagiannaki
#      copyright notice, this list of conditions and the following
9 d1e7d2b4 Sofia Papagiannaki
#      disclaimer.
10 d1e7d2b4 Sofia Papagiannaki
#
11 d1e7d2b4 Sofia Papagiannaki
#   2. Redistributions in binary form must reproduce the above
12 d1e7d2b4 Sofia Papagiannaki
#      copyright notice, this list of conditions and the following
13 d1e7d2b4 Sofia Papagiannaki
#      disclaimer in the documentation and/or other materials
14 d1e7d2b4 Sofia Papagiannaki
#      provided with the distribution.
15 d1e7d2b4 Sofia Papagiannaki
#
16 d1e7d2b4 Sofia Papagiannaki
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
17 d1e7d2b4 Sofia Papagiannaki
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 d1e7d2b4 Sofia Papagiannaki
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 d1e7d2b4 Sofia Papagiannaki
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
20 d1e7d2b4 Sofia Papagiannaki
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 d1e7d2b4 Sofia Papagiannaki
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 d1e7d2b4 Sofia Papagiannaki
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23 d1e7d2b4 Sofia Papagiannaki
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24 d1e7d2b4 Sofia Papagiannaki
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 d1e7d2b4 Sofia Papagiannaki
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26 d1e7d2b4 Sofia Papagiannaki
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 d1e7d2b4 Sofia Papagiannaki
# POSSIBILITY OF SUCH DAMAGE.
28 d1e7d2b4 Sofia Papagiannaki
#
29 d1e7d2b4 Sofia Papagiannaki
# The views and conclusions contained in the software and
30 d1e7d2b4 Sofia Papagiannaki
# documentation are those of the authors and should not be
31 d1e7d2b4 Sofia Papagiannaki
# interpreted as representing official policies, either expressed
32 d1e7d2b4 Sofia Papagiannaki
# or implied, of GRNET S.A.
33 d1e7d2b4 Sofia Papagiannaki
34 eb83c485 Sofia Papagiannaki
from datetime import datetime
35 eb83c485 Sofia Papagiannaki
from django.core.management.base import NoArgsCommand, CommandError
36 d1e7d2b4 Sofia Papagiannaki
37 d1e7d2b4 Sofia Papagiannaki
from optparse import make_option
38 d1e7d2b4 Sofia Papagiannaki
39 d1e7d2b4 Sofia Papagiannaki
from pithos.api.util import get_backend
40 bab17726 Sofia Papagiannaki
41 d758784b Christos Stavrakakis
from snf_django.management import utils
42 bab17726 Sofia Papagiannaki
43 2ff02341 Sofia Papagiannaki
from astakosclient.errors import QuotaLimit, NotFound
44 eb83c485 Sofia Papagiannaki
from snf_django.utils import reconcile
45 d1e7d2b4 Sofia Papagiannaki
46 d1e7d2b4 Sofia Papagiannaki
backend = get_backend()
47 eb83c485 Sofia Papagiannaki
RESOURCES = ['pithos.diskspace']
48 d1e7d2b4 Sofia Papagiannaki
49 30aca88f Sofia Papagiannaki
50 d1e7d2b4 Sofia Papagiannaki
class Command(NoArgsCommand):
51 30aca88f Sofia Papagiannaki
    help = """Reconcile resource usage of Astakos with Pithos DB.
52 30aca88f Sofia Papagiannaki

53 30aca88f Sofia Papagiannaki
    Detect unsynchronized usage between Astakos and Pithos DB resources and
54 30aca88f Sofia Papagiannaki
    synchronize them if specified so.
55 d1e7d2b4 Sofia Papagiannaki

56 30aca88f Sofia Papagiannaki
    """
57 d1e7d2b4 Sofia Papagiannaki
    option_list = NoArgsCommand.option_list + (
58 30aca88f Sofia Papagiannaki
        make_option("--userid", dest="userid",
59 30aca88f Sofia Papagiannaki
                    default=None,
60 30aca88f Sofia Papagiannaki
                    help="Reconcile resources only for this user"),
61 eb83c485 Sofia Papagiannaki
        make_option("--project",
62 eb83c485 Sofia Papagiannaki
                    help="Reconcile resources only for this project"),
63 30aca88f Sofia Papagiannaki
        make_option("--fix", dest="fix",
64 d1e7d2b4 Sofia Papagiannaki
                    default=False,
65 d1e7d2b4 Sofia Papagiannaki
                    action="store_true",
66 30aca88f Sofia Papagiannaki
                    help="Synchronize Astakos quotas with Pithos DB."),
67 30aca88f Sofia Papagiannaki
        make_option("--force",
68 d1e7d2b4 Sofia Papagiannaki
                    default=False,
69 30aca88f Sofia Papagiannaki
                    action="store_true",
70 bab17726 Sofia Papagiannaki
                    help="Override Astakos quotas. Force Astakos to impose "
71 bab17726 Sofia Papagiannaki
                         "the Pithos quota, independently of their value.")
72 d1e7d2b4 Sofia Papagiannaki
    )
73 d1e7d2b4 Sofia Papagiannaki
74 d1e7d2b4 Sofia Papagiannaki
    def handle_noargs(self, **options):
75 eb83c485 Sofia Papagiannaki
        write = self.stdout.write
76 d1e7d2b4 Sofia Papagiannaki
        try:
77 3248f20a Sofia Papagiannaki
            backend.pre_exec()
78 2ff02341 Sofia Papagiannaki
            userid = options['userid']
79 eb83c485 Sofia Papagiannaki
            project = options['project']
80 bab17726 Sofia Papagiannaki
81 2ff02341 Sofia Papagiannaki
            # Get holding from Pithos DB
82 eb83c485 Sofia Papagiannaki
            db_usage = backend.node.node_account_usage(userid, project)
83 eb83c485 Sofia Papagiannaki
            db_project_usage = backend.node.node_project_usage(project)
84 d1e7d2b4 Sofia Papagiannaki
85 2ff02341 Sofia Papagiannaki
            users = set(db_usage.keys())
86 2ff02341 Sofia Papagiannaki
            if userid and userid not in users:
87 ff7accbe Sofia Papagiannaki
                if backend._lookup_account(userid) is None:
88 eb83c485 Sofia Papagiannaki
                    write("User '%s' does not exist in DB!\n" % userid)
89 ff7accbe Sofia Papagiannaki
                    return
90 d1e7d2b4 Sofia Papagiannaki
91 2ff02341 Sofia Papagiannaki
            # Get holding from Quotaholder
92 2ff02341 Sofia Papagiannaki
            try:
93 1f47fbe3 Giorgos Korfiatis
                qh_result = backend.astakosclient.service_get_quotas(userid)
94 2ff02341 Sofia Papagiannaki
            except NotFound:
95 eb83c485 Sofia Papagiannaki
                write("User '%s' does not exist in Quotaholder!\n" % userid)
96 2ff02341 Sofia Papagiannaki
                return
97 2ff02341 Sofia Papagiannaki
98 eb83c485 Sofia Papagiannaki
            try:
99 eb83c485 Sofia Papagiannaki
                qh_project_result = \
100 eb83c485 Sofia Papagiannaki
                    backend.astakosclient.service_get_project_quotas(project)
101 eb83c485 Sofia Papagiannaki
            except NotFound:
102 eb83c485 Sofia Papagiannaki
                write("Project '%s' does not exist in Quotaholder!\n" %
103 eb83c485 Sofia Papagiannaki
                      project)
104 eb83c485 Sofia Papagiannaki
105 eb83c485 Sofia Papagiannaki
            unsynced_users, users_pending, users_unknown =\
106 eb83c485 Sofia Papagiannaki
                reconcile.check_users(self.stderr, RESOURCES,
107 eb83c485 Sofia Papagiannaki
                                      db_usage, qh_result)
108 eb83c485 Sofia Papagiannaki
109 eb83c485 Sofia Papagiannaki
            unsynced_projects, projects_pending, projects_unknown =\
110 eb83c485 Sofia Papagiannaki
            reconcile.check_projects(self.stderr, RESOURCES,
111 eb83c485 Sofia Papagiannaki
                                     db_project_usage, qh_project_result)
112 eb83c485 Sofia Papagiannaki
            pending_exists = users_pending or projects_pending
113 eb83c485 Sofia Papagiannaki
            unknown_exists = users_unknown or projects_unknown
114 eb83c485 Sofia Papagiannaki
115 eb83c485 Sofia Papagiannaki
            headers = ("Type", "Holder", "Source", "Resource",
116 eb83c485 Sofia Papagiannaki
                       "Database", "Quotaholder")
117 eb83c485 Sofia Papagiannaki
            unsynced = unsynced_users + unsynced_projects
118 30aca88f Sofia Papagiannaki
            if unsynced:
119 30aca88f Sofia Papagiannaki
                utils.pprint_table(self.stdout, unsynced, headers)
120 eb83c485 Sofia Papagiannaki
                if options["fix"]:
121 eb83c485 Sofia Papagiannaki
                    force = options["force"]
122 eb83c485 Sofia Papagiannaki
                    name = ("client: reconcile-resources-pithos, time: %s"
123 eb83c485 Sofia Papagiannaki
                            % datetime.now())
124 eb83c485 Sofia Papagiannaki
                    user_provisions = reconcile.create_user_provisions(
125 eb83c485 Sofia Papagiannaki
                        unsynced_users)
126 eb83c485 Sofia Papagiannaki
                    project_provisions = reconcile.create_project_provisions(
127 eb83c485 Sofia Papagiannaki
                        unsynced_projects)
128 205cc8d3 Giorgos Korfiatis
                    try:
129 eb83c485 Sofia Papagiannaki
                        backend.astakosclient.issue_commission_generic(
130 eb83c485 Sofia Papagiannaki
                            user_provisions, project_provisions, name=name,
131 eb83c485 Sofia Papagiannaki
                            force=force, auto_accept=True)
132 205cc8d3 Giorgos Korfiatis
                    except QuotaLimit:
133 eb83c485 Sofia Papagiannaki
                        write("Reconciling failed because a limit has been "
134 eb83c485 Sofia Papagiannaki
                              "reached. Use --force to ignore the check.\n")
135 205cc8d3 Giorgos Korfiatis
                        return
136 eb83c485 Sofia Papagiannaki
                    write("Fixed unsynced resources\n")
137 205cc8d3 Giorgos Korfiatis
138 30aca88f Sofia Papagiannaki
            if pending_exists:
139 eb83c485 Sofia Papagiannaki
                write("Found pending commissions. Run 'snf-manage"
140 eb83c485 Sofia Papagiannaki
                      " reconcile-commissions-pithos'\n")
141 eb83c485 Sofia Papagiannaki
            elif not (unsynced or unknown_exists):
142 eb83c485 Sofia Papagiannaki
                write("Everything in sync.\n")
143 1f47fbe3 Giorgos Korfiatis
        except BaseException as e:
144 3248f20a Sofia Papagiannaki
            backend.post_exec(False)
145 eb83c485 Sofia Papagiannaki
            raise CommandError(e)
146 3248f20a Sofia Papagiannaki
        else:
147 3248f20a Sofia Papagiannaki
            backend.post_exec(True)
148 d1e7d2b4 Sofia Papagiannaki
        finally:
149 d1e7d2b4 Sofia Papagiannaki
            backend.close()