mirror of https://github.com/jumpserver/jumpserver
perf: 修改 v3
parent
951d4e4e0d
commit
585f0c64cd
|
@ -6,7 +6,7 @@ from common.drf.serializers import GroupedChoiceSerailizer
|
|||
from assets.models import Platform
|
||||
from assets.serializers import PlatformSerializer
|
||||
from assets.const import AllTypes, Category
|
||||
from assets.resources.platform import get_platform_methods
|
||||
from assets.playbooks.platform import filter_platform_methods
|
||||
|
||||
|
||||
__all__ = ['AssetPlatformViewSet']
|
||||
|
@ -43,14 +43,8 @@ class AssetPlatformViewSet(JMSModelViewSet):
|
|||
def ops_methods(self, request, *args, **kwargs):
|
||||
category = request.query_params.get('category')
|
||||
tp = request.query_params.get('type')
|
||||
item = request.query_params.get('item')
|
||||
methods = get_platform_methods()
|
||||
if category:
|
||||
methods = list(filter(lambda x: x['category'] == category, methods))
|
||||
if tp:
|
||||
methods = list(filter(lambda x: x['type'] == tp, methods))
|
||||
if item:
|
||||
methods = list(filter(lambda x: x.get('method') == item, methods))
|
||||
method = request.query_params.get('method')
|
||||
methods = filter_platform_methods(category, tp, method)
|
||||
return Response(methods)
|
||||
|
||||
def check_object_permissions(self, request, obj):
|
||||
|
|
|
@ -8,33 +8,20 @@ import django.db.models.deletion
|
|||
def migrate_platform_set_ops(apps, *args):
|
||||
platform_model = apps.get_model('assets', 'Platform')
|
||||
|
||||
Attr = namedtuple('ops', [
|
||||
'su_enabled', 'su_method', 'domain_enabled',
|
||||
'change_password_enabled', 'change_password_method',
|
||||
'verify_account_enabled', 'verify_account_method',
|
||||
'create_account_enabled', 'create_account_method',
|
||||
])
|
||||
default_ok = {
|
||||
'su_enabled': True,
|
||||
'su_method': 'sudo',
|
||||
'domain_enabled': True,
|
||||
'change_password_enabled': True,
|
||||
'change_password_method': 'change_password_ansible',
|
||||
'change_password_method': 'change_password_linux',
|
||||
'verify_account_enabled': True,
|
||||
'verify_account_method': 'verify_account_ansible',
|
||||
'create_account_enabled': True,
|
||||
'create_account_method': 'create_account_ansible',
|
||||
}
|
||||
|
||||
platform_ops_map = {
|
||||
'Linux': default_ok,
|
||||
'Windows': default_ok,
|
||||
'AIX': Attr(
|
||||
True, 'sudo', True,
|
||||
True, 'change_password_ansible',
|
||||
True, 'verify_account_ansible',
|
||||
True, 'create_account_ansible'
|
||||
)
|
||||
'Linux': {**default_ok, 'change_password_method': 'change_password_linux'},
|
||||
'Windows': {**default_ok, 'change_password_method': 'change_password_windows'},
|
||||
'AIX': {**default_ok, 'change_password_method': 'change_password_aix'},
|
||||
}
|
||||
platforms = platform_model.objects.all()
|
||||
|
||||
|
|
|
@ -0,0 +1,60 @@
|
|||
import os
|
||||
import yaml
|
||||
from functools import partial
|
||||
|
||||
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
|
||||
|
||||
|
||||
def check_platform_method(manifest):
|
||||
required_keys = ['category', 'method', 'name', 'id']
|
||||
less_key = set(required_keys) - set(manifest.keys())
|
||||
if less_key:
|
||||
raise ValueError("Manifest missing keys: {}".format(less_key))
|
||||
return True
|
||||
|
||||
|
||||
def get_platform_methods():
|
||||
methods = []
|
||||
for root, dirs, files in os.walk(BASE_DIR, topdown=False):
|
||||
for name in dirs:
|
||||
path = os.path.join(root, name)
|
||||
rel_path = path.replace(BASE_DIR, '.')
|
||||
if len(rel_path.split('/')) != 3:
|
||||
continue
|
||||
manifest_path = os.path.join(path, 'manifest.yml')
|
||||
if not os.path.exists(manifest_path):
|
||||
continue
|
||||
|
||||
with open(manifest_path, 'r') as f:
|
||||
manifest = yaml.safe_load(f)
|
||||
check_platform_method(manifest)
|
||||
|
||||
methods.append(manifest)
|
||||
return methods
|
||||
|
||||
|
||||
def filter_key(manifest, attr, value):
|
||||
manifest_value = manifest.get(attr, '')
|
||||
if manifest_value == 'all':
|
||||
return True
|
||||
if isinstance(manifest_value, str):
|
||||
manifest_value = [manifest_value]
|
||||
return value in manifest_value
|
||||
|
||||
|
||||
def filter_platform_methods(category, tp, method):
|
||||
methods = platform_ops_methods
|
||||
if category:
|
||||
methods = filter(partial(filter_key, attr='category', value=category), methods)
|
||||
if tp:
|
||||
methods = filter(partial(filter_key, attr='type', value=tp), methods)
|
||||
if method:
|
||||
methods = filter(lambda x: x['method'] == method, methods)
|
||||
return methods
|
||||
|
||||
|
||||
platform_ops_methods = get_platform_methods()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
print(get_platform_methods())
|
|
@ -0,0 +1,6 @@
|
|||
id: change_password_mysql
|
||||
name: Change password for MySQL
|
||||
category: database
|
||||
type: mysql
|
||||
method: change_password
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
id: change_password_oracle
|
||||
name: Change password for Oracle
|
||||
method: change_password
|
||||
category: database
|
||||
type: oracle
|
|
@ -0,0 +1,5 @@
|
|||
id: change_password_postgresql
|
||||
name: Change password for PostgreSQL
|
||||
category: database
|
||||
type: postgresql
|
||||
method: change_password
|
|
@ -0,0 +1,27 @@
|
|||
- name: ping
|
||||
ping:
|
||||
|
||||
#- name: print variables
|
||||
# debug:
|
||||
# msg: "Username: {{ account.username }}, Password: {{ account.password }}"
|
||||
|
||||
- name: Change password
|
||||
user:
|
||||
name: "{{ account.username }}"
|
||||
password: "{{ account.password | password_hash('des') }}"
|
||||
update_password: always
|
||||
when: account.password
|
||||
|
||||
- name: Change public key
|
||||
authorized_key:
|
||||
user: "{{ account.username }}"
|
||||
key: "{{ account.public_key }}"
|
||||
state: present
|
||||
when: account.public_key
|
||||
|
||||
- name: Verify password
|
||||
ping:
|
||||
vars:
|
||||
ansible_user: "{{ account.username }}"
|
||||
ansible_pass: "{{ account.password }}"
|
||||
ansible_ssh_connection: paramiko
|
|
@ -0,0 +1,10 @@
|
|||
{% for account in accounts %}
|
||||
- hosts: {{ account.asset.name }}
|
||||
vars:
|
||||
account:
|
||||
username: {{ account.username }}
|
||||
password: {{ account.password }}
|
||||
public_key: {{ account.public_key }}
|
||||
roles:
|
||||
- change_password
|
||||
{% endfor %}
|
|
@ -0,0 +1,7 @@
|
|||
id: change_password_sqlserver
|
||||
name: Change password for SQLServer
|
||||
version: 1
|
||||
category: database
|
||||
type: sqlserver
|
||||
method: change_password
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
- name: ping
|
||||
ping:
|
||||
|
||||
#- name: print variables
|
||||
# debug:
|
||||
# msg: "Username: {{ account.username }}, Password: {{ account.password }}"
|
||||
|
||||
- name: Change password
|
||||
user:
|
||||
name: "{{ account.username }}"
|
||||
password: "{{ account.password | password_hash('des') }}"
|
||||
update_password: always
|
||||
when: account.password
|
||||
|
||||
- name: Change public key
|
||||
authorized_key:
|
||||
user: "{{ account.username }}"
|
||||
key: "{{ account.public_key }}"
|
||||
state: present
|
||||
when: account.public_key
|
||||
|
||||
- name: Verify password
|
||||
ping:
|
||||
vars:
|
||||
ansible_user: "{{ account.username }}"
|
||||
ansible_pass: "{{ account.password }}"
|
||||
ansible_ssh_connection: paramiko
|
|
@ -0,0 +1,9 @@
|
|||
id: change_password_example
|
||||
name: Change password example
|
||||
category: host
|
||||
method: change_password
|
||||
vars:
|
||||
account:
|
||||
username: test
|
||||
password: teset123
|
||||
public_key: test
|
|
@ -0,0 +1,6 @@
|
|||
#!/usr/bin/env python
|
||||
#
|
||||
"""
|
||||
Will run with the args:
|
||||
$0 $asset_json $account_json
|
||||
"""
|
|
@ -0,0 +1,10 @@
|
|||
{% for account in accounts %}
|
||||
- hosts: {{ account.asset.name }}
|
||||
vars:
|
||||
account:
|
||||
username: {{ account.username }}
|
||||
password: {{ account.password }}
|
||||
public_key: {{ account.public_key }}
|
||||
roles:
|
||||
- change_password
|
||||
{% endfor %}
|
|
@ -0,0 +1,5 @@
|
|||
id: change_password_aix
|
||||
name: Change password for AIX
|
||||
version: 1
|
||||
category: host
|
||||
method: change_password
|
|
@ -0,0 +1,27 @@
|
|||
- name: ping
|
||||
ping:
|
||||
|
||||
#- name: print variables
|
||||
# debug:
|
||||
# msg: "Username: {{ account.username }}, Password: {{ account.password }}"
|
||||
|
||||
- name: Change password
|
||||
user:
|
||||
name: "{{ account.username }}"
|
||||
password: "{{ account.password | password_hash('des') }}"
|
||||
update_password: always
|
||||
when: account.password
|
||||
|
||||
- name: Change public key
|
||||
authorized_key:
|
||||
user: "{{ account.username }}"
|
||||
key: "{{ account.public_key }}"
|
||||
state: present
|
||||
when: account.public_key
|
||||
|
||||
- name: Verify password
|
||||
ping:
|
||||
vars:
|
||||
ansible_user: "{{ account.username }}"
|
||||
ansible_pass: "{{ account.password }}"
|
||||
ansible_ssh_connection: paramiko
|
|
@ -0,0 +1,10 @@
|
|||
{% for account in accounts %}
|
||||
- hosts: {{ account.asset.name }}
|
||||
vars:
|
||||
account:
|
||||
username: {{ account.username }}
|
||||
password: {{ account.password }}
|
||||
public_key: {{ account.public_key }}
|
||||
roles:
|
||||
- change_password
|
||||
{% endfor %}
|
|
@ -0,0 +1,12 @@
|
|||
id: change_password_linux
|
||||
name: Change password for Linux
|
||||
category: host
|
||||
type:
|
||||
- unix
|
||||
- linux
|
||||
method: change_password
|
||||
vars:
|
||||
account:
|
||||
username: test
|
||||
password: teset123
|
||||
public_key: test
|
|
@ -0,0 +1,10 @@
|
|||
{% for account in accounts %}
|
||||
- hosts: {{ account.asset.name }}
|
||||
vars:
|
||||
account:
|
||||
username: {{ account.username }}
|
||||
password: {{ account.password }}
|
||||
public_key: {{ account.public_key }}
|
||||
roles:
|
||||
- change_password
|
||||
{% endfor %}
|
|
@ -0,0 +1,11 @@
|
|||
id: change_password_local_windows
|
||||
name: Change password local account for Windows
|
||||
version: 1
|
||||
method: change_password
|
||||
category: host
|
||||
type: windows
|
||||
vars:
|
||||
account:
|
||||
username: test
|
||||
password: teset123
|
||||
public_key: test
|
|
@ -0,0 +1,27 @@
|
|||
- name: ping
|
||||
ping:
|
||||
|
||||
#- name: print variables
|
||||
# debug:
|
||||
# msg: "Username: {{ account.username }}, Password: {{ account.password }}"
|
||||
|
||||
- name: Change password
|
||||
user:
|
||||
name: "{{ account.username }}"
|
||||
password: "{{ account.password | password_hash('des') }}"
|
||||
update_password: always
|
||||
when: account.password
|
||||
|
||||
- name: Change public key
|
||||
authorized_key:
|
||||
user: "{{ account.username }}"
|
||||
key: "{{ account.public_key }}"
|
||||
state: present
|
||||
when: account.public_key
|
||||
|
||||
- name: Verify password
|
||||
ping:
|
||||
vars:
|
||||
ansible_user: "{{ account.username }}"
|
||||
ansible_pass: "{{ account.password }}"
|
||||
ansible_ssh_connection: paramiko
|
|
@ -0,0 +1,6 @@
|
|||
id: verify_account_ansible
|
||||
name: Ansible ping
|
||||
description: Ansible ping
|
||||
category: host
|
||||
type: all
|
||||
method: verify_account
|
|
@ -1,30 +0,0 @@
|
|||
import os
|
||||
import yaml
|
||||
|
||||
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
|
||||
|
||||
platform_ops_methods = None
|
||||
|
||||
|
||||
def get_platform_methods():
|
||||
methods = []
|
||||
for root, dirs, files in os.walk(BASE_DIR, topdown=False):
|
||||
for name in dirs:
|
||||
path = os.path.join(root, name)
|
||||
rel_path = path.replace(BASE_DIR, '.')
|
||||
if len(rel_path.split('/')) != 3:
|
||||
continue
|
||||
manifest_path = os.path.join(path, 'manifest.yml')
|
||||
if not os.path.exists(manifest_path):
|
||||
continue
|
||||
f = open(manifest_path, 'r')
|
||||
try:
|
||||
manifest = yaml.safe_load(f)
|
||||
except yaml.YAMLError as e:
|
||||
continue
|
||||
methods.append(manifest)
|
||||
return methods
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
print(get_platform_methods())
|
|
@ -1,11 +0,0 @@
|
|||
id: change_password_ansible
|
||||
name: Change password using ansible
|
||||
version: 1
|
||||
description: 使用特权账号更改账号的密码
|
||||
author: ibuler
|
||||
method: change_password
|
||||
vars:
|
||||
account:
|
||||
username: test
|
||||
password: teset123
|
||||
public_key: test
|
|
@ -1,11 +0,0 @@
|
|||
id: change_password_ansible
|
||||
name: Change password using ansible
|
||||
version: 1
|
||||
description: 使用特权账号更改账号的密码
|
||||
author: ibuler
|
||||
method: change_password
|
||||
vars:
|
||||
account:
|
||||
username: test
|
||||
password: teset123
|
||||
public_key: test
|
|
@ -1,11 +0,0 @@
|
|||
id: change_password_ansible
|
||||
name: Change password using ansible
|
||||
version: 1
|
||||
description: 使用特权账号更改账号的密码
|
||||
author: ibuler
|
||||
method: change_password
|
||||
vars:
|
||||
account:
|
||||
username: test
|
||||
password: teset123
|
||||
public_key: test
|
|
@ -1,8 +0,0 @@
|
|||
id: verify_account_ansible
|
||||
name: Change password using ansible
|
||||
version: 1
|
||||
description: 使用特权账号更改账号的密码
|
||||
author: ibuler
|
||||
category: host
|
||||
type: linux
|
||||
method: verify_account
|
|
@ -11,7 +11,8 @@ from .common import BaseAccountSerializer
|
|||
|
||||
|
||||
class AccountSerializer(
|
||||
AccountTemplateSerializerMixin, AuthSerializerMixin, BulkOrgResourceModelSerializer
|
||||
AccountTemplateSerializerMixin, AuthSerializerMixin,
|
||||
BulkOrgResourceModelSerializer
|
||||
):
|
||||
ip = serializers.ReadOnlyField(label=_("IP"))
|
||||
asset_name = serializers.ReadOnlyField(label=_("Asset"))
|
||||
|
|
|
@ -73,7 +73,6 @@ class AssetSerializer(JMSWritableNestedModelSerializer):
|
|||
"""
|
||||
资产的数据结构
|
||||
"""
|
||||
|
||||
class Meta:
|
||||
model = Asset
|
||||
fields_mini = [
|
||||
|
|
|
@ -49,7 +49,6 @@ class PlatformSerializer(JMSWritableNestedModelSerializer):
|
|||
'domain_enabled', 'domain_default', 'su_enabled', 'su_method',
|
||||
'protocols_enabled', 'protocols', 'ping_enabled', 'ping_method',
|
||||
'verify_account_enabled', 'verify_account_method',
|
||||
'create_account_enabled', 'create_account_method',
|
||||
'change_password_enabled', 'change_password_method',
|
||||
'type_constraints', 'comment', 'charset',
|
||||
]
|
||||
|
@ -59,8 +58,8 @@ class PlatformSerializer(JMSWritableNestedModelSerializer):
|
|||
'verify_account_method': {'label': '校验账号方式'},
|
||||
'create_account_enabled': {'label': '启用创建账号'},
|
||||
'create_account_method': {'label': '创建账号方式'},
|
||||
'change_password_enabled': {'label': '启用账号改密'},
|
||||
'change_password_method': {'label': '账号改密方式'},
|
||||
'change_password_enabled': {'label': '启用账号创建改密'},
|
||||
'change_password_method': {'label': '账号创建改密方式'},
|
||||
}
|
||||
|
||||
def validate(self, attrs):
|
||||
|
|
|
@ -124,7 +124,7 @@ class ConfigCrypto:
|
|||
if plaintext:
|
||||
value = plaintext
|
||||
except Exception as e:
|
||||
logger.error('decrypt %s error: %s', item, e)
|
||||
pass
|
||||
return value
|
||||
|
||||
@classmethod
|
||||
|
@ -134,7 +134,7 @@ class ConfigCrypto:
|
|||
secret_encrypt_key = os.environ.get('SECRET_ENCRYPT_KEY', '')
|
||||
if not secret_encrypt_key:
|
||||
return None
|
||||
print('Info: Using SM4 to encrypt config secret value')
|
||||
print('Info: try using SM4 to decrypt config secret value')
|
||||
return cls(secret_encrypt_key)
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue