Commit a6855022 authored by Giorgos Korfiatis's avatar Giorgos Korfiatis
Browse files

astakos: Separate importing resources from setting limits

`snf-manage resource-import' does not provide a way to change the
default base quota any more. When importing a resource for the first
time, it sets the limit to zero.

Use `snf-manage resource-modify' to change limits. It supports both
interactive mode and reading limits from file, either for a specified
resource or for all resources.
parent 6812a184
......@@ -39,6 +39,7 @@ from django.utils import simplejson as json
from snf_django.lib.db.transaction import commit_on_success_strict
from astakos.im.resources import add_resource
from astakos.im.models import Service
class Command(BaseCommand):
......@@ -81,35 +82,40 @@ class Command(BaseCommand):
if json_file:
with open(json_file) as file_data:
data = json.load(file_data)
service = data.get('service')
resources = data.get('resources')
if service is None or resources is None:
m = "JSON file should contain service and resource data."
m = ('Input should be a JSON dict containing "service" '
'and "resource" keys.')
try:
data = json.load(file_data)
except json.JSONDecodeError:
raise CommandError(m)
if not isinstance(data, dict):
raise CommandError(m)
else:
try:
service = data['service']
resources = data['resources']
except KeyError:
raise CommandError(m)
self.add_resources(service, resources, config)
self.add_resources(service, resources)
@commit_on_success_strict()
def add_resources(self, service, resources, config):
def add_resources(self, service, resources):
try:
s = Service.objects.get(name=service)
except Service.DoesNotExist:
raise CommandError("Service '%s' is not registered." % (service))
for resource in resources:
if not isinstance(resource, dict):
raise CommandError("Malformed resource dict.")
exists = add_resource(s, resource)
name = resource['name']
uplimit = config.get(name)
if uplimit is None:
desc = resource['desc']
unit = resource.get('unit')
self.stdout.write(
"Provide default base quota for resource '%s' (%s)" %
(name, desc))
m = (" in %s: " % unit) if unit else ": "
self.stdout.write(m)
uplimit = raw_input()
try:
uplimit = int(uplimit)
except ValueError:
m = "Limit for resource %s is not an integer." % (name)
raise CommandError(m)
add_resource(service, resource, uplimit)
if exists:
m = "Resource '%s' updated in database.\n" % (name)
else:
m = ("Resource '%s' created in database with default "
"quota limit 0.\n" % (name))
self.stdout.write(m)
......@@ -33,6 +33,7 @@
from optparse import make_option
from django.core.management.base import BaseCommand, CommandError
from django.utils import simplejson as json
from astakos.im.models import Resource
from astakos.im.resources import update_resource
......@@ -40,30 +41,108 @@ from astakos.im.resources import update_resource
class Command(BaseCommand):
args = "<resource name>"
help = "Modify a resource (currently only change the default base quota)"
help = ("Modify a resource (currently only change the default base quota)."
"\nIf no resource is specified, all resources are considered.")
option_list = BaseCommand.option_list + (
make_option('--limit',
dest='limit',
help="Change default base quota"),
help="Specify default base quota"),
make_option('--interactive',
action='store_true',
dest='interactive',
default=None,
help="Prompt user to change default base quotas"),
make_option('--from-file',
dest='from_file',
metavar='<limits_file.json>',
help="Read default base quotas from a json file"),
)
def handle(self, *args, **options):
if len(args) < 1:
resource_name = args[0] if len(args) > 0 else None
actions = {
'limit': self.change_limit,
'interactive': self.change_interactive,
'from_file': self.change_from_file,
}
opts = [(key, value)
for (key, value) in options.items()
if key in actions and value is not None]
if len(opts) != 1:
raise CommandError("Please provide exactly one option.")
key, value = opts[0]
action = actions[key]
action(resource_name, value)
def get_resource(self, resource_name):
try:
return Resource.objects.get_for_update(name=resource_name)
except Resource.DoesNotExist:
raise CommandError("Resource %s does not exist."
% resource_name)
def change_limit(self, resource_name, limit):
if resource_name is None:
raise CommandError("Please provide a resource name.")
resource_name = args[0]
resource = self.get_resource(resource_name)
self.change_resource_limit(resource, limit)
limit = options['limit']
if limit is None:
raise CommandError("Use --limit to change default base quota.")
def change_from_file(self, resource_name, filename):
with open(filename) as file_data:
try:
config = json.load(file_data)
except json.JSONDecodeError:
raise CommandError("Malformed JSON file.")
if not isinstance(config, dict):
raise CommandError("Malformed JSON file.")
self.change_with_conf(resource_name, config)
def change_with_conf(self, resource_name, config):
if resource_name is None:
resources = Resource.objects.all().select_for_update()
else:
resources = [self.get_resource(resource_name)]
for resource in resources:
limit = config.get(resource.name)
if limit is not None:
self.change_resource_limit(resource, limit)
def change_interactive(self, resource_name, _placeholder):
if resource_name is None:
resources = Resource.objects.all().select_for_update()
else:
resources = [self.get_resource(resource_name)]
for resource in resources:
self.stdout.write("Resource '%s' (%s)\n" %
(resource.name, resource.desc))
unit = (" in %s" % resource.unit) if resource.unit else ""
self.stdout.write("Current limit%s: %s\n"
% (unit, resource.uplimit))
while True:
self.stdout.write("New limit%s (leave blank to keep current): "
% (unit))
response = raw_input()
if response == "":
break
else:
try:
value = int(response)
except ValueError:
continue
update_resource(resource, value)
break
def change_resource_limit(self, resource, limit):
try:
limit = int(limit)
except:
raise CommandError("Limit should be an integer.")
try:
update_resource(resource_name, limit)
except Resource.DoesNotExist:
raise CommandError("Resource %s does not exist." % resource_name)
update_resource(resource, limit)
......@@ -31,57 +31,58 @@
# interpreted as representing official policies, either expressed
# or implied, of GRNET S.A.
from astakos.im.models import Service, Resource
from astakos.im.models import Resource
from astakos.im.quotas import qh_add_resource_limit, qh_sync_new_resource
import logging
logger = logging.getLogger(__name__)
fields = ['name', 'desc', 'unit']
def add_resource(service, resource, uplimit):
try:
s = Service.objects.get(name=service)
except Service.DoesNotExist:
raise Exception("Service %s is not registered." % (service))
name = resource['name']
class ResourceException(Exception):
pass
def add_resource(service, resource_dict):
name = resource_dict.get('name')
if not name:
raise ResourceException("Malformed resource dict.")
try:
r = Resource.objects.get_for_update(name=name)
old_uplimit = r.uplimit
exists = True
except Resource.DoesNotExist:
r = Resource()
old_uplimit = None
r = Resource(uplimit=0)
exists = False
r.uplimit = uplimit
r.service = s
for key, value in resource.iteritems():
setattr(r, key, value)
r.service = service
for field in fields:
value = resource_dict.get(field)
if value is not None:
setattr(r, field, value)
r.save()
if not exists:
qh_sync_new_resource(r, 0)
if old_uplimit is not None:
logger.info("Updated resource %s with limit %s." % (name, uplimit))
if exists:
logger.info("Updated resource %s." % (name))
else:
logger.info("Added resource %s with limit %s." % (name, uplimit))
if old_uplimit is not None:
diff = uplimit - old_uplimit
if diff != 0:
qh_add_resource_limit(r, diff)
else:
qh_sync_new_resource(r, uplimit)
logger.info("Added resource %s." % (name))
return exists
def update_resource(name, uplimit):
r = Resource.objects.get_for_update(name=name)
old_uplimit = r.uplimit
r.uplimit = uplimit
r.save()
def update_resource(resource, uplimit):
old_uplimit = resource.uplimit
resource.uplimit = uplimit
resource.save()
logger.info("Updated resource %s with limit %s." % (name, uplimit))
logger.info("Updated resource %s with limit %s."
% (resource.name, uplimit))
diff = uplimit - old_uplimit
if diff != 0:
qh_add_resource_limit(r, diff)
qh_add_resource_limit(resource, diff)
def get_resources(resources=None, services=None):
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment