[Pkg-nagios-changes] [SCM] UNNAMED PROJECT branch, debian/master, updated. 810edbdd3feedbfe37f4a65bee50b57b2f60fa2a

Naparuba naparuba at gmail.com
Tue Feb 28 22:11:49 UTC 2012


The following commit has been merged in the debian/master branch:
commit 3b1d62821e77dd56321c5d8c213209829fc3e57a
Author: Naparuba <naparuba at gmail.com>
Date:   Wed Jan 4 14:06:45 2012 +0100

    * Add : (reported by : MINOZA, Landy) multi-layer management for serice template on host template. So if you apply a service on layer 3 and your host inherit from layer1->layer2->layer3, it will inherit the service.
    * Fix : bad setup with setup.py (yes, AGAIN problem with that script....) for packs.

diff --git a/etc/nagios.cfg b/etc/nagios.cfg
index 0885171..5a964a1 100644
--- a/etc/nagios.cfg
+++ b/etc/nagios.cfg
@@ -34,7 +34,7 @@ cfg_file=contactgroups.cfg
 # discovered hosts 
 cfg_dir=hosts
 cfg_dir=services
-cfg_fir=packs
+cfg_dir=packs
 cfg_dir=objects/discovery
 
 # Un comment this for a sample configuration
diff --git a/setup.py b/setup.py
index 5d8ba80..1219ce6 100644
--- a/setup.py
+++ b/setup.py
@@ -494,6 +494,17 @@ config_objects_file = (
                         'certs/ca.pem'
 )
 
+# Now service packs files
+srv_pack_files = gen_data_files('etc/packs')
+# We must remove the etc from the paths
+srv_pack_files = [s.replace('etc/', '') for s in srv_pack_files]
+#print "SRV PACK FILES", srv_pack_files
+config_objects_file_extended = list(config_objects_file)
+config_objects_file_extended.extend(srv_pack_files)
+config_objects_file = tuple(config_objects_file_extended)
+print config_objects_file
+
+
 # daemon configs
 daemon_ini_files = (('broker', 'brokerd.ini'),
                     ('broker', 'brokerd-windows.ini'),
@@ -518,7 +529,6 @@ resource_cfg_files = ('resource.cfg', )
 full_path_webui_files = gen_data_files('shinken/webui')
 webui_files = [s.replace('shinken/webui/', 'webui/') for s in full_path_webui_files]
 
-
 package_data = ['*.py','modules/*.py','modules/*/*.py']
 package_data.extend(webui_files)
 
@@ -550,6 +560,8 @@ if not is_update:
          ['build/bin/default/shinken' ]
          ))
 
+
+#print "DATA", data_files
     
 print "All package _data"
 if __name__ == "__main__":
diff --git a/shinken/graph.py b/shinken/graph.py
index 9d084ef..4db7978 100644
--- a/shinken/graph.py
+++ b/shinken/graph.py
@@ -21,8 +21,8 @@
 #along with Shinken.  If not, see <http://www.gnu.org/licenses/>.
 
 
-#Graph is a class to make graph things like DFS checks or accessibility
-#Why use an atomic bomb when a little hammer is enought?
+# Graph is a class to make graph things like DFS checks or accessibility
+# Why use an atomic bomb when a little hammer is enough?
 
 
 class Graph:
@@ -30,30 +30,30 @@ class Graph:
         self.nodes = {}
 
 
-    #Do not call twice...
+    # Do not call twice...
     def add_node(self, node):
         self.nodes[node] = []
 
 
-    #Just loop over nodes
+    # Just loop over nodes
     def add_nodes(self, nodes):
         for node in nodes:
             self.add_node(node)
 
-    #Add an edge to the graph from->to
+    # Add an edge to the graph from->to
     def add_edge(self, from_node, to_node):
-        #Maybe to_node is unknown
+        # Maybe to_node is unknown
         if to_node not in self.nodes:
             self.add_node(to_node)
 
         try:
             self.nodes[from_node].append(to_node)
-        #If from_node do not exist, add it with it's son
-        except KeyError:
+        # If from_node do not exist, add it with it's son
+        except KeyError, exp:
             self.nodes[from_node] = [to_node]
 
 
-    #Return all nodes that are in a loop. So if return [], no loop
+    # Return all nodes that are in a loop. So if return [], no loop
     def loop_check(self):
         in_loop = []
         #Add the tag for dfs check
@@ -69,86 +69,86 @@ class Graph:
             if node.dfs_loop_status == 'DFS_LOOP_INSIDE':
                 in_loop.append(node)
 
-        #Remove the tag
+        # Remove the tag
         for node in self.nodes:
             del node.dfs_loop_status
 
         return in_loop
 
 
-    #DFS_UNCHECKED default value
-    #DFS_TEMPORARY_CHECKED check just one time
-    #DFS_OK no problem for node and it's childs
-    #DFS_NEAR_LOOP has trouble sons
-    #DFS_LOOP_INSIDE is a part of a loop!
+    # DFS_UNCHECKED default value
+    # DFS_TEMPORARY_CHECKED check just one time
+    # DFS_OK no problem for node and it's childs
+    # DFS_NEAR_LOOP has trouble sons
+    # DFS_LOOP_INSIDE is a part of a loop!
     def dfs_loop_search(self, root):
-        #Make the root temporary checkded
+        # Make the root temporary checkded
         root.dfs_loop_status = 'DFS_TEMPORARY_CHECKED'
 
-        #We are scanning the sons
+        # We are scanning the sons
         for child in self.nodes[root]:
             child_status = child.dfs_loop_status
-            #If a child is not checked, check it
+            # If a child is not checked, check it
             if child_status == 'DFS_UNCHECKED':
                 self.dfs_loop_search(child)
                 child_status = child.dfs_loop_status
 
-            #If a child already temporary checked, its a problem,
-            #loop inside, and its a acked status
+            # If a child already temporary checked, its a problem,
+            # loop inside, and its a acked status
             if child_status == 'DFS_TEMPORARY_CHECKED':
                 child.dfs_loop_status = 'DFS_LOOP_INSIDE'
                 root.dfs_loop_status = 'DFS_LOOP_INSIDE'
 
-            #If a child already temporary checked, its a problem, loop inside
+            # If a child already temporary checked, its a problem, loop inside
             if child_status in ('DFS_NEAR_LOOP', 'DFS_LOOP_INSIDE'):
-                #if a node is know to be part of a loop, do not let it be less
+                # if a node is know to be part of a loop, do not let it be less
                 if root.dfs_loop_status != 'DFS_LOOP_INSIDE':
                     root.dfs_loop_status = 'DFS_NEAR_LOOP'
-                #We already saw this child, it's a problem
+                # We already saw this child, it's a problem
                 child.dfs_loop_status = 'DFS_LOOP_INSIDE'
 
-        #If root have been modified, do not set it OK
-        #A node is OK if and only if all of his childs are OK
-        #if it does not have child, goes ok
+        # If root have been modified, do not set it OK
+        # A node is OK if and only if all of his childs are OK
+        # if it does not have child, goes ok
         if root.dfs_loop_status == 'DFS_TEMPORARY_CHECKED':
             root.dfs_loop_status = 'DFS_OK'
 
 
-    #Get accessibility packs of the graph : in one pack,
-    #element are related in a way. Between packs, there is no relation
-    #at all.
-    #TODO : Get it work for directionnal graph too
-    #Because for now, edge must be father->son AND son->father
+    # Get accessibility packs of the graph : in one pack,
+    # element are related in a way. Between packs, there is no relation
+    # at all.
+    # TODO : Get it work for directionnal graph too
+    # Because for now, edge must be father->son AND son->father
     def get_accessibility_packs(self):
         packs = []
-        #Add the tag for dfs check
+        # Add the tag for dfs check
         for node in self.nodes:
             node.dfs_loop_status = 'DFS_UNCHECKED'
 
         for node in self.nodes:
-            #Run the dfs only if the node is not already done */
+            # Run the dfs only if the node is not already done */
             if node.dfs_loop_status == 'DFS_UNCHECKED':
                 packs.append(self.dfs_get_all_childs(node))
 
-        #Remove the tag
+        # Remove the tag
         for node in self.nodes:
             del node.dfs_loop_status
 
         return packs
 
 
-    #Return all mychilds, and all childs of my childs
+    # Return all mychilds, and all childs of my childs
     def dfs_get_all_childs(self, root):
         root.dfs_loop_status = 'DFS_CHECKED'
 
         ret = set()
-        #Me
+        # Me
         ret.add(root)
-        #And my sons
+        # And my sons
         ret.update(self.nodes[root])
 
         for child in self.nodes[root]:
-            #I just don't care about already check childs
+            # I just don't care about already check childs
             if child.dfs_loop_status == 'DFS_UNCHECKED':
                 ret.update(self.dfs_get_all_childs(child))
 
diff --git a/shinken/objects/host.py b/shinken/objects/host.py
index ca5edcf..4baa626 100644
--- a/shinken/objects/host.py
+++ b/shinken/objects/host.py
@@ -1096,26 +1096,46 @@ class Hosts(Items):
 
 
     # Return a list of the host_name of the hosts
-    # that gotthe template with name=tpl_name
+    # that got the template with name=tpl_name or inherit from
+    # a template that use it
     def find_hosts_that_use_template(self, tpl_name):
-        res = []
-        # first find the template
+        res = set()
+
+        # First find the template
         tpl = None
         for h in self:
             # Look for template with the good name
             if h.is_tpl() and hasattr(h, 'name') and h.name.strip() == tpl_name.strip():
                 tpl = h
 
-        # If we find noone, we return nothing (easy case:) )
+        # If we find none, we return nothing (easy case:) )
         if tpl is None:
             return []
 
-        # Ok, we find the tpl
+        # Ok, we find the tpl. We should find its father template too
+        for t in self.templates.values():
+            t.dfs_loop_status = 'DFS_UNCHECKED'
+        all_tpl_searched = self.templates_graph.dfs_get_all_childs(tpl)
+        # Clean the search tag
+        # TODO : better way?
+        for t in self.templates.values():
+            del t.dfs_loop_status
+
+        # Now we got all the templates we are looking for (so the template
+        # and all its own templates too, we search for the hosts that are
+        # using them
         for h in self:
-            if tpl in h.templates and hasattr(h, 'host_name'):
-                res.append(h.host_name)
-
-        return res
+            # If the host is a not valid one, skip it
+            if not hasattr(h, 'host_name'):
+                continue
+            # look if there is a match between host templates
+            # and the ones we are looking for
+            for t in h.templates:
+                if t in all_tpl_searched:
+                    res.add(h.host_name)
+                    continue
+
+        return list(res)
 
 
     # Will create all business tree for the
diff --git a/shinken/objects/item.py b/shinken/objects/item.py
index c891b90..ab549cb 100644
--- a/shinken/objects/item.py
+++ b/shinken/objects/item.py
@@ -27,6 +27,7 @@
 import time
 from copy import copy
 
+from shinken.graph import Graph
 from shinken.commandcall import CommandCall
 from shinken.property import StringProp, ListProp
 from shinken.brok import Brok
@@ -572,7 +573,8 @@ class Items(object):
         for i in items:
             self.items[i.id] = i
         self.templates = {}
-
+        # We should keep a graph of templates relations
+        self.templates_graph = Graph()
 
 
     def __iter__(self):
@@ -657,13 +659,14 @@ class Items(object):
 
 
     def find_tpl_by_name(self, name):
-        for id in self.templates:
-            i = self.items[id]
+        for i in self.templates.values():
             if hasattr(i, 'name') and i.name == name:
                 return i
         return None
 
 
+    # We will link all templates, and create the template
+    # graph too
     def linkify_templates(self):
         # First we create a list of all templates
         self.create_tpl_list()
@@ -672,13 +675,24 @@ class Items(object):
             new_tpls = []
             for tpl in tpls:
                 t = self.find_tpl_by_name(tpl.strip())
+                # If it's ok, add the template and update the
+                # template graph too
                 if t is not None:
+                    # add the template object to us
                     new_tpls.append(t)
                 else: # not find? not good!
                     err = "ERROR: the template '%s' defined for '%s' is unknown" % (tpl, i.get_name())
                     i.configuration_errors.append(err)
             i.templates = new_tpls
 
+        # Now we will create the template graph, so
+        # we look only for templates here. First we sould declare our nodes
+        for tpl in self.templates.values():
+            self.templates_graph.add_node(tpl)
+        # And then really create our edge
+        for tpl in self.templates.values():
+            for father in tpl.templates:
+                self.templates_graph.add_edge(father, tpl)
 
 
     def is_correct(self):
@@ -719,6 +733,7 @@ class Items(object):
         for i in tpls:
             del self.items[i.id]
         del self.templates
+        del self.templates_graph
 
 
     def clean(self):
diff --git a/shinken/objects/service.py b/shinken/objects/service.py
index 27d65be..017a9d1 100644
--- a/shinken/objects/service.py
+++ b/shinken/objects/service.py
@@ -1100,11 +1100,10 @@ class Services(Items):
         # because they are our final host_name after all
         if not s.is_tpl():
             for_hosts_to_create.append(hname)
-
-        # But for template it's more tricky : it's a template name
-        # we've got, not a real host_name/ So we must get a list of host_name
-        # that use this template
         else:
+            # But for template it's more tricky : it's a template name
+            # we've got, not a real host_name/ So we must get a list of host_name
+            # that use this template
             hosts_from_tpl = hosts.find_hosts_that_use_template(hname.strip())
 
             # And now copy our real services
diff --git a/test/etc/service_tpl_on_host_tpl/hosts.cfg b/test/etc/service_tpl_on_host_tpl/hosts.cfg
index d53ab64..93aded2 100644
--- a/test/etc/service_tpl_on_host_tpl/hosts.cfg
+++ b/test/etc/service_tpl_on_host_tpl/hosts.cfg
@@ -72,3 +72,42 @@ define host{
   use                            generic-host, template_host_with_service
 }
 
+
+
+
+
+
+########## Multi player part
+
+
+define host{
+     use      layer2
+     name     layer1
+     register 0
+}
+
+
+define host{
+     use      layer3
+     name     layer2
+     register 0
+}
+
+define host{
+     use      generic-host
+     name     layer3
+     register 0
+}
+
+
+#Ok, so we want this one to have the new service from template_host_with_service
+define host{
+  address                        127.0.0.1
+  alias                          up_0
+  check_command                  check-host-alive-parent!up!$HOSTSTATE:test_router_0$
+  event_handler                  eventhandler
+  check_period                   24x7
+  host_name                      host_multi_layers
+  use                            layer1
+}
+
diff --git a/test/etc/service_tpl_on_host_tpl/services.cfg b/test/etc/service_tpl_on_host_tpl/services.cfg
index 9d6a6c4..b60bd4e 100644
--- a/test/etc/service_tpl_on_host_tpl/services.cfg
+++ b/test/etc/service_tpl_on_host_tpl/services.cfg
@@ -63,3 +63,15 @@ define service{
   #And of course make it a template
   register			 0
 }
+
+define service{
+  #Here host_name is just a template name, and the high level layer
+  host_name                      layer3
+  service_description            srv_multi_layer
+  use                            generic-service
+  check_command			 check_service!ok
+
+  #And of course make it a template
+  register                       0
+}
+
diff --git a/test/test_service_tpl_on_host_tpl.py b/test/test_service_tpl_on_host_tpl.py
index 176e871..0a5d0bd 100755
--- a/test/test_service_tpl_on_host_tpl.py
+++ b/test/test_service_tpl_on_host_tpl.py
@@ -26,17 +26,16 @@
 from shinken_test import *
 
 
-class TestConfig(ShinkenTest):
+class TestSrvTplOnHostTpl(ShinkenTest):
     #setUp is in shinken_test
     def setUp(self):
         self.setup_with_file('etc/nagios_service_tpl_on_host_tpl.cfg')
 
     
-    #Look is a service template apply on a host one will
-    #make hosts that inherit from it got such service
-    def test_service_tpl_on_host_tpl(self):
-        
-        #In fac the whole thing will be to have the service defined :)
+    # Look is a service template apply on a host one will
+    # make hosts that inherit from it got such service
+    def test_service_tpl_on_host_tpl(self):        
+        # In fact the whole thing will be to have the service defined :)
         host = self.sched.hosts.find_by_name("test_host_0")
         print "All the test_host_0 services"
         for s in host.services:
@@ -45,6 +44,22 @@ class TestConfig(ShinkenTest):
         svc = self.sched.services.find_srv_by_name_and_hostname("test_host_0", "Service_Template_Description")
         self.assert_(svc is not None)
 
+
+    # And look for multy layer template too. Like a service is apply on
+    # layer1, that use layer2. And srv is apply on layer2
+    def test_service_tpl_on_host_tpl_n_layers(self):
+        
+        host = self.sched.hosts.find_by_name("host_multi_layers")
+        print "All the test_host_0 services"
+        for s in host.services:
+            print s.get_dbg_name()
+
+        svc = self.sched.services.find_srv_by_name_and_hostname("host_multi_layers", "srv_multi_layer")
+        self.assert_(svc is not None)
+
+
+
+
 if __name__ == '__main__':
     unittest.main()
 

-- 
UNNAMED PROJECT



More information about the Pkg-nagios-changes mailing list