From: Frank Brehm Date: Sun, 21 Nov 2010 22:53:56 +0000 (+0000) Subject: Weitergemacht X-Git-Url: https://git.uhu-banane.net/?a=commitdiff_plain;h=91248cb29fb90f26b80ea4a0e32237f28df1f356;p=my-stuff%2Fnagios.git Weitergemacht git-svn-id: http://svn.brehm-online.com/svn/my-stuff/nagios/trunk@129 ec8d2aa5-1599-4edb-8739-2b3a1bc399aa --- diff --git a/bin/nagios/config.py b/bin/nagios/config.py index 4130d12..71ee8db 100644 --- a/bin/nagios/config.py +++ b/bin/nagios/config.py @@ -248,9 +248,8 @@ class NagiosConfig(object): for file_name in files: self.read_objectfile(file_name) - #self.logger.debug( "Gelesene Objekte: {0!r}".format( self.objects ) ) pp = pprint.PrettyPrinter( indent = 4, depth = 6, width = 120 ) - self.logger.debug( "Gelesene Objekte: {0}".format( pp.pformat( self.objects ) ) ) + self.logger.debug( "Gelesene Objekte:\n{0}".format( pp.pformat( self.objects ) ) ) return @@ -258,6 +257,8 @@ class NagiosConfig(object): def read_objectfile( self, file_name ): "Liest eine Datei mit Objektdefinitionen ein und legt diese unter self.objects ab." + self.logger.info( "Reading configuration file {0!r} ...".format( file_name ) ) + try: file = open( file_name, 'rU' ) except IOError as e: @@ -269,6 +270,8 @@ class NagiosConfig(object): pattern_comment = re.compile( r'^\s*#.*', re.MULTILINE ); row_num = 0 + pp = pprint.PrettyPrinter( indent = 4, depth = 6, width = 120 ) + try: for line in file: @@ -285,22 +288,43 @@ class NagiosConfig(object): if in_block: if line == '}': + in_block = False + if not object_type in self.objects: - self.objects[object_type] = [] - self.objects[object_type].append( cur_object ) + self.objects[object_type] = {} + + #self.objects[object_type].append( cur_object ) + # Verifying the object: + if object_type == 'host': + + ( identifier, struct ) = nagios.object.host.verify( cur_object, self.logger ) + self.logger.debug( "Found host object structure for {0!r}: {1}".format( identifier, pp.pformat( struct ) ) ) + ( file_name, rownum ) = cur_object['__object_definition__'] + + if identifier is None: + self.logger.warn( "Couldn't verify host object structure of {0!r}({1})".format( + file_name, rownum ) ) + else: + if identifier in self.objects['host']: + msg = "Host object {0!r} even exists, ".format( identifier ) + msg = msg + "new definition in {0!r}({1}) will not accepted.".format( file_name, rownum ) + self.logger.warn( msg ) + else: + self.objects['host'][identifier] = struct + cur_object = {} - self.logger.debug( "Zeile {0} in {1}: Beende Block vom Type {2!r}".format( row_num, file_name, object_type ) ) + self.logger.debug( "Row {0} in {1}: finishing block of type {2!r}".format( row_num, file_name, object_type ) ) else: ( key, value ) = self.check_object_file_entry( line, object_type, file_name, row_num ) if ( key == None ): - self.logger.debug( "Nichts gefunden." ) + self.logger.debug( "nothing found." ) else: - self.logger.debug( "Gefunden: key: {0!r}, value: {1!r}".format( key, value ) ) + self.logger.debug( "Found: key: {0!r}, value: {1!r}".format( key, value ) ) if key in cur_object: - self.logger.warn( "Doppelter Eintrag für Eigenschaft {0!r} von {1!r} in {2}({3}).".format( + self.logger.warn( "Double entry of property {0!r} as {1!r} in {2}({3}).".format( key, object_type, file_name, row_num ) ) else: cur_object[key] = ( value, file_name, row_num ) @@ -313,57 +337,14 @@ class NagiosConfig(object): cur_object = {} object_type = match.group(1).lower() cur_object['__object_definition__'] = ( file_name, row_num ) - self.logger.debug( "Zeile {0} in {1}: Beginne Block vom Type {2!r}".format( row_num, file_name, object_type ) ) + self.logger.debug( "Row {0} in {1}: Starting block of type {2!r}".format( row_num, file_name, object_type ) ) continue - self.logger.debug( "Ungültige Zeile {0} in {1} gefunden: {2!r}".format( row_num, file_name, line ) ) + self.logger.debug( "Invalid row{0} found in {1}: {2!r}".format( row_num, file_name, line ) ) finally: file.close() - #------------------------------------------------------ - def verify_objects( self, as_cache_objects = False ): - "Überprüft die Syntax der eingelesenen Konfiguration" - - verify_success = True - self.config_objects = {} - - for object_type in self.objects: - - for definition in self.objects[object_type]: - - if object_type == 'host': - - ( identifier, struct ) = nagios.object.host.verify( definition, self.logger ) - - if identifier is None: - verify_success = False - continue - - if as_cache_objects: - if not 'host' in self.cache_objects: - self.cache_objects['host'] = {} - else: - if not 'host' in self.config_objects: - self.config_objects['host'] = {} - - if identifier in self.config_objects['host']: - ( file_name, rownum ) = definition['__object_definition__'] - msg = "Host-Objekt {0!r} ist bereits vorhanden, ".format( identifier ) - msg = msg + "neue Definition in {0}({1}) wird nicht beachtet.".format( file_name, rownum ) - self.logger.warn( msg ) - continue - - if as_cache_objects: - self.cache_objects['host'][identifier] = struct - else: - self.config_objects['host'][identifier] = struct - - if not verify_success: - raise NagiosConfigError( "Objektstruktur konnte nicht verifiziert werden." ) - - return True - #------------------------------------------------------ def check_object_file_entry( self, line, object_type, file_name, row_num ): diff --git a/bin/nagios/object/host.py b/bin/nagios/object/host.py index 168a972..d61af16 100644 --- a/bin/nagios/object/host.py +++ b/bin/nagios/object/host.py @@ -5,11 +5,12 @@ # $URL$ import re +import pprint -from nagios.object.verify import NagiosVerifyError, verify_object_property +from nagios.object.verify import NagiosVerifyError, NagiosObjectVerifier #----------------------------------------------------------------------- -def verfify( definition, logger ): +def verify( definition, logger ): "Verifiziert einen übergebenen Definitionsblock als Nagios-Host." res = {} @@ -63,7 +64,7 @@ define host{ } """ - valid_keys = set( + valid_keys = set( [ 'host_name', 'alias', 'display_name', 'address', 'parents', 'hostgroups', 'check_command', 'initial_state', 'max_check_attempts', 'check_interval', 'retry_interval', 'active_checks_enabled', 'passive_checks_enabled', 'check_period', 'obsess_over_host', 'check_freshness', 'freshness_threshold', 'event_handler', 'event_handler_enabled', @@ -71,38 +72,77 @@ define host{ 'retain_status_information', 'retain_nonstatus_information', 'contacts', 'contact_groups', 'notification_interval', 'first_notification_delay', 'notification_period', 'notification_options', 'notifications_enabled', 'stalking_options', 'notes', 'notes_url', 'action_url', 'icon_image', 'icon_image_alt', 'vrml_image', 'statusmap_image', - '2d_coords', '3d_coords' - ) + '2d_coords', '3d_coords', + 'use', 'register', 'name' + ] ) + + pp = pprint.PrettyPrinter( indent = 4, depth = 6, width = 120 ) + logger.debug( "Verifying host object structure:\n{0}".format( pp.pformat( definition ) ) ) for key in definition: + if key == '__object_definition__': + continue if not key in valid_keys: logger.warn( "Ungültige Eigenschaft {0!r} für Hostdefinition in {1}({2}).".format( key, definition[key][1], definition[key][2] ) ) + verifier = NagiosObjectVerifier( logger = logger ) + # Einfache String-Eigenschaften - for key in ( 'host_name', 'alias', 'address', 'display_name', 'check_period', 'event_handler', 'notification_period', + for key in ( 'name', 'host_name', 'alias', 'address', 'display_name', 'check_period', 'event_handler', 'notification_period', 'notes', 'notes_url', 'action_url', 'icon_image', 'icon_image_alt', 'vrml_image', 'statusmap_image' ): if key in definition: try: if key in res: logger.warn( "Double entry {0} for host definition in {1}({2}).".format( key, definition[key][1], definition[key][2] ) ) else: - res[key] = verify_object_property( definition[key][0], 'string' ) + args = dict( file = definition[key][1], row = definition[key][2] ) + res[key] = verifier.verify_property( definition[key][0], 'string', args ) except NagiosVerifyError as e: logger.warn( "Property error for host definition in {0}({1}): {2}".format( definition[key][1], definition[key][2], e ) ) # Array-String-Eigenschaften - for key in ( 'parents', 'hostgroups', 'contacts', 'contact_groups' ): + for key in ( 'use', 'parents', 'hostgroups', 'contacts', 'contact_groups' ): + if key in definition: + try: + if key in res: + logger.warn( "Double entry {0} for host definition in {1}({2}).".format( key, definition[key][1], definition[key][2] ) ) + else: + args = dict( file = definition[key][1], row = definition[key][2] ) + res[key] = verifier.verify_property( definition[key][0], 'array', args ) + except NagiosVerifyError as e: + logger.warn( "Property error for host definition in {0}({1}): {2}".format( definition[key][1], definition[key][2], e ) ) + + for key in ( 'initial_state', 'flap_detection_options', 'stalking_options' ): if key in definition: array = re.split( r',+', definition[key][0] ) - res[key] = array[:] - - if 'initial_state' in definition: - array = re.split( r',+', definition['initial_state'][0] ) - for value in array: - if value not in ( 'o', 'd', 'u' ): - logger.warn( "Ungültiger Wert für 'initial_state' in {0}({1}) gegeben.".format( - definition['initial_state'][1], definition['initial_state'][2] ) ) + for value in array: + try: + if key in res: + logger.warn( "Double entry {0} for host definition in {1}({2}).".format( key, definition[key][1], definition[key][2] ) ) + else: + args = dict( file = definition[key][1], row = definition[key][2], valid_values = set( [ 'o', 'd', 'u' ] ) ) + res[key] = verifier.verify_property( definition[key][0], 'set', args ) + except NagiosVerifyError as e: + logger.warn( "Property error for host definition in {0}({1}): {2}".format( definition[key][1], definition[key][2], e ) ) + + for key in ( 'notification_options' ): + if key in definition: + array = re.split( r',+', definition[key][0] ) + for value in array: + try: + if key in res: + logger.warn( "Double entry {0} for host definition in {1}({2}).".format( key, definition[key][1], definition[key][2] ) ) + else: + args = dict( file = definition[key][1], row = definition[key][2], valid_values = set( [ 'r', 'd', 'u', 'f', 's' ] ) ) + res[key] = verifier.verify_property( definition[key][0], 'set', args ) + except NagiosVerifyError as e: + logger.warn( "Property error for host definition in {0}({1}): {2}".format( definition[key][1], definition[key][2], e ) ) + + if 'host_name' in res: + identifier = res['host_name'] + elif 'name' in res: + identifier = res['name'] return ( identifier, res ) diff --git a/bin/nagios/object/verify.py b/bin/nagios/object/verify.py index c3a37a7..220435d 100644 --- a/bin/nagios/object/verify.py +++ b/bin/nagios/object/verify.py @@ -5,6 +5,8 @@ # $URL$ import re +import logging +import pprint #----------------------------------------------------------------------- class NagiosVerifyError(Exception): @@ -12,30 +14,110 @@ class NagiosVerifyError(Exception): pass #----------------------------------------------------------------------- -def verify_object_property( definition, type, args = None ): - "Verifiziert den Wert einer übergebenen Objekteigenschaft." +class NagiosObjectVerifier(object): - if definition is None: - raise NagiosVerifyError( "Undefined property given." ) + #------------------------------------------------------ + def __init__( self, logger = None ): + "Constructor." - definition = re.sub( r'^\s+', '', definition, 0 ) - definition = re.sub( r'\s+$', '', definition, 0 ) + # Logging-Setup + if logger is None: - if type == "string": - return verify_string_property( definition, args ) + self.logger = logging.getLogger('nagiosConfig') + self.logger.setLevel(logging.DEBUG) -#----------------------------------------------------------------------- -def verify_string_property( definition, args = None ): - "Verifiziert den Wert als einfachen String" + ch = logging.StreamHandler() + ch.setLevel(logging.DEBUG) + + formatter = logging.Formatter("%(name)s - %(funcName)s(%(lineno)d) - %(levelname)s - %(message)s") + ch.setFormatter(formatter) + + self.logger.addHandler(ch) + + else: + self.logger = logger + + #------------------------------------------------------ + def verify_property( self, definition, type, args = None ): + """Verifying the value of the given property as the given type. +Returns the verified structure or raises an NagiosVerifyError. +""" + + if definition is None: + raise NagiosVerifyError( "Undefined property given." ) + + definition = re.sub( r'^\s+', '', definition, 0 ) + definition = re.sub( r'\s+$', '', definition, 0 ) + + if type == "string": + return self.verify_string_property( definition, args ) + elif type == "array": + return self.verify_array_property( definition, args ) + elif type == "set": + return self.verify_set_property( definition, args ) + + raise NagiosVerifyError( "Unknown property type {0!r} given.".format( type ) ) + + #------------------------------------------------------ + def verify_string_property( self, definition, args = None ): + """Verifying the value as a simple string with any contents. +Raises a NagiosVerifyError unless args['empty_ok'] is given. +""" + + if args is None: + args = dict() + + if definition == '': + if not 'empty_ok' in args: + raise NagiosVerifyError( "Empty property is not allowed." ) - if args is None: - args = dict() + return definition - if definition == '': - if not 'empty_ok' in args: - raise NagiosVerifyError( "Empty property is not allowed." ) + #------------------------------------------------------ + def verify_array_property( self, definition, args = None ): + """Verifying the value as a comma separated list of strings (without whitespaces). +Raises a NagiosVerifyError unless args['empty_ok'] is given. +""" - return definition - + if args is None: + args = dict() + + array = re.split( r',+', definition ) + + if len(array) == 0: + if not 'empty_ok' in args: + raise NagiosVerifyError( "Empty property is not allowed." ) + + return array + + #------------------------------------------------------ + def verify_set_property( self, definition, args = None ): + """Verifying the value as a comma separated list of strings (without whitespaces). +Raises a NagiosVerifyError unless args['empty_ok'] is given. +""" + + if args is None: + args = dict() + + if not 'valid_values' in args: + raise Exception( "No valid values given in calling verify_set_property." ) + + if len( args['valid_values'] ) == 0: + raise Exception( "Empty array given as valid values in calling verify_set_property." ) + + array = re.split( r',+', definition ) + + res = set() + for key in array: + if not key in args['valid_values']: + raise Exception( "Invalid value given in {0!r}({1})".format( args['file'], args['row'] ) ) + if key in res: + self.logger.warn( "Double value {0!r} found in {1!r}({2})".format( key, args['file'], args['row'] ) ) + else: + res.add(key) + + return res + +#----------------------------------------------------------------------- # vim: fileencoding=utf-8 filetype=python ts=4 expandtab