From 1e7665f2bbd7a7d14639bd1be96e5943c0cc2894 Mon Sep 17 00:00:00 2001 From: Stefan Reimer Date: Fri, 1 Jul 2022 14:56:53 +0200 Subject: [PATCH] feat: improve docs task to render pulumi docs with live outputs --- cloudbender/jinja.py | 6 ++++++ cloudbender/pulumi.py | 14 ++++++++++++++ cloudbender/stack.py | 25 +++++++++++++++++-------- 3 files changed, 37 insertions(+), 8 deletions(-) diff --git a/cloudbender/jinja.py b/cloudbender/jinja.py index 097e36a..b0c0b5a 100644 --- a/cloudbender/jinja.py +++ b/cloudbender/jinja.py @@ -200,6 +200,12 @@ def JinjaEnv(template_locations=[]): return jenv +def render_docs(docs, outputs): + jenv = jinja2.Environment(undefined=jinja2.ChainableUndefined) + + return jenv.from_string(docs).render(outputs) + + def read_config_file(path, variables={}): """reads yaml config file, passes it through jinja and returns data structre diff --git a/cloudbender/pulumi.py b/cloudbender/pulumi.py index c05b2c4..bf9b86d 100644 --- a/cloudbender/pulumi.py +++ b/cloudbender/pulumi.py @@ -31,6 +31,20 @@ def get_pulumi_version(): return None +def resolve_outputs(outputs): + my_outputs = {} + + for k,v in outputs.items(): + if type(v) == pulumi.automation._output.OutputValue: + if v.secret: + my_outputs[k] = "***" + else: + my_outputs[k] = v.value + else: + my_outputs[k] = v + + return my_outputs + def pulumi_ws(func): @wraps(func) def decorated(self, *args, **kwargs): diff --git a/cloudbender/stack.py b/cloudbender/stack.py index 8a57383..4793c22 100644 --- a/cloudbender/stack.py +++ b/cloudbender/stack.py @@ -17,11 +17,11 @@ from botocore.exceptions import ClientError from .utils import dict_merge, search_refs, ensure_dir, get_s3_url from .connection import BotoConnection -from .jinja import JinjaEnv, read_config_file +from .jinja import JinjaEnv, read_config_file, render_docs from . import __version__ from .exceptions import ParameterNotFound, ParameterIllegalValue, ChecksumError from .hooks import exec_hooks -from .pulumi import pulumi_ws +from .pulumi import pulumi_ws, resolve_outputs import cfnlint.core import cfnlint.template @@ -581,22 +581,31 @@ class Stack(object): """ if self.mode == "pulumi": + try: + pulumi_stack = self._get_pulumi_stack() + outputs=pulumi_stack.outputs() + except pulumi.automation.errors.StackNotFoundError: + outputs = {} + pass + if vars(self._pulumi_code)["__doc__"]: - print(vars(self._pulumi_code)["__doc__"]) + output= render_docs(vars(self._pulumi_code)["__doc__"], resolve_outputs(outputs)) else: - print("No template documentation found.") + output = "No template documentation found." # collect all __doc__ from available _execute_ functions - _help = "" + headerAdded = False for k in vars(self._pulumi_code).keys(): if k.startswith("_execute_"): + if not headerAdded: + output = output + "\n# Available `execute` functions: \n" + headerAdded = True docstring = vars(self._pulumi_code)[k].__doc__ - _help = _help + "## {}\n{}\n".format( + output = output + "\n* {}\n{}".format( k.lstrip("_execute_"), docstring ) - if _help: - print(f"# Available `execute` functions: \n\n{_help}") + print(output) else: try: