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
3c825440
Commit
3c825440
authored
Jul 05, 2019
by
ibuler
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[Update] 优化协议
parent
64e1e619
Show whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
201 additions
and
230 deletions
+201
-230
remote_app.py
apps/applications/forms/remote_app.py
+2
-4
asset.py
apps/assets/api/asset.py
+1
-1
node.py
apps/assets/api/node.py
+1
-1
asset.py
apps/assets/forms/asset.py
+11
-17
0029_auto_20190522_1114.py
apps/assets/migrations/0029_auto_20190522_1114.py
+0
-9
0034_auto_20190705_1348.py
apps/assets/migrations/0034_auto_20190705_1348.py
+38
-0
asset.py
apps/assets/models/asset.py
+46
-54
asset.py
apps/assets/serializers/asset.py
+56
-72
asset_detail.html
apps/assets/templates/assets/asset_detail.html
+1
-5
asset.py
apps/assets/views/asset.py
+32
-60
command_execution_create.html
apps/ops/templates/ops/command_execution_create.html
+1
-3
asset_permission.py
apps/perms/utils/asset_permission.py
+12
-4
No files found.
apps/applications/forms/remote_app.py
View file @
3c825440
...
...
@@ -5,7 +5,7 @@ from django.utils.translation import ugettext as _
from
django
import
forms
from
orgs.mixins
import
OrgModelForm
from
assets.models
import
SystemUser
,
Protocol
from
assets.models
import
SystemUser
from
..models
import
RemoteApp
from
..
import
const
...
...
@@ -88,9 +88,7 @@ class RemoteAppCreateUpdateForm(RemoteAppTypeForms, OrgModelForm):
# 过滤RDP资产和系统用户
super
()
.
__init__
(
*
args
,
**
kwargs
)
field_asset
=
self
.
fields
[
'asset'
]
field_asset
.
queryset
=
field_asset
.
queryset
.
filter
(
protocols__name
=
Protocol
.
PROTOCOL_RDP
)
field_asset
.
queryset
=
field_asset
.
queryset
.
has_protocol
(
'rdp'
)
field_system_user
=
self
.
fields
[
'system_user'
]
field_system_user
.
queryset
=
field_system_user
.
queryset
.
filter
(
protocol
=
SystemUser
.
PROTOCOL_RDP
...
...
apps/assets/api/asset.py
View file @
3c825440
...
...
@@ -37,7 +37,7 @@ __all__ = [
]
class
AssetViewSet
(
LabelFilter
,
ApiMessageMixin
,
OrgBulkModelViewSet
):
class
AssetViewSet
(
LabelFilter
,
OrgBulkModelViewSet
):
"""
API endpoint that allows Asset to be viewed or edited.
"""
...
...
apps/assets/api/node.py
View file @
3c825440
...
...
@@ -130,7 +130,7 @@ class NodeChildrenAsTreeApi(generics.ListAPIView):
include_assets
=
self
.
request
.
query_params
.
get
(
'assets'
,
'0'
)
==
'1'
if
not
include_assets
:
return
queryset
assets
=
self
.
node
.
get_assets
()
.
prefetch_related
(
"protocols"
)
.
only
(
assets
=
self
.
node
.
get_assets
()
.
only
(
"id"
,
"hostname"
,
"ip"
,
'platform'
,
"os"
,
"org_id"
,
)
for
asset
in
assets
:
...
...
apps/assets/forms/asset.py
View file @
3c825440
...
...
@@ -6,33 +6,27 @@ from django.utils.translation import gettext_lazy as _
from
common.utils
import
get_logger
from
orgs.mixins
import
OrgModelForm
from
..models
import
Asset
,
Protocol
,
Node
from
..models
import
Asset
,
Node
logger
=
get_logger
(
__file__
)
__all__
=
[
'AssetCreateForm'
,
'AssetUpdateForm'
,
'AssetBulkUpdateForm'
,
'ProtocolForm'
'AssetCreateForm'
,
'AssetUpdateForm'
,
'AssetBulkUpdateForm'
,
'ProtocolForm'
,
]
class
ProtocolForm
(
forms
.
ModelForm
):
class
Meta
:
model
=
Protocol
fields
=
[
'name'
,
'port'
]
widgets
=
{
'name'
:
forms
.
Select
(
attrs
=
{
'class'
:
'form-control protocol-name'
}),
'port'
:
forms
.
TextInput
(
attrs
=
{
'class'
:
'form-control protocol-port'
}),
}
class
ProtocolForm
(
forms
.
Form
):
name
=
forms
.
ChoiceField
(
choices
=
Asset
.
PROTOCOL_CHOICES
,
label
=
_
(
"Name"
),
initial
=
'ssh'
,
widget
=
forms
.
Select
(
attrs
=
{
'class'
:
'form-control protocol-name'
})
)
port
=
forms
.
IntegerField
(
max_value
=
65534
,
min_value
=
1
,
label
=
_
(
"Port"
),
initial
=
22
,
widget
=
forms
.
TextInput
(
attrs
=
{
'class'
:
'form-control protocol-port'
})
)
class
AssetCreateForm
(
OrgModelForm
):
PROTOCOL_CHOICES
=
Protocol
.
PROTOCOL_CHOICES
def
__init__
(
self
,
*
args
,
**
kwargs
):
super
()
.
__init__
(
*
args
,
**
kwargs
)
if
not
self
.
data
:
...
...
apps/assets/migrations/0029_auto_20190522_1114.py
View file @
3c825440
...
...
@@ -3,14 +3,6 @@
from
django.db
import
migrations
def
migrate_assets_protocol
(
apps
,
schema_editor
):
asset_model
=
apps
.
get_model
(
"assets"
,
"Asset"
)
db_alias
=
schema_editor
.
connection
.
alias
assets
=
asset_model
.
objects
.
using
(
db_alias
)
.
all
()
for
asset
in
assets
:
asset
.
protocols
.
create
(
name
=
asset
.
protocol
,
port
=
asset
.
port
)
class
Migration
(
migrations
.
Migration
):
dependencies
=
[
...
...
@@ -18,5 +10,4 @@ class Migration(migrations.Migration):
]
operations
=
[
migrations
.
RunPython
(
migrate_assets_protocol
),
]
apps/assets/migrations/0034_auto_20190705_1348.py
0 → 100644
View file @
3c825440
# Generated by Django 2.1.7 on 2019-07-05 05:48
from
django.db
import
migrations
from
django.db.models
import
F
from
django.db.models
import
CharField
,
Value
as
V
from
django.db.models.functions
import
Concat
def
migrate_assets_protocol
(
apps
,
schema_editor
):
asset_model
=
apps
.
get_model
(
"assets"
,
"Asset"
)
db_alias
=
schema_editor
.
connection
.
alias
assets
=
asset_model
.
objects
.
using
(
db_alias
)
.
all
()
.
annotate
(
protocols_new
=
Concat
(
'protocol'
,
V
(
'/'
),
'port'
,
output_field
=
CharField
(),
),
)
assets
.
update
(
protocols
=
F
(
'protocols_new'
))
class
Migration
(
migrations
.
Migration
):
dependencies
=
[
(
'assets'
,
'0033_auto_20190624_2108'
),
]
operations
=
[
migrations
.
RemoveField
(
model_name
=
'asset'
,
name
=
'protocols'
,
),
migrations
.
AddField
(
model_name
=
'asset'
,
name
=
'protocols'
,
field
=
CharField
(
blank
=
True
,
max_length
=
128
,
null
=
True
,
verbose_name
=
'Protocols'
),
),
migrations
.
RunPython
(
migrate_assets_protocol
),
]
apps/assets/models/asset.py
View file @
3c825440
...
...
@@ -6,16 +6,16 @@ import uuid
import
logging
import
random
from
functools
import
reduce
from
collections
import
OrderedDict
from
django.db
import
models
from
django.utils.translation
import
ugettext_lazy
as
_
from
django.core.validators
import
MinValueValidator
,
MaxValueValidator
from
.user
import
AdminUser
,
SystemUser
from
.utils
import
Connectivity
from
orgs.mixins
import
OrgModelMixin
,
OrgManager
__all__
=
[
'Asset'
,
'Protocol'
]
__all__
=
[
'Asset'
]
logger
=
logging
.
getLogger
(
__name__
)
...
...
@@ -45,8 +45,12 @@ class AssetQuerySet(models.QuerySet):
def
valid
(
self
):
return
self
.
active
()
def
has_protocol
(
self
,
name
):
return
self
.
filter
(
protocols__contains
=
name
)
class
Protocol
(
models
.
Model
):
class
ProtocolsMixin
:
protocols
=
''
PROTOCOL_SSH
=
'ssh'
PROTOCOL_RDP
=
'rdp'
PROTOCOL_TELNET
=
'telnet'
...
...
@@ -57,19 +61,42 @@ class Protocol(models.Model):
(
PROTOCOL_TELNET
,
'telnet (beta)'
),
(
PROTOCOL_VNC
,
'vnc'
),
)
PORT_VALIDATORS
=
[
MaxValueValidator
(
65535
),
MinValueValidator
(
1
)]
id
=
models
.
UUIDField
(
default
=
uuid
.
uuid4
,
primary_key
=
True
)
name
=
models
.
CharField
(
max_length
=
16
,
choices
=
PROTOCOL_CHOICES
,
default
=
PROTOCOL_SSH
,
verbose_name
=
_
(
"Name"
))
port
=
models
.
IntegerField
(
default
=
22
,
verbose_name
=
_
(
"Port"
),
validators
=
PORT_VALIDATORS
)
@property
def
protocols_as_list
(
self
):
if
not
self
.
protocols
:
return
[]
return
self
.
protocols
.
split
(
' '
)
def
__str__
(
self
):
return
"{}/{}"
.
format
(
self
.
name
,
self
.
port
)
@property
def
protocols_as_dict
(
self
):
d
=
OrderedDict
()
protocols
=
self
.
protocols_as_list
for
i
in
protocols
:
if
'/'
not
in
i
:
continue
name
,
port
=
i
.
split
(
'/'
)[:
2
]
if
not
all
([
name
,
port
]):
continue
d
[
name
]
=
int
(
port
)
return
d
@property
def
protocols_as_json
(
self
):
return
[
{
"name"
:
name
,
"port"
:
port
}
for
name
,
port
in
self
.
protocols_as_dict
.
items
()
]
def
has_protocol
(
self
,
name
):
return
name
in
self
.
protocols_as_dict
@property
def
ssh_port
(
self
):
return
self
.
protocols_as_dict
.
get
(
"ssh"
,
22
)
class
Asset
(
OrgModelMixin
):
class
Asset
(
ProtocolsMixin
,
OrgModelMixin
):
# Important
PLATFORM_CHOICES
=
(
(
'Linux'
,
'Linux'
),
...
...
@@ -84,12 +111,12 @@ class Asset(OrgModelMixin):
id
=
models
.
UUIDField
(
default
=
uuid
.
uuid4
,
primary_key
=
True
)
ip
=
models
.
CharField
(
max_length
=
128
,
verbose_name
=
_
(
'IP'
),
db_index
=
True
)
hostname
=
models
.
CharField
(
max_length
=
128
,
verbose_name
=
_
(
'Hostname'
))
protocol
=
models
.
CharField
(
max_length
=
128
,
default
=
Protocol
.
PROTOCOL_SSH
,
choices
=
Protocol
.
PROTOCOL_CHOICES
,
protocol
=
models
.
CharField
(
max_length
=
128
,
default
=
Protocol
sMixin
.
PROTOCOL_SSH
,
choices
=
Protocol
sMixin
.
PROTOCOL_CHOICES
,
verbose_name
=
_
(
'Protocol'
))
port
=
models
.
IntegerField
(
default
=
22
,
verbose_name
=
_
(
'Port'
))
protocols
=
models
.
ManyToManyField
(
'Protocol'
,
verbose_name
=
_
(
"Protocol
"
))
protocols
=
models
.
CharField
(
max_length
=
128
,
null
=
True
,
blank
=
True
,
verbose_name
=
_
(
"Protocols
"
))
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"
))
...
...
@@ -136,41 +163,9 @@ class Asset(OrgModelMixin):
warning
=
''
if
not
self
.
is_active
:
warning
+=
' inactive'
else
:
return
True
,
''
if
warning
:
return
False
,
warning
@property
def
protocols_name
(
self
):
names
=
[]
for
protocol
in
self
.
protocols
.
all
():
names
.
append
(
protocol
.
name
)
return
names
def
has_protocol
(
self
,
name
):
return
name
in
self
.
protocols_name
def
get_protocol_by_name
(
self
,
name
):
for
i
in
self
.
protocols
.
all
():
if
i
.
name
.
lower
()
==
name
.
lower
():
return
i
return
None
@property
def
protocol_ssh
(
self
):
return
self
.
get_protocol_by_name
(
"ssh"
)
@property
def
protocol_rdp
(
self
):
return
self
.
get_protocol_by_name
(
"rdp"
)
@property
def
ssh_port
(
self
):
if
self
.
protocol_ssh
:
port
=
self
.
protocol_ssh
.
port
else
:
port
=
22
return
port
return
True
,
warning
def
is_windows
(
self
):
if
self
.
platform
in
(
"Windows"
,
"Windows2016"
):
...
...
@@ -278,10 +273,7 @@ class Asset(OrgModelMixin):
'id'
:
self
.
id
,
'hostname'
:
self
.
hostname
,
'ip'
:
self
.
ip
,
'protocols'
:
[
{
"name"
:
p
.
name
,
"port"
:
p
.
port
}
for
p
in
self
.
protocols
.
all
()
],
'protocols'
:
self
.
protocols_as_list
,
'platform'
:
self
.
platform
,
}
}
...
...
@@ -314,7 +306,7 @@ class Asset(OrgModelMixin):
created_by
=
'Fake'
)
try
:
asset
.
save
()
asset
.
protocols
.
create
(
name
=
"ssh"
,
port
=
22
)
asset
.
protocols
=
'ssh/22'
if
nodes
and
len
(
nodes
)
>
3
:
_nodes
=
random
.
sample
(
nodes
,
3
)
else
:
...
...
apps/assets/serializers/asset.py
View file @
3c825440
# -*- coding: utf-8 -*-
#
from
rest_framework
import
serializers
from
rest_framework.validators
import
ValidationError
from
django.db.models
import
Prefetch
from
django.utils.translation
import
ugettext_lazy
as
_
from
orgs.mixins
import
BulkOrgResourceModelSerializer
from
common.serializers
import
AdaptedBulkListSerializer
from
..models
import
Asset
,
Protocol
,
Node
,
Label
from
..models
import
Asset
,
Node
,
Label
from
.base
import
ConnectivitySerializer
__all__
=
[
'AssetSerializer'
,
'AssetSimpleSerializer'
,
'Protocol
Serializer'
,
'ProtocolsRelated
Field'
,
'Protocol
s
Field'
,
]
class
ProtocolSerializer
(
serializers
.
ModelSerializer
):
class
Meta
:
model
=
Protocol
fields
=
[
"name"
,
"port"
]
class
ProtocolField
(
serializers
.
RegexField
):
protocols
=
'|'
.
join
(
dict
(
Asset
.
PROTOCOL_CHOICES
)
.
keys
())
default_error_messages
=
{
'invalid'
:
_
(
'Protocol format should {}/{}'
.
format
(
protocols
,
'1-65535'
))
}
regex
=
r'^(
%
s)/(\d{1,5})$'
%
protocols
def
__init__
(
self
,
*
args
,
**
kwargs
):
super
()
.
__init__
(
self
.
regex
,
**
kwargs
)
class
ProtocolsRelatedField
(
serializers
.
RelatedField
):
def
to_representation
(
self
,
value
):
return
str
(
value
)
def
to_internal_value
(
self
,
data
):
if
isinstance
(
data
,
dict
):
return
data
if
'/'
not
in
data
:
raise
ValidationError
(
"protocol not contain /: {}"
.
format
(
data
))
v
=
data
.
split
(
"/"
)
if
len
(
v
)
!=
2
:
raise
ValidationError
(
"protocol format should be name/port: {}"
.
format
(
data
))
name
,
port
=
v
cleaned_data
=
{
"name"
:
name
,
"port"
:
port
}
return
cleaned_data
def
validate_duplicate_protocols
(
values
):
errors
=
[]
names
=
[]
for
value
in
values
:
if
not
value
or
'/'
not
in
value
:
continue
name
=
value
.
split
(
'/'
)[
0
]
if
name
in
names
:
errors
.
append
(
_
(
"Protocol duplicate: {}"
)
.
format
(
name
))
names
.
append
(
name
)
errors
.
append
(
''
)
if
any
(
errors
):
raise
serializers
.
ValidationError
(
errors
)
class
ProtocolsField
(
serializers
.
ListField
):
default_validators
=
[
validate_duplicate_protocols
]
def
__init__
(
self
,
*
args
,
**
kwargs
):
kwargs
[
'child'
]
=
ProtocolField
()
kwargs
[
'allow_null'
]
=
True
kwargs
[
'allow_empty'
]
=
True
kwargs
[
'min_length'
]
=
1
kwargs
[
'max_length'
]
=
4
super
()
.
__init__
(
*
args
,
**
kwargs
)
def
to_representation
(
self
,
value
):
if
not
value
:
return
[]
return
value
.
split
(
' '
)
class
AssetSerializer
(
BulkOrgResourceModelSerializer
):
protocols
=
ProtocolsRelatedField
(
many
=
True
,
queryset
=
Protocol
.
objects
.
all
(),
label
=
_
(
"Protocols"
)
)
protocols
=
ProtocolsField
(
label
=
_
(
'Protocols'
),
required
=
False
)
connectivity
=
ConnectivitySerializer
(
read_only
=
True
,
label
=
_
(
"Connectivity"
))
"""
...
...
@@ -79,66 +97,32 @@ class AssetSerializer(BulkOrgResourceModelSerializer):
queryset
=
queryset
.
prefetch_related
(
Prefetch
(
'nodes'
,
queryset
=
Node
.
objects
.
all
()
.
only
(
'id'
)),
Prefetch
(
'labels'
,
queryset
=
Label
.
objects
.
all
()
.
only
(
'id'
)),
'protocols'
)
.
select_related
(
'admin_user'
,
'domain'
)
return
queryset
@staticmethod
def
validate_protocols
(
attr
):
protocols_serializer
=
ProtocolSerializer
(
data
=
attr
,
many
=
True
)
protocols_serializer
.
is_valid
(
raise_exception
=
True
)
protocols_name
=
[
i
.
get
(
"name"
,
"ssh"
)
for
i
in
attr
]
errors
=
[{}
for
i
in
protocols_name
]
for
i
,
name
in
enumerate
(
protocols_name
):
if
name
in
protocols_name
[:
i
]:
errors
[
i
]
=
{
"name"
:
_
(
"Protocol duplicate: {}"
)
.
format
(
name
)}
if
any
(
errors
):
raise
ValidationError
(
errors
)
return
attr
def
create
(
self
,
validated_data
):
def
compatible_with_old_protocol
(
self
,
validated_data
):
protocols_data
=
validated_data
.
pop
(
"protocols"
,
[])
# 兼容老的api
protocol
=
validated_data
.
get
(
"protocol"
)
name
=
validated_data
.
get
(
"protocol"
)
port
=
validated_data
.
get
(
"port"
)
if
not
protocols_data
and
protocol
and
port
:
protocols_data
=
[{
"name"
:
protocol
,
"port"
:
port
}]
if
not
protocols_data
and
name
and
port
:
protocols_data
.
insert
(
0
,
'/'
.
join
([
name
,
str
(
port
)]))
elif
not
name
and
not
port
and
protocols_data
:
protocol
=
protocols_data
[
0
]
.
split
(
'/'
)
validated_data
[
"protocol"
]
=
protocol
[
0
]
validated_data
[
"port"
]
=
int
(
protocol
[
1
])
if
validated_data
:
validated_data
[
"protocols"
]
=
' '
.
join
(
protocols_data
)
if
not
protocol
and
not
port
and
protocols_data
:
validated_data
[
"protocol"
]
=
protocols_data
[
0
][
"name"
]
validated_data
[
"port"
]
=
protocols_data
[
0
][
"port"
]
protocols_serializer
=
ProtocolSerializer
(
data
=
protocols_data
,
many
=
True
)
protocols_serializer
.
is_valid
(
raise_exception
=
True
)
protocols
=
protocols_serializer
.
save
()
def
create
(
self
,
validated_data
):
self
.
compatible_with_old_protocol
(
validated_data
)
instance
=
super
()
.
create
(
validated_data
)
instance
.
protocols
.
set
(
protocols
)
return
instance
def
update
(
self
,
instance
,
validated_data
):
protocols_data
=
validated_data
.
pop
(
"protocols"
,
[])
# 兼容老的api
protocol
=
validated_data
.
get
(
"protocol"
)
port
=
validated_data
.
get
(
"port"
)
if
not
protocols_data
and
protocol
and
port
:
protocols_data
=
[{
"name"
:
protocol
,
"port"
:
port
}]
if
not
protocol
and
not
port
and
protocols_data
:
validated_data
[
"protocol"
]
=
protocols_data
[
0
][
"name"
]
validated_data
[
"port"
]
=
protocols_data
[
0
][
"port"
]
protocols
=
None
if
protocols_data
:
protocols_serializer
=
ProtocolSerializer
(
data
=
protocols_data
,
many
=
True
)
protocols_serializer
.
is_valid
(
raise_exception
=
True
)
protocols
=
protocols_serializer
.
save
()
instance
=
super
()
.
update
(
instance
,
validated_data
)
if
protocols
:
instance
.
protocols
.
all
()
.
delete
()
instance
.
protocols
.
set
(
protocols
)
return
instance
self
.
compatible_with_old_protocol
(
validated_data
)
return
super
()
.
update
(
instance
,
validated_data
)
class
AssetSimpleSerializer
(
serializers
.
ModelSerializer
):
...
...
apps/assets/templates/assets/asset_detail.html
View file @
3c825440
...
...
@@ -70,11 +70,7 @@
</tr>
<tr>
<td>
{% trans 'Protocol' %}
</td>
<td>
{% for protocol in asset.protocols.all %}
<b>
{{ protocol }}
</b>
{% endfor %}
</td>
<td>
{{ asset.protocols }}
</td>
</tr>
<tr>
<td>
{% trans 'Admin user' %}:
</td>
...
...
apps/assets/views/asset.py
View file @
3c825440
# coding:utf-8
from
__future__
import
absolute_import
,
unicode_literals
import
csv
import
json
import
uuid
import
codecs
import
chardet
from
io
import
StringIO
from
django.db
import
transaction
from
django.contrib
import
messages
from
django.utils.translation
import
ugettext_lazy
as
_
from
django.views.generic
import
TemplateView
,
ListView
,
View
from
django.views.generic.edit
import
CreateView
,
DeleteView
,
FormView
,
UpdateView
from
django.views.generic
import
TemplateView
,
ListView
from
django.views.generic.edit
import
FormMixin
from
django.views.generic.edit
import
CreateView
,
DeleteView
,
UpdateView
from
django.urls
import
reverse_lazy
from
django.views.generic.detail
import
DetailView
from
django.http
import
HttpResponse
,
JsonResponse
from
django.views.decorators.csrf
import
csrf_exempt
from
django.utils.decorators
import
method_decorator
from
django.core.cache
import
cache
from
django.utils
import
timezone
from
django.shortcuts
import
redirect
from
django.contrib.messages.views
import
SuccessMessageMixin
from
django.forms.formsets
import
formset_factory
from
common.mixins
import
JSONResponseMixin
from
common.utils
import
get_object_or_none
,
get_logger
from
common.permissions
import
PermissionsMixin
,
IsOrgAdmin
,
IsValidUser
from
common.const
import
(
create_success_msg
,
update_success_msg
,
KEY_CACHE_RESOURCES_ID
)
from
..
import
forms
from
..models
import
Asset
,
AdminUser
,
SystemUser
,
Label
,
Node
,
Domain
from
..models
import
Asset
,
SystemUser
,
Label
,
Node
__all__
=
[
...
...
@@ -87,7 +75,7 @@ class UserAssetListView(PermissionsMixin, TemplateView):
return
super
()
.
get_context_data
(
**
kwargs
)
class
AssetCreateView
(
PermissionsMixin
,
SuccessMessageMixin
,
Cre
ateView
):
class
AssetCreateView
(
PermissionsMixin
,
FormMixin
,
Templ
ateView
):
model
=
Asset
form_class
=
forms
.
AssetCreateForm
template_name
=
'assets/asset_create.html'
...
...
@@ -112,16 +100,6 @@ class AssetCreateView(PermissionsMixin, SuccessMessageMixin, CreateView):
formset
=
ProtocolFormset
()
return
formset
def
form_valid
(
self
,
form
):
formset
=
self
.
get_protocol_formset
()
valid
=
formset
.
is_valid
()
if
not
valid
:
return
self
.
form_invalid
(
form
)
protocols
=
formset
.
save
()
instance
=
super
()
.
form_valid
(
form
)
instance
.
protocols
.
set
(
protocols
)
return
instance
def
get_context_data
(
self
,
**
kwargs
):
formset
=
self
.
get_protocol_formset
()
context
=
{
...
...
@@ -132,8 +110,32 @@ class AssetCreateView(PermissionsMixin, SuccessMessageMixin, CreateView):
kwargs
.
update
(
context
)
return
super
()
.
get_context_data
(
**
kwargs
)
def
get_success_message
(
self
,
cleaned_data
):
return
create_success_msg
%
({
"name"
:
cleaned_data
[
"hostname"
]})
class
AssetUpdateView
(
PermissionsMixin
,
UpdateView
):
model
=
Asset
form_class
=
forms
.
AssetUpdateForm
template_name
=
'assets/asset_update.html'
success_url
=
reverse_lazy
(
'assets:asset-list'
)
permission_classes
=
[
IsOrgAdmin
]
def
get_protocol_formset
(
self
):
ProtocolFormset
=
formset_factory
(
forms
.
ProtocolForm
,
extra
=
0
,
min_num
=
1
,
max_num
=
5
)
if
self
.
request
.
method
==
"POST"
:
formset
=
ProtocolFormset
(
self
.
request
.
POST
)
else
:
initial_data
=
self
.
object
.
protocols_as_json
formset
=
ProtocolFormset
(
initial
=
initial_data
)
return
formset
def
get_context_data
(
self
,
**
kwargs
):
formset
=
self
.
get_protocol_formset
()
context
=
{
'app'
:
_
(
'Assets'
),
'action'
:
_
(
'Update asset'
),
'formset'
:
formset
,
}
kwargs
.
update
(
context
)
return
super
()
.
get_context_data
(
**
kwargs
)
class
AssetBulkUpdateView
(
PermissionsMixin
,
ListView
):
...
...
@@ -177,36 +179,6 @@ class AssetBulkUpdateView(PermissionsMixin, ListView):
return
super
()
.
get_context_data
(
**
kwargs
)
class
AssetUpdateView
(
PermissionsMixin
,
SuccessMessageMixin
,
UpdateView
):
model
=
Asset
form_class
=
forms
.
AssetUpdateForm
template_name
=
'assets/asset_update.html'
success_url
=
reverse_lazy
(
'assets:asset-list'
)
permission_classes
=
[
IsOrgAdmin
]
def
get_protocol_formset
(
self
):
ProtocolFormset
=
formset_factory
(
forms
.
ProtocolForm
,
extra
=
0
,
min_num
=
1
,
max_num
=
5
)
if
self
.
request
.
method
==
"POST"
:
formset
=
ProtocolFormset
(
self
.
request
.
POST
)
else
:
initial_data
=
[{
"name"
:
p
.
name
,
"port"
:
p
.
port
}
for
p
in
self
.
object
.
protocols
.
all
()]
formset
=
ProtocolFormset
(
initial
=
initial_data
)
return
formset
def
get_context_data
(
self
,
**
kwargs
):
formset
=
self
.
get_protocol_formset
()
context
=
{
'app'
:
_
(
'Assets'
),
'action'
:
_
(
'Update asset'
),
'formset'
:
formset
,
}
kwargs
.
update
(
context
)
return
super
()
.
get_context_data
(
**
kwargs
)
def
get_success_message
(
self
,
cleaned_data
):
return
update_success_msg
%
({
"name"
:
cleaned_data
[
"hostname"
]})
class
AssetDeleteView
(
PermissionsMixin
,
DeleteView
):
model
=
Asset
template_name
=
'delete_confirm.html'
...
...
@@ -222,7 +194,7 @@ class AssetDetailView(PermissionsMixin, DetailView):
def
get_queryset
(
self
):
return
super
()
.
get_queryset
()
.
prefetch_related
(
"nodes"
,
"labels"
,
"protocols"
"nodes"
,
"labels"
,
)
.
select_related
(
'admin_user'
,
'domain'
)
def
get_context_data
(
self
,
**
kwargs
):
...
...
apps/ops/templates/ops/command_execution_create.html
View file @
3c825440
...
...
@@ -135,9 +135,7 @@ function getSelectedAssetsNode() {
var
assetsNode
=
[];
nodes
.
forEach
(
function
(
node
)
{
if
(
node
.
meta
.
type
===
'asset'
&&
!
node
.
isHidden
)
{
var
protocols
=
$
.
map
(
node
.
meta
.
asset
.
protocols
,
function
(
v
)
{
return
v
.
name
});
var
protocols
=
node
.
meta
.
asset
.
protocols
;
if
(
assetsNodeId
.
indexOf
(
node
.
id
)
===
-
1
&&
protocols
.
indexOf
(
"ssh"
)
>
-
1
)
{
assetsNodeId
.
push
(
node
.
id
);
assetsNode
.
push
(
node
)
...
...
apps/perms/utils/asset_permission.py
View file @
3c825440
...
...
@@ -126,7 +126,7 @@ class GenerateTree:
for
asset
,
system_users
in
assets
.
items
():
self
.
add_asset
(
asset
,
system_users
)
#@timeit
#
#
@timeit
def
add_asset
(
self
,
asset
,
system_users
=
None
):
nodes
=
asset
.
nodes
.
all
()
nodes
=
self
.
node_util
.
get_nodes_by_queryset
(
nodes
)
...
...
@@ -492,13 +492,21 @@ class AssetPermissionUtil(AssetPermissionCacheMixin):
for
node
in
nodes
:
pattern
.
add
(
r'^{0}$|^{0}:'
.
format
(
node
.
key
))
pattern
=
'|'
.
join
(
list
(
pattern
))
print
(
self
.
object
.
username
)
print
(
pattern
)
print
(
"Start get nodes assets"
)
clock1
=
time
.
clock
()
if
pattern
:
assets
=
Asset
.
objects
.
filter
(
nodes__key__regex
=
pattern
)
\
.
prefetch_related
(
'nodes'
,
"protocols"
)
\
assets
=
Asset
.
objects
.
filter
(
nodes__key__regex
=
pattern
)
\
.
only
(
*
self
.
assets_only
)
\
.
distinct
()
# .prefetch_related('nodes')\
else
:
assets
=
[]
assets
=
list
(
assets
)
print
(
"get nodes assets using: {}"
.
format
(
time
.
clock
()
-
clock1
))
print
(
len
(
assets
))
return
[]
self
.
tree
.
add_assets_without_system_users
(
assets
)
assets
=
self
.
tree
.
get_assets
()
self
.
_assets
=
assets
...
...
@@ -598,7 +606,7 @@ def parse_asset_to_tree_node(node, asset, system_users):
'id'
:
asset
.
id
,
'hostname'
:
asset
.
hostname
,
'ip'
:
asset
.
ip
,
'protocols'
:
[
str
(
p
)
for
p
in
asset
.
protocols
.
all
()]
,
'protocols'
:
asset
.
protocols_as_list
,
'platform'
:
asset
.
platform
,
'domain'
:
None
if
not
asset
.
domain
else
asset
.
domain
.
id
,
'is_active'
:
asset
.
is_active
,
...
...
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