perf: 修改改密

pull/8970/head
ibuler 2022-10-14 16:33:24 +08:00
parent f2f75add8e
commit 4e2aebde6c
13 changed files with 126 additions and 69 deletions

View File

@ -123,8 +123,22 @@ class BasePlaybookManager:
runners.append(runer) runners.append(runer)
return runners return runners
def on_host_success(self, host, result):
pass
def on_host_error(self, host, error, result):
pass
def on_runner_success(self, runner, cb): def on_runner_success(self, runner, cb):
raise NotImplementedError summary = cb.summary
for state, hosts in summary.items():
for host in hosts:
result = cb.result.get(host)
if state == 'ok':
self.on_host_success(host, result)
else:
error = hosts.get(host)
self.on_host_error(host, error, result)
def on_runner_failed(self, runner, e): def on_runner_failed(self, runner, e):
print("Runner failed: {} {}".format(e, self)) print("Runner failed: {} {}".format(e, self))

View File

@ -1,7 +1,7 @@
- hosts: demo - hosts: demo
tasks: tasks:
- name: ping - name: ping
ping: ansible.builtin.ping:
#- name: print variables #- name: print variables
# debug: # debug:
@ -22,7 +22,7 @@
when: account.public_key when: account.public_key
- name: Verify password - name: Verify password
ping: ansible.builtin.ping:
vars: vars:
ansible_user: "{{ account.username }}" ansible_user: "{{ account.username }}"
ansible_pass: "{{ account.password }}" ansible_pass: "{{ account.password }}"

View File

@ -2,29 +2,33 @@
gather_facts: no gather_facts: no
tasks: tasks:
- name: Test privileged account - name: Test privileged account
ping: ansible.builtin.ping:
#
#- name: print variables # - name: print variables
# debug: # debug:
# msg: "Username: {{ account.username }}, Secret: {{ account.secret }}, Secret type: {{ account.secret_type }}" # msg: "Username: {{ account.username }}, Secret: {{ account.secret }}, Secret type: {{ account.secret_type }}"
- name: Change password - name: Change password
user: ansible.builtin.user:
name: "{{ account.username }}" name: "{{ account.username }}"
password: "{{ account.secret | password_hash('sha512') }}" password: "{{ account.secret | password_hash('sha512') }}"
update_password: always update_password: always
when: account.secret_type == 'password' when: account.secret_type == "password"
- name: Change public key - name: Change public key
authorized_key: ansible.builtin.authorized_key:
user: "{{ account.username }}" user: "{{ account.username }}"
key: "{{ account.public_key }}" key: "{{ account.public_key }}"
state: present state: present
when: account.public_key when: account.secret_type == "public_key"
- name: Refresh connection
ansible.builtin.meta: reset_connection
- name: Verify password - name: Verify password
ping: ansible.builtin.ping:
become: no
vars: vars:
ansible_user: "{{ account.username }}" ansible_user: "{{ account.username }}"
ansible_pass: "{{ account.secret }}" ansible_password: "{{ account.secret }}"
ansible_ssh_connection: paramiko ansible_become: no

View File

@ -2,29 +2,24 @@
gather_facts: no gather_facts: no
tasks: tasks:
- name: ping - name: ping
ping: ansible.windows.win_ping:
#- name: print variables # - name: Print variables
# debug: # debug:
# msg: "Username: {{ account.username }}, Password: {{ account.password }}" # msg: "Username: {{ account.username }}, Password: {{ account.secret }}"
- name: Change password - name: Change password
user: ansible.windows.win_user:
name: "{{ account.username }}" name: "{{ account.username }}"
password: "{{ account.password | password_hash('des') }}" password: "{{ account.secret }}"
update_password: always update_password: always
when: account.password when: account.secret_type == "password"
- name: Change public key - name: Refresh connection
authorized_key: ansible.builtin.meta: reset_connection
user: "{{ account.username }}"
key: "{{ account.public_key }}"
state: present
when: account.public_key
- name: Verify password - name: Verify password
ping: ansible.windows.win_ping:
vars: vars:
ansible_user: "{{ account.username }}" ansible_user: "{{ account.username }}"
ansible_pass: "{{ account.password }}" ansible_password: "{{ account.secret }}"
ansible_ssh_connection: paramiko

View File

@ -1,11 +1,13 @@
from copy import deepcopy
from collections import defaultdict
import random import random
import string import string
from copy import deepcopy
from collections import defaultdict
from django.utils import timezone
from common.utils import lazyproperty, gen_key_pair from common.utils import lazyproperty, gen_key_pair
from ..base.manager import BasePlaybookManager
from assets.models import ChangeSecretRecord, SecretStrategy from assets.models import ChangeSecretRecord, SecretStrategy
from ..base.manager import BasePlaybookManager
string_punctuation = '!#$%&()*+,-.:;<=>?@[]^_~' string_punctuation = '!#$%&()*+,-.:;<=>?@[]^_~'
DEFAULT_PASSWORD_LENGTH = 30 DEFAULT_PASSWORD_LENGTH = 30
@ -121,10 +123,26 @@ class ChangeSecretManager(BasePlaybookManager):
ChangeSecretRecord.objects.bulk_create(records) ChangeSecretRecord.objects.bulk_create(records)
return inventory_hosts return inventory_hosts
def on_runner_success(self, runner, cb): def on_host_success(self, host, result):
summary = cb.summary recorder = self.name_recorder_mapper.get(host)
print("Summary: ") if not recorder:
print(summary) return
recorder.status = 'succeed'
recorder.date_finished = timezone.now()
recorder.save()
account = recorder.account
account.secret = recorder.new_secret
account.save(update_fields=['secret'])
def on_host_error(self, host, error, result):
recorder = self.name_recorder_mapper.get(host)
if not recorder:
return
recorder.status = 'failed'
recorder.date_finished = timezone.now()
recorder.error = error
recorder.save()
def on_runner_failed(self, runner, e): def on_runner_failed(self, runner, e):
pass pass

View File

@ -1,5 +1,5 @@
- name: ping - name: ping
ping: ansible.builtin.ping:
#- name: print variables #- name: print variables
# debug: # debug:
@ -20,7 +20,7 @@
when: account.public_key when: account.public_key
- name: Verify password - name: Verify password
ping: ansible.builtin.ping:
vars: vars:
ansible_user: "{{ account.username }}" ansible_user: "{{ account.username }}"
ansible_pass: "{{ account.password }}" ansible_pass: "{{ account.password }}"

View File

@ -3,6 +3,5 @@ name: Gather posix facts
category: host category: host
type: type:
- linux - linux
- windows
- unix - unix
method: gather_facts method: gather_facts

View File

@ -2,4 +2,4 @@
gather_facts: no gather_facts: no
tasks: tasks:
- name: Posix ping - name: Posix ping
ping: ansible.builtin.ping:

View File

@ -3,6 +3,5 @@ name: Posix ping
category: host category: host
type: type:
- linux - linux
- windows
- unix - unix
method: ping method: ping

View File

@ -1,7 +1,7 @@
id: win_ping id: win_ping
name: Windows ping name: Windows ping
version: 1 version: 1
method: change_secret method: ping
category: host category: host
type: type:
- windows - windows

View File

@ -33,6 +33,9 @@ class HostTypes(BaseType):
return { return {
'*': { '*': {
'choices': ['ssh', 'telnet', 'vnc', 'rdp'] 'choices': ['ssh', 'telnet', 'vnc', 'rdp']
},
cls.WINDOWS: {
'choices': ['rdp', 'ssh', 'vnc']
} }
} }

View File

@ -10,15 +10,15 @@ __all__ = ['JMSInventory']
class JMSInventory: class JMSInventory:
def __init__(self, assets, account='', account_policy='smart', host_callback=None): def __init__(self, assets, account_policy='smart', account_prefer='root,administrator', host_callback=None):
""" """
:param assets: :param assets:
:param account: account username name if not set use account_policy :param account_prefer: account username name if not set use account_policy
:param account_policy: :param account_policy:
:param host_callback: after generate host, call this callback to modify host :param host_callback: after generate host, call this callback to modify host
""" """
self.assets = self.clean_assets(assets) self.assets = self.clean_assets(assets)
self.account_username = account self.account_prefer = account_prefer
self.account_policy = account_policy self.account_policy = account_policy
self.host_callback = host_callback self.host_callback = host_callback
@ -58,6 +58,46 @@ class JMSInventory:
) )
return {"ansible_ssh_common_args": proxy_command} return {"ansible_ssh_common_args": proxy_command}
@staticmethod
def make_account_ansible_vars(account):
var = {
'ansible_user': account.username,
}
if not account.secret:
return var
if account.secret_type == 'password':
var['ansible_password'] = account.secret
elif account.secret_type == 'ssh_key':
var['ansible_ssh_private_key_file'] = account.private_key_file
return var
def make_ssh_account_vars(self, host, asset, account, automation, protocols, platform, gateway):
if not account:
host['error'] = _("No account available")
return host
ssh_protocol_matched = list(filter(lambda x: x.name == 'ssh', protocols))
ssh_protocol = ssh_protocol_matched[0] if ssh_protocol_matched else None
host['ansible_host'] = asset.address
host['ansible_port'] = ssh_protocol.port if ssh_protocol else 22
su_from = account.su_from
if platform.su_enabled and su_from:
host.update(self.make_account_ansible_vars(su_from))
become_method = 'sudo' if platform.su_method != 'su' else 'su'
host['ansible_become'] = True
host['ansible_become_method'] = 'sudo'
host['ansible_become_user'] = account.username
if become_method == 'sudo':
host['ansible_become_password'] = su_from.secret
else:
host['ansible_become_password'] = account.secret
else:
host.update(self.make_account_ansible_vars(account))
if gateway:
host.update(self.make_proxy_command(gateway))
def asset_to_host(self, asset, account, automation, protocols, platform): def asset_to_host(self, asset, account, automation, protocols, platform):
host = { host = {
'name': '{}'.format(asset.name), 'name': '{}'.format(asset.name),
@ -73,14 +113,12 @@ class JMSInventory:
} if account else None } if account else None
} }
ansible_config = dict(automation.ansible_config) ansible_config = dict(automation.ansible_config)
ansible_connection = ansible_config.pop('ansible_connection', 'ssh') ansible_connection = ansible_config.get('ansible_connection', 'ssh')
host.update(ansible_config) host.update(ansible_config)
gateway = None gateway = None
if asset.domain: if asset.domain:
gateway = asset.domain.select_gateway() gateway = asset.domain.select_gateway()
ssh_protocol_matched = list(filter(lambda x: x.name == 'ssh', protocols))
ssh_protocol = ssh_protocol_matched[0] if ssh_protocol_matched else None
if ansible_connection == 'local': if ansible_connection == 'local':
if gateway: if gateway:
host['ansible_host'] = gateway.address host['ansible_host'] = gateway.address
@ -91,29 +129,16 @@ class JMSInventory:
else: else:
host['ansible_connection'] = 'local' host['ansible_connection'] = 'local'
else: else:
host['ansible_host'] = asset.address self.make_ssh_account_vars(host, asset, account, automation, protocols, platform, gateway)
host['ansible_port'] = ssh_protocol.port if ssh_protocol else 22
if account:
host['ansible_user'] = account.username
if account.secret_type == 'password' and account.secret:
host['ansible_password'] = account.secret
elif account.secret_type == 'private_key' and account.secret:
host['ssh_private_key'] = account.private_key_file
else:
host['error'] = _("No account found")
if gateway:
host.update(self.make_proxy_command(gateway))
return host return host
def select_account(self, asset): def select_account(self, asset):
accounts = list(asset.accounts.all()) accounts = list(asset.accounts.all())
account_selected = None account_selected = None
account_username = self.account_username account_username = self.account_prefer
if isinstance(self.account_username, str): if isinstance(self.account_prefer, str):
account_username = [self.account_username] account_username = self.account_prefer.split(',')
if account_username: if account_username:
for username in account_username: for username in account_username:

View File

@ -7,7 +7,7 @@
tasks: tasks:
- name: 监测特权用户密码 - name: 监测特权用户密码
ping: ansible.builtin.ping:
- name: 更改用户密码 - name: 更改用户密码
user: user:
@ -19,5 +19,5 @@
vars: vars:
- ansible_user: '{{ user1 }}' - ansible_user: '{{ user1 }}'
ansible_ssh_password: '{{ user1password }}' ansible_ssh_password: '{{ user1password }}'
ping: ansible.builtin.ping: