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)
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()
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()
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()
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)
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)
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
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
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
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
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
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)
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)
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
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)
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()
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)