diff --git a/circle/storage/models.py b/circle/storage/models.py index b8ec6ee..24c3107 100644 --- a/circle/storage/models.py +++ b/circle/storage/models.py @@ -11,6 +11,7 @@ from django.utils.translation import ugettext_lazy as _ from model_utils.models import TimeStampedModel from sizefield.models import FileSizeField +from acl.models import AclBase from .tasks import local_tasks, remote_tasks from common.models import ActivityModel, activitycontextimpl @@ -38,10 +39,15 @@ class DataStore(Model): return self.hostname + '.' + queue_id -class Disk(TimeStampedModel): +class Disk(AclBase, TimeStampedModel): """A virtual disk. """ + ACL_LEVELS = ( + ('user', _('user')), # see all details + ('operator', _('operator')), + ('owner', _('owner')), # superuser, can delete, delegate perms + ) TYPES = [('qcow2-norm', 'qcow2 normal'), ('qcow2-snap', 'qcow2 snapshot'), ('iso', 'iso'), ('raw-ro', 'raw read-only'), ('raw-rw', 'raw')] name = CharField(blank=True, max_length=100, verbose_name=_("name")) diff --git a/circle/vm/models/instance.py b/circle/vm/models/instance.py index fe756ed..1d685d4 100644 --- a/circle/vm/models/instance.py +++ b/circle/vm/models/instance.py @@ -78,7 +78,7 @@ class VirtualMachineDescModel(BaseResourceConfigModel): abstract = True -class InstanceTemplate(VirtualMachineDescModel, TimeStampedModel): +class InstanceTemplate(AclBase, VirtualMachineDescModel, TimeStampedModel): """Virtual machine template. @@ -94,6 +94,11 @@ class InstanceTemplate(VirtualMachineDescModel, TimeStampedModel): * lease times (suspension & deletion) * time of creation and last modification """ + ACL_LEVELS = ( + ('user', _('user')), # see all details + ('operator', _('operator')), + ('owner', _('owner')), # superuser, can delete, delegate perms + ) STATES = [('NEW', _('new')), # template has just been created ('SAVING', _('saving')), # changes are being saved ('READY', _('ready'))] # template is ready for instantiation @@ -258,6 +263,13 @@ class Instance(AclBase, VirtualMachineDescModel, TimeStampedModel): """ disks = template.disks.all() if disks is None else disks + for disk in disks: + if not disk.has_level(owner, 'user'): + raise PermissionDenied() + elif (disk.type == 'qcow2-snap' + and not disk.has_level(owner, 'owner')): + raise PermissionDenied() + networks = (template.interface_set.all() if networks is None else networks)