Commit 1e44ca63 by Szabolcs Gelencser

Add initial group assignment

parent cc8d0f7e
......@@ -44,6 +44,7 @@ from django.views.decorators.debug import sensitive_post_parameters
from django.views.generic import DetailView, View, DeleteView, FormView
from django.views.generic.detail import SingleObjectMixin
from keystoneauth1.identity import v3
from vm.models.instance import TemplateGroupMember
from openstack_auth.utils import fix_auth_url_version
from vm.models import Instance
......@@ -413,27 +414,9 @@ class RequestFormOperationMixin(FormOperationMixin):
class AclUpdateView(LoginRequiredMixin, View, SingleObjectMixin):
# def send_success_message(self, whom, old_level, new_level):
# if old_level and new_level:
# msg = _("Acl user/group %(w)s successfully modified.")
# elif not old_level and new_level:
# msg = _("Acl user/group %(w)s successfully added.")
# elif old_level and not new_level:
# msg = _("Acl user/group %(w)s successfully removed.")
# if msg:
# messages.success(self.request, msg % {'w': whom})
#
# def add_levels(self):
# self.request, _('User "%s" has already '
# 'access to this object.') % name)
# self.request, _('Group "%s" has already '
# 'access to this object.') % name)
# self.request, _('User or group "%s" not found.') % name)
def __get_current_users_groups(self, request):
def __get_current_users_groups(self):
from openstack_api import keystone
groups = keystone.group_list(request=self.request, user=self.request.user)
return [g.name for g in groups]
return keystone.group_list(request=self.request, user=self.request.user)
def __get_glance_admin_client(self, project_id):
from keystoneauth1 import session
......@@ -449,7 +432,7 @@ class AclUpdateView(LoginRequiredMixin, View, SingleObjectMixin):
return Client('2', session=session)
def __get_all_projects(self):
def __get_keystone_admin_client(self):
from keystoneauth1 import session
from keystoneclient.v3 import client
......@@ -459,9 +442,10 @@ class AclUpdateView(LoginRequiredMixin, View, SingleObjectMixin):
password=settings.OPENSTACK_CIRCLE_PASSWORD,
)
sess = session.Session(auth=auth, verify=False)
keystone = client.Client(session=sess, interface=settings.OPENSTACK_INTERFACE)
return client.Client(session=sess, interface=settings.OPENSTACK_INTERFACE)
return keystone.projects.list(
def __get_all_projects(self):
return self.__get_keystone_admin_client().projects.list(
domain=settings.OPENSTACK_CIRCLE_DOMAIN_ID,
user=settings.OPENSTACK_CIRCLE_USERID
)
......@@ -478,13 +462,35 @@ class AclUpdateView(LoginRequiredMixin, View, SingleObjectMixin):
glance = self.__get_glance_admin_client(project_id_of_user)
glance.image_members.update(template.image_id, project_id_of_user, 'accepted')
def __handle_group_assignment(self, request):
def __list_users_of_group(self, group_id):
keystone = self.__get_keystone_admin_client()
return keystone.users.list(group=group_id)
def __get_group_by_name(self, name):
groups = self.__get_current_users_groups()
for g in groups:
if g.name == name:
return g
return None
def __handle_group_assignment(self):
new_group_name = self.request.POST['name']
template = self.get_object()
new_group = self.__get_group_by_name(new_group_name)
old_groups = TemplateGroupMember.objects.filter(
instancetemplate__image_id=template.image_id)
if new_group.id in old_groups:
msg = _("Already shared with group %s" % new_group_name)
messages.warning(self.request, msg)
else:
template.groups.get_or_create(group_id=new_group.id)
template.save()
def __handle_user_assignment(self, request):
glance = self.__get_glance_admin_client(request.user.tenant_id)
def __handle_user_assignment(self):
glance = self.__get_glance_admin_client(self.request.user.tenant_id)
template = self.get_object()
new_template_user = request.POST['name']
new_template_user = self.request.POST['name']
project_id_of_user = self.__get_project_id_by_name(new_template_user)
old_members_generator = glance.image_members.list(template.image_id)
......@@ -494,31 +500,33 @@ class AclUpdateView(LoginRequiredMixin, View, SingleObjectMixin):
msg = _("Template is already shared with %s" % new_template_user)
messages.warning(self.request, msg)
elif project_id_of_user is not None:
membership = glance.image_members.create(template.image_id, project_id_of_user)
glance.image_members.create(template.image_id, project_id_of_user)
self.__accept_membership(project_id_of_user)
msg = _("Successfully shared with %s" % new_template_user)
messages.success(self.request, msg)
else:
msg = _("User or group with name '%s' doesn't exist" % new_template_user)
msg = _("User or group with name '%s' doesn't exist "
"or you are not authorized to share with it" % new_template_user)
messages.error(self.request, msg)
def __handle_assignments(self, request):
current_users_groups = self.__get_current_users_groups(request)
new_template_user = request.POST['name']
def __handle_assignments(self):
current_users_groups = self.__get_current_users_groups()
current_group_names = [g.name for g in current_users_groups]
new_template_user = self.request.POST['name']
if new_template_user is not None and len(new_template_user) > 0:
if new_template_user in current_users_groups:
self.__handle_group_assignment(request)
if new_template_user in current_group_names:
self.__handle_group_assignment()
else:
self.__handle_user_assignment(request)
self.__handle_user_assignment()
def __get_removes(self, request):
def __get_removes(self):
removes = {
"u": [],
"g": [],
}
for key, value in request.POST.items():
for key, value in self.request.POST.items():
m = re.match('remove-([ug])-(.+)', key)
if m:
t, name = m.groups()
......@@ -526,23 +534,23 @@ class AclUpdateView(LoginRequiredMixin, View, SingleObjectMixin):
return removes
def __remove_user(self, request, member_id):
def __remove_user(self, member_id):
template = self.get_object()
glance = self.__get_glance_admin_client(request.user.tenant_id)
glance = self.__get_glance_admin_client(self.request.user.tenant_id)
glance.image_members.delete(template.image_id, member_id)
def __handle_removes(self, request):
removes = self.__get_removes(request)
def __handle_removes(self):
removes = self.__get_removes()
for member_id in removes['u']:
self.__remove_user(request, member_id)
messages.success(request, _("Successfully removed user"))
self.__remove_user(member_id)
messages.success(self.request, _("Successfully removed user"))
def post(self, request, *args, **kwargs):
template = self.get_object()
openstack_api.glance.image_update(request, template.image_id, visibility="shared")
self.__handle_assignments(request)
self.__handle_removes(request)
self.__handle_assignments()
self.__handle_removes()
return redirect("%s#access" % template.get_absolute_url())
......
......@@ -427,7 +427,7 @@ def user_list(request, project=None, domain=None, group=None, filters=None):
except keystone_exceptions.NotFound:
raise exceptions.NotFound()
else:
users = keystoneclient(request, admin=True).users.list(**kwargs)
users = keystoneclient(request).users.list(**kwargs) # TODO: was admin API
return [VERSIONS.upgrade_v2_user(user) for user in users]
......
# -*- coding: utf-8 -*-
# Generated by Django 1.11.6 on 2018-05-31 12:55
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('vm', '0016_auto_20180522_1515'),
]
operations = [
migrations.CreateModel(
name='TemplateGroupMember',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('group_id', models.CharField(max_length=100, unique=True)),
],
options={
'db_table': 'vm_template_group_member',
},
),
migrations.CreateModel(
name='TemplateUserMember',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('user_id', models.CharField(max_length=100, unique=True)),
],
options={
'db_table': 'vm_template_user_member',
},
),
migrations.AddField(
model_name='instancetemplate',
name='groups',
field=models.ManyToManyField(blank=True, help_text='Shared with groups', to='vm.TemplateGroupMember', verbose_name='groups'),
),
migrations.AddField(
model_name='instancetemplate',
name='users',
field=models.ManyToManyField(blank=True, help_text='Shared with users', to='vm.TemplateUserMember', verbose_name='users'),
),
]
......@@ -119,13 +119,20 @@ class VirtualMachineDescModel(BaseResourceConfigModel):
abstract = True
class TemplateMemberGroup(Model):
group_id = CharField(blank=False, max_length=100, unique=True)
class TemplateUserMember(Model):
user_id = CharField(blank=False, max_length=100, unique=True)
class Meta:
app_label = 'vm'
db_table = 'vm_template_member_group'
db_table = 'vm_template_user_member'
class TemplateGroupMember(Model):
group_id = CharField(blank=False, max_length=100, unique=True)
class Meta:
app_label = 'vm'
db_table = 'vm_template_group_member'
class InstanceTemplate(TimeStampedModel):
......@@ -147,6 +154,20 @@ class InstanceTemplate(TimeStampedModel):
flavor_id = CharField(blank=False, max_length=100)
owner_id = CharField(blank=False, max_length=100)
users = ManyToManyField(
TemplateUserMember,
blank=True,
help_text=_("Shared with users"),
verbose_name=_('users'),
)
groups = ManyToManyField(
TemplateGroupMember,
blank=True,
help_text=_("Shared with groups"),
verbose_name=_('groups'),
)
class Meta:
app_label = 'vm'
db_table = 'vm_instancetemplate'
......
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