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)
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})
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
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)
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)
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)
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)
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
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
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)