Exemplo n.º 1
0
def set_periodic_task(name=None,
                      interval=None,
                      nodes=None,
                      taskmodule=None,
                      ordering=0,
                      options=None,
                      active=True,
                      id=None,
                      retry_if_failed=True):
    """
    Set a periodic task configuration. If ``id`` is None, this creates a new database entry.
    Otherwise, an existing entry is overwritten. We actually ensure that such
    an entry exists and throw a ``ParameterError`` otherwise.

    This also checks if ``interval`` is a valid cron expression, and throws
    a ``ParameterError`` if it is not.

    :param name: Unique name of the periodic task
    :type name: unicode
    :param interval: Periodicity as a string in crontab format
    :type interval: unicode
    :param nodes: List of nodes on which this task should be run
    :type nodes: list of unicode
    :param taskmodule: Name of the task module
    :type taskmodule: unicode
    :param ordering: Ordering of the periodic task (>= 0). Lower numbers are executed first.
    :type ordering: int
    :param options: Additional options for the task module
    :type options: Dictionary mapping unicodes to values that can be converted to unicode or None
    :param active: Flag determining whether the periodic task is active
    :type active: bool
    :param retry_if_failed: true if privacyidea should retry to execute this periodic task if it fails
                            false if privacyidea should just try onetime regardless the failing of the task
    :type retry_if_failed: bool
    :param id: ID of the existing entry, or None
    :type id: int or None
    :return: ID of the entry
    """
    try:
        croniter(interval)
    except ValueError as e:
        raise ParameterError("Invalid interval: {!s}".format(e))
    if ordering < 0:
        raise ParameterError("Invalid ordering: {!s}".format(ordering))
    if id is not None:
        # This will throw a ParameterError if there is no such entry
        get_periodic_task_by_id(id)
    periodic_task = PeriodicTask(name, active, interval, nodes, taskmodule,
                                 ordering, options, id, retry_if_failed)
    return periodic_task.id
Exemplo n.º 2
0
    def test_26_periodictask(self):
        current_utc_time = datetime(2018, 3, 4, 5, 6, 8)
        with mock.patch('privacyidea.models.datetime') as mock_dt:
            mock_dt.utcnow.return_value = current_utc_time

            task1 = PeriodicTask("task1", False, "0 5 * * *", ["localhost"], "some.module", 2, {
                "key1": "value2",
                "KEY2": True,
                "key3": u"öfføff",
            })
            task2 = PeriodicTask("some other task", True, "0 6 * * *", ["localhost"], "some.other.module", 1, {
                "foo": "bar"
            })

        self.assertEqual(PeriodicTask.query.filter_by(name="task1").one(), task1)
        self.assertEqual(PeriodicTask.query.filter_by(name="some other task").one(), task2)
        self.assertEqual(PeriodicTaskOption.query.filter_by(periodictask_id=task1.id, key="KEY2").one().value,
                         "True")
        # Values are converted to strings
        self.assertEqual(task1.get(), {
            "id": task1.id,
            "name": "task1",
            "active": False,
            "interval": "0 5 * * *",
            # we get a timezone-aware datetime here
            "last_update": current_utc_time.replace(tzinfo=tzutc()),
            "nodes": ["localhost"],
            "taskmodule": "some.module",
            "ordering": 2,
            "options": {
                "key1": "value2",
                "KEY2": "True",
                "key3": u"öfføff",
            },
            "last_runs": {}})

        # register a run
        task1.set_last_run("localhost", datetime(2018, 3, 4, 5, 6, 7))

        # assert we can update the task
        later_utc_time = current_utc_time + timedelta(seconds=1)
        with mock.patch('privacyidea.models.datetime') as mock_dt:
            mock_dt.utcnow.return_value = later_utc_time
            PeriodicTask("task one", True, "0 8 * * *", ["localhost", "otherhost"], "some.module", 3, {
                "KEY2": "value number 2",
                "key 4": 1234
            }, id=task1.id)
        # the first run for otherhost
        task1.set_last_run("otherhost", datetime(2018, 8, 9, 10, 11, 12))
        result = PeriodicTask.query.filter_by(name="task one").one().get()
        self.assertEqual(result,
                         {
                             "id": task1.id,
                             "active": True,
                             "name": "task one",
                             "interval": "0 8 * * *",
                             "last_update": later_utc_time.replace(tzinfo=tzutc()),
                             "nodes": ["localhost", "otherhost"],
                             "taskmodule": "some.module",
                             "ordering": 3,
                             "options": {"KEY2": "value number 2",
                                         "key 4": "1234"},
                             "last_runs": {
                                 "localhost": datetime(2018, 3, 4, 5, 6, 7, tzinfo=tzutc()),
                                 "otherhost": datetime(2018, 8, 9, 10, 11, 12, tzinfo=tzutc()),
                             }
                         })
        # assert all old options are removed
        self.assertEqual(PeriodicTaskOption.query.filter_by(periodictask_id=task1.id, key="key3").count(), 0)
        # the second run for localhost
        task1.set_last_run("localhost", datetime(2018, 3, 4, 5, 6, 8))
        result = PeriodicTask.query.filter_by(name="task one").one().get()
        self.assertEqual(result,
                         {
                             "id": task1.id,
                             "active": True,
                             "name": "task one",
                             "interval": "0 8 * * *",
                             "last_update": later_utc_time.replace(tzinfo=tzutc()),
                             "nodes": ["localhost", "otherhost"],
                             "taskmodule": "some.module",
                             "ordering": 3,
                             "options": {"KEY2": "value number 2",
                                         "key 4": "1234"},
                             "last_runs": {
                                 "localhost": datetime(2018, 3, 4, 5, 6, 8, tzinfo=tzutc()),
                                 "otherhost": datetime(2018, 8, 9, 10, 11, 12, tzinfo=tzutc()),
                             }
                         })

        # remove "localhost", assert the last run is removed
        PeriodicTask("task one", True, "0 8 * * *", ["otherhost"], "some.module", 4, {"foo": "bar"}, id=task1.id)
        self.assertEqual(PeriodicTaskOption.query.filter_by(periodictask_id=task1.id).count(), 1)
        self.assertEqual(PeriodicTaskLastRun.query.filter_by(periodictask_id=task1.id).one().node, "otherhost")
        # naive timestamp in the database
        self.assertEqual(PeriodicTaskLastRun.query.filter_by(periodictask_id=task1.id).one().timestamp,
                         datetime(2018, 8, 9, 10, 11, 12, tzinfo=None))
        self.assertEqual(PeriodicTaskLastRun.query.filter_by(periodictask_id=task1.id).one().aware_timestamp,
                         datetime(2018, 8, 9, 10, 11, 12, tzinfo=tzutc()))

        # remove the tasks, everything is removed
        task1.delete()
        self.assertEqual(PeriodicTaskOption.query.count(), 1) # from task2
        self.assertEqual(PeriodicTaskLastRun.query.count(), 0)
        task2.delete()
        self.assertEqual(PeriodicTaskOption.query.count(), 0)
Exemplo n.º 3
0
    def test_26_periodictask(self):
        current_utc_time = datetime(2018, 3, 4, 5, 6, 8)
        with mock.patch('privacyidea.models.datetime') as mock_dt:
            mock_dt.utcnow.return_value = current_utc_time

            task1 = PeriodicTask("task1", False, "0 5 * * *", ["localhost"],
                                 "some.module", 2, {
                                     "key1": "value2",
                                     "KEY2": True,
                                     "key3": u"öfføff",
                                 })
            task2 = PeriodicTask("some other task", True, "0 6 * * *",
                                 ["localhost"], "some.other.module", 1,
                                 {"foo": "bar"})

        self.assertEqual(
            PeriodicTask.query.filter_by(name="task1").one(), task1)
        self.assertEqual(
            PeriodicTask.query.filter_by(name="some other task").one(), task2)
        self.assertEqual(
            PeriodicTaskOption.query.filter_by(periodictask_id=task1.id,
                                               key="KEY2").one().value, "True")
        # Values are converted to strings
        self.assertEqual(
            task1.get(),
            {
                "id": task1.id,
                "name": "task1",
                "active": False,
                "interval": "0 5 * * *",
                # we get a timezone-aware datetime here
                "last_update": current_utc_time.replace(tzinfo=tzutc()),
                "nodes": ["localhost"],
                "taskmodule": "some.module",
                "ordering": 2,
                "options": {
                    "key1": "value2",
                    "KEY2": "True",
                    "key3": u"öfføff",
                },
                "last_runs": {}
            })

        # register a run
        task1.set_last_run("localhost", datetime(2018, 3, 4, 5, 6, 7))

        # assert we can update the task
        later_utc_time = current_utc_time + timedelta(seconds=1)
        with mock.patch('privacyidea.models.datetime') as mock_dt:
            mock_dt.utcnow.return_value = later_utc_time
            PeriodicTask("task one",
                         True,
                         "0 8 * * *", ["localhost", "otherhost"],
                         "some.module",
                         3, {
                             "KEY2": "value number 2",
                             "key 4": 1234
                         },
                         id=task1.id)
        # the first run for otherhost
        task1.set_last_run("otherhost", datetime(2018, 8, 9, 10, 11, 12))
        result = PeriodicTask.query.filter_by(name="task one").one().get()
        self.assertEqual(
            result, {
                "id": task1.id,
                "active": True,
                "name": "task one",
                "interval": "0 8 * * *",
                "last_update": later_utc_time.replace(tzinfo=tzutc()),
                "nodes": ["localhost", "otherhost"],
                "taskmodule": "some.module",
                "ordering": 3,
                "options": {
                    "KEY2": "value number 2",
                    "key 4": "1234"
                },
                "last_runs": {
                    "localhost": datetime(2018, 3, 4, 5, 6, 7, tzinfo=tzutc()),
                    "otherhost": datetime(
                        2018, 8, 9, 10, 11, 12, tzinfo=tzutc()),
                }
            })
        # assert all old options are removed
        self.assertEqual(
            PeriodicTaskOption.query.filter_by(periodictask_id=task1.id,
                                               key="key3").count(), 0)
        # the second run for localhost
        task1.set_last_run("localhost", datetime(2018, 3, 4, 5, 6, 8))
        result = PeriodicTask.query.filter_by(name="task one").one().get()
        self.assertEqual(
            result, {
                "id": task1.id,
                "active": True,
                "name": "task one",
                "interval": "0 8 * * *",
                "last_update": later_utc_time.replace(tzinfo=tzutc()),
                "nodes": ["localhost", "otherhost"],
                "taskmodule": "some.module",
                "ordering": 3,
                "options": {
                    "KEY2": "value number 2",
                    "key 4": "1234"
                },
                "last_runs": {
                    "localhost": datetime(2018, 3, 4, 5, 6, 8, tzinfo=tzutc()),
                    "otherhost": datetime(
                        2018, 8, 9, 10, 11, 12, tzinfo=tzutc()),
                }
            })

        # remove "localhost", assert the last run is removed
        PeriodicTask("task one",
                     True,
                     "0 8 * * *", ["otherhost"],
                     "some.module",
                     4, {"foo": "bar"},
                     id=task1.id)
        self.assertEqual(
            PeriodicTaskOption.query.filter_by(
                periodictask_id=task1.id).count(), 1)
        self.assertEqual(
            PeriodicTaskLastRun.query.filter_by(
                periodictask_id=task1.id).one().node, "otherhost")
        # naive timestamp in the database
        self.assertEqual(
            PeriodicTaskLastRun.query.filter_by(
                periodictask_id=task1.id).one().timestamp,
            datetime(2018, 8, 9, 10, 11, 12, tzinfo=None))
        self.assertEqual(
            PeriodicTaskLastRun.query.filter_by(
                periodictask_id=task1.id).one().aware_timestamp,
            datetime(2018, 8, 9, 10, 11, 12, tzinfo=tzutc()))

        # remove the tasks, everything is removed
        task1.delete()
        self.assertEqual(PeriodicTaskOption.query.count(), 1)  # from task2
        self.assertEqual(PeriodicTaskLastRun.query.count(), 0)
        task2.delete()
        self.assertEqual(PeriodicTaskOption.query.count(), 0)
Exemplo n.º 4
0
    def test_26_periodictask(self):
        task1 = PeriodicTask("task1", False, "0 5 * * *", ["localhost"],
                             "some.module", {
                                 "key1": "value2",
                                 "KEY2": True,
                                 "key3": u"öfføff",
                             })
        task2 = PeriodicTask("some other task", True, "0 6 * * *",
                             ["localhost"], "some.other.module",
                             {"foo": "bar"})
        self.assertEqual(
            PeriodicTask.query.filter_by(name="task1").one(), task1)
        self.assertEqual(
            PeriodicTask.query.filter_by(name="some other task").one(), task2)
        self.assertEqual(
            PeriodicTaskOption.query.filter_by(periodictask_id=task1.id,
                                               key="KEY2").one().value, "True")
        # Values are converted to strings
        self.assertEqual(
            task1.get(), {
                "id": task1.id,
                "name": "task1",
                "active": False,
                "interval": "0 5 * * *",
                "nodes": ["localhost"],
                "taskmodule": "some.module",
                "options": {
                    "key1": "value2",
                    "KEY2": "True",
                    "key3": u"öfføff",
                },
                "last_runs": {}
            })

        # register a run
        task1.set_last_run("localhost", datetime(2018, 3, 4, 5, 6, 7))

        # assert we can update the task
        PeriodicTask("task one",
                     True,
                     "0 8 * * *", ["localhost", "otherhost"],
                     "some.module", {
                         "KEY2": "value number 2",
                         "key 4": 1234
                     },
                     id=task1.id)
        # the first run for otherhost
        task1.set_last_run("otherhost", datetime(2018, 8, 9, 10, 11, 12))
        result = PeriodicTask.query.filter_by(name="task one").one().get()
        self.assertEqual(
            result, {
                "id": task1.id,
                "active": True,
                "name": "task one",
                "interval": "0 8 * * *",
                "nodes": ["localhost", "otherhost"],
                "taskmodule": "some.module",
                "options": {
                    "KEY2": "value number 2",
                    "key 4": "1234"
                },
                "last_runs": {
                    "localhost": datetime(2018, 3, 4, 5, 6, 7),
                    "otherhost": datetime(2018, 8, 9, 10, 11, 12),
                }
            })
        # assert all old options are removed
        self.assertEqual(
            PeriodicTaskOption.query.filter_by(periodictask_id=task1.id,
                                               key="key3").count(), 0)
        # the second run for localhost
        task1.set_last_run("localhost", datetime(2018, 3, 4, 5, 6, 8))
        result = PeriodicTask.query.filter_by(name="task one").one().get()
        self.assertEqual(
            result, {
                "id": task1.id,
                "active": True,
                "name": "task one",
                "interval": "0 8 * * *",
                "nodes": ["localhost", "otherhost"],
                "taskmodule": "some.module",
                "options": {
                    "KEY2": "value number 2",
                    "key 4": "1234"
                },
                "last_runs": {
                    "localhost": datetime(2018, 3, 4, 5, 6, 8),
                    "otherhost": datetime(2018, 8, 9, 10, 11, 12),
                }
            })

        # remove "localhost", assert the last run is removed
        PeriodicTask("task one",
                     True,
                     "0 8 * * *", ["otherhost"],
                     "some.module", {"foo": "bar"},
                     id=task1.id)
        self.assertEqual(
            PeriodicTaskOption.query.filter_by(
                periodictask_id=task1.id).count(), 1)
        self.assertEqual(
            PeriodicTaskLastRun.query.filter_by(
                periodictask_id=task1.id).one().node, "otherhost")

        # remove the tasks, everything is removed
        task1.delete()
        self.assertEqual(PeriodicTaskOption.query.count(), 1)  # from task2
        self.assertEqual(PeriodicTaskLastRun.query.count(), 0)
        task2.delete()
        self.assertEqual(PeriodicTaskOption.query.count(), 0)