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
a609f170
Unverified
Commit
a609f170
authored
6 years ago
by
老广
Committed by
GitHub
6 years ago
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[Update] Stash it (#2197)
* [Update] Stash it * [Bugfix] 修复错误 * [Update] 修改jms
parent
1293d721
Show whitespace changes
Inline
Side-by-side
Showing
23 changed files
with
358 additions
and
330 deletions
+358
-330
admin_user.py
apps/assets/api/admin_user.py
+22
-3
asset.py
apps/assets/api/asset.py
+3
-3
node.py
apps/assets/api/node.py
+2
-2
system_user.py
apps/assets/api/system_user.py
+8
-7
user.py
apps/assets/forms/user.py
+3
-3
asset.py
apps/assets/models/asset.py
+49
-64
base.py
apps/assets/models/base.py
+7
-0
user.py
apps/assets/models/user.py
+72
-27
asset.py
apps/assets/serializers/asset.py
+8
-2
system_user.py
apps/assets/serializers/system_user.py
+8
-5
signals_handler.py
apps/assets/signals_handler.py
+3
-3
tasks.py
apps/assets/tasks.py
+106
-177
admin_user_assets.html
apps/assets/templates/assets/admin_user_assets.html
+34
-11
system_user_asset.html
apps/assets/templates/assets/system_user_asset.html
+5
-3
system_user_list.html
apps/assets/templates/assets/system_user_list.html
+1
-1
api_urls.py
apps/assets/urls/api_urls.py
+8
-6
admin_user.py
apps/assets/views/admin_user.py
+1
-1
conf.py
apps/jumpserver/conf.py
+2
-1
django.mo
apps/locale/zh/LC_MESSAGES/django.mo
+0
-0
django.po
apps/locale/zh/LC_MESSAGES/django.po
+9
-9
adhoc.py
apps/ops/api/adhoc.py
+3
-1
adhoc.py
apps/ops/views/adhoc.py
+1
-1
user.py
apps/users/api/user.py
+3
-0
No files found.
apps/assets/api/admin_user.py
View file @
a609f170
...
...
@@ -14,6 +14,7 @@
# limitations under the License.
from
django.db
import
transaction
from
django.shortcuts
import
get_object_or_404
from
rest_framework
import
generics
from
rest_framework.response
import
Response
from
rest_framework_bulk
import
BulkModelViewSet
...
...
@@ -24,13 +25,14 @@ from common.utils import get_logger
from
..hands
import
IsOrgAdmin
from
..models
import
AdminUser
,
Asset
from
..
import
serializers
from
..tasks
import
test_admin_user_connect
abil
ity_manual
from
..tasks
import
test_admin_user_connect
iv
ity_manual
logger
=
get_logger
(
__file__
)
__all__
=
[
'AdminUserViewSet'
,
'ReplaceNodesAdminUserApi'
,
'AdminUserTestConnectiveApi'
,
'AdminUserAuthApi'
,
'AdminUserAssetsListView'
,
]
...
...
@@ -81,12 +83,29 @@ class ReplaceNodesAdminUserApi(generics.UpdateAPIView):
class
AdminUserTestConnectiveApi
(
generics
.
RetrieveAPIView
):
"""
Test asset admin user connectivity
Test asset admin user
assets_
connectivity
"""
queryset
=
AdminUser
.
objects
.
all
()
permission_classes
=
(
IsOrgAdmin
,)
def
retrieve
(
self
,
request
,
*
args
,
**
kwargs
):
admin_user
=
self
.
get_object
()
task
=
test_admin_user_connect
abil
ity_manual
.
delay
(
admin_user
)
task
=
test_admin_user_connect
iv
ity_manual
.
delay
(
admin_user
)
return
Response
({
"task"
:
task
.
id
})
class
AdminUserAssetsListView
(
generics
.
ListAPIView
):
permission_classes
=
(
IsOrgAdmin
,)
serializer_class
=
serializers
.
AssetSimpleSerializer
pagination_class
=
LimitOffsetPagination
filter_fields
=
(
"hostname"
,
"ip"
)
http_method_names
=
[
'get'
]
search_fields
=
filter_fields
def
get_object
(
self
):
pk
=
self
.
kwargs
.
get
(
'pk'
)
return
get_object_or_404
(
AdminUser
,
pk
=
pk
)
def
get_queryset
(
self
):
admin_user
=
self
.
get_object
()
return
admin_user
.
get_related_assets
()
This diff is collapsed.
Click to expand it.
apps/assets/api/asset.py
View file @
a609f170
...
...
@@ -17,7 +17,7 @@ from common.permissions import IsOrgAdmin, IsOrgAdminOrAppUser
from
..models
import
Asset
,
AdminUser
,
Node
from
..
import
serializers
from
..tasks
import
update_asset_hardware_info_manual
,
\
test_asset_connect
abil
ity_manual
test_asset_connect
iv
ity_manual
from
..utils
import
LabelFilter
...
...
@@ -109,7 +109,7 @@ class AssetRefreshHardwareApi(generics.RetrieveAPIView):
class
AssetAdminUserTestApi
(
generics
.
RetrieveAPIView
):
"""
Test asset admin user connectivity
Test asset admin user
assets_
connectivity
"""
queryset
=
Asset
.
objects
.
all
()
permission_classes
=
(
IsOrgAdmin
,)
...
...
@@ -117,7 +117,7 @@ class AssetAdminUserTestApi(generics.RetrieveAPIView):
def
retrieve
(
self
,
request
,
*
args
,
**
kwargs
):
asset_id
=
kwargs
.
get
(
'pk'
)
asset
=
get_object_or_404
(
Asset
,
pk
=
asset_id
)
task
=
test_asset_connect
abil
ity_manual
.
delay
(
asset
)
task
=
test_asset_connect
iv
ity_manual
.
delay
(
asset
)
return
Response
({
"task"
:
task
.
id
})
...
...
This diff is collapsed.
Click to expand it.
apps/assets/api/node.py
View file @
a609f170
...
...
@@ -24,7 +24,7 @@ from common.utils import get_logger, get_object_or_none
from
common.tree
import
TreeNodeSerializer
from
..hands
import
IsOrgAdmin
from
..models
import
Node
from
..tasks
import
update_assets_hardware_info_util
,
test_asset_connect
abil
ity_util
from
..tasks
import
update_assets_hardware_info_util
,
test_asset_connect
iv
ity_util
from
..
import
serializers
...
...
@@ -273,5 +273,5 @@ class TestNodeConnectiveApi(APIView):
assets
=
node
.
assets
.
all
()
# task_name = _("测试节点下资产是否可连接: {}".format(node.name))
task_name
=
_
(
"Test if the assets under the node are connectable: {}"
.
format
(
node
.
name
))
task
=
test_asset_connect
abil
ity_util
.
delay
(
assets
,
task_name
=
task_name
)
task
=
test_asset_connect
iv
ity_util
.
delay
(
assets
,
task_name
=
task_name
)
return
Response
({
"task"
:
task
.
id
})
This diff is collapsed.
Click to expand it.
apps/assets/api/system_user.py
View file @
a609f170
...
...
@@ -24,8 +24,8 @@ from common.permissions import IsOrgAdmin, IsOrgAdminOrAppUser
from
..models
import
SystemUser
,
Asset
from
..
import
serializers
from
..tasks
import
push_system_user_to_assets_manual
,
\
test_system_user_connect
abil
ity_manual
,
push_system_user_a_asset_manual
,
\
test_system_user_connect
abil
ity_a_asset
test_system_user_connect
iv
ity_manual
,
push_system_user_a_asset_manual
,
\
test_system_user_connect
iv
ity_a_asset
logger
=
get_logger
(
__file__
)
...
...
@@ -33,7 +33,7 @@ __all__ = [
'SystemUserViewSet'
,
'SystemUserAuthInfoApi'
,
'SystemUserPushApi'
,
'SystemUserTestConnectiveApi'
,
'SystemUserAssetsListView'
,
'SystemUserPushToAssetApi'
,
'SystemUserTestAssetConnect
abil
ityApi'
,
'SystemUserCommandFilterRuleListApi'
,
'SystemUserTestAssetConnect
iv
ityApi'
,
'SystemUserCommandFilterRuleListApi'
,
]
...
...
@@ -93,15 +93,16 @@ class SystemUserTestConnectiveApi(generics.RetrieveAPIView):
def
retrieve
(
self
,
request
,
*
args
,
**
kwargs
):
system_user
=
self
.
get_object
()
task
=
test_system_user_connect
abil
ity_manual
.
delay
(
system_user
)
task
=
test_system_user_connect
iv
ity_manual
.
delay
(
system_user
)
return
Response
({
"task"
:
task
.
id
})
class
SystemUserAssetsListView
(
generics
.
ListAPIView
):
permission_classes
=
(
IsOrgAdmin
,)
serializer_class
=
serializers
.
AssetSerializer
serializer_class
=
serializers
.
AssetS
impleS
erializer
pagination_class
=
LimitOffsetPagination
filter_fields
=
(
"hostname"
,
"ip"
)
http_method_names
=
[
'get'
]
search_fields
=
filter_fields
def
get_object
(
self
):
...
...
@@ -125,7 +126,7 @@ class SystemUserPushToAssetApi(generics.RetrieveAPIView):
return
Response
({
"task"
:
task
.
id
})
class
SystemUserTestAssetConnect
abil
ityApi
(
generics
.
RetrieveAPIView
):
class
SystemUserTestAssetConnect
iv
ityApi
(
generics
.
RetrieveAPIView
):
queryset
=
SystemUser
.
objects
.
all
()
permission_classes
=
(
IsOrgAdmin
,)
...
...
@@ -133,7 +134,7 @@ class SystemUserTestAssetConnectabilityApi(generics.RetrieveAPIView):
system_user
=
self
.
get_object
()
asset_id
=
self
.
kwargs
.
get
(
'aid'
)
asset
=
get_object_or_404
(
Asset
,
id
=
asset_id
)
task
=
test_system_user_connect
abil
ity_a_asset
.
delay
(
system_user
,
asset
)
task
=
test_system_user_connect
iv
ity_a_asset
.
delay
(
system_user
,
asset
)
return
Response
({
"task"
:
task
.
id
})
...
...
This diff is collapsed.
Click to expand it.
apps/assets/forms/user.py
View file @
a609f170
...
...
@@ -99,8 +99,8 @@ class SystemUserForm(OrgModelForm, PasswordAndKeyAuthForm):
auto_generate_key
=
self
.
cleaned_data
.
get
(
'auto_generate_key'
,
False
)
private_key
,
public_key
=
super
()
.
gen_keys
()
if
login_mode
==
SystemUser
.
MANUAL_LOGIN
or
\
protocol
in
[
SystemUser
.
RDP_PROTOCOL
,
SystemUser
.
TELNET_PROTOCOL
]:
if
login_mode
==
SystemUser
.
LOGIN_MANUAL
or
\
protocol
in
[
SystemUser
.
PROTOCOL_RDP
,
SystemUser
.
PROTOCOL_TELNET
]:
system_user
.
auto_push
=
0
auto_generate_key
=
False
system_user
.
save
()
...
...
@@ -124,7 +124,7 @@ class SystemUserForm(OrgModelForm, PasswordAndKeyAuthForm):
validated
=
super
()
.
is_valid
()
username
=
self
.
cleaned_data
.
get
(
'username'
)
login_mode
=
self
.
cleaned_data
.
get
(
'login_mode'
)
if
login_mode
==
SystemUser
.
AUTO_LOGIN
and
not
username
:
if
login_mode
==
SystemUser
.
LOGIN_AUTO
and
not
username
:
self
.
add_error
(
"username"
,
_
(
'* Automatic login mode,'
' must fill in the username.'
)
...
...
This diff is collapsed.
Click to expand it.
apps/assets/models/asset.py
View file @
a609f170
...
...
@@ -13,7 +13,6 @@ from django.db.models import Q
from
django.utils.translation
import
ugettext_lazy
as
_
from
django.core.cache
import
cache
from
..const
import
ASSET_ADMIN_CONN_CACHE_KEY
from
.user
import
AdminUser
,
SystemUser
from
orgs.mixins
import
OrgModelMixin
,
OrgManager
...
...
@@ -75,63 +74,48 @@ class Asset(OrgModelMixin):
protocol
=
models
.
CharField
(
max_length
=
128
,
default
=
SSH_PROTOCOL
,
choices
=
PROTOCOL_CHOICES
,
verbose_name
=
_
(
'Protocol'
))
port
=
models
.
IntegerField
(
default
=
22
,
verbose_name
=
_
(
'Port'
))
platform
=
models
.
CharField
(
max_length
=
128
,
choices
=
PLATFORM_CHOICES
,
default
=
'Linux'
,
verbose_name
=
_
(
'Platform'
))
domain
=
models
.
ForeignKey
(
"assets.Domain"
,
null
=
True
,
blank
=
True
,
related_name
=
'assets'
,
verbose_name
=
_
(
"Domain"
),
on_delete
=
models
.
SET_NULL
)
nodes
=
models
.
ManyToManyField
(
'assets.Node'
,
default
=
default_node
,
related_name
=
'assets'
,
verbose_name
=
_
(
"Nodes"
))
domain
=
models
.
ForeignKey
(
"assets.Domain"
,
null
=
True
,
blank
=
True
,
related_name
=
'assets'
,
verbose_name
=
_
(
"Domain"
),
on_delete
=
models
.
SET_NULL
)
nodes
=
models
.
ManyToManyField
(
'assets.Node'
,
default
=
default_node
,
related_name
=
'assets'
,
verbose_name
=
_
(
"Nodes"
))
is_active
=
models
.
BooleanField
(
default
=
True
,
verbose_name
=
_
(
'Is active'
))
# Auth
admin_user
=
models
.
ForeignKey
(
'assets.AdminUser'
,
on_delete
=
models
.
PROTECT
,
null
=
True
,
verbose_name
=
_
(
"Admin user"
))
admin_user
=
models
.
ForeignKey
(
'assets.AdminUser'
,
on_delete
=
models
.
PROTECT
,
null
=
True
,
verbose_name
=
_
(
"Admin user"
))
# Some information
public_ip
=
models
.
GenericIPAddressField
(
max_length
=
32
,
blank
=
True
,
null
=
True
,
verbose_name
=
_
(
'Public IP'
))
number
=
models
.
CharField
(
max_length
=
32
,
null
=
True
,
blank
=
True
,
verbose_name
=
_
(
'Asset number'
))
# Collect
vendor
=
models
.
CharField
(
max_length
=
64
,
null
=
True
,
blank
=
True
,
verbose_name
=
_
(
'Vendor'
))
model
=
models
.
CharField
(
max_length
=
54
,
null
=
True
,
blank
=
True
,
verbose_name
=
_
(
'Model'
))
sn
=
models
.
CharField
(
max_length
=
128
,
null
=
True
,
blank
=
True
,
verbose_name
=
_
(
'Serial number'
))
cpu_model
=
models
.
CharField
(
max_length
=
64
,
null
=
True
,
blank
=
True
,
verbose_name
=
_
(
'CPU model'
))
vendor
=
models
.
CharField
(
max_length
=
64
,
null
=
True
,
blank
=
True
,
verbose_name
=
_
(
'Vendor'
))
model
=
models
.
CharField
(
max_length
=
54
,
null
=
True
,
blank
=
True
,
verbose_name
=
_
(
'Model'
))
sn
=
models
.
CharField
(
max_length
=
128
,
null
=
True
,
blank
=
True
,
verbose_name
=
_
(
'Serial number'
))
cpu_model
=
models
.
CharField
(
max_length
=
64
,
null
=
True
,
blank
=
True
,
verbose_name
=
_
(
'CPU model'
))
cpu_count
=
models
.
IntegerField
(
null
=
True
,
verbose_name
=
_
(
'CPU count'
))
cpu_cores
=
models
.
IntegerField
(
null
=
True
,
verbose_name
=
_
(
'CPU cores'
))
cpu_vcpus
=
models
.
IntegerField
(
null
=
True
,
verbose_name
=
_
(
'CPU vcpus'
))
memory
=
models
.
CharField
(
max_length
=
64
,
null
=
True
,
blank
=
True
,
verbose_name
=
_
(
'Memory'
))
disk_total
=
models
.
CharField
(
max_length
=
1024
,
null
=
True
,
blank
=
True
,
verbose_name
=
_
(
'Disk total'
))
disk_info
=
models
.
CharField
(
max_length
=
1024
,
null
=
True
,
blank
=
True
,
verbose_name
=
_
(
'Disk info'
))
os
=
models
.
CharField
(
max_length
=
128
,
null
=
True
,
blank
=
True
,
verbose_name
=
_
(
'OS'
))
os_version
=
models
.
CharField
(
max_length
=
16
,
null
=
True
,
blank
=
True
,
verbose_name
=
_
(
'OS version'
))
os_arch
=
models
.
CharField
(
max_length
=
16
,
blank
=
True
,
null
=
True
,
verbose_name
=
_
(
'OS arch'
))
hostname_raw
=
models
.
CharField
(
max_length
=
128
,
blank
=
True
,
null
=
True
,
verbose_name
=
_
(
'Hostname raw'
))
labels
=
models
.
ManyToManyField
(
'assets.Label'
,
blank
=
True
,
related_name
=
'assets'
,
verbose_name
=
_
(
"Labels"
))
created_by
=
models
.
CharField
(
max_length
=
32
,
null
=
True
,
blank
=
True
,
verbose_name
=
_
(
'Created by'
))
date_created
=
models
.
DateTimeField
(
auto_now_add
=
True
,
null
=
True
,
blank
=
True
,
verbose_name
=
_
(
'Date created'
))
comment
=
models
.
TextField
(
max_length
=
128
,
default
=
''
,
blank
=
True
,
verbose_name
=
_
(
'Comment'
))
memory
=
models
.
CharField
(
max_length
=
64
,
null
=
True
,
blank
=
True
,
verbose_name
=
_
(
'Memory'
))
disk_total
=
models
.
CharField
(
max_length
=
1024
,
null
=
True
,
blank
=
True
,
verbose_name
=
_
(
'Disk total'
))
disk_info
=
models
.
CharField
(
max_length
=
1024
,
null
=
True
,
blank
=
True
,
verbose_name
=
_
(
'Disk info'
))
os
=
models
.
CharField
(
max_length
=
128
,
null
=
True
,
blank
=
True
,
verbose_name
=
_
(
'OS'
))
os_version
=
models
.
CharField
(
max_length
=
16
,
null
=
True
,
blank
=
True
,
verbose_name
=
_
(
'OS version'
))
os_arch
=
models
.
CharField
(
max_length
=
16
,
blank
=
True
,
null
=
True
,
verbose_name
=
_
(
'OS arch'
))
hostname_raw
=
models
.
CharField
(
max_length
=
128
,
blank
=
True
,
null
=
True
,
verbose_name
=
_
(
'Hostname raw'
))
labels
=
models
.
ManyToManyField
(
'assets.Label'
,
blank
=
True
,
related_name
=
'assets'
,
verbose_name
=
_
(
"Labels"
))
created_by
=
models
.
CharField
(
max_length
=
32
,
null
=
True
,
blank
=
True
,
verbose_name
=
_
(
'Created by'
))
date_created
=
models
.
DateTimeField
(
auto_now_add
=
True
,
null
=
True
,
blank
=
True
,
verbose_name
=
_
(
'Date created'
))
comment
=
models
.
TextField
(
max_length
=
128
,
default
=
''
,
blank
=
True
,
verbose_name
=
_
(
'Comment'
))
objects
=
OrgManager
.
from_queryset
(
AssetQuerySet
)()
CONNECTIVITY_CACHE_KEY
=
'_JMS_ASSET_CONNECTIVITY_{}'
UNREACHABLE
,
REACHABLE
,
UNKNOWN
=
range
(
0
,
3
)
CONNECTIVITY_CHOICES
=
(
(
UNREACHABLE
,
_
(
"Unreachable"
)),
(
REACHABLE
,
_
(
'Reachable'
)),
(
UNKNOWN
,
_
(
"Unknown"
)),
)
def
__str__
(
self
):
return
'{0.hostname}({0.ip})'
.
format
(
self
)
...
...
@@ -197,25 +181,17 @@ class Asset(OrgModelMixin):
return
''
@property
def
is_connective
(
self
):
def
connectivity
(
self
):
if
not
self
.
is_unixlike
():
return
True
val
=
cache
.
get
(
ASSET_ADMIN_CONN_CACHE_KEY
.
format
(
self
.
hostname
))
if
val
==
1
:
return
True
else
:
return
False
return
self
.
UNKNOWN
key
=
self
.
CONNECTIVITY_CACHE_KEY
.
format
(
str
(
self
.
id
))
cached
=
cache
.
get
(
key
,
None
)
return
cached
if
cached
is
not
None
else
self
.
UNKNOWN
def
to_json
(
self
):
info
=
{
'id'
:
self
.
id
,
'hostname'
:
self
.
hostname
,
'ip'
:
self
.
ip
,
'port'
:
self
.
port
,
}
if
self
.
domain
and
self
.
domain
.
gateway_set
.
all
():
info
[
"gateways"
]
=
[
d
.
id
for
d
in
self
.
domain
.
gateway_set
.
all
()]
return
info
@connectivity.setter
def
connectivity
(
self
,
value
):
key
=
self
.
CONNECTIVITY_CACHE_KEY
.
format
(
str
(
self
.
id
))
cache
.
set
(
key
,
value
,
3600
*
2
)
def
get_auth_info
(
self
):
if
self
.
admin_user
:
...
...
@@ -236,11 +212,20 @@ class Asset(OrgModelMixin):
fake_node
.
is_node
=
False
return
fake_node
def
to_json
(
self
):
info
=
{
'id'
:
self
.
id
,
'hostname'
:
self
.
hostname
,
'ip'
:
self
.
ip
,
'port'
:
self
.
port
,
}
if
self
.
domain
and
self
.
domain
.
gateway_set
.
all
():
info
[
"gateways"
]
=
[
d
.
id
for
d
in
self
.
domain
.
gateway_set
.
all
()]
return
info
def
_to_secret_json
(
self
):
"""
Ansible use it create inventory, First using asset user,
otherwise using cluster admin user
Ansible use it create inventory
Todo: May be move to ops implements it
"""
data
=
self
.
to_json
()
...
...
This diff is collapsed.
Click to expand it.
apps/assets/models/base.py
View file @
a609f170
...
...
@@ -29,6 +29,13 @@ class AssetUser(OrgModelMixin):
date_updated
=
models
.
DateTimeField
(
auto_now
=
True
)
created_by
=
models
.
CharField
(
max_length
=
128
,
null
=
True
,
verbose_name
=
_
(
'Created by'
))
UNREACHABLE
,
REACHABLE
,
UNKNOWN
=
range
(
0
,
3
)
CONNECTIVITY_CHOICES
=
(
(
UNREACHABLE
,
_
(
"Unreachable"
)),
(
REACHABLE
,
_
(
'Reachable'
)),
(
UNKNOWN
,
_
(
"Unknown"
)),
)
@property
def
password
(
self
):
if
self
.
_password
:
...
...
This diff is collapsed.
Click to expand it.
apps/assets/models/user.py
View file @
a609f170
...
...
@@ -14,7 +14,7 @@ from ..const import SYSTEM_USER_CONN_CACHE_KEY
from
.base
import
AssetUser
__all__
=
[
'AdminUser'
,
'SystemUser'
,
]
__all__
=
[
'AdminUser'
,
'SystemUser'
]
logger
=
logging
.
getLogger
(
__name__
)
signer
=
get_signer
()
...
...
@@ -31,6 +31,7 @@ class AdminUser(AssetUser):
become_method
=
models
.
CharField
(
choices
=
BECOME_METHOD_CHOICES
,
default
=
'sudo'
,
max_length
=
4
)
become_user
=
models
.
CharField
(
default
=
'root'
,
max_length
=
64
)
_become_pass
=
models
.
CharField
(
default
=
''
,
max_length
=
128
)
CONNECTIVE_CACHE_KEY
=
'_JMS_ADMIN_USER_CONNECTIVE_{}'
def
__str__
(
self
):
return
self
.
name
...
...
@@ -67,6 +68,23 @@ class AdminUser(AssetUser):
def
assets_amount
(
self
):
return
self
.
get_related_assets
()
.
count
()
@property
def
connectivity
(
self
):
from
.asset
import
Asset
assets
=
self
.
get_related_assets
()
.
values_list
(
'id'
,
'hostname'
,
flat
=
True
)
data
=
{
'unreachable'
:
[],
'reachable'
:
[],
}
for
asset_id
,
hostname
in
assets
:
key
=
Asset
.
CONNECTIVITY_CACHE_KEY
.
format
(
str
(
self
.
id
))
value
=
cache
.
get
(
key
,
Asset
.
UNKNOWN
)
if
value
==
Asset
.
REACHABLE
:
data
[
'reachable'
]
.
append
(
hostname
)
elif
value
==
Asset
.
UNREACHABLE
:
data
[
'unreachable'
]
.
append
(
hostname
)
return
data
class
Meta
:
ordering
=
[
'name'
]
unique_together
=
[(
'name'
,
'org_id'
)]
...
...
@@ -94,34 +112,34 @@ class AdminUser(AssetUser):
class
SystemUser
(
AssetUser
):
SSH_PROTOCOL
=
'ssh'
RDP_PROTOCOL
=
'rdp'
TELNET_PROTOCOL
=
'telnet'
PROTOCOL_SSH
=
'ssh'
PROTOCOL_RDP
=
'rdp'
PROTOCOL_TELNET
=
'telnet'
PROTOCOL_CHOICES
=
(
(
SSH_PROTOCOL
,
'ssh'
),
(
RDP_PROTOCOL
,
'rdp'
),
(
TELNET_PROTOCOL
,
'telnet (beta)'
),
(
PROTOCOL_SSH
,
'ssh'
),
(
PROTOCOL_RDP
,
'rdp'
),
(
PROTOCOL_TELNET
,
'telnet (beta)'
),
)
AUTO_LOGIN
=
'auto'
MANUAL_LOGIN
=
'manual'
LOGIN_AUTO
=
'auto'
LOGIN_MANUAL
=
'manual'
LOGIN_MODE_CHOICES
=
(
(
AUTO_LOGIN
,
_
(
'Automatic login'
)),
(
MANUAL_LOGIN
,
_
(
'Manually login'
))
(
LOGIN_AUTO
,
_
(
'Automatic login'
)),
(
LOGIN_MANUAL
,
_
(
'Manually login'
))
)
nodes
=
models
.
ManyToManyField
(
'assets.Node'
,
blank
=
True
,
verbose_name
=
_
(
"Nodes"
))
assets
=
models
.
ManyToManyField
(
'assets.Asset'
,
blank
=
True
,
verbose_name
=
_
(
"Assets"
))
priority
=
models
.
IntegerField
(
default
=
20
,
verbose_name
=
_
(
"Priority"
),
validators
=
[
MinValueValidator
(
1
),
MaxValueValidator
(
100
)])
priority
=
models
.
IntegerField
(
default
=
20
,
verbose_name
=
_
(
"Priority"
),
validators
=
[
MinValueValidator
(
1
),
MaxValueValidator
(
100
)])
protocol
=
models
.
CharField
(
max_length
=
16
,
choices
=
PROTOCOL_CHOICES
,
default
=
'ssh'
,
verbose_name
=
_
(
'Protocol'
))
auto_push
=
models
.
BooleanField
(
default
=
True
,
verbose_name
=
_
(
'Auto push'
))
sudo
=
models
.
TextField
(
default
=
'/bin/whoami'
,
verbose_name
=
_
(
'Sudo'
))
shell
=
models
.
CharField
(
max_length
=
64
,
default
=
'/bin/bash'
,
verbose_name
=
_
(
'Shell'
))
login_mode
=
models
.
CharField
(
choices
=
LOGIN_MODE_CHOICES
,
default
=
AUTO_LOGIN
,
max_length
=
10
,
verbose_name
=
_
(
'Login mode'
))
login_mode
=
models
.
CharField
(
choices
=
LOGIN_MODE_CHOICES
,
default
=
LOGIN_AUTO
,
max_length
=
10
,
verbose_name
=
_
(
'Login mode'
))
cmd_filters
=
models
.
ManyToManyField
(
'CommandFilter'
,
related_name
=
'system_users'
,
verbose_name
=
_
(
"Command filter"
),
blank
=
True
)
cache_key
=
"__SYSTEM_USER_CACHED_{}"
SYSTEM_USER_CACHE_KEY
=
"__SYSTEM_USER_CACHED_{}"
CONNECTIVE_CACHE_KEY
=
'_JMS_SYSTEM_USER_CONNECTIVE_{}'
def
__str__
(
self
):
return
'{0.name}({0.username})'
.
format
(
self
)
...
...
@@ -136,34 +154,61 @@ class SystemUser(AssetUser):
'auto_push'
:
self
.
auto_push
,
}
def
get_assets
(
self
):
def
get_
related_
assets
(
self
):
assets
=
set
(
self
.
assets
.
all
())
return
assets
@property
def
assets_connective
(
self
):
_result
=
cache
.
get
(
SYSTEM_USER_CONN_CACHE_KEY
.
format
(
self
.
name
),
{})
return
_result
def
connectivity
(
self
):
cache_key
=
self
.
CONNECTIVE_CACHE_KEY
.
format
(
str
(
self
.
id
))
value
=
cache
.
get
(
cache_key
,
None
)
if
not
value
or
'unreachable'
not
in
value
:
return
{
'unreachable'
:
[],
'reachable'
:
[]}
else
:
return
value
@connectivity.setter
def
connectivity
(
self
,
value
):
data
=
self
.
connectivity
unreachable
=
data
[
'unreachable'
]
reachable
=
data
[
'reachable'
]
for
host
in
value
.
get
(
'dark'
,
{})
.
keys
():
if
host
not
in
unreachable
:
unreachable
.
append
(
host
)
if
host
in
reachable
:
reachable
.
remove
(
host
)
for
host
in
value
.
get
(
'contacted'
):
if
host
not
in
reachable
:
reachable
.
append
(
host
)
if
host
in
unreachable
:
unreachable
.
remove
(
host
)
cache_key
=
self
.
CONNECTIVE_CACHE_KEY
.
format
(
str
(
self
.
id
))
cache
.
set
(
cache_key
,
data
,
3600
)
@property
def
assets_unreachable
(
self
):
return
self
.
connectivity
.
get
(
'unreachable'
)
@property
def
unreachable_assets
(
self
):
return
list
(
self
.
assets_connective
.
get
(
'dark'
,
{})
.
keys
()
)
def
assets_reachable
(
self
):
return
self
.
connectivity
.
get
(
'reachable'
)
@property
def
reachable_assets
(
self
):
return
self
.
assets_connective
.
get
(
'contacted'
,
[]
)
def
login_mode_display
(
self
):
return
self
.
get_login_mode_display
(
)
def
is_need_push
(
self
):
if
self
.
auto_push
and
self
.
protocol
==
self
.
__class__
.
SSH_PROTOCOL
:
if
self
.
auto_push
and
self
.
protocol
==
self
.
PROTOCOL_SSH
:
return
True
else
:
return
False
def
set_cache
(
self
):
cache
.
set
(
self
.
cache_key
.
format
(
self
.
id
),
self
,
3600
)
cache
.
set
(
self
.
SYSTEM_USER_CACHE_KEY
.
format
(
self
.
id
),
self
,
3600
)
def
expire_cache
(
self
):
cache
.
delete
(
self
.
cache_key
.
format
(
self
.
id
))
cache
.
delete
(
self
.
SYSTEM_USER_CACHE_KEY
.
format
(
self
.
id
))
@property
def
cmd_filter_rules
(
self
):
...
...
@@ -184,7 +229,7 @@ class SystemUser(AssetUser):
@classmethod
def
get_system_user_by_id_or_cached
(
cls
,
sid
):
cached
=
cache
.
get
(
cls
.
cache_key
.
format
(
sid
))
cached
=
cache
.
get
(
cls
.
SYSTEM_USER_CACHE_KEY
.
format
(
sid
))
if
cached
:
return
cached
try
:
...
...
This diff is collapsed.
Click to expand it.
apps/assets/serializers/asset.py
View file @
a609f170
...
...
@@ -9,7 +9,7 @@ from .system_user import AssetSystemUserSerializer
__all__
=
[
'AssetSerializer'
,
'AssetGrantedSerializer'
,
'MyAssetGrantedSerializer'
,
'AssetAsNodeSerializer'
,
'AssetAsNodeSerializer'
,
'AssetSimpleSerializer'
,
]
...
...
@@ -33,7 +33,7 @@ class AssetSerializer(BulkSerializerMixin, serializers.ModelSerializer):
def
get_field_names
(
self
,
declared_fields
,
info
):
fields
=
super
()
.
get_field_names
(
declared_fields
,
info
)
fields
.
extend
([
'hardware_info'
,
'
is_connective
'
,
'org_name'
'hardware_info'
,
'
connectivity
'
,
'org_name'
])
return
fields
...
...
@@ -78,3 +78,9 @@ class MyAssetGrantedSerializer(AssetGrantedSerializer):
"is_active"
,
"system_users_join"
,
"org_name"
,
"os"
,
"platform"
,
"comment"
,
"org_id"
,
"protocol"
)
class
AssetSimpleSerializer
(
serializers
.
ModelSerializer
):
class
Meta
:
model
=
Asset
fields
=
[
'id'
,
'hostname'
,
'port'
,
'ip'
,
'connectivity'
]
This diff is collapsed.
Click to expand it.
apps/assets/serializers/system_user.py
View file @
a609f170
from
rest_framework
import
serializers
from
..models
import
SystemUser
from
..models
import
SystemUser
,
Asset
from
.base
import
AuthSerializer
...
...
@@ -21,17 +21,17 @@ class SystemUserSerializer(serializers.ModelSerializer):
def
get_field_names
(
self
,
declared_fields
,
info
):
fields
=
super
(
SystemUserSerializer
,
self
)
.
get_field_names
(
declared_fields
,
info
)
fields
.
extend
([
'
get_
login_mode_display'
,
'login_mode_display'
,
])
return
fields
@staticmethod
def
get_unreachable_assets
(
obj
):
return
obj
.
unreachable_assets
return
obj
.
assets_unreachable
@staticmethod
def
get_reachable_assets
(
obj
):
return
obj
.
reachable_assets
return
obj
.
assets_reachable
def
get_unreachable_amount
(
self
,
obj
):
return
len
(
self
.
get_unreachable_assets
(
obj
))
...
...
@@ -41,7 +41,7 @@ class SystemUserSerializer(serializers.ModelSerializer):
@staticmethod
def
get_assets_amount
(
obj
):
return
len
(
obj
.
get_assets
())
return
len
(
obj
.
get_
related_
assets
())
class
SystemUserAuthSerializer
(
AuthSerializer
):
...
...
@@ -76,3 +76,6 @@ class SystemUserSimpleSerializer(serializers.ModelSerializer):
class
Meta
:
model
=
SystemUser
fields
=
(
'id'
,
'name'
,
'username'
)
This diff is collapsed.
Click to expand it.
apps/assets/signals_handler.py
View file @
a609f170
...
...
@@ -7,7 +7,7 @@ from django.dispatch import receiver
from
common.utils
import
get_logger
from
.models
import
Asset
,
SystemUser
,
Node
from
.tasks
import
update_assets_hardware_info_util
,
\
test_asset_connect
abil
ity_util
,
push_system_user_to_assets
test_asset_connect
iv
ity_util
,
push_system_user_to_assets
logger
=
get_logger
(
__file__
)
...
...
@@ -19,8 +19,8 @@ def update_asset_hardware_info_on_created(asset):
def
test_asset_conn_on_created
(
asset
):
logger
.
debug
(
"Test asset `{}` connect
abil
ity"
.
format
(
asset
))
test_asset_connect
abil
ity_util
.
delay
([
asset
])
logger
.
debug
(
"Test asset `{}` connect
iv
ity"
.
format
(
asset
))
test_asset_connect
iv
ity_util
.
delay
([
asset
])
def
set_asset_root_node
(
asset
):
...
...
This diff is collapsed.
Click to expand it.
apps/assets/tasks.py
View file @
a609f170
...
...
@@ -26,6 +26,23 @@ disk_pattern = re.compile(r'^hd|sd|xvd|vd')
PERIOD_TASK
=
os
.
environ
.
get
(
"PERIOD_TASK"
,
"off"
)
def
clean_hosts
(
assets
):
clean_assets
=
[]
for
asset
in
assets
:
if
not
asset
.
is_active
:
msg
=
_
(
"Asset has been disabled, skipped: {}"
)
.
format
(
asset
)
logger
.
info
(
msg
)
continue
if
not
asset
.
support_ansible
():
msg
=
_
(
"Asset may not be support ansible, skipped: {}"
)
.
format
(
asset
)
logger
.
info
(
msg
)
continue
clean_assets
.
append
(
asset
)
if
not
clean_assets
:
logger
.
info
(
_
(
"No assets matched, stop task"
))
return
clean_assets
@shared_task
def
set_assets_hardware_info
(
assets
,
result
,
**
kwargs
):
"""
...
...
@@ -60,9 +77,12 @@ def set_assets_hardware_info(assets, result, **kwargs):
___cpu_model
=
'Unknown'
___cpu_model
=
___cpu_model
[:
64
]
___cpu_count
=
info
.
get
(
'ansible_processor_count'
,
0
)
___cpu_cores
=
info
.
get
(
'ansible_processor_cores'
,
None
)
or
len
(
info
.
get
(
'ansible_processor'
,
[]))
___cpu_cores
=
info
.
get
(
'ansible_processor_cores'
,
None
)
or
\
len
(
info
.
get
(
'ansible_processor'
,
[]))
___cpu_vcpus
=
info
.
get
(
'ansible_processor_vcpus'
,
0
)
___memory
=
'
%
s
%
s'
%
capacity_convert
(
'{} MB'
.
format
(
info
.
get
(
'ansible_memtotal_mb'
)))
___memory
=
'
%
s
%
s'
%
capacity_convert
(
'{} MB'
.
format
(
info
.
get
(
'ansible_memtotal_mb'
))
)
disk_info
=
{}
for
dev
,
dev_info
in
info
.
get
(
'ansible_devices'
,
{})
.
items
():
if
disk_pattern
.
match
(
dev
)
and
dev_info
[
'removable'
]
==
'0'
:
...
...
@@ -96,19 +116,8 @@ def update_assets_hardware_info_util(assets, task_name=None):
if
task_name
is
None
:
task_name
=
_
(
"Update some assets hardware info"
)
tasks
=
const
.
UPDATE_ASSETS_HARDWARE_TASKS
hosts
=
[]
for
asset
in
assets
:
if
not
asset
.
is_active
:
msg
=
_
(
"Asset has been disabled, skipped: {}"
)
.
format
(
asset
)
logger
.
info
(
msg
)
continue
if
not
asset
.
support_ansible
():
msg
=
_
(
"Asset may not be support ansible, skipped: {}"
)
.
format
(
asset
)
logger
.
info
(
msg
)
continue
hosts
.
append
(
asset
)
hosts
=
clean_hosts
(
assets
)
if
not
hosts
:
logger
.
info
(
_
(
"No assets matched, stop task"
))
return
{}
created_by
=
str
(
assets
[
0
]
.
org_id
)
task
,
created
=
update_or_create_ansible_task
(
...
...
@@ -125,7 +134,6 @@ def update_assets_hardware_info_util(assets, task_name=None):
@shared_task
def
update_asset_hardware_info_manual
(
asset
):
task_name
=
_
(
"Update asset hardware info: {}"
)
.
format
(
asset
.
hostname
)
# task_name = _("更新资产硬件信息")
return
update_assets_hardware_info_util
(
[
asset
],
task_name
=
task_name
)
...
...
@@ -141,166 +149,92 @@ def update_assets_hardware_info_period():
logger
.
debug
(
"Period task disabled, update assets hardware info pass"
)
return
# from ops.utils import update_or_create_ansible_task
# from orgs.models import Organization
# orgs = Organization.objects.all().values_list('id', flat=True)
# orgs.append('')
# task_name = _("Update assets hardware info period")
# for org_id in orgs:
# org_id = str(org_id)
# hostname_list = [
# asset for asset in Asset.objects.all()
# if asset.is_active and asset.is_unixlike()
# ]
# tasks = const.UPDATE_ASSETS_HARDWARE_TASKS
#
# # Only create, schedule by celery beat
# update_or_create_ansible_task(
# task_name, hosts=hostname_list, tasks=tasks, pattern='all',
# options=const.TASK_OPTIONS, run_as_admin=True, created_by='System',
# interval=60*60*24, is_periodic=True, callback=set_assets_hardware_info.name,
# )
## ADMIN USER CONNECTIVE ##
def
set_admin_user_connectability_info
(
result
,
**
kwargs
):
admin_user
=
kwargs
.
get
(
"admin_user"
)
task_name
=
kwargs
.
get
(
"task_name"
)
if
admin_user
is
None
and
task_name
is
not
None
:
admin_user
=
task_name
.
split
(
":"
)[
-
1
]
raw
,
summary
=
result
cache_key
=
const
.
ADMIN_USER_CONN_CACHE_KEY
.
format
(
admin_user
)
cache
.
set
(
cache_key
,
summary
,
CACHE_MAX_TIME
)
@shared_task
def
test_asset_connectivity_util
(
assets
,
task_name
=
None
):
from
ops.utils
import
update_or_create_ansible_task
for
i
in
summary
.
get
(
'contacted'
,
[]):
asset_conn_cache_key
=
const
.
ASSET_ADMIN_CONN_CACHE_KEY
.
format
(
i
)
cache
.
set
(
asset_conn_cache_key
,
1
,
CACHE_MAX_TIME
)
if
task_name
is
None
:
task_name
=
_
(
"Test assets connectivity"
)
hosts
=
clean_hosts
(
assets
)
if
not
hosts
:
return
{}
tasks
=
const
.
TEST_ADMIN_USER_CONN_TASKS
created_by
=
assets
[
0
]
.
org_id
task
,
created
=
update_or_create_ansible_task
(
task_name
=
task_name
,
hosts
=
hosts
,
tasks
=
tasks
,
pattern
=
'all'
,
options
=
const
.
TASK_OPTIONS
,
run_as_admin
=
True
,
created_by
=
created_by
,
)
result
=
task
.
run
()
summary
=
result
[
1
]
for
asset
in
assets
:
if
asset
.
hostname
in
summary
.
get
(
'dark'
,
{}):
asset
.
connectivity
=
asset
.
UNREACHABLE
elif
asset
.
hostname
in
summary
.
get
(
'contacted'
,
[]):
asset
.
connectivity
=
asset
.
REACHABLE
else
:
asset
.
connectivity
=
asset
.
UNKNOWN
return
summary
for
i
,
msg
in
summary
.
get
(
'dark'
,
{})
.
items
():
asset_conn_cache_key
=
const
.
ASSET_ADMIN_CONN_CACHE_KEY
.
format
(
i
)
cache
.
set
(
asset_conn_cache_key
,
0
,
CACHE_MAX_TIME
)
logger
.
error
(
msg
)
@shared_task
def
test_asset_connectivity_manual
(
asset
):
task_name
=
_
(
"Test assets connectivity: {}"
)
.
format
(
asset
)
summary
=
test_asset_connectivity_util
([
asset
],
task_name
=
task_name
)
if
summary
.
get
(
'dark'
):
return
False
,
summary
[
'dark'
]
else
:
return
True
,
""
@shared_task
def
test_admin_user_connect
abil
ity_util
(
admin_user
,
task_name
):
def
test_admin_user_connect
iv
ity_util
(
admin_user
,
task_name
):
"""
Test asset admin user can connect or not. Using ansible api do that
:param admin_user:
:param task_name:
:return:
"""
from
ops.utils
import
update_or_create_ansible_task
assets
=
admin_user
.
get_related_assets
()
hosts
=
[]
for
asset
in
assets
:
if
not
asset
.
is_active
:
msg
=
_
(
"Asset has been disabled, skipped: {}"
)
.
format
(
asset
)
logger
.
info
(
msg
)
continue
if
not
asset
.
support_ansible
():
msg
=
_
(
"Asset may not be support ansible, skipped: {}"
)
.
format
(
asset
)
logger
.
info
(
msg
)
continue
hosts
.
append
(
asset
)
hosts
=
clean_hosts
(
assets
)
if
not
hosts
:
logger
.
info
(
_
(
"No assets matched, stop task"
))
return
{}
tasks
=
const
.
TEST_ADMIN_USER_CONN_TASKS
task
,
created
=
update_or_create_ansible_task
(
task_name
=
task_name
,
hosts
=
hosts
,
tasks
=
tasks
,
pattern
=
'all'
,
options
=
const
.
TASK_OPTIONS
,
run_as_admin
=
True
,
created_by
=
admin_user
.
org_id
,
)
result
=
task
.
run
()
set_admin_user_connectability_info
(
result
,
admin_user
=
admin_user
.
name
)
return
result
summary
=
test_asset_connectivity_util
(
hosts
,
task_name
)
return
summary
@shared_task
@register_as_period_task
(
interval
=
3600
)
def
test_admin_user_connect
abil
ity_period
():
def
test_admin_user_connect
iv
ity_period
():
"""
A period task that update the ansible task period
"""
admin_users
=
AdminUser
.
objects
.
all
()
for
admin_user
in
admin_users
:
task_name
=
_
(
"Test admin user connect
abil
ity period: {}"
)
.
format
(
admin_user
.
name
)
test_admin_user_connect
abil
ity_util
(
admin_user
,
task_name
)
task_name
=
_
(
"Test admin user connect
iv
ity period: {}"
)
.
format
(
admin_user
.
name
)
test_admin_user_connect
iv
ity_util
(
admin_user
,
task_name
)
@shared_task
def
test_admin_user_connectability_manual
(
admin_user
):
task_name
=
_
(
"Test admin user connectability: {}"
)
.
format
(
admin_user
.
name
)
# task_name = _("测试管理行号可连接性: {}").format(admin_user.name)
return
test_admin_user_connectability_util
(
admin_user
,
task_name
)
@shared_task
def
test_asset_connectability_util
(
assets
,
task_name
=
None
):
from
ops.utils
import
update_or_create_ansible_task
if
task_name
is
None
:
task_name
=
_
(
"Test assets connectability"
)
# task_name = _("测试资产可连接性")
hosts
=
[]
for
asset
in
assets
:
if
not
asset
.
is_active
:
msg
=
_
(
"Asset has been disabled, skip: {}"
)
.
format
(
asset
)
logger
.
info
(
msg
)
continue
if
not
asset
.
support_ansible
():
msg
=
_
(
"Asset may not be support ansible, skip: {}"
)
.
format
(
asset
)
logger
.
info
(
msg
)
continue
hosts
.
append
(
asset
)
if
not
hosts
:
logger
.
info
(
_
(
"No assets, task stop"
))
return
{}
tasks
=
const
.
TEST_ADMIN_USER_CONN_TASKS
created_by
=
assets
[
0
]
.
org_id
task
,
created
=
update_or_create_ansible_task
(
task_name
=
task_name
,
hosts
=
hosts
,
tasks
=
tasks
,
pattern
=
'all'
,
options
=
const
.
TASK_OPTIONS
,
run_as_admin
=
True
,
created_by
=
created_by
,
)
result
=
task
.
run
()
summary
=
result
[
1
]
for
k
in
summary
.
get
(
'dark'
):
cache
.
set
(
const
.
ASSET_ADMIN_CONN_CACHE_KEY
.
format
(
k
),
0
,
CACHE_MAX_TIME
)
for
k
in
summary
.
get
(
'contacted'
):
cache
.
set
(
const
.
ASSET_ADMIN_CONN_CACHE_KEY
.
format
(
k
),
1
,
CACHE_MAX_TIME
)
return
summary
@shared_task
def
test_asset_connectability_manual
(
asset
):
task_name
=
_
(
"Test assets connectability: {}"
)
.
format
(
asset
)
summary
=
test_asset_connectability_util
([
asset
],
task_name
=
task_name
)
if
summary
.
get
(
'dark'
):
return
False
,
summary
[
'dark'
]
else
:
return
True
,
""
def
test_admin_user_connectivity_manual
(
admin_user
):
task_name
=
_
(
"Test admin user connectivity: {}"
)
.
format
(
admin_user
.
name
)
return
test_admin_user_connectivity_util
(
admin_user
,
task_name
)
## System user connective ##
@shared_task
def
set_system_user_connect
ablity_info
(
result
,
**
kwargs
):
def
set_system_user_connect
ivity_info
(
system_user
,
result
):
summary
=
result
[
1
]
task_name
=
kwargs
.
get
(
"task_name"
)
system_user
=
kwargs
.
get
(
"system_user"
)
if
system_user
is
None
:
system_user
=
task_name
.
split
(
":"
)[
-
1
]
cache_key
=
const
.
SYSTEM_USER_CONN_CACHE_KEY
.
format
(
str
(
system_user
.
id
))
cache
.
set
(
cache_key
,
summary
,
CACHE_MAX_TIME
)
system_user
.
connectivity
=
summary
@shared_task
def
test_system_user_connect
abil
ity_util
(
system_user
,
assets
,
task_name
):
def
test_system_user_connect
iv
ity_util
(
system_user
,
assets
,
task_name
):
"""
Test system cant connect his assets or not.
:param system_user:
...
...
@@ -309,20 +243,9 @@ def test_system_user_connectability_util(system_user, assets, task_name):
:return:
"""
from
ops.utils
import
update_or_create_ansible_task
hosts
=
[]
tasks
=
const
.
TEST_SYSTEM_USER_CONN_TASKS
for
asset
in
assets
:
if
not
asset
.
is_active
:
msg
=
_
(
"Asset has been disabled, skip: {}"
)
.
format
(
asset
)
logger
.
info
(
msg
)
continue
if
not
asset
.
support_ansible
():
msg
=
_
(
"Asset may not be support ansible, skip: {}"
)
.
format
(
asset
)
logger
.
info
(
msg
)
continue
hosts
.
append
(
asset
)
hosts
=
clean_hosts
(
assets
)
if
not
hosts
:
logger
.
info
(
_
(
"No assets matched, stop task"
))
return
{}
task
,
created
=
update_or_create_ansible_task
(
task_name
,
hosts
=
hosts
,
tasks
=
tasks
,
pattern
=
'all'
,
...
...
@@ -330,36 +253,35 @@ def test_system_user_connectability_util(system_user, assets, task_name):
run_as
=
system_user
,
created_by
=
system_user
.
org_id
,
)
result
=
task
.
run
()
set_system_user_connect
ablity_info
(
result
,
system_user
=
system_user
)
set_system_user_connect
ivity_info
(
system_user
,
result
)
return
result
@shared_task
def
test_system_user_connect
abil
ity_manual
(
system_user
):
task_name
=
_
(
"Test system user connect
abil
ity: {}"
)
.
format
(
system_user
)
assets
=
system_user
.
get_assets
()
return
test_system_user_connect
abil
ity_util
(
system_user
,
assets
,
task_name
)
def
test_system_user_connect
iv
ity_manual
(
system_user
):
task_name
=
_
(
"Test system user connect
iv
ity: {}"
)
.
format
(
system_user
)
assets
=
system_user
.
get_
related_
assets
()
return
test_system_user_connect
iv
ity_util
(
system_user
,
assets
,
task_name
)
@shared_task
def
test_system_user_connect
abil
ity_a_asset
(
system_user
,
asset
):
task_name
=
_
(
"Test system user connect
abil
ity: {} => {}"
)
.
format
(
def
test_system_user_connect
iv
ity_a_asset
(
system_user
,
asset
):
task_name
=
_
(
"Test system user connect
iv
ity: {} => {}"
)
.
format
(
system_user
,
asset
)
return
test_system_user_connect
abil
ity_util
(
system_user
,
[
asset
],
task_name
)
return
test_system_user_connect
iv
ity_util
(
system_user
,
[
asset
],
task_name
)
@shared_task
def
test_system_user_connect
abil
ity_period
():
def
test_system_user_connect
iv
ity_period
():
if
PERIOD_TASK
!=
"on"
:
logger
.
debug
(
"Period task disabled, test system user connect
abil
ity pass"
)
logger
.
debug
(
"Period task disabled, test system user connect
iv
ity pass"
)
return
# Todo: 暂时禁用定期测试
# system_users = SystemUser.objects.all()
# for system_user in system_users:
# task_name = _("Test system user connectability period: {}").format(system_user)
# # task_name = _("定期测试系统用户可连接性: {}".format(system_user))
# test_system_user_connectability_util(system_user, task_name)
system_users
=
SystemUser
.
objects
.
all
()
for
system_user
in
system_users
:
task_name
=
_
(
"Test system user connectivity period: {}"
)
.
format
(
system_user
)
assets
=
system_user
.
get_related_assets
()
test_system_user_connectivity_util
(
system_user
,
assets
,
task_name
)
#### Push system user tasks ####
...
...
@@ -381,6 +303,24 @@ def get_push_system_user_tasks(system_user):
),
}
})
tasks
.
extend
([
{
'name'
:
'Check home dir exists'
,
'action'
:
{
'module'
:
'stat'
,
'args'
:
'path=/home/{}'
.
format
(
system_user
.
username
)
},
'register'
:
'home_existed'
},
{
'name'
:
"Set home dir permission"
,
'action'
:
{
'module'
:
'file'
,
'args'
:
"path=/home/{0} owner={0} group={0} mode=700"
.
format
(
system_user
.
username
)
},
'when'
:
'home_existed.stat.exists == true'
}
])
if
system_user
.
public_key
:
tasks
.
append
({
'name'
:
'Set {} authorized key'
.
format
(
system_user
.
username
),
...
...
@@ -417,19 +357,8 @@ def push_system_user_util(system_user, assets, task_name):
return
tasks
=
get_push_system_user_tasks
(
system_user
)
hosts
=
[]
for
asset
in
assets
:
if
not
asset
.
is_active
:
msg
=
_
(
"Asset has been disabled, skip: {}"
)
.
format
(
asset
)
logger
.
info
(
msg
)
continue
if
not
asset
.
support_ansible
():
msg
=
_
(
"Asset may not be support ansible, skip: {}"
)
.
format
(
asset
)
logger
.
info
(
msg
)
continue
hosts
.
append
(
asset
)
hosts
=
clean_hosts
(
assets
)
if
not
hosts
:
logger
.
info
(
_
(
"No assets matched, stop task"
))
return
{}
task
,
created
=
update_or_create_ansible_task
(
task_name
=
task_name
,
hosts
=
hosts
,
tasks
=
tasks
,
pattern
=
'all'
,
...
...
@@ -441,7 +370,7 @@ def push_system_user_util(system_user, assets, task_name):
@shared_task
def
push_system_user_to_assets_manual
(
system_user
):
assets
=
system_user
.
get_assets
()
assets
=
system_user
.
get_
related_
assets
()
task_name
=
_
(
"Push system users to assets: {}"
)
.
format
(
system_user
.
name
)
return
push_system_user_util
(
system_user
,
assets
,
task_name
=
task_name
)
...
...
This diff is collapsed.
Click to expand it.
apps/assets/templates/assets/admin_user_assets.html
View file @
a609f170
...
...
@@ -45,13 +45,11 @@
<table
class=
"table table-striped table-bordered table-hover"
id=
"asset_list_table"
>
<thead>
<tr>
<th
class=
"text-center"
>
<input
type=
"checkbox"
id=
"check_all"
class=
"ipt_check_all"
>
</th>
<th>
{% trans 'Hostname' %}
</th>
<th>
{% trans 'IP' %}
</th>
<th>
{% trans 'Port' %}
</th>
<th>
{% trans 'Reachable' %}
</th>
<th>
{% trans 'Action' %}
</th>
</tr>
</thead>
<tbody>
...
...
@@ -91,26 +89,36 @@
<script>
function
initTable
()
{
var
reachable
=
{{
admin_user
.
REACHABLE
}};
var
unreachable
=
{{
admin_user
.
UNREACHABLE
}};
var
options
=
{
ele
:
$
(
'#asset_list_table'
),
buttons
:
[],
order
:
[],
columnDefs
:
[
{
targets
:
1
,
createdCell
:
function
(
td
,
cellData
,
rowData
)
{
{
targets
:
0
,
createdCell
:
function
(
td
,
cellData
,
rowData
)
{
var
detail_btn
=
'<a href="{% url "assets:asset-detail" pk=DEFAULT_PK %}" data-aid="'
+
rowData
.
id
+
'">'
+
cellData
+
'</a>'
;
$
(
td
).
html
(
detail_btn
.
replace
(
'{{ DEFAULT_PK }}'
,
rowData
.
id
));
}},
{
targets
:
4
,
createdCell
:
function
(
td
,
cellData
)
{
if
(
!
cellData
)
{
{
targets
:
3
,
createdCell
:
function
(
td
,
cellData
)
{
if
(
cellData
===
unreachable
)
{
$
(
td
).
html
(
'<i class="fa fa-times text-danger"></i>'
)
}
else
{
}
else
if
(
cellData
===
reachable
)
{
$
(
td
).
html
(
'<i class="fa fa-check text-navy"></i>'
)
}
else
{
$
(
td
).
html
(
''
)
}
}}],
ajax_url
:
'{% url "api-assets:asset-list" %}?admin_user_id={{ admin_user.id }}'
,
}},
{
targets
:
4
,
createdCell
:
function
(
td
,
cellData
)
{
var
test_btn
=
' <a class="btn btn-xs btn-info btn-test-asset" data-uid="{{ DEFAULT_PK }}" >{% trans "Test" %}</a>'
.
replace
(
"{{ DEFAULT_PK }}"
,
cellData
);
$
(
td
).
html
(
test_btn
);
}}
],
ajax_url
:
'{% url "api-assets:admin-user-assets" pk=admin_user.id %}'
,
columns
:
[
{
data
:
function
(){
return
""
}},
{
data
:
"hostname"
},
{
data
:
"ip"
},
{
data
:
"port"
},
{
data
:
"
is_connective"
}],
{
data
:
"hostname"
},
{
data
:
"ip"
},
{
data
:
"port"
},
{
data
:
"
connectivity"
},
{
data
:
"id"
}],
op_html
:
$
(
'#actions'
).
html
()
};
jumpserver
.
initServerSideDataTable
(
options
);
...
...
@@ -119,6 +127,21 @@ function initTable() {
$
(
document
).
ready
(
function
()
{
initTable
();
})
.
on
(
'click'
,
'.btn-test-asset'
,
function
()
{
var
asset_id
=
$
(
this
).
data
(
'uid'
);
var
the_url
=
"{% url 'api-assets:asset-alive-test' pk=DEFAULT_PK %}"
.
replace
(
'{{ DEFAULT_PK }}'
,
asset_id
);
var
success
=
function
(
data
)
{
var
task_id
=
data
.
task
;
var
url
=
'{% url "ops:celery-task-log" pk=DEFAULT_PK %}'
.
replace
(
"{{ DEFAULT_PK }}"
,
task_id
);
window
.
open
(
url
,
''
,
'width=800,height=600,left=400,top=400'
)
};
APIUpdateAttr
({
url
:
the_url
,
method
:
'GET'
,
success
:
success
,
flash_message
:
false
});
})
.
on
(
'click'
,
'.btn-test-connective'
,
function
()
{
var
the_url
=
"{% url 'api-assets:admin-user-connective' pk=admin_user.id %}"
;
var
success
=
function
(
data
)
{
...
...
This diff is collapsed.
Click to expand it.
apps/assets/templates/assets/system_user_asset.html
View file @
a609f170
...
...
@@ -136,7 +136,7 @@
{% block custom_foot_js %}
<script>
function
initAssetsTable
()
{
var
unreachable
=
{{
system_user
.
unreachable_assets
|
safe
}};
var
connectivity
=
{{
system_user
.
connectivity
|
safe
}};
var
options
=
{
ele
:
$
(
'#system_user_list'
),
buttons
:
[],
...
...
@@ -147,10 +147,12 @@ function initAssetsTable() {
$
(
td
).
html
(
detail_btn
.
replace
(
'{{ DEFAULT_PK }}'
,
rowData
.
id
));
}},
{
targets
:
3
,
createdCell
:
function
(
td
,
cellData
)
{
if
(
unreachable
.
indexOf
(
cellData
)
>=
0
)
{
if
(
connectivity
.
unreachable
.
indexOf
(
cellData
)
>=
0
)
{
$
(
td
).
html
(
'<i class="fa fa-times text-danger"></i>'
)
}
else
{
}
else
if
(
connectivity
.
reachable
.
indexOf
(
cellData
)
>=
0
)
{
$
(
td
).
html
(
'<i class="fa fa-check text-navy"></i>'
)
}
else
{
$
(
td
).
html
(
''
)
}
}},
{
targets
:
4
,
createdCell
:
function
(
td
,
cellData
)
{
...
...
This diff is collapsed.
Click to expand it.
apps/assets/templates/assets/system_user_list.html
View file @
a609f170
...
...
@@ -95,7 +95,7 @@ function initTable() {
}}],
ajax_url
:
'{% url "api-assets:system-user-list" %}'
,
columns
:
[
{
data
:
"id"
},
{
data
:
"name"
},
{
data
:
"username"
},
{
data
:
"protocol"
},
{
data
:
"
get_
login_mode_display"
},
{
data
:
"assets_amount"
},
{
data
:
"id"
},
{
data
:
"name"
},
{
data
:
"username"
},
{
data
:
"protocol"
},
{
data
:
"login_mode_display"
},
{
data
:
"assets_amount"
},
{
data
:
"reachable_amount"
},
{
data
:
"unreachable_amount"
},
{
data
:
"id"
},
{
data
:
"comment"
},
{
data
:
"id"
}
],
op_html
:
$
(
'#actions'
).
html
()
...
...
This diff is collapsed.
Click to expand it.
apps/assets/urls/api_urls.py
View file @
a609f170
...
...
@@ -24,32 +24,34 @@ cmd_filter_router.register(r'rules', api.CommandFilterRuleViewSet, 'cmd-filter-r
urlpatterns
=
[
path
(
'assets-bulk/'
,
api
.
AssetListUpdateApi
.
as_view
(),
name
=
'asset-bulk-update'
),
path
(
'system-user/<uuid:pk>/auth-info/'
,
api
.
SystemUserAuthInfoApi
.
as_view
(),
name
=
'system-user-auth-info'
),
path
(
'system-user/<uuid:pk>/assets/'
,
api
.
SystemUserAssetsListView
.
as_view
(),
name
=
'system-user-assets'
),
path
(
'assets/<uuid:pk>/refresh/'
,
api
.
AssetRefreshHardwareApi
.
as_view
(),
name
=
'asset-refresh'
),
path
(
'assets/<uuid:pk>/alive/'
,
api
.
AssetAdminUserTestApi
.
as_view
(),
name
=
'asset-alive-test'
),
path
(
'assets/<uuid:pk>/gateway/'
,
api
.
AssetGatewayApi
.
as_view
(),
name
=
'asset-gateway'
),
path
(
'admin-user/<uuid:pk>/nodes/'
,
api
.
ReplaceNodesAdminUserApi
.
as_view
(),
name
=
'replace-nodes-admin-user'
),
path
(
'admin-user/<uuid:pk>/auth/'
,
api
.
AdminUserAuthApi
.
as_view
(),
name
=
'admin-user-auth'
),
path
(
'admin-user/<uuid:pk>/connective/'
,
api
.
AdminUserTestConnectiveApi
.
as_view
(),
name
=
'admin-user-connective'
),
path
(
'admin-user/<uuid:pk>/assets/'
,
api
.
AdminUserAssetsListView
.
as_view
(),
name
=
'admin-user-assets'
),
path
(
'system-user/<uuid:pk>/auth-info/'
,
api
.
SystemUserAuthInfoApi
.
as_view
(),
name
=
'system-user-auth-info'
),
path
(
'system-user/<uuid:pk>/assets/'
,
api
.
SystemUserAssetsListView
.
as_view
(),
name
=
'system-user-assets'
),
path
(
'system-user/<uuid:pk>/push/'
,
api
.
SystemUserPushApi
.
as_view
(),
name
=
'system-user-push'
),
path
(
'system-user/<uuid:pk>/asset/<uuid:aid>/push/'
,
api
.
SystemUserPushToAssetApi
.
as_view
(),
name
=
'system-user-push-to-asset'
),
path
(
'system-user/<uuid:pk>/asset/<uuid:aid>/test/'
,
api
.
SystemUserTestAssetConnect
abil
ityApi
.
as_view
(),
name
=
'system-user-test-to-asset'
),
api
.
SystemUserTestAssetConnect
iv
ityApi
.
as_view
(),
name
=
'system-user-test-to-asset'
),
path
(
'system-user/<uuid:pk>/connective/'
,
api
.
SystemUserTestConnectiveApi
.
as_view
(),
name
=
'system-user-connective'
),
path
(
'system-user/<uuid:pk>/cmd-filter-rules/'
,
api
.
SystemUserCommandFilterRuleListApi
.
as_view
(),
name
=
'system-user-cmd-filter-rule-list'
),
...
...
This diff is collapsed.
Click to expand it.
apps/assets/views/admin_user.py
View file @
a609f170
...
...
@@ -102,7 +102,7 @@ class AdminUserAssetsView(AdminUserRequiredMixin, SingleObjectMixin, ListView):
'app'
:
_
(
'Assets'
),
'action'
:
_
(
'Admin user detail'
),
"total_amount"
:
len
(
self
.
queryset
),
'unreachable_amount'
:
len
([
asset
for
asset
in
self
.
queryset
if
asset
.
is_connective
is
False
])
'unreachable_amount'
:
len
([
asset
for
asset
in
self
.
queryset
if
asset
.
connectivity
is
False
])
}
kwargs
.
update
(
context
)
return
super
()
.
get_context_data
(
**
kwargs
)
...
...
This diff is collapsed.
Click to expand it.
apps/jumpserver/conf.py
View file @
a609f170
...
...
@@ -304,7 +304,7 @@ defaults = {
'REDIS_DB_CELERY'
:
3
,
'REDIS_DB_CACHE'
:
4
,
'CAPTCHA_TEST_MODE'
:
None
,
'TOKEN_EXPIRATION'
:
3600
,
'TOKEN_EXPIRATION'
:
3600
*
24
,
'DISPLAY_PER_PAGE'
:
25
,
'DEFAULT_EXPIRED_YEARS'
:
70
,
'SESSION_COOKIE_DOMAIN'
:
None
,
...
...
@@ -312,6 +312,7 @@ defaults = {
'SESSION_COOKIE_AGE'
:
3600
*
24
,
'SESSION_EXPIRE_AT_BROWSER_CLOSE'
:
False
,
'AUTH_OPENID'
:
False
,
'OTP_ISSUER_NAME'
:
'Jumpserver'
,
'EMAIL_SUFFIX'
:
'jumpserver.org'
,
'TERMINAL_PASSWORD_AUTH'
:
True
,
'TERMINAL_PUBLIC_KEY_AUTH'
:
True
,
...
...
This diff is collapsed.
Click to expand it.
apps/locale/zh/LC_MESSAGES/django.mo
View file @
a609f170
No preview for this file type
This diff is collapsed.
Click to expand it.
apps/locale/zh/LC_MESSAGES/django.po
View file @
a609f170
...
...
@@ -637,7 +637,7 @@ msgstr "分类"
#: assets/models/node.py:20
msgid "Key"
msgstr ""
msgstr "
键
"
#: assets/models/node.py:127
msgid "New node"
...
...
@@ -739,15 +739,15 @@ msgid "Update asset hardware info: {}"
msgstr "更新资产硬件信息: {}"
#: assets/tasks.py:230
msgid "Test admin user connect
abil
ity period: {}"
msgid "Test admin user connect
iv
ity period: {}"
msgstr "定期测试管理账号可连接性: {}"
#: assets/tasks.py:236
msgid "Test admin user connect
abil
ity: {}"
msgid "Test admin user connect
iv
ity: {}"
msgstr "测试管理行号可连接性: {}"
#: assets/tasks.py:246
msgid "Test assets connect
abil
ity"
msgid "Test assets connect
iv
ity"
msgstr "测试资产可连接性"
#: assets/tasks.py:251 assets/tasks.py:316 assets/tasks.py:423
...
...
@@ -763,15 +763,15 @@ msgid "No assets, task stop"
msgstr "没有匹配到资产,结束任务"
#: assets/tasks.py:280
msgid "Test assets connect
abil
ity: {}"
msgid "Test assets connect
iv
ity: {}"
msgstr "测试资产可连接性: {}"
#: assets/tasks.py:339
msgid "Test system user connect
abil
ity: {}"
msgid "Test system user connect
iv
ity: {}"
msgstr "测试系统用户可连接性: {}"
#: assets/tasks.py:346
msgid "Test system user connect
abil
ity: {} => {}"
msgid "Test system user connect
iv
ity: {} => {}"
msgstr "测试系统用户可连接性: {} => {}"
#: assets/tasks.py:414
...
...
@@ -4508,7 +4508,7 @@ msgstr "创建账户"
#: xpack/plugins/cloud/templates/cloud/sync_instance_task_create.html:91
msgid "Loading..."
msgstr ""
msgstr "
加载中...
"
#: xpack/plugins/cloud/templates/cloud/sync_instance_task_create.html:106
msgid "Load failed"
...
...
@@ -4634,7 +4634,7 @@ msgstr "更新组织"
#~ msgid "Update assets hardware info period"
#~ msgstr "定期更新资产硬件信息"
#~ msgid "Test system user connect
abil
ity period: {}"
#~ msgid "Test system user connect
iv
ity period: {}"
#~ msgstr "定期测试系统用户可连接性: {}"
#~ msgid "Date finished"
...
...
This diff is collapsed.
Click to expand it.
apps/ops/api/adhoc.py
View file @
a609f170
...
...
@@ -24,8 +24,10 @@ class TaskViewSet(viewsets.ModelViewSet):
def
get_queryset
(
self
):
queryset
=
super
()
.
get_queryset
()
if
current_org
:
if
current_org
.
is_real
()
:
queryset
=
queryset
.
filter
(
created_by
=
current_org
.
id
)
else
:
queryset
=
queryset
.
filter
(
created_by
=
''
)
return
queryset
...
...
This diff is collapsed.
Click to expand it.
apps/ops/views/adhoc.py
View file @
a609f170
...
...
@@ -27,7 +27,7 @@ class TaskListView(AdminUserRequiredMixin, DatetimeSearchMixin, ListView):
def
get_queryset
(
self
):
queryset
=
super
()
.
get_queryset
()
if
current_org
:
if
current_org
.
is_real
()
:
queryset
=
queryset
.
filter
(
created_by
=
current_org
.
id
)
else
:
queryset
=
queryset
.
filter
(
created_by
=
''
)
...
...
This diff is collapsed.
Click to expand it.
apps/users/api/user.py
View file @
a609f170
...
...
@@ -46,6 +46,9 @@ class UserViewSet(IDInFilterMixin, BulkModelViewSet):
self
.
permission_classes
=
(
IsOrgAdminOrAppUser
,)
return
super
()
.
get_permissions
()
def
allow_bulk_destroy
(
self
,
qs
,
filtered
):
return
qs
.
count
()
==
filtered
.
count
()
class
UserChangePasswordApi
(
generics
.
RetrieveUpdateAPIView
):
permission_classes
=
(
IsOrgAdmin
,)
...
...
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