From 8ea3c3288bbed194e1052e80f61fd83d8d13c6fe Mon Sep 17 00:00:00 2001 From: fit2bot <68588906+fit2bot@users.noreply.github.com> Date: Tue, 8 Aug 2023 17:26:29 +0800 Subject: [PATCH] =?UTF-8?q?perf:=20=E6=94=B9=E5=AF=86=E6=9B=BF=E6=8D=A2?= =?UTF-8?q?=E6=A0=A1=E9=AA=8C=E5=8F=AF=E8=BF=9E=E6=8E=A5=E6=80=A7=E6=96=B9?= =?UTF-8?q?=E6=B3=95=20(#11224)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: feng <1304903146@qq.com> --- .../change_secret/host/aix/main.yml | 32 +++++++----- .../change_secret/host/posix/main.yml | 32 +++++++----- .../push_account/host/aix/main.yml | 33 +++++++----- .../push_account/host/posix/main.yml | 33 +++++++----- apps/ops/ansible/inventory.py | 4 +- .../ansible/modules_utils/custom_common.py | 52 ++++++++++++++++++- 6 files changed, 128 insertions(+), 58 deletions(-) diff --git a/apps/accounts/automations/change_secret/host/aix/main.yml b/apps/accounts/automations/change_secret/host/aix/main.yml index 8593c7534..56fde8a2c 100644 --- a/apps/accounts/automations/change_secret/host/aix/main.yml +++ b/apps/accounts/automations/change_secret/host/aix/main.yml @@ -73,20 +73,24 @@ - name: Refresh connection ansible.builtin.meta: reset_connection - - name: "Verify {{ account.username }} password" - ansible.builtin.ping: - become: no - vars: - ansible_user: "{{ account.username }}" - ansible_password: "{{ account.secret }}" - ansible_become: no + - name: "Verify {{ account.username }} password (paramiko)" + ssh_ping: + login_user: "{{ account.username }}" + login_password: "{{ account.secret }}" + login_host: "{{ jms_asset.address }}" + login_port: "{{ jms_asset.port }}" + gateway_args: "{{ jms_asset.ansible_ssh_common_args | default('') }}" + become: false when: account.secret_type == "password" + delegate_to: localhost - - name: "Verify {{ account.username }} SSH key" - ansible.builtin.ping: - become: no - vars: - ansible_user: "{{ account.username }}" - ansible_ssh_private_key_file: "{{ account.private_key_path }}" - ansible_become: no + - name: "Verify {{ account.username }} SSH KEY (paramiko)" + ssh_ping: + login_host: "{{ jms_asset.address }}" + login_port: "{{ jms_asset.port }}" + login_user: "{{ account.username }}" + login_private_key_path: "{{ account.private_key_path }}" + gateway_args: "{{ jms_asset.ansible_ssh_common_args | default('') }}" + become: false when: account.secret_type == "ssh_key" + delegate_to: localhost diff --git a/apps/accounts/automations/change_secret/host/posix/main.yml b/apps/accounts/automations/change_secret/host/posix/main.yml index 5ed6a10b4..1dca70a5a 100644 --- a/apps/accounts/automations/change_secret/host/posix/main.yml +++ b/apps/accounts/automations/change_secret/host/posix/main.yml @@ -73,20 +73,24 @@ - name: Refresh connection ansible.builtin.meta: reset_connection - - name: "Verify {{ account.username }} password" - ansible.builtin.ping: - become: no - vars: - ansible_user: "{{ account.username }}" - ansible_password: "{{ account.secret }}" - ansible_become: no + - name: "Verify {{ account.username }} password (paramiko)" + ssh_ping: + login_user: "{{ account.username }}" + login_password: "{{ account.secret }}" + login_host: "{{ jms_asset.address }}" + login_port: "{{ jms_asset.port }}" + gateway_args: "{{ jms_asset.ansible_ssh_common_args | default('') }}" + become: false when: account.secret_type == "password" + delegate_to: localhost - - name: "Verify {{ account.username }} SSH key" - ansible.builtin.ping: - become: no - vars: - ansible_user: "{{ account.username }}" - ansible_ssh_private_key_file: "{{ account.private_key_path }}" - ansible_become: no + - name: "Verify {{ account.username }} SSH KEY (paramiko)" + ssh_ping: + login_host: "{{ jms_asset.address }}" + login_port: "{{ jms_asset.port }}" + login_user: "{{ account.username }}" + login_private_key_path: "{{ account.private_key_path }}" + gateway_args: "{{ jms_asset.ansible_ssh_common_args | default('') }}" + become: false when: account.secret_type == "ssh_key" + delegate_to: localhost diff --git a/apps/accounts/automations/push_account/host/aix/main.yml b/apps/accounts/automations/push_account/host/aix/main.yml index 8593c7534..0e6fba5c5 100644 --- a/apps/accounts/automations/push_account/host/aix/main.yml +++ b/apps/accounts/automations/push_account/host/aix/main.yml @@ -73,20 +73,25 @@ - name: Refresh connection ansible.builtin.meta: reset_connection - - name: "Verify {{ account.username }} password" - ansible.builtin.ping: - become: no - vars: - ansible_user: "{{ account.username }}" - ansible_password: "{{ account.secret }}" - ansible_become: no + - name: "Verify {{ account.username }} password (paramiko)" + ssh_ping: + login_user: "{{ account.username }}" + login_password: "{{ account.secret }}" + login_host: "{{ jms_asset.address }}" + login_port: "{{ jms_asset.port }}" + gateway_args: "{{ jms_asset.ansible_ssh_common_args | default('') }}" + become: false when: account.secret_type == "password" + delegate_to: localhost - - name: "Verify {{ account.username }} SSH key" - ansible.builtin.ping: - become: no - vars: - ansible_user: "{{ account.username }}" - ansible_ssh_private_key_file: "{{ account.private_key_path }}" - ansible_become: no + - name: "Verify {{ account.username }} SSH KEY (paramiko)" + ssh_ping: + login_host: "{{ jms_asset.address }}" + login_port: "{{ jms_asset.port }}" + login_user: "{{ account.username }}" + login_private_key_path: "{{ account.private_key_path }}" + gateway_args: "{{ jms_asset.ansible_ssh_common_args | default('') }}" + become: false when: account.secret_type == "ssh_key" + delegate_to: localhost + diff --git a/apps/accounts/automations/push_account/host/posix/main.yml b/apps/accounts/automations/push_account/host/posix/main.yml index 5ed6a10b4..ea5128b17 100644 --- a/apps/accounts/automations/push_account/host/posix/main.yml +++ b/apps/accounts/automations/push_account/host/posix/main.yml @@ -73,20 +73,25 @@ - name: Refresh connection ansible.builtin.meta: reset_connection - - name: "Verify {{ account.username }} password" - ansible.builtin.ping: - become: no - vars: - ansible_user: "{{ account.username }}" - ansible_password: "{{ account.secret }}" - ansible_become: no + - name: "Verify {{ account.username }} password (paramiko)" + ssh_ping: + login_user: "{{ account.username }}" + login_password: "{{ account.secret }}" + login_host: "{{ jms_asset.address }}" + login_port: "{{ jms_asset.port }}" + gateway_args: "{{ jms_asset.ansible_ssh_common_args | default('') }}" + become: false when: account.secret_type == "password" + delegate_to: localhost - - name: "Verify {{ account.username }} SSH key" - ansible.builtin.ping: - become: no - vars: - ansible_user: "{{ account.username }}" - ansible_ssh_private_key_file: "{{ account.private_key_path }}" - ansible_become: no + - name: "Verify {{ account.username }} SSH KEY (paramiko)" + ssh_ping: + login_host: "{{ jms_asset.address }}" + login_port: "{{ jms_asset.port }}" + login_user: "{{ account.username }}" + login_private_key_path: "{{ account.private_key_path }}" + gateway_args: "{{ jms_asset.ansible_ssh_common_args | default('') }}" + become: false when: account.secret_type == "ssh_key" + delegate_to: localhost + diff --git a/apps/ops/ansible/inventory.py b/apps/ops/ansible/inventory.py index 3f3dc19b0..a650b158e 100644 --- a/apps/ops/ansible/inventory.py +++ b/apps/ops/ansible/inventory.py @@ -127,7 +127,9 @@ class JMSInventory: } host['jms_asset']['port'] = port else: - host.update(self.make_proxy_command(gateway)) + ansible_ssh_common_args = self.make_proxy_command(gateway) + host['jms_asset'].update(ansible_ssh_common_args) + host.update(ansible_ssh_common_args) @staticmethod def get_primary_protocol(ansible_config, protocols): diff --git a/apps/ops/ansible/modules_utils/custom_common.py b/apps/ops/ansible/modules_utils/custom_common.py index 01546ff33..0eb454e5a 100644 --- a/apps/ops/ansible/modules_utils/custom_common.py +++ b/apps/ops/ansible/modules_utils/custom_common.py @@ -1,6 +1,8 @@ +import re import time import paramiko +from sshtunnel import SSHTunnelForwarder def common_argument_spec(): @@ -12,6 +14,7 @@ def common_argument_spec(): login_secret_type=dict(type='str', required=False, default='password'), login_private_key_path=dict(type='str', required=False, no_log=True), first_conn_delay_time=dict(type='float', required=False, default=0.5), + gateway_args=dict(type='str', required=False, default=''), become=dict(type='bool', default=False, required=False), become_method=dict(type='str', required=False), @@ -27,8 +30,10 @@ class SSHClient: self.module = module self.channel = None self.is_connect = False + self.gateway_server = None self.client = paramiko.SSHClient() self.client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) + self.connect_params = self.get_connect_params() def get_connect_params(self): params = { @@ -90,11 +95,56 @@ class SSHClient: err_msg = su_output return err_msg + def local_gateway_prepare(self): + gateway_args = self.module.params['gateway_args'] or '' + pattern = r"(?:sshpass -p ([\w@]+))?\s*ssh -o Port=(\d+)\s+-o StrictHostKeyChecking=no\s+([\w@]+)@([" \ + r"\d.]+)\s+-W %h:%p -q(?: -i (.+))?'" + match = re.search(pattern, gateway_args) + + if not match: + return + + password, port, username, address, private_key_path = match.groups() + password = password if password else None + private_key_path = private_key_path if private_key_path else None + remote_hostname = self.module.params['login_host'] + remote_port = self.module.params['login_port'] + + server = SSHTunnelForwarder( + (address, int(port)), + ssh_username=username, + ssh_password=password, + ssh_pkey=private_key_path, + remote_bind_address=(remote_hostname, remote_port) + ) + + server.start() + self.connect_params['hostname'] = '127.0.0.1' + self.connect_params['port'] = server.local_bind_port + self.gateway_server = server + + def local_gateway_clean(self): + gateway_server = self.gateway_server + if not gateway_server: + return + try: + gateway_server.stop() + except Exception: + pass + + def before_runner_start(self): + self.local_gateway_prepare() + + def after_runner_end(self): + self.local_gateway_clean() + def connect(self): try: - self.client.connect(**self.get_connect_params()) + self.before_runner_start() + self.client.connect(**self.connect_params) self.is_connect = True err_msg = self.switch_user() + self.after_runner_end() except Exception as err: err_msg = str(err) return err_msg