This commit is contained in:
romain
2025-07-10 13:33:56 +02:00
parent 6010d0999e
commit ddfbdffa3d
7 changed files with 1033 additions and 14 deletions

File diff suppressed because one or more lines are too long

BIN
data/example.log Normal file

Binary file not shown.

500
data/example.sections.json Normal file

File diff suppressed because one or more lines are too long

10
main.py
View File

@@ -1,8 +1,9 @@
# main.py
import json
from pathlib import Path
from utils.texttools import split_display_sections
from models.hpe5130 import SwitchHPE5130
from output.export_json import export_switch_to_json
def read_file_with_fallback(path: Path) -> str:
@@ -14,7 +15,7 @@ def read_file_with_fallback(path: Path) -> str:
def main():
log_path = Path("data/example-a.log")
log_path = Path("data/example.log")
if not log_path.exists():
print(f"Fichier non trouvé : {log_path}")
return
@@ -27,10 +28,7 @@ def main():
switch.parse_block(section["section"], section["content"])
output_path = Path("data/switch_parsed.json")
with open(output_path, "w", encoding="utf-8") as f:
json.dump(switch.to_dict(), f, indent=2, ensure_ascii=False)
print(f"Switch exporté dans {output_path}")
export_switch_to_json(switch, output_path)
if __name__ == "__main__":

View File

@@ -1,5 +1,12 @@
# models/base_switch.py
from typing import List, Optional
import re
def normalize_port_name(port: str) -> str:
port = port.upper()
port = port.replace("GE", "GIGABITETHERNET")
port = port.replace("XGE", "TEN-GIGABITETHERNET")
port = port.replace("BAGG", "BRIDGE-AGGREGATION")
return port
class PowerSupply:
def __init__(self, id: int, state: str, mode: Optional[str] = None):
@@ -55,14 +62,20 @@ class Port:
self.speed = None
self.vlan = None
self.link_type = None
self.trunk_vlans = []
self.trunk_vlans: List[int] = []
self.bpdu_protection = False
self.portfast = False
self.loopback_detection = None
self.mac_addresses = []
self.mac_addresses: List[str] = []
self.summary = ""
def to_dict(self):
mac_count = len(self.mac_addresses)
mac_info = f", {mac_count} MAC" if mac_count else ""
vlan_info = f"TRUNK ({', '.join(map(str, sorted(self.trunk_vlans)))})" if self.link_type == "trunk" else f"VLAN {self.vlan or '?'}"
status = self.status.upper() if self.status else "INCONNU"
speed = self.speed or "vitesse inconnue"
self.summary = f"Port {self.name} est {status} à {speed}, {vlan_info}{mac_info}"
return {
"object": "port",
"name": self.name,
@@ -70,11 +83,11 @@ class Port:
"speed": self.speed,
"vlan": self.vlan,
"link_type": self.link_type,
"trunk_vlans": self.trunk_vlans if self.link_type == "trunk" else None,
"trunk_vlans": ", ".join(map(str, self.trunk_vlans)) if self.link_type == "trunk" else None,
"bpdu_protection": self.bpdu_protection,
"portfast": self.portfast,
"loopback_detection": self.loopback_detection,
"mac_addresses": [m.to_dict() for m in self.mac_addresses],
"mac_addresses": self.mac_addresses,
"summary": self.summary,
}

View File

@@ -1,5 +1,5 @@
# models/hpe5130.py
from models.base_switch import Switch
from models.base_switch import Switch, normalize_port_name
from models.base_switch import Fan, PowerSupply, MACEntry, Port, VLAN
import re
@@ -78,7 +78,14 @@ class SwitchHPE5130(Switch):
mac = match.group(1).replace("-", ":").lower()
vlan = int(match.group(2))
port = match.group(3)
self.mac_table.append(MACEntry(mac, vlan, port, type_="dynamic"))
mac_entry = MACEntry(mac, vlan, port, type_="dynamic")
self.mac_table.append(mac_entry)
# 🔁 Ajout dans le bon port (nom normalisé)
normalized_port = normalize_port_name(port)
port_obj = next((p for p in self.ports if p.name.upper() == normalized_port), None)
if port_obj:
port_obj.mac_addresses.append(mac)
def _parse_display_interface(self, content: str):
pattern = re.compile(r"^(Bridge-Aggregation\d+|\S*Ethernet\d+/\d+/\d+|InLoopBack\d+|NULL\d+)$", re.MULTILINE)
@@ -220,4 +227,5 @@ class SwitchHPE5130(Switch):
block_lines.append(line)
if current_interface and block_lines:
self._apply_interface_config(current_interface, block_lines)
self._apply_interface_config(current_interface, block_lines)

View File

@@ -0,0 +1,18 @@
import json
import os
from pathlib import Path
def export_switch_to_json(switch_obj, output_path: Path):
def compact(obj):
# sérialise en JSON sans indent, puis ré-indente les lignes manuellement
return json.dumps(
obj,
indent=None,
separators=(",", ": "),
ensure_ascii=False
)
os.makedirs(os.path.dirname(output_path), exist_ok=True)
with open(output_path, "w", encoding="utf-8") as f:
parsed = json.loads(compact(switch_obj.to_dict()))
json.dump(parsed, f, indent=2, separators=(",", ": "), ensure_ascii=False)