def test_regenerator_load_from_scheduler(self): # # Config is not correct because of a wrong relative path # in the main config file # # for h in self.sched.hosts: # h.realm = h.realm.get_name() self.rg = Regenerator() self.rg.load_from_scheduler(self.sched) self.sched.conf.skip_initial_broks = False self.sched.brokers['Default-Broker'] = { 'broks': [], 'has_full_broks': False } self.sched.fill_initial_broks('Default-Broker') # Got the initial creation ones t0 = time.time() for b in self.sched.broks: print "Manage b", b.type b.prepare() self.rg.manage_brok(b) t1 = time.time() print 'First inc', t1 - t0, len(self.sched.broks) del self.sched.broks[:] self.look_for_same_values()
def test_regenerator_load_from_scheduler(self): # # Config is not correct because of a wrong relative path # in the main config file # # for h in self.sched.hosts: # h.realm = h.realm.get_name() self.rg = Regenerator() self.rg.load_from_scheduler(self.sched) self.sched.conf.skip_initial_broks = False self.sched.fill_initial_broks() # Got the initial creation ones ids = self.sched.broks.keys() ids.sort() t0 = time.time() for i in ids: b = self.sched.broks[i] print "Manage b", b.type b.prepare() self.rg.manage_brok(b) t1 = time.time() print 'First inc', t1 - t0, len(self.sched.broks) self.sched.broks.clear() self.look_for_same_values()
def test_regenerator_load_from_scheduler(self): # # Config is not correct because of a wrong relative path # in the main config file # # for h in self.sched.hosts: # h.realm = h.realm.get_name() self.rg = Regenerator() self.rg.load_from_scheduler(self.sched) self.sched.conf.skip_initial_broks = False self.sched.brokers['Default-Broker'] = {'broks' : [], 'has_full_broks' : False} self.sched.fill_initial_broks('Default-Broker') # Got the initial creation ones t0 = time.time() for b in self.sched.broks: print "Manage b", b.type b.prepare() self.rg.manage_brok(b) t1 = time.time() print 'First inc', t1 - t0, len(self.sched.broks) del self.sched.broks[:] self.look_for_same_values()
def test_reversed_list(self): """ Test to ensure new conf is properly merge with different servicegroup definition The first conf has all its servicegroup defined servicegroups.cfg and services.cfg The second conf has both, so that servicegroups defined ins services.cfg are genretaed by Shinken This lead to another generated id witch should be handled properly when regenerating reversed list / merging servicegroups definition """ sg = self.sched.servicegroups.find_by_name('servicegroup_01') prev_id = sg.id reg = Regenerator() data = {"instance_id": 0} b = Brok('program_status', data) b.prepare() reg.manage_program_status_brok(b) reg.all_done_linking(0) self.setup_with_file("etc/shinken_reversed_list.cfg") reg.all_done_linking(0) #for service in self.sched.servicegroups: # assert(service.servicegroup_name in self.sched.servicegroups.reversed_list.keys()) # assert(service.id == self.sched.servicegroups.reversed_list[service.servicegroup_name]) sg = self.sched.servicegroups.find_by_name('servicegroup_01') assert(prev_id != sg.id) for sname in [u'servicegroup_01', u'ok', u'flap', u'unknown', u'random', u'servicegroup_02', u'servicegroup_03', u'warning', u'critical', u'servicegroup_04', u'servicegroup_05', u'pending', u'mynewgroup']: sg = self.sched.servicegroups.find_by_name(sname) assert(sname is not None)
def __init__(self, modconf): BaseModule.__init__(self, modconf) logger.debug('[hokuto-log-cacher] Initializing') self.regen = Regenerator() # TODO: Keep this ? seems useless self.db_path = getattr(modconf, 'db_path', None) if self.db_path is None: logger.error( '[hokuto-log-cacher] No database path configured. Please specify one with db_path in the module configuration file.' ) raise
def test_regenerator(self): # # Config is not correct because of a wrong relative path # in the main config file # self.sched.fill_initial_broks() self.rg = Regenerator() # Got the initial creation ones ids = self.sched.broks.keys() ids.sort() for i in ids: b = self.sched.broks[i] print "Manage b", b.type self.rg.manage_brok(b) self.sched.broks.clear() self.look_for_same_values() print "Get the hosts and services" now = time.time() host = self.sched.hosts.find_by_name("test_host_0") host.checks_in_progress = [] host.act_depend_of = [] # ignore the router router = self.sched.hosts.find_by_name("test_router_0") router.checks_in_progress = [] router.act_depend_of = [] # ignore the router svc = self.sched.services.find_srv_by_name_and_hostname("test_host_0", "test_ok_0") svc.checks_in_progress = [] svc.act_depend_of = [] # no hostchecks on critical checkresults self.scheduler_loop(3, [[host, 2, 'DOWN | value1=1 value2=2'], [router, 0, 'UP | rtt=10'], [svc, 2, 'BAD | value1=0 value2=0']]) self.assert_(host.state == 'DOWN') self.assert_(host.state_type == 'HARD') ids = self.sched.broks.keys() ids.sort() for i in ids: b = self.sched.broks[i] print "Manage b", b.type self.rg.manage_brok(b) self.sched.broks.clear() self.look_for_same_values()
def __init__(self, modconf): BaseModule.__init__(self, modconf) logger.debug('[hokuto] Initializing') self.port = int(getattr(modconf, 'port', '7768')) self.host = getattr(modconf, 'host', '0.0.0.0') self.dbpath = getattr(modconf, 'dbpath', '/var/lib/shinken/hokuto.db') self.secret_key = getattr(modconf, 'secretkey', 'Enter the secretest key here!') self.logging = getattr(modconf, 'logging', '/var/log/shinken/hokuto.log') self.threaded = getattr(modconf, 'threaded', '1') == '1' self.nanto_database = getattr(modconf, 'nanto_database', None) self.livestatus_socket = getattr(modconf, 'livestatus_socket', None) self.livestatus_host = None self.livestatus_port = None if self.livestatus_socket is None: self.livestatus_host = getattr(modconf, 'livestatus_host', '127.0.0.1') self.livestatus_port = getattr(modconf, 'livestatus_port', 50000) self.regen = Regenerator() # TODO: Keep this ? seems useless
def test_reversed_list(self): """ Test to ensure new conf is properly merge with different servicegroup definition The first conf has all its servicegroup defined servicegroups.cfg and services.cfg The second conf has both, so that servicegroups defined ins services.cfg are genretaed by Shinken This lead to another generated id witch should be handled properly when regenerating reversed list / merging servicegroups definition """ sg = self.sched.servicegroups.find_by_name('servicegroup_01') prev_id = sg.id reg = Regenerator() data = {"instance_id": 0} b = Brok('program_status', data) b.prepare() reg.manage_program_status_brok(b) reg.all_done_linking(0) self.setup_with_file("etc/shinken_reversed_list.cfg") reg.all_done_linking(0) #for service in self.sched.servicegroups: # assert(service.servicegroup_name in self.sched.servicegroups.reversed_list.keys()) # assert(service.id == self.sched.servicegroups.reversed_list[service.servicegroup_name]) sg = self.sched.servicegroups.find_by_name('servicegroup_01') assert (prev_id != sg.id) for sname in [ u'servicegroup_01', u'ok', u'flap', u'unknown', u'random', u'servicegroup_02', u'servicegroup_03', u'warning', u'critical', u'servicegroup_04', u'servicegroup_05', u'pending', u'mynewgroup' ]: sg = self.sched.servicegroups.find_by_name(sname) assert (sname is not None)
def test_regenerator(self): # # Config is not correct because of a wrong relative path # in the main config file # # for h in self.sched.hosts: # h.realm = h.realm.get_name() self.sched.conf.skip_initial_broks = False self.sched.brokers['Default-Broker'] = { 'broks': [], 'has_full_broks': False } self.sched.fill_initial_broks('Default-Broker') self.rg = Regenerator() # Got the initial creation ones t0 = time.time() for b in self.sched.broks: print "Manage b", b.type b.prepare() self.rg.manage_brok(b) t1 = time.time() print 'First inc', t1 - t0, len(self.sched.broks) del self.sched.broks[:] self.look_for_same_values() print "Get the hosts and services" host = self.sched.hosts.find_by_name("test_host_0") host.checks_in_progress = [] host.act_depend_of = [] # ignore the router router = self.sched.hosts.find_by_name("test_router_0") router.checks_in_progress = [] router.act_depend_of = [] # ignore the router svc = self.sched.services.find_srv_by_name_and_hostname( "test_host_0", "test_ok_0") svc.checks_in_progress = [] svc.act_depend_of = [] # no hostchecks on critical checkresults self.scheduler_loop( 3, [[host, 2, 'DOWN | value1=1 value2=2'], [router, 0, 'UP | rtt=10'], [svc, 2, 'BAD | value1=0 value2=0']]) self.assertEqual('DOWN', host.state) self.assertEqual('HARD', host.state_type) t0 = time.time() for b in self.sched.broks: print "Manage b", b.type b.prepare() self.rg.manage_brok(b) t1 = time.time() print 'Time', t1 - t0 del self.sched.broks[:] self.look_for_same_values() print 'Time', t1 - t0 b = svc.get_initial_status_brok() b.prepare() print "GO BENCH!" t0 = time.time() for i in xrange(1, 1000): b = svc.get_initial_status_brok() b.prepare() s = Service({}) for (prop, value) in b.data.iteritems(): setattr(s, prop, value) t1 = time.time() print "Bench end:", t1 - t0 times = {} sizes = {} import cPickle data = {} cls = svc.__class__ start = time.time() for i in xrange(1, 10000): for prop, entry in svc.__class__.properties.items(): # Is this property intended for brokking? if 'full_status' in entry.fill_brok: data[prop] = svc.get_property_value_for_brok( prop, cls.properties) if not prop in times: times[prop] = 0 sizes[prop] = 0 t0 = time.time() tmp = cPickle.dumps(data[prop], 0) sizes[prop] += len(tmp) times[prop] += time.time() - t0 print "Times" for (k, v) in times.iteritems(): print "\t%s: %s" % (k, v) print "\n\n" print "Sizes" for (k, v) in sizes.iteritems(): print "\t%s: %s" % (k, v) print "\n" print "total time", time.time() - start
class Webui_broker(BaseModule, Daemon): def __init__(self, modconf): BaseModule.__init__(self, modconf) self.plugins = [] self.modconf = modconf # Web server configuration self.host = getattr(modconf, 'host', '0.0.0.0') self.port = int(getattr(modconf, 'port', '7767')) logger.info("[WebUI] server: %s:%d", self.host, self.port) self.endpoint = getattr(modconf, 'endpoint', None) if self.endpoint: if self.endpoint.endswith('/'): self.endpoint = self.endpoint[:-1] logger.info("[WebUI] configured endpoint: %s", self.endpoint) logger.warning("[WebUI] endpoint feature is not implemented! WebUI is served from root URL: http://%s:%d/", self.host, self.port) self.endpoint = None self.auth_secret = resolve_auth_secret(modconf) # TODO : common preferences self.play_sound = to_bool(getattr(modconf, 'play_sound', '0')) # TODO : common preferences self.login_text = getattr(modconf, 'login_text', None) # TODO : common preferences self.company_logo = getattr(modconf, 'company_logo', 'default_company') if self.company_logo == '': # Set a dummy value if webui.cfg value is empty to force using the default logo ... self.company_logo = 'abcdef' # TODO : common preferences self.gravatar = to_bool(getattr(modconf, 'gravatar', '0')) # TODO : common preferences self.allow_html_output = to_bool(getattr(modconf, 'allow_html_output', '0')) # TODO : common preferences #self.max_output_length = int(getattr(modconf, 'max_output_length', '100')) # TODO : common preferences self.refresh_period = int(getattr(modconf, 'refresh_period', '60')) # Use element tag as image or use text self.tag_as_image = to_bool(getattr(modconf, 'tag_as_image', '0')) # Manage user's ACL self.manage_acl = to_bool(getattr(modconf, 'manage_acl', '1')) self.allow_anonymous = to_bool(getattr(modconf, 'allow_anonymous', '0')) # Advanced options self.http_backend = getattr(modconf, 'http_backend', 'auto') self.remote_user_enable = getattr(modconf, 'remote_user_enable', '0') self.remote_user_variable = getattr(modconf, 'remote_user_variable', 'X_REMOTE_USER') self.serveropts = {} umask = getattr(modconf, 'umask', None) if umask is not None: self.serveropts['umask'] = int(umask) bindAddress = getattr(modconf, 'bindAddress', None) if bindAddress: self.serveropts['bindAddress'] = str(bindAddress) # Apache htpasswd file for authentication self.htpasswd_file = getattr(modconf, 'htpasswd_file', None) if self.htpasswd_file: if not os.path.exists(self.htpasswd_file): logger.warning("[WebUI] htpasswd file '%s' does not exist.", self.htpasswd_file) self.htpasswd_file = None # Load the config dir and make it an absolute path self.config_dir = getattr(modconf, 'config_dir', 'share') self.config_dir = os.path.abspath(self.config_dir) logger.info("[WebUI] Config dir: %s", self.config_dir) # Load the share dir and make it an absolute path self.share_dir = getattr(modconf, 'share_dir', 'share') self.share_dir = os.path.abspath(self.share_dir) logger.info("[WebUI] Share dir: %s", self.share_dir) # Load the photo dir and make it an absolute path self.photo_dir = getattr(modconf, 'photos_dir', 'photos') self.photo_dir = os.path.abspath(self.photo_dir) logger.info("[WebUI] Photo dir: %s", self.photo_dir) self.user_picture = '' # @mohierf: still useful ? No value in webui.cfg, so always False ... # self.embeded_graph = to_bool(getattr(modconf, 'embeded_graph', '0')) # Look for an additional pages dir self.additional_plugins_dir = getattr(modconf, 'additional_plugins_dir', '') if self.additional_plugins_dir: self.additional_plugins_dir = os.path.abspath(self.additional_plugins_dir) logger.info("[WebUI] Additional plugins dir: %s", self.additional_plugins_dir) # Web UI timezone self.timezone = getattr(modconf, 'timezone', 'Europe/Paris') if self.timezone: logger.info("[WebUI] Setting our timezone to %s", self.timezone) os.environ['TZ'] = self.timezone time.tzset() logger.info("[WebUI] parameter timezone: %s", self.timezone) # Visual alerting thresholds # Used in the dashboard view to select background color for percentages self.hosts_states_warning = int(getattr(modconf, 'hosts_states_warning', '95')) self.hosts_states_critical = int(getattr(modconf, 'hosts_states_critical', '90')) self.services_states_warning = int(getattr(modconf, 'services_states_warning', '95')) self.services_states_critical = int(getattr(modconf, 'services_states_critical', '90')) # Web UI information self.app_version = getattr(modconf, 'about_version', WEBUI_VERSION) self.app_copyright = getattr(modconf, 'about_copyright', WEBUI_COPYRIGHT) self.app_release = getattr(modconf, 'about_release', WEBUI_RELEASENOTES) # We will save all widgets self.widgets = {} # We need our regenerator now (before main) so if we are in a scheduler, # rg will be able to skip some broks self.rg = Regenerator() # My bottle object ... self.bottle = bottle bottle.BaseTemplate.defaults['app'] = self # Called by Broker so we can do init stuff def init(self): logger.info("[WebUI] Initializing ...") self.rg.load_external_queue(self.from_q) # This is called only when we are in a scheduler # and just before we are started. So we can gain time, and # just load all scheduler objects without fear :) (we # will be in another process, so we will be able to hack objects # if need) def hook_pre_scheduler_mod_start(self, sched): print "pre_scheduler_mod_start::", sched.__dict__ self.rg.load_from_scheduler(sched) # In a scheduler we will have a filter of what we really want as a brok def want_brok(self, b): return self.rg.want_brok(b) def main(self): self.set_proctitle(self.name) # Daemon like init self.debug_output = [] self.modules_dir = modulesctx.get_modulesdir() self.modules_manager = ModulesManager('webui', self.find_modules_path(), []) self.modules_manager.set_modules(self.modules) # We can now output some previously silenced debug output self.do_load_modules() for inst in self.modules_manager.instances: f = getattr(inst, 'load', None) if f and callable(f): f(self) for s in self.debug_output: print s del self.debug_output # Check if the Bottle view dir really exist if not os.path.exists(bottle.TEMPLATE_PATH[0]): logger.error("[WebUI] The view path do not exist at %s" % bottle.TEMPLATE_PATH) sys.exit(2) # Check directories # We check if the photo directory exists. If not, try to create it for d in [self.photo_dir, self.share_dir, self.config_dir]: logger.debug("[WebUI] Checking dir: %s", d) if not os.path.exists(d): try: os.mkdir(d) logger.info("[WebUI] Created dir: %s", d) except Exception, exp: logger.error("[WebUI] Dir creation failed: %s", exp) # :TODO:maethor:150724: Complete with other function names self.auth_module = AuthMetaModule(AuthMetaModule.find_modules(self.modules_manager.get_internal_instances()), self) self.prefs_module = PrefsMetaModule(PrefsMetaModule.find_modules(self.modules_manager.get_internal_instances()), self) self.logs_module = LogsMetaModule(LogsMetaModule.find_modules(self.modules_manager.get_internal_instances()), self) self.graphs_module = GraphsMetaModule(GraphsMetaModule.find_modules(self.modules_manager.get_internal_instances()), self) self.helpdesk_module = HelpdeskMetaModule(HelpdeskMetaModule.find_modules(self.modules_manager.get_internal_instances()), self) # Data manager self.datamgr = WebUIDataManager(self.rg) self.helper = helper self.request = bottle.request self.response = bottle.response # :TODO:maethor:150717: Doesn't work #username = self.request.get_cookie("user", secret=self.auth_secret) #if username: #self.user = User.from_contact(self.datamgr.get_contact(username), self.gravatar) #else: #self.user = None try: self.do_main() except Exception, exp: msg = Message(id=0, type='ICrash', data={'name': self.get_name(), 'exception': exp, 'trace': traceback.format_exc()}) self.from_q.put(msg) # wait 2 sec so we know that the broker got our message, and die time.sleep(2) raise
class TestRegenerator(ShinkenTest): #Uncomment this is you want to use a specific configuration #for your test def setUp(self): self.setup_with_file('etc/nagios_regenerator.cfg') def look_for_same_values(self): # Look at Regenerator values print "Hosts:", self.rg.hosts.__dict__ for h in self.rg.hosts: orig_h = self.sched.hosts.find_by_name(h.host_name) print h.state, orig_h.state # Look for same states self.assert_(h.state == orig_h.state) self.assert_(h.state_type == orig_h.state_type) # Look for same impacts for i in h.impacts: print "Got impact", i.get_name() same_impacts = i.get_name() in [j.get_name() for j in orig_h.impacts] self.assert_(same_impacts) # And look for same source problems for i in h.source_problems: print "Got source pb", i.get_name() same_pbs = i.get_name() in [j.get_name() for j in orig_h.source_problems] self.assert_(same_pbs) print "Services:", self.rg.services.__dict__ for s in self.rg.services: orig_s = self.sched.services.find_srv_by_name_and_hostname(s.host.host_name, s.service_description) print s.state, orig_s.state self.assert_(s.state == orig_s.state) self.assert_(s.state_type == orig_s.state_type) #Look for same impacts too for i in s.impacts: print "Got impact", i.get_name() same_impacts = i.get_name() in [j.get_name() for j in orig_s.impacts] self.assert_(same_impacts) # And look for same source problems for i in s.source_problems: print "Got source pb", i.get_name() same_pbs = i.get_name() in [j.get_name() for j in orig_s.source_problems] self.assert_(same_pbs) # Look for same host self.assert_(s.host.get_name() == orig_s.host.get_name()) #Change ME :) def test_regenerator(self): # # Config is not correct because of a wrong relative path # in the main config file # self.sched.fill_initial_broks() self.rg = Regenerator() # Got the initial creation ones ids = self.sched.broks.keys() ids.sort() for i in ids: b = self.sched.broks[i] print "Manage b", b.type self.rg.manage_brok(b) self.sched.broks.clear() self.look_for_same_values() print "Get the hosts and services" now = time.time() host = self.sched.hosts.find_by_name("test_host_0") host.checks_in_progress = [] host.act_depend_of = [] # ignore the router router = self.sched.hosts.find_by_name("test_router_0") router.checks_in_progress = [] router.act_depend_of = [] # ignore the router svc = self.sched.services.find_srv_by_name_and_hostname("test_host_0", "test_ok_0") svc.checks_in_progress = [] svc.act_depend_of = [] # no hostchecks on critical checkresults self.scheduler_loop(3, [[host, 2, 'DOWN | value1=1 value2=2'], [router, 0, 'UP | rtt=10'], [svc, 2, 'BAD | value1=0 value2=0']]) self.assert_(host.state == 'DOWN') self.assert_(host.state_type == 'HARD') ids = self.sched.broks.keys() ids.sort() for i in ids: b = self.sched.broks[i] print "Manage b", b.type self.rg.manage_brok(b) self.sched.broks.clear() self.look_for_same_values()
class TestRegenerator(ShinkenTest): def setUp(self): self.setup_with_file('etc/shinken_regenerator.cfg') def look_for_same_values(self): # Look at Regenerator values print "Hosts:", self.rg.hosts.__dict__ for h in self.rg.hosts: orig_h = self.sched.hosts.find_by_name(h.host_name) print h.state, orig_h.state # Look for same states self.assertEqual(orig_h.state, h.state) self.assertEqual(orig_h.state_type, h.state_type) # Look for same impacts for i in h.impacts: print "Got impact", i.get_name() same_impacts = i.get_name() in [ j.get_name() for j in orig_h.impacts ] self.assertTrue(same_impacts) # And look for same source problems for i in h.source_problems: print "Got source pb", i.get_name() same_pbs = i.get_name() in [ j.get_name() for j in orig_h.source_problems ] self.assertTrue(same_pbs) print "Services:", self.rg.services.__dict__ for s in self.rg.services: orig_s = self.sched.services.find_srv_by_name_and_hostname( s.host.host_name, s.service_description) print s.state, orig_s.state self.assertEqual(orig_s.state, s.state) self.assertEqual(orig_s.state_type, s.state_type) # Look for same impacts too for i in s.impacts: print "Got impact", i.get_name() same_impacts = i.get_name() in [ j.get_name() for j in orig_s.impacts ] self.assertTrue(same_impacts) # And look for same source problems for i in s.source_problems: print "Got source pb", i.get_name() same_pbs = i.get_name() in [ j.get_name() for j in orig_s.source_problems ] self.assertTrue(same_pbs) # Look for same host self.assertEqual(orig_s.host.get_name(), s.host.get_name()) def test_regenerator(self): # # Config is not correct because of a wrong relative path # in the main config file # # for h in self.sched.hosts: # h.realm = h.realm.get_name() self.sched.conf.skip_initial_broks = False self.sched.brokers['Default-Broker'] = { 'broks': [], 'has_full_broks': False } self.sched.fill_initial_broks('Default-Broker') self.rg = Regenerator() # Got the initial creation ones t0 = time.time() for b in self.sched.broks: print "Manage b", b.type b.prepare() self.rg.manage_brok(b) t1 = time.time() print 'First inc', t1 - t0, len(self.sched.broks) del self.sched.broks[:] self.look_for_same_values() print "Get the hosts and services" host = self.sched.hosts.find_by_name("test_host_0") host.checks_in_progress = [] host.act_depend_of = [] # ignore the router router = self.sched.hosts.find_by_name("test_router_0") router.checks_in_progress = [] router.act_depend_of = [] # ignore the router svc = self.sched.services.find_srv_by_name_and_hostname( "test_host_0", "test_ok_0") svc.checks_in_progress = [] svc.act_depend_of = [] # no hostchecks on critical checkresults self.scheduler_loop( 3, [[host, 2, 'DOWN | value1=1 value2=2'], [router, 0, 'UP | rtt=10'], [svc, 2, 'BAD | value1=0 value2=0']]) self.assertEqual('DOWN', host.state) self.assertEqual('HARD', host.state_type) t0 = time.time() for b in self.sched.broks: print "Manage b", b.type b.prepare() self.rg.manage_brok(b) t1 = time.time() print 'Time', t1 - t0 del self.sched.broks[:] self.look_for_same_values() print 'Time', t1 - t0 b = svc.get_initial_status_brok() b.prepare() print "GO BENCH!" t0 = time.time() for i in xrange(1, 1000): b = svc.get_initial_status_brok() b.prepare() s = Service({}) for (prop, value) in b.data.iteritems(): setattr(s, prop, value) t1 = time.time() print "Bench end:", t1 - t0 times = {} sizes = {} import cPickle data = {} cls = svc.__class__ start = time.time() for i in xrange(1, 10000): for prop, entry in svc.__class__.properties.items(): # Is this property intended for brokking? if 'full_status' in entry.fill_brok: data[prop] = svc.get_property_value_for_brok( prop, cls.properties) if not prop in times: times[prop] = 0 sizes[prop] = 0 t0 = time.time() tmp = cPickle.dumps(data[prop], 0) sizes[prop] += len(tmp) times[prop] += time.time() - t0 print "Times" for (k, v) in times.iteritems(): print "\t%s: %s" % (k, v) print "\n\n" print "Sizes" for (k, v) in sizes.iteritems(): print "\t%s: %s" % (k, v) print "\n" print "total time", time.time() - start def test_regenerator_load_from_scheduler(self): # # Config is not correct because of a wrong relative path # in the main config file # # for h in self.sched.hosts: # h.realm = h.realm.get_name() self.rg = Regenerator() self.rg.load_from_scheduler(self.sched) self.sched.conf.skip_initial_broks = False self.sched.brokers['Default-Broker'] = { 'broks': [], 'has_full_broks': False } self.sched.fill_initial_broks('Default-Broker') # Got the initial creation ones t0 = time.time() for b in self.sched.broks: print "Manage b", b.type b.prepare() self.rg.manage_brok(b) t1 = time.time() print 'First inc', t1 - t0, len(self.sched.broks) del self.sched.broks[:] self.look_for_same_values()
def test_regenerator(self): # # Config is not correct because of a wrong relative path # in the main config file # # for h in self.sched.hosts: # h.realm = h.realm.get_name() self.sched.conf.skip_initial_broks = False self.sched.brokers['Default-Broker'] = {'broks' : [], 'has_full_broks' : False} self.sched.fill_initial_broks('Default-Broker') self.rg = Regenerator() # Got the initial creation ones t0 = time.time() for b in self.sched.broks: print "Manage b", b.type b.prepare() self.rg.manage_brok(b) t1 = time.time() print 'First inc', t1 - t0, len(self.sched.broks) del self.sched.broks[:] self.look_for_same_values() print "Get the hosts and services" host = self.sched.hosts.find_by_name("test_host_0") host.checks_in_progress = [] host.act_depend_of = [] # ignore the router router = self.sched.hosts.find_by_name("test_router_0") router.checks_in_progress = [] router.act_depend_of = [] # ignore the router svc = self.sched.services.find_srv_by_name_and_hostname("test_host_0", "test_ok_0") svc.checks_in_progress = [] svc.act_depend_of = [] # no hostchecks on critical checkresults self.scheduler_loop(3, [[host, 2, 'DOWN | value1=1 value2=2'], [router, 0, 'UP | rtt=10'], [svc, 2, 'BAD | value1=0 value2=0']]) self.assertEqual('DOWN', host.state) self.assertEqual('HARD', host.state_type) t0 = time.time() for b in self.sched.broks: print "Manage b", b.type b.prepare() self.rg.manage_brok(b) t1 = time.time() print 'Time', t1 - t0 del self.sched.broks[:] self.look_for_same_values() print 'Time', t1 - t0 b = svc.get_initial_status_brok() b.prepare() print "GO BENCH!" t0 = time.time() for i in xrange(1, 1000): b = svc.get_initial_status_brok() b.prepare() s = Service({}) for (prop, value) in b.data.iteritems(): setattr(s, prop, value) t1 = time.time() print "Bench end:", t1 - t0 times = {} sizes = {} import cPickle data = {} cls = svc.__class__ start = time.time() for i in xrange(1, 10000): for prop, entry in svc.__class__.properties.items(): # Is this property intended for brokking? if 'full_status' in entry.fill_brok: data[prop] = svc.get_property_value_for_brok(prop, cls.properties) if not prop in times: times[prop] = 0 sizes[prop] = 0 t0 = time.time() tmp = cPickle.dumps(data[prop], 0) sizes[prop] += len(tmp) times[prop] += time.time() - t0 print "Times" for (k, v) in times.iteritems(): print "\t%s: %s" % (k, v) print "\n\n" print "Sizes" for (k, v) in sizes.iteritems(): print "\t%s: %s" % (k, v) print "\n" print "total time", time.time() - start
class Webui_broker(BaseModule, Daemon): def __init__(self, modconf): BaseModule.__init__(self, modconf) self.plugins = [] self.modconf = modconf # Web server configuration self.host = getattr(modconf, 'host', '0.0.0.0') self.port = int(getattr(modconf, 'port', '7767')) self.auth_secret = getattr(modconf, 'auth_secret', 'secret').encode('utf8', 'replace') # TODO : common preferences self.play_sound = to_bool(getattr(modconf, 'play_sound', '0')) # TODO : common preferences self.login_text = getattr(modconf, 'login_text', None) # TODO : common preferences self.company_logo = getattr(modconf, 'company_logo', 'default_company') if self.company_logo == '': # Set a dummy value if webui.cfg value is empty to force using the default logo ... self.company_logo = 'abcdef' # TODO : common preferences self.gravatar = to_bool(getattr(modconf, 'gravatar', '0')) # TODO : common preferences self.allow_html_output = to_bool( getattr(modconf, 'allow_html_output', '0')) # TODO : common preferences #self.max_output_length = int(getattr(modconf, 'max_output_length', '100')) # TODO : common preferences self.refresh_period = int(getattr(modconf, 'refresh_period', '60')) # Use element tag as image or use text self.tag_as_image = to_bool(getattr(modconf, 'tag_as_image', '0')) # Manage user's ACL self.manage_acl = to_bool(getattr(modconf, 'manage_acl', '1')) self.allow_anonymous = to_bool(getattr(modconf, 'allow_anonymous', '0')) # Advanced options self.http_backend = getattr(modconf, 'http_backend', 'auto') self.remote_user_enable = getattr(modconf, 'remote_user_enable', '0') self.remote_user_variable = getattr(modconf, 'remote_user_variable', 'X_REMOTE_USER') self.serveropts = {} umask = getattr(modconf, 'umask', None) if umask is not None: self.serveropts['umask'] = int(umask) bindAddress = getattr(modconf, 'bindAddress', None) if bindAddress: self.serveropts['bindAddress'] = str(bindAddress) # Apache htpasswd file for authentication self.htpasswd_file = getattr(modconf, 'htpasswd_file', '/etc/shinken/htpasswd.users') logger.info("[WebUI] htpasswd file: %s", self.htpasswd_file) if self.htpasswd_file: if not os.path.exists(self.htpasswd_file): logger.warning("[WebUI] htpasswd file '%s' does not exist.", self.htpasswd_file) self.htpasswd_file = None # Load the config dir and make it an absolute path self.config_dir = getattr(modconf, 'config_dir', 'share') self.config_dir = os.path.abspath(self.config_dir) logger.info("[WebUI] Config dir: %s", self.config_dir) # Load the share dir and make it an absolute path self.share_dir = getattr(modconf, 'share_dir', 'share') self.share_dir = os.path.abspath(self.share_dir) logger.info("[WebUI] Share dir: %s", self.share_dir) # Load the photo dir and make it an absolute path self.photo_dir = getattr(modconf, 'photos_dir', 'photos') self.photo_dir = os.path.abspath(self.photo_dir) logger.info("[WebUI] Photo dir: %s", self.photo_dir) self.user_picture = '' # @mohierf: still useful ? No value in webui.cfg, so always False ... # self.embeded_graph = to_bool(getattr(modconf, 'embeded_graph', '0')) # Look for an additional pages dir self.additional_plugins_dir = getattr(modconf, 'additional_plugins_dir', '') if self.additional_plugins_dir: self.additional_plugins_dir = os.path.abspath( self.additional_plugins_dir) logger.info("[WebUI] Additional plugins dir: %s", self.additional_plugins_dir) # Web UI timezone self.timezone = getattr(modconf, 'timezone', 'Europe/Paris') if self.timezone: logger.info("[WebUI] Setting our timezone to %s", self.timezone) os.environ['TZ'] = self.timezone time.tzset() logger.info("[WebUI] parameter timezone: %s", self.timezone) # Visual alerting thresholds # Used in the dashboard view to select background color for percentages self.hosts_states_warning = int( getattr(modconf, 'hosts_states_warning', '95')) self.hosts_states_critical = int( getattr(modconf, 'hosts_states_critical', '90')) self.services_states_warning = int( getattr(modconf, 'services_states_warning', '95')) self.services_states_critical = int( getattr(modconf, 'services_states_critical', '90')) # Web UI information self.app_version = getattr(modconf, 'about_version', WEBUI_VERSION) self.app_copyright = getattr(modconf, 'about_copyright', WEBUI_COPYRIGHT) self.app_release = getattr(modconf, 'about_release', WEBUI_RELEASENOTES) # We will save all widgets self.widgets = {} # We need our regenerator now (before main) so if we are in a scheduler, # rg will be able to skip some broks self.rg = Regenerator() # My bottle object ... self.bottle = bottle bottle.BaseTemplate.defaults['app'] = self # Called by Broker so we can do init stuff def init(self): logger.info("[WebUI] Initializing ...") self.rg.load_external_queue(self.from_q) # This is called only when we are in a scheduler # and just before we are started. So we can gain time, and # just load all scheduler objects without fear :) (we # will be in another process, so we will be able to hack objects # if need) def hook_pre_scheduler_mod_start(self, sched): print "pre_scheduler_mod_start::", sched.__dict__ self.rg.load_from_scheduler(sched) # In a scheduler we will have a filter of what we really want as a brok def want_brok(self, b): return self.rg.want_brok(b) def main(self): self.set_proctitle(self.name) # Daemon like init self.debug_output = [] self.modules_dir = modulesctx.get_modulesdir() self.modules_manager = ModulesManager('webui', self.find_modules_path(), []) self.modules_manager.set_modules(self.modules) # We can now output some previously silenced debug output self.do_load_modules() for inst in self.modules_manager.instances: f = getattr(inst, 'load', None) if f and callable(f): f(self) for s in self.debug_output: print s del self.debug_output # Check if the Bottle view dir really exist if not os.path.exists(bottle.TEMPLATE_PATH[0]): logger.error("[WebUI] The view path do not exist at %s" % bottle.TEMPLATE_PATH) sys.exit(2) # Check directories # We check if the photo directory exists. If not, try to create it for d in [self.photo_dir, self.share_dir, self.config_dir]: logger.debug("[WebUI] Checking dir: %s", d) if not os.path.exists(d): try: os.mkdir(d) logger.info("[WebUI] Created dir: %s", d) except Exception, exp: logger.error("[WebUI] Dir creation failed: %s", exp) # :TODO:maethor:150724: Complete with other function names self.auth_module = AuthMetaModule( AuthMetaModule.find_modules( self.modules_manager.get_internal_instances()), self) self.prefs_module = PrefsMetaModule( PrefsMetaModule.find_modules( self.modules_manager.get_internal_instances()), self) self.logs_module = LogsMetaModule( LogsMetaModule.find_modules( self.modules_manager.get_internal_instances()), self) self.graphs_module = GraphsMetaModule( GraphsMetaModule.find_modules( self.modules_manager.get_internal_instances()), self) self.helpdesk_module = HelpdeskMetaModule( HelpdeskMetaModule.find_modules( self.modules_manager.get_internal_instances()), self) # Data manager self.datamgr = WebUIDataManager(self.rg) self.helper = helper self.request = request self.response = response self.template_call = template # :TODO:maethor:150717: Doesn't work #username = self.request.get_cookie("user", secret=self.auth_secret) #if username: #self.user = User.from_contact(self.datamgr.get_contact(username), self.gravatar) #else: #self.user = None try: self.do_main() except Exception, exp: msg = Message(id=0, type='ICrash', data={ 'name': self.get_name(), 'exception': exp, 'trace': traceback.format_exc() }) self.from_q.put(msg) # wait 2 sec so we know that the broker got our message, and die time.sleep(2) raise
class TestRegenerator(ShinkenTest): def setUp(self): self.setup_with_file('etc/shinken_regenerator.cfg') def look_for_same_values(self): # Look at Regenerator values print "Hosts:", self.rg.hosts.__dict__ for h in self.rg.hosts: orig_h = self.sched.hosts.find_by_name(h.host_name) print h.state, orig_h.state # Look for same states self.assertEqual(orig_h.state, h.state) self.assertEqual(orig_h.state_type, h.state_type) # Look for same impacts for i in h.impacts: print "Got impact", i.get_name() same_impacts = i.get_name() in [j.get_name() for j in orig_h.impacts] self.assertTrue(same_impacts) # And look for same source problems for i in h.source_problems: print "Got source pb", i.get_name() same_pbs = i.get_name() in [j.get_name() for j in orig_h.source_problems] self.assertTrue(same_pbs) print "Services:", self.rg.services.__dict__ for s in self.rg.services: orig_s = self.sched.services.find_srv_by_name_and_hostname(s.host.host_name, s.service_description) print s.state, orig_s.state self.assertEqual(orig_s.state, s.state) self.assertEqual(orig_s.state_type, s.state_type) # Look for same impacts too for i in s.impacts: print "Got impact", i.get_name() same_impacts = i.get_name() in [j.get_name() for j in orig_s.impacts] self.assertTrue(same_impacts) # And look for same source problems for i in s.source_problems: print "Got source pb", i.get_name() same_pbs = i.get_name() in [j.get_name() for j in orig_s.source_problems] self.assertTrue(same_pbs) # Look for same host self.assertEqual(orig_s.host.get_name(), s.host.get_name()) def test_regenerator(self): # # Config is not correct because of a wrong relative path # in the main config file # # for h in self.sched.hosts: # h.realm = h.realm.get_name() self.sched.conf.skip_initial_broks = False self.sched.brokers['Default-Broker'] = {'broks' : [], 'has_full_broks' : False} self.sched.fill_initial_broks('Default-Broker') self.rg = Regenerator() # Got the initial creation ones t0 = time.time() for b in self.sched.broks: print "Manage b", b.type b.prepare() self.rg.manage_brok(b) t1 = time.time() print 'First inc', t1 - t0, len(self.sched.broks) del self.sched.broks[:] self.look_for_same_values() print "Get the hosts and services" host = self.sched.hosts.find_by_name("test_host_0") host.checks_in_progress = [] host.act_depend_of = [] # ignore the router router = self.sched.hosts.find_by_name("test_router_0") router.checks_in_progress = [] router.act_depend_of = [] # ignore the router svc = self.sched.services.find_srv_by_name_and_hostname("test_host_0", "test_ok_0") svc.checks_in_progress = [] svc.act_depend_of = [] # no hostchecks on critical checkresults self.scheduler_loop(3, [[host, 2, 'DOWN | value1=1 value2=2'], [router, 0, 'UP | rtt=10'], [svc, 2, 'BAD | value1=0 value2=0']]) self.assertEqual('DOWN', host.state) self.assertEqual('HARD', host.state_type) t0 = time.time() for b in self.sched.broks: print "Manage b", b.type b.prepare() self.rg.manage_brok(b) t1 = time.time() print 'Time', t1 - t0 del self.sched.broks[:] self.look_for_same_values() print 'Time', t1 - t0 b = svc.get_initial_status_brok() b.prepare() print "GO BENCH!" t0 = time.time() for i in xrange(1, 1000): b = svc.get_initial_status_brok() b.prepare() s = Service({}) for (prop, value) in b.data.iteritems(): setattr(s, prop, value) t1 = time.time() print "Bench end:", t1 - t0 times = {} sizes = {} import cPickle data = {} cls = svc.__class__ start = time.time() for i in xrange(1, 10000): for prop, entry in svc.__class__.properties.items(): # Is this property intended for brokking? if 'full_status' in entry.fill_brok: data[prop] = svc.get_property_value_for_brok(prop, cls.properties) if not prop in times: times[prop] = 0 sizes[prop] = 0 t0 = time.time() tmp = cPickle.dumps(data[prop], 0) sizes[prop] += len(tmp) times[prop] += time.time() - t0 print "Times" for (k, v) in times.iteritems(): print "\t%s: %s" % (k, v) print "\n\n" print "Sizes" for (k, v) in sizes.iteritems(): print "\t%s: %s" % (k, v) print "\n" print "total time", time.time() - start def test_regenerator_load_from_scheduler(self): # # Config is not correct because of a wrong relative path # in the main config file # # for h in self.sched.hosts: # h.realm = h.realm.get_name() self.rg = Regenerator() self.rg.load_from_scheduler(self.sched) self.sched.conf.skip_initial_broks = False self.sched.brokers['Default-Broker'] = {'broks' : [], 'has_full_broks' : False} self.sched.fill_initial_broks('Default-Broker') # Got the initial creation ones t0 = time.time() for b in self.sched.broks: print "Manage b", b.type b.prepare() self.rg.manage_brok(b) t1 = time.time() print 'First inc', t1 - t0, len(self.sched.broks) del self.sched.broks[:] self.look_for_same_values()
def __init__(self, modconf): BaseModule.__init__(self, modconf) self.plugins = [] self.modconf = modconf # Web server configuration self.host = getattr(modconf, 'host', '0.0.0.0') self.port = int(getattr(modconf, 'port', '7767')) self.auth_secret = getattr(modconf, 'auth_secret', 'secret').encode('utf8', 'replace') # TODO : common preferences self.play_sound = to_bool(getattr(modconf, 'play_sound', '0')) # TODO : common preferences self.login_text = getattr(modconf, 'login_text', None) # TODO : common preferences self.company_logo = getattr(modconf, 'company_logo', 'default_company') if self.company_logo == '': # Set a dummy value if webui.cfg value is empty to force using the default logo ... self.company_logo = 'abcdef' # TODO : common preferences self.gravatar = to_bool(getattr(modconf, 'gravatar', '0')) # TODO : common preferences self.allow_html_output = to_bool( getattr(modconf, 'allow_html_output', '0')) # TODO : common preferences #self.max_output_length = int(getattr(modconf, 'max_output_length', '100')) # TODO : common preferences self.refresh_period = int(getattr(modconf, 'refresh_period', '60')) # Use element tag as image or use text self.tag_as_image = to_bool(getattr(modconf, 'tag_as_image', '0')) # Manage user's ACL self.manage_acl = to_bool(getattr(modconf, 'manage_acl', '1')) self.allow_anonymous = to_bool(getattr(modconf, 'allow_anonymous', '0')) # Advanced options self.http_backend = getattr(modconf, 'http_backend', 'auto') self.remote_user_enable = getattr(modconf, 'remote_user_enable', '0') self.remote_user_variable = getattr(modconf, 'remote_user_variable', 'X_REMOTE_USER') self.serveropts = {} umask = getattr(modconf, 'umask', None) if umask is not None: self.serveropts['umask'] = int(umask) bindAddress = getattr(modconf, 'bindAddress', None) if bindAddress: self.serveropts['bindAddress'] = str(bindAddress) # Apache htpasswd file for authentication self.htpasswd_file = getattr(modconf, 'htpasswd_file', '/etc/shinken/htpasswd.users') logger.info("[WebUI] htpasswd file: %s", self.htpasswd_file) if self.htpasswd_file: if not os.path.exists(self.htpasswd_file): logger.warning("[WebUI] htpasswd file '%s' does not exist.", self.htpasswd_file) self.htpasswd_file = None # Load the config dir and make it an absolute path self.config_dir = getattr(modconf, 'config_dir', 'share') self.config_dir = os.path.abspath(self.config_dir) logger.info("[WebUI] Config dir: %s", self.config_dir) # Load the share dir and make it an absolute path self.share_dir = getattr(modconf, 'share_dir', 'share') self.share_dir = os.path.abspath(self.share_dir) logger.info("[WebUI] Share dir: %s", self.share_dir) # Load the photo dir and make it an absolute path self.photo_dir = getattr(modconf, 'photos_dir', 'photos') self.photo_dir = os.path.abspath(self.photo_dir) logger.info("[WebUI] Photo dir: %s", self.photo_dir) self.user_picture = '' # @mohierf: still useful ? No value in webui.cfg, so always False ... # self.embeded_graph = to_bool(getattr(modconf, 'embeded_graph', '0')) # Look for an additional pages dir self.additional_plugins_dir = getattr(modconf, 'additional_plugins_dir', '') if self.additional_plugins_dir: self.additional_plugins_dir = os.path.abspath( self.additional_plugins_dir) logger.info("[WebUI] Additional plugins dir: %s", self.additional_plugins_dir) # Web UI timezone self.timezone = getattr(modconf, 'timezone', 'Europe/Paris') if self.timezone: logger.info("[WebUI] Setting our timezone to %s", self.timezone) os.environ['TZ'] = self.timezone time.tzset() logger.info("[WebUI] parameter timezone: %s", self.timezone) # Visual alerting thresholds # Used in the dashboard view to select background color for percentages self.hosts_states_warning = int( getattr(modconf, 'hosts_states_warning', '95')) self.hosts_states_critical = int( getattr(modconf, 'hosts_states_critical', '90')) self.services_states_warning = int( getattr(modconf, 'services_states_warning', '95')) self.services_states_critical = int( getattr(modconf, 'services_states_critical', '90')) # Web UI information self.app_version = getattr(modconf, 'about_version', WEBUI_VERSION) self.app_copyright = getattr(modconf, 'about_copyright', WEBUI_COPYRIGHT) self.app_release = getattr(modconf, 'about_release', WEBUI_RELEASENOTES) # We will save all widgets self.widgets = {} # We need our regenerator now (before main) so if we are in a scheduler, # rg will be able to skip some broks self.rg = Regenerator() # My bottle object ... self.bottle = bottle bottle.BaseTemplate.defaults['app'] = self
def __init__(self, modconf): BaseModule.__init__(self, modconf) self.plugins = [] self.modconf = modconf # Web server configuration self.host = getattr(modconf, 'host', '0.0.0.0') self.port = int(getattr(modconf, 'port', '7767')) logger.info("[WebUI] server: %s:%d", self.host, self.port) self.endpoint = getattr(modconf, 'endpoint', None) if self.endpoint: if self.endpoint.endswith('/'): self.endpoint = self.endpoint[:-1] logger.info("[WebUI] configured endpoint: %s", self.endpoint) logger.warning("[WebUI] endpoint feature is not implemented! WebUI is served from root URL: http://%s:%d/", self.host, self.port) self.endpoint = None self.auth_secret = resolve_auth_secret(modconf) # TODO : common preferences self.play_sound = to_bool(getattr(modconf, 'play_sound', '0')) # TODO : common preferences self.login_text = getattr(modconf, 'login_text', None) # TODO : common preferences self.company_logo = getattr(modconf, 'company_logo', 'default_company') if self.company_logo == '': # Set a dummy value if webui.cfg value is empty to force using the default logo ... self.company_logo = 'abcdef' # TODO : common preferences self.gravatar = to_bool(getattr(modconf, 'gravatar', '0')) # TODO : common preferences self.allow_html_output = to_bool(getattr(modconf, 'allow_html_output', '0')) # TODO : common preferences #self.max_output_length = int(getattr(modconf, 'max_output_length', '100')) # TODO : common preferences self.refresh_period = int(getattr(modconf, 'refresh_period', '60')) # Use element tag as image or use text self.tag_as_image = to_bool(getattr(modconf, 'tag_as_image', '0')) # Manage user's ACL self.manage_acl = to_bool(getattr(modconf, 'manage_acl', '1')) self.allow_anonymous = to_bool(getattr(modconf, 'allow_anonymous', '0')) # Advanced options self.http_backend = getattr(modconf, 'http_backend', 'auto') self.remote_user_enable = getattr(modconf, 'remote_user_enable', '0') self.remote_user_variable = getattr(modconf, 'remote_user_variable', 'X_REMOTE_USER') self.serveropts = {} umask = getattr(modconf, 'umask', None) if umask is not None: self.serveropts['umask'] = int(umask) bindAddress = getattr(modconf, 'bindAddress', None) if bindAddress: self.serveropts['bindAddress'] = str(bindAddress) # Apache htpasswd file for authentication self.htpasswd_file = getattr(modconf, 'htpasswd_file', None) if self.htpasswd_file: if not os.path.exists(self.htpasswd_file): logger.warning("[WebUI] htpasswd file '%s' does not exist.", self.htpasswd_file) self.htpasswd_file = None # Load the config dir and make it an absolute path self.config_dir = getattr(modconf, 'config_dir', 'share') self.config_dir = os.path.abspath(self.config_dir) logger.info("[WebUI] Config dir: %s", self.config_dir) # Load the share dir and make it an absolute path self.share_dir = getattr(modconf, 'share_dir', 'share') self.share_dir = os.path.abspath(self.share_dir) logger.info("[WebUI] Share dir: %s", self.share_dir) # Load the photo dir and make it an absolute path self.photo_dir = getattr(modconf, 'photos_dir', 'photos') self.photo_dir = os.path.abspath(self.photo_dir) logger.info("[WebUI] Photo dir: %s", self.photo_dir) self.user_picture = '' # @mohierf: still useful ? No value in webui.cfg, so always False ... # self.embeded_graph = to_bool(getattr(modconf, 'embeded_graph', '0')) # Look for an additional pages dir self.additional_plugins_dir = getattr(modconf, 'additional_plugins_dir', '') if self.additional_plugins_dir: self.additional_plugins_dir = os.path.abspath(self.additional_plugins_dir) logger.info("[WebUI] Additional plugins dir: %s", self.additional_plugins_dir) # Web UI timezone self.timezone = getattr(modconf, 'timezone', 'Europe/Paris') if self.timezone: logger.info("[WebUI] Setting our timezone to %s", self.timezone) os.environ['TZ'] = self.timezone time.tzset() logger.info("[WebUI] parameter timezone: %s", self.timezone) # Visual alerting thresholds # Used in the dashboard view to select background color for percentages self.hosts_states_warning = int(getattr(modconf, 'hosts_states_warning', '95')) self.hosts_states_critical = int(getattr(modconf, 'hosts_states_critical', '90')) self.services_states_warning = int(getattr(modconf, 'services_states_warning', '95')) self.services_states_critical = int(getattr(modconf, 'services_states_critical', '90')) # Web UI information self.app_version = getattr(modconf, 'about_version', WEBUI_VERSION) self.app_copyright = getattr(modconf, 'about_copyright', WEBUI_COPYRIGHT) self.app_release = getattr(modconf, 'about_release', WEBUI_RELEASENOTES) # We will save all widgets self.widgets = {} # We need our regenerator now (before main) so if we are in a scheduler, # rg will be able to skip some broks self.rg = Regenerator() # My bottle object ... self.bottle = bottle bottle.BaseTemplate.defaults['app'] = self
class Webui_broker(BaseModule, Daemon): def __init__(self, modconf): BaseModule.__init__(self, modconf) self.plugins = [] self.modconf = modconf # Web server configuration self.host = getattr(modconf, 'host', '0.0.0.0') self.port = int(getattr(modconf, 'port', '7767')) logger.info("[WebUI] server: %s:%d", self.host, self.port) self.endpoint = getattr(modconf, 'endpoint', None) if self.endpoint: if self.endpoint.endswith('/'): self.endpoint = self.endpoint[:-1] logger.info("[WebUI] configured endpoint: %s", self.endpoint) logger.warning( "[WebUI] endpoint feature is not implemented! WebUI is served from root URL: http://%s:%d/", self.host, self.port) self.endpoint = None # Build session cookie self.session_cookie = getattr(modconf, 'cookie_name', 'user') self.auth_secret = resolve_auth_secret(modconf) logger.info("[WebUI] cookie: %s", self.session_cookie) # TODO : common preferences self.play_sound = to_bool(getattr(modconf, 'play_sound', '0')) # TODO : common preferences self.login_text = getattr(modconf, 'login_text', None) # TODO : common preferences self.company_logo = getattr(modconf, 'company_logo', 'default_company') if self.company_logo == '': # Set a dummy value if webui.cfg value is empty to force using the default logo ... self.company_logo = 'abcdef' # TODO : common preferences self.gravatar = to_bool(getattr(modconf, 'gravatar', '0')) # TODO : common preferences self.allow_html_output = to_bool( getattr(modconf, 'allow_html_output', '0')) # TODO : common preferences #self.max_output_length = int(getattr(modconf, 'max_output_length', '100')) # TODO : common preferences self.refresh_period = int(getattr(modconf, 'refresh_period', '60')) self.refresh = False if self.refresh_period == 0 else True # Use element tag as image or use text self.tag_as_image = to_bool(getattr(modconf, 'tag_as_image', '0')) # Manage user's ACL self.manage_acl = to_bool(getattr(modconf, 'manage_acl', '1')) self.allow_anonymous = to_bool(getattr(modconf, 'allow_anonymous', '0')) # Allow to customize default downtime duration self.default_downtime_hours = int( getattr(modconf, 'default_downtime_hours', '48')) self.shinken_downtime_fixed = int( getattr(modconf, 'shinken_downtime_fixed', '1')) self.shinken_downtime_trigger = int( getattr(modconf, 'shinken_downtime_trigger', '0')) self.shinken_downtime_duration = int( getattr(modconf, 'shinken_downtime_duration', '0')) # Allow to customize default acknowledge parameters self.default_ack_sticky = int( getattr(modconf, 'default_ack_sticky', '2')) self.default_ack_notify = int( getattr(modconf, 'default_ack_notify', '1')) self.default_ack_persistent = int( getattr(modconf, 'default_ack_persistent', '1')) # Advanced options self.http_backend = getattr(modconf, 'http_backend', 'auto') self.remote_user_enable = getattr(modconf, 'remote_user_enable', '0') self.remote_user_variable = getattr(modconf, 'remote_user_variable', 'X_REMOTE_USER') self.serveropts = {} umask = getattr(modconf, 'umask', None) if umask is not None: self.serveropts['umask'] = int(umask) bindAddress = getattr(modconf, 'bindAddress', None) if bindAddress: self.serveropts['bindAddress'] = str(bindAddress) # Apache htpasswd file for authentication self.htpasswd_file = getattr(modconf, 'htpasswd_file', None) if self.htpasswd_file: if not os.path.exists(self.htpasswd_file): logger.warning("[WebUI] htpasswd file '%s' does not exist.", self.htpasswd_file) self.htpasswd_file = None # Alignak backend for authentication self.frontend = None self.alignak_backend_objects = False self.alignak_backend_endpoint = getattr(modconf, 'alignak_backend_endpoint', None) if frontend_available and self.alignak_backend_endpoint: self.frontend = FrontEnd() if self.frontend: self.frontend.configure(self.alignak_backend_endpoint) logger.info("[WebUI] alignak backend: %s", self.frontend.url_endpoint_root) self.alignak_backend_objects = to_bool( getattr(modconf, 'alignak_backend_objects', '0')) # Load the config dir and make it an absolute path self.config_dir = getattr(modconf, 'config_dir', 'share') self.config_dir = os.path.abspath(self.config_dir) logger.info("[WebUI] Config dir: %s", self.config_dir) # Load the share dir and make it an absolute path self.share_dir = getattr(modconf, 'share_dir', 'share') self.share_dir = os.path.abspath(self.share_dir) logger.info("[WebUI] Share dir: %s", self.share_dir) # Load the photo dir and make it an absolute path self.photo_dir = getattr(modconf, 'photos_dir', 'photos') self.photo_dir = os.path.abspath(self.photo_dir) logger.info("[WebUI] Photo dir: %s", self.photo_dir) # User information self.user_session = None self.user_info = None # @mohierf: still useful ? No value in webui.cfg, so always False ... # self.embeded_graph = to_bool(getattr(modconf, 'embeded_graph', '0')) # Look for an additional pages dir self.additional_plugins_dir = getattr(modconf, 'additional_plugins_dir', '') if self.additional_plugins_dir: self.additional_plugins_dir = os.path.abspath( self.additional_plugins_dir) logger.info("[WebUI] Additional plugins dir: %s", self.additional_plugins_dir) # Web UI timezone self.timezone = getattr(modconf, 'timezone', 'Europe/Paris') if self.timezone: logger.info("[WebUI] Setting our timezone to %s", self.timezone) os.environ['TZ'] = self.timezone time.tzset() logger.info("[WebUI] parameter timezone: %s", self.timezone) # Visual alerting thresholds # Used in the dashboard view to select background color for percentages self.hosts_states_warning = int( getattr(modconf, 'hosts_states_warning', '95')) self.hosts_states_critical = int( getattr(modconf, 'hosts_states_critical', '90')) self.services_states_warning = int( getattr(modconf, 'services_states_warning', '95')) self.services_states_critical = int( getattr(modconf, 'services_states_critical', '90')) # Web UI information self.app_version = getattr(modconf, 'about_version', WEBUI_VERSION) self.app_copyright = getattr(modconf, 'about_copyright', WEBUI_COPYRIGHT) # We will save all widgets self.widgets = {} # We need our regenerator now (before main) so if we are in a scheduler, # rg will be able to skip some broks self.rg = None if not self.alignak_backend_objects: self.rg = Regenerator() # My bottle object ... self.bottle = bottle bottle.BaseTemplate.defaults['app'] = self # Called by Broker so we can do init stuff def init(self): logger.info("[WebUI] Initializing ...") if not self.alignak_backend_objects: self.rg.load_external_queue(self.from_q) # This is called only when we are in a scheduler # and just before we are started. So we can gain time, and # just load all scheduler objects without fear :) (we # will be in another process, so we will be able to hack objects # if need) def hook_pre_scheduler_mod_start(self, sched): print "pre_scheduler_mod_start::", sched.__dict__ self.rg.load_from_scheduler(sched) # In a scheduler we will have a filter of what we really want as a brok def want_brok(self, b): return self.rg.want_brok(b) def main(self, stand_alone=False): """ Module main function """ self.stand_alone = stand_alone if self.stand_alone: setproctitle(self.name) else: self.set_proctitle(self.name) # Modules management self.debug_output = [] self.modules_dir = modulesctx.get_modulesdir() self.modules_manager = ModulesManager('webui', self.find_modules_path(), []) self.modules_manager.set_modules(self.modules) logger.info("[WebUI] modules %s", self.modules) # We can now output some previously silenced debug output self.do_load_modules() for inst in self.modules_manager.instances: f = getattr(inst, 'load', None) if f and callable(f): f(self) for s in self.debug_output: print s del self.debug_output logger.info("[WebUI] loaded modules %s", self.modules) # Check if the Bottle view dir really exist if not os.path.exists(bottle.TEMPLATE_PATH[0]): logger.error("[WebUI] The view path do not exist at %s", bottle.TEMPLATE_PATH) sys.exit(2) # Load internal sub modules self.auth_module = AuthMetaModule( AuthMetaModule.find_modules( self.modules_manager.get_internal_instances()), self) self.prefs_module = PrefsMetaModule( PrefsMetaModule.find_modules( self.modules_manager.get_internal_instances()), self) self.logs_module = LogsMetaModule( LogsMetaModule.find_modules( self.modules_manager.get_internal_instances()), self) self.graphs_module = GraphsMetaModule( GraphsMetaModule.find_modules( self.modules_manager.get_internal_instances()), self) self.helpdesk_module = HelpdeskMetaModule( HelpdeskMetaModule.find_modules( self.modules_manager.get_internal_instances()), self) # Data manager self.datamgr = WebUIDataManager(self.rg, self.frontend, self.alignak_backend_objects) self.helper = helper # Check directories # We check if the photo directory exists. If not, try to create it for dir in [self.share_dir, self.photo_dir, self.config_dir]: logger.debug("[WebUI] Checking dir: %s", dir) if not os.path.exists(dir): try: # os.mkdir(dir) os.makedirs(dir, mode=0o777) logger.info("[WebUI] Created directory: %s", dir) except Exception as e: logger.error( "[WebUI] Directory creation failed: %s, error: %s", dir, str(e)) else: logger.debug("[WebUI] Still existing directory: %s", dir) # Bottle objects self.request = bottle.request self.response = bottle.response try: # I register my exit function self.set_exit_handler() # First load the additional plugins so they will have the lead on URI routes if self.additional_plugins_dir: self.load_plugins(self.additional_plugins_dir) # Modules can also override some views if need for inst in self.modules_manager.instances: f = getattr(inst, 'get_webui_plugins_path', None) if f and callable(f): mod_plugins_path = os.path.abspath(f(self)) self.load_plugins(mod_plugins_path) # Then look at the plugins into core and load all we can there core_plugin_dir = os.path.join( os.path.abspath(os.path.dirname(__file__)), 'plugins') self.load_plugins(core_plugin_dir) # Declare the whole app static files AFTER the plugin ones self.declare_common_static() # Mount Web UI application # if self.endpoint: # root_app.mount(self.endpoint, webui_app) # logger.info("[WebUI] root routes: %s", root_app.routes) # for route in webui_app.routes: # logger.info("[WebUI] route: %s", route) for route in webui_app.routes: logger.info("[WebUI] route: %s", route) # We will protect the operations on # the non read+write with a lock and # 2 int self.global_lock = threading.RLock() self.nb_readers = 0 self.nb_writers = 0 self.data_thread = None self.ls_thread = None # For alignak backend ... if self.frontend: # Launch the livestate thread ... self.ls_thread = threading.Thread(None, self.manage_ls_thread, 'lsthread') self.ls_thread.start() else: # Launch the data thread ... self.data_thread = threading.Thread(None, self.manage_brok_thread, 'datathread') self.data_thread.start() # TODO: look for alive and killing logger.info("[WebUI] starting Web UI server on %s:%d ...", self.host, self.port) bottle.TEMPLATES.clear() webui_app.run(host=self.host, port=self.port, server=self.http_backend, **self.serveropts) except Exception as e: if self.stand_alone: logger.error("[WebUI] do_main exception: %s", str(e)) logger.error("[WebUI] traceback: %s", traceback.format_exc()) exit(1) else: msg = Message(id=0, type='ICrash', data={ 'name': self.get_name(), 'exception': e, 'trace': traceback.format_exc() }) self.from_q.put(msg) # wait 2 sec so we know that the broker got our message, and die time.sleep(2) raise # External commands # ----------------------------------------------------- def push_external_command(self, e): """ A plugin sends us an external command. Notify this command to the monitoring framework ... """ logger.debug("[WebUI] Got an external command: %s", e.__dict__) if self.stand_alone: logger.warning( "[WebUI] --------------------------------------------------") logger.warning("[WebUI] TODO: notify external command: %s", e.__dict__) logger.warning( "[WebUI] --------------------------------------------------") else: try: self.from_q.put(e) except Exception, exp: logger.error("[WebUI] External command push, exception: %s", str(exp))
def __init__(self, modconf): BaseModule.__init__(self, modconf) self.plugins = [] self.modconf = modconf # Web server configuration self.host = getattr(modconf, 'host', '0.0.0.0') self.port = int(getattr(modconf, 'port', '7767')) logger.info("[WebUI] server: %s:%d", self.host, self.port) self.endpoint = getattr(modconf, 'endpoint', None) if self.endpoint: if self.endpoint.endswith('/'): self.endpoint = self.endpoint[:-1] logger.info("[WebUI] configured endpoint: %s", self.endpoint) logger.warning( "[WebUI] endpoint feature is not implemented! WebUI is served from root URL: http://%s:%d/", self.host, self.port) self.endpoint = None # Build session cookie self.session_cookie = getattr(modconf, 'cookie_name', 'user') self.auth_secret = resolve_auth_secret(modconf) logger.info("[WebUI] cookie: %s", self.session_cookie) # TODO : common preferences self.play_sound = to_bool(getattr(modconf, 'play_sound', '0')) # TODO : common preferences self.login_text = getattr(modconf, 'login_text', None) # TODO : common preferences self.company_logo = getattr(modconf, 'company_logo', 'default_company') if self.company_logo == '': # Set a dummy value if webui.cfg value is empty to force using the default logo ... self.company_logo = 'abcdef' # TODO : common preferences self.gravatar = to_bool(getattr(modconf, 'gravatar', '0')) # TODO : common preferences self.allow_html_output = to_bool( getattr(modconf, 'allow_html_output', '0')) # TODO : common preferences #self.max_output_length = int(getattr(modconf, 'max_output_length', '100')) # TODO : common preferences self.refresh_period = int(getattr(modconf, 'refresh_period', '60')) self.refresh = False if self.refresh_period == 0 else True # Use element tag as image or use text self.tag_as_image = to_bool(getattr(modconf, 'tag_as_image', '0')) # Manage user's ACL self.manage_acl = to_bool(getattr(modconf, 'manage_acl', '1')) self.allow_anonymous = to_bool(getattr(modconf, 'allow_anonymous', '0')) # Allow to customize default downtime duration self.default_downtime_hours = int( getattr(modconf, 'default_downtime_hours', '48')) self.shinken_downtime_fixed = int( getattr(modconf, 'shinken_downtime_fixed', '1')) self.shinken_downtime_trigger = int( getattr(modconf, 'shinken_downtime_trigger', '0')) self.shinken_downtime_duration = int( getattr(modconf, 'shinken_downtime_duration', '0')) # Allow to customize default acknowledge parameters self.default_ack_sticky = int( getattr(modconf, 'default_ack_sticky', '2')) self.default_ack_notify = int( getattr(modconf, 'default_ack_notify', '1')) self.default_ack_persistent = int( getattr(modconf, 'default_ack_persistent', '1')) # Advanced options self.http_backend = getattr(modconf, 'http_backend', 'auto') self.remote_user_enable = getattr(modconf, 'remote_user_enable', '0') self.remote_user_variable = getattr(modconf, 'remote_user_variable', 'X_REMOTE_USER') self.serveropts = {} umask = getattr(modconf, 'umask', None) if umask is not None: self.serveropts['umask'] = int(umask) bindAddress = getattr(modconf, 'bindAddress', None) if bindAddress: self.serveropts['bindAddress'] = str(bindAddress) # Apache htpasswd file for authentication self.htpasswd_file = getattr(modconf, 'htpasswd_file', None) if self.htpasswd_file: if not os.path.exists(self.htpasswd_file): logger.warning("[WebUI] htpasswd file '%s' does not exist.", self.htpasswd_file) self.htpasswd_file = None # Alignak backend for authentication self.frontend = None self.alignak_backend_objects = False self.alignak_backend_endpoint = getattr(modconf, 'alignak_backend_endpoint', None) if frontend_available and self.alignak_backend_endpoint: self.frontend = FrontEnd() if self.frontend: self.frontend.configure(self.alignak_backend_endpoint) logger.info("[WebUI] alignak backend: %s", self.frontend.url_endpoint_root) self.alignak_backend_objects = to_bool( getattr(modconf, 'alignak_backend_objects', '0')) # Load the config dir and make it an absolute path self.config_dir = getattr(modconf, 'config_dir', 'share') self.config_dir = os.path.abspath(self.config_dir) logger.info("[WebUI] Config dir: %s", self.config_dir) # Load the share dir and make it an absolute path self.share_dir = getattr(modconf, 'share_dir', 'share') self.share_dir = os.path.abspath(self.share_dir) logger.info("[WebUI] Share dir: %s", self.share_dir) # Load the photo dir and make it an absolute path self.photo_dir = getattr(modconf, 'photos_dir', 'photos') self.photo_dir = os.path.abspath(self.photo_dir) logger.info("[WebUI] Photo dir: %s", self.photo_dir) # User information self.user_session = None self.user_info = None # @mohierf: still useful ? No value in webui.cfg, so always False ... # self.embeded_graph = to_bool(getattr(modconf, 'embeded_graph', '0')) # Look for an additional pages dir self.additional_plugins_dir = getattr(modconf, 'additional_plugins_dir', '') if self.additional_plugins_dir: self.additional_plugins_dir = os.path.abspath( self.additional_plugins_dir) logger.info("[WebUI] Additional plugins dir: %s", self.additional_plugins_dir) # Web UI timezone self.timezone = getattr(modconf, 'timezone', 'Europe/Paris') if self.timezone: logger.info("[WebUI] Setting our timezone to %s", self.timezone) os.environ['TZ'] = self.timezone time.tzset() logger.info("[WebUI] parameter timezone: %s", self.timezone) # Visual alerting thresholds # Used in the dashboard view to select background color for percentages self.hosts_states_warning = int( getattr(modconf, 'hosts_states_warning', '95')) self.hosts_states_critical = int( getattr(modconf, 'hosts_states_critical', '90')) self.services_states_warning = int( getattr(modconf, 'services_states_warning', '95')) self.services_states_critical = int( getattr(modconf, 'services_states_critical', '90')) # Web UI information self.app_version = getattr(modconf, 'about_version', WEBUI_VERSION) self.app_copyright = getattr(modconf, 'about_copyright', WEBUI_COPYRIGHT) # We will save all widgets self.widgets = {} # We need our regenerator now (before main) so if we are in a scheduler, # rg will be able to skip some broks self.rg = None if not self.alignak_backend_objects: self.rg = Regenerator() # My bottle object ... self.bottle = bottle bottle.BaseTemplate.defaults['app'] = self