Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
J
jumpserver
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
ops
jumpserver
Commits
bf9bb1b9
Commit
bf9bb1b9
authored
Dec 24, 2017
by
ibuler
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[Update] 修改ops task运行
parent
30efec1b
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
22 changed files
with
273 additions
and
232 deletions
+273
-232
api.py
apps/assets/api.py
+8
-8
const.py
apps/assets/const.py
+15
-11
user.py
apps/assets/models/user.py
+2
-1
tasks.py
apps/assets/tasks.py
+0
-0
asset_modal_list.html
apps/assets/templates/assets/asset_modal_list.html
+0
-3
asset.py
apps/assets/views/asset.py
+1
-5
celery.py
apps/common/celery.py
+172
-1
tasks.py
apps/common/tasks.py
+1
-1
utils.py
apps/common/utils.py
+18
-56
settings.py
apps/jumpserver/settings.py
+2
-1
decorators.py
apps/ops/decorators.py
+0
-38
models.py
apps/ops/models.py
+10
-5
tasks.py
apps/ops/tasks.py
+2
-2
task_list.html
apps/ops/templates/ops/task_list.html
+11
-5
utils.py
apps/ops/utils.py
+21
-77
jumpserver.js
apps/static/js/jumpserver.js
+0
-3
_left_side_bar.html
apps/templates/_left_side_bar.html
+1
-1
_user_profile.html
apps/templates/_user_profile.html
+3
-3
group.py
apps/users/models/group.py
+0
-7
user.py
apps/users/models/user.py
+2
-2
serializers.py
apps/users/serializers.py
+3
-1
run_server.py
run_server.py
+1
-1
No files found.
apps/assets/api.py
View file @
bf9bb1b9
...
@@ -25,9 +25,9 @@ from .hands import IsSuperUser, IsValidUser, IsSuperUserOrAppUser, \
...
@@ -25,9 +25,9 @@ from .hands import IsSuperUser, IsValidUser, IsSuperUserOrAppUser, \
get_user_granted_assets
get_user_granted_assets
from
.models
import
AssetGroup
,
Asset
,
Cluster
,
SystemUser
,
AdminUser
from
.models
import
AssetGroup
,
Asset
,
Cluster
,
SystemUser
,
AdminUser
from
.
import
serializers
from
.
import
serializers
from
.tasks
import
update_assets_hardware_info
,
test_admin_user_connectability
,
\
from
.tasks
import
update_assets_hardware_info
_manual
,
test_admin_user_connectability_util
,
\
test_a
dmin_user_connectability_manual
,
push_system_user_to_cluster_assets
,
\
test_a
sset_connectability_manual
,
push_system_user_to_cluster_assets_manual
,
\
test_system_user_connectability
test_system_user_connectability
_manual
class
AssetViewSet
(
IDInFilterMixin
,
BulkModelViewSet
):
class
AssetViewSet
(
IDInFilterMixin
,
BulkModelViewSet
):
...
@@ -222,7 +222,7 @@ class AssetRefreshHardwareApi(generics.RetrieveAPIView):
...
@@ -222,7 +222,7 @@ class AssetRefreshHardwareApi(generics.RetrieveAPIView):
def
retrieve
(
self
,
request
,
*
args
,
**
kwargs
):
def
retrieve
(
self
,
request
,
*
args
,
**
kwargs
):
asset_id
=
kwargs
.
get
(
'pk'
)
asset_id
=
kwargs
.
get
(
'pk'
)
asset
=
get_object_or_404
(
Asset
,
pk
=
asset_id
)
asset
=
get_object_or_404
(
Asset
,
pk
=
asset_id
)
summary
=
update_assets_hardware_info
([
asset
])
summary
=
update_assets_hardware_info
_manual
([
asset
])
if
summary
.
get
(
'dark'
):
if
summary
.
get
(
'dark'
):
return
Response
(
summary
[
'dark'
]
.
values
(),
status
=
501
)
return
Response
(
summary
[
'dark'
]
.
values
(),
status
=
501
)
else
:
else
:
...
@@ -239,7 +239,7 @@ class AssetAdminUserTestApi(generics.RetrieveAPIView):
...
@@ -239,7 +239,7 @@ class AssetAdminUserTestApi(generics.RetrieveAPIView):
def
retrieve
(
self
,
request
,
*
args
,
**
kwargs
):
def
retrieve
(
self
,
request
,
*
args
,
**
kwargs
):
asset_id
=
kwargs
.
get
(
'pk'
)
asset_id
=
kwargs
.
get
(
'pk'
)
asset
=
get_object_or_404
(
Asset
,
pk
=
asset_id
)
asset
=
get_object_or_404
(
Asset
,
pk
=
asset_id
)
ok
,
msg
=
test_a
dmin_user
_connectability_manual
(
asset
)
ok
,
msg
=
test_a
sset
_connectability_manual
(
asset
)
if
ok
:
if
ok
:
return
Response
({
"msg"
:
"pong"
})
return
Response
({
"msg"
:
"pong"
})
else
:
else
:
...
@@ -255,7 +255,7 @@ class AdminUserTestConnectiveApi(generics.RetrieveAPIView):
...
@@ -255,7 +255,7 @@ class AdminUserTestConnectiveApi(generics.RetrieveAPIView):
def
retrieve
(
self
,
request
,
*
args
,
**
kwargs
):
def
retrieve
(
self
,
request
,
*
args
,
**
kwargs
):
admin_user
=
self
.
get_object
()
admin_user
=
self
.
get_object
()
test_admin_user_connectability
.
delay
(
admin_user
,
force
=
True
)
test_admin_user_connectability
_util
.
delay
(
admin_user
,
force
=
True
)
return
Response
({
"msg"
:
"Task created"
})
return
Response
({
"msg"
:
"Task created"
})
...
@@ -268,7 +268,7 @@ class SystemUserPushApi(generics.RetrieveAPIView):
...
@@ -268,7 +268,7 @@ class SystemUserPushApi(generics.RetrieveAPIView):
def
retrieve
(
self
,
request
,
*
args
,
**
kwargs
):
def
retrieve
(
self
,
request
,
*
args
,
**
kwargs
):
system_user
=
self
.
get_object
()
system_user
=
self
.
get_object
()
push_system_user_to_cluster_assets
.
delay
(
system_user
,
force
=
True
)
push_system_user_to_cluster_assets
_manual
.
delay
(
system_user
,
force
=
True
)
return
Response
({
"msg"
:
"Task created"
})
return
Response
({
"msg"
:
"Task created"
})
...
@@ -281,5 +281,5 @@ class SystemUserTestConnectiveApi(generics.RetrieveAPIView):
...
@@ -281,5 +281,5 @@ class SystemUserTestConnectiveApi(generics.RetrieveAPIView):
def
retrieve
(
self
,
request
,
*
args
,
**
kwargs
):
def
retrieve
(
self
,
request
,
*
args
,
**
kwargs
):
system_user
=
self
.
get_object
()
system_user
=
self
.
get_object
()
test_system_user_connectability
.
delay
(
system_user
,
force
=
True
)
test_system_user_connectability
_manual
.
delay
(
system_user
,
force
=
True
)
return
Response
({
"msg"
:
"Task created"
})
return
Response
({
"msg"
:
"Task created"
})
apps/assets/const.py
View file @
bf9bb1b9
...
@@ -2,14 +2,20 @@
...
@@ -2,14 +2,20 @@
#
#
from
django.utils.translation
import
ugettext
as
_
from
django.utils.translation
import
ugettext
as
_
PUSH_SYSTEM_USER_PERIOD_LOCK_KEY
=
"PUSH_SYSTEM_USER_PERIOD_KEY"
# PUSH_SYSTEM_USER_PERIOD_LOCK_KEY = "PUSH_SYSTEM_USER_PERIOD_KEY"
PUSH_SYSTEM_USER_PERIOD_TASK_NAME
=
_
(
"PUSH SYSTEM USER TO CLUSTER PERIOD TASK"
)
PUSH_SYSTEM_USER_PERIOD_TASK_NAME
=
_
(
"PUSH SYSTEM USER TO CLUSTER PERIOD: {}"
)
PUSH_SYSTEM_USER_MANUAL_TASK_NAME
=
_
(
"PUSH SYSTEM USER TO CLUSTER MANUALLY: {}"
)
PUSH_SYSTEM_USER_TASK_NAME
=
_
(
"PUSH SYSTEM USER TO CLUSTER: {}"
)
PUSH_SYSTEM_USER_TASK_NAME
=
_
(
"PUSH SYSTEM USER TO CLUSTER: {}"
)
PUSH_SYSTEM_USER_LOCK_KEY
=
"PUSH_SYSTEM_USER_TO_CLUSTER_LOCK_{}"
# PUSH_SYSTEM_USER_LOCK_KEY = "PUSH_SYSTEM_USER_TO_CLUSTER_LOCK_{}"
PUSH_SYSTEM_USER_ON_CHANGE_TASK_NAME
=
_
(
"PUSH SYSTEM USER ON CHANGE: {}"
)
PUSH_SYSTEM_USER_ON_CREATE_TASK_NAME
=
_
(
"PUSH SYSTEM USER ON CREATE: {}"
)
PUSH_SYSTEM_USERS_ON_ASSET_CREATE_TASK_NAME
=
_
(
"PUSH SYSTEM USERS ON ASSET CREAT: {}"
)
UPDATE_ASSETS_HARDWARE_TASK_NAME
=
_
(
'UPDATE ASSETS HARDWARE INFO'
)
UPDATE_ASSETS_HARDWARE_TASK_NAME
=
_
(
'UPDATE ASSETS HARDWARE INFO'
)
UPDATE_ASSETS_HARDWARE_PERIOD_LOCK_KEY
=
"UPDATE_ASSETS_HARDWARE_PERIOD_LOCK_KEY"
UPDATE_ASSETS_HARDWARE_MANUAL_TASK_NAME
=
_
(
'UPDATE ASSETS HARDWARE INFO MANUALLY'
)
UPDATE_ASSETS_HARDWARE_ON_CREATE_TASK_NAME
=
_
(
'UPDATE ASSETS HARDWARE INFO ON CREATE'
)
# UPDATE_ASSETS_HARDWARE_PERIOD_LOCK_KEY = "UPDATE_ASSETS_HARDWARE_PERIOD_LOCK_KEY"
UPDATE_ASSETS_HARDWARE_PERIOD_TASK_NAME
=
_
(
'UPDATE ASSETS HARDWARE INFO PERIOD'
)
UPDATE_ASSETS_HARDWARE_PERIOD_TASK_NAME
=
_
(
'UPDATE ASSETS HARDWARE INFO PERIOD'
)
UPDATE_ASSETS_HARDWARE_TASKS
=
[
UPDATE_ASSETS_HARDWARE_TASKS
=
[
{
{
...
@@ -20,10 +26,10 @@ UPDATE_ASSETS_HARDWARE_TASKS = [
...
@@ -20,10 +26,10 @@ UPDATE_ASSETS_HARDWARE_TASKS = [
}
}
]
]
TEST_ADMIN_USER_CONN_PERIOD_LOCK_KEY
=
"TEST_ADMIN_USER_CONN_PERIOD_KEY"
# TEST_ADMIN_USER_CONN_PERIOD_LOCK_KEY = "TEST_ADMIN_USER_CONN_PERIOD_KEY"
TEST_ADMIN_USER_CONN_PERIOD_TASK_NAME
=
_
(
"TEST ADMIN USER CONN PERIOD TASK"
)
TEST_ADMIN_USER_CONN_PERIOD_TASK_NAME
=
_
(
"TEST ADMIN USER CONN PERIOD: {}"
)
TEST_ADMIN_USER_CONN_MANUAL_TASK_NAME
=
_
(
"TEST ADMIN USER CONN MANUALLY: {}"
)
TEST_ADMIN_USER_CONN_TASK_NAME
=
_
(
"TEST ADMIN USER CONN: {}"
)
TEST_ADMIN_USER_CONN_TASK_NAME
=
_
(
"TEST ADMIN USER CONN: {}"
)
TEST_ADMIN_USER_CONN_LOCK_KEY
=
TEST_ADMIN_USER_CONN_TASK_NAME
ADMIN_USER_CONN_CACHE_KEY
=
"ADMIN_USER_CONN_{}"
ADMIN_USER_CONN_CACHE_KEY
=
"ADMIN_USER_CONN_{}"
TEST_ADMIN_USER_CONN_TASKS
=
[
TEST_ADMIN_USER_CONN_TASKS
=
[
{
{
...
@@ -38,10 +44,8 @@ ASSET_ADMIN_CONN_CACHE_KEY = "ASSET_ADMIN_USER_CONN_{}"
...
@@ -38,10 +44,8 @@ ASSET_ADMIN_CONN_CACHE_KEY = "ASSET_ADMIN_USER_CONN_{}"
TEST_ASSET_CONN_TASK_NAME
=
_
(
"ASSET CONN TEST MANUAL"
)
TEST_ASSET_CONN_TASK_NAME
=
_
(
"ASSET CONN TEST MANUAL"
)
TEST_SYSTEM_USER_CONN_PERIOD_LOCK_KEY
=
"TEST_SYSTEM_USER_CONN_PERIOD_KEY"
TEST_SYSTEM_USER_CONN_PERIOD_LOCK_KEY
=
"TEST_SYSTEM_USER_CONN_PERIOD_KEY"
TEST_SYSTEM_USER_CONN_PERIOD_TASK_NAME
=
_
(
"TEST SYSTEM USER CONN PERIOD TASK"
)
TEST_SYSTEM_USER_CONN_PERIOD_TASK_NAME
=
_
(
"TEST SYSTEM USER CONN PERIOD: {}"
)
TEST_SYSTEM_USER_CONN_CACHE_KEY_PREFIX
=
"SYSTEM_USER_CONN_"
TEST_SYSTEM_USER_CONN_MANUAL_TASK_NAME
=
_
(
"TEST SYSTEM USER CONN MANUALLY: {}"
)
TEST_SYSTEM_USER_CONN_TASK_NAME
=
_
(
"TEST SYSTEM USER CONN: {}"
)
TEST_SYSTEM_USER_CONN_LOCK_KEY
=
"TEST_SYSTEM_USER_CONN_{}"
SYSTEM_USER_CONN_CACHE_KEY
=
"SYSTEM_USER_CONN_{}"
SYSTEM_USER_CONN_CACHE_KEY
=
"SYSTEM_USER_CONN_{}"
TEST_SYSTEM_USER_CONN_TASKS
=
[
TEST_SYSTEM_USER_CONN_TASKS
=
[
{
{
...
...
apps/assets/models/user.py
View file @
bf9bb1b9
...
@@ -13,13 +13,14 @@ from django.db import models
...
@@ -13,13 +13,14 @@ from django.db import models
from
django.utils.translation
import
ugettext_lazy
as
_
from
django.utils.translation
import
ugettext_lazy
as
_
from
django.conf
import
settings
from
django.conf
import
settings
from
common.utils
import
signer
,
ssh_key_string_to_obj
,
ssh_key_gen
from
common.utils
import
get_
signer
,
ssh_key_string_to_obj
,
ssh_key_gen
from
.utils
import
private_key_validator
from
.utils
import
private_key_validator
from
..const
import
SYSTEM_USER_CONN_CACHE_KEY
from
..const
import
SYSTEM_USER_CONN_CACHE_KEY
__all__
=
[
'AdminUser'
,
'SystemUser'
,]
__all__
=
[
'AdminUser'
,
'SystemUser'
,]
logger
=
logging
.
getLogger
(
__name__
)
logger
=
logging
.
getLogger
(
__name__
)
signer
=
get_signer
()
class
AssetUser
(
models
.
Model
):
class
AssetUser
(
models
.
Model
):
...
...
apps/assets/tasks.py
View file @
bf9bb1b9
This diff is collapsed.
Click to expand it.
apps/assets/templates/assets/asset_modal_list.html
View file @
bf9bb1b9
...
@@ -49,9 +49,6 @@ $(document).ready(function(){
...
@@ -49,9 +49,6 @@ $(document).ready(function(){
"aaSorting"
:
[[
2
,
"asc"
]],
"aaSorting"
:
[[
2
,
"asc"
]],
"aoColumnDefs"
:
[
{
"bSortable"
:
false
,
"aTargets"
:
[
0
]
}],
"aoColumnDefs"
:
[
{
"bSortable"
:
false
,
"aTargets"
:
[
0
]
}],
"bAutoWidth"
:
false
,
"bAutoWidth"
:
false
,
"language"
:
{
"url"
:
"/static/js/plugins/dataTables/i18n/zh-hans.json"
},
columns
:
[
columns
:
[
{
data
:
"checkbox"
},
{
data
:
"checkbox"
},
{
data
:
"id"
},
{
data
:
"id"
},
...
...
apps/assets/views/asset.py
View file @
bf9bb1b9
...
@@ -28,7 +28,7 @@ from common.utils import get_object_or_none, get_logger, is_uuid
...
@@ -28,7 +28,7 @@ from common.utils import get_object_or_none, get_logger, is_uuid
from
..
import
forms
from
..
import
forms
from
..models
import
Asset
,
AssetGroup
,
AdminUser
,
Cluster
,
SystemUser
from
..models
import
Asset
,
AssetGroup
,
AdminUser
,
Cluster
,
SystemUser
from
..hands
import
AdminUserRequiredMixin
from
..hands
import
AdminUserRequiredMixin
from
..tasks
import
update_assets_hardware_info
from
..tasks
import
update_assets_hardware_info
_util
__all__
=
[
__all__
=
[
...
@@ -314,10 +314,6 @@ class BulkImportAssetView(AdminUserRequiredMixin, JSONResponseMixin, FormView):
...
@@ -314,10 +314,6 @@ class BulkImportAssetView(AdminUserRequiredMixin, JSONResponseMixin, FormView):
except
Exception
as
e
:
except
Exception
as
e
:
failed
.
append
(
'
%
s:
%
s'
%
(
asset_dict
[
'hostname'
],
str
(
e
)))
failed
.
append
(
'
%
s:
%
s'
%
(
asset_dict
[
'hostname'
],
str
(
e
)))
if
assets
:
update_assets_hardware_info
.
delay
([
asset
.
_to_secret_json
()
for
asset
in
assets
])
data
=
{
data
=
{
'created'
:
created
,
'created'
:
created
,
'created_info'
:
'Created {}'
.
format
(
len
(
created
)),
'created_info'
:
'Created {}'
.
format
(
len
(
created
)),
...
...
apps/common/celery.py
View file @
bf9bb1b9
# ~*~ coding: utf-8 ~*~
# ~*~ coding: utf-8 ~*~
import
os
import
os
import
json
from
functools
import
wraps
from
celery
import
Celery
from
celery
import
Celery
,
subtask
from
celery.signals
import
worker_ready
,
worker_shutdown
from
.utils
import
get_logger
logger
=
get_logger
(
__file__
)
# set the default Django settings module for the 'celery' program.
# set the default Django settings module for the 'celery' program.
os
.
environ
.
setdefault
(
'DJANGO_SETTINGS_MODULE'
,
'jumpserver.settings'
)
os
.
environ
.
setdefault
(
'DJANGO_SETTINGS_MODULE'
,
'jumpserver.settings'
)
...
@@ -15,3 +22,167 @@ app = Celery('jumpserver')
...
@@ -15,3 +22,167 @@ app = Celery('jumpserver')
# pickle the object when using Windows.
# pickle the object when using Windows.
app
.
config_from_object
(
'django.conf:settings'
,
namespace
=
'CELERY'
)
app
.
config_from_object
(
'django.conf:settings'
,
namespace
=
'CELERY'
)
app
.
autodiscover_tasks
(
lambda
:
[
app_config
.
split
(
'.'
)[
0
]
for
app_config
in
settings
.
INSTALLED_APPS
])
app
.
autodiscover_tasks
(
lambda
:
[
app_config
.
split
(
'.'
)[
0
]
for
app_config
in
settings
.
INSTALLED_APPS
])
def
create_or_update_celery_periodic_tasks
(
tasks
):
from
django_celery_beat.models
import
PeriodicTask
,
IntervalSchedule
,
CrontabSchedule
"""
:param tasks: {
'add-every-monday-morning': {
'task': 'tasks.add' # A registered celery task,
'interval': 30,
'crontab': "30 7 * * *",
'args': (16, 16),
'kwargs': {},
'enabled': False,
},
}
:return:
"""
# Todo: check task valid, task and callback must be a celery task
for
name
,
detail
in
tasks
.
items
():
interval
=
None
crontab
=
None
if
isinstance
(
detail
.
get
(
"interval"
),
int
):
intervals
=
IntervalSchedule
.
objects
.
filter
(
every
=
detail
[
"interval"
],
period
=
IntervalSchedule
.
SECONDS
)
if
intervals
:
interval
=
intervals
[
0
]
else
:
interval
=
IntervalSchedule
.
objects
.
create
(
every
=
detail
[
'interval'
],
period
=
IntervalSchedule
.
SECONDS
,
)
elif
isinstance
(
detail
.
get
(
"crontab"
),
str
):
try
:
minute
,
hour
,
day
,
month
,
week
=
detail
[
"crontab"
]
.
split
()
except
ValueError
:
raise
SyntaxError
(
"crontab is not valid"
)
kwargs
=
dict
(
minute
=
minute
,
hour
=
hour
,
day_of_week
=
week
,
day_of_month
=
day
,
month_of_year
=
month
,
)
contabs
=
CrontabSchedule
.
objects
.
filter
(
**
kwargs
)
if
contabs
:
crontab
=
contabs
[
0
]
else
:
crontab
=
CrontabSchedule
.
objects
.
create
(
**
kwargs
)
else
:
raise
SyntaxError
(
"Schedule is not valid"
)
defaults
=
dict
(
interval
=
interval
,
crontab
=
crontab
,
name
=
name
,
task
=
detail
[
'task'
],
args
=
json
.
dumps
(
detail
.
get
(
'args'
,
[])),
kwargs
=
json
.
dumps
(
detail
.
get
(
'kwargs'
,
{})),
enabled
=
detail
.
get
(
'enabled'
,
True
),
)
task
=
PeriodicTask
.
objects
.
update_or_create
(
defaults
=
defaults
,
name
=
name
,
)
return
task
def
disable_celery_periodic_task
(
task_name
):
from
django_celery_beat.models
import
PeriodicTask
PeriodicTask
.
objects
.
filter
(
name
=
task_name
)
.
update
(
enabled
=
False
)
def
delete_celery_periodic_task
(
task_name
):
from
django_celery_beat.models
import
PeriodicTask
PeriodicTask
.
objects
.
filter
(
name
=
task_name
)
.
delete
()
__REGISTER_PERIODIC_TASKS
=
[]
__AFTER_APP_SHUTDOWN_CLEAN_TASKS
=
[]
__AFTER_APP_READY_RUN_TASKS
=
[]
def
register_as_period_task
(
crontab
=
None
,
interval
=
None
):
"""
Warning: Task must be have not any args and kwargs
:param crontab: "* * * * *"
:param interval: 60*60*60
:return:
"""
if
crontab
is
None
and
interval
is
None
:
raise
SyntaxError
(
"Must set crontab or interval one"
)
def
decorate
(
func
):
if
crontab
is
None
and
interval
is
None
:
raise
SyntaxError
(
"Interval and crontab must set one"
)
# Because when this decorator run, the task was not created,
# So we can't use func.name
name
=
'{func.__module__}.{func.__name__}'
.
format
(
func
=
func
)
if
name
not
in
__REGISTER_PERIODIC_TASKS
:
create_or_update_celery_periodic_tasks
({
name
:
{
'task'
:
name
,
'interval'
:
interval
,
'crontab'
:
crontab
,
'args'
:
(),
'enabled'
:
True
,
}
})
__REGISTER_PERIODIC_TASKS
.
append
(
name
)
@wraps
(
func
)
def
wrapper
(
*
args
,
**
kwargs
):
return
func
(
*
args
,
**
kwargs
)
return
wrapper
return
decorate
def
after_app_ready_start
(
func
):
# Because when this decorator run, the task was not created,
# So we can't use func.name
name
=
'{func.__module__}.{func.__name__}'
.
format
(
func
=
func
)
if
name
not
in
__AFTER_APP_READY_RUN_TASKS
:
__AFTER_APP_READY_RUN_TASKS
.
append
(
name
)
@wraps
(
func
)
def
decorate
(
*
args
,
**
kwargs
):
return
func
(
*
args
,
**
kwargs
)
return
decorate
def
after_app_shutdown_clean
(
func
):
# Because when this decorator run, the task was not created,
# So we can't use func.name
name
=
'{func.__module__}.{func.__name__}'
.
format
(
func
=
func
)
if
name
not
in
__AFTER_APP_READY_RUN_TASKS
:
__AFTER_APP_SHUTDOWN_CLEAN_TASKS
.
append
(
name
)
@wraps
(
func
)
def
decorate
(
*
args
,
**
kwargs
):
return
func
(
*
args
,
**
kwargs
)
return
decorate
@worker_ready.connect
def
on_app_ready
(
sender
=
None
,
headers
=
None
,
body
=
None
,
**
kwargs
):
logger
.
debug
(
"App ready signal recv"
)
logger
.
debug
(
"Start need start task: [{}]"
.
format
(
", "
.
join
(
__AFTER_APP_READY_RUN_TASKS
))
)
for
task
in
__AFTER_APP_READY_RUN_TASKS
:
subtask
(
task
)
.
delay
()
@worker_shutdown.connect
def
after_app_shutdown
(
sender
=
None
,
headers
=
None
,
body
=
None
,
**
kwargs
):
from
django_celery_beat.models
import
PeriodicTask
logger
.
debug
(
"App shutdown signal recv"
)
logger
.
debug
(
"Clean need cleaned period tasks: [{}]"
.
format
(
', '
.
join
(
__AFTER_APP_SHUTDOWN_CLEAN_TASKS
))
)
PeriodicTask
.
objects
.
filter
(
name__in
=
__AFTER_APP_SHUTDOWN_CLEAN_TASKS
)
.
delete
()
apps/common/tasks.py
View file @
bf9bb1b9
from
django.core.mail
import
send_mail
from
django.core.mail
import
send_mail
from
django.conf
import
settings
from
django.conf
import
settings
from
common
import
celery_app
as
app
from
.celery
import
app
from
.utils
import
get_logger
from
.utils
import
get_logger
...
...
apps/common/utils.py
View file @
bf9bb1b9
# -*- coding: utf-8 -*-
# -*- coding: utf-8 -*-
#
#
import
json
import
re
import
re
from
collections
import
OrderedDict
from
collections
import
OrderedDict
from
six
import
string_types
from
six
import
string_types
import
base64
import
base64
import
os
import
os
from
itertools
import
chain
from
itertools
import
chain
import
string
import
logging
import
logging
import
datetime
import
datetime
import
time
import
time
...
@@ -27,9 +25,6 @@ from django.conf import settings
...
@@ -27,9 +25,6 @@ from django.conf import settings
from
django.utils
import
timezone
from
django.utils
import
timezone
from
.compat
import
to_bytes
,
to_string
SECRET_KEY
=
settings
.
SECRET_KEY
UUID_PATTERN
=
re
.
compile
(
r'[0-9a-zA-Z\-]{36}'
)
UUID_PATTERN
=
re
.
compile
(
r'[0-9a-zA-Z\-]{36}'
)
...
@@ -51,9 +46,22 @@ def get_object_or_none(model, **kwargs):
...
@@ -51,9 +46,22 @@ def get_object_or_none(model, **kwargs):
return
obj
return
obj
class
Signer
(
object
):
class
Singleton
(
type
):
def
__init__
(
cls
,
*
args
,
**
kwargs
):
cls
.
__instance
=
None
super
()
.
__init__
(
*
args
,
**
kwargs
)
def
__call__
(
cls
,
*
args
,
**
kwargs
):
if
cls
.
__instance
is
None
:
cls
.
__instance
=
super
()
.
__call__
(
*
args
,
**
kwargs
)
return
cls
.
__instance
else
:
return
cls
.
__instance
class
Signer
(
metaclass
=
Singleton
):
"""用来加密,解密,和基于时间戳的方式验证token"""
"""用来加密,解密,和基于时间戳的方式验证token"""
def
__init__
(
self
,
secret_key
=
SECRET_KEY
):
def
__init__
(
self
,
secret_key
=
None
):
self
.
secret_key
=
secret_key
self
.
secret_key
=
secret_key
def
sign
(
self
,
value
):
def
sign
(
self
,
value
):
...
@@ -100,58 +108,10 @@ def combine_seq(s1, s2, callback=None):
...
@@ -100,58 +108,10 @@ def combine_seq(s1, s2, callback=None):
return
seq
return
seq
def
search_object_attr
(
obj
,
value
=
''
,
attr_list
=
None
,
ignore_case
=
False
):
"""It's provide a method to search a object attribute equal some value
If object some attribute equal :param: value, return True else return False
class A():
name = 'admin'
age = 7
:param obj: A object
:param value: A string match object attribute
:param attr_list: Only match attribute in attr_list
:param ignore_case: Ignore case
:return: Boolean
"""
if
value
==
''
:
return
True
try
:
object_attr
=
obj
.
__dict__
except
AttributeError
:
return
False
if
attr_list
is
not
None
:
new_object_attr
=
{}
for
attr
in
attr_list
:
new_object_attr
[
attr
]
=
object_attr
.
pop
(
attr
)
object_attr
=
new_object_attr
if
ignore_case
:
if
not
isinstance
(
value
,
string_types
):
return
False
if
value
.
lower
()
in
map
(
string
.
lower
,
map
(
str
,
object_attr
.
values
())):
return
True
else
:
if
value
in
object_attr
.
values
():
return
True
return
False
def
get_logger
(
name
=
None
):
def
get_logger
(
name
=
None
):
return
logging
.
getLogger
(
'jumpserver.
%
s'
%
name
)
return
logging
.
getLogger
(
'jumpserver.
%
s'
%
name
)
def
int_seq
(
seq
):
try
:
return
map
(
int
,
seq
)
except
ValueError
:
return
seq
def
timesince
(
dt
,
since
=
''
,
default
=
"just now"
):
def
timesince
(
dt
,
since
=
''
,
default
=
"just now"
):
"""
"""
Returns string representing "time since" e.g.
Returns string representing "time since" e.g.
...
@@ -391,4 +351,6 @@ def is_uuid(s):
...
@@ -391,4 +351,6 @@ def is_uuid(s):
return
False
return
False
signer
=
Signer
()
def
get_signer
():
signer
=
Signer
(
settings
.
SECRET_KEY
)
return
signer
apps/jumpserver/settings.py
View file @
bf9bb1b9
...
@@ -337,8 +337,9 @@ CELERY_ACCEPT_CONTENT = ['json', 'pickle']
...
@@ -337,8 +337,9 @@ CELERY_ACCEPT_CONTENT = ['json', 'pickle']
CELERY_RESULT_EXPIRES
=
3600
CELERY_RESULT_EXPIRES
=
3600
CELERY_WORKER_LOG_FORMAT
=
'
%(asctime)
s [
%(module)
s
%(levelname)
s]
%(message)
s'
CELERY_WORKER_LOG_FORMAT
=
'
%(asctime)
s [
%(module)
s
%(levelname)
s]
%(message)
s'
CELERY_WORKER_TASK_LOG_FORMAT
=
'
%(asctime)
s [
%(module)
s
%(levelname)
s]
%(message)
s'
CELERY_WORKER_TASK_LOG_FORMAT
=
'
%(asctime)
s [
%(module)
s
%(levelname)
s]
%(message)
s'
CELERY_TASK_EAGER_PROPAGATES
=
True
CELERY_TIMEZONE
=
TIME_ZONE
CELERY_TIMEZONE
=
TIME_ZONE
#
TERMINAL_HEATBEAT_INTERVAL = CONFIG.TERMINAL_HEATBEAT_INTERVAL or 30
#
CELERY_ENABLE_UTC = True
# Cache use redis
# Cache use redis
...
...
apps/ops/decorators.py
deleted
100644 → 0
View file @
30efec1b
# -*- coding: utf-8 -*-
#
from
functools
import
wraps
TASK_PREFIX
=
"TOOT"
CALLBACK_PREFIX
=
"COC"
def
register_as_period_task
(
crontab
=
None
,
interval
=
None
):
"""
:param crontab: "* * * * *"
:param interval: 60*60*60
:return:
"""
from
.utils
import
create_or_update_celery_periodic_tasks
if
crontab
is
None
and
interval
is
None
:
raise
SyntaxError
(
"Must set crontab or interval one"
)
def
decorate
(
func
):
@wraps
(
func
)
def
wrapper
(
*
args
,
**
kwargs
):
tasks
=
{
func
.
__name__
:
{
'task'
:
func
.
__name__
,
'args'
:
args
,
'kwargs'
:
kwargs
,
'interval'
:
interval
,
'crontab'
:
crontab
,
'enabled'
:
True
,
}
}
create_or_update_celery_periodic_tasks
(
tasks
)
return
func
(
*
args
,
**
kwargs
)
return
wrapper
return
decorate
apps/ops/models.py
View file @
bf9bb1b9
...
@@ -9,7 +9,9 @@ from django.utils import timezone
...
@@ -9,7 +9,9 @@ from django.utils import timezone
from
django.utils.translation
import
ugettext_lazy
as
_
from
django.utils.translation
import
ugettext_lazy
as
_
from
django_celery_beat.models
import
CrontabSchedule
,
IntervalSchedule
,
PeriodicTask
from
django_celery_beat.models
import
CrontabSchedule
,
IntervalSchedule
,
PeriodicTask
from
common.utils
import
signer
,
get_logger
from
common.utils
import
get_signer
,
get_logger
from
common.celery
import
delete_celery_periodic_task
,
create_or_update_celery_periodic_tasks
,
\
disable_celery_periodic_task
from
.ansible
import
AdHocRunner
,
AnsibleError
from
.ansible
import
AdHocRunner
,
AnsibleError
from
.inventory
import
JMSInventory
from
.inventory
import
JMSInventory
...
@@ -17,6 +19,7 @@ __all__ = ["Task", "AdHoc", "AdHocRunHistory"]
...
@@ -17,6 +19,7 @@ __all__ = ["Task", "AdHoc", "AdHocRunHistory"]
logger
=
get_logger
(
__file__
)
logger
=
get_logger
(
__file__
)
signer
=
get_signer
()
class
Task
(
models
.
Model
):
class
Task
(
models
.
Model
):
...
@@ -82,8 +85,6 @@ class Task(models.Model):
...
@@ -82,8 +85,6 @@ class Task(models.Model):
def
save
(
self
,
force_insert
=
False
,
force_update
=
False
,
using
=
None
,
def
save
(
self
,
force_insert
=
False
,
force_update
=
False
,
using
=
None
,
update_fields
=
None
):
update_fields
=
None
):
from
.utils
import
create_or_update_celery_periodic_tasks
,
\
disable_celery_periodic_task
from
.tasks
import
run_ansible_task
from
.tasks
import
run_ansible_task
super
()
.
save
(
super
()
.
save
(
force_insert
=
force_insert
,
force_update
=
force_update
,
force_insert
=
force_insert
,
force_update
=
force_update
,
...
@@ -114,7 +115,6 @@ class Task(models.Model):
...
@@ -114,7 +115,6 @@ class Task(models.Model):
disable_celery_periodic_task
(
self
.
name
)
disable_celery_periodic_task
(
self
.
name
)
def
delete
(
self
,
using
=
None
,
keep_parents
=
False
):
def
delete
(
self
,
using
=
None
,
keep_parents
=
False
):
from
.utils
import
delete_celery_periodic_task
super
()
.
delete
(
using
=
using
,
keep_parents
=
keep_parents
)
super
()
.
delete
(
using
=
using
,
keep_parents
=
keep_parents
)
delete_celery_periodic_task
(
self
.
name
)
delete_celery_periodic_task
(
self
.
name
)
...
@@ -246,7 +246,7 @@ class AdHoc(models.Model):
...
@@ -246,7 +246,7 @@ class AdHoc(models.Model):
}
}
:return:
:return:
"""
"""
self
.
_become
=
signer
.
sign
(
json
.
dumps
(
item
))
self
.
_become
=
signer
.
sign
(
json
.
dumps
(
item
))
.
decode
(
'utf-8'
)
@property
@property
def
options
(
self
):
def
options
(
self
):
...
@@ -271,6 +271,11 @@ class AdHoc(models.Model):
...
@@ -271,6 +271,11 @@ class AdHoc(models.Model):
except
AdHocRunHistory
.
DoesNotExist
:
except
AdHocRunHistory
.
DoesNotExist
:
return
None
return
None
def
save
(
self
,
force_insert
=
False
,
force_update
=
False
,
using
=
None
,
update_fields
=
None
):
super
()
.
save
(
force_insert
=
force_insert
,
force_update
=
force_update
,
using
=
using
,
update_fields
=
update_fields
)
def
__str__
(
self
):
def
__str__
(
self
):
return
"{} of {}"
.
format
(
self
.
task
.
name
,
self
.
short_id
)
return
"{} of {}"
.
format
(
self
.
task
.
name
,
self
.
short_id
)
...
...
apps/ops/tasks.py
View file @
bf9bb1b9
...
@@ -21,9 +21,9 @@ def run_ansible_task(task_id, callback=None, **kwargs):
...
@@ -21,9 +21,9 @@ def run_ansible_task(task_id, callback=None, **kwargs):
task
=
get_object_or_none
(
Task
,
id
=
task_id
)
task
=
get_object_or_none
(
Task
,
id
=
task_id
)
if
task
:
if
task
:
result
=
task
.
object
.
run
()
result
=
task
.
run
()
if
callback
is
not
None
:
if
callback
is
not
None
:
subtask
(
callback
)
.
delay
(
result
)
subtask
(
callback
)
.
delay
(
result
,
task_name
=
task
.
name
)
return
result
return
result
else
:
else
:
logger
.
error
(
"No task found"
)
logger
.
error
(
"No task found"
)
...
...
apps/ops/templates/ops/task_list.html
View file @
bf9bb1b9
...
@@ -57,14 +57,20 @@
...
@@ -57,14 +57,20 @@
<td
class=
"text-center"
>
{{ object.adhoc.all | length}}
</td>
<td
class=
"text-center"
>
{{ object.adhoc.all | length}}
</td>
<td
class=
"text-center"
>
{{ object.latest_adhoc.hosts | length}}
</td>
<td
class=
"text-center"
>
{{ object.latest_adhoc.hosts | length}}
</td>
<td
class=
"text-center"
>
<td
class=
"text-center"
>
{% if object.latest_history.is_success %}
{% if object.latest_history %}
<i
class=
"fa fa-check text-navy"
></i>
{% if object.latest_history.is_success %}
{% else %}
<i
class=
"fa fa-check text-navy"
></i>
<i
class=
"fa fa-times text-danger"
></i>
{% else %}
<i
class=
"fa fa-times text-danger"
></i>
{% endif %}
{% endif %}
{% endif %}
</td>
</td>
<td
class=
"text-center"
>
{{ object.latest_history.date_start }}
</td>
<td
class=
"text-center"
>
{{ object.latest_history.date_start }}
</td>
<td
class=
"text-center"
>
{{ object.latest_history.timedelta|floatformat }} s
</td>
<td
class=
"text-center"
>
{% if object.latest_history %}
{{ object.latest_history.timedelta|floatformat }} s
{% endif %}
</td>
<td
class=
"text-center"
>
<td
class=
"text-center"
>
<a
href=
"{% url 'ops:task-run' pk=object.id %}"
class=
"btn btn-xs btn-info"
>
{% trans "Run" %}
</a>
<a
href=
"{% url 'ops:task-run' pk=object.id %}"
class=
"btn btn-xs btn-info"
>
{% trans "Run" %}
</a>
<a
data-uid=
"{{ object.id }}"
class=
"btn btn-xs btn-danger btn-del"
>
{% trans "Delete" %}
</a>
<a
data-uid=
"{{ object.id }}"
class=
"btn btn-xs btn-danger btn-del"
>
{% trans "Delete" %}
</a>
...
...
apps/ops/utils.py
View file @
bf9bb1b9
# ~*~ coding: utf-8 ~*~
# ~*~ coding: utf-8 ~*~
import
json
from
django_celery_beat.models
import
PeriodicTask
,
IntervalSchedule
,
CrontabSchedule
from
common.utils
import
get_logger
,
get_object_or_none
from
common.utils
import
get_logger
,
get_object_or_none
from
.models
import
Task
,
AdHoc
from
.models
import
Task
,
AdHoc
...
@@ -13,22 +9,27 @@ def get_task_by_id(task_id):
...
@@ -13,22 +9,27 @@ def get_task_by_id(task_id):
return
get_object_or_none
(
Task
,
id
=
task_id
)
return
get_object_or_none
(
Task
,
id
=
task_id
)
def
create_or_update_ansible_task
(
def
update_or_create_ansible_task
(
task_name
,
hosts
,
tasks
,
pattern
=
'all'
,
options
=
None
,
task_name
,
hosts
,
tasks
,
interval
=
None
,
crontab
=
None
,
is_periodic
=
False
,
callback
=
None
,
pattern
=
'all'
,
options
=
None
,
run_as_admin
=
False
,
run_as
=
""
,
become_info
=
None
,
run_as_admin
=
False
,
run_as
=
""
,
become_info
=
None
,
created_by
=
None
,
interval
=
None
,
crontab
=
None
,
created_by
=
None
,
is_periodic
=
False
,
callback
=
None
,
):
):
task
=
get_object_or_none
(
Task
,
name
=
task_name
)
defaults
=
{
'name'
:
task_name
,
'interval'
:
interval
,
'crontab'
:
crontab
,
'is_periodic'
:
is_periodic
,
'callback'
:
callback
,
'created_by'
:
created_by
,
}
if
task
is
None
:
created
=
False
task
=
Task
(
task
,
_
=
Task
.
objects
.
update_or_create
(
name
=
task_name
,
interval
=
interval
,
defaults
=
defaults
,
name
=
task_name
,
crontab
=
crontab
,
is_periodic
=
is_periodic
,
)
callback
=
callback
,
created_by
=
created_by
)
task
.
save
()
adhoc
=
task
.
latest_adhoc
adhoc
=
task
.
latest_adhoc
new_adhoc
=
AdHoc
(
task
=
task
,
pattern
=
pattern
,
new_adhoc
=
AdHoc
(
task
=
task
,
pattern
=
pattern
,
...
@@ -38,70 +39,13 @@ def create_or_update_ansible_task(
...
@@ -38,70 +39,13 @@ def create_or_update_ansible_task(
new_adhoc
.
tasks
=
tasks
new_adhoc
.
tasks
=
tasks
new_adhoc
.
options
=
options
new_adhoc
.
options
=
options
new_adhoc
.
become
=
become_info
new_adhoc
.
become
=
become_info
if
not
adhoc
or
adhoc
!=
new_adhoc
:
if
not
adhoc
or
adhoc
!=
new_adhoc
:
logger
.
debug
(
"Task create new adhoc: {}"
.
format
(
task_name
))
new_adhoc
.
save
()
new_adhoc
.
save
()
task
.
latest_adhoc
=
new_adhoc
task
.
latest_adhoc
=
new_adhoc
return
task
created
=
True
return
task
,
created
def
create_or_update_celery_periodic_tasks
(
tasks
):
"""
:param tasks: {
'add-every-monday-morning': {
'task': 'tasks.add' # A registered celery task,
'interval': 30,
'crontab': "30 7 * * *",
'args': (16, 16),
'kwargs': {},
'enabled': False,
},
}
:return:
"""
# Todo: check task valid, task and callback must be a celery task
for
name
,
detail
in
tasks
.
items
():
interval
=
None
crontab
=
None
if
isinstance
(
detail
.
get
(
"interval"
),
int
):
interval
,
_
=
IntervalSchedule
.
objects
.
get_or_create
(
every
=
detail
[
'interval'
],
period
=
IntervalSchedule
.
SECONDS
,
)
elif
isinstance
(
detail
.
get
(
"crontab"
),
str
):
try
:
minute
,
hour
,
day
,
month
,
week
=
detail
[
"crontab"
]
.
split
()
except
ValueError
:
raise
SyntaxError
(
"crontab is not valid"
)
crontab
,
_
=
CrontabSchedule
.
objects
.
get_or_create
(
minute
=
minute
,
hour
=
hour
,
day_of_week
=
week
,
day_of_month
=
day
,
month_of_year
=
month
,
)
else
:
raise
SyntaxError
(
"Schedule is not valid"
)
defaults
=
dict
(
interval
=
interval
,
crontab
=
crontab
,
name
=
name
,
task
=
detail
[
'task'
],
args
=
json
.
dumps
(
detail
.
get
(
'args'
,
[])),
kwargs
=
json
.
dumps
(
detail
.
get
(
'kwargs'
,
{})),
enabled
=
detail
[
'enabled'
]
)
task
=
PeriodicTask
.
objects
.
update_or_create
(
defaults
=
defaults
,
name
=
name
,
)
logger
.
info
(
"Create periodic task: {}"
.
format
(
task
))
return
task
def
disable_celery_periodic_task
(
task_name
):
PeriodicTask
.
objects
.
filter
(
name
=
task_name
)
.
update
(
enabled
=
False
)
def
delete_celery_periodic_task
(
task_name
):
PeriodicTask
.
objects
.
filter
(
name
=
task_name
)
.
delete
()
apps/static/js/jumpserver.js
View file @
bf9bb1b9
...
@@ -262,9 +262,6 @@ jumpserver.initDataTable = function (options) {
...
@@ -262,9 +262,6 @@ jumpserver.initDataTable = function (options) {
var
table
=
ele
.
DataTable
({
var
table
=
ele
.
DataTable
({
pageLength
:
options
.
pageLength
||
15
,
pageLength
:
options
.
pageLength
||
15
,
dom
:
options
.
dom
||
'<"#uc.pull-left">flt<"row m-t"<"col-md-8"<"#op.col-md-6"><"col-md-6 text-center"i>><"col-md-4"p>>'
,
dom
:
options
.
dom
||
'<"#uc.pull-left">flt<"row m-t"<"col-md-8"<"#op.col-md-6"><"col-md-6 text-center"i>><"col-md-4"p>>'
,
language
:
{
url
:
options
.
i18n_url
||
"/static/js/plugins/dataTables/i18n/zh-hans.json"
},
order
:
options
.
order
||
[],
order
:
options
.
order
||
[],
select
:
options
.
select
||
'multi'
,
select
:
options
.
select
||
'multi'
,
buttons
:
[],
buttons
:
[],
...
...
apps/templates/_left_side_bar.html
View file @
bf9bb1b9
...
@@ -2,7 +2,7 @@
...
@@ -2,7 +2,7 @@
<div
class=
"sidebar-collapse"
>
<div
class=
"sidebar-collapse"
>
<ul
class=
"nav"
id=
"side-menu"
>
<ul
class=
"nav"
id=
"side-menu"
>
{% include '_user_profile.html' %}
{% include '_user_profile.html' %}
{% if request.user.is_superuser and request.COOKIES.
admin == "Yes
" %}
{% if request.user.is_superuser and request.COOKIES.
IN_ADMIN_PAGE != "No
" %}
{% include '_nav.html' %}
{% include '_nav.html' %}
{% else %}
{% else %}
{% include '_nav_user.html' %}
{% include '_nav_user.html' %}
...
...
apps/templates/_user_profile.html
View file @
bf9bb1b9
...
@@ -20,7 +20,7 @@
...
@@ -20,7 +20,7 @@
<li><a
href=
"{% url 'users:user-profile-update' %}"
>
{% trans 'Profile settings' %}
</a></li>
<li><a
href=
"{% url 'users:user-profile-update' %}"
>
{% trans 'Profile settings' %}
</a></li>
<li
class=
"divider"
></li>
<li
class=
"divider"
></li>
{% if request.user.is_superuser %}
{% if request.user.is_superuser %}
{% if request.COOKIES.
admin
== 'No' %}
{% if request.COOKIES.
IN_ADMIN_PAGE
== 'No' %}
<li><a
id=
"switch_admin"
>
{% trans 'Admin page' %}
</a></li>
<li><a
id=
"switch_admin"
>
{% trans 'Admin page' %}
</a></li>
{% else %}
{% else %}
<li><a
id=
"switch_user"
>
{% trans 'User page' %}
</a></li>
<li><a
id=
"switch_user"
>
{% trans 'User page' %}
</a></li>
...
@@ -37,11 +37,11 @@
...
@@ -37,11 +37,11 @@
$
(
document
).
ready
(
function
()
{
$
(
document
).
ready
(
function
()
{
})
})
.
on
(
'click'
,
'#switch_admin'
,
function
()
{
.
on
(
'click'
,
'#switch_admin'
,
function
()
{
setCookie
(
"
admin
"
,
"Yes"
);
setCookie
(
"
IN_ADMIN_PAGE
"
,
"Yes"
);
window
.
location
=
"/"
window
.
location
=
"/"
})
})
.
on
(
'click'
,
'#switch_user'
,
function
()
{
.
on
(
'click'
,
'#switch_user'
,
function
()
{
setCookie
(
"
admin
"
,
"No"
);
setCookie
(
"
IN_ADMIN_PAGE
"
,
"No"
);
window
.
location
=
"/"
window
.
location
=
"/"
})
})
</script>
</script>
apps/users/models/group.py
View file @
bf9bb1b9
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# -*- coding: utf-8 -*-
#
from
__future__
import
unicode_literals
import
uuid
import
uuid
from
django.db
import
models
,
IntegrityError
from
django.db
import
models
,
IntegrityError
from
django.contrib.auth.models
import
Group
from
django.utils.translation
import
ugettext_lazy
as
_
from
django.utils.translation
import
ugettext_lazy
as
_
from
common.utils
import
signer
,
date_expired_default
from
common.mixins
import
NoDeleteModelMixin
from
common.mixins
import
NoDeleteModelMixin
__all__
=
[
'UserGroup'
]
__all__
=
[
'UserGroup'
]
...
...
apps/users/models/user.py
View file @
bf9bb1b9
#!/usr/bin/env python
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# -*- coding: utf-8 -*-
#
#
import
os
import
uuid
import
uuid
from
collections
import
OrderedDict
from
collections
import
OrderedDict
...
@@ -15,10 +14,11 @@ from django.utils import timezone
...
@@ -15,10 +14,11 @@ from django.utils import timezone
from
django.shortcuts
import
reverse
from
django.shortcuts
import
reverse
from
.group
import
UserGroup
from
.group
import
UserGroup
from
common.utils
import
signer
,
date_expired_default
from
common.utils
import
get_
signer
,
date_expired_default
__all__
=
[
'User'
]
__all__
=
[
'User'
]
signer
=
get_signer
()
class
User
(
AbstractUser
):
class
User
(
AbstractUser
):
...
...
apps/users/serializers.py
View file @
bf9bb1b9
...
@@ -5,10 +5,12 @@ from django.utils.translation import ugettext_lazy as _
...
@@ -5,10 +5,12 @@ from django.utils.translation import ugettext_lazy as _
from
rest_framework
import
serializers
from
rest_framework
import
serializers
from
rest_framework_bulk
import
BulkListSerializer
from
rest_framework_bulk
import
BulkListSerializer
from
common.utils
import
signer
,
validate_ssh_public_key
from
common.utils
import
get_
signer
,
validate_ssh_public_key
from
common.mixins
import
BulkSerializerMixin
from
common.mixins
import
BulkSerializerMixin
from
.models
import
User
,
UserGroup
from
.models
import
User
,
UserGroup
signer
=
get_signer
()
class
UserSerializer
(
BulkSerializerMixin
,
serializers
.
ModelSerializer
):
class
UserSerializer
(
BulkSerializerMixin
,
serializers
.
ModelSerializer
):
groups_display
=
serializers
.
SerializerMethodField
()
groups_display
=
serializers
.
SerializerMethodField
()
...
...
run_server.py
View file @
bf9bb1b9
...
@@ -45,7 +45,7 @@ def start_beat():
...
@@ -45,7 +45,7 @@ def start_beat():
os
.
chdir
(
APPS_DIR
)
os
.
chdir
(
APPS_DIR
)
os
.
environ
.
setdefault
(
'PYTHONOPTIMIZE'
,
'1'
)
os
.
environ
.
setdefault
(
'PYTHONOPTIMIZE'
,
'1'
)
scheduler
=
"django_celery_beat.schedulers:DatabaseScheduler"
scheduler
=
"django_celery_beat.schedulers:DatabaseScheduler"
cmd
=
'celery -A common beat -l {} --scheduler {} --max-interval
30
'
.
format
(
LOG_LEVEL
,
scheduler
)
cmd
=
'celery -A common beat -l {} --scheduler {} --max-interval
5
'
.
format
(
LOG_LEVEL
,
scheduler
)
subprocess
.
call
(
cmd
,
shell
=
True
)
subprocess
.
call
(
cmd
,
shell
=
True
)
...
...
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