Statistics
| Branch: | Tag: | Revision:

root / snf-astakos-app / astakos / im / management / commands / resource-modify.py @ a0fcfb35

History | View | Annotate | Download (7.1 kB)

1 720955ff Giorgos Korfiatis
# Copyright 2013 GRNET S.A. All rights reserved.
2 720955ff Giorgos Korfiatis
#
3 720955ff Giorgos Korfiatis
# Redistribution and use in source and binary forms, with or
4 720955ff Giorgos Korfiatis
# without modification, are permitted provided that the following
5 720955ff Giorgos Korfiatis
# conditions are met:
6 720955ff Giorgos Korfiatis
#
7 720955ff Giorgos Korfiatis
#   1. Redistributions of source code must retain the above
8 720955ff Giorgos Korfiatis
#      copyright notice, this list of conditions and the following
9 720955ff Giorgos Korfiatis
#      disclaimer.
10 720955ff Giorgos Korfiatis
#
11 720955ff Giorgos Korfiatis
#   2. Redistributions in binary form must reproduce the above
12 720955ff Giorgos Korfiatis
#      copyright notice, this list of conditions and the following
13 720955ff Giorgos Korfiatis
#      disclaimer in the documentation and/or other materials
14 720955ff Giorgos Korfiatis
#      provided with the distribution.
15 720955ff Giorgos Korfiatis
#
16 720955ff Giorgos Korfiatis
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
17 720955ff Giorgos Korfiatis
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 720955ff Giorgos Korfiatis
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 720955ff Giorgos Korfiatis
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
20 720955ff Giorgos Korfiatis
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 720955ff Giorgos Korfiatis
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 720955ff Giorgos Korfiatis
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23 720955ff Giorgos Korfiatis
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24 720955ff Giorgos Korfiatis
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 720955ff Giorgos Korfiatis
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26 720955ff Giorgos Korfiatis
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 720955ff Giorgos Korfiatis
# POSSIBILITY OF SUCH DAMAGE.
28 720955ff Giorgos Korfiatis
#
29 720955ff Giorgos Korfiatis
# The views and conclusions contained in the software and
30 720955ff Giorgos Korfiatis
# documentation are those of the authors and should not be
31 720955ff Giorgos Korfiatis
# interpreted as representing official policies, either expressed
32 720955ff Giorgos Korfiatis
# or implied, of GRNET S.A.
33 720955ff Giorgos Korfiatis
34 720955ff Giorgos Korfiatis
from optparse import make_option
35 720955ff Giorgos Korfiatis
from django.core.management.base import BaseCommand, CommandError
36 3a527b3a Giorgos Korfiatis
from django.utils import simplejson as json
37 720955ff Giorgos Korfiatis
38 a0fcfb35 Giorgos Korfiatis
from synnefo.webproject.management import utils
39 720955ff Giorgos Korfiatis
from astakos.im.models import Resource
40 720955ff Giorgos Korfiatis
from astakos.im.resources import update_resource
41 44f510e1 Giorgos Korfiatis
from ._common import show_resource_value, style_options, check_style, units
42 720955ff Giorgos Korfiatis
43 720955ff Giorgos Korfiatis
44 720955ff Giorgos Korfiatis
class Command(BaseCommand):
45 720955ff Giorgos Korfiatis
    args = "<resource name>"
46 a0fcfb35 Giorgos Korfiatis
    help = "Modify a resource's default base quota and boolean flags."
47 720955ff Giorgos Korfiatis
48 720955ff Giorgos Korfiatis
    option_list = BaseCommand.option_list + (
49 720955ff Giorgos Korfiatis
        make_option('--limit',
50 3a527b3a Giorgos Korfiatis
                    help="Specify default base quota"),
51 a0fcfb35 Giorgos Korfiatis
        make_option('--limit-interactive',
52 3a527b3a Giorgos Korfiatis
                    action='store_true',
53 3a527b3a Giorgos Korfiatis
                    default=None,
54 a0fcfb35 Giorgos Korfiatis
                    help=("Prompt user to change default base quota. "
55 a0fcfb35 Giorgos Korfiatis
                          "If no resource is given, prompts for all "
56 a0fcfb35 Giorgos Korfiatis
                          "resources.")),
57 a0fcfb35 Giorgos Korfiatis
        make_option('--limit-from-file',
58 3a527b3a Giorgos Korfiatis
                    metavar='<limits_file.json>',
59 a0fcfb35 Giorgos Korfiatis
                    help=("Read default base quota from a file. "
60 a0fcfb35 Giorgos Korfiatis
                          "File should contain a json dict mapping resource "
61 a0fcfb35 Giorgos Korfiatis
                          "names to limits")),
62 44f510e1 Giorgos Korfiatis
        make_option('--unit-style',
63 44f510e1 Giorgos Korfiatis
                    default='mb',
64 44f510e1 Giorgos Korfiatis
                    help=("Specify display unit for resource values "
65 44f510e1 Giorgos Korfiatis
                          "(one of %s); defaults to mb") % style_options),
66 a0fcfb35 Giorgos Korfiatis
        make_option('--allow-in-projects',
67 a0fcfb35 Giorgos Korfiatis
                    metavar='True|False',
68 a0fcfb35 Giorgos Korfiatis
                    help=("Specify whether to allow this resource "
69 a0fcfb35 Giorgos Korfiatis
                          "in projects.")),
70 720955ff Giorgos Korfiatis
    )
71 720955ff Giorgos Korfiatis
72 720955ff Giorgos Korfiatis
    def handle(self, *args, **options):
73 3a527b3a Giorgos Korfiatis
        resource_name = args[0] if len(args) > 0 else None
74 3a527b3a Giorgos Korfiatis
75 3a527b3a Giorgos Korfiatis
        actions = {
76 3a527b3a Giorgos Korfiatis
            'limit': self.change_limit,
77 a0fcfb35 Giorgos Korfiatis
            'limit_interactive': self.change_interactive,
78 a0fcfb35 Giorgos Korfiatis
            'limit_from_file': self.change_from_file,
79 a0fcfb35 Giorgos Korfiatis
            'allow_in_projects': self.set_allow_in_projects,
80 3a527b3a Giorgos Korfiatis
        }
81 3a527b3a Giorgos Korfiatis
82 3a527b3a Giorgos Korfiatis
        opts = [(key, value)
83 3a527b3a Giorgos Korfiatis
                for (key, value) in options.items()
84 3a527b3a Giorgos Korfiatis
                if key in actions and value is not None]
85 3a527b3a Giorgos Korfiatis
86 3a527b3a Giorgos Korfiatis
        if len(opts) != 1:
87 a0fcfb35 Giorgos Korfiatis
            raise CommandError("Please provide exactly one of the options: "
88 a0fcfb35 Giorgos Korfiatis
                               "--limit, --limit-interactive, "
89 a0fcfb35 Giorgos Korfiatis
                               "--limit-from-file, --allow-in-projects.")
90 44f510e1 Giorgos Korfiatis
91 44f510e1 Giorgos Korfiatis
        self.unit_style = options['unit_style']
92 44f510e1 Giorgos Korfiatis
        check_style(self.unit_style)
93 3a527b3a Giorgos Korfiatis
94 3a527b3a Giorgos Korfiatis
        key, value = opts[0]
95 3a527b3a Giorgos Korfiatis
        action = actions[key]
96 3a527b3a Giorgos Korfiatis
        action(resource_name, value)
97 3a527b3a Giorgos Korfiatis
98 a0fcfb35 Giorgos Korfiatis
    def set_allow_in_projects(self, resource_name, allow):
99 a0fcfb35 Giorgos Korfiatis
        if resource_name is None:
100 a0fcfb35 Giorgos Korfiatis
            raise CommandError("Please provide a resource name.")
101 a0fcfb35 Giorgos Korfiatis
102 a0fcfb35 Giorgos Korfiatis
        try:
103 a0fcfb35 Giorgos Korfiatis
            allow = utils.parse_bool(allow)
104 a0fcfb35 Giorgos Korfiatis
        except ValueError:
105 a0fcfb35 Giorgos Korfiatis
            raise CommandError("Expecting a boolean value.")
106 a0fcfb35 Giorgos Korfiatis
        resource = self.get_resource(resource_name)
107 a0fcfb35 Giorgos Korfiatis
        resource.allow_in_projects = allow
108 a0fcfb35 Giorgos Korfiatis
        resource.save()
109 a0fcfb35 Giorgos Korfiatis
110 3a527b3a Giorgos Korfiatis
    def get_resource(self, resource_name):
111 3a527b3a Giorgos Korfiatis
        try:
112 3a527b3a Giorgos Korfiatis
            return Resource.objects.get_for_update(name=resource_name)
113 3a527b3a Giorgos Korfiatis
        except Resource.DoesNotExist:
114 3a527b3a Giorgos Korfiatis
            raise CommandError("Resource %s does not exist."
115 3a527b3a Giorgos Korfiatis
                               % resource_name)
116 3a527b3a Giorgos Korfiatis
117 3a527b3a Giorgos Korfiatis
    def change_limit(self, resource_name, limit):
118 3a527b3a Giorgos Korfiatis
        if resource_name is None:
119 720955ff Giorgos Korfiatis
            raise CommandError("Please provide a resource name.")
120 720955ff Giorgos Korfiatis
121 3a527b3a Giorgos Korfiatis
        resource = self.get_resource(resource_name)
122 3a527b3a Giorgos Korfiatis
        self.change_resource_limit(resource, limit)
123 720955ff Giorgos Korfiatis
124 3a527b3a Giorgos Korfiatis
    def change_from_file(self, resource_name, filename):
125 3a527b3a Giorgos Korfiatis
        with open(filename) as file_data:
126 3a527b3a Giorgos Korfiatis
            try:
127 3a527b3a Giorgos Korfiatis
                config = json.load(file_data)
128 3a527b3a Giorgos Korfiatis
            except json.JSONDecodeError:
129 3a527b3a Giorgos Korfiatis
                raise CommandError("Malformed JSON file.")
130 3a527b3a Giorgos Korfiatis
            if not isinstance(config, dict):
131 3a527b3a Giorgos Korfiatis
                raise CommandError("Malformed JSON file.")
132 3a527b3a Giorgos Korfiatis
            self.change_with_conf(resource_name, config)
133 720955ff Giorgos Korfiatis
134 3a527b3a Giorgos Korfiatis
    def change_with_conf(self, resource_name, config):
135 3a527b3a Giorgos Korfiatis
        if resource_name is None:
136 3a527b3a Giorgos Korfiatis
            resources = Resource.objects.all().select_for_update()
137 3a527b3a Giorgos Korfiatis
        else:
138 3a527b3a Giorgos Korfiatis
            resources = [self.get_resource(resource_name)]
139 3a527b3a Giorgos Korfiatis
140 3a527b3a Giorgos Korfiatis
        for resource in resources:
141 3a527b3a Giorgos Korfiatis
            limit = config.get(resource.name)
142 3a527b3a Giorgos Korfiatis
            if limit is not None:
143 3a527b3a Giorgos Korfiatis
                self.change_resource_limit(resource, limit)
144 3a527b3a Giorgos Korfiatis
145 3a527b3a Giorgos Korfiatis
    def change_interactive(self, resource_name, _placeholder):
146 3a527b3a Giorgos Korfiatis
        if resource_name is None:
147 3a527b3a Giorgos Korfiatis
            resources = Resource.objects.all().select_for_update()
148 3a527b3a Giorgos Korfiatis
        else:
149 3a527b3a Giorgos Korfiatis
            resources = [self.get_resource(resource_name)]
150 3a527b3a Giorgos Korfiatis
151 3a527b3a Giorgos Korfiatis
        for resource in resources:
152 3a527b3a Giorgos Korfiatis
            self.stdout.write("Resource '%s' (%s)\n" %
153 3a527b3a Giorgos Korfiatis
                              (resource.name, resource.desc))
154 44f510e1 Giorgos Korfiatis
            value = show_resource_value(resource.uplimit, resource.name,
155 44f510e1 Giorgos Korfiatis
                                        self.unit_style)
156 44f510e1 Giorgos Korfiatis
            self.stdout.write("Current limit: %s\n" % value)
157 3a527b3a Giorgos Korfiatis
            while True:
158 44f510e1 Giorgos Korfiatis
                self.stdout.write("New limit (leave blank to keep current): ")
159 3a527b3a Giorgos Korfiatis
                response = raw_input()
160 3a527b3a Giorgos Korfiatis
                if response == "":
161 3a527b3a Giorgos Korfiatis
                    break
162 3a527b3a Giorgos Korfiatis
                else:
163 3a527b3a Giorgos Korfiatis
                    try:
164 44f510e1 Giorgos Korfiatis
                        value = units.parse(response)
165 44f510e1 Giorgos Korfiatis
                    except units.ParseError:
166 3a527b3a Giorgos Korfiatis
                        continue
167 3a527b3a Giorgos Korfiatis
                    update_resource(resource, value)
168 3a527b3a Giorgos Korfiatis
                    break
169 3a527b3a Giorgos Korfiatis
170 3a527b3a Giorgos Korfiatis
    def change_resource_limit(self, resource, limit):
171 44f510e1 Giorgos Korfiatis
        if not isinstance(limit, (int, long)):
172 44f510e1 Giorgos Korfiatis
            try:
173 44f510e1 Giorgos Korfiatis
                limit = units.parse(limit)
174 44f510e1 Giorgos Korfiatis
            except units.ParseError:
175 44f510e1 Giorgos Korfiatis
                m = ("Limit should be an integer, optionally followed "
176 44f510e1 Giorgos Korfiatis
                     "by a unit.")
177 44f510e1 Giorgos Korfiatis
                raise CommandError(m)
178 44f510e1 Giorgos Korfiatis
            update_resource(resource, limit)