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