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.models import Platform
|
||||||
from assets.serializers import PlatformSerializer
|
from assets.serializers import PlatformSerializer
|
||||||
from assets.const import AllTypes, Category
|
from assets.const import AllTypes, Category
|
||||||
from assets.resources.platform import get_platform_methods
|
from assets.playbooks.platform import filter_platform_methods
|
||||||
|
|
||||||
|
|
||||||
__all__ = ['AssetPlatformViewSet']
|
__all__ = ['AssetPlatformViewSet']
|
||||||
|
@ -43,14 +43,8 @@ class AssetPlatformViewSet(JMSModelViewSet):
|
||||||
def ops_methods(self, request, *args, **kwargs):
|
def ops_methods(self, request, *args, **kwargs):
|
||||||
category = request.query_params.get('category')
|
category = request.query_params.get('category')
|
||||||
tp = request.query_params.get('type')
|
tp = request.query_params.get('type')
|
||||||
item = request.query_params.get('item')
|
method = request.query_params.get('method')
|
||||||
methods = get_platform_methods()
|
methods = filter_platform_methods(category, tp, method)
|
||||||
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))
|
|
||||||
return Response(methods)
|
return Response(methods)
|
||||||
|
|
||||||
def check_object_permissions(self, request, obj):
|
def check_object_permissions(self, request, obj):
|
||||||
|
|
|
@ -8,33 +8,20 @@ import django.db.models.deletion
|
||||||
def migrate_platform_set_ops(apps, *args):
|
def migrate_platform_set_ops(apps, *args):
|
||||||
platform_model = apps.get_model('assets', 'Platform')
|
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 = {
|
default_ok = {
|
||||||
'su_enabled': True,
|
'su_enabled': True,
|
||||||
'su_method': 'sudo',
|
'su_method': 'sudo',
|
||||||
'domain_enabled': True,
|
'domain_enabled': True,
|
||||||
'change_password_enabled': True,
|
'change_password_enabled': True,
|
||||||
'change_password_method': 'change_password_ansible',
|
'change_password_method': 'change_password_linux',
|
||||||
'verify_account_enabled': True,
|
'verify_account_enabled': True,
|
||||||
'verify_account_method': 'verify_account_ansible',
|
'verify_account_method': 'verify_account_ansible',
|
||||||
'create_account_enabled': True,
|
|
||||||
'create_account_method': 'create_account_ansible',
|
|
||||||
}
|
}
|
||||||
|
|
||||||
platform_ops_map = {
|
platform_ops_map = {
|
||||||
'Linux': default_ok,
|
'Linux': {**default_ok, 'change_password_method': 'change_password_linux'},
|
||||||
'Windows': default_ok,
|
'Windows': {**default_ok, 'change_password_method': 'change_password_windows'},
|
||||||
'AIX': Attr(
|
'AIX': {**default_ok, 'change_password_method': 'change_password_aix'},
|
||||||
True, 'sudo', True,
|
|
||||||
True, 'change_password_ansible',
|
|
||||||
True, 'verify_account_ansible',
|
|
||||||
True, 'create_account_ansible'
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
platforms = platform_model.objects.all()
|
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(
|
class AccountSerializer(
|
||||||
AccountTemplateSerializerMixin, AuthSerializerMixin, BulkOrgResourceModelSerializer
|
AccountTemplateSerializerMixin, AuthSerializerMixin,
|
||||||
|
BulkOrgResourceModelSerializer
|
||||||
):
|
):
|
||||||
ip = serializers.ReadOnlyField(label=_("IP"))
|
ip = serializers.ReadOnlyField(label=_("IP"))
|
||||||
asset_name = serializers.ReadOnlyField(label=_("Asset"))
|
asset_name = serializers.ReadOnlyField(label=_("Asset"))
|
||||||
|
|
|
@ -73,7 +73,6 @@ class AssetSerializer(JMSWritableNestedModelSerializer):
|
||||||
"""
|
"""
|
||||||
资产的数据结构
|
资产的数据结构
|
||||||
"""
|
"""
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Asset
|
model = Asset
|
||||||
fields_mini = [
|
fields_mini = [
|
||||||
|
|
|
@ -49,7 +49,6 @@ class PlatformSerializer(JMSWritableNestedModelSerializer):
|
||||||
'domain_enabled', 'domain_default', 'su_enabled', 'su_method',
|
'domain_enabled', 'domain_default', 'su_enabled', 'su_method',
|
||||||
'protocols_enabled', 'protocols', 'ping_enabled', 'ping_method',
|
'protocols_enabled', 'protocols', 'ping_enabled', 'ping_method',
|
||||||
'verify_account_enabled', 'verify_account_method',
|
'verify_account_enabled', 'verify_account_method',
|
||||||
'create_account_enabled', 'create_account_method',
|
|
||||||
'change_password_enabled', 'change_password_method',
|
'change_password_enabled', 'change_password_method',
|
||||||
'type_constraints', 'comment', 'charset',
|
'type_constraints', 'comment', 'charset',
|
||||||
]
|
]
|
||||||
|
@ -59,8 +58,8 @@ class PlatformSerializer(JMSWritableNestedModelSerializer):
|
||||||
'verify_account_method': {'label': '校验账号方式'},
|
'verify_account_method': {'label': '校验账号方式'},
|
||||||
'create_account_enabled': {'label': '启用创建账号'},
|
'create_account_enabled': {'label': '启用创建账号'},
|
||||||
'create_account_method': {'label': '创建账号方式'},
|
'create_account_method': {'label': '创建账号方式'},
|
||||||
'change_password_enabled': {'label': '启用账号改密'},
|
'change_password_enabled': {'label': '启用账号创建改密'},
|
||||||
'change_password_method': {'label': '账号改密方式'},
|
'change_password_method': {'label': '账号创建改密方式'},
|
||||||
}
|
}
|
||||||
|
|
||||||
def validate(self, attrs):
|
def validate(self, attrs):
|
||||||
|
|
|
@ -124,7 +124,7 @@ class ConfigCrypto:
|
||||||
if plaintext:
|
if plaintext:
|
||||||
value = plaintext
|
value = plaintext
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error('decrypt %s error: %s', item, e)
|
pass
|
||||||
return value
|
return value
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
|
@ -134,7 +134,7 @@ class ConfigCrypto:
|
||||||
secret_encrypt_key = os.environ.get('SECRET_ENCRYPT_KEY', '')
|
secret_encrypt_key = os.environ.get('SECRET_ENCRYPT_KEY', '')
|
||||||
if not secret_encrypt_key:
|
if not secret_encrypt_key:
|
||||||
return None
|
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)
|
return cls(secret_encrypt_key)
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue