Exemple #1
0
 def specmatch(self, context):
     """Return a MonitorAction if this rule can be applies in this context (GraphNodes)
     Note that the GraphNodes that we're given at the present time are typically expected to be
     the Drone node for the node it's running on and the Process node for the process
     to be monitored.
     We return (MonitoringRule.NOMATCH, None) on no match
     """
     # print >> sys.stderr, 'SPECMATCH BEING EVALED:', self._tuplespec, self.__class__
     for tup in self._tuplespec:
         expression = tup[0]
         value = GraphNodeExpression.evaluate(expression, context)
         if value is None:
             # print >> sys.stderr, 'NOMATCH from expression', expression
             return (MonitoringRule.NOMATCH, None)
     # We now have a complete set of values to match against our regexes...
     for tup in self._tuplespec:
         name = tup[0]
         regex = tup[1]
         # print >> sys.stderr, 'TUPLE BEING EVALED:', name, regex.pattern
         val = GraphNodeExpression.evaluate(name, context)
         # print >> sys.stderr, 'EXPRESSION %s => %s' % (name, val)
         if not isinstance(val, (str, unicode)):
             val = str(val)
         if not regex.match(val):
             # print >> sys.stderr, 'NOMATCH from regex [%s] [%s]' % (regex.pattern, val)
             return (MonitoringRule.NOMATCH, None)
     # We now have a matching set of values to give our monitoring constructor
     # print >> sys.stderr, 'CALLING CONSTRUCTACTION:', self._tuplespec
     ret = self.constructaction(context)
     # print >> sys.stderr, 'CONSTRUCTACTION => %s' % str(ret)
     return ret
Exemple #2
0
 def specmatch(self, context):
     '''Return a MonitorAction if this rule can be applies in this context (GraphNodes)
     Note that the GraphNodes that we're given at the present time are typically expected to be
     the Drone node for the node it's running on and the Process node for the process
     to be monitored.
     We return (MonitoringRule.NOMATCH, None) on no match
     '''
     #print >> sys.stderr, 'SPECMATCH BEING EVALED:', self._tuplespec, self.__class__
     for tup in self._tuplespec:
         expression = tup[0]
         value = GraphNodeExpression.evaluate(expression, context)
         if value is None:
             #print >> sys.stderr, 'NOMATCH from expression', expression
             return (MonitoringRule.NOMATCH, None)
     # We now have a complete set of values to match against our regexes...
     for tup in self._tuplespec:
         name = tup[0]
         regex = tup[1]
         #print >> sys.stderr, 'TUPLE BEING EVALED:', name, regex.pattern
         val = GraphNodeExpression.evaluate(name, context)
         #print >> sys.stderr, 'EXPRESSION %s => %s' % (name, val)
         if not isinstance(val, (str, unicode)):
             val = str(val)
         if not regex.match(val):
             #print >> sys.stderr, 'NOMATCH from regex [%s] [%s]' % (regex.pattern, val)
             return (MonitoringRule.NOMATCH, None)
     # We now have a matching set of values to give our monitoring constructor
     #print >> sys.stderr, 'CALLING CONSTRUCTACTION:', self._tuplespec
     ret = self.constructaction(context)
     #print >> sys.stderr, 'CONSTRUCTACTION => %s' % str(ret)
     return ret
 def specmatch(self, context):
     '''Return a MonitorAction if this rule can be applies in this context (GraphNodes)
     Note that the GraphNodes that we're given at the present time are typically expected to be
     the Drone node for the node it's running on and the Process node for the process
     to be monitored.
     We return (MonitoringRule.NOMATCH, None) on no match
     '''
     #print >> sys.stderr, 'SPECMATCH BEING EVALED:', self._tuplespec, self.__class__
     for tup in self._tuplespec:
         expression = tup[0]
         value = GraphNodeExpression.evaluate(expression, context)
         if value is None:
             #print >> sys.stderr, 'NOMATCH from expression %s =>[%s]' % (expression, value)
             return (MonitoringRule.NOMATCH, None)
     # We now have a complete set of values to match against our regexes...
     for tup in self._tuplespec:
         name = tup[0]
         regex = tup[1]
         #CMAdb.log.debug('TUPLE BEING EVALED ("%s","%s")' %  (name, regex.pattern))
         val = str(GraphNodeExpression.evaluate(name, context))
         #CMAdb.log.debug('EXPRESSION %s => %s' % (name, val))
         #print >> sys.stderr, 'value, REGEX BEING EVALED ("%s","%s")' %  (val, regex.pattern)
         if not regex.match(val):
             #print >> sys.stderr, 'NOMATCH from regex [%s] [%s]' % (regex.pattern, val)
             #CMAdb.log.debug('NOMATCH from regex [%s] [%s]:%s'
             #                % (regex.pattern, val, type(val)))
             return (MonitoringRule.NOMATCH, None)
     # We now have a matching set of values to give our monitoring constructor
     #print >> sys.stderr, 'CALLING CONSTRUCTACTION:', self._tuplespec
     ret =  self.constructaction(context)
     #CMAdb.log.debug('GOT MATCH: CONSTRUCTACTION => %s' % str(ret))
     return ret
Exemple #4
0
 def evaluate(self, drone, unusedsrcaddr, jsonobj):
     'Evaluate our rules given the current/changed data'
     unusedsrcaddr = unusedsrcaddr
     drone = drone
     #oldcontext = ExpressionContext((drone,), prefix='JSON_proc_sys')
     newcontext = ExpressionContext((jsonobj, ))
     ruleids = self.rules.keys()
     ruleids.sort()
     for rulekey in ruleids:
         ruleinfo = self.rules[rulekey]
         rule = ruleinfo['rule']
         url = ruleinfo['url']
         ruleid = ruleinfo['id']
         result = GraphNodeExpression.evaluate(rule, newcontext)
         if result is None:
             print >> sys.stderr, 'n/a:  ID %s %s (%s)' % (ruleid, rule,
                                                           self.category)
         elif not isinstance(result, bool):
             print >> sys.stderr, 'Rule id %s %s returned %s (%s)' % (
                 ruleid, rule, result, type(result))
         elif result:
             print >> sys.stderr, 'PASS: ID %s %s (%s)' % (ruleid, rule,
                                                           self.category)
         else:
             print >> sys.stderr, 'FAIL: ID %s %s %s (%s) => %s' % (
                 ruleid, rule, result, self.category, url)
 def constructaction(self, context):
     '''Construct arguments to give MonitorAction constructor
         We can either return a complete match (HIGHPRIOMATCH)
         or an incomplete match (PARTMATCH) if we can't find
         all the parameter values in the nodes we're given
         We can also return NOMATCH if some things don't match
         at all.
     '''
     agentcache = MonitoringRule.compute_available_agents(context)
     agentpath = '%s/%s' % (self.provider, self.rsctype)
     if 'ocf' not in agentcache or agentpath not in agentcache['ocf']:
         #print >> sys.stderr, "OCF agent %s not in agent cache" % agentpath
         return (MonitoringRule.NOMATCH, None)
     #
     missinglist = []
     arglist = {}
     # Figure out what we know how to supply and what we need to ask
     # a human for -- in order to properly monitor this resource
     for name in self.nvpairs:
         if name.startswith('?'):
             optional = True
             exprname = name[1:]
         else:
             optional = False
             exprname=name
         expression = self.nvpairs[name] # NOT exprname
         val = GraphNodeExpression.evaluate(expression, context)
         #print >> sys.stderr, 'CONSTRUCTACTION.eval(%s) => %s' % (expression, val)
         if val is None and not optional:
             missinglist.append(exprname)
         else:
             arglist[exprname] = str(val)
     if len(missinglist) == 0:
         # Hah!  We can automatically monitor it!
         return  (MonitoringRule.HIGHPRIOMATCH
                 ,    {   'monitorclass':    'ocf'
                         ,   'monitortype':  self.rsctype
                         ,   'provider':     self.provider
                         ,   'arglist':      arglist
                     }
                 )
     else:
         # We can monitor it with some more help from a human
         # Better incomplete than a sharp stick in the eye ;-)
         return (MonitoringRule.PARTMATCH
                 ,   {   'monitorclass':     'ocf'
                         ,   'monitortype':  self.rsctype
                         ,   'provider':     self.provider
                         ,   'arglist':      arglist
                     }
                 ,   missinglist
                 )
Exemple #6
0
 def constructaction(self, context):
     '''Construct arguments to give MonitorAction constructor
         We can either return a complete match (HIGHPRIOMATCH)
         or an incomplete match (PARTMATCH) if we can't find
         all the parameter values in the nodes we're given
         We can also return NOMATCH if some things don't match
         at all.
     '''
     agentcache = MonitoringRule.compute_available_agents(context)
     agentpath = '%s/%s' % (self.provider, self.rsctype)
     if 'ocf' not in agentcache or agentpath not in agentcache['ocf']:
         #print >> sys.stderr, "OCF agent %s not in agent cache" % agentpath
         return (MonitoringRule.NOMATCH, None)
     #
     missinglist = []
     arglist = {}
     # Figure out what we know how to supply and what we need to ask
     # a human for -- in order to properly monitor this resource
     for name in self.nvpairs:
         if name.startswith('?'):
             optional = True
             exprname = name[1:]
         else:
             optional = False
             exprname=name
         expression = self.nvpairs[name] # NOT exprname
         val = GraphNodeExpression.evaluate(expression, context)
         #print >> sys.stderr, 'CONSTRUCTACTION.eval(%s) => %s' % (expression, val)
         if val is None and not optional:
             missinglist.append(exprname)
         else:
             arglist[exprname] = str(val)
     if len(missinglist) == 0:
         # Hah!  We can automatically monitor it!
         return  (MonitoringRule.HIGHPRIOMATCH
                 ,    {   'monitorclass':    'ocf'
                         ,   'monitortype':  self.rsctype
                         ,   'provider':     self.provider
                         ,   'arglist':      arglist
                     }
                 )
     else:
         # We can monitor it with some more help from a human
         # Better incomplete than a sharp stick in the eye ;-)
         return (MonitoringRule.PARTMATCH
                 ,   {   'monitorclass':     'ocf'
                         ,   'monitortype':  self.rsctype
                         ,   'provider':     self.provider
                         ,   'arglist':      arglist
                     }
                 ,   missinglist
                 )
 def evaluate(_unused_drone, _unusedsrcaddr, wholejsonobj, ruleobj,
              description):
     '''Evaluate our rules given the current/changed data.
     '''
     jsonobj = wholejsonobj['data']
     #oldcontext = ExpressionContext((drone,), prefix='JSON_proc_sys')
     newcontext = ExpressionContext((jsonobj, ))
     if hasattr(ruleobj, '_jsonobj'):
         ruleobj = getattr(ruleobj, '_jsonobj')
     ruleids = ruleobj.keys()
     ruleids.sort()
     statuses = {
         'pass': [],
         'fail': [],
         'ignore': [],
         'NA': [],
         'score': 0.0
     }
     if len(ruleids) < 1:
         return statuses
     print >> sys.stderr, '\n==== Evaluating %d Best Practice rules on "%s" [%s]' \
         % (len(ruleids)-1, wholejsonobj['description'], description)
     for ruleid in ruleids:
         ruleinfo = ruleobj[ruleid]
         rule = ruleinfo['rule']
         rulecategory = ruleinfo['category']
         result = GraphNodeExpression.evaluate(rule, newcontext)
         if result is None:
             print >> sys.stderr, 'n/a:    %s ID %s %s' \
                 % (rulecategory, ruleid, rule)
             statuses['NA'].append(ruleid)
         elif not isinstance(result, bool):
             print >> sys.stderr, 'Rule id %s %s returned %s (%s)' \
                 % (ruleid, rule, result, type(result))
             statuses['fail'].append(ruleid)
         elif result:
             if rule.startswith('IGNORE'):
                 if not rulecategory.lower().startswith('comment'):
                     statuses['ignore'].append(ruleid)
                     print >> sys.stderr, 'IGNORE: %s ID %s %s' % \
                         (rulecategory, ruleid, rule)
             else:
                 statuses['pass'].append(ruleid)
                 print >> sys.stderr, 'PASS:   %s ID %s %s' \
                     % (rulecategory, ruleid, rule)
         else:
             print >> sys.stderr, 'FAIL:   %s ID %s %s'\
                 % (rulecategory, ruleid, rule)
             statuses['fail'].append(ruleid)
     return statuses
 def evaluate(_unused_drone, _unusedsrcaddr, wholejsonobj, ruleobj, description):
     '''Evaluate our rules given the current/changed data.
     '''
     jsonobj = wholejsonobj['data']
     #oldcontext = ExpressionContext((drone,), prefix='JSON_proc_sys')
     newcontext = ExpressionContext((jsonobj,))
     if hasattr(ruleobj, '_jsonobj'):
         ruleobj = getattr(ruleobj, '_jsonobj')
     ruleids = ruleobj.keys()
     ruleids.sort()
     statuses = {'pass': [], 'fail': [], 'ignore': [], 'NA': [], 'score': 0.0}
     if len(ruleids) < 1:
         return statuses
     print >> sys.stderr, '\n==== Evaluating %d Best Practice rules on "%s" [%s]' \
         % (len(ruleids)-1, wholejsonobj['description'], description)
     for ruleid in ruleids:
         ruleinfo = ruleobj[ruleid]
         rule = ruleinfo['rule']
         rulecategory = ruleinfo['category']
         result = GraphNodeExpression.evaluate(rule, newcontext)
         if result is None:
             print >> sys.stderr, 'n/a:    %s ID %s %s' \
                 % (rulecategory, ruleid, rule)
             statuses['NA'].append(ruleid)
         elif not isinstance(result, bool):
             print >> sys.stderr, 'Rule id %s %s returned %s (%s)' \
                 % (ruleid, rule, result, type(result))
             statuses['fail'].append(ruleid)
         elif result:
             if rule.startswith('IGNORE'):
                 if not rulecategory.lower().startswith('comment'):
                     statuses['ignore'].append(ruleid)
                     print >> sys.stderr, 'IGNORE: %s ID %s %s' % \
                         (rulecategory, ruleid, rule)
             else:
                 statuses['pass'].append(ruleid)
                 print >> sys.stderr, 'PASS:   %s ID %s %s' \
                     % (rulecategory, ruleid, rule)
         else:
             print >> sys.stderr, 'FAIL:   %s ID %s %s'\
                 % (rulecategory, ruleid, rule)
             statuses['fail'].append(ruleid)
     return statuses
 def evaluate(_unused_drone, _unusedsrcaddr, wholejsonobj, ruleobj, description):
     """Evaluate our rules given the current/changed data.
     """
     jsonobj = wholejsonobj["data"]
     # oldcontext = ExpressionContext((drone,), prefix='JSON_proc_sys')
     newcontext = ExpressionContext((jsonobj,))
     if hasattr(ruleobj, "_jsonobj"):
         ruleobj = getattr(ruleobj, "_jsonobj")
     ruleids = ruleobj.keys()
     ruleids.sort()
     statuses = {"pass": [], "fail": [], "ignore": [], "NA": [], "score": 0.0}
     if len(ruleids) < 1:
         return statuses
     print >> sys.stderr, '\n==== Evaluating %d Best Practice rules on "%s" [%s]' % (
         len(ruleids) - 1,
         wholejsonobj["description"],
         description,
     )
     for ruleid in ruleids:
         ruleinfo = ruleobj[ruleid]
         rule = ruleinfo["rule"]
         rulecategory = ruleinfo["category"]
         result = GraphNodeExpression.evaluate(rule, newcontext)
         if result is None:
             print >> sys.stderr, "n/a:    %s ID %s %s" % (rulecategory, ruleid, rule)
             statuses["NA"].append(ruleid)
         elif not isinstance(result, bool):
             print >> sys.stderr, "Rule id %s %s returned %s (%s)" % (ruleid, rule, result, type(result))
             statuses["fail"].append(ruleid)
         elif result:
             if rule.startswith("IGNORE"):
                 if not rulecategory.lower().startswith("comment"):
                     statuses["ignore"].append(ruleid)
                     print >> sys.stderr, "IGNORE: %s ID %s %s" % (rulecategory, ruleid, rule)
             else:
                 statuses["pass"].append(ruleid)
                 print >> sys.stderr, "PASS:   %s ID %s %s" % (rulecategory, ruleid, rule)
         else:
             print >> sys.stderr, "FAIL:   %s ID %s %s" % (rulecategory, ruleid, rule)
             statuses["fail"].append(ruleid)
     return statuses
 def evaluate(drone, _unusedsrcaddr, jsonobj, ruleobj):
     '''Evaluate our rules given the current/changed data.
     '''
     drone = drone
     #oldcontext = ExpressionContext((drone,), prefix='JSON_proc_sys')
     newcontext = ExpressionContext((jsonobj,))
     if hasattr(ruleobj, '_jsonobj'):
         ruleobj = getattr(ruleobj, '_jsonobj')
     ruleids = ruleobj.keys()
     ruleids.sort()
     statuses = {'pass': [], 'fail': [], 'ignore': [], 'NA': []}
     for ruleid in ruleids:
         ruleinfo = ruleobj[ruleid]
         rule = ruleinfo['rule']
         rulecategory = ruleinfo['category']
         result = GraphNodeExpression.evaluate(rule, newcontext)
         if result is None:
             print >> sys.stderr, 'n/a:    %s ID %s %s' % (rulecategory, ruleid, rule)
             statuses['NA'].append(ruleid)
         elif not isinstance(result, bool):
             print >> sys.stderr, 'Rule id %s %s returned %s (%s)' % (ruleid
             ,       rule, result, type(result))
             statuses['fail'].append(ruleid)
         elif result:
             if rule.startswith('IGNORE'):
                 if not rulecategory.lower().startswith('comment'):
                     statuses['ignore'].append(ruleid)
                     print >> sys.stderr, 'IGNORE: %s ID %s %s' % \
                         (rulecategory, ruleid, rule)
             else:
                 statuses['pass'].append(ruleid)
                 print >> sys.stderr, 'PASS:   %s ID %s %s' % (rulecategory, ruleid, rule)
         else:
             print >> sys.stderr, 'FAIL:   %s ID %s %s' % (rulecategory
             ,       ruleid, rule)
             statuses['fail'].append(ruleid)
     return statuses
Exemple #11
0
 def evaluate(self, drone, unusedsrcaddr, jsonobj):
     'Evaluate our rules given the current/changed data'
     unusedsrcaddr = unusedsrcaddr
     drone = drone
     #oldcontext = ExpressionContext((drone,), prefix='JSON_proc_sys')
     newcontext = ExpressionContext((jsonobj,))
     ruleids = self.rules.keys()
     ruleids.sort()
     for rulekey in ruleids:
         ruleinfo = self.rules[rulekey]
         rule = ruleinfo['rule']
         url = ruleinfo['url']
         ruleid = ruleinfo['id']
         result = GraphNodeExpression.evaluate(rule, newcontext)
         if result is None:
             print >> sys.stderr, 'n/a:  ID %s %s (%s)' % (ruleid, rule, self.category)
         elif not isinstance(result, bool):
             print >> sys.stderr, 'Rule id %s %s returned %s (%s)' % (ruleid
             ,       rule, result, type(result))
         elif result:
             print >> sys.stderr, 'PASS: ID %s %s (%s)' % (ruleid, rule, self.category)
         else:
             print >> sys.stderr, 'FAIL: ID %s %s %s (%s) => %s' % (ruleid
             ,       rule, result, self.category, url)
Exemple #12
0
 def constructaction(self, context):
     """Construct arguments to give MonitorAction constructor
         We can either return a complete match (HIGHPRIOMATCH)
         or an incomplete match (PARTMATCH) if we can't find
         all the parameter values in the nodes we're given
         We can also return NOMATCH if some things don't match
         at all.
     """
     agentcache = MonitoringRule.compute_available_agents(context)
     if "nagios" in agentcache and self.rsctype not in agentcache["nagios"]:
         return (MonitoringRule.NOMATCH, None)
     #
     missinglist = []
     arglist = {}
     argv = []
     if self.initargs:
         argv = self.initargs
     if self.argv:
         argv.extend(self.argv)
     final_argv = []
     # Figure out what we know how to supply and what we need to ask
     # a human for -- in order to properly monitor this resource
     for name in self.nvpairs:
         # This code is very similar to the OCF code - but not quite the same...
         if name.startswith("?"):
             optional = True
             exprname = name[1:]
         else:
             optional = False
             exprname = name
         expression = self.nvpairs[exprname]
         # print >> sys.stderr, 'exprname is %s, expression is %s' % (exprname,expression)
         val = GraphNodeExpression.evaluate(expression, context)
         # print >> sys.stderr, 'CONSTRUCTACTION.eval(%s) => %s' % (expression, val)
         if val is None:
             if not optional:
                 missinglist.append(exprname)
             else:
                 continue
         if exprname.startswith("-"):
             argv.append(exprname)
             argv.append(str(val))
         elif exprname == "__ARGV__":
             final_argv.append(str(val))
         else:
             arglist[exprname] = str(val)
     argv.extend(final_argv)
     if len(arglist) == 0:
         arglist = None
     if not argv:
         argv = None
     if len(missinglist) == 0:
         # Hah!  We can automatically monitor it!
         return (
             self.prio,
             {
                 "monitorclass": "nagios",
                 "monitortype": self.rsctype,
                 "provider": None,
                 "argv": argv,
                 "arglist": arglist,
             },
         )
     else:
         # We can monitor it with some more help from a human
         # Better incomplete than a sharp stick in the eye ;-)
         return (
             MonitoringRule.PARTMATCH,
             {
                 "monitorclass": "nagios",
                 "monitortype": self.rsctype,
                 "provider": None,
                 "argv": argv,
                 "arglist": arglist,
             },
             missinglist,
         )
Exemple #13
0
 def constructaction(self, context):
     '''Construct arguments to give MonitorAction constructor
         We can either return a complete match (HIGHPRIOMATCH)
         or an incomplete match (PARTMATCH) if we can't find
         all the parameter values in the nodes we're given
         We can also return NOMATCH if some things don't match
         at all.
     '''
     agentcache = MonitoringRule.compute_available_agents(context)
     if 'nagios' in agentcache and self.rsctype not in agentcache['nagios']:
         return (MonitoringRule.NOMATCH, None)
     #
     missinglist = []
     arglist = {}
     argv = []
     if self.initargs:
         argv = self.initargs
     if self.argv:
         argv.extend(self.argv)
     final_argv = []
     # Figure out what we know how to supply and what we need to ask
     # a human for -- in order to properly monitor this resource
     for name in self.nvpairs:
         # This code is very similar to the OCF code - but not quite the same...
         if name.startswith('?'):
             optional = True
             exprname = name[1:]
         else:
             optional = False
             exprname = name
         expression = self.nvpairs[exprname]
         #print >> sys.stderr, 'exprname is %s, expression is %s' % (exprname,expression)
         val = GraphNodeExpression.evaluate(expression, context)
         #print >> sys.stderr, 'CONSTRUCTACTION.eval(%s) => %s' % (expression, val)
         if val is None:
             if not optional:
                 missinglist.append(exprname)
             else:
                 continue
         if exprname.startswith('-'):
             argv.append(exprname)
             argv.append(str(val))
         elif exprname == '__ARGV__':
             final_argv.append(str(val))
         else:
             arglist[exprname] = str(val)
     argv.extend(final_argv)
     if len(arglist) == 0:
         arglist = None
     if not argv:
         argv = None
     if len(missinglist) == 0:
         # Hah!  We can automatically monitor it!
         return (self.prio, {
             'monitorclass': 'nagios',
             'monitortype': self.rsctype,
             'provider': None,
             'argv': argv,
             'arglist': arglist
         })
     else:
         # We can monitor it with some more help from a human
         # Better incomplete than a sharp stick in the eye ;-)
         return (MonitoringRule.PARTMATCH, {
             'monitorclass': 'nagios',
             'monitortype': self.rsctype,
             'provider': None,
             'argv': argv,
             'arglist': arglist
         }, missinglist)
Exemple #14
0
                assert isinstance(testresult[1]['arglist'], dict)
            elif testresult[1]['monitorclass'] == 'lsb':
                assert testresult[1]['provider'] is None
                assert testresult[1]['arglist'] is None
                assert isinstance(testresult[1]['rscname'], str)
            if testresult[0] == MonitoringRule.PARTMATCH:
                assert testresult[1]['monitorclass'] in ('ocf', )
                assert len(testresult) == 3
                assert isinstance(testresult[2],
                                  (list, tuple))  # List of missing fields...
                assert len(testresult[2]) > 0

        print "Test %s passes [%s]." % (count, testresult)

    print 'Documentation of functions available for use in match expressions:'
    longest = 0
    for (funcname, description) in GraphNodeExpression.FunctionDescriptions():
        if len(funcname) > longest:
            longest = len(funcname)
    fmt = '%%%ds: %%s' % longest
    pad = (longest + 2) * ' '
    fmt2 = pad + '%s'

    for (funcname, description) in GraphNodeExpression.FunctionDescriptions():
        descriptions = description.split('\n')
        print fmt % (funcname, descriptions[0])
        for descr in descriptions[1:]:
            print fmt2 % descr

    MonitoringRule.load_tree("monrules")
 def constructaction(self, context):
     '''Construct arguments to give MonitorAction constructor
         We can either return a complete match (HIGHPRIOMATCH)
         or an incomplete match (PARTMATCH) if we can't find
         all the parameter values in the nodes we're given
         We can also return NOMATCH if some things don't match
         at all.
     '''
     agentcache = MonitoringRule.compute_available_agents(context)
     if 'nagios' not in agentcache or str(self.rsctype) not in agentcache['nagios']:
         #CMAdb.log.debug('CONSTRUCTACTION.NOMATCH(%s) %s' % (self.rsctype, type(self.rsctype)))
         #CMAdb.log.debug('AGENTCACHE: %s' % (str(agentcache)))
         return (MonitoringRule.NOMATCH, None)
     #
     missinglist = []
     arglist = {}
     argv = []
     if self.initargs:
         argv = self.initargs
     if self.argv:
         argv.extend(self.argv)
     final_argv = []
     # Figure out what we know how to supply and what we need to ask
     # a human for -- in order to properly monitor this resource
     for name in self.nvpairs:
         # This code is very similar to the OCF code - but not quite the same...
         if name.startswith('?'):
             optional = True
             exprname = name[1:]
         else:
             optional = False
             exprname=name
         expression = self.nvpairs[exprname]
         #CMAdb.log.debug('exprname is %s, expression is %s' % (exprname,expression))
         val = GraphNodeExpression.evaluate(expression, context)
         #CMAdb.log.debug('CONSTRUCTACTION.eval(%s) => %s' % (expression, val))
         if val is None:
             if not optional:
                 missinglist.append(exprname)
             else:
                 continue
         if exprname.startswith('-'):
             argv.append(exprname)
             argv.append(str(val))
         elif exprname == '__ARGV__':
             final_argv.append(str(val))
         else:
             arglist[exprname] = str(val)
     argv.extend(final_argv)
     if len(arglist) == 0:
         arglist = None
     if not argv:
         argv = None
     if len(missinglist) == 0:
         # Hah!  We can automatically monitor it!
         return  (self.prio
                 ,    {   'monitorclass':    'nagios'
                         ,   'monitortype':  self.rsctype
                         ,   'provider':     None
                         ,   'argv':         argv
                         ,   'arglist':      arglist
                     }
                 )
     else:
         # We can monitor it with some more help from a human
         # Better incomplete than a sharp stick in the eye ;-)
         return (MonitoringRule.PARTMATCH
                 ,   {   'monitorclass':     'nagios'
                         ,   'monitortype':  self.rsctype
                         ,   'provider':     None
                         ,   'argv':         argv
                         ,   'arglist':      arglist
                     }
                 ,   missinglist
                 )