Skip to content

Instantly share code, notes, and snippets.

@ScoreUnder
Created November 22, 2017 13:29
Show Gist options
  • Save ScoreUnder/6735d45ed85e2e5fb0bf5c9adc18478f to your computer and use it in GitHub Desktop.
Save ScoreUnder/6735d45ed85e2e5fb0bf5c9adc18478f to your computer and use it in GitHub Desktop.
Convert salt lowstate to graphviz format
#!/usr/bin/env python3
import itertools
import yaml
import sys
class MultiDict(dict):
def add(self, key, value):
if key not in self:
self[key] = []
self[key].append(value)
deps = MultiDict()
states = MultiDict()
def find_state(name):
return states.get(name, ["<!!!>" + name])
def foreach_dep(action, dep_list):
for dep in dep_list:
if not isinstance(dep, str):
key, val = next(iter(dep.items()))
dep = "{}.{}".format(key, val)
action(dep)
if len(sys.argv) > 1:
filename = sys.argv[1]
else:
filename = 'lowstate'
lowstate = yaml.load(open(filename))['local']
for state in lowstate:
state_id = '{state}.{__id__}'.format(**state)
states.add(state['__id__'], state_id)
states.add(state_id, state_id)
states.add('sls.' + state['__sls__'], state_id)
for key in 'require watch prereq use onchanges onfail listen'.split():
foreach_dep(lambda n: deps.add(state_id, n), state.get(key, {}))
foreach_dep(lambda n: deps.add(n, state_id), state.get(key + '_in', {}))
print("digraph { node[shape=rectangle]")
for key, vals in deps.items():
key = find_state(key)
vals = itertools.chain(*map(find_state, vals))
for state in set(key):
for val in set(vals):
print('"{}" -> "{}"'.format(state, val))
print("}")
@ScoreUnder
Copy link
Author

ScoreUnder commented Nov 22, 2017

Usage:

  1. On the server to test with, salt-call state.show_lowstate --output=yaml or salt-call state.show_low_sls statename --output=yaml
  2. Copy that output into a file locally
  3. Run this script on the output, piped into dot: ./lowstate_dep_graph.py output.txt | dot -Txlib

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment