def evaluate_functions(payload, context, get_node_instances_method, get_node_instance_method, get_node_method, get_secret_method): """Evaluate functions in payload. :param payload: The payload to evaluate. :param context: Context used during evaluation. :param get_node_instances_method: A method for getting node instances. :param get_node_instance_method: A method for getting a node instance. :param get_node_method: A method for getting a node. :param get_secret_method: A method for getting a secret. :return: payload. """ handler = runtime_evaluation_handler(get_node_instances_method, get_node_instance_method, get_node_method, get_secret_method) scan.scan_properties(payload, handler, scope=None, context=context, path='payload', replace=True) return payload
def evaluate_node_instance_functions(instance, storage): handler = runtime_evaluation_handler(storage) scan.scan_properties(instance.get('runtime_properties', {}), handler, scope=scan.NODE_TEMPLATE_SCOPE, context=instance, path='{0}.runtime_properties'.format(instance['id']), replace=True) return instance
def handler(v, scope, context, path): func = parse(v, scope=scope, context=context, path=path) if isinstance(func, Function): func.validate(plan) scan.scan_properties(v, handler, scope=scope, context=context, path=path, replace=False) return v
def evaluate_outputs(outputs_def, get_node_instances_method): """Evaluates an outputs definition containing intrinsic functions. :param outputs_def: Outputs definition. :param get_node_instances_method: A method for getting node instances. :return: Outputs dict. """ ctx = {} outputs = {k: v['value'] for k, v in outputs_def.iteritems()} def handler(dict_, k, v, scope, context, path): func = parse(v, scope=scope, context=context, path=path) if isinstance(func, GetAttribute): attributes = [] if 'node_instances' not in ctx: ctx['node_instances'] = get_node_instances_method() for instance in ctx['node_instances']: if instance.node_id == func.node_name: attributes.append( instance.runtime_properties.get( func.attribute_name) if instance.runtime_properties else None) if len(attributes) == 1: dict_[k] = attributes[0] elif len(attributes) == 0: raise exceptions.FunctionEvaluationError( GET_ATTRIBUTE_FUNCTION, 'Node specified in function does not exist: {0}.'.format( func.node_name) ) else: raise exceptions.FunctionEvaluationError( GET_ATTRIBUTE_FUNCTION, 'Multi instances of node "{0}" are not supported by ' 'function.'.format(func.node_name)) scan.scan_properties(outputs, handler, scope=scan.OUTPUTS_SCOPE, context=outputs, path='outputs') return outputs
def validate_no_circular_get_property(*args): r = args[0] if isinstance(r, GetProperty): func_id = '{0}.{1}'.format( r.get_node_template(plan)['name'], constants.FUNCTION_NAME_PATH_SEPARATOR.join( r.property_path)) if func_id in visited_functions: visited_functions.append(func_id) error_output = [ x.replace(constants.FUNCTION_NAME_PATH_SEPARATOR, ',') for x in visited_functions ] raise RuntimeError( 'Circular get_property function call detected: ' '{0}'.format(' -> '.join(error_output))) visited_functions.append(func_id) r = r.evaluate(plan) validate_no_circular_get_property(r) else: scan.scan_properties(r, validate_no_circular_get_property)
def evaluate_functions(payload, context, storage): """Evaluate functions in payload. :param payload: The payload to evaluate. :param context: Context used during evaluation. :param storage: Storage backend for runtime function evaluation :return: payload. """ scope = None if 'source' in context and 'target' in context: scope = scan.NODE_TEMPLATE_RELATIONSHIP_SCOPE elif 'self' in context: scope = scan.NODE_TEMPLATE_SCOPE handler = runtime_evaluation_handler(storage) scan.scan_properties(payload, handler, scope=scope, context=context, path='payload', replace=True) return payload
def evaluate_functions(payload, context, get_node_instances_method, get_node_instance_method, get_node_method): """Evaluate functions in payload. :param payload: The payload to evaluate. :param context: Context used during evaluation. :param get_node_instances_method: A method for getting node instances. :param get_node_instance_method: A method for getting a node instance. :param get_node_method: A method for getting a node. :return: payload. """ handler = runtime_evaluation_handler(get_node_instances_method, get_node_instance_method, get_node_method) scan.scan_properties(payload, handler, scope=None, context=context, path='payload', replace=True) return payload
def evaluate_outputs(outputs_def, get_node_instances_method): """Evaluates an outputs definition containing intrinsic functions. :param outputs_def: Outputs definition. :param get_node_instances_method: A method for getting node instances. :return: Outputs dict. """ ctx = {} outputs = {k: v['value'] for k, v in outputs_def.iteritems()} def handler(dict_, k, v, scope, context, path): func = parse(v, scope=scope, context=context, path=path) if isinstance(func, GetAttribute): attributes = [] if 'node_instances' not in ctx: ctx['node_instances'] = get_node_instances_method() for instance in ctx['node_instances']: if instance.node_id == func.node_name: attributes.append( instance.runtime_properties.get(func.attribute_name) if instance.runtime_properties else None) if len(attributes) == 1: dict_[k] = attributes[0] elif len(attributes) == 0: raise exceptions.FunctionEvaluationError( GET_ATTRIBUTE_FUNCTION, 'Node specified in function does not exist: {0}.'.format( func.node_name)) else: raise exceptions.FunctionEvaluationError( GET_ATTRIBUTE_FUNCTION, 'Multi instances of node "{0}" are not supported by ' 'function.'.format(func.node_name)) scan.scan_properties(outputs, handler, scope=scan.OUTPUTS_SCOPE, context=outputs, path='outputs') return outputs
def handler(v, scope, context, path): evaluated_value = v scanned = False while True: func = parse(evaluated_value, scope=scope, context=context, path=path) if not isinstance(func, Function): break previous_evaluated_value = evaluated_value evaluated_value = getattr(func, evaluator)(**evaluator_kwargs) if scanned and previous_evaluated_value == evaluated_value: break scan.scan_properties(evaluated_value, handler, scope=scope, context=context, path=path, replace=True) scanned = True return evaluated_value
def handler(v, scope, context, path): evaluated_value = v scanned = False while True: scan.scan_properties(evaluated_value, handler, scope=scope, context=context, path=path, replace=True) func = parse(evaluated_value, scope=scope, context=context, path=path) if not isinstance(func, Function): break previous_evaluated_value = evaluated_value evaluated_value = getattr(func, evaluator)(**evaluator_kwargs) if scanned and previous_evaluated_value == evaluated_value: break scanned = True return evaluated_value
def __call__(self, v, scope, context, path): evaluated_value = v scanned = False while True: scan.scan_properties(evaluated_value, self, scope=scope, context=context, path=path, replace=True) func = parse(evaluated_value, scope=scope, context=context, path=path) if not isinstance(func, Function): break previous_evaluated_value = evaluated_value evaluated_value = self.evaluate_function(func) if scanned and previous_evaluated_value == evaluated_value: break scanned = True return evaluated_value