Skip to content
Toggle navigation
P
Projects
G
Groups
S
Snippets
Help
Fukász Rómeó Ervin
/
cloud
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
0
Merge Requests
0
Pipelines
Wiki
Members
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
A prog2-höz tartozó friss repo anyagok itt elérhetőek:
https://git.iit.bme.hu/
Commit
2c9fc11e
authored
Mar 06, 2014
by
Őry Máté
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
dashboard: add VmRenewView
parent
c6c2d058
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
179 additions
and
3 deletions
+179
-3
circle/dashboard/templates/dashboard/confirm/base-renew.html
+32
-0
circle/dashboard/urls.py
+3
-1
circle/dashboard/views.py
+144
-2
No files found.
circle/dashboard/templates/dashboard/confirm/base-renew.html
0 → 100644
View file @
2c9fc11e
{% extends "dashboard/base.html" %}
{% load i18n %}
{% block content %}
<div
class=
"body-content"
>
<div
class=
"panel panel-default"
>
<div
class=
"panel-heading"
>
<h3
class=
"no-margin"
>
{%blocktrans with instance=instance.name%}
Renewing
<em>
{{instance}}
</em>
{%endblocktrans%}
</h3>
</div>
<div
class=
"panel-body"
>
{%blocktrans with object=object%}
Do you want to renew
<strong>
{{ object }}
</strong>
?
{%endblocktrans%}
{%blocktrans with suspend=time_of_suspend delete=time_of_delete|default:"n/a" %}
The instance will be suspended at
<em>
{{suspend}}
</em>
and removed at
<em>
{{delete}}
</em>
if you renew it now.
{%endblocktrans%}
<div
class=
"pull-right"
>
<form
action=
""
method=
"POST"
>
{% csrf_token %}
<a
class=
"btn btn-default"
href=
"{{instance.get_absolute_path}}"
>
{% trans "Back" %}
</a>
<button
class=
"btn btn-danger"
>
{% trans "Renew" %}
</button>
</form>
</div>
</div>
</div>
{% endblock %}
circle/dashboard/urls.py
View file @
2c9fc11e
...
@@ -9,7 +9,7 @@ from .views import (
...
@@ -9,7 +9,7 @@ from .views import (
FavouriteView
,
NodeStatus
,
GroupList
,
TemplateDelete
,
LeaseDelete
,
FavouriteView
,
NodeStatus
,
GroupList
,
TemplateDelete
,
LeaseDelete
,
VmGraphView
,
TemplateAclUpdateView
,
GroupDetailView
,
GroupDelete
,
VmGraphView
,
TemplateAclUpdateView
,
GroupDetailView
,
GroupDelete
,
GroupAclUpdateView
,
GroupUserDelete
,
NotificationView
,
NodeGraphView
,
GroupAclUpdateView
,
GroupUserDelete
,
NotificationView
,
NodeGraphView
,
VmMigrateView
,
VmDetailVncTokenView
,
VmMigrateView
,
VmDetailVncTokenView
,
VmRenewView
,
)
)
urlpatterns
=
patterns
(
urlpatterns
=
patterns
(
...
@@ -53,6 +53,8 @@ urlpatterns = patterns(
...
@@ -53,6 +53,8 @@ urlpatterns = patterns(
url
(
r'^vm/(?P<pk>\d+)/activity/$'
,
vm_activity
),
url
(
r'^vm/(?P<pk>\d+)/activity/$'
,
vm_activity
),
url
(
r'^vm/(?P<pk>\d+)/migrate/$'
,
VmMigrateView
.
as_view
(),
url
(
r'^vm/(?P<pk>\d+)/migrate/$'
,
VmMigrateView
.
as_view
(),
name
=
'dashboard.views.vm-migrate'
),
name
=
'dashboard.views.vm-migrate'
),
url
(
r'^vm/(?P<pk>\d+)/renew/((?P<key>.*)/?)$'
,
VmRenewView
.
as_view
(),
name
=
'dashboard.views.vm-renew'
),
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
(),
...
...
circle/dashboard/views.py
View file @
2c9fc11e
...
@@ -6,6 +6,7 @@ from datetime import datetime
...
@@ -6,6 +6,7 @@ from datetime import datetime
import
requests
import
requests
from
django.contrib.auth.models
import
User
,
Group
from
django.contrib.auth.models
import
User
,
Group
from
django.contrib.auth.views
import
redirect_to_login
from
django.contrib.messages
import
warning
from
django.contrib.messages
import
warning
from
django.core.exceptions
import
(
from
django.core.exceptions
import
(
PermissionDenied
,
SuspiciousOperation
,
PermissionDenied
,
SuspiciousOperation
,
...
@@ -13,7 +14,7 @@ from django.core.exceptions import (
...
@@ -13,7 +14,7 @@ from django.core.exceptions import (
from
django.core
import
signing
from
django.core
import
signing
from
django.core.urlresolvers
import
reverse
,
reverse_lazy
from
django.core.urlresolvers
import
reverse
,
reverse_lazy
from
django.http
import
HttpResponse
,
HttpResponseRedirect
,
Http404
from
django.http
import
HttpResponse
,
HttpResponseRedirect
,
Http404
from
django.shortcuts
import
redirect
,
render
from
django.shortcuts
import
redirect
,
render
,
get_object_or_404
from
django.views.decorators.http
import
require_GET
from
django.views.decorators.http
import
require_GET
from
django.views.generic.detail
import
SingleObjectMixin
from
django.views.generic.detail
import
SingleObjectMixin
from
django.views.generic
import
(
TemplateView
,
DetailView
,
View
,
DeleteView
,
from
django.views.generic
import
(
TemplateView
,
DetailView
,
View
,
DeleteView
,
...
@@ -25,7 +26,9 @@ from django.template.loader import render_to_string
...
@@ -25,7 +26,9 @@ from django.template.loader import render_to_string
from
django.forms.models
import
inlineformset_factory
from
django.forms.models
import
inlineformset_factory
from
django_tables2
import
SingleTableView
from
django_tables2
import
SingleTableView
from
braces.views
import
LoginRequiredMixin
,
SuperuserRequiredMixin
from
braces.views
import
(
LoginRequiredMixin
,
SuperuserRequiredMixin
,
AccessMixin
)
from
.forms
import
(
from
.forms
import
(
VmCustomizeForm
,
TemplateForm
,
LeaseForm
,
NodeForm
,
HostForm
,
VmCustomizeForm
,
TemplateForm
,
LeaseForm
,
NodeForm
,
HostForm
,
...
@@ -1524,6 +1527,145 @@ class TransferOwnershipView(LoginRequiredMixin, DetailView):
...
@@ -1524,6 +1527,145 @@ class TransferOwnershipView(LoginRequiredMixin, DetailView):
kwargs
=
{
'pk'
:
obj
.
pk
}))
kwargs
=
{
'pk'
:
obj
.
pk
}))
class
AbstractVmFunctionView
(
AccessMixin
,
View
):
"""Abstract instance-action view.
User can do the action with a valid token or if has at least required_level
ACL level for the instance.
Children should at least implement/add template_name, success_message,
url_name, and do_action().
"""
token_max_age
=
3
*
24
*
3600
required_level
=
'owner'
success_message
=
_
(
"Failed to perform requested action."
)
@classmethod
def
check_acl
(
cls
,
instance
,
user
):
if
not
instance
.
has_level
(
user
,
cls
.
required_level
):
raise
PermissionDenied
()
@classmethod
def
get_salt
(
cls
):
return
unicode
(
cls
)
@classmethod
def
get_token
(
cls
,
instance
,
user
,
*
args
):
t
=
tuple
([
getattr
(
i
,
'pk'
,
i
)
for
i
in
[
instance
,
user
]
+
list
(
args
)])
return
signing
.
dumps
(
t
,
salt
=
cls
.
get_salt
())
@classmethod
def
get_token_url
(
cls
,
instance
,
user
,
*
args
):
key
=
cls
.
get_token
(
instance
,
user
,
*
args
)
args
=
(
instance
.
pk
,
key
)
+
args
return
reverse
(
cls
.
url_name
,
args
=
args
)
# this wont work, CBVs suck: reverse(cls.as_view(), args=args)
def
get_template_names
(
self
):
return
[
self
.
template_name
]
def
get
(
self
,
request
,
pk
,
key
=
None
,
*
args
,
**
kwargs
):
class
LoginNeeded
(
Exception
):
pass
pk
=
int
(
pk
)
instance
=
get_object_or_404
(
Instance
,
pk
=
pk
)
try
:
if
key
:
logger
.
debug
(
'Confirm dialog for token
%
s.'
,
key
)
try
:
self
.
validate_key
(
pk
,
key
)
except
signing
.
SignatureExpired
:
messages
.
error
(
request
,
_
(
'The token has expired, please log in.'
))
raise
LoginNeeded
()
self
.
key
=
key
else
:
if
not
request
.
user
.
is_authenticated
():
raise
LoginNeeded
()
self
.
check_acl
(
instance
,
request
.
user
)
except
LoginNeeded
:
return
redirect_to_login
(
request
.
get_full_path
(),
self
.
get_login_url
(),
self
.
get_redirect_field_name
())
except
SuspiciousOperation
as
e
:
messages
.
error
(
request
,
_
(
'This token is invalid.'
))
logger
.
warning
(
'This token
%
s is invalid.
%
s'
,
key
,
unicode
(
e
))
raise
PermissionDenied
()
return
render
(
request
,
self
.
get_template_names
(),
self
.
get_context
(
instance
))
def
post
(
self
,
request
,
pk
,
key
=
None
,
*
args
,
**
kwargs
):
pk
=
int
(
pk
)
instance
=
get_object_or_404
(
Instance
,
pk
=
pk
)
if
key
:
user
=
self
.
validate_key
(
pk
,
key
)
else
:
user
=
request
.
user
self
.
check_acl
(
instance
,
user
)
if
self
.
do_action
(
instance
,
user
):
messages
.
success
(
request
,
self
.
success_message
)
else
:
messages
.
error
(
request
,
self
.
fail_message
)
return
HttpResponseRedirect
(
instance
.
get_absolute_url
())
def
validate_key
(
self
,
pk
,
key
):
"""Get object based on signed token.
"""
try
:
data
=
signing
.
loads
(
key
,
salt
=
self
.
get_salt
())
logger
.
debug
(
'Token data:
%
s'
,
unicode
(
data
))
instance
,
user
=
data
logger
.
debug
(
'Extracted token data: instance:
%
s, user:
%
s'
,
unicode
(
instance
),
unicode
(
user
))
except
(
signing
.
BadSignature
,
ValueError
,
TypeError
)
as
e
:
logger
.
warning
(
'Tried invalid token. Token:
%
s, user:
%
s.
%
s'
,
key
,
unicode
(
self
.
request
.
user
),
unicode
(
e
))
raise
SuspiciousOperation
()
try
:
instance
,
user
=
signing
.
loads
(
key
,
max_age
=
self
.
token_max_age
,
salt
=
self
.
get_salt
())
logger
.
debug
(
'Extracted non-expired token data:
%
s,
%
s'
,
unicode
(
instance
),
unicode
(
user
))
except
signing
.
BadSignature
as
e
:
raise
signing
.
SignatureExpired
()
if
pk
!=
instance
:
logger
.
debug
(
'pk (
%
d) != instance (
%
d)'
,
pk
,
instance
)
raise
SuspiciousOperation
()
user
=
User
.
objects
.
get
(
pk
=
user
)
return
user
def
do_action
(
self
,
instance
,
user
):
raise
NotImplementedError
(
'Please override do_action(instance, user)'
)
def
get_context
(
self
,
instance
):
context
=
{
'instance'
:
instance
}
if
getattr
(
self
,
'key'
,
None
)
is
not
None
:
context
[
'key'
]
=
self
.
key
return
context
class
VmRenewView
(
AbstractVmFunctionView
):
"""User can renew an instance."""
template_name
=
'dashboard/confirm/base-renew.html'
success_message
=
_
(
"Virtual machine is successfully renewed."
)
url_name
=
'dashboard.views.vm-renew'
def
get_context
(
self
,
instance
):
context
=
super
(
VmRenewView
,
self
)
.
get_context
(
instance
)
(
context
[
'time_of_suspend'
],
context
[
'time_of_delete'
])
=
instance
.
get_renew_times
()
return
context
def
do_action
(
self
,
instance
,
user
):
instance
.
renew
(
user
=
user
)
logger
.
info
(
'Instance
%
s renewed by
%
s.'
,
unicode
(
instance
),
unicode
(
user
))
return
True
class
TransferOwnershipConfirmView
(
LoginRequiredMixin
,
View
):
class
TransferOwnershipConfirmView
(
LoginRequiredMixin
,
View
):
"""User can accept an ownership offer."""
"""User can accept an ownership offer."""
...
...
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