Statistics
| Branch: | Tag: | Revision:

root / snf-cyclades-app / synnefo / quotas / management / commands / reconcile-resources-cyclades.py @ ff5edb80

History | View | Annotate | Download (5.2 kB)

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

47 62c86226 Christos Stavrakakis
    Detect unsynchronized usage between Astakos and Cyclades DB resources and
48 ccfbf77b Christos Stavrakakis
    synchronize them if specified so.
49 f8955d79 Georgios D. Tsoukalas

50 f8955d79 Georgios D. Tsoukalas
    """
51 600a3d4d Christos Stavrakakis
    option_list = BaseCommand.option_list + (
52 600a3d4d Christos Stavrakakis
        make_option("--userid", dest="userid",
53 600a3d4d Christos Stavrakakis
                    default=None,
54 ccfbf77b Christos Stavrakakis
                    help="Reconcile resources only for this user"),
55 2e2fc330 Giorgos Korfiatis
        make_option("--project",
56 2e2fc330 Giorgos Korfiatis
                    help="Reconcile resources only for this project"),
57 ccfbf77b Christos Stavrakakis
        make_option("--fix", dest="fix",
58 ccfbf77b Christos Stavrakakis
                    default=False,
59 ccfbf77b Christos Stavrakakis
                    action="store_true",
60 ccfbf77b Christos Stavrakakis
                    help="Synchronize Astakos quotas with Cyclades DB."),
61 ccfbf77b Christos Stavrakakis
        make_option("--force",
62 ccfbf77b Christos Stavrakakis
                    default=False,
63 ccfbf77b Christos Stavrakakis
                    action="store_true",
64 ccfbf77b Christos Stavrakakis
                    help="Override Astakos quotas. Force Astakos to impose"
65 ccfbf77b Christos Stavrakakis
                         " the Cyclades quota, independently of their value.")
66 600a3d4d Christos Stavrakakis
    )
67 600a3d4d Christos Stavrakakis
68 600a3d4d Christos Stavrakakis
    def handle(self, *args, **options):
69 d9a7f0bb Giorgos Korfiatis
        write = self.stderr.write
70 600a3d4d Christos Stavrakakis
        userid = options['userid']
71 2e2fc330 Giorgos Korfiatis
        project = options["project"]
72 600a3d4d Christos Stavrakakis
73 ccfbf77b Christos Stavrakakis
        # Get holdings from Cyclades DB
74 2e2fc330 Giorgos Korfiatis
        db_holdings = util.get_db_holdings(userid, project)
75 2e2fc330 Giorgos Korfiatis
        db_project_holdings = util.get_db_project_holdings(project)
76 39d44eba Christos Stavrakakis
77 2e2fc330 Giorgos Korfiatis
        # Get holdings from QuotaHolder
78 2e2fc330 Giorgos Korfiatis
        qh_holdings = util.get_qh_users_holdings(
79 2e2fc330 Giorgos Korfiatis
            [userid] if userid is not None else None)
80 2e2fc330 Giorgos Korfiatis
        qh_project_holdings = util.get_qh_project_holdings(
81 2e2fc330 Giorgos Korfiatis
            [project] if project is not None else None)
82 2e2fc330 Giorgos Korfiatis
83 2e2fc330 Giorgos Korfiatis
        unsynced_users, users_pending, users_unknown =\
84 2e2fc330 Giorgos Korfiatis
            reconcile.check_users(self.stderr, quotas.RESOURCES,
85 2e2fc330 Giorgos Korfiatis
                                  db_holdings, qh_holdings)
86 2e2fc330 Giorgos Korfiatis
87 2e2fc330 Giorgos Korfiatis
        unsynced_projects, projects_pending, projects_unknown =\
88 2e2fc330 Giorgos Korfiatis
            reconcile.check_projects(self.stderr, quotas.RESOURCES,
89 2e2fc330 Giorgos Korfiatis
                                     db_project_holdings, qh_project_holdings)
90 2e2fc330 Giorgos Korfiatis
        pending_exists = users_pending or projects_pending
91 2e2fc330 Giorgos Korfiatis
        unknown_exists = users_unknown or projects_unknown
92 2e2fc330 Giorgos Korfiatis
93 2e2fc330 Giorgos Korfiatis
        headers = ("Type", "Holder", "Source", "Resource",
94 2e2fc330 Giorgos Korfiatis
                   "Database", "Quotaholder")
95 2e2fc330 Giorgos Korfiatis
        unsynced = unsynced_users + unsynced_projects
96 600a3d4d Christos Stavrakakis
        if unsynced:
97 d9a7f0bb Giorgos Korfiatis
            pprint_table(self.stdout, unsynced, headers)
98 ccfbf77b Christos Stavrakakis
            if options["fix"]:
99 ccfbf77b Christos Stavrakakis
                qh = quotas.Quotaholder.get()
100 2e2fc330 Giorgos Korfiatis
                force = options["force"]
101 2e2fc330 Giorgos Korfiatis
                name = ("client: reconcile-resources-cyclades, time: %s"
102 2e2fc330 Giorgos Korfiatis
                        % datetime.now())
103 2e2fc330 Giorgos Korfiatis
                user_provisions = reconcile.create_user_provisions(
104 2e2fc330 Giorgos Korfiatis
                    unsynced_users)
105 2e2fc330 Giorgos Korfiatis
                project_provisions = reconcile.create_project_provisions(
106 2e2fc330 Giorgos Korfiatis
                    unsynced_projects)
107 205cc8d3 Giorgos Korfiatis
                try:
108 2e2fc330 Giorgos Korfiatis
                    qh.issue_commission_generic(
109 2e2fc330 Giorgos Korfiatis
                        user_provisions, project_provisions,
110 2e2fc330 Giorgos Korfiatis
                        name=name, force=force,
111 2e2fc330 Giorgos Korfiatis
                        auto_accept=True)
112 87726194 Giorgos Korfiatis
                except quotas.errors.QuotaLimit:
113 205cc8d3 Giorgos Korfiatis
                    write("Reconciling failed because a limit has been "
114 205cc8d3 Giorgos Korfiatis
                          "reached. Use --force to ignore the check.\n")
115 205cc8d3 Giorgos Korfiatis
                    return
116 9b964eff Christos Stavrakakis
                write("Fixed unsynced resources\n")
117 9b964eff Christos Stavrakakis
118 9b964eff Christos Stavrakakis
        if pending_exists:
119 9b964eff Christos Stavrakakis
            write("Found pending commissions. Run 'snf-manage"
120 9b964eff Christos Stavrakakis
                  " reconcile-commissions-cyclades'\n")
121 2e2fc330 Giorgos Korfiatis
        elif not (unsynced or unknown_exists):
122 ccfbf77b Christos Stavrakakis
            write("Everything in sync.\n")