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
Dec 18, 2018
by
老广
Committed by
GitHub
Dec 18, 2018
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[Update] Stash it (#2197)
* [Update] Stash it * [Bugfix] 修复错误 * [Update] 修改jms
parent
1293d721
Hide whitespace changes
Inline
Side-by-side
Showing
23 changed files
with
361 additions
and
334 deletions
+361
-334
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
+9
-7
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
+35
-12
system_user_asset.html
apps/assets/templates/assets/system_user_asset.html
+6
-4
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
()
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
})
...
...
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
})
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
})
...
...
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.'
)
...
...
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
()
...
...
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
:
...
...
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
:
...
...
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'
]
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
):
...
...
@@ -75,4 +75,7 @@ class SystemUserSimpleSerializer(serializers.ModelSerializer):
"""
class
Meta
:
model
=
SystemUser
fields
=
(
'id'
,
'name'
,
'username'
)
\ No newline at end of file
fields
=
(
'id'
,
'name'
,
'username'
)
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
):
...
...
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
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
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
)
@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
)
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
)
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
)
...
...
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>'
)
}
}}],
ajax_url
:
'{% url "api-assets:asset-list" %}?admin_user_id={{ admin_user.id }}'
,
}
else
{
$
(
td
).
html
(
''
)
}
}},
{
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
)
{
...
...
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,11 +147,13 @@ 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
)
{
var
push_btn
=
''
;
...
...
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
()
...
...
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'
),
...
...
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
)
...
...
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
,
...
...
apps/locale/zh/LC_MESSAGES/django.mo
View file @
a609f170
No preview for this file type
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"
...
...
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
...
...
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
=
''
)
...
...
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
,)
...
...
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