djagios-0.1.3+dfsg/0000755000175000017500000000000011271302730013024 5ustar bigonbigondjagios-0.1.3+dfsg/urls.py0000644000175000017500000000436011271274740014377 0ustar bigonbigon# Copyright (c) 2009 Jochen Maes # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. from django.conf.urls.defaults import * from djagios.core import views from djagios import config # Uncomment the next two lines to enable the admin: from django.contrib import admin admin.autodiscover() urlpatterns = patterns('', # Example: # (r'^djagios/', include('djagios.foo.urls')), # Uncomment the admin/doc line below and add 'django.contrib.admindocs' # to INSTALLED_APPS to enable admin documentation: # (r'^admin/doc/', include('django.contrib.admindocs.urls')), # Uncomment the next line to enable the admin: (r'^admin/(.*)', admin.site.root), (r'^login/$', 'django.contrib.auth.views.login', {'template_name': '%s/login.html'%config.theme_name}), (r'^logout', 'django.contrib.auth.views.logout_then_login', {'login_url': '/login'},), (r'^@@media/(?P.*)$', 'django.views.static.serve', {'document_root': '/home/sejo/playground/djagios/src/djagios/media/%s/'%config.theme_name}), (r'^hosttemplate/add', views.add_host_template), (r'^host/add', views.add_host), (r'^host/delete', views.delete_host), (r'^service/addhost', views.add_host_to_service), (r'^service/removehost', views.remove_host_from_service), (r'^service/addhosttemplate', views.add_host_template_to_service), (r'^service/removehosttemplate', views.remove_host_template_from_service), (r'^json/servicesforhost/(?P.*)/$',views.get_services_for_host ), (r'^(?P(json|yaml|python))/(?P\w+)/(?P.+)/$',views.get_general), (r'^$', views.home), ) djagios-0.1.3+dfsg/setup.py0000644000175000017500000000205611271274740014552 0ustar bigonbigonimport sys import os import glob from distutils.core import setup def add_folder(source): s = set() for path in os.listdir(source): tpath = os.path.join(source,path) if os.path.isfile(tpath): s.add(tpath) elif os.path.isdir(tpath): s = s.union(add_folder(tpath)) return list(s) data_files = [ ('templates', add_folder(os.path.abspath('djagios/templates'))), ('media', add_folder(os.path.abspath('djagios/media'))), ] print data_files setup( name = "djagios", version = "0.1.3", packages = ['djagios','djagios.core', 'djagios.common',], data_files = [ ('/usr/share/djagios-0.1/templates/default', add_folder(os.path.abspath('djagios/templates'))), ('/usr/share/djagios-0.1/media/default', add_folder(os.path.abspath('djagios/media'))), ], author = "Jochen Maes", author_email = "sejo@djagios.org", description = "A package to help configure nagios written in Django", url = "http://djagios.org/", license = 'GPL2', ) djagios-0.1.3+dfsg/PKG-INFO0000644000175000017500000000037011271302730014121 0ustar bigonbigonMetadata-Version: 1.0 Name: djagios Version: 0.1.3 Summary: A package to help configure nagios written in Django Home-page: http://djagios.org/ Author: Jochen Maes Author-email: sejo@djagios.org License: GPL2 Description: UNKNOWN Platform: UNKNOWN djagios-0.1.3+dfsg/djagios/0000755000175000017500000000000011271302730014444 5ustar bigonbigondjagios-0.1.3+dfsg/djagios/import.py0000644000175000017500000007745311266003241016347 0ustar bigonbigon#!/usr/bin/python # # Djagios import tool # Copyright (c) 2009 Jochen Maes # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. import fileinput import uuid import re import os import sys import logging from django.core.management import setup_environ import settings from django.db import models from djagios.core import models from djagios.core.models import * __version__ = '0.1' setup_environ(settings) LEVELS = {'debug': logging.DEBUG, 'info': logging.INFO, 'warning': logging.WARNING, 'error': logging.ERROR, 'critical': logging.CRITICAL} block_pattern = "define\s+(?P\S*)\s*\{\n*(?P.*?)\}" attrib_pattern = '\s*(?P\S+)\s+(?P.*)' class NagiosConfigParser(): ''' Parser for Nagios Configuration files. Parsing is done in multiple steps. 1) parse main configuration file 2) parse separate config files and write out to standard files 3) parse the standard files following a correct order 4) all objects that cannot be put in the db write out again redo this step until the object is empty 5) remove standard files (if -d is not given) ''' hosts = dict() host_groups = dict() services = dict() service_groups = dict() contacts = dict() contact_groups = dict() def __init__(self): logging.debug('NagiosConfigParser.__init__() called') # temp folder where we will put our config files self.tmp_path = os.path.join('/tmp/', str(uuid.uuid4())) # create folder of tmp_path try: os.mkdir(self.tmp_path) logging.info('Temporary directory %s created for the parsed config files'%self.tmp_path) except: logging.critical('Cannot create %s, exiting!'%self.tmp_path) sys.exit(1) logging.info('NagiosConfigParser initialized!') def write_object(self, key, value): '''Write the data to the correct file.''' text = '''define %s { %s } ''' logging.debug('opening %s/%s.cfg'%(self.tmp_path, key)) file = open('%s/%s.cfg'%(self.tmp_path,key), 'a') file.write(text%(key,value)) file.flush() file.close() logging.debug('closing %s/%s.cfg'%(self.tmp_path, key)) def sanitize(self, path): s = self._get_file_content(path) fd = open(path, 'w') for line in s.splitlines(): if not line.strip(): continue if re.compile('^\s*#').search(line): continue fd.write('%s\n'%line) fd.flush() fd.close() def parse_config(self, path): ''' Parsing object file and writing out to correct file in temp dir. ''' fd = open(path, 'r') s = fd.read() s = s.replace('\\\n','') mo = re.findall("define\s+(?P\S*)\s*\{\n*(?P.*?)\}", s, re.S) for key,value in mo: self.write_object(key, value) fd.close() def parse_main(self,server_name,path): ''' Parse the main nagios configuration. This will allow us to fetch all the needed configuration setting and files. ''' nc = None try: nc = NagiosCfg.objects.get(server_name=server_name) except NagiosCfg.DoesNotExist: nc = NagiosCfg() nc.server_name=server_name nc.save() print "Initial save happend!\n" # open the nagios_file for line in fileinput.input(path): if not line.strip(): continue if re.compile('^#').search(line): continue res = line.split('=', 1) # certain attributes are in fact foreign keys. # So first check whether the entry belongs to one of them. path = CfgPath() logging.debug('setting %s to %s'%(res[0],res[1].strip())) paths_list = ('cfg_dir', 'cfg_file', 'log_file', 'object_cache_file' ,\ 'precached_object_file', 'resource_file', 'temp_file',\ 'temp_path', 'status_file', 'command_file', 'log_archive_path',\ 'check_result_path','state_retention_file', 'lock_file', 'p1_file', ) if res[0] in paths_list: path = CfgPath.get(res[1].strip()) #cfg_dir is manytomany and setattr will fail if res[0] == 'cfg_dir': nc.cfg_dir.add(path) continue #cfg_file is manytomany and setattr will fail if res[0] == 'cfg_file': nc.cfg_file.add(path) continue setattr(nc, res[0], path) continue if isinstance(nc._meta.get_field_by_name(res[0])[0],\ models.NullBooleanField): if res[1].strip() == '1': setattr(nc, res[0], True) else: setattr(nc, res[0], False) continue setattr(nc, res[0], res[1].strip()) nc.save() fileinput.close() print "Nagios main config imported, starting with the other objects" def _delete_all_objects(self, o): '''Delete all objects from database. how to run manage.py reset core?''' pass def _get_file_content(self,filename,delete=True): file = open(filename, 'r') s = file.read() file.close() os.remove(filename) logging.debug('removed %s, filling up with failed objects'%filename) return s def write_queue(self, filename, key, val): block = 'define %s {\n%s\n}\n'%(key,val) queue = open(filename, 'a') queue.write(block) queue.flush() queue.close() def import_command_to_db(self): filename = os.path.join(self.tmp_path, 'command.cfg') s = self._get_file_content(filename) logging.debug('Cleaning out the Command objects from db.') self._delete_all_objects(Command) logging.debug('Finished cleaning the Command objects from db.') mo = re.findall(block_pattern, s, re.S) for key,val in mo: o = Command() #we have our block, so read line per line and parse the block logging.debug('got "%s"'%val.strip()) for line in val.strip().splitlines(): if not line: continue logging.debug('Parsing line %s'%line) m = re.search(attrib_pattern, line, re.I) rdict = m.groupdict() attrib = rdict['attrib'].strip() value = rdict['value'].strip().split(';')[0] if hasattr(o,attrib): setattr(o, attrib, value) try: o.save() except: self.write_queue(filename, key, value) def import_contact_to_db(self,name): logging.debug('starting contact import %s'%name) # list of all the TimePeriod keys TP_KEYS = ('host_notification_period', 'service_notification_period') C_KEYS = ('host_notification_commands', 'service_notification_commands') o = Contact() o.save() #we have our block, so read line per line and parse the block for attrib,value in self.contacts[name].iteritems(): if hasattr(o,attrib): if attrib == 'contactgroups': try: o.contactgroups.add(ContactGroup.get(value)) continue except Contact.DoesNotExist: self.write_queue(filename, key, val) continue if attrib == 'use': try: o.use = Contact.get(value) except Contact.DoesNotExist: self.import_contact_to_db(value) o.use = Contact.get(value) continue if attrib in TP_KEYS: try: setattr(o, attrib, TimePeriod.get(value)) continue except TimePeriod.DoesNotExist: self.write_queue(filename, key, val) continue if attrib == 'host_notification_commands': try: o.host_notification_commands.add(CheckCommand.get(value)) continue except Contact.DoesNotExist: self.write_queue(filename, key, val) continue if attrib == 'service_notification_commands': try: o.service_notification_commands.add(CheckCommand.get(value)) continue except Contact.DoesNotExist: self.write_queue(filename, key, val) continue if isinstance(o._meta.get_field_by_name(attrib)[0],\ models.NullBooleanField): if value == '1': setattr(o, attrib, True) else: setattr(o, attrib, False) continue setattr(o, attrib, value) try: o.save() except Exception, e: logging.debug('Cannot save: %s'%str(e)) def import_contact_group_to_db(self, name): logging.debug('starting contactgroup import %s'%name) o = ContactGroup() o.save() for attrib,value in self.contact_groups[name].iteritems(): if attrib == 'members': for v in value.split(','): o.members.add(Contact.get(v)) continue if attrib == 'contactgroup_members': o.members.add(ContactGroup.get(value)) continue if hasattr(o,attrib): setattr(o, attrib, value) if o.contactgroup_name: o.save() else: ContactGroup.delete(o) logging.debug('finished contactgroup import %s'%name) def import_timeperiod_to_db(self): '''Separate class as the time period needs to be able to create timeranges. WIth other classes we can find out what class is excpected and first fetch or create it. Timerange has dynamic attributes. ''' logging.debug('fetching timerange objects') filename = os.path.join(self.tmp_path, 'timeperiod.cfg') s = self._get_file_content(filename) logging.debug('removed %s, filling up with failed objects'%filename) self._delete_all_objects(TimePeriod) self._delete_all_objects(TimeRange) logging.debug('Finished cleaning the TimePeriod and TimeRange objects from db.') mo = re.findall(block_pattern, s, re.S) for key,val in mo: o = TimePeriod() o.save() for line in val.strip().splitlines(): if not line: continue logging.debug('parse ATTRLINE: %s'%line.strip()) m = re.search(attrib_pattern, line.strip(), re.I) rdict = m.groupdict() logging.debug(rdict) if hasattr(o,rdict['attrib']): if rdict['attrib'] == 'exclude': o.exclude.add(get_timeperiod(rdict['value'].strip().split(';')[0])) continue setattr(o,rdict['attrib'], rdict['value'].split(';')[0]) else: # attribute not found, thus it must be a timeframe tr =TimeRange.get(rdict['attrib'], rdict['value'].split(';')[0]) o.ranges.add(tr) o.save() def import_final_objects(self): '''Here we will import hosts, hostgroups, services and servicegroups. This due to the fact that they are all dependent on each other''' # call the parser that adds the type to global dict. logging.info('Starting with host.cfg') self.parse_to_dict(os.path.join(self.tmp_path, 'host.cfg')) logging.info('Finished with host.cfg') logging.info('Starting with hostgroup.cfg') self.parse_to_dict(os.path.join(self.tmp_path, 'hostgroup.cfg')) logging.info('Finished with hostgroup.cfg') logging.info('Starting with service.cfg') self.parse_to_dict(os.path.join(self.tmp_path, 'service.cfg')) logging.info('Finished with service.cfg') logging.info('Starting with servicegroup.cfg') self.parse_to_dict(os.path.join(self.tmp_path, 'servicegroup.cfg')) logging.info('Finished with servicegroup.cfg') logging.info('Starting with contactgroup.cfg') self.parse_to_dict(os.path.join(self.tmp_path, 'contactgroup.cfg')) logging.info('Finished with contactgroup.cfg') logging.info('Starting with contact.cfg') self.parse_to_dict(os.path.join(self.tmp_path, 'contact.cfg')) logging.info('Finished with contact.cfg') for c in self.contacts: self.import_contact_to_db(c) for cg in self.contact_groups: self.import_contact_group_to_db(cg) # start running over the host dict and import one by one for h in self.hosts: self.import_host_to_db(h) for hg in self.host_groups: self.import_hostgroup_to_db(hg) # we now do the final_stage which will also add the hostgroups # the other values are updated untill we fix it up for h in self.hosts: self.import_host_to_db(h, final_stage=True) for s in self.services: self.import_service_to_db(s) for sg in self.service_groups: self.import_servicegroup_to_db(sg) # we now do the final_stage which will also add the servicegroups # the other values are updated untill we fix it up for s in self.services: self.import_service_to_db(s) def parse_to_dict(self, filename): if not os.path.exists(filename): return s = self._get_file_content(filename) mo = re.findall(block_pattern, s, re.S) for key,val in mo: d = dict() for line in val.strip().splitlines(): if not line or line.startswith('#'): continue if re.match('\s*;.*', line): continue m = re.search(attrib_pattern, line.strip(), re.I) rdict = m.groupdict() attrib = rdict['attrib'].strip() value = rdict['value'].split(';')[0].strip() d[attrib]=value logging.debug('d = %s'%d) if key == 'host': if 'host_name' in d: self.hosts[d['host_name']]=d elif 'name' in d: self.hosts[d['name']]=d continue if key == 'hostgroup': self.host_groups[d['hostgroup_name']]=d continue if key == 'service': if 'service_description' in d: self.services[d['service_description']]=d elif 'name' in d: self.services[d['name']]=d continue if key == 'servicegroup': self.service_groups[d['servicegroup_name']]=d continue if key == 'contactgroup': self.contact_groups[d['contactgroup_name']]=d continue if key == 'contact': if 'contact_name' in d: self.contacts[d['contact_name']]=d elif 'name' in d: self.contacts[d['name']]=d continue def import_hostgroup_to_db(self, name): logging.debug('starting hostgroup import %s'%name) o=None try: o = HostGroup.get(name) logging.debug('hostgroup %s already exists, skipping'%name) return except: o = HostGroup() o.save() for attrib,value in self.host_groups[name].iteritems(): logging.debug('attrib: %s, value: %s'%(attrib, str(value))) if hasattr(o,attrib): if attrib == 'members': for host in value.split(','): logging.debug('found member: %s'%host.strip()) try: h = Host.get(host.strip()) o.members.add(h) except Host.DoesNotExist: self.import_host_to_db(host.strip()) o.members.add(host.strip()) continue if attrib == 'hostgroup_members': for hg in value.split(','): logging.debug('found hostgroup_ member: %s'%hg) hg = hg.strip() try: h = HostGroup.get(hg) o.hostgroup_members.add(HostGroup.get(hg)) except HostGroup.DoesNotExist: self.import_hostgroup_to_db(hg) o.hostgroup_members.add(HostGroup.get(hg)) continue setattr(o,attrib, value) o.save() logging.debug('finished hostgroup import %s'%name) def import_host_to_db(self, name,final_stage=False): logging.debug('starting host import %s'%name) try: o = Host.get(name) except Host.DoesNotExist: o = Host() o.name=name o.save() o.name=None for attrib,value in self.hosts[name].iteritems(): logging.debug('attrib: %s, value: %s'%(attrib, str(value))) if attrib == 'use': try: setattr(o, attrib, Host.get(value)) continue except Host.DoesNotExist: self.import_host_to_db(value) setattr(o, attrib, Host.get(value)) continue if attrib == 'parents': for h in value.split(','): logging.debug('%s: parent found --> %s'%(name,h)) try: o.parents.add(Host.get(h)) continue except Host.DoesNotExist: self.import_host_to_db(h) o.parents.add(Host.get(h)) continue continue if attrib == 'hostgroups': if final_stage: for hg in value.split(','): try: o.hostgroups.add(HostGroup.get(hg)) continue except HostGroup.DoesNotExist: self.import_hostgroup_to_db(value) o.hostgroups.add(HostGroup.get(value)) continue continue else: continue if attrib == 'contacts': o.contacts.add(Contact.get(value)) continue if attrib == 'contact_groups': o.contact_groups.add(ContactGroup.get(value)) continue if attrib == 'notification_period': setattr(o, attrib, TimePeriod.get(value)) continue if attrib == 'check_command': setattr(o, attrib, CheckCommand.get(value)) continue if attrib == 'check_period': setattr(o, attrib, TimePeriod.get(value)) continue if attrib == 'event_handler': setattr(o, attrib, CheckCommand.get(value)) continue if hasattr(o,attrib): if isinstance(o._meta.get_field_by_name(attrib)[0],\ models.NullBooleanField): if value == '1': setattr(o, attrib, True) else: setattr(o, attrib, False) continue setattr(o, attrib, value) elif not attrib.startswith('_'): raise RuntimeError('ERROR: Attribute %s with value "%s" not found'%(attrib,value)) o.save() o = None logging.debug('finished host import %s'%name) def import_service_to_db(self,name,final_stage=False): logging.debug('starting service import %s'%name) try: o = Service.get(name) return except Service.DoesNotExist: o = Service() o.service_description=name o.save() o.service_description=None for attrib,value in self.services[name].iteritems(): logging.debug('attrib: %s, value: %s'%(attrib, str(value))) if attrib == 'use': try: o.use = Service.get(value) continue except Service.DoesNotExist: self.import_service_to_db(value) o.use = Service.get(value) continue if attrib == 'host_name': for h in value.split(','): if h.startswith('!'): o.host_name_n.add(Host.get(h.strip()[1:])) else: o.host_name.add(Host.get(h.strip())) continue if attrib == 'hostgroup_name': for hg in value.split(','): if hg.startswith('!'): o.hostgroup_name_n.add(HostGroup.get(hg.strip()[1:])) else: o.hostgroup_name.add(HostGroup.get(hg.strip())) continue if attrib == 'servicegroups': if final_stage: for sg in value.split(','): try: o.servicegroups.add(ServiceGroup.get(sg)) continue except ServiceGroup.DoesNotExist: self.import_servicegroups_to_db(sg) o.servicegroups.add(ServiceGroup.get(sg)) continue else: continue if attrib == 'contacts': o.contacts.add(Contact.get(value)) continue if attrib == 'contact_groups': o.contact_groups.add(ContactGroup.get(value)) continue if attrib == 'notification_period': setattr(o, attrib, TimePeriod.get(value)) continue if attrib == 'check_command': setattr(o, attrib, CheckCommand.get(value)) continue if attrib == 'check_period': setattr(o, attrib, TimePeriod.get(value)) continue if attrib == 'event_handler': setattr(o, attrib, CheckCommand.get(value)) continue if hasattr(o,attrib): if isinstance(o._meta.get_field_by_name(attrib)[0],\ models.NullBooleanField): if value == '1': setattr(o, attrib, True) else: setattr(o, attrib, False) continue setattr(o, attrib, value) elif not attrib.startswith('_'): raise RuntimeError('ERROR: Attribute %s with value "%s" not found'%(attrib,value)) try : o.save() except: logging.error('Could not save service %s!!!'%o.service_description) logging.debug('finished Service import %s'%name) def import_servicegroup_to_db(self, name): logging.debug('starting servicegroup import %s'%name) o = ServiceGroup() o.save() for attrib,value in self.service_groups[name].iteritems(): logging.debug('attrib: %s, value: %s'%(attrib, str(value))) if hasattr(o,attrib): if attrib == 'members': for s in value.split(','): logging.debug('found member: %s'%s.strip()) try: s = Service.get(s.strip()) o.members.add(s) except Host.DoesNotExist: self.import_host_to_db(s.strip()) o.members.add(Service.get(s)) continue if attrib == 'servicegroup_members': for sg in value.split(','): logging.debug('found servicegroup_member: %s'%host) sg = sg.strip() try: s = ServiceGroup.get(sg) o.servicegroup_members.add(ServiceGroup.get(sg)) except ServiceGroup.DoesNotExist: self.import_servicegroup_to_db(sg) o.servicegroup_members.add(ServiceGroup.get(sg)) continue setattr(o,attrib, value) o.save() logging.debug('finished servicegroup import %s'%name) def import_servicedependency_to_db(self, name): logging.debug('starting servicedependency import %s'%name) o = ServiceDependency() o.save() for attrib,value in self.service_dependencies[name].iteritems(): logging.debug('attrib: %s, value: %s'%(attrib, str(value))) if hasattr(o,attrib): if attrib in ('dependent_host_name','host_name'): for s in value.split(','): logging.debug('found host_name: %s'%s.strip()) try: h = Host.get(s.strip()) if attrib == 'host_name': o.host_name.add(h) else: o.dependent_host_name.add(h) except Host.DoesNotExist: self.import_host_to_db(h.strip()) if attrib == 'host_name': o.host_name.add(Host.get(h)) else: o.dependent_host_name.add(Host.get(h)) continue if attrib in ('dependent_hostgroup_name','hostgroup_name'): for s in value.split(','): logging.debug('found hostgroup_name: %s'%s.strip()) try: hg = HostGroup.get(s.strip()) if attrib == 'host_name': o.hostgroup_name.add(hg) else: o.dependent_hostgroup_name.add(hg) except HostGroup.DoesNotExist: self.import_hostgroup_to_db(hg.strip()) if attrib == 'hostgroup_name': o.hostgroup_name.add(HostGroup.get(hg)) else: o.dependent_hostgroup_name.add(HostGroup.get(hg)) continue if attrib in ('dependent_service_description', 'service_description'): try: settattr(o,attrib,Service.get(value.strip())) except Service.DoesNotExist: self.import_service_to_db(value.strip()) settattr(o,attrib,Service.get(value.strip())) continue if attrib == 'dependency_period': settattr(o,attrib,TimePeriod.get(value.strip())) continue setattr(o,attrib, value) o.save() logging.debug('finished servicegroup import %s'%name) def get_config_files(self, path): """method to fetch all files in a certain path""" dirlist = os.listdir(path) reslist = set() for file in dirlist: abs_file = os.path.join(path, file) if os.path.isfile(abs_file) \ and abs_file.endswith('cfg'): reslist.add(abs_file) elif os.path.isdir(abs_file): reslist.update(self.get_config_files(abs_file)) return reslist def import_config(self,server_name,path): '''Imports the config files fetched from the nagios.cfg file and parses all objects to a file per object type. This will allow us to import the the different files without having key issues. ''' self.parse_main(server_name, path) nc = NagiosCfg.objects.get(server_name=server_name) for path in nc.cfg_dir.values(): logging.debug('Found %s as cfg_dir path'%(path['path'])) if os.path.isdir(path['path']): dirlist = self.get_config_files(path['path']) for file in dirlist: if file.endswith('.cfg'): logging.debug('Found %s as nagios config file'%file) logging.debug('Sanitizing the config file first') self.sanitize(file) self.parse_config(file) for path in nc.cfg_file.values(): if os.path.isfile(path['path']) \ and path['path'].endswith('.cfg'): logging.debug('Found %s as nagios config file'%path) logging.debug('Sanitizing the config file first') self.sanitize(path['path']) logging.debug('parsing the config file') self.parse_config(path['path']) # import the files into objects and db self.import_command_to_db() self.import_timeperiod_to_db() self.import_final_objects() # remove the temp dir! TODO os.rmdir(self.tmp_path) if __name__ == '__main__': from optparse import OptionParser, make_option option_list = [ make_option("-s", "--server_name", action="store", dest="server_name", default='localhost', help="Submit the server name for the config"), make_option("-p", "--path", action="store", dest="path", default='/etc/nagios/nagios.cfg', help="Path of the main configuration file."), make_option("-d", "--debuglevel", action="store", dest="debuglevel", default="info", help="Level of debugging can be any of \ (debug,info,warning, error or critical)") ] parser = OptionParser(usage="python %prog [options]", version=__version__, description="An import tool for adding an existing nagios configuration to Djagios.", option_list=option_list) (options,args) = parser.parse_args() level = LEVELS.get(options.debuglevel, logging.NOTSET) logging.basicConfig(level=level) ncp = NagiosConfigParser() ncp.import_config(options.server_name, options.path) djagios-0.1.3+dfsg/djagios/core/0000755000175000017500000000000011271302730015374 5ustar bigonbigondjagios-0.1.3+dfsg/djagios/core/views.py0000644000175000017500000002010511271274740017112 0ustar bigonbigon# Copyright (c) 2009 Jochen Maes # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. from django.http import HttpResponse, HttpResponseRedirect from django.utils import simplejson from django.shortcuts import render_to_response from django.template import RequestContext, loader from django.core import serializers from django.contrib.auth.decorators import login_required, permission_required from django.core.paginator import Paginator, InvalidPage, EmptyPage from django import forms from djagios import config from djagios.core.models import * def _sanitize_alias(name): return name.replace(' ', '_').lower() @login_required def home(request): t = loader.get_template('%s/home.html'%config.theme_name) # getting lists of hosts and their services hlist = Host.objects.exclude(register=False).order_by('host_name') paginator = Paginator(hlist, 10) try: page = int(request.GET.get('page', '1')) except ValueError: page = 1 try: hosts = paginator.page(page) except (EmptyPage, InvalidPage): hosts = paginator.page(paginator.num_pages) c = RequestContext(request, {'config': config, 'hosts':hosts, 'hlist':hlist}) return HttpResponse(t.render(c)) @permission_required('core.add_hosttemplate', login_url='/login') def add_host_template(request): if request.method == 'POST': form = HostTemplateForm(request.POST) if form.is_valid(): form.save() return HttpResponseRedirect('/') else: form = HostTemplateForm() t = loader.get_template('%s/hosttemplateadd.html'%config.theme_name) c = RequestContext(request, {'config':config, 'form':form,}) return HttpResponse(t.render(c)) @permission_required('core.add_host', login_url='/login') def add_host(request): if request.method == 'POST': form = HostForm(request.POST) if form.is_valid(): h = Host() h.host_name = _sanitize_alias(form.cleaned_data['name']) h.alias = form.cleaned_data['name'] h.address = form.cleaned_data['address'] h.use = form.cleaned_data['template'] h.save() return HttpResponseRedirect('/') else: form = HostForm() t = loader.get_template('%s/hostadd.html'%config.theme_name) c = RequestContext(request, {'config':config, 'form':form,}) return HttpResponse(t.render(c)) @permission_required('core.delete_host', login_url='/login') def delete_host(request): if request.method == 'POST': form = HostDeleteForm(request.POST) if form.is_valid(): h = form.cleaned_data['host'] h.delete() return HttpResponseRedirect('/') else: form = HostDeleteForm() t = loader.get_template('%s/hostdelete.html'%config.theme_name) c = RequestContext(request, {'config':config, 'form':form,}) return HttpResponse(t.render(c)) @permission_required('core.change_service', login_url='/login') def add_host_to_service(request): return _add_host_to_service(request, False) @permission_required('core.change_host', login_url='/login') def add_host_template_to_service(request): return _add_host_to_service(request, True) def _add_host_to_service(request, template): if request.method == 'POST': form=None if template: form=HostTemplateToServiceForm(request.POST) else: form = HostToServiceForm(request.POST) if form.is_valid(): s = form.cleaned_data['service'] h = form.cleaned_data['host'] s.host_name.add(h) s.save() return HttpResponseRedirect('/') else: form=None t=None if template: form = HostTemplateToServiceForm() t = loader.get_template('%s/hosttemplateservice.html'%config.theme_name) else: form = HostToServiceForm() t = loader.get_template('%s/hostservice.html'%config.theme_name) c = RequestContext(request, {'config':config, 'form':form,}) return HttpResponse(t.render(c)) @permission_required('core.change_service', login_url='/login') def remove_host_from_service(request): return _remove_host_from_service(request,False) @permission_required('core.change_host', login_url='/login') def remove_host_template_from_service(request): return _remove_host_from_service(request,True) def _remove_host_from_service(request,template): if request.method == 'POST': form=None if template: form=HostTemplateFromServiceForm(request.POST) else: form = HostFromServiceForm(request.POST) if form.is_valid(): s = form.cleaned_data['service'] h = form.cleaned_data['host'] if h in s.host_name.all(): s.host_name.remove(h) else: s.host_name_n.add(h) s.save() return HttpResponseRedirect('/') else: form=None t=None if template: form = HostTemplateFromServiceForm() t = loader.get_template('%s/hosttemplateservice.html'%config.theme_name) else: form = HostFromServiceForm() t = loader.get_template('%s/hostservice.html'%config.theme_name) c = RequestContext(request, {'config':config, 'form':form, 'remove':True}) return HttpResponse(t.render(c)) ################################## ##### Helper methods ################################## def _services_for_host(host_id): host = Host.objects.get(id=host_id) slist = Service.objects.filter(host_name=host_id) for hg in HostGroup.objects.filter(members=host_id): slist = slist | Service.objects.filter(hostgroup_name=hg).exclude(hostgroup_name_n=hg) if host.use: slist = slist | _services_for_host(host.use.id) return slist.exclude(host_name_n=host_id).order_by('service_description') def get_services_for_host(request, host_id): slist = _services_for_host(host_id) json_value = serializers.serialize('json', slist) return HttpResponse(json_value, mimetype="application/javascript") def get_general(request, exporttype, type, name): """Get the object requested if it exists. """ type=type.lower() value='' o=None try: if type =='host': o = Host.get(name) elif type == 'hostgroup': o = HostGroup.get(name) elif type == 'service': o = Service.get(name) elif type == 'servicegroup': o = ServiceGroup.get(name) elif type == 'contact': o = Contact.get(name) elif type == 'contactgroup': o = ContactGroup.get(name) elif type == 'command': o = Command.get(name) elif type == 'checkcommand': o = CheckCommand.get(name) elif type == 'timeperiod': o == TimePeriod.get(name) elif type == 'timerange': o == TimeRange.get(name) elif type == 'servicedependency': o == ServiceDependency.get(name) elif type == 'cfgpath': o == CfgPath.get(name) else: txt="""ObjectType not Known: supported list: Host HostGroup Service ServiceGroup Contact Command CheckCommand TimePeriod TimeRange CfgPath """ return HttpResponse(txt) value = serializers.serialize(exporttype,(o,)) return HttpResponse(value, mimetype="application/javascript") except: return HttpResponse("Object not found") djagios-0.1.3+dfsg/djagios/core/__init__.py0000644000175000017500000000134211263720041017505 0ustar bigonbigon# Copyright (c) 2009 Jochen Maes # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. djagios-0.1.3+dfsg/djagios/core/exceptions.py0000644000175000017500000000233511266774152020151 0ustar bigonbigon# Copyright (c) 2009 Jochen Maes # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. class ParseError(Exception): """Exception should be rased when parsing to or from the nagios format failed""" def __init__(self, msg): self.msg = msg def __str__(self): return "Error occured got error message: %s"%self.msg class InvalidObjectError(Exception): """Exception should be rased when deserializing from an external stream""" def __init__(self, msg): self.msg = msg def __str__(self): return "Error occured got error message: %s"%self.msg djagios-0.1.3+dfsg/djagios/core/admin.py0000644000175000017500000000415611263720041017044 0ustar bigonbigon# Copyright (c) 2009 Jochen Maes # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. from django.contrib import admin from djagios.core.models import * class HostAdmin(admin.ModelAdmin): list_display = ('alias', 'host_name', 'name', 'address') class HostGroupAdmin(admin.ModelAdmin): list_display = ('alias', 'hostgroup_name') class NagiosCfgAdmin(admin.ModelAdmin): pass class CfgPathAdmin(admin.ModelAdmin): pass class CommandAdmin(admin.ModelAdmin): pass class CheckCommandAdmin(admin.ModelAdmin): pass class ServiceAdmin(admin.ModelAdmin): pass class ServiceGroupAdmin(admin.ModelAdmin): pass class ContactAdmin(admin.ModelAdmin): pass class ContactGroupAdmin(admin.ModelAdmin): pass class TimePeriodAdmin(admin.ModelAdmin): pass class TimeRangeAdmin(admin.ModelAdmin): pass class HostTemplateAdmin(admin.ModelAdmin): pass admin.site.register(Host, HostAdmin) admin.site.register(HostGroup, HostGroupAdmin) admin.site.register(NagiosCfg, NagiosCfgAdmin) admin.site.register(CfgPath, CfgPathAdmin) admin.site.register(Command, CommandAdmin) admin.site.register(CheckCommand, CheckCommandAdmin) admin.site.register(Service, ServiceAdmin) admin.site.register(ServiceGroup, ServiceGroupAdmin) admin.site.register(Contact, ContactAdmin) admin.site.register(ContactGroup, ContactGroupAdmin) admin.site.register(TimePeriod, TimePeriodAdmin) admin.site.register(TimeRange, TimeRangeAdmin) admin.site.register(HostTemplate, HostTemplateAdmin) djagios-0.1.3+dfsg/djagios/core/models.py0000644000175000017500000017412611271274740017255 0ustar bigonbigon# Copyright (c) 2009 Jochen Maes # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. """The models module defines the nagios configuration datastructures as classes. For obvious reasons you should also check the Nagios documentation for the attributes. Each attribute has been named as the configuration option in nagios. example:: define command { command_name com1 command_line line1 } The previous example is a basic definition of the command object in nagios. We mapped this to the following api:: >>> com = Command() >>> com.command_name = 'com1' >>> com.command_line = 'line1' Where we could we would link to another object. example:: define contactgroup { contactgroup_name cg1 alias Contact group 1 members admins,nagios } To map this example we can link the members section to a list of Contact objects. This would be done with a many to many relationship. This resulted in following api:: >>> cg = ContactGroup() >>> cg.contactgroup_name = 'cg1' >>> cg.alias = 'Contact group 1' >>> cg.save() >>> cg.members.add(Contact.get('admins')) >>> cg.members.add(Contact.get('nagios')) As you can see we saved before adding a member. This is to be able to save the many to many references correctly. So as long as the object has no ID we cannot add many to many relations. """ import os import logging import StringIO from django.db import models from django.core import serializers from django import forms from djagios.core.exceptions import ParseError, InvalidObjectError HOST_STATES = ( ('d', 'down'), ('u', 'unreachable'), ('o', 'up') ) LOG_ROTATION_METHODS = ( ('n', 'none'), ('h', 'hourly'), ('d', 'daily'), ('w', 'weekly'), ('m', 'monthly'), ) OPEN_FILE_MODES = ( ('a', 'append'), ('w', 'write'), ('p', 'non-blocking read-write'), ) class NagiosObject: """Abstract class for all NagiosObjects Each NagiosObject contains following methods: - :func:`get` - :func:`parse_to_nagios_cfg` Basicly :func:`get` will fetch the information from the database, :func:`export` will export the object to a nagios configuration string """ @classmethod def get(self, criterion): """Classmethod :func:`get` should always provide a way to fetch an object from the database by providing on of the key values. Returns the object or raises an error if no object with that criterion has been found :param criterion: Criterion to fetch the object :type criterion: :class:`str` :rtype: :class:`NagiosObject` :raises: :exc:`DoesNotExist` """ raise NotImplementedError('Method not implemented go slap the developer!') def serialize(self, type='python'): """:func:`serialize` Allows you to serialize the object to the possible serializers in django. Right now we can serialize to following formats: - json - python - xml - yaml For more information on the serializers in django please visit: http://docs.djangoproject.com/en/dev/topics/serialization/ :param type: Type of the serialization default set to python :type type: :class:`str` :return str: String containing the the serialized information """ serializer = serializers.get_serializer(type)() return serializer.serialize((self,)) def deserialize(self, data, type='python'): """:func:`deserialize` allows you to import data you received into the database. :func:`deserialize` will first check whether the data can be imported, else it throws an error. :param type: Type of the serialization default set to python :rtype type: :class:`str` :param data: Data containing the serialized object(s) :type data: :class:`str` """ for deserialized_object in serializers.deserialize(type, data): if object_should_be_saved(deserialized_object): deserialized_object.save() else: raise InvalidObjectError('The %s data cannot be saved to the database.') def parse_to_nagios_cfg(self, path=None): """Each NagiosObject should provide a way to parse the object to a string containing the nagios configuration block. :param path: Optional, allows to pass the dir where the file will be written. :type path: :class:`str` :rtype: :class:`str` """ raise NotImplementedError('Method not implemented go slap the developer!') class Host (NagiosObject, models.Model): """Host is the class that defines the nagios host model. It uses foreign keys and many2many relationships to have a basic validation and control. At this time Django does not support validation for attributes so this will be included later. Before you can start assigning m2m relations you need to save the object first. Make sure you add a host_name or name before saving. This to allow you to fetch the host easily:: >>> from djagios.core.models import Host >>> host = Host() >>> host.host_name="host01" >>> host.save() :class:`Host` has following m2m relations: - parents: :class:`Host` - hostgroups: :class:`HostGroup` - contacts: :class:`Contact` - contact_groups: :class:`ContactGroup` :class:`Host` has following Foreign Keys: - use: :class:`Host` - check_command: :class:`CheckCommand` - check_period: :class:`TimePeriod` - event_handler: :class:`CheckCommand` - notification_period: :class:`TimePeriod` :parent: :class:`NagiosObject` """ FILE_NAME = 'host.cfg' use = models.ForeignKey('self', related_name='H_use_H', \ blank=True,null=True) name = models.CharField(max_length=100, blank=True, null=True) host_name = models.CharField(max_length=255, blank=True,null=True) alias = models.CharField(max_length=255, blank=True, null=True) address = models.CharField(max_length=255, blank=True, null=True) display_name = models.CharField(max_length=255, blank=True, null=True) parents = models.ManyToManyField('self', symmetrical=False, related_name='%(class)s_parents_H',\ blank=True, null=True) hostgroups = models.ManyToManyField('HostGroup', related_name='H_hg_HG',\ blank=True,null=True) check_command = models.ForeignKey('CheckCommand', related_name='H_cc_CC,', blank=True,null=True) check_period = models.ForeignKey('TimePeriod', related_name='H_cp_TP', blank=True,null=True) initial_state = models.CharField(max_length=1, choices=HOST_STATES, blank=True, null=True) max_check_attempts = models.IntegerField(blank=True, null=True) check_interval = models.IntegerField(blank=True, null=True) retry_interval = models.IntegerField(blank=True, null=True) active_checks_enabled = models.NullBooleanField(blank=True, null=True) passive_checks_enables = models.NullBooleanField(blank=True, null=True) obsess_over_host = models.NullBooleanField(blank=True, null=True) check_freshness = models.NullBooleanField(blank=True, null=True) freshness_threshold = models.IntegerField(blank=True, null=True) event_handler = models.ForeignKey('CheckCommand', related_name='H_eh_CC',\ blank=True, null=True) event_handler_enabled = models.NullBooleanField(blank=True, null=True) low_flap_threshold = models.IntegerField(blank=True, null=True) high_flap_threshold = models.IntegerField(blank=True, null=True) flap_detection_enabled = models.NullBooleanField(blank=True, null=True) flap_detection_options = models.CharField(max_length=10, blank=True,null=True) process_perf_data = models.NullBooleanField(blank=True, null=True) retain_status_information = models.NullBooleanField(blank=True, null=True) retain_nonstatus_information = models.NullBooleanField(blank=True, null=True) contacts = models.ManyToManyField('Contact', related_name='H_c_C',\ blank=True,null=True) contact_groups = models.ManyToManyField('ContactGroup', related_name='H_cg_CG',\ blank=True, null=True) notification_interval = models.IntegerField(blank=True, null=True) first_notification_delay = models.IntegerField(blank=True, null=True) notification_period = models.ForeignKey('TimePeriod', related_name='H_np_TP',\ blank=True, null=True) notification_options = models.CharField(max_length=20, blank=True, null=True) notifications_enabled = models.NullBooleanField(blank=True, null=True) stalking_options = models.CharField(max_length=10,blank=True, null=True) notes = models.TextField(blank=True,null=True) notes_url = models.URLField(verify_exists=True, blank=True, null=True) action_url = models.URLField(verify_exists=True, blank=True, null=True) icon_image = models.CharField(max_length=100, blank=True, null=True) icon_image_alt = models.CharField(max_length=255, blank=True, null=True) vrml_image = models.CharField(max_length=255, blank=True, null=True) statusmap_image = models.CharField(max_length=255, blank=True, null=True) x_coord = models.IntegerField(blank=True, null=True) y_coord = models.IntegerField(blank=True, null=True) z_coord = models.IntegerField(blank=True, null=True) register = models.NullBooleanField(blank=True,null=True) def Meta(self): """Here for Host we define the unique key that exists out of 2 attributes host_name and name. """ unique_together = (('host_name', 'name', 'address'),) @classmethod def get(self, criterion): """classmethod that will allow you to fetch a :class:`Host` object from the database. >>> h = host.get('nagios1') >>> type(h) >>> h.host_name nagios1 :param criterion: criterion you wish to supply, for :class:`Host` this is host_name or name :type criterion: str :rtype: :class:`Host` or None :raises: :exc:`DoesNotExist` """ o = None try: o = Host.objects.get(name=criterion) return o except Host.DoesNotExist: try: o = Host.objects.get(host_name=criterion) return o except Host.DoesNotExist: raise Host.DoesNotExist('Cannot find the host based on your criterion: %s'%criterion) def parse_to_nagios_cfg(self, path=None): """:func:`parse_to_nagios_cfg` will create a nagios formatted block of the current :class:`Host` object. :param path: Optional, allows to pass the dir where the file will be written. :type path: :class:`str` :rtype: :class:`str` :raises: :Exc:`djagios.core.exceptions.ParseError` """ s = StringIO.StringIO() s.write('define host {\n') for attr in self._meta.get_all_field_names(): if not hasattr(self, attr) or attr == 'id': continue if attr in ('parents', 'hostgroups', 'contacts', 'contact_groups', ): if len(getattr(self,attr).values()) > 0: vals = list() for i in getattr(self,attr).iterator(): vals.append(str(i)) s.write('\t%s\t\t%s\n'%(attr, ",".join(vals))) continue value = getattr(self, attr) if not value and not attr == 'register': continue if isinstance(value, (str,int, unicode, long,\ CheckCommand, Service, Host, HostGroup, TimePeriod)): s.write('\t%s\t\t%s\n'%(attr,value)) s.write('}\n') s.flush() ret = s.getvalue() s.close() return ret def __str__(self): return self.host_name or self.name class HostGroup(NagiosObject, models.Model): """Definition for the Nagios hostgroup object. :class:`HostGroup` has following m2m fields: - members: :class:`Host` - hostgroup_members: :class:`HostGroup` """ FILE_NAME = 'hostgroup.cfg' hostgroup_name = models.CharField(max_length=255, unique=True) alias = models.CharField(max_length=255, blank=True,null=True) members = models.ManyToManyField(Host, related_name='HG_m_H',\ blank=True,null=True) hostgroup_members= models.ManyToManyField('self', symmetrical=False, related_name='HG_hgm_HG',\ blank=True,null=True) notes = models.TextField(blank=True,null=True) notes_url = models.URLField(verify_exists=True, blank=True,null=True) action_url = models.URLField(verify_exists=True, blank=True,null=True) @classmethod def get(self, criterion): """classmethod that will allow you to fetch a :class:`HostGroup` object from the database. :param criterion: criterion you wish to supply, for :class:`HostGroup` this is the hostgroup_name :type criterion: str :rtype: :class:`HostGroup` or None :raises: :exc:`DoesNotExist` """ o = None try: o = HostGroup.objects.get(hostgroup_name=criterion) return o except HostGroup.DoesNotExist: raise HostGroup.DoesNotExist('Cannot find the hostgroup based on your criterion: %s'%criterion) def parse_to_nagios_cfg(self, path=None): """:func:`parse_to_nagios_cfg` will create a nagios formatted block of the current :class:`HostGroup` object. :param path: Optional, allows to pass the dir where the file will be written. :type path: :class:`str` :rtype: :class:`str` :raises: :Exc:`djagios.core.exceptions.ParseError` """ s = StringIO.StringIO() s.write('define hostgroup {\n') for attr in self._meta.get_all_field_names(): if not hasattr(self, attr) or attr == 'id': continue if attr in ('members', 'hostgroup_members',): if len(getattr(self,attr).values()) > 0: vals = list() for i in getattr(self,attr).iterator(): vals.append(str(i)) s.write('\t%s\t\t%s\n'%(attr, ",".join(vals))) continue value = getattr(self, attr) if not value: continue if isinstance(value, (str,int, unicode, long)): s.write('\t%s\t\t%s\n'%(attr,value)) continue if isinstance(value, bool): if value: s.write('\t%s\t\t%s\n'%(attr,'1')) else: s.write('\t%s\t\t%s\n'%(attr,'0')) s.write('}\n') s.flush() ret = s.getvalue() s.close() return ret def __str__(self): return self.hostgroup_name class Service(NagiosObject, models.Model): """Service is the class that defines the Nagios service object. :class:`Service` has following m2m fields: - host_name: :class:`Host` - hostgroup_name: :class:`HostGroup` - host_name_n: :class:`Host` - hostgroup_name_n: :class:`HostGroup` - servicegroups: :class:`ServiceGroup` - contacts: :class:`Contact` - contact_groups: :class:`ContactGroup` :class:`Service` has following Foreign keys: - use: :class:`Service` - check_command: :class:`CheckCommand` - check_period: :class:`TimePeriod` - event_handler: :class:`CheckCommand` - notification_period: :class:`TimePeriod` """ FILE_NAME = 'service.cfg' use = models.ForeignKey('Service', related_name='S_use_S', \ blank=True,null=True) name = models.CharField(max_length=100, blank=True) host_name = models.ManyToManyField(Host, related_name='S_hostname_H',\ blank=True,null=True) hostgroup_name = models.ManyToManyField(HostGroup, related_name='S_hostgroup_HG',\ blank=True,null=True) host_name_n = models.ManyToManyField(Host, related_name='S_hostname_n_H',\ blank=True,null=True) hostgroup_name_n = models.ManyToManyField(HostGroup, related_name='S_hostgroup_n_HG',\ blank=True,null=True) service_description = models.CharField(max_length=255, blank=True,null=True) display_name = models.CharField(max_length=255, blank=True) servicegroups = models.ManyToManyField('ServiceGroup', related_name='S_sg_SG',\ blank=True,null=True) is_volatile = models.NullBooleanField(blank=True,null=True) check_command = models.ForeignKey('CheckCommand', related_name='S_cc_CC',\ blank=True,null=True) initial_state = models.CharField(max_length=1,blank=True, null=True) max_check_attempts = models.IntegerField(blank=True,null=True) check_interval = models.IntegerField(blank=True,null=True) retry_interval = models.IntegerField(blank=True,null=True) active_checks_enabled = models.NullBooleanField(blank=True,null=True) passive_checks_enabled = models.NullBooleanField(blank=True,null=True) check_period = models.ForeignKey('TimePeriod',related_name='S_cp_TP',\ blank=True,null=True) obsess_over_service = models.NullBooleanField(default=False) check_freshness = models.NullBooleanField(blank=True,null=True) freshness_threshold = models.IntegerField(blank=True,null=True) event_handler = models.ForeignKey('CheckCommand', related_name='S_eh_CC',\ blank=True, null=True) event_handler_enabled = models.NullBooleanField(default=False) low_flap_threshold = models.IntegerField(default=0) high_flap_threshold = models.IntegerField(default=0) flap_detection_enabled = models.NullBooleanField(default=False) flap_detection_options = models.CharField(max_length=10, blank=True) process_perf_data = models.NullBooleanField(default=False) retain_status_information = models.NullBooleanField() retain_nonstatus_information = models.NullBooleanField(default=False) contacts = models.ManyToManyField('Contact', related_name='S_c_C',\ blank=True,null=True) contact_groups = models.ManyToManyField('ContactGroup', related_name='S_cg_CG',\ blank=True,null=True) notification_interval = models.IntegerField(blank=True,null=True) first_notification_delay = models.IntegerField(blank=True,null=True) notification_period = models.ForeignKey('TimePeriod', related_name='S_np_TP',\ blank=True,null=True) notification_options = models.CharField(max_length=10, blank=True) notifications_enabled = models.NullBooleanField() stalking_options = models.CharField(max_length=10,blank=True) notes = models.TextField(blank=True) notes_url = models.URLField(verify_exists=True,blank=True) action_url = models.URLField(verify_exists=True,blank=True) icon_image = models.CharField(max_length=100,blank=True) icon_image_alt = models.CharField(max_length=255,blank=True) register = models.NullBooleanField(blank=True, null=True) def __str__(self): return self.service_description or self.name def Meta(self): unique_together = (('name', 'host_name', 'service_description',),) @classmethod def get(self,criterion): """classmethod that will allow you to fetch a :class:Service` object from the database. :param criterion: criterion you wish to supply, for :class:`Service` this is the service_description or name :type criterion: str :rtype: :class:`Service` or None :raises: :exc:`DoesNotExist` """ o = None try: o = Service.objects.get(service_description=criterion) return o except Service.DoesNotExist: try: o = Service.objects.get(name=criterion) return o except Service.DoesNotExist: raise Service.DoesNotExist('Cannot find the service based on your criterion: %s'%criterion) def parse_to_nagios_cfg(self, path=None): """:func:`parse_to_nagios_cfg` will create a nagios formatted block of the current :class:`Service` object. :param path: Optional, allows to pass the dir where the file will be written. :type path: :class:`str` :rtype: :class:`str` :raises: :Exc:`djagios.core.exceptions.ParseError` """ s = StringIO.StringIO() s.write('define service {\n') hlist = list() hglist = list() for attr in self._meta.get_all_field_names(): if not hasattr(self, attr) or attr == 'id' or attr == 'id': continue if attr == 'host_name': if len(getattr(self,attr).values()) > 0: vals = list() for i in getattr(self,attr).iterator(): hlist.append(str(i)) continue if attr == 'host_name_n': if len(getattr(self,attr).values()) > 0: vals = list() for i in getattr(self,attr).iterator(): hlist.append('!%s'%str(i)) continue if attr == 'hostgroup_name': if len(getattr(self,attr).values()) > 0: vals = list() for i in getattr(self,attr).iterator(): hglist.append(str(i)) continue if attr == 'hostgroup_name_n': if len(getattr(self,attr).values()) > 0: vals = list() for i in getattr(self,attr).iterator(): hlist.append('!%s'%str(i)) continue if attr in ('servicegroups', 'contacts', 'contact_groups', ): if len(getattr(self,attr).values()) > 0: vals = list() for i in getattr(self,attr).iterator(): vals.append(str(i)) s.write('\t%s\t\t%s\n'%(attr, ",".join(vals))) continue value = getattr(self, attr) if not value: continue if isinstance(value, (str,int, unicode, bool, long,\ CheckCommand, Service, TimePeriod)): s.write('\t%s\t\t%s\n'%(attr,value)) if len(hlist): s.write('\t%s\t\t%s\n'%('host_name', ",".join(hlist))) if len(hglist): s.write('\t%s\t\t%s\n'%('hostgroup_name', ",".join(hglist))) s.write('}\n') s.flush() ret = s.getvalue() s.close() return ret class ServiceGroup(NagiosObject, models.Model): """Definition for the Nagios servicegroup object. :class:`ServiceGroup` has following m2m fields: - members: :class:`Service` - servicegroup_members: :class:`ServiceGroup` """ FILE_NAME='servicegroup.cfg' servicegroup_name = models.CharField(max_length=255, unique=True) alias = models.CharField(max_length=255,blank=True) members = models.ManyToManyField(Service, related_name='SG_members_S',\ blank=True,null=True) servicegroup_members= models.ManyToManyField('self', symmetrical=False, related_name='SG_sgm_SG',\ blank=True,null=True) notes = models.TextField() notes_url = models.URLField(verify_exists=True) action_url = models.URLField(verify_exists=True) @classmethod def get(self, criterion): """classmethod that will allow you to fetch a :class:ServiceGroup` object from the database. :param criterion: criterion you wish to supply, for :class:`ServiceGroup` this is the servicegroup_name :type criterion: str :rtype: :class:`ServiceGroup` or None :raises: :exc:`DoesNotExist` """ o = None try: o = ServiceGroup.objects.get(servicegroup_name=criterion) return o except ServiceGroup.DoesNotExist: raise Contact.DoesNotExist('Cannot find the servicegroup based on your criterion: %s'%criterion) def parse_to_nagios_cfg(self, path=None): """:func:`parse_to_nagios_cfg` will create a nagios formatted block of the current :class:`ServiceGroup` object. :rtype: :class:`str` :raises: :Exc:`djagios.core.exceptions.ParseError` """ s = StringIO.StringIO() s.write('define servicegroup {\n') for attr in self._meta.get_all_field_names(): if not hasattr(self, attr) or attr == 'id': continue if attr in ('members', 'servicegroup_members',): if len(getattr(self,attr).values()) > 0: vals = list() for i in getattr(self,attr).iterator(): vals.append(str(i)) s.write('\t%s\t\t%s\n'%(attr, ",".join(vals))) continue value = getattr(self, attr) if not value: continue if isinstance(value, (str,int, unicode, bool, long,\ CheckCommand, Service)): s.write('\t%s\t\t%s\n'%(attr,value)) s.write('}\n') s.flush() ret = s.getvalue() s.close() return ret def __str__(self): return self.servicegroup_name class Contact(NagiosObject, models.Model): """Definition for the Nagios contact object :class:`Contact` has following :class:`django.db.models.ManyToManyField` attributes: - :attr:`contactgroups` - :attr:`host_notification_commands` - :attr:`service_notification_options` :class:`Contact` has following :class:`django.db.models.ForeignKey` attributes: - :attr:`use` - :attr:`host_notification_period` - :attr:`service_notification_period` """ FILE_NAME = 'contact.cfg' use = models.ForeignKey('Contact', related_name='C_use_C', \ blank=True,null=True) name = models.CharField(max_length=100, blank=True) contact_name = models.CharField(max_length=255, blank=True) alias = models.CharField(max_length=255, blank=True) contactgroups = models.ManyToManyField('ContactGroup', related_name='C_cg_CG',\ blank=True, null=True) host_notifications_enabled = models.NullBooleanField(blank=True,null=True) service_notifications_enabled = models.NullBooleanField(blank=True,null=True) host_notification_period = models.ForeignKey('TimePeriod', related_name='C_hnp_TP',\ blank=True, null=True) service_notification_period = models.ForeignKey('TimePeriod', related_name='C_snp_TP',\ blank=True, null=True) host_notification_options = models.CharField(max_length=20) service_notification_options = models.CharField(max_length=20) host_notification_commands = models.ManyToManyField('CheckCommand',related_name='C_hnc_CC',\ blank=True, null=True) service_notification_commands = models.ManyToManyField('CheckCommand', related_name='C_snc_CC',\ blank=True, null=True) email = models.EmailField(blank=True) pager = models.CharField(max_length=255, blank=True) address = models.TextField(blank=True) can_submit_commands = models.NullBooleanField(blank=True,null=True) retain_status_information = models.NullBooleanField(blank=True,null=True) retain_nonstatus_information = models.NullBooleanField(blank=True,null=True) register = models.NullBooleanField(blank=True,null=True) @classmethod def get(self, criterion): """classmethod that will allow you to fetch a :class:Contact` object from the database. :param criterion: criterion you wish to supply, for :class:`Contact` this is the :attr:`name` or :attr:`contact_name` :type criterion: str :rtype: :class:`Contact` or :class:`None` :raises: :exc:`DoesNotExist` """ o = None try: o = Contact.objects.get(name=criterion) return o except Contact.DoesNotExist: try: o = Contact.objects.get(contact_name=criterion) return o except Contact.DoesNotExist: raise Contact.DoesNotExist('Cannot find the contact based on your criterion: %s'%criterion) def parse_to_nagios_cfg(self, path=None): """:func:`parse_to_nagios_cfg` will create a nagios formatted block of the current :class:`Contact` object. :param path: Optional, allows to pass the dir where the file will be written. :type path: :class:`str` :rtype: :class:`str` :raises: :Exc:`djagios.core.exceptions.ParseError` """ s = StringIO.StringIO() s.write('define contact {\n') for attr in self._meta.get_all_field_names(): if not hasattr(self, attr) or attr == 'id': continue if attr in ('contactgroups', 'host_notification_commands',\ 'service_notification_commands',): if len(getattr(self,attr).values()) > 0: vals = list() for i in getattr(self,attr).iterator(): vals.append(str(i)) s.write('\t%s\t\t%s\n'%(attr, ",".join(vals))) continue value = getattr(self, attr) if not value: continue if isinstance(value, (str,int, unicode, bool, long,\ CheckCommand, Service, TimePeriod, Contact)): s.write('\t%s\t\t%s\n'%(attr,value)) s.write('}\n') s.flush() ret = s.getvalue() s.close() return ret def Meta(self): unique_together = (('name', 'contact_name',),) def __str__(self): return self.contact_name or self.name class ContactGroup(NagiosObject, models.Model): """Definition for the Nagios contactgroup object :class:`ContactGroup` has following :class:`django.db.models.ManyToManyField` attributes: - :attr:`members` - :attr:`contactgroup_members` """ FILE_NAME = 'contactgroup.cfg' contactgroup_name = models.CharField(max_length=255, unique=True) alias = models.CharField(max_length=255) members = models.ManyToManyField(Contact, related_name='CG_m_C',\ blank=True,null=True) contactgroup_members= models.ManyToManyField('self', symmetrical=False, related_name='CG_cgm_CG',\ blank=True,null=True) @classmethod def get(self,criterion): """classmethod that will allow you to fetch a :class:ContactGroup` object from the database. :param criterion: criterion you wish to supply, for :class:`ContactGroup` this is the :attr:`contactgroup_name` :type criterion: str :rtype: :class:`ContactGroup` or :class:`None` :raises: :exc:`DoesNotExist` """ o = None try: o = ContactGroup.objects.get(contactgroup_name=criterion) return o except ContactGroup.DoesNotExist: raise ContactGroup.DoesNotExist('Cannot find the contact group based on your criterion: %s'%criterion) def parse_to_nagios_cfg(self, path=None): """:func:`parse_to_nagios_cfg` will create a nagios formatted block of the current :class:`ContactGroup` object. :param path: Optional, allows to pass the dir where the file will be written. :type path: :class:`str` :rtype: :class:`str` :raises: :Exc:`djagios.core.exceptions.ParseError` """ s = StringIO.StringIO() s.write('define contactgroup {\n') for attr in self._meta.get_all_field_names(): if not hasattr(self, attr) or attr == 'id': continue if attr in ('contactgroup_members', 'members'): if len(getattr(self,attr).values()) > 0: vals = list() for i in getattr(self,attr).iterator(): vals.append(str(i)) s.write('\t%s\t\t%s\n'%(attr, ",".join(vals))) continue value = getattr(self, attr) if not value: continue if isinstance(value, (str,int, unicode, bool, long,\ CheckCommand, Service, TimePeriod)): s.write('\t%s\t\t%s\n'%(attr,value)) s.write('}\n') s.flush() ret = s.getvalue() s.close() return ret def __str__(self): return self.contactgroup_name class Command(NagiosObject, models.Model): """Definition for the Nagios command object""" FILE_NAME = 'command.cfg' command_name = models.CharField(max_length=255,unique=True) command_line = models.TextField() @classmethod def get(self,criterion): """classmethod that will allow you to fetch a :class:Command` object from the database. :param criterion: criterion you wish to supply, for :class:`Command` this is the :attr:`command_name` :type criterion: str :rtype: :class:`Command` or :class:`None` :raises: :exc:`DoesNotExist` As the command_name is usually given with the parameters attached to it, we split on ! and take the first entry of the resulting list. So there is no need to parse the check_command entry before passing to this function. """ o = None try: o = Command.objects.get(command_name=criterion.split('!')[0]) return o except Command.DoesNotExist: raise Command.DoesNotExist('Cannot find the command based on you criterion %s'%criterion) def parse_to_nagios_cfg(self, path=None): """:func:`parse_to_nagios_cfg` will create a nagios formatted block of the current :class:`Command` object. :param path: Optional, allows to pass the dir where the file will be written. :type path: :class:`str` :rtype: :class:`str` :raises: :Exc:`djagios.core.exceptions.ParseError` """ s = StringIO.StringIO() s.write('define command {\n') for attr in self._meta.get_all_field_names(): if not hasattr(self, attr) or attr == 'id': continue value = getattr(self, attr) if not value: continue if isinstance(value, (str,int, unicode, bool,)): s.write('\t%s\t\t%s\n'%(attr,value)) s.write('}\n') s.flush() ret = s.getvalue() s.close() return ret def __str__(self): return self.command_name class CheckCommand(models.Model): """:class:`CheckCommand` is the class that is used in :class:`Host`, :class:`Service`. This contains a foreign key to the :class:`Command` object and has an extra field with it's parameters. We keep them in the format like Nagios uses them, then we do not need another database tablerow for each possible parameter. """ command = models.ForeignKey('Command') paramline = models.CharField(max_length=255) class Meta: unique_together = ('command', 'paramline',) @classmethod def get(self, criterion): """A classmethod that will return a :class:`CheckCommand` object. If we do not find a corresponding object in the database, we will save one ourselved and return that one. :param criterion: Criterion for the object you want to fetch :type criterion: :class:`str` :rtype: :class:`CheckCommand` """ c_name = criterion.split('!')[0] c_attr = criterion.replace(c_name, '') try: o = CheckCommand.objects.get(command=Command.get(c_name), paramline=c_attr) return o except CheckCommand.DoesNotExist: o = CheckCommand(command=Command.get(c_name), paramline=c_attr) o.save() return o def __str__(self): return "%s%s"%(self.command, self.paramline) def __repr__(self): return self.__str__() class TimePeriod(NagiosObject, models.Model): """Definition for the Nagios TimePeriod object Ths TimePeriod object is a special object. Nagios allows to configure ranges. As the key of a range is chosen by the admin we cannot foresee columns with their names. Thus we parse the ranges into :class:`TimeRange` objects and link them to this object. There are also multiple excludes possible, each exclude is a reference to a :class:`TimePeriod`. :class:`TimePeriod` has following :class:`django.db.models.ManyToManyField` attributes: - :attr:`ranges` - :attr:`exclude` """ FILE_NAME = 'timeperiod.cfg' timeperiod_name = models.CharField(max_length=255, unique=True) alias = models.CharField(max_length=255) ranges = models.ManyToManyField('TimeRange', related_name='TP_r_TR') exclude = models.ManyToManyField('self', symmetrical=False, related_name='TP_e_TP',\ blank=True,null=True) def __str__(self): return self.timeperiod_name def parse_to_nagios_cfg(self, path=None): """:func:`parse_to_nagios_cfg` will create a nagios formatted block of the current :class:`TimePeriod` object. :param path: Optional, allows to pass the dir where the file will be written. :type path: :class:`str` :rtype: :class:`str` :raises: :Exc:`djagios.core.exceptions.ParseError` """ s = StringIO.StringIO() s.write('define timeperiod {\n') for attr in self._meta.get_all_field_names(): if not hasattr(self, attr) or attr == 'id': continue if attr in ('ranges', 'exclude',): if len(getattr(self,attr).values()) > 0: for i in getattr(self,attr).iterator(): s.write('\t%s\t\t%s\n'%(str(i),i.value )) continue value = getattr(self, attr) if not value: continue if isinstance(value, (str,int,unicode,bool)): s.write('\t%s\t\t%s\n'%(attr,value)) s.write('}\n') s.flush() ret = s.getvalue() s.close() return ret @classmethod def get(self, criterion): """classmethod that will allow you to fetch a :class:TimePeriod` object from the database. :param criterion: criterion you wish to supply, for :class:`TimePeriod` this is the :attr:`timeperiod_name` :type criterion: str :rtype: :class:`TimePeriod` or :class:`None` :raises: :exc:`DoesNotExist` """ o = None try: o = TimePeriod.objects.get(timeperiod_name=criterion) return o except TimePeriod.DoesNotExist: raise TimePeriod.DoesNotExist('Cannot find the TimePeriod based on your criterion %s'%criterion) class TimeRange(models.Model): """A helper class for the :class:`TimePeriod` object By creating a key-value pair object we can simply add the :class:`TimeRange` to the :class:`TimePeriod` for the [weekdays] and [exceptions] directives. Nagios allows those directives to have a unique key. This was the only way to solve it from a database viewpoint. """ key = models.CharField(max_length=255, unique=True) value = models.CharField(max_length=255) @classmethod def get(self,k, v=None): """:func:`get` will check the database if an object exists with the provided key and return it. It it does not exist, :func:`get` will create a :class:`TimeRange` and save it to the database. :param k: key for the :class:`TimeRange` :type k: str :param v: value for the :class:`TimeRange` :type v: str :return: :class:`TimeRange` """ try: o = TimeRange.objects.get(key=k) return o except TimeRange.DoesNotExist: o = TimeRange() o.key = k.strip() o.value = v.strip() o.save() return o def __str__(self): return self.key class ServiceDependency(NagiosObject, models.Model): """Definition for the Nagios servicedependency object. :class:`ServiceDependency` has following :class:`django.db.models.ManyToManyField` attributes: - :attr:`dependent_host_name` - :attr:`dependent_hostgroup_name` - :attr:`host_name` - :attr:`hostgroup_name` :class:`ServiceDependency` has following :class:`django.db.models.ForeignKey` attributes: - :attr:`dependent_service_description` - :attr:`service_description` - :attr:`dependency_period` """ dependent_host_name = models.ManyToManyField('Host', related_name='SD_dh_H',\ blank=True, null=True) dependent_hostgroup_name = models.ManyToManyField('HostGroup', related_name='SD_dhg_HG',\ blank=True, null=True) dependent_service_description = models.ForeignKey('Service', related_name='SD_ds_S') host_name = models.ManyToManyField('Host', related_name='SD_hn_H',\ blank=True, null=True) hostgroup_name = models.ManyToManyField('HostGroup', related_name='SD_hgn_HG',\ blank=True, null=True) service_description = models.ForeignKey('Service', related_name='SD_s_S',\ blank=True, null=True) inherits_parent = models.NullBooleanField(default=False) execution_failure_criteria = models.CharField(max_length=10) notification_failure_criteria = models.CharField(max_length=10) dependency_period = models.ForeignKey('TimePeriod', related_name='SD_dp_TP',\ blank=True, null=True) def parse_to_nagios_cfg(self, path=None): """:func:`parse_to_nagios_cfg` will create a nagios formatted block of the current :class:`ServiceDependency` object. :param path: Optional, allows to pass the dir where the file will be written. :type path: :class:`str` :rtype: :class:`str` :raises: :Exc:`djagios.core.exceptions.ParseError` """ s = StringIO.StringIO() s.write('define servicedependency {\n') for attr in self._meta.get_all_field_names(): if attr in ('dependent_host_name', 'depndent_host_group_name',\ 'dependent_service_description', 'host_name', 'hostgroup_name'): if len(getattr(self,attr).values()) > 0: vals = list() for i in getattr(self,attr).iterator(): vals.append(str(i)) s.write('\t%s\t\t%s\n'%(attr, ",".join(vals))) continue value = getattr(self, attr) if not value: continue if isinstance(value, (str,int, unicode, bool, long,\ CheckCommand, Service, TimePeriod)): s.write('\t%s\t\t%s\n'%(attr,value)) if len(hlist): s.write('\t%s\t\t%s\n'%('host_name', ",".join(hlist))) if len(hglist): s.write('\t%s\t\t%s\n'%('hostgroup_name', ",".join(hglist))) s.write('}\n') s.flush() ret = s.getvalue() s.close() return ret @classmethod def get(self,criterion): """classmethod that will allow you to fetch a :class:ServiceDependency` object from the database. :param criterion: criterion you wish to supply, for :class:`ServiceDependency` this is the service_description :type criterion: str :rtype: :class:`ServiceDependency` or None :raises: :exc:`DoesNotExist` """ o = None try: o = ServiceDependency.objects.get(service_description=criterion) return o except Service.DoesNotExist: raise Service.DoesNotExist('Cannot find the servicedependency on your criterion: %s'%criterion) class ServiceEscalation(NagiosObject, models.Model): """Definition of the serviceescalation object. :class:`ServiceEscalation` has following :class:`django.db.models.ManyToManyField` attributes: - :attr:`host_name` - :attr:`hostgroup_name` :class:`ServiceEscalation` has following :class:`django.db.models.ForeignKey` attributes: - :attr:`service_description` - :attr:`escalation_period` """ host_name = models.ManyToManyField('Host', related_name='SE_hn_H',\ blank=True, null=True) hostgroup_name = models.ManyToManyField('HostGroup', related_name='SE_hgn_HG',\ blank=True, null=True) service_description = models.ForeignKey('Service', related_name='SE_sd_S',\ blank=True, null=True) contacts = models.ForeignKey(Contact) contactgroups = models.ForeignKey(ContactGroup) first_notification = models.IntegerField() last_notification = models.IntegerField() notification_interval = models.IntegerField() escalation_period = models.ForeignKey('TimePeriod', related_name='SD_ep_TP',\ blank=True, null=True) escalation_options = models.CharField(max_length=10) class HostDependency(NagiosObject, models.Model): dependent_host = models.ForeignKey('Host', related_name='HD_dh_H') dependent_hostgroup = models.ForeignKey('HostGroup', related_name='HD_dhg_hg') dependent_service = models.ForeignKey('Service', related_name='HD_ds_S') host_name = models.ForeignKey(Host) hostgroup_name = models.ForeignKey(HostGroup) inherits_parent = models.NullBooleanField() execution_failure_criteria = models.CharField(max_length=10) notification_failure_criteria = models.CharField(max_length=10) dependency_periode = models.ForeignKey(TimePeriod) class HostEscalation(NagiosObject, models.Model): host_name = models.ForeignKey(Host, unique=True) hostgroup_name = models.ForeignKey(HostGroup) contacts = models.ForeignKey(Contact) contactgroups = models.ForeignKey(ContactGroup) first_notification = models.IntegerField() last_notification = models.IntegerField() notification_interval = models.IntegerField() escalation_period = models.ForeignKey(TimePeriod) escalation_options = models.CharField(max_length=10) class CfgPath(models.Model): path = models.CharField(max_length=255,unique=True) @classmethod def get(self, criterion): try: o = CfgPath.objects.get(path=criterion) return o except CfgPath.DoesNotExist: o = CfgPath() o.path=criterion o.save() return o def __unicode__(self): return self.path class NagiosCfg(NagiosObject, models.Model): '''Nagios main configuration file. We need the information of the file in the database, so we can fetch the default information ''' FILE_NAME = 'nagios.cfg' server_name = models.CharField(max_length=255, default='localhost', unique=True) log_file = models.ForeignKey(CfgPath, related_name='NC_lf_CP',\ default=lambda : CfgPath.get('/var/log/nagios/nagios.log').id) cfg_file = models.ManyToManyField(CfgPath, related_name='NC_cfg_file_CP',\ blank=True,null=True) cfg_dir = models.ManyToManyField(CfgPath, related_name='NC_cfg_dir_CP',\ blank=True,null=True) object_cache_file = models.ForeignKey(CfgPath, related_name='NC_ocf_CP',\ default=lambda : CfgPath.get('/var/nagios/objects.cache').id) precached_object_file = models.ForeignKey(CfgPath, related_name='NC_pof_CP',\ default=lambda : CfgPath.get('/var/nagios/objects.precache').id) resource_file = models.ForeignKey(CfgPath, related_name='NC_rf_CP',\ default=lambda : CfgPath.get('/etc/nagios/resource.cfg').id) temp_file = models.ForeignKey(CfgPath, related_name='NC_tf_CP',\ default=lambda : CfgPath.get('/var/nagios/nagios.tmp').id) temp_path = models.ForeignKey(CfgPath, related_name='NC_tp_CP',\ default=lambda : CfgPath.get('/tmp').id) status_file = models.ForeignKey(CfgPath, related_name='NC_sf_CP',\ default=lambda : CfgPath.get('/var/nagios/status.dat').id) status_update_interval = models.IntegerField(default=1) nagios_user = models.CharField(max_length=20, default='nagios') nagios_group = models.CharField(max_length=20, default='nagios') enable_notifications = models.NullBooleanField(blank=True,null=True) execute_service_checks = models.NullBooleanField(blank=True,null=True) accept_passive_service_checks = models.NullBooleanField(blank=True,null=True) execute_host_checks = models.NullBooleanField(blank=True,null=True) accept_passive_host_checks = models.NullBooleanField(blank=True,null=True) enable_event_handlers = models.NullBooleanField(blank=True,null=True) log_rotation_method = models.CharField(max_length=1, choices=LOG_ROTATION_METHODS, default='n') log_archive_path = models.ForeignKey(CfgPath, related_name='NC_laf_CP',\ default=lambda : CfgPath.get('/var/log/nagios/archives').id) check_external_commands = models.NullBooleanField(blank=True,null=True) command_check_interval = models.IntegerField(default=1) command_file = models.ForeignKey(CfgPath, related_name='NC_cf_CP',\ default=lambda : CfgPath.get('/var/nagios/rw/nagios.cmd').id) external_command_buffer_slots = models.IntegerField(default=512) check_for_updates = models.NullBooleanField(blank=True,null=True) bare_update_checks = models.NullBooleanField(default=False) lock_file = models.ForeignKey(CfgPath, related_name='NC_lckf_CP',\ default=lambda : CfgPath.get('/var/nagios/rw/nagios.cmd').id) retain_state_information = models.NullBooleanField(blank=True,null=True) state_retention_file = models.ForeignKey(CfgPath, related_name='NC_srf_CP',\ default=lambda : CfgPath.get('/var/nagios/retention.dat').id) retention_update_interval = models.IntegerField(default=60) use_retained_program_state = models.NullBooleanField(blank=True,null=True) use_retained_scheduling_info = models.NullBooleanField(blank=True,null=True) retained_host_attribute_mask = models.IntegerField(null=True) retained_service_attribute_mask = models.IntegerField(null=True) retained_process_host_attribute_mask = models.IntegerField(null=True) retained_process_service_attribute_mask = models.IntegerField(null=True) retained_contact_host_attribute_mask = models.IntegerField(null=True) retained_contact_service_attribute_mask = models.IntegerField(null=True) use_syslog = models.NullBooleanField(default=False) log_notifications = models.NullBooleanField(blank=True,null=True) log_service_retries = models.NullBooleanField(blank=True,null=True) log_host_retries = models.NullBooleanField(blank=True,null=True) log_event_handlers = models.NullBooleanField(blank=True,null=True) log_initial_states = models.NullBooleanField(default=False) log_external_commands = models.NullBooleanField(blank=True,null=True) log_passive_checks = models.NullBooleanField(blank=True,null=True) global_host_event_handler = models.CharField(max_length=255,blank=True,null=True) global_service_event_handler = models.CharField(max_length=255,blank=True,null=True) sleep_time = models.DecimalField(max_digits=4,decimal_places=2,default='0.25') # users can insert a choice or a proper value. This is why we keep it as a charfield service_inter_check_delay_method = models.CharField(max_length=6) max_service_check_spread = models.IntegerField(default=30) # service_interleave factor can be a number or s. keeping as char service_interleave_factor = models.CharField(max_length=2) max_concurrent_checks = models.IntegerField(default=0) check_result_reaper_frequency = models.IntegerField(default=10) max_check_result_reaper_time = models.IntegerField(default=60) check_result_path = models.ForeignKey(CfgPath, related_name='NC_crp_CP',\ default=lambda : CfgPath.get('/var/nagios/spool/checkresults').id) max_check_result_file_age = models.IntegerField(default=3600) # users can insert a choice or a proper value. This is why we keep it as a charfield host_inter_check_delay_method = models.CharField(max_length=6) max_host_check_spread = models.IntegerField(default=30) interval_length = models.IntegerField(default=60) auto_reschedule_checks = models.NullBooleanField() auto_rescheduling_interval = models.IntegerField(default=30) auto_rescheduling_window = models.IntegerField(default=180) use_aggressive_host_checking = models.NullBooleanField(default=False) translate_passive_host_checks = models.NullBooleanField(default=False) passive_host_checks_are_soft = models.NullBooleanField(default=False) enable_predictive_host_dependency_checks = models.NullBooleanField(blank=True,null=True) enable_predictive_service_dependency_checks = models.NullBooleanField(blank=True,null=True) cached_host_check_horizon = models.IntegerField(default=15) cached_service_check_horizon = models.IntegerField(default=15) use_large_installation_tweaks = models.NullBooleanField(default=False) free_child_process_memory = models.NullBooleanField(blank=True,null=True) child_processes_fork_twice = models.NullBooleanField(blank=True,null=True) enable_environment_macros = models.NullBooleanField(blank=True,null=True) enable_flap_detection = models.NullBooleanField(blank=True,null=True) low_service_flap_threshold = models.DecimalField(max_digits=4,decimal_places=1,default='25.0') high_service_flap_threshold = models.DecimalField(max_digits=4,decimal_places=1,default='50.0') low_host_flap_threshold = models.DecimalField(max_digits=4,decimal_places=1,default='25.0') high_host_flap_threshold = models.DecimalField(max_digits=4,decimal_places=1,default='50.0') soft_state_dependencies = models.NullBooleanField(default=False) service_check_timeout = models.IntegerField(default=60) host_check_timeout = models.IntegerField(default=60) event_handler_timeout = models.IntegerField(default=60) notification_timeout = models.IntegerField(default=60) ocsp_timeout = models.IntegerField(default=5) ochp_timeout = models.IntegerField(default=5) perfdata_timeout = models.IntegerField(default=5) obsess_over_services = models.NullBooleanField(default=False) ocsp_command = models.CharField(max_length=255, blank=True,null=True) obsess_over_hosts = models.NullBooleanField(default=False) ochp_command = models.CharField(max_length=255, blank=True,null=True) process_performance_data = models.NullBooleanField(default=False) host_perfdata_command = models.CharField(max_length=255, blank=True,null=True) service_perfdata_command = models.CharField(max_length=255, blank=True,null=True) host_perfdata_file = models.CharField(max_length=255, blank=True, null=True) service_perfdata_file = models.CharField(max_length=255, blank=True, null=True) host_perfdata_file_template = models.CharField(max_length=255, \ default="[HOSTPERFDATA]\t$TIMET$\t$HOSTNAME$\t$HOSTEXECUTIONTIME$\t$HOSTOUTPUT$\t$HOSTPERFDATA$",\ blank=True,null=True) service_perfdata_file_template = models.CharField(max_length=255, \ default="[SERVICEPERFDATA]\t$TIMET$\t$HOSTNAME$\t$SERVICEDESC$\t$SERVICEEXECUTIONTIME$\t$SERVICELATENCY$\t$SERVICEOUTPUT$\t$SERVICEPERFDATA$",\ blank=True,null=True) host_perfdata_file_mode = models.CharField(max_length=1, choices=OPEN_FILE_MODES,\ blank=True,null=True) service_perfdata_file_mode = models.CharField(max_length=1, choices=OPEN_FILE_MODES,\ blank=True,null=True) host_perfdata_file_processing_interval = models.IntegerField(default=60,\ blank=True,null=True) service_perfdata_file_processing_interval = models.IntegerField(default=60,\ blank=True,null=True) host_perfdata_file_processing_command = models.CharField(max_length=255, blank=True,null=True) service_perfdata_file_processing_command = models.CharField(max_length=255, blank=True,null=True) check_for_orphaned_services = models.NullBooleanField(blank=True,null=True) check_for_orphaned_hosts = models.NullBooleanField(blank=True,null=True) check_service_freshness = models.NullBooleanField(blank=True,null=True) service_freshness_check_interval = models.IntegerField(default=60,\ blank=True,null=True) check_host_freshness = models.NullBooleanField(blank=True,null=True) host_freshness_check_interval = models.IntegerField(default=60,\ blank=True,null=True) additional_freshness_latency = models.IntegerField(default=15) enable_embedded_perl = models.NullBooleanField(blank=True,null=True) use_embedded_perl_implicitly = models.NullBooleanField(blank=True,null=True) date_format = models.CharField(max_length=10) use_timezone = models.CharField(max_length=100, blank=True,null=True) illegal_object_name_chars = models.CharField(max_length=255,\ default="`~!$%^&*|'\"<>?,()=") illegal_macro_output_chars = models.CharField(max_length=255,\ default="~$^&\"|'<>") use_regexp_matching = models.NullBooleanField(blank=True,null=True) use_true_regexp_matching = models.NullBooleanField(default=False) admin_email = models.EmailField(default='djagios@localhost.local') admin_pager = models.CharField(max_length=75, default='djagios@pager.localhost.local') event_broker_options = models.IntegerField(default=-1) debug_file = models.CharField(max_length=255) # debug level should be a logical OR! debug_level = models.IntegerField(default=0) debug_verbosity = models.IntegerField(default=1, \ choices=(('0','basic'),('1','detailed'),('1','extreme'))) max_debug_file_size = models.IntegerField(default=1000000) p1_file = models.ForeignKey(CfgPath, related_name='NC_p1f_CP',\ default=lambda : CfgPath.get('/usr/bin/p1.pl').id) daemon_dumps_core = models.NullBooleanField(default=False) bare_update_check = models.NullBooleanField(default=False) def __unicode__(self): return self.server_name def parse_to_nagios_cfg(self, path=None): """:func:`parse_to_nagios_cfg` will create a nagios formatted block of the current :class:`NagiosCfg` object. :param path: Optional, allows to pass the dir where the file will be written. :type path: :class:`str` :rtype: :class:`str` :raises: :Exc:`djagios.core.exceptions.ParseError` """ s = StringIO.StringIO() s.write("# Nagios configuration for %s\n# Generated by Djagios.\n"%self.server_name) # log_file is always the first item!!!! s.write('log_file=%s\n'%self.log_file) s.write('cfg_dir=%s\n'%(os.path.join(path, 'objects'))) for attr in self._meta.get_all_field_names(): if not hasattr(self, attr) or attr == 'id': continue # attributes to ignore if attr in ('cfg_dir', 'cfg_file', 'server_name',\ 'log_file','bare_update_checks',): continue value = getattr(self, attr) if isinstance(value, str) and not value: continue if isinstance(value, (str,int, unicode, bool,\ CfgPath,)): s.write('%s=%s\n'%(attr,value)) s.flush() ret = s.getvalue() s.close() return ret #################################################### # Models for the website and the configuration help. #################################################### class HostTemplate(models.Model): """:class:`HostTemplate` is a helper class for Djagios website. This class will allow us to assign service, servicegroups, contact and contactgroups to the Host. These can be created by the admins, and only selected by the users. obsolete!!!!! """ name = models.CharField(max_length=255, unique=True) use = models.ForeignKey(Host, related_name='HT_use_H') services = models.ManyToManyField(Service, related_name='HT_s_S',\ blank=True,null=True) contacts = models.ManyToManyField(Contact, related_name='HT_c_C',\ blank=True,null=True) contact_groups = models.ManyToManyField(ContactGroup, related_name='HT_cg_CG',\ blank=True,null=True) def __str__(self): return self.name def __repr__(self): return self.__str__() class HostTemplateForm(forms.ModelForm): pass class Meta: model = HostTemplate class HostForm(forms.Form): name = forms.CharField(label='Server Name', max_length=50) address = forms.CharField(label='Servers Address (dns or IP)', max_length=50) template = forms.ModelChoiceField(label='Template', queryset=Host.objects.filter(register=False).order_by('name')) class HostToServiceForm(forms.Form): service = forms.ModelChoiceField(label='Service', queryset=Service.objects.exclude(register=False).order_by('service_description')) host = forms.ModelChoiceField(label='Host', queryset=Host.objects.exclude(register=False).order_by('host_name')) class HostFromServiceForm(forms.Form): host = forms.ModelChoiceField(label='Host', queryset=Host.objects.exclude(register=False).order_by('host_name')) service = forms.ModelChoiceField(Service.objects.exclude(register=False), widget=forms.Select(attrs={'disabled': 'True'}, choices=(('-1', 'Select Host'),))) class HostTemplateToServiceForm(forms.Form): service = forms.ModelChoiceField(label='Service', queryset=Service.objects.exclude(register=False).order_by('service_description')) host = forms.ModelChoiceField(label='Host', queryset=Host.objects.exclude(register=True).order_by('host_name')) class HostTemplateFromServiceForm(forms.Form): host = forms.ModelChoiceField(label='Host', queryset=Host.objects.exclude(register=False).order_by('host_name')) service = forms.ModelChoiceField(Service.objects.exclude(register=True), widget=forms.Select(attrs={'disabled': 'True'}, choices=(('-1', 'Select Host'),))) class HostDeleteForm(forms.Form): host = forms.ModelChoiceField(label='Host', queryset=Host.objects.exclude(register=False).order_by('host_name')) sure = forms.BooleanField(label='Check if you are sure', required=True) djagios-0.1.3+dfsg/djagios/release-notes.txt0000644000175000017500000000276011271274740017771 0ustar bigonbigon~~ Djagios 0.1.3 Release codename Katala ~~ Katala is probably last 0.1 release with following changes: Features: - (model) Beta import servicedependency - (model) Deserialization: preparation to allow the import of a json/python/yaml formatted configuration - (template) Added an overview of your hosts on the homepage of the default template - (template) Added /// to fetch json/yaml/python serialized object Bug fixes: - (model) Fixed the negative hosts to be exported correctly - (model) Service Export only export attributes that need to be exported (as opposed to all) - (model) Exporter removes the nagios.cfg before exporting - (model) Fix incorrect export of contactgroup and contact - (model) Removed all FKs to Command and CheckCommand from NagiosCfg - (model) Removed the symmetrical m2m's where needed - (website) Order services alphabetical - (website) Improved the installation docs ~~ Djagios 0.1.x Release codename milamber ~~ At this time Djagios is in development stage. The current release was made more to establish a release model as to have a functional release. However the 0.1.x code should be fully working with following functionalities: - working import/export for all objects except hostextinfo, servicedependency, serviceescalation, hostdependency, servicedependency - working webfunctions are: add host, add service to host, remove service from host, remove host. - admin section fully working djagios-0.1.3+dfsg/djagios/__init__.py0000644000175000017500000000000011263720041016543 0ustar bigonbigondjagios-0.1.3+dfsg/djagios/templates/0000755000175000017500000000000011271302730016442 5ustar bigonbigondjagios-0.1.3+dfsg/djagios/templates/default/0000755000175000017500000000000011271302730020066 5ustar bigonbigondjagios-0.1.3+dfsg/djagios/templates/default/hostadd.html0000644000175000017500000000033311263720041022401 0ustar bigonbigon{% extends "default/index.html" %} {% block content %}
{{ form }}
{% endblock content %} djagios-0.1.3+dfsg/djagios/templates/default/hosttemplateadd.html0000644000175000017500000000034311263720041024136 0ustar bigonbigon{% extends "default/index.html" %} {% block content %}
{{ form }}
{% endblock content %} djagios-0.1.3+dfsg/djagios/templates/default/home.html0000644000175000017500000000375611270003272021715 0ustar bigonbigon{% extends "default/index.html" %} {% block header %} {% endblock header %} {% block content %}

Welcome {{ user.username }}.
Here is the list of installed hosts and services:

Hosts:
{% for host in hosts.object_list %} {{ host }}
{% endfor %}
Services:
{% endblock content %} {% block pagination %} {% endblock %} djagios-0.1.3+dfsg/djagios/templates/default/index.html0000644000175000017500000000402011267554535022100 0ustar bigonbigon Djagios {% block header %} {% endblock header %}
{% block content %} {% endblock %}
{% block pagination %} {% endblock %}

djagios-0.1.3+dfsg/djagios/templates/default/hostservice.html0000644000175000017500000000233111263720041023311 0ustar bigonbigon{% extends "default/index.html" %} {% block header %} {% if remove %} {% endif %} {% endblock header %} {% block content %} {% if remove %}
{% else %} {% endif %} {{ form }}
{% if remove %} {% else %} {% endif %}
{% endblock content %} djagios-0.1.3+dfsg/djagios/templates/default/login.html0000644000175000017500000000115511263720041022066 0ustar bigonbigon{% extends "default/index.html" %} {% block content %} {% if form.errors %}

Your username and password didn't match. Please try again.

{% endif %}
{{ form.username.label_tag }} {{ form.username }}
{{ form.password.label_tag }} {{ form.password }}
{% if next %} {% else %} {% endif %}
{% endblock %} djagios-0.1.3+dfsg/djagios/templates/default/hostdelete.html0000644000175000017500000000034311263720041023114 0ustar bigonbigon{% extends "default/index.html" %} {% block content %}
{{ form }}
{% endblock content %} djagios-0.1.3+dfsg/djagios/common/0000755000175000017500000000000011271302730015734 5ustar bigonbigondjagios-0.1.3+dfsg/djagios/common/__init__.py0000644000175000017500000000000011263720041020033 0ustar bigonbigondjagios-0.1.3+dfsg/djagios/common/utils.py0000644000175000017500000000675211267035666017500 0ustar bigonbigon# Copyright (c) 2009 Jochen Maes # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. import os import sys import logging from djagios.core.models import * class Exporter(): """Exporter provides the functionality to export the different objects to the correct format used by Nagios. This tool will have to be adapted each time the configuration format of Nagios changes. """ def _write_file(self, content, path): """Internal function that will write out the string to a file. """ logging.debug("Exporter._write_file: opening %s"%path) if os.path.exists(path) and not os.path.isfile(path): logging.error("Exporter._write_file: %s is not a file"%path) return file = open(path, 'a') file.write(content) file.flush() file.close() logging.debug("Exporter._write_file: closed %s"%path) def export(self, path): """export will run over all objects and export them one by one to the specified path. Here they will be ordered per objecttype. The export is not recursive. :param path: containing the location where to put the cfg files, **must be a directory** :type path: :class:`str` """ if not os.path.isdir(path): raise ValueError('given path %s is not a directory!'%path) # creating the objects dir if not os.path.exists(os.path.join(path, 'objects')): os.mkdir(os.path.join(path, 'objects')) # removing previous nagios.cfg if os.path.exists(os.path.join(path, 'nagios.cfg')): os.remove(os.path.join(path, 'nagios.cfg')) OBJECT_LIST = (Host, HostGroup, Service, ServiceGroup, Command, TimePeriod,\ Contact, ContactGroup,) for o in OBJECT_LIST: for obj in o.objects.all(): self.export_object(obj, os.path.join(path, 'objects')) self.export_object(NagiosCfg.objects.all()[0], path) def export_object(self, nagios_obj, path): """:func:`export_object` will open a file (with the name of the object type) and write the content of the object to it. To do that It depends on the export function defined in the model class. :param nagios_obj: object that should be written as a nagios config object :type nagios_obj: :class:`djagios.core.models.NagiosObject` :param path: containing the location of the configfiles. :type path: :class:`str` """ if not isinstance(nagios_obj, NagiosObject): raise RuntimeError('object received is not a NagiosObject') if os.path.isfile(path): self._write_file(nagios_obj.parse_to_nagios_cfg(), path) elif os.path.isdir(path): p = os.path.join(path, nagios_obj.FILE_NAME) self._write_file(nagios_obj.parse_to_nagios_cfg(path), p) djagios-0.1.3+dfsg/djagios/media/0000755000175000017500000000000011271302730015523 5ustar bigonbigondjagios-0.1.3+dfsg/djagios/media/default/0000755000175000017500000000000011330261604017147 5ustar bigonbigondjagios-0.1.3+dfsg/djagios/media/default/logo.jpg0000644000175000017500000003310711271302603020614 0ustar bigonbigonJFIFHH khttp://ns.adobe.com/xap/1.0/ image/jpeg djagios-07 2009-07-03T23:51:43+02:00 2009-07-03T21:51:47Z 2009-07-03T23:51:43+02:00 Adobe Illustrator CS4 xmp.iid:D657888A5820681195FE9D18FACF4FCD uuid:5D20892493BFDB11914A8590D31508C8 proof:pdf xmp.iid:2812A7BA0A20681195FE9D18FACF4FCD xmp.did:2812A7BA0A20681195FE9D18FACF4FCD uuid:5D20892493BFDB11914A8590D31508C8 proof:pdf Print False False 1 99.998375 72.143056 Millimeters Cyan Magenta Yellow Black Adobe PDF library 9.00 CCi  7 !1AQ "aq#2% C !1AQ"2aq#B3b$Rcr%Cs4S ?Q+`/{|n +Z\U$Aͮ]71|9 )&}{9fշvPWG 22x{[QXԊD'v\9D X2*E#]O$֭pqp3">՞mӠ@Hkb?Ƣk|?tVrbiC򋲆|4d&?C/UU63U|"]`{KII#1;)l&O#@- p*bWW{.f4` +Fzg?Q\&:PH 3K*jۡHa@;O~߫ '+OOz/U??C"o+=rDx%f@Q8(q$scu||=H )? ZT㒇VQ23%B%&r.WaXa:I/R$PߤT ~}&{Ŷw6VvT'3ܨ"7ǡ2wdS&: ?|?*w 8^b9m;,tRE%U0xN"j&"a'k^7{oZ5ݴVsR桐&9+ 2Udžp;%ٕ6*IAA󥩗RJ9|OZG%!dvW[{cmv ^h>Hd]tS>O#6 [2)װ;2؞CSY[x@MR0Lҫ":,?(?RYڝ}ʕ( B%aQD⠏`LCU o@Fѻr]!lu%rqڜ9HrOЮzGs?/zd2rG$[jn8LQ1TQ%t*C+d*(GB< }\W)G6)[ [HLB_G+Sc$U_J2ddX({zcۗuݟo ӗ)(5g 7,q2|~@xG^J.a )Nt:48Dѭr-OA^DQg͔DDQ7NNpp./2zl4l?TB=C~(%4sxNp~lȭ2kg$HbA06*JnW}*ݵrvږ,/.؋T'SVsz .y[TCc#D p\wW0g ꬩuTPLs~"YI$9|~$O~>yҨS.*uH<vI0A0 e .{.Gu'ٟo[)xMv~3gCxUSQ;ۊVۿv0+Ï:`FzթGKa_.,CfrEfl)dtĞ&";jUom1(IOmے=rb'#GA;u\uJxaS`͓G`H__Ӹwn2iη6KDt;dmǵ*э( 3^&X?KU/zwUwbkKF?B|Fx1YeiYJѶr@>OYږɓ即H\4h*'b!Ȓɮ6]yDrG=vkuiGmmʙFXA$R@"[%uf "k(mMAH=WЏ1#sak+w:el%e.)e~JM^c[&p6*biiݚ9-+83\8%#$ԬhC0U6gUG{G&U}:O8r6Ke3UayY y2ҏG@DꟺELu Mw&_\ =zLG y"8Nb97ާpn\~<>$Z8˘QQ(Ԫ"S*nD뮩DH&QeNa"iL" B( s=Ik7Y4ܶ{Oɷ̂UV;!@$< P)JP=4,wvVP@>}k~s󭇳Zq&UMRk mϚHF?*wPxv8wa=nv&wD-tGiY9WcշW]3MQ>GuJv F2gʹ|sǰfPhɓDVP nD_BNqYeFvgؖbrKzOS1,Ė'$3_g?R)Gݥqx1F.LAH!9(Ŏ^Ѫ*n),`>d{Crcgp9$Gόԫ*[ a`~с ֬&Z9v2l2\,rPN*ߝչ[Mȍ) lr,>dTg)bHOq >&V'+C=#i_?'לq}N<==)3qE9~A4>JQ)uJպk^s$J8X =0(G׷~ϳfTBmN"2xs ך0vzs)@~)W=Znw ,}>+IbG 1$qI|ULEq絗hkkVi=<7.<SpH7WK\^GTdךuXR)GW>.޿.*ȸ4 )+n>PQ|CTo,9duXsSi?E7`nLL*bT]]A&%EGȧڧB:er_̚mRZه?oՇ{Z#D2eV{P~_EC՞)GSꜪt$scbidLbNG ;*bQ؀Sƃ ?p|*u_C\vJy ]ZV*@挫jdPXW-0I$rrtdX54Ԡ*rGgٮιSkwVv EI&DhIn 5V=O{E?l~qRWhz.ʽS@C8J{xX):m#Z`&0Gu [^I'F,̳O8K,HKJXI9'Ml\R)GVNI^l9Li4|+c3* Q'6b̲Ta^օw=a 3KE˱*[˨"|@Y65Ts 0dشfm{h;;8,m"-cETP>[ ,Qi>`VH_(w c42.y hݎȱG1yf[krl3TU"(7UgW]u:i#*{gy[rEo,=JP Vi"P鏹'fn囅ټnGmUR;w- s$w )UAtT(0` ͣ$ A#[abe`cȲdFZ^ZML#٦2"H (?Z[Ӥv!wv!UUA,U@$ ':rI'u$*U4_^3qF[3$ Rj9aQ(-_,MEU fM.Tvڜ=0\B y,hWfhKrkGY-"31<BoxuO\ 鰩m ̑5uZOal5 P2dv3w4NQ!8WesA˴r..+Xs G$31R+d謿"џ2ޢ/{wFwC?)P/89X$[ )AdbAT62C9,p%K~ǖ;5iwp]3Uy!Ð< JsP6:˺A?Ǧye)wߐc5^rV\rM֧j1BZ.} v=%  PޅN\4'T֯O(ci$oRbO:Ѥ?£W'Mq b^'Γ8C#1GIpUS9QL%s2heA VhT{}C 5}]Xr7.❦ g*y3 Q xK4Cu2 Nj:YPM1#U)"9R[dHfqe ^7>j0J,ͲK[^<0%sgujlTu$ n+oLא(*Q-JPe5!Lc$TS&{.vu6cT 42[HBݴD؋9nDɻ/UT9\?,y+J1+N5niq J1XI Rbwj^,XDìwliJؽabSfp#Fw=ݹtGqA:g6i}?OniG)Gpa|qN26)Z5L]2t+,Ve52AQ< l 1TD H l}kw$&V)<䋙l :(\ϼ:AbgӮ/a0W"NC$xSn񫒨f["+,S7TN[9ncnTS݌SpHdc_"<*Pz?Yl6Xi']!| ½sTt[)=?x1Io8)%nzJ7|ڲ V= 0ğ>Bh3l ٠FPEVQ#v͛7 $ݻt)A((JPtj!-cB UU JU" :_84jf<^{֘w3d'u!9,!)|D[7 hͤd7l|.Z{` ㉭B9*?T Xέ9d?O5S)@D ҥNCP0j$&1/.lRT4]4gǶ;`yardqFcZlиM=s- 4ok}OO6[s|i7s2V ˉd%xf48,r45oӞ$-=-lX:b&a 1q8doZ' 1 ŠEHzlWN9;;tvc6RɩI(i'S(U$0 iYQZvy]li\.|]x<2N ilTϹkc\35_tuS2VZi77^"$'[m\#\63SHP.LHVe9-dhX !uNsJd > SI6F 1>a,Fe6WɎ6<*N7xWpft \r.ֶ}ui)F+ :+dKO*GTѶ9*8y|)U_]2tu/uV2zJw6o.x<((R SZm5HCk2]`q2Md$i@9SxV&fcP8><G`u+Lʼn*eMTRJYQ̯Yyj=չeȚI+g% r]{ќ15Gy3cY Vm}WVOX#@Ÿ#M&yW>gnѭro^ppIJTa..;3N)gj&i&(.J7Զm6Բ, m.nN[yLIJoÖeΟkVpi g$lJ}7!RuozDQ{ЗVj"-rāmֶ̢h{ʌ3El*hxkvGgiÍI #12~RGڅxF8 ?`/C+&|qJ8p?oNO^֕U.EK3XC,,Ѳ Va`#a*]ft@hDTE0XN4gkR]"KݚYܟzxYZX36]931r+jZRdyO/=G\R5h.fǥyrF(|)n 4(YGٳuj.̑QpX.H\}Zvg5V@"YNvpȡR#xU3!F^voeWSBShV#Ƭf=:`:B(}]Λñi Fb)VmvT]*qlUΩ 9Iq;E6n:3HKǙ +-k.f.ero/E rǩO̅- V23׭j齡Cb6,[I9ș1Z&eWDq LɗHbuټu탴6!ڰh,"Edܺ؊3߱"Pk˳ڜpv8d:C!#%׺TR,&d"4-|g"e <|C*:tv\qEHh6n친i=ē^^\om9{# 1#=⢬[k93r|? )mE[9w?e.+.^ri h f/9 ch*aviF;d:ej[e]rmcc,Vćfl5nJJV)6쥎[L:8b8nbmtav:KZF$U$TG=OSn 7[[F=$1nEY8Yi,+=^ݡ'^CgmkLma7S8VpȫekX)+e AAP0O&z iҽjt"j6IW9mytB5v[U\^B9tg"H*%#!nζյx9c|(@2RY^/f 9i6i%9r"sN.kҭڵIW&MO7`o]Aob)''ƮtAȤݺI DIH"HM$PһR)G-=7v^֣2*SzĥI]kk)t͒q)(COٸUӺPu^7SbzIkA}B䍞SqE663t2yrG \[,'JY۸"߅S$HMezvfYrH+<v*Uڇ*IqW;ov6ܱ%x$RQE æB 8d!TտR-5kcix 98 @#|A*LnrX˷qlBל˕DF^Je IO$[t a_+}9T @(9FXmVl۽ ;#Ӣ*dCkOꞞlҸ~{۽W/OUV]ٍ_ӱ)I dT'o1z޷&U${F|=\Emt;aM1[TG -UxG>/uWQqxl CA^uǙ$, ?D k+]iu)֪az.|ozMX^n4[NGV5K ] $_ eh݃ldWG-ܬ$OrNm b4=">21iZo44Z' rFJy)=XVKN|[!!K5 f</ ) V2*R|uh+0Պj 9vb^4}>Kӭ-ⴳɄ$Qv쬏"wj9d'7+77oPĐ,q (I0 O(UbGYC5`B:ᄱu_޳z#T?D2Pvp4An#\SOC$Bd28HY+я,КzdpOR3NIVn;6$͍7{6x鶿£XT(lج{3g&ܿEĜؔYZku:g$l$&MI{0nS$S9vĠ*݃WR(qJ8R)GWR$%]DE"EVTM4!DQE B)P_3"9vW]r 26JUur@- S҉**֨8^9'ަd{U)¬kX| QoVΟ\4,L#>gCh/UQՆb±検 U*aoN)H6g#} y6aNίa]_wXTl.2jۨ#T}lFF q:l",΢VԫSBBCkppB5IdLLce"DH! )\&"RsQ𰐱efe7n99"ф{UTIcPW+ҸŗSzҳv^&APdޣ:'j>2BE",thV6AJΨ&+]t:Ņ .2C)- "Y4^l̼*IW0)NQ(qJ8R)GQ(^+B+eo#-9cK;=)U}'TОYf_+~ooZF Eh7RCx6R}1i>d6##;S#ߚScK_tzQ ,qaC@4|U}m)R(qJ8R)GQ(qJ8R)GV>M+#S}qv{]Yt$#ӝЂt-;u?WV~z37]SlmYkO6Le&([H. u{f$:'Cn4h1HYk[MΔOY*!'ܱnh#a5VZ+^Go՞gpnl{ r" "VCdlis=?T~^ UcCfn]tޝE.#H="#~A-UW=|/.YIU 8AK!ޜ=@vu*@E(X9tVF,L%;e+卯sK5y3$kWty8}/Poí{ s`|O=@Z#q-AWX. ~@~>Otpv E&/d#XꋥC$:8 u:bc[(h[Qؠ# kGY(!4aUmu3 bky[G$t8EO1Y!H xύ&vur۩9 gإV1}IkDZ!s\<BO MzkH#|.wRE4[Ír̎GQN`9{Pl,-u6RYYmg#-#ӆ@ω2[cOɜsǽO`{:ADvusd͘n QԌ%;e-ZY5 ߦ>Ipށq\e]ɗ>A]Ǫ_9ځu]zpk'<%6 y]%LTP6 jVj0 t\}BG-r]c]6OhT"X־Wv[KgG=S\夷dZ{me0%IBL eR48;_st[R@;Nz'be`ytꚷGO'Mhv+s;p}-(kDT!e!tk"n GxJ(,ֺz Cױҟo}+@$8N&n7[mBj9~5ʂӯV]vV\bMc;?~Gú sxuf7~Ov.An~F|e'Į֊n}Ǫr>^fIE]p!nc,lR#>A^ҹ5eʼw"ֺƵGk4/1146lzIl?N t=';Aa%u)oe& Efu|xumҥ솓N:Wx~ s>e{M{xP5׋n?T۩=$Q0Og7Ga7oynnނwi댴56o`xh߀e߳pO友46'CDoӗ1kΈ84\|J vh MިƛZ i>}6 _..*YȘ}=\%W0 =7{K\59qDC9?N].ώᶚ oC#iKIogvwU:3^Lp,0cL>3dwHi#w/`9uKo-;g{qW_PMP~~CAאtp*xAs$`sN#PsН%M VT\n50ǝG!#;7Q?U\xOg&Er=MM;Kds^񦻘8Kev|A=d0B4"[}itcj᝱H#\=7G+ݛEr Lo1eT`t̨>}he%.!g9_p.7>ָ`g)C#}\vkZv<e=_ylltmevPϑ)H֜kv5H:?wh98Cߖ~\6Mޞ}޷q,g/yd`wgH?<ȭ=\=fsY]tV:'UJ {Fr۸0"Prq2>$h6G{/ l{XHIhesf䆳ՀU[=,[`Xݓǰ>~Վ/]{ :V5u/,ˏq ̷&ǣTWkb4:z k@缵ᱺRQxy4qܳ#u l/S j6;$20cnd٥fįTkrLhqbv H:sKیbcK4S;s aV[_#ϒ@7ꛓrI2w`6˥}>C)^؜lW7|fݬ<:UB﹤kt4Dwm.h={qk]0|fizB>OrNv{K .ۍxE;ղANXim9T4I.{tD@DDD@DDD@DDD@DDD@DDD@DDD@QQlCtܾzIxC*$KOHRAñ!aōZ魖t7?.q$ "dϙH{Gglgdjagios-0.1.3+dfsg/djagios/media/default/main.css0000644000175000017500000000203411271302630020603 0ustar bigonbigonbody { font-family: sans-serif, Arial, Helvetica; background-color: #92CC47; color: #000000; margin: 0; } div.head { height: 105px; background-color: #ffffff; margin: 20px; } div.body { width: 100% float: left; } .clear { clear: both; } div.menu { width: 20%; margin-left: 20px; float: left; } div.content { width: 75%; margin-left: 10px; background-color: #ffffff; float: right; margin-right: 20px; } div.actualcontent { margin: 10px; float: left; } div.footer { color: #ffffff; width:: 100%; font-size: 75%; text-align: center; } div#pagination{ float: left; margin-left: 10px; width: 100%; } ul { margin: 0pt; padding: 0pt; } li { list-style-type: none; font-weight: bold; } a:hover { color: #000000; text-decoration: underline; } a:visited { color: #000000; text-decoration: underline; } a { color: #000000; text-decoration: underline; } h4 { color: #ffffff; } .errorlist { color: #b90000; } djagios-0.1.3+dfsg/djagios/config.py0000644000175000017500000000006011263720041016257 0ustar bigonbigon# Djagios Configuration theme_name = 'default'