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
99c4875d
Unverified
Commit
99c4875d
authored
Jun 05, 2018
by
老广
Committed by
GitHub
Jun 05, 2018
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #1395 from jumpserver/dev
Dev
parents
4f521e5a
482d1bb2
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
20 changed files
with
294 additions
and
262 deletions
+294
-262
asset.py
apps/assets/api/asset.py
+20
-23
node.py
apps/assets/api/node.py
+31
-40
hands.py
apps/assets/hands.py
+0
-1
asset.py
apps/assets/models/asset.py
+67
-27
node.py
apps/assets/models/node.py
+65
-59
asset.py
apps/assets/serializers/asset.py
+0
-25
node.py
apps/assets/serializers/node.py
+3
-9
signals_handler.py
apps/assets/signals_handler.py
+18
-14
_asset_list_modal.html
apps/assets/templates/assets/_asset_list_modal.html
+1
-1
asset_list.html
apps/assets/templates/assets/asset_list.html
+3
-4
api_urls.py
apps/assets/urls/api_urls.py
+18
-11
utils.py
apps/assets/utils.py
+15
-13
api.py
apps/common/api.py
+6
-16
tasks.py
apps/common/tasks.py
+5
-0
utils.py
apps/common/utils.py
+15
-0
api.py
apps/perms/api.py
+21
-17
utils.py
apps/perms/utils.py
+0
-0
login.py
apps/users/views/login.py
+3
-1
jms
jms
+1
-0
upgrade.sh
utils/upgrade.sh
+2
-1
No files found.
apps/assets/api/asset.py
View file @
99c4875d
...
...
@@ -11,9 +11,8 @@ from django.db.models import Q
from
common.mixins
import
IDInFilterMixin
from
common.utils
import
get_logger
from
..hands
import
IsSuperUser
,
IsValidUser
,
IsSuperUserOrAppUser
,
\
NodePermissionUtil
from
..models
import
Asset
,
SystemUser
,
AdminUser
,
Node
from
..hands
import
IsSuperUser
,
IsValidUser
,
IsSuperUserOrAppUser
from
..models
import
Asset
,
SystemUser
,
AdminUser
,
Node
from
..
import
serializers
from
..tasks
import
update_asset_hardware_info_manual
,
\
test_asset_connectability_manual
...
...
@@ -22,7 +21,7 @@ from ..utils import LabelFilter
logger
=
get_logger
(
__file__
)
__all__
=
[
'AssetViewSet'
,
'
UserAssetListView'
,
'
AssetListUpdateApi'
,
'AssetViewSet'
,
'AssetListUpdateApi'
,
'AssetRefreshHardwareApi'
,
'AssetAdminUserTestApi'
]
...
...
@@ -40,7 +39,9 @@ class AssetViewSet(IDInFilterMixin, LabelFilter, BulkModelViewSet):
permission_classes
=
(
IsSuperUserOrAppUser
,)
def
get_queryset
(
self
):
queryset
=
super
()
.
get_queryset
()
queryset
=
super
()
.
get_queryset
()
\
.
prefetch_related
(
'labels'
,
'nodes'
)
\
.
select_related
(
'admin_user'
)
admin_user_id
=
self
.
request
.
query_params
.
get
(
'admin_user_id'
)
node_id
=
self
.
request
.
query_params
.
get
(
"node_id"
)
show_current_asset
=
self
.
request
.
query_params
.
get
(
"show_current_asset"
)
...
...
@@ -48,28 +49,24 @@ class AssetViewSet(IDInFilterMixin, LabelFilter, BulkModelViewSet):
if
admin_user_id
:
admin_user
=
get_object_or_404
(
AdminUser
,
id
=
admin_user_id
)
queryset
=
queryset
.
filter
(
admin_user
=
admin_user
)
if
node_id
:
if
node_id
and
show_current_asset
:
node
=
get_object_or_404
(
Node
,
id
=
node_id
)
if
no
t
no
de
.
is_root
():
if
node
.
is_root
():
queryset
=
queryset
.
filter
(
nodes__key__regex
=
'^{}(:[0-9]+)*$'
.
format
(
node
.
key
),
Q
(
nodes
=
node_id
)
|
Q
(
nodes__isnull
=
True
)
)
.
distinct
()
if
show_current_asset
and
node_id
:
queryset
=
queryset
.
filter
(
nodes
=
node_id
)
.
distinct
()
return
queryset
else
:
queryset
=
queryset
.
filter
(
nodes
=
node
)
.
distinct
()
class
UserAssetListView
(
generics
.
ListAPIView
):
queryset
=
Asset
.
objects
.
all
()
serializer_class
=
serializers
.
AssetSerializer
permission_classes
=
(
IsValidUser
,)
def
get_queryset
(
self
):
assets_granted
=
NodePermissionUtil
.
get_user_assets
(
self
.
request
.
user
)
.
keys
()
queryset
=
self
.
queryset
.
filter
(
id__in
=
[
asset
.
id
for
asset
in
assets_granted
]
)
if
node_id
and
not
show_current_asset
:
node
=
get_object_or_404
(
Node
,
id
=
node_id
)
if
node
.
is_root
():
queryset
=
Asset
.
objects
.
all
()
else
:
queryset
=
queryset
.
filter
(
nodes__key__regex
=
'^{}(:[0-9]+)*$'
.
format
(
node
.
key
),
)
.
distinct
()
return
queryset
...
...
apps/assets/api/node.py
View file @
99c4875d
...
...
@@ -31,7 +31,7 @@ from .. import serializers
logger
=
get_logger
(
__file__
)
__all__
=
[
'NodeViewSet'
,
'NodeChildrenApi'
,
'NodeAssetsApi'
,
'NodeWithAssetsApi'
,
'NodeAssetsApi'
,
'NodeAddAssetsApi'
,
'NodeRemoveAssetsApi'
,
'NodeReplaceAssetsApi'
,
'NodeAddChildrenApi'
,
'RefreshNodeHardwareInfoApi'
,
...
...
@@ -42,14 +42,7 @@ __all__ = [
class
NodeViewSet
(
BulkModelViewSet
):
queryset
=
Node
.
objects
.
all
()
permission_classes
=
(
IsSuperUser
,)
# serializer_class = serializers.NodeSerializer
def
get_serializer_class
(
self
):
show_current_asset
=
self
.
request
.
query_params
.
get
(
'show_current_asset'
)
if
show_current_asset
:
return
serializers
.
NodeCurrentSerializer
else
:
return
serializers
.
NodeSerializer
serializer_class
=
serializers
.
NodeSerializer
def
perform_create
(
self
,
serializer
):
child_key
=
Node
.
root
()
.
get_next_child_key
()
...
...
@@ -57,32 +50,32 @@ class NodeViewSet(BulkModelViewSet):
serializer
.
save
()
class
NodeWithAssetsApi
(
generics
.
ListAPIView
):
permission_classes
=
(
IsSuperUser
,)
serializers
=
serializers
.
NodeSerializer
def
get_node
(
self
):
pk
=
self
.
kwargs
.
get
(
'pk'
)
or
self
.
request
.
query_params
.
get
(
'node'
)
if
not
pk
:
node
=
Node
.
root
()
else
:
node
=
get_object_or_404
(
Node
,
pk
)
return
node
def
get_queryset
(
self
):
queryset
=
[]
node
=
self
.
get_node
()
children
=
node
.
get_children
()
assets
=
node
.
get_assets
()
queryset
.
extend
(
list
(
children
))
for
asset
in
assets
:
node
=
Node
()
node
.
id
=
asset
.
id
node
.
parent
=
node
.
id
node
.
value
=
asset
.
hostname
queryset
.
append
(
node
)
return
queryset
#
class NodeWithAssetsApi(generics.ListAPIView):
#
permission_classes = (IsSuperUser,)
#
serializers = serializers.NodeSerializer
#
#
def get_node(self):
#
pk = self.kwargs.get('pk') or self.request.query_params.get('node')
#
if not pk:
#
node = Node.root()
#
else:
#
node = get_object_or_404(Node, pk)
#
return node
#
#
def get_queryset(self):
#
queryset = []
#
node = self.get_node()
#
children = node.get_children()
#
assets = node.get_assets()
#
queryset.extend(list(children))
#
#
for asset in assets:
#
node = Node()
#
node.id = asset.id
#
node.parent = node.id
#
node.value = asset.hostname
#
queryset.append(node)
#
return queryset
class
NodeChildrenApi
(
mixins
.
ListModelMixin
,
generics
.
CreateAPIView
):
...
...
@@ -146,9 +139,9 @@ class NodeChildrenApi(mixins.ListModelMixin, generics.CreateAPIView):
for
asset
in
assets
:
node_fake
=
Node
()
node_fake
.
id
=
asset
.
id
node_fake
.
parent
=
node
node_fake
.
value
=
asset
.
hostname
node_fake
.
is_node
=
False
node_fake
.
parent_id
=
node
.
id
node_fake
.
value
=
asset
.
hostname
queryset
.
append
(
node_fake
)
queryset
=
sorted
(
queryset
,
key
=
lambda
x
:
x
.
is_node
,
reverse
=
True
)
return
queryset
...
...
@@ -184,9 +177,7 @@ class NodeAddChildrenApi(generics.UpdateAPIView):
for
node
in
children
:
if
not
node
:
continue
# node.parent = instance
# node.save()
node
.
set_parent
(
instance
)
node
.
parent
=
instance
return
Response
(
"OK"
)
...
...
apps/assets/hands.py
View file @
99c4875d
...
...
@@ -14,4 +14,3 @@
from
common.mixins
import
AdminUserRequiredMixin
from
common.permissions
import
IsAppUser
,
IsSuperUser
,
IsValidUser
,
IsSuperUserOrAppUser
from
users.models
import
User
,
UserGroup
from
perms.utils
import
NodePermissionUtil
apps/assets/models/asset.py
View file @
99c4875d
...
...
@@ -4,6 +4,8 @@
import
uuid
import
logging
import
random
from
functools
import
reduce
from
django.db
import
models
from
django.utils.translation
import
ugettext_lazy
as
_
...
...
@@ -58,42 +60,70 @@ class Asset(models.Model):
(
'Other'
,
'Other'
),
)
id
=
models
.
UUIDField
(
default
=
uuid
.
uuid4
,
primary_key
=
True
)
ip
=
models
.
GenericIPAddressField
(
max_length
=
32
,
verbose_name
=
_
(
'IP'
),
db_index
=
True
)
hostname
=
models
.
CharField
(
max_length
=
128
,
unique
=
True
,
verbose_name
=
_
(
'Hostname'
))
ip
=
models
.
GenericIPAddressField
(
max_length
=
32
,
verbose_name
=
_
(
'IP'
),
db_index
=
True
)
hostname
=
models
.
CharField
(
max_length
=
128
,
unique
=
True
,
verbose_name
=
_
(
'Hostname'
))
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"
))
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"
))
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'
))
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'
))
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
=
AssetManager
()
...
...
@@ -120,6 +150,15 @@ class Asset(models.Model):
nodes
=
self
.
nodes
.
all
()
or
[
Node
.
root
()]
return
nodes
def
get_all_nodes
(
self
,
flat
=
False
):
nodes
=
[]
for
node
in
self
.
get_nodes
():
_nodes
=
node
.
get_ancestor
(
with_self
=
True
)
_nodes
.
append
(
_nodes
)
if
flat
:
nodes
=
list
(
reduce
(
lambda
x
,
y
:
set
(
x
)
|
set
(
y
),
nodes
))
return
nodes
@property
def
hardware_info
(
self
):
if
self
.
cpu_count
:
...
...
@@ -191,7 +230,8 @@ class Asset(models.Model):
seed
()
for
i
in
range
(
count
):
asset
=
cls
(
ip
=
'
%
s.
%
s.
%
s.
%
s'
%
(
i
,
i
,
i
,
i
),
ip
=
[
str
(
i
)
for
i
in
random
.
sample
(
range
(
255
),
4
)]
asset
=
cls
(
ip
=
'.'
.
join
(
ip
),
hostname
=
forgery_py
.
internet
.
user_name
(
True
),
admin_user
=
choice
(
AdminUser
.
objects
.
all
()),
port
=
22
,
...
...
apps/assets/models/node.py
View file @
99c4875d
...
...
@@ -5,7 +5,7 @@ import uuid
from
django.db
import
models
,
transaction
from
django.db.models
import
Q
from
django.utils.translation
import
ugettext_lazy
as
_
from
common.utils
import
with_cache
__all__
=
[
'Node'
]
...
...
@@ -13,9 +13,6 @@ __all__ = ['Node']
class
Node
(
models
.
Model
):
id
=
models
.
UUIDField
(
default
=
uuid
.
uuid4
,
primary_key
=
True
)
key
=
models
.
CharField
(
unique
=
True
,
max_length
=
64
,
verbose_name
=
_
(
"Key"
))
# '1:1:1:1'
# value = models.CharField(
# max_length=128, unique=True, verbose_name=_("Value")
# )
value
=
models
.
CharField
(
max_length
=
128
,
verbose_name
=
_
(
"Value"
))
child_mark
=
models
.
IntegerField
(
default
=
0
)
date_create
=
models
.
DateTimeField
(
auto_now_add
=
True
)
...
...
@@ -25,31 +22,36 @@ class Node(models.Model):
def
__str__
(
self
):
return
self
.
full_value
def
__eq__
(
self
,
other
):
return
self
.
key
==
other
.
key
def
__gt__
(
self
,
other
):
if
self
.
is_root
():
return
True
self_key
=
[
int
(
k
)
for
k
in
self
.
key
.
split
(
':'
)]
other_key
=
[
int
(
k
)
for
k
in
other
.
key
.
split
(
':'
)]
if
len
(
self_key
)
<
len
(
other_key
):
return
True
elif
len
(
self_key
)
>
len
(
other_key
):
return
False
else
:
return
self_key
[
-
1
]
<
other_key
[
-
1
]
@property
def
name
(
self
):
return
self
.
value
@property
def
full_value
(
self
):
if
self
==
self
.
__class__
.
root
():
ancestor
=
[
a
.
value
for
a
in
self
.
get_ancestor
(
with_self
=
True
)]
if
self
.
is_root
():
return
self
.
value
else
:
return
'{} / {}'
.
format
(
self
.
parent
.
full_value
,
self
.
value
)
return
' / '
.
join
(
ancestor
)
@property
def
level
(
self
):
return
len
(
self
.
key
.
split
(
':'
))
def
set_parent
(
self
,
instance
):
children
=
self
.
get_all_children
()
old_key
=
self
.
key
with
transaction
.
atomic
():
self
.
parent
=
instance
for
child
in
children
:
child
.
key
=
child
.
key
.
replace
(
old_key
,
self
.
key
,
1
)
child
.
save
()
self
.
save
()
def
get_next_child_key
(
self
):
mark
=
self
.
child_mark
self
.
child_mark
+=
1
...
...
@@ -57,32 +59,35 @@ class Node(models.Model):
return
"{}:{}"
.
format
(
self
.
key
,
mark
)
def
create_child
(
self
,
value
):
child_key
=
self
.
get_next_child_key
()
child
=
self
.
__class__
.
objects
.
create
(
key
=
child_key
,
value
=
value
)
return
child
def
get_children
(
self
):
return
self
.
__class__
.
objects
.
filter
(
key__regex
=
r'^{}:[0-9]+$'
.
format
(
self
.
key
)
)
with
transaction
.
atomic
():
child_key
=
self
.
get_next_child_key
()
child
=
self
.
__class__
.
objects
.
create
(
key
=
child_key
,
value
=
value
)
return
child
def
get_children_with_self
(
self
):
def
get_children
(
self
,
with_self
=
False
):
pattern
=
r'^{0}$|^{}:[0-9]+$'
if
with_self
else
r'^{}:[0-9]+$'
return
self
.
__class__
.
objects
.
filter
(
key__regex
=
r'^{0}$|^{0}:[0-9]+$'
.
format
(
self
.
key
)
key__regex
=
pattern
.
format
(
self
.
key
)
)
def
get_all_children
(
self
):
def
get_all_children
(
self
,
with_self
=
False
):
pattern
=
r'^{0}$|^{0}:'
if
with_self
else
r'^{0}'
return
self
.
__class__
.
objects
.
filter
(
key__
startswith
=
'{}:'
.
format
(
self
.
key
)
key__
regex
=
pattern
.
format
(
self
.
key
)
)
def
get_all_children_with_self
(
self
):
return
self
.
__class__
.
objects
.
filter
(
key__regex
=
r'^{0}$|^{0}:'
.
format
(
self
.
key
)
def
get_sibling
(
self
,
with_self
=
False
):
key
=
':'
.
join
(
self
.
key
.
split
(
':'
)[:
-
1
])
pattern
=
r'^{}:[0-9]+$'
.
format
(
key
)
sibling
=
self
.
__class__
.
objects
.
filter
(
key__regex
=
pattern
.
format
(
self
.
key
)
)
if
not
with_self
:
sibling
=
sibling
.
exclude
(
key
=
self
.
key
)
return
sibling
def
get_family
(
self
):
ancestor
=
self
.
ancestor
ancestor
=
self
.
get_ancestor
()
children
=
self
.
get_all_children
()
return
[
*
tuple
(
ancestor
),
self
,
*
tuple
(
children
)]
...
...
@@ -93,7 +98,7 @@ class Node(models.Model):
Q
(
nodes__id
=
self
.
id
)
|
Q
(
nodes__isnull
=
True
)
)
else
:
assets
=
Asset
.
objects
.
filter
(
nodes__id
=
self
.
id
)
assets
=
self
.
assets
.
all
(
)
return
assets
def
get_valid_assets
(
self
):
...
...
@@ -104,18 +109,10 @@ class Node(models.Model):
if
self
.
is_root
():
assets
=
Asset
.
objects
.
all
()
else
:
nodes
=
self
.
get_all_children_with_self
(
)
assets
=
Asset
.
objects
.
filter
(
nodes__
in
=
nodes
)
.
distinct
(
)
pattern
=
r'^{0}$|^{0}:'
.
format
(
self
.
key
)
assets
=
Asset
.
objects
.
filter
(
nodes__
key__regex
=
pattern
)
return
assets
def
get_current_assets
(
self
):
from
.asset
import
Asset
assets
=
Asset
.
objects
.
filter
(
nodes
=
self
)
.
distinct
()
return
assets
def
has_assets
(
self
):
return
self
.
get_all_assets
()
def
get_all_valid_assets
(
self
):
return
self
.
get_all_assets
()
.
valid
()
...
...
@@ -126,7 +123,6 @@ class Node(models.Model):
def
parent
(
self
):
if
self
.
key
==
"0"
or
not
self
.
key
.
startswith
(
"0"
):
return
self
.
__class__
.
root
()
parent_key
=
":"
.
join
(
self
.
key
.
split
(
":"
)[:
-
1
])
try
:
parent
=
self
.
__class__
.
objects
.
get
(
key
=
parent_key
)
...
...
@@ -136,25 +132,33 @@ class Node(models.Model):
@parent.setter
def
parent
(
self
,
parent
):
self
.
key
=
parent
.
get_next_child_key
()
@property
def
ancestor
(
self
):
_key
=
self
.
key
.
split
(
':'
)
ancestor_keys
=
[]
if
self
.
is_node
:
children
=
self
.
get_all_children
()
old_key
=
self
.
key
with
transaction
.
atomic
():
self
.
key
=
parent
.
get_next_child_key
()
for
child
in
children
:
child
.
key
=
child
.
key
.
replace
(
old_key
,
self
.
key
,
1
)
child
.
save
()
self
.
save
()
else
:
self
.
key
=
parent
.
key
+
':fake'
def
get_ancestor
(
self
,
with_self
=
False
):
if
self
.
is_root
():
return
[
self
.
__class__
.
root
()]
ancestor
=
self
.
__class__
.
objects
.
filter
(
key
=
'0'
)
return
ancestor
for
i
in
range
(
len
(
_key
)
-
1
):
_key
=
self
.
key
.
split
(
':'
)
if
not
with_self
:
_key
.
pop
()
ancestor_keys
=
[]
for
i
in
range
(
len
(
_key
)):
ancestor_keys
.
append
(
':'
.
join
(
_key
))
return
self
.
__class__
.
objects
.
filter
(
key__in
=
ancestor_keys
)
@property
def
ancestor_with_self
(
self
):
ancestor
=
list
(
self
.
ancestor
)
ancestor
.
insert
(
0
,
self
)
_key
.
pop
()
ancestor
=
self
.
__class__
.
objects
.
filter
(
key__in
=
ancestor_keys
)
.
order_by
(
'key'
)
return
ancestor
@classmethod
...
...
@@ -162,4 +166,6 @@ class Node(models.Model):
obj
,
created
=
cls
.
objects
.
get_or_create
(
key
=
'0'
,
defaults
=
{
"key"
:
'0'
,
'value'
:
"ROOT"
}
)
print
(
obj
)
return
obj
apps/assets/serializers/asset.py
View file @
99c4875d
...
...
@@ -12,35 +12,10 @@ __all__ = [
]
class
NodeTMPSerializer
(
serializers
.
ModelSerializer
):
parent
=
serializers
.
SerializerMethodField
()
assets_amount
=
serializers
.
SerializerMethodField
()
class
Meta
:
model
=
Node
fields
=
[
'id'
,
'key'
,
'value'
,
'parent'
,
'assets_amount'
,
'is_node'
]
list_serializer_class
=
BulkListSerializer
@staticmethod
def
get_parent
(
obj
):
return
obj
.
parent
.
id
@staticmethod
def
get_assets_amount
(
obj
):
return
obj
.
get_all_assets
()
.
count
()
def
get_fields
(
self
):
fields
=
super
()
.
get_fields
()
field
=
fields
[
"key"
]
field
.
required
=
False
return
fields
class
AssetSerializer
(
BulkSerializerMixin
,
serializers
.
ModelSerializer
):
"""
资产的数据结构
"""
class
Meta
:
model
=
Asset
list_serializer_class
=
BulkListSerializer
...
...
apps/assets/serializers/node.py
View file @
99c4875d
...
...
@@ -9,7 +9,7 @@ from .asset import AssetGrantedSerializer
__all__
=
[
'NodeSerializer'
,
"NodeGrantedSerializer"
,
"NodeAddChildrenSerializer"
,
"NodeAssetsSerializer"
,
"NodeCurrentSerializer"
,
"NodeAssetsSerializer"
,
]
...
...
@@ -64,11 +64,11 @@ class NodeSerializer(serializers.ModelSerializer):
@staticmethod
def
get_parent
(
obj
):
return
obj
.
parent
.
id
return
obj
.
parent
.
id
if
obj
.
is_node
else
obj
.
parent_id
@staticmethod
def
get_assets_amount
(
obj
):
return
obj
.
get_all_assets
()
.
count
()
return
obj
.
get_all_assets
()
.
count
()
if
obj
.
is_node
else
0
def
get_fields
(
self
):
fields
=
super
()
.
get_fields
()
...
...
@@ -77,12 +77,6 @@ class NodeSerializer(serializers.ModelSerializer):
return
fields
class
NodeCurrentSerializer
(
NodeSerializer
):
@staticmethod
def
get_assets_amount
(
obj
):
return
obj
.
get_current_assets
()
.
count
()
class
NodeAssetsSerializer
(
serializers
.
ModelSerializer
):
assets
=
serializers
.
PrimaryKeyRelatedField
(
many
=
True
,
queryset
=
Asset
.
objects
.
all
())
...
...
apps/assets/signals_handler.py
View file @
99c4875d
...
...
@@ -63,22 +63,26 @@ def on_system_user_assets_change(sender, instance=None, **kwargs):
@receiver
(
m2m_changed
,
sender
=
Asset
.
nodes
.
through
)
def
on_asset_node_changed
(
sender
,
instance
=
None
,
**
kwargs
):
if
isinstance
(
instance
,
Asset
)
and
kwargs
[
'action'
]
==
'post_add'
:
logger
.
debug
(
"Asset node change signal received"
)
nodes
=
kwargs
[
'model'
]
.
objects
.
filter
(
pk__in
=
kwargs
[
'pk_set'
])
system_users_assets
=
defaultdict
(
set
)
system_users
=
SystemUser
.
objects
.
filter
(
nodes__in
=
nodes
)
for
system_user
in
system_users
:
system_users_assets
[
system_user
]
.
update
({
instance
})
for
system_user
,
assets
in
system_users_assets
.
items
():
system_user
.
assets
.
add
(
*
tuple
(
assets
))
if
isinstance
(
instance
,
Asset
):
if
kwargs
[
'action'
]
==
'post_add'
:
logger
.
debug
(
"Asset node change signal received"
)
nodes
=
kwargs
[
'model'
]
.
objects
.
filter
(
pk__in
=
kwargs
[
'pk_set'
])
system_users_assets
=
defaultdict
(
set
)
system_users
=
SystemUser
.
objects
.
filter
(
nodes__in
=
nodes
)
# 清理节点缓存
for
system_user
in
system_users
:
system_users_assets
[
system_user
]
.
update
({
instance
})
for
system_user
,
assets
in
system_users_assets
.
items
():
system_user
.
assets
.
add
(
*
tuple
(
assets
))
@receiver
(
m2m_changed
,
sender
=
Asset
.
nodes
.
through
)
def
on_node_assets_changed
(
sender
,
instance
=
None
,
**
kwargs
):
if
isinstance
(
instance
,
Node
)
and
kwargs
[
'action'
]
==
'post_add'
:
logger
.
debug
(
"Node assets change signal received"
)
if
isinstance
(
instance
,
Node
):
assets
=
kwargs
[
'model'
]
.
objects
.
filter
(
pk__in
=
kwargs
[
'pk_set'
])
system_users
=
SystemUser
.
objects
.
filter
(
nodes
=
instance
)
for
system_user
in
system_users
:
system_user
.
assets
.
add
(
*
tuple
(
assets
))
if
kwargs
[
'action'
]
==
'post_add'
:
logger
.
debug
(
"Node assets change signal received"
)
# 重新关联系统用户和资产的关系
system_users
=
SystemUser
.
objects
.
filter
(
nodes
=
instance
)
for
system_user
in
system_users
:
system_user
.
assets
.
add
(
*
tuple
(
assets
))
apps/assets/templates/assets/_asset_list_modal.html
View file @
99c4875d
...
...
@@ -59,7 +59,7 @@ var zTree2, asset_table2 = 0;
function
initTable2
()
{
var
options
=
{
ele
:
$
(
'#asset_list_modal_table'
),
ajax_url
:
'{% url "api-assets:asset-list" %}'
,
ajax_url
:
'{% url "api-assets:asset-list" %}
?show_current_asset=1
'
,
columns
:
[
{
data
:
"id"
},
{
data
:
"hostname"
},
{
data
:
"ip"
}
],
...
...
apps/assets/templates/assets/asset_list.html
View file @
99c4875d
...
...
@@ -399,8 +399,7 @@ function initTree() {
};
var
zNodes
=
[];
var
query_params
=
{
'show_current_asset'
:
getCookie
(
'show_current_asset'
)};
$
.
get
(
"{% url 'api-assets:node-list' %}"
,
query_params
,
function
(
data
,
status
){
$
.
get
(
"{% url 'api-assets:node-list' %}"
,
function
(
data
,
status
){
$
.
each
(
data
,
function
(
index
,
value
)
{
value
[
"pId"
]
=
value
[
"parent"
];
if
(
value
[
"key"
]
===
"0"
)
{
...
...
@@ -436,7 +435,7 @@ $(document).ready(function(){
initTable
();
initTree
();
if
(
getCookie
(
'show_current_asset'
)
===
'
yes
'
){
if
(
getCookie
(
'show_current_asset'
)
===
'
1
'
){
$
(
'#show_all_asset'
).
css
(
'display'
,
'inline-block'
);
}
else
{
...
...
@@ -564,7 +563,7 @@ $(document).ready(function(){
hideRMenu
();
$
(
this
).
css
(
'display'
,
'none'
);
$
(
'#show_all_asset'
).
css
(
'display'
,
'inline-block'
);
setCookie
(
'show_current_asset'
,
'
yes
'
);
setCookie
(
'show_current_asset'
,
'
1
'
);
location
.
reload
();
})
.
on
(
'click'
,
'.btn-show-all-asset'
,
function
(){
...
...
apps/assets/urls/api_urls.py
View file @
99c4875d
...
...
@@ -23,8 +23,6 @@ urlpatterns = [
api
.
AssetRefreshHardwareApi
.
as_view
(),
name
=
'asset-refresh'
),
url
(
r'^v1/assets/(?P<pk>[0-9a-zA-Z\-]{36})/alive/$'
,
api
.
AssetAdminUserTestApi
.
as_view
(),
name
=
'asset-alive-test'
),
url
(
r'^v1/assets/user-assets/$'
,
api
.
UserAssetListView
.
as_view
(),
name
=
'user-asset-list'
),
url
(
r'^v1/admin-user/(?P<pk>[0-9a-zA-Z\-]{36})/nodes/$'
,
api
.
ReplaceNodesAdminUserApi
.
as_view
(),
name
=
'replace-nodes-admin-user'
),
url
(
r'^v1/admin-user/(?P<pk>[0-9a-zA-Z\-]{36})/auth/$'
,
...
...
@@ -35,17 +33,26 @@ urlpatterns = [
api
.
SystemUserPushApi
.
as_view
(),
name
=
'system-user-push'
),
url
(
r'^v1/system-user/(?P<pk>[0-9a-zA-Z\-]{36})/connective/$'
,
api
.
SystemUserTestConnectiveApi
.
as_view
(),
name
=
'system-user-connective'
),
url
(
r'^v1/nodes/(?P<pk>[0-9a-zA-Z\-]{36})/children/$'
,
api
.
NodeChildrenApi
.
as_view
(),
name
=
'node-children'
),
url
(
r'^v1/nodes/(?P<pk>[0-9a-zA-Z\-]{36})/children/$'
,
api
.
NodeChildrenApi
.
as_view
(),
name
=
'node-children'
),
url
(
r'^v1/nodes/children/$'
,
api
.
NodeChildrenApi
.
as_view
(),
name
=
'node-children-2'
),
url
(
r'^v1/nodes/(?P<pk>[0-9a-zA-Z\-]{36})/children/add/$'
,
api
.
NodeAddChildrenApi
.
as_view
(),
name
=
'node-add-children'
),
url
(
r'^v1/nodes/(?P<pk>[0-9a-zA-Z\-]{36})/assets/$'
,
api
.
NodeAssetsApi
.
as_view
(),
name
=
'node-assets'
),
url
(
r'^v1/nodes/(?P<pk>[0-9a-zA-Z\-]{36})/assets/add/$'
,
api
.
NodeAddAssetsApi
.
as_view
(),
name
=
'node-add-assets'
),
url
(
r'^v1/nodes/(?P<pk>[0-9a-zA-Z\-]{36})/assets/replace/$'
,
api
.
NodeReplaceAssetsApi
.
as_view
(),
name
=
'node-replace-assets'
),
url
(
r'^v1/nodes/(?P<pk>[0-9a-zA-Z\-]{36})/assets/remove/$'
,
api
.
NodeRemoveAssetsApi
.
as_view
(),
name
=
'node-remove-assets'
),
url
(
r'^v1/nodes/(?P<pk>[0-9a-zA-Z\-]{36})/refresh-hardware-info/$'
,
api
.
RefreshNodeHardwareInfoApi
.
as_view
(),
name
=
'node-refresh-hardware-info'
),
url
(
r'^v1/nodes/(?P<pk>[0-9a-zA-Z\-]{36})/test-connective/$'
,
api
.
TestNodeConnectiveApi
.
as_view
(),
name
=
'node-test-connective'
),
url
(
r'^v1/nodes/(?P<pk>[0-9a-zA-Z\-]{36})/children/add/$'
,
api
.
NodeAddChildrenApi
.
as_view
(),
name
=
'node-add-children'
),
url
(
r'^v1/nodes/(?P<pk>[0-9a-zA-Z\-]{36})/assets/$'
,
api
.
NodeAssetsApi
.
as_view
(),
name
=
'node-assets'
),
url
(
r'^v1/nodes/(?P<pk>[0-9a-zA-Z\-]{36})/assets/add/$'
,
api
.
NodeAddAssetsApi
.
as_view
(),
name
=
'node-add-assets'
),
url
(
r'^v1/nodes/(?P<pk>[0-9a-zA-Z\-]{36})/assets/replace/$'
,
api
.
NodeReplaceAssetsApi
.
as_view
(),
name
=
'node-replace-assets'
),
url
(
r'^v1/nodes/(?P<pk>[0-9a-zA-Z\-]{36})/assets/remove/$'
,
api
.
NodeRemoveAssetsApi
.
as_view
(),
name
=
'node-remove-assets'
),
url
(
r'^v1/nodes/(?P<pk>[0-9a-zA-Z\-]{36})/refresh-hardware-info/$'
,
api
.
RefreshNodeHardwareInfoApi
.
as_view
(),
name
=
'node-refresh-hardware-info'
),
url
(
r'^v1/nodes/(?P<pk>[0-9a-zA-Z\-]{36})/test-connective/$'
,
api
.
TestNodeConnectiveApi
.
as_view
(),
name
=
'node-test-connective'
),
url
(
r'^v1/gateway/(?P<pk>[0-9a-zA-Z\-]{36})/test-connective/$'
,
api
.
GatewayTestConnectionApi
.
as_view
(),
name
=
'test-gateway-connective'
),
url
(
r'^v1/gateway/(?P<pk>[0-9a-zA-Z\-]{36})/test-connective/$'
,
api
.
GatewayTestConnectionApi
.
as_view
(),
name
=
'test-gateway-connective'
),
]
urlpatterns
+=
router
.
urls
...
...
apps/assets/utils.py
View file @
99c4875d
# ~*~ coding: utf-8 ~*~
#
import
os
import
paramiko
from
paramiko.ssh_exception
import
SSHException
from
common.utils
import
get_object_or_none
from
.models
import
Asset
,
SystemUser
,
Label
...
...
@@ -49,22 +50,23 @@ def test_gateway_connectability(gateway):
"""
client
=
paramiko
.
SSHClient
()
client
.
set_missing_host_key_policy
(
paramiko
.
AutoAddPolicy
())
proxy_command
=
[
"ssh"
,
"{}@{}"
.
format
(
gateway
.
username
,
gateway
.
ip
),
"-p"
,
str
(
gateway
.
port
),
"-W"
,
"127.0.0.1:{}"
.
format
(
gateway
.
port
),
]
if
gateway
.
password
:
proxy_command
.
insert
(
0
,
"sshpass -p '{}'"
.
format
(
gateway
.
password
))
if
gateway
.
private_key
:
proxy_command
.
append
(
"-i {}"
.
format
(
gateway
.
private_key_file
))
proxy
=
paramiko
.
SSHClient
()
proxy
.
load_host_keys
(
os
.
path
.
expanduser
(
'~/.ssh/known_hosts'
))
proxy
.
set_missing_host_key_policy
(
paramiko
.
AutoAddPolicy
())
try
:
sock
=
paramiko
.
ProxyCommand
(
" "
.
join
(
proxy_command
))
except
paramiko
.
ProxyCommandFailure
as
e
:
proxy
.
connect
(
gateway
.
ip
,
username
=
gateway
.
username
,
password
=
gateway
.
password
,
pkey
=
gateway
.
private_key_obj
)
except
(
paramiko
.
AuthenticationException
,
paramiko
.
BadAuthenticationType
,
SSHException
)
as
e
:
return
False
,
str
(
e
)
sock
=
proxy
.
get_transport
()
.
open_channel
(
'direct-tcpip'
,
(
'127.0.0.1'
,
gateway
.
port
),
(
'127.0.0.1'
,
0
)
)
try
:
client
.
connect
(
"127.0.0.1"
,
port
=
gateway
.
port
,
username
=
gateway
.
username
,
...
...
apps/common/api.py
View file @
99c4875d
...
...
@@ -21,23 +21,13 @@ class MailTestingAPI(APIView):
serializer
=
self
.
serializer_class
(
data
=
request
.
data
)
if
serializer
.
is_valid
():
email_host_user
=
serializer
.
validated_data
[
"EMAIL_HOST_USER"
]
kwargs
=
{
"host"
:
serializer
.
validated_data
[
"EMAIL_HOST"
],
"port"
:
serializer
.
validated_data
[
"EMAIL_PORT"
],
"username"
:
serializer
.
validated_data
[
"EMAIL_HOST_USER"
],
"password"
:
serializer
.
validated_data
[
"EMAIL_HOST_PASSWORD"
],
"use_ssl"
:
serializer
.
validated_data
[
"EMAIL_USE_SSL"
],
"use_tls"
:
serializer
.
validated_data
[
"EMAIL_USE_TLS"
]
}
connection
=
get_connection
(
timeout
=
5
,
**
kwargs
)
for
k
,
v
in
serializer
.
validated_data
.
items
():
if
k
.
startswith
(
'EMAIL'
):
setattr
(
settings
,
k
,
v
)
try
:
connection
.
open
()
except
Exception
as
e
:
return
Response
({
"error"
:
str
(
e
)},
status
=
401
)
try
:
send_mail
(
"Test"
,
"Test smtp setting"
,
email_host_user
,
[
email_host_user
],
connection
=
connection
)
subject
=
"Test"
message
=
"Test smtp setting"
send_mail
(
subject
,
message
,
email_host_user
,
[
email_host_user
])
except
Exception
as
e
:
return
Response
({
"error"
:
str
(
e
)},
status
=
401
)
...
...
apps/common/tasks.py
View file @
99c4875d
...
...
@@ -2,6 +2,7 @@ from django.core.mail import send_mail
from
django.conf
import
settings
from
celery
import
shared_task
from
.utils
import
get_logger
from
.models
import
Setting
logger
=
get_logger
(
__file__
)
...
...
@@ -21,6 +22,10 @@ def send_mail_async(*args, **kwargs):
Example:
send_mail_sync.delay(subject, message, recipient_list, fail_silently=False, html_message=None)
"""
configs
=
Setting
.
objects
.
filter
(
name__startswith
=
'EMAIL'
)
for
config
in
configs
:
setattr
(
settings
,
config
.
name
,
config
.
cleaned_value
)
if
len
(
args
)
==
3
:
args
=
list
(
args
)
args
[
0
]
=
settings
.
EMAIL_SUBJECT_PREFIX
+
args
[
0
]
...
...
apps/common/utils.py
View file @
99c4875d
...
...
@@ -16,6 +16,7 @@ import calendar
import
threading
from
io
import
StringIO
import
uuid
from
functools
import
wraps
import
paramiko
import
sshpubkeys
...
...
@@ -395,3 +396,17 @@ class TeeObj:
def
close
(
self
):
self
.
file_obj
.
close
()
def
with_cache
(
func
):
cache
=
{}
key
=
"_{}.{}"
.
format
(
func
.
__module__
,
func
.
__name__
)
@wraps
(
func
)
def
wrapper
(
*
args
,
**
kwargs
):
cached
=
cache
.
get
(
key
)
if
cached
:
return
cached
res
=
func
(
*
args
,
**
kwargs
)
cache
[
key
]
=
res
return
res
return
wrapper
apps/perms/api.py
View file @
99c4875d
...
...
@@ -41,11 +41,11 @@ class AssetPermissionViewSet(viewsets.ModelViewSet):
asset
=
get_object_or_404
(
Asset
,
pk
=
asset_id
)
permissions
=
set
(
queryset
.
filter
(
assets
=
asset
))
for
node
in
asset
.
nodes
.
all
():
inherit_nodes
.
update
(
set
(
node
.
ancestor_with_self
))
inherit_nodes
.
update
(
set
(
node
.
get_ancestor
(
with_self
=
True
)
))
elif
node_id
:
node
=
get_object_or_404
(
Node
,
pk
=
node_id
)
permissions
=
set
(
queryset
.
filter
(
nodes
=
node
))
inherit_nodes
=
node
.
ancestor
inherit_nodes
=
node
.
get_ancestor
()
for
n
in
inherit_nodes
:
_permissions
=
queryset
.
filter
(
nodes
=
n
)
...
...
@@ -70,7 +70,8 @@ class UserGrantedAssetsApi(ListAPIView):
else
:
user
=
self
.
request
.
user
for
k
,
v
in
AssetPermissionUtil
.
get_user_assets
(
user
)
.
items
():
util
=
AssetPermissionUtil
(
user
)
for
k
,
v
in
util
.
get_assets
()
.
items
():
if
k
.
is_unixlike
():
system_users_granted
=
[
s
for
s
in
v
if
s
.
protocol
==
'ssh'
]
else
:
...
...
@@ -95,7 +96,8 @@ class UserGrantedNodesApi(ListAPIView):
user
=
get_object_or_404
(
User
,
id
=
user_id
)
else
:
user
=
self
.
request
.
user
nodes
=
AssetPermissionUtil
.
get_user_nodes_with_assets
(
user
)
util
=
AssetPermissionUtil
(
user
)
nodes
=
util
.
get_nodes_with_assets
()
return
nodes
.
keys
()
def
get_permissions
(
self
):
...
...
@@ -116,7 +118,8 @@ class UserGrantedNodesWithAssetsApi(ListAPIView):
else
:
user
=
get_object_or_404
(
User
,
id
=
user_id
)
nodes
=
AssetPermissionUtil
.
get_user_nodes_with_assets
(
user
)
util
=
AssetPermissionUtil
(
user
)
nodes
=
util
.
get_nodes_with_assets
()
for
node
,
_assets
in
nodes
.
items
():
assets
=
_assets
.
keys
()
for
k
,
v
in
_assets
.
items
():
...
...
@@ -147,13 +150,9 @@ class UserGrantedNodeAssetsApi(ListAPIView):
user
=
get_object_or_404
(
User
,
id
=
user_id
)
else
:
user
=
self
.
request
.
user
nodes
=
AssetPermissionUtil
.
get_user_nodes_with_assets
(
user
)
node
=
get_object_or_none
(
Node
,
id
=
node_id
)
if
not
node
:
unnode
=
[
node
for
node
in
nodes
if
node
.
name
==
'Unnode'
]
node
=
unnode
[
0
]
if
unnode
else
None
util
=
AssetPermissionUtil
(
user
)
node
=
get_object_or_404
(
Node
,
id
=
node_id
)
nodes
=
util
.
get_nodes_with_assets
()
assets
=
nodes
.
get
(
node
,
[])
for
asset
,
system_users
in
assets
.
items
():
asset
.
system_users_granted
=
system_users
...
...
@@ -177,7 +176,8 @@ class UserGroupGrantedAssetsApi(ListAPIView):
return
queryset
user_group
=
get_object_or_404
(
UserGroup
,
id
=
user_group_id
)
assets
=
AssetPermissionUtil
.
get_user_group_assets
(
user_group
)
util
=
AssetPermissionUtil
(
user_group
)
assets
=
util
.
get_assets
()
for
k
,
v
in
assets
.
items
():
k
.
system_users_granted
=
v
queryset
.
append
(
k
)
...
...
@@ -194,7 +194,8 @@ class UserGroupGrantedNodesApi(ListAPIView):
if
group_id
:
group
=
get_object_or_404
(
UserGroup
,
id
=
group_id
)
nodes
=
AssetPermissionUtil
.
get_user_group_nodes_with_assets
(
group
)
util
=
AssetPermissionUtil
(
group
)
nodes
=
util
.
get_nodes_with_assets
()
return
nodes
.
keys
()
return
queryset
...
...
@@ -211,7 +212,8 @@ class UserGroupGrantedNodesWithAssetsApi(ListAPIView):
return
queryset
user_group
=
get_object_or_404
(
UserGroup
,
id
=
user_group_id
)
nodes
=
AssetPermissionUtil
.
get_user_group_nodes_with_assets
(
user_group
)
util
=
AssetPermissionUtil
(
user_group
)
nodes
=
util
.
get_nodes_with_assets
()
for
node
,
_assets
in
nodes
.
items
():
assets
=
_assets
.
keys
()
for
asset
,
system_users
in
_assets
.
items
():
...
...
@@ -231,7 +233,8 @@ class UserGroupGrantedNodeAssetsApi(ListAPIView):
user_group
=
get_object_or_404
(
UserGroup
,
id
=
user_group_id
)
node
=
get_object_or_404
(
Node
,
id
=
node_id
)
nodes
=
AssetPermissionUtil
.
get_user_group_nodes_with_assets
(
user_group
)
util
=
AssetPermissionUtil
(
user_group
)
nodes
=
util
.
get_nodes_with_assets
()
assets
=
nodes
.
get
(
node
,
[])
for
asset
,
system_users
in
assets
.
items
():
asset
.
system_users_granted
=
system_users
...
...
@@ -251,7 +254,8 @@ class ValidateUserAssetPermissionView(APIView):
asset
=
get_object_or_404
(
Asset
,
id
=
asset_id
)
system_user
=
get_object_or_404
(
SystemUser
,
id
=
system_id
)
assets_granted
=
AssetPermissionUtil
.
get_user_assets
(
user
)
util
=
AssetPermissionUtil
(
user
)
assets_granted
=
util
.
get_assets
()
if
system_user
in
assets_granted
.
get
(
asset
,
[]):
return
Response
({
'msg'
:
True
},
status
=
200
)
else
:
...
...
apps/perms/utils.py
View file @
99c4875d
This diff is collapsed.
Click to expand it.
apps/users/views/login.py
View file @
99c4875d
...
...
@@ -50,7 +50,9 @@ class UserLoginView(FormView):
def
get
(
self
,
request
,
*
args
,
**
kwargs
):
if
request
.
user
.
is_staff
:
return
redirect
(
self
.
get_success_url
())
return
redirect
(
redirect_user_first_login_or_index
(
request
,
self
.
redirect_field_name
)
)
request
.
session
.
set_test_cookie
()
return
super
()
.
get
(
request
,
*
args
,
**
kwargs
)
...
...
jms
View file @
99c4875d
...
...
@@ -123,6 +123,7 @@ def start_gunicorn():
'gunicorn'
,
'jumpserver.wsgi'
,
'-b'
,
bind
,
'-w'
,
str
(
WORKERS
),
'-k'
,
'eventlet'
,
'--access-logformat'
,
log_format
,
'-p'
,
pid_file
,
]
...
...
utils/upgrade.sh
View file @
99c4875d
#!/bin/bash
if
grep
-q
'source
~/.
autoenv/activate.sh'
~/.bashrc
;
then
if
grep
-q
'source
/opt/
autoenv/activate.sh'
~/.bashrc
;
then
echo
-e
"
\0
33[31m 正在自动载入 python 环境
\0
33[0m"
else
echo
-e
"
\0
33[31m 不支持自动升级,请参考 http://docs.jumpserver.org/zh/docs/upgrade.html 手动升级
\0
33[0m"
...
...
@@ -40,5 +40,6 @@ git pull && pip install -r requirements/requirements.txt && cd utils && sh make_
cd
..
&&
./jms start all
-d
echo
-e
"
\0
33[31m 请检查jumpserver是否启动成功
\0
33[0m"
echo
-e
"
\0
33[31m 备份文件存放于
$jumpserver_backup
目录
\0
33[0m"
stty
erase ^?
exit
0
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