Commit 132dd4a5 by Szabolcs Gelencser

Remove ACL model and arch field from instance and template

parent 8ea3fe0c
"""
Creates Levels for all installed apps that have levels.
"""
from django.db.models import signals
from django.apps import apps
from django.db import DEFAULT_DB_ALIAS
from django.core.exceptions import ImproperlyConfigured
from ..models import Level, AclBase
def create_levels(app_config, verbosity=False, using=DEFAULT_DB_ALIAS,
**kwargs):
"""Create and set the weights of the configured Levels.
Based on django.contrib.auth.management.__init__.create_permissions"""
# if not router.allow_migrate(using, auth_app.Permission):
# return
from django.contrib.contenttypes.models import ContentType
app_models = [k for k in apps.get_models(app_config)
if AclBase in k.__bases__]
print "Creating levels for models: %s." % ", ".join(
[m.__name__ for m in app_models])
# This will hold the levels we're looking for as
# (content_type, (codename, name))
searched_levels = list()
level_weights = list()
# The codenames and ctypes that should exist.
ctypes = set()
for klass in app_models:
# Force looking up the content types in the current database
# before creating foreign keys to them.
ctype1 = ContentType.objects.db_manager(using).get_for_model(klass)
ctypes.add(ctype1)
weight = 0
try:
for codename, name in klass.ACL_LEVELS:
searched_levels.append((ctype1, (codename, name)))
level_weights.append((ctype1, codename, weight))
weight += 1
except AttributeError:
raise ImproperlyConfigured(
"Class %s doesn't have ACL_LEVELS attribute." % klass)
# Find all the Levels that have a content_type for a model we're
# looking for. We don't need to check for codenames since we already have
# a list of the ones we're going to create.
all_levels = set(Level.objects.using(using).filter(
content_type__in=ctypes,
).values_list(
"content_type", "codename"
))
levels = [
Level(codename=codename, name=name, content_type=ctype)
for ctype, (codename, name) in searched_levels
if (ctype.pk, codename) not in all_levels
]
Level.objects.using(using).bulk_create(levels)
if verbosity >= 2:
print("Adding levels [%s]." % ", ".join(unicode(l) for l in levels))
print("Searched: [%s]." % ", ".join(
unicode(l) for l in searched_levels))
print("All: [%s]." % ", ".join(unicode(l) for l in all_levels))
# set weights
for ctype, codename, weight in level_weights:
Level.objects.filter(codename=codename,
content_type=ctype).update(weight=weight)
signals.post_migrate.connect(
create_levels, dispatch_uid="circle.acl.management.create_levels")
# Copyright 2014 Budapest University of Technology and Economics (BME IK)
#
# This file is part of CIRCLE Cloud.
#
# CIRCLE is free software: you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free
# Software Foundation, either version 3 of the License, or (at your option)
# any later version.
#
# CIRCLE is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
# details.
#
# You should have received a copy of the GNU General Public License along
# with CIRCLE. If not, see <http://www.gnu.org/licenses/>.
from django.core.management.base import BaseCommand
from .. import create_levels
class Command(BaseCommand):
args = ''
help = 'Regenerates Levels'
def handle(self, *args, **options):
create_levels(None, None, 3)
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models, migrations
from django.conf import settings
class Migration(migrations.Migration):
dependencies = [
('auth', '0001_initial'),
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('contenttypes', '0001_initial'),
]
operations = [
migrations.CreateModel(
name='Level',
fields=[
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
('name', models.CharField(max_length=50, verbose_name=b'name')),
('codename', models.CharField(max_length=100, verbose_name=b'codename')),
('weight', models.IntegerField(null=True, verbose_name=b'weight')),
('content_type', models.ForeignKey(to='contenttypes.ContentType')),
],
options={
},
bases=(models.Model,),
),
migrations.CreateModel(
name='ObjectLevel',
fields=[
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
('object_id', models.IntegerField()),
('content_type', models.ForeignKey(to='contenttypes.ContentType')),
('groups', models.ManyToManyField(to='auth.Group')),
('level', models.ForeignKey(to='acl.Level')),
('users', models.ManyToManyField(to=settings.AUTH_USER_MODEL)),
],
options={
},
bases=(models.Model,),
),
migrations.AlterUniqueTogether(
name='objectlevel',
unique_together=set([('content_type', 'object_id', 'level')]),
),
migrations.AlterUniqueTogether(
name='level',
unique_together=set([('content_type', 'codename')]),
),
]
# Copyright 2014 Budapest University of Technology and Economics (BME IK)
#
# This file is part of CIRCLE Cloud.
#
# CIRCLE is free software: you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free
# Software Foundation, either version 3 of the License, or (at your option)
# any later version.
#
# CIRCLE is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
# details.
#
# You should have received a copy of the GNU General Public License along
# with CIRCLE. If not, see <http://www.gnu.org/licenses/>.
import logging
from django.contrib.auth.models import Group
from django.contrib.contenttypes.fields import (
GenericForeignKey, GenericRelation
)
from django.contrib.contenttypes.models import ContentType
from django.db.models import (
ManyToManyField, ForeignKey, CharField, Model, IntegerField, Q
)
from openstack_auth.user import User
logger = logging.getLogger(__name__)
class Level(Model):
"""Definition of a permission level.
Instances are automatically populated based on AclBase."""
name = CharField('name', max_length=50)
content_type = ForeignKey(ContentType)
codename = CharField('codename', max_length=100)
weight = IntegerField('weight', null=True)
def __unicode__(self):
return "<%s/%s>" % (unicode(self.content_type), self.name)
class Meta:
app_label = 'acl'
unique_together = (('content_type', 'codename'),
# ('content_type', 'weight'),
# TODO find a way of temp. disabling this constr.
)
class ObjectLevel(Model):
"""Permission level for a specific object."""
level = ForeignKey(Level)
content_type = ForeignKey(ContentType)
object_id = IntegerField()
content_object = GenericForeignKey()
users = ManyToManyField(User)
groups = ManyToManyField(Group)
def __unicode__(self):
return "<%s: %s>" % (unicode(self.content_object), unicode(self.level))
class Meta:
app_label = 'acl'
unique_together = (('content_type', 'object_id', 'level'),)
class AclBase(Model):
"""Define permission levels for Users/Groups per object."""
object_level_set = GenericRelation(ObjectLevel)
def clone_acl(self, other):
pass
@classmethod
def get_level_object(cls, level):
ct = ContentType.objects.get_for_model(cls)
return Level.objects.get(codename=level, content_type=ct)
def set_level(self, whom, level):
"""Set level of object for a user or group.
:param whom: user or group the level is set for
:type whom: User or Group
:param level: codename of level to set, or None
:type level: Level or str or unicode or NoneType
"""
if isinstance(whom, User):
self.set_user_level(whom, level)
elif isinstance(whom, Group):
self.set_group_level(whom, level)
else:
raise AttributeError('"whom" must be a User or Group object.')
def set_user_level(self, user, level):
#TODO: delete
pass
def set_group_level(self, group, level):
#TODO: delete
pass
def has_level(self, user, level, group_also=True):
#TODO: implement
logger.debug('%s.has_level(%s, %s, %s) called',
*[unicode(p) for p in [self, user, level, group_also]])
return True
def get_users_with_level(self, **kwargs):
# TODO: implement
logger.debug('%s.get_users_with_level() called', unicode(self))
return []
def get_groups_with_level(self):
# TODO: implement
logger.debug('%s.get_groups_with_level() called', unicode(self))
return []
@classmethod
def get_objects_with_level(cls, level, user,
group_also=True, owner_also=False,
disregard_superuser=False):
logger.debug('%s.get_objects_with_level(%s,%s) called',
unicode(cls), unicode(level), unicode(user))
if user is None or not user.is_authenticated():
return cls.objects.none()
if getattr(user, 'is_superuser', False) and not disregard_superuser:
logger.debug('- superuser granted')
return cls.objects.all()
if isinstance(level, basestring):
level = cls.get_level_object(level)
logger.debug("- level set by str: %s", unicode(level))
ct = ContentType.objects.get_for_model(cls)
levelfilter = Q(users=user)
if group_also:
levelfilter |= Q(groups__in=user.groups.all())
ols = ObjectLevel.objects.filter(
levelfilter,
content_type=ct, level__weight__gte=level.weight).distinct()
clsfilter = Q(object_level_set__in=ols.all())
if owner_also:
clsfilter |= Q(owner=user)
return cls.objects.filter(clsfilter).distinct()
@classmethod
def get_objects_with_group_level(cls, level, group):
if isinstance(level, basestring):
level = cls.get_level_object(level)
ct = ContentType.objects.get_for_model(cls)
levelfilter = Q(groups=group)
ols = ObjectLevel.objects.filter(
levelfilter,
content_type=ct, level__weight__gte=level.weight).distinct()
clsfilter = Q(object_level_set__in=ols.all())
return cls.objects.filter(clsfilter).distinct()
def save(self, *args, **kwargs):
super(AclBase, self).save(*args, **kwargs)
if 'owner' in dict(self.ACL_LEVELS) and (hasattr(self, 'owner') and
self.owner):
self.set_user_level(self.owner, 'owner')
class Meta:
abstract = True
# Copyright 2014 Budapest University of Technology and Economics (BME IK)
#
# This file is part of CIRCLE Cloud.
#
# CIRCLE is free software: you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free
# Software Foundation, either version 3 of the License, or (at your option)
# any later version.
#
# CIRCLE is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
# details.
#
# You should have received a copy of the GNU General Public License along
# with CIRCLE. If not, see <http://www.gnu.org/licenses/>.
from django.conf import settings
# https://code.djangoproject.com/ticket/7835
if settings.SETTINGS_MODULE == 'circle.settings.test':
from .test_acl import TestModel, Test2Model # noqa
# Copyright 2014 Budapest University of Technology and Economics (BME IK)
#
# This file is part of CIRCLE Cloud.
#
# CIRCLE is free software: you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free
# Software Foundation, either version 3 of the License, or (at your option)
# any later version.
#
# CIRCLE is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
# details.
#
# You should have received a copy of the GNU General Public License along
# with CIRCLE. If not, see <http://www.gnu.org/licenses/>.
# Create your views here.
No preview for this file type
...@@ -368,7 +368,6 @@ LOCAL_APPS = ( ...@@ -368,7 +368,6 @@ LOCAL_APPS = (
'network', 'network',
'dashboard', 'dashboard',
'manager', 'manager',
'acl',
'monitor', 'monitor',
'request', 'request',
'openstack_auth', 'openstack_auth',
......
...@@ -44,7 +44,6 @@ from model_utils.models import TimeFramedModel, TimeStampedModel ...@@ -44,7 +44,6 @@ from model_utils.models import TimeFramedModel, TimeStampedModel
from model_utils.fields import StatusField from model_utils.fields import StatusField
from model_utils import Choices from model_utils import Choices
from acl.models import AclBase
from common.models import HumanReadableObject, create_readable, Encoder from common.models import HumanReadableObject, create_readable, Encoder
from vm.models.instance import ACCESS_METHODS from vm.models.instance import ACCESS_METHODS
...@@ -283,12 +282,7 @@ class FutureMember(Model): ...@@ -283,12 +282,7 @@ class FutureMember(Model):
return u"%s (%s)" % (self.org_id, self.group) return u"%s (%s)" % (self.org_id, self.group)
class GroupProfile(AclBase): class GroupProfile(Model):
ACL_LEVELS = (
('operator', _('operator')),
('owner', _('owner')),
)
group = OneToOneField(Group) group = OneToOneField(Group)
org_id = CharField( org_id = CharField(
unique=True, blank=True, null=True, max_length=64, unique=True, blank=True, null=True, max_length=64,
......
...@@ -138,15 +138,12 @@ class VmDetailView(LoginRequiredMixin, GraphMixin, DetailView): ...@@ -138,15 +138,12 @@ class VmDetailView(LoginRequiredMixin, GraphMixin, DetailView):
activities = openstack_api.nova.instance_action_list(self.request, instance.os_server_id) activities = openstack_api.nova.instance_action_list(self.request, instance.os_server_id)
context['vlans'] = Vlan.get_objects_with_level( # context['vlans'] = Vlan.get_objects_with_level(
'user', self.request.user # 'user', self.request.user
).exclude( # exclude already added interfaces # ).exclude( # exclude already added interfaces
pk__in=Interface.objects.filter( # pk__in=Interface.objects.filter(
instance=self.get_object()).values_list("vlan", flat=True) # instance=self.get_object()).values_list("vlan", flat=True)
).all() # ).all()
# context['acl'] = AclUpdateView.get_acl_data(
# instance, self.request.user, 'dashboard.views.vm-acl')
context['aclform'] = AclUserOrGroupAddForm()
context['os_type_icon'] = instance.os_type.replace("unknown", context['os_type_icon'] = instance.os_type.replace("unknown",
"question") "question")
# ipv6 infos # ipv6 infos
......
...@@ -42,7 +42,6 @@ from common.models import method_cache, WorkerNotFound, HumanSortField ...@@ -42,7 +42,6 @@ from common.models import method_cache, WorkerNotFound, HumanSortField
from firewall.tasks.local_tasks import reloadtask from firewall.tasks.local_tasks import reloadtask
from firewall.tasks.remote_tasks import get_dhcp_clients from firewall.tasks.remote_tasks import get_dhcp_clients
from .iptables import IptRule from .iptables import IptRule
from acl.models import AclBase
from openstack_auth.user import User from openstack_auth.user import User
...@@ -272,7 +271,7 @@ class Rule(models.Model): ...@@ -272,7 +271,7 @@ class Rule(models.Model):
) )
class Vlan(AclBase, models.Model): class Vlan(models.Model):
""" """
A vlan of the network, A vlan of the network,
...@@ -284,11 +283,6 @@ class Vlan(AclBase, models.Model): ...@@ -284,11 +283,6 @@ class Vlan(AclBase, models.Model):
Each vlan network has a unique identifier, a name, a unique IPv4 and IPv6 Each vlan network has a unique identifier, a name, a unique IPv4 and IPv6
range. The gateway also has an IP address in each range. range. The gateway also has an IP address in each range.
""" """
ACL_LEVELS = (
('user', _('user')),
('operator', _('operator')),
)
CHOICES_NETWORK_TYPE = (('public', _('public')), CHOICES_NETWORK_TYPE = (('public', _('public')),
('portforward', _('portforward'))) ('portforward', _('portforward')))
vid = models.IntegerField(unique=True, vid = models.IntegerField(unique=True,
......
# -*- coding: utf-8 -*-
# Generated by Django 1.11.6 on 2018-02-26 11:39
from __future__ import unicode_literals
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('vm', '0006_remove_instance_name'),
]
operations = [
migrations.RemoveField(
model_name='instancetemplate',
name='arch',
),
migrations.RemoveField(
model_name='namedbaseresourceconfig',
name='arch',
),
]
...@@ -25,13 +25,6 @@ from django.utils.timesince import timeuntil ...@@ -25,13 +25,6 @@ from django.utils.timesince import timeuntil
from model_utils.models import TimeStampedModel from model_utils.models import TimeStampedModel
from acl.models import AclBase
ARCHITECTURES = (('x86_64', 'x86-64 (64 bit)'),
('i686', 'x86 (32 bit)'))
class BaseResourceConfigModel(Model): class BaseResourceConfigModel(Model):
"""Abstract base for models with base resource configuration parameters. """Abstract base for models with base resource configuration parameters.
...@@ -47,8 +40,6 @@ class BaseResourceConfigModel(Model): ...@@ -47,8 +40,6 @@ class BaseResourceConfigModel(Model):
help_text=_('Upper memory size limit ' help_text=_('Upper memory size limit '
'for balloning.'), 'for balloning.'),
validators=[MinValueValidator(0)]) validators=[MinValueValidator(0)])
arch = CharField(max_length=10, verbose_name=_('architecture'),
choices=ARCHITECTURES)
priority = IntegerField(verbose_name=_('priority'), priority = IntegerField(verbose_name=_('priority'),
help_text=_('CPU priority.'), help_text=_('CPU priority.'),
validators=[MinValueValidator(0)]) validators=[MinValueValidator(0)])
...@@ -73,18 +64,13 @@ class NamedBaseResourceConfig(BaseResourceConfigModel, TimeStampedModel): ...@@ -73,18 +64,13 @@ class NamedBaseResourceConfig(BaseResourceConfigModel, TimeStampedModel):
return self.name return self.name
class Lease(AclBase): class Lease(Model):
"""Lease times for VM instances. """Lease times for VM instances.
Specifies a time duration until suspension and deletion of a VM Specifies a time duration until suspension and deletion of a VM
instance. instance.
""" """
ACL_LEVELS = (
('user', _('user')), # use this lease
('operator', _('operator')), # share this lease
('owner', _('owner')), # change this lease
)
name = CharField(max_length=100, unique=True, name = CharField(max_length=100, unique=True,
verbose_name=_('name')) verbose_name=_('name'))
suspend_interval_seconds = IntegerField( suspend_interval_seconds = IntegerField(
......
...@@ -41,7 +41,6 @@ from model_utils.models import TimeStampedModel, StatusModel ...@@ -41,7 +41,6 @@ from model_utils.models import TimeStampedModel, StatusModel
from openstack_api.nova import Server from openstack_api.nova import Server
from taggit.managers import TaggableManager from taggit.managers import TaggableManager
from acl.models import AclBase
from common.models import ( from common.models import (
activitycontextimpl, create_readable, HumanReadableException, activitycontextimpl, create_readable, HumanReadableException,
) )
...@@ -125,15 +124,10 @@ class VirtualMachineDescModel(BaseResourceConfigModel): ...@@ -125,15 +124,10 @@ class VirtualMachineDescModel(BaseResourceConfigModel):
abstract = True abstract = True
class InstanceTemplate(AclBase, VirtualMachineDescModel, TimeStampedModel): class InstanceTemplate(VirtualMachineDescModel, TimeStampedModel):
"""Virtual machine template. """Virtual machine template.
""" """
ACL_LEVELS = (
('user', _('user')), # see all details
('operator', _('operator')),
('owner', _('owner')), # superuser, can delete, delegate perms
)
name = CharField(max_length=100, verbose_name=_('name'), name = CharField(max_length=100, verbose_name=_('name'),
help_text=_('Human readable name of template.')) help_text=_('Human readable name of template.'))
description = TextField(verbose_name=_('description'), blank=True) description = TextField(verbose_name=_('description'), blank=True)
...@@ -213,11 +207,6 @@ class Instance(OperatedMixin, TimeStampedModel): ...@@ -213,11 +207,6 @@ class Instance(OperatedMixin, TimeStampedModel):
"""Virtual machine instance. """Virtual machine instance.
""" """
ACL_LEVELS = (
('user', _('user')), # see all details
('operator', _('operator')), # console, networking, change state
('owner', _('owner')), # superuser, can delete, delegate perms
)
STATUS = Choices( STATUS = Choices(
('PAUSED', _('paused')), ('PAUSED', _('paused')),
('SUSPENDED', _('suspended')), ('SUSPENDED', _('suspended')),
......
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 sign in to comment