def get_inherited_operations(context, presentation): """ Returns our operation definitions added on top of those of our parent, if we have one (recursively). Allows overriding all aspects of parent operations except input data types. """ # Get operations from parent parent = presentation._get_parent(context) operations = get_inherited_operations( context, parent) if parent is not None else OrderedDict() # Add/merge our operations our_operations = presentation.operations # OperationDefinition merge_operation_definitions(context, operations, our_operations, presentation._name, presentation, 'type') for operation in operations.itervalues(): operation._reset_method_cache() return operations
def get_and_override_operation_definitions_from_type(context, presentation): """ Returns our operation definitions added on top of those of the interface type, if specified. Allows overriding all aspects of parent interface type inputs except data types. """ operations = OrderedDict() # Get operations from type the_type = presentation._get_type(context) # InterfaceType type_operations = the_type._get_operations( context) if the_type is not None else None if type_operations: for operations_name, type_operation in type_operations.iteritems(): operations[operations_name] = type_operation._clone(presentation) # Add/merge our operations our_operations = presentation.operations # OperationDefinition merge_operation_definitions(context, operations, our_operations, presentation._name, presentation, 'definition') return operations
def assign_raw_inputs(context, raw, assignments, definitions, interface_name, operation_name, presentation): if assignments is None: assignments = {} if definitions is None: definitions = {} # Make sure we have the dict if ('inputs' not in raw) or (raw['inputs'] is None): raw['inputs'] = OrderedDict() # Defaults for input_name, definition in definitions.iteritems(): if ('default' in definition._raw) and (input_name not in raw['inputs']): raw['inputs'][input_name] = coerce_parameter_value(context, definition, definition, definition.default, 'default') # Assign inputs for input_name, assignment in assignments.iteritems(): if (not context.presentation.configuration.get('tosca.adhoc_inputs', True)) and \ (input_name not in definitions): if operation_name is not None: context.validation.report( u'interface definition "{0}" assigns a value to an unknown operation input' u' "{1}.{2}" in "{3}"' .format(interface_name, operation_name, input_name, presentation._fullname), locator=assignment._locator, level=Issue.BETWEEN_TYPES) else: context.validation.report( u'interface definition "{0}" assigns a value to an unknown input "{1}" in "{2}"' .format(interface_name, input_name, presentation._fullname), locator=assignment._locator, level=Issue.BETWEEN_TYPES) definition = definitions.get(input_name) # Could be None! raw['inputs'][input_name] = coerce_parameter_value(context, assignment, definition, assignment.value)
def merge_capability_definition(context, presentation, capability_definition, from_capability_definition): raw_properties = OrderedDict() capability_definition._raw['type'] = from_capability_definition.type # Merge properties from type from_property_defintions = from_capability_definition.properties merge_raw_parameter_definitions(context, presentation, raw_properties, from_property_defintions, 'properties') # Merge our properties merge_raw_parameter_definitions(context, presentation, raw_properties, capability_definition.properties, 'properties') if raw_properties: capability_definition._raw['properties'] = raw_properties capability_definition._reset_method_cache() # Merge occurrences occurrences = from_capability_definition._raw.get('occurrences') if (occurrences is not None) and (capability_definition._raw.get('occurrences') is None): capability_definition._raw['occurrences'] = \ deepcopy_with_locators(occurrences)
def merge_capability_definition_from_type(context, presentation, capability_definition): raw_properties = OrderedDict() # Merge properties from type the_type = capability_definition._get_type(context) type_property_defintions = the_type._get_properties(context) merge_raw_parameter_definitions(context, presentation, raw_properties, type_property_defintions, 'properties') # Merge our properties merge_raw_parameter_definitions(context, presentation, raw_properties, capability_definition.properties, 'properties') if raw_properties: capability_definition._raw['properties'] = raw_properties # Override valid_source_types if capability_definition._raw.get('valid_source_types') is None: valid_source_types = the_type._get_valid_source_types(context) if valid_source_types is not None: capability_definition._raw['valid_source_types'] = \ deepcopy_with_locators(valid_source_types)
def get_inherited_artifact_definitions(context, presentation, for_presentation=None): if for_presentation is None: for_presentation = presentation if hasattr(presentation, '_get_type'): # In NodeTemplate parent = presentation._get_type(context) else: # In NodeType parent = presentation._get_parent(context) # Get artifact definitions from parent artifacts = get_inherited_artifact_definitions(context, parent, for_presentation) \ if parent is not None else OrderedDict() # Add/override our artifact definitions our_artifacts = presentation.artifacts if our_artifacts: for artifact_name, artifact in our_artifacts.iteritems(): artifacts[artifact_name] = artifact._clone(for_presentation) return artifacts
def merge_requirement_assignment_relationship(context, presentation, property_definitions, interface_definitions, requirement, our_relationship): the_type = our_relationship.type if the_type is not None: # Could be a type or a template: requirement._raw['relationship']['type'] = deepcopy_with_locators( the_type) our_relationship_properties = our_relationship._raw.get('properties') if our_relationship_properties: # Make sure we have a dict if 'properties' not in requirement._raw['relationship']: requirement._raw['relationship']['properties'] = OrderedDict() # Merge our properties for property_name, prop in our_relationship_properties.iteritems(): if property_name in property_definitions: definition = property_definitions[property_name] requirement._raw['relationship']['properties'][property_name] = \ coerce_property_value(context, presentation, definition, prop) else: context.validation.report( 'relationship property "%s" not declared at definition of requirement "%s"' ' in "%s"' % (property_name, presentation._fullname, presentation._container._container._fullname), locator=our_relationship._get_child_locator( 'properties', property_name), level=Issue.BETWEEN_TYPES) our_interfaces = our_relationship.interfaces if our_interfaces: # Make sure we have a dict if 'interfaces' not in requirement._raw['relationship']: requirement._raw['relationship']['interfaces'] = OrderedDict() # Merge interfaces for interface_name, our_interface in our_interfaces.iteritems(): if interface_name not in requirement._raw['relationship'][ 'interfaces']: requirement._raw['relationship']['interfaces'][ interface_name] = OrderedDict() if (interface_definitions is not None) and (interface_name in interface_definitions): interface_definition = interface_definitions[interface_name] interface_assignment = requirement.relationship.interfaces[ interface_name] merge_interface(context, presentation, interface_assignment, our_interface, interface_definition, interface_name) else: context.validation.report( 'interface definition "%s" not declared at definition of requirement "%s"' ' in "%s"' % (interface_name, presentation._fullname, presentation._container._container._fullname), locator=our_relationship._locator, level=Issue.BETWEEN_TYPES)
def convert_requirement_from_definition_to_assignment( context, requirement_definition, # pylint: disable=too-many-branches our_requirement_assignment, container): from ..assignments import RequirementAssignment raw = OrderedDict() # Capability type name: raw['capability'] = deepcopy_with_locators( requirement_definition.capability) node_type = requirement_definition._get_node_type(context) if node_type is not None: raw['node'] = deepcopy_with_locators(node_type._name) relationship_type = None relationship_template = None relationship_property_definitions = None relationship_interface_definitions = None # First try to find the relationship if we declared it # RelationshipAssignment: our_relationship = our_requirement_assignment.relationship \ if our_requirement_assignment is not None else None if our_relationship is not None: relationship_type, relationship_type_variant = our_relationship._get_type( context) if relationship_type_variant == 'relationship_template': relationship_template = relationship_type relationship_type = relationship_template._get_type(context) definition_relationship_type = None relationship_definition = requirement_definition.relationship # RelationshipDefinition if relationship_definition is not None: definition_relationship_type = relationship_definition._get_type( context) # If not exists, try at the node type if relationship_type is None: relationship_type = definition_relationship_type else: # Make sure the type is derived if not definition_relationship_type._is_descendant( context, relationship_type): context.validation.report( 'assigned relationship type "%s" is not a descendant of declared relationship type "%s"' % (relationship_type._name, definition_relationship_type._name), locator=container._locator, level=Issue.BETWEEN_TYPES) if relationship_type is not None: raw['relationship'] = OrderedDict() type_name = our_relationship.type if our_relationship is not None else None if type_name is None: type_name = relationship_type._name raw['relationship']['type'] = deepcopy_with_locators(type_name) # These are our property definitions relationship_property_definitions = relationship_type._get_properties( context) if relationship_template is not None: # Property values from template raw['properties'] = relationship_template._get_property_values( context) else: if relationship_property_definitions: # Convert property definitions to values raw['properties'] = \ convert_property_definitions_to_values(context, relationship_property_definitions) # These are our interface definitions # InterfaceDefinition: relationship_interface_definitions = OrderedDict( relationship_type._get_interfaces(context)) # Convert interface definitions to templates convert_requirement_interface_definitions_from_type_to_raw_template( context, raw['relationship'], relationship_interface_definitions) if relationship_definition: # Merge extra interface definitions # InterfaceDefinition: relationship_interface_definitions = relationship_definition.interfaces merge_interface_definitions(context, relationship_interface_definitions, relationship_interface_definitions, requirement_definition, container) if relationship_template is not None: # Interfaces from template interfaces = relationship_template._get_interfaces(context) if interfaces: raw['relationship']['interfaces'] = OrderedDict() for interface_name, interface in interfaces.iteritems(): raw['relationship']['interfaces'][ interface_name] = interface._raw return \ RequirementAssignment(name=requirement_definition._name, raw=raw, container=container), \ relationship_property_definitions, \ relationship_interface_definitions
def create_operation_template_model(context, service_template, operation): model = OperationTemplate(name=operation._name) if operation.description: model.description = operation.description.value implementation = operation.implementation if implementation is not None: primary = implementation.primary extract_implementation_primary(context, service_template, operation, model, primary) relationship_edge = operation._get_extensions(context).get( 'relationship_edge') if relationship_edge is not None: if relationship_edge == 'source': model.relationship_edge = False elif relationship_edge == 'target': model.relationship_edge = True dependencies = implementation.dependencies configuration = OrderedDict() if dependencies: for dependency in dependencies: key, value = split_prefix(dependency) if key is not None: # Special ARIA prefix: signifies configuration parameters # Parse as YAML try: value = yaml.load(value) except yaml.parser.MarkedYAMLError as e: context.validation.report( 'YAML parser {0} in operation configuration: {1}'. format(e.problem, value), locator=implementation._locator, level=Issue.FIELD) continue # Coerce to intrinsic functions, if there are any value = coerce_parameter_value(context, implementation, None, value).value # Support dot-notation nesting set_nested(configuration, key.split('.'), value) else: if model.dependencies is None: model.dependencies = [] model.dependencies.append(dependency) # Convert configuration to Configuration models for key, value in configuration.iteritems(): model.configurations[key] = Configuration.wrap( key, value, description='Operation configuration.') inputs = operation.inputs if inputs: for input_name, the_input in inputs.iteritems(): model.inputs[input_name] = Input( name=input_name, # pylint: disable=unexpected-keyword-arg type_name=the_input.value.type, value=the_input.value.value, description=the_input.value.description) return model
def get_template_interfaces(context, presentation, type_name): """ Returns the assigned interface_template values while making sure they are defined in the type. This includes the interfaces themselves, their operations, and inputs for interfaces and operations. Interface and operation inputs' default values, if available, will be used if we did not assign them. Makes sure that required inputs indeed end up with a value. This code is especially complex due to the many levels of nesting involved. """ template_interfaces = OrderedDict() the_type = presentation._get_type( context) # NodeType, RelationshipType, GroupType # InterfaceDefinition (or InterfaceAssignment in the case of RelationshipTemplate): interface_definitions = the_type._get_interfaces( context) if the_type is not None else None # Copy over interfaces from the type (will initialize inputs with default values) if interface_definitions is not None: for interface_name, interface_definition in interface_definitions.iteritems( ): # Note that in the case of a RelationshipTemplate, we will already have the values as # InterfaceAssignment. It will not be converted, just cloned. template_interfaces[interface_name] = \ convert_interface_definition_from_type_to_template(context, interface_definition, presentation) # Fill in our interfaces our_interface_assignments = presentation.interfaces if our_interface_assignments: # InterfaceAssignment: for interface_name, our_interface_assignment in our_interface_assignments.iteritems( ): if interface_name in template_interfaces: interface_assignment = template_interfaces[ interface_name] # InterfaceAssignment # InterfaceDefinition (or InterfaceAssignment in the case of RelationshipTemplate): interface_definition = interface_definitions[interface_name] merge_interface(context, presentation, interface_assignment, our_interface_assignment, interface_definition, interface_name) else: context.validation.report( 'interface definition "%s" not declared at %s "%s" in "%s"' % (interface_name, type_name, presentation.type, presentation._fullname), locator=our_interface_assignment._locator, level=Issue.BETWEEN_TYPES) # Check that there are no required inputs that we haven't assigned for interface_name, interface_template in template_interfaces.iteritems(): if interface_name in interface_definitions: # InterfaceDefinition (or InterfaceAssignment in the case of RelationshipTemplate): interface_definition = interface_definitions[interface_name] our_interface_assignment = our_interface_assignments.get(interface_name) \ if our_interface_assignments is not None else None validate_required_inputs(context, presentation, interface_template, interface_definition, our_interface_assignment, interface_name) return template_interfaces
def convert_parameter_definitions_to_values(context, definitions): values = OrderedDict() for name, definition in definitions.iteritems(): values[name] = coerce_parameter_value(context, definition, definition, definition.default, 'default') return values
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
def as_raw(self): return OrderedDict( (('value', self.value), ('factor', self.factor), ('unit', self.unit), ('unit_size', self.UNITS[self.unit]))) # pylint: disable=no-member
def as_raw(self): return OrderedDict(self)