Пример #1
0
class IDateTaskScheduling(IBaseTaskScheduling):
    """Base interface for date-style scheduled tasks"""

    start_date = Datetime(
        title=_("Execution date"),
        description=_("Date and time on which execution should start"),
        required=True)
Пример #2
0
class ITaskInfo(Interface):
    """Scheduler task interface"""

    containers('.IScheduler')

    name = TextLine(title=_("Task name"),
                    description=_("Descriptive name given to this task"),
                    required=True)

    schedule_mode = Choice(
        title=_("Scheduling mode"),
        description=_("Scheduling mode defines how task will be scheduled"),
        vocabulary=TASK_SCHEDULING_MODES_VOCABULARY,
        required=True)

    keep_empty_reports = Bool(
        title=_("Keep empty reports history?"),
        description=_("If 'Yes', empty reports will be kept in task "
                      "history"),
        required=True,
        default=False)

    history_duration = Int(
        title=_("History duration"),
        description=_("Number of days during which execution reports are "
                      "kept in history; enter 0 to remove limit"),
        required=False)

    history_length = Int(
        title=_("History max length"),
        description=_(
            "Number of execution reports to keep in history; enter 0 "
            "to remove limit"),
        required=False)
Пример #3
0
class ISchedulerRoles(IContentRoles):
    """Scheduler roles"""

    scheduler_managers = PrincipalsSetField(title=_("Scheduler managers"),
                                            role_id=SCHEDULER_MANAGER_ROLE,
                                            required=False)

    tasks_managers = PrincipalsSetField(title=_("Tasks manager"),
                                        role_id=TASKS_MANAGER_ROLE,
                                        required=False)
Пример #4
0
class IMailNotification(ITaskNotification):
    """Mail notification info interface"""

    target_email = TextLineListField(
        title=_("Target's email"),
        description=_("Email address of report's recipient; you can "
                      "enter email address in a simple form or in "
                      "in a complete \"Name <*****@*****.**>\" "
                      "form"),
        required=True)
Пример #5
0
class ITaskHistory(Interface):
    """Scheduler task history item interface"""

    containers(ITaskHistoryContainer)

    status = TextLine(title=_("Execution status"))

    date = Datetime(title=_("Execution start date"), required=True)

    duration = Float(title=_("Execution duration"), required=True)

    report = Text(title=_("Execution report"), required=True)
Пример #6
0
class IBaseTaskScheduling(Interface):
    """Base interface for task scheduling info"""

    active = Bool(title=_("Activate task?"),
                  description=_("You can disable a task by selecting 'No'"),
                  required=True,
                  default=False)

    start_date = Datetime(
        title=_("First execution date"),
        description=_("Date and time from which scheduling should start"),
        required=False)
Пример #7
0
class SchedulerTasksView(TableAdminView):
    """Scheduler tasks view"""

    title = _("Scheduler tasks")
    table_class = SchedulerTasksTable
    table_label = _("List of scheduler tasks")

    @property
    def back_url(self):
        """Form back URL getter"""
        return absolute_url(self.request.root, self.request,
                            'admin#utilities.html')  # pylint: disable=no-member

    back_url_target = None
Пример #8
0
def include_package(config):
    """Pyramid package include"""

    # add translations
    config.add_translation_dirs('pyams_scheduler:locales')

    # add scheduler permissions and roles
    config.register_permission({
        'id': MANAGE_SCHEDULER_PERMISSION,
        'title': _("Manage scheduler properties")
    })
    config.register_permission({
        'id': MANAGE_TASKS_PERMISSION,
        'title': _("Manage scheduler tasks")
    })

    # upgrade system manager roles
    config.upgrade_role(
        SYSTEM_ADMIN_ROLE,
        permissions={MANAGE_SCHEDULER_PERMISSION, MANAGE_TASKS_PERMISSION})

    # register new roles
    config.register_role({
        'id': SCHEDULER_MANAGER_ROLE,
        'title': _("Scheduler manager (role)"),
        'permissions': {
            MANAGE_ROLES_PERMISSION, MANAGE_SCHEDULER_PERMISSION,
            MANAGE_TASKS_PERMISSION
        },
        'managers': {ADMIN_USER_ID,
                     ROLE_ID.format(SYSTEM_ADMIN_ROLE)}
    })
    config.register_role({
        'id': TASKS_MANAGER_ROLE,
        'title': _("Tasks manager (role)"),
        'permissions': {MANAGE_TASKS_PERMISSION},
        'managers': {
            ADMIN_USER_ID,
            ROLE_ID.format(SYSTEM_ADMIN_ROLE),
            ROLE_ID.format(SCHEDULER_MANAGER_ROLE)
        }
    })

    try:
        import pyams_zmi  # pylint: disable=import-outside-toplevel,unused-import
    except ImportError:
        config.scan(
            ignore=[re.compile(r'pyams_scheduler\..*\.zmi\.?.*').search])
    else:
        config.scan()
Пример #9
0
def extract_rest_proxy_info(event):
    """Extract REST task proxy info"""
    data = event.data
    use_proxy = data.get('use_proxy')
    if use_proxy and not data.get('proxy_server'):
        event.form.widgets.errors += (Invalid(
            _("Proxy access defined without proxy server!")), )
Пример #10
0
class ISSHCallTaskInfo(Interface):
    """SSH caller task info"""

    connection = Object(title=_("SSH connection"),
                        schema=ISSHConnectionInfo,
                        required=True)

    cmdline = TextLine(title=_("Command line"),
                       description=_("Enter command line, using absolute path names"),
                       required=True)

    ok_status = TextLine(title=_("OK status"),
                         description=_("Comma-separated list of command exit codes which "
                                       "should be considered as success"),
                         required=True,
                         default='0')
Пример #11
0
class SchedulerHistoryStatusColumn(I18nColumnMixin, GetAttrColumn):
    """Scheduler history status column"""

    i18n_header = _("Status")
    attr_name = 'status'

    weight = 40
Пример #12
0
class JobHistoryView(AdminModalDisplayForm):
    """Job run history display form"""
    @property
    def title(self):
        """Title getter"""
        return get_parent(self.context, ITask).name

    legend = _("Task run history")
    modal_class = 'modal-max'

    label_css_class = 'col-sm-3 col-md-2'
    input_css_class = 'col-sm-9 col-md-10'

    fields = Fields(ITaskHistory).omit('__parent__', '__name__')

    def update_widgets(self, prefix=None):
        super().update_widgets(prefix)
        duration = self.widgets.get('duration')
        if duration is not None:
            duration.value = get_duration(
                timedelta(seconds=self.context.duration))
        report = self.widgets.get('report')
        if report is not None:
            report.rows = 15
            report.add_class('monospace')
Пример #13
0
class TaskRunEditForm(TaskBaseFormMixin, AdminModalEditForm):
    """Task run edit form"""

    legend = _("Task execution")
    modal_class = 'modal-xl'
    has_border = True

    fields = Fields(Interface)
    buttons = Buttons(ITaskRunButtons).select('debug', 'run', 'close')

    def update_actions(self):
        super().update_actions()
        debug = self.actions.get('debug')
        if debug is not None:
            debug.add_class('btn-info mr-auto')

    @handler(ITaskRunButtons['debug'])
    def handle_debug(self, action):
        """Debug button handler"""
        report = StringIO()
        self.context.run(report)
        self.finished_state.update({
            'action': action,
            'changes': report.getvalue()
        })

    @handler(ITaskRunButtons['run'])
    def handle_apply(self, action):
        """Task run button handler"""
        self.context.launch()
        self.finished_state.update({'action': action, 'changes': self.context})
Пример #14
0
class RESTTaskFormJWTHelp(AlertMessage):
    """REST task form JWT help"""

    css_class = 'mb-1 p-2'

    _message = _(
        "If this service require a JWT token, you can define the authentication "
        "authority which will be used to get new access tokens.")
Пример #15
0
class SchedulerHistoryDateColumn(I18nColumnMixin, DateColumn):
    """Scheduler history date column"""

    i18n_header = _("Run date")
    attr_name = 'date'
    formatter = SH_DATETIME_FORMAT

    weight = 20
Пример #16
0
def extract_rest_jwt_info(event):
    """Extract REST task JWT info"""
    data = event.data
    use_jwt_authority = data.get('use_jwt_authority')
    if use_jwt_authority and not data.get('jwt_authority_url'):
        event.form.widgets.errors += (Invalid(
            _("JWT authority location is required to enable "
              "JWT authentication!")), )
Пример #17
0
def extract_rest_task_info(event):
    """Extract REST task info"""
    data = event.data
    if 'base_url' in data:
        parsed_url = parse.urlparse(data['base_url'])
        if not (parsed_url.scheme and parsed_url.netloc):
            event.form.widgets.errors += (Invalid(
                _("Missing base target URI!")), )
Пример #18
0
def extract_rest_auth_info(event):
    """Extract REST task auth info"""
    data = event.data
    authenticate = data.get('authenticate')
    if authenticate and not data.get('username'):
        event.form.widgets.errors += (Invalid(
            _("Username and password are required to use "
              "authentication!")), )
Пример #19
0
class TaskHistoryHelpMessage(AlertMessage):
    """Task history help message"""

    css_class = 'mb-1 p-2'
    _message = _(
        "You can limit history conservation to a duration or to a number of iterations. "
        "If both are specified, the first encountered limit will take precedence."
    )
Пример #20
0
 def title(self):
     """Title getter"""
     translate = self.request.localizer.translate
     scheduler = query_utility(IScheduler)
     task = get_parent(self.context, ITask)
     return '<small>{}</small><br />{}'.format(
         get_object_label(scheduler, self.request, self),
         translate(_("Task: {}")).format(task.name))
Пример #21
0
class TaskCloneColumn(ActionColumn):
    """Task clone column"""

    hint = _("Clone task")
    icon_class = 'far fa-clone'

    href = 'clone-task.html'

    weight = 100
Пример #22
0
class TaskNotificationsColumn(ActionColumn):
    """Task notifications column"""

    hint = _("Task notifications")
    icon_class = 'far fa-envelope'

    href = 'notifications.html'

    weight = 35
Пример #23
0
class TaskNotificationAddForm(TaskBaseFormMixin, AdminModalAddForm):
    """Base task notification add form"""

    legend = _("New notification properties")

    def add(self, obj):
        intids = get_utility(IIntIds)
        container = ITaskNotificationContainer(self.context)
        container[hex(intids.register(obj))[2:]] = obj
Пример #24
0
 def get_trigger(self, task):
     """Get date trigger"""
     if not self.marker_interface.providedBy(task):
         raise Exception(
             _("Task is not configured for date-style scheduling!"))
     info = self.schema(task, None)
     if info is None:
         return None
     return DateTrigger(run_date=tztime(date_to_datetime(info.start_date)))
Пример #25
0
class ISSHConnectionInfo(Interface):
    """SSH connection info interface"""

    hostname = TextLine(title=_("Hostname or IP address"),
                        description=_("Enter hostname or IP address of a remote host; "
                                      "keep empty for local server host"),
                        required=False)

    auto_add_host_key = Bool(title=_("Automatically add host key?"),
                             description=_("If 'yes', connection will be opened event if "
                                           "server key is unknown"),
                             required=False,
                             default=False)

    port = Int(title=_("Port number"),
               default=22,
               required=False)

    username = TextLine(title=_("User name"),
                        required=False)

    private_key = TextLine(title=_("Private key filename"),
                           description=_("Enter name of private key file; use '~' to identify "
                                         "running server user home directory, as in "
                                         "~/.ssh/id_rsa"),
                           required=False)

    password = Password(title=_("Password"),
                        description=_("If not using private key, you must provide user's "
                                      "password"),
                        required=False)

    @invariant
    def check_remote_host(self):
        """Check for password or private key if remote host is defined"""
        if self.hostname and (bool(self.private_key) == bool(self.password)):
            raise Invalid(_("You must provide a private key filename OR a password when "
                            "defining remote tasks"))

    def get_connection(self):
        """Get SSH connection"""

    def get_sftp_client(self):
        """Get SFTP client"""
Пример #26
0
class SchedulerHistoryNameColumn(NameColumn):
    """Scheduler history name column"""

    i18n_header = _("Task name")

    weight = 10

    def get_value(self, obj):
        task = get_parent(obj, ITask)
        return task.name
Пример #27
0
class TaskRunFormHelp(AlertMessage):
    """Task run form help"""

    _message = _(
        "You can run the task in normal mode or in debug mode.\n"
        "In debug mode, the task is started in current application thread, and you will "
        "get the output directly in this form.\n"
        "In normal mode, the task is scheduled as usual, but for immediate execution.\n"
        "Please note that in both modes, the scheduling mode is not taken into account, "
        "including when the task is disabled!")
Пример #28
0
class SchedulerTaskScheduleColumn(ActionColumn):
    """Scheduler task schedule column"""

    href = 'schedule.html'
    icon_class = 'fas fa-clock'
    hint = _("Schedule task")

    permission = MANAGE_TASKS_PERMISSION

    weight = 50
Пример #29
0
class SchedulerTaskRunColumn(ActionColumn):
    """Scheduler task run column"""

    href = 'run.html'
    icon_class = 'far fa-play-circle'
    hint = _("Run task")

    permission = MANAGE_TASKS_PERMISSION

    weight = 40
Пример #30
0
class SchedulerTaskHistoryColumn(ActionColumn):
    """Scheduler task history column"""

    href = 'jobs-history.html'
    icon_class = 'fas fa-history'
    hint = _("Task run history")

    permission = MANAGE_TASKS_PERMISSION

    weight = 70