Commit 66d07d8c authored by Giorgos Korfiatis's avatar Giorgos Korfiatis Committed by Christos Stavrakakis
Browse files

astakos: Add resource visibility flags

Rename flag `allow_in_projects' to `ui_visible'. Add flag `api_visible'.
The former entails the latter.
parent 2fad1177
......@@ -48,7 +48,8 @@ astakos_services = {
'name': "astakos.pending_app",
'service_type': "account",
'service_origin': "astakos_account",
'allow_in_projects': False},
'ui_visible': False,
'api_visible': False},
},
},
......
......@@ -886,7 +886,7 @@ class ProjectApplicationForm(forms.ModelForm):
# keep only resource limits for selected resource groups
if self.data.get('is_selected_%s' %
resource.group, "0") == "1":
if not resource.allow_in_projects:
if not resource.ui_visible:
raise forms.ValidationError("Invalid resource %s" %
resource.name)
d = model_to_dict(resource)
......
......@@ -55,12 +55,13 @@ class Command(ListCommand):
"service origin": ("service_origin", "Service"),
"default_quota": ("limit_with_unit", "Default Quota"),
"description": ("desc", "Description"),
"allow_in_projects": ("allow_in_projects",
"Make resource available in projects"),
"api_visible": ("api_visible",
"Resource accessibility through the API"),
"ui_visible": ("ui_visible",
"Resource accessibility through the UI"),
}
fields = ["id", "name", "service origin", "default_quota",
"description"]
fields = ["id", "name", "default_quota", "api_visible", "ui_visible"]
def show_limit(self, resource):
limit = resource.uplimit
......
......@@ -64,10 +64,12 @@ class Command(BaseCommand):
default='mb',
help=("Specify display unit for resource values "
"(one of %s); defaults to mb") % style_options),
make_option('--allow-in-projects',
make_option('--api-visible',
metavar='True|False',
help=("Specify whether to allow this resource "
"in projects.")),
help="Control visibility of this resource in the API"),
make_option('--ui-visible',
metavar='True|False',
help="Control visibility of this resource in the UI"),
)
def handle(self, *args, **options):
......@@ -77,7 +79,8 @@ class Command(BaseCommand):
'default_quota': self.change_limit,
'default_quota_interactive': self.change_interactive,
'default_quota_from_file': self.change_from_file,
'allow_in_projects': self.set_allow_in_projects,
'api_visible': self.set_api_visible,
'ui_visible': self.set_ui_visible,
}
opts = [(key, value)
......@@ -88,7 +91,7 @@ class Command(BaseCommand):
raise CommandError("Please provide exactly one of the options: "
"--default-quota, --default-quota-interactive, "
"--default-quota-from-file, "
"--allow-in-projects.")
"--api-visible, --ui-visible.")
self.unit_style = options['unit_style']
check_style(self.unit_style)
......@@ -97,7 +100,22 @@ class Command(BaseCommand):
action = actions[key]
action(resource_name, value)
def set_allow_in_projects(self, resource_name, allow):
def set_api_visible(self, resource_name, allow):
if resource_name is None:
raise CommandError("Please provide a resource name.")
try:
allow = utils.parse_bool(allow)
except ValueError:
raise CommandError("Expecting a boolean value.")
resource = self.get_resource(resource_name)
resource.api_visible = allow
if not allow and resource.ui_visible:
self.stdout.write("Also resetting 'ui_visible' for consistency.\n")
resource.ui_visible = False
resource.save()
def set_ui_visible(self, resource_name, allow):
if resource_name is None:
raise CommandError("Please provide a resource name.")
......@@ -106,7 +124,11 @@ class Command(BaseCommand):
except ValueError:
raise CommandError("Expecting a boolean value.")
resource = self.get_resource(resource_name)
resource.allow_in_projects = allow
resource.ui_visible = allow
if allow and not resource.api_visible:
self.stdout.write("Also setting 'api_visible' for consistency.\n")
resource.api_visible = True
resource.save()
def get_resource(self, resource_name):
......
......@@ -233,7 +233,8 @@ class Resource(models.Model):
service_origin = models.CharField(max_length=255, db_index=True)
unit = models.CharField(_('Unit'), null=True, max_length=255)
uplimit = models.BigIntegerField(default=0)
allow_in_projects = models.BooleanField(default=True)
ui_visible = models.BooleanField(default=True)
api_visible = models.BooleanField(default=True)
def __str__(self):
return self.name
......@@ -245,7 +246,8 @@ class Resource(models.Model):
return {'service': self.service_origin,
'description': self.desc,
'unit': self.unit,
'allow_in_projects': self.allow_in_projects,
'ui_visible': self.ui_visible,
'api_visible': self.api_visible,
}
@property
......
......@@ -195,7 +195,6 @@ RESOURCES = {
'cyclades.floating_ip',
'astakos.pending_app'
],
'exclude_from_usage': ['astakos.pending_app']
}
# extend from settings
......
......@@ -38,7 +38,7 @@ import logging
logger = logging.getLogger(__name__)
resource_fields = ['desc', 'unit', 'allow_in_projects']
resource_fields = ['desc', 'unit', 'ui_visible', 'api_visible']
class RegisterException(Exception):
......@@ -93,6 +93,10 @@ def add_resource(resource_dict):
if value is not None:
setattr(r, field, value)
if r.ui_visible and not r.api_visible:
m = "Flag 'ui_visible' should entail 'api_visible'."
raise RegisterException(m)
r.save()
if not exists:
quotas.qh_sync_new_resource(r)
......
......@@ -62,7 +62,7 @@ class QuotaAPITest(TestCase):
"desc": "resource11 desc",
"service_type": "type1",
"service_origin": "service1",
"allow_in_projects": True}
"ui_visible": True}
r, _ = register.add_resource(resource11)
register.update_resources([(r, 100)])
resource12 = {"name": "service1.resource12",
......@@ -89,7 +89,7 @@ class QuotaAPITest(TestCase):
"desc": "resource11 desc",
"service_type": "type2",
"service_origin": "service2",
"allow_in_projects": False}
"ui_visible": False}
r, _ = register.add_resource(resource21)
register.update_resources([(r, 3)])
......
......@@ -46,7 +46,7 @@ class ProjectAPITest(TestCase):
"desc": "resource11 desc",
"service_type": "type1",
"service_origin": "service1",
"allow_in_projects": True}
"ui_visible": True}
r, _ = register.add_resource(resource11)
register.update_resources([(r, 100)])
resource12 = {"name": "service1.resource12",
......@@ -74,7 +74,8 @@ class ProjectAPITest(TestCase):
"desc": "pend app desc",
"service_type": "account",
"service_origin": "astakos_account",
"allow_in_projects": False}
"ui_visible": False,
"api_visible": False}
r, _ = register.add_resource(pending_app)
register.update_resources([(r, 3)])
......@@ -598,7 +599,8 @@ class TestProjects(TestCase):
# astakos resources
self.resource = Resource.objects.create(name="astakos.pending_app",
uplimit=0,
allow_in_projects=False,
ui_visible=False,
api_visible=False,
service_type="astakos")
# custom service resources
......@@ -638,11 +640,11 @@ class TestProjects(TestCase):
self.assertRedirects(r, reverse('project_add'))
@im_settings(PROJECT_ADMINS=['uuid1'])
def test_allow_in_project(self):
def test_ui_visible(self):
dfrom = datetime.now()
dto = datetime.now() + timedelta(days=30)
# astakos.pending_uplimit allow_in_project flag is False
# astakos.pending_app ui_visible flag is False
# we shouldn't be able to create a project application using this
# resource.
application_data = {
......
......@@ -826,7 +826,7 @@ def resource_usage(request):
current_usage = quotas.get_user_quotas(request.user)
current_usage = json.dumps(current_usage['system'])
resource_catalog, resource_groups = _resources_catalog(for_usage=True)
resource_catalog, resource_groups = _resources_catalog()
if resource_catalog is False:
# on fail resource_groups contains the result object
result = resource_groups
......
......@@ -97,7 +97,7 @@ def project_add(request):
"end_date", "comments"]
membership_fields = ["member_join_policy", "member_leave_policy",
"limit_on_members_number"]
resource_catalog, resource_groups = _resources_catalog(for_project=True)
resource_catalog, resource_groups = _resources_catalog()
if resource_catalog is False:
# on fail resource_groups contains the result object
result = resource_groups
......@@ -235,7 +235,7 @@ def project_modify(request, application_id):
"end_date", "comments"]
membership_fields = ["member_join_policy", "member_leave_policy",
"limit_on_members_number"]
resource_catalog, resource_groups = _resources_catalog(for_project=True)
resource_catalog, resource_groups = _resources_catalog()
if resource_catalog is False:
# on fail resource_groups contains the result object
result = resource_groups
......
......@@ -190,7 +190,7 @@ def _update_object(request, model=None, object_id=None, slug=None,
return response
def _resources_catalog(for_project=False, for_usage=False):
def _resources_catalog():
"""
`resource_catalog` contains a list of tuples. Each tuple contains the group
key the resource is assigned to and resources list of dicts that contain
......@@ -252,13 +252,9 @@ def _resources_catalog(for_project=False, for_usage=False):
resource_groups.pop(gindex)
# filter out resources which user cannot request in a project application
exclude = resources_meta.get('exclude_from_usage', [])
for group_index, group_resources in enumerate(list(resource_catalog)):
group, resources = group_resources
for index, resource in list(enumerate(resources)):
if for_project and not resource.get('allow_in_projects'):
resources.remove(resource)
if resource.get('str_repr') in exclude and for_usage:
for group, resources in list(resource_catalog):
for resource in resources:
if not resource.get('ui_visible'):
resources.remove(resource)
# cleanup empty groups
......
......@@ -21,7 +21,8 @@ astakos_services = {
'name': "astakos.pending_app",
'service_type': "account",
'service_origin': "astakos_account",
'allow_in_projects': False},
"ui_visible": False,
"api_visible": False},
},
},
......@@ -93,6 +94,8 @@ cyclades_services = {
"desc": "Number of virtual machine processors",
"service_type": "compute",
"service_origin": "cyclades_compute",
"ui_visible": False,
"api_visible": False,
},
'cpu': {
"name": "cyclades.cpu",
......@@ -107,6 +110,8 @@ cyclades_services = {
"unit": "bytes",
"service_type": "compute",
"service_origin": "cyclades_compute",
"ui_visible": False,
"api_visible": False,
},
'ram': {
"name": "cyclades.ram",
......
......@@ -56,6 +56,8 @@ cyclades_services = {
"desc": "Number of virtual machine processors",
"service_type": "compute",
"service_origin": "cyclades_compute",
"ui_visible": False,
"api_visible": False,
},
'cpu': {
"name": "cyclades.cpu",
......@@ -70,6 +72,8 @@ cyclades_services = {
"unit": "bytes",
"service_type": "compute",
"service_origin": "cyclades_compute",
"ui_visible": False,
"api_visible": False,
},
'ram': {
"name": "cyclades.ram",
......
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