mirror of https://github.com/jumpserver/jumpserver
perf: 修改改密
parent
f2f75add8e
commit
4e2aebde6c
|
@ -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))
|
||||||
|
|
|
@ -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 }}"
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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 }}"
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -2,4 +2,4 @@
|
||||||
gather_facts: no
|
gather_facts: no
|
||||||
tasks:
|
tasks:
|
||||||
- name: Posix ping
|
- name: Posix ping
|
||||||
ping:
|
ansible.builtin.ping:
|
||||||
|
|
|
@ -3,6 +3,5 @@ name: Posix ping
|
||||||
category: host
|
category: host
|
||||||
type:
|
type:
|
||||||
- linux
|
- linux
|
||||||
- windows
|
|
||||||
- unix
|
- unix
|
||||||
method: ping
|
method: ping
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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']
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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:
|
||||||
|
|
|
@ -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:
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue