Beispiel #1
0
    def test_action_description(self):
        std_http = db_api.get_action_definition("std.http")
        std_echo = db_api.get_action_definition("std.echo")

        self.assertIn("HTTP action", std_http.description)
        self.assertIn("param body: (optional) Dictionary, bytes",
                      std_http.description)

        self.assertIn("This action just returns a configured value",
                      std_echo.description)
    def test_action_description(self):
        std_http = db_api.get_action_definition("std.http")
        std_echo = db_api.get_action_definition("std.echo")

        self.assertIn("Constructs an HTTP action", std_http.description)
        self.assertIn("param body: (optional) Dictionary, bytes",
                      std_http.description)

        self.assertIn("This action just returns a configured value",
                      std_echo.description)
Beispiel #3
0
    def __init__(self, action_def, action_ex=None, task_ex=None, task_ctx=None,
                 wf_ctx=None):
        self.action_spec = spec_parser.get_action_spec(action_def.spec)

        try:
            base_action_def = db_api.get_action_definition(
                self.action_spec.get_base()
            )
        except exc.DBEntityNotFoundError:
            raise exc.InvalidActionException(
                "Failed to find action [action_name=%s]" %
                self.action_spec.get_base()
            )

        base_action_def = self._gather_base_actions(
            action_def, base_action_def
        )

        super(AdHocAction, self).__init__(
            base_action_def,
            action_ex,
            task_ex
        )

        self.adhoc_action_def = action_def
        self.task_ctx = task_ctx or {}
        self.wf_ctx = wf_ctx or {}
Beispiel #4
0
    def _gather_base_actions(self, action_def, base_action_def):
        """Find all base ad-hoc actions and store them

        An ad-hoc action may be based on another ad-hoc action (and this
        recursively). Using twice the same base action is not allowed to
        avoid infinite loops. It stores the list of ad-hoc actions.
        :param action_def: Action definition
        :type action_def: ActionDefinition
        :param base_action_def: Original base action definition
        :type base_action_def: ActionDefinition
        :return; The definition of the base system action
        :rtype; ActionDefinition
        """
        self.adhoc_action_defs = [action_def]
        original_base_name = self.action_spec.get_name()
        action_names = set([original_base_name])

        base = base_action_def
        while not base.is_system and base.name not in action_names:
            action_names.add(base.name)
            self.adhoc_action_defs.append(base)

            base_name = base.spec['base']
            base = db_api.get_action_definition(base_name)

        # if the action is repeated
        if base.name in action_names:
            raise ValueError(
                'An ad-hoc action cannot use twice the same action, %s is '
                'used at least twice' % base.name
            )

        return base
Beispiel #5
0
    def test_get_all_pagination(self):
        # Create an adhoc action for the purpose of the test.
        adhoc_actions.create_actions(ADHOC_ACTION_YAML)

        resp = self.app.get('/v2/actions?limit=1&sort_keys=id,name')

        self.assertEqual(200, resp.status_int)
        self.assertIn('next', resp.json)
        self.assertEqual(1, len(resp.json['actions']))

        self.check_adhoc_action_json(resp.json['actions'][0])

        param_dict = utils.get_dict_from_string(
            resp.json['next'].split('?')[1],
            delimiter='&'
        )

        action_def = db_api.get_action_definition('my_action')

        # TODO(rakhmerov): In this case we can't use IDs for marker because
        # in general we don't identify action descriptors with IDs.
        expected_dict = {
            'marker': action_def.id,
            'limit': 1,
            'sort_keys': 'id,name',
            'sort_dirs': 'asc,asc'
        }

        self.assertTrue(
            set(expected_dict.items()).issubset(set(param_dict.items()))
        )
Beispiel #6
0
    def _gather_base_actions(self, action_def, base_action_def):
        """Find all base ad-hoc actions and store them

        An ad-hoc action may be based on another ad-hoc action (and this
        recursively). Using twice the same base action is not allowed to
        avoid infinite loops. It stores the list of ad-hoc actions.
        :param action_def: Action definition
        :type action_def: ActionDefinition
        :param base_action_def: Original base action definition
        :type base_action_def: ActionDefinition
        :return; The definition of the base system action
        :rtype; ActionDefinition
        """
        self.adhoc_action_defs = [action_def]
        original_base_name = self.action_spec.get_name()
        action_names = set([original_base_name])

        base = base_action_def
        while not base.is_system and base.name not in action_names:
            action_names.add(base.name)
            self.adhoc_action_defs.append(base)

            base_name = base.spec['base']
            base = db_api.get_action_definition(base_name)

        # if the action is repeated
        if base.name in action_names:
            raise ValueError(
                'An ad-hoc action cannot use twice the same action, %s is '
                'used at least twice' % base.name)

        return base
Beispiel #7
0
    def test_get_all_operational_error(self, mocked_get_all):
        # Create an adhoc action for the purpose of the test.
        adhoc_actions.create_actions(ADHOC_ACTION_YAML)

        action_def = db_api.get_action_definition('my_action')

        mocked_get_all.side_effect = [
            # Emulating DB OperationalError
            sa.exc.OperationalError('Mock', 'mock', 'mock'),
            [action_def]  # Successful run
        ]

        resp = self.app.get('/v2/actions')

        actions_json = resp.json['actions']

        # There will be 'std.' actions and the one we've just created.
        self.assertGreater(len(actions_json), 1)

        # Let's check some of the well-known 'std.' actions.
        self._assert_single_item(actions_json, name='std.echo')
        self._assert_single_item(actions_json, name='std.ssh')
        self._assert_single_item(actions_json, name='std.fail')
        self._assert_single_item(actions_json, name='std.noop')
        self._assert_single_item(actions_json, name='std.async_noop')

        # Now let's check the ad-hoc action data.
        adhoc_action_json = self._assert_single_item(
            actions_json,
            name='my_action'
        )

        self.check_adhoc_action_json(adhoc_action_json)
Beispiel #8
0
    def get(self, name):
        """Return the named action."""
        LOG.info("Fetch action [name=%s]" % name)

        db_model = db_api.get_action_definition(name)

        return Action.from_dict(db_model.to_dict())
Beispiel #9
0
    def get(self, name):
        """Return the named action."""
        LOG.info("Fetch action [name=%s]" % name)

        db_model = db_api.get_action_definition(name)

        return Action.from_dict(db_model.to_dict())
Beispiel #10
0
    def get(self, name):
        """Return the named action."""
        acl.enforce('actions:get', context.ctx())
        LOG.info("Fetch action [name=%s]" % name)

        db_model = db_api.get_action_definition(name)

        return Action.from_dict(db_model.to_dict())
    def test_action_input(self):
        std_http = db_api.get_action_definition("std.http")
        std_email = db_api.get_action_definition("std.email")

        http_action_input = ('url, method="GET", params=null, body=null, '
                             'headers=null, cookies=null, auth=null, '
                             'timeout=null, allow_redirects=null, '
                             'proxies=null, verify=null')

        self.assertEqual(http_action_input, std_http.input)

        std_email_input = (
            "from_addr, to_addrs, smtp_server, reply_to=null, cc_addrs=null, "
            "bcc_addrs=null, smtp_password=null, subject=null, body=null, "
            "html_body=null")

        self.assertEqual(std_email_input, std_email.input)
Beispiel #12
0
    def get(self, name):
        """Return the named action."""
        acl.enforce('actions:get', context.ctx())
        LOG.info("Fetch action [name=%s]" % name)

        db_model = db_api.get_action_definition(name)

        return Action.from_dict(db_model.to_dict())
Beispiel #13
0
    def __init__(self, action_def, action_ex=None, task_ex=None):
        self.action_spec = spec_parser.get_action_spec(action_def.spec)

        base_action_def = db_api.get_action_definition(
            self.action_spec.get_base())

        super(AdHocAction, self).__init__(base_action_def, action_ex, task_ex)

        self.adhoc_action_def = action_def
Beispiel #14
0
        def _delete_action_definition():
            with db_api.transaction():
                db_model = db_api.get_action_definition(identifier)

                if db_model.is_system:
                    msg = "Attempt to delete a system action: %s" % identifier
                    raise exc.DataAccessException(msg)

                db_api.delete_action_definition(identifier)
Beispiel #15
0
        def _delete_action_definition():
            with db_api.transaction():
                db_model = db_api.get_action_definition(identifier)

                if db_model.is_system:
                    msg = "Attempt to delete a system action: %s" % identifier
                    raise exc.DataAccessException(msg)

                db_api.delete_action_definition(identifier)
Beispiel #16
0
def _run_existing_action(action_ex_id, target):
    action_ex = db_api.get_action_execution(action_ex_id)
    action_def = db_api.get_action_definition(action_ex.name)

    result = rpc.get_executor_client().run_action(action_ex_id,
                                                  action_def.action_class,
                                                  action_def.attributes or {},
                                                  action_ex.input, target)

    return _get_action_output(result) if result else None
Beispiel #17
0
def run_existing_action(action_ex_id, target):
    action_ex = db_api.get_action_execution(action_ex_id)
    action_def = db_api.get_action_definition(action_ex.name)

    return run_action(
        action_def,
        action_ex.input,
        action_ex_id,
        target
    )
    def test_action_input(self):
        std_http = db_api.get_action_definition("std.http")
        std_email = db_api.get_action_definition("std.email")

        http_action_input = (
            'url, method="GET", params=null, body=null, '
            'headers=null, cookies=null, auth=null, '
            'timeout=null, allow_redirects=null, '
            'proxies=null, verify=null'
        )

        self.assertEqual(http_action_input, std_http.input)

        std_email_input = (
            "from_addr, to_addrs, smtp_server, "
            "smtp_password, subject=null, body=null"
        )

        self.assertEqual(std_email_input, std_email.input)
Beispiel #19
0
def run_existing_action(action_ex_id, target):
    action_ex = db_api.get_action_execution(action_ex_id)
    action_def = db_api.get_action_definition(action_ex.name)

    return run_action(
        action_def,
        action_ex.input,
        action_ex_id,
        target
    )
Beispiel #20
0
    def test_action_input(self):
        std_http = db_api.get_action_definition("std.http")
        std_email = db_api.get_action_definition("std.email")

        http_action_input = (
            "url, method=GET, params=None, body=None, "
            "headers=None, cookies=None, auth=None, "
            "timeout=None, allow_redirects=None, "
            "proxies=None, verify=None"
        )

        self.assertEqual(http_action_input, std_http.input)

        std_email_input = (
            "from_addr, to_addrs, smtp_server, "
            "smtp_password, subject=None, body=None"
        )

        self.assertEqual(std_email_input, std_email.input)
Beispiel #21
0
def run_action(action_ex_id, target):
    action_ex = db_api.get_action_execution(action_ex_id)
    action_def = db_api.get_action_definition(action_ex.name)

    rpc.get_executor_client().run_action(
        action_ex.id,
        action_def.action_class,
        action_def.attributes or {},
        action_ex.input,
        target
    )
Beispiel #22
0
        def _delete_action_definition():
            with db_api.transaction():
                db_model = db_api.get_action_definition(identifier,
                                                        namespace=namespace)

                if db_model.is_system:
                    raise exc.DataAccessException(
                        "Attempt to delete a system action: %s" % identifier)

                db_api.delete_action_definition(identifier,
                                                namespace=namespace)
Beispiel #23
0
    def delete(self, name):
        """Delete the named action."""
        LOG.info("Delete action [name=%s]" % name)

        with db_api.transaction():
            db_model = db_api.get_action_definition(name)

            if db_model.is_system:
                msg = "Attempt to delete a system action: %s" % name
                raise exc.DataAccessException(msg)

            db_api.delete_action_definition(name)
Beispiel #24
0
    def get(self, identifier):
        """Return the named action.

        :param identifier: ID or name of the Action to get.
        """

        acl.enforce('actions:get', context.ctx())
        LOG.info("Fetch action [identifier=%s]", identifier)

        db_model = db_api.get_action_definition(identifier)

        return resources.Action.from_dict(db_model.to_dict())
Beispiel #25
0
    def delete(self, name):
        """Delete the named action."""
        LOG.info("Delete action [name=%s]" % name)

        with db_api.transaction():
            db_model = db_api.get_action_definition(name)

            if db_model.is_system:
                msg = "Attempt to delete a system action: %s" % name
                raise exc.DataAccessException(msg)

            db_api.delete_action_definition(name)
Beispiel #26
0
    def get(self, identifier):
        """Return the named action.

        :param identifier: ID or name of the Action to get.
        """

        acl.enforce('actions:get', context.ctx())
        LOG.info("Fetch action [identifier=%s]", identifier)

        db_model = db_api.get_action_definition(identifier)

        return resources.Action.from_dict(db_model.to_dict())
Beispiel #27
0
    def delete(self, identifier):
        """Delete the named action."""
        acl.enforce('actions:delete', context.ctx())
        LOG.info("Delete action [identifier=%s]", identifier)

        with db_api.transaction():
            db_model = db_api.get_action_definition(identifier)

            if db_model.is_system:
                msg = "Attempt to delete a system action: %s" % identifier
                raise exc.DataAccessException(msg)

            db_api.delete_action_definition(identifier)
Beispiel #28
0
def _run_existing_action(action_ex_id, target):
    action_ex = db_api.get_action_execution(action_ex_id)
    action_def = db_api.get_action_definition(action_ex.name)

    result = rpc.get_executor_client().run_action(
        action_ex_id,
        action_def.action_class,
        action_def.attributes or {},
        action_ex.input,
        target,
        safe_rerun=action_ex.runtime_context.get('safe_rerun', False))

    return _get_action_output(result) if result else None
Beispiel #29
0
def _run_existing_action(action_ex_id, target):
    action_ex = db_api.get_action_execution(action_ex_id)
    action_def = db_api.get_action_definition(action_ex.name)

    result = rpc.get_executor_client().run_action(
        action_ex_id,
        action_def.action_class,
        action_def.attributes or {},
        action_ex.input,
        target
    )

    return _get_action_output(result) if result else None
Beispiel #30
0
    def delete(self, identifier):
        """Delete the named action."""
        acl.enforce('actions:delete', context.ctx())
        LOG.info("Delete action [identifier=%s]", identifier)

        with db_api.transaction():
            db_model = db_api.get_action_definition(identifier)

            if db_model.is_system:
                msg = "Attempt to delete a system action: %s" % identifier
                raise exc.DataAccessException(msg)

            db_api.delete_action_definition(identifier)
Beispiel #31
0
    def __init__(self, action_def, action_ex=None, task_ex=None):
        self.action_spec = spec_parser.get_action_spec(action_def.spec)

        base_action_def = db_api.get_action_definition(
            self.action_spec.get_base()
        )

        super(AdHocAction, self).__init__(
            base_action_def,
            action_ex,
            task_ex
        )

        self.adhoc_action_def = action_def
Beispiel #32
0
def _run_existing_action(action_ex_id, target):
    action_ex = db_api.get_action_execution(action_ex_id)
    action_def = db_api.get_action_definition(action_ex.name)

    result = rpc.get_executor_client().run_action(
        action_ex_id,
        action_def.action_class,
        action_def.attributes or {},
        action_ex.input,
        target,
        safe_rerun=action_ex.runtime_context.get('safe_rerun', False)
    )

    return _get_action_output(result) if result else None
    def test_delete_action(self):

        # Create action.
        adhoc_action_service.create_actions(ACTION_LIST, namespace=NAMESPACE)

        action = db_api.get_action_definition('action1', namespace=NAMESPACE)
        self.assertEqual(NAMESPACE, action.get('namespace'))
        self.assertEqual('action1', action.get('name'))

        # Delete action.
        db_api.delete_action_definition('action1', namespace=NAMESPACE)

        self.assertRaises(DBEntityNotFoundError,
                          db_api.get_action_definition,
                          name='action1',
                          namespace=NAMESPACE)
Beispiel #34
0
    def test_get_operational_error(self, mocked_get):
        # Create an adhoc action for the purpose of the test.
        adhoc_actions.create_actions(ADHOC_ACTION_YAML)

        action_def = db_api.get_action_definition('my_action')

        mocked_get.side_effect = [
            # Emulating DB OperationalError
            sa.exc.OperationalError('Mock', 'mock', 'mock'),
            action_def  # Successful run
        ]

        resp = self.app.get('/v2/actions/my_action')

        self.assertEqual(200, resp.status_int)

        self.check_adhoc_action_json(resp.json)
Beispiel #35
0
    def _gather_base_actions(self, action_def, base_action_def):
        """Find all base ad-hoc actions and store them.

        An ad-hoc action may be based on another ad-hoc action and this
        works recursively, so that the base action can also be based on an
        ad-hoc action. Using the same base action more than once in this
        action hierarchy is not allowed to avoid infinite loops.
        The method stores the list of ad-hoc actions.

        :param action_def: Action definition
        :type action_def: ActionDefinition
        :param base_action_def: Original base action definition
        :type base_action_def: ActionDefinition
        :return: The definition of the base system action
        :rtype: ActionDefinition
        """

        self.adhoc_action_defs = [action_def]

        original_base_name = self.action_spec.get_name()
        action_names = set([original_base_name])

        base = base_action_def

        while not base.is_system and base.name not in action_names:
            action_names.add(base.name)
            self.adhoc_action_defs.append(base)

            base_name = base.spec['base']
            try:
                base = db_api.get_action_definition(base_name,
                                                    namespace=base.namespace)
            except exc.DBEntityNotFoundError:
                raise exc.InvalidActionException(
                    "Failed to find action [action_name=%s namespace=%s] "
                    % (base_name, base.namespace)
                )

        # if the action is repeated
        if base.name in action_names:
            raise ValueError(
                'An ad-hoc action cannot use twice the same action, %s is '
                'used at least twice' % base.name
            )

        return base
Beispiel #36
0
    def check_adhoc_action_json(self, action_json):
        self.assertIsNotNone(action_json)
        self.assertIsInstance(action_json, dict)

        action_name = action_json['name']

        action_def = db_api.get_action_definition(action_name)

        self.assertIsNotNone(
            action_def,
            'Ad-hoc action definition does not exist [name=%s]' % action_name
        )

        # Compare action JSON with the state of the corresponding
        # persistent object.
        for k, v in action_json.items():
            self.assertEqual(v, utils.datetime_to_str(getattr(action_def, k)))
Beispiel #37
0
    def __init__(self,
                 action_def,
                 action_ex=None,
                 task_ex=None,
                 task_ctx=None,
                 wf_ctx=None):
        self.action_spec = spec_parser.get_action_spec(action_def.spec)

        base_action_def = db_api.get_action_definition(
            self.action_spec.get_base())
        base_action_def = self._gather_base_actions(action_def,
                                                    base_action_def)

        super(AdHocAction, self).__init__(base_action_def, action_ex, task_ex)

        self.adhoc_action_def = action_def
        self.task_ctx = task_ctx or {}
        self.wf_ctx = wf_ctx or {}