diff --git a/Parseurs_config_Firewall/README.md b/Parseurs_config_Firewall/README.md index cc330b4..3b8c50a 100644 --- a/Parseurs_config_Firewall/README.md +++ b/Parseurs_config_Firewall/README.md @@ -5,6 +5,7 @@ Cet outil permet de **parser les configurations de différents types de firewalls** (Palo Alto, Stormshield, Forcepoint) et de **convertir ces informations en un format JSON normalisé basé sur des modèles OpenConfig en YANG**. Il fournit également la possibilité de générer une **matrice de flux au format Excel** pour visualiser les communications et règles de trafic dans l’infrastructure. +Il founit également la possibilité de générer une **matrice de routage au format Excel** pour visualiser les routes statiques dans l’infrastructure. ## Fonctionnalités principales @@ -41,6 +42,10 @@ Il fournit également la possibilité de générer une **matrice de flux au form - les règles de sécurité - les communications entre objets et groupes d’adresses/services. +6. **Génération de matrices de routage** + - Script Python qui utilise le JSON normalisé pour générer automatiquement une matrice Excel détaillant : + - les routes statiques + ## Utilisation ### Pré-requis @@ -50,21 +55,20 @@ python -m venv .venv pip install -r .\src\requierements.txt ``` -- Mettre le/les fichier(s) de configurations dans le dossier `/src/input/` -- Modifier le fichier `site.json` de données dans `/src/data/` #### Commandes principales ```bash -python3 .\src\main.py stormshield .\src\input\backup\ -m -python3 .\src\main.py paloalto .\src\input\nomfichier -m -python3 .\src\main.py forcepoint .\src\input\nomfichier -m +python3 .\src\main.py stormshield .\src\input\backup\ -f -r +python3 .\src\main.py paloalto .\src\input\nomfichier -f -r +python3 .\src\main.py forcepoint .\src\input\nomfichier -f -r ``` #### Options | Option | Description | |--------|-------------| | -o [nom_fichier] | Spécifie le nom du fichier JSON de sortie (optionnel) -| -m | Génère un rapport Excel de type matrice de flux (optionnel) +| -f | Génère un rapport Excel de type matrice de flux (optionnel) +| -r | Génère un rapport Excel de type matrice de routage (optionnel) --- ## Arborescence du projet diff --git a/Parseurs_config_Firewall/src/main.py b/Parseurs_config_Firewall/src/main.py index b98f52f..e9f3532 100644 --- a/Parseurs_config_Firewall/src/main.py +++ b/Parseurs_config_Firewall/src/main.py @@ -4,21 +4,23 @@ import time from scripts.json_PaloAlto import generate_json_paloalto from scripts.json_Stormshield import generate_json_stormshield from scripts.json_Forcepoint import generate_json_forcepoint -from scripts.export_excel import export_to_excel +from scripts.export_matrice_flux import export_to_excel as export_flux_to_excel +from scripts.export_matrice_routage import export_to_excel as export_routing_to_excel def main(): if len(sys.argv) < 3: - print("Usage: python3 src/main.py [paloalto|stormshield|forcepoint] [-o ] [-m]") + print("Usage: python3 src/main.py [paloalto|stormshield|forcepoint] [-o ] [-f] [-r]") print("Options:") print(" Type of firewall to process (paloalto|stormshield|forcepoint)") print(" -o Specify output JSON file name (optional)") - print(" -m Generate Excel report (optional)") + print(" -f Generate matrix flux report (optional)") + print(" -r Generate routing matrix report (optional)") sys.exit(1) firewall_type = sys.argv[1].lower() input_data = sys.argv[2] + input_path = "src/input/" output_path = "src/output/" - if "-o" in sys.argv: o_index = sys.argv.index("-o") if o_index + 1 < len(sys.argv): @@ -41,20 +43,36 @@ def main(): print("Erreur: type de firewall inconnu. Utilisez 'paloalto', 'stormshield' ou 'forcepoint'.") sys.exit(1) - if "-m" in sys.argv: - print(f"\nGénération de l'export Excel...") + if "-f" in sys.argv: + print(f"\nGénération de l'export la matrice flux...") if "-o" in sys.argv: o_index = sys.argv.index("-o") if o_index + 1 < len(sys.argv): - output_file_excel = os.path.join(f"{output_path}matrice_{firewall_type}_{sys.argv[o_index + 1]}.xlsx") + output_file_excel = os.path.join(f"{output_path}matrice_flux_{firewall_type}_{sys.argv[o_index + 1]}.xlsx") else: print("Erreur: nom de fichier de sortie manquant après '-o'.") sys.exit(1) else: timestamp = time.strftime("%Y%m%d") - output_file_excel = f"{output_path}matrice_{firewall_type}_{timestamp}.xlsx" + output_file_excel = f"{output_path}matrice_flux_{firewall_type}_{timestamp}.xlsx" - excel_file = export_to_excel(output_file_json, output_file_excel) + excel_file = export_flux_to_excel(output_file_json, output_file_excel) + print(f"✓ Processus terminé. Fichiers générés:\n - JSON: {output_file_json}\n - Excel: {excel_file}") + + if "-r" in sys.argv: + print(f"\nGénération de l'export la matrice routage...") + if "-o" in sys.argv: + o_index = sys.argv.index("-o") + if o_index + 1 < len(sys.argv): + output_file_excel = os.path.join(f"{output_path}matrice_routage_{firewall_type}_{sys.argv[o_index + 1]}.xlsx") + else: + print("Erreur: nom de fichier de sortie manquant après '-o'.") + sys.exit(1) + else: + timestamp = time.strftime("%Y%m%d") + output_file_excel = f"{output_path}matrice_routage_{firewall_type}_{timestamp}.xlsx" + + excel_file = export_routing_to_excel(output_file_json, output_file_excel) print(f"✓ Processus terminé. Fichiers générés:\n - JSON: {output_file_json}\n - Excel: {excel_file}") if __name__ == "__main__": diff --git a/Parseurs_config_Firewall/src/scripts/export_excel.py b/Parseurs_config_Firewall/src/scripts/export_matrice_flux.py similarity index 100% rename from Parseurs_config_Firewall/src/scripts/export_excel.py rename to Parseurs_config_Firewall/src/scripts/export_matrice_flux.py diff --git a/Parseurs_config_Firewall/src/scripts/export_matrice_routage.py b/Parseurs_config_Firewall/src/scripts/export_matrice_routage.py new file mode 100644 index 0000000..4934dc6 --- /dev/null +++ b/Parseurs_config_Firewall/src/scripts/export_matrice_routage.py @@ -0,0 +1,97 @@ +import json +import re +import pandas as pd +import ipaddress +import time +from collections import deque +from openpyxl import load_workbook +from scripts.style_excel.style_matrice_routage import style_matrice_routage + +def is_pure_cidr(value): + try: + ipaddress.ip_network(value, strict=False) + return True + except ValueError: + return False + +def export_to_excel(json_file_path, output_file_excel): + """ + Export firewall data from JSON to Excel + Args: + json_file_path: Path to the JSON file to process + output_file_excel: Path to the output Excel file + """ + + with open(json_file_path, "r", encoding="utf-8") as f: + data = json.load(f) + + address_objects = {} + addr_objs = data.get( + "custom-firewall-objects:firewall-objects", {} + ).get("address", []) + + for obj in addr_objs: + name = obj.get("name") + ip_netmask = obj.get("config", {}).get("ip_netmask") + + if name and ip_netmask: + address_objects[name] = ip_netmask + + rows = [] + network_instances = data.get( + "openconfig-network-instance:network-instances", {} + ).get("network-instance", []) + + for ni in network_instances: + equipement = ni.get("name", "") + + protocols = ni.get("protocols", {}).get("protocol", []) + for proto in protocols: + if proto.get("identifier") != "STATIC": + continue + + static_routes = proto.get("static-routes", {}).get("static", []) + for route in static_routes: + prefix = route.get("prefix", "") + + # Découpage réseau / masque + resolved_prefix = prefix + if not is_pure_cidr(prefix): + resolved_prefix = address_objects.get(prefix, prefix) + + + try: + net = ipaddress.ip_network(resolved_prefix, strict=False) + reseau = str(net.network_address) + masque = str(net.netmask) + except ValueError: + reseau = resolved_prefix + masque = "" + + next_hops = route.get("next-hops", {}).get("next-hop", []) + for nh in next_hops: + nh_config = nh.get("config", {}) + + rows.append({ + "Equipement": equipement, + "Réseau destination": reseau, + "Masque": masque, + "Next Hop": nh_config.get("next-hop", ""), + "Metrique": nh_config.get("metric", ""), + "Commentaire": prefix + }) + + df = pd.DataFrame(rows) + + with pd.ExcelWriter(output_file_excel, engine="openpyxl") as writer: + df.to_excel(writer,sheet_name="Routes statiques",index=False,startrow=1) + + wb = load_workbook(output_file_excel) + if "Sheet1" in wb.sheetnames: + del wb["Sheet1"] + + style_matrice_routage(wb["Routes statiques"]) + + wb.save(output_file_excel) + print(f"✓ Export Excel OK: {output_file_excel}") + return output_file_excel \ No newline at end of file diff --git a/Parseurs_config_Firewall/src/scripts/json_Stormshield.py b/Parseurs_config_Firewall/src/scripts/json_Stormshield.py index 272f971..4a26c05 100644 --- a/Parseurs_config_Firewall/src/scripts/json_Stormshield.py +++ b/Parseurs_config_Firewall/src/scripts/json_Stormshield.py @@ -196,59 +196,95 @@ class StormshieldParser(ParserMixin): if not os.path.exists(route_path): return + virtual_routers = {} + default_route = None + section = None with open(route_path, encoding="utf-8", errors="ignore") as f: for raw_line in f: line = raw_line.strip() - if not line or line.startswith("#"): + if not line or line.startswith("off") or line.startswith("#"): continue if line.startswith("[") and line.endswith("]"): section = line.strip("[]") continue + # ===== Default route ===== if section == "Config" and line.startswith("DefaultRoute="): - self.config["default_route"] = line.split("=", 1)[1].strip() + default_route = line.split("=", 1)[1].strip() - elif section == "StaticRoutes" and not line.startswith("#"): - parts = line.split(",") - if len(parts) >= 2: - self.config["static_routes"].append({ - "destination": parts[0], - "interface": parts[1], - "extra": parts[2:] if len(parts) > 2 else [] - }) + # ===== Static routes ===== + elif section == "StaticRoutes": + parts = [p.strip() for p in line.split(",")] + if len(parts) < 2: + continue - static_routes = [] - if self.config["default_route"]: - static_routes.append( + destination = parts[0] + + vr_name = None + interface = None + next_hop_ip = None + + # Format : VR->NextHop + if "->" in parts[1]: + vr_name, next_hop_ip = map(str.strip, parts[1].split("->", 1)) + interface = vr_name + else: + vr_name = parts[1] + interface = parts[1] + + # Création VR si absent + if vr_name not in virtual_routers: + virtual_routers[vr_name] = { + "interfaces": set(), + "static_routes": [] + } + + virtual_routers[vr_name]["interfaces"].add(interface) + + static_route = StaticRoute( + name=f"{vr_name}-static-{len(virtual_routers[vr_name]['static_routes']) + 1}", + destination=destination, + metric=None, + next_vr=None, + next_hop_ip=next_hop_ip, + interface=interface, + bfd_profile=None + ) + + virtual_routers[vr_name]["static_routes"].append(static_route) + + # ===== Default VR (route par défaut) ===== + if default_route: + vr_name = "default" + virtual_routers.setdefault(vr_name, { + "interfaces": set(), + "static_routes": [] + }) + + virtual_routers[vr_name]["static_routes"].insert( + 0, StaticRoute( name="default-route", destination="0.0.0.0/0", metric=1, - next_hop_ip=self.config["default_route"], - interface=None + next_vr=None, + next_hop_ip=default_route, + interface=None, + bfd_profile=None ) ) - for idx, route in enumerate(self.config["static_routes"]): - static_routes.append( - StaticRoute( - name=f"static-{idx+1}", - destination=route["destination"], - metric=1, - next_hop_ip=None, - interface=route["interface"] - ) + # ===== Construction finale ===== + self.config["virtual_routers"] = [ + VirtualRouter( + name=vr_name, + interfaces=list(data["interfaces"]), + static_routes=data["static_routes"] ) - - vr = VirtualRouter( - name="default-vr", - interfaces=[r["interface"] for r in self.config["static_routes"]], - static_routes=static_routes - ) - - self.config["virtual_routers"] = [vr] + for vr_name, data in virtual_routers.items() + ] # def _parse_slotinfo_file(self): # path = os.path.join(self.base_dir, "Filter", "slotinfo") diff --git a/Parseurs_config_Firewall/src/scripts/style_excel/style_matrice_routage.py b/Parseurs_config_Firewall/src/scripts/style_excel/style_matrice_routage.py new file mode 100644 index 0000000..d1dba96 --- /dev/null +++ b/Parseurs_config_Firewall/src/scripts/style_excel/style_matrice_routage.py @@ -0,0 +1,58 @@ +from openpyxl.styles import Alignment, PatternFill, Font, Border, Side +from openpyxl.utils import get_column_letter + +def style_matrice_routage(ws): + + headers = [ + "Equipement", + "Réseau destination", + "Masque", + "Next Hop", + "Metrique", + "Commentaire" + ] + + header_fill = PatternFill("solid", fgColor="1F4E78") + header_font = Font(color="FFFFFF", bold=True) + header_alignment = Alignment(horizontal="center", vertical="center") + + cell_alignment_left = Alignment(horizontal="left", vertical="center") + cell_alignment_center = Alignment(horizontal="center", vertical="center") + + thin_border = Border( + left=Side(style="thin"), + right=Side(style="thin"), + top=Side(style="thin"), + bottom=Side(style="thin") + ) + + for col_idx, header in enumerate(headers, start=1): + cell = ws.cell(row=1, column=col_idx, value=header) + cell.fill = header_fill + cell.font = header_font + cell.alignment = header_alignment + cell.border = thin_border + + column_widths = { + "A": 22, # Equipement + "B": 22, # Réseau destination + "C": 18, # Masque + "D": 20, # Next Hop + "E": 12, # Metrique + "F": 30 # Commentaire + } + + for col_letter, width in column_widths.items(): + ws.column_dimensions[col_letter].width = width + + for row in ws.iter_rows(min_row=2, max_row=ws.max_row, max_col=len(headers)): + for cell in row: + cell.border = thin_border + + if cell.column in (1, 2, 4, 6): + cell.alignment = cell_alignment_left + else: + cell.alignment = cell_alignment_center + + ws.freeze_panes = "A2" + ws.auto_filter.ref = ws.dimensions diff --git a/Parseurs_logs_Switch/README.md b/Parseurs_logs_Switch/README.md new file mode 100644 index 0000000..f809f88 --- /dev/null +++ b/Parseurs_logs_Switch/README.md @@ -0,0 +1,57 @@ +# Parseur de Logs HPE 5130 + +Ce projet permet d'extraire automatiquement des informations pertinentes depuis les logs de switchs **HPE 5130**, notamment les connexions entre les switchs d'accès et le cœur de réseau. Les résultats sont exportés sous deux formats : + +- Un **fichier Excel** listant les interfaces côté accès et cœur. +- Un **diagramme Mermaid** simplifié représentant les connexions. + +--- + +## 🧰 Fonctionnalités + +- Extraction des données utiles depuis les fichiers `.log` au format **JSON**. +- Génération d’un **rapport Excel (`uplink_report.xlsx`)** contenant : + - Les informations des interfaces côté accès connectées au cœur. + - Les informations des interfaces du cœur. +- Création d’un **fichier Mermaid (`mermaid.md`)** représentant graphiquement les connexions. + +--- + +## 🚀 Lancement + +Pour lancer l’outil, placez-vous dans le dossier du projet et exécutez la commande suivante : + +```bash +python .\src\main.py [fichier logs du cœur] +``` +#### 💡 Exemple : python .\src\main.py .\src\logs\core_switch.log + +--- + +## 📁 Arborescence du projet +```makefile +C:. +└───src + ├───logs # Contient les fichiers .log des switchs (à déposer ici) + ├───output # Contient les fichiers générés (Excel et Mermaid) + ├───scripts # Contient les scripts de traitement + │ ├───extract_json.py # Extraction des données en JSON + │ ├───format.py # Formatage des données + │ ├───mermaid.py # Formatage et génération du fichier Mermaid + │ └───parse_uplinks.py # Création du fichier Excel + └───main.py # Programme de lancement +``` + +--- + +## 📌 Instructions d'utilisation +1. Déposer les fichiers .log dans le dossier src/logs. +2. Lancer le script main.py avec en argument le log du switch cœur. +3. Les résultats seront disponibles dans le dossier src/output : + - uplink_report.xlsx + - mermaid.md + +--- + +## ⚠️ Remarque +- Bien penser à **mettre les fichiers de logs avec l'extension `.log`** dans le dossier `src/logs`. \ No newline at end of file diff --git a/Parseurs_logs_Switch/LogAnalyzer/src/main.py b/Parseurs_logs_Switch/src/main.py similarity index 100% rename from Parseurs_logs_Switch/LogAnalyzer/src/main.py rename to Parseurs_logs_Switch/src/main.py diff --git a/Parseurs_logs_Switch/LogAnalyzer/src/scripts/extract_json.py b/Parseurs_logs_Switch/src/scripts/extract_json.py similarity index 93% rename from Parseurs_logs_Switch/LogAnalyzer/src/scripts/extract_json.py rename to Parseurs_logs_Switch/src/scripts/extract_json.py index 37538b9..569e4d1 100644 --- a/Parseurs_logs_Switch/LogAnalyzer/src/scripts/extract_json.py +++ b/Parseurs_logs_Switch/src/scripts/extract_json.py @@ -7,7 +7,7 @@ from datetime import datetime class InterfaceParser: """ - Parses 'display interface' command output to extract interface details. + Parse les données de la commande 'display interface' pour extraire les informations des interfaces. """ def parse(self, content: str) -> dict: interfaces = {} @@ -72,11 +72,11 @@ class InterfaceParser: class LinkAggregationParser: """ - Parses 'display link-aggregation verbose' command output. - Extracts link counts, MAC mappings, and bridge mappings. + Parse les données de la commande 'display link-aggregation verbose'. + Extrait les comptes de liens, les mappages MAC et les mappages de pont. """ def _convert_port_name(self, port_name: str) -> str: - """Converts the port name to a standardized format.""" + """Convertit le nom du port en un format standardisé.""" port_name = re.sub(r'\([A-Z]\)', '', port_name) patterns = [ (r'^XGE(\d+/\d+/\d+)$', r'Ten-GigabitEthernet\1'), @@ -175,11 +175,11 @@ class LinkAggregationParser: class ConfigurationParser: """ - Parses 'display current-configuration' command output. - Extracts interface configurations and general switch configurations. + Parse les données de la commande 'display current-configuration'. + Extrait les configurations des interfaces et les configurations générales du commutateur. """ def _parse_vlan_ranges(self, vlan_string: str) -> list: - """Parses a VLAN string and returns a list of unique VLANs.""" + """Parse un string de VLAN et renvoie une liste de VLANs uniques.""" vlans = set() parts = vlan_string.split() i = 0 @@ -370,7 +370,7 @@ class ConfigurationParser: class DeviceInfoParser: """ - Parses 'display device manuinfo' command output to extract MAC addresses. + Parse les données de la commande 'display device manuinfo' pour extraire les adresses MAC. """ def parse(self, content: str) -> list[str]: mac_addresses = [] @@ -394,8 +394,8 @@ class DeviceInfoParser: class LogFileProcessor: """ - Manages the parsing of a single log file, coordinating different parsers - and merging their results into a unified JSON structure. + Manage le parsing d'un fichier journal unique, en coordonnant différents analyseurs + et en fusionnant leurs résultats dans une structure JSON unifiée. """ def __init__(self): self.interface_parser = InterfaceParser() @@ -404,7 +404,7 @@ class LogFileProcessor: self.device_info_parser = DeviceInfoParser() def _extract_sections(self, file_content: str) -> dict: - """Extracts different sections from the log file content.""" + """Extrait les sections pertinentes du contenu du fichier journal en fonction des motifs définis.""" sections = {} current_section = None lines = file_content.splitlines() @@ -441,14 +441,14 @@ class LogFileProcessor: return sections def _extract_switch_name(self, content: str) -> str | None: - """Extracts the switch name from the log file content.""" + """Extrait le nom du commutateur à partir du contenu du fichier journal.""" sysname_match = re.search(r"(?m)^\s*sysname\s+(.+)$", content) if sysname_match: return sysname_match.group(1).strip() return None def _merge_configuration_into_interfaces(self, interfaces: dict, interfaces_config: dict): - """Merges configuration details into the parsed interface data.""" + """Merge les détails de configuration dans les données d'interface analysées.""" for interface_name, config in interfaces_config.items(): if interface_name in interfaces: interfaces[interface_name].update({ @@ -480,13 +480,13 @@ class LogFileProcessor: } def _merge_link_aggregation_counts(self, interfaces: dict, link_counts: dict): - """Merges link aggregation counts into the interface data.""" + """Merge le nombre de link aggregation dans les données d'interface.""" for interface_name, count in link_counts.items(): if interface_name in interfaces: interfaces[interface_name]["nb_liens"] = count def _merge_mac_mappings(self, interfaces: dict, mac_mappings: dict): - """Merges MAC address mappings into the interface data.""" + """Merge les mappages d'adresses MAC dans les données d'interface.""" for interface_name, mac_address in mac_mappings.items(): if interface_name in interfaces: interfaces[interface_name]["mac_destination"] = mac_address @@ -509,15 +509,15 @@ class LogFileProcessor: } def _merge_bridge_mappings(self, interfaces: dict, bridge_mappings: dict): - """Merges bridge aggregation mappings into existing interfaces.""" + """Merge les bridge agreggation dans les interfaces existantes.""" for interface_name, bridge_name in bridge_mappings.items(): if interface_name in interfaces: interfaces[interface_name]["bridge_name"] = bridge_name def process_file(self, filepath: str) -> dict | None: """ - Processes a single log file to extract and consolidate network device data. - Returns a dictionary containing metadata and parsed data, or None on error. + Gère le parsing d'un fichier journal unique pour extraire et consolider les données des appareils réseau. + Renvoie un dictionnaire contenant des métadonnées et des données analysées, ou None en cas d'erreur. """ try: with open(filepath, 'r', encoding='latin-1', errors='ignore') as f: @@ -580,7 +580,7 @@ class LogFileProcessor: class DataExporter: """ - Handles the export of processed data to a JSON file. + Gère l'export des données traitées vers un fichier JSON. """ def export(self, data: dict, output_filepath: str): try: @@ -596,7 +596,8 @@ class DataExporter: class MainApplication: """ - Main application class to orchestrate the log file processing. + Application principale pour coordonner le traitement des fichiers journaux, + l'export des données et la gestion des erreurs. """ def __init__(self): self.processor = LogFileProcessor() @@ -625,8 +626,8 @@ class MainApplication: def process_file_return_json(filepath: str) -> dict | None: """ - Standalone function to process a single file and return JSON object, - useful for external calls that don't need the full CLI application. + Fonction autonome pour traiter un fichier unique et renvoyer un objet JSON, + utile pour les appels externes. """ processor = LogFileProcessor() return processor.process_file(filepath) diff --git a/Parseurs_logs_Switch/LogAnalyzer/src/scripts/format.py b/Parseurs_logs_Switch/src/scripts/format.py similarity index 100% rename from Parseurs_logs_Switch/LogAnalyzer/src/scripts/format.py rename to Parseurs_logs_Switch/src/scripts/format.py diff --git a/Parseurs_logs_Switch/LogAnalyzer/src/scripts/mermaid.py b/Parseurs_logs_Switch/src/scripts/mermaid.py similarity index 100% rename from Parseurs_logs_Switch/LogAnalyzer/src/scripts/mermaid.py rename to Parseurs_logs_Switch/src/scripts/mermaid.py diff --git a/Parseurs_logs_Switch/LogAnalyzer/src/scripts/parse_uplinks.py b/Parseurs_logs_Switch/src/scripts/parse_uplinks.py similarity index 100% rename from Parseurs_logs_Switch/LogAnalyzer/src/scripts/parse_uplinks.py rename to Parseurs_logs_Switch/src/scripts/parse_uplinks.py diff --git a/gui.py b/gui.py index 7408c2e..203d669 100644 --- a/gui.py +++ b/gui.py @@ -68,7 +68,7 @@ class ToolTip: # Fenêtre principale root = tk.Tk() root.title("Analyse Réseau") -root.geometry("650x300") +root.geometry("650x350") root.resizable(False, False) @@ -89,7 +89,8 @@ def open_firewall_gui(): input_var = tk.StringVar() output_var = tk.StringVar() - excel_var = tk.BooleanVar() + matrice_flux = tk.BooleanVar() + matrice_routage = tk.BooleanVar() def browse_input(): fw_type = firewall_var.get() @@ -114,17 +115,24 @@ def open_firewall_gui(): if output_var.get(): f_json = os.path.join(OUTPUT_DIR, f"{fw}_{output_var.get()}.json") - f_excel = os.path.join(OUTPUT_DIR, f"matrice_{fw}_{output_var.get()}.xlsx") + f_flux = os.path.join(OUTPUT_DIR, f"matrice_flux_{fw}_{output_var.get()}.xlsx") + f_routage = os.path.join(OUTPUT_DIR, f"matrice_routage_{fw}_{output_var.get()}.xlsx") else: dt = datetime.now().strftime("%Y%m%d") f_json = os.path.join(OUTPUT_DIR, f"{fw}_{dt}.json") - f_excel = os.path.join(OUTPUT_DIR, f"matrice_{fw}_{dt}.xlsx") - - if not excel_var.get(): - output_label_var.set("Fichier de sortie :\n" + f_json) - else: - output_label_var.set("Fichiers de sortie :\n" + f_json + "\n" + f_excel) + f_flux = os.path.join(OUTPUT_DIR, f"matrice_flux_{fw}_{dt}.xlsx") + f_routage = os.path.join(OUTPUT_DIR, f"matrice_routage_{fw}_{dt}.xlsx") + if not matrice_flux.get(): + if not matrice_routage.get(): + output_label_var.set("Fichier de sortie :\n" + f_json) + else: + output_label_var.set("Fichiers de sortie :\n" + f_json + "\n" + f_routage) + else: + if not matrice_routage.get(): + output_label_var.set("Fichiers de sortie :\n" + f_json + "\n" + f_flux) + else: + output_label_var.set("Fichiers de sortie :\n" + f_json + "\n" + f_flux + "\n" + f_routage) app.update_idletasks() def open_output_folder(): @@ -172,8 +180,11 @@ def open_firewall_gui(): if output_var.get(): cmd.extend(["-o", output_var.get()]) - if excel_var.get(): - cmd.append("-m") + if matrice_flux.get(): + cmd.append("-f") + + if matrice_routage.get(): + cmd.append("-r") print("Commande exécutée :", " ".join(cmd)) print("Dossier courant (cwd) :", FIREWALL_DIR) @@ -274,15 +285,23 @@ def open_firewall_gui(): ttk.Checkbutton( app, text="Générer la matrice de flux en Excel", - variable=excel_var - ).pack(anchor="w", padx=10, pady=10) - excel_var.set(True) + variable=matrice_flux + ).pack(anchor="w", padx=10, pady=(10, 0)) + matrice_flux.set(True) + + ttk.Checkbutton( + app, + text="Générer la matrice de routage en Excel (route statique uniquement)", + variable=matrice_routage + ).pack(anchor="w", padx=10, pady=(0, 10)) + matrice_routage.set(True) output_label_var = tk.StringVar() ttk.Label(app, textvariable=output_label_var).pack(anchor="w", padx=10) firewall_var.trace_add("write", update_output_label) output_var.trace_add("write", update_output_label) - excel_var.trace_add("write", update_output_label) + matrice_flux.trace_add("write", update_output_label) + matrice_routage.trace_add("write", update_output_label) update_output_label() ttk.Button( @@ -321,8 +340,9 @@ ttk.Button( ttk.Label( root, - text="(Mise des données au format normalisé Yang dans un fichier JSON)" \ - "\n + possibilité de générer une matrice de flux en Excel", + text="(Convertir les données au format normalisé Yang dans un fichier JSON)" \ + "\n + possibilité de générer une matrice de flux en Excel" \ + "\n + possibilité de générer une matrice de routage en Excel (route statique uniquement)", font=("Arial", 9, "italic"), anchor="center", justify="center" @@ -339,7 +359,7 @@ ttk.Button( ttk.Label( root, - text="(Mise des données au format normalisé Yang dans un fichier JSON)" \ + text="(Convertir les données au format normalisé Yang dans un fichier JSON)" \ "\n + possibilité de générer un schéma réseau", font=("Arial", 9, "italic"), anchor="center", diff --git a/help_Firewall.md b/help_Firewall.md index 00a985a..371d8b7 100644 --- a/help_Firewall.md +++ b/help_Firewall.md @@ -5,6 +5,7 @@ Cet outil permet de **récupérer les données des configurations de différents types de firewalls** (Palo Alto, Stormshield, Forcepoint) et de **convertir ces informations en un format JSON normalisé basé sur des modèles OpenConfig en YANG**. Il fournit également la possibilité de générer une **matrice de flux au format Excel** pour visualiser les communications et règles de trafic dans l’infrastructure. +Il founit également la possibilité de générer une **matrice de routage au format Excel** pour visualiser les routes statiques dans l’infrastructure. ## Utilisation @@ -14,7 +15,7 @@ cd .\Parseurs_config_Firewall\ python -m venv .venv .\.venv\Scripts\activate -pip install -r .\src\requierements.txt +pip install -r .\Parseurs_config_Firewall\src\requirements.txt ``` - Mettre le/les fichier(s) et/ou dossier(s) de configurations dans le dossier `/Parseurs_config_Firewall/src/input/` - Modifier le fichier `site.json` de données dans `/Parseurs_config_Firewall/src/data/` \ No newline at end of file