Statistics
| Branch: | Tag: | Revision:

root / snf-astakos-app / astakos / im / management / commands / project-show.py @ def409e0

History | View | Annotate | Download (8.3 kB)

1
# Copyright 2012-2013 GRNET S.A. All rights reserved.
2
#
3
# Redistribution and use in source and binary forms, with or
4
# without modification, are permitted provided that the following
5
# conditions are met:
6
#
7
#   1. Redistributions of source code must retain the above
8
#      copyright notice, this list of conditions and the following
9
#      disclaimer.
10
#
11
#   2. Redistributions in binary form must reproduce the above
12
#      copyright notice, this list of conditions and the following
13
#      disclaimer in the documentation and/or other materials
14
#      provided with the distribution.
15
#
16
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
17
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
20
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27
# POSSIBILITY OF SUCH DAMAGE.
28
#
29
# The views and conclusions contained in the software and
30
# documentation are those of the authors and should not be
31
# interpreted as representing official policies, either expressed
32
# or implied, of GRNET S.A.
33

    
34
from optparse import make_option
35
from django.core.management.base import CommandError
36

    
37
from synnefo.lib.ordereddict import OrderedDict
38
from snf_django.management.commands import SynnefoCommand
39
from snf_django.management import utils
40
from astakos.im.models import ProjectApplication, Project
41
from astakos.im import quotas
42
from ._common import show_resource_value, style_options, check_style
43
from synnefo.util import units
44

    
45

    
46
class Command(SynnefoCommand):
47
    args = "<id>"
48
    help = "Show details for project <id>"
49

    
50
    option_list = SynnefoCommand.option_list + (
51
        make_option('--pending',
52
                    action='store_true',
53
                    dest='pending',
54
                    default=False,
55
                    help=("For a given project, show also pending "
56
                          "modification, if any")
57
                    ),
58
        make_option('--members',
59
                    action='store_true',
60
                    dest='members',
61
                    default=False,
62
                    help=("Show a list of project memberships")
63
                    ),
64
        make_option('--quota',
65
                    action='store_true',
66
                    dest='list_quotas',
67
                    default=False,
68
                    help="List project quota"),
69
        make_option('--unit-style',
70
                    default='mb',
71
                    help=("Specify display unit for resource values "
72
                          "(one of %s); defaults to mb") % style_options),
73
    )
74

    
75
    def handle(self, *args, **options):
76
        if len(args) != 1:
77
            raise CommandError("Please provide project ID or name")
78

    
79
        self.unit_style = options['unit_style']
80
        check_style(self.unit_style)
81

    
82
        show_pending = bool(options['pending'])
83
        show_members = bool(options['members'])
84
        show_quota = bool(options['list_quotas'])
85
        self.output_format = options['output_format']
86

    
87
        id_ = args[0]
88
        if True:
89
            project = get_chain_state(id_)
90
            self.print_project(project, show_quota)
91
            if show_members and project is not None:
92
                self.stdout.write("\n")
93
                fields, labels = members_fields(project)
94
                self.pprint_table(fields, labels, title="Members")
95
            if show_pending:
96
                app = project.last_application
97
                if app and app.state == ProjectApplication.PENDING:
98
                    self.stdout.write("\n")
99
                    self.print_app(app)
100

    
101
    def pprint_dict(self, d, vertical=True):
102
        utils.pprint_table(self.stdout, [d.values()], d.keys(),
103
                           self.output_format, vertical=vertical)
104

    
105
    def pprint_table(self, tbl, labels, title=None):
106
        utils.pprint_table(self.stdout, tbl, labels,
107
                           self.output_format, title=title)
108

    
109
    def print_app(self, app):
110
        app_info = app_fields(app)
111
        self.pprint_dict(app_info)
112
        self.print_app_resources(app)
113

    
114
    def print_project(self, project, show_quota=False):
115
        self.pprint_dict(project_fields(project))
116
        quota = (quotas.get_project_quota(project)
117
                 if show_quota else None)
118
        self.print_resources(project, quota=quota)
119

    
120
    def print_resources(self, project, quota=None):
121
        policies = project.projectresourcequota_set.all()
122
        fields, labels = resource_fields(policies, quota, self.unit_style)
123
        if fields:
124
            self.stdout.write("\n")
125
            self.pprint_table(fields, labels, title="Resource limits")
126

    
127
    def print_app_resources(self, app):
128
        policies = app.projectresourcegrant_set.all()
129
        fields, labels = resource_fields(policies, None, self.unit_style)
130
        if fields:
131
            self.stdout.write("\n")
132
            self.pprint_table(fields, labels, title="Resource limits")
133

    
134

    
135
def get_chain_state(project_id):
136
    try:
137
        return Project.objects.get(uuid=project_id)
138
    except Project.DoesNotExist:
139
        raise CommandError("Project with id %s not found." % project_id)
140

    
141

    
142
def resource_fields(policies, quota, style):
143
    labels = ('name', 'max per member', 'max per project')
144
    if quota:
145
        labels += ('usage',)
146
    collect = []
147
    for policy in policies:
148
        name = policy.resource.name
149
        capacity = policy.member_capacity
150
        p_capacity = policy.project_capacity
151
        row = (name,
152
               show_resource_value(capacity, name, style),
153
               show_resource_value(p_capacity, name, style))
154
        if quota:
155
            r_quota = quota.get(name)
156
            usage = r_quota.get('project_usage')
157
            row += (show_resource_value(usage, name, style),)
158
        collect.append(row)
159
    return collect, labels
160

    
161

    
162
def app_fields(app):
163
    d = OrderedDict([
164
        ('project id', app.chain.uuid),
165
        ('application id', app.id),
166
        ('status', app.state_display()),
167
        ('applicant', app.applicant),
168
        ('comments for review', app.comments),
169
        ('request issue date', app.issue_date),
170
        ])
171
    if app.name:
172
        d['name'] = app.name
173
    if app.owner:
174
        d['owner'] = app.owner
175
    if app.homepage:
176
        d['homepage'] = app.homepage
177
    if app.description:
178
        d['description'] = app.description
179
    if app.start_date:
180
        d['request start date'] = app.start_date
181
    if app.end_date:
182
        d['request end date'] = app.end_date
183
    if app.member_join_policy:
184
        d['join policy'] = app.member_join_policy_display
185
    if app.member_leave_policy:
186
        d['leave policy'] = app.member_leave_policy_display
187
    if app.limit_on_members_number:
188
        d['max members'] = units.show(app.limit_on_members_number, None)
189

    
190
    return d
191

    
192

    
193
def project_fields(project):
194
    app = project.last_application
195

    
196
    d = OrderedDict([
197
        ('project id', project.uuid),
198
        ('name', project.realname),
199
        ('status', project.state_display()),
200
        ('owner', project.owner),
201
        ('homepage', project.homepage),
202
        ('description', project.description),
203
        ('creation date', project.creation_date),
204
        ('request end date', project.end_date),
205
        ])
206

    
207
    deact = project.last_deactivation()
208
    if deact is not None:
209
        d['deactivation date'] = deact.date
210

    
211
    d.update([
212
            ('join policy', project.member_join_policy_display),
213
            ('leave policy', project.member_leave_policy_display),
214
            ('max members', units.show(project.limit_on_members_number, None)),
215
            ('total members', project.members_count()),
216
    ])
217

    
218
    return d
219

    
220

    
221
def members_fields(project):
222
    labels = ('member uuid', 'email', 'status')
223
    objs = project.projectmembership_set.select_related('person')
224
    memberships = objs.all().order_by('state', 'person__email')
225
    collect = []
226
    for m in memberships:
227
        user = m.person
228
        collect.append((user.uuid,
229
                       user.email,
230
                       m.state_display()))
231

    
232
    return collect, labels