Erstelle Repo
This commit is contained in:
144
docker_info_export.py
Executable file
144
docker_info_export.py
Executable file
@@ -0,0 +1,144 @@
|
||||
import docker
|
||||
import pandas as pd
|
||||
import re
|
||||
|
||||
def sanitize_id(text):
|
||||
# Erlaubt nur Buchstaben, Zahlen und Unterstriche
|
||||
return re.sub(r'\W|^(?=\d)', '_', text)
|
||||
|
||||
def get_container_info():
|
||||
client = docker.from_env()
|
||||
containers = client.containers.list(all=True)
|
||||
|
||||
data = []
|
||||
|
||||
for container in containers:
|
||||
container_info = client.api.inspect_container(container.id)
|
||||
|
||||
name = container.name
|
||||
labels = container_info.get('Config', {}).get('Labels', {})
|
||||
watchtower_enabled = labels.get('com.centurylinklabs.watchtower.enable',
|
||||
labels.get('watchtower.enable', 'not set'))
|
||||
|
||||
networks = container_info.get('NetworkSettings', {}).get('Networks', {})
|
||||
|
||||
for net_name, net_data in networks.items():
|
||||
ip_address = net_data.get('IPAddress', 'N/A')
|
||||
gateway = net_data.get('Gateway', 'N/A')
|
||||
|
||||
data.append({
|
||||
'Container Name': name,
|
||||
'Watchtower Enabled': watchtower_enabled,
|
||||
'Network': net_name,
|
||||
'IP Address': ip_address,
|
||||
'Gateway': gateway
|
||||
})
|
||||
|
||||
return data
|
||||
|
||||
def save_to_csv(data, filename='docker_container_info.csv'):
|
||||
df = pd.DataFrame(data)
|
||||
df.to_csv(filename, index=False)
|
||||
print(f"[+] Daten erfolgreich in {filename} gespeichert.")
|
||||
|
||||
def save_to_graphml(data, filename='docker_container_info.graphml'):
|
||||
from xml.etree.ElementTree import Element, SubElement, ElementTree, register_namespace
|
||||
|
||||
# Nur yEd Namespace registrieren!
|
||||
register_namespace('y', "http://www.yworks.com/xml/graphml")
|
||||
|
||||
graphml = Element('graphml', xmlns="http://graphml.graphdrawing.org/xmlns")
|
||||
|
||||
# yEd-Label-Schlüssel
|
||||
key_label = SubElement(graphml, 'key', id="d0", **{
|
||||
"for": "node",
|
||||
"yfiles.type": "nodegraphics"
|
||||
})
|
||||
key_watchtower = SubElement(graphml, 'key', id="d1", **{
|
||||
"for": "node",
|
||||
"attr.name": "Watchtower Enabled",
|
||||
"attr.type": "string"
|
||||
})
|
||||
|
||||
graph = SubElement(graphml, 'graph', id="G", edgedefault="undirected")
|
||||
|
||||
container_labels = {}
|
||||
containers = set()
|
||||
networks = set()
|
||||
for entry in data:
|
||||
cname = entry['Container Name']
|
||||
containers.add(cname)
|
||||
networks.add(entry['Network'])
|
||||
if cname not in container_labels:
|
||||
container_labels[cname] = {}
|
||||
container_labels[cname]['Watchtower Enabled'] = entry['Watchtower Enabled']
|
||||
|
||||
# Star Schema: Netzwerke in der Mitte, Container im Kreis
|
||||
import math
|
||||
|
||||
# Positioniere Netzwerk-Knoten im Zentrum
|
||||
center_x = 500
|
||||
center_y = 400
|
||||
net_radius = 0 # Alle Netzwerke exakt im Zentrum
|
||||
net_positions = {}
|
||||
for idx, n in enumerate(networks):
|
||||
node_id = f"network_{sanitize_id(n)}"
|
||||
node = SubElement(graph, 'node', id=node_id)
|
||||
net_infos = [entry for entry in data if entry['Network'] == n]
|
||||
net_texts = [f"{entry['Container Name']}: IP: {entry['IP Address']}, GW: {entry['Gateway']}" for entry in net_infos]
|
||||
label_text = f"{n}\n" + "\n".join(net_texts)
|
||||
data_elem = SubElement(node, 'data', key="d0")
|
||||
y_shape_node = SubElement(data_elem, '{http://www.yworks.com/xml/graphml}ShapeNode')
|
||||
# Alle Netzwerke im Zentrum
|
||||
geometry = SubElement(y_shape_node, '{http://www.yworks.com/xml/graphml}Geometry',
|
||||
x=str(center_x), y=str(center_y), width="200", height="60")
|
||||
y_node_label = SubElement(y_shape_node, '{http://www.yworks.com/xml/graphml}NodeLabel')
|
||||
y_node_label.text = label_text
|
||||
net_positions[n] = (center_x, center_y)
|
||||
|
||||
# Container-Knoten im Kreis um das Zentrum
|
||||
container_count = len(containers)
|
||||
radius = 300
|
||||
angle_step = 2 * math.pi / max(container_count, 1)
|
||||
container_positions = {}
|
||||
for idx, c in enumerate(containers):
|
||||
node_id = f"container_{sanitize_id(c)}"
|
||||
ip_infos = [entry for entry in data if entry['Container Name'] == c]
|
||||
ip_texts = [f"IP: {info['IP Address']}, GW: {info['Gateway']}, Net: {info['Network']}" for info in ip_infos]
|
||||
# Ermittle Watchtower-Status aus com.centurylinklabs.watchtower.enable
|
||||
watchtower_status = "aktiviert" if any(
|
||||
info.get('Watchtower Enabled', '').lower() in ['true', '1', 'yes', 'enabled']
|
||||
for info in ip_infos
|
||||
) else "deaktiviert"
|
||||
label_text = f"{c}\nWatchtower: {watchtower_status}\n" + "\n".join(ip_texts)
|
||||
node = SubElement(graph, 'node', id=node_id)
|
||||
data_elem = SubElement(node, 'data', key="d0")
|
||||
y_shape_node = SubElement(data_elem, '{http://www.yworks.com/xml/graphml}ShapeNode')
|
||||
# Kreisförmige Position
|
||||
angle = idx * angle_step
|
||||
x = center_x + radius * math.cos(angle)
|
||||
y = center_y + radius * math.sin(angle)
|
||||
geometry = SubElement(y_shape_node, '{http://www.yworks.com/xml/graphml}Geometry',
|
||||
x=str(x), y=str(y), width="200", height="60")
|
||||
y_node_label = SubElement(y_shape_node, '{http://www.yworks.com/xml/graphml}NodeLabel')
|
||||
y_node_label.text = label_text
|
||||
watchtower_elem = SubElement(node, 'data', key="d1")
|
||||
watchtower_elem.text = container_labels[c]['Watchtower Enabled']
|
||||
container_positions[c] = (x, y)
|
||||
|
||||
edge_id = 0
|
||||
for entry in data:
|
||||
source = f"container_{sanitize_id(entry['Container Name'])}"
|
||||
target = f"network_{sanitize_id(entry['Network'])}"
|
||||
edge = SubElement(graph, 'edge', id=f"e{edge_id}", source=source, target=target)
|
||||
edge_id += 1
|
||||
|
||||
tree = ElementTree(graphml)
|
||||
tree.write(filename, encoding='utf-8', xml_declaration=True)
|
||||
print(f"[+] GraphML erfolgreich in {filename} gespeichert.")
|
||||
|
||||
if __name__ == '__main__':
|
||||
print("[*] Sammle Container-Informationen...")
|
||||
container_data = get_container_info()
|
||||
save_to_csv(container_data)
|
||||
save_to_graphml(container_data)
|
||||
Reference in New Issue
Block a user