diff --git a/CHANGES.md b/CHANGES.md index 52b7645..4528e2d 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,5 +1,9 @@ # Changelog +## 0.9.4 +- new option to generate Dot Graph files via `--graph` option for the create-docs command +- fix validate command using latest cfn-lint library + ## 0.9.3 - Improved bash minify for user-data - Unused additional parameters are now printed as a warning to catch potential typos early diff --git a/cloudbender/__init__.py b/cloudbender/__init__.py index 9ab824e..405c893 100644 --- a/cloudbender/__init__.py +++ b/cloudbender/__init__.py @@ -2,7 +2,7 @@ import logging __author__ = "Stefan Reimer" __email__ = "stefan@zero-downtimet.net" -__version__ = "0.9.3" +__version__ = "0.9.4" # Set up logging to ``/dev/null`` like a library is supposed to. diff --git a/cloudbender/cli.py b/cloudbender/cli.py index 085af01..d1c0c4b 100644 --- a/cloudbender/cli.py +++ b/cloudbender/cli.py @@ -105,13 +105,14 @@ def outputs(cb, stack_names, multi, include, values): @click.command() @click.argument("stack_names", nargs=-1) @click.option("--multi", is_flag=True, help="Allow more than one stack to match") +@click.option("--graph", is_flag=True, help="Create Dot Graph file") @click.pass_obj -def create_docs(cb, stack_names, multi): +def create_docs(cb, stack_names, multi, graph): """ Parses all documentation fragments out of rendered templates creating docs/*.md file """ stacks = _find_stacks(cb, stack_names, multi) for s in stacks: - s.create_docs() + s.create_docs(graph=graph) @click.command() diff --git a/cloudbender/stack.py b/cloudbender/stack.py index 2845071..2489e0e 100644 --- a/cloudbender/stack.py +++ b/cloudbender/stack.py @@ -19,6 +19,8 @@ from .exceptions import ParameterNotFound, ParameterIllegalValue from .hooks import exec_hooks import cfnlint.core +import cfnlint.template +import cfnlint.graph try: import importlib.resources as pkg_resources @@ -353,7 +355,7 @@ class Stack(object): output_contents.write(template.render(**data)) logger.info('Wrote outputs for %s to %s', self.stackname, output_file) - def create_docs(self, template=False): + def create_docs(self, template=False, graph=False): """ Read rendered template, parse documentation fragments, eg. parameter description and create a mardown doc file for the stack same idea as eg. helm-docs for values.yaml @@ -404,6 +406,24 @@ class Stack(object): doc_contents.write(template.render(**data)) logger.info('Wrote documentation for %s to %s', self.stackname, doc_file) + # Write Graph in Dot format + if graph: + filename = os.path.join(self.ctx['template_path'], self.rel_path, self.stackname + ".yaml") + + lint_args = ['--template', filename] + (args, filenames, formatter) = cfnlint.core.get_args_filenames(lint_args) + (template, rules, matches) = cfnlint.core.get_template_rules(filename, args) + template_obj = cfnlint.template.Template(filename, template, [self.region]) + + g = cfnlint.graph.Graph(template_obj) + path = os.path.join(self.ctx['docs_path'], self.rel_path, self.stackname + ".dot") + try: + g.to_dot(path) + logger.info('DOT representation of the graph written to %s', path) + except ImportError: + logger.error( + 'Could not write the graph in DOT format. Please install either `pygraphviz` or `pydot` modules.') + def resolve_parameters(self): """ Renders parameters for the stack based on the source template and the environment configuration """ diff --git a/requirements.txt b/requirements.txt index dcdd514..59a158f 100644 --- a/requirements.txt +++ b/requirements.txt @@ -3,4 +3,4 @@ Jinja2 oyaml click pyminifier -cfn-lint +cfn-lint>=0.34