Add command line parameters

This commit is contained in:
LeoVerto 2018-08-31 04:50:58 +02:00
parent f715389aa6
commit ab88c610e1
5 changed files with 100 additions and 81 deletions

5
.gitignore vendored
View file

@ -1,4 +1,3 @@
/sandbox *.gv
/*.gv *.pdf
/*.pdf
.idea .idea

View file

@ -10,4 +10,4 @@ graphviz = "*"
[dev-packages] [dev-packages]
[requires] [requires]
python_version = "3.7" python_version = "3"

4
Pipfile.lock generated
View file

@ -1,11 +1,11 @@
{ {
"_meta": { "_meta": {
"hash": { "hash": {
"sha256": "dd7e5eeba8f90bf7a95640eb165b90b96af947ddf7220542916f95709f01f14d" "sha256": "b980cd984b5794dc93711b11dcaadee33a6ee25a811c7aa8c8a6c7db32a78204"
}, },
"pipfile-spec": 6, "pipfile-spec": 6,
"requires": { "requires": {
"python_version": "3.7" "python_version": "3"
}, },
"sources": [ "sources": [
{ {

View file

@ -1,13 +1,23 @@
Docker Network Graph # Docker Network Graph
--------------------
Sample python script to draw graph of Docker networks and containers Sample python script to draw graph of Docker networks and containers
Install/run ## Usage
=========== usage: docker-net-graph.py [-h] [-v] [-o OUT]
#> git clone https://github.com/LeoVerto/docker-network-graph-poc.git Generate docker network graph.
#> cd docker-network-graph-poc
#> pipenv install optional arguments:
#> pipenv run python docker-net-graph.py -h, --help show this help message and exit
-v, --verbose Verbose output
-o OUT, --out OUT Write output to file
In most cases what you want to run are the following couple commands:
git clone https://github.com/LeoVerto/docker-network-graph-poc.git
cd docker-network-graph-poc
pipenv install
pipenv run python docker-net-graph.py -o output.gv
This will end up generating a .pdf file containing the graph.

46
docker-net-graph.py Normal file → Executable file
View file

@ -1,21 +1,22 @@
from docker import Client #!/usr/bin/python3
import os import os
import pprint
import json import json
import argparse
from docker import Client
from graphviz import Graph from graphviz import Graph
dot = Graph(comment='Docker Network Graph',
graph_attr=dict( rankdir="TB", packmode='graph', pack='true') def generate_graph(verbose: bool, file: str):
dot = Graph(comment='Docker Network Graph',
graph_attr=dict(rankdir="TB", packmode='graph', pack='true')
) )
docker_client = Client(os.environ.get("DOCKER_HOST", "unix:///var/run/docker.sock")) docker_client = Client(os.environ.get("DOCKER_HOST", "unix:///var/run/docker.sock"))
def dump_json(obj): def dump_json(obj):
print(json.dumps(obj, indent=4)) print(json.dumps(obj, indent=4))
for c in sorted(docker_client.containers()): for c in docker_client.containers():
name = c['Names'][0] name = c['Names'][0]
container_id = c['Id'] container_id = c['Id']
@ -28,18 +29,16 @@ for c in sorted(docker_client.containers()):
iface_labels.append(label_iface) iface_labels.append(label_iface)
if verbose:
print('|'.join(iface_labels)) print('|'.join(iface_labels))
dot.node(node_id, dot.node(node_id,
shape='record', shape='record',
label="{ %s | { %s } }" % (name, '|'.join(iface_labels)), label="{ %s | { %s } }" % (name, '|'.join(iface_labels)),
fillcolor='#ff9999', fillcolor='#ff9999',
style='filled') style='filled')
for net in docker_client.networks():
for net in docker_client.networks():
net_name = net['Name'] net_name = net['Name']
try: try:
@ -52,11 +51,12 @@ for net in docker_client.networks():
except IndexError: except IndexError:
subnet = None subnet = None
print("Network: %s %s gw:%s" % ( net_name, subnet,gateway)) if verbose:
print("Network: %s %s gw:%s" % (net_name, subnet, gateway))
net_node_id = "net_%s" % (net_name,) net_node_id = "net_%s" % (net_name,)
net_label_html = '<br/>'.join([s for s in ['<font color="#777777"><i>network</i></font>', net_name, subnet, gateway] if s != None]) net_label_html = '<br/>'.join([s for s in ['<font color="#777777"><i>network</i></font>', net_name, subnet, gateway] if s is not None])
dot.node(net_node_id, dot.node(net_node_id,
shape='record', shape='record',
@ -64,9 +64,10 @@ for net in docker_client.networks():
fillcolor='#99ff99', fillcolor='#99ff99',
style='filled') style='filled')
for container_id, container in sorted(net['Containers'].items()): for container_id, container in sorted(net['Containers'].items()):
if verbose:
dump_json(container) dump_json(container)
if verbose:
print(" * ", container['Name'], container['IPv4Address'], container['IPv6Address']) print(" * ", container['Name'], container['IPv4Address'], container['IPv6Address'])
container_node_id = 'container_%s' % container_id container_node_id = 'container_%s' % container_id
@ -75,6 +76,15 @@ for net in docker_client.networks():
dot.edge(container_iface_ref, net_node_id+":gw_iface") dot.edge(container_iface_ref, net_node_id+":gw_iface")
print(dot.source) print(dot.source)
dot.render('dng.gv') if file:
dot.render(file)
if __name__ == "__main__":
parser = argparse.ArgumentParser(description="Generate docker network graph.")
parser.add_argument("-v", "--verbose", help="Verbose output", action="store_true")
parser.add_argument("-o", "--out", help="Write output to file", type=str)
args = parser.parse_args()
generate_graph(args.verbose, args.out)