diff --git a/apps/assets/automations/base/manager.py b/apps/assets/automations/base/manager.py index 83097d0eb..e55a564bf 100644 --- a/apps/assets/automations/base/manager.py +++ b/apps/assets/automations/base/manager.py @@ -20,7 +20,7 @@ class BasePlaybookManager: def playbook_dir_path(self): ansible_dir = settings.ANSIBLE_DIR path = os.path.join( - ansible_dir, self.automation.type, self.automation.name, + ansible_dir, self.automation.type, self.automation.name.replace(' ', '_'), timezone.now().strftime('%Y%m%d_%H%M%S') ) return path @@ -41,12 +41,13 @@ class BasePlaybookManager: def prepare_playbook_dir(self): inventory_dir = os.path.dirname(self.inventory_path) playbook_dir = os.path.dirname(self.playbook_path) - for d in [inventory_dir, playbook_dir]: + for d in [inventory_dir, playbook_dir, self.playbook_dir_path]: + print("Create dir: {}".format(d)) if not os.path.exists(d): os.makedirs(d, exist_ok=True, mode=0o755) def inventory_kwargs(self): - raise NotImplemented + raise NotImplementedError def generate_inventory(self): inventory = JMSInventory( @@ -58,10 +59,10 @@ class BasePlaybookManager: print("Generate inventory done: {}".format(self.inventory_path)) def generate_playbook(self): - raise NotImplemented + raise NotImplementedError def get_runner(self): - raise NotImplemented + raise NotImplementedError def run(self, **kwargs): self.generate() diff --git a/apps/assets/automations/change_password/host/change_password_linux/main.yml b/apps/assets/automations/change_password/host/change_password_linux/main.yml index 1ad590cff..8bdaa5cdc 100644 --- a/apps/assets/automations/change_password/host/change_password_linux/main.yml +++ b/apps/assets/automations/change_password/host/change_password_linux/main.yml @@ -1,4 +1,5 @@ - hosts: demo + gather_facts: no tasks: - name: Test privileged account ping: diff --git a/apps/assets/automations/change_password/host/change_password_local_windows/main.yml b/apps/assets/automations/change_password/host/change_password_local_windows/main.yml index 483554a1e..d10c3681e 100644 --- a/apps/assets/automations/change_password/host/change_password_local_windows/main.yml +++ b/apps/assets/automations/change_password/host/change_password_local_windows/main.yml @@ -1,4 +1,5 @@ - hosts: demo + gather_facts: no tasks: - name: ping ping: diff --git a/apps/assets/automations/change_password/manager.py b/apps/assets/automations/change_password/manager.py index ea0bb9a26..aa86c6d08 100644 --- a/apps/assets/automations/change_password/manager.py +++ b/apps/assets/automations/change_password/manager.py @@ -34,7 +34,7 @@ class ChangePasswordManager(BasePlaybookManager): automation.change_password_method in self.id_method_mapper if not change_password_enabled: - host.exclude = _('Change password disabled') + host['exclude'] = _('Change password disabled') return [host] hosts = [] @@ -60,14 +60,18 @@ class ChangePasswordManager(BasePlaybookManager): playbook = [] for method_id, host_names in self.method_hosts_mapper.items(): method = self.id_method_mapper[method_id] - playbook_dir_path = method['dir'] - playbook_dir_name = os.path.dirname(playbook_dir_path) - shutil.copytree(playbook_dir_path, self.playbook_dir_path) - sub_playbook_path = os.path.join(self.playbook_dir_path, playbook_dir_name, 'main.yml') + method_playbook_dir_path = method['dir'] + method_playbook_dir_name = os.path.basename(method_playbook_dir_path) + sub_playbook_dir = os.path.join(os.path.dirname(self.playbook_path), method_playbook_dir_name) + shutil.copytree(method_playbook_dir_path, sub_playbook_dir) + sub_playbook_path = os.path.join(sub_playbook_dir, 'main.yml') with open(sub_playbook_path, 'r') as f: host_playbook_play = yaml.safe_load(f) + if isinstance(host_playbook_play, list): + host_playbook_play = host_playbook_play[0] + plays = [] for name in host_names: play = deepcopy(host_playbook_play) @@ -75,17 +79,24 @@ class ChangePasswordManager(BasePlaybookManager): plays.append(play) with open(sub_playbook_path, 'w') as f: - yaml.safe_dump(plays, f, default_flow_style=False) + yaml.safe_dump(plays, f) playbook.append({ 'name': method['name'], - 'import_playbook': playbook_dir_name + '/' + 'main.yml' + 'import_playbook': os.path.join(method_playbook_dir_name, 'main.yml') }) with open(self.playbook_path, 'w') as f: - yaml.safe_dump(playbook, f, default_flow_style=False) + yaml.safe_dump(playbook, f) print("Generate playbook done: " + self.playbook_path) + def get_runner(self): + return PlaybookRunner( + self.inventory_path, + self.playbook_path, + self.playbook_dir_path + ) + diff --git a/apps/assets/automations/endpoint.py b/apps/assets/automations/endpoint.py index f99defdd8..8064ae58f 100644 --- a/apps/assets/automations/endpoint.py +++ b/apps/assets/automations/endpoint.py @@ -1,7 +1,18 @@ # from .backup.manager import AccountBackupExecutionManager # # +from .change_password.manager import ChangePasswordManager + + class ExecutionManager: - manager_type = { + manager_type_mapper = { + 'change_password': ChangePasswordManager, } + def __init__(self, execution): + self.execution = execution + self._runner = self.manager_type_mapper[execution.automation.type](execution) + + def run(self, **kwargs): + return self._runner.run(**kwargs) + diff --git a/apps/assets/models/automations/base.py b/apps/assets/models/automations/base.py index ba0d393ea..e440429f4 100644 --- a/apps/assets/models/automations/base.py +++ b/apps/assets/models/automations/base.py @@ -58,9 +58,8 @@ class BaseAutomation(JMSOrgBaseModel, PeriodTaskModelMixin): except AttributeError: eid = str(uuid.uuid4()) - execution = AutomationExecution.objects.create( - id=eid, strategy=self, trigger=trigger, - snapshot=self.to_attr_json(), + execution = self.executions.create( + id=eid, trigger=trigger, ) return execution.start() diff --git a/apps/assets/models/label.py b/apps/assets/models/label.py index 937d0d95c..afad1f069 100644 --- a/apps/assets/models/label.py +++ b/apps/assets/models/label.py @@ -1,13 +1,13 @@ # -*- coding: utf-8 -*- # -import uuid from django.db import models from django.utils.translation import ugettext_lazy as _ -from orgs.mixins.models import OrgModelMixin + +from orgs.mixins.models import JMSOrgBaseModel -class Label(OrgModelMixin): +class Label(JMSOrgBaseModel): SYSTEM_CATEGORY = "S" USER_CATEGORY = "U" CATEGORY_CHOICES = ( diff --git a/apps/common/drf/parsers/base.py b/apps/common/drf/parsers/base.py index 1f15ea72d..ac75ff645 100644 --- a/apps/common/drf/parsers/base.py +++ b/apps/common/drf/parsers/base.py @@ -39,7 +39,7 @@ class BaseFileParser(BaseParser): @abc.abstractmethod def generate_rows(self, stream_data): - raise NotImplemented + raise NotImplementedError def get_column_titles(self, rows): return next(rows) diff --git a/apps/ops/ansible/inventory.py b/apps/ops/ansible/inventory.py index 5528f1a14..42cd7320c 100644 --- a/apps/ops/ansible/inventory.py +++ b/apps/ops/ansible/inventory.py @@ -63,7 +63,7 @@ class JMSInventory: host = { 'name': asset.name, 'asset': { - 'id': asset.id, 'name': asset.name, 'ip': asset.ip, + 'id': str(asset.id), 'name': asset.name, 'address': asset.address, 'type': asset.type, 'category': asset.category, 'protocol': asset.protocol, 'port': asset.port, 'protocols': [{'name': p.name, 'port': p.port} for p in protocols], @@ -125,7 +125,7 @@ class JMSInventory: if not account_selected: if self.account_policy in ['privileged_must', 'privileged_first']: - account_matched = list(filter(lambda account: account.is_privileged, accounts)) + account_matched = list(filter(lambda account: account.privileged, accounts)) account_selected = account_matched[0] if account_matched else None if not account_selected and self.account_policy == 'privileged_first': @@ -152,8 +152,8 @@ class JMSInventory: exclude_hosts = list(filter(lambda x: x.get('exclude'), hosts)) if exclude_hosts: print(_("Skip hosts below:")) - for host in exclude_hosts: - print(" {}:\t{}".format(host['name'], host['exclude'])) + for i, host in enumerate(exclude_hosts, start=1): + print("{}: [{}] \t{}".format(i, host['name'], host['exclude'])) hosts = list(filter(lambda x: not x.get('exclude'), hosts)) data = {'all': {'hosts': {}}} diff --git a/apps/ops/models/base.py b/apps/ops/models/base.py index e91af13a6..4ff69277f 100644 --- a/apps/ops/models/base.py +++ b/apps/ops/models/base.py @@ -29,10 +29,10 @@ class BaseAnsibleTask(PeriodTaskModelMixin, JMSOrgBaseModel): return inv def get_register_task(self): - raise NotImplemented + raise NotImplementedError def to_json(self): - raise NotImplemented + raise NotImplementedError def create_execution(self): execution = self.executions.create() @@ -71,7 +71,7 @@ class BaseAnsibleExecution(models.Model): return os.path.join(self.private_dir, 'inventory', 'hosts') def get_runner(self): - raise NotImplemented + raise NotImplementedError def finish_task(self): self.date_finished = timezone.now() diff --git a/apps/orgs/signal_handlers/common.py b/apps/orgs/signal_handlers/common.py index 7b825b748..a4e1c7085 100644 --- a/apps/orgs/signal_handlers/common.py +++ b/apps/orgs/signal_handlers/common.py @@ -5,11 +5,11 @@ from collections import defaultdict from functools import partial from django.dispatch import receiver +from django.conf import settings from django.utils.functional import LazyObject -from django.db.models.signals import m2m_changed -from django.db.models.signals import post_save, pre_delete +from django.db.models.signals import post_save, pre_delete, m2m_changed -from orgs.utils import tmp_to_org +from orgs.utils import tmp_to_org, set_to_default_org from orgs.models import Organization from orgs.hands import set_current_org, Node, get_current_org from perms.models import AssetPermission @@ -44,6 +44,8 @@ def expire_orgs_mapping_for_memory(org_id): @receiver(django_ready) def subscribe_orgs_mapping_expire(sender, **kwargs): logger.debug("Start subscribe for expire orgs mapping from memory") + if settings.DEBUG: + set_to_default_org() def keep_subscribe_org_mapping(): orgs_mapping_for_memory_pub_sub.subscribe(