black, format
This commit is contained in:
parent
243fcad43f
commit
7b641843b8
1 changed files with 62 additions and 27 deletions
|
@ -10,8 +10,19 @@ from graphviz import Graph
|
||||||
from graphviz.backend import FORMATS
|
from graphviz.backend import FORMATS
|
||||||
|
|
||||||
# colorlover.scales["12"]["qual"]["Paired"] converted to hex strings
|
# colorlover.scales["12"]["qual"]["Paired"] converted to hex strings
|
||||||
COLORS = ["#1f78b4", "#33a02c", "#e31a1c", "#ff7f00", "#6a3d9a", "#b15928", "#a6cee3", "#b2df8a", "#fdbf6f",
|
COLORS = [
|
||||||
"#cab2d6", "#ffff99"]
|
"#1f78b4",
|
||||||
|
"#33a02c",
|
||||||
|
"#e31a1c",
|
||||||
|
"#ff7f00",
|
||||||
|
"#6a3d9a",
|
||||||
|
"#b15928",
|
||||||
|
"#a6cee3",
|
||||||
|
"#b2df8a",
|
||||||
|
"#fdbf6f",
|
||||||
|
"#cab2d6",
|
||||||
|
"#ffff99",
|
||||||
|
]
|
||||||
i = 0
|
i = 0
|
||||||
|
|
||||||
|
|
||||||
|
@ -58,7 +69,9 @@ def get_unique_color() -> str:
|
||||||
return c
|
return c
|
||||||
|
|
||||||
|
|
||||||
def get_networks(client: docker.DockerClient, verbose: bool) -> typing.Dict[str, Network]:
|
def get_networks(
|
||||||
|
client: docker.DockerClient, verbose: bool
|
||||||
|
) -> typing.Dict[str, Network]:
|
||||||
networks: typing.Dict[str, Network] = {}
|
networks: typing.Dict[str, Network] = {}
|
||||||
|
|
||||||
for net in sorted(client.networks.list(), key=lambda k: k.name):
|
for net in sorted(client.networks.list(), key=lambda k: k.name):
|
||||||
|
@ -83,7 +96,9 @@ def get_networks(client: docker.DockerClient, verbose: bool) -> typing.Dict[str,
|
||||||
pass
|
pass
|
||||||
|
|
||||||
if verbose:
|
if verbose:
|
||||||
print(f"Network: {net.name} {'internal' if internal else ''} {'isolated' if isolated else ''} gw:{gateway}")
|
print(
|
||||||
|
f"Network: {net.name} {'internal' if internal else ''} {'isolated' if isolated else ''} gw:{gateway}"
|
||||||
|
)
|
||||||
|
|
||||||
color = get_unique_color()
|
color = get_unique_color()
|
||||||
networks[net.name] = Network(net.name, gateway, internal, isolated, color)
|
networks[net.name] = Network(net.name, gateway, internal, isolated, color)
|
||||||
|
@ -93,7 +108,9 @@ def get_networks(client: docker.DockerClient, verbose: bool) -> typing.Dict[str,
|
||||||
return networks
|
return networks
|
||||||
|
|
||||||
|
|
||||||
def get_containers(client: docker.DockerClient, verbose: bool) -> (typing.List[Container], typing.List[Link]):
|
def get_containers(
|
||||||
|
client: docker.DockerClient, verbose: bool
|
||||||
|
) -> (typing.List[Container], typing.List[Link]):
|
||||||
containers: typing.List[Container] = []
|
containers: typing.List[Container] = []
|
||||||
links: typing.List[Link] = []
|
links: typing.List[Link] = []
|
||||||
|
|
||||||
|
@ -101,7 +118,9 @@ def get_containers(client: docker.DockerClient, verbose: bool) -> (typing.List[C
|
||||||
interfaces: typing.List[Interface] = []
|
interfaces: typing.List[Interface] = []
|
||||||
|
|
||||||
# Iterate over container interfaces
|
# Iterate over container interfaces
|
||||||
for net_name, net_info in container.attrs["NetworkSettings"]["Networks"].items():
|
for net_name, net_info in container.attrs["NetworkSettings"][
|
||||||
|
"Networks"
|
||||||
|
].items():
|
||||||
endpoint_id = net_info["EndpointID"]
|
endpoint_id = net_info["EndpointID"]
|
||||||
|
|
||||||
aliases = []
|
aliases = []
|
||||||
|
@ -111,11 +130,13 @@ def get_containers(client: docker.DockerClient, verbose: bool) -> (typing.List[C
|
||||||
if alias != container.id[:12] and alias != container.name:
|
if alias != container.id[:12] and alias != container.name:
|
||||||
aliases.append(alias)
|
aliases.append(alias)
|
||||||
|
|
||||||
interfaces.append(Interface(endpoint_id, net_info['IPAddress'], aliases))
|
interfaces.append(Interface(endpoint_id, net_info["IPAddress"], aliases))
|
||||||
links.append(Link(container.id, endpoint_id, net_name))
|
links.append(Link(container.id, endpoint_id, net_name))
|
||||||
|
|
||||||
if verbose:
|
if verbose:
|
||||||
print(f"Container: {container.name} {''.join([iface.address for iface in interfaces])}")
|
print(
|
||||||
|
f"Container: {container.name} {''.join([iface.address for iface in interfaces])}"
|
||||||
|
)
|
||||||
|
|
||||||
containers.append(Container(container.id, container.name, interfaces))
|
containers.append(Container(container.id, container.name, interfaces))
|
||||||
|
|
||||||
|
@ -130,11 +151,12 @@ def draw_network(g: Graph, net: Network):
|
||||||
label += " | Containers isolated"
|
label += " | Containers isolated"
|
||||||
label += "}"
|
label += "}"
|
||||||
|
|
||||||
g.node(f"network_{net.name}",
|
g.node(
|
||||||
|
f"network_{net.name}",
|
||||||
shape="record",
|
shape="record",
|
||||||
label=label,
|
label=label,
|
||||||
fillcolor=net.color,
|
fillcolor=net.color,
|
||||||
style="filled"
|
style="filled",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@ -152,18 +174,20 @@ def draw_container(g: Graph, c: Container):
|
||||||
|
|
||||||
label = f"{{ {c.name} | {{ {' | '.join(iface_labels)} }} }}"
|
label = f"{{ {c.name} | {{ {' | '.join(iface_labels)} }} }}"
|
||||||
|
|
||||||
g.node(f"container_{c.container_id}",
|
g.node(
|
||||||
|
f"container_{c.container_id}",
|
||||||
shape="record",
|
shape="record",
|
||||||
label=label,
|
label=label,
|
||||||
fillcolor="#ff9999",
|
fillcolor="#ff9999",
|
||||||
style="filled"
|
style="filled",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def draw_link(g: Graph, networks: typing.Dict[str, Network], link: Link):
|
def draw_link(g: Graph, networks: typing.Dict[str, Network], link: Link):
|
||||||
g.edge(f"container_{link.container_id}:{link.endpoint_id}",
|
g.edge(
|
||||||
|
f"container_{link.container_id}:{link.endpoint_id}",
|
||||||
f"network_{link.network_name}",
|
f"network_{link.network_name}",
|
||||||
color=networks[link.network_name].color
|
color=networks[link.network_name].color,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@ -175,9 +199,18 @@ def generate_graph(verbose: bool, file: str):
|
||||||
|
|
||||||
if file:
|
if file:
|
||||||
base, ext = os.path.splitext(file)
|
base, ext = os.path.splitext(file)
|
||||||
g = Graph(comment="Docker Network Graph", engine="sfdp", format=ext[1:], graph_attr=dict(splines="true"))
|
g = Graph(
|
||||||
|
comment="Docker Network Graph",
|
||||||
|
engine="sfdp",
|
||||||
|
format=ext[1:],
|
||||||
|
graph_attr=dict(splines="true"),
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
g = Graph(comment="Docker Network Graph", engine="sfdp", graph_attr=dict(splines="true"))
|
g = Graph(
|
||||||
|
comment="Docker Network Graph",
|
||||||
|
engine="sfdp",
|
||||||
|
graph_attr=dict(splines="true"),
|
||||||
|
)
|
||||||
|
|
||||||
for _, network in networks.items():
|
for _, network in networks.items():
|
||||||
draw_network(g, network)
|
draw_network(g, network)
|
||||||
|
@ -205,7 +238,9 @@ def graphviz_output_file(filename: str):
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
parser = argparse.ArgumentParser(description="Visualize docker networks.")
|
parser = argparse.ArgumentParser(description="Visualize docker networks.")
|
||||||
parser.add_argument("-v", "--verbose", help="Verbose output", action="store_true")
|
parser.add_argument("-v", "--verbose", help="Verbose output", action="store_true")
|
||||||
parser.add_argument("-o", "--out", help="Write output to file", type=graphviz_output_file)
|
parser.add_argument(
|
||||||
|
"-o", "--out", help="Write output to file", type=graphviz_output_file
|
||||||
|
)
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
generate_graph(args.verbose, args.out)
|
generate_graph(args.verbose, args.out)
|
||||||
|
|
Loading…
Reference in a new issue