mirror of https://github.com/jumpserver/jumpserver
fix: 修复自动化修改密码bug
parent
091bffa626
commit
64daacce63
|
@ -49,7 +49,7 @@ class BasePlaybookManager:
|
||||||
ansible_dir = settings.ANSIBLE_DIR
|
ansible_dir = settings.ANSIBLE_DIR
|
||||||
dir_name = '{}_{}'.format(self.automation.name.replace(' ', '_'), self.execution.id)
|
dir_name = '{}_{}'.format(self.automation.name.replace(' ', '_'), self.execution.id)
|
||||||
path = os.path.join(
|
path = os.path.join(
|
||||||
ansible_dir, 'automations', self.automation.type,
|
ansible_dir, 'automations', self.execution.snapshot['type'],
|
||||||
dir_name, timezone.now().strftime('%Y%m%d_%H%M%S')
|
dir_name, timezone.now().strftime('%Y%m%d_%H%M%S')
|
||||||
)
|
)
|
||||||
if not os.path.exists(path):
|
if not os.path.exists(path):
|
||||||
|
|
|
@ -13,26 +13,26 @@
|
||||||
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: "{{ secret_type == 'password' }}"
|
when: secret_type == "password"
|
||||||
|
|
||||||
- name: create user If it already exists, no operation will be performed
|
- name: create user If it already exists, no operation will be performed
|
||||||
ansible.builtin.user:
|
ansible.builtin.user:
|
||||||
name: "{{ account.username }}"
|
name: "{{ account.username }}"
|
||||||
when: "{{ secret_type == 'ssh_key' }}"
|
when: secret_type == "ssh_key"
|
||||||
|
|
||||||
- name: remove jumpserver ssh key
|
- name: remove jumpserver ssh key
|
||||||
ansible.builtin.lineinfile:
|
ansible.builtin.lineinfile:
|
||||||
dest: "{{ kwargs.dest }}"
|
dest: "{{ kwargs.dest }}"
|
||||||
regexp: "{{ kwargs.regexp }}"
|
regexp: "{{ kwargs.regexp }}"
|
||||||
state: absent
|
state: absent
|
||||||
when: "{{ secret_type == 'ssh_key' and kwargs.strategy == 'set_jms' }}"
|
when: secret_type == "ssh_key" and kwargs.strategy == "set_jms"
|
||||||
|
|
||||||
- name: Change SSH key
|
- name: Change SSH key
|
||||||
ansible.builtin.authorized_key:
|
ansible.builtin.authorized_key:
|
||||||
user: "{{ account.username }}"
|
user: "{{ account.username }}"
|
||||||
key: "{{ account.secret }}"
|
key: "{{ account.secret }}"
|
||||||
exclusive: "{{ kwargs.exclusive }}"
|
exclusive: "{{ kwargs.exclusive }}"
|
||||||
when: "{{ secret_type == 'ssh_key' }}"
|
when: secret_type == "ssh_key"
|
||||||
|
|
||||||
- name: Refresh connection
|
- name: Refresh connection
|
||||||
ansible.builtin.meta: reset_connection
|
ansible.builtin.meta: reset_connection
|
||||||
|
@ -44,7 +44,7 @@
|
||||||
ansible_user: "{{ account.username }}"
|
ansible_user: "{{ account.username }}"
|
||||||
ansible_password: "{{ account.secret }}"
|
ansible_password: "{{ account.secret }}"
|
||||||
ansible_become: no
|
ansible_become: no
|
||||||
when: "{{ secret_type == 'password' }}"
|
when: secret_type == "password"
|
||||||
|
|
||||||
- name: Verify SSH key
|
- name: Verify SSH key
|
||||||
ansible.builtin.ping:
|
ansible.builtin.ping:
|
||||||
|
@ -53,4 +53,4 @@
|
||||||
ansible_user: "{{ account.username }}"
|
ansible_user: "{{ account.username }}"
|
||||||
ansible_ssh_private_key_file: "{{ account.private_key_path }}"
|
ansible_ssh_private_key_file: "{{ account.private_key_path }}"
|
||||||
ansible_become: no
|
ansible_become: no
|
||||||
when: "{{ secret_type == 'ssh_key' }}"
|
when: secret_type == "ssh_key"
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
name: "{{ account.username }}"
|
name: "{{ account.username }}"
|
||||||
password: "{{ account.secret }}"
|
password: "{{ account.secret }}"
|
||||||
update_password: always
|
update_password: always
|
||||||
when: "{{ account.secret_type == 'password' }}"
|
when: account.secret_type == "password"
|
||||||
|
|
||||||
- name: Refresh connection
|
- name: Refresh connection
|
||||||
ansible.builtin.meta: reset_connection
|
ansible.builtin.meta: reset_connection
|
||||||
|
@ -23,4 +23,4 @@
|
||||||
vars:
|
vars:
|
||||||
ansible_user: "{{ account.username }}"
|
ansible_user: "{{ account.username }}"
|
||||||
ansible_password: "{{ account.secret }}"
|
ansible_password: "{{ account.secret }}"
|
||||||
when: "{{ account.secret_type == 'password' }}"
|
when: account.secret_type == "password"
|
||||||
|
|
|
@ -20,15 +20,15 @@ class ChangeSecretManager(BasePlaybookManager):
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
super().__init__(*args, **kwargs)
|
super().__init__(*args, **kwargs)
|
||||||
self.method_hosts_mapper = defaultdict(list)
|
self.method_hosts_mapper = defaultdict(list)
|
||||||
self.secret_type = self.execution.plan_snapshot.get('secret_type')
|
self.secret_type = self.execution.snapshot['secret_type']
|
||||||
self.secret_strategy = self.execution.plan_snapshot['secret_strategy']
|
self.secret_strategy = self.execution.snapshot['secret_strategy']
|
||||||
self._password_generated = None
|
self._password_generated = None
|
||||||
self._ssh_key_generated = None
|
self._ssh_key_generated = None
|
||||||
self.name_recorder_mapper = {} # 做个映射,方便后面处理
|
self.name_recorder_mapper = {} # 做个映射,方便后面处理
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def method_type(cls):
|
def method_type(cls):
|
||||||
return AutomationTypes.method_id_meta_mapper
|
return AutomationTypes.change_secret
|
||||||
|
|
||||||
@lazyproperty
|
@lazyproperty
|
||||||
def related_accounts(self):
|
def related_accounts(self):
|
||||||
|
@ -53,7 +53,7 @@ class ChangeSecretManager(BasePlaybookManager):
|
||||||
return key_path
|
return key_path
|
||||||
|
|
||||||
def generate_password(self):
|
def generate_password(self):
|
||||||
kwargs = self.automation.plan_snapshot['password_rules'] or {}
|
kwargs = self.execution.snapshot['password_rules'] or {}
|
||||||
length = int(kwargs.get('length', DEFAULT_PASSWORD_RULES['length']))
|
length = int(kwargs.get('length', DEFAULT_PASSWORD_RULES['length']))
|
||||||
symbol_set = kwargs.get('symbol_set')
|
symbol_set = kwargs.get('symbol_set')
|
||||||
if symbol_set is None:
|
if symbol_set is None:
|
||||||
|
@ -69,7 +69,7 @@ class ChangeSecretManager(BasePlaybookManager):
|
||||||
|
|
||||||
def get_ssh_key(self):
|
def get_ssh_key(self):
|
||||||
if self.secret_strategy == SecretStrategy.custom:
|
if self.secret_strategy == SecretStrategy.custom:
|
||||||
ssh_key = self.automation.plan_snapshot['ssh_key']
|
ssh_key = self.execution.snapshot['ssh_key']
|
||||||
if not ssh_key:
|
if not ssh_key:
|
||||||
raise ValueError("Automation SSH key must be set")
|
raise ValueError("Automation SSH key must be set")
|
||||||
return ssh_key
|
return ssh_key
|
||||||
|
@ -82,7 +82,7 @@ class ChangeSecretManager(BasePlaybookManager):
|
||||||
|
|
||||||
def get_password(self):
|
def get_password(self):
|
||||||
if self.secret_strategy == SecretStrategy.custom:
|
if self.secret_strategy == SecretStrategy.custom:
|
||||||
password = self.automation.plan_snapshot['password']
|
password = self.execution.snapshot['secret']
|
||||||
if not password:
|
if not password:
|
||||||
raise ValueError("Automation Password must be set")
|
raise ValueError("Automation Password must be set")
|
||||||
return password
|
return password
|
||||||
|
@ -106,7 +106,7 @@ class ChangeSecretManager(BasePlaybookManager):
|
||||||
kwargs = {}
|
kwargs = {}
|
||||||
if self.secret_type != SecretType.ssh_key:
|
if self.secret_type != SecretType.ssh_key:
|
||||||
return kwargs
|
return kwargs
|
||||||
kwargs['strategy'] = self.automation.plan_snapshot['ssh_key_change_strategy']
|
kwargs['strategy'] = self.execution.snapshot['ssh_key_change_strategy']
|
||||||
kwargs['exclusive'] = 'yes' if kwargs['strategy'] == SSHKeyStrategy.set else 'no'
|
kwargs['exclusive'] = 'yes' if kwargs['strategy'] == SSHKeyStrategy.set else 'no'
|
||||||
|
|
||||||
if kwargs['strategy'] == SSHKeyStrategy.set_jms:
|
if kwargs['strategy'] == SSHKeyStrategy.set_jms:
|
||||||
|
@ -123,11 +123,11 @@ class ChangeSecretManager(BasePlaybookManager):
|
||||||
accounts = asset.accounts.all()
|
accounts = asset.accounts.all()
|
||||||
if account:
|
if account:
|
||||||
accounts = accounts.exclude(id=account.id)
|
accounts = accounts.exclude(id=account.id)
|
||||||
if '*' not in self.automation.accounts:
|
|
||||||
accounts = accounts.filter(
|
|
||||||
username__in=self.automation.accounts, secret_type=self.secret_type
|
|
||||||
)
|
|
||||||
|
|
||||||
|
if '*' not in self.execution.snapshot['accounts']:
|
||||||
|
accounts = accounts.filter(username__in=self.execution.snapshot['accounts'])
|
||||||
|
|
||||||
|
accounts = accounts.filter(secret_type=self.secret_type)
|
||||||
method_attr = getattr(automation, self.method_type() + '_method')
|
method_attr = getattr(automation, self.method_type() + '_method')
|
||||||
method_hosts = self.method_hosts_mapper[method_attr]
|
method_hosts = self.method_hosts_mapper[method_attr]
|
||||||
method_hosts = [h for h in method_hosts if h != host['name']]
|
method_hosts = [h for h in method_hosts if h != host['name']]
|
||||||
|
@ -153,7 +153,6 @@ class ChangeSecretManager(BasePlaybookManager):
|
||||||
new_secret = self.generate_public_key(new_secret)
|
new_secret = self.generate_public_key(new_secret)
|
||||||
|
|
||||||
h['kwargs'] = self.get_kwargs(account, new_secret)
|
h['kwargs'] = self.get_kwargs(account, new_secret)
|
||||||
|
|
||||||
h['account'] = {
|
h['account'] = {
|
||||||
'name': account.name,
|
'name': account.name,
|
||||||
'username': account.username,
|
'username': account.username,
|
||||||
|
|
|
@ -40,15 +40,18 @@ class BaseAutomation(CommonModelMixin, PeriodTaskModelMixin, OrgModelMixin):
|
||||||
def get_register_task(self):
|
def get_register_task(self):
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
|
def get_many_to_many_ids(self, field: str):
|
||||||
|
return [str(i) for i in getattr(self, field).all().values_list('id', flat=True)]
|
||||||
|
|
||||||
def to_attr_json(self):
|
def to_attr_json(self):
|
||||||
return {
|
return {
|
||||||
'name': self.name,
|
'name': self.name,
|
||||||
'type': self.type,
|
'type': self.type,
|
||||||
'org_id': self.org_id,
|
'org_id': str(self.org_id),
|
||||||
'comment': self.comment,
|
'comment': self.comment,
|
||||||
'accounts': self.accounts,
|
'accounts': self.accounts,
|
||||||
'nodes': list(self.nodes.all().values_list('id', flat=True)),
|
'nodes': self.get_many_to_many_ids('nodes'),
|
||||||
'assets': list(self.assets.all().values_list('id', flat=True)),
|
'assets': self.get_many_to_many_ids('assets'),
|
||||||
}
|
}
|
||||||
|
|
||||||
def execute(self, trigger=Trigger.manual):
|
def execute(self, trigger=Trigger.manual):
|
||||||
|
@ -59,7 +62,7 @@ class BaseAutomation(CommonModelMixin, PeriodTaskModelMixin, OrgModelMixin):
|
||||||
|
|
||||||
execution = self.executions.model.objects.create(
|
execution = self.executions.model.objects.create(
|
||||||
id=eid, trigger=trigger, automation=self,
|
id=eid, trigger=trigger, automation=self,
|
||||||
plan_snapshot=self.to_attr_json(),
|
snapshot=self.to_attr_json(),
|
||||||
)
|
)
|
||||||
return execution.start()
|
return execution.start()
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,7 @@ class ChangeSecretAutomation(BaseAutomation):
|
||||||
)
|
)
|
||||||
secret_strategy = models.CharField(
|
secret_strategy = models.CharField(
|
||||||
choices=SecretStrategy.choices, max_length=16,
|
choices=SecretStrategy.choices, max_length=16,
|
||||||
default=SecretStrategy.random_one, verbose_name=_('Secret strategy')
|
default=SecretStrategy.custom, verbose_name=_('Secret strategy')
|
||||||
)
|
)
|
||||||
secret = fields.EncryptTextField(blank=True, null=True, verbose_name=_('Secret'))
|
secret = fields.EncryptTextField(blank=True, null=True, verbose_name=_('Secret'))
|
||||||
password_rules = models.JSONField(default=dict, verbose_name=_('Password rules'))
|
password_rules = models.JSONField(default=dict, verbose_name=_('Password rules'))
|
||||||
|
|
|
@ -61,6 +61,7 @@ class JMSInventory:
|
||||||
var = {
|
var = {
|
||||||
'ansible_user': account.username,
|
'ansible_user': account.username,
|
||||||
}
|
}
|
||||||
|
|
||||||
if not account.secret:
|
if not account.secret:
|
||||||
return var
|
return var
|
||||||
if account.secret_type == 'password':
|
if account.secret_type == 'password':
|
||||||
|
@ -77,7 +78,10 @@ class JMSInventory:
|
||||||
ssh_protocol_matched = list(filter(lambda x: x.name == 'ssh', protocols))
|
ssh_protocol_matched = list(filter(lambda x: x.name == 'ssh', protocols))
|
||||||
ssh_protocol = ssh_protocol_matched[0] if ssh_protocol_matched else None
|
ssh_protocol = ssh_protocol_matched[0] if ssh_protocol_matched else None
|
||||||
host['ansible_host'] = asset.address
|
host['ansible_host'] = asset.address
|
||||||
host['ansible_port'] = ssh_protocol.port if ssh_protocol else 22
|
if asset.port == 0:
|
||||||
|
host['ansible_port'] = ssh_protocol.port if ssh_protocol else 22
|
||||||
|
else:
|
||||||
|
host['ansible_port'] = asset.port
|
||||||
|
|
||||||
su_from = account.su_from
|
su_from = account.su_from
|
||||||
if platform.su_enabled and su_from:
|
if platform.su_enabled and su_from:
|
||||||
|
|
Loading…
Reference in New Issue