diff --git a/apps/assets/automations/base/manager.py b/apps/assets/automations/base/manager.py index d093d22eb..e2faecd64 100644 --- a/apps/assets/automations/base/manager.py +++ b/apps/assets/automations/base/manager.py @@ -49,7 +49,7 @@ class BasePlaybookManager: ansible_dir = settings.ANSIBLE_DIR dir_name = '{}_{}'.format(self.automation.name.replace(' ', '_'), self.execution.id) 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') ) if not os.path.exists(path): diff --git a/apps/assets/automations/change_secret/host/linux/main.yml b/apps/assets/automations/change_secret/host/linux/main.yml index cc0e1ae61..d295079ba 100644 --- a/apps/assets/automations/change_secret/host/linux/main.yml +++ b/apps/assets/automations/change_secret/host/linux/main.yml @@ -13,26 +13,26 @@ name: "{{ account.username }}" password: "{{ account.secret | password_hash('sha512') }}" update_password: always - when: "{{ secret_type == 'password' }}" + when: secret_type == "password" - name: create user If it already exists, no operation will be performed ansible.builtin.user: name: "{{ account.username }}" - when: "{{ secret_type == 'ssh_key' }}" + when: secret_type == "ssh_key" - name: remove jumpserver ssh key ansible.builtin.lineinfile: dest: "{{ kwargs.dest }}" regexp: "{{ kwargs.regexp }}" 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 ansible.builtin.authorized_key: user: "{{ account.username }}" key: "{{ account.secret }}" exclusive: "{{ kwargs.exclusive }}" - when: "{{ secret_type == 'ssh_key' }}" + when: secret_type == "ssh_key" - name: Refresh connection ansible.builtin.meta: reset_connection @@ -44,7 +44,7 @@ ansible_user: "{{ account.username }}" ansible_password: "{{ account.secret }}" ansible_become: no - when: "{{ secret_type == 'password' }}" + when: secret_type == "password" - name: Verify SSH key ansible.builtin.ping: @@ -53,4 +53,4 @@ ansible_user: "{{ account.username }}" ansible_ssh_private_key_file: "{{ account.private_key_path }}" ansible_become: no - when: "{{ secret_type == 'ssh_key' }}" + when: secret_type == "ssh_key" diff --git a/apps/assets/automations/change_secret/host/windows/main.yml b/apps/assets/automations/change_secret/host/windows/main.yml index 8a2e08363..0c27301dc 100644 --- a/apps/assets/automations/change_secret/host/windows/main.yml +++ b/apps/assets/automations/change_secret/host/windows/main.yml @@ -13,7 +13,7 @@ name: "{{ account.username }}" password: "{{ account.secret }}" update_password: always - when: "{{ account.secret_type == 'password' }}" + when: account.secret_type == "password" - name: Refresh connection ansible.builtin.meta: reset_connection @@ -23,4 +23,4 @@ vars: ansible_user: "{{ account.username }}" ansible_password: "{{ account.secret }}" - when: "{{ account.secret_type == 'password' }}" + when: account.secret_type == "password" diff --git a/apps/assets/automations/change_secret/manager.py b/apps/assets/automations/change_secret/manager.py index 80ca26d72..954a309b5 100644 --- a/apps/assets/automations/change_secret/manager.py +++ b/apps/assets/automations/change_secret/manager.py @@ -20,15 +20,15 @@ class ChangeSecretManager(BasePlaybookManager): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.method_hosts_mapper = defaultdict(list) - self.secret_type = self.execution.plan_snapshot.get('secret_type') - self.secret_strategy = self.execution.plan_snapshot['secret_strategy'] + self.secret_type = self.execution.snapshot['secret_type'] + self.secret_strategy = self.execution.snapshot['secret_strategy'] self._password_generated = None self._ssh_key_generated = None self.name_recorder_mapper = {} # 做个映射,方便后面处理 @classmethod def method_type(cls): - return AutomationTypes.method_id_meta_mapper + return AutomationTypes.change_secret @lazyproperty def related_accounts(self): @@ -53,7 +53,7 @@ class ChangeSecretManager(BasePlaybookManager): return key_path 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'])) symbol_set = kwargs.get('symbol_set') if symbol_set is None: @@ -69,7 +69,7 @@ class ChangeSecretManager(BasePlaybookManager): def get_ssh_key(self): 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: raise ValueError("Automation SSH key must be set") return ssh_key @@ -82,7 +82,7 @@ class ChangeSecretManager(BasePlaybookManager): def get_password(self): if self.secret_strategy == SecretStrategy.custom: - password = self.automation.plan_snapshot['password'] + password = self.execution.snapshot['secret'] if not password: raise ValueError("Automation Password must be set") return password @@ -106,7 +106,7 @@ class ChangeSecretManager(BasePlaybookManager): kwargs = {} if self.secret_type != SecretType.ssh_key: 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' if kwargs['strategy'] == SSHKeyStrategy.set_jms: @@ -123,11 +123,11 @@ class ChangeSecretManager(BasePlaybookManager): accounts = asset.accounts.all() if account: 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_hosts = self.method_hosts_mapper[method_attr] 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) h['kwargs'] = self.get_kwargs(account, new_secret) - h['account'] = { 'name': account.name, 'username': account.username, diff --git a/apps/assets/models/automations/base.py b/apps/assets/models/automations/base.py index b0fbd80a2..904b98717 100644 --- a/apps/assets/models/automations/base.py +++ b/apps/assets/models/automations/base.py @@ -40,15 +40,18 @@ class BaseAutomation(CommonModelMixin, PeriodTaskModelMixin, OrgModelMixin): def get_register_task(self): 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): return { 'name': self.name, 'type': self.type, - 'org_id': self.org_id, + 'org_id': str(self.org_id), 'comment': self.comment, 'accounts': self.accounts, - 'nodes': list(self.nodes.all().values_list('id', flat=True)), - 'assets': list(self.assets.all().values_list('id', flat=True)), + 'nodes': self.get_many_to_many_ids('nodes'), + 'assets': self.get_many_to_many_ids('assets'), } def execute(self, trigger=Trigger.manual): @@ -59,7 +62,7 @@ class BaseAutomation(CommonModelMixin, PeriodTaskModelMixin, OrgModelMixin): execution = self.executions.model.objects.create( id=eid, trigger=trigger, automation=self, - plan_snapshot=self.to_attr_json(), + snapshot=self.to_attr_json(), ) return execution.start() diff --git a/apps/assets/models/automations/change_secret.py b/apps/assets/models/automations/change_secret.py index 47462320d..5624caf1f 100644 --- a/apps/assets/models/automations/change_secret.py +++ b/apps/assets/models/automations/change_secret.py @@ -18,7 +18,7 @@ class ChangeSecretAutomation(BaseAutomation): ) secret_strategy = models.CharField( 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')) password_rules = models.JSONField(default=dict, verbose_name=_('Password rules')) diff --git a/apps/ops/ansible/inventory.py b/apps/ops/ansible/inventory.py index 8f555eb85..09427f3e5 100644 --- a/apps/ops/ansible/inventory.py +++ b/apps/ops/ansible/inventory.py @@ -61,6 +61,7 @@ class JMSInventory: var = { 'ansible_user': account.username, } + if not account.secret: return var if account.secret_type == 'password': @@ -77,7 +78,10 @@ class JMSInventory: 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 + 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 if platform.su_enabled and su_from: