nagrest/src/nagparse.py

134 lines
6.3 KiB
Python
Raw Normal View History

2022-03-25 18:07:23 +01:00
#!/usr/bin/env python3
import re
from enum import Enum, auto
2022-03-28 10:01:36 +02:00
from nag_object import NagObject, NagObjectType
2022-03-25 18:07:23 +01:00
class ParserState(Enum):
2022-03-28 20:10:32 +02:00
COMMENT = auto()
2022-03-25 18:07:23 +01:00
DEFINE = auto()
DIRECTIVE = auto()
MULTILINE = auto()
class NagParse:
def __init__(self, config_files: list[str]):
self.m_config_files: list[str] = config_files
2022-03-28 10:01:36 +02:00
self.m_commands: list[NagObject] = list()
self.m_contacts: list[NagObject] = list()
self.m_contactgroups: list[NagObject] = list()
self.m_hosts: list[NagObject] = list()
self.m_hostdependencies: list[NagObject] = list()
self.m_hostescalations: list[NagObject] = list()
self.m_hostgroups: list[NagObject] = list()
self.m_services: list[NagObject] = list()
self.m_servicedependencies: list[NagObject] = list()
self.m_serviceescalations: list[NagObject] = list()
self.m_servicegroups: list[NagObject] = list()
self.m_timeperiods: list[NagObject] = list()
2022-03-25 18:07:23 +01:00
for config_file in self.m_config_files:
for object in self.parse_config(config_file):
match object.m_type:
2022-03-28 10:01:36 +02:00
case NagObjectType.Command:
2022-03-25 18:07:23 +01:00
self.m_commands.append(object)
2022-03-28 10:01:36 +02:00
case NagObjectType.Contact:
2022-03-25 18:07:23 +01:00
self.m_contacts.append(object)
2022-03-28 10:01:36 +02:00
case NagObjectType.ContactGroup:
2022-03-25 18:07:23 +01:00
self.m_contactgroups.append(object)
2022-03-28 10:01:36 +02:00
case NagObjectType.Host:
2022-03-25 18:07:23 +01:00
self.m_hosts.append(object)
2022-03-28 10:01:36 +02:00
case NagObjectType.HostDependency:
2022-03-25 18:07:23 +01:00
self.m_hostdependencies.append(object)
2022-03-28 10:01:36 +02:00
case NagObjectType.HostEscalation:
2022-03-25 18:07:23 +01:00
self.m_hostescalations.append(object)
2022-03-28 10:01:36 +02:00
case NagObjectType.HostGroup:
2022-03-25 18:07:23 +01:00
self.m_hostgroups.append(object)
2022-03-28 10:01:36 +02:00
case NagObjectType.Service:
2022-03-25 18:07:23 +01:00
self.m_services.append(object)
2022-03-28 10:01:36 +02:00
case NagObjectType.ServiceDependency:
2022-03-25 18:07:23 +01:00
self.m_servicedependencies.append(object)
2022-03-28 10:01:36 +02:00
case NagObjectType.ServiceEscalation:
2022-03-25 18:07:23 +01:00
self.m_serviceescalations.append(object)
2022-03-28 10:01:36 +02:00
case NagObjectType.ServiceGroup:
2022-03-25 18:07:23 +01:00
self.m_servicegroups.append(object)
2022-03-28 10:01:36 +02:00
case NagObjectType.TimePeriod:
2022-03-25 18:07:23 +01:00
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
2022-03-28 10:01:36 +02:00
def parse_config(self,config_file: str) -> list[NagObject]:
2022-03-25 18:07:23 +01:00
state = ParserState.DEFINE
2022-03-28 10:01:36 +02:00
objects: list[NagObject] = list()
2022-03-25 18:07:23 +01:00
with open(config_file, 'r') as file_handle:
line_no = 0
2022-03-28 10:01:36 +02:00
cur_object = NagObject(config_file=config_file)
2022-03-25 18:07:23 +01:00
for rawline in file_handle.readlines():
2022-03-28 10:01:36 +02:00
# Clean up the config
2022-03-25 18:07:23 +01:00
line = re.sub(r'([a-z]){', r'\1 {',rawline.strip())
2022-03-28 10:01:36 +02:00
#line = re.sub(r'([a-zA-Z0-9])}', r'\1\n}',line.strip())
#line = re.sub(r'([a-zA-Z0-9]) }', r'\1\n}',line.strip())
2022-03-25 18:07:23 +01:00
line_no += 1
2022-03-28 10:01:36 +02:00
# This means it is a comment, we might want to save those later on
if len(line) == 0 or re.match('^[\t ]*[#]+', line):
2022-03-25 18:07:23 +01:00
continue
2022-03-28 10:01:36 +02:00
# This means we are done parsing and should reset for new object
2022-03-25 18:07:23 +01:00
if re.match(r'}', line):
objects.append(cur_object)
2022-03-28 10:01:36 +02:00
del cur_object
2022-03-25 18:07:23 +01:00
state = ParserState.DEFINE
continue
2022-03-28 10:01:36 +02:00
#if we get here it is not a comment and not the end of an object
2022-03-25 18:07:23 +01:00
fragments: list[str] = re.sub(' +', ' ', line.strip()).split()
2022-03-28 10:01:36 +02:00
# This is a new object and we should see what type it is, and what line number it is on
2022-03-25 18:07:23 +01:00
if state == ParserState.DEFINE:
if fragments[0] == 'define':
2022-03-28 10:01:36 +02:00
cur_object = NagObject(config_file=config_file, directives=list())
2022-03-25 18:07:23 +01:00
cur_object.m_line_no = line_no
2022-03-28 10:01:36 +02:00
cur_object.m_type = NagObjectType(fragments[1])
# For the next line we should be in DIRECTIVE state
2022-03-25 18:07:23 +01:00
state = ParserState.DIRECTIVE
else:
2022-03-28 10:01:36 +02:00
print("It's fucked up man")
break
# This is the DIRECTIVE state, where we want to collect key, values and find out if we should go to multiline mode
elif state == ParserState.DIRECTIVE:
if fragments[-1][-1] == '\\':
2022-03-25 18:07:23 +01:00
state = ParserState.MULTILINE
if re.match('^[a-z]+', fragments[0]):
cur_object.m_directives.append(
2022-03-28 10:01:36 +02:00
[fragments[0], " ".join(fragments[1:])])
# This is the MULTILINE state, directives can be on many lines if the '\n' is escaped with '\'
elif state == ParserState.MULTILINE:
cur_object.m_directives[-1][1] = cur_object.m_directives[-1][1].strip('\\') + ' ' + " ".join(fragments)
if fragments[-1][-1] != '\\':
state = ParserState.DIRECTIVE
else:
print("It's fucked up man")
break
2022-03-25 18:07:23 +01:00
return objects