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
c38e0610
authored
Feb 07, 2014
by
Kálmán Viktor
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
dashboard: template acl
parent
3f0ef5e7
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
118 additions
and
8 deletions
+118
-8
circle/dashboard/forms.py
+16
-1
circle/dashboard/templates/dashboard/template-edit.html
+50
-2
circle/dashboard/urls.py
+8
-1
circle/dashboard/views.py
+38
-4
circle/vm/models/instance.py
+6
-0
No files found.
circle/dashboard/forms.py
View file @
c38e0610
from
datetime
import
timedelta
from
datetime
import
timedelta
import
uuid
import
uuid
from
django.contrib.auth.models
import
User
from
crispy_forms.helper
import
FormHelper
from
crispy_forms.helper
import
FormHelper
from
crispy_forms.layout
import
(
from
crispy_forms.layout
import
(
Layout
,
Div
,
BaseInput
,
Field
,
HTML
,
Submit
,
Fieldset
,
TEMPLATE_PACK
Layout
,
Div
,
BaseInput
,
Field
,
HTML
,
Submit
,
Fieldset
,
TEMPLATE_PACK
...
@@ -430,8 +432,16 @@ class TemplateForm(forms.ModelForm):
...
@@ -430,8 +432,16 @@ class TemplateForm(forms.ModelForm):
def
__init__
(
self
,
*
args
,
**
kwargs
):
def
__init__
(
self
,
*
args
,
**
kwargs
):
parent
=
kwargs
.
pop
(
"parent"
,
None
)
parent
=
kwargs
.
pop
(
"parent"
,
None
)
self
.
user
=
kwargs
.
pop
(
"user"
,
None
)
super
(
TemplateForm
,
self
)
.
__init__
(
*
args
,
**
kwargs
)
super
(
TemplateForm
,
self
)
.
__init__
(
*
args
,
**
kwargs
)
self
.
fields
[
'disks'
]
=
forms
.
ModelMultipleChoiceField
(
queryset
=
DISKS
)
self
.
fields
[
'disks'
]
=
forms
.
ModelMultipleChoiceField
(
queryset
=
Disk
.
get_objects_with_level
(
'user'
,
self
.
user
)
.
exclude
(
type
=
"qcow2-snap"
)
)
data
=
self
.
data
.
copy
()
data
[
'owner'
]
=
self
.
user
.
pk
self
.
data
=
data
if
parent
is
not
None
:
if
parent
is
not
None
:
template
=
InstanceTemplate
.
objects
.
get
(
pk
=
parent
)
template
=
InstanceTemplate
.
objects
.
get
(
pk
=
parent
)
...
@@ -458,6 +468,11 @@ class TemplateForm(forms.ModelForm):
...
@@ -458,6 +468,11 @@ class TemplateForm(forms.ModelForm):
self
.
instance
.
ram_size
=
512
self
.
instance
.
ram_size
=
512
self
.
instance
.
num_cores
=
2
self
.
instance
.
num_cores
=
2
def
clean_owner
(
self
):
if
self
.
instance
.
pk
is
not
None
:
return
User
.
objects
.
get
(
pk
=
self
.
instance
.
owner
.
pk
)
return
self
.
user
def
save
(
self
,
commit
=
True
):
def
save
(
self
,
commit
=
True
):
data
=
self
.
cleaned_data
data
=
self
.
cleaned_data
self
.
instance
.
max_ram_size
=
data
.
get
(
'ram_size'
)
self
.
instance
.
max_ram_size
=
data
.
get
(
'ram_size'
)
...
...
circle/dashboard/templates/dashboard/template-edit.html
View file @
c38e0610
...
@@ -4,11 +4,11 @@
...
@@ -4,11 +4,11 @@
{% block content %}
{% block content %}
<div
class=
"row"
>
<div
class=
"row"
>
<div
class=
"col-md-
12
"
>
<div
class=
"col-md-
8
"
>
<div
class=
"panel panel-default"
>
<div
class=
"panel panel-default"
>
<div
class=
"panel-heading"
>
<div
class=
"panel-heading"
>
<a
class=
"pull-right btn btn-default btn-xs"
href=
"{% url "
dashboard
.
views
.
template-list
"
%}"
>
Back
</a>
<a
class=
"pull-right btn btn-default btn-xs"
href=
"{% url "
dashboard
.
views
.
template-list
"
%}"
>
Back
</a>
<h3
class=
"no-margin"
><i
class=
"icon-desktop"
></i>
Edit template
</h3>
<h3
class=
"no-margin"
><i
class=
"icon-desktop"
></i>
{% trans "Edit template" %}
</h3>
</div>
</div>
<div
class=
"panel-body"
>
<div
class=
"panel-body"
>
{% with form=form %}
{% with form=form %}
...
@@ -18,8 +18,56 @@
...
@@ -18,8 +18,56 @@
</div>
</div>
</div>
</div>
</div>
</div>
<div
class=
"col-md-4"
>
<div
class=
"panel panel-default"
>
<div
class=
"panel-heading"
>
<h3
class=
"no-margin"
><i
class=
"icon-group"
></i>
{% trans "Manage access" %}
</h3>
</div>
<div
class=
"panel-body"
>
<form
action=
"{% url "
dashboard
.
views
.
template-acl
"
pk=
object.pk
%}"
method=
"post"
>
{% csrf_token %}
<table
class=
"table table-striped table-with-form-fields"
>
<thead><tr><th></th><th>
{% trans "Who" %}
</th><th>
{% trans "What" %}
</th><th></th></tr></thead>
<tbody>
{% for i in acl.users %}
<tr><td><i
class=
"icon-user"
></i></td><td>
{{i.user}}
</td>
<td><select
class=
"form-control"
name=
"perm-u-{{i.user.id}}"
>
{% for id, name in acl.levels %}
<option
{%
if
id =
i.level%}
selected=
"selected"
{%
endif
%}
value=
"{{id}}"
>
{{name}}
</option>
{% endfor %}
</select></td>
<td><a
href=
"#"
class=
"btn btn-link btn-xs"
><i
class=
"icon-remove"
><span
class=
"sr-only"
>
{% trans "remove" %}
</span></i></a></td></tr>
{% endfor %}
{% for i in acl.groups %}
<tr><td><i
class=
"icon-group"
></i></td><td>
{{i.group}}
</td>
<td><select
class=
"form-control"
name=
"perm-g-{{i.group.id}}"
>
{% for id, name in acl.levels %}
<option
{%
if
id =
i.level%}
selected=
"selected"
{%
endif
%}
value=
"{{id}}"
>
{{name}}
</option>
{% endfor %}
</select></td>
<td><a
href=
"#"
class=
"btn btn-link btn-xs"
><i
class=
"icon-remove"
><span
class=
"sr-only"
>
{% trans "remove" %}
</span></i></a></td></tr>
{% endfor %}
<tr><td><i
class=
"icon-plus"
></i></td>
<td><input
type=
"text"
class=
"form-control"
name=
"perm-new-name"
placeholder=
"{% trans "
Name
of
group
or
user
"
%}"
></td>
<td><select
class=
"form-control"
name=
"perm-new"
>
{% for id, name in acl.levels %}
<option
value=
"{{id}}"
>
{{name}}
</option>
{% endfor %}
</select></td><td></td>
</tr>
</tbody>
</table>
<div
class=
"form-actions"
>
<button
type=
"submit"
class=
"btn btn-success"
>
{% trans "Save" %}
</button>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
<style>
<style>
fieldset
{
fieldset
{
margin-top
:
40px
;
margin-top
:
40px
;
...
...
circle/dashboard/urls.py
View file @
c38e0610
...
@@ -7,7 +7,7 @@ from .views import (
...
@@ -7,7 +7,7 @@ from .views import (
TransferOwnershipView
,
TransferOwnershipConfirmView
,
NodeDelete
,
TransferOwnershipView
,
TransferOwnershipConfirmView
,
NodeDelete
,
TemplateList
,
LeaseDetail
,
NodeCreate
,
LeaseCreate
,
TemplateCreate
,
TemplateList
,
LeaseDetail
,
NodeCreate
,
LeaseCreate
,
TemplateCreate
,
FavouriteView
,
NodeStatus
,
GroupList
,
TemplateDelete
,
LeaseDelete
,
FavouriteView
,
NodeStatus
,
GroupList
,
TemplateDelete
,
LeaseDelete
,
VmGraphView
,
VmGraphView
,
TemplateAclUpdateView
)
)
urlpatterns
=
patterns
(
urlpatterns
=
patterns
(
...
@@ -19,14 +19,18 @@ urlpatterns = patterns(
...
@@ -19,14 +19,18 @@ urlpatterns = patterns(
name
=
"dashboard.views.lease-create"
),
name
=
"dashboard.views.lease-create"
),
url
(
r'^lease/delete/(?P<pk>\d+)/$'
,
LeaseDelete
.
as_view
(),
url
(
r'^lease/delete/(?P<pk>\d+)/$'
,
LeaseDelete
.
as_view
(),
name
=
"dashboard.views.lease-delete"
),
name
=
"dashboard.views.lease-delete"
),
url
(
r'^template/create/$'
,
TemplateCreate
.
as_view
(),
url
(
r'^template/create/$'
,
TemplateCreate
.
as_view
(),
name
=
"dashboard.views.template-create"
),
name
=
"dashboard.views.template-create"
),
url
(
r'template/(?P<pk>\d+)/acl/$'
,
TemplateAclUpdateView
.
as_view
(),
name
=
'dashboard.views.template-acl'
),
url
(
r'^template/(?P<pk>\d+)/$'
,
TemplateDetail
.
as_view
(),
url
(
r'^template/(?P<pk>\d+)/$'
,
TemplateDetail
.
as_view
(),
name
=
'dashboard.views.template-detail'
),
name
=
'dashboard.views.template-detail'
),
url
(
r"^template/list/$"
,
TemplateList
.
as_view
(),
url
(
r"^template/list/$"
,
TemplateList
.
as_view
(),
name
=
"dashboard.views.template-list"
),
name
=
"dashboard.views.template-list"
),
url
(
r"^template/delete/(?P<pk>\d+)/$"
,
TemplateDelete
.
as_view
(),
url
(
r"^template/delete/(?P<pk>\d+)/$"
,
TemplateDelete
.
as_view
(),
name
=
"dashboard.views.template-delete"
),
name
=
"dashboard.views.template-delete"
),
url
(
r'^vm/(?P<pk>\d+)/remove_port/(?P<rule>\d+)/$'
,
PortDelete
.
as_view
(),
url
(
r'^vm/(?P<pk>\d+)/remove_port/(?P<rule>\d+)/$'
,
PortDelete
.
as_view
(),
name
=
'dashboard.views.remove-port'
),
name
=
'dashboard.views.remove-port'
),
url
(
r'^vm/(?P<pk>\d+)/$'
,
VmDetailView
.
as_view
(),
url
(
r'^vm/(?P<pk>\d+)/$'
,
VmDetailView
.
as_view
(),
...
@@ -43,6 +47,7 @@ urlpatterns = patterns(
...
@@ -43,6 +47,7 @@ urlpatterns = patterns(
url
(
r'^vm/mass-delete/'
,
VmMassDelete
.
as_view
(),
url
(
r'^vm/mass-delete/'
,
VmMassDelete
.
as_view
(),
name
=
'dashboard.view.mass-delete-vm'
),
name
=
'dashboard.view.mass-delete-vm'
),
url
(
r'^vm/(?P<pk>\d+)/activity/$'
,
vm_activity
),
url
(
r'^vm/(?P<pk>\d+)/activity/$'
,
vm_activity
),
url
(
r'^node/list/$'
,
NodeList
.
as_view
(),
name
=
'dashboard.views.node-list'
),
url
(
r'^node/list/$'
,
NodeList
.
as_view
(),
name
=
'dashboard.views.node-list'
),
url
(
r'^node/(?P<pk>\d+)/$'
,
NodeDetailView
.
as_view
(),
url
(
r'^node/(?P<pk>\d+)/$'
,
NodeDetailView
.
as_view
(),
name
=
'dashboard.views.node-detail'
),
name
=
'dashboard.views.node-detail'
),
...
@@ -54,8 +59,10 @@ urlpatterns = patterns(
...
@@ -54,8 +59,10 @@ urlpatterns = patterns(
name
=
"dashboard.views.status-node"
),
name
=
"dashboard.views.status-node"
),
url
(
r'^node/create/$'
,
NodeCreate
.
as_view
(),
url
(
r'^node/create/$'
,
NodeCreate
.
as_view
(),
name
=
'dashboard.views.node-create'
),
name
=
'dashboard.views.node-create'
),
url
(
r'^favourite/$'
,
FavouriteView
.
as_view
(),
url
(
r'^favourite/$'
,
FavouriteView
.
as_view
(),
name
=
'dashboard.views.favourite'
),
name
=
'dashboard.views.favourite'
),
url
(
r'^group/list/$'
,
GroupList
.
as_view
(),
url
(
r'^group/list/$'
,
GroupList
.
as_view
(),
name
=
'dashboard.views.group-list'
),
name
=
'dashboard.views.group-list'
),
url
((
r'^vm/(?P<pk>\d+)/graph/(?P<metric>cpu|memory|network)/'
url
((
r'^vm/(?P<pk>\d+)/graph/(?P<metric>cpu|memory|network)/'
...
...
circle/dashboard/views.py
View file @
c38e0610
...
@@ -487,6 +487,29 @@ class AclUpdateView(LoginRequiredMixin, View, SingleObjectMixin):
...
@@ -487,6 +487,29 @@ class AclUpdateView(LoginRequiredMixin, View, SingleObjectMixin):
value
,
unicode
(
request
.
user
))
value
,
unicode
(
request
.
user
))
class
TemplateAclUpdateView
(
AclUpdateView
):
model
=
InstanceTemplate
def
post
(
self
,
request
,
*
args
,
**
kwargs
):
template
=
self
.
get_object
()
if
not
(
template
.
has_level
(
request
.
user
,
"owner"
)
or
getattr
(
template
,
'owner'
,
None
)
==
request
.
user
):
logger
.
warning
(
'Tried to set permissions of
%
s by non-owner
%
s.'
,
unicode
(
template
),
unicode
(
request
.
user
))
raise
PermissionDenied
()
self
.
set_levels
(
request
,
template
)
self
.
add_levels
(
request
,
template
)
post_for_disk
=
request
.
POST
.
copy
()
post_for_disk
[
'perm-new'
]
=
'user'
request
.
POST
=
post_for_disk
for
d
in
template
.
disks
.
all
():
self
.
add_levels
(
request
,
d
)
return
redirect
(
reverse
(
"dashboard.views.template-detail"
,
kwargs
=
self
.
kwargs
))
class
TemplateCreate
(
SuccessMessageMixin
,
CreateView
):
class
TemplateCreate
(
SuccessMessageMixin
,
CreateView
):
model
=
InstanceTemplate
model
=
InstanceTemplate
form_class
=
TemplateForm
form_class
=
TemplateForm
...
@@ -496,27 +519,28 @@ class TemplateCreate(SuccessMessageMixin, CreateView):
...
@@ -496,27 +519,28 @@ class TemplateCreate(SuccessMessageMixin, CreateView):
def
get
(
self
,
*
args
,
**
kwargs
):
def
get
(
self
,
*
args
,
**
kwargs
):
if
not
self
.
request
.
user
.
has_perm
(
'vm.create_template'
):
if
not
self
.
request
.
user
.
has_perm
(
'vm.create_template'
):
raise
PermissionDenied
()
raise
PermissionDenied
()
form
=
self
.
form_class
()
form
.
fields
[
'disks'
]
.
queryset
=
Disk
.
get_objects_with_level
(
'user'
,
self
.
request
.
user
)
.
exclude
(
type
=
"qcow2-snap"
)
self
.
parent
=
self
.
request
.
GET
.
get
(
"parent"
)
self
.
parent
=
self
.
request
.
GET
.
get
(
"parent"
)
return
super
(
TemplateCreate
,
self
)
.
get
(
*
args
,
**
kwargs
)
return
super
(
TemplateCreate
,
self
)
.
get
(
*
args
,
**
kwargs
)
def
get_form_kwargs
(
self
):
def
get_form_kwargs
(
self
):
kwargs
=
super
(
TemplateCreate
,
self
)
.
get_form_kwargs
()
kwargs
=
super
(
TemplateCreate
,
self
)
.
get_form_kwargs
()
kwargs
[
'parent'
]
=
getattr
(
self
,
"parent"
,
None
)
kwargs
[
'parent'
]
=
getattr
(
self
,
"parent"
,
None
)
kwargs
[
'user'
]
=
self
.
request
.
user
return
kwargs
return
kwargs
def
post
(
self
,
request
,
*
args
,
**
kwargs
):
def
post
(
self
,
request
,
*
args
,
**
kwargs
):
if
not
self
.
request
.
user
.
has_perm
(
'vm.create_template'
):
if
not
self
.
request
.
user
.
has_perm
(
'vm.create_template'
):
raise
PermissionDenied
()
raise
PermissionDenied
()
form
=
self
.
form_class
(
request
.
POST
)
form
=
self
.
form_class
(
request
.
POST
,
user
=
request
.
user
)
if
not
form
.
is_valid
():
if
not
form
.
is_valid
():
return
self
.
get
(
request
,
form
,
*
args
,
**
kwargs
)
return
self
.
get
(
request
,
form
,
*
args
,
**
kwargs
)
post
=
form
.
cleaned_data
post
=
form
.
cleaned_data
for
disk
in
post
[
'disks'
]:
for
disk
in
post
[
'disks'
]:
if
not
disk
.
has_level
(
request
.
user
,
'user'
):
if
not
disk
.
has_level
(
request
.
user
,
'user'
):
raise
PermissionDenied
()
raise
PermissionDenied
()
return
super
(
TemplateCreate
,
self
)
.
post
(
self
,
request
,
args
,
kwargs
)
return
super
(
TemplateCreate
,
self
)
.
post
(
self
,
request
,
args
,
kwargs
)
def
get_success_url
(
self
):
def
get_success_url
(
self
):
...
@@ -556,6 +580,11 @@ class TemplateDetail(LoginRequiredMixin, SuccessMessageMixin, UpdateView):
...
@@ -556,6 +580,11 @@ class TemplateDetail(LoginRequiredMixin, SuccessMessageMixin, UpdateView):
else
:
else
:
return
super
(
TemplateDetail
,
self
)
.
get
(
request
,
*
args
,
**
kwargs
)
return
super
(
TemplateDetail
,
self
)
.
get
(
request
,
*
args
,
**
kwargs
)
def
get_context_data
(
self
,
**
kwargs
):
context
=
super
(
TemplateDetail
,
self
)
.
get_context_data
(
**
kwargs
)
context
[
'acl'
]
=
get_acl_data
(
self
.
get_object
())
return
context
def
get_success_url
(
self
):
def
get_success_url
(
self
):
return
reverse_lazy
(
"dashboard.views.template-detail"
,
return
reverse_lazy
(
"dashboard.views.template-detail"
,
kwargs
=
self
.
kwargs
)
kwargs
=
self
.
kwargs
)
...
@@ -569,6 +598,11 @@ class TemplateDetail(LoginRequiredMixin, SuccessMessageMixin, UpdateView):
...
@@ -569,6 +598,11 @@ class TemplateDetail(LoginRequiredMixin, SuccessMessageMixin, UpdateView):
raise
PermissionDenied
()
raise
PermissionDenied
()
return
super
(
TemplateDetail
,
self
)
.
post
(
self
,
request
,
args
,
kwargs
)
return
super
(
TemplateDetail
,
self
)
.
post
(
self
,
request
,
args
,
kwargs
)
def
get_form_kwargs
(
self
):
kwargs
=
super
(
TemplateDetail
,
self
)
.
get_form_kwargs
()
kwargs
[
'user'
]
=
self
.
request
.
user
return
kwargs
class
TemplateList
(
LoginRequiredMixin
,
SingleTableView
):
class
TemplateList
(
LoginRequiredMixin
,
SingleTableView
):
template_name
=
"dashboard/template-list.html"
template_name
=
"dashboard/template-list.html"
...
...
circle/vm/models/instance.py
View file @
c38e0610
...
@@ -147,6 +147,12 @@ class InstanceTemplate(AclBase, VirtualMachineDescModel, TimeStampedModel):
...
@@ -147,6 +147,12 @@ class InstanceTemplate(AclBase, VirtualMachineDescModel, TimeStampedModel):
else
:
else
:
return
'linux'
return
'linux'
def
save
(
self
,
*
args
,
**
kwargs
):
is_new
=
getattr
(
self
,
"pk"
,
None
)
is
None
super
(
InstanceTemplate
,
self
)
.
save
(
*
args
,
**
kwargs
)
if
is_new
:
self
.
set_level
(
self
.
owner
,
'owner'
)
class
Instance
(
AclBase
,
VirtualMachineDescModel
,
TimeStampedModel
):
class
Instance
(
AclBase
,
VirtualMachineDescModel
,
TimeStampedModel
):
...
...
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