def validate_required_inputs(context,
                             presentation,
                             assignment,
                             definition,
                             original_assignment,
                             interface_name,
                             operation_name=None):
    # The validation of the `required` field of inputs that belong to operations and interfaces
    # (as opposed to topology template and workflow inputs) is done only in the parsing stage.
    # This reasoning follows the TOSCA spirit, where anything that is declared as required in the
    # type, must be assigned in the corresponding template.
    input_definitions = definition.inputs
    if input_definitions:
        for input_name, input_definition in input_definitions.iteritems():
            if input_definition.required:
                prop = assignment.inputs.get(input_name) \
                    if ((assignment is not None) and (assignment.inputs is not None)) else None
                value = prop.value if prop is not None else None
                value = value.value if value is not None else None
                if value is None:
                    if operation_name is not None:
                        context.validation.report(
                            'interface definition "%s" does not assign a value to a required'
                            ' operation input "%s.%s" in "%s"' %
                            (interface_name, operation_name, input_name,
                             presentation._fullname),
                            locator=get_locator(original_assignment,
                                                presentation._locator),
                            level=Issue.BETWEEN_TYPES)
                    else:
                        context.validation.report(
                            'interface definition "%s" does not assign a value to a required input'
                            ' "%s" in "%s"' % (interface_name, input_name,
                                               presentation._fullname),
                            locator=get_locator(original_assignment,
                                                presentation._locator),
                            level=Issue.BETWEEN_TYPES)

    if operation_name is not None:
        return

    assignment_operations = assignment.operations
    operation_definitions = definition._get_operations(context)
    if operation_definitions:
        for operation_name, operation_definition in operation_definitions.iteritems(
        ):
            assignment_operation = assignment_operations.get(operation_name) \
                if assignment_operations is not None else None
            original_operation = \
                original_assignment.operations.get(operation_name, original_assignment) \
                if (original_assignment is not None) \
                and (original_assignment.operations is not None) \
                else original_assignment
            validate_required_inputs(context, presentation,
                                     assignment_operation,
                                     operation_definition, original_operation,
                                     interface_name, operation_name)
Esempio n. 2
0
def validate_required_inputs(context,
                             presentation,
                             assignment,
                             definition,
                             original_assignment,
                             interface_name,
                             operation_name=None):
    input_definitions = definition.inputs
    if input_definitions:
        for input_name, input_definition in input_definitions.iteritems():
            if input_definition.required:
                prop = assignment.inputs.get(input_name) \
                    if ((assignment is not None) and (assignment.inputs is not None)) else None
                value = prop.value if prop is not None else None
                value = value.value if value is not None else None
                if value is None:
                    if operation_name is not None:
                        context.validation.report(
                            'interface definition "%s" does not assign a value to a required'
                            ' operation input "%s.%s" in "%s"' %
                            (interface_name, operation_name, input_name,
                             presentation._fullname),
                            locator=get_locator(original_assignment,
                                                presentation._locator),
                            level=Issue.BETWEEN_TYPES)
                    else:
                        context.validation.report(
                            'interface definition "%s" does not assign a value to a required input'
                            ' "%s" in "%s"' % (interface_name, input_name,
                                               presentation._fullname),
                            locator=get_locator(original_assignment,
                                                presentation._locator),
                            level=Issue.BETWEEN_TYPES)

    if operation_name is not None:
        return

    assignment_operations = assignment.operations
    operation_definitions = definition._get_operations(context)
    if operation_definitions:
        for operation_name, operation_definition in operation_definitions.iteritems(
        ):
            assignment_operation = assignment_operations.get(operation_name) \
                if assignment_operations is not None else None
            original_operation = \
                original_assignment.operations.get(operation_name, original_assignment) \
                if (original_assignment is not None) \
                and (original_assignment.operations is not None) \
                else original_assignment
            validate_required_inputs(context, presentation,
                                     assignment_operation,
                                     operation_definition, original_operation,
                                     interface_name, operation_name)
Esempio n. 3
0
def coerce_data_type_value(context, presentation, data_type, entry_schema, constraints, value, # pylint: disable=unused-argument
                           aspect):
    """
    Handles the :code:`_coerce_data()` hook for complex data types.

    There are two kinds of handling:

    1. If we have a primitive type as our great ancestor, then we do primitive type coersion, and
       just check for constraints.

    2. Otherwise, for normal complex data types we return the assigned property values while making
       sure they are defined in our type. The property definition's default value, if available,
       will be used if we did not assign it. We also make sure that required definitions indeed end
       up with a value.
    """

    primitive_type = data_type._get_primitive_ancestor(context)
    if primitive_type is not None:
        # Must be coercible to primitive ancestor
        value = coerce_to_primitive(context, presentation, primitive_type, constraints, value,
                                    aspect)
    else:
        definitions = data_type._get_properties(context)
        if isinstance(value, dict):
            temp = OrderedDict()

            # Fill in our values, but make sure they are defined
            for name, v in value.iteritems():
                if name in definitions:
                    definition = definitions[name]
                    definition_type = definition._get_type(context)
                    definition_entry_schema = definition.entry_schema
                    definition_constraints = definition._get_constraints(context)
                    temp[name] = coerce_value(context, presentation, definition_type,
                                              definition_entry_schema, definition_constraints, v,
                                              aspect)
                else:
                    context.validation.report(
                        'assignment to undefined property "%s" in type "%s" in "%s"'
                        % (name, data_type._fullname, presentation._fullname),
                        locator=get_locator(v, value, presentation), level=Issue.BETWEEN_TYPES)

            # Fill in defaults from the definitions, and check if required definitions have not been
            # assigned
            for name, definition in definitions.iteritems():
                if (temp.get(name) is None) and hasattr(definition, 'default') \
                    and (definition.default is not None):
                    definition_type = definition._get_type(context)
                    definition_entry_schema = definition.entry_schema
                    definition_constraints = definition._get_constraints(context)
                    temp[name] = coerce_value(context, presentation, definition_type,
                                              definition_entry_schema, definition_constraints,
                                              definition.default, 'default')

                if getattr(definition, 'required', False) and (temp.get(name) is None):
                    context.validation.report(
                        'required property "%s" in type "%s" is not assigned a value in "%s"'
                        % (name, data_type._fullname, presentation._fullname),
                        locator=presentation._get_child_locator('definitions'),
                        level=Issue.BETWEEN_TYPES)

            value = temp
        elif value is not None:
            context.validation.report('value of type "%s" is not a dict in "%s"'
                                      % (data_type._fullname, presentation._fullname),
                                      locator=get_locator(value, presentation),
                                      level=Issue.BETWEEN_TYPES)
            value = None

    return value