예제 #1
0
class Serviceescalation(Item):
    id = 1  # zero is always special in database, so we do not take risk here
    my_type = 'serviceescalation'

    properties = Item.properties.copy()
    properties.update({
        'host_name':
        StringProp(),
        'hostgroup_name':
        StringProp(),
        'service_description':
        StringProp(),
        'first_notification':
        IntegerProp(),
        'last_notification':
        IntegerProp(),
        'notification_interval':
        IntegerProp(default=30),  # like Nagios value
        'escalation_period':
        StringProp(default=''),
        'escalation_options':
        ListProp(default=['d', 'u', 'r', 'w', 'c'], split_on_coma=True),
        'contacts':
        StringProp(),
        'contact_groups':
        StringProp(),
        'first_notification_time':
        IntegerProp(),
        'last_notification_time':
        IntegerProp(),
    })

    # For debugging purpose only (nice name)
    def get_name(self):
        return ''
예제 #2
0
파일: pollerlink.py 프로젝트: zxahu/shinken
class PollerLink(SatelliteLink):
    """This class is the link between Arbiter and Poller. With it, arbiter
    can see if a poller is alive, and can send it new configuration

    """

    id = 0
    my_type = 'poller'
    # To_send: send or not to satellite conf
    properties = SatelliteLink.properties.copy()
    properties.update({
        'poller_name':
        StringProp(fill_brok=['full_status'], to_send=True),
        'port':
        IntegerProp(default=7771, fill_brok=['full_status']),
        'passive':
        BoolProp(default='0', fill_brok=['full_status'], to_send=True),
        'min_workers':
        IntegerProp(default='0', fill_brok=['full_status'], to_send=True),
        'max_workers':
        IntegerProp(default='30', fill_brok=['full_status'], to_send=True),
        'processes_by_worker':
        IntegerProp(default='256', fill_brok=['full_status'], to_send=True),
        'poller_tags':
        ListProp(default='None', to_send=True),
    })

    def get_name(self):
        return self.poller_name

    def register_to_my_realm(self):
        self.realm.pollers.append(self)
예제 #3
0
class ReactionnerLink(SatelliteLink):
    """Please Add a Docstring to describe the class here"""

    id = 0
    my_type = 'reactionner'
    properties = SatelliteLink.properties.copy()
    properties.update({
        'reactionner_name':
        StringProp(fill_brok=['full_status'], to_send=True),
        'port':
        IntegerProp(default=7769, fill_brok=['full_status']),
        'min_workers':
        IntegerProp(default=1, fill_brok=['full_status'], to_send=True),
        'max_workers':
        IntegerProp(default=30, fill_brok=['full_status'], to_send=True),
        'processes_by_worker':
        IntegerProp(default=256, fill_brok=['full_status'], to_send=True),
        'reactionner_tags':
        ListProp(default=['None'], to_send=True),
    })

    def get_name(self):
        return self.reactionner_name

    def register_to_my_realm(self):
        self.realm.reactionners.append(self)
예제 #4
0
class ReactionnerLink(SatelliteLink):
    id = 0
    my_type = 'reactionner'
    properties = SatelliteLink.properties.copy()
    properties.update({
        'reactionner_name':
        StringProp(fill_brok=['full_status'], to_send=True),
        'port':
        IntegerProp(default='7769', fill_brok=['full_status']),
        'passive':
        BoolProp(default='0', fill_brok=['full_status'], to_send=True),
        'min_workers':
        IntegerProp(default='1', fill_brok=['full_status'], to_send=True),
        'max_workers':
        IntegerProp(default='30', fill_brok=['full_status'], to_send=True),
        'processes_by_worker':
        IntegerProp(default='256', fill_brok=['full_status'], to_send=True),
        'reactionner_tags':
        ListProp(default='None', to_send=True),
    })

    def get_name(self):
        return self.reactionner_name

    def register_to_my_realm(self):
        self.realm.reactionners.append(self)
예제 #5
0
class Contactgroup(Itemgroup):
    id = 1
    my_type = 'contactgroup'

    properties = Itemgroup.properties.copy()
    properties.update({
        'id':                   IntegerProp(default=0, fill_brok=['full_status']),
        'contactgroup_name':    StringProp(fill_brok=['full_status']),
        'alias':                StringProp(fill_brok=['full_status']),
    })

    macros = {
        'CONTACTGROUPALIAS': 'alias',
        'CONTACTGROUPMEMBERS': 'get_members'
    }

    def get_contacts(self):
        return getattr(self, 'members', '')

    def get_name(self):
        return getattr(self, 'contactgroup_name', 'UNNAMED-CONTACTGROUP')

    def get_contactgroup_members(self):
        if self.has('contactgroup_members'):
            return self.contactgroup_members.split(',')
        else:
            return []

    # We fillfull properties with template ones if need
    # Because hostgroup we call may not have it's members
    # we call get_hosts_by_explosion on it
    def get_contacts_by_explosion(self, contactgroups):
        # First we tag the hg so it will not be explode
        # if a son of it already call it
        self.already_explode = True

        # Now the recursive part
        # rec_tag is set to False every CG we explode
        # so if True here, it must be a loop in HG
        # calls... not GOOD!
        if self.rec_tag:
            logger.error("[contactgroup::%s] got a loop in contactgroup definition", self.get_name())
            if self.has('members'):
                return self.members
            else:
                return ''
        # Ok, not a loop, we tag it and continue
        self.rec_tag = True

        cg_mbrs = self.get_contactgroup_members()
        for cg_mbr in cg_mbrs:
            cg = contactgroups.find_by_name(cg_mbr.strip())
            if cg is not None:
                value = cg.get_contacts_by_explosion(contactgroups)
                if value is not None:
                    self.add_string_member(value)
        if self.has('members'):
            return self.members
        else:
            return ''
예제 #6
0
class SchedulerLink(SatelliteLink):
    """Please Add a Docstring to describe the class here"""

    id = 0

    # Ok we lie a little here because we are a mere link in fact
    my_type = 'scheduler'

    properties = SatelliteLink.properties.copy()
    properties.update({
        'scheduler_name':
        StringProp(fill_brok=['full_status']),
        'port':
        IntegerProp(default=7768, fill_brok=['full_status']),
        'weight':
        IntegerProp(default=1, fill_brok=['full_status']),
        'skip_initial_broks':
        BoolProp(default=False, fill_brok=['full_status']),
        'accept_passive_unknown_check_results':
        BoolProp(default=False, fill_brok=['full_status']),
        'harakiri_threshold':
        StringProp(default=None, fill_brok=['full_status'], to_send=True),
    })

    running_properties = SatelliteLink.running_properties.copy()
    running_properties.update({
        'conf': StringProp(default=None),
        'need_conf': StringProp(default=True),
        'external_commands': StringProp(default=[]),
        'push_flavor': IntegerProp(default=0),
    })

    def get_name(self):
        return self.scheduler_name

    def run_external_commands(self, commands):
        if self.con is None:
            self.create_connection()
        if not self.alive:
            return None
        logger.debug("[SchedulerLink] Sending %d commands", len(commands))
        try:
            self.con.post('run_external_commands', {'cmds': commands})
        except HTTPExceptions, exp:
            self.con = None
            logger.debug(exp)
            return False
예제 #7
0
파일: realm.py 프로젝트: popomomi/shinken-1
class Realm(Itemgroup):
    id = 1  # zero is always a little bit special... like in database
    my_type = 'realm'

    properties = Itemgroup.properties.copy()
    properties.update({
        'id':            IntegerProp(default=0, fill_brok=['full_status']),
        'realm_name':    StringProp(fill_brok=['full_status']),
        'realm_members': StringProp(default=''), # No status_broker_name because it put hosts, not host_name
        'higher_realms': StringProp(default=''),
        'default':       BoolProp(default='0'),
        'broker_complete_links':       BoolProp(default='0'),
        #'alias': {'required':  True, 'fill_brok': ['full_status']},
        #'notes': {'required': False, 'default':'', 'fill_brok': ['full_status']},
        #'notes_url': {'required': False, 'default':'', 'fill_brok': ['full_status']},
        #'action_url': {'required': False, 'default':'', 'fill_brok': ['full_status']},
    })

    running_properties = Item.running_properties.copy()
    running_properties.update({
            'serialized_confs': StringProp(default={}),
        })

    macros = {
        'REALMNAME': 'realm_name',
        'REALMMEMBERS': 'members',
    }


    def get_name(self):
        return self.realm_name


    def get_realms(self):
        return self.realm_members


    def add_string_member(self, member):
        self.realm_members += ',' + member


    def get_realm_members(self):
        if self.has('realm_members'):
            return [r.strip() for r in self.realm_members.split(',')]
        else:
            return []

    # Use to make python properties
    # TODO: change itemgroup function pythonize?
    def pythonize(self):
        cls = self.__class__
        for prop, tab in cls.properties.items():
            try:
                old_val = getattr(self, prop)
                new_val = tab.pythonize(old_val)
                #print "Changing ", old_val, "by", new_val
                setattr(self, prop, new_val)
            except AttributeError, exp:
                pass  # Will be catch at the is_correct moment
예제 #8
0
class SchedulerLink(SatelliteLink):
    """Please Add a Docstring to describe the class here"""

    id = 0

    # Ok we lie a little here because we are a mere link in fact
    my_type = 'scheduler'

    properties = SatelliteLink.properties.copy()
    properties.update({
        'scheduler_name':
        StringProp(fill_brok=['full_status']),
        'port':
        IntegerProp(default='7768', fill_brok=['full_status']),
        'weight':
        IntegerProp(default='1', fill_brok=['full_status']),
        'skip_initial_broks':
        BoolProp(default='0', fill_brok=['full_status']),
    })

    running_properties = SatelliteLink.running_properties.copy()
    running_properties.update({
        'conf': StringProp(default=None),
        'need_conf': StringProp(default=True),
        'external_commands': StringProp(default=[]),
        'push_flavor': IntegerProp(default=0),
    })

    def get_name(self):
        return self.scheduler_name

    def run_external_commands(self, commands):
        if self.con is None:
            self.create_connection()
        if not self.alive:
            return None
        logger.debug("[SchedulerLink] Sending %d commands" % len(commands))
        try:
            self.con.run_external_commands(commands)
        except Pyro.errors.URIError, exp:
            self.con = None
            return False
        except Pyro.errors.ProtocolError, exp:
            self.con = None
            return False
예제 #9
0
class ArbiterLink(SatelliteLink):
    id = 0
    my_type = 'arbiter'
    properties = SatelliteLink.properties.copy()
    properties.update({
        'arbiter_name':    StringProp(),
        'host_name':       StringProp(default=socket.gethostname()),
        'port':            IntegerProp(default=7770),
    })

    def get_name(self):
        return self.arbiter_name

    def get_config(self):
        return self.con.get('get_config')

    # Check is required when prop are set:
    # contacts OR contactgroups is need
    def is_correct(self):
        state = True
        cls = self.__class__

        for prop, entry in cls.properties.items():
            if not hasattr(self, prop) and entry.required:
                # This should raise an error afterwards?
                # Log the issue
                logger.warning("%s arbiterlink is missing %s property", self.get_name(), prop)
                self.debug("%s arbiterlink is missing %s property" % (self.get_name(), prop))
                state = False  # Bad boy...
        return state


    # Look for ourself as an arbiter. If we search for a specific arbiter name, go forit
    # If not look be our fqdn name, or if not, our hostname
    def is_me(self, lookup_name):
        logger.info("And arbiter is launched with the hostname:%s from an arbiter point of view of addr:%s", self.host_name, socket.getfqdn())
        if lookup_name:
            return lookup_name == self.get_name()
        else:
            return self.host_name == socket.getfqdn() or self.host_name == socket.gethostname()


    def give_satellite_cfg(self):
        return {'port': self.port, 'address': self.address, 'name': self.arbiter_name, 'use_ssl':self.use_ssl, 'hard_ssl_name_check':self.hard_ssl_name_check}


    def do_not_run(self):
        if self.con is None:
            self.create_connection()
        try:
            self.con.get('do_not_run')
            return True
        except HTTPExceptions, exp:
            self.con = None
            return False
예제 #10
0
class Contact(Item):
    id = 1  # zero is always special in database, so we do not take risk here
    my_type = 'contact'

    properties = Item.properties.copy()
    properties.update({
        'contact_name':     StringProp(fill_brok=['full_status']),
        'alias':            StringProp(default='none', fill_brok=['full_status']),
        'contactgroups':    ListProp(default=[], fill_brok=['full_status']),
        'host_notifications_enabled': BoolProp(default=True, fill_brok=['full_status']),
        'service_notifications_enabled': BoolProp(default=True, fill_brok=['full_status']),
        'host_notification_period': StringProp(fill_brok=['full_status']),
        'service_notification_period': StringProp(fill_brok=['full_status']),
        'host_notification_options': ListProp(default=[''], fill_brok=['full_status'],
                                              split_on_coma=True),
        'service_notification_options': ListProp(default=[''], fill_brok=['full_status'],
                                                 split_on_coma=True),
        # To be consistent with notificationway object attributes
        'host_notification_commands': ListProp(fill_brok=['full_status']),
        'service_notification_commands': ListProp(fill_brok=['full_status']),
        'min_business_impact':    IntegerProp(default=0, fill_brok=['full_status']),
        'email':            StringProp(default='none', fill_brok=['full_status']),
        'pager':            StringProp(default='none', fill_brok=['full_status']),
        'address1':         StringProp(default='none', fill_brok=['full_status']),
        'address2':         StringProp(default='none', fill_brok=['full_status']),
        'address3':        StringProp(default='none', fill_brok=['full_status']),
        'address4':         StringProp(default='none', fill_brok=['full_status']),
        'address5':         StringProp(default='none', fill_brok=['full_status']),
        'address6':         StringProp(default='none', fill_brok=['full_status']),
        'can_submit_commands': BoolProp(default=False, fill_brok=['full_status']),
        'is_admin':         BoolProp(default=False, fill_brok=['full_status']),
        'expert':           BoolProp(default=False, fill_brok=['full_status']),
        'retain_status_information': BoolProp(default=True, fill_brok=['full_status']),
        'notificationways': ListProp(default=[], fill_brok=['full_status']),
        'password':        StringProp(default='NOPASSWORDSET', fill_brok=['full_status']),
    })

    running_properties = Item.running_properties.copy()
    running_properties.update({
        'modified_attributes': IntegerProp(default=0L, fill_brok=['full_status'], retention=True),
        'downtimes': StringProp(default=[], fill_brok=['full_status'], retention=True),
    })
예제 #11
0
class Hostescalation(Item):
    id = 1  # zero is always special in database, so we do not take risk here
    my_type = 'hostescalation'

    properties = Item.properties.copy()
    properties.update({
        'host_name':             StringProp(),
        'hostgroup_name':        StringProp(),
        'first_notification':    IntegerProp(),
        'last_notification':     IntegerProp(),
        'notification_interval': IntegerProp(default='30'), # like Nagios value
        'escalation_period':     StringProp(default=''),
        'escalation_options':    ListProp(default='d,u,r,w,c'),
        'contacts':              StringProp(),
        'contact_groups':        StringProp(),
    })

    # For debugging purpose only (nice name)
    def get_name(self):
        return ''
예제 #12
0
class BrokerLink(SatelliteLink):
    """TODO: Add some comment about this class for the doc"""
    id = 0
    my_type = 'broker'
    properties = SatelliteLink.properties.copy()
    properties.update({
        'broker_name':
        StringProp(fill_brok=['full_status'], to_send=True),
        'port':
        IntegerProp(default=7772, fill_brok=['full_status']),
        'broks_batch':
        IntegerProp(default=0, fill_brok=['full_status'], to_send=True),
        'harakiri_threshold':
        StringProp(default=None, fill_brok=['full_status'], to_send=True),
    })

    def get_name(self):
        return self.broker_name

    def register_to_my_realm(self):
        self.realm.brokers.append(self)
class Businessimpactmodulation(Item):
    id = 1  # zero is always special in database, so we do not take risk here
    my_type = 'businessimpactmodulation'

    properties = Item.properties.copy()
    properties.update({'business_impact_modulation_name': StringProp(),
                       'business_impact':                 IntegerProp(),
                       'modulation_period':               StringProp(default=''),
                       })

    # For debugging purpose only (nice name)
    def get_name(self):
        return self.business_impact_modulation_name
예제 #14
0
class SchedulerLink(SatelliteLink):
    id = 0

    #Ok we lie a little here because we are a mere link in fact
    my_type = 'scheduler'

    properties = SatelliteLink.properties.copy()
    properties.update({
        'scheduler_name':   StringProp(fill_brok=['full_status']),
        'port':             IntegerProp(default='7768', fill_brok=['full_status']),
        'weight':           IntegerProp(default='1', fill_brok=['full_status']),
    })
    
    running_properties = SatelliteLink.running_properties.copy() 
    running_properties.update({
        'conf':      StringProp(default=None),
        'need_conf': StringProp(default=True),
    })


    def get_name(self):
        return self.scheduler_name


    def run_external_command(self, command):
        if self.con is None:
            self.create_connexion()
        if not self.alive:
            return None
        print "Send command", command
        try:
            self.con.run_external_command(command)
        except Pyro.errors.URIError , exp:
            self.con = None
            return False
        except Pyro.errors.ProtocolError , exp:
            self.con = None
            return False
예제 #15
0
class Poller(Satellite):
    do_checks = True  # I do checks
    do_actions = False  # but no actions

    properties = Satellite.properties.copy()
    properties.update({
        'pidfile': PathProp(default='pollerd.pid'),
        'port': IntegerProp(default='7771'),
        'local_log': PathProp(default='pollerd.log'),
    })

    def __init__(self, config_file, is_daemon, do_replace, debug, debug_file):
        super(Poller, self).__init__('poller', config_file, is_daemon,
                                     do_replace, debug, debug_file)
예제 #16
0
class Hostescalation(Item):
    id = 1  #0 is always special in database, so we do not take risk here
    my_type = 'hostescalation'

    properties = {
        'host_name': StringProp(),
        'hostgroup_name': StringProp(),
        'first_notification': IntegerProp(),
        'last_notification': IntegerProp(),
        'notification_interval': IntegerProp(),
        'escalation_period': StringProp(default=''),
        'escalation_options': ListProp(default='d,u,r,w,c'),
        'contacts': StringProp(),
        'contact_groups': StringProp(),
    }

    running_properties = {}

    macros = {}

    #For debugging purpose only (nice name)
    def get_name(self):
        return ''
예제 #17
0
class PollerLink(SatelliteLink):
    id = 0
    my_type = 'poller'
    #To_send : send or not to satellite conf
    properties = SatelliteLink.properties.copy()
    properties.update({
        'poller_name':  StringProp(fill_brok=['full_status'], to_send=True),
        'port':         IntegerProp(default=7771, fill_brok=['full_status']),
        'passive' :     BoolProp(default='0', fill_brok=['full_status'], to_send=True),
        'min_workers':  IntegerProp(default='1', fill_brok=['full_status'], to_send=True),
        'max_workers':  IntegerProp(default='30', fill_brok=['full_status'], to_send=True),
        'processes_by_worker': IntegerProp(default='256', fill_brok=['full_status'], to_send=True),
        'poller_tags':  ListProp(default='None', to_send=True),
    })

    def get_name(self):
        return self.poller_name


    def register_to_my_realm(self):
        self.realm.pollers.append(self)
        if self.poller_tags != []:
            print "I %s manage tags : %s " % (self.get_name(), self.poller_tags)
예제 #18
0
class ArbiterLink(SatelliteLink):
    id = 0
    my_type = 'arbiter'
    properties = SatelliteLink.properties.copy()
    properties.update({
        'arbiter_name': StringProp(),
        'host_name': StringProp(default=socket.gethostname()),
        'port': IntegerProp(default='7770'),
    })

    def get_name(self):
        return self.arbiter_name

    #Check is required prop are set:
    #contacts OR contactgroups is need
    def is_correct(self):
        state = True  #guilty or not? :)
        cls = self.__class__

        for prop, entry in cls.properties.items():
            if not hasattr(self, prop) and entry.required:
                print self.get_name(), " : I do not have", prop
                state = False  #Bad boy...
        return state

    def is_me(self):
        print "Hostname:%s, gethostname:%s" % (self.host_name,
                                               socket.gethostname())
        return self.host_name == socket.gethostname()

    def give_satellite_cfg(self):
        return {
            'port': self.port,
            'address': self.address,
            'name': self.arbiter_name
        }

    def do_not_run(self):
        if self.con is None:
            self.create_connexion()
        try:
            self.con.do_not_run()
            return True
        except Pyro.errors.URIError, exp:
            self.con = None
            return False
        except Pyro.errors.ProtocolError, exp:
            self.con = None
            return False
예제 #19
0
class ReceiverLink(SatelliteLink):
    """Please Add a Docstring to describe the class here"""

    id = 0
    my_type = 'receiver'
    properties = SatelliteLink.properties.copy()
    properties.update({
        'receiver_name':
        StringProp(fill_brok=['full_status'], to_send=True),
        'port':
        IntegerProp(default=7772, fill_brok=['full_status']),
        'manage_sub_realms':
        BoolProp(default=True, fill_brok=['full_status']),
        'manage_arbiters':
        BoolProp(default=False, fill_brok=['full_status'], to_send=True),
        'direct_routing':
        BoolProp(default=False, fill_brok=['full_status'], to_send=True),
        'accept_passive_unknown_check_results':
        BoolProp(default=False, fill_brok=['full_status'], to_send=True),
        'harakiri_threshold':
        StringProp(default=None, fill_brok=['full_status'], to_send=True),
    })

    def get_name(self):
        return self.receiver_name

    def register_to_my_realm(self):
        self.realm.receivers.append(self)

    def push_host_names(self, sched_id, hnames):
        try:
            if self.con is None:
                self.create_connection()
            logger.info(" (%s)", self.uri)

            # If the connection failed to initialize, bail out
            if self.con is None:
                self.add_failed_check_attempt()
                return

            # r = self.con.push_host_names(sched_id, hnames)
            self.con.get('ping')
            self.con.post('push_host_names', {
                'sched_id': sched_id,
                'hnames': hnames
            },
                          wait='long')
        except HTTPExceptions, exp:
            self.add_failed_check_attempt(reason=str(exp))
예제 #20
0
class Reactionner(Satellite):
    do_checks = False  # I do not do checks
    do_actions = True
    my_type = 'reactionner'

    properties = Satellite.properties.copy()
    properties.update({
        'pidfile':   PathProp(default='reactionnerd.pid'),
        'port':      IntegerProp(default=7769),
        'local_log': PathProp(default='reactionnerd.log'),
    })

    def __init__(self, config_file, is_daemon, do_replace, debug, debug_file, profile=''):
        super(Reactionner, self).__init__('reactionner', config_file, is_daemon, do_replace, debug,
                                          debug_file)
예제 #21
0
class BrokerLink(SatelliteLink):
    id = 0
    my_type = 'broker'
    properties = SatelliteLink.properties.copy()
    properties.update({
        'broker_name':
        StringProp(fill_brok=['full_status'], to_send=True),
        'port':
        IntegerProp(default='7772', fill_brok=['full_status']),
    })

    def get_name(self):
        return self.broker_name

    def register_to_my_realm(self):
        self.realm.brokers.append(self)
예제 #22
0
class ArbiterLink(SatelliteLink):
    id = 0
    my_type = 'arbiter'
    properties = SatelliteLink.properties.copy()
    properties.update({
        'arbiter_name': StringProp(),
        'host_name': StringProp(default=socket.gethostname()),
        'port': IntegerProp(default=7770),
    })

    def get_name(self):
        return self.arbiter_name

    def get_config(self):
        return self.con.get('get_config')

    # Look for ourself as an arbiter. If we search for a specific arbiter name, go forit
    # If not look be our fqdn name, or if not, our hostname
    def is_me(self, lookup_name):
        logger.info(
            "And arbiter is launched with the hostname:%s "
            "from an arbiter point of view of addr:%s", self.host_name,
            socket.getfqdn())
        if lookup_name:
            return lookup_name == self.get_name()
        else:
            return self.host_name == socket.getfqdn(
            ) or self.host_name == socket.gethostname()

    def give_satellite_cfg(self):
        return {
            'port': self.port,
            'address': self.address,
            'name': self.arbiter_name,
            'use_ssl': self.use_ssl,
            'hard_ssl_name_check': self.hard_ssl_name_check
        }

    def do_not_run(self):
        if self.con is None:
            self.create_connection()
        try:
            self.con.get('do_not_run')
            return True
        except HTTPExceptions, exp:
            self.con = None
            return False
예제 #23
0
class Reactionner(Satellite):
    do_checks = False  # I do not do checks
    do_actions = True  # just actions like notifications

    properties = Satellite.properties.copy()
    properties.update({
        'pidfile':
        PathProp(default='/usr/local/shinken/var/reactionnerd.pid'),
        'port':
        IntegerProp(default='7769'),
        'local_log':
        PathProp(default='/usr/local/shinken/var/reactionnerd.log'),
    })

    def __init__(self, config_file, is_daemon, do_replace, debug, debug_file):
        super(Reactionner,
              self).__init__('reactionner', config_file, is_daemon, do_replace,
                             debug, debug_file)
예제 #24
0
class Resultmodulation(Item):
    id = 1  # zero is always special in database, so we do not take risk here
    my_type = 'resultmodulation'

    properties = Item.properties.copy()
    properties.update({
        'resultmodulation_name': StringProp(),
        'exit_codes_match':      IntListProp(default=[]),
        'exit_code_modulation':  IntegerProp(default=None),
        'modulation_period':     StringProp(default=None),
    })

    # For debugging purpose only (nice name)
    def get_name(self):
        return self.resultmodulation_name

    # Make the return code modulation if need
    def module_return(self, return_code):
        # Only if in modulation_period of modulation_period == None
        if self.modulation_period is None or self.modulation_period.is_time_valid(time.time()):
            # Try to change the exit code only if a new one is defined
            if self.exit_code_modulation is not None:
                # First with the exit_code_match
                if return_code in self.exit_codes_match:
                    return_code = self.exit_code_modulation

        return return_code

    # We override the pythonize because we have special cases that we do not want
    # to be do at running
    def pythonize(self):
        # First apply Item pythonize
        super(Resultmodulation, self).pythonize()

        # Then very special cases
        # Intify the exit_codes_match, and make list
        self.exit_codes_match = [int(ec) for ec in getattr(self, 'exit_codes_match', [])]

        if hasattr(self, 'exit_code_modulation'):
            self.exit_code_modulation = int(self.exit_code_modulation)
        else:
            self.exit_code_modulation = None
예제 #25
0
class ReceiverLink(SatelliteLink):
    id = 0
    my_type = 'receiver'
    properties = SatelliteLink.properties.copy()
    properties.update({
        'receiver_name':
        StringProp(fill_brok=['full_status'], to_send=True),
        'port':
        IntegerProp(default='7772', fill_brok=['full_status']),
        'manage_sub_realms':
        BoolProp(default='1', fill_brok=['full_status']),
        'manage_arbiters':
        BoolProp(default='0', fill_brok=['full_status'], to_send=True),
    })

    def get_name(self):
        return self.receiver_name

    def register_to_my_realm(self):
        self.realm.receivers.append(self)
예제 #26
0
class PollerLink(SatelliteLink):
    """This class is the link between Arbiter and Poller. With it, arbiter
    can see if a poller is alive, and can send it new configuration

    """

    id = 0
    my_type = 'poller'
    # To_send: send or not to satellite conf
    properties = SatelliteLink.properties.copy()
    properties.update({
        'poller_name':
        StringProp(fill_brok=['full_status'], to_send=True),
        'port':
        IntegerProp(default=7771, fill_brok=['full_status']),
        'min_workers':
        IntegerProp(default=0, fill_brok=['full_status'], to_send=True),
        'max_workers':
        IntegerProp(default=30, fill_brok=['full_status'], to_send=True),
        'processes_by_worker':
        IntegerProp(default=256, fill_brok=['full_status'], to_send=True),
        'max_q_size':
        IntegerProp(default=0, fill_brok=['full_status'], to_send=True),
        'q_factor':
        IntegerProp(default=0, fill_brok=['full_status'], to_send=True),
        'results_batch':
        IntegerProp(default=0, fill_brok=['full_status'], to_send=True),
        'poller_tags':
        ListProp(default=['None'], to_send=True),
        'harakiri_threshold':
        StringProp(default=None, fill_brok=['full_status'], to_send=True),
    })

    def get_name(self):
        return getattr(self, 'poller_name', 'UNNAMED-POLLER')

    def register_to_my_realm(self):
        self.realm.pollers.append(self)
예제 #27
0
class EventHandler(Action):
    # AutoSlots create the __slots__ with properties and
    # running_properties names
    __metaclass__ = AutoSlots

    my_type = 'eventhandler'

    properties = {
        'is_a':           StringProp(default='eventhandler'),
        'type':           StringProp(default=''),
        '_in_timeout':    StringProp(default=False),
        'status':         StringProp(default=''),
        'exit_status':    StringProp(default=3),
        'output':         StringProp(default=''),
        'long_output':    StringProp(default=''),
        't_to_go':        StringProp(default=0),
        'check_time':     StringProp(default=0),
        'execution_time': FloatProp(default=0),
        'u_time':         FloatProp(default=0.0),
        's_time':         FloatProp(default=0.0),
        'env':            StringProp(default={}),
        'perf_data':      StringProp(default=''),
        'sched_id':       IntegerProp(default=0),
        'timeout':        IntegerProp(default=10),
        'check_time':     IntegerProp(default=0),
        'command':        StringProp(default=''),
        'module_type':    StringProp(default='fork'),
        'worker':         StringProp(default='none'),
        'reactionner_tag':     StringProp(default='None'),
    }

    # id = 0  #Is common to Actions
    def __init__(self, command, id=None, ref=None, timeout=10, env={}, \
                     module_type='fork', reactionner_tag='None'):
        self.is_a = 'eventhandler'
        self.type = ''
        self.status = 'scheduled'
        if id is None:  # id != None is for copy call only
            self.id = Action.id
            Action.id += 1
        self.ref = ref
        self._in_timeout = False
        self.timeout = timeout
        self.exit_status = 3
        self.command = command
        self.output = ''
        self.long_output = ''
        self.t_to_go = time.time()
        self.check_time = 0
        self.execution_time = 0
        self.u_time = 0
        self.s_time = 0
        self.perf_data = ''
        self.env = {}
        self.module_type = module_type
        self.worker = 'none'
        self.reactionner_tag = reactionner_tag


    # return a copy of the check but just what is important for execution
    # So we remove the ref and all
    def copy_shell(self):
        # We create a dummy check with nothing in it, just defaults values
        return self.copy_shell__(EventHandler('', id=self.id))

    def get_return_from(self, e):
        self.exit_status = e.exit_status
        self.output = e.output
        self.long_output = getattr(e, 'long_output', '')
        self.check_time = e.check_time
        self.execution_time = getattr(e, 'execution_time', 0.0)
        self.perf_data = getattr(e, 'perf_data', '')

    # <TMI!!>
    def get_outputs(self, out, max_plugins_output_length):
        elts = out.split('\n')
        # For perf data
        elts_line1 = elts[0].split('|')
        # First line before | is output
        self.output = elts_line1[0]
        # After | is perfdata
        if len(elts_line1) > 1:
            self.perf_data = elts_line1[1]
        # The others lines are long_output
        if len(elts) > 1:
            self.long_output = '\n'.join(elts[1:])
    # </TMI!!>

    def is_launchable(self, t):
        return t >= self.t_to_go

    def __str__(self):
        return "Check %d status:%s command:%s" % (self.id, self.status, self.command)

    def get_id(self):
        return self.id

    # Call by pickle to dataify the comment
    # because we DO NOT WANT REF in this pickleisation!
    def __getstate__(self):
        cls = self.__class__
        # id is not in *_properties
        res = {'id': self.id}
        for prop in cls.properties:
            if hasattr(self, prop):
                res[prop] = getattr(self, prop)

        return res

    # Inverted function of getstate
    def __setstate__(self, state):
        cls = self.__class__
        self.id = state['id']
        for prop in cls.properties:
            if prop in state:
                setattr(self, prop, state[prop])
        if not hasattr(self, 'worker'):
            self.worker = 'none'
        if not getattr(self, 'module_type', None):
            self.module_type = 'fork'
        # s_time and u_time are added between 1.2 and 1.4
        if not hasattr(self, 'u_time'):
            self.u_time = 0
            self.s_time = 0
예제 #28
0
class Receiver(BaseSatellite):

    properties = BaseSatellite.properties.copy()
    properties.update({
        'pidfile':
        PathProp(default='/usr/local/shinken/var/receiverd.pid'),
        'port':
        IntegerProp(default='7773'),
        'local_log':
        PathProp(default='/usr/local/shinken/var/receiverd.log'),
    })

    def __init__(self, config_file, is_daemon, do_replace, debug, debug_file):

        super(Receiver, self).__init__('receiver', config_file, is_daemon,
                                       do_replace, debug, debug_file)

        # Our arbiters
        self.arbiters = {}

        # Our pollers and reactionners
        self.pollers = {}
        self.reactionners = {}

        # Modules are load one time
        self.have_modules = False

        # Can have a queue of external_commands give by modules
        # will be taken by arbiter to process
        self.external_commands = []

        # All broks to manage
        self.broks = []  # broks to manage
        # broks raised this turn and that need to be put in self.broks
        self.broks_internal_raised = []

    # Schedulers have some queues. We can simplify call by adding
    # elements into the proper queue just by looking at their type
    # Brok -> self.broks
    # TODO : better tag ID?
    # External commands -> self.external_commands
    def add(self, elt):
        cls_type = elt.__class__.my_type
        if cls_type == 'brok':
            # For brok, we TAG brok with our instance_id
            elt.data['instance_id'] = 0
            self.broks_internal_raised.append(elt)
            return
        elif cls_type == 'externalcommand':
            print "Adding in queue an external command", ExternalCommand.__dict__
            self.external_commands.append(elt)

#    # Get teh good tabs for links by the kind. If unknown, return None
#    def get_links_from_type(self, type):
#        t = {'scheduler' : self.schedulers, 'arbiter' : self.arbiters, \
#             'poller' : self.pollers, 'reactionner' : self.reactionners}
#        if type in t :
#            return t[type]
#        return None

# Call by arbiter to get our external commands

    def get_external_commands(self):
        res = self.external_commands
        self.external_commands = []
        return res

    # Get a brok. Our role is to put it in the modules
    # THEY MUST DO NOT CHANGE data of b !!!
    # REF: doc/receiver-modules.png (4-5)
    def manage_brok(self, b):
        to_del = []
        # Call all modules if they catch the call
        for mod in self.modules_manager.get_internal_instances():
            try:
                mod.manage_brok(b)
            except Exception, exp:
                print exp.__dict__
                logger.log(
                    "[%s] Warning : The mod %s raise an exception: %s, I kill it"
                    % (self.name, mod.get_name(), str(exp)))
                logger.log("[%s] Exception type : %s" % (self.name, type(exp)))
                logger.log("Back trace of this kill: %s" %
                           (traceback.format_exc()))
                to_del.append(mod)
        # Now remove mod that raise an exception
        self.modules_manager.clear_instances(to_del)
예제 #29
0
class Downtime:
    id = 1

    # Just to list the properties we will send as pickle
    # so to others daemons, so all but NOT REF
    properties = {
        'activate_me':        StringProp(default=[]),
        'entry_time':         IntegerProp(default=0, fill_brok=['full_status']),
        'fixed':              BoolProp(default=True, fill_brok=['full_status']),
        'start_time':         IntegerProp(default=0, fill_brok=['full_status']),
        'duration':           IntegerProp(default=0, fill_brok=['full_status']),
        'trigger_id':         IntegerProp(default=0),
        'end_time':           IntegerProp(default=0, fill_brok=['full_status']),
        'real_end_time':      IntegerProp(default=0),
        'author':             StringProp(default='', fill_brok=['full_status']),
        'comment':            StringProp(default=''),
        'is_in_effect':       BoolProp(default=False),
        'has_been_triggered': BoolProp(default=False),
        'can_be_deleted':     BoolProp(default=False),

        # TODO: find a very good way to handle the downtime "ref".
        # ref must effectively not be in properties because it points
        # onto a real object.
        # 'ref': None
    }


    def __init__(self, ref, start_time, end_time, fixed, trigger_id, duration, author, comment):
        now = datetime.datetime.now()
        self.id = int(time.mktime(now.timetuple()) * 1e6 + now.microsecond)
        self.__class__.id = self.id + 1
        self.ref = ref  # pointer to srv or host we are apply
        self.activate_me = []  # The other downtimes i need to activate
        self.entry_time = int(time.time())
        self.fixed = fixed
        self.start_time = start_time
        self.duration = duration
        self.trigger_id = trigger_id
        if self.trigger_id != 0:  # triggered plus fixed makes no sense
            self.fixed = False
        self.end_time = end_time
        if fixed:
            self.duration = end_time - start_time
        # This is important for flexible downtimes. Here start_time and
        # end_time mean: in this time interval it is possible to trigger
        # the beginning of the downtime which lasts for duration.
        # Later, when a non-ok event happens, real_end_time will be
        # recalculated from now+duration
        # end_time will be displayed in the web interface, but real_end_time
        # is used internally
        self.real_end_time = end_time
        self.author = author
        self.comment = comment
        self.is_in_effect = False
        # fixed: start_time has been reached,
        # flexible: non-ok checkresult

        self.has_been_triggered = False  # another downtime has triggered me
        self.can_be_deleted = False
        self.add_automatic_comment()


    def __str__(self):
        if self.is_in_effect is True:
            active = "active"
        else:
            active = "inactive"
        if self.fixed is True:
            type = "fixed"
        else:
            type = "flexible"
        return "%s %s Downtime id=%d %s - %s" % (
            active, type, self.id, time.ctime(self.start_time), time.ctime(self.end_time))


    def trigger_me(self, other_downtime):
        self.activate_me.append(other_downtime)


    def in_scheduled_downtime(self):
        return self.is_in_effect


    # The referenced host/service object enters now a (or another) scheduled
    # downtime. Write a log message only if it was not already in a downtime
    def enter(self):
        res = []
        self.is_in_effect = True
        if self.fixed is False:
            now = time.time()
            self.real_end_time = now + self.duration
        if self.ref.scheduled_downtime_depth == 0:
            self.ref.raise_enter_downtime_log_entry()
            self.ref.create_notifications('DOWNTIMESTART')
        self.ref.scheduled_downtime_depth += 1
        self.ref.in_scheduled_downtime = True
        for dt in self.activate_me:
            res.extend(dt.enter())
        return res


    # The end of the downtime was reached.
    def exit(self):
        res = []
        if self.is_in_effect is True:
            # This was a fixed or a flexible+triggered downtime
            self.is_in_effect = False
            self.ref.scheduled_downtime_depth -= 1
            if self.ref.scheduled_downtime_depth <= 0:
                self.ref.raise_exit_downtime_log_entry()
                self.ref.create_notifications('DOWNTIMEEND')
                self.ref.in_scheduled_downtime = False
        else:
            # This was probably a flexible downtime which was not triggered
            # In this case it silently disappears
            pass
        self.del_automatic_comment()
        self.can_be_deleted = True
        # when a downtime ends and the service was critical
        # a notification is sent with the next critical check
        # So we should set a flag here which signals consume_result
        # to send a notification
        self.ref.in_scheduled_downtime_during_last_check = True
        return res


    # A scheduled downtime was prematurely canceled
    def cancel(self):
        res = []
        self.is_in_effect = False
        self.ref.scheduled_downtime_depth -= 1
        if self.ref.scheduled_downtime_depth == 0:
            self.ref.raise_cancel_downtime_log_entry()
            self.ref.in_scheduled_downtime = False
        self.del_automatic_comment()
        self.can_be_deleted = True
        self.ref.in_scheduled_downtime_during_last_check = True
        # Nagios does not notify on canceled downtimes, but we does
        self.ref.create_notifications('DOWNTIMECANCELLED')
        # Also cancel other downtimes triggered by me
        for dt in self.activate_me:
            res.extend(dt.cancel())
        return res


    # Scheduling a downtime creates a comment automatically
    def add_automatic_comment(self):
        if self.fixed is True:
            text = (
                "This %s has been scheduled for fixed downtime from %s to %s. "
                "Notifications for the %s will not be sent out during that time period." % (
                    self.ref.my_type,
                    time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(self.start_time)),
                    time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(self.end_time)),
                    self.ref.my_type)
            )
        else:
            hours, remainder = divmod(self.duration, 3600)
            minutes, seconds = divmod(remainder, 60)
            text = ("This %s has been scheduled for flexible downtime starting between %s and %s "
                    "and lasting for a period of %d hours and %d minutes. "
                    "Notifications for the %s will not be sent out during that time period." % (
                        self.ref.my_type,
                        time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(self.start_time)),
                        time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(self.end_time)),
                        hours, minutes, self.ref.my_type)
                    )
        if self.ref.my_type == 'host':
            comment_type = 1
        else:
            comment_type = 2
        c = Comment(self.ref, False, "(Nagios Process)", text, comment_type, 2, 0, False, 0)
        self.comment_id = c.id
        self.extra_comment = c
        self.ref.add_comment(c)


    def del_automatic_comment(self):
        # Extra comment can be None if we load it from a old version of Shinken
        # TODO: remove it in a future version when every one got upgrade
        if self.extra_comment is not None:
            self.extra_comment.can_be_deleted = True
            # self.ref.del_comment(self.comment_id)


    # Fill data with info of item by looking at brok_type
    # in props of properties or running_properties
    def fill_data_brok_from(self, data, brok_type):
        cls = self.__class__
        # Now config properties
        for prop, entry in cls.properties.items():
            if hasattr(prop, 'fill_brok'):
                if brok_type in entry['fill_brok']:
                    data[prop] = getattr(self, prop)


    # Get a brok with initial status
    def get_initial_status_brok(self):
        data = {'id': self.id}

        self.fill_data_brok_from(data, 'full_status')
        b = Brok('downtime_raise', data)
        return b


    # Call by pickle for dataify the downtime
    # because we DO NOT WANT REF in this pickleisation!
    def __getstate__(self):
        cls = self.__class__
        # id is not in *_properties
        res = {'id': self.id}
        for prop in cls.properties:
            if hasattr(self, prop):
                res[prop] = getattr(self, prop)
        return res


    # Inverted function of getstate
    def __setstate__(self, state):
        cls = self.__class__

        self.id = state['id']
        for prop in cls.properties:
            if prop in state:
                setattr(self, prop, state[prop])

        if self.id >= cls.id:
            cls.id = self.id + 1
예제 #30
0
class CommandCall(DummyCommandCall):
    """This class is use when a service, contact or host define
    a command with args.
    """
    # AutoSlots create the __slots__ with properties and
    # running_properties names
    __metaclass__ = AutoSlots

    #__slots__ = ('id', 'call', 'command', 'valid', 'args', 'poller_tag',
    #             'reactionner_tag', 'module_type', '__dict__')
    id = 0
    my_type = 'CommandCall'

    properties = {
        'call':            StringProp(),
        'command':         StringProp(),
        'poller_tag':      StringProp(default='None'),
        'reactionner_tag': StringProp(default='None'),
        'module_type':     StringProp(default='fork'),
        'valid':           BoolProp(default=False),
        'args':            StringProp(default=[]),
        'timeout':         IntegerProp(default='-1'),
        'late_relink_done':BoolProp(default=False),
    }

    def __init__(self, commands, call, poller_tag='None',
                 reactionner_tag='None'):
        self.id = self.__class__.id
        self.__class__.id += 1
        self.call = call
        self.timeout = -1
        # Now split by ! and get command and args
        self.get_command_and_args()
        self.command = commands.find_by_name(self.command.strip())
        self.late_relink_done = False  # To do not relink again and again the same commandcall
        if self.command is not None:
            self.valid = True
        else:
            self.valid = False
        if self.valid:
            # If the host/service do not give an override poller_tag, take
            # the one of the command
            self.poller_tag = poller_tag  # from host/service
            self.reactionner_tag = reactionner_tag
            self.module_type = self.command.module_type
            self.timeout = int(self.command.timeout)
            if self.valid and poller_tag is 'None':
                # from command if not set
                self.poller_tag = self.command.poller_tag
            # Same for reactionner tag
            if self.valid and reactionner_tag is 'None':
                # from command if not set
                self.reactionner_tag = self.command.reactionner_tag

    def get_command_and_args(self):
        """We want to get the command and the args with ! splitting.
        but don't forget to protect against the \! to do not split them
        """

        # First protect
        p_call = self.call.replace('\!', '___PROTECT_EXCLAMATION___')
        tab = p_call.split('!')
        self.command = tab[0]
        # Reverse the protection
        self.args = [s.replace('___PROTECT_EXCLAMATION___', '!')
                     for s in tab[1:]]

    # If we didn't already lately relink us, do it
    def late_linkify_with_command(self, commands):
        if self.late_relink_done:
            return
        self.late_relink_done = True
        c = commands.find_by_name(self.command)
        self.command = c

    def is_valid(self):
        return self.valid

    def __str__(self):
        return str(self.__dict__)

    def get_name(self):
        return self.call

    def __getstate__(self):
        """Call by pickle to dataify the comment
        because we DO NOT WANT REF in this pickleisation!
        """
        cls = self.__class__
        # id is not in *_properties
        res = {'id': self.id}

        for prop in cls.properties:
            if hasattr(self, prop):
                res[prop] = getattr(self, prop)

        # The command is a bit special, we just put it's name
        # or a '' if need
        if self.command and not isinstance(self.command, basestring):
            res['command'] = self.command.get_name()
        # Maybe it's a repickle of a unpickle thing... (like with deepcopy). If so
        # only take the value
        elif self.command and isinstance(self.command, basestring):
            res['command'] = self.command
        else:
            res['command'] = ''

        return res

    def __setstate__(self, state):
        """Inverted function of getstate"""
        cls = self.__class__
        # We move during 1.0 to a dict state
        # but retention file from 0.8 was tuple
        if isinstance(state, tuple):
            self.__setstate_pre_1_0__(state)
            return

        self.id = state['id']
        for prop in cls.properties:
            if prop in state:
                setattr(self, prop, state[prop])

    def __setstate_pre_1_0__(self, state):
        """In 1.0 we move to a dict save. Before, it was
        a tuple save, like
        ({'id': 11}, {'poller_tag': 'None', 'reactionner_tag': 'None',
        'command_line': u'/usr/local/nagios/bin/rss-multiuser',
        'module_type': 'fork', 'command_name': u'notify-by-rss'})
        """
        for d in state:
            for k, v in d.items():
                setattr(self, k, v)