From 02adc2a4208d394a811028ea4a06cda058cd8cb2 Mon Sep 17 00:00:00 2001 From: Frank Brehm Date: Fri, 3 Dec 2010 15:12:41 +0000 Subject: [PATCH] Umstrukturiert git-svn-id: http://svn.brehm-online.com/svn/my-stuff/nagios/trunk@138 ec8d2aa5-1599-4edb-8739-2b3a1bc399aa --- bin/nagios/cfg/struct.py | 133 ++++++++++++++++++++++----------------- bin/nagios/config.py | 64 +++++-------------- 2 files changed, 92 insertions(+), 105 deletions(-) diff --git a/bin/nagios/cfg/struct.py b/bin/nagios/cfg/struct.py index cc6cc36..fff857c 100755 --- a/bin/nagios/cfg/struct.py +++ b/bin/nagios/cfg/struct.py @@ -55,7 +55,7 @@ class NagiosConfigStruct(object): def get_valid_object_types( self ): """Returns a set with all valid Nagios object types""" - return set( { + return set( [ 'host', 'hostgroup', 'service', @@ -70,7 +70,7 @@ class NagiosConfigStruct(object): 'hostescalation', 'hostextinfo', 'serviceextinfo', - } ) + ] ) #------------------------------------------------------ def get_object_identifier_name( self, object_type ): @@ -127,6 +127,12 @@ class NagiosConfigStruct(object): def check_line_syntax( self, line, object_type, file, rownum ): """Verifying a given line as a property of a Nagios object of given object type.""" + self.logger.debug( "Checking line {0!r} for object type {1!r} in {2!r}({3}).".format( + line, object_type, file, rownum ) ) + + if not object_type in self.get_valid_object_types(): + raise NagiosConfigStructError( "Invalid object type {0!r}.".format( object_type ) ) + # Check for some strange timeperiod definitions if object_type == 'timeperiod': result = self.check_timeperiod_line_syntax( line ) @@ -146,16 +152,16 @@ class NagiosConfigStruct(object): key_upper = key.upper() return ( key_upper, value ) - verifier = NagiosObjectVerifier( logger = logger ) + verifier = NagiosObjectVerifier( logger = self.logger ) res = None - args = dict( file = file, row = rownum ) + args = { 'file': file, 'row': rownum } # Generic properties for inheritance - generic_property = dict( - 'name' = 'string', - 'use' = 'array', - 'register' = 'bool', - ) + generic_property = { + 'name': 'string', + 'use': 'array', + 'register': 'bool', + } if key in generic_property: try: @@ -164,8 +170,21 @@ class NagiosConfigStruct(object): except NagiosVerifyError as e: raise NagiosConfigStructError( "Property error for {0} definition: {1}".format( object_type, e ) ) + checktype_tupel = self.get_key_checktype( key, object_type ) + if checktype_tupel is None: + raise NagiosConfigStructError( "Invalid key {0!r} for hosttype {1!r}.".format( key, object_type ) ) + + if checktype_tupel[1] is not None: + for argkey in checktype_tupel[1]: + argval = checktype_tupel[1][argkey] + args[argkey] = argval + + try: + res = verifier.verify_property( value, checktype_tupel[0], args ) + except NagiosVerifyError as e: + raise NagiosConfigStructError( "Property error for {0} definition: {1}".format( object_type, e ) ) - return ( key, value ) + return ( key, res ) #------------------------------------------------------ def get_key_checktype( self, key, object_type ): @@ -173,53 +192,53 @@ class NagiosConfigStruct(object): dependend to the given object_type. Returns None if the key is invalid.""" - key_def = dict( - 'host' = dict( - 'host_name' = ( 'string', None ), - 'alias' = ( 'string', None ), - 'display_name' = ( 'string', None ), - 'address' = ( 'string', None ), - 'parents' = ( 'array', None ), - 'hostgroups' = ( 'array', None ), - 'check_command' = ( 'string', None ), - 'initial_state' = ( 'set', dict( valid_values = set( [ 'o', 'd', 'u' ] ) ) ), - 'max_check_attempts' = ( 'int', None ), - 'check_interval' = ( 'int', None ), - 'retry_interval' = ( 'int', None ), - 'active_checks_enabled' = ( 'bool', None ), - 'passive_checks_enabled' = ( 'bool', None ), - 'check_period' = ( 'string', None ), - 'obsess_over_host' = ( 'bool', None ), - 'check_freshness' = ( 'bool', None ), - 'freshness_threshold' = ( 'int', None ), - 'event_handler' = ( 'string', None ), - 'event_handler_enabled' = ( 'bool', None ), - 'low_flap_threshold' = ( 'int', None ), - 'high_flap_threshold' = ( 'int', None ), - 'flap_detection_enabled' = ( 'bool', None ), - 'flap_detection_options' = ( 'set', dict( valid_values = set( [ 'o', 'd', 'u' ] ) ) ), - 'process_perf_data' = ( 'bool', None ), - 'retain_status_information' = ( 'bool', None ), - 'retain_nonstatus_information' = ( 'bool', None ), - 'contacts' = ( 'array', None ), - 'contact_groups' = ( 'array', None ), - 'notification_interval' = ( 'int', None ), - 'first_notification_delay' = ( 'int', None ), - 'notification_period' = ( 'string', None ), - 'notification_options' = ( 'set', dict( valid_values = set( [ 'd', 'u', 'r', 'f', 's' ] ) ) ), - 'notifications_enabled' = ( 'bool', None ), - 'stalking_options' = ( 'set', dict( valid_values = set( [ 'o', 'd', 'u' ] ) ) ), - 'notes' = ( 'string', None ), - 'notes_url' = ( 'string', None ), - 'action_url' = ( 'string', None ), - 'icon_image' = ( 'string', None ), - 'icon_image_alt' = ( 'string', None ), - 'vrml_image' = ( 'string', None ), - 'statusmap_image' = ( 'string', None ), - '2d_coords' = ( 'intarray', dict( count_min = 2, count_max = 2 ) ), - '3d_coords' = ( 'intarray', dict( count_min = 3, count_max = 3 ) ), - ), - ) + key_def = { + 'host': { + 'host_name': ( 'string', None ), + 'alias': ( 'string', None ), + 'display_name': ( 'string', None ), + 'address': ( 'string', None ), + 'parents': ( 'array', None ), + 'hostgroups': ( 'array', None ), + 'check_command': ( 'string', None ), + 'initial_state': ( 'set', { 'valid_values': set( [ 'o', 'd', 'u' ] ) } ), + 'max_check_attempts': ( 'int', None ), + 'check_interval': ( 'int', None ), + 'retry_interval': ( 'int', None ), + 'active_checks_enabled': ( 'bool', None ), + 'passive_checks_enabled': ( 'bool', None ), + 'check_period': ( 'string', None ), + 'obsess_over_host': ( 'bool', None ), + 'check_freshness': ( 'bool', None ), + 'freshness_threshold': ( 'int', None ), + 'event_handler': ( 'string', None ), + 'event_handler_enabled': ( 'bool', None ), + 'low_flap_threshold': ( 'int', None ), + 'high_flap_threshold': ( 'int', None ), + 'flap_detection_enabled': ( 'bool', None ), + 'flap_detection_options': ( 'set', { 'valid_values': set( [ 'o', 'd', 'u' ] ) } ), + 'process_perf_data': ( 'bool', None ), + 'retain_status_information': ( 'bool', None ), + 'retain_nonstatus_information': ( 'bool', None ), + 'contacts': ( 'array', None ), + 'contact_groups': ( 'array', None ), + 'notification_interval': ( 'int', None ), + 'first_notification_delay': ( 'int', None ), + 'notification_period': ( 'string', None ), + 'notification_options': ( 'set', { 'valid_values': set( [ 'd', 'u', 'r', 'f', 's' ] ) } ), + 'notifications_enabled': ( 'bool', None ), + 'stalking_options': ( 'set', { 'valid_values': set( [ 'o', 'd', 'u' ] ) } ), + 'notes': ( 'string', None ), + 'notes_url': ( 'string', None ), + 'action_url': ( 'string', None ), + 'icon_image': ( 'string', None ), + 'icon_image_alt': ( 'string', None ), + 'vrml_image': ( 'string', None ), + 'statusmap_image': ( 'string', None ), + '2d_coords': ( 'intarray', { 'count_min': 2, 'count_max': 2 } ), + '3d_coords': ( 'intarray', { 'count_min': 3, 'count_max': 3 } ), + }, + } if object_type not in key_def: return None diff --git a/bin/nagios/config.py b/bin/nagios/config.py index ba5e8d2..948a30e 100644 --- a/bin/nagios/config.py +++ b/bin/nagios/config.py @@ -10,9 +10,8 @@ import sys import warnings import logging import pprint -import nagios.object.host -import nagios.object.hostgroup -import nagios.object.service + +from nagios.cfg.struct import NagiosConfigStruct, NagiosConfigStructError class NagiosConfigError(Exception): """Base class for exceptions in this module.""" @@ -219,6 +218,7 @@ class NagiosConfig(object): self.objects_read = {} files = set([]) dirs = set([]) + self.struct_verifier = NagiosConfigStruct( logger = self.logger ) # cfg_file auswerten if 'cfg_file' in self.conf: @@ -259,6 +259,8 @@ class NagiosConfig(object): pp = pprint.PrettyPrinter( indent = 4, depth = 6, width = 120 ) self.logger.debug( "Gelesene Objekte:\n{0}".format( pp.pformat( self.objects_read ) ) ) + del self.struct_verifier + return #------------------------------------------------------ @@ -302,46 +304,20 @@ class NagiosConfig(object): if not object_type in self.objects_read: self.objects_read[object_type] = [] - # 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 identifier of {0!r}({1})".format( - file_name, rownum ) ) - self.objects_read[object_type].append( struct ) - - if object_type == 'hostgroup': - - ( identifier, struct ) = nagios.object.hostgroup.verify( cur_object, self.logger ) - self.logger.debug( "Found hostgroup 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 hostgroup object identifier of {0!r}({1})".format( - file_name, rownum ) ) - self.objects_read[object_type].append( struct ) - - if object_type == 'service': - - ( identifier, struct ) = nagios.object.service.verify( cur_object, self.logger ) - self.logger.debug( "Found service 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 service object identifier of {0!r}({1})".format( - file_name, rownum ) ) - self.objects_read[object_type].append( struct ) + self.objects_read[object_type].append(cur_object) cur_object = {} self.logger.debug( "Row {0} in {1}: finishing block of type {2!r}".format( row_num, file_name, object_type ) ) else: + match = re.search( r'^define\s+\w+\s*{$', line, re.IGNORECASE ) + if match is not None: + raise NagiosConfigError( "Beginning of a object definition inside a block at {2}({3}).".format( + file_name, row_num ) ) + ( key, value ) = self.check_object_file_entry( line, object_type, file_name, row_num ) + if ( key == None ): self.logger.debug( "nothing found." ) else: @@ -371,20 +347,12 @@ class NagiosConfig(object): #------------------------------------------------------ def check_object_file_entry( self, line, object_type, file_name, row_num ): - line = re.sub( r'\s*;(?!.*").*$', '', line, 0 ) - if line == '': return ( None, None ) - - key = 'key{0!s}'.format( row_num ) - value = line - - match = re.search( r'^\s*(\w+)(?:\s+(.*))?', line ) - if match is None: - self.logger.error( "Konnte Zeile {0} in {1} nicht auswerten: {2!r}.".format( row_num, file_name, line ) ) + try: + ( key, value ) = self.struct_verifier.check_line_syntax( line, object_type, file_name, row_num ) + except NagiosConfigStructError as e: + self.logger.error( "Could not parse row {0} in {1!r}: {2}\n\t{3!r}".format( row_num, file_name, e, line ) ) return ( None, None ) - key = match.group(1) - value = match.group(2) - return ( key, value ) #------------------------------------------------------ -- 2.39.5