--- /dev/null
+import os
+import sys
+import xmlrpclib
+
+### downloaded makeHTML from:
+### article
+### http://www.hoboes.com/Mimsy/?ART=128
+### download \
+### http://www.hoboes.com/Mimsy/library/downloads/makeHTML.py.gz
+import makeHTML
+
+# utilities for building comon queries
+import comon_query
+
+
+class NagiosConfig:
+
+ # static
+ _admin_role=10
+ _pi_role=20
+ # person emails to exclude
+ _exclude_admins={'maint@localhost.localdomain':True}
+
+ # set of services to check on each node
+ # these refer to generic services you must have in generic.cfg
+ _full_node_services = ['ssh',
+ 'ssh-root',
+ 'ssh-pl_conf',
+ ]
+ _restricted_node_services = ['ssh',
+ 'planetlab',
+ ]
+
+ _verbose = False
+# WARNING : some site names come with wierd unicode chars
+# in this case verbose mode might fail
+# _verbose = True
+
+ plchost=None
+ xmlrpcserver = None
+ auth=None
+
+ dest_email = None
+
+ # a tree of sites, for access to nodes and contacts
+ siteTree = None
+ # list of admin people
+ allAdmins = {}
+
+ ### record arguments
+ def __init__ (self, plchost, plcid, plcpasswd, plcrole):
+ self.plchost = plchost
+
+ self.auth={}
+ self.auth['Username'] = plcid
+ self.auth['AuthMethod'] = "password"
+ self.auth['AuthString'] = plcpasswd
+ self.auth['Role']=plcrole
+
+ def Auth (self):
+ return self.auth
+
+ ### connect to xml rpc server
+ def Connect (self):
+
+ try:
+ self.xmlrpcserver = xmlrpclib.Server("https://%s/PLCAPI/"
+ % (self.plchost))
+ except:
+ self.xmlrpcserver = None
+
+ return self.xmlrpcserver
+
+ def set_verbose (self):
+ self._verbose = True
+
+ def verbose (self,arg):
+ if (self._verbose):
+ print str(arg)
+
+ def GatherData (self, email, sitefile):
+
+ # if email is None, we NEED to have admin role
+ # otherwise let's dont wait 10 minutes before we fail
+ AdminRoleRequired = "admin role required, or provide -o/-O"
+ if not email:
+ if self.auth['Role'] != 'admin':
+ raise AdminRoleRequired
+
+ self.dest_email = email
+
+ self.verbose ("Gathering")
+ server = self.Connect()
+ auth = self.Auth ()
+
+ if sitefile:
+ # open and parse the file, let's gather site_ids in the process
+ self.verbose("Opening site file %s"%sitefile)
+ siteF=open(sitefile,'r')
+ selected_ids=[]
+ while 1:
+ siteline=siteF.readline()
+ if not siteline:
+ break
+ selected_ids += [int(siteline.split(' ')[0])]
+ siteF.close()
+ sitesList = server.GetSites(auth,selected_ids)
+ else:
+ # get list of all sites
+ sitesList = server.GetSites(auth)
+ self.verbose("Working on a total of %d sites"%len(sitesList))
+
+ selectedNodeIds = [];
+ for site in sitesList:
+ selectedNodeIds += site['node_ids']
+
+ # get all nodenetworks
+ allNodeNetworks = server.GetNodeNetworks (auth)
+ allNodeNetworksIndex = dict ( [ ( nn['nodenetwork_id'],nn) for nn in allNodeNetworks ] )
+
+ # get list of nodes
+ # might wish to restrict the returned attributes
+ selectedNodes = server.GetNodes(auth,selectedNodeIds,['node_id','hostname','nodenetwork_ids'])
+ self.verbose("Got a total of %d nodes"%len(selectedNodes))
+
+ for node in selectedNodes:
+ if not node['nodenetwork_ids']:
+ print 'WARNING : Node %s has no nodenetwork thus no IP'%node['hostname']
+ nn = allNodeNetworksIndex[node['nodenetwork_ids'][0]]
+ node['ip'] = nn['ip']
+
+
+ # index it by node_id
+ selectedNodesIndex = dict( [ (node['node_id'],node) for node in selectedNodes ] )
+
+ self.siteTree = {}
+ for site in sitesList :
+ self.verbose( "SITE = %s" % site['name'])
+ site_id=site['site_id']
+ siteHash = {}
+ self.siteTree[site_id] = siteHash
+ node_ids = site['node_ids']
+ self.verbose( "NODES IDS = " + str(node_ids))
+ siteNodes=[ selectedNodesIndex[node_id] for node_id in node_ids ]
+ nodesHash = dict ( [ (node['node_id'],node) for node in siteNodes ] )
+ personsHash = {}
+ siteHash['site'] = site
+ siteHash['nodes'] = nodesHash
+ siteHash['persons'] = personsHash
+
+ # We are provided a hard-wired e-mail :
+ # dont scan all people (maybe we cannot)
+ if not email:
+
+ # get list of people
+ allPersons = server.GetPersons (auth, [],['person_id','email',
+ 'first_name','last_name'])
+ for person in allPersons:
+ person_id = person['person_id']
+ # keep only PIs
+ roles = server.AdmGetPersonRoles (auth,person_id)
+ is_admin = roles.has_key(str(self._admin_role))
+ is_pi = roles.has_key(str(self._pi_role))
+ if is_admin:
+ ### handle exclude list
+ if not self._exclude_admins.has_key(person['email']):
+ self.allAdmins[person_id]=person
+ elif is_pi:
+ person_sites=server.AdmGetPersonSites(auth,person_id)
+ for site_id in person_sites:
+ personsHash = self.siteTree[site_id]['persons']
+ personsHash[person_id]=person
+ person['full_name']=person['first_name']+person['last_name']
+ self.verbose("Added PI %s" % person['full_name'])
+
+ _define_host="""define host{
+ use generic-host
+ host_name %s
+ alias %s
+ address %s
+ contact_groups %s_pis
+ }\n"""
+ _define_hostgroup="""define hostgroup{
+ hostgroup_name %s
+ alias %s
+ members %s
+ }\n"""
+ # as of nagios-2.5-2.fc4 - apparently cannot use genericity in contacts
+ _define_contact="""define contact{
+ contact_name %s
+ alias %s %s
+ email %s
+ service_notification_period 24x7
+ host_notification_period 24x7
+ service_notification_options w,u,c,r
+ host_notification_options d,r
+ service_notification_commands notify-by-email
+ host_notification_commands host-notify-by-email
+ }\n"""
+ _define_contactgroup="""define contactgroup{
+ contactgroup_name %s_pis
+ alias %s
+ members %s
+ }\n"""
+ _define_service="""define service{
+ use generic-%s
+ host_name %s
+ contact_groups %s_pis
+ servicegroups %s
+ }\n"""
+ _define_servicegroup="""define servicegroup{
+ servicegroup_name %s
+ alias all %s
+ }\n"""
+
+ def WriteNagiosConfig (self, dirname):
+
+ site_ids=self.siteTree.keys()
+ site_ids.sort()
+
+
+ # by default use all avail services
+ node_services = self._full_node_services
+ # but in restricted mode some wont work out
+ if self.dest_email:
+ node_services = self._restricted_node_services
+
+ # generate contact file
+ # with people with admin roles, and also
+ # centraladmin if email was provided
+ # located in main dir so we can have control on load order
+ filename = "%s/%s.cfg"%(dirname,"planetlab")
+ print ( "Opening %s for writing" % filename)
+ file = open (filename,'w')
+ for admin_id in self.allAdmins.keys():
+ admin=self.allAdmins[admin_id]
+ file.write(self._define_contact%
+ ('rootadmin','root','admin',admin['email']))
+ if self.dest_email:
+ file.write(self._define_contact%
+ (self.dest_email,'central','admin',self.dest_email))
+
+ for service in node_services:
+ file.write(self._define_servicegroup
+ %(service,service))
+
+ file.close()
+
+ ### manage planetlab subdir
+ planetlabdir="%s/planetlab/"%dirname
+ import os.path
+ if not os.path.isdir (planetlabdir):
+ try:
+ print "Trying to create subdir %s"%planetlabdir
+ os.mkdir (planetlabdir)
+ except Exception,e:
+ print "Failed -- exiting"
+ sys.exit(1)
+
+ import dircache
+ ls = dircache.listdir(planetlabdir)
+ import re
+ m=re.compile('^.*\.cfg$')
+ cfgs=filter(lambda x: m.match(x),ls)
+ if len(cfgs) != 0:
+ print "Warning : you have %d nagios configs left in %s"%(
+ len(cfgs),planetlabdir)
+ print "It's OK to keep them, if that's what you're trying to do"
+
+ ### scan over sites
+ for site_id in site_ids:
+
+ siteHash=self.siteTree[site_id]
+ site = siteHash['site']
+ sitename = site['name']
+ sitebase = site['login_base']
+
+ nodes = siteHash['nodes']
+ node_ids = nodes.keys()
+ node_ids.sort()
+ if len(node_ids) != 0:
+
+ filename = "%s/%s.cfg"%(planetlabdir,sitebase)
+ print ( "Opening %s for writing" % filename)
+ file = open (filename,'w')
+
+ ### without email / use real people
+ if not self.dest_email:
+ persons = siteHash ['persons']
+
+ self.verbose("retrieved PIs = %s"%str(persons))
+
+ if len(persons) != 0:
+ personnames=''
+ for person_id in persons.keys():
+ person=persons[person_id]
+ personname=person['full_name']
+ if len(personnames) == 0:
+ personnames = personname
+ else:
+ personnames = "%s,%s"%(personnames,personname)
+ file.write(self._define_contact
+ %(personname,
+ person['first_name'],
+ person['last_name'],
+ person['email']))
+
+ file.write(self._define_contactgroup
+ %(sitebase,sitename,personnames))
+ else:
+ file.write(self._define_contactgroup
+ %(sitebase,sitename,self.dest_email))
+
+
+ nodenames=""
+ for node_id in node_ids:
+ node = nodes[node_id]
+ if len(nodenames) == 0:
+ nodenames = node['hostname']
+ else:
+ nodenames = "%s,%s"%(nodenames,node['hostname'])
+ file.write(self._define_host
+ %(node['hostname'],node['hostname'],
+ node['ip'],sitebase))
+
+ for service in node_services:
+ file.write(self._define_service
+ %(service,node['hostname'],sitebase,service))
+
+
+ file.write(self._define_hostgroup
+ %(sitebase,sitename,nodenames))
+
+ file.close()
+
+#################### static html file with bookmarks to comon site-centric queries
+# a first draft tried to create a column for easying the bookmarking process
+# I did not completely succeed, because
+# the javascript interface for firefox seems to only allow
+# the creation of bookmarks in the sidebar
+# in fact you can bookmark the link, but when you use that bookmark
+# the target url is opened in the sidebar
+# you can easily fix this by editing the bookmark and uncheck
+# a dialob box, but that's not what we want
+# it's much easier to directly use the 'Bookmark this link'
+# from the firefox menu
+# so let's forget about this altogether
+
+# ### bookmarks
+# def ManualBookmark (self, url, text, bookmark_name):
+# bookmark_link="""<a href='javascript:addToFavorites("%s","%s")'>
+# <font color='#0000FF' face="Verdana">%s</font></a>"""
+# # the single quotes in the URL need to be html-encoded
+# cleanurl = url.replace ("'","%27")
+# return bookmark_link%(makeHTML.encode(cleanurl),bookmark_name,text)
+#
+# bookmark_code="""<script language="JavaScript" type="Text/Javascript">
+#<!-- // Hide script from older browsers
+# // script by http://www.hypergurl.com
+# function addToFavorites(url,title) {
+# if (window.sidebar) { // Mozilla Firefox Bookmark
+# window.sidebar.addPanel(title, url,"");
+# } else if (window.external) { // IE Favorite
+# window.external.AddFavorite(url,title)
+# } else {
+# alert("Sorry! Your browser doesn't support this function.");
+# }
+# }
+#// -->
+#</script>""" ### ' for fooling emacs
+
+ def ComonNodesSelect (self,nodes):
+ names = map(lambda node: node['hostname'],nodes)
+ filters = map (comon_query.filter_node,names)
+ server = comon_query.SERVER
+ return comon_query.full_url(server,'||'.join(filters))
+
+ ### could not find the makeHTML tool for that
+ def ManualAnchor (self,name,value):
+ return '<a name="%s">%s</a>' % (name,value)
+
+ def SiteRow (self,site_id):
+ ### returns a (makeHTML) row for the given site
+
+ siteHash = self.siteTree[site_id]
+ site = siteHash['site']
+ sitename = site['name']
+ sitebase = site['login_base']
+
+ nodes = siteHash['nodes'].values()
+ if len(nodes) == 0 :
+ return None
+ else:
+ row = makeHTML.tableRow()
+ query=self.ComonNodesSelect(nodes)
+ row.addCells([makeHTML.link(content=sitename, url=query),
+ self.ManualAnchor(sitebase,sitebase),
+# self.ManualBookmark(query,
+# "Bookmark it",
+# "Comon on %s"%sitename),
+ ])
+ return row
+
+ def MakeSiteTable (self, sites):
+ ### create table / sitename
+ table = makeHTML.table ()
+ ### first row
+ head_row = makeHTML.tableRow()
+ head_row.addCells ( ['Site name',
+ 'Site login',
+# 'Comon query',
+ ])
+ table.addRow(rowList=[head_row])
+
+ for site in sites:
+ table.addRow ( rowList=[self.SiteRow(site['site_id'])])
+ return table
+
+ ### Write a single index page that contains one bookmark per site
+ def WriteComonLinks (self, indexname):
+
+ pageHead = makeHTML.part('head')
+ pageHead.addPart('title',content='Comon links for all sites')
+# pageHead.addPiece(bookmark_code)
+
+ pageBody = makeHTML.part('body')
+ pageBody.addPart('h1',content='Comon links, per site')
+
+ sites = map(lambda s: s['site'],self.siteTree.values())
+
+ pageBody.addPart('h2',content='By site name')
+
+ sites.sort (lambda s1,s2: cmp(s1['name'],s2['name']))
+ pageBody.addPart('p',self.MakeSiteTable(sites))
+
+ pageBody.addPart('h2',content='By site login')
+
+ sites.sort (lambda s1,s2: cmp(s1['login_base'],s2['login_base']))
+ pageBody.addPart('p',self.MakeSiteTable(sites))
+
+ fullPage = makeHTML.part('html')
+ fullPage.addPiece(pageHead)
+ fullPage.addPiece(pageBody)
+
+ text=fullPage.make()
+
+ print ( "Opening %s for writing" % indexname)
+ index=open (indexname,"w")
+ index.write(text+"\n")
+ index.close()
--- /dev/null
+#################################################################
+#
+# CGI.CFG - Sample CGI Configuration File for Nagios
+#
+# Last Modified: 05-05-2005
+#
+#################################################################
+
+
+# MAIN CONFIGURATION FILE
+# This tells the CGIs where to find your main configuration file.
+# The CGIs will read the main and host config files for any other
+# data they might need.
+
+main_config_file=/etc/nagios/nagios.cfg
+
+
+
+# PHYSICAL HTML PATH
+# This is the path where the HTML files for Nagios reside. This
+# value is used to locate the logo images needed by the statusmap
+# and statuswrl CGIs.
+
+physical_html_path=/usr/share/nagios/share
+
+
+
+# URL HTML PATH
+# This is the path portion of the URL that corresponds to the
+# physical location of the Nagios HTML files (as defined above).
+# This value is used by the CGIs to locate the online documentation
+# and graphics. If you access the Nagios pages with an URL like
+# http://www.myhost.com/nagios, this value should be '/nagios'
+# (without the quotes).
+
+url_html_path=/nagios
+
+
+
+# CONTEXT-SENSITIVE HELP
+# This option determines whether or not a context-sensitive
+# help icon will be displayed for most of the CGIs.
+# Values: 0 = disables context-sensitive help
+# 1 = enables context-sensitive help
+
+show_context_help=0
+
+
+
+# NAGIOS PROCESS CHECK COMMAND
+# This is the full path and filename of the program used to check
+# the status of the Nagios process. It is used only by the CGIs
+# and is completely optional. However, if you don't use it, you'll
+# see warning messages in the CGIs about the Nagios process
+# not running and you won't be able to execute any commands from
+# the web interface. The program should follow the same rules
+# as plugins; the return codes are the same as for the plugins,
+# it should have timeout protection, it should output something
+# to STDIO, etc.
+#
+# Note: The command line for the check_nagios plugin below may
+# have to be tweaked a bit, as different versions of the plugin
+# use different command line arguments/syntaxes.
+
+nagios_check_command=/usr/lib/nagios/plugins/check_nagios /var/log/nagios/status.dat 5 '/usr/sbin/nagios'
+
+
+
+# AUTHENTICATION USAGE
+# This option controls whether or not the CGIs will use any
+# authentication when displaying host and service information, as
+# well as committing commands to Nagios for processing.
+#
+# Read the HTML documentation to learn how the authorization works!
+#
+# NOTE: It is a really *bad* idea to disable authorization, unless
+# you plan on removing the command CGI (cmd.cgi)! Failure to do
+# so will leave you wide open to kiddies messing with Nagios and
+# possibly hitting you with a denial of service attack by filling up
+# your drive by continuously writing to your command file!
+#
+# Setting this value to 0 will cause the CGIs to *not* use
+# authentication (bad idea), while any other value will make them
+# use the authentication functions (the default).
+
+use_authentication=1
+
+
+
+# DEFAULT USER
+# Setting this variable will define a default user name that can
+# access pages without authentication. This allows people within a
+# secure domain (i.e., behind a firewall) to see the current status
+# without authenticating. You may want to use this to avoid basic
+# authentication if you are not using a sercure server since basic
+# authentication transmits passwords in the clear.
+#
+# Important: Do not define a default username unless you are
+# running a secure web server and are sure that everyone who has
+# access to the CGIs has been authenticated in some manner! If you
+# define this variable, anyone who has not authenticated to the web
+# server will inherit all rights you assign to this user!
+
+#default_user_name=guest
+
+
+
+# SYSTEM/PROCESS INFORMATION ACCESS
+# This option is a comma-delimited list of all usernames that
+# have access to viewing the Nagios process information as
+# provided by the Extended Information CGI (extinfo.cgi). By
+# default, *no one* has access to this unless you choose to
+# not use authorization. You may use an asterisk (*) to
+# authorize any user who has authenticated to the web server.
+
+#authorized_for_system_information=nagiosadmin,theboss,jdoe
+
+
+
+# CONFIGURATION INFORMATION ACCESS
+# This option is a comma-delimited list of all usernames that
+# can view ALL configuration information (hosts, commands, etc).
+# By default, users can only view configuration information
+# for the hosts and services they are contacts for. You may use
+# an asterisk (*) to authorize any user who has authenticated
+# to the web server.
+
+#authorized_for_configuration_information=nagiosadmin,jdoe
+
+
+
+# SYSTEM/PROCESS COMMAND ACCESS
+# This option is a comma-delimited list of all usernames that
+# can issue shutdown and restart commands to Nagios via the
+# command CGI (cmd.cgi). Users in this list can also change
+# the program mode to active or standby. By default, *no one*
+# has access to this unless you choose to not use authorization.
+# You may use an asterisk (*) to authorize any user who has
+# authenticated to the web server.
+
+#authorized_for_system_commands=nagiosadmin
+
+
+
+# GLOBAL HOST/SERVICE VIEW ACCESS
+# These two options are comma-delimited lists of all usernames that
+# can view information for all hosts and services that are being
+# monitored. By default, users can only view information
+# for hosts or services that they are contacts for (unless you
+# you choose to not use authorization). You may use an asterisk (*)
+# to authorize any user who has authenticated to the web server.
+
+
+authorized_for_all_services=thierry.parmentelat@sophia.inria.fr
+authorized_for_all_hosts=thierry.parmentelat@sophia.inria.fr
+
+
+
+# GLOBAL HOST/SERVICE COMMAND ACCESS
+# These two options are comma-delimited lists of all usernames that
+# can issue host or service related commands via the command
+# CGI (cmd.cgi) for all hosts and services that are being monitored.
+# By default, users can only issue commands for hosts or services
+# that they are contacts for (unless you you choose to not use
+# authorization). You may use an asterisk (*) to authorize any
+# user who has authenticated to the web server.
+
+#authorized_for_all_service_commands=nagiosadmin
+#authorized_for_all_host_commands=nagiosadmin
+
+
+
+
+# STATUSMAP BACKGROUND IMAGE
+# This option allows you to specify an image to be used as a
+# background in the statusmap CGI. It is assumed that the image
+# resides in the HTML images path (i.e. /usr/local/nagios/share/images).
+# This path is automatically determined by appending "/images"
+# to the path specified by the 'physical_html_path' directive.
+# Note: The image file may be in GIF, PNG, JPEG, or GD2 format.
+# However, I recommend that you convert your image to GD2 format
+# (uncompressed), as this will cause less CPU load when the CGI
+# generates the image.
+
+#statusmap_background_image=smbackground.gd2
+
+
+
+# DEFAULT STATUSMAP LAYOUT METHOD
+# This option allows you to specify the default layout method
+# the statusmap CGI should use for drawing hosts. If you do
+# not use this option, the default is to use user-defined
+# coordinates. Valid options are as follows:
+# 0 = User-defined coordinates
+# 1 = Depth layers
+# 2 = Collapsed tree
+# 3 = Balanced tree
+# 4 = Circular
+# 5 = Circular (Marked Up)
+
+default_statusmap_layout=5
+
+
+
+# DEFAULT STATUSWRL LAYOUT METHOD
+# This option allows you to specify the default layout method
+# the statuswrl (VRML) CGI should use for drawing hosts. If you
+# do not use this option, the default is to use user-defined
+# coordinates. Valid options are as follows:
+# 0 = User-defined coordinates
+# 2 = Collapsed tree
+# 3 = Balanced tree
+# 4 = Circular
+
+default_statuswrl_layout=4
+
+
+
+# STATUSWRL INCLUDE
+# This option allows you to include your own objects in the
+# generated VRML world. It is assumed that the file
+# resides in the HTML path (i.e. /usr/local/nagios/share).
+
+#statuswrl_include=myworld.wrl
+
+
+
+# PING SYNTAX
+# This option determines what syntax should be used when
+# attempting to ping a host from the WAP interface (using
+# the statuswml CGI. You must include the full path to
+# the ping binary, along with all required options. The
+# $HOSTADDRESS$ macro is substituted with the address of
+# the host before the command is executed.
+# Please note that the syntax for the ping binary is
+# notorious for being different on virtually ever *NIX
+# OS and distribution, so you may have to tweak this to
+# work on your system.
+
+ping_syntax=/bin/ping -n -U -c 5 $HOSTADDRESS$
+
+
+
+# REFRESH RATE
+# This option allows you to specify the refresh rate in seconds
+# of various CGIs (status, statusmap, extinfo, and outages).
+
+refresh_rate=90
+
+
+
+# SOUND OPTIONS
+# These options allow you to specify an optional audio file
+# that should be played in your browser window when there are
+# problems on the network. The audio files are used only in
+# the status CGI. Only the sound for the most critical problem
+# will be played. Order of importance (higher to lower) is as
+# follows: unreachable hosts, down hosts, critical services,
+# warning services, and unknown services. If there are no
+# visible problems, the sound file optionally specified by
+# 'normal_sound' variable will be played.
+#
+#
+# <varname>=<sound_file>
+#
+# Note: All audio files must be placed in the /media subdirectory
+# under the HTML path (i.e. /usr/local/nagios/share/media/).
+
+#host_unreachable_sound=hostdown.wav
+#host_down_sound=hostdown.wav
+#service_critical_sound=critical.wav
+#service_warning_sound=warning.wav
+#service_unknown_sound=warning.wav
+#normal_sound=noproblem.wav
+
--- /dev/null
+#!/usr/bin/env python
+
+#
+# This module checks for a planetlab node by
+# (*) connecting to the comon central query interface
+# (*) retrieving the latest info for a given node
+#
+
+import sys
+import socket
+import re
+import string
+import urllib2
+
+import nagios
+
+# default server
+SERVER='summer.cs.princeton.edu'
+
+NodeUnknownException="NodeUnknownByComon"
+
+####################
+def check (node,server=None):
+
+ if (server == None):
+ server = SERVER
+
+ try:
+
+ # compute node IP number
+ node_address = compute_address (node)
+# print 'int address',node_address
+ # build URL, connect and return attributes dict
+ node_dict = query_node (server,node_address)
+ for key in node_dict.keys():
+ print key,node_dict[key]
+ # interpret
+ return interpret (node_dict)
+
+ except NodeUnknownException:
+ return nagios.UNKNOWN
+ except Exception,e:
+ print "comon_query.check got exception",e
+ return nagios.UNKNOWN
+
+##########
+re_dec="([0-9]{1,3})"
+re_ipsep="\."
+re_ip=(re_dec+re_ipsep)*3+re_dec
+ma_ip = re.compile (re_ip)
+
+def compute_address (nodename):
+ ip=socket.gethostbyname(nodename)
+ ints=map(int,ma_ip.match(ip).groups())
+ res=ints[0]
+ for i in range(1,4):
+ res = (res*256)+ints[i]
+ return res
+
+##########
+URL_FORMAT="http://%s/status/tabulator.cgi"
+ARGS_FORMAT="table=table_nodeviewshort&select='%s'"
+FILTER_FORMAT="address==%d"
+CSV_FORMAT="&format=formatcsv"
+
+def filter_address (address):
+ return FILTER_FORMAT%address
+def filter_node (nodename):
+ return filter_address(compute_address(nodename))
+
+def full_url (server, filter):
+ return (URL_FORMAT%server
+ + '?'
+ + ARGS_FORMAT%filter)
+
+def full_url_csv (server,filter):
+ return full_url(server,filter)+CSV_FORMAT
+
+
+# mention field here means we'll parse it and keep it
+# see store_dict below
+FIELDS_FOCUS={
+ 'resptime': 'float',
+ 'sshstatus':'int',
+ 'bootstate':'string',
+ }
+
+NOTHING_MATCHED='nothing matched select statement'
+##########
+def query_node (server,address):
+ filter=filter_address(address)
+ full_url=full_url_csv(server,filter)
+ req = urllib2.urlopen(full_url)
+ # let's parse this manually
+ headers=map(string.strip,req.readline().split(','))
+ # handle the case where the node is unknown to comon
+ values=req.readline()
+ if values.find(NOTHING_MATCHED) != -1:
+ raise NodeUnknownException
+
+ values=values.split(',')
+
+ print 'h',headers
+ print 'v', values
+
+ dict={}
+# store_dict=lambda key,val: dict[key]=val
+# -> SyntaxError: can't assign to lambda
+ def store_dict (key,val):
+ if FIELDS_FOCUS.has_key(key):
+ format = FIELDS_FOCUS[key]
+ if format == 'float':
+ dict[key]=float(val)
+ elif format == 'int':
+ dict[key]=int(val)
+ elif format == 'string':
+ dict[key]=string.strip(val)
+ map (store_dict, headers, values)
+
+ return dict
+
+##########
+# function for decomposing a number along units
+# tuple [n] must be a multiple of tuple[n+1]
+# e.g.
+# 1223456, (10000, 500, 10) -> (122, 68, 5)
+# coz 1223456 = 122*10000 + 68*500 + 5*10 + 6
+def split_number (n,tuple):
+ result=()
+ for i in range(0,len(tuple)):
+ base=tuple[i]
+ result+=(n/base,)
+ n=n%base
+ return result
+
+###
+MINUTE=60
+HOUR=60*MINUTE
+DAY=HOUR*24
+WEEK=DAY*7
+MONTH=DAY*30
+
+# from a delay in seconds, returns a human-readable string
+def seconds_printable (seconds):
+ month,week,day,hour,minute = split_number(seconds,
+ (MONTH,WEEK,DAY,HOUR,MINUTE))
+ if month != 0:
+ return "%d month(s), %d weeks, %d day(s)"%(month,week,day)
+ elif week !=0:
+ return "%d weeks, %d day(s), %d hour(s)"%(week,day,hour)
+ elif day != 0:
+ return "%d day(s), %d hour(s)"%(day,hour)
+ elif hour != 0:
+ return "%d hour(s), %d minute(s)"%(hour,minute)
+ else:
+ return "%d minute(s)"%(minute)
+
+##########
+def interpret (dict):
+ # check sshstatus is null
+ sshstatus=dict['sshstatus']
+ if sshstatus != 0:
+ print 'No response to comon/ssh for %s'%seconds_printable(sshstatus)
+ if sshstatus >= 10*MINUTE:
+ return nagios.KO
+ else:
+ return nagios.WARNING
+ else:
+ # let's focus on resptime
+ resptime = dict['resptime']
+ print "Response time as measured by comon = %.2f s"%resptime
+ if resptime >= 10.0:
+ return nagios.KO
+ elif resptime >= 5.0:
+ return nagios.WARNING
+ else:
+ return nagios.OK
+
+#################### quick test
+def usage():
+ print "Usage comon_query.py node"
+ sys.exit(1)
+
+if __name__=='__main__':
+ if len(sys.argv) != 2:
+ usage()
+ print 'comon_query.check would return %d'%check(sys.argv[1])
+# print 'get >%s<',seconds_printable(int(sys.argv[1]))
--- /dev/null
+#!/usr/bin/env python
+
+# WARNING - you might need to set your locale before you can run this script
+# e.g.
+# export LANG=en_US.UTF-8
+# nagios.py ...
+
+import sys
+import getopt
+
+from NagiosConfig import NagiosConfig
+
+SERVER="www.planet-lab.org"
+DIRNAME="/etc/nagios"
+
+options='h:o:Os:d:nNv'
+
+usage_string="""Usage : %s [options] plc-id plc-passwd role
+Outputs a nagios config for watching a given set of sites
+Also writes a static HTML page for bookmarking site-centric queries to comon
+Options:
+ -h plc-hostname To provide an alternate plc hostname
+ (defaults to %s)
+ -o e-mail If you provide an e-mail address, all notifications
+ will be sent there. Otherwise, you'll need admin role
+ so that we can determine the respective PI's e-mails
+ -O same as -e with the plc-id as dest. e-mail
+ -s site-file You can provide a list of sites in a separate file
+ expected format is one line per site, site_id first
+ the default is to list all sites
+ -d dirname To specify an alternate output dir
+ (defaults to %s)
+ -n Does not generate the nagios config
+ -N Does not generate the HTML page
+ -v Runs in verbose mode
+"""%(sys.argv[0],SERVER,DIRNAME)
+
+def usage ():
+ print usage_string
+ sys.exit(1)
+
+
+def main ():
+ command = sys.argv[0]
+ argv = sys.argv[1:]
+
+ try:
+ opts,args = getopt.getopt(argv, options)
+ except getopt.GetoptError:
+ print "Unknown option"
+ usage()
+
+ plc_server=SERVER
+ output_mail=None
+ opt_same_email=False
+ site_file=None
+ dirname=DIRNAME
+ opt_nagios = True
+ opt_html = True
+ opt_verbose = False
+
+ for o,a in opts:
+ if o in ['-h']:
+ plc_server = a
+ elif o in ['-o']:
+ output_mail = a
+ elif o in ['-O']:
+ opt_same_email = True
+ elif o in ['-s']:
+ site_file = a
+ elif o in ['-d']:
+ dirname = a
+ elif o in ['-n']:
+ opt_nagios = False
+ elif o in ['-N']:
+ opt_html = False
+ elif o in ['-v']:
+ opt_verbose = True
+ else:
+ print "Unknown option",o
+ usage()
+
+ if not len(args) == 3:
+ usage()
+
+ (plc_id,passwd,role) = args
+ if opt_same_email:
+ output_mail=plc_id
+
+# print plc_server,output_mail,dirname,opt_nagios,opt_html
+# print plc_id,passwd,role,site_file
+
+ print "Connecting to %s and gathering data"%plc_server
+ config = NagiosConfig (plc_server,plc_id,passwd,role)
+ if opt_verbose:
+ config.set_verbose()
+ config.GatherData (output_mail,site_file)
+
+ if opt_nagios:
+ print "Creating nagios config in %s"%dirname
+ config.WriteNagiosConfig (dirname)
+
+ if opt_html:
+ html_page = "%s/comon.html"%dirname
+ config.WriteComonLinks (html_page)
+
+
+####################
+if __name__ == "__main__":
+ main ()
+
--- /dev/null
+###############################################################################
+# MINIMAL.CFG
+#
+# MINIMALISTIC OBJECT CONFIG FILE (Template-Based Object File Format)
+#
+# Last Modified: 05-30-2006
+#
+#
+# NOTE: This config file is intended to be used to test a Nagios installation
+# that has been compiled with support for the template-based object
+# configuration files.
+#
+# This config file is intended to servce as an *extremely* simple
+# example of how you can create your object configuration file(s).
+# If you're interested in more complex object configuration files for
+# Nagios, look in the sample-config/template-object/ subdirectory of
+# the distribution.
+#
+###############################################################################
+
+
+
+###############################################################################
+###############################################################################
+#
+# TIME PERIODS
+#
+###############################################################################
+###############################################################################
+
+# This defines a timeperiod where all times are valid for checks,
+# notifications, etc. The classic "24x7" support nightmare. :-)
+
+define timeperiod{
+ timeperiod_name 24x7
+ alias 24 Hours A Day, 7 Days A Week
+ sunday 00:00-24:00
+ monday 00:00-24:00
+ tuesday 00:00-24:00
+ wednesday 00:00-24:00
+ thursday 00:00-24:00
+ friday 00:00-24:00
+ saturday 00:00-24:00
+ }
+
+
+################################################################################
+#
+# SERVICE CHECK COMMANDS
+#
+################################################################################
+
+# 'check_udp' command definition
+define command{
+ command_name check_udp
+ command_line $USER1$/check_udp -H $HOSTADDRESS$ -p $ARG1$
+ }
+
+define command{
+ command_name check_ssh
+ command_line $USER1$/check_ssh $HOSTADDRESS$
+ }
+
+define command{
+ command_name check_ssh_root
+ command_line $USER1$/check_by_ssh -H $HOSTADDRESS$ -l root -i /etc/nagios/root_ssh_key.rsa -C date
+ }
+
+define command{
+ command_name check_ssh_pl_conf
+ command_line $USER1$/check_by_ssh -H $HOSTADDRESS$ -l root -i /etc/nagios/root_ssh_key.rsa -C "server pl_conf status 2>/dev/null"
+ }
+
+define command{
+ command_name check_planetlab
+ command_line $USER1$/check_planetlab.py -t 3 $HOSTADDRESS$
+ }
+
+################################################################################
+#
+# HOST CHECK COMMAND
+#
+################################################################################
+
+# This command checks to see if a host is "alive" by pinging it
+# The check must result in a 100% packet loss or 5 second (5000ms) round trip
+# average time to produce a critical error.
+# Note: Only one ICMP echo packet is sent (determined by the '-p 1' argument)
+
+# 'check-host-alive' command definition
+define command{
+ command_name check-host-alive
+ command_line $USER1$/check_ping -H $HOSTADDRESS$ -w 3000.0,40% -c 5000.0,80% -p 1
+ }
+
+###############################################################################
+###############################################################################
+#
+# HOSTS
+#
+###############################################################################
+###############################################################################
+
+# Generic host definition template - This is NOT a real host, just a template!
+
+define host{
+ name generic-host ; The name of this host template
+ notifications_enabled 1 ; Host notifications are enabled
+ event_handler_enabled 1 ; Host event handler is enabled
+ flap_detection_enabled 1 ; Flap detection is enabled
+ failure_prediction_enabled 1 ; Failure prediction is enabled
+ process_perf_data 1 ; Process performance data
+ retain_status_information 1 ; Retain status information across program restarts
+ retain_nonstatus_information 1 ; Retain non-status information across program restarts
+ check_command check-host-alive
+ max_check_attempts 10
+ check_period 24x7
+ notification_interval 1440
+ notification_period 24x7
+ notification_options d,r
+ register 0 ; DONT REGISTER THIS DEFINITION - ITS NOT A REAL HOST, JUST A TEMPLATE!
+ }
+
+# actual hosts to be defined by python in planetlab.cfg
+
+###############################################################################
+###############################################################################
+#
+# SERVICES
+#
+###############################################################################
+###############################################################################
+
+# Generic service definition template - This is NOT a real service, just a template!
+
+define service{
+ name generic-service ; The 'name' of this service template
+ active_checks_enabled 1 ; Active service checks are enabled
+ passive_checks_enabled 1 ; Passive service checks are enabled/accepted
+ parallelize_check 1 ; Active service checks should be parallelized (disabling this can lead to major performance problems)
+ obsess_over_service 1 ; We should obsess over this service (if necessary)
+ check_freshness 0 ; Default is to NOT check service 'freshness'
+ notifications_enabled 1 ; Service notifications are enabled
+ event_handler_enabled 1 ; Service event handler is enabled
+ flap_detection_enabled 1 ; Flap detection is enabled
+ failure_prediction_enabled 1 ; Failure prediction is enabled
+ process_perf_data 1 ; Process performance data
+ retain_status_information 1 ; Retain status information across program restarts
+ retain_nonstatus_information 1 ; Retain non-status information across program restarts
+ register 0 ; DONT REGISTER THIS DEFINITION - ITS NOT A REAL SERVICE, JUST A TEMPLATE!
+ is_volatile 0
+ check_period 24x7
+ max_check_attempts 2
+ normal_check_interval 240 ; every 2 hours is OK
+ retry_check_interval 5
+###
+ notification_options c,r
+ notification_interval 1440
+ notification_period 24x7
+ }
+
+
+### ping tunings
+# warning is set to 2 seconds, 40% packet loss
+# critical is set to 5 seconds, 80% packet loss
+### We DONT register this service because it's basically what nagios reverts to
+# if the others services turn out to be not responding
+define service{
+ use generic-service
+ name generic-ping
+ service_description ping
+# check_command check_ping!100.0,20%!500.0,60%
+ check_command check_ping!2000.0,40%!5000.0,80%
+ register 0
+ }
+
+
+define service{
+ use generic-service
+ name generic-ssh
+ service_description ssh server
+ check_command check_ssh
+ register 0
+ }
+
+define service{
+ use generic-service
+ name generic-ssh-root
+ service_description ssh root
+ check_command check_ssh_root
+ register 0
+ }
+
+define service{
+ use generic-service
+ name generic-ssh-pl_conf
+ service_description pl_conf vserver
+ check_command check_ssh_pl_conf
+ register 0
+ }
+
+define service{
+ use generic-service
+ name generic-planetlab
+ service_description comon
+ check_command check_planetlab
+ register 0
+ }
+
+# actual services to be defined by python in planetlab.cfg
+
+# EOF
--- /dev/null
+#makeHTML.py version 0.8 May 1, 2005 Jerry Stratton
+#
+#part(code="tag" (defaults to paragraph), content="text" style="css style name", id="css id", attributes={named array of attributes for tag}
+# addAttribute(attributename="name for tag attribute", attributevalue="value for tag attribute")
+# addPart(code, content, style, id, attributes): adds at end
+# addPiece(thePart=another part object or "content text")
+# addPieces(pices=a list of part objects or content texts)
+# insertPart(code, content, style, id, attributes): inserts at start
+# insertPiece(thePart)
+# make(tab="initial tabs")
+# makePart(code, content, style, id, attributes): returns a part object
+# __len__: parts support the len() function; return number of pieces directly contained
+#snippet(code (defaults to "em"), content, posttext="text that comes directly after tag", pretext="text that comes directly before tag", style, id, attributes)
+#
+#head(title="text for title of page")
+#body(title="text for main headline", style, id, attributes)
+#page(pieces, style, id, attributes)
+#styleSheet(sheet="url of stylesheet", media="relevance of style sheet")
+#
+#headline(content="text content" (required), level="numerical level", style, id, attributes)
+#
+#table(rows=list of data for rows, style, thStyle="css style for table headers", tdStyle="css style for table cells",
+# trStyle="css style for table rows", tdBlankStyle="css style for blank cells", firstRowHeader=1--if first row is a header row,
+# firstColumnHeader=1--if first column is a header column, id, attributes)
+# addRow(rowList=[list of cells or data], celltype="th or td", cellclass="css style of cells", attributes, style)
+# addRows(rows=[list of list of cells or data], celltype, cellclass, attributes)
+# columnCount()
+#tableByColumn(columns=[list of columns], style, thStyle, tdStyle, trStyle, tdBlankStyle, firstRowHeader, firstColumnHeader, id, attributes)
+# addColumn(columnList=[list of column data or cells], celltype, cellclass, attributes)
+# addColumns(columns=[list of list of columns or column data], celltype, cellclass, attributes)
+#tableColumn(column=[list of data or cells for column], celltype, cellclass, firstRowHeader, thStyle, tdBlankStyle, attributes)
+# addCell(cell="cell or cell content", celltype, cellclass, id, attributes)
+# addCells(column="list of cells or cell contents", celltype, cellclass, attributes)
+#tableRow(celltype, row=[list of cells or cell data], style, cellclass, firstColumnHeader, thStyle, id, attributes)
+# addCell(cell="cell or cell content", celltype, cellclass, colspan="numerical span of cell vertically", rowspan="numerical span of cell horizontally")
+# addCells(cells=[list of cells or cell content])
+# columnCount()
+#
+#linkedList(links=[list of items of the form [url, name]], outer="outer html tag", inner="inner html tag", style="outer css style",
+# iclass="inner css style", id, attributes)
+# addLink(link=[url, name])
+# addLinks(links)
+#simpleList(items=[list of text items], outer, inner, defaultname="text for marking default entry", default="text of default entry",
+# style, iclass, id, attributes)
+# addItem(item="text of item")
+# addItems(items)
+#
+#image(src="url of image", alt="alternate text for image", align="alignment", style, id, attributes)
+#link(content, url, posttext, pretext, style, id, attributes)
+#
+#form(submitText="text of submit button", pieces, method="submit method", action="form action", submitName="name for submit button", submitAction="javascript for submission"
+# headline="headline text", headlineLevel (defaults to 2), style, attributes, id)
+#input(type="type of form input", name="name for input", value="default value for input", size="size for input", maxlength="maximum characters accepted",
+# style, id, attributes)
+#select(name, items, default, style, iclass, id, attributes
+#textinput(name, text, value, size, maxlength, style, id, attributes, type, tableRow=true if this should be a tr row, otherwise it is a paragraph)
+
+#basic parts
+class part:
+ def __init__(self, code="p", content=None, style=None, id=None, attributes=None):
+ self.style = style
+ self.id=id
+ self.pieces = []
+ self.code = code
+ if attributes == None:
+ self.attributes = {}
+ else:
+ self.attributes = attributes
+ if isinstance(content, list):
+ self.addPieces(content)
+ elif content != None:
+ self.addPiece(content)
+
+ def __len__(self):
+ return len(self.pieces)
+
+ def addAttribute(self, attributename, attributevalue):
+ self.attributes[attributename] = attributevalue
+
+ def addPart(self, code='p', content=None, style=None, id=None, attributes=None):
+ newPart = self.makePart(code, content, style, id, attributes)
+ self.addPiece(newPart)
+
+ def addPiece(self, thePart):
+ self.pieces.append(thePart)
+
+ def addPieces(self, theParts):
+ if theParts != None:
+ if isinstance(theParts, list):
+ for part in theParts:
+ self.addPiece(part)
+ else:
+ self.addPiece(theParts)
+
+ def insertPart(self, code='p', content=None, style=None, id=None, attributes=None):
+ newPart = self.makePart(code, content, style, id, attributes)
+ self.insertPiece(newPart)
+
+ def insertPiece(self, thePart):
+ self.pieces.insert(0, thePart)
+
+ def make(self, tab="\t"):
+ startHTML = '<' + self.code
+
+ if (self.attributes):
+ for attribute in self.attributes:
+ content = self.attributes[attribute]
+ if content == None:
+ startHTML += ' ' + attribute
+ else:
+ startHTML += ' ' + attribute + '="' + str(content) + '"'
+
+ if (self.style):
+ startHTML += ' class="' + self.style + '"'
+
+ if (self.id):
+ startHTML += ' id="' + self.id + '"'
+
+ if self.pieces:
+ startHTML += '>'
+
+ partItems = [startHTML]
+
+ if len(self.pieces) > 1:
+ sep = "\n" + tab
+ finalSep = sep[:-1]
+ newtab = tab + "\t"
+ else:
+ newtab = tab
+ sep = ""
+ finalSep = ""
+
+ for piece in self.pieces:
+ if isinstance(piece, str):
+ partItems.append(piece)
+ elif isinstance(piece, int) or isinstance(piece, float):
+ partItems.append(str(piece))
+ elif piece == None:
+ partItems.append("")
+ else:
+ partItems.append(piece.make(newtab))
+
+ code = sep.join(partItems)
+ code += finalSep + '</' + self.code + '>'
+ return code
+
+ else:
+ startHTML += ' />'
+ return startHTML
+
+ def makePart(self, code='p', content=None, style=None, id=None, attributes=None):
+ if content == None:
+ newPart = part(code)
+ else:
+ newPart = part(code, content, style, id, attributes)
+
+ return newPart
+
+class snippet(part):
+ def __init__(self, code="em", content=None, posttext=None, pretext=None, style=None, id=None, attributes=None):
+ part.__init__(self, code, content, style, id, attributes)
+ self.posttext = posttext
+ self.pretext = pretext
+
+ def make(self, tab=''):
+ snippets = []
+
+ if self.pretext:
+ snippets.append(self.pretext)
+
+ snippets.append(part.make(self, tab))
+
+ if self.posttext:
+ snippets.append(self.posttext)
+
+ return "".join(snippets)
+
+#common body parts
+
+class head(part):
+ def __init__(self, title=None):
+ part.__init__(self, code="head")
+ if title:
+ self.addPiece(part("title", title))
+
+class body(part):
+ def __init__(self, title=None, style=None, id=None, attributes=None):
+ part.__init__(self, code="body", style=style, id=id, attributes=attributes)
+ if title:
+ self.addPiece(headline(title, 1))
+
+class page(part):
+ def __init__(self, pieces=None, style=None, id=None, attributes=None):
+ part.__init__(self, code="html", style=style, id=id, attributes=attributes)
+ if isinstance(pieces, list):
+ self.addPieces(pieces)
+ elif isinstance(pieces, part):
+ self.addPiece(pieces)
+
+ def make(self, tab=''):
+ pageContent = part.make(self)
+
+ print 'Content-type: text/html'
+ print ''
+
+ print pageContent
+
+class styleSheet(part):
+ def __init__(self, sheet, media='all'):
+ attributes = {}
+ attributes['rel'] = "StyleSheet"
+ attributes['href'] = sheet + '.css'
+ attributes['type'] = "text/css"
+ attributes['media'] = media
+ part.__init__(self, code="link", attributes=attributes)
+
+
+#paragraph level parts
+class headline(part):
+ def __init__(self, content, level=2, style=None, id=None, attributes=None):
+ code = "h"+str(level)
+ part.__init__(self, content=content, style=style, code=code, id=id, attributes=attributes)
+
+
+
+#tables
+class table(part):
+ def __init__(self, rows=None, style=None, thStyle=None, tdStyle=None, trStyle=None, tdBlankStyle=None, firstRowHeader=None, firstColumnHeader=None, id=None, attributes=None):
+ part.__init__(self, code="table", style=style, id=id, attributes=attributes)
+ self.rowclass=trStyle
+ self.cellclass=tdStyle
+ self.cellheaderclass=thStyle
+ self.cellblankclass=tdBlankStyle
+ self.firstRowHeader=firstRowHeader
+ self.firstColumnHeader=firstColumnHeader
+ if rows:
+ self.addRows(rows)
+
+ def addRow(self, rowList, celltype=None, cellclass=None, attributes=None, style=None):
+ if cellclass==None:
+ if self.firstRowHeader and len(self.pieces) == 0:
+ celltype="th"
+ cellclass=self.cellheaderclass
+ else:
+ cellclass=self.cellclass
+
+ if style==None:
+ style = self.rowclass
+
+ newRow = tableRow(celltype, rowList, style, cellclass, self.firstColumnHeader, self.cellheaderclass, attributes)
+ self.addPiece(newRow)
+
+ def addRows(self, rows, cellclass=None, celltype=None, attributes=None):
+ for row in rows:
+ self.addRow(row)
+
+ def columnCount(self):
+ maxCount = 0
+ for row in self.pieces:
+ if isinstance(row, tableRow):
+ colCount = row.columnCount()
+ maxCount = max(maxCount, colCount)
+
+ return maxCount
+
+class tableByColumn(table):
+ def __init__(self, columns=None, style=None, thStyle=None, tdStyle=None, trStyle=None, tdBlankStyle=None, firstRowHeader=None, firstColumnHeader=None, id=None, attributes=None):
+ table.__init__(self, [], style, thStyle, tdStyle, trStyle, tdBlankStyle, firstRowHeader, firstColumnHeader, id, attributes)
+ self.columns = []
+ if columns:
+ self.addColumns(columns)
+
+ def addColumn(self, columnList, celltype=None, cellclass=None, attributes=None):
+ if cellclass==None:
+ if celltype == "th" or (self.firstColumnHeader and len(self.columns) == 0):
+ celltype="th"
+ cellclass=self.cellheaderclass
+ else:
+ cellclass=self.cellclass
+
+ newColumn = tableColumn(columnList, celltype, cellclass, self.firstRowHeader, self.cellheaderclass, self.cellblankclass, attributes)
+ self.columns.append(newColumn)
+
+ def addColumns(self, columns, celltype=None, cellclass=None, attributes=None):
+ for column in columns:
+ self.addColumn(column)
+
+ def addPiece(self, thePart):
+ if isinstance(thePart, tableColumn):
+ self.columns.append(thePart)
+ else:
+ part.addPiece(self, thePart)
+
+ def make(self, tabs):
+ rowCount = 0
+ for column in self.columns:
+ rowCount = max(rowCount, len(column.pieces))
+
+ if rowCount:
+ for cRow in range(rowCount):
+ row = tableRow()
+ for column in self.columns:
+ if cRow < len(column.pieces):
+ cell = column.pieces[cRow]
+ else:
+ cell = part("td")
+ row.addPiece(cell)
+
+ self.addPiece(row)
+
+ myPart = part.make(self, tabs)
+ return myPart
+
+
+class tableColumn(part):
+ def __init__(self, column=None, celltype="td", cellclass=None, firstRowHeader=None, thStyle=None, tdBlankStyle=None, attributes=None):
+ part.__init__(self, "column", style=cellclass, attributes=attributes)
+ if celltype==None:
+ self.celltype = "td"
+ else:
+ self.celltype=celltype
+
+ self.firstRowHeader=firstRowHeader
+ self.cellheaderclass=thStyle
+ self.cellblankclass=tdBlankStyle
+
+ if column:
+ self.addCells(column)
+
+ def addCell(self, cell=None, celltype=None, cellclass=None, id=None, attributes=None):
+ if self.cellblankclass and (cell==None or cell==""):
+ celltype="td"
+ cellclass = self.cellblankclass
+ elif self.firstRowHeader and len(self.pieces) == 0:
+ celltype = "th"
+ cellclass = self.cellheaderclass
+ else:
+ if celltype == None:
+ celltype = self.celltype
+ if cellclass == None:
+ cellclass = self.style
+ if cell == None:
+ cell = ""
+
+ tableCell = part(code=celltype, style=cellclass, content=cell, id=id, attributes=attributes)
+ self.addPiece(tableCell)
+
+ def addCells(self, column, celltype=None, cellclass=None, attributes=None):
+ for cell in column:
+ self.addCell(cell, celltype, cellclass, attributes=attributes)
+
+ def make(self):
+ print "Problem: columns should never be requested to make themselves."
+ print "Columns are not true html structures, and should only be added to tableByColumn parts."
+
+
+class tableRow(part):
+ def __init__(self, celltype="td", row=None, style=None, cellclass=None, firstColumnHeader=None, thStyle=None, id=None, attributes=None):
+ part.__init__(self, "tr", style=style, id=id, attributes=attributes)
+ self.celltype=celltype
+ self.cellclass=cellclass
+ self.firstColumnHeader=firstColumnHeader
+ self.cellheaderclass=thStyle
+ if row:
+ self.addCells(row)
+
+ def addCell(self, cell, celltype=None, cellclass=None, colspan=None, rowspan=None):
+ if self.firstColumnHeader and len(self.pieces) == 0:
+ celltype="th"
+ cellclass=self.cellheaderclass
+ elif celltype == None:
+ celltype = self.celltype
+
+ if celltype == None:
+ celltype = "td"
+
+ if cellclass==None:
+ cellclass=self.cellclass
+
+ attributes = {}
+ if colspan:
+ attributes['colspan'] = colspan
+ if rowspan:
+ attributes['rowspan'] = rowspan
+
+ if cell == None:
+ cell = ""
+
+ self.addPiece(part(code=celltype, style=cellclass, content=cell, attributes=attributes))
+
+ def addCells(self, cells):
+ for cell in cells:
+ self.addCell(cell)
+
+ def columnCount(self):
+ return len(self.pieces)
+
+
+#lists
+
+class linkedList(part):
+ def __init__(self, links=None, outer = "ul", inner="li", style=None, iclass=None, id=None, attributes=None):
+ part.__init__(self, code=outer, style=style, id=id, attributes=attributes)
+ self.innercode = inner
+ self.innerstyle = iclass
+ if isinstance(links, list):
+ self.addLinks(links)
+
+ def addLink(self, link):
+ [url, name] = link
+ link = part("a", attributes={"href": url}, content=name)
+ listitem = part(self.innercode, content=link, style=self.innerstyle)
+ self.pieces.append(listitem)
+
+ def addLinks(self, links):
+ theLinks = []
+ for link in links:
+ self.addLink(link)
+
+class simpleList(part):
+ def __init__(self, items=None, outer = "ul", inner="li", defaultname=None, default=None, style=None, iclass=None, id=None, attributes=None):
+ part.__init__(self, code=outer, style=style, id=id, attributes=attributes)
+ self.innercode = inner
+ self.innerstyle = iclass
+ self.defaultname = defaultname
+ self.default=default
+ if isinstance(items, list):
+ self.addItems(items)
+
+ def addItem(self, item):
+ attributes = {}
+ if self.defaultname:
+ if item == self.default:
+ attributes[self.defaultname] = None
+
+ theItem = part(self.innercode, content=item, style=self.innerstyle, attributes=attributes)
+ self.pieces.append(theItem)
+
+ def addItems(self, items):
+ theList = []
+ for item in items:
+ self.addItem(item)
+
+#individual pieces
+
+class image(part):
+ def __init__(self, src, alt=None, align=None, style=None, id=None, attributes=None):
+ if attributes == None:
+ attributes = {}
+ attributes['src'] = src
+ if alt:
+ attributes['alt'] = alt
+ if align:
+ attributes['align'] = align
+
+ part.__init__(self, 'img', style=style, id=id, attributes=attributes)
+
+class link(snippet):
+ def __init__(self, content=None, url=None, posttext=None, pretext=None, style=None, id=None, attributes=None):
+ if url != None:
+ if attributes == None:
+ attributes = {}
+ attributes['href'] = url
+
+ snippet.__init__(self, "a", content, posttext, pretext, style, id, attributes)
+
+
+#forms
+
+class form(part):
+ def __init__(self, submitText="Submit", pieces=None, method="get", action='./', submitName = None, submitAction=None, headline=None, headlineLevel = 2, style=None, attributes=None):
+ self.submitText = submitText
+ self.submitName = submitName
+ self.making = None
+ if attributes == None:
+ attributes = {}
+ if action != None:
+ attributes['action'] = action
+ if method != None:
+ attributes['method'] = method
+ if submitAction != None:
+ attributes['onSubmit'] = '"' + submitaction + '"'
+
+ part.__init__(self, 'form', style=style, attributes=attributes)
+
+ if headline != None:
+ headcode = "h" + headlineLevel
+ self.addPart(headcode, content=headline)
+
+ self.addPieces(pieces)
+
+
+ def make(self, tab=''):
+ if self.making:
+ return part.make(self, tab)
+ else:
+ if self.submitName:
+ submitButton = input("submit", value=self.submitText, name=self.submitName)
+ else:
+ submitButton = input("submit", value=self.submitText)
+ trueForm = self
+ trueForm.making = 1
+ trueForm.addPiece(submitButton)
+ pageContent = trueForm.make(tab)
+ return pageContent
+
+class input(part):
+ def __init__(self, type, name=None, value=None, size=None, maxlength=None, style=None, id=None, attributes=None):
+ if attributes == None:
+ attributes = {}
+
+ attributes['type'] = type
+ if name:
+ attributes['name'] = name
+ if value!=None:
+ attributes['value'] = value
+ if size:
+ attributes['size'] = size
+ if maxlength:
+ attributes['maxlength'] = maxlength
+
+ part.__init__(self, 'input', style=style, id=id, attributes=attributes)
+
+class select(simpleList):
+ def __init__(self, name, items=None, default=None, style=None, iclass=None, id=None, attributes=None):
+ if attributes==None:
+ attributes={}
+ attributes['name'] = name
+
+ simpleList.__init__(self, items, outer='select', inner='option', defaultname='selected', default=default, style=style, iclass=iclass, id=id, attributes=attributes)
+
+class textinput(part):
+ def __init__(self, name=None, text=None, value=None, size=None, maxlength=None, style=None, id=None, attributes=None, type="text", tableRow=None):
+ if (text == None):
+ text = name
+ self.field = input(type=type, name=name, value=value, size=size, maxlength=maxlength, style=style, id=id, attributes=attributes)
+ self.text = text
+
+ if tableRow == None:
+ part.__init__(self, 'p', style=style, attributes=attributes)
+ self.addPiece(self.text)
+ self.addPiece(self.field)
+ else:
+ part.__init__(self, 'tr', style=style, attributes=attributes)
+ self.addPart('th', content=self.text)
+ self.addPart('td', content=self.field)
+
+
+
+#need some functions for HTML
+#ought to be somewhere else in Python?
+#cgi.escape only seems to do <, >, and &
+from htmlentitydefs import entitydefs
+import re
+
+entitydefs_inverted = {}
+for k,v in entitydefs.items():
+ entitydefs_inverted[v] = k
+
+needencoding = re.compile('|'.join(entitydefs.values()))
+alreadyencoded = re.compile('&\w+;|&#[0-9]+;')
+
+#encodes any special characters to their HTML equivalents
+def encode(text, skip=None, once_only=1):
+ # if extra_careful, check to see if this text has already been converted
+ if not (once_only and alreadyencoded.findall(text)):
+ if not isinstance(skip, list):
+ skip = [skip]
+
+ #do ampersands on their own or we might end up converting our conversions
+ if '&' not in skip:
+ text = text.replace('&','&')
+ skip.append('&')
+
+ needlist= []
+ #grab the characters in the text that need encoding
+ for x in needencoding.findall(text):
+ #and make sure we aren't skipping them
+ if x not in skip:
+ needlist.append(x)
+
+ for uncoded in needlist:
+ encoded = entitydefs_inverted[uncoded]
+ #if it is not a numerical encoding, we need to do the & and ; ourselves
+ if not encoded.startswith('&#'):
+ encoded = '&%s;'%entitydefs_inverted[uncoded]
+
+ text = text.replace(uncoded, encoded)
+
+ return text
--- /dev/null
+################################################################################
+# Sample object config file for Nagios
+#
+# Read the documentation for more information on this configuration file. I've
+# provided some comments here, but things may not be so clear without further
+# explanation, so make sure to read the HTML documentation!
+#
+# Last Modified: 12-17-2005
+#
+################################################################################
+
+
+################################################################################
+# COMMAND DEFINITIONS
+#
+# SYNTAX:
+#
+# define command{
+# template <templatename>
+# name <objectname>
+# command_name <commandname>
+# command_line <commandline>
+# }
+#
+# WHERE:
+#
+# <templatename> = object name of another command definition that should be
+# used as a template for this definition (optional)
+# <objectname> = object name of command definition, referenced by other
+# command definitions that use it as a template (optional)
+# <commandname> = name of the command, as recognized/used by Nagios
+# <commandline> = command line
+#
+################################################################################
+
+
+
+
+################################################################################
+#
+# SAMPLE NOTIFICATION COMMANDS
+#
+# These are some example notification commands. They may or may not work on
+# your system without modification.
+#
+################################################################################
+
+
+# 'host-notify-by-email' command definition
+define command{
+ command_name host-notify-by-email
+ command_line /usr/bin/printf "%b" "***** Nagios *****\n\nNotification Type: $NOTIFICATIONTYPE$\nHost: $HOSTNAME$\nState: $HOSTSTATE$\nAddress: $HOSTADDRESS$\nInfo: $HOSTOUTPUT$\n\nDate/Time: $LONGDATETIME$\n" | /bin/mail -s "Host $HOSTSTATE$ alert for $HOSTNAME$!" $CONTACTEMAIL$
+ }
+
+
+# 'host-notify-by-epager' command definition
+define command{
+ command_name host-notify-by-epager
+ command_line /usr/bin/printf "%b" "Host '$HOSTALIAS$' is $HOSTSTATE$\nInfo: $HOSTOUTPUT$\nTime: $LONGDATETIME$" | /bin/mail -s "$NOTIFICATIONTYPE$ alert - Host $HOSTNAME$ is $HOSTSTATE$" $CONTACTPAGER$
+ }
+
+# 'notify-by-email' command definition
+define command{
+ command_name notify-by-email
+ command_line /usr/bin/printf "%b" "***** Nagios *****\n\nNotification Type: $NOTIFICATIONTYPE$\n\nService: $SERVICEDESC$\nHost: $HOSTALIAS$\nAddress: $HOSTADDRESS$\nState: $SERVICESTATE$\n\nDate/Time: $LONGDATETIME$\n\nAdditional Info:\n\n$SERVICEOUTPUT$" | /bin/mail -s "** $NOTIFICATIONTYPE$ alert - $HOSTALIAS$/$SERVICEDESC$ is $SERVICESTATE$ **" $CONTACTEMAIL$
+ }
+
+
+# 'notify-by-epager' command definition
+define command{
+ command_name notify-by-epager
+ command_line /usr/bin/printf "%b" "Service: $SERVICEDESC$\nHost: $HOSTNAME$\nAddress: $HOSTADDRESS$\nState: $SERVICESTATE$\nInfo: $SERVICEOUTPUT$\nDate: $LONGDATETIME$" | /bin/mail -s "$NOTIFICATIONTYPE$: $HOSTALIAS$/$SERVICEDESC$ is $SERVICESTATE$" $CONTACTPAGER$
+ }
+
+
+
+
+
+################################################################################
+#
+# SAMPLE PERFORMANCE DATA COMMANDS
+#
+# These are sample performance data commands that can be used to send performance
+# data output to two text files (one for hosts, another for services). If you
+# plan on simply writing performance data out to a file, consider using the
+# host_perfdata_file and service_perfdata_file options in the main config file.
+#
+################################################################################
+
+
+# 'process-host-perfdata' command definition
+define command{
+ command_name process-host-perfdata
+ command_line /usr/bin/printf "%b" "$LASTHOSTCHECK$\t$HOSTNAME$\t$HOSTSTATE$\t$HOSTATTEMPT$\t$HOSTSTATETYPE$\t$HOSTEXECUTIONTIME$\t$HOSTOUTPUT$\t$HOSTPERFDATA$\n" >> /var/log/nagios/host-perfdata.out
+ }
+
+
+# 'process-service-perfdata' command definition
+define command{
+ command_name process-service-perfdata
+ command_line /usr/bin/printf "%b" "$LASTSERVICECHECK$\t$HOSTNAME$\t$SERVICEDESC$\t$SERVICESTATE$\t$SERVICEATTEMPT$\t$SERVICESTATETYPE$\t$SERVICEEXECUTIONTIME$\t$SERVICELATENCY$\t$SERVICEOUTPUT$\t$SERVICEPERFDATA$\n" >> /var/log/nagios/service-perfdata.out
+ }
+
+
--- /dev/null
+##############################################################################
+#
+# NAGIOS.CFG - Sample Main Config File for Nagios
+#
+# Read the documentation for more information on this configuration
+# file. I've provided some comments here, but things may not be so
+# clear without further explanation.
+#
+# Last Modified: 11-23-2005
+#
+##############################################################################
+
+
+# LOG FILE
+# This is the main log file where service and host events are logged
+# for historical purposes. This should be the first option specified
+# in the config file!!!
+
+log_file=/var/log/nagios/nagios.log
+
+
+
+# OBJECT CONFIGURATION FILE(S)
+# This is the configuration file in which you define hosts, host
+# groups, contacts, contact groups, services, etc. I guess it would
+# be better called an object definition file, but for historical
+# reasons it isn't. You can split object definitions into several
+# different config files by using multiple cfg_file statements here.
+# Nagios will read and process all the config files you define.
+# This can be very useful if you want to keep command definitions
+# separate from host and contact definitions...
+
+# Plugin commands (service and host check commands)
+# Arguments are likely to change between different releases of the
+# plugins, so you should use the same config file provided with the
+# plugin release rather than the one provided with Nagios.
+# merged into generic.cfg
+#cfg_file=/etc/nagios/checkcommands.cfg
+
+# Misc commands (notification and event handler commands, etc)
+cfg_file=/etc/nagios/misccommands.cfg
+
+# You can split other types of object definitions across several
+# config files if you wish (as done here), or keep them all in a
+# single config file.
+
+# we define here the generic stuff that planetlab.cfg relies upon
+cfg_file=/etc/nagios/generic.cfg
+
+# python-generated common definitions - need to be loaded first
+cfg_file=/etc/nagios/planetlab.cfg
+
+# python-generated details
+cfg_dir=/etc/nagios/planetlab/
+
+
+
+# OBJECT CACHE FILE
+# This option determines where object definitions are cached when
+# Nagios starts/restarts. The CGIs read object definitions from
+# this cache file (rather than looking at the object config files
+# directly) in order to prevent inconsistencies that can occur
+# when the config files are modified after Nagios starts.
+
+object_cache_file=/var/log/nagios/objects.cache
+
+
+# RESOURCE FILE
+# This is an optional resource file that contains $USERx$ macro
+# definitions. Multiple resource files can be specified by using
+# multiple resource_file definitions. The CGIs will not attempt to
+# read the contents of resource files, so information that is
+# considered to be sensitive (usernames, passwords, etc) can be
+# defined as macros in this file and restrictive permissions (600)
+# can be placed on this file.
+
+resource_file=/etc/nagios/private/resource.cfg
+
+
+
+# STATUS FILE
+# This is where the current status of all monitored services and
+# hosts is stored. Its contents are read and processed by the CGIs.
+# The contents of the status file are deleted every time Nagios
+# restarts.
+
+status_file=/var/log/nagios/status.dat
+
+
+
+# NAGIOS USER
+# This determines the effective user that Nagios should run as.
+# You can either supply a username or a UID.
+
+nagios_user=nagios
+
+
+
+# NAGIOS GROUP
+# This determines the effective group that Nagios should run as.
+# You can either supply a group name or a GID.
+
+nagios_group=nagios
+
+
+
+# EXTERNAL COMMAND OPTION
+# This option allows you to specify whether or not Nagios should check
+# for external commands (in the command file defined below). By default
+# Nagios will *not* check for external commands, just to be on the
+# cautious side. If you want to be able to use the CGI command interface
+# you will have to enable this. Setting this value to 0 disables command
+# checking (the default), other values enable it.
+
+check_external_commands=1
+
+
+
+# EXTERNAL COMMAND CHECK INTERVAL
+# This is the interval at which Nagios should check for external commands.
+# This value works of the interval_length you specify later. If you leave
+# that at its default value of 60 (seconds), a value of 1 here will cause
+# Nagios to check for external commands every minute. If you specify a
+# number followed by an "s" (i.e. 15s), this will be interpreted to mean
+# actual seconds rather than a multiple of the interval_length variable.
+# Note: In addition to reading the external command file at regularly
+# scheduled intervals, Nagios will also check for external commands after
+# event handlers are executed.
+# NOTE: Setting this value to -1 causes Nagios to check the external
+# command file as often as possible.
+
+#command_check_interval=1
+#command_check_interval=15s
+command_check_interval=-1
+
+
+
+# EXTERNAL COMMAND FILE
+# This is the file that Nagios checks for external command requests.
+# It is also where the command CGI will write commands that are submitted
+# by users, so it must be writeable by the user that the web server
+# is running as (usually 'nobody'). Permissions should be set at the
+# directory level instead of on the file, as the file is deleted every
+# time its contents are processed.
+
+command_file=/var/spool/nagios/cmd/nagios.cmd
+
+
+
+# COMMENT FILE
+# This is the file that Nagios will use for storing host and service
+# comments.
+
+comment_file=/var/log/nagios/comments.dat
+
+
+
+# DOWNTIME FILE
+# This is the file that Nagios will use for storing host and service
+# downtime data.
+
+downtime_file=/var/log/nagios/downtime.dat
+
+
+
+# LOCK FILE
+# This is the lockfile that Nagios will use to store its PID number
+# in when it is running in daemon mode.
+
+lock_file=/var/run/nagios.pid
+
+
+
+# TEMP FILE
+# This is a temporary file that is used as scratch space when Nagios
+# updates the status log, cleans the comment file, etc. This file
+# is created, used, and deleted throughout the time that Nagios is
+# running.
+
+temp_file=/var/log/nagios/nagios.tmp
+
+
+
+# EVENT BROKER OPTIONS
+# Controls what (if any) data gets sent to the event broker.
+# Values: 0 = Broker nothing
+# -1 = Broker everything
+# <other> = See documentation
+
+event_broker_options=-1
+
+
+
+# EVENT BROKER MODULE(S)
+# This directive is used to specify an event broker module that should
+# by loaded by Nagios at startup. Use multiple directives if you want
+# to load more than one module. Arguments that should be passed to
+# the module at startup are seperated from the module path by a space.
+#
+# Example:
+#
+# broker_module=<modulepath> [moduleargs]
+
+#broker_module=/somewhere/module1.o
+#broker_module=/somewhere/module2.o arg1 arg2=3 debug=0
+
+
+
+
+# LOG ROTATION METHOD
+# This is the log rotation method that Nagios should use to rotate
+# the main log file. Values are as follows..
+# n = None - don't rotate the log
+# h = Hourly rotation (top of the hour)
+# d = Daily rotation (midnight every day)
+# w = Weekly rotation (midnight on Saturday evening)
+# m = Monthly rotation (midnight last day of month)
+
+log_rotation_method=d
+
+
+
+# LOG ARCHIVE PATH
+# This is the directory where archived (rotated) log files should be
+# placed (assuming you've chosen to do log rotation).
+
+log_archive_path=/var/log/nagios/archives
+
+
+
+# LOGGING OPTIONS
+# If you want messages logged to the syslog facility, as well as the
+# NetAlarm log file set this option to 1. If not, set it to 0.
+
+use_syslog=1
+
+
+
+# NOTIFICATION LOGGING OPTION
+# If you don't want notifications to be logged, set this value to 0.
+# If notifications should be logged, set the value to 1.
+
+log_notifications=1
+
+
+
+# SERVICE RETRY LOGGING OPTION
+# If you don't want service check retries to be logged, set this value
+# to 0. If retries should be logged, set the value to 1.
+
+log_service_retries=1
+
+
+
+# HOST RETRY LOGGING OPTION
+# If you don't want host check retries to be logged, set this value to
+# 0. If retries should be logged, set the value to 1.
+
+log_host_retries=1
+
+
+
+# EVENT HANDLER LOGGING OPTION
+# If you don't want host and service event handlers to be logged, set
+# this value to 0. If event handlers should be logged, set the value
+# to 1.
+
+log_event_handlers=1
+
+
+
+# INITIAL STATES LOGGING OPTION
+# If you want Nagios to log all initial host and service states to
+# the main log file (the first time the service or host is checked)
+# you can enable this option by setting this value to 1. If you
+# are not using an external application that does long term state
+# statistics reporting, you do not need to enable this option. In
+# this case, set the value to 0.
+
+log_initial_states=0
+
+
+
+# EXTERNAL COMMANDS LOGGING OPTION
+# If you don't want Nagios to log external commands, set this value
+# to 0. If external commands should be logged, set this value to 1.
+# Note: This option does not include logging of passive service
+# checks - see the option below for controlling whether or not
+# passive checks are logged.
+
+log_external_commands=1
+
+
+
+# PASSIVE CHECKS LOGGING OPTION
+# If you don't want Nagios to log passive host and service checks, set
+# this value to 0. If passive checks should be logged, set
+# this value to 1.
+
+log_passive_checks=1
+
+
+
+# GLOBAL HOST AND SERVICE EVENT HANDLERS
+# These options allow you to specify a host and service event handler
+# command that is to be run for every host or service state change.
+# The global event handler is executed immediately prior to the event
+# handler that you have optionally specified in each host or
+# service definition. The command argument is the short name of a
+# command definition that you define in your host configuration file.
+# Read the HTML docs for more information.
+
+#global_host_event_handler=somecommand
+#global_service_event_handler=somecommand
+
+
+
+# SERVICE INTER-CHECK DELAY METHOD
+# This is the method that Nagios should use when initially
+# "spreading out" service checks when it starts monitoring. The
+# default is to use smart delay calculation, which will try to
+# space all service checks out evenly to minimize CPU load.
+# Using the dumb setting will cause all checks to be scheduled
+# at the same time (with no delay between them)! This is not a
+# good thing for production, but is useful when testing the
+# parallelization functionality.
+# n = None - don't use any delay between checks
+# d = Use a "dumb" delay of 1 second between checks
+# s = Use "smart" inter-check delay calculation
+# x.xx = Use an inter-check delay of x.xx seconds
+
+service_inter_check_delay_method=s
+
+
+
+# MAXIMUM SERVICE CHECK SPREAD
+# This variable determines the timeframe (in minutes) from the
+# program start time that an initial check of all services should
+# be completed. Default is 30 minutes.
+
+max_service_check_spread=30
+
+
+
+# SERVICE CHECK INTERLEAVE FACTOR
+# This variable determines how service checks are interleaved.
+# Interleaving the service checks allows for a more even
+# distribution of service checks and reduced load on remote
+# hosts. Setting this value to 1 is equivalent to how versions
+# of Nagios previous to 0.0.5 did service checks. Set this
+# value to s (smart) for automatic calculation of the interleave
+# factor unless you have a specific reason to change it.
+# s = Use "smart" interleave factor calculation
+# x = Use an interleave factor of x, where x is a
+# number greater than or equal to 1.
+
+service_interleave_factor=s
+
+
+
+# HOST INTER-CHECK DELAY METHOD
+# This is the method that Nagios should use when initially
+# "spreading out" host checks when it starts monitoring. The
+# default is to use smart delay calculation, which will try to
+# space all host checks out evenly to minimize CPU load.
+# Using the dumb setting will cause all checks to be scheduled
+# at the same time (with no delay between them)!
+# n = None - don't use any delay between checks
+# d = Use a "dumb" delay of 1 second between checks
+# s = Use "smart" inter-check delay calculation
+# x.xx = Use an inter-check delay of x.xx seconds
+
+host_inter_check_delay_method=s
+
+
+
+# MAXIMUM HOST CHECK SPREAD
+# This variable determines the timeframe (in minutes) from the
+# program start time that an initial check of all hosts should
+# be completed. Default is 30 minutes.
+
+max_host_check_spread=30
+
+
+
+# MAXIMUM CONCURRENT SERVICE CHECKS
+# This option allows you to specify the maximum number of
+# service checks that can be run in parallel at any given time.
+# Specifying a value of 1 for this variable essentially prevents
+# any service checks from being parallelized. A value of 0
+# will not restrict the number of concurrent checks that are
+# being executed.
+
+max_concurrent_checks=0
+
+
+
+# SERVICE CHECK REAPER FREQUENCY
+# This is the frequency (in seconds!) that Nagios will process
+# the results of services that have been checked.
+
+service_reaper_frequency=10
+
+
+
+
+# AUTO-RESCHEDULING OPTION
+# This option determines whether or not Nagios will attempt to
+# automatically reschedule active host and service checks to
+# "smooth" them out over time. This can help balance the load on
+# the monitoring server.
+# WARNING: THIS IS AN EXPERIMENTAL FEATURE - IT CAN DEGRADE
+# PERFORMANCE, RATHER THAN INCREASE IT, IF USED IMPROPERLY
+
+auto_reschedule_checks=0
+
+
+
+# AUTO-RESCHEDULING INTERVAL
+# This option determines how often (in seconds) Nagios will
+# attempt to automatically reschedule checks. This option only
+# has an effect if the auto_reschedule_checks option is enabled.
+# Default is 30 seconds.
+# WARNING: THIS IS AN EXPERIMENTAL FEATURE - IT CAN DEGRADE
+# PERFORMANCE, RATHER THAN INCREASE IT, IF USED IMPROPERLY
+
+auto_rescheduling_interval=30
+
+
+
+
+# AUTO-RESCHEDULING WINDOW
+# This option determines the "window" of time (in seconds) that
+# Nagios will look at when automatically rescheduling checks.
+# Only host and service checks that occur in the next X seconds
+# (determined by this variable) will be rescheduled. This option
+# only has an effect if the auto_reschedule_checks option is
+# enabled. Default is 180 seconds (3 minutes).
+# WARNING: THIS IS AN EXPERIMENTAL FEATURE - IT CAN DEGRADE
+# PERFORMANCE, RATHER THAN INCREASE IT, IF USED IMPROPERLY
+
+auto_rescheduling_window=180
+
+
+
+# SLEEP TIME
+# This is the number of seconds to sleep between checking for system
+# events and service checks that need to be run.
+
+sleep_time=0.25
+
+
+
+# TIMEOUT VALUES
+# These options control how much time Nagios will allow various
+# types of commands to execute before killing them off. Options
+# are available for controlling maximum time allotted for
+# service checks, host checks, event handlers, notifications, the
+# ocsp command, and performance data commands. All values are in
+# seconds.
+
+service_check_timeout=60
+host_check_timeout=30
+event_handler_timeout=30
+notification_timeout=30
+ocsp_timeout=5
+perfdata_timeout=5
+
+
+
+# RETAIN STATE INFORMATION
+# This setting determines whether or not Nagios will save state
+# information for services and hosts before it shuts down. Upon
+# startup Nagios will reload all saved service and host state
+# information before starting to monitor. This is useful for
+# maintaining long-term data on state statistics, etc, but will
+# slow Nagios down a bit when it (re)starts. Since its only
+# a one-time penalty, I think its well worth the additional
+# startup delay.
+
+retain_state_information=1
+
+
+
+# STATE RETENTION FILE
+# This is the file that Nagios should use to store host and
+# service state information before it shuts down. The state
+# information in this file is also read immediately prior to
+# starting to monitor the network when Nagios is restarted.
+# This file is used only if the preserve_state_information
+# variable is set to 1.
+
+state_retention_file=/var/log/nagios/retention.dat
+
+
+
+# RETENTION DATA UPDATE INTERVAL
+# This setting determines how often (in minutes) that Nagios
+# will automatically save retention data during normal operation.
+# If you set this value to 0, Nagios will not save retention
+# data at regular interval, but it will still save retention
+# data before shutting down or restarting. If you have disabled
+# state retention, this option has no effect.
+
+retention_update_interval=60
+
+
+
+# USE RETAINED PROGRAM STATE
+# This setting determines whether or not Nagios will set
+# program status variables based on the values saved in the
+# retention file. If you want to use retained program status
+# information, set this value to 1. If not, set this value
+# to 0.
+
+use_retained_program_state=1
+
+
+
+# USE RETAINED SCHEDULING INFO
+# This setting determines whether or not Nagios will retain
+# the scheduling info (next check time) for hosts and services
+# based on the values saved in the retention file. If you
+# If you want to use retained scheduling info, set this
+# value to 1. If not, set this value to 0.
+
+use_retained_scheduling_info=0
+
+
+
+# INTERVAL LENGTH
+# This is the seconds per unit interval as used in the
+# host/contact/service configuration files. Setting this to 60 means
+# that each interval is one minute long (60 seconds). Other settings
+# have not been tested much, so your mileage is likely to vary...
+
+interval_length=60
+
+
+
+# AGGRESSIVE HOST CHECKING OPTION
+# If you don't want to turn on aggressive host checking features, set
+# this value to 0 (the default). Otherwise set this value to 1 to
+# enable the aggressive check option. Read the docs for more info
+# on what aggressive host check is or check out the source code in
+# base/checks.c
+
+use_aggressive_host_checking=0
+
+
+
+# SERVICE CHECK EXECUTION OPTION
+# This determines whether or not Nagios will actively execute
+# service checks when it initially starts. If this option is
+# disabled, checks are not actively made, but Nagios can still
+# receive and process passive check results that come in. Unless
+# you're implementing redundant hosts or have a special need for
+# disabling the execution of service checks, leave this enabled!
+# Values: 1 = enable checks, 0 = disable checks
+
+execute_service_checks=1
+
+
+
+# PASSIVE SERVICE CHECK ACCEPTANCE OPTION
+# This determines whether or not Nagios will accept passive
+# service checks results when it initially (re)starts.
+# Values: 1 = accept passive checks, 0 = reject passive checks
+
+accept_passive_service_checks=1
+
+
+
+# HOST CHECK EXECUTION OPTION
+# This determines whether or not Nagios will actively execute
+# host checks when it initially starts. If this option is
+# disabled, checks are not actively made, but Nagios can still
+# receive and process passive check results that come in. Unless
+# you're implementing redundant hosts or have a special need for
+# disabling the execution of host checks, leave this enabled!
+# Values: 1 = enable checks, 0 = disable checks
+
+execute_host_checks=1
+
+
+
+# PASSIVE HOST CHECK ACCEPTANCE OPTION
+# This determines whether or not Nagios will accept passive
+# host checks results when it initially (re)starts.
+# Values: 1 = accept passive checks, 0 = reject passive checks
+
+accept_passive_host_checks=1
+
+
+
+# NOTIFICATIONS OPTION
+# This determines whether or not Nagios will sent out any host or
+# service notifications when it is initially (re)started.
+# Values: 1 = enable notifications, 0 = disable notifications
+
+enable_notifications=1
+
+
+
+# EVENT HANDLER USE OPTION
+# This determines whether or not Nagios will run any host or
+# service event handlers when it is initially (re)started. Unless
+# you're implementing redundant hosts, leave this option enabled.
+# Values: 1 = enable event handlers, 0 = disable event handlers
+
+enable_event_handlers=1
+
+
+
+# PROCESS PERFORMANCE DATA OPTION
+# This determines whether or not Nagios will process performance
+# data returned from service and host checks. If this option is
+# enabled, host performance data will be processed using the
+# host_perfdata_command (defined below) and service performance
+# data will be processed using the service_perfdata_command (also
+# defined below). Read the HTML docs for more information on
+# performance data.
+# Values: 1 = process performance data, 0 = do not process performance data
+
+process_performance_data=0
+
+
+
+# HOST AND SERVICE PERFORMANCE DATA PROCESSING COMMANDS
+# These commands are run after every host and service check is
+# performed. These commands are executed only if the
+# enable_performance_data option (above) is set to 1. The command
+# argument is the short name of a command definition that you
+# define in your host configuration file. Read the HTML docs for
+# more information on performance data.
+
+#host_perfdata_command=process-host-perfdata
+#service_perfdata_command=process-service-perfdata
+
+
+
+# HOST AND SERVICE PERFORMANCE DATA FILES
+# These files are used to store host and service performance data.
+# Performance data is only written to these files if the
+# enable_performance_data option (above) is set to 1.
+
+#host_perfdata_file=/tmp/host-perfdata
+#service_perfdata_file=/tmp/service-perfdata
+
+
+
+# HOST AND SERVICE PERFORMANCE DATA FILE TEMPLATES
+# These options determine what data is written (and how) to the
+# performance data files. The templates may contain macros, special
+# characters (\t for tab, \r for carriage return, \n for newline)
+# and plain text. A newline is automatically added after each write
+# to the performance data file. Some examples of what you can do are
+# shown below.
+
+#host_perfdata_file_template=[HOSTPERFDATA]\t$TIMET$\t$HOSTNAME$\t$HOSTEXECUTIONTIME$\t$HOSTOUTPUT$\t$HOSTPERFDATA$
+#service_perfdata_file_template=[SERVICEPERFDATA]\t$TIMET$\t$HOSTNAME$\t$SERVICEDESC$\t$SERVICEEXECUTIONTIME$\t$SERVICELATENCY$\t$SERVICEOUTPUT$\t$SERVICEPERFDATA$
+
+
+
+
+# HOST AND SERVICE PERFORMANCE DATA FILE MODES
+# This option determines whether or not the host and service
+# performance data files are opened in write ("w") or append ("a")
+# mode. Unless you are the files are named pipes, you will probably
+# want to use the default mode of append ("a").
+
+#host_perfdata_file_mode=a
+#service_perfdata_file_mode=a
+
+
+
+# HOST AND SERVICE PERFORMANCE DATA FILE PROCESSING INTERVAL
+# These options determine how often (in seconds) the host and service
+# performance data files are processed using the commands defined
+# below. A value of 0 indicates the files should not be periodically
+# processed.
+
+#host_perfdata_file_processing_interval=0
+#service_perfdata_file_processing_interval=0
+
+
+
+# HOST AND SERVICE PERFORMANCE DATA FILE PROCESSING COMMANDS
+# These commands are used to periodically process the host and
+# service performance data files. The interval at which the
+# processing occurs is determined by the options above.
+
+#host_perfdata_file_processing_command=process-host-perfdata-file
+#service_perfdata_file_processing_command=process-service-perfdata-file
+
+
+
+# OBSESS OVER SERVICE CHECKS OPTION
+# This determines whether or not Nagios will obsess over service
+# checks and run the ocsp_command defined below. Unless you're
+# planning on implementing distributed monitoring, do not enable
+# this option. Read the HTML docs for more information on
+# implementing distributed monitoring.
+# Values: 1 = obsess over services, 0 = do not obsess (default)
+
+obsess_over_services=0
+
+
+
+# OBSESSIVE COMPULSIVE SERVICE PROCESSOR COMMAND
+# This is the command that is run for every service check that is
+# processed by Nagios. This command is executed only if the
+# obsess_over_service option (above) is set to 1. The command
+# argument is the short name of a command definition that you
+# define in your host configuration file. Read the HTML docs for
+# more information on implementing distributed monitoring.
+
+#ocsp_command=somecommand
+
+
+
+# ORPHANED SERVICE CHECK OPTION
+# This determines whether or not Nagios will periodically
+# check for orphaned services. Since service checks are not
+# rescheduled until the results of their previous execution
+# instance are processed, there exists a possibility that some
+# checks may never get rescheduled. This seems to be a rare
+# problem and should not happen under normal circumstances.
+# If you have problems with service checks never getting
+# rescheduled, you might want to try enabling this option.
+# Values: 1 = enable checks, 0 = disable checks
+
+check_for_orphaned_services=0
+
+
+
+# SERVICE FRESHNESS CHECK OPTION
+# This option determines whether or not Nagios will periodically
+# check the "freshness" of service results. Enabling this option
+# is useful for ensuring passive checks are received in a timely
+# manner.
+# Values: 1 = enabled freshness checking, 0 = disable freshness checking
+
+check_service_freshness=1
+
+
+
+# SERVICE FRESHNESS CHECK INTERVAL
+# This setting determines how often (in seconds) Nagios will
+# check the "freshness" of service check results. If you have
+# disabled service freshness checking, this option has no effect.
+
+service_freshness_check_interval=60
+
+
+
+# HOST FRESHNESS CHECK OPTION
+# This option determines whether or not Nagios will periodically
+# check the "freshness" of host results. Enabling this option
+# is useful for ensuring passive checks are received in a timely
+# manner.
+# Values: 1 = enabled freshness checking, 0 = disable freshness checking
+
+check_host_freshness=0
+
+
+
+# HOST FRESHNESS CHECK INTERVAL
+# This setting determines how often (in seconds) Nagios will
+# check the "freshness" of host check results. If you have
+# disabled host freshness checking, this option has no effect.
+
+host_freshness_check_interval=60
+
+
+
+# AGGREGATED STATUS UPDATES
+# This option determines whether or not Nagios will
+# aggregate updates of host, service, and program status
+# data. Normally, status data is updated immediately when
+# a change occurs. This can result in high CPU loads if
+# you are monitoring a lot of services. If you want Nagios
+# to only refresh status data every few seconds, disable
+# this option.
+# Values: 1 = enable aggregate updates, 0 = disable aggregate updates
+
+aggregate_status_updates=1
+
+
+
+# AGGREGATED STATUS UPDATE INTERVAL
+# Combined with the aggregate_status_updates option,
+# this option determines the frequency (in seconds!) that
+# Nagios will periodically dump program, host, and
+# service status data. If you are not using aggregated
+# status data updates, this option has no effect.
+
+status_update_interval=15
+
+
+
+# FLAP DETECTION OPTION
+# This option determines whether or not Nagios will try
+# and detect hosts and services that are "flapping".
+# Flapping occurs when a host or service changes between
+# states too frequently. When Nagios detects that a
+# host or service is flapping, it will temporarily suppress
+# notifications for that host/service until it stops
+# flapping. Flap detection is very experimental, so read
+# the HTML documentation before enabling this feature!
+# Values: 1 = enable flap detection
+# 0 = disable flap detection (default)
+
+enable_flap_detection=0
+
+
+
+# FLAP DETECTION THRESHOLDS FOR HOSTS AND SERVICES
+# Read the HTML documentation on flap detection for
+# an explanation of what this option does. This option
+# has no effect if flap detection is disabled.
+
+low_service_flap_threshold=5.0
+high_service_flap_threshold=20.0
+low_host_flap_threshold=5.0
+high_host_flap_threshold=20.0
+
+
+
+# DATE FORMAT OPTION
+# This option determines how short dates are displayed. Valid options
+# include:
+# us (MM-DD-YYYY HH:MM:SS)
+# euro (DD-MM-YYYY HH:MM:SS)
+# iso8601 (YYYY-MM-DD HH:MM:SS)
+# strict-iso8601 (YYYY-MM-DDTHH:MM:SS)
+#
+
+date_format=us
+
+
+
+# P1.PL FILE LOCATION
+# This value determines where the p1.pl perl script (used by the
+# embedded Perl interpreter) is located. If you didn't compile
+# Nagios with embedded Perl support, this option has no effect.
+
+p1_file=/usr/sbin/p1.pl
+
+
+
+# ILLEGAL OBJECT NAME CHARACTERS
+# This option allows you to specify illegal characters that cannot
+# be used in host names, service descriptions, or names of other
+# object types.
+
+illegal_object_name_chars=`~!$%^&*|'"<>?,()=
+
+
+
+# ILLEGAL MACRO OUTPUT CHARACTERS
+# This option allows you to specify illegal characters that are
+# stripped from macros before being used in notifications, event
+# handlers, etc. This DOES NOT affect macros used in service or
+# host check commands.
+# The following macros are stripped of the characters you specify:
+# $HOSTOUTPUT$
+# $HOSTPERFDATA$
+# $HOSTACKAUTHOR$
+# $HOSTACKCOMMENT$
+# $SERVICEOUTPUT$
+# $SERVICEPERFDATA$
+# $SERVICEACKAUTHOR$
+# $SERVICEACKCOMMENT$
+
+illegal_macro_output_chars=`~$&|'"<>
+
+
+
+# REGULAR EXPRESSION MATCHING
+# This option controls whether or not regular expression matching
+# takes place in the object config files. Regular expression
+# matching is used to match host, hostgroup, service, and service
+# group names/descriptions in some fields of various object types.
+# Values: 1 = enable regexp matching, 0 = disable regexp matching
+
+use_regexp_matching=0
+
+
+
+# "TRUE" REGULAR EXPRESSION MATCHING
+# This option controls whether or not "true" regular expression
+# matching takes place in the object config files. This option
+# only has an effect if regular expression matching is enabled
+# (see above). If this option is DISABLED, regular expression
+# matching only occurs if a string contains wildcard characters
+# (* and ?). If the option is ENABLED, regexp matching occurs
+# all the time (which can be annoying).
+# Values: 1 = enable true matching, 0 = disable true matching
+
+use_true_regexp_matching=0
+
+
+
+
+# ADMINISTRATOR EMAIL ADDRESS
+# The email address of the administrator of *this* machine (the one
+# doing the monitoring). Nagios never uses this value itself, but
+# you can access this value by using the $ADMINEMAIL$ macro in your
+# notification commands.
+
+admin_email=nagios
+
+
+
+# ADMINISTRATOR PAGER NUMBER/ADDRESS
+# The pager number/address for the administrator of *this* machine.
+# Nagios never uses this value itself, but you can access this
+# value by using the $ADMINPAGER$ macro in your notification
+# commands.
+
+admin_pager=pagenagios
+
+
+
+# DAEMON CORE DUMP OPTION
+# This option determines whether or not Nagios is allowed to create
+# a core dump when it runs as a daemon. Note that it is generally
+# considered bad form to allow this, but it may be useful for
+# debugging purposes.
+# Values: 1 - Allow core dumps
+# 0 - Do not allow core dumps (default)
+
+daemon_dumps_core=0
+
+
+
+# EOF (End of file)
+
--- /dev/null
+## as per nagios doc
+OK=0
+WARNING=1
+KO=2
+UNKNOWN=3
+
--- /dev/null
+2 INRIA Sophia OneLab