Zeileninhalt in unterschiedlichen Datein mit unterschiedlicher Darstellung vergleichen

Sockets, TCP/IP, (XML-)RPC und ähnliche Themen gehören in dieses Forum
Antworten
xconsole
User
Beiträge: 4
Registriert: Donnerstag 7. Dezember 2017, 08:43

Hallo meine Frage bezieht sich nur weitesgehend um die Netzwerkprogrammierung, hat aber damit zu tun.

Ich habe eine Installationsdatei für ein LinuxFirewall in der sind z.B. folgende Zeilen zu finden:

Code: Alles auswählen

###########################################################################################################################
SN12345678, setconf, network, ethernet6, Address, 192.168.1.1
SN12345678, setconf, network, ethernet6, Mask, 30
SN12345678, setconf, network, ethernet6, Protected, 1
SN12345678, setconf, network, ethernet6, Media, 0
SN12345678, setconf, network, ethernet6, Name, "Port5"
SN12345678, setconf, network, ethernet7, Address, 192.168.2.1
SN12345678, setconf, network, ethernet7, Mask, 30
SN12345678, setconf, network, ethernet7, Protected, 1
SN12345678, setconf, network, ethernet7, Media, 0
SN12345678, setconf, network, ethernet7, Name, "Port6"
#
SN12345678, setconf, snmp, System, location, zuHause
#
SN12345678, setconf, ntp, Server, "ntp-Server,0,Firewall_Eth3"
###########################################################################################################################
Dieses Installationsscript läuft durch und normalerweis klappt auch alles, aber wenn ich es verifizieren will muss ich auf die Maschine und dort unterschiedlieche Datein aufrufen und sehe dort neben vielen anderen auch die konfigurierten Zeilen.

Code: Alles auswählen

###########################################################################################################################
# cat /ConfigFiles/network # 
[ethernet6]
State=1
Name=Port5
Protected=1
Media=0
Type=2
EEE=0
Address=192.168.1.1
Mask=30

[ethernet7]
State=1
Name=Port6
Protected=1
Media=0
Type=2
EEE=0
Address=192.168.2.1
Mask=30

###########################################################################################################################
# cat ~/ConfigFiles/ntp
[Config]
State=1
AllowUnauth=1

[Server]
ntp-Server,0,Firewall_Eth3

###########################################################################################################################
# cat /ConfigFiles/snmp
[System]
location=zuHause
Das ganze geht also von einer Installationsdatei aus und diese Werte landen in unterschiedlichen Datein an unterschiedlichen Stellen auf der Firewall.
Ich würde gern hier eine Verknüpfung aufbauen die es möglich macht von links nach recht und auch von rechts nach links zu prüfen.

Wenn in der Installationsdatei das steht:

Code: Alles auswählen

SN12345678, setconf, ntp, Server, "ntp-Server,0,Firewall_Eth3"
Dann muss in System am ende in der Datei /ConfigFiles/ntp das stehen:

Code: Alles auswählen

[Config]
State=1
AllowUnauth=1

[Server]
ntp-Server,0,Firewall_Eth3
Gleichzeitig wünsche ich mir natürlich ein Rückwärtscheck, also wenn die Datei /ConfigFiles/ntp folgenden Inhalt hat:

Code: Alles auswählen

[Config]
State=1
AllowUnauth=1

[Server]
ntp-Server,0,Firewall_Eth3
Dann erstelle eine Installationsdatein mit folgender Zeile:

Code: Alles auswählen

SERIENNUMMER, setconf, ntp, Server, "ntp-Server,0,Firewall_Eth3"
Ich hoffe ihr habt eine tolle Idee, ich kann irgendwie nur "normal" vergleichen. :roll:
Danke!
Matthias
Benutzeravatar
__blackjack__
User
Beiträge: 13004
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@xconsole: Das ist an sich möglich, die Frage ist wie die Dateien geparst werden können/müssen, also ob man da etwas fertiges benutzen kann, oder man sich einen eigenen Parser schreiben muss.

Die Installationsdatei sieht, soweit wir sie jetzt kennen, so aus, als wenn man sie als CSV-Datei einlesen kann. Und für die Config-Dateien, wieder soweit wir die kennen, kann man das `configparser`-Modul verwenden.

Hier Code der die gezeigten Beispieldateien in verschachtelte Wörterbücher einliest und auf der Konsole ausgibt:

Code: Alles auswählen

#!/usr/bin/env python3
import csv
from configparser import RawConfigParser
from pathlib import Path
from pprint import pprint

SELF_PATH = Path(__file__).parent
INSTALL_FILE_PATH = SELF_PATH / "test.csv"
CONFIG_FILES_PATH = Path.home() / "tmp" / "forum" / "ConfigFiles"


def load_install_file(file_path):
    result = {}
    with file_path.open(encoding="utf-8", newline="") as file:
        for row in csv.reader(file, skipinitialspace=True):
            if row and not row[0].strip().startswith("#"):
                serial, command, *arguments = row
                if command == "setconf":
                    if len(arguments) == 4:
                        filename, section, option, value = arguments
                    elif len(arguments) == 3:
                        filename, section, option = arguments
                        value = None
                    else:
                        raise ValueError(
                            f"expected 3 or 4 setconf arguments,"
                            f" got {len(arguments)} instead: {arguments!r}"
                        )

                    mapping = result
                    for key in [serial, filename, section]:
                        mapping = mapping.setdefault(key, {})
                    mapping[option] = value

    return result


def load_config(file_path):
    config = RawConfigParser(
        allow_no_value=True, delimiters=["="], comment_prefixes=None
    )
    config.optionxform = lambda value: value

    if not config.read(file_path, encoding="utf-8"):
        raise ValueError(f"could not read {file_path!r}")

    return {section: dict(config[section]) for section in config.sections()}


def load_config_files(base_path):
    return {
        path.name: load_config(path)
        for path in base_path.iterdir()
        if path.is_file()
    }


def main():
    install_data = load_install_file(INSTALL_FILE_PATH)
    print("install file:")
    pprint(install_data)
    print("\nconfig files:")
    config_data = load_config_files(CONFIG_FILES_PATH)
    pprint(config_data)


if __name__ == "__main__":
    main()
Die Ausgabe für die Beispieldaten sieht so aus:

Code: Alles auswählen

install file:
{'SN12345678': {'network': {'ethernet6': {'Address': '192.168.1.1',
                                          'Mask': '30',
                                          'Media': '0',
                                          'Name': 'Port5',
                                          'Protected': '1'},
                            'ethernet7': {'Address': '192.168.2.1',
                                          'Mask': '30',
                                          'Media': '0',
                                          'Name': 'Port6',
                                          'Protected': '1'}},
                'ntp': {'Server': {'ntp-Server,0,Firewall_Eth3': None}},
                'snmp': {'System': {'location': 'zuHause'}}}}

config files:
{'network': {'ethernet6': {'Address': '192.168.1.1',
                           'EEE': '0',
                           'Mask': '30',
                           'Media': '0',
                           'Name': 'Port5',
                           'Protected': '1',
                           'State': '1',
                           'Type': '2'},
             'ethernet7': {'Address': '192.168.2.1',
                           'EEE': '0',
                           'Mask': '30',
                           'Media': '0',
                           'Name': 'Port6',
                           'Protected': '1',
                           'State': '1',
                           'Type': '2'}},
 'ntp': {'Config': {'AllowUnauth': '1', 'State': '1'},
         'Server': {'ntp-Server,0,Firewall_Eth3': None}},
 'snmp': {'System': {'location': 'zuHause'}}}

Jetzt könnte man Code schreiben, der schaut ob alle Schlüssel und Werte die in einem Wörterbuch stecken, auch im anderen zu finden sind, oder zumindest ob die, die vorhanden sind, in den Werten übereinstimmen. Denn in den Config-Dateien sind ja Einträge, die es nicht in der (gezeigten) Install-Datei gibt.
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
Antworten