def _register_internal_trigger_type(trigger_definition): try: trigger_type_db = create_trigger_type_db(trigger_type=trigger_definition) except (NotUniqueError, StackStormDBObjectConflictError): # We ignore conflict error since this operation is idempotent and race is not an issue LOG.debug('Internal trigger type "%s" already exists, ignoring...' % (trigger_definition['name']), exc_info=True) ref = ResourceReference.to_string_reference(name=trigger_definition['name'], pack=trigger_definition['pack']) trigger_type_db = get_trigger_type_db(ref) if trigger_type_db: LOG.debug('Registered internal trigger: %s.', trigger_definition['name']) # trigger types with parameters do no require a shadow trigger. if trigger_type_db and not trigger_type_db.parameters_schema: try: trigger_db = create_shadow_trigger(trigger_type_db) extra = {'trigger_db': trigger_db} LOG.audit('Trigger created for parameter-less internal TriggerType. Trigger.id=%s' % (trigger_db.id), extra=extra) except StackStormDBObjectConflictError: LOG.debug('Shadow trigger "%s" already exists. Ignoring.', trigger_type_db.get_reference().ref, exc_info=True) except (ValidationError, ValueError): LOG.exception('Validation failed in shadow trigger. TriggerType=%s.', trigger_type_db.get_reference().ref) raise return trigger_type_db
def validate_trigger_parameters(trigger_type_ref, parameters): """ This function validates parameters for system and user-defined triggers. :param trigger_type_ref: Reference of a trigger type. :type trigger_type_ref: ``str`` :param parameters: Trigger parameters. :type parameters: ``dict`` :return: Cleaned parameters on success, None if validation is not performed. """ if not trigger_type_ref: return None is_system_trigger = trigger_type_ref in SYSTEM_TRIGGER_TYPES if is_system_trigger: # System trigger parameters_schema = SYSTEM_TRIGGER_TYPES[trigger_type_ref][ "parameters_schema"] else: trigger_type_db = triggers.get_trigger_type_db(trigger_type_ref) if not trigger_type_db: # Trigger doesn't exist in the database return None parameters_schema = getattr(trigger_type_db, "parameters_schema", {}) if not parameters_schema: # Parameters schema not defined for the this trigger return None # We only validate non-system triggers if config option is set (enabled) if not is_system_trigger and not cfg.CONF.system.validate_trigger_parameters: LOG.debug( 'Got non-system trigger "%s", but trigger parameter validation for non-system' "triggers is disabled, skipping validation." % (trigger_type_ref)) return None cleaned = util_schema.validate( instance=parameters, schema=parameters_schema, cls=util_schema.CustomValidator, use_default=True, allow_default_none=True, ) # Additional validation for CronTimer trigger # TODO: If we need to add more checks like this we should consider abstracting this out. if trigger_type_ref == CRON_TIMER_TRIGGER_REF: # Validate that the user provided parameters are valid. This is required since JSON schema # allows arbitrary strings, but not any arbitrary string is a valid CronTrigger argument # Note: Constructor throws ValueError on invalid parameters CronTrigger(**parameters) return cleaned
def validate_trigger_parameters(trigger_type_ref, parameters): """ This function validates parameters for system and user-defined triggers. :param trigger_type_ref: Reference of a trigger type. :type trigger_type_ref: ``str`` :param parameters: Trigger parameters. :type parameters: ``dict`` :return: Cleaned parameters on success, None if validation is not performed. """ if not trigger_type_ref: return None is_system_trigger = trigger_type_ref in SYSTEM_TRIGGER_TYPES if is_system_trigger: # System trigger parameters_schema = SYSTEM_TRIGGER_TYPES[trigger_type_ref]['parameters_schema'] else: trigger_type_db = triggers.get_trigger_type_db(trigger_type_ref) if not trigger_type_db: # Trigger doesn't exist in the database return None parameters_schema = getattr(trigger_type_db, 'parameters_schema', {}) if not parameters_schema: # Parameters schema not defined for the this trigger return None # We only validate non-system triggers if config option is set (enabled) if not is_system_trigger and not cfg.CONF.system.validate_trigger_parameters: LOG.debug('Got non-system trigger "%s", but trigger parameter validation for non-system' 'triggers is disabled, skipping validation.' % (trigger_type_ref)) return None cleaned = util_schema.validate(instance=parameters, schema=parameters_schema, cls=util_schema.CustomValidator, use_default=True, allow_default_none=True) # Additional validation for CronTimer trigger # TODO: If we need to add more checks like this we should consider abstracting this out. if trigger_type_ref == CRON_TIMER_TRIGGER_REF: # Validate that the user provided parameters are valid. This is required since JSON schema # allows arbitrary strings, but not any arbitrary string is a valid CronTrigger argument # Note: Constructor throws ValueError on invalid parameters CronTrigger(**parameters) return cleaned
def _register_internal_trigger_type(trigger_definition): try: trigger_type_db = create_trigger_type_db( trigger_type=trigger_definition, log_not_unique_error_as_debug=True) except (NotUniqueError, StackStormDBObjectConflictError): # We ignore conflict error since this operation is idempotent and race is not an issue LOG.debug( 'Internal trigger type "%s" already exists, ignoring error...' % (trigger_definition["name"])) ref = ResourceReference.to_string_reference( name=trigger_definition["name"], pack=trigger_definition["pack"]) trigger_type_db = get_trigger_type_db(ref) if trigger_type_db: LOG.debug("Registered internal trigger: %s.", trigger_definition["name"]) # trigger types with parameters do no require a shadow trigger. if trigger_type_db and not trigger_type_db.parameters_schema: try: trigger_db = create_shadow_trigger( trigger_type_db, log_not_unique_error_as_debug=True) extra = {"trigger_db": trigger_db} LOG.audit( "Trigger created for parameter-less internal TriggerType. Trigger.id=%s" % (trigger_db.id), extra=extra, ) except (NotUniqueError, StackStormDBObjectConflictError): LOG.debug( 'Shadow trigger "%s" already exists. Ignoring.', trigger_type_db.get_reference().ref, exc_info=True, ) except (ValidationError, ValueError): LOG.exception( "Validation failed in shadow trigger. TriggerType=%s.", trigger_type_db.get_reference().ref, ) raise return trigger_type_db
def validate_trigger_payload(trigger_type_ref, payload): """ This function validates trigger payload parameters for system and user-defined triggers. :param trigger_type_ref: Reference of a trigger type. :type trigger_type_ref: ``str`` :param payload: Trigger payload. :type payload: ``dict`` :return: Cleaned payload on success, None if validation is not performed. """ if not trigger_type_ref: return None is_system_trigger = trigger_type_ref in SYSTEM_TRIGGER_TYPES if is_system_trigger: # System trigger payload_schema = SYSTEM_TRIGGER_TYPES[trigger_type_ref][ 'payload_schema'] else: trigger_type_db = triggers.get_trigger_type_db(trigger_type_ref) if not trigger_type_db: # Trigger doesn't exist in the database return None payload_schema = getattr(trigger_type_db, 'payload_schema', {}) if not payload_schema: # Payload schema not defined for the this trigger return None # We only validate non-system triggers if config option is set (enabled) if not is_system_trigger and not cfg.CONF.system.validate_trigger_payload: LOG.debug( 'Got non-system trigger "%s", but trigger payload validation for non-system' 'triggers is disabled, skipping validation.' % (trigger_type_ref)) return None cleaned = util_schema.validate(instance=payload, schema=payload_schema, cls=util_schema.CustomValidator, use_default=True, allow_default_none=True) return cleaned
def validate_trigger_payload(trigger_type_ref, payload): """ This function validates trigger payload parameters for system and user-defined triggers. :param trigger_type_ref: Reference of a trigger type. :type trigger_type_ref: ``str`` :param payload: Trigger payload. :type payload: ``dict`` :return: Cleaned payload on success, None if validation is not performed. """ if not trigger_type_ref: return None is_system_trigger = trigger_type_ref in SYSTEM_TRIGGER_TYPES if is_system_trigger: # System trigger payload_schema = SYSTEM_TRIGGER_TYPES[trigger_type_ref]['payload_schema'] else: trigger_type_db = triggers.get_trigger_type_db(trigger_type_ref) if not trigger_type_db: # Trigger doesn't exist in the database return None payload_schema = getattr(trigger_type_db, 'payload_schema', {}) if not payload_schema: # Payload schema not defined for the this trigger return None # We only validate non-system triggers if config option is set (enabled) if not is_system_trigger and not cfg.CONF.system.validate_trigger_payload: LOG.debug('Got non-system trigger "%s", but trigger payload validation for non-system' 'triggers is disabled, skipping validation.' % (trigger_type_ref)) return None cleaned = util_schema.validate(instance=payload, schema=payload_schema, cls=util_schema.CustomValidator, use_default=True, allow_default_none=True) return cleaned
def validate_trigger_payload(trigger_type_ref, payload, throw_on_inexistent_trigger=False): """ This function validates trigger payload parameters for system and user-defined triggers. :param trigger_type_ref: Reference of a trigger type / trigger / trigger dictionary object. :type trigger_type_ref: ``str`` :param payload: Trigger payload. :type payload: ``dict`` :return: Cleaned payload on success, None if validation is not performed. """ if not trigger_type_ref: return None # NOTE: Due to the awful code in some other places we also need to support a scenario where # this variable is a dictionary and contains various TriggerDB object attributes. if isinstance(trigger_type_ref, dict): if trigger_type_ref.get('type', None): trigger_type_ref = trigger_type_ref['type'] else: trigger_db = triggers.get_trigger_db_by_ref_or_dict( trigger_type_ref) if not trigger_db: # Corresponding TriggerDB not found, likely a corrupted database, skip the # validation. return None trigger_type_ref = trigger_db.type is_system_trigger = trigger_type_ref in SYSTEM_TRIGGER_TYPES if is_system_trigger: # System trigger payload_schema = SYSTEM_TRIGGER_TYPES[trigger_type_ref][ 'payload_schema'] else: # We assume Trigger ref and not TriggerType ref is passed in if second # part (trigger name) is a valid UUID version 4 try: trigger_uuid = uuid.UUID(trigger_type_ref.split('.')[-1]) except ValueError: is_trigger_db = False else: is_trigger_db = (trigger_uuid.version == 4) if is_trigger_db: trigger_db = triggers.get_trigger_db_by_ref(trigger_type_ref) if trigger_db: trigger_type_ref = trigger_db.type trigger_type_db = triggers.get_trigger_type_db(trigger_type_ref) if not trigger_type_db: # Trigger doesn't exist in the database if throw_on_inexistent_trigger: msg = ( 'Trigger type with reference "%s" doesn\'t exist in the database' % (trigger_type_ref)) raise ValueError(msg) return None payload_schema = getattr(trigger_type_db, 'payload_schema', {}) if not payload_schema: # Payload schema not defined for the this trigger return None # We only validate non-system triggers if config option is set (enabled) if not is_system_trigger and not cfg.CONF.system.validate_trigger_payload: LOG.debug( 'Got non-system trigger "%s", but trigger payload validation for non-system' 'triggers is disabled, skipping validation.' % (trigger_type_ref)) return None cleaned = util_schema.validate(instance=payload, schema=payload_schema, cls=util_schema.CustomValidator, use_default=True, allow_default_none=True) return cleaned
def validate_trigger_payload(trigger_type_ref, payload, throw_on_inexistent_trigger=False): """ This function validates trigger payload parameters for system and user-defined triggers. :param trigger_type_ref: Reference of a trigger type / trigger / trigger dictionary object. :type trigger_type_ref: ``str`` :param payload: Trigger payload. :type payload: ``dict`` :return: Cleaned payload on success, None if validation is not performed. """ if not trigger_type_ref: return None # NOTE: Due to the awful code in some other places we also need to support a scenario where # this variable is a dictionary and contains various TriggerDB object attributes. if isinstance(trigger_type_ref, dict): if trigger_type_ref.get('type', None): trigger_type_ref = trigger_type_ref['type'] else: trigger_db = triggers.get_trigger_db_by_ref_or_dict(trigger_type_ref) if not trigger_db: # Corresponding TriggerDB not found, likely a corrupted database, skip the # validation. return None trigger_type_ref = trigger_db.type is_system_trigger = trigger_type_ref in SYSTEM_TRIGGER_TYPES if is_system_trigger: # System trigger payload_schema = SYSTEM_TRIGGER_TYPES[trigger_type_ref]['payload_schema'] else: # We assume Trigger ref and not TriggerType ref is passed in if second # part (trigger name) is a valid UUID version 4 try: trigger_uuid = uuid.UUID(trigger_type_ref.split('.')[-1]) except ValueError: is_trigger_db = False else: is_trigger_db = (trigger_uuid.version == 4) if is_trigger_db: trigger_db = triggers.get_trigger_db_by_ref(trigger_type_ref) if trigger_db: trigger_type_ref = trigger_db.type trigger_type_db = triggers.get_trigger_type_db(trigger_type_ref) if not trigger_type_db: # Trigger doesn't exist in the database if throw_on_inexistent_trigger: msg = ('Trigger type with reference "%s" doesn\'t exist in the database' % (trigger_type_ref)) raise ValueError(msg) return None payload_schema = getattr(trigger_type_db, 'payload_schema', {}) if not payload_schema: # Payload schema not defined for the this trigger return None # We only validate non-system triggers if config option is set (enabled) if not is_system_trigger and not cfg.CONF.system.validate_trigger_payload: LOG.debug('Got non-system trigger "%s", but trigger payload validation for non-system' 'triggers is disabled, skipping validation.' % (trigger_type_ref)) return None cleaned = util_schema.validate(instance=payload, schema=payload_schema, cls=util_schema.CustomValidator, use_default=True, allow_default_none=True) return cleaned