def add_server(self, server_enum, timeout=30): # add new server (collrelay or snmp_relay) identity_str = process_tools.zmq_identity_str(self.__msg_prefix, short=True) zmq_context = self.__process.zmq_context cur_timeout = timeout client_send = zmq_context.socket(zmq.PUSH) client_recv = zmq_context.socket(zmq.SUB) client_send.setsockopt(zmq.LINGER, cur_timeout * 2) client_recv.setsockopt_string(zmq.SUBSCRIBE, identity_str) send_conn_str = "{}".format( process_tools.get_zmq_ipc_name( "receiver", s_name=server_enum.value, connect_to_root_instance=True, )) recv_conn_str = "{}".format( process_tools.get_zmq_ipc_name( "sender", s_name=server_enum.value, connect_to_root_instance=True, )) self.log("adding server ({} -> {} -> {})".format( send_conn_str, server_enum.value, recv_conn_str, )) self.__sock_list.append(client_send) self.__sock_list.append(client_recv) self.__sock_lut[server_enum] = (client_send, client_recv) client_send.connect(send_conn_str) client_recv.connect(recv_conn_str) self.register_poller(client_recv, zmq.POLLIN, self._handle_message)
def init_connection(self): if self.args.identity_string: self.identity_str = self.args.identity_string else: self.identity_str = process_tools.zmq_identity_str( self.args.identity_substring) s_type = "DEALER" if not self.args.split else "PUSH" client = self.zmq_context.socket(getattr(zmq, s_type)) client.setsockopt_string(zmq.IDENTITY, self.identity_str) client.setsockopt(zmq.LINGER, self.args.timeout) if self.args.protocoll == "ipc": if self.args.root: process_tools.ALLOW_MULTIPLE_INSTANCES = False conn_str = "{}".format( process_tools.get_zmq_ipc_name( self.args.host, s_name=self.args.server_name, connect_to_root_instance=self.args.root)) else: conn_str = "{}://{}:{:d}".format(self.args.protocoll, self.args.host, self.args.port) if self.args.split: recv_conn_str = "{}".format( process_tools.get_zmq_ipc_name( self.args.split, s_name=self.args.server_name, connect_to_root_instance=self.args.root)) recv_sock = self.zmq_context.socket(zmq.ROUTER) recv_sock.setsockopt_string(zmq.IDENTITY, self.identity_str) recv_sock.setsockopt(zmq.LINGER, self.args.timeout) else: recv_conn_str = None recv_sock = None self.send_sock = client self.recv_sock = recv_sock self.conn_str = conn_str self.recv_conn_str = recv_conn_str self.verbose( "socket_type is {}\nIdentity_string is '{}'\nconnection_string is '{}'" .format( s_type, self.identity_str, conn_str, )) if self.args.split: self.verbose( "receive connection string is '{}'".format(recv_conn_str))
def call(self, dc_action): self.__msg_id += 1 _msg_id = process_tools.zmq_identity_str("{}_{:04d}".format( self.__msg_prefix, self.__msg_id), short=True) dc_action.start_time = time.time() self.__pending_messages[_msg_id] = dc_action srv_com = server_command.srv_command(command=dc_action.command, identity=_msg_id) _to_localhost = dc_action.kwargs.pop("connect_to_localhost", False) # print("+++", _msg_id, id(dc_action), dc_action.special_instance.Meta.name) # destination _target_ip = "127.0.0.1" if _to_localhost else dc_action.hbc.ip srv_com["host"] = _target_ip srv_com["port"] = self.__hm_port # special raw mode srv_com["raw"] = "True" # add arguments and keys srv_com["arg_list"] = " ".join( list(dc_action.args) + [ "--{}={}".format(_key, _value) for _key, _value in dc_action.kwargs.items() ]) # add additional keys # for key, value in dc_action.kwargs.iteritems(): # srv_com[key] = "{:d}".format(value) if isinstance(value, int) else value dc_action.log( "calling server '{}' for {}, command is '{}', {}, {}".format( dc_action.srv_enum.name, _target_ip, dc_action.command, "args is '{}'".format(", ".join([ str(value) for value in dc_action.args ])) if dc_action.args else "no arguments", ", ".join([ "{}='{}'".format(key, str(value)) for key, value in dc_action.kwargs.items() ]) if dc_action.kwargs else "no kwargs", )) try: self.__sock_lut[dc_action.srv_enum][0].send_unicode(str(srv_com)) except: dc_action.log( "unable to send: {}".format(process_tools.get_except_info()), logging_tools.LOG_LEVEL_ERROR) self.feed_result(_msg_id, None)
def _init_network_sockets(self): zmq_id_name = "/etc/sysconfig/host-monitoring.d/0mq_id" my_0mq_id = uuid_tools.get_uuid().get_urn() if not config_store.ConfigStore.exists(ZMQ_ID_MAP_STORE): create_0mq_cs = True if os.path.exists(zmq_id_name): try: zmq_id_dict = { cur_el.attrib["bind_address"]: (cur_el.text, True if "virtual" in cur_el.attrib else False) for cur_el in etree.fromstring(file(zmq_id_name, "r").read()).xpath( ".//zmq_id[@bind_address]", smart_strings=False) } except: self.log( "error reading from {}: {}".format( zmq_id_name, process_tools.get_except_info()), logging_tools.LOG_LEVEL_ERROR) zmq_id_dict = {} else: zmq_id_dict = {} if "*" not in zmq_id_dict: zmq_id_dict["*"] = (my_0mq_id, False) _cs = config_store.ConfigStore( ZMQ_ID_MAP_STORE, log_com=self.log, read=False, prefix="bind", access_mode=config_store.AccessModeEnum.LOCAL, fix_access_mode=True, ) for _idx, _key in enumerate(["*"] + sorted( [_key for _key in zmq_id_dict.keys() if _key not in ["*"]])): _cs["{:d}".format(_idx)] = { "address": _key, "uuid": zmq_id_dict[_key][0], "virtual": zmq_id_dict[_key][1] } else: # read from cs _cs = config_store.ConfigStore( ZMQ_ID_MAP_STORE, log_com=self.log, prefix="bind", access_mode=config_store.AccessModeEnum.LOCAL, fix_access_mode=True, ) create_0mq_cs = False if "0" not in _cs: _cs["0"] = { "address": "*", "virtual": False, "uuid": my_0mq_id, } if _cs["0"]["uuid"] != my_0mq_id: self.log( "0MQ id from cluster ({}) differs from host-monitoring 0MQ id ({})" .format( my_0mq_id, _cs["bind_0_uuid"], )) # code snippet to update value _cur = _cs["0"] _cur["uuid"] = my_0mq_id _cs["0"] = _cur create_0mq_cs = True if create_0mq_cs: _cs.write() # get all ipv4 interfaces with their ip addresses, dict: interfacename -> IPv4 zmq_id_dict = {} for _idx in _cs.keys(): _bind = _cs[_idx] zmq_id_dict[_bind["address"]] = ( _bind["uuid"], _bind["virtual"], ) ipv4_dict = { cur_if_name: [ip_tuple["addr"] for ip_tuple in value[2]][0] for cur_if_name, value in [(if_name, netifaces.ifaddresses(if_name)) for if_name in netifaces.interfaces()] if 2 in value } # ipv4_lut = dict([(value, key) for key, value in ipv4_dict.iteritems()]) ipv4_addresses = ipv4_dict.values() if zmq_id_dict.keys() == ["*"]: # wildcard bind pass else: if "*" in zmq_id_dict: wc_urn, wc_virtual = zmq_id_dict.pop("*") for target_ip in ipv4_addresses: if target_ip not in zmq_id_dict: zmq_id_dict[target_ip] = (wc_urn, wc_virtual) ref_id = "*" if "*" in zmq_id_dict else "127.0.0.1" self.zeromq_id = zmq_id_dict[ref_id][0].split(":")[-1] self.log("0MQ bind info (global 0MQ id is {})".format(self.zeromq_id)) for key in sorted(zmq_id_dict.iterkeys()): self.log("bind address {:<15s}: {}{}".format( key, zmq_id_dict[key][0], " is virtual" if zmq_id_dict[key][1] else "")) self.zmq_id_dict = zmq_id_dict self._bind_external() sock_list = [ ("ipc", "vector", zmq.PULL, 512, None, ""), # @UndefinedVariable ("ipc", "command", zmq.PULL, 512, self._recv_ext_command, ""), # @UndefinedVariable ("ipc", "result", zmq.ROUTER, 512, None, process_tools.zmq_identity_str("host_monitor") ) # @UndefinedVariable ] for _sock_proto, short_sock_name, sock_type, hwm_size, dst_func, zmq_id in sock_list: sock_name = process_tools.get_zmq_ipc_name(short_sock_name, s_name="collserver") file_name = sock_name[5:] self.log("init {} ipc_socket '{}' (HWM: {:d})".format( short_sock_name, sock_name, hwm_size)) if os.path.exists(file_name): self.log("removing previous file") try: os.unlink(file_name) except: self.log("... {}".format(process_tools.get_except_info()), logging_tools.LOG_LEVEL_ERROR) wait_iter = 0 while os.path.exists(file_name) and wait_iter < 100: self.log("socket {} still exists, waiting".format(sock_name)) time.sleep(0.1) wait_iter += 1 cur_socket = self.zmq_context.socket(sock_type) if zmq_id: cur_socket.setsockopt_string(zmq.IDENTITY, zmq_id) # @UndefinedVariable try: process_tools.bind_zmq_socket(cur_socket, sock_name) # client.bind("tcp://*:8888") except zmq.ZMQError: self.log( "error binding {}: {}".format( short_sock_name, process_tools.get_except_info()), logging_tools.LOG_LEVEL_CRITICAL) raise else: setattr(self, "{}_socket".format(short_sock_name), cur_socket) _backlog_size = self.CC.CS["hm.socket.backlog.size"] os.chmod(file_name, 0777) cur_socket.setsockopt(zmq.LINGER, 0) # @UndefinedVariable cur_socket.setsockopt(zmq.SNDHWM, hwm_size) # @UndefinedVariable cur_socket.setsockopt(zmq.RCVHWM, hwm_size) # @UndefinedVariable if dst_func: self.register_poller(cur_socket, zmq.POLLIN, dst_func) # @UndefinedVariable
def send_and_receive_zmq(target_host, command, *args, **kwargs): identity_str = process_tools.zmq_identity_str( kwargs.pop("identity_string", "srv_com")) zmq_context = kwargs.pop("zmq_context") cur_timeout = kwargs.pop("timeout", 20) client_send = zmq_context.socket(zmq.PUSH) client_recv = zmq_context.socket(zmq.SUB) client_send.setsockopt(zmq.LINGER, cur_timeout * 2) client_recv.setsockopt(zmq.SUBSCRIBE, identity_str) # kwargs["server"] : collrelay or snmprelay server_name = kwargs.pop("server") send_conn_str = "{}".format( process_tools.get_zmq_ipc_name( kwargs.pop("process", "receiver"), s_name=server_name, connect_to_root_instance=True, )) recv_conn_str = "{}".format( process_tools.get_zmq_ipc_name( kwargs.pop("process", "sender"), s_name=server_name, connect_to_root_instance=True, )) client_send.connect(send_conn_str) client_recv.connect(recv_conn_str) srv_com = server_command.srv_command(command=command, identity=identity_str) srv_com["host"] = target_host srv_com["raw"] = "True" srv_com["arg_list"] = " ".join(args) # add additional keys for key, value in kwargs.items(): srv_com[key] = "{:d}".format(value) if isinstance(value, int) else value s_time = time.time() client_send.send_unicode(str(srv_com)) client_send.close() if client_recv.poll(cur_timeout * 1000): id_str = client_recv.recv() else: id_str = None if id_str and client_recv.getsockopt(zmq.RCVMORE): e_time = time.time() if client_recv.poll((cur_timeout - (e_time - s_time)) * 1000): recv_str = client_recv.recv() else: recv_str = None else: recv_str = None client_recv.close() if recv_str and id_str: try: srv_reply = server_command.srv_command(source=recv_str) except: # srv_reply = None raise else: # srv_reply = None raise SystemError("timeout ({:d} seconds) exceeded".format( int(cur_timeout))) return srv_reply