--- /dev/null
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+# $Id$
+# $URL$
+
+import os
+import re
+
+from nagios.object.verify import NagiosVerifyError, NagiosObjectVerifier
+
+class NagiosConfigStructError(Exception):
+ """Base class for exceptions in this module."""
+ pass
+
+class NagiosConfigStruct(object):
+ """Capsulating class for handling with nagios object structures."""
+
+ #------------------------------------------------------
+ def __repr__( self ):
+ "Dumper of hitself"
+
+ dump = {}
+
+ return repr(dump)
+
+ #------------------------------------------------------
+ def __init__( self, logger = None ):
+ "Constructor."
+
+ # Logging-Setup
+ if logger is None:
+
+ self.logger = logging.getLogger('nagiosConfig')
+ self.logger.setLevel(logging.DEBUG)
+
+ 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 __del__( self ):
+ "Destructor"
+
+ self.logger.debug( "Mayday - someone destroys me!!" )
+
+ #------------------------------------------------------
+ def get_valid_object_types( self ):
+ """Returns a set with all valid Nagios object types"""
+
+ return set( {
+ 'host',
+ 'hostgroup',
+ 'service',
+ 'servicegroup',
+ 'contact',
+ 'contactgroup',
+ 'timeperiod',
+ 'command',
+ 'servicedependency',
+ 'serviceescalation',
+ 'hostdependency',
+ 'hostescalation',
+ 'hostextinfo',
+ 'serviceextinfo',
+ } )
+
+ #------------------------------------------------------
+ def get_object_identifier_name( self, object_type ):
+ """Returns an ordered list withe the names of the identifiers of the given object_type."""
+
+ if object_type == 'host':
+ return [ 'host_name' ]
+
+ if object_type == 'hostgroup':
+ return [ 'hostgroup_name' ]
+
+ if object_type == 'service':
+ return [ 'host_name', 'service_description' ]
+
+ if object_type == 'servicegroup':
+ return [ 'servicegroup_name' ]
+
+ if object_type == 'contact':
+ return [ 'contact_name' ]
+
+ if object_type == 'contactgroup':
+ return [ 'contactgroup_name' ]
+
+ if object_type == 'timeperiod':
+ return [ 'timeperiod_name' ]
+
+ if object_type == 'timeperiod':
+ return [ 'timeperiod_name' ]
+
+ if object_type == 'command':
+ return [ 'command_name' ]
+
+ if object_type == 'servicedependency':
+ return [ 'dependent_host_name', 'dependent_service_description', 'host_name', 'service_description' ]
+
+ if object_type == 'serviceescalation':
+ return [ 'host_name', 'service_description', 'first_notification' ]
+
+ if object_type == 'hostdependency':
+ return [ 'dependent_host_name', 'host_name' ]
+
+ if object_type == 'hostescalation':
+ return [ 'host_name', 'first_notification' ]
+
+ if object_type == 'hostextinfo':
+ return [ 'host_name' ]
+
+ if object_type == 'serviceextinfo':
+ return [ 'host_name', 'service_description' ]
+
+ raise NagiosConfigStructError( "Object type {0!r} is invalid.".format( object_type ) )
+
+ #------------------------------------------------------
+ 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."""
+
+ # Check for some strange timeperiod definitions
+ if object_type == 'timeperiod':
+ result = self.check_timeperiod_line_syntax( line )
+ if result is not None:
+ return result
+
+ # Split line into key and value
+ match = re.search( r'^\s*(\w+)\s+(.*)', line )
+ if match is None:
+ raise NagiosConfigStructError( "Couldn't evaluate line {0!r}.".format( line ) )
+
+ key = match.group(1)
+ value = match.group(2)
+
+ # User defined definitions
+ if re.match( r'^_', key ):
+ key_upper = key.upper()
+ return ( key_upper, value )
+
+ verifier = NagiosObjectVerifier( logger = logger )
+ res = None
+ args = dict( file = file, row = rownum )
+
+ # Generic properties for inheritance
+ generic_property = dict(
+ 'name' = 'string',
+ 'use' = 'array',
+ 'register' = 'bool',
+ )
+
+ if key in generic_property:
+ try:
+ res = verifier.verify_property( value, generic_property[key], args )
+ return ( key, res )
+ except NagiosVerifyError as e:
+ raise NagiosConfigStructError( "Property error for {0} definition: {1}".format( object_type, e ) )
+
+
+ return ( key, value )
+
+ #------------------------------------------------------
+ def get_key_checktype( self, key, object_type ):
+ """Returns the checktype and some check parameters of the given key
+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 ) ),
+ ),
+ )
+
+ if object_type not in key_def:
+ return None
+
+ if key not in key_def[object_type]:
+ return None
+
+ return key_def[object_type][key]
+
+ #------------------------------------------------------
+ def check_timeperiod_line_syntax( self, line ):
+ """Verifies the line against a possible timeperiod definition,
+returns a key/value pair on success,
+returns None on failure"""
+
+ # Currently only a stub
+ return None
+
+ #------------------------------------------------------
+
+# vim: fileencoding=utf-8 filetype=python ts=4 expandtab