def create_recipe_type(self, name, version, title, description, definition, trigger_rule): """Creates a new recipe type and saves it in the database. All database changes occur in an atomic transaction. :param name: The system name of the recipe type :type name: str :param version: The version of the recipe type :type version: str :param title: The human-readable name of the recipe type :type title: str :param description: An optional description of the recipe type :type description: str :param definition: The definition for running a recipe of this type :type definition: :class:`recipe.configuration.definition.recipe_definition.RecipeDefinition` :param trigger_rule: The trigger rule that creates recipes of this type :type trigger_rule: :class:`trigger.models.TriggerRule` :returns: The new recipe type :rtype: :class:`recipe.models.RecipeType` :raises :class:`recipe.configuration.definition.exceptions.InvalidDefinition`: If any part of the recipe definition violates the specification :raises :class:`trigger.configuration.exceptions.InvalidTriggerType`: If the given trigger rule is an invalid type for creating recipes :raises :class:`trigger.configuration.exceptions.InvalidTriggerRule`: If the given trigger rule configuration is invalid :raises :class:`recipe.configuration.data.exceptions.InvalidRecipeConnection`: If the trigger rule connection to the recipe type definition is invalid """ # Must lock job type interfaces so the new recipe type definition can be validated _ = definition.get_job_types(lock=True) definition.validate_job_interfaces() # Validate the trigger rule if trigger_rule: trigger_config = trigger_rule.get_configuration() if not isinstance(trigger_config, RecipeTriggerRuleConfiguration): raise InvalidTriggerType( '%s is an invalid trigger rule type for creating recipes' % trigger_rule.type) trigger_config.validate_trigger_for_recipe(definition) # Create the new recipe type recipe_type = RecipeType() recipe_type.name = name recipe_type.version = version recipe_type.title = title recipe_type.description = description recipe_type.definition = definition.get_dict() recipe_type.trigger_rule = trigger_rule recipe_type.save() # Create first revision of the recipe type RecipeTypeRevision.objects.create_recipe_type_revision(recipe_type) return recipe_type
def get_trigger_rule_handler(trigger_rule_type): """Returns the trigger rule handler that is registered with the given type :param trigger_rule_type: The trigger rule type :type trigger_rule_type: string :returns: The trigger rule handler, possibly None :rtype: :class:`trigger.handler.TriggerRuleHandler` :raises :class:`trigger.configuration.exceptions.InvalidTriggerType`: If the trigger type is invalid """ if trigger_rule_type not in TRIGGER_RULE_HANDLERS: raise InvalidTriggerType('%s is an invalid trigger rule type' % trigger_rule_type) return TRIGGER_RULE_HANDLERS[trigger_rule_type]
def validate_recipe_type(self, name, title, version, description, definition, trigger_config): """Validates a new recipe type prior to attempting a save :param name: The system name of the recipe type :type name: str :param title: The human-readable name of the recipe type :type title: str :param version: The version of the recipe type :type version: str :param description: An optional description of the recipe type :type description: str :param definition: The definition for running a recipe of this type :type definition: :class:`recipe.configuration.definition.recipe_definition.RecipeDefinition` :param trigger_config: The trigger rule configuration :type trigger_config: :class:`trigger.configuration.trigger_rule.TriggerRuleConfiguration` :returns: A list of warnings discovered during validation. :rtype: list[:class:`job.configuration.data.job_data.ValidationWarning`] :raises :class:`recipe.configuration.definition.exceptions.InvalidDefinition`: If any part of the recipe definition violates the specification :raises :class:`trigger.configuration.exceptions.InvalidTriggerType`: If the given trigger rule is an invalid type for creating recipes :raises :class:`trigger.configuration.exceptions.InvalidTriggerRule`: If the given trigger rule configuration is invalid :raises :class:`recipe.configuration.data.exceptions.InvalidRecipeConnection`: If the trigger rule connection to the recipe type definition is invalid """ warnings = definition.validate_job_interfaces() if trigger_config: trigger_config.validate() if not isinstance(trigger_config, RecipeTriggerRuleConfiguration): msg = '%s is an invalid trigger rule type for creating recipes' raise InvalidTriggerType(msg % trigger_config.trigger_rule_type) warnings.extend( trigger_config.validate_trigger_for_recipe(definition)) return warnings
def edit_recipe_type(self, recipe_type_id, title, description, definition, trigger_rule, remove_trigger_rule): """Edits the given recipe type and saves the changes in the database. The caller must provide the related trigger_rule model. All database changes occur in an atomic transaction. An argument of None for a field indicates that the field should not change. The remove_trigger_rule parameter indicates the difference between no change to the trigger rule (False) and removing the trigger rule (True) when trigger_rule is None. :param recipe_type_id: The unique identifier of the recipe type to edit :type recipe_type_id: int :param title: The human-readable name of the recipe type, possibly None :type title: str :param description: A description of the recipe type, possibly None :type description: str :param definition: The definition for running a recipe of this type, possibly None :type definition: :class:`recipe.configuration.definition.recipe_definition.RecipeDefinition` :param trigger_rule: The trigger rule that creates recipes of this type, possibly None :type trigger_rule: :class:`trigger.models.TriggerRule` :param remove_trigger_rule: Indicates whether the trigger rule should be unchanged (False) or removed (True) when trigger_rule is None :type remove_trigger_rule: bool :raises :class:`recipe.configuration.definition.exceptions.InvalidDefinition`: If any part of the recipe definition violates the specification :raises :class:`trigger.configuration.exceptions.InvalidTriggerType`: If the given trigger rule is an invalid type for creating recipes :raises :class:`trigger.configuration.exceptions.InvalidTriggerRule`: If the given trigger rule configuration is invalid :raises :class:`recipe.configuration.data.exceptions.InvalidRecipeConnection`: If the trigger rule connection to the recipe type definition is invalid """ # Acquire model lock recipe_type = RecipeType.objects.select_for_update().get(pk=recipe_type_id) if title is not None: recipe_type.title = title if description is not None: recipe_type.description = description if definition: # Must lock job type interfaces so the new recipe type definition can be validated _ = definition.get_job_types(lock=True) definition.validate_job_interfaces() recipe_type.definition = definition.get_dict() recipe_type.revision_num = recipe_type.revision_num + 1 if trigger_rule or remove_trigger_rule: if recipe_type.trigger_rule: # Archive old trigger rule since we are changing to a new one TriggerRule.objects.archive_trigger_rule(recipe_type.trigger_rule_id) recipe_type.trigger_rule = trigger_rule # Validate updated trigger rule against updated definition if recipe_type.trigger_rule: trigger_config = recipe_type.trigger_rule.get_configuration() if not isinstance(trigger_config, RecipeTriggerRuleConfiguration): msg = '%s is an invalid trigger rule type for creating recipes' raise InvalidTriggerType(msg % recipe_type.trigger_rule.type) trigger_config.validate_trigger_for_recipe(recipe_type.get_recipe_definition()) recipe_type.save() if definition: # Create new revision of the recipe type for new definition RecipeTypeRevision.objects.create_recipe_type_revision(recipe_type)