def getfact(context: Context, resource: "any", fact_name: "string", default_value: "any"=None) -> "any": """ Retrieve a fact of the given resource """ resource_id = resources.to_id(resource) if resource_id is None: raise Exception("Facts can only be retreived from resources.") # Special case for unit testing and mocking if hasattr(context.compiler, "refs") and "facts" in context.compiler.refs: if resource_id in context.compiler.refs["facts"] and fact_name in context.compiler.refs["facts"][resource_id]: return context.compiler.refs["facts"][resource_id][fact_name] fact_value = Unknown(source=resource) unknown_parameters.append({"resource": resource_id, "parameter": fact_name, "source": "fact"}) if default_value is not None: return default_value return fact_value # End special case fact_value = None try: client = context.get_client() env = Config.get("config", "environment", None) if env is None: raise Exception("The environment of this model should be configured in config>environment") def call(): return client.get_param(tid=env, id=fact_name, resource_id=resource_id) result = context.run_sync(call) if result.code == 200: fact_value = result.result["parameter"]["value"] else: logging.getLogger(__name__).info("Param %s of resource %s is unknown", fact_name, resource_id) fact_value = Unknown(source=resource) unknown_parameters.append({"resource": resource_id, "parameter": fact_name, "source": "fact"}) except ConnectionRefusedError: logging.getLogger(__name__).warning("Param %s of resource %s is unknown because connection to server was refused", fact_name, resource_id) fact_value = Unknown(source=resource) unknown_parameters.append({"resource": resource_id, "parameter": fact_name, "source": "fact"}) if isinstance(fact_value, Unknown) and default_value is not None: return default_value return fact_value
def resume(self, requires, resolver, queue, result): """ Evaluate this statement. """ # get the object to call the function on function = self.function arguments = [a.execute(requires, resolver, queue) for a in self.arguments] no_unknows = function.check_args(arguments) if not no_unknows: result.set_value(Unknown(self), self.location) return if function._context is not -1: arguments.insert(function._context, plugins.Context(resolver, queue, self, result)) if function.opts["emits_statements"]: function(*arguments) else: try: value = function(*arguments) result.set_value(value, self.location) except UnknownException as e: result.set_value(e.unknown, self.location) except UnsetException as e: raise e except Exception as e: raise WrappingRuntimeException(self, "Exception in plugin %s" % self.name, e)
def resume(self, requires: Dict[object, ResultVariable], resolver: Resolver, queue: QueueScheduler) -> None: if self.condition_value is None: condition_value: object = self.expression.condition.execute( {k: v.get_value() for k, v in requires.items()}, resolver, queue) if isinstance(condition_value, Unknown): self.result.set_value(Unknown(self), self.location) return if not isinstance(condition_value, bool): raise RuntimeException( self, "Invalid value `%s`: the condition for a conditional expression must be a boolean expression" ) self.condition_value = condition_value # Schedule execution of appropriate subexpression subexpression: ExpressionStatement = ( self.expression.if_expression if self.condition_value else self.expression.else_expression) RawUnit( queue, resolver, subexpression.requires_emit(resolver, queue), self, ) else: value: object = ( self.expression.if_expression if self.condition_value else self.expression.else_expression).execute( {k: v.get_value() for k, v in requires.items()}, resolver, queue) self.result.set_value(value, self.location)
def get_env_int(name: "string", default_value: "number" = None) -> "number": env = os.environ if name in env: return int(env[name]) elif default_value is not None: return default_value else: return Unknown(source=name)
def get_env(name: "string", default_value: "string" = None) -> "string": env = os.environ if name in env: return env[name] elif default_value is not None: return default_value else: return Unknown(source=name)
def environment_server(ctx: Context) -> "string": """ Return the address of the management server """ client = ctx.get_client() server_url = client._transport_instance._get_client_config() match = re.search("^http[s]?://([^:]+):", server_url) if match is not None: return match.group(1) return Unknown(source=server_url)
def execute_direct(self, requires: Dict[object, object]) -> object: condition_value: object = self.condition.execute_direct(requires) if isinstance(condition_value, Unknown): return Unknown(self) if not isinstance(condition_value, bool): raise RuntimeException( self, "Invalid value `%s`: the condition for a conditional expression must be a boolean expression" ) return (self.if_expression if condition_value else self.else_expression).execute_direct(requires)
def execute(self, requires: typing.Dict[object, object], resolver: Resolver, queue: QueueScheduler) -> object: result_string = self._format_string for _var, str_id in self._variables: value = _var.execute(requires, resolver, queue) if isinstance(value, Unknown): return Unknown(self) if isinstance(value, float) and (value - int(value)) == 0: value = int(value) result_string = result_string.replace(str_id, str(value)) return result_string
def environment_name(ctx: Context) -> "string": """ Return the name of the environment (as defined on the server) """ env = environment() def call(): return ctx.get_client().get_environment(id=env) result = ctx.run_sync(call) if result.code != 200: return Unknown(source=env) return result.result["environment"]["name"]
def call_in_context( self, args: List[object], kwargs: Dict[str, object], resolver: Resolver, queue: QueueScheduler, result: ResultVariable ) -> None: no_unknows = self.plugin.check_args(args, kwargs) if not no_unknows and not self.plugin.opts["allow_unknown"]: result.set_value(Unknown(self), self.ast_node.location) return if self.plugin._context != -1: args.insert(self.plugin._context, plugins.Context(resolver, queue, self.ast_node, self.plugin, result)) if self.plugin.opts["emits_statements"]: self.plugin(*args, **kwargs) else: try: value = self.plugin(*args, **kwargs) result.set_value(value if value is not None else NoneValue(), self.ast_node.location) except UnknownException as e: result.set_value(e.unknown, self.ast_node.location) except UnsetException as e: call: str = str(self.plugin) location: str = str(self.ast_node.location) LOGGER.debug( "Unset value in python code in plugin at call: %s (%s) (Will be rescheduled by compiler)", call, location ) # Don't handle it here! # This exception is used by the scheduler to re-queue the unit # If it is handled here, the re-queueing can not be done, # leading to very subtle errors such as #2787 raise e except RuntimeException as e: raise WrappingRuntimeException(self.ast_node, "Exception in plugin %s" % self.ast_node.name, e) except plugins.PluginException as e: raise ExplicitPluginException(self.ast_node, "PluginException in plugin %s" % self.ast_node.name, e) except Exception as e: raise ExternalException(self.ast_node, "Exception in plugin %s" % self.ast_node.name, e)
def unknown() -> "any": return Unknown(None)