mirror of https://github.com/jumpserver/jumpserver
Merge branch 'v3' of github.com:jumpserver/jumpserver into v3
commit
706488d293
|
@ -14,6 +14,7 @@ from common.utils import get_logger
|
||||||
from common.db.encoder import ModelJSONFieldEncoder
|
from common.db.encoder import ModelJSONFieldEncoder
|
||||||
from common.db.models import BitOperationChoice
|
from common.db.models import BitOperationChoice
|
||||||
from common.mixins.models import CommonModelMixin
|
from common.mixins.models import CommonModelMixin
|
||||||
|
from common.const.choices import Trigger
|
||||||
from ..const import AllTypes, Category
|
from ..const import AllTypes, Category
|
||||||
|
|
||||||
__all__ = ['AccountBackupPlan', 'AccountBackupPlanExecution', 'Type']
|
__all__ = ['AccountBackupPlan', 'AccountBackupPlanExecution', 'Type']
|
||||||
|
@ -89,7 +90,7 @@ class AccountBackupPlan(CommonModelMixin, PeriodTaskModelMixin, OrgModelMixin):
|
||||||
from ..tasks import execute_account_backup_plan
|
from ..tasks import execute_account_backup_plan
|
||||||
name = "account_backup_plan_period_{}".format(str(self.id)[:8])
|
name = "account_backup_plan_period_{}".format(str(self.id)[:8])
|
||||||
task = execute_account_backup_plan.name
|
task = execute_account_backup_plan.name
|
||||||
args = (str(self.id), AccountBackupPlanExecution.Trigger.timing)
|
args = (str(self.id), Trigger.timing)
|
||||||
kwargs = {}
|
kwargs = {}
|
||||||
return name, task, args, kwargs
|
return name, task, args, kwargs
|
||||||
|
|
||||||
|
@ -120,10 +121,6 @@ class AccountBackupPlan(CommonModelMixin, PeriodTaskModelMixin, OrgModelMixin):
|
||||||
|
|
||||||
|
|
||||||
class AccountBackupPlanExecution(OrgModelMixin):
|
class AccountBackupPlanExecution(OrgModelMixin):
|
||||||
class Trigger(models.TextChoices):
|
|
||||||
manual = 'manual', _('Manual trigger')
|
|
||||||
timing = 'timing', _('Timing trigger')
|
|
||||||
|
|
||||||
id = models.UUIDField(default=uuid.uuid4, primary_key=True)
|
id = models.UUIDField(default=uuid.uuid4, primary_key=True)
|
||||||
date_start = models.DateTimeField(
|
date_start = models.DateTimeField(
|
||||||
auto_now_add=True, verbose_name=_('Date start')
|
auto_now_add=True, verbose_name=_('Date start')
|
||||||
|
|
|
@ -1,4 +1,11 @@
|
||||||
|
from django.db import models
|
||||||
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
|
||||||
ADMIN = 'Admin'
|
ADMIN = 'Admin'
|
||||||
USER = 'User'
|
USER = 'User'
|
||||||
AUDITOR = 'Auditor'
|
AUDITOR = 'Auditor'
|
||||||
|
|
||||||
|
|
||||||
|
class Trigger(models.TextChoices):
|
||||||
|
manual = 'manual', _('Manual trigger')
|
||||||
|
timing = 'timing', _('Timing trigger')
|
||||||
|
|
|
@ -0,0 +1,29 @@
|
||||||
|
from django.db import models
|
||||||
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
|
||||||
|
|
||||||
|
class StrategyChoice(models.TextChoices):
|
||||||
|
push = 'push', _('Push')
|
||||||
|
verify = 'verify', _('Verify')
|
||||||
|
collect = 'collect', _('Collect')
|
||||||
|
change_auth = 'change_auth', _('Change auth')
|
||||||
|
|
||||||
|
|
||||||
|
class SSHKeyStrategy(models.TextChoices):
|
||||||
|
add = 'add', _('Append SSH KEY')
|
||||||
|
set = 'set', _('Empty and append SSH KEY')
|
||||||
|
set_jms = 'set_jms', _('Replace (The key generated by JumpServer) ')
|
||||||
|
|
||||||
|
|
||||||
|
class PasswordStrategy(models.TextChoices):
|
||||||
|
custom = 'custom', _('Custom password')
|
||||||
|
random_one = 'random_one', _('All assets use the same random password')
|
||||||
|
random_all = 'random_all', _('All assets use different random password')
|
||||||
|
|
||||||
|
|
||||||
|
string_punctuation = '!#$%&()*+,-.:;<=>?@[]^_~'
|
||||||
|
DEFAULT_PASSWORD_LENGTH = 30
|
||||||
|
DEFAULT_PASSWORD_RULES = {
|
||||||
|
'length': DEFAULT_PASSWORD_LENGTH,
|
||||||
|
'symbol_set': string_punctuation
|
||||||
|
}
|
|
@ -4,3 +4,4 @@
|
||||||
from .adhoc import *
|
from .adhoc import *
|
||||||
from .celery import *
|
from .celery import *
|
||||||
from .command import *
|
from .command import *
|
||||||
|
from .automation import *
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
from .change_auth import *
|
||||||
|
from .collect import *
|
||||||
|
from .push import *
|
||||||
|
from .verify import *
|
||||||
|
from .common import *
|
|
@ -0,0 +1,2 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
#
|
|
@ -0,0 +1,71 @@
|
||||||
|
from django.db import models
|
||||||
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
|
||||||
|
from ops.const import SSHKeyStrategy, PasswordStrategy, StrategyChoice
|
||||||
|
from ops.utils import generate_random_password
|
||||||
|
from common.db.fields import (
|
||||||
|
EncryptCharField, EncryptTextField, JsonDictCharField
|
||||||
|
)
|
||||||
|
from .common import AutomationStrategy
|
||||||
|
|
||||||
|
|
||||||
|
class ChangeAuthStrategy(AutomationStrategy):
|
||||||
|
is_password = models.BooleanField(default=True)
|
||||||
|
password_strategy = models.CharField(
|
||||||
|
max_length=128, blank=True, null=True, choices=PasswordStrategy.choices,
|
||||||
|
verbose_name=_('Password strategy')
|
||||||
|
)
|
||||||
|
password_rules = JsonDictCharField(
|
||||||
|
max_length=2048, blank=True, null=True, verbose_name=_('Password rules')
|
||||||
|
)
|
||||||
|
password = EncryptCharField(
|
||||||
|
max_length=256, blank=True, null=True, verbose_name=_('Password')
|
||||||
|
)
|
||||||
|
|
||||||
|
is_ssh_key = models.BooleanField(default=False)
|
||||||
|
ssh_key_strategy = models.CharField(
|
||||||
|
max_length=128, blank=True, null=True, choices=SSHKeyStrategy.choices,
|
||||||
|
verbose_name=_('SSH Key strategy')
|
||||||
|
)
|
||||||
|
private_key = EncryptTextField(
|
||||||
|
max_length=4096, blank=True, null=True, verbose_name=_('SSH private key')
|
||||||
|
)
|
||||||
|
public_key = EncryptTextField(
|
||||||
|
max_length=4096, blank=True, null=True, verbose_name=_('SSH public key')
|
||||||
|
)
|
||||||
|
recipients = models.ManyToManyField(
|
||||||
|
'users.User', related_name='recipients_change_auth_strategy', blank=True,
|
||||||
|
verbose_name=_("Recipient")
|
||||||
|
)
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
verbose_name = _("Change auth strategy")
|
||||||
|
|
||||||
|
def gen_execute_password(self):
|
||||||
|
if self.password_strategy == PasswordStrategy.custom:
|
||||||
|
return self.password
|
||||||
|
elif self.password_strategy == PasswordStrategy.random_one:
|
||||||
|
return generate_random_password(**self.password_rules)
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
|
||||||
|
def to_attr_json(self):
|
||||||
|
attr_json = super().to_attr_json()
|
||||||
|
attr_json.update({
|
||||||
|
'type': StrategyChoice.change_auth,
|
||||||
|
|
||||||
|
'password': self.gen_execute_password(),
|
||||||
|
'is_password': self.is_password,
|
||||||
|
'password_rules': self.password_rules,
|
||||||
|
'password_strategy': self.password_strategy,
|
||||||
|
|
||||||
|
'is_ssh_key': self.is_ssh_key,
|
||||||
|
'public_key': self.public_key,
|
||||||
|
'private_key': self.private_key,
|
||||||
|
'ssh_key_strategy': self.ssh_key_strategy,
|
||||||
|
'recipients': {
|
||||||
|
str(recipient.id): (str(recipient), bool(recipient.secret_key))
|
||||||
|
for recipient in self.recipients.all()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return attr_json
|
|
@ -0,0 +1,16 @@
|
||||||
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
|
||||||
|
from ops.const import StrategyChoice
|
||||||
|
from .common import AutomationStrategy
|
||||||
|
|
||||||
|
|
||||||
|
class CollectStrategy(AutomationStrategy):
|
||||||
|
class Meta:
|
||||||
|
verbose_name = _("Collect strategy")
|
||||||
|
|
||||||
|
def to_attr_json(self):
|
||||||
|
attr_json = super().to_attr_json()
|
||||||
|
attr_json.update({
|
||||||
|
'type': StrategyChoice.collect
|
||||||
|
})
|
||||||
|
return attr_json
|
|
@ -0,0 +1,111 @@
|
||||||
|
import uuid
|
||||||
|
from celery import current_task
|
||||||
|
from django.db import models
|
||||||
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
|
||||||
|
from common.const.choices import Trigger
|
||||||
|
from common.mixins.models import CommonModelMixin
|
||||||
|
from common.db.fields import EncryptJsonDictTextField
|
||||||
|
from orgs.mixins.models import OrgModelMixin
|
||||||
|
from ops.mixin import PeriodTaskModelMixin
|
||||||
|
from ops.tasks import execute_automation_strategy
|
||||||
|
from ops.task_handlers import ExecutionManager
|
||||||
|
|
||||||
|
|
||||||
|
class AutomationStrategy(CommonModelMixin, PeriodTaskModelMixin, OrgModelMixin):
|
||||||
|
id = models.UUIDField(default=uuid.uuid4, primary_key=True)
|
||||||
|
accounts = models.JSONField(default=list, verbose_name=_("Accounts"))
|
||||||
|
nodes = models.ManyToManyField(
|
||||||
|
'assets.Node', related_name='automation_strategy', blank=True, verbose_name=_("Nodes")
|
||||||
|
)
|
||||||
|
assets = models.ManyToManyField(
|
||||||
|
'assets.Asset', related_name='automation_strategy', blank=True, verbose_name=_("Assets")
|
||||||
|
)
|
||||||
|
comment = models.TextField(blank=True, verbose_name=_('Comment'))
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return self.name + '@' + str(self.created_by)
|
||||||
|
|
||||||
|
def get_register_task(self):
|
||||||
|
name = "automation_strategy_period_{}".format(str(self.id)[:8])
|
||||||
|
task = execute_automation_strategy.name
|
||||||
|
args = (str(self.id), Trigger.timing)
|
||||||
|
kwargs = {}
|
||||||
|
return name, task, args, kwargs
|
||||||
|
|
||||||
|
def to_attr_json(self):
|
||||||
|
return {
|
||||||
|
'name': self.name,
|
||||||
|
'accounts': self.accounts,
|
||||||
|
'assets': list(self.assets.all().values_list('id', flat=True)),
|
||||||
|
'nodes': list(self.assets.all().values_list('id', flat=True)),
|
||||||
|
}
|
||||||
|
|
||||||
|
def execute(self, trigger):
|
||||||
|
try:
|
||||||
|
eid = current_task.request.id
|
||||||
|
except AttributeError:
|
||||||
|
eid = str(uuid.uuid4())
|
||||||
|
execution = AutomationStrategyExecution.objects.create(
|
||||||
|
id=eid, strategy=self, snapshot=self.to_attr_json(), trigger=trigger
|
||||||
|
)
|
||||||
|
return execution.start()
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
unique_together = [('org_id', 'name')]
|
||||||
|
verbose_name = _("Automation plan")
|
||||||
|
|
||||||
|
|
||||||
|
class AutomationStrategyExecution(OrgModelMixin):
|
||||||
|
id = models.UUIDField(default=uuid.uuid4, primary_key=True)
|
||||||
|
|
||||||
|
date_created = models.DateTimeField(auto_now_add=True)
|
||||||
|
timedelta = models.FloatField(default=0.0, verbose_name=_('Time'), null=True)
|
||||||
|
date_start = models.DateTimeField(auto_now_add=True, verbose_name=_('Date start'))
|
||||||
|
|
||||||
|
snapshot = EncryptJsonDictTextField(
|
||||||
|
default=dict, blank=True, null=True, verbose_name=_('Automation snapshot')
|
||||||
|
)
|
||||||
|
strategy = models.ForeignKey(
|
||||||
|
'AutomationStrategy', related_name='execution', on_delete=models.CASCADE,
|
||||||
|
verbose_name=_('Automation strategy')
|
||||||
|
)
|
||||||
|
trigger = models.CharField(
|
||||||
|
max_length=128, default=Trigger.manual, choices=Trigger.choices, verbose_name=_('Trigger mode')
|
||||||
|
)
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
verbose_name = _('Automation strategy execution')
|
||||||
|
|
||||||
|
@property
|
||||||
|
def manager_type(self):
|
||||||
|
return self.snapshot['type']
|
||||||
|
|
||||||
|
def start(self):
|
||||||
|
manager = ExecutionManager(execution=self)
|
||||||
|
return manager.run()
|
||||||
|
|
||||||
|
|
||||||
|
class AutomationStrategyTask(OrgModelMixin):
|
||||||
|
id = models.UUIDField(default=uuid.uuid4, primary_key=True)
|
||||||
|
asset = models.ForeignKey(
|
||||||
|
'assets.Asset', on_delete=models.CASCADE, verbose_name=_('Asset')
|
||||||
|
)
|
||||||
|
account = models.ForeignKey(
|
||||||
|
'assets.Account', on_delete=models.CASCADE, verbose_name=_('Account')
|
||||||
|
)
|
||||||
|
is_success = models.BooleanField(default=False, verbose_name=_('Is success'))
|
||||||
|
timedelta = models.FloatField(default=0.0, null=True, verbose_name=_('Time'))
|
||||||
|
date_start = models.DateTimeField(auto_now_add=True, verbose_name=_('Date start'))
|
||||||
|
reason = models.CharField(max_length=1024, blank=True, null=True, verbose_name=_('Reason'))
|
||||||
|
execution = models.ForeignKey(
|
||||||
|
'AutomationStrategyExecution', related_name='task', on_delete=models.CASCADE,
|
||||||
|
verbose_name=_('Automation strategy execution')
|
||||||
|
)
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
verbose_name = _('Automation strategy task')
|
||||||
|
|
||||||
|
@property
|
||||||
|
def handler_type(self):
|
||||||
|
return self.execution.snapshot['type']
|
|
@ -0,0 +1,16 @@
|
||||||
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
|
||||||
|
from ops.const import StrategyChoice
|
||||||
|
from .common import AutomationStrategy
|
||||||
|
|
||||||
|
|
||||||
|
class PushStrategy(AutomationStrategy):
|
||||||
|
class Meta:
|
||||||
|
verbose_name = _("Push strategy")
|
||||||
|
|
||||||
|
def to_attr_json(self):
|
||||||
|
attr_json = super().to_attr_json()
|
||||||
|
attr_json.update({
|
||||||
|
'type': StrategyChoice.push
|
||||||
|
})
|
||||||
|
return attr_json
|
|
@ -0,0 +1,16 @@
|
||||||
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
|
||||||
|
from ops.const import StrategyChoice
|
||||||
|
from .common import AutomationStrategy
|
||||||
|
|
||||||
|
|
||||||
|
class VerifyStrategy(AutomationStrategy):
|
||||||
|
class Meta:
|
||||||
|
verbose_name = _("Verify strategy")
|
||||||
|
|
||||||
|
def to_attr_json(self):
|
||||||
|
attr_json = super().to_attr_json()
|
||||||
|
attr_json.update({
|
||||||
|
'type': StrategyChoice.verify
|
||||||
|
})
|
||||||
|
return attr_json
|
|
@ -0,0 +1 @@
|
||||||
|
from .endpoint import *
|
|
@ -0,0 +1,2 @@
|
||||||
|
from .manager import *
|
||||||
|
from .handlers import *
|
|
@ -0,0 +1,16 @@
|
||||||
|
"""
|
||||||
|
执行改密计划的基类
|
||||||
|
"""
|
||||||
|
from common.utils import get_logger
|
||||||
|
|
||||||
|
logger = get_logger(__file__)
|
||||||
|
|
||||||
|
|
||||||
|
class BaseHandler:
|
||||||
|
def __init__(self, task, show_step_info=True):
|
||||||
|
self.task = task
|
||||||
|
self.conn = None
|
||||||
|
self.retry_times = 3
|
||||||
|
self.current_step = 0
|
||||||
|
self.is_frozen = False # 任务状态冻结标志
|
||||||
|
self.show_step_info = show_step_info
|
|
@ -0,0 +1,78 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
#
|
||||||
|
import time
|
||||||
|
from openpyxl import Workbook
|
||||||
|
from django.utils import timezone
|
||||||
|
|
||||||
|
from common.utils import get_logger
|
||||||
|
from common.utils.timezone import local_now_display
|
||||||
|
|
||||||
|
logger = get_logger(__file__)
|
||||||
|
|
||||||
|
|
||||||
|
class BaseExecutionManager:
|
||||||
|
task_back_up_serializer: None
|
||||||
|
|
||||||
|
def __init__(self, execution):
|
||||||
|
self.execution = execution
|
||||||
|
self.date_start = timezone.now()
|
||||||
|
self.time_start = time.time()
|
||||||
|
self.date_end = None
|
||||||
|
self.time_end = None
|
||||||
|
self.timedelta = 0
|
||||||
|
self.total_tasks = []
|
||||||
|
|
||||||
|
def on_tasks_pre_run(self, tasks):
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
|
def on_per_task_pre_run(self, task, total, index):
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
|
def create_csv_file(self, tasks, file_name):
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
|
def get_handler_cls(self):
|
||||||
|
raise NotImplemented
|
||||||
|
|
||||||
|
def do_run(self):
|
||||||
|
tasks = self.total_tasks = self.execution.create_plan_tasks()
|
||||||
|
self.on_tasks_pre_run(tasks)
|
||||||
|
total = len(tasks)
|
||||||
|
|
||||||
|
for index, task in enumerate(tasks, start=1):
|
||||||
|
self.on_per_task_pre_run(task, total, index)
|
||||||
|
task.start(show_step_info=False)
|
||||||
|
|
||||||
|
def pre_run(self):
|
||||||
|
self.execution.date_start = self.date_start
|
||||||
|
self.execution.save()
|
||||||
|
self.show_execution_steps()
|
||||||
|
|
||||||
|
def show_execution_steps(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def show_summary(self):
|
||||||
|
split_line = '#' * 40
|
||||||
|
summary = self.execution.result_summary
|
||||||
|
logger.info(f'\n{split_line} 改密计划执行结果汇总 {split_line}')
|
||||||
|
logger.info(
|
||||||
|
'\n成功: {succeed}, 失败: {failed}, 总数: {total}\n'
|
||||||
|
''.format(**summary)
|
||||||
|
)
|
||||||
|
|
||||||
|
def post_run(self):
|
||||||
|
self.time_end = time.time()
|
||||||
|
self.date_end = timezone.now()
|
||||||
|
|
||||||
|
logger.info('\n\n' + '-' * 80)
|
||||||
|
logger.info('任务执行结束 {}\n'.format(local_now_display()))
|
||||||
|
self.timedelta = int(self.time_end - self.time_start)
|
||||||
|
logger.info('用时: {}s'.format(self.timedelta))
|
||||||
|
self.execution.timedelta = self.timedelta
|
||||||
|
self.execution.save()
|
||||||
|
self.show_summary()
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
self.pre_run()
|
||||||
|
self.do_run()
|
||||||
|
self.post_run()
|
|
@ -0,0 +1,2 @@
|
||||||
|
from .manager import *
|
||||||
|
from .handlers import *
|
|
@ -0,0 +1,10 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
#
|
||||||
|
from common.utils import get_logger
|
||||||
|
from ..base import BaseHandler
|
||||||
|
|
||||||
|
logger = get_logger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
class ChangeAuthHandler(BaseHandler):
|
||||||
|
pass
|
|
@ -0,0 +1,12 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
#
|
||||||
|
from common.utils import get_logger
|
||||||
|
from ..base import BaseExecutionManager
|
||||||
|
from .handlers import ChangeAuthHandler
|
||||||
|
|
||||||
|
logger = get_logger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
class ChangeAuthExecutionManager(BaseExecutionManager):
|
||||||
|
def get_handler_cls(self):
|
||||||
|
return ChangeAuthHandler
|
|
@ -0,0 +1,2 @@
|
||||||
|
from .manager import *
|
||||||
|
from .handlers import *
|
|
@ -0,0 +1,10 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
#
|
||||||
|
from common.utils import get_logger
|
||||||
|
from ..base import BaseHandler
|
||||||
|
|
||||||
|
logger = get_logger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
class CollectHandler(BaseHandler):
|
||||||
|
pass
|
|
@ -0,0 +1,10 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
#
|
||||||
|
from common.utils import get_logger
|
||||||
|
from ..base import BaseExecutionManager
|
||||||
|
|
||||||
|
logger = get_logger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
class CollectExecutionManager(object):
|
||||||
|
pass
|
|
@ -0,0 +1,31 @@
|
||||||
|
from ops.const import StrategyChoice
|
||||||
|
from .push import PushExecutionManager, PushHandler
|
||||||
|
from .verify import VerifyExecutionManager, VerifyHandler
|
||||||
|
from .collect import CollectExecutionManager, CollectHandler
|
||||||
|
from .change_auth import ChangeAuthExecutionManager, ChangeAuthHandler
|
||||||
|
|
||||||
|
|
||||||
|
class ExecutionManager:
|
||||||
|
manager_type = {
|
||||||
|
StrategyChoice.push: PushExecutionManager,
|
||||||
|
StrategyChoice.verify: VerifyExecutionManager,
|
||||||
|
StrategyChoice.collect: CollectExecutionManager,
|
||||||
|
StrategyChoice.change_auth: ChangeAuthExecutionManager,
|
||||||
|
}
|
||||||
|
|
||||||
|
def __new__(cls, execution):
|
||||||
|
manager = cls.manager_type[execution.manager_type]
|
||||||
|
return manager(execution)
|
||||||
|
|
||||||
|
|
||||||
|
class TaskHandler:
|
||||||
|
handler_type = {
|
||||||
|
StrategyChoice.push: PushHandler,
|
||||||
|
StrategyChoice.verify: VerifyHandler,
|
||||||
|
StrategyChoice.collect: CollectHandler,
|
||||||
|
StrategyChoice.change_auth: ChangeAuthHandler,
|
||||||
|
}
|
||||||
|
|
||||||
|
def __new__(cls, task, show_step_info):
|
||||||
|
handler = cls.handler_type[task.handler_type]
|
||||||
|
return handler(task, show_step_info)
|
|
@ -0,0 +1,2 @@
|
||||||
|
from .manager import *
|
||||||
|
from .handlers import *
|
|
@ -0,0 +1,10 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
#
|
||||||
|
from common.utils import get_logger
|
||||||
|
from ..base import BaseHandler
|
||||||
|
|
||||||
|
logger = get_logger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
class PushHandler(BaseHandler):
|
||||||
|
pass
|
|
@ -0,0 +1,10 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
#
|
||||||
|
from common.utils import get_logger
|
||||||
|
from ..base import BaseExecutionManager
|
||||||
|
|
||||||
|
logger = get_logger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
class PushExecutionManager(BaseExecutionManager):
|
||||||
|
pass
|
|
@ -0,0 +1,2 @@
|
||||||
|
from .manager import *
|
||||||
|
from .handlers import *
|
|
@ -0,0 +1,10 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
#
|
||||||
|
from common.utils import get_logger
|
||||||
|
from ..base import BaseHandler
|
||||||
|
|
||||||
|
logger = get_logger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
class VerifyHandler(BaseHandler):
|
||||||
|
pass
|
|
@ -0,0 +1,10 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
#
|
||||||
|
from common.utils import get_logger
|
||||||
|
from ..base import BaseExecutionManager
|
||||||
|
|
||||||
|
logger = get_logger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
class VerifyExecutionManager(BaseExecutionManager):
|
||||||
|
pass
|
|
@ -179,3 +179,15 @@ def add_m(x):
|
||||||
res = chain(*tuple(s))()
|
res = chain(*tuple(s))()
|
||||||
return res
|
return res
|
||||||
|
|
||||||
|
|
||||||
|
@shared_task
|
||||||
|
def execute_automation_strategy(pid, trigger):
|
||||||
|
from .models import AutomationStrategy
|
||||||
|
with tmp_to_root_org():
|
||||||
|
instance = get_object_or_none(AutomationStrategy, pk=pid)
|
||||||
|
if not instance:
|
||||||
|
logger.error("No automation plan found: {}".format(pid))
|
||||||
|
return
|
||||||
|
with tmp_to_org(instance.org):
|
||||||
|
instance.execute(trigger)
|
||||||
|
|
||||||
|
|
|
@ -5,11 +5,11 @@ import uuid
|
||||||
from django.utils.translation import ugettext_lazy as _
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
|
||||||
from common.utils import get_logger, get_object_or_none
|
from common.utils import get_logger, get_object_or_none
|
||||||
from common.tasks import send_mail_async
|
|
||||||
from orgs.utils import org_aware_func
|
from orgs.utils import org_aware_func
|
||||||
from jumpserver.const import PROJECT_DIR
|
from jumpserver.const import PROJECT_DIR
|
||||||
|
|
||||||
from .models import Task, AdHoc
|
from .models import Task, AdHoc
|
||||||
|
from .const import DEFAULT_PASSWORD_RULES
|
||||||
|
|
||||||
logger = get_logger(__file__)
|
logger = get_logger(__file__)
|
||||||
|
|
||||||
|
@ -29,7 +29,7 @@ def update_or_create_ansible_task(
|
||||||
interval=None, crontab=None, is_periodic=False,
|
interval=None, crontab=None, is_periodic=False,
|
||||||
callback=None, pattern='all', options=None,
|
callback=None, pattern='all', options=None,
|
||||||
run_as_admin=False, run_as=None, system_user=None, become_info=None,
|
run_as_admin=False, run_as=None, system_user=None, become_info=None,
|
||||||
):
|
):
|
||||||
if not hosts or not tasks or not task_name:
|
if not hosts or not tasks or not task_name:
|
||||||
return None, None
|
return None, None
|
||||||
if options is None:
|
if options is None:
|
||||||
|
@ -80,3 +80,15 @@ def get_task_log_path(base_path, task_id, level=2):
|
||||||
path = os.path.join(base_path, rel_path)
|
path = os.path.join(base_path, rel_path)
|
||||||
os.makedirs(os.path.dirname(path), exist_ok=True)
|
os.makedirs(os.path.dirname(path), exist_ok=True)
|
||||||
return path
|
return path
|
||||||
|
|
||||||
|
|
||||||
|
def generate_random_password(**kwargs):
|
||||||
|
import random
|
||||||
|
import string
|
||||||
|
length = int(kwargs.get('length', DEFAULT_PASSWORD_RULES['length']))
|
||||||
|
symbol_set = kwargs.get('symbol_set')
|
||||||
|
if symbol_set is None:
|
||||||
|
symbol_set = DEFAULT_PASSWORD_RULES['symbol_set']
|
||||||
|
chars = string.ascii_letters + string.digits + symbol_set
|
||||||
|
password = ''.join([random.choice(chars) for _ in range(length)])
|
||||||
|
return password
|
||||||
|
|
Loading…
Reference in New Issue