Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
#!/usr/bin/env python
import click
from glob import glob
import graphviz as gv
import os
import sys
import yaml
''' Generate a directed graph of ansible role dependencies.
Usage: ./ansible-role-graph --output-format pdf --engine dot --roles-path ~/openshift-ansible/roles/
'''
@click.command()
@click.option('--output-format', 'output_format',
default='pdf',
help=('The output format to use. Valid output formats include '
'"pdf" (default), "png" and "svg".'))
@click.option('--engine',
default='dot',
help=('The graphviz engine type. Valid engines include "dot" '
'(default), "neato", "twopi", "circo", "fdp", "sfdp", '
'"patchwork" and "osage".'))
@click.option('--open/--dont-open', 'view',
default=True,
help='Open the generated graph. Graph will be opened by default.')
@click.option('--roles-path', 'roles_path',
default='./roles/',
help='Path to ansible roles directory. Defaults to "./roles/"')
def generate_role_graph(output_format, engine, view, roles_path):
dot = gv.Digraph(engine=engine, format=output_format)
meta_files = glob(os.path.abspath(roles_path) + '/*/meta/main.yml')
if len(meta_files) == 0:
print("Unable to locate roles within {0}".format(os.path.abspath(roles_path)))
sys.exit(1)
for path in meta_files:
dependent_role = path.split('roles')[1].split('/')[1]
dot.node(dependent_role)
with open(path, 'r') as f:
meta_config = yaml.load(f.read())
if 'dependencies' in meta_config.keys():
for dependency in meta_config['dependencies']:
depended_role = dependency['role']
dot.node(depended_role)
dot.edge(dependent_role, depended_role)
if not view:
print "Generated graph. Open with: xdg-open ansible-role-graph.{0}".format(output_format)
dot.render('ansible-role-graph', view=view)
if __name__ == '__main__':
generate_role_graph()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.