From 37a307a9d0fb9e4852ccf4653ba05aecce956bae Mon Sep 17 00:00:00 2001 From: feng <1304903146@qq.com> Date: Wed, 9 Apr 2025 18:12:18 +0800 Subject: [PATCH] perf: Windows AD --- apps/accounts/automations/base/manager.py | 1 + .../change_secret/host/windows_ad/main.yml | 27 +++++++++++++++++++ .../host/windows_ad/manifest.yml | 27 +++++++++++++++++++ .../gather_account/host/windows/manifest.yml | 5 +++- .../push_account/host/windows_ad/main.yml | 27 +++++++++++++++++++ .../push_account/host/windows_ad/manifest.yml | 25 +++++++++++++++++ .../remove_account/host/windows_ad/main.yml | 9 +++++++ .../host/windows_ad/manifest.yml | 14 ++++++++++ .../verify_account/custom/rdp/main.yml | 2 +- .../verify_account/custom/rdp/manifest.yml | 2 ++ .../verify_account/host/windows/main.yml | 2 +- .../verify_account/host/windows/manifest.yml | 5 +++- .../automations/verify_account/manager.py | 1 + .../gather_facts/host/windows/manifest.yml | 5 +++- .../automations/ping/custom/rdp/manifest.yml | 2 ++ .../automations/ping/custom/ssh/manifest.yml | 1 + .../ping/custom/telnet/manifest.yml | 1 + .../ping/host/windows/manifest.yml | 5 +++- apps/assets/const/ds.py | 1 + .../migrations/0017_auto_20250407_1124.py | 2 +- apps/ops/ansible/inventory.py | 14 +++++----- 21 files changed, 164 insertions(+), 14 deletions(-) create mode 100644 apps/accounts/automations/change_secret/host/windows_ad/main.yml create mode 100644 apps/accounts/automations/change_secret/host/windows_ad/manifest.yml create mode 100644 apps/accounts/automations/push_account/host/windows_ad/main.yml create mode 100644 apps/accounts/automations/push_account/host/windows_ad/manifest.yml create mode 100644 apps/accounts/automations/remove_account/host/windows_ad/main.yml create mode 100644 apps/accounts/automations/remove_account/host/windows_ad/manifest.yml diff --git a/apps/accounts/automations/base/manager.py b/apps/accounts/automations/base/manager.py index 57f6fb5f8..1c7997eae 100644 --- a/apps/accounts/automations/base/manager.py +++ b/apps/accounts/automations/base/manager.py @@ -94,6 +94,7 @@ class BaseChangeSecretPushManager(AccountBasePlaybookManager): h['account'] = { 'name': account.name, 'username': account.username, + 'full_username': account.full_username, 'secret_type': secret_type, 'secret': account.escape_jinja2_syntax(new_secret), 'private_key_path': private_key_path, diff --git a/apps/accounts/automations/change_secret/host/windows_ad/main.yml b/apps/accounts/automations/change_secret/host/windows_ad/main.yml new file mode 100644 index 000000000..1b8634f38 --- /dev/null +++ b/apps/accounts/automations/change_secret/host/windows_ad/main.yml @@ -0,0 +1,27 @@ +- hosts: demo + gather_facts: no + tasks: + - name: Test privileged account + ansible.windows.win_ping: + + - name: Change password + community.windows.win_domain_user: + name: "{{ account.username }}" + password: "{{ account.secret }}" + update_password: always + password_never_expires: yes + state: present + groups: "{{ params.groups }}" + groups_action: add + ignore_errors: true + when: account.secret_type == "password" + + - name: Refresh connection + ansible.builtin.meta: reset_connection + + - name: Verify password + ansible.windows.win_ping: + vars: + ansible_user: "{{ account.full_username }}" + ansible_password: "{{ account.secret }}" + when: account.secret_type == "password" and check_conn_after_change diff --git a/apps/accounts/automations/change_secret/host/windows_ad/manifest.yml b/apps/accounts/automations/change_secret/host/windows_ad/manifest.yml new file mode 100644 index 000000000..4c4c66fb6 --- /dev/null +++ b/apps/accounts/automations/change_secret/host/windows_ad/manifest.yml @@ -0,0 +1,27 @@ +id: change_secret_ad_windows +name: "{{ 'Windows account change secret' | trans }}" +version: 1 +method: change_secret +category: + - ds +type: + - windows_ad +params: + - name: groups + type: str + label: '用户组' + default: 'Users,Remote Desktop Users' + help_text: "{{ 'Params groups help text' | trans }}" + + +i18n: + Windows account change secret: + zh: '使用 Ansible 模块 win_domain_user 执行 Windows 账号改密' + ja: 'Ansible win_domain_user モジュールを使用して Windows アカウントのパスワード変更' + en: 'Using Ansible module win_domain_user to change Windows account secret' + + Params groups help text: + zh: '请输入用户组,多个用户组使用逗号分隔(需填写已存在的用户组)' + ja: 'グループを入力してください。複数のグループはコンマで区切ってください(既存のグループを入力してください)' + en: 'Please enter the group. Multiple groups are separated by commas (please enter the existing group)' + diff --git a/apps/accounts/automations/gather_account/host/windows/manifest.yml b/apps/accounts/automations/gather_account/host/windows/manifest.yml index c98fb0b2b..1d771d0fd 100644 --- a/apps/accounts/automations/gather_account/host/windows/manifest.yml +++ b/apps/accounts/automations/gather_account/host/windows/manifest.yml @@ -2,9 +2,12 @@ id: gather_accounts_windows name: "{{ 'Windows account gather' | trans }}" version: 1 method: gather_accounts -category: host +category: + - host + - ds type: - windows + - windows_ad i18n: Windows account gather: diff --git a/apps/accounts/automations/push_account/host/windows_ad/main.yml b/apps/accounts/automations/push_account/host/windows_ad/main.yml new file mode 100644 index 000000000..fc8a41f4f --- /dev/null +++ b/apps/accounts/automations/push_account/host/windows_ad/main.yml @@ -0,0 +1,27 @@ +- hosts: demo + gather_facts: no + tasks: + - name: Test privileged account + ansible.windows.win_ping: + + - name: Push user password + community.windows.win_domain_user: + name: "{{ account.username }}" + password: "{{ account.secret }}" + update_password: always + password_never_expires: yes + state: present + groups: "{{ params.groups }}" + groups_action: add + ignore_errors: true + when: account.secret_type == "password" + + - name: Refresh connection + ansible.builtin.meta: reset_connection + + - name: Verify password + ansible.windows.win_ping: + vars: + ansible_user: "{{ account.full_username }}" + ansible_password: "{{ account.secret }}" + when: account.secret_type == "password" and check_conn_after_change diff --git a/apps/accounts/automations/push_account/host/windows_ad/manifest.yml b/apps/accounts/automations/push_account/host/windows_ad/manifest.yml new file mode 100644 index 000000000..60f603b5f --- /dev/null +++ b/apps/accounts/automations/push_account/host/windows_ad/manifest.yml @@ -0,0 +1,25 @@ +id: push_account_ad_windows +name: "{{ 'Windows account push' | trans }}" +version: 1 +method: push_account +category: + - ds +type: + - windows_ad +params: + - name: groups + type: str + label: '用户组' + default: 'Users,Remote Desktop Users' + help_text: "{{ 'Params groups help text' | trans }}" + +i18n: + Windows account push: + zh: '使用 Ansible 模块 win_domain_user 执行 Windows 账号推送' + ja: 'Ansible win_domain_user モジュールを使用して Windows アカウントをプッシュする' + en: 'Using Ansible module win_domain_user to push account' + + Params groups help text: + zh: '请输入用户组,多个用户组使用逗号分隔(需填写已存在的用户组)' + ja: 'グループを入力してください。複数のグループはコンマで区切ってください(既存のグループを入力してください)' + en: 'Please enter the group. Multiple groups are separated by commas (please enter the existing group)' diff --git a/apps/accounts/automations/remove_account/host/windows_ad/main.yml b/apps/accounts/automations/remove_account/host/windows_ad/main.yml new file mode 100644 index 000000000..6fd268b84 --- /dev/null +++ b/apps/accounts/automations/remove_account/host/windows_ad/main.yml @@ -0,0 +1,9 @@ +- hosts: windows + gather_facts: no + tasks: + - name: "Remove account" + ansible.windows.win_domain_user: + name: "{{ account.username }}" + state: absent + + diff --git a/apps/accounts/automations/remove_account/host/windows_ad/manifest.yml b/apps/accounts/automations/remove_account/host/windows_ad/manifest.yml new file mode 100644 index 000000000..d813836bf --- /dev/null +++ b/apps/accounts/automations/remove_account/host/windows_ad/manifest.yml @@ -0,0 +1,14 @@ +id: remove_account_ad_windows +name: "{{ 'Windows account remove' | trans }}" +version: 1 +method: remove_account +category: + - ds +type: + - windows_ad + +i18n: + Windows account remove: + zh: 使用 Ansible 模块 win_domain_user 删除账号 + ja: Ansible モジュール win_domain_user を使用してアカウントを削除する + en: Use the Ansible module win_domain_user to delete an account diff --git a/apps/accounts/automations/verify_account/custom/rdp/main.yml b/apps/accounts/automations/verify_account/custom/rdp/main.yml index 33ee8282b..94e895004 100644 --- a/apps/accounts/automations/verify_account/custom/rdp/main.yml +++ b/apps/accounts/automations/verify_account/custom/rdp/main.yml @@ -10,6 +10,6 @@ rdp_ping: login_host: "{{ jms_asset.address }}" login_port: "{{ jms_asset.port }}" - login_user: "{{ account.username }}" + login_user: "{{ account.full_username }}" login_password: "{{ account.secret }}" login_secret_type: "{{ account.secret_type }}" diff --git a/apps/accounts/automations/verify_account/custom/rdp/manifest.yml b/apps/accounts/automations/verify_account/custom/rdp/manifest.yml index 3cfaf1880..12d92c5d6 100644 --- a/apps/accounts/automations/verify_account/custom/rdp/manifest.yml +++ b/apps/accounts/automations/verify_account/custom/rdp/manifest.yml @@ -2,8 +2,10 @@ id: verify_account_by_rdp name: "{{ 'Windows rdp account verify' | trans }}" category: - host + - ds type: - windows + - windows_ad method: verify_account protocol: rdp priority: 1 diff --git a/apps/accounts/automations/verify_account/host/windows/main.yml b/apps/accounts/automations/verify_account/host/windows/main.yml index a0a722eba..a7b49545c 100644 --- a/apps/accounts/automations/verify_account/host/windows/main.yml +++ b/apps/accounts/automations/verify_account/host/windows/main.yml @@ -7,5 +7,5 @@ - name: Verify account ansible.windows.win_ping: vars: - ansible_user: "{{ account.username }}" + ansible_user: "{{ account.full_username }}" ansible_password: "{{ account.secret }}" diff --git a/apps/accounts/automations/verify_account/host/windows/manifest.yml b/apps/accounts/automations/verify_account/host/windows/manifest.yml index a277f8c62..39198bf58 100644 --- a/apps/accounts/automations/verify_account/host/windows/manifest.yml +++ b/apps/accounts/automations/verify_account/host/windows/manifest.yml @@ -2,9 +2,12 @@ id: verify_account_windows name: "{{ 'Windows account verify' | trans }}" version: 1 method: verify_account -category: host +category: + - host + - ds type: - windows + - windows_ad i18n: Windows account verify: diff --git a/apps/accounts/automations/verify_account/manager.py b/apps/accounts/automations/verify_account/manager.py index 235e5c601..8280760c2 100644 --- a/apps/accounts/automations/verify_account/manager.py +++ b/apps/accounts/automations/verify_account/manager.py @@ -64,6 +64,7 @@ class VerifyAccountManager(AccountBasePlaybookManager): h['account'] = { 'name': account.name, 'username': account.username, + 'full_username': account.full_username, 'secret_type': account.secret_type, 'secret': account.escape_jinja2_syntax(secret), 'private_key_path': private_key_path, diff --git a/apps/assets/automations/gather_facts/host/windows/manifest.yml b/apps/assets/automations/gather_facts/host/windows/manifest.yml index 7068f4d6e..2977dc84c 100644 --- a/apps/assets/automations/gather_facts/host/windows/manifest.yml +++ b/apps/assets/automations/gather_facts/host/windows/manifest.yml @@ -2,9 +2,12 @@ id: gather_facts_windows name: "{{ 'Gather facts windows' | trans }}" version: 1 method: gather_facts -category: host +category: + - host + - ds type: - windows + - windows_ad i18n: Gather facts windows: zh: '使用 Ansible 指令 gather_facts 从 Windows 获取设备信息' diff --git a/apps/assets/automations/ping/custom/rdp/manifest.yml b/apps/assets/automations/ping/custom/rdp/manifest.yml index ad499b90e..07dbbdc21 100644 --- a/apps/assets/automations/ping/custom/rdp/manifest.yml +++ b/apps/assets/automations/ping/custom/rdp/manifest.yml @@ -3,8 +3,10 @@ name: "{{ 'Ping by pyfreerdp' | trans }}" category: - device - host + - ds type: - windows + - windows_ad method: ping protocol: rdp priority: 1 diff --git a/apps/assets/automations/ping/custom/ssh/manifest.yml b/apps/assets/automations/ping/custom/ssh/manifest.yml index c6d08ca12..e50eb9fe6 100644 --- a/apps/assets/automations/ping/custom/ssh/manifest.yml +++ b/apps/assets/automations/ping/custom/ssh/manifest.yml @@ -3,6 +3,7 @@ name: "{{ 'Ping by paramiko' | trans }}" category: - device - host + - ds type: - all method: ping diff --git a/apps/assets/automations/ping/custom/telnet/manifest.yml b/apps/assets/automations/ping/custom/telnet/manifest.yml index fc3a0a40a..2a48c63d5 100644 --- a/apps/assets/automations/ping/custom/telnet/manifest.yml +++ b/apps/assets/automations/ping/custom/telnet/manifest.yml @@ -3,6 +3,7 @@ name: "{{ 'Ping by telnet' | trans }}" category: - device - host + - ds type: - all method: ping diff --git a/apps/assets/automations/ping/host/windows/manifest.yml b/apps/assets/automations/ping/host/windows/manifest.yml index 7c42e03ba..6e53f1e14 100644 --- a/apps/assets/automations/ping/host/windows/manifest.yml +++ b/apps/assets/automations/ping/host/windows/manifest.yml @@ -2,9 +2,12 @@ id: win_ping name: "{{ 'Windows ping' | trans }}" version: 1 method: ping -category: host +category: + - host + - ds type: - windows + - windows_ad i18n: Windows ping: zh: 使用 Ansible 模块 内置模块 win_ping 来测试可连接性 diff --git a/apps/assets/const/ds.py b/apps/assets/const/ds.py index 064c3b1fd..e0acca5a6 100644 --- a/apps/assets/const/ds.py +++ b/apps/assets/const/ds.py @@ -36,6 +36,7 @@ class DirectoryTypes(BaseType): 'change_secret_enabled': True, 'push_account_enabled': True, 'gather_accounts_enabled': True, + 'remove_account_enabled': True, } } return constrains diff --git a/apps/assets/migrations/0017_auto_20250407_1124.py b/apps/assets/migrations/0017_auto_20250407_1124.py index a3a6c1dd0..756b7af76 100644 --- a/apps/assets/migrations/0017_auto_20250407_1124.py +++ b/apps/assets/migrations/0017_auto_20250407_1124.py @@ -48,7 +48,7 @@ def add_ds_platforms(apps, schema_editor): }, "gather_accounts_enabled": true, - "gather_accounts_method": "gather_accounts_ad_windows", + "gather_accounts_method": "gather_accounts_windows", "gather_accounts_params": { }, diff --git a/apps/ops/ansible/inventory.py b/apps/ops/ansible/inventory.py index 2a5153c5a..fabb0c06d 100644 --- a/apps/ops/ansible/inventory.py +++ b/apps/ops/ansible/inventory.py @@ -2,7 +2,6 @@ import json import os import re -import sys from collections import defaultdict from django.utils.translation import gettext as _ @@ -79,7 +78,7 @@ class JMSInventory: @staticmethod def make_account_ansible_vars(account, path_dir): var = { - 'ansible_user': account.username, + 'ansible_user': account.full_username, } if not account.secret: return var @@ -111,7 +110,8 @@ class JMSInventory: setting = getattr(p, 'setting') host['old_ssh_version'] = setting.get('old_ssh_version', False) - def make_account_vars(self, host, asset, account, automation, protocol, platform, gateway, path_dir): + def make_account_vars(self, host, asset, account, automation, protocol, platform, gateway, path_dir, + ansible_config): from accounts.const import AutomationTypes if not account: host['error'] = _("No account available") @@ -129,7 +129,8 @@ class JMSInventory: elif platform.su_enabled and not su_from and \ self.task_type in (AutomationTypes.change_secret, AutomationTypes.push_account): host.update(self.make_account_ansible_vars(account, path_dir)) - host['ansible_become'] = True + if ansible_config.get('ansible_shell_type') != 'powershell': + host['ansible_become'] = True host['ansible_become_user'] = 'root' host['ansible_become_password'] = account.escape_jinja2_syntax(account.secret) else: @@ -192,7 +193,6 @@ class JMSInventory: secret_info = {k: v for k, v in asset.secret_info.items() if v} host = { 'name': name, - 'local_python_interpreter': sys.executable, 'jms_asset': { 'id': str(asset.id), 'name': asset.name, 'address': asset.address, 'type': tp, 'category': category, @@ -202,7 +202,7 @@ class JMSInventory: 'origin_address': asset.address }, 'jms_account': { - 'id': str(account.id), 'username': account.username, + 'id': str(account.id), 'username': account.full_username, 'secret': account.escape_jinja2_syntax(account.secret), 'secret_type': account.secret_type, 'private_key_path': account.get_private_key_path(path_dir) } if account else None @@ -223,7 +223,7 @@ class JMSInventory: gateway = asset.domain.select_gateway() self.make_account_vars( - host, asset, account, automation, protocol, platform, gateway, path_dir + host, asset, account, automation, protocol, platform, gateway, path_dir, ansible_config ) return host