From 139540fafe8257819a09df55ebeeaea33a03fcc4 Mon Sep 17 00:00:00 2001 From: feng626 <1304903146@qq.com> Date: Wed, 14 Sep 2022 15:51:04 +0800 Subject: [PATCH 1/2] =?UTF-8?q?perf:=20=E4=BF=AE=E6=94=B9change=20password?= =?UTF-8?q?=20linux=20ansible=20yaml?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/assets/api/accounts.py | 4 +- apps/assets/models/asset/common.py | 4 + apps/assets/models/platform.py | 4 +- .../database/change_password_mysql/main.yml | 10 -- .../change_password_mysql/manifest.yml | 6 - .../roles/change_password/tasks/main.yml | 27 ----- .../database/change_password_oracle/main.yml | 10 -- .../change_password_oracle/manifest.yml | 6 - .../roles/change_password/tasks/main.yml | 27 ----- .../change_password_postgresql/main.yml | 10 -- .../change_password_postgresql/manifest.yml | 6 - .../roles/change_password/tasks/main.yml | 27 ----- .../change_password_sqlserver/main.yml | 10 -- .../change_password_sqlserver/manifest.yml | 8 -- .../roles/change_password/tasks/main.yml | 27 ----- .../host/change_password_aix/main.yml | 10 -- .../host/change_password_aix/manifest.yml | 6 - .../roles/change_password/tasks/main.yml | 27 ----- .../host/change_password_linux/main.yml | 8 -- .../host/change_password_linux/manifest.yml | 7 -- .../roles/change_password/tasks/main.yml | 23 ---- .../change_password_local_windows/main.yml | 10 -- .../manifest.yml | 7 -- .../roles/change_password/tasks/main.yml | 27 ----- .../playbooks/generate_playbook/__init__.py | 0 .../playbooks/generate_playbook/base.py | 32 ++++++ .../generate_playbook/change_password.py | 104 ++++++++++++++++++ .../playbooks/generate_playbook/verify.py | 0 .../change_password/roles/linux/main.yml | 12 ++ .../roles/linux/tasks/main.yml | 36 ++++++ .../strategy/verify/roles/linux/main.yml | 7 ++ .../verify/roles/linux/tasks/main.yml | 8 ++ .../host/ansible_posix_ping/main.yml | 13 --- .../host/ansible_posix_ping/manifest.yml | 10 -- .../host/ansible_win_ping/main.yml | 13 --- .../host/ansible_win_ping/manifest.yml | 6 - apps/ops/const.py | 2 +- apps/ops/task_handlers/endpoint.py | 4 +- 38 files changed, 210 insertions(+), 348 deletions(-) delete mode 100644 apps/assets/playbooks/change_password/database/change_password_mysql/main.yml delete mode 100644 apps/assets/playbooks/change_password/database/change_password_mysql/manifest.yml delete mode 100644 apps/assets/playbooks/change_password/database/change_password_mysql/roles/change_password/tasks/main.yml delete mode 100644 apps/assets/playbooks/change_password/database/change_password_oracle/main.yml delete mode 100644 apps/assets/playbooks/change_password/database/change_password_oracle/manifest.yml delete mode 100644 apps/assets/playbooks/change_password/database/change_password_oracle/roles/change_password/tasks/main.yml delete mode 100644 apps/assets/playbooks/change_password/database/change_password_postgresql/main.yml delete mode 100644 apps/assets/playbooks/change_password/database/change_password_postgresql/manifest.yml delete mode 100644 apps/assets/playbooks/change_password/database/change_password_postgresql/roles/change_password/tasks/main.yml delete mode 100644 apps/assets/playbooks/change_password/database/change_password_sqlserver/main.yml delete mode 100644 apps/assets/playbooks/change_password/database/change_password_sqlserver/manifest.yml delete mode 100644 apps/assets/playbooks/change_password/database/change_password_sqlserver/roles/change_password/tasks/main.yml delete mode 100644 apps/assets/playbooks/change_password/host/change_password_aix/main.yml delete mode 100644 apps/assets/playbooks/change_password/host/change_password_aix/manifest.yml delete mode 100644 apps/assets/playbooks/change_password/host/change_password_aix/roles/change_password/tasks/main.yml delete mode 100644 apps/assets/playbooks/change_password/host/change_password_linux/main.yml delete mode 100644 apps/assets/playbooks/change_password/host/change_password_linux/manifest.yml delete mode 100644 apps/assets/playbooks/change_password/host/change_password_linux/roles/change_password/tasks/main.yml delete mode 100644 apps/assets/playbooks/change_password/host/change_password_local_windows/main.yml delete mode 100644 apps/assets/playbooks/change_password/host/change_password_local_windows/manifest.yml delete mode 100644 apps/assets/playbooks/change_password/host/change_password_local_windows/roles/change_password/tasks/main.yml create mode 100644 apps/assets/playbooks/generate_playbook/__init__.py create mode 100644 apps/assets/playbooks/generate_playbook/base.py create mode 100644 apps/assets/playbooks/generate_playbook/change_password.py create mode 100644 apps/assets/playbooks/generate_playbook/verify.py create mode 100644 apps/assets/playbooks/strategy/change_password/roles/linux/main.yml create mode 100644 apps/assets/playbooks/strategy/change_password/roles/linux/tasks/main.yml create mode 100644 apps/assets/playbooks/strategy/verify/roles/linux/main.yml create mode 100644 apps/assets/playbooks/strategy/verify/roles/linux/tasks/main.yml delete mode 100644 apps/assets/playbooks/verify_account/host/ansible_posix_ping/main.yml delete mode 100644 apps/assets/playbooks/verify_account/host/ansible_posix_ping/manifest.yml delete mode 100644 apps/assets/playbooks/verify_account/host/ansible_win_ping/main.yml delete mode 100644 apps/assets/playbooks/verify_account/host/ansible_win_ping/manifest.yml diff --git a/apps/assets/api/accounts.py b/apps/assets/api/accounts.py index 00f569357..909f0ad27 100644 --- a/apps/assets/api/accounts.py +++ b/apps/assets/api/accounts.py @@ -49,10 +49,10 @@ class AccountViewSet(OrgBulkModelViewSet): filterset_class = AccountFilterSet serializer_classes = { 'default': serializers.AccountSerializer, - 'verify_account': serializers.AssetTaskSerializer + 'verify': serializers.AssetTaskSerializer } rbac_perms = { - 'verify_account': 'assets.test_authbook', + 'verify': 'assets.test_authbook', 'partial_update': 'assets.change_assetaccountsecret', } diff --git a/apps/assets/models/asset/common.py b/apps/assets/models/asset/common.py index a9396e17c..eead9667a 100644 --- a/apps/assets/models/asset/common.py +++ b/apps/assets/models/asset/common.py @@ -89,6 +89,10 @@ class Asset(AbsConnectivity, NodesRelationMixin, JMSOrgBaseModel): def get_target_ip(self): return self.ip + def get_target_ssh_port(self): + protocol = self.protocols.all().filter(name='ssh').first() + return protocol.port if protocol else 22 + @property def is_valid(self): warning = '' diff --git a/apps/assets/models/platform.py b/apps/assets/models/platform.py index 38e6c6c90..0fe784a16 100644 --- a/apps/assets/models/platform.py +++ b/apps/assets/models/platform.py @@ -66,7 +66,7 @@ class Platform(models.Model): 'su_method': 'sudo', 'domain_enabled': True, 'change_password_enabled': True, - 'change_password_method': 'change_password_linux', + 'change_password_method': 'linux', 'verify_account_enabled': True, 'verify_account_method': 'ansible_posix_ping', } @@ -80,7 +80,7 @@ class Platform(models.Model): platform_ops_map = { ('host', 'linux'): { **default_ok, - 'change_password_method': 'change_password_linux', + 'change_password_method': 'linux', 'verify_account_method': 'ansible_posix_ping' }, ('host', 'windows'): { diff --git a/apps/assets/playbooks/change_password/database/change_password_mysql/main.yml b/apps/assets/playbooks/change_password/database/change_password_mysql/main.yml deleted file mode 100644 index 402c7fa8d..000000000 --- a/apps/assets/playbooks/change_password/database/change_password_mysql/main.yml +++ /dev/null @@ -1,10 +0,0 @@ -{% 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 %} diff --git a/apps/assets/playbooks/change_password/database/change_password_mysql/manifest.yml b/apps/assets/playbooks/change_password/database/change_password_mysql/manifest.yml deleted file mode 100644 index 043549ec6..000000000 --- a/apps/assets/playbooks/change_password/database/change_password_mysql/manifest.yml +++ /dev/null @@ -1,6 +0,0 @@ -id: change_password_mysql -name: Change password for MySQL -category: database -type: - - mysql -method: change_password diff --git a/apps/assets/playbooks/change_password/database/change_password_mysql/roles/change_password/tasks/main.yml b/apps/assets/playbooks/change_password/database/change_password_mysql/roles/change_password/tasks/main.yml deleted file mode 100644 index 903cd9115..000000000 --- a/apps/assets/playbooks/change_password/database/change_password_mysql/roles/change_password/tasks/main.yml +++ /dev/null @@ -1,27 +0,0 @@ -- 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 diff --git a/apps/assets/playbooks/change_password/database/change_password_oracle/main.yml b/apps/assets/playbooks/change_password/database/change_password_oracle/main.yml deleted file mode 100644 index 402c7fa8d..000000000 --- a/apps/assets/playbooks/change_password/database/change_password_oracle/main.yml +++ /dev/null @@ -1,10 +0,0 @@ -{% 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 %} diff --git a/apps/assets/playbooks/change_password/database/change_password_oracle/manifest.yml b/apps/assets/playbooks/change_password/database/change_password_oracle/manifest.yml deleted file mode 100644 index d3bab86e1..000000000 --- a/apps/assets/playbooks/change_password/database/change_password_oracle/manifest.yml +++ /dev/null @@ -1,6 +0,0 @@ -id: change_password_oracle -name: Change password for Oracle -method: change_password -category: database -type: - - oracle diff --git a/apps/assets/playbooks/change_password/database/change_password_oracle/roles/change_password/tasks/main.yml b/apps/assets/playbooks/change_password/database/change_password_oracle/roles/change_password/tasks/main.yml deleted file mode 100644 index 903cd9115..000000000 --- a/apps/assets/playbooks/change_password/database/change_password_oracle/roles/change_password/tasks/main.yml +++ /dev/null @@ -1,27 +0,0 @@ -- 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 diff --git a/apps/assets/playbooks/change_password/database/change_password_postgresql/main.yml b/apps/assets/playbooks/change_password/database/change_password_postgresql/main.yml deleted file mode 100644 index 402c7fa8d..000000000 --- a/apps/assets/playbooks/change_password/database/change_password_postgresql/main.yml +++ /dev/null @@ -1,10 +0,0 @@ -{% 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 %} diff --git a/apps/assets/playbooks/change_password/database/change_password_postgresql/manifest.yml b/apps/assets/playbooks/change_password/database/change_password_postgresql/manifest.yml deleted file mode 100644 index 9abe184be..000000000 --- a/apps/assets/playbooks/change_password/database/change_password_postgresql/manifest.yml +++ /dev/null @@ -1,6 +0,0 @@ -id: change_password_postgresql -name: Change password for PostgreSQL -category: database -type: - - postgresql -method: change_password diff --git a/apps/assets/playbooks/change_password/database/change_password_postgresql/roles/change_password/tasks/main.yml b/apps/assets/playbooks/change_password/database/change_password_postgresql/roles/change_password/tasks/main.yml deleted file mode 100644 index 903cd9115..000000000 --- a/apps/assets/playbooks/change_password/database/change_password_postgresql/roles/change_password/tasks/main.yml +++ /dev/null @@ -1,27 +0,0 @@ -- 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 diff --git a/apps/assets/playbooks/change_password/database/change_password_sqlserver/main.yml b/apps/assets/playbooks/change_password/database/change_password_sqlserver/main.yml deleted file mode 100644 index 402c7fa8d..000000000 --- a/apps/assets/playbooks/change_password/database/change_password_sqlserver/main.yml +++ /dev/null @@ -1,10 +0,0 @@ -{% 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 %} diff --git a/apps/assets/playbooks/change_password/database/change_password_sqlserver/manifest.yml b/apps/assets/playbooks/change_password/database/change_password_sqlserver/manifest.yml deleted file mode 100644 index b16a24dc9..000000000 --- a/apps/assets/playbooks/change_password/database/change_password_sqlserver/manifest.yml +++ /dev/null @@ -1,8 +0,0 @@ -id: change_password_sqlserver -name: Change password for SQLServer -version: 1 -category: database -type: - - sqlserver -method: change_password - diff --git a/apps/assets/playbooks/change_password/database/change_password_sqlserver/roles/change_password/tasks/main.yml b/apps/assets/playbooks/change_password/database/change_password_sqlserver/roles/change_password/tasks/main.yml deleted file mode 100644 index 903cd9115..000000000 --- a/apps/assets/playbooks/change_password/database/change_password_sqlserver/roles/change_password/tasks/main.yml +++ /dev/null @@ -1,27 +0,0 @@ -- 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 diff --git a/apps/assets/playbooks/change_password/host/change_password_aix/main.yml b/apps/assets/playbooks/change_password/host/change_password_aix/main.yml deleted file mode 100644 index 402c7fa8d..000000000 --- a/apps/assets/playbooks/change_password/host/change_password_aix/main.yml +++ /dev/null @@ -1,10 +0,0 @@ -{% 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 %} diff --git a/apps/assets/playbooks/change_password/host/change_password_aix/manifest.yml b/apps/assets/playbooks/change_password/host/change_password_aix/manifest.yml deleted file mode 100644 index 451c10f8e..000000000 --- a/apps/assets/playbooks/change_password/host/change_password_aix/manifest.yml +++ /dev/null @@ -1,6 +0,0 @@ -id: change_password_aix -name: Change password for AIX -category: host -type: - - aix -method: change_password diff --git a/apps/assets/playbooks/change_password/host/change_password_aix/roles/change_password/tasks/main.yml b/apps/assets/playbooks/change_password/host/change_password_aix/roles/change_password/tasks/main.yml deleted file mode 100644 index 903cd9115..000000000 --- a/apps/assets/playbooks/change_password/host/change_password_aix/roles/change_password/tasks/main.yml +++ /dev/null @@ -1,27 +0,0 @@ -- 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 diff --git a/apps/assets/playbooks/change_password/host/change_password_linux/main.yml b/apps/assets/playbooks/change_password/host/change_password_linux/main.yml deleted file mode 100644 index 6b5f0df66..000000000 --- a/apps/assets/playbooks/change_password/host/change_password_linux/main.yml +++ /dev/null @@ -1,8 +0,0 @@ -- hosts: {{ account.asset.name }} - vars: - account: - username: {{ account.username }} - password: {{ account.password }} - public_key: {{ account.public_key }} - roles: - - change_password diff --git a/apps/assets/playbooks/change_password/host/change_password_linux/manifest.yml b/apps/assets/playbooks/change_password/host/change_password_linux/manifest.yml deleted file mode 100644 index 25183c25d..000000000 --- a/apps/assets/playbooks/change_password/host/change_password_linux/manifest.yml +++ /dev/null @@ -1,7 +0,0 @@ -id: change_password_linux -name: Change password for Linux -category: host -type: - - unix - - linux -method: change_password diff --git a/apps/assets/playbooks/change_password/host/change_password_linux/roles/change_password/tasks/main.yml b/apps/assets/playbooks/change_password/host/change_password_linux/roles/change_password/tasks/main.yml deleted file mode 100644 index e0ba9c73f..000000000 --- a/apps/assets/playbooks/change_password/host/change_password_linux/roles/change_password/tasks/main.yml +++ /dev/null @@ -1,23 +0,0 @@ -- name: Check connection - ping: - -- name: Change password - user: - name: "{{ account.username }}" - password: "{{ account.password | password_hash('sha512') }}" - 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 diff --git a/apps/assets/playbooks/change_password/host/change_password_local_windows/main.yml b/apps/assets/playbooks/change_password/host/change_password_local_windows/main.yml deleted file mode 100644 index 402c7fa8d..000000000 --- a/apps/assets/playbooks/change_password/host/change_password_local_windows/main.yml +++ /dev/null @@ -1,10 +0,0 @@ -{% 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 %} diff --git a/apps/assets/playbooks/change_password/host/change_password_local_windows/manifest.yml b/apps/assets/playbooks/change_password/host/change_password_local_windows/manifest.yml deleted file mode 100644 index 7f34008e6..000000000 --- a/apps/assets/playbooks/change_password/host/change_password_local_windows/manifest.yml +++ /dev/null @@ -1,7 +0,0 @@ -id: change_password_local_windows -name: Change password local account for Windows -version: 1 -method: change_password -category: host -type: - - windows diff --git a/apps/assets/playbooks/change_password/host/change_password_local_windows/roles/change_password/tasks/main.yml b/apps/assets/playbooks/change_password/host/change_password_local_windows/roles/change_password/tasks/main.yml deleted file mode 100644 index 903cd9115..000000000 --- a/apps/assets/playbooks/change_password/host/change_password_local_windows/roles/change_password/tasks/main.yml +++ /dev/null @@ -1,27 +0,0 @@ -- 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 diff --git a/apps/assets/playbooks/generate_playbook/__init__.py b/apps/assets/playbooks/generate_playbook/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/apps/assets/playbooks/generate_playbook/base.py b/apps/assets/playbooks/generate_playbook/base.py new file mode 100644 index 000000000..12a39f12c --- /dev/null +++ b/apps/assets/playbooks/generate_playbook/base.py @@ -0,0 +1,32 @@ +import os +import time +import shutil +from typing import List + +from django.conf import settings +from assets.models import Asset + + +class BaseGeneratePlaybook: + src_filepath: str + + def __init__(self, assets: List[Asset], strategy): + self.assets = assets + self.strategy = strategy + self.temp_folder = self.temp_folder_path() + + @staticmethod + def temp_folder_path(): + project_dir = settings.PROJECT_DIR + tmp_dir = os.path.join(project_dir, 'tmp') + filepath = os.path.join(tmp_dir, str(time.time())) + return filepath + + def del_temp_folder(self): + shutil.rmtree(self.temp_folder) + + def generate_temp_playbook(self): + src = self.src_filepath + dst = os.path.join(self.temp_folder, self.strategy) + shutil.copytree(src, dst) + return dst diff --git a/apps/assets/playbooks/generate_playbook/change_password.py b/apps/assets/playbooks/generate_playbook/change_password.py new file mode 100644 index 000000000..a3f723d28 --- /dev/null +++ b/apps/assets/playbooks/generate_playbook/change_password.py @@ -0,0 +1,104 @@ +import os +import yaml +import jinja2 +from typing import List + +from django.conf import settings +from assets.models import Asset +from .base import BaseGeneratePlaybook + + +class GenerateChangePasswordPlaybook(BaseGeneratePlaybook): + + def __init__( + self, assets: List[Asset], strategy, usernames, password='', + private_key='', public_key='', key_strategy='' + ): + super().__init__(assets, strategy) + self.password = password + self.public_key = public_key + self.private_key = private_key + self.key_strategy = key_strategy + self.relation_asset_map = self.get_username_relation_asset_map(usernames) + + def get_username_relation_asset_map(self, usernames): + # TODO 没牛逼用户的资产 网关 + + complete_map = { + asset: list(asset.accounts.value_list('username', flat=True)) + for asset in self.assets + } + + if '*' in usernames: + return complete_map + + relation_map = {} + for asset, usernames in complete_map.items(): + relation_map[asset] = list(set(usernames) & set(usernames)) + return relation_map + + @property + def src_filepath(self): + return os.path.join( + settings.BASE_DIR, 'assets', 'playbooks', 'strategy', + 'change_password', 'roles', self.strategy + ) + + def generate_hosts(self): + host_pathname = os.path.join(self.temp_folder, 'hosts') + with open(host_pathname, 'w', encoding='utf8') as f: + for asset in self.relation_asset_map.keys(): + f.write(f'{asset.name}\n') + + def generate_host_vars(self): + host_vars_pathname = os.path.join(self.temp_folder, 'hosts', 'host_vars') + os.makedirs(host_vars_pathname, exist_ok=True) + for asset, usernames in self.relation_asset_map.items(): + host_vars = { + 'ansible_host': asset.get_target_ip(), + 'ansible_port': asset.get_target_ssh_port(), # TODO 需要根绝协议取端口号 + 'ansible_user': asset.admin_user.username, + 'ansible_pass': asset.admin_user.username, + 'ansible_connection': 'ssh', + 'usernames': usernames, + } + pathname = os.path.join(host_vars_pathname, f'{asset.name}.yml') + with open(pathname, 'w', encoding='utf8') as f: + f.write(yaml.dump(host_vars, allow_unicode=True)) + + def generate_secret_key_files(self): + if not self.private_key and not self.public_key: + return + + file_pathname = os.path.join(self.temp_folder, self.strategy, 'files') + public_pathname = os.path.join(file_pathname, 'id_rsa.pub') + private_pathname = os.path.join(file_pathname, 'id_rsa') + + os.makedirs(file_pathname, exist_ok=True) + with open(public_pathname, 'w', encoding='utf8') as f: + f.write(self.public_key) + with open(private_pathname, 'w', encoding='utf8') as f: + f.write(self.private_key) + + def generate_role_main(self): + task_main_pathname = os.path.join(self.temp_folder, 'main.yaml') + context = { + 'password': self.password, + 'key_strategy': self.key_strategy, + 'private_key_file': 'id_rsa' if self.private_key else '', + 'exclusive': 'no' if self.key_strategy == 'all' else 'yes', + 'jms_key': self.public_key.split()[2].strip() if self.public_key else '', + } + with open(task_main_pathname, 'r+', encoding='utf8') as f: + string_var = f.read() + f.seek(0, 0) + response = jinja2.Template(string_var).render(context) + results = yaml.safe_load(response) + f.write(yaml.dump(results, allow_unicode=True)) + + def execute(self): + self.generate_temp_playbook() + self.generate_hosts() + self.generate_host_vars() + self.generate_secret_key_files() + self.generate_role_main() diff --git a/apps/assets/playbooks/generate_playbook/verify.py b/apps/assets/playbooks/generate_playbook/verify.py new file mode 100644 index 000000000..e69de29bb diff --git a/apps/assets/playbooks/strategy/change_password/roles/linux/main.yml b/apps/assets/playbooks/strategy/change_password/roles/linux/main.yml new file mode 100644 index 000000000..cb229d9d6 --- /dev/null +++ b/apps/assets/playbooks/strategy/change_password/roles/linux/main.yml @@ -0,0 +1,12 @@ +- hosts: all + vars: + connection_type: ssh + password: + value: {{ password}} + public_key: + value: {{ jms_key }} + exclusive: {{ exclusive }} + key_strategy: {{ key_strategy }} + private_key_file: {{ private_key_file }} + roles: + - linux diff --git a/apps/assets/playbooks/strategy/change_password/roles/linux/tasks/main.yml b/apps/assets/playbooks/strategy/change_password/roles/linux/tasks/main.yml new file mode 100644 index 000000000..cc9467ca1 --- /dev/null +++ b/apps/assets/playbooks/strategy/change_password/roles/linux/tasks/main.yml @@ -0,0 +1,36 @@ +- name: Check connection + ping: + +- name: Change password + user: + name: "{{ item }}" + password: "{{ password.value | password_hash('sha512') }}" + update_password: always + with_items: "{{ usernames }}" + when: "{{ password.value }}" + +- name: Change public key + authorized_key: + user: "{{ item }}" + key: "{{ lookup('file', id_rsa.pub) }}" + state: present + exclusive: "{{ public_key.exclusive }}" + with_items: "{{ usernames }}" + when: "{{ public_key.value and key_strategy != 'set_jms' }}" + +- name: Change public key + lineinfile: + user: "{{ item }}" + dest: /home/{{ item }}/.ssh/authorized_keys regexp='.*{{ public_key.value }}$ + state: absent + with_items: "{{ usernames }}" + when: "{{ public_key.value and key_strategy == 'set_jms' }}" + +- name: Verify user + ping: + vars: + ansible_user: "{{ item }}" + ansible_pass: "{{ password.value }}" + ansible_ssh_private_key_file: "{{ private_key_file }}" + ansible_connection: "{{ connection_type | default('ssh') }}" + with_items: "{{ usernames }}" diff --git a/apps/assets/playbooks/strategy/verify/roles/linux/main.yml b/apps/assets/playbooks/strategy/verify/roles/linux/main.yml new file mode 100644 index 000000000..ba07ece17 --- /dev/null +++ b/apps/assets/playbooks/strategy/verify/roles/linux/main.yml @@ -0,0 +1,7 @@ +- hosts: all + vars: + connection_type: ssh + password: + value: {{ password}} + roles: + - linux diff --git a/apps/assets/playbooks/strategy/verify/roles/linux/tasks/main.yml b/apps/assets/playbooks/strategy/verify/roles/linux/tasks/main.yml new file mode 100644 index 000000000..0bf6e8ee1 --- /dev/null +++ b/apps/assets/playbooks/strategy/verify/roles/linux/tasks/main.yml @@ -0,0 +1,8 @@ +- name: Verify user + ping: + vars: + ansible_user: "{{ item }}" + ansible_pass: "{{ password }}" + ansible_connection: "{{ connection_type | default('ssh') }}" + ansible_ssh_private_key_file: "{{ private_key_file }}" + with_items: "{{ usernames }}" diff --git a/apps/assets/playbooks/verify_account/host/ansible_posix_ping/main.yml b/apps/assets/playbooks/verify_account/host/ansible_posix_ping/main.yml deleted file mode 100644 index 4ccdb3074..000000000 --- a/apps/assets/playbooks/verify_account/host/ansible_posix_ping/main.yml +++ /dev/null @@ -1,13 +0,0 @@ -- hosts: centos - gather_facts: no - vars: - account: - username: web - password: test123 - - tasks: - - name: Verify password - ping: - vars: - ansible_user: "{{ account.username }}" - ansible_pass: "{{ account.password }}" diff --git a/apps/assets/playbooks/verify_account/host/ansible_posix_ping/manifest.yml b/apps/assets/playbooks/verify_account/host/ansible_posix_ping/manifest.yml deleted file mode 100644 index 6cd223f1c..000000000 --- a/apps/assets/playbooks/verify_account/host/ansible_posix_ping/manifest.yml +++ /dev/null @@ -1,10 +0,0 @@ -id: ansible_posix_ping -name: Ansible posix ping -description: Ansible ping -category: host -type: - - linux - - unix - - macos - - bsd -method: verify_account diff --git a/apps/assets/playbooks/verify_account/host/ansible_win_ping/main.yml b/apps/assets/playbooks/verify_account/host/ansible_win_ping/main.yml deleted file mode 100644 index 726d04a53..000000000 --- a/apps/assets/playbooks/verify_account/host/ansible_win_ping/main.yml +++ /dev/null @@ -1,13 +0,0 @@ -- hosts: centos - gather_facts: no - vars: - account: - username: web - password: test123 - - tasks: - - name: Verify password - win_ping: - vars: - ansible_user: "{{ account.username }}" - ansible_pass: "{{ account.password }}" diff --git a/apps/assets/playbooks/verify_account/host/ansible_win_ping/manifest.yml b/apps/assets/playbooks/verify_account/host/ansible_win_ping/manifest.yml deleted file mode 100644 index fe881de3b..000000000 --- a/apps/assets/playbooks/verify_account/host/ansible_win_ping/manifest.yml +++ /dev/null @@ -1,6 +0,0 @@ -id: ansible_win_ping -name: Ansible win ping -category: host -type: - - windows -method: verify_account diff --git a/apps/ops/const.py b/apps/ops/const.py index ee2a17340..b9016f450 100644 --- a/apps/ops/const.py +++ b/apps/ops/const.py @@ -6,7 +6,7 @@ class StrategyChoice(models.TextChoices): push = 'push', _('Push') verify = 'verify', _('Verify') collect = 'collect', _('Collect') - change_auth = 'change_auth', _('Change auth') + change_password = 'change_password', _('Change password') class SSHKeyStrategy(models.TextChoices): diff --git a/apps/ops/task_handlers/endpoint.py b/apps/ops/task_handlers/endpoint.py index 4bca2631b..2d95dcad5 100644 --- a/apps/ops/task_handlers/endpoint.py +++ b/apps/ops/task_handlers/endpoint.py @@ -10,7 +10,7 @@ class ExecutionManager: StrategyChoice.push: PushExecutionManager, StrategyChoice.verify: VerifyExecutionManager, StrategyChoice.collect: CollectExecutionManager, - StrategyChoice.change_auth: ChangeAuthExecutionManager, + StrategyChoice.change_password: ChangeAuthExecutionManager, } def __new__(cls, execution): @@ -23,7 +23,7 @@ class TaskHandler: StrategyChoice.push: PushHandler, StrategyChoice.verify: VerifyHandler, StrategyChoice.collect: CollectHandler, - StrategyChoice.change_auth: ChangeAuthHandler, + StrategyChoice.change_password: ChangeAuthHandler, } def __new__(cls, task, show_step_info): From a4d0ef3706387b5de4885c900441b618da22df65 Mon Sep 17 00:00:00 2001 From: feng626 <1304903146@qq.com> Date: Thu, 15 Sep 2022 21:14:14 +0800 Subject: [PATCH 2/2] perf: verify ansible linux --- .../generate_playbook/change_password.py | 6 +- .../playbooks/generate_playbook/verify.py | 86 +++++++++++++++++++ .../strategy/verify/roles/linux/main.yml | 2 - .../verify/roles/linux/tasks/main.yml | 8 +- 4 files changed, 94 insertions(+), 8 deletions(-) diff --git a/apps/assets/playbooks/generate_playbook/change_password.py b/apps/assets/playbooks/generate_playbook/change_password.py index a3f723d28..20c3f0889 100644 --- a/apps/assets/playbooks/generate_playbook/change_password.py +++ b/apps/assets/playbooks/generate_playbook/change_password.py @@ -22,7 +22,7 @@ class GenerateChangePasswordPlaybook(BaseGeneratePlaybook): self.relation_asset_map = self.get_username_relation_asset_map(usernames) def get_username_relation_asset_map(self, usernames): - # TODO 没牛逼用户的资产 网关 + # TODO 没特权用户的资产 要考虑网关 complete_map = { asset: list(asset.accounts.value_list('username', flat=True)) @@ -34,6 +34,9 @@ class GenerateChangePasswordPlaybook(BaseGeneratePlaybook): relation_map = {} for asset, usernames in complete_map.items(): + usernames = list(set(usernames) & set(usernames)) + if not usernames: + continue relation_map[asset] = list(set(usernames) & set(usernames)) return relation_map @@ -59,7 +62,6 @@ class GenerateChangePasswordPlaybook(BaseGeneratePlaybook): 'ansible_port': asset.get_target_ssh_port(), # TODO 需要根绝协议取端口号 'ansible_user': asset.admin_user.username, 'ansible_pass': asset.admin_user.username, - 'ansible_connection': 'ssh', 'usernames': usernames, } pathname = os.path.join(host_vars_pathname, f'{asset.name}.yml') diff --git a/apps/assets/playbooks/generate_playbook/verify.py b/apps/assets/playbooks/generate_playbook/verify.py index e69de29bb..88695b814 100644 --- a/apps/assets/playbooks/generate_playbook/verify.py +++ b/apps/assets/playbooks/generate_playbook/verify.py @@ -0,0 +1,86 @@ +import os +import yaml +from typing import List + +from django.conf import settings +from assets.models import Asset +from .base import BaseGeneratePlaybook + + +class GenerateVerifyPlaybook(BaseGeneratePlaybook): + + def __init__( + self, assets: List[Asset], strategy, usernames + ): + super().__init__(assets, strategy) + self.relation_asset_map = self.get_account_relation_asset_map(usernames) + + def get_account_relation_asset_map(self, usernames): + # TODO 没特权用户的资产 要考虑网关 + complete_map = { + asset: list(asset.accounts.all()) + for asset in self.assets + } + + if '*' in usernames: + return complete_map + + relation_map = {} + for asset, accounts in complete_map.items(): + account_map = {account.username: account for account in accounts} + accounts = [account_map[i] for i in (set(usernames) & set(account_map))] + if not accounts: + continue + relation_map[asset] = accounts + return relation_map + + @property + def src_filepath(self): + return os.path.join( + settings.BASE_DIR, 'assets', 'playbooks', 'strategy', + 'verify', 'roles', self.strategy + ) + + def generate_hosts(self): + host_pathname = os.path.join(self.temp_folder, 'hosts') + with open(host_pathname, 'w', encoding='utf8') as f: + for asset in self.relation_asset_map.keys(): + f.write(f'{asset.name}\n') + + def generate_host_vars(self): + host_vars_pathname = os.path.join(self.temp_folder, 'hosts', 'host_vars') + os.makedirs(host_vars_pathname, exist_ok=True) + for asset, accounts in self.relation_asset_map.items(): + account_info = [] + for account in accounts: + private_key_filename = f'{asset.name}_{account.username}' if account.private_key else '' + account_info.append({ + 'username': account.username, + 'password': account.password, + 'private_key_filename': private_key_filename, + }) + host_vars = { + 'ansible_host': asset.get_target_ip(), + 'ansible_port': asset.get_target_ssh_port(), # TODO 需要根绝协议取端口号 + 'account_info': account_info, + } + pathname = os.path.join(host_vars_pathname, f'{asset.name}.yml') + with open(pathname, 'w', encoding='utf8') as f: + f.write(yaml.dump(host_vars, allow_unicode=True)) + + def generate_secret_key_files(self): + file_pathname = os.path.join(self.temp_folder, self.strategy, 'files') + os.makedirs(file_pathname, exist_ok=True) + for asset, accounts in self.relation_asset_map.items(): + for account in accounts: + if account.private_key: + path_name = os.path.join(file_pathname, f'{asset.name}_{account.username}') + with open(path_name, 'w', encoding='utf8') as f: + f.write(account.private_key) + + def execute(self): + self.generate_temp_playbook() + self.generate_hosts() + self.generate_host_vars() + self.generate_secret_key_files() + # self.generate_role_main() # TODO Linux 暂时不需要 diff --git a/apps/assets/playbooks/strategy/verify/roles/linux/main.yml b/apps/assets/playbooks/strategy/verify/roles/linux/main.yml index ba07ece17..03c666df7 100644 --- a/apps/assets/playbooks/strategy/verify/roles/linux/main.yml +++ b/apps/assets/playbooks/strategy/verify/roles/linux/main.yml @@ -1,7 +1,5 @@ - hosts: all vars: connection_type: ssh - password: - value: {{ password}} roles: - linux diff --git a/apps/assets/playbooks/strategy/verify/roles/linux/tasks/main.yml b/apps/assets/playbooks/strategy/verify/roles/linux/tasks/main.yml index 0bf6e8ee1..ff9e1eb99 100644 --- a/apps/assets/playbooks/strategy/verify/roles/linux/tasks/main.yml +++ b/apps/assets/playbooks/strategy/verify/roles/linux/tasks/main.yml @@ -1,8 +1,8 @@ - name: Verify user ping: vars: - ansible_user: "{{ item }}" - ansible_pass: "{{ password }}" + ansible_user: "{{ item.username }}" + ansible_pass: "{{ item.username }}" ansible_connection: "{{ connection_type | default('ssh') }}" - ansible_ssh_private_key_file: "{{ private_key_file }}" - with_items: "{{ usernames }}" + ansible_ssh_private_key_file: "{{ item.private_key_file }}" + with_items: "{{ account_info }}"