Skip to content
Toggle navigation
P
Projects
G
Groups
S
Snippets
Help
Gelencsér Szabolcs
/
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
4565cf03
authored
Jul 08, 2017
by
Czémán Arnold
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'issue_392' into 'master'
Rename operation See merge request !389
parents
0623def3
e0f32040
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
85 additions
and
44 deletions
+85
-44
circle/dashboard/forms.py
+4
-0
circle/dashboard/static/dashboard/vm-details.js
+2
-1
circle/dashboard/templates/dashboard/vm-detail.html
+1
-1
circle/dashboard/templates/dashboard/vm-detail/home.html
+1
-1
circle/dashboard/tests/test_views.py
+29
-17
circle/dashboard/views/vm.py
+27
-24
circle/vm/operations.py
+21
-0
No files found.
circle/dashboard/forms.py
View file @
4565cf03
...
@@ -1538,6 +1538,10 @@ class VmResourcesForm(forms.ModelForm):
...
@@ -1538,6 +1538,10 @@ class VmResourcesForm(forms.ModelForm):
fields
=
(
'num_cores'
,
'priority'
,
'ram_size'
,
)
fields
=
(
'num_cores'
,
'priority'
,
'ram_size'
,
)
class
VmRenameForm
(
forms
.
Form
):
new_name
=
forms
.
CharField
()
vm_search_choices
=
(
vm_search_choices
=
(
(
"owned"
,
_
(
"owned"
)),
(
"owned"
,
_
(
"owned"
)),
(
"shared"
,
_
(
"shared"
)),
(
"shared"
,
_
(
"shared"
)),
...
...
circle/dashboard/static/dashboard/vm-details.js
View file @
4565cf03
...
@@ -111,9 +111,10 @@ $(function() {
...
@@ -111,9 +111,10 @@ $(function() {
/* rename ajax */
/* rename ajax */
$
(
'.vm-details-rename-submit'
).
click
(
function
()
{
$
(
'.vm-details-rename-submit'
).
click
(
function
()
{
var
name
=
$
(
this
).
parent
(
"span"
).
prev
(
"input"
).
val
();
var
name
=
$
(
this
).
parent
(
"span"
).
prev
(
"input"
).
val
();
var
url
=
$
(
"#vm-details-rename-form"
).
attr
(
"action"
);
$
.
ajax
({
$
.
ajax
({
method
:
'POST'
,
method
:
'POST'
,
url
:
location
.
href
,
url
:
url
,
data
:
{
'new_name'
:
name
},
data
:
{
'new_name'
:
name
},
headers
:
{
"X-CSRFToken"
:
getCookie
(
'csrftoken'
)},
headers
:
{
"X-CSRFToken"
:
getCookie
(
'csrftoken'
)},
success
:
function
(
data
,
textStatus
,
xhr
)
{
success
:
function
(
data
,
textStatus
,
xhr
)
{
...
...
circle/dashboard/templates/dashboard/vm-detail.html
View file @
4565cf03
...
@@ -55,7 +55,7 @@
...
@@ -55,7 +55,7 @@
</div>
</div>
<h1>
<h1>
<div
id=
"vm-details-rename"
class=
"vm-details-home-rename-form-div"
>
<div
id=
"vm-details-rename"
class=
"vm-details-home-rename-form-div"
>
<form
action=
""
method=
"POST"
id=
"vm-details-rename-form"
>
<form
action=
"
{{ op.rename.get_url }}
"
method=
"POST"
id=
"vm-details-rename-form"
>
{% csrf_token %}
{% csrf_token %}
<div
class=
"input-group vm-details-home-name"
>
<div
class=
"input-group vm-details-home-name"
>
<input
id=
"vm-details-rename-name"
class=
"form-control input-sm"
name=
"new_name"
type=
"text"
value=
"{{ instance.name }}"
/>
<input
id=
"vm-details-rename-name"
class=
"form-control input-sm"
name=
"new_name"
type=
"text"
value=
"{{ instance.name }}"
/>
...
...
circle/dashboard/templates/dashboard/vm-detail/home.html
View file @
4565cf03
...
@@ -16,7 +16,7 @@
...
@@ -16,7 +16,7 @@
<small
class=
"vm-details-home-edit-name"
>
{{ instance.name }}
</small>
<small
class=
"vm-details-home-edit-name"
>
{{ instance.name }}
</small>
</div>
</div>
<div
class=
"js-hidden vm-details-home-rename-form-div"
id=
"vm-details-home-rename"
>
<div
class=
"js-hidden vm-details-home-rename-form-div"
id=
"vm-details-home-rename"
>
<form
method=
"POST"
>
<form
action=
"{{ op.rename.get_url }}"
method=
"POST"
>
{% csrf_token %}
{% csrf_token %}
<div
class=
"input-group"
>
<div
class=
"input-group"
>
<input
type=
"text"
name=
"new_name"
value=
"{{ instance.name }}"
class=
"form-control input-sm"
/>
<input
type=
"text"
name=
"new_name"
value=
"{{ instance.name }}"
class=
"form-control input-sm"
/>
...
...
circle/dashboard/tests/test_views.py
View file @
4565cf03
...
@@ -30,7 +30,7 @@ from dashboard.views import VmAddInterfaceView
...
@@ -30,7 +30,7 @@ from dashboard.views import VmAddInterfaceView
from
vm.models
import
Instance
,
InstanceTemplate
,
Lease
,
Node
,
Trait
from
vm.models
import
Instance
,
InstanceTemplate
,
Lease
,
Node
,
Trait
from
vm.operations
import
(
WakeUpOperation
,
AddInterfaceOperation
,
from
vm.operations
import
(
WakeUpOperation
,
AddInterfaceOperation
,
AddPortOperation
,
RemoveInterfaceOperation
,
AddPortOperation
,
RemoveInterfaceOperation
,
DeployOperation
)
DeployOperation
,
RenameOperation
)
from
..models
import
Profile
from
..models
import
Profile
from
firewall.models
import
Vlan
,
Host
,
VlanGroup
from
firewall.models
import
Vlan
,
Host
,
VlanGroup
from
mock
import
Mock
,
patch
from
mock
import
Mock
,
patch
...
@@ -437,31 +437,43 @@ class VmDetailTest(LoginMixin, MockCeleryMixin, TestCase):
...
@@ -437,31 +437,43 @@ class VmDetailTest(LoginMixin, MockCeleryMixin, TestCase):
def
test_unpermitted_set_name
(
self
):
def
test_unpermitted_set_name
(
self
):
c
=
Client
()
c
=
Client
()
self
.
login
(
c
,
"user2"
)
self
.
login
(
c
,
"user2"
)
inst
=
Instance
.
objects
.
get
(
pk
=
1
)
with
patch
.
object
(
RenameOperation
,
'async'
)
as
mock_method
:
inst
.
set_level
(
self
.
u2
,
'user'
)
inst
=
Instance
.
objects
.
get
(
pk
=
1
)
old_name
=
inst
.
name
mock_method
.
side_effect
=
inst
.
rename
response
=
c
.
post
(
"/dashboard/vm/1/"
,
{
'new_name'
:
'test1235'
})
inst
.
set_level
(
self
.
u2
,
'user'
)
self
.
assertEqual
(
response
.
status_code
,
403
)
old_name
=
inst
.
name
self
.
assertEqual
(
Instance
.
objects
.
get
(
pk
=
1
)
.
name
,
old_name
)
response
=
c
.
post
(
"/dashboard/vm/1/op/rename/"
,
{
'new_name'
:
'test1235'
})
self
.
assertEqual
(
response
.
status_code
,
403
)
assert
not
mock_method
.
called
self
.
assertEqual
(
Instance
.
objects
.
get
(
pk
=
1
)
.
name
,
old_name
)
def
test_permitted_set_name
(
self
):
def
test_permitted_set_name
(
self
):
c
=
Client
()
c
=
Client
()
self
.
login
(
c
,
"user2"
)
self
.
login
(
c
,
"user2"
)
inst
=
Instance
.
objects
.
get
(
pk
=
1
)
with
patch
.
object
(
RenameOperation
,
'async'
)
as
mock_method
:
inst
.
set_level
(
self
.
u2
,
'owner'
)
inst
=
Instance
.
objects
.
get
(
pk
=
1
)
response
=
c
.
post
(
"/dashboard/vm/1/"
,
{
'new_name'
:
'test1234'
})
mock_method
.
side_effect
=
inst
.
rename
self
.
assertEqual
(
response
.
status_code
,
302
)
inst
.
set_level
(
self
.
u2
,
'owner'
)
self
.
assertEqual
(
Instance
.
objects
.
get
(
pk
=
1
)
.
name
,
'test1234'
)
response
=
c
.
post
(
"/dashboard/vm/1/op/rename/"
,
{
'new_name'
:
'test1234'
})
self
.
assertEqual
(
response
.
status_code
,
302
)
assert
mock_method
.
called
self
.
assertEqual
(
Instance
.
objects
.
get
(
pk
=
1
)
.
name
,
'test1234'
)
def
test_permitted_set_name_w_ajax
(
self
):
def
test_permitted_set_name_w_ajax
(
self
):
c
=
Client
()
c
=
Client
()
self
.
login
(
c
,
"user2"
)
self
.
login
(
c
,
"user2"
)
inst
=
Instance
.
objects
.
get
(
pk
=
1
)
inst
=
Instance
.
objects
.
get
(
pk
=
1
)
inst
.
set_level
(
self
.
u2
,
'owner'
)
with
patch
.
object
(
RenameOperation
,
'async'
)
as
mock_method
:
response
=
c
.
post
(
"/dashboard/vm/1/"
,
{
'new_name'
:
'test123'
},
inst
.
set_level
(
self
.
u2
,
'owner'
)
HTTP_X_REQUESTED_WITH
=
'XMLHttpRequest'
)
mock_method
.
side_effect
=
inst
.
rename
self
.
assertEqual
(
response
.
status_code
,
200
)
response
=
c
.
post
(
"/dashboard/vm/1/op/rename/"
,
self
.
assertEqual
(
Instance
.
objects
.
get
(
pk
=
1
)
.
name
,
'test123'
)
{
'new_name'
:
'test123'
},
HTTP_X_REQUESTED_WITH
=
'XMLHttpRequest'
)
self
.
assertEqual
(
response
.
status_code
,
200
)
assert
mock_method
.
called
self
.
assertEqual
(
Instance
.
objects
.
get
(
pk
=
1
)
.
name
,
'test123'
)
def
test_permitted_wake_up_wrong_state
(
self
):
def
test_permitted_wake_up_wrong_state
(
self
):
c
=
Client
()
c
=
Client
()
...
...
circle/dashboard/views/vm.py
View file @
4565cf03
...
@@ -68,6 +68,7 @@ from ..forms import (
...
@@ -68,6 +68,7 @@ from ..forms import (
VmMigrateForm
,
VmDeployForm
,
VmMigrateForm
,
VmDeployForm
,
VmPortRemoveForm
,
VmPortAddForm
,
VmPortRemoveForm
,
VmPortAddForm
,
VmRemoveInterfaceForm
,
VmRemoveInterfaceForm
,
VmRenameForm
,
)
)
from
request.models
import
TemplateAccessType
,
LeaseType
from
request.models
import
TemplateAccessType
,
LeaseType
from
request.forms
import
LeaseRequestForm
,
TemplateRequestForm
from
request.forms
import
LeaseRequestForm
,
TemplateRequestForm
...
@@ -199,7 +200,6 @@ class VmDetailView(GraphMixin, CheckedDetailView):
...
@@ -199,7 +200,6 @@ class VmDetailView(GraphMixin, CheckedDetailView):
def
post
(
self
,
request
,
*
args
,
**
kwargs
):
def
post
(
self
,
request
,
*
args
,
**
kwargs
):
options
=
{
options
=
{
'new_name'
:
self
.
__set_name
,
'new_description'
:
self
.
__set_description
,
'new_description'
:
self
.
__set_description
,
'new_tag'
:
self
.
__add_tag
,
'new_tag'
:
self
.
__add_tag
,
'to_remove'
:
self
.
__remove_tag
,
'to_remove'
:
self
.
__remove_tag
,
...
@@ -210,29 +210,6 @@ class VmDetailView(GraphMixin, CheckedDetailView):
...
@@ -210,29 +210,6 @@ class VmDetailView(GraphMixin, CheckedDetailView):
return
v
(
request
)
return
v
(
request
)
raise
Http404
()
raise
Http404
()
def
__set_name
(
self
,
request
):
self
.
object
=
self
.
get_object
()
if
not
self
.
object
.
has_level
(
request
.
user
,
"operator"
):
raise
PermissionDenied
()
new_name
=
request
.
POST
.
get
(
"new_name"
)
Instance
.
objects
.
filter
(
pk
=
self
.
object
.
pk
)
.
update
(
**
{
'name'
:
new_name
})
success_message
=
_
(
"VM successfully renamed."
)
if
request
.
is_ajax
():
response
=
{
'message'
:
success_message
,
'new_name'
:
new_name
,
'vm_pk'
:
self
.
object
.
pk
}
return
HttpResponse
(
json
.
dumps
(
response
),
content_type
=
"application/json"
)
else
:
messages
.
success
(
request
,
success_message
)
return
redirect
(
self
.
object
.
get_absolute_url
())
def
__set_description
(
self
,
request
):
def
__set_description
(
self
,
request
):
self
.
object
=
self
.
get_object
()
self
.
object
=
self
.
get_object
()
if
not
self
.
object
.
has_level
(
request
.
user
,
"operator"
):
if
not
self
.
object
.
has_level
(
request
.
user
,
"operator"
):
...
@@ -743,6 +720,31 @@ class VmDeployView(FormOperationMixin, VmOperationView):
...
@@ -743,6 +720,31 @@ class VmDeployView(FormOperationMixin, VmOperationView):
return
kwargs
return
kwargs
class
VmRenameView
(
FormOperationMixin
,
VmOperationView
):
op
=
'rename'
icon
=
'pencil'
effect
=
'success'
show_in_toolbar
=
False
form_class
=
VmRenameForm
def
post
(
self
,
request
,
extra
=
None
,
*
args
,
**
kwargs
):
if
extra
is
None
:
extra
=
{}
form
=
self
.
form_class
(
self
.
request
.
POST
,
**
self
.
get_form_kwargs
())
if
form
.
is_valid
():
extra
.
update
(
form
.
cleaned_data
)
resp
=
super
(
FormOperationMixin
,
self
)
.
post
(
request
,
extra
,
*
args
,
**
kwargs
)
success_message
=
_
(
'VM successfully renamed.'
)
if
request
.
is_ajax
():
return
JsonResponse
({
'new_name'
:
extra
[
'new_name'
]})
else
:
messages
.
success
(
request
,
success_message
)
return
resp
else
:
return
self
.
get
(
request
)
vm_ops
=
OrderedDict
([
vm_ops
=
OrderedDict
([
(
'deploy'
,
VmDeployView
),
(
'deploy'
,
VmDeployView
),
(
'wake_up'
,
VmOperationView
.
factory
(
(
'wake_up'
,
VmOperationView
.
factory
(
...
@@ -792,6 +794,7 @@ vm_ops = OrderedDict([
...
@@ -792,6 +794,7 @@ vm_ops = OrderedDict([
op
=
'install_keys'
,
icon
=
'key'
,
effect
=
'info'
,
op
=
'install_keys'
,
icon
=
'key'
,
effect
=
'info'
,
show_in_toolbar
=
False
,
show_in_toolbar
=
False
,
)),
)),
(
'rename'
,
VmRenameView
),
])
])
...
...
circle/vm/operations.py
View file @
4565cf03
...
@@ -1403,6 +1403,27 @@ class ResourcesOperation(InstanceOperation):
...
@@ -1403,6 +1403,27 @@ class ResourcesOperation(InstanceOperation):
@register_operation
@register_operation
class
RenameOperation
(
InstanceOperation
):
id
=
"rename"
name
=
_
(
"rename"
)
description
=
_
(
"Change the name of virtual machine."
)
acl_level
=
"operator"
required_perms
=
()
def
_operation
(
self
,
user
,
activity
,
new_name
):
old_name
=
self
.
instance
.
name
self
.
instance
.
name
=
new_name
self
.
instance
.
full_clean
()
self
.
instance
.
save
()
return
create_readable
(
ugettext_noop
(
"Changed name from '
%(old_name)
s' to '
%(new_name)
s'."
),
old_name
=
old_name
,
new_name
=
new_name
)
@register_operation
class
PasswordResetOperation
(
RemoteAgentOperation
):
class
PasswordResetOperation
(
RemoteAgentOperation
):
id
=
'password_reset'
id
=
'password_reset'
name
=
_
(
"password reset"
)
name
=
_
(
"password reset"
)
...
...
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