def merge_raw_operation_definition(context, raw_operation, our_operation, interface_name, presentation, type_name): if not isinstance(our_operation._raw, dict): # Convert short form to long form raw_operation['implementation'] = deepcopy_with_locators( our_operation._raw) return # Add/merge inputs our_operation_inputs = our_operation.inputs if our_operation_inputs: # Make sure we have the dict if ('inputs' not in raw_operation) or (raw_operation.get('inputs') is None): raw_operation['inputs'] = OrderedDict() merge_raw_input_definitions(context, raw_operation['inputs'], our_operation_inputs, interface_name, our_operation._name, presentation, type_name) # Overrides if our_operation._raw.get('implementation') is not None: raw_operation['implementation'] = deepcopy_with_locators( our_operation._raw['implementation']) if our_operation._raw.get('executor') is not None: raw_operation['executor'] = deepcopy_with_locators( our_operation._raw['executor']) if our_operation._raw.get('max_retries') is not None: raw_operation['max_retries'] = deepcopy_with_locators( our_operation._raw['max_retries']) if our_operation._raw.get('retry_interval') is not None: raw_operation['retry_interval'] = deepcopy_with_locators( our_operation._raw['retry_interval'])
def convert_interface_definition_from_type_to_raw_template( context, presentation): # pylint: disable=invalid-name raw = OrderedDict() # Copy default values for inputs inputs = presentation._get_inputs(context) if inputs is not None: raw['inputs'] = convert_property_definitions_to_values(context, inputs) # Copy operations operations = presentation._get_operations(context) if operations: for operation_name, operation in operations.iteritems(): raw[operation_name] = OrderedDict() description = operation.description if description is not None: raw[operation_name]['description'] = deepcopy_with_locators( description._raw) implementation = operation.implementation if implementation is not None: raw[operation_name]['implementation'] = deepcopy_with_locators( implementation._raw) inputs = operation.inputs if inputs is not None: raw[operation_name][ 'inputs'] = convert_property_definitions_to_values( context, inputs) return raw
def convert_interface_definition_from_type_to_raw_template( context, presentation): raw = OrderedDict() # Copy operations operations = presentation.operations if operations: for operation_name, operation in operations.iteritems(): raw[operation_name] = OrderedDict() implementation = operation.implementation if implementation is not None: raw[operation_name]['implementation'] = deepcopy_with_locators( implementation) executor = operation.executor if executor is not None: raw[operation_name]['executor'] = deepcopy_with_locators( executor) if hasattr(operation, 'max_retries'): # Introduced in DSL v1.1 max_retries = operation.max_retries if max_retries is not None: raw[operation_name][ 'max_retries'] = deepcopy_with_locators(max_retries) retry_interval = operation.retry_interval if retry_interval is not None: raw[operation_name][ 'retry_interval'] = deepcopy_with_locators( retry_interval) inputs = operation.inputs if inputs is not None: raw[operation_name][ 'inputs'] = convert_property_definitions_to_values( context, presentation, inputs) return raw
def merge_requirement_assignment(context, presentation, relationship_property_definitions, relationship_interface_definitions, requirement, our_requirement): our_capability = our_requirement.capability if our_capability is not None: requirement._raw['capability'] = deepcopy_with_locators(our_capability) our_node = our_requirement.node if our_node is not None: requirement._raw['node'] = deepcopy_with_locators(our_node) our_node_filter = our_requirement.node_filter if our_node_filter is not None: requirement._raw['node_filter'] = deepcopy_with_locators( our_node_filter._raw) our_relationship = our_requirement.relationship # RelationshipAssignment if our_relationship is not None: # Make sure we have a dict if 'relationship' not in requirement._raw: requirement._raw['relationship'] = OrderedDict() elif not isinstance(requirement._raw['relationship'], dict): # Convert existing short form to long form the_type = requirement._raw['relationship'] requirement._raw['relationship'] = OrderedDict() requirement._raw['relationship']['type'] = deepcopy_with_locators( the_type) merge_requirement_assignment_relationship( context, our_relationship, relationship_property_definitions, relationship_interface_definitions, requirement, our_relationship)
def merge_interface(context, presentation, interface_assignment, our_interface_assignment, interface_definition, interface_name): # Assign operation implementations and inputs our_operation_templates = our_interface_assignment.operations # OperationAssignment operation_definitions = interface_definition._get_operations( context ) if hasattr( interface_definition, '_get_operations' ) else interface_definition.operations # OperationDefinition or OperationAssignment if our_operation_templates: for operation_name, our_operation_template in our_operation_templates.iteritems( ): # OperationAssignment operation_definition = operation_definitions.get( operation_name) # OperationDefinition our_input_assignments = our_operation_template.inputs our_implementation = our_operation_template.implementation if (our_input_assignments is not None) or (our_implementation is not None): # Make sure we have the dict if (operation_name not in interface_assignment._raw) or ( interface_assignment._raw[operation_name] is None): interface_assignment._raw[operation_name] = OrderedDict() if our_implementation is not None: interface_assignment._raw[operation_name][ 'implementation'] = deepcopy_with_locators( our_implementation) our_executor = our_operation_template.executor if our_executor is not None: interface_assignment._raw[operation_name][ 'executor'] = deepcopy_with_locators(our_executor) if hasattr(our_operation_template, 'max_retries'): # Introduced in DSL v1.1 our_max_retries = our_operation_template.max_retries if our_max_retries is not None or our_implementation is not None: interface_assignment._raw[operation_name][ 'max_retries'] = deepcopy_with_locators( our_max_retries) our_retry_interval = our_operation_template.retry_interval if our_retry_interval is not None or our_implementation is not None: interface_assignment._raw[operation_name][ 'retry_interval'] = deepcopy_with_locators( our_retry_interval) # Assign/merge operation inputs input_definitions = operation_definition.inputs if operation_definition is not None else None assign_raw_inputs(context, interface_assignment._raw[operation_name], our_input_assignments, input_definitions, interface_name, operation_name, presentation)
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: requirement._raw['relationship']['type'] = deepcopy_with_locators( the_type) # could be a type or a template 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 get_assigned_and_defined_property_values(context, presentation, field_name='properties'): """ Returns 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. Makes sure that required properties indeed end up with a value. """ values = OrderedDict() the_type = presentation._get_type(context) assignments = getattr(presentation, field_name) definitions = the_type._get_properties( context) if the_type is not None else None # Fill in our assignments, but make sure they are defined if assignments: for name, value in assignments.iteritems(): if (definitions is not None) and (name in definitions): definition = definitions[name] v = value.value # For data type values, merge into the default value (note: this is Cloudify behavior; in TOSCA these values are always replaced) default = definition.default if isinstance(v, dict) and isinstance( default, dict) and (context.presentation.get_from_dict( 'service_template', 'data_types', definition.type) is not None): t = deepcopy_with_locators(default) merge(t, v) v = t elif v is None: v = default values[name] = coerce_property_value(context, value, definition, v) else: context.validation.report( 'assignment to undefined property "%s" in "%s"' % (name, presentation._fullname), locator=value._locator, level=Issue.BETWEEN_TYPES) # Fill in defaults from the definitions if definitions: for name, definition in definitions.iteritems(): if (values.get(name) is None) and (definition.default is not None): values[name] = coerce_property_value(context, presentation, definition, definition.default) validate_required_values(context, presentation, values, definitions) return values
def merge_raw_input_definitions(context, raw_inputs, our_inputs, interface_name, operation_name, presentation, type_name): for input_name, our_input in our_inputs.iteritems(): if input_name in raw_inputs: merge_raw_input_definition(context, raw_inputs[input_name], our_input, interface_name, operation_name, presentation, type_name) else: raw_inputs[input_name] = deepcopy_with_locators(our_input._raw)
def evaluate(self, context): inputs = context.deployment_plan['inputs'] if self.input_property_name not in inputs: raise InvalidValueError( 'input does not exist for function "get_input": %s' % safe_repr(self.input_property_name), locator=self.locator) the_input = inputs[self.input_property_name] value = the_input.get('value', the_input.get('default')) return deepcopy_with_locators(value)
def merge_interface(context, presentation, interface_assignment, our_interface_assignment, interface_definition, interface_name): # Assign/merge interface inputs assign_raw_inputs(context, interface_assignment._raw, our_interface_assignment.inputs, interface_definition._get_inputs(context), our_interface_assignment, interface_name, None, presentation) # Assign operation implementations and inputs our_operation_templates = our_interface_assignment.operations # OperationAssignment operation_definitions = interface_definition._get_operations( context ) if hasattr( interface_definition, '_get_operations' ) else interface_definition.operations # OperationDefinition or OperationAssignment if our_operation_templates: for operation_name, our_operation_template in our_operation_templates.iteritems( ): # OperationAssignment operation_definition = operation_definitions.get( operation_name) # OperationDefinition our_input_assignments = our_operation_template.inputs our_implementation = our_operation_template.implementation if operation_definition is None: context.validation.report( 'interface definition "%s" refers to an unknown operation "%s" in "%s"' % (interface_name, operation_name, presentation._fullname), locator=our_operation_template._locator, level=Issue.BETWEEN_TYPES) if (our_input_assignments is not None) or (our_implementation is not None): # Make sure we have the dict if (operation_name not in interface_assignment._raw) or ( interface_assignment._raw[operation_name] is None): interface_assignment._raw[operation_name] = OrderedDict() if our_implementation is not None: interface_assignment._raw[operation_name][ 'implementation'] = deepcopy_with_locators( our_implementation._raw) # Assign/merge operation inputs input_definitions = operation_definition.inputs if operation_definition is not None else None assign_raw_inputs(context, interface_assignment._raw[operation_name], our_input_assignments, input_definitions, our_operation_template, interface_name, operation_name, presentation)
def prepare_deployment_plan(plan, inputs=None, **kwargs): """ Prepare a plan for deployment """ #print '!!! prepare_deployment_plan', inputs, kwargs plan = deepcopy_with_locators(plan) add_deployment_plan_attributes(plan) if inputs: unknown_inputs = [] for input_name, the_input in inputs.iteritems(): if input_name in plan['inputs']: plan['inputs'][input_name]['value'] = deepcopy_with_locators( the_input) else: unknown_inputs.append(input_name) if unknown_inputs: raise UnknownInputError('unknown inputs specified: %s' % string_list_as_string(unknown_inputs)) missing_inputs = [] for input_name, the_input in plan['inputs'].iteritems(): if the_input.get('value') is None: the_input['value'] = the_input.get('default') if the_input.get('value') is None: missing_inputs.append(input_name) if missing_inputs: raise MissingRequiredInputError('inputs not specified: %s' % string_list_as_string(missing_inputs)) # TODO: now that we have inputs, we should scan properties and inputs # and evaluate functions context = PostProcessingContext(plan, None, None, None, None) context.process(plan) return plan
def merge_raw_operation_definitions(context, raw_operations, our_operations, interface_name, presentation, type_name): for operation_name, our_operation in our_operations.iteritems(): if operation_name in raw_operations: raw_operation = raw_operations[operation_name] if isinstance(raw_operation, basestring): # Convert short form to long form raw_operations[operation_name] = OrderedDict( (('implementation', raw_operation), )) raw_operation = raw_operations[operation_name] merge_raw_operation_definition(context, raw_operation, our_operation, interface_name, presentation, type_name) else: raw_operations[operation_name] = deepcopy_with_locators( our_operation._raw)
def merge_raw_property_definitions(context, presentation, raw_property_definitions, our_property_definitions, field_name): if not our_property_definitions: return for property_name, our_property_definition in our_property_definitions.iteritems( ): if property_name in raw_property_definitions: raw_property_definition = raw_property_definitions[property_name] merge_raw_property_definition(context, presentation, raw_property_definition, our_property_definition, field_name, property_name) else: raw_property_definitions[property_name] = \ deepcopy_with_locators(our_property_definition._raw)
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_property_definitions(context, presentation, raw_properties, type_property_defintions, 'properties') # Merge our properties merge_raw_property_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 coerce_value(context, presentation, the_type, value, aspect=None): """ Returns the value after it's coerced to its type, reporting validation errors if it cannot be coerced. Supports both complex data types and primitives. Data types can use the :code:`coerce_value` extension to hook their own specialized function. If the extension is present, we will delegate to that hook. """ is_function, fn = get_function(context, presentation, value) if is_function: return fn if the_type is None: if isinstance(value, dict) or isinstance(value, list): value = deepcopy_with_locators(value) find_functions(context, presentation, value) return value # Delegate to 'coerce_value' extension if hasattr(the_type, '_get_extension'): coerce_value_fn_name = the_type._get_extension('coerce_value') if coerce_value_fn_name is not None: if value is None: return None coerce_value_fn = import_fullname(coerce_value_fn_name) return coerce_value_fn(context, presentation, the_type, value, aspect) if hasattr(the_type, '_coerce_value'): # Delegate to '_coerce_value' (likely a DataType instance) return the_type._coerce_value(context, presentation, value, aspect) # Coerce to primitive type return coerce_to_primitive(context, presentation, the_type, value, aspect)
def convert_requirement_from_definition_to_assignment( context, presentation, requirement_definition, our_requirement_assignment, container): from ..assignments import RequirementAssignment raw = OrderedDict() raw['capability'] = deepcopy_with_locators( requirement_definition.capability) # capability type name 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 our_relationship = our_requirement_assignment.relationship if our_requirement_assignment is not None else None # RelationshipAssignment 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) # If not exists, try at the node type relationship_definition = None if relationship_type is None: relationship_definition = requirement_definition.relationship # RelationshipDefinition if relationship_definition is not None: relationship_type = relationship_definition._get_type(context) 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, presentation, relationship_property_definitions) # These are our interface definitions relationship_interface_definitions = OrderedDict( relationship_type._get_interfaces(context)) # InterfaceDefinition if relationship_definition: # Merge extra interface definitions relationship_interface_definitions = relationship_definition.interfaces # InterfaceDefinition 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 else: # Convert interface definitions to templates convert_requirement_interface_definitions_from_type_to_raw_template( context, raw['relationship'], relationship_interface_definitions) return RequirementAssignment( name=requirement_definition._name, raw=raw, container=container ), relationship_property_definitions, relationship_interface_definitions