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
a1d135bf
authored
Feb 22, 2018
by
Szabolcs Gelencser
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Deploy and Shutoff operations work
parent
7cb09284
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
76 additions
and
213 deletions
+76
-213
.idea/workspace.xml
+0
-0
circle/acl/models.py
+10
-96
circle/circle/db.sqlite3
+0
-0
circle/common/operations.py
+12
-73
circle/dashboard/urls.py
+3
-3
circle/dashboard/views/util.py
+1
-1
circle/dashboard/views/vm.py
+30
-39
circle/vm/migrations/0006_remove_instance_name.py
+19
-0
circle/vm/models/instance.py
+1
-1
circle/vm/operations.py
+0
-0
No files found.
.idea/workspace.xml
View file @
a1d135bf
This diff is collapsed.
Click to expand it.
circle/acl/models.py
View file @
a1d135bf
...
@@ -76,20 +76,10 @@ class AclBase(Model):
...
@@ -76,20 +76,10 @@ class AclBase(Model):
object_level_set
=
GenericRelation
(
ObjectLevel
)
object_level_set
=
GenericRelation
(
ObjectLevel
)
def
clone_acl
(
self
,
other
):
def
clone_acl
(
self
,
other
):
"""Clone full ACL from other object."""
pass
assert
self
.
id
!=
other
.
id
or
type
(
self
)
!=
type
(
other
)
self
.
object_level_set
.
clear
()
for
i
in
other
.
object_level_set
.
all
():
ol
=
self
.
object_level_set
.
create
(
level
=
i
.
level
)
for
j
in
i
.
users
.
all
():
ol
.
users
.
add
(
j
)
for
j
in
i
.
groups
.
all
():
ol
.
groups
.
add
(
j
)
@classmethod
@classmethod
def
get_level_object
(
cls
,
level
):
def
get_level_object
(
cls
,
level
):
"""Get Level object for this model by codename."""
ct
=
ContentType
.
objects
.
get_for_model
(
cls
)
ct
=
ContentType
.
objects
.
get_for_model
(
cls
)
return
Level
.
objects
.
get
(
codename
=
level
,
content_type
=
ct
)
return
Level
.
objects
.
get
(
codename
=
level
,
content_type
=
ct
)
...
@@ -110,104 +100,28 @@ class AclBase(Model):
...
@@ -110,104 +100,28 @@ class AclBase(Model):
raise
AttributeError
(
'"whom" must be a User or Group object.'
)
raise
AttributeError
(
'"whom" must be a User or Group object.'
)
def
set_user_level
(
self
,
user
,
level
):
def
set_user_level
(
self
,
user
,
level
):
#TODO: delete
"""Set level of object for a user.
pass
:param whom: user the level is set for
:type whom: User
:param level: codename of level to set, or None
:type level: Level or str or unicode or NoneType
"""
logger
.
info
(
'
%
s.set_user_level(
%
s,
%
s) called'
,
*
[
unicode
(
p
)
for
p
in
[
self
,
user
,
level
]])
if
level
is
None
:
pk
=
None
else
:
if
isinstance
(
level
,
basestring
):
level
=
self
.
get_level_object
(
level
)
if
not
self
.
object_level_set
.
filter
(
level_id
=
level
.
pk
)
.
exists
():
self
.
object_level_set
.
create
(
level
=
level
)
pk
=
level
.
pk
for
i
in
self
.
object_level_set
.
all
():
if
i
.
level_id
!=
pk
:
i
.
users
.
remove
(
user
)
else
:
i
.
users
.
add
(
user
)
i
.
save
()
def
set_group_level
(
self
,
group
,
level
):
def
set_group_level
(
self
,
group
,
level
):
#TODO: delete
"""Set level of object for a user.
pass
:param whom: user the level is set for
:type whom: User or unicode or str
:param level: codename of level to set
:type level: str or unicode
"""
logger
.
info
(
'
%
s.set_group_level(
%
s,
%
s) called'
,
*
[
unicode
(
p
)
for
p
in
[
self
,
group
,
level
]])
if
level
is
None
:
pk
=
None
else
:
if
isinstance
(
level
,
basestring
):
level
=
self
.
get_level_object
(
level
)
if
not
self
.
object_level_set
.
filter
(
level_id
=
level
.
pk
)
.
exists
():
self
.
object_level_set
.
create
(
level
=
level
)
pk
=
level
.
pk
for
i
in
self
.
object_level_set
.
all
():
if
i
.
level_id
!=
pk
:
i
.
groups
.
remove
(
group
)
else
:
i
.
groups
.
add
(
group
)
i
.
save
()
def
has_level
(
self
,
user
,
level
,
group_also
=
True
):
def
has_level
(
self
,
user
,
level
,
group_also
=
True
):
return
True
#TODO: implement
logger
.
debug
(
'
%
s.has_level(
%
s,
%
s,
%
s) called'
,
logger
.
debug
(
'
%
s.has_level(
%
s,
%
s,
%
s) called'
,
*
[
unicode
(
p
)
for
p
in
[
self
,
user
,
level
,
group_also
]])
*
[
unicode
(
p
)
for
p
in
[
self
,
user
,
level
,
group_also
]])
if
user
is
None
or
not
user
.
is_authenticated
():
return
False
if
getattr
(
user
,
'is_superuser'
,
False
):
logger
.
debug
(
'- superuser granted'
)
return
True
if
isinstance
(
level
,
basestring
):
level
=
self
.
get_level_object
(
level
)
logger
.
debug
(
"- level set by str:
%
s"
,
unicode
(
level
))
object_levels
=
self
.
object_level_set
.
filter
(
level__weight__gte
=
level
.
weight
)
.
all
()
groups
=
user
.
groups
.
values_list
(
'id'
,
flat
=
True
)
if
group_also
else
[]
for
i
in
object_levels
:
if
i
.
users
.
filter
(
pk
=
user
.
pk
)
.
exists
():
return
True
if
group_also
and
i
.
groups
.
filter
(
pk__in
=
groups
)
.
exists
():
return
True
return
True
return
False
def
get_users_with_level
(
self
,
**
kwargs
):
def
get_users_with_level
(
self
,
**
kwargs
):
# TODO: implement
logger
.
debug
(
'
%
s.get_users_with_level() called'
,
unicode
(
self
))
logger
.
debug
(
'
%
s.get_users_with_level() called'
,
unicode
(
self
))
object_levels
=
(
self
.
object_level_set
.
filter
(
**
kwargs
)
.
select_related
(
return
[]
'level'
)
.
prefetch_related
(
'users'
)
.
all
())
users
=
[]
for
object_level
in
object_levels
:
name
=
object_level
.
level
.
codename
olusers
=
object_level
.
users
.
all
()
users
.
extend
([(
u
,
name
)
for
u
in
olusers
])
logger
.
debug
(
'-
%
s:
%
s'
%
(
name
,
[
u
.
username
for
u
in
olusers
]))
return
users
def
get_groups_with_level
(
self
):
def
get_groups_with_level
(
self
):
# TODO: implement
logger
.
debug
(
'
%
s.get_groups_with_level() called'
,
unicode
(
self
))
logger
.
debug
(
'
%
s.get_groups_with_level() called'
,
unicode
(
self
))
object_levels
=
(
self
.
object_level_set
.
select_related
(
return
[]
'level'
)
.
prefetch_related
(
'groups'
)
.
all
())
groups
=
[]
for
object_level
in
object_levels
:
name
=
object_level
.
level
.
codename
olgroups
=
object_level
.
groups
.
all
()
groups
.
extend
([(
g
,
name
)
for
g
in
olgroups
])
logger
.
debug
(
'-
%
s:
%
s'
%
(
name
,
[
g
.
name
for
g
in
olgroups
]))
return
groups
@classmethod
@classmethod
def
get_objects_with_level
(
cls
,
level
,
user
,
def
get_objects_with_level
(
cls
,
level
,
user
,
...
...
circle/circle/db.sqlite3
View file @
a1d135bf
No preview for this file type
circle/common/operations.py
View file @
a1d135bf
...
@@ -26,32 +26,15 @@ from .models import (activity_context, has_suffix, humanize_exception,
...
@@ -26,32 +26,15 @@ from .models import (activity_context, has_suffix, humanize_exception,
logger
=
getLogger
(
__name__
)
logger
=
getLogger
(
__name__
)
class
SubOperationMixin
(
object
):
required_perms
=
()
def
create_activity
(
self
,
parent
,
user
,
kwargs
):
if
not
parent
:
raise
TypeError
(
"SubOperation can only be called with "
"parent_activity specified."
)
return
super
(
SubOperationMixin
,
self
)
.
create_activity
(
parent
,
user
,
kwargs
)
class
Operation
(
object
):
class
Operation
(
object
):
"""Base class for VM operations.
"""Base class for VM operations.
"""
"""
async_queue
=
'localhost.man'
required_perms
=
None
required_perms
=
None
superuser_required
=
False
superuser_required
=
False
do_not_call_in_templates
=
True
do_not_call_in_templates
=
True
abortable
=
False
abortable
=
False
has_percentage
=
False
has_percentage
=
False
@classmethod
def
get_activity_code_suffix
(
cls
):
return
cls
.
id
def
__call__
(
self
,
**
kwargs
):
def
__call__
(
self
,
**
kwargs
):
return
self
.
call
(
**
kwargs
)
return
self
.
call
(
**
kwargs
)
...
@@ -63,10 +46,12 @@ class Operation(object):
...
@@ -63,10 +46,12 @@ class Operation(object):
def
__unicode__
(
self
):
def
__unicode__
(
self
):
return
self
.
name
return
self
.
name
def
__prelude
(
self
,
kwargs
):
def
__prelude
(
self
,
request
,
kwargs
):
"""This method contains the shared prelude of call and async.
"""This method contains the shared prelude of call and async.
"""
"""
defaults
=
{
'parent_activity'
:
None
,
'system'
:
False
,
'user'
:
None
}
self
.
_operation
.
im_self
.
get_from_os
(
request
)
defaults
=
{
'system'
:
False
,
'user'
:
None
}
allargs
=
dict
(
defaults
,
**
kwargs
)
# all arguments
allargs
=
dict
(
defaults
,
**
kwargs
)
# all arguments
auxargs
=
allargs
.
copy
()
# auxiliary (i.e. only for _operation) args
auxargs
=
allargs
.
copy
()
# auxiliary (i.e. only for _operation) args
...
@@ -75,9 +60,6 @@ class Operation(object):
...
@@ -75,9 +60,6 @@ class Operation(object):
skip_auth_check
=
auxargs
.
pop
(
'system'
)
skip_auth_check
=
auxargs
.
pop
(
'system'
)
user
=
auxargs
.
pop
(
'user'
)
user
=
auxargs
.
pop
(
'user'
)
parent_activity
=
auxargs
.
pop
(
'parent_activity'
)
if
parent_activity
and
user
is
None
and
not
skip_auth_check
:
user
=
allargs
[
'user'
]
=
parent_activity
.
user
if
user
is
None
:
# parent was a system call
if
user
is
None
:
# parent was a system call
skip_auth_check
=
True
skip_auth_check
=
True
...
@@ -93,12 +75,9 @@ class Operation(object):
...
@@ -93,12 +75,9 @@ class Operation(object):
self
.
check_auth
(
user
)
self
.
check_auth
(
user
)
self
.
check_precond
()
self
.
check_precond
()
activity
=
self
.
create_activity
(
return
allargs
,
auxargs
parent
=
parent_activity
,
user
=
user
,
kwargs
=
kwargs
)
return
activity
,
allargs
,
auxargs
def
_exec_op
(
self
,
request
,
allargs
,
auxargs
):
def
_exec_op
(
self
,
allargs
,
auxargs
):
"""Execute the operation inside the specified activity's context.
"""Execute the operation inside the specified activity's context.
"""
"""
# compile arguments for _operation
# compile arguments for _operation
...
@@ -110,13 +89,7 @@ class Operation(object):
...
@@ -110,13 +89,7 @@ class Operation(object):
if
k
in
argspec
.
args
}
if
k
in
argspec
.
args
}
arguments
.
update
(
auxargs
)
arguments
.
update
(
auxargs
)
with
activity_context
(
allargs
[
'activity'
],
on_abort
=
self
.
on_abort
,
return
self
.
_operation
(
request
,
**
arguments
)
on_commit
=
self
.
on_commit
)
as
act
:
retval
=
self
.
_operation
(
**
arguments
)
if
(
act
.
result
is
None
and
isinstance
(
retval
,
(
basestring
,
int
,
HumanReadableObject
))):
act
.
result
=
retval
return
retval
def
_operation
(
self
,
**
kwargs
):
def
_operation
(
self
,
**
kwargs
):
"""This method is the operation's particular implementation.
"""This method is the operation's particular implementation.
...
@@ -125,25 +98,7 @@ class Operation(object):
...
@@ -125,25 +98,7 @@ class Operation(object):
"""
"""
raise
NotImplementedError
raise
NotImplementedError
def
async
(
self
,
**
kwargs
):
def
call
(
self
,
request
,
**
kwargs
):
"""Execute the operation asynchronously.
Only a quick, preliminary check is ran before creating the associated
activity and queuing the job.
The returned value is the handle for the asynchronous job.
For more information, check the synchronous call's documentation.
"""
logger
.
info
(
"
%
s called asynchronously on
%
s with the following "
"parameters:
%
r"
,
self
.
__class__
.
__name__
,
self
.
subject
,
kwargs
)
activity
,
allargs
,
auxargs
=
self
.
__prelude
(
kwargs
)
return
self
.
async_operation
.
apply_async
(
args
=
(
self
.
id
,
self
.
subject
.
pk
,
activity
.
pk
,
allargs
,
auxargs
,
),
queue
=
self
.
async_queue
)
def
call
(
self
,
**
kwargs
):
"""Execute the operation (synchronously).
"""Execute the operation (synchronously).
Anticipated keyword arguments:
Anticipated keyword arguments:
...
@@ -159,9 +114,8 @@ class Operation(object):
...
@@ -159,9 +114,8 @@ class Operation(object):
logger
.
info
(
"
%
s called (synchronously) on
%
s with the following "
logger
.
info
(
"
%
s called (synchronously) on
%
s with the following "
"parameters:
%
r"
,
self
.
__class__
.
__name__
,
self
.
subject
,
"parameters:
%
r"
,
self
.
__class__
.
__name__
,
self
.
subject
,
kwargs
)
kwargs
)
activity
,
allargs
,
auxargs
=
self
.
__prelude
(
kwargs
)
allargs
,
auxargs
=
self
.
__prelude
(
request
,
kwargs
)
allargs
[
'activity'
]
=
activity
return
self
.
_exec_op
(
request
,
allargs
,
auxargs
)
return
self
.
_exec_op
(
allargs
,
auxargs
)
def
check_precond
(
self
):
def
check_precond
(
self
):
pass
pass
...
@@ -185,11 +139,8 @@ class Operation(object):
...
@@ -185,11 +139,8 @@ class Operation(object):
def
check_auth
(
self
,
user
):
def
check_auth
(
self
,
user
):
"""Check if user is permitted to run this operation on this instance
"""Check if user is permitted to run this operation on this instance
"""
"""
#TODO: implement
self
.
check_perms
(
user
)
pass
def
create_activity
(
self
,
parent
,
user
,
kwargs
):
raise
NotImplementedError
def
on_abort
(
self
,
activity
,
error
):
def
on_abort
(
self
,
activity
,
error
):
"""This method is called when the operation aborts (i.e. raises an
"""This method is called when the operation aborts (i.e. raises an
...
@@ -197,18 +148,6 @@ class Operation(object):
...
@@ -197,18 +148,6 @@ class Operation(object):
"""
"""
pass
pass
def
get_activity_name
(
self
,
kwargs
):
try
:
return
self
.
activity_name
except
AttributeError
:
try
:
return
self
.
name
.
_proxy____args
[
0
]
# ewww!
except
AttributeError
:
raise
ImproperlyConfigured
(
"Set Operation.activity_name to an ugettext_nooped "
"string or a create_readable call, or override "
"get_activity_name to create a name dynamically"
)
def
on_commit
(
self
,
activity
):
def
on_commit
(
self
,
activity
):
"""This method is called when the operation executes successfully.
"""This method is called when the operation executes successfully.
"""
"""
...
...
circle/dashboard/urls.py
View file @
a1d135bf
...
@@ -18,7 +18,7 @@
...
@@ -18,7 +18,7 @@
from
__future__
import
absolute_import
from
__future__
import
absolute_import
from
dashboard.views.autocomplete
import
AclUserGroupAutocomplete
,
AclUserAutocomplete
from
dashboard.views.autocomplete
import
AclUserGroupAutocomplete
,
AclUserAutocomplete
from
dashboard.views.vm
import
VmDetailView
,
VmList
,
VmCreate
,
vm_activity
,
vm_ops
from
dashboard.views.vm
import
VmDetailView
,
VmList
,
VmCreate
,
vm_activity
,
vm_ops
,
FavouriteView
from
django.conf.urls
import
url
from
django.conf.urls
import
url
from
.views
import
(
from
.views
import
(
...
@@ -99,8 +99,8 @@ urlpatterns = [
...
@@ -99,8 +99,8 @@ urlpatterns = [
# url(r'^node/activity/(?P<pk>\d+)/$', NodeActivityDetail.as_view(),
# url(r'^node/activity/(?P<pk>\d+)/$', NodeActivityDetail.as_view(),
# name='dashboard.views.node-activity'),
# name='dashboard.views.node-activity'),
#
#
#
url(r'^favourite/$', FavouriteView.as_view(),
url
(
r'^favourite/$'
,
FavouriteView
.
as_view
(),
#
name='dashboard.views.favourite'),
name
=
'dashboard.views.favourite'
),
# url(r'^group/delete/(?P<pk>\d+)/$', GroupDelete.as_view(),
# url(r'^group/delete/(?P<pk>\d+)/$', GroupDelete.as_view(),
# name="dashboard.views.delete-group"),
# name="dashboard.views.delete-group"),
# url(r'^group/list/$', GroupList.as_view(),
# url(r'^group/list/$', GroupList.as_view(),
...
...
circle/dashboard/views/util.py
View file @
a1d135bf
...
@@ -294,7 +294,7 @@ class OperationView(RedirectToLoginMixin, DetailView):
...
@@ -294,7 +294,7 @@ class OperationView(RedirectToLoginMixin, DetailView):
result
=
None
result
=
None
done
=
False
done
=
False
try
:
try
:
task
=
self
.
get_op
()
.
async
(
user
=
request
.
user
,
**
extra
)
task
=
self
.
get_op
()
.
call
(
request
,
user
=
request
.
user
,
**
extra
)
except
HumanReadableException
as
e
:
except
HumanReadableException
as
e
:
e
.
send_message
(
request
)
e
.
send_message
(
request
)
logger
.
exception
(
"Could not start operation"
)
logger
.
exception
(
"Could not start operation"
)
...
...
circle/dashboard/views/vm.py
View file @
a1d135bf
...
@@ -21,6 +21,7 @@ import logging
...
@@ -21,6 +21,7 @@ import logging
from
collections
import
OrderedDict
from
collections
import
OrderedDict
import
openstack_api
import
openstack_api
from
dashboard.models
import
Favourite
from
django.conf
import
settings
from
django.conf
import
settings
from
django.contrib
import
messages
from
django.contrib
import
messages
from
django.contrib.auth.mixins
import
LoginRequiredMixin
from
django.contrib.auth.mixins
import
LoginRequiredMixin
...
@@ -110,8 +111,6 @@ class VmDetailView(LoginRequiredMixin, GraphMixin, DetailView):
...
@@ -110,8 +111,6 @@ class VmDetailView(LoginRequiredMixin, GraphMixin, DetailView):
context
=
super
(
VmDetailView
,
self
)
.
get_context_data
(
**
kwargs
)
context
=
super
(
VmDetailView
,
self
)
.
get_context_data
(
**
kwargs
)
instance
=
context
[
'instance'
]
instance
=
context
[
'instance'
]
user
=
self
.
request
.
user
user
=
self
.
request
.
user
is_operator
=
instance
.
has_level
(
user
,
"operator"
)
is_owner
=
instance
.
has_level
(
user
,
"owner"
)
ops
=
get_operations
(
instance
,
user
)
ops
=
get_operations
(
instance
,
user
)
hide_tutorial
=
self
.
request
.
COOKIES
.
get
(
hide_tutorial
=
self
.
request
.
COOKIES
.
get
(
"hide_tutorial_for_
%
s"
%
instance
.
pk
)
==
"True"
"hide_tutorial_for_
%
s"
%
instance
.
pk
)
==
"True"
...
@@ -155,9 +154,7 @@ class VmDetailView(LoginRequiredMixin, GraphMixin, DetailView):
...
@@ -155,9 +154,7 @@ class VmDetailView(LoginRequiredMixin, GraphMixin, DetailView):
# context['ipv6_port'] = instance.get_connect_port(use_ipv6=True)
# context['ipv6_port'] = instance.get_connect_port(use_ipv6=True)
# resources forms
# resources forms
can_edit
=
(
can_edit
=
True
instance
.
has_level
(
user
,
"owner"
)
and
self
.
request
.
user
.
has_perm
(
"vm.change_resources"
))
context
[
'resources_form'
]
=
VmResourcesForm
(
context
[
'resources_form'
]
=
VmResourcesForm
(
can_edit
=
can_edit
,
instance
=
instance
)
can_edit
=
can_edit
,
instance
=
instance
)
...
@@ -173,11 +170,7 @@ class VmDetailView(LoginRequiredMixin, GraphMixin, DetailView):
...
@@ -173,11 +170,7 @@ class VmDetailView(LoginRequiredMixin, GraphMixin, DetailView):
context
[
'client_download'
]
=
self
.
request
.
COOKIES
.
get
(
context
[
'client_download'
]
=
self
.
request
.
COOKIES
.
get
(
'downloaded_client'
)
'downloaded_client'
)
# can link template
# can link template
context
[
'can_link_template'
]
=
instance
.
template
and
is_operator
context
[
'can_link_template'
]
=
instance
.
template
# is operator/owner
context
[
'is_operator'
]
=
is_operator
context
[
'is_owner'
]
=
is_owner
# operation also allows RUNNING (if with_shutdown is present)
# operation also allows RUNNING (if with_shutdown is present)
context
[
'save_resources_enabled'
]
=
instance
.
status
in
(
context
[
'save_resources_enabled'
]
=
instance
.
status
in
(
...
@@ -307,7 +300,7 @@ def get_operations(instance, user):
...
@@ -307,7 +300,7 @@ def get_operations(instance, user):
try
:
try
:
op
=
v
.
get_op_by_object
(
instance
)
op
=
v
.
get_op_by_object
(
instance
)
# op.check_auth(user)
# op.check_auth(user)
#
op.check_precond()
op
.
check_precond
()
except
PermissionDenied
as
e
:
except
PermissionDenied
as
e
:
logger
.
debug
(
'Not showing operation
%
s for
%
s:
%
s'
,
logger
.
debug
(
'Not showing operation
%
s for
%
s:
%
s'
,
k
,
instance
,
unicode
(
e
))
k
,
instance
,
unicode
(
e
))
...
@@ -743,26 +736,24 @@ vm_ops = OrderedDict([
...
@@ -743,26 +736,24 @@ vm_ops = OrderedDict([
(
'deploy'
,
VmDeployView
),
(
'deploy'
,
VmDeployView
),
(
'wake_up'
,
VmOperationView
.
factory
(
(
'wake_up'
,
VmOperationView
.
factory
(
op
=
'wake_up'
,
icon
=
'sun-o'
,
effect
=
'success'
)),
op
=
'wake_up'
,
icon
=
'sun-o'
,
effect
=
'success'
)),
# ('sleep', VmOperationView.factory(
(
'sleep'
,
VmOperationView
.
factory
(
# extra_bases=[TokenOperationView],
op
=
'sleep'
,
icon
=
'moon-o'
,
effect
=
'info'
)),
# op='sleep', icon='moon-o', effect='info')),
# ('migrate', VmMigrateView),
# ('migrate', VmMigrateView),
# ('save_as_template', VmSaveView),
# ('save_as_template', VmSaveView),
#
('reboot', VmOperationView.factory(
(
'reboot'
,
VmOperationView
.
factory
(
#
op='reboot', icon='refresh', effect='warning')),
op
=
'reboot'
,
icon
=
'refresh'
,
effect
=
'warning'
)),
# ('reset', VmOperationView.factory(
# ('reset', VmOperationView.factory(
# op='reset', icon='bolt', effect='warning')),
# op='reset', icon='bolt', effect='warning')),
# ('shutdown', VmOperationView.factory(
# ('shutdown', VmOperationView.factory(
# op='shutdown', icon='power-off', effect='warning')),
# op='shutdown', icon='power-off', effect='warning')),
#
('shut_off', VmOperationView.factory(
(
'shut_off'
,
VmOperationView
.
factory
(
#
op='shut_off', icon='plug', effect='warning')),
op
=
'shut_off'
,
icon
=
'plug'
,
effect
=
'warning'
)),
# ('recover', VmOperationView.factory(
# ('recover', VmOperationView.factory(
# op='recover', icon='medkit', effect='warning')),
# op='recover', icon='medkit', effect='warning')),
# ('nostate', VmStateChangeView),
# ('nostate', VmStateChangeView),
# ('redeploy', RedeployView),
# ('redeploy', RedeployView),
# ('destroy', VmOperationView.factory(
(
'destroy'
,
VmOperationView
.
factory
(
# extra_bases=[TokenOperationView],
op
=
'destroy'
,
icon
=
'times'
,
effect
=
'danger'
)),
# op='destroy', icon='times', effect='danger')),
# ('create_disk', VmCreateDiskView),
# ('create_disk', VmCreateDiskView),
# ('download_disk', VmDownloadDiskView),
# ('download_disk', VmDownloadDiskView),
# ('resize_disk', VmDiskModifyView.factory(
# ('resize_disk', VmDiskModifyView.factory(
...
@@ -790,8 +781,8 @@ vm_ops = OrderedDict([
...
@@ -790,8 +781,8 @@ vm_ops = OrderedDict([
# )),
# )),
# ('rename', VmRenameView),
# ('rename', VmRenameView),
])
])
#
#
def
_get_activity_icon
(
act
):
def
_get_activity_icon
(
act
):
op
=
act
.
get_operation
()
op
=
act
.
get_operation
()
if
op
and
op
.
id
in
vm_ops
:
if
op
and
op
.
id
in
vm_ops
:
...
@@ -1265,7 +1256,7 @@ def vm_activity(request, pk):
...
@@ -1265,7 +1256,7 @@ def vm_activity(request, pk):
# activities = activities[:10]
# activities = activities[:10]
response
[
'connect_uri'
]
=
instance
.
get_connect_uri
()
response
[
'connect_uri'
]
=
instance
.
get_connect_uri
()
response
[
'human_readable_status'
]
=
instance
.
get_status_display
()
response
[
'human_readable_status'
]
=
'#TODO'
#
instance.get_status_display()
response
[
'status'
]
=
instance
.
status
response
[
'status'
]
=
instance
.
status
response
[
'icon'
]
=
instance
.
get_status_icon
()
response
[
'icon'
]
=
instance
.
get_status_icon
()
latest
=
instance
.
get_latest_activity_in_progress
()
latest
=
instance
.
get_latest_activity_in_progress
()
...
@@ -1275,8 +1266,8 @@ def vm_activity(request, pk):
...
@@ -1275,8 +1266,8 @@ def vm_activity(request, pk):
context
=
{
context
=
{
'instance'
:
instance
,
'instance'
:
instance
,
# 'activities': activities
,
'activities'
:
()
,
# 'show_show_all': show_show_all
,
'show_show_all'
:
False
,
'ops'
:
get_operations
(
instance
,
request
.
user
),
'ops'
:
get_operations
(
instance
,
request
.
user
),
}
}
...
@@ -1299,19 +1290,19 @@ def vm_activity(request, pk):
...
@@ -1299,19 +1290,19 @@ def vm_activity(request, pk):
)
)
#
#
#
#
#
class FavouriteView(TemplateView):
class
FavouriteView
(
TemplateView
):
#
#
def post(self, *args, **kwargs):
def
post
(
self
,
*
args
,
**
kwargs
):
#
user = self.request.user
user
=
self
.
request
.
user
#
vm = Instance.objects.get(pk=self.request.POST.get("vm"))
vm
=
Instance
.
objects
.
get
(
pk
=
self
.
request
.
POST
.
get
(
"vm"
))
#
if not vm.has_level(user, 'user'):
if
not
vm
.
has_level
(
user
,
'user'
):
#
raise PermissionDenied()
raise
PermissionDenied
()
#
try:
try
:
#
Favourite.objects.get(instance=vm, user=user).delete()
Favourite
.
objects
.
get
(
instance
=
vm
,
user
=
user
)
.
delete
()
#
return HttpResponse("Deleted.")
return
HttpResponse
(
"Deleted."
)
#
except Favourite.DoesNotExist:
except
Favourite
.
DoesNotExist
:
#
Favourite(instance=vm, user=user).save()
Favourite
(
instance
=
vm
,
user
=
user
)
.
save
()
#
return HttpResponse("Added.")
return
HttpResponse
(
"Added."
)
#
#
#
#
# class TransferInstanceOwnershipConfirmView(TransferOwnershipConfirmView):
# class TransferInstanceOwnershipConfirmView(TransferOwnershipConfirmView):
...
...
circle/vm/migrations/0006_remove_instance_name.py
0 → 100644
View file @
a1d135bf
# -*- coding: utf-8 -*-
# Generated by Django 1.11.6 on 2018-02-22 09:53
from
__future__
import
unicode_literals
from
django.db
import
migrations
class
Migration
(
migrations
.
Migration
):
dependencies
=
[
(
'vm'
,
'0005_remove_instance_owner'
),
]
operations
=
[
migrations
.
RemoveField
(
model_name
=
'instance'
,
name
=
'name'
,
),
]
circle/vm/models/instance.py
View file @
a1d135bf
...
@@ -209,7 +209,7 @@ class InstanceTemplate(AclBase, VirtualMachineDescModel, TimeStampedModel):
...
@@ -209,7 +209,7 @@ class InstanceTemplate(AclBase, VirtualMachineDescModel, TimeStampedModel):
return
'template.
%
d'
%
self
.
pk
return
'template.
%
d'
%
self
.
pk
class
Instance
(
AclBase
,
OperatedMixin
,
TimeStampedModel
):
class
Instance
(
OperatedMixin
,
TimeStampedModel
):
"""Virtual machine instance.
"""Virtual machine instance.
"""
"""
...
...
circle/vm/operations.py
View file @
a1d135bf
This diff is collapsed.
Click to expand it.
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