Ejemplo n.º 1
0
    def apply_actions(self, node_info, data=None):
        """Run actions on a node.

        :param node_info: NodeInfo instance
        :param data: introspection data
        """
        LOG.debug('Running actions for rule "%s"', self.description,
                  node_info=node_info, data=data)

        ext_mgr = plugins_base.rule_actions_manager()
        for act in self._actions:
            ext = ext_mgr[act.action].obj

            for formatted_param in ext.FORMATTED_PARAMS:
                value = act.params.get(formatted_param)
                if not value or not isinstance(value, six.string_types):
                    continue

                # NOTE(aarefiev): verify provided value with introspection
                # data format specifications.
                # TODO(aarefiev): simple verify on import rule time.
                try:
                    act.params[formatted_param] = value.format(data=data)
                except KeyError as e:
                    raise utils.Error(_('Invalid formatting variable key '
                                        'provided: %s') % e,
                                      node_info=node_info, data=data)

            LOG.debug('Running action `%(action)s %(params)s`',
                      {'action': act.action, 'params': act.params},
                      node_info=node_info, data=data)
            ext.apply(node_info, act.params)

        LOG.debug('Successfully applied actions',
                  node_info=node_info, data=data)
Ejemplo n.º 2
0
    def apply_actions(self, node_info, rollback=False):
        """Run actions on a node.

        :param node_info: NodeInfo instance
        :param rollback: if True, rollback actions are executed
        """
        if rollback:
            method = 'rollback'
        else:
            method = 'apply'

        LOG.debug('Running %(what)s actions for rule "%(rule)s" '
                  'on node %(node)s',
                  {'what': method, 'rule': self.description,
                   'node': node_info.uuid})

        ext_mgr = plugins_base.rule_actions_manager()
        for act in self._actions:
            LOG.debug('Running %(what)s action `%(action)s %(params)s` for '
                      'node %(node)s',
                      {'action': act.action, 'params': act.params,
                       'node': node_info.uuid, 'what': method})
            ext = ext_mgr[act.action].obj
            getattr(ext, method)(node_info, act.params)

        LOG.debug('Successfully applied %(what)s to node %(node)s',
                  {'what': 'rollback actions' if rollback else 'actions',
                   'node': node_info.uuid})
Ejemplo n.º 3
0
def _validate_actions(actions_json):
    """Validates actions from jsonschema.

    :returns: a list of actions.
    """
    try:
        jsonschema.validate(actions_json, actions_schema())
    except jsonschema.ValidationError as exc:
        raise utils.Error(_('Validation failed for actions: %s') % exc)

    act_mgr = plugins_base.rule_actions_manager()
    actions = []
    for action_json in actions_json:
        plugin = act_mgr[action_json['action']].obj
        params = {k: v for k, v in action_json.items() if k != 'action'}
        try:
            plugin.validate(params)
        except ValueError as exc:
            raise utils.Error(
                _('Invalid parameters for action %(act)s: '
                  '%(error)s') % {
                      'act': action_json['action'],
                      'error': exc
                  })

        actions.append((action_json['action'], params))
    return actions
Ejemplo n.º 4
0
    def apply_actions(self, node_info, data=None):
        """Run actions on a node.

        :param node_info: NodeInfo instance
        :param data: introspection data
        """
        LOG.debug('Running actions for rule "%s"',
                  self.description,
                  node_info=node_info,
                  data=data)

        ext_mgr = plugins_base.rule_actions_manager()
        for act in self._actions:
            ext = ext_mgr[act.action].obj

            for formatted_param in ext.FORMATTED_PARAMS:
                try:
                    initial = act.params[formatted_param]
                except KeyError:
                    # Ignore parameter that wasn't given.
                    continue
                else:
                    act.params[formatted_param] = _format_value(initial, data)

            LOG.debug('Running action `%(action)s %(params)s`', {
                'action': act.action,
                'params': act.params
            },
                      node_info=node_info,
                      data=data)
            ext.apply(node_info, act.params)

        LOG.debug('Successfully applied actions',
                  node_info=node_info,
                  data=data)
Ejemplo n.º 5
0
    def apply_actions(self, node_info, data=None):
        """Run actions on a node.

        :param node_info: NodeInfo instance
        :param data: introspection data
        """
        LOG.debug('Running actions for rule "%s"', self.description,
                  node_info=node_info, data=data)

        ext_mgr = plugins_base.rule_actions_manager()
        for act in self._actions:
            ext = ext_mgr[act.action].obj

            for formatted_param in ext.FORMATTED_PARAMS:
                try:
                    initial = act.params[formatted_param]
                except KeyError:
                    # Ignore parameter that wasn't given.
                    continue
                else:
                    act.params[formatted_param] = _format_value(initial, data)

            LOG.debug('Running action `%(action)s %(params)s`',
                      {'action': act.action, 'params': act.params},
                      node_info=node_info, data=data)
            ext.apply(node_info, act.params)

        LOG.debug('Successfully applied actions',
                  node_info=node_info, data=data)
Ejemplo n.º 6
0
    def apply_actions(self, node_info, rollback=False, data=None):
        """Run actions on a node.

        :param node_info: NodeInfo instance
        :param rollback: if True, rollback actions are executed
        :param data: introspection data
        """
        if rollback:
            method = 'rollback'
        else:
            method = 'apply'

        LOG.debug('Running %(what)s actions for rule "%(rule)s"', {
            'what': method,
            'rule': self.description
        },
                  node_info=node_info,
                  data=data)

        ext_mgr = plugins_base.rule_actions_manager()
        for act in self._actions:
            ext = ext_mgr[act.action].obj
            for formatted_param in ext.FORMATTED_PARAMS:
                value = act.params.get(formatted_param)
                if not value or not isinstance(value, six.string_types):
                    continue

                # NOTE(aarefiev): verify provided value with introspection
                # data format specifications.
                # TODO(aarefiev): simple verify on import rule time.
                try:
                    act.params[formatted_param] = value.format(data=data)
                except KeyError as e:
                    raise utils.Error(_('Invalid formatting variable key '
                                        'provided: %s') % e,
                                      node_info=node_info,
                                      data=data)

            LOG.debug('Running %(what)s action `%(action)s %(params)s`', {
                'action': act.action,
                'params': act.params,
                'what': method
            },
                      node_info=node_info,
                      data=data)
            getattr(ext, method)(node_info, act.params)

        LOG.debug('Successfully applied %s',
                  'rollback actions' if rollback else 'actions',
                  node_info=node_info,
                  data=data)
Ejemplo n.º 7
0
    def apply_actions(self, node_info, rollback=False, data=None):
        """Run actions on a node.

        :param node_info: NodeInfo instance
        :param rollback: if True, rollback actions are executed
        :param data: introspection data
        """
        if rollback:
            method = 'rollback'
        else:
            method = 'apply'

        LOG.debug('Running %(what)s actions for rule "%(rule)s"',
                  {'what': method, 'rule': self.description},
                  node_info=node_info, data=data)

        ext_mgr = plugins_base.rule_actions_manager()
        for act in self._actions:
            ext = ext_mgr[act.action].obj
            for formatted_param in ext.FORMATTED_PARAMS:
                value = act.params.get(formatted_param)
                if not value or not isinstance(value, six.string_types):
                    continue

                # NOTE(aarefiev): verify provided value with introspection
                # data format specifications.
                # TODO(aarefiev): simple verify on import rule time.
                try:
                    act.params[formatted_param] = value.format(data=data)
                except KeyError as e:
                    raise utils.Error(_('Invalid formatting variable key '
                                        'provided: %s') % e,
                                      node_info=node_info, data=data)

            LOG.debug('Running %(what)s action `%(action)s %(params)s`',
                      {'action': act.action, 'params': act.params,
                       'what': method},
                      node_info=node_info, data=data)
            getattr(ext, method)(node_info, act.params)

        LOG.debug('Successfully applied %s',
                  'rollback actions' if rollback else 'actions',
                  node_info=node_info, data=data)
Ejemplo n.º 8
0
def actions_schema():
    global _ACTIONS_SCHEMA
    if _ACTIONS_SCHEMA is None:
        action_plugins = [x.name for x in plugins_base.rule_actions_manager()]
        _ACTIONS_SCHEMA = {
            "title": "Inspector rule actions schema",
            "type": "array",
            "minItems": 1,
            "items": {
                "type": "object",
                "required": ["action"],
                "properties": {
                    "action": {
                        "description": "action to take",
                        "enum": action_plugins
                    },
                },
                # other properties are validated by plugins
                "additionalProperties": True
            }
        }

    return _ACTIONS_SCHEMA
Ejemplo n.º 9
0
def actions_schema():
    global _ACTIONS_SCHEMA
    if _ACTIONS_SCHEMA is None:
        action_plugins = [x.name for x in
                          plugins_base.rule_actions_manager()]
        _ACTIONS_SCHEMA = {
            "title": "Inspector rule actions schema",
            "type": "array",
            "minItems": 1,
            "items": {
                "type": "object",
                "required": ["action"],
                "properties": {
                    "action": {
                        "description": "action to take",
                        "enum": action_plugins
                    },
                },
                # other properties are validated by plugins
                "additionalProperties": True
            }
        }

    return _ACTIONS_SCHEMA
Ejemplo n.º 10
0
def _validate_actions(actions_json):
    """Validates actions from jsonschema.

    :returns: a list of actions.
    """
    try:
        jsonschema.validate(actions_json, actions_schema())
    except jsonschema.ValidationError as exc:
        raise utils.Error(_('Validation failed for actions: %s') % exc)

    act_mgr = plugins_base.rule_actions_manager()
    actions = []
    for action_json in actions_json:
        plugin = act_mgr[action_json['action']].obj
        params = {k: v for k, v in action_json.items() if k != 'action'}
        try:
            plugin.validate(params)
        except ValueError as exc:
            raise utils.Error(_('Invalid parameters for action %(act)s: '
                                '%(error)s') %
                              {'act': action_json['action'], 'error': exc})

        actions.append((action_json['action'], params))
    return actions
Ejemplo n.º 11
0
def create(conditions_json, actions_json, uuid=None,
           description=None):
    """Create a new rule in database.

    :param conditions_json: list of dicts with the following keys:
                            * op - operator
                            * field - JSON path to field to compare
                            Other keys are stored as is.
    :param actions_json: list of dicts with the following keys:
                         * action - action type
                         Other keys are stored as is.
    :param uuid: rule UUID, will be generated if empty
    :param description: human-readable rule description
    :returns: new IntrospectionRule object
    :raises: utils.Error on failure
    """
    uuid = uuid or uuidutils.generate_uuid()
    LOG.debug('Creating rule %(uuid)s with description "%(descr)s", '
              'conditions %(conditions)s and actions %(actions)s',
              {'uuid': uuid, 'descr': description,
               'conditions': conditions_json, 'actions': actions_json})

    try:
        jsonschema.validate(conditions_json, conditions_schema())
    except jsonschema.ValidationError as exc:
        raise utils.Error(_('Validation failed for conditions: %s') % exc)

    try:
        jsonschema.validate(actions_json, actions_schema())
    except jsonschema.ValidationError as exc:
        raise utils.Error(_('Validation failed for actions: %s') % exc)

    cond_mgr = plugins_base.rule_conditions_manager()
    act_mgr = plugins_base.rule_actions_manager()

    conditions = []
    for cond_json in conditions_json:
        field = cond_json['field']
        try:
            jsonpath.parse(field)
        except Exception as exc:
            raise utils.Error(_('Unable to parse field JSON path %(field)s: '
                                '%(error)s') % {'field': field, 'error': exc})

        plugin = cond_mgr[cond_json['op']].obj
        params = {k: v for k, v in cond_json.items()
                  if k not in ('op', 'field', 'multiple')}
        try:
            plugin.validate(params)
        except ValueError as exc:
            raise utils.Error(_('Invalid parameters for operator %(op)s: '
                                '%(error)s') %
                              {'op': cond_json['op'], 'error': exc})

        conditions.append((cond_json['field'], cond_json['op'],
                           cond_json.get('multiple', 'any'), params))

    actions = []
    for action_json in actions_json:
        plugin = act_mgr[action_json['action']].obj
        params = {k: v for k, v in action_json.items() if k != 'action'}
        try:
            plugin.validate(params)
        except ValueError as exc:
            raise utils.Error(_('Invalid parameters for action %(act)s: '
                                '%(error)s') %
                              {'act': action_json['action'], 'error': exc})

        actions.append((action_json['action'], params))

    try:
        with db.ensure_transaction() as session:
            rule = db.Rule(uuid=uuid, description=description,
                           disabled=False, created_at=timeutils.utcnow())

            for field, op, multiple, params in conditions:
                rule.conditions.append(db.RuleCondition(op=op, field=field,
                                                        multiple=multiple,
                                                        params=params))

            for action, params in actions:
                rule.actions.append(db.RuleAction(action=action,
                                                  params=params))

            rule.save(session)
    except db_exc.DBDuplicateEntry as exc:
        LOG.error(_LE('Database integrity error %s when '
                      'creating a rule'), exc)
        raise utils.Error(_('Rule with UUID %s already exists') % uuid,
                          code=409)

    LOG.info(_LI('Created rule %(uuid)s with description "%(descr)s"'),
             {'uuid': uuid, 'descr': description})
    return IntrospectionRule(uuid=uuid,
                             conditions=rule.conditions,
                             actions=rule.actions,
                             description=description)