Merge pull request #9380 from jumpserver/pr@dev@perf_asset_info

perf: 优化 asset info
pull/9384/head
老广 2023-01-31 19:37:51 +08:00 committed by GitHub
commit fa6d819f10
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
36 changed files with 181 additions and 162 deletions

View File

@ -10,12 +10,12 @@
login_password: "{{ jms_account.secret }}" login_password: "{{ jms_account.secret }}"
login_host: "{{ jms_asset.address }}" login_host: "{{ jms_asset.address }}"
login_port: "{{ jms_asset.port }}" login_port: "{{ jms_asset.port }}"
login_database: "{{ jms_asset.specific.db_name }}" login_database: "{{ jms_asset.spec_info.db_name }}"
ssl: "{{ jms_asset.specific.use_ssl }}" ssl: "{{ jms_asset.spec_info.use_ssl }}"
ssl_ca_certs: "{{ jms_asset.specific.ca_cert }}" ssl_ca_certs: "{{ jms_asset.secret_info.ca_cert }}"
ssl_certfile: "{{ jms_asset.specific.client_key }}" ssl_certfile: "{{ jms_asset.secret_info.client_key }}"
connection_options: connection_options:
- tlsAllowInvalidHostnames: "{{ jms_asset.specific.allow_invalid_cert}}" - tlsAllowInvalidHostnames: "{{ jms_asset.spec_info.allow_invalid_cert}}"
register: db_info register: db_info
- name: Display MongoDB version - name: Display MongoDB version
@ -29,13 +29,13 @@
login_password: "{{ jms_account.secret }}" login_password: "{{ jms_account.secret }}"
login_host: "{{ jms_asset.address }}" login_host: "{{ jms_asset.address }}"
login_port: "{{ jms_asset.port }}" login_port: "{{ jms_asset.port }}"
login_database: "{{ jms_asset.specific.db_name }}" login_database: "{{ jms_asset.spec_info.db_name }}"
ssl: "{{ jms_asset.specific.use_ssl }}" ssl: "{{ jms_asset.spec_info.use_ssl }}"
ssl_ca_certs: "{{ jms_asset.specific.ca_cert }}" ssl_ca_certs: "{{ jms_asset.secret_info.ca_cert }}"
ssl_certfile: "{{ jms_asset.specific.client_key }}" ssl_certfile: "{{ jms_asset.secret_info.client_key }}"
connection_options: connection_options:
- tlsAllowInvalidHostnames: "{{ jms_asset.specific.allow_invalid_cert}}" - tlsAllowInvalidHostnames: "{{ jms_asset.spec_info.allow_invalid_cert}}"
db: "{{ jms_asset.specific.db_name }}" db: "{{ jms_asset.spec_info.db_name }}"
name: "{{ account.username }}" name: "{{ account.username }}"
password: "{{ account.secret }}" password: "{{ account.secret }}"
when: db_info is succeeded when: db_info is succeeded
@ -47,12 +47,12 @@
login_password: "{{ account.secret }}" login_password: "{{ account.secret }}"
login_host: "{{ jms_asset.address }}" login_host: "{{ jms_asset.address }}"
login_port: "{{ jms_asset.port }}" login_port: "{{ jms_asset.port }}"
login_database: "{{ jms_asset.specific.db_name }}" login_database: "{{ jms_asset.spec_info.db_name }}"
ssl: "{{ jms_asset.specific.use_ssl }}" ssl: "{{ jms_asset.spec_info.use_ssl }}"
ssl_ca_certs: "{{ jms_asset.specific.ca_cert }}" ssl_ca_certs: "{{ jms_asset.secret_info.ca_cert }}"
ssl_certfile: "{{ jms_asset.specific.client_key }}" ssl_certfile: "{{ jms_asset.secret_info.client_key }}"
connection_options: connection_options:
- tlsAllowInvalidHostnames: "{{ jms_asset.specific.allow_invalid_cert}}" - tlsAllowInvalidHostnames: "{{ jms_asset.spec_info.allow_invalid_cert}}"
when: when:
- db_info is succeeded - db_info is succeeded
- change_info is succeeded - change_info is succeeded

View File

@ -10,7 +10,7 @@
login_password: "{{ jms_account.secret }}" login_password: "{{ jms_account.secret }}"
login_host: "{{ jms_asset.address }}" login_host: "{{ jms_asset.address }}"
login_port: "{{ jms_asset.port }}" login_port: "{{ jms_asset.port }}"
login_database: "{{ jms_asset.specific.db_name }}" login_database: "{{ jms_asset.spec_info.db_name }}"
mode: "{{ jms_account.mode }}" mode: "{{ jms_account.mode }}"
register: db_info register: db_info
@ -25,7 +25,7 @@
login_password: "{{ jms_account.secret }}" login_password: "{{ jms_account.secret }}"
login_host: "{{ jms_asset.address }}" login_host: "{{ jms_asset.address }}"
login_port: "{{ jms_asset.port }}" login_port: "{{ jms_asset.port }}"
login_database: "{{ jms_asset.specific.db_name }}" login_database: "{{ jms_asset.spec_info.db_name }}"
mode: "{{ jms_account.mode }}" mode: "{{ jms_account.mode }}"
name: "{{ account.username }}" name: "{{ account.username }}"
password: "{{ account.secret }}" password: "{{ account.secret }}"
@ -38,8 +38,8 @@
login_password: "{{ account.secret }}" login_password: "{{ account.secret }}"
login_host: "{{ jms_asset.address }}" login_host: "{{ jms_asset.address }}"
login_port: "{{ jms_asset.port }}" login_port: "{{ jms_asset.port }}"
login_database: "{{ jms_asset.specific.db_name }}" login_database: "{{ jms_asset.spec_info.db_name }}"
mode: "{{ account.mode }}" mode: "{{ account.mode }}"
when: when:
- db_info is succeeded - db_info is succeeded
- change_info is succeeded - change_info is succeeded

View File

@ -10,7 +10,7 @@
login_password: "{{ jms_account.secret }}" login_password: "{{ jms_account.secret }}"
login_host: "{{ jms_asset.address }}" login_host: "{{ jms_asset.address }}"
login_port: "{{ jms_asset.port }}" login_port: "{{ jms_asset.port }}"
login_db: "{{ jms_asset.specific.db_name }}" login_db: "{{ jms_asset.spec_info.db_name }}"
register: db_info register: db_info
- name: Display PostgreSQL version - name: Display PostgreSQL version
@ -24,7 +24,7 @@
login_password: "{{ jms_account.secret }}" login_password: "{{ jms_account.secret }}"
login_host: "{{ jms_asset.address }}" login_host: "{{ jms_asset.address }}"
login_port: "{{ jms_asset.port }}" login_port: "{{ jms_asset.port }}"
db: "{{ jms_asset.specific.db_name }}" db: "{{ jms_asset.spec_info.db_name }}"
name: "{{ account.username }}" name: "{{ account.username }}"
password: "{{ account.secret }}" password: "{{ account.secret }}"
when: db_info is succeeded when: db_info is succeeded
@ -36,7 +36,7 @@
login_password: "{{ account.secret }}" login_password: "{{ account.secret }}"
login_host: "{{ jms_asset.address }}" login_host: "{{ jms_asset.address }}"
login_port: "{{ jms_asset.port }}" login_port: "{{ jms_asset.port }}"
db: "{{ jms_asset.specific.db_name }}" db: "{{ jms_asset.spec_info.db_name }}"
when: when:
- db_info is succeeded - db_info is succeeded
- change_info is succeeded - change_info is succeeded

View File

@ -10,38 +10,38 @@
login_password: "{{ jms_account.secret }}" login_password: "{{ jms_account.secret }}"
login_host: "{{ jms_asset.address }}" login_host: "{{ jms_asset.address }}"
login_port: "{{ jms_asset.port }}" login_port: "{{ jms_asset.port }}"
name: '{{ jms_asset.specific.db_name }}' name: '{{ jms_asset.spec_info.db_name }}'
script: | script: |
SELECT @@version SELECT @@version
register: db_info register: db_info
- name: SQLServer version - name: SQLServer version
set_fact: set_fact:
info: info:
version: "{{ db_info.query_results[0][0][0][0].splitlines()[0] }}" version: "{{ db_info.query_results[0][0][0][0].splitlines()[0] }}"
- debug: - debug:
var: info var: info
- name: Change SQLServer password - name: Change SQLServer password
community.general.mssql_script: community.general.mssql_script:
login_user: "{{ jms_account.username }}" login_user: "{{ jms_account.username }}"
login_password: "{{ jms_account.secret }}" login_password: "{{ jms_account.secret }}"
login_host: "{{ jms_asset.address }}" login_host: "{{ jms_asset.address }}"
login_port: "{{ jms_asset.port }}" login_port: "{{ jms_asset.port }}"
name: '{{ jms_asset.specific.db_name }}' name: '{{ jms_asset.spec_info.db_name }}'
script: "ALTER LOGIN {{ account.username }} WITH PASSWORD = '{{ account.secret }}'; select @@version" script: "ALTER LOGIN {{ account.username }} WITH PASSWORD = '{{ account.secret }}'; select @@version"
when: db_info is succeeded when: db_info is succeeded
register: change_info register: change_info
- name: Verify password - name: Verify password
community.general.mssql_script: community.general.mssql_script:
login_user: "{{ account.username }}" login_user: "{{ account.username }}"
login_password: "{{ account.secret }}" login_password: "{{ account.secret }}"
login_host: "{{ jms_asset.address }}" login_host: "{{ jms_asset.address }}"
login_port: "{{ jms_asset.port }}" login_port: "{{ jms_asset.port }}"
name: '{{ jms_asset.specific.db_name }}' name: '{{ jms_asset.spec_info.db_name }}'
script: | script: |
SELECT @@version SELECT @@version
when: when:
- db_info is succeeded - db_info is succeeded
- change_info is succeeded - change_info is succeeded

View File

@ -10,12 +10,12 @@
login_password: "{{ jms_account.secret }}" login_password: "{{ jms_account.secret }}"
login_host: "{{ jms_asset.address }}" login_host: "{{ jms_asset.address }}"
login_port: "{{ jms_asset.port }}" login_port: "{{ jms_asset.port }}"
login_database: "{{ jms_asset.specific.db_name }}" login_database: "{{ jms_asset.spec_info.db_name }}"
ssl: "{{ jms_asset.specific.use_ssl }}" ssl: "{{ jms_asset.spec_info.use_ssl }}"
ssl_ca_certs: "{{ jms_asset.specific.ca_cert }}" ssl_ca_certs: "{{ jms_asset.secret_info.ca_cert }}"
ssl_certfile: "{{ jms_asset.specific.client_key }}" ssl_certfile: "{{ jms_asset.secret_info.client_key }}"
connection_options: connection_options:
- tlsAllowInvalidHostnames: "{{ jms_asset.specific.allow_invalid_cert}}" - tlsAllowInvalidHostnames: "{{ jms_asset.spec_info.allow_invalid_cert}}"
filter: users filter: users
register: db_info register: db_info

View File

@ -10,7 +10,7 @@
login_password: "{{ jms_account.secret }}" login_password: "{{ jms_account.secret }}"
login_host: "{{ jms_asset.address }}" login_host: "{{ jms_asset.address }}"
login_port: "{{ jms_asset.port }}" login_port: "{{ jms_asset.port }}"
login_database: "{{ jms_asset.specific.db_name }}" login_database: "{{ jms_asset.spec_info.db_name }}"
mode: "{{ jms_account.mode }}" mode: "{{ jms_account.mode }}"
filter: users filter: users
register: db_info register: db_info

View File

@ -10,7 +10,7 @@
login_password: "{{ jms_account.secret }}" login_password: "{{ jms_account.secret }}"
login_host: "{{ jms_asset.address }}" login_host: "{{ jms_asset.address }}"
login_port: "{{ jms_asset.port }}" login_port: "{{ jms_asset.port }}"
login_db: "{{ jms_asset.specific.db_name }}" login_db: "{{ jms_asset.spec_info.db_name }}"
filter: "roles" filter: "roles"
register: db_info register: db_info

View File

@ -10,9 +10,9 @@
login_password: "{{ jms_account.secret }}" login_password: "{{ jms_account.secret }}"
login_host: "{{ jms_asset.address }}" login_host: "{{ jms_asset.address }}"
login_port: "{{ jms_asset.port }}" login_port: "{{ jms_asset.port }}"
login_database: "{{ jms_asset.specific.db_name }}" login_database: "{{ jms_asset.spec_info.db_name }}"
ssl: "{{ jms_asset.specific.use_ssl }}" ssl: "{{ jms_asset.spec_info.use_ssl }}"
ssl_ca_certs: "{{ jms_asset.specific.ca_cert }}" ssl_ca_certs: "{{ jms_asset.secret_info.ca_cert }}"
ssl_certfile: "{{ jms_asset.specific.client_key }}" ssl_certfile: "{{ jms_asset.secret_info.client_key }}"
connection_options: connection_options:
- tlsAllowInvalidHostnames: "{{ jms_asset.specific.allow_invalid_cert}}" - tlsAllowInvalidHostnames: "{{ jms_asset.spec_info.allow_invalid_cert}}"

View File

@ -10,5 +10,5 @@
login_password: "{{ jms_account.secret }}" login_password: "{{ jms_account.secret }}"
login_host: "{{ jms_asset.address }}" login_host: "{{ jms_asset.address }}"
login_port: "{{ jms_asset.port }}" login_port: "{{ jms_asset.port }}"
login_database: "{{ jms_asset.specific.db_name }}" login_database: "{{ jms_asset.spec_info.db_name }}"
mode: "{{ jms_account.mode }}" mode: "{{ jms_account.mode }}"

View File

@ -10,4 +10,4 @@
login_password: "{{ account.secret }}" login_password: "{{ account.secret }}"
login_host: "{{ jms_asset.address }}" login_host: "{{ jms_asset.address }}"
login_port: "{{ jms_asset.port }}" login_port: "{{ jms_asset.port }}"
db: "{{ jms_asset.specific.db_name }}" db: "{{ jms_asset.spec_info.db_name }}"

View File

@ -10,6 +10,6 @@
login_password: "{{ jms_account.secret }}" login_password: "{{ jms_account.secret }}"
login_host: "{{ jms_asset.address }}" login_host: "{{ jms_asset.address }}"
login_port: "{{ jms_asset.port }}" login_port: "{{ jms_asset.port }}"
name: '{{ jms_asset.specific.db_name }}' name: '{{ jms_asset.spec_info.db_name }}'
script: | script: |
SELECT @@version SELECT @@version

View File

@ -1,7 +1,7 @@
from django.db.models import QuerySet from django.db.models import QuerySet
from common.utils import get_logger
from accounts.const import AutomationTypes, Connectivity from accounts.const import AutomationTypes, Connectivity
from common.utils import get_logger
from ..base.manager import PushOrVerifyHostCallbackMixin, AccountBasePlaybookManager from ..base.manager import PushOrVerifyHostCallbackMixin, AccountBasePlaybookManager
logger = get_logger(__name__) logger = get_logger(__name__)
@ -29,4 +29,4 @@ class VerifyAccountManager(PushOrVerifyHostCallbackMixin, AccountBasePlaybookMan
def on_host_error(self, host, error, result): def on_host_error(self, host, error, result):
account = self.host_account_mapper.get(host) account = self.host_account_mapper.get(host)
account.set_connectivity(Connectivity.FAILED) account.set_connectivity(Connectivity.ERR)

View File

@ -29,8 +29,7 @@ class Migration(migrations.Migration):
('id', models.UUIDField(default=uuid.uuid4, primary_key=True, serialize=False)), ('id', models.UUIDField(default=uuid.uuid4, primary_key=True, serialize=False)),
('org_id', ('org_id',
models.CharField(blank=True, db_index=True, default='', max_length=36, verbose_name='Organization')), models.CharField(blank=True, db_index=True, default='', max_length=36, verbose_name='Organization')),
('connectivity', models.CharField(choices=[('unknown', 'Unknown'), ('ok', 'Ok'), ('failed', 'Failed')], ('connectivity', models.CharField(choices=[('-', 'Unknown'), ('ok', 'Ok'), ('err', 'Error')], default='-', max_length=16, verbose_name='Connectivity')),
default='unknown', max_length=16, verbose_name='Connectivity')),
('date_verified', models.DateTimeField(null=True, verbose_name='Date verified')), ('date_verified', models.DateTimeField(null=True, verbose_name='Date verified')),
('name', models.CharField(max_length=128, verbose_name='Name')), ('name', models.CharField(max_length=128, verbose_name='Name')),
('username', models.CharField(blank=True, db_index=True, max_length=128, verbose_name='Username')), ('username', models.CharField(blank=True, db_index=True, max_length=128, verbose_name='Username')),

View File

@ -50,7 +50,7 @@ class BaseAccount(JMSOrgBaseModel):
return bool(self.username) return bool(self.username)
@property @property
def specific(self): def spec_info(self):
data = {} data = {}
if self.secret_type != SecretType.SSH_KEY: if self.secret_type != SecretType.SSH_KEY:
return data return data

View File

@ -68,14 +68,14 @@ class BaseAccountSerializer(AuthValidateMixin, BulkOrgResourceModelSerializer):
fields_mini = ['id', 'name', 'username'] fields_mini = ['id', 'name', 'username']
fields_small = fields_mini + [ fields_small = fields_mini + [
'secret_type', 'secret', 'has_secret', 'passphrase', 'secret_type', 'secret', 'has_secret', 'passphrase',
'privileged', 'is_active', 'specific', 'privileged', 'is_active', 'spec_info',
] ]
fields_other = ['created_by', 'date_created', 'date_updated', 'comment'] fields_other = ['created_by', 'date_created', 'date_updated', 'comment']
fields = fields_small + fields_other fields = fields_small + fields_other
read_only_fields = [ read_only_fields = [
'has_secret', 'specific', 'has_secret', 'spec_info',
'date_verified', 'created_by', 'date_created', 'date_verified', 'created_by', 'date_created',
] ]
extra_kwargs = { extra_kwargs = {
'specific': {'label': _('Specific')}, 'spec_info': {'label': _('Spec info')},
} }

View File

@ -2,7 +2,6 @@
# #
import django_filters import django_filters
from django.db.models import Q from django.db.models import Q
from django.utils.translation import ugettext_lazy as _
from rest_framework.decorators import action from rest_framework.decorators import action
from rest_framework.response import Response from rest_framework.response import Response
@ -72,11 +71,13 @@ class AssetViewSet(SuggestionMixin, NodeFilterMixin, OrgBulkModelViewSet):
("platform", serializers.PlatformSerializer), ("platform", serializers.PlatformSerializer),
("suggestion", serializers.MiniAssetSerializer), ("suggestion", serializers.MiniAssetSerializer),
("gateways", serializers.GatewaySerializer), ("gateways", serializers.GatewaySerializer),
("spec_info", serializers.SpecSerializer),
) )
rbac_perms = ( rbac_perms = (
("match", "assets.match_asset"), ("match", "assets.match_asset"),
("platform", "assets.view_platform"), ("platform", "assets.view_platform"),
("gateways", "assets.view_gateway"), ("gateways", "assets.view_gateway"),
("spec_info", "assets.view_asset"),
) )
extra_filter_backends = [LabelFilterBackend, IpInFilterBackend, NodeFilterBackend] extra_filter_backends = [LabelFilterBackend, IpInFilterBackend, NodeFilterBackend]
@ -94,6 +95,11 @@ class AssetViewSet(SuggestionMixin, NodeFilterMixin, OrgBulkModelViewSet):
serializer = super().get_serializer(instance=asset.platform) serializer = super().get_serializer(instance=asset.platform)
return Response(serializer.data) return Response(serializer.data)
@action(methods=["GET"], detail=True, url_path="spec-info")
def spec_info(self, *args, **kwargs):
asset = super().get_object()
return Response(asset.spec_info)
@action(methods=["GET"], detail=True, url_path="gateways") @action(methods=["GET"], detail=True, url_path="gateways")
def gateways(self, *args, **kwargs): def gateways(self, *args, **kwargs):
asset = self.get_object() asset = self.get_object()

View File

@ -10,12 +10,12 @@
login_password: "{{ jms_account.secret }}" login_password: "{{ jms_account.secret }}"
login_host: "{{ jms_asset.address }}" login_host: "{{ jms_asset.address }}"
login_port: "{{ jms_asset.port }}" login_port: "{{ jms_asset.port }}"
login_database: "{{ jms_asset.specific.db_name }}" login_database: "{{ jms_asset.spec_info.db_name }}"
ssl: "{{ jms_asset.specific.use_ssl }}" ssl: "{{ jms_asset.spec_info.use_ssl }}"
ssl_ca_certs: "{{ jms_asset.specific.ca_cert }}" ssl_ca_certs: "{{ jms_asset.secret_info.ca_cert }}"
ssl_certfile: "{{ jms_asset.specific.client_key }}" ssl_certfile: "{{ jms_asset.secret_info.client_key }}"
connection_options: connection_options:
- tlsAllowInvalidHostnames: "{{ jms_asset.specific.allow_invalid_cert}}" - tlsAllowInvalidHostnames: "{{ jms_asset.spec_info.allow_invalid_cert}}"
register: db_info register: db_info
- name: Define info by set_fact - name: Define info by set_fact

View File

@ -10,7 +10,7 @@
login_password: "{{ jms_account.secret }}" login_password: "{{ jms_account.secret }}"
login_host: "{{ jms_asset.address }}" login_host: "{{ jms_asset.address }}"
login_port: "{{ jms_asset.port }}" login_port: "{{ jms_asset.port }}"
login_database: "{{ jms_asset.specific.db_name }}" login_database: "{{ jms_asset.spec_info.db_name }}"
mode: "{{ jms_account.mode }}" mode: "{{ jms_account.mode }}"
register: db_info register: db_info

View File

@ -10,7 +10,7 @@
login_password: "{{ jms_account.secret }}" login_password: "{{ jms_account.secret }}"
login_host: "{{ jms_asset.address }}" login_host: "{{ jms_asset.address }}"
login_port: "{{ jms_asset.port }}" login_port: "{{ jms_asset.port }}"
login_db: "{{ jms_asset.specific.db_name }}" login_db: "{{ jms_asset.spec_info.db_name }}"
register: db_info register: db_info
- name: Define info by set_fact - name: Define info by set_fact

View File

@ -10,9 +10,9 @@
login_password: "{{ jms_account.secret }}" login_password: "{{ jms_account.secret }}"
login_host: "{{ jms_asset.address }}" login_host: "{{ jms_asset.address }}"
login_port: "{{ jms_asset.port }}" login_port: "{{ jms_asset.port }}"
login_database: "{{ jms_asset.specific.db_name }}" login_database: "{{ jms_asset.spec_info.db_name }}"
ssl: "{{ jms_asset.specific.use_ssl }}" ssl: "{{ jms_asset.spec_info.use_ssl }}"
ssl_ca_certs: "{{ jms_asset.specific.ca_cert }}" ssl_ca_certs: "{{ jms_asset.secret_info.ca_cert }}"
ssl_certfile: "{{ jms_asset.specific.client_key }}" ssl_certfile: "{{ jms_asset.secret_info.client_key }}"
connection_options: connection_options:
- tlsAllowInvalidHostnames: "{{ jms_asset.specific.allow_invalid_cert}}" - tlsAllowInvalidHostnames: "{{ jms_asset.spec_info.allow_invalid_cert}}"

View File

@ -10,5 +10,5 @@
login_password: "{{ jms_account.secret }}" login_password: "{{ jms_account.secret }}"
login_host: "{{ jms_asset.address }}" login_host: "{{ jms_asset.address }}"
login_port: "{{ jms_asset.port }}" login_port: "{{ jms_asset.port }}"
login_database: "{{ jms_asset.specific.db_name }}" login_database: "{{ jms_asset.spec_info.db_name }}"
mode: "{{ jms_account.mode }}" mode: "{{ jms_account.mode }}"

View File

@ -10,4 +10,4 @@
login_password: "{{ jms_account.secret }}" login_password: "{{ jms_account.secret }}"
login_host: "{{ jms_asset.address }}" login_host: "{{ jms_asset.address }}"
login_port: "{{ jms_asset.port }}" login_port: "{{ jms_asset.port }}"
login_db: "{{ jms_asset.specific.db_name }}" login_db: "{{ jms_asset.spec_info.db_name }}"

View File

@ -10,6 +10,6 @@
login_password: "{{ jms_account.secret }}" login_password: "{{ jms_account.secret }}"
login_host: "{{ jms_asset.address }}" login_host: "{{ jms_asset.address }}"
login_port: "{{ jms_asset.port }}" login_port: "{{ jms_asset.port }}"
name: '{{ jms_asset.specific.db_name }}' name: '{{ jms_asset.spec_info.db_name }}'
script: | script: |
SELECT @@version SELECT @@version

View File

@ -1,5 +1,5 @@
from common.utils import get_logger
from assets.const import AutomationTypes, Connectivity from assets.const import AutomationTypes, Connectivity
from common.utils import get_logger
from ..base.manager import BasePlaybookManager from ..base.manager import BasePlaybookManager
logger = get_logger(__name__) logger = get_logger(__name__)
@ -28,7 +28,7 @@ class PingManager(BasePlaybookManager):
def on_host_error(self, host, error, result): def on_host_error(self, host, error, result):
asset, account = self.host_asset_and_account_mapper.get(host) asset, account = self.host_asset_and_account_mapper.get(host)
asset.set_connectivity(Connectivity.FAILED) asset.set_connectivity(Connectivity.ERR)
if not account: if not account:
return return
account.set_connectivity(Connectivity.FAILED) account.set_connectivity(Connectivity.ERR)

View File

@ -1,12 +1,12 @@
import socket import socket
import paramiko
import paramiko
from django.utils import timezone from django.utils import timezone
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from common.utils import get_logger
from assets.models import Gateway
from assets.const import AutomationTypes, Connectivity from assets.const import AutomationTypes, Connectivity
from assets.models import Gateway
from common.utils import get_logger
logger = get_logger(__name__) logger = get_logger(__name__)
@ -100,10 +100,10 @@ class PingGatewayManager:
@staticmethod @staticmethod
def on_host_error(gateway, account, error): def on_host_error(gateway, account, error):
logger.info('\033[31m {} -> {} 原因: {} \033[0m\n'.format(gateway, account, error)) logger.info('\033[31m {} -> {} 原因: {} \033[0m\n'.format(gateway, account, error))
gateway.set_connectivity(Connectivity.FAILED) gateway.set_connectivity(Connectivity.ERR)
if not account: if not account:
return return
account.set_connectivity(Connectivity.FAILED) account.set_connectivity(Connectivity.ERR)
@staticmethod @staticmethod
def before_runner_start(): def before_runner_start():

View File

@ -3,9 +3,9 @@ from django.utils.translation import ugettext_lazy as _
class Connectivity(TextChoices): class Connectivity(TextChoices):
UNKNOWN = 'unknown', _('Unknown') UNKNOWN = '-', _('Unknown')
OK = 'ok', _('Ok') OK = 'ok', _('Ok')
FAILED = 'failed', _('Failed') ERR = 'err', _('Error')
class AutomationTypes(TextChoices): class AutomationTypes(TextChoices):

View File

@ -13,7 +13,7 @@ class Migration(migrations.Migration):
migrations.AddField( migrations.AddField(
model_name='asset', model_name='asset',
name='connectivity', name='connectivity',
field=models.CharField(choices=[('unknown', 'Unknown'), ('ok', 'Ok'), ('failed', 'Failed')], default='unknown', max_length=16, verbose_name='Connectivity'), field=models.CharField(choices=[('-', 'Unknown'), ('ok', 'Ok'), ('err', 'Error')], default='-', max_length=16, verbose_name='Connectivity'),
), ),
migrations.AddField( migrations.AddField(
model_name='asset', model_name='asset',
@ -23,7 +23,7 @@ class Migration(migrations.Migration):
migrations.AddField( migrations.AddField(
model_name='authbook', model_name='authbook',
name='connectivity', name='connectivity',
field=models.CharField(choices=[('unknown', 'Unknown'), ('ok', 'Ok'), ('failed', 'Failed')], default='unknown', max_length=16, verbose_name='Connectivity'), field=models.CharField(choices=[('-', 'Unknown'), ('ok', 'Ok'), ('err', 'Error')], default='-', max_length=16, verbose_name='Connectivity'),
), ),
migrations.AddField( migrations.AddField(
model_name='authbook', model_name='authbook',
@ -33,7 +33,7 @@ class Migration(migrations.Migration):
migrations.AddField( migrations.AddField(
model_name='historicalauthbook', model_name='historicalauthbook',
name='connectivity', name='connectivity',
field=models.CharField(choices=[('unknown', 'Unknown'), ('ok', 'Ok'), ('failed', 'Failed')], default='unknown', max_length=16, verbose_name='Connectivity'), field=models.CharField(choices=[('-', 'Unknown'), ('ok', 'Ok'), ('err', 'Error')], default='-', max_length=16, verbose_name='Connectivity'),
), ),
migrations.AddField( migrations.AddField(
model_name='historicalauthbook', model_name='historicalauthbook',

View File

@ -34,6 +34,13 @@ def migrate_macos_platform(apps, schema_editor):
platform_model.objects.using(db_alias).filter(id=old_macos.id).delete() platform_model.objects.using(db_alias).filter(id=old_macos.id).delete()
def migrate_connectivity(apps, schema_editor):
db_alias = schema_editor.connection.alias
asset_model = apps.get_model('assets', 'Asset')
asset_model.objects.using(db_alias).filter(connectivity='unknown').update(connectivity='-')
asset_model.objects.using(db_alias).filter(connectivity='failed').update(connectivity='err')
class Migration(migrations.Migration): class Migration(migrations.Migration):
dependencies = [ dependencies = [
('assets', '0096_auto_20220426_1550'), ('assets', '0096_auto_20220426_1550'),
@ -43,4 +50,5 @@ class Migration(migrations.Migration):
migrations.RunPython(create_internal_platforms), migrations.RunPython(create_internal_platforms),
migrations.RunPython(update_user_platforms), migrations.RunPython(update_user_platforms),
migrations.RunPython(migrate_macos_platform), migrations.RunPython(migrate_macos_platform),
migrations.RunPython(migrate_connectivity),
] ]

View File

@ -52,11 +52,7 @@ class Migration(migrations.Migration):
migrations.AlterModelOptions( migrations.AlterModelOptions(
name='asset', name='asset',
options={'ordering': ['name'], options={'ordering': ['name'],
'permissions': [('refresh_assethardwareinfo', 'Can refresh asset hardware info'), 'permissions': [('refresh_assethardwareinfo', 'Can refresh asset hardware info'), ('test_assetconnectivity', 'Can test asset connectivity'), ('push_assetaccount', 'Can push account to asset'), ('test_account', 'Can verify account'), ('match_asset', 'Can match asset'), ('add_assettonode', 'Add asset to node'), ('move_assettonode', 'Move asset to node')], 'verbose_name': 'Asset'},
('test_assetconnectivity', 'Can test asset connectivity'),
('push_assetaccount', 'Can push account to asset'),
('match_asset', 'Can match asset'), ('add_assettonode', 'Add asset to node'),
('move_assettonode', 'Move asset to node')], 'verbose_name': 'Asset'},
), ),
migrations.AlterUniqueTogether( migrations.AlterUniqueTogether(
name='accountbackupplan', name='accountbackupplan',

View File

@ -10,8 +10,8 @@ from django.db import models
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from assets import const from assets import const
from common.utils import lazyproperty
from common.db.fields import EncryptMixin from common.db.fields import EncryptMixin
from common.utils import lazyproperty
from orgs.mixins.models import OrgManager, JMSOrgBaseModel from orgs.mixins.models import OrgManager, JMSOrgBaseModel
from ..base import AbsConnectivity from ..base import AbsConnectivity
from ..platform import Platform from ..platform import Platform
@ -113,45 +113,47 @@ class Asset(NodesRelationMixin, AbsConnectivity, JMSOrgBaseModel):
verbose_name=_("Nodes")) verbose_name=_("Nodes"))
is_active = models.BooleanField(default=True, verbose_name=_('Is active')) is_active = models.BooleanField(default=True, verbose_name=_('Is active'))
labels = models.ManyToManyField('assets.Label', blank=True, related_name='assets', verbose_name=_("Labels")) labels = models.ManyToManyField('assets.Label', blank=True, related_name='assets', verbose_name=_("Labels"))
info = models.JSONField(verbose_name='Info', default=dict, blank=True) info = models.JSONField(verbose_name='Info', default=dict, blank=True) # 资产的一些信息,如 硬件信息
objects = AssetManager.from_queryset(AssetQuerySet)() objects = AssetManager.from_queryset(AssetQuerySet)()
def __str__(self): def __str__(self):
return '{0.name}({0.address})'.format(self) return '{0.name}({0.address})'.format(self)
@property @staticmethod
def specific(self): def get_spec_values(instance, fields):
instance = getattr(self, self.category, None)
if not instance:
return {}
specific_fields = self.get_specific_fields(instance)
info = {} info = {}
for i in specific_fields: for i in fields:
v = getattr(instance, i.name) v = getattr(instance, i.name)
if isinstance(i, models.JSONField) and not isinstance(v, (list, dict)): if isinstance(i, models.JSONField) and not isinstance(v, (list, dict)):
v = json.loads(v) v = json.loads(v)
info[i.name] = v info[i.name] = v
return info return info
@property @lazyproperty
def spec_info(self): def spec_info(self):
instance = getattr(self, self.category, None) instance = getattr(self, self.category, None)
if not instance: if not instance:
return [] return {}
specific_fields = self.get_specific_fields(instance) spec_fields = self.get_spec_fields(instance)
info = [ return self.get_spec_values(instance, spec_fields)
{
'label': i.verbose_name, @staticmethod
'name': i.name, def get_spec_fields(instance, secret=False):
'value': getattr(instance, i.name) spec_fields = [i for i in instance._meta.local_fields if i.name != 'asset_ptr']
} spec_fields = [i for i in spec_fields if isinstance(i, EncryptMixin) == secret]
for i in specific_fields return spec_fields
]
return info
@lazyproperty @lazyproperty
def enabled_info(self): def secret_info(self):
instance = getattr(self, self.category, None)
if not instance:
return {}
spec_fields = self.get_spec_fields(instance, secret=True)
return self.get_spec_values(instance, spec_fields)
@lazyproperty
def auto_info(self):
platform = self.platform platform = self.platform
automation = self.platform.automation automation = self.platform.automation
return { return {
@ -165,12 +167,6 @@ class Asset(NodesRelationMixin, AbsConnectivity, JMSOrgBaseModel):
'gather_accounts_enabled': automation.gather_accounts_enabled, 'gather_accounts_enabled': automation.gather_accounts_enabled,
} }
@staticmethod
def get_specific_fields(instance):
specific_fields = [i for i in instance._meta.local_fields if i.name != 'asset_ptr']
specific_fields = [i for i in specific_fields if not isinstance(i, EncryptMixin)]
return specific_fields
def get_target_ip(self): def get_target_ip(self):
return self.address return self.address

View File

@ -18,7 +18,7 @@ __all__ = [
'AssetSerializer', 'AssetSimpleSerializer', 'MiniAssetSerializer', 'AssetSerializer', 'AssetSimpleSerializer', 'MiniAssetSerializer',
'AssetTaskSerializer', 'AssetsTaskSerializer', 'AssetProtocolsSerializer', 'AssetTaskSerializer', 'AssetsTaskSerializer', 'AssetProtocolsSerializer',
'AssetDetailSerializer', 'DetailMixin', 'AssetAccountSerializer', 'AssetDetailSerializer', 'DetailMixin', 'AssetAccountSerializer',
'AccountSecretSerializer' 'AccountSecretSerializer', 'SpecSerializer'
] ]
@ -113,13 +113,25 @@ class AccountSecretSerializer(SecretReadableMixin, CommonModelSerializer):
} }
class SpecSerializer(serializers.Serializer):
# 数据库
db_name = serializers.CharField(label=_("Database"), max_length=128, required=False)
use_ssl = serializers.BooleanField(label=_("Use SSL"), required=False)
allow_invalid_cert = serializers.BooleanField(label=_("Allow invalid cert"), required=False)
# Web
autofill = serializers.CharField(label=_("Auto fill"), required=False)
username_selector = serializers.CharField(label=_("Username selector"), required=False)
password_selector = serializers.CharField(label=_("Password selector"), required=False)
submit_selector = serializers.CharField(label=_("Submit selector"), required=False)
script = serializers.JSONField(label=_("Script"), required=False)
class AssetSerializer(BulkOrgResourceModelSerializer, WritableNestedModelSerializer): class AssetSerializer(BulkOrgResourceModelSerializer, WritableNestedModelSerializer):
category = LabeledChoiceField(choices=Category.choices, read_only=True, label=_('Category')) category = LabeledChoiceField(choices=Category.choices, read_only=True, label=_('Category'))
type = LabeledChoiceField(choices=AllTypes.choices(), read_only=True, label=_('Type')) type = LabeledChoiceField(choices=AllTypes.choices(), read_only=True, label=_('Type'))
labels = AssetLabelSerializer(many=True, required=False, label=_('Label')) labels = AssetLabelSerializer(many=True, required=False, label=_('Label'))
protocols = AssetProtocolsSerializer(many=True, required=False, label=_('Protocols')) protocols = AssetProtocolsSerializer(many=True, required=False, label=_('Protocols'))
accounts = AssetAccountSerializer(many=True, required=False, write_only=True, label=_('Account')) accounts = AssetAccountSerializer(many=True, required=False, write_only=True, label=_('Account'))
enabled_info = serializers.DictField(read_only=True, label=_('Enabled info'))
class Meta: class Meta:
model = Asset model = Asset
@ -127,11 +139,11 @@ class AssetSerializer(BulkOrgResourceModelSerializer, WritableNestedModelSeriali
fields_small = fields_mini + ['is_active', 'comment'] fields_small = fields_mini + ['is_active', 'comment']
fields_fk = ['domain', 'platform'] fields_fk = ['domain', 'platform']
fields_m2m = [ fields_m2m = [
'nodes', 'labels', 'protocols', 'nodes_display', 'accounts' 'nodes', 'labels', 'protocols',
'nodes_display', 'accounts'
] ]
read_only_fields = [ read_only_fields = [
'category', 'type', 'info', 'enabled_info', 'category', 'type', 'connectivity', 'date_verified',
'connectivity', 'date_verified',
'created_by', 'date_created' 'created_by', 'date_created'
] ]
fields = fields_small + fields_fk + fields_m2m + read_only_fields fields = fields_small + fields_fk + fields_m2m + read_only_fields
@ -235,11 +247,13 @@ class AssetSerializer(BulkOrgResourceModelSerializer, WritableNestedModelSeriali
class DetailMixin(serializers.Serializer): class DetailMixin(serializers.Serializer):
accounts = AssetAccountSerializer(many=True, required=False, label=_('Accounts')) accounts = AssetAccountSerializer(many=True, required=False, label=_('Accounts'))
spec_info = serializers.DictField(label=_('Spec info'), read_only=True)
auto_info = serializers.DictField(read_only=True, label=_('Auto info'))
def get_field_names(self, declared_fields, info): def get_field_names(self, declared_fields, info):
names = super().get_field_names(declared_fields, info) names = super().get_field_names(declared_fields, info)
names.extend([ names.extend([
'accounts', 'info', 'specific', 'spec_info' 'accounts', 'info', 'spec_info', 'auto_info'
]) ])
return names return names

View File

@ -31,7 +31,8 @@ class _ConnectionTokenAssetSerializer(serializers.ModelSerializer):
model = Asset model = Asset
fields = [ fields = [
'id', 'name', 'address', 'protocols', 'id', 'name', 'address', 'protocols',
'category', 'type', 'org_id', 'specific' 'category', 'type', 'org_id', 'spec_info',
'secret_info',
] ]

View File

@ -105,7 +105,7 @@ class JMSInventory:
'id': str(asset.id), 'name': asset.name, 'address': asset.address, 'id': str(asset.id), 'name': asset.name, 'address': asset.address,
'type': asset.type, 'category': asset.category, 'type': asset.type, 'category': asset.category,
'protocol': asset.protocol, 'port': asset.port, 'protocol': asset.protocol, 'port': asset.port,
'specific': asset.specific, 'spec_info': asset.spec_info,
'protocols': [{'name': p.name, 'port': p.port} for p in protocols], 'protocols': [{'name': p.name, 'port': p.port} for p in protocols],
}, },
'jms_account': { 'jms_account': {

View File

@ -4,13 +4,13 @@
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from rest_framework import serializers from rest_framework import serializers
from accounts.models import Account
from assets.const import Category, AllTypes from assets.const import Category, AllTypes
from assets.models import Node, Asset, Platform from assets.models import Node, Asset, Platform
from accounts.models import Account
from assets.serializers.asset.common import AssetProtocolsSerializer from assets.serializers.asset.common import AssetProtocolsSerializer
from common.serializers.fields import ObjectRelatedField, LabeledChoiceField from common.serializers.fields import ObjectRelatedField, LabeledChoiceField
from perms.serializers.permission import ActionChoicesField
from orgs.mixins.serializers import OrgResourceModelSerializerMixin from orgs.mixins.serializers import OrgResourceModelSerializerMixin
from perms.serializers.permission import ActionChoicesField
__all__ = [ __all__ = [
'NodePermedSerializer', 'AssetPermedSerializer', 'NodePermedSerializer', 'AssetPermedSerializer',
@ -32,7 +32,7 @@ class AssetPermedSerializer(OrgResourceModelSerializerMixin):
"id", "name", "address", 'domain', 'platform', "id", "name", "address", 'domain', 'platform',
"comment", "org_id", "is_active", "comment", "org_id", "is_active",
] ]
fields = only_fields + ['protocols', 'category', 'type', 'specific'] + ['org_name'] fields = only_fields + ['protocols', 'category', 'type', 'spec_info'] + ['org_name']
read_only_fields = fields read_only_fields = fields

View File

@ -87,13 +87,13 @@ class WebAPP(object):
self.account = account self.account = account
self.platform = platform self.platform = platform
self.extra_data = self.asset.specific self.extra_data = self.asset.spec_info
self._steps = list() self._steps = list()
autofill_type = self.asset.specific.autofill autofill_type = self.asset.spec_info.autofill
if autofill_type == "basic": if autofill_type == "basic":
self._steps = self._default_custom_steps() self._steps = self._default_custom_steps()
elif autofill_type == "script": elif autofill_type == "script":
script_list = self.asset.specific.script script_list = self.asset.spec_info.script
steps = sorted(script_list, key=lambda step_item: step_item.step) steps = sorted(script_list, key=lambda step_item: step_item.step)
for item in steps: for item in steps:
val = item.value val = item.value
@ -105,24 +105,24 @@ class WebAPP(object):
def _default_custom_steps(self) -> list: def _default_custom_steps(self) -> list:
account = self.account account = self.account
specific_property = self.asset.specific spec_info = self.asset.spec_info
default_steps = [ default_steps = [
Step({ Step({
"step": 1, "step": 1,
"value": account.username, "value": account.username,
"target": specific_property.username_selector, "target": spec_info.username_selector,
"command": "type" "command": "type"
}), }),
Step({ Step({
"step": 2, "step": 2,
"value": account.secret, "value": account.secret,
"target": specific_property.password_selector, "target": spec_info.password_selector,
"command": "type" "command": "type"
}), }),
Step({ Step({
"step": 3, "step": 3,
"value": "", "value": "",
"target": specific_property.submit_selector, "target": spec_info.submit_selector,
"command": "click" "command": "click"
}) })
] ]

View File

@ -11,7 +11,6 @@ if sys.platform == 'win32':
) )
from common import wait_pid, BaseApplication from common import wait_pid, BaseApplication
_default_path = r'C:\Program Files\PremiumSoft\Navicat Premium 16\navicat.exe' _default_path = r'C:\Program Files\PremiumSoft\Navicat Premium 16\navicat.exe'
@ -24,7 +23,7 @@ class AppletApplication(BaseApplication):
self.privileged = self.account.privileged self.privileged = self.account.privileged
self.host = self.asset.address self.host = self.asset.address
self.port = self.asset.get_protocol_port(self.protocol) self.port = self.asset.get_protocol_port(self.protocol)
self.db = self.asset.specific.db_name self.db = self.asset.spec_info.db_name
self.name = '%s-%s' % (self.host, self.db) self.name = '%s-%s' % (self.host, self.db)
self.pid = None self.pid = None
self.app = None self.app = None