#!/usr/bin/env python3 import re from enum import Enum, auto from object import Object, ObjectType class ParserState(Enum): DEFINE = auto() DIRECTIVE = auto() MULTILINE = auto() class NagParse: def __init__(self, config_files: list[str]): self.m_config_files: list[str] = config_files self.m_commands: list[Object] = list() self.m_contacts: list[Object] = list() self.m_contactgroups: list[Object] = list() self.m_hosts: list[Object] = list() self.m_hostdependencies: list[Object] = list() self.m_hostescalations: list[Object] = list() self.m_hostgroups: list[Object] = list() self.m_services: list[Object] = list() self.m_servicedependencies: list[Object] = list() self.m_serviceescalations: list[Object] = list() self.m_servicegroups: list[Object] = list() self.m_timeperiods: list[Object] = list() for config_file in self.m_config_files: for object in self.parse_config(config_file): match object.m_type: case ObjectType.Command: self.m_commands.append(object) case ObjectType.Contact: self.m_contacts.append(object) case ObjectType.ContactGroup: self.m_contactgroups.append(object) case ObjectType.Host: self.m_hosts.append(object) case ObjectType.HostDependency: self.m_hostdependencies.append(object) case ObjectType.HostEscalation: self.m_hostescalations.append(object) case ObjectType.HostGroup: self.m_hostgroups.append(object) case ObjectType.Service: self.m_services.append(object) case ObjectType.ServiceDependency: self.m_servicedependencies.append(object) case ObjectType.ServiceEscalation: self.m_serviceescalations.append(object) case ObjectType.ServiceGroup: self.m_servicegroups.append(object) case ObjectType.TimePeriod: self.m_timeperiods.append(object) def __str__(self): string = str() for fragment in self.m_commands: string += str(fragment) + "\n" for fragment in self.m_contacts: string += str(fragment) + "\n" for fragment in self.m_contactgroups: string += str(fragment) + "\n" for fragment in self.m_hosts: string += str(fragment) + "\n" for fragment in self.m_hostdependencies: string += str(fragment) + "\n" for fragment in self.m_hostescalations: string += str(fragment) + "\n" for fragment in self.m_hostgroups: string += str(fragment) + "\n" for fragment in self.m_services: string += str(fragment) + "\n" for fragment in self.m_servicedependencies: string += str(fragment) + "\n" for fragment in self.m_serviceescalations: string += str(fragment) + "\n" for fragment in self.m_servicegroups: string += str(fragment) + "\n" for fragment in self.m_timeperiods: string += str(fragment) + "\n" return string def parse_config(self,config_file: str) -> list[Object]: state = ParserState.DEFINE objects: list[Object] = list() with open(config_file, 'r') as file_handle: line_no = 0 cur_object = Object(config_file=config_file) for rawline in file_handle.readlines(): line = re.sub(r'([a-z]){', r'\1 {',rawline.strip()) line_no += 1 if len(line) == 0 or re.match('^#', line): continue if re.match(r'}', line): objects.append(cur_object) cur_object = Object() state = ParserState.DEFINE continue fragments: list[str] = re.sub(' +', ' ', line.strip()).split() if state == ParserState.DEFINE: if fragments[0] == 'define': cur_object.m_line_no = line_no cur_object.m_type = ObjectType(fragments[1]) state = ParserState.DIRECTIVE elif state == ParserState.MULTILINE: cur_object.m_directive[-1:][1] = cur_object.m_directives[-1:][1] + ' ' + " ".join(fragments) if fragments[-1:][-1:] != '\\': state = ParserState.DIRECTIVE else: fragments[-1:][-1:] = '' # This is ParserState.DIRECTIVE else: if fragments[-1:][-1:] == '\\': fragments[-1:][-1:] = '' state = ParserState.MULTILINE if re.match('^[a-z]+', fragments[0]): cur_object.m_directives.append( (fragments[0], " ".join(fragments[1:]))) return objects