Merge branch 'v3' of github.com:jumpserver/jumpserver into v3

pull/8970/head
Jiangjie.Bai 2022-10-14 17:01:44 +08:00
commit c79c3f8aec
13 changed files with 126 additions and 69 deletions

View File

@ -123,8 +123,22 @@ class BasePlaybookManager:
runners.append(runer)
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):
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):
print("Runner failed: {} {}".format(e, self))

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -10,15 +10,15 @@ __all__ = ['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 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 host_callback: after generate host, call this callback to modify host
"""
self.assets = self.clean_assets(assets)
self.account_username = account
self.account_prefer = account_prefer
self.account_policy = account_policy
self.host_callback = host_callback
@ -58,6 +58,46 @@ class JMSInventory:
)
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):
host = {
'name': '{}'.format(asset.name),
@ -73,14 +113,12 @@ class JMSInventory:
} if account else None
}
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)
gateway = None
if asset.domain:
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 gateway:
host['ansible_host'] = gateway.address
@ -91,29 +129,16 @@ class JMSInventory:
else:
host['ansible_connection'] = 'local'
else:
host['ansible_host'] = asset.address
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))
self.make_ssh_account_vars(host, asset, account, automation, protocols, platform, gateway)
return host
def select_account(self, asset):
accounts = list(asset.accounts.all())
account_selected = None
account_username = self.account_username
account_username = self.account_prefer
if isinstance(self.account_username, str):
account_username = [self.account_username]
if isinstance(self.account_prefer, str):
account_username = self.account_prefer.split(',')
if account_username:
for username in account_username:

View File

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