Skip to content
Toggle navigation
P
Projects
G
Groups
S
Snippets
Help
Gutyán Gábor
/
circlestack
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
0
Merge Requests
0
Pipelines
Wiki
Snippets
Members
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Commit
41f8460e
authored
May 31, 2018
by
Szabolcs Gelencser
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Fix user assignment, use group-compatible listing
parent
1e44ca63
Show whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
90 additions
and
63 deletions
+90
-63
circle/dashboard/templates/dashboard/_manage_access.html
+7
-16
circle/dashboard/views/template.py
+5
-44
circle/dashboard/views/util.py
+28
-2
circle/vm/migrations/0018_auto_20180531_1805.py
+27
-0
circle/vm/migrations/0019_auto_20180531_1809.py
+20
-0
circle/vm/models/instance.py
+3
-1
No files found.
circle/dashboard/templates/dashboard/_manage_access.html
View file @
41f8460e
...
@@ -19,32 +19,23 @@
...
@@ -19,32 +19,23 @@
{#
title=
"{{ i.user.username }}"
>
#}
{#
title=
"{{ i.user.username }}"
>
#}
{# {% include "dashboard/_display-name.html" with user=i.user show_org=True %}#}
{# {% include "dashboard/_display-name.html" with user=i.user show_org=True %}#}
{#
</a>
#}
{#
</a>
#}
{{ member.
user
name }}
{{ member.name }}
</td>
</td>
<td>
<td>
<input
type=
"checkbox"
name=
"remove-u-{{ member.
member
_id }}"
title=
"{% trans "
Remove
"
%}"
/>
<input
type=
"checkbox"
name=
"remove-u-{{ member.
project
_id }}"
title=
"{% trans "
Remove
"
%}"
/>
</td>
</td>
</tr>
</tr>
{% endfor %}
{% endfor %}
{% for
i in acl.
groups %}
{% for
member in shared_with_
groups %}
<tr>
<tr>
<td><i
class=
"fa fa-group"
></i></td>
<td><i
class=
"fa fa-group"
></i></td>
<td>
<td>
<a
href=
"{% url "
dashboard
.
views
.
group-detail
"
pk=
i.group.pk
%}"
>
{#
<a
href=
"{% url "
dashboard
.
views
.
group-detail
"
pk=
i.group.pk
%}"
>
#}
{{i.group}}
{{ member.name }}
</a>
{#
</a>
#}
</td>
<td>
<select
class=
"form-control"
name=
"perm-g-{{i.group.id}}{% if i.level not in acl.allowed_levels %} disabled{% endif %}"
>
{% for id, name in acl.levels %}
<option
{%
if
id =
=
i
.
level
%}
selected=
"selected"
{%
endif
%}
{%
if
id
not
in
acl
.
allowed_levels
%}
disabled
{%
endif
%}
value=
"{{id}}"
>
{{name}}
</option>
{% endfor %}
</select>
</td>
</td>
<td>
<td>
<input
type=
"checkbox"
name=
"remove-g-{{
i.group.id
}}"
title=
"{% trans "
Remove
"
%}"
/>
<input
type=
"checkbox"
name=
"remove-g-{{
member.id
}}"
title=
"{% trans "
Remove
"
%}"
/>
</td>
</td>
</tr>
</tr>
{% endfor %}
{% endfor %}
...
...
circle/dashboard/views/template.py
View file @
41f8460e
...
@@ -44,6 +44,7 @@ from django.views.generic.edit import BaseUpdateView, ModelFormMixin, FormView
...
@@ -44,6 +44,7 @@ from django.views.generic.edit import BaseUpdateView, ModelFormMixin, FormView
from
django_tables2
import
SingleTableView
from
django_tables2
import
SingleTableView
from
keystoneauth1
import
session
from
keystoneauth1
import
session
from
keystoneauth1.identity
import
v3
from
keystoneauth1.identity
import
v3
from
vm.models.instance
import
TemplateUserMember
,
TemplateGroupMember
from
openstack_auth.utils
import
fix_auth_url_version
from
openstack_auth.utils
import
fix_auth_url_version
from
vm.models
import
(
from
vm.models
import
(
...
@@ -340,49 +341,6 @@ class TemplateDetail(LoginRequiredMixin, GraphMixin, SuccessMessageMixin, Update
...
@@ -340,49 +341,6 @@ class TemplateDetail(LoginRequiredMixin, GraphMixin, SuccessMessageMixin, Update
else
:
else
:
return
super
(
TemplateDetail
,
self
)
.
get
(
request
,
*
args
,
**
kwargs
)
return
super
(
TemplateDetail
,
self
)
.
get
(
request
,
*
args
,
**
kwargs
)
def
__get_glance_admin_client
(
self
,
request
):
from
keystoneauth1
import
session
from
glanceclient
import
Client
auth
=
v3
.
Password
(
auth_url
=
fix_auth_url_version
(
settings
.
OPENSTACK_KEYSTONE_URL
),
user_id
=
settings
.
OPENSTACK_CIRCLE_USERID
,
password
=
settings
.
OPENSTACK_CIRCLE_PASSWORD
,
project_id
=
request
.
user
.
tenant_id
,
)
session
=
session
.
Session
(
auth
=
auth
,
verify
=
False
)
return
Client
(
'2'
,
session
=
session
)
def
__get_members_shared_with
(
self
):
template
=
self
.
get_object
()
glance
=
self
.
__get_glance_admin_client
(
self
.
request
)
members_generator
=
glance
.
image_members
.
list
(
template
.
image_id
)
return
[
m
for
m
in
members_generator
]
def
__get_project_client
(
self
,
project_id
):
from
keystoneclient.v3
import
client
auth
=
v3
.
Password
(
auth_url
=
fix_auth_url_version
(
settings
.
OPENSTACK_KEYSTONE_URL
),
user_id
=
settings
.
OPENSTACK_CIRCLE_USERID
,
password
=
settings
.
OPENSTACK_CIRCLE_PASSWORD
,
project_id
=
project_id
,
)
sess
=
session
.
Session
(
auth
=
auth
,
verify
=
False
)
return
client
.
Client
(
session
=
sess
,
interface
=
'public'
)
def
__get_username_for
(
self
,
project_id
):
client
=
self
.
__get_project_client
(
project_id
)
project
=
client
.
projects
.
get
(
project_id
)
return
project
.
name
# as username = project's name
def
__get_users_shared_with
(
self
):
members
=
self
.
__get_members_shared_with
()
for
m
in
members
:
m
[
'username'
]
=
self
.
__get_username_for
(
m
.
member_id
)
return
members
def
get_context_data
(
self
,
**
kwargs
):
def
get_context_data
(
self
,
**
kwargs
):
template
=
self
.
get_object
()
template
=
self
.
get_object
()
openstack_api
.
glance
.
image_update
(
self
.
request
,
template
.
image_id
,
visibility
=
"shared"
)
openstack_api
.
glance
.
image_update
(
self
.
request
,
template
.
image_id
,
visibility
=
"shared"
)
...
@@ -391,7 +349,10 @@ class TemplateDetail(LoginRequiredMixin, GraphMixin, SuccessMessageMixin, Update
...
@@ -391,7 +349,10 @@ class TemplateDetail(LoginRequiredMixin, GraphMixin, SuccessMessageMixin, Update
# template, self.request.user, 'dashboard.views.template-acl')
# template, self.request.user, 'dashboard.views.template-acl')
context
[
'manage_access_url'
]
=
reverse_lazy
(
'dashboard.views.template-acl'
,
context
[
'manage_access_url'
]
=
reverse_lazy
(
'dashboard.views.template-acl'
,
kwargs
=
{
'pk'
:
template
.
id
})
kwargs
=
{
'pk'
:
template
.
id
})
context
[
'shared_with_users'
]
=
self
.
__get_users_shared_with
()
context
[
'shared_with_users'
]
=
TemplateUserMember
.
objects
.
filter
(
instancetemplate__image_id
=
template
.
image_id
)
context
[
'shared_with_groups'
]
=
TemplateGroupMember
.
objects
.
filter
(
instancetemplate__image_id
=
template
.
image_id
)
# context['disks'] = template.disks.all()
# context['disks'] = template.disks.all()
context
[
'is_owner'
]
=
template
.
owner_id
==
self
.
request
.
user
.
id
context
[
'is_owner'
]
=
template
.
owner_id
==
self
.
request
.
user
.
id
context
[
'aclform'
]
=
AclUserOrGroupAddForm
()
context
[
'aclform'
]
=
AclUserOrGroupAddForm
()
...
...
circle/dashboard/views/util.py
View file @
41f8460e
...
@@ -29,6 +29,7 @@ from django.contrib.auth.mixins import AccessMixin
...
@@ -29,6 +29,7 @@ from django.contrib.auth.mixins import AccessMixin
from
django.contrib.auth.models
import
User
,
Group
from
django.contrib.auth.models
import
User
,
Group
from
django.core.exceptions
import
PermissionDenied
from
django.core.exceptions
import
PermissionDenied
from
django.core.urlresolvers
import
reverse
from
django.core.urlresolvers
import
reverse
from
django.db
import
IntegrityError
from
django.db.models
import
Q
,
Count
,
Sum
from
django.db.models
import
Q
,
Count
,
Sum
from
django.http
import
(
from
django.http
import
(
HttpResponse
,
Http404
,
HttpResponseRedirect
,
JsonResponse
HttpResponse
,
Http404
,
HttpResponseRedirect
,
JsonResponse
...
@@ -44,7 +45,7 @@ from django.views.decorators.debug import sensitive_post_parameters
...
@@ -44,7 +45,7 @@ from django.views.decorators.debug import sensitive_post_parameters
from
django.views.generic
import
DetailView
,
View
,
DeleteView
,
FormView
from
django.views.generic
import
DetailView
,
View
,
DeleteView
,
FormView
from
django.views.generic.detail
import
SingleObjectMixin
from
django.views.generic.detail
import
SingleObjectMixin
from
keystoneauth1.identity
import
v3
from
keystoneauth1.identity
import
v3
from
vm.models.instance
import
TemplateGroupMember
from
vm.models.instance
import
TemplateGroupMember
,
TemplateUserMember
from
openstack_auth.utils
import
fix_auth_url_version
from
openstack_auth.utils
import
fix_auth_url_version
from
vm.models
import
Instance
from
vm.models
import
Instance
...
@@ -484,8 +485,15 @@ class AclUpdateView(LoginRequiredMixin, View, SingleObjectMixin):
...
@@ -484,8 +485,15 @@ class AclUpdateView(LoginRequiredMixin, View, SingleObjectMixin):
msg
=
_
(
"Already shared with group
%
s"
%
new_group_name
)
msg
=
_
(
"Already shared with group
%
s"
%
new_group_name
)
messages
.
warning
(
self
.
request
,
msg
)
messages
.
warning
(
self
.
request
,
msg
)
else
:
else
:
template
.
groups
.
get_or_create
(
group_id
=
new_group
.
id
)
try
:
group
=
TemplateGroupMember
(
group_id
=
new_group
.
id
,
name
=
new_group_name
)
group
.
save
()
except
IntegrityError
:
group
=
TemplateGroupMember
.
objects
.
get
(
group_id
=
new_group
.
id
)
template
.
groups
.
add
(
group
)
template
.
save
()
template
.
save
()
msg
=
_
(
"Successfully shared with group
%
s"
%
new_group_name
)
messages
.
success
(
self
.
request
,
msg
)
def
__handle_user_assignment
(
self
):
def
__handle_user_assignment
(
self
):
glance
=
self
.
__get_glance_admin_client
(
self
.
request
.
user
.
tenant_id
)
glance
=
self
.
__get_glance_admin_client
(
self
.
request
.
user
.
tenant_id
)
...
@@ -502,6 +510,13 @@ class AclUpdateView(LoginRequiredMixin, View, SingleObjectMixin):
...
@@ -502,6 +510,13 @@ class AclUpdateView(LoginRequiredMixin, View, SingleObjectMixin):
elif
project_id_of_user
is
not
None
:
elif
project_id_of_user
is
not
None
:
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
)
self
.
__accept_membership
(
project_id_of_user
)
try
:
user
=
TemplateUserMember
(
project_id
=
project_id_of_user
,
name
=
new_template_user
)
user
.
save
()
except
IntegrityError
:
user
=
TemplateUserMember
.
objects
.
get
(
project_id
=
project_id_of_user
)
template
.
users
.
add
(
user
)
template
.
save
()
msg
=
_
(
"Successfully shared with
%
s"
%
new_template_user
)
msg
=
_
(
"Successfully shared with
%
s"
%
new_template_user
)
messages
.
success
(
self
.
request
,
msg
)
messages
.
success
(
self
.
request
,
msg
)
else
:
else
:
...
@@ -538,12 +553,23 @@ class AclUpdateView(LoginRequiredMixin, View, SingleObjectMixin):
...
@@ -538,12 +553,23 @@ class AclUpdateView(LoginRequiredMixin, View, SingleObjectMixin):
template
=
self
.
get_object
()
template
=
self
.
get_object
()
glance
=
self
.
__get_glance_admin_client
(
self
.
request
.
user
.
tenant_id
)
glance
=
self
.
__get_glance_admin_client
(
self
.
request
.
user
.
tenant_id
)
glance
.
image_members
.
delete
(
template
.
image_id
,
member_id
)
glance
.
image_members
.
delete
(
template
.
image_id
,
member_id
)
user
=
TemplateUserMember
.
objects
.
get
(
project_id
=
member_id
)
template
.
users
.
remove
(
user
)
template
.
save
()
def
__remove_group
(
self
,
member_id
):
template
=
self
.
get_object
()
template
.
groups
.
remove
(
member_id
)
template
.
save
()
def
__handle_removes
(
self
):
def
__handle_removes
(
self
):
removes
=
self
.
__get_removes
()
removes
=
self
.
__get_removes
()
for
member_id
in
removes
[
'u'
]:
for
member_id
in
removes
[
'u'
]:
self
.
__remove_user
(
member_id
)
self
.
__remove_user
(
member_id
)
messages
.
success
(
self
.
request
,
_
(
"Successfully removed user"
))
messages
.
success
(
self
.
request
,
_
(
"Successfully removed user"
))
for
member_id
in
removes
[
'g'
]:
self
.
__remove_group
(
member_id
)
messages
.
success
(
self
.
request
,
_
(
"Successfully removed group"
))
def
post
(
self
,
request
,
*
args
,
**
kwargs
):
def
post
(
self
,
request
,
*
args
,
**
kwargs
):
template
=
self
.
get_object
()
template
=
self
.
get_object
()
...
...
circle/vm/migrations/0018_auto_20180531_1805.py
0 → 100644
View file @
41f8460e
# -*- coding: utf-8 -*-
# Generated by Django 1.11.6 on 2018-05-31 16:05
from
__future__
import
unicode_literals
from
django.db
import
migrations
,
models
class
Migration
(
migrations
.
Migration
):
dependencies
=
[
(
'vm'
,
'0017_auto_20180531_1455'
),
]
operations
=
[
migrations
.
AddField
(
model_name
=
'templategroupmember'
,
name
=
'name'
,
field
=
models
.
CharField
(
default
=
'asd'
,
max_length
=
100
,
unique
=
True
),
preserve_default
=
False
,
),
migrations
.
AddField
(
model_name
=
'templateusermember'
,
name
=
'name'
,
field
=
models
.
CharField
(
default
=
'qwe'
,
max_length
=
100
,
unique
=
True
),
preserve_default
=
False
,
),
]
circle/vm/migrations/0019_auto_20180531_1809.py
0 → 100644
View file @
41f8460e
# -*- coding: utf-8 -*-
# Generated by Django 1.11.6 on 2018-05-31 16:09
from
__future__
import
unicode_literals
from
django.db
import
migrations
class
Migration
(
migrations
.
Migration
):
dependencies
=
[
(
'vm'
,
'0018_auto_20180531_1805'
),
]
operations
=
[
migrations
.
RenameField
(
model_name
=
'templateusermember'
,
old_name
=
'user_id'
,
new_name
=
'project_id'
,
),
]
circle/vm/models/instance.py
View file @
41f8460e
...
@@ -120,7 +120,8 @@ class VirtualMachineDescModel(BaseResourceConfigModel):
...
@@ -120,7 +120,8 @@ class VirtualMachineDescModel(BaseResourceConfigModel):
class
TemplateUserMember
(
Model
):
class
TemplateUserMember
(
Model
):
user_id
=
CharField
(
blank
=
False
,
max_length
=
100
,
unique
=
True
)
name
=
CharField
(
blank
=
False
,
max_length
=
100
,
unique
=
True
)
project_id
=
CharField
(
blank
=
False
,
max_length
=
100
,
unique
=
True
)
class
Meta
:
class
Meta
:
app_label
=
'vm'
app_label
=
'vm'
...
@@ -128,6 +129,7 @@ class TemplateUserMember(Model):
...
@@ -128,6 +129,7 @@ class TemplateUserMember(Model):
class
TemplateGroupMember
(
Model
):
class
TemplateGroupMember
(
Model
):
name
=
CharField
(
blank
=
False
,
max_length
=
100
,
unique
=
True
)
group_id
=
CharField
(
blank
=
False
,
max_length
=
100
,
unique
=
True
)
group_id
=
CharField
(
blank
=
False
,
max_length
=
100
,
unique
=
True
)
class
Meta
:
class
Meta
:
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment