Example #1
0
    def __init__(self, config, settings, conn, queue, system, application_type):
        """
        :type config: dict (xml)
        :type settings: zoom.agent.entities.thread_safe_object.ThreadSafeObject
        :type conn: multiprocessing.Connection
        :type queue: zoom.agent.entities.unique_queue.UniqueQueue
        :type system: zoom.common.types.PlatformType
        :type application_type: zoom.common.types.ApplicationType
        """
        self.config = config
        self._settings = settings
        self.name = verify_attribute(self.config, 'id', none_allowed=False)
        self._log = logging.getLogger('sent.{0}.app'.format(self.name))
        # informational attributes
        self._host = platform.node().upper()
        self._fqdn = socket.getfqdn()
        self._system = system
        self._predicates = list()
        self._running = True  # used to manually stop the run loop
        self._prev_state = None
        self._actions = dict()  # created in _reset_watches on zk connect
        self._env = os.environ.get('EnvironmentToUse', 'Staging')
        self._apptype = application_type

        # tool-like attributes
        self.listener_lock = Lock()
        self._action_queue = queue
        self._mode = ApplicationMode(ApplicationMode.MANUAL)
        self._state = ThreadSafeObject(ApplicationState.OK)
        self._trigger_time = ''     # Default to empty string for comparison
        self._login_user = '******'   # Default to Zoom
        self._run_check_mode = False
        self._pd_svc_key = verify_attribute(config, 'pagerduty_service',
                                            none_allowed=True)

        self._paths = self._init_paths(self.config, settings, application_type)

        # clients
        if self._system == PlatformType.LINUX:
            self.zkclient = KazooClient(
                hosts=ZK_CONN_STRING,
                handler=SequentialThreadingHandler(),
                logger=logging.getLogger('kazoo.app.{0}'.format(self.name)))
        elif self._system == PlatformType.WINDOWS:
            self.zkclient = KazooClient(hosts=ZK_CONN_STRING,
                                        handler=SequentialThreadingHandler())

        self.zkclient.add_listener(self._zk_listener)
        self._proc_client = self._init_proc_client(self.config,
                                                   settings,
                                                   application_type)

        self._actions = self._init_actions(settings)
        self._work_manager = self._init_work_manager(self._action_queue, conn)
Example #2
0
    def __init__(self, config, system, settings):
        """
        :type config: xml.etree.ElementTree.Element
        :type system: zoom.common.types.PlatformType
        """
        self._log = logging.getLogger('sent.child')
        self.parent_conn, self.child_conn = Pipe()
        self._action_queue = UniqueQueue()

        self.name = verify_attribute(config, 'id')
        self._application_type = verify_attribute(config, 'type')
        self._config = config
        self._system = system  # Linux or Windows
        self._settings = settings
        self._process = self._create_process()
Example #3
0
    def __init__(self, config, system, settings):
        """
        :type config: xml.etree.ElementTree.Element
        :type system: zoom.common.types.PlatformType
        :type settings: dict
        """
        self._log = logging.getLogger("sent.child")
        self._action_queue = UniqueQueue()
        self._cancel_flag = ThreadSafeObject(False)

        self.name = verify_attribute(config, "id")
        self._application_type = verify_attribute(config, "type")
        self._config = config
        self._system = system  # Linux or Windows
        self._settings = settings
        self._process = self._create_process()
Example #4
0
    def __init__(self, config, system, settings):
        """
        :type config: xml.etree.ElementTree.Element
        :type system: zoom.common.types.PlatformType
        :type settings: dict
        """
        self._log = logging.getLogger('sent.child')
        self._action_queue = UniqueQueue()
        self._cancel_flag = ThreadSafeObject(False)

        self.name = verify_attribute(config, 'id')
        self._application_type = verify_attribute(config, 'type')
        self._config = config
        self._system = system  # Linux or Windows
        self._settings = settings
        self._process = self._create_process()
Example #5
0
    def _init_proc_client(self, config, atype, cancel_flag):
        """Create the process client."""
        start_cmd = verify_attribute(config, 'start_cmd', none_allowed=True)
        stop_cmd = verify_attribute(config, 'stop_cmd', none_allowed=True)
        status_cmd = verify_attribute(config, 'status_cmd', none_allowed=True)
        script = verify_attribute(config, 'script', none_allowed=True)

        g_names = self._get_graphite_metric_names()

        return ProcessClient(name=self.name,
                             start_cmd=start_cmd,
                             stop_cmd=stop_cmd,
                             status_cmd=status_cmd,
                             script=script,
                             apptype=atype,
                             restart_logic=self._rl,
                             graphite_metric_names=g_names,
                             cancel_flag=cancel_flag)
Example #6
0
    def _init_proc_client(self, config, atype, cancel_flag):
        """Create the process client."""
        start_cmd = verify_attribute(config, 'start_cmd', none_allowed=True)
        stop_cmd = verify_attribute(config, 'stop_cmd', none_allowed=True)
        status_cmd = verify_attribute(config, 'status_cmd', none_allowed=True)
        script = verify_attribute(config, 'script', none_allowed=True)

        g_names = self._get_graphite_metric_names()

        return ProcessClient(name=self.name,
                             start_cmd=start_cmd,
                             stop_cmd=stop_cmd,
                             status_cmd=status_cmd,
                             script=script,
                             apptype=atype,
                             restart_logic=self._rl,
                             graphite_metric_names=g_names,
                             cancel_flag=cancel_flag)
Example #7
0
    def _init_proc_client(self, config, settings, atype):
        """Create the process client."""
        command = verify_attribute(config, 'command', none_allowed=True)
        script = verify_attribute(config, 'script', none_allowed=True)
        restartmax = verify_attribute(config, 'restartmax', none_allowed=True,
                                      cast=int)

        if restartmax is None:
            self._log.info('Restartmax not specified. Assuming 3.')
            restartmax = 3

        g_names = self._get_graphite_metric_names()

        return ProcessClient(name=self.name,
                             command=command,
                             script=script,
                             apptype=atype,
                             system=self._system,
                             restart_logic=RestartLogic(restartmax),
                             graphite_metric_names=g_names,
                             settings=settings)
Example #8
0
    def _spawn_children(self, config):
        """
        Populate the self.children dictionary
        :type config: xml.etree.ElementTree.Element
        """
        for component in config.iter('Component'):
            try:
                name = verify_attribute(component, 'id')
                self._log.info('Spawning %s' % name)
                self.children[name] = {
                    'config':
                    component,
                    'process':
                    ChildProcess(component, self._system, self._settings)
                }

            except ValueError as e:
                self._log.error('Error with ID in config: {0}'.format(e))
                continue
Example #9
0
    def _spawn_children(self, config):
        """
        Populate the self.children dictionary
        :type config: xml.etree.ElementTree.Element
        """
        for component in config.iter('Component'):
            try:
                name = verify_attribute(component, 'id')
                self._log.info('Spawning %s' % name)
                self.children[name] = {
                    'config': component,
                    'process': ChildProcess(component,
                                            self._system,
                                            self._settings)
                }

            except ValueError as e:
                self._log.error('Error with ID in config: {0}'.format(e))
                continue
Example #10
0
    def _init_paths(self, config, settings, atype):
        """
        :rtype: dict
        """
        paths = dict()
        paths['zk_state_base'] = verify_attribute(
            config,
            'registrationpath',
            none_allowed=True,
            default=self._pathjoin(
                settings.get('zookeeper', {}).get('state'), atype, self.name))

        paths['zk_state_path'] = \
            self._pathjoin(paths['zk_state_base'], self._host)
        paths['zk_config_path'] = \
            self._pathjoin(settings.get('zookeeper', {}).get('config'), atype, self.name)
        paths['zk_agent_path'] = \
            self._pathjoin(settings.get('zookeeper', {}).get('agent_state'), self._host)

        return paths
Example #11
0
    def _init_paths(self, config, settings, atype):
        """
        :rtype: dict
        """
        paths = dict()
        paths['zk_state_base'] = verify_attribute(
            config,
            'registrationpath',
            none_allowed=True,
            default=self._pathjoin(settings.get('zookeeper', {}).get('state'), atype, self.name)
        )

        paths['zk_state_path'] = \
            self._pathjoin(paths['zk_state_base'], self._host)
        paths['zk_config_path'] = \
            self._pathjoin(settings.get('zookeeper', {}).get('config'), atype, self.name)
        paths['zk_agent_path'] = \
            self._pathjoin(settings.get('zookeeper', {}).get('agent_state'), self._host)

        return paths
Example #12
0
    def _init_paths(self, config, settings, atype):
        """
        :rtype: dict
        """
        paths = dict()
        registrationpath = verify_attribute(config, 'registrationpath',
                                            none_allowed=True)

        if registrationpath is not None:
            paths['zk_state_base'] = registrationpath
        else:
            paths['zk_state_base'] = \
                self._pathjoin(settings.get('ZK_STATE_PATH'), atype, self.name)

        paths['zk_state_path'] = \
            self._pathjoin(paths['zk_state_base'], self._host)
        paths['zk_config_path'] = \
            self._pathjoin(settings.get('ZK_CONFIG_PATH'), atype, self.name)
        paths['zk_agent_path'] = \
            self._pathjoin(settings.get('ZK_AGENT_STATE_PATH'), self._host)

        return paths
Example #13
0
    def create(self, xmlpart):
        """
        :type xmlpart: xml.etree.ElementTree.Element
        :rtype: dict
        """
        if isinstance(xmlpart, str):
            root = ElementTree.fromstring(xmlpart)
        else:
            root = xmlpart

        actions = dict()
        for element in root.iter('Action'):
            name = verify_attribute(element, 'id').lower()
            staggerpath = verify_attribute(element, 'staggerpath',
                                           none_allowed=True)
            staggertime = verify_attribute(element, 'staggertime',
                                           none_allowed=True, cast=int)
            mode_controlled = verify_attribute(element, 'mode_controlled',
                                               none_allowed=True)
            disabled = verify_attribute(element, 'disabled', none_allowed=True)
            pd_enabled = verify_attribute(element, 'pd_enabled',
                                          none_allowed=True)
            if pd_enabled is None:
                pagerduty_enabled = True
            else:
                pagerduty_enabled = pd_enabled

            action = getattr(self._comp, name, None)
            actions[name] = Action(name, self._comp.name, action, element,
                                   action_q=self._action_q,
                                   staggerpath=staggerpath,
                                   staggertime=staggertime,
                                   mode_controlled=mode_controlled,
                                   zkclient=self._zk,
                                   proc_client=self._proc,
                                   mode=self._mode,
                                   system=self._system,
                                   pred_list=self._pred_list,
                                   settings=self._settings,
                                   disabled=bool(disabled),
                                   pd_enabled=pagerduty_enabled)
            self._log.info('Registered {0}.'.format(actions[name]))

        return actions
    def _parse_dependencies(self, action):
        """
        Parse dependencies out of XML
        :type action: xml.etree.ElementTree.Element
        :rtype: list
        """
        # TODO: rename 'path' when it really isn't a path. this is a hack...
        # prev_was_not keeps track of whether the outer class was 'not'
        dependencies = []
        prev_was_not = False
        for predicate in action.iter('Predicate'):
            pred_type = predicate.get('type').lower()
            pred_path = predicate.get('path', None)
            # pred_oper = predicate.get('operational', False)
            pred_oper = bool(
                verify_attribute(predicate, 'operational', none_allowed=True))
            if pred_type == PredicateType.ZOOKEEPERHASCHILDREN:
                dependencies.append({
                    'type': pred_type,
                    'path': pred_path,
                    'operational': pred_oper
                })
                prev_was_not = False
            elif pred_type == PredicateType.ZOOKEEPERHASGRANDCHILDREN:
                dependencies.append({
                    'type': pred_type,
                    'path': pred_path,
                    'operational': pred_oper
                })
                prev_was_not = False
            elif pred_type == PredicateType.ZOOKEEPERGOODUNTILTIME:
                if len(pred_path.split('gut/')) > 1:
                    dependencies.append({
                        'type':
                        pred_type,
                        'path': ("I should be up between: {0}".format(
                            pred_path.split("gut/")[1])),
                        'operational':
                        pred_oper
                    })
                else:
                    logging.debug('Invalid GUT path: {0}'.format(pred_path))
                prev_was_not = False
            elif pred_type == PredicateType.HOLIDAY:
                dependencies.append({
                    'type':
                    pred_type,
                    'path': ("Does NOT run on holidays"
                             if prev_was_not else "Runs on holidays"),
                    'operational':
                    pred_oper
                })
                prev_was_not = False
            elif pred_type == PredicateType.WEEKEND:
                dependencies.append({
                    'type':
                    pred_type,
                    'path': ("Does NOT run on weekends"
                             if prev_was_not else "Runs on weekends"),
                    'operational':
                    pred_oper
                })
                prev_was_not = False
            elif pred_type == PredicateType.TIMEWINDOW:
                begin = predicate.get('begin', None)
                end = predicate.get('end', None)
                weekdays = predicate.get('weekdays', None)
                msg = 'I should be up '
                if begin is not None:
                    msg += 'after: {0} '.format(begin)
                if end is not None:
                    msg += 'until: {0}'.format(end)
                # only send dependency if there is something to send
                if begin is not None or end is not None:
                    dependencies.append({
                        'type': pred_type,
                        'path': msg,
                        'operational': pred_oper
                    })

                # pretend this is a weekend predicate for convenience
                if weekdays is not None:
                    day_range = TimeWindow.parse_range(weekdays)
                    if Weekdays.SATURDAY in day_range or Weekdays.SUNDAY in day_range:
                        wk_msg = 'Runs on weekends'
                    else:
                        wk_msg = 'Does NOT run on weekends'

                    dependencies.append({
                        'type': PredicateType.WEEKEND,
                        'path': wk_msg,
                        'operational': pred_oper
                    })

            elif pred_type == PredicateType.NOT:
                prev_was_not = True

        return dependencies
Example #15
0
    def create(self, xmlpart, callback=None, parent=None):
        """
        :type xmlpart: xml.etree.ElementTree.Element
        :type callback: types.FunctionType or None
        :type parent: str or None
        """
        if xmlpart is None:
            # A dummy predicate will be returned if there are no predicates
            # met is true b/c we don't want to block on no predicates
            return create_dummy(comp=self._component_name,
                                parent=self._action,
                                met=True)

        if isinstance(xmlpart, str):
            root = ElementTree.fromstring(xmlpart)
        else:
            root = xmlpart

        if parent is None:
            parent = self._action

        ptype = verify_attribute(root, 'type').lower()
        operational = bool(verify_attribute(root, 'operational',
                                            none_allowed=True))

        if ptype == 'simple':
            return self._ensure_new(
                SimplePredicate(self._component_name,
                                operational=operational,
                                parent=parent),
                callback=callback
            )
        elif ptype == PredicateType.ZOOKEEPERNODEEXISTS:
            return self._ensure_new(
                ZookeeperNodeExists(self._component_name,
                                    self.zkclient,
                                    verify_attribute(root, 'path'),
                                    operational=operational,
                                    parent=parent),
                callback=callback
            )
        elif ptype == PredicateType.ZOOKEEPERHASCHILDREN:
            return self._ensure_new(
                ZookeeperHasChildren(
                    self._component_name,
                    self.zkclient,
                    verify_attribute(root, 'path'),
                    ephemeral_only=verify_attribute(root, 'ephemeral_only',
                                                    none_allowed=True, default=True),
                    operational=operational,
                    parent=parent),
                callback=callback
            )
        elif ptype == PredicateType.ZOOKEEPERHASGRANDCHILDREN:
            return self._ensure_new(
                ZookeeperHasGrandChildren(
                    self._component_name,
                    self.zkclient,
                    verify_attribute(root, 'path'),
                    ephemeral_only=verify_attribute(root, 'ephemeral_only',
                                                    none_allowed=True, default=True),
                    operational=operational,
                    parent=parent),
                callback=callback
            )
        elif ptype == PredicateType.ZOOKEEPERGLOB:
            return self._ensure_new(
                ZookeeperGlob(
                    self._component_name,
                    self.zkclient,
                    verify_attribute(root, 'path'),
                    ephemeral_only=verify_attribute(root, 'ephemeral_only',
                                                    none_allowed=True, default=True),
                    operational=operational,
                    parent=parent),
                callback=callback
            )
        elif ptype == PredicateType.ZOOKEEPERGOODUNTILTIME:
            return self._ensure_new(
                ZookeeperGoodUntilTime(self._component_name,
                                       self.zkclient,
                                       verify_attribute(root, 'path'),
                                       operational=operational,
                                       parent=parent),
                callback=callback
            )
        elif ptype == PredicateType.PROCESS:
            return self._ensure_new(
                PredicateProcess(self._component_name,
                                 self._proc_client,
                                 verify_attribute(root, 'interval', cast=float),
                                 operational=operational,
                                 parent=parent),
                callback=callback
            )
        elif ptype == PredicateType.API:
            return self._ensure_new(
                APIPredicate(self._component_name,
                             verify_attribute(root, 'url'),
                             verb=verify_attribute(root, 'verb', none_allowed=True,
                                                   default='GET'),
                             expected_code=verify_attribute(root, 'expected_code',
                                                            none_allowed=True,
                                                            cast=int, default=200),
                             interval=verify_attribute(root, 'interval', cast=float),
                             operational=operational,
                             parent=parent),
                callback=callback
            )
        elif ptype == PredicateType.HEALTH:
            return self._ensure_new(
                PredicateHealth(self._component_name,
                                verify_attribute(root, 'command'),
                                verify_attribute(root, 'interval', cast=float),
                                self._system,
                                operational=operational,
                                parent=parent),
                callback=callback
            )
        elif ptype == PredicateType.HOLIDAY:
            return self._ensure_new(PredicateHoliday(self._component_name,
                                                     self.zkclient,
                                                     path=self._holiday_path,
                                                     operational=operational,
                                                     parent=parent),
                                    callback=callback
                                    )
        elif ptype == PredicateType.WEEKEND:
            return self._ensure_new(PredicateWeekend(self._component_name,
                                                     operational=operational,
                                                     parent=parent),
                                    callback=callback
                                    )
        elif ptype == PredicateType.TIMEWINDOW:
            return self._ensure_new(
                TimeWindow(self._component_name,
                           begin=verify_attribute(root, 'begin',
                                                  none_allowed=True),
                           end=verify_attribute(root, 'end', none_allowed=True),
                           weekdays=verify_attribute(root, 'weekdays',
                                                     none_allowed=True),
                           operational=operational,
                           parent=parent),
                callback=callback
            )

        # below, use recursion to get nested predicates
        elif ptype == PredicateType.NOT:
            for element in root.findall('Predicate'):
                dep = self.create(element, callback=callback)
                return self._ensure_new(
                    PredicateNot(self._component_name, dep,
                                 parent=self._parent_name(parent, 'not'))
                )
        elif ptype == PredicateType.AND:
            deps = list()
            for element in root.findall('Predicate'):
                deps.append(self.create(element, callback=callback,
                                        parent=self._parent_name(parent, 'and')))
            return self._ensure_new(
                PredicateAnd(self._component_name, deps, parent=parent)
            )
        elif ptype == PredicateType.OR:
            deps = list()
            for element in root.findall('Predicate'):
                deps.append(self.create(element, callback=callback,
                                        parent=self._parent_name(parent, 'or')))
            return self._ensure_new(
                PredicateOr(self._component_name, deps, parent=parent)
            )
        else:
            self._log.error('Unknown predicate type "{0}". Ignoring'
                            .format(ptype))
            # create dummy if it is an unknown predicate type.
            # met is set to true b/c we don't want to block on error
            return create_dummy(comp=self._component_name,
                                parent=self._action,
                                met=True)
Example #16
0
    def create(self, xmlpart, callback=None, parent=None):
        """
        :type xmlpart: xml.etree.ElementTree.Element
        :type callback: types.FunctionType or None
        :type parent: str or None
        """
        if xmlpart is None:
            # A dummy predicate will be returned if there are no predicates
            # met is true b/c we don't want to block on no predicates
            return create_dummy(comp=self._component_name,
                                parent=self._action,
                                met=True)

        if isinstance(xmlpart, str):
            root = ElementTree.fromstring(xmlpart)
        else:
            root = xmlpart

        if parent is None:
            parent = self._action

        ptype = verify_attribute(root, 'type').lower()
        operational = bool(
            verify_attribute(root, 'operational', none_allowed=True))

        if ptype == 'simple':
            return self._ensure_new(SimplePredicate(self._component_name,
                                                    operational=operational,
                                                    parent=parent),
                                    callback=callback)
        elif ptype == PredicateType.ZOOKEEPERNODEEXISTS:
            return self._ensure_new(ZookeeperNodeExists(
                self._component_name,
                self.zkclient,
                verify_attribute(root, 'path'),
                operational=operational,
                parent=parent),
                                    callback=callback)
        elif ptype == PredicateType.ZOOKEEPERHASCHILDREN:
            return self._ensure_new(ZookeeperHasChildren(
                self._component_name,
                self.zkclient,
                verify_attribute(root, 'path'),
                ephemeral_only=verify_attribute(root,
                                                'ephemeral_only',
                                                none_allowed=True,
                                                default=True),
                operational=operational,
                parent=parent),
                                    callback=callback)
        elif ptype == PredicateType.ZOOKEEPERHASGRANDCHILDREN:
            return self._ensure_new(ZookeeperHasGrandChildren(
                self._component_name,
                self.zkclient,
                verify_attribute(root, 'path'),
                ephemeral_only=verify_attribute(root,
                                                'ephemeral_only',
                                                none_allowed=True,
                                                default=True),
                operational=operational,
                parent=parent),
                                    callback=callback)
        elif ptype == PredicateType.ZOOKEEPERGLOB:
            return self._ensure_new(ZookeeperGlob(
                self._component_name,
                self.zkclient,
                verify_attribute(root, 'path'),
                ephemeral_only=verify_attribute(root,
                                                'ephemeral_only',
                                                none_allowed=True,
                                                default=True),
                operational=operational,
                parent=parent),
                                    callback=callback)
        elif ptype == PredicateType.ZOOKEEPERGOODUNTILTIME:
            return self._ensure_new(ZookeeperGoodUntilTime(
                self._component_name,
                self.zkclient,
                verify_attribute(root, 'path'),
                operational=operational,
                parent=parent),
                                    callback=callback)
        elif ptype == PredicateType.PROCESS:
            return self._ensure_new(PredicateProcess(self._component_name,
                                                     self._proc_client,
                                                     verify_attribute(
                                                         root,
                                                         'interval',
                                                         cast=float),
                                                     operational=operational,
                                                     parent=parent),
                                    callback=callback)
        elif ptype == PredicateType.API:
            return self._ensure_new(APIPredicate(
                self._component_name,
                verify_attribute(root, 'url'),
                verb=verify_attribute(root,
                                      'verb',
                                      none_allowed=True,
                                      default='GET'),
                expected_code=verify_attribute(root,
                                               'expected_code',
                                               none_allowed=True,
                                               cast=int,
                                               default=200),
                interval=verify_attribute(root, 'interval', cast=float),
                operational=operational,
                parent=parent),
                                    callback=callback)
        elif ptype == PredicateType.HEALTH:
            return self._ensure_new(PredicateHealth(
                self._component_name,
                verify_attribute(root, 'command'),
                verify_attribute(root, 'interval', cast=float),
                self._system,
                operational=operational,
                parent=parent),
                                    callback=callback)
        elif ptype == PredicateType.HOLIDAY:
            return self._ensure_new(PredicateHoliday(self._component_name,
                                                     self.zkclient,
                                                     path=self._holiday_path,
                                                     operational=operational,
                                                     parent=parent),
                                    callback=callback)
        elif ptype == PredicateType.WEEKEND:
            return self._ensure_new(PredicateWeekend(self._component_name,
                                                     operational=operational,
                                                     parent=parent),
                                    callback=callback)
        elif ptype == PredicateType.TIMEWINDOW:
            return self._ensure_new(TimeWindow(
                self._component_name,
                begin=verify_attribute(root, 'begin', none_allowed=True),
                end=verify_attribute(root, 'end', none_allowed=True),
                weekdays=verify_attribute(root, 'weekdays', none_allowed=True),
                operational=operational,
                parent=parent),
                                    callback=callback)

        # below, use recursion to get nested predicates
        elif ptype == PredicateType.NOT:
            for element in root.findall('Predicate'):
                dep = self.create(element, callback=callback)
                return self._ensure_new(
                    PredicateNot(self._component_name,
                                 dep,
                                 parent=self._parent_name(parent, 'not')))
        elif ptype == PredicateType.AND:
            deps = list()
            for element in root.findall('Predicate'):
                deps.append(
                    self.create(element,
                                callback=callback,
                                parent=self._parent_name(parent, 'and')))
            return self._ensure_new(
                PredicateAnd(self._component_name, deps, parent=parent))
        elif ptype == PredicateType.OR:
            deps = list()
            for element in root.findall('Predicate'):
                deps.append(
                    self.create(element,
                                callback=callback,
                                parent=self._parent_name(parent, 'or')))
            return self._ensure_new(
                PredicateOr(self._component_name, deps, parent=parent))
        else:
            self._log.error(
                'Unknown predicate type "{0}". Ignoring'.format(ptype))
            # create dummy if it is an unknown predicate type.
            # met is set to true b/c we don't want to block on error
            return create_dummy(comp=self._component_name,
                                parent=self._action,
                                met=True)
Example #17
0
    def create(self, xmlpart):
        """
        :type xmlpart: xml.etree.ElementTree.Element
        :rtype: dict
        """
        if isinstance(xmlpart, str):
            root = ElementTree.fromstring(xmlpart)
        else:
            root = xmlpart

        actions = dict()
        for element in root.iter('Action'):
            func = verify_attribute(element, 'func', none_allowed=True)
            op_func = verify_attribute(element, 'op_func', none_allowed=True)
            name = verify_attribute(element, 'id').lower()
            staggerpath = verify_attribute(element, 'staggerpath',
                                           none_allowed=True)
            staggertime = verify_attribute(element, 'staggertime',
                                           none_allowed=True, cast=int)
            mode_controlled = verify_attribute(element, 'mode_controlled',
                                               none_allowed=True)
            disabled = verify_attribute(element, 'disabled', none_allowed=True)
            pd_enabled = verify_attribute(element, 'pd_enabled',
                                          none_allowed=True, default=True)
            pd_reason = verify_attribute(element, 'pd_reason',
                                         none_allowed=True)

            if func is not None:
                action = getattr(self._comp, func, None)
            else:
                action = getattr(self._comp, name, None)

            if op_func is None:
                # default operational dependency action to 'stop'
                op_action = getattr(self._comp, 'stop', None)
            else:
                op_action = getattr(self._comp, op_func, None)

            if action is not None:
                actions[name] = Action(name, self._comp.name, action, element,
                                       action_q=self._action_q,
                                       staggerpath=staggerpath,
                                       staggertime=staggertime,
                                       mode_controlled=mode_controlled,
                                       zkclient=self._zk,
                                       proc_client=self._proc,
                                       mode=self._mode,
                                       system=self._system,
                                       pred_list=self._pred_list,
                                       settings=self._settings,
                                       disabled=bool(disabled),
                                       pd_enabled=pd_enabled,
                                       pd_reason=pd_reason,
                                       op_action=op_action,
                                       app_state=self._app_state)
                self._log.info('Registered {0}.'.format(actions[name]))
            else:
                self._log.error('Invalid action ID or func specified: '
                                'ID: {0}, func: {1}'.format(name, func))

        return actions
Example #18
0
    def __init__(self, config, settings, queue, system, application_type,
                 cancel_flag):
        """
        :type config: dict (xml)
        :type settings: dict
        :type queue: zoom.agent.entities.unique_queue.UniqueQueue
        :type system: zoom.common.types.PlatformType
        :type application_type: zoom.common.types.ApplicationType
        :type cancel_flag: zoom.agent.entities.thread_safe_object.ThreadSafeObject
        """
        self.config = config
        self._settings = settings
        self.name = verify_attribute(self.config, 'id', none_allowed=False)
        self._log = logging.getLogger('sent.{0}.app'.format(self.name))
        # informational attributes
        self._host = socket.getfqdn()
        self._system = system
        self._predicates = list()
        self._running = True  # used to manually stop the run loop
        self._prev_state = None
        self._actions = dict()  # created in _reset_watches on zk connect
        self._env = os.environ.get('EnvironmentToUse', 'Staging')
        self._apptype = application_type
        self._restart_on_crash = \
            verify_attribute(self.config, 'restart_on_crash', none_allowed=True)
        self._post_stop_sleep = verify_attribute(self.config, 'post_stop_sleep',
                                                 none_allowed=True, cast=int,
                                                 default=5)

        # tool-like attributes
        self.listener_lock = Lock()
        self._action_queue = queue
        self._mode = ApplicationMode(
            ApplicationMode.MANUAL,
            callback=self._update_agent_node_with_app_details)
        self._state = ThreadSafeObject(
            ApplicationState.OK,
            callback=self._update_agent_node_with_app_details)
        self._start_stop_time = ''  # Default to empty string for comparison
        self._login_user = '******'  # Default to Zoom
        self._user_set_in_react = False
        self._run_check_mode = False
        self._pd_svc_key = verify_attribute(config, 'pagerduty_service',
                                            none_allowed=True)

        restartmax = verify_attribute(config, 'restartmax', none_allowed=True,
                                      cast=int, default=3)
        self._rl = RestartLogic(
            self.name,
            restartmax,
            count_callback=self._update_agent_node_with_app_details)

        self._read_only = False

        self._paths = self._init_paths(self.config, settings, application_type)

        # clients
        self.zkclient = KazooClient(
            hosts=get_zk_conn_string(),
            timeout=60.0,
            handler=SequentialThreadingHandler(),
            logger=logging.getLogger('kazoo.app.{0}'.format(self.name)))

        self.zkclient.add_listener(self._zk_listener)
        self._proc_client = self._init_proc_client(self.config,
                                                   application_type,
                                                   cancel_flag)

        self._actions = self._init_actions(settings)
        self._work_manager = self._init_work_manager(self._action_queue)
Example #19
0
    def create(self, xmlpart):
        """
        :type xmlpart: xml.etree.ElementTree.Element
        :rtype: dict
        """
        if isinstance(xmlpart, str):
            root = ElementTree.fromstring(xmlpart)
        else:
            root = xmlpart

        actions = dict()
        for element in root.iter('Action'):
            func = verify_attribute(element, 'func', none_allowed=True)
            op_func = verify_attribute(element, 'op_func', none_allowed=True)
            name = verify_attribute(element, 'id').lower()
            staggerpath = verify_attribute(element,
                                           'staggerpath',
                                           none_allowed=True)
            staggertime = verify_attribute(element,
                                           'staggertime',
                                           none_allowed=True,
                                           cast=int)
            mode_controlled = verify_attribute(element,
                                               'mode_controlled',
                                               none_allowed=True)
            disabled = verify_attribute(element, 'disabled', none_allowed=True)
            pd_enabled = verify_attribute(element,
                                          'pd_enabled',
                                          none_allowed=True,
                                          default=True)
            pd_reason = verify_attribute(element,
                                         'pd_reason',
                                         none_allowed=True)

            if func is not None:
                action = getattr(self._comp, func, None)
            else:
                action = getattr(self._comp, name, None)

            if op_func is None:
                # default operational dependency action to 'stop'
                op_action = getattr(self._comp, 'stop', None)
            else:
                op_action = getattr(self._comp, op_func, None)

            if action is not None:
                actions[name] = Action(name,
                                       self._comp.name,
                                       action,
                                       element,
                                       action_q=self._action_q,
                                       staggerpath=staggerpath,
                                       staggertime=staggertime,
                                       mode_controlled=mode_controlled,
                                       zkclient=self._zk,
                                       proc_client=self._proc,
                                       mode=self._mode,
                                       system=self._system,
                                       pred_list=self._pred_list,
                                       settings=self._settings,
                                       disabled=bool(disabled),
                                       pd_enabled=pd_enabled,
                                       pd_reason=pd_reason,
                                       op_action=op_action,
                                       app_state=self._app_state)
                self._log.info('Registered {0}.'.format(actions[name]))
            else:
                self._log.error('Invalid action ID or func specified: '
                                'ID: {0}, func: {1}'.format(name, func))

        return actions
Example #20
0
    def create(self, xmlpart, callback=None):
        """
        :type xmlpart: xml.etree.ElementTree.Element
        :type callback: types.FunctionType or None
        """
        if xmlpart is None:
            return self._create_dummy_predicate()

        if isinstance(xmlpart, str):
            root = ElementTree.fromstring(xmlpart)
        else:
            root = xmlpart

        ptype = verify_attribute(root, 'type').lower()

        if ptype == 'simple':
            return self._ensure_new(
                SimplePredicate(self._component_name,
                                self._settings,
                                parent=self._parent),
                callback=callback
            )
        elif ptype == PredicateType.ZOOKEEPERNODEEXISTS:
            return self._ensure_new(
                ZookeeperNodeExists(self._component_name,
                                    self._settings,
                                    self.zkclient,
                                    verify_attribute(root, 'path'),
                                    parent=self._parent),
                callback=callback
            )
        elif ptype == PredicateType.ZOOKEEPERHASCHILDREN:
            return self._ensure_new(
                ZookeeperHasChildren(self._component_name,
                                     self._settings,
                                     self.zkclient,
                                     verify_attribute(root, 'path'),
                                     parent=self._parent),
                callback=callback
            )
        elif ptype == PredicateType.ZOOKEEPERHASGRANDCHILDREN:
            return self._ensure_new(
                ZookeeperHasGrandChildren(self._component_name,
                                          self._settings,
                                          self.zkclient,
                                          verify_attribute(root, 'path'),
                                          parent=self._parent),
                callback=callback
            )
        elif ptype == PredicateType.ZOOKEEPERGOODUNTILTIME:
            return self._ensure_new(
                ZookeeperGoodUntilTime(self._component_name,
                                       self._settings,
                                       self.zkclient,
                                       verify_attribute(root, 'path'),
                                       parent=self._parent),
                callback=callback
            )
        elif ptype == PredicateType.PROCESS:
            return self._ensure_new(
                PredicateProcess(self._component_name,
                                 self._settings,
                                 self._proc_client,
                                 verify_attribute(root, 'interval', cast=float),
                                 parent=self._parent),
                callback=callback
            )
        elif ptype == PredicateType.HEALTH:
            return self._ensure_new(
                PredicateHealth(self._component_name,
                                self._settings,
                                verify_attribute(root, 'command'),
                                verify_attribute(root, 'interval', cast=float),
                                self._system,
                                parent=self._parent),
                callback=callback
            )
        elif ptype == PredicateType.HOLIDAY:
            return self._ensure_new(PredicateHoliday(self._component_name,
                                                     self._settings,
                                                     self.zkclient,
                                                     parent=self._parent),
                                    callback=callback
            )
        elif ptype == PredicateType.WEEKEND:
            return self._ensure_new(PredicateWeekend(self._component_name,
                                                     self._settings,
                                                     parent=self._parent),
                                    callback=callback
            )
        elif ptype == PredicateType.TIME:
            return self._ensure_new(
                PredicateTime(self._component_name,
                              self._settings,
                              start=verify_attribute(root, 'start',
                                                     none_allowed=True),
                              stop=verify_attribute(root, 'stop',
                                                    none_allowed=True),
                              weekdays=verify_attribute(root, 'weekdays',
                                                        none_allowed=True),
                              parent=self._parent),
                callback=callback
            )

        # below, use recursion to get nested predicates
        elif ptype == PredicateType.NOT:
            for element in root.findall('Predicate'):
                dep = self.create(element, callback=callback)
                return self._ensure_new(
                    PredicateNot(self._component_name, self._settings, dep)
                )
        elif ptype == PredicateType.AND:
            deps = list()
            for element in root.findall('Predicate'):
                deps.append(self.create(element, callback=callback))
            return self._ensure_new(
                PredicateAnd(self._component_name, self._settings, deps)
            )
        elif ptype == PredicateType.OR:
            deps = list()
            for element in root.findall('Predicate'):
                deps.append(self.create(element, callback=callback))
            return self._ensure_new(
                PredicateOr(self._component_name, self._settings, deps)
            )
        else:
            self._log.error('Unknown predicate type "{0}". Ignoring'
                            .format(ptype))

            return self._create_dummy_predicate()
Example #21
0
    def __init__(self, config, settings, queue, system, application_type,
                 cancel_flag):
        """
        :type config: dict (xml)
        :type settings: dict
        :type queue: zoom.agent.entities.unique_queue.UniqueQueue
        :type system: zoom.common.types.PlatformType
        :type application_type: zoom.common.types.ApplicationType
        :type cancel_flag: zoom.agent.entities.thread_safe_object.ThreadSafeObject
        """
        self.config = config
        self._settings = settings
        self.name = verify_attribute(self.config, 'id', none_allowed=False)
        self._log = logging.getLogger('sent.{0}.app'.format(self.name))
        # informational attributes
        self._host = socket.getfqdn()
        self._system = system
        self._predicates = list()
        self._running = True  # used to manually stop the run loop
        self._prev_state = None
        self._actions = dict()  # created in _reset_watches on zk connect
        self._env = os.environ.get('EnvironmentToUse', 'Staging')
        self._apptype = application_type
        self._restart_on_crash = \
            verify_attribute(self.config, 'restart_on_crash', none_allowed=True)
        self._post_stop_sleep = verify_attribute(self.config,
                                                 'post_stop_sleep',
                                                 none_allowed=True,
                                                 cast=int,
                                                 default=5)

        # tool-like attributes
        self.listener_lock = Lock()
        self._action_queue = queue
        self._mode = ApplicationMode(
            ApplicationMode.MANUAL,
            callback=self._update_agent_node_with_app_details)
        self._state = ThreadSafeObject(
            ApplicationState.OK,
            callback=self._update_agent_node_with_app_details)
        self._start_stop_time = ''  # Default to empty string for comparison
        self._login_user = '******'  # Default to Zoom
        self._user_set_in_react = False
        self._run_check_mode = False
        self._pd_svc_key = verify_attribute(config,
                                            'pagerduty_service',
                                            none_allowed=True)

        restartmax = verify_attribute(config,
                                      'restartmax',
                                      none_allowed=True,
                                      cast=int,
                                      default=3)
        self._rl = RestartLogic(
            self.name,
            restartmax,
            count_callback=self._update_agent_node_with_app_details)

        self._read_only = False

        self._paths = self._init_paths(self.config, settings, application_type)

        # clients
        self.zkclient = KazooClient(hosts=get_zk_conn_string(),
                                    timeout=60.0,
                                    handler=SequentialThreadingHandler(),
                                    logger=logging.getLogger(
                                        'kazoo.app.{0}'.format(self.name)))

        self.zkclient.add_listener(self._zk_listener)
        self._proc_client = self._init_proc_client(self.config,
                                                   application_type,
                                                   cancel_flag)

        self._actions = self._init_actions(settings)
        self._work_manager = self._init_work_manager(self._action_queue)