def get(self, request): cur_routing = routing.SrvTypeRouting(force="force" in request.POST) _return = { "service_types": {key: True for key in routing.SrvTypeRouting().service_types}, "routing": cur_routing.resolv_dict, "local_device": str(cur_routing.local_device.full_name) if cur_routing.local_device is not None else None, "internal_dict": cur_routing.internal_dict, "unroutable_configs": cur_routing.unroutable_configs, } return HttpResponse(json.dumps(_return), content_type="application/json")
def handle(self, **options): _csr = routing.SrvTypeRouting(force=True) _rsd = _csr.resolv_dict print( "local device is {}".format( str(_csr.local_device), ) ) for _conf in sorted(_rsd): _c_list = _rsd[_conf] print( "config '{}' ({})".format( _conf, logging_tools.get_plural("entry", len(_c_list)) ) ) for _name, _ip, _dev_pk, _penalty, _conf_names in _c_list: print( " {0:30s} {1:20s} pk={2:<4d} penalty={3:<4d}, config names: {4}".format( _name, _ip, _dev_pk, _penalty, ", ".join(_conf_names), ) )
def post(self, request): cur_routing = routing.SrvTypeRouting(force=True) _server_list = [] for _server in cur_routing.resolv_dict.get(icswServiceEnum.cluster_server.name, []): srv_com = server_command.srv_command(command="server_status") _res = contact_server( request, icswServiceEnum.cluster_server, srv_com, timeout=10, connection_id="server_status", target_server_id=_server[2], ) if _res is not None and _res.tree is not None: # dirty stuff _res["command"].attrib["server_name"] = _server[0] _res["command"].attrib["server_id"] = "{:d}".format(_server[2]) _tree = _res.tree else: srv_com["command"].attrib["server_name"] = _server[0] srv_com["command"].attrib["server_id"] = "{:d}".format(_server[2]) _tree = srv_com.tree for _node in _tree.iter(): if str(_node.tag).startswith("{"): _node.tag = _node.tag.split("}", 1)[1] _server_list.append(_tree) request.xml_response["result"] = _server_list
def post(self, request): _post = request.POST to_dev_pk = int(_post["device"]) to_dev = device.objects.prefetch_related( "netdevice_set__net_ip_set__network__network_type" ).get( Q(pk=to_dev_pk) ) # from-device is where virtual desktop client config is set server_by_type = config_tools.server_check(server_type="virtual_desktop_client") from_dev = server_by_type.effective_device if from_dev is None: # fall back to local device cur_routing = routing.SrvTypeRouting(force=True) from_dev = cur_routing.local_device from_server_check = config_tools.server_check(device=from_dev, config=None, server_type="node") to_server_check = config_tools.server_check(device=to_dev, config=None, server_type="node") # calc route to it and use target ip _router = config_tools.RouterObject(logger) route = from_server_check.get_route_to_other_device(_router, to_server_check, allow_route_to_other_networks=True, prefer_production_net=True) if route: ip = route[0][3][1][0] else: ip = "127.0.0.1" # try fallback (it might not work, but it will not make things more broken) return HttpResponse(json.dumps({"ip": ip}), content_type="application/json")
def send_to_remote_server(self, srv_type_enum, send_obj): from initat.cluster.backbone import routing if self.__target_dict is None: from initat.cluster.backbone import db_tools db_tools.close_connection() self.__target_dict = {} self.__strs_router = routing.SrvTypeRouting(log_com=self.log) if srv_type_enum not in self.__target_dict: self.__target_dict[srv_type_enum] = RemoteServerAddress(self, srv_type_enum) _rsa = self.__target_dict[srv_type_enum] _rsa.check_for_address(self.__strs_router) return self.send_to_remote_server_int(_rsa, send_obj)
def contact_server(request, srv_type_enum, send_com, **kwargs): # log lines _log_lines = [] # xml request _xml_req = kwargs.get("xml_request", hasattr(request, "xml_response")) # simple mapping cur_router = routing.SrvTypeRouting() if srv_type_enum.name not in cur_router: # try again harder (rebuild routing table) cur_router = routing.SrvTypeRouting(force=True) if srv_type_enum.name in cur_router: # print send_com.pretty_print() if request.user: send_com["user_id"] = request.user.pk _conn = net_tools.ZMQConnection(kwargs.get("connection_id", "webfrontend"), timeout=kwargs.get("timeout", 10)) # split to node-local servers ? if kwargs.get("split_send", True): send_list = cur_router.check_for_split_send( srv_type_enum.name, send_com) if cur_router.no_bootserver_devices: # for _miss_pk, _miss_name in cur_router.no_bootserver_devices: cur_router._log( request, _log_lines, "no bootserver for {}: {}".format( logging_tools.get_plural( "device", len(cur_router.no_bootserver_devices)), ", ".join( sorted([ _v[1] for _v in cur_router.no_bootserver_devices ])), ), logging_tools.LOG_LEVEL_WARN) else: send_list = [(None, send_com)] if send_list: _conn_strs = [] for _send_id, _send_com in send_list: if _send_id is None: # get send_id from target_server_id _send_id = kwargs.get("target_server_id", None) # no split send, decide based on target_server_id # _conn_str = cur_router.get_connection_string(srv_type, server_id=) # else: # print "*", _send_id _connect_port_enum = kwargs.get("connect_port_enum", None) _conn_str = cur_router.get_connection_string( srv_type_enum, server_id=_send_id, connect_port_enum=_connect_port_enum) _conn_strs.append(_conn_str) _conn.add_connection(_conn_str, _send_com, multi=True, immediate=True) log_result = kwargs.get("log_result", True) log_error = kwargs.get("log_error", True) cur_router.start_result_feed() # merge results [ cur_router.feed_srv_result( send_com, _res, request if _xml_req else None, _conn_str, _log_lines, log_result, log_error, srv_type_enum, ) for _res, _conn_str in zip(_conn.loop(), _conn_strs) ] result = cur_router.result else: result = None else: result = None _err_str = u"ServiceType '{}' not defined in routing".format( srv_type_enum.name) cur_router._log(request, _log_lines, _err_str, logging_tools.LOG_LEVEL_ERROR) if _xml_req: return result else: return result, _log_lines
def device_syslog(opt_ns, cur_dev, j_logs): print( "Information about device '{}' (full name {}, devicegroup {})".format( str(cur_dev), str(cur_dev.full_name), str(cur_dev.device_group))) print("UUID is '{}', database-ID is {:d}".format(cur_dev.uuid, cur_dev.pk)) _cr = routing.SrvTypeRouting(force=True, ignore_errors=True) _ST = "logcheck-server" if _ST in _cr.service_types: _inst_xml = InstanceXML(quiet=True) # get logcheck-server IP _ls_ip = _cr[_ST][0][1] # get logcheck-server Port _ls_port = _inst_xml.get_port_dict(_ST, ptype="command") _sc = server_command.srv_command(command="get_syslog", ) _sc["devices"] = _sc.builder( "devices", *[ _sc.builder( "device", pk="{:d}".format(cur_dev.pk), lines="{:d}".format(opt_ns.loglines), minutes="{:d}".format(opt_ns.minutes), ) ]) _conn_str = "tcp://{}:{:d}".format(_ls_ip, _ls_port) _result = net_tools.ZMQConnection("icsw_state_{:d}".format( os.getpid())).add_connection( _conn_str, _sc, ) if _result is not None: _dev = _result.xpath(".//ns:devices/ns:device[@pk]")[0] _lines = _result.xpath("ns:lines", start_el=_dev)[0] _rates = _result.xpath("ns:rates", start_el=_dev) if _rates: _rates = { int(_el.get("timeframe")): float(_el.get("rate")) for _el in _rates[0] } print("rate info: {}".format(", ".join([ "{:.2f} lines/sec in {}".format( _rates[_seconds], logging_tools.get_diff_time_str(_seconds)) for _seconds in sorted(_rates) ]))) else: print("no rate info found") print(_rates) _out_lines = logging_tools.NewFormList() for _entry in server_command.decompress(_lines.text, json=True): _out_lines.append([ logging_tools.form_entry(_entry["line_id"], header="idx"), logging_tools.form_entry( "{:04d}-{:02d}-{:02d} {:02d}:{:02d}:{:02d}".format( *_entry["line_datetime_parsed"]), header="Timestamp", ), ] + [ logging_tools.form_entry(_entry[_key], header=_key) for _key in ["hostname", "priority", "facility", "tag"] ] + [ logging_tools.form_entry(_entry["text"], header="text"), ]) print(str(_out_lines)) else: print("got no result from {} ({})".format(_conn_str, _ST)) else: print("No logcheck-server found, skipping syslog display")
def __init__(self, log_com, full_build, routing_fingerprint=None, router_obj=None): tm = logging_tools.MeasureTime(log_com=self.log) self.log_com = log_com self.router = routing.SrvTypeRouting(log_com=self.log_com) self.instance_xml = InstanceXML(log_com=self.log, quiet=True) # build cache to speed up config generation # stores various cached objects # routing handling if router_obj is None: # slave, no consumer self.consumer = None self.routing_fingerprint = routing_fingerprint # must exist self.__trace_gen = MonHostTraceGeneration.objects.get( Q(fingerprint=self.routing_fingerprint)) else: # master, install the egg consumer self.consumer = server_mixins.EggConsumeObject(self) self.consumer.init( {"SERVICE_ENUM_NAME": icswServiceEnum.monitor_server.name}) self.routing_fingerprint = router_obj.fingerprint # get generation try: self.__trace_gen = MonHostTraceGeneration.objects.get( Q(fingerprint=self.routing_fingerprint)) except MonHostTraceGeneration.DoesNotExist: self.log("creating new tracegeneration") self.__trace_gen = router_obj.create_trace_generation() # delete old ones MonHostTrace.objects.exclude( Q(generation=self.__trace_gen)).delete() # global luts # print("i0") self.mcc_lut_3 = { _check.pk: _check for _check in mon_check_command.objects.all() } # add dummy entries for _value in self.mcc_lut_3.values(): # why ? FIXME # _value.mccs_id = None # _value.check_command_pk = _value.pk pass self.mcc_lut = { key: (v0, v1, v2) for key, v0, v1, v2 in mon_check_command.objects.all().values_list( "pk", "name", "description", "config_rel__name") } # lookup table for config -> mon_check_commands self.mcc_lut_2 = {} for v_list in mon_check_command.objects.all().values_list( "name", "config_rel__name"): self.mcc_lut_2.setdefault(v_list[1], []).append(v_list[0]) # print("i1") # import pprint # pprint.pprint(self.mcc_lut) # host list, set from caller self.host_list = [] self.dev_templates = None self.serv_templates = None self.single_build = False self.debug = False self.__var_cache = VarCache(prefill=full_build, def_dict={ "SNMP_VERSION": 2, "SNMP_READ_COMMUNITY": "public", "SNMP_WRITE_COMMUNITY": "private", }) self.join_char = "_" if global_config["SAFE_NAMES"] else " " # device_group user access self.dg_user_access = {} mon_user_pks = list( user.objects.filter(Q(mon_contact__pk__gt=0)).values_list( "pk", flat=True)) for _dg in device_group.objects.all().prefetch_related("user_set"): self.dg_user_access[_dg.pk] = list([ _user for _user in _dg.user_set.all() if _user.pk in mon_user_pks ]) # all hosts dict self.all_hosts_dict = { cur_dev.pk: cur_dev for cur_dev in device.objects.filter( Q(device_group__enabled=True) & Q(enabled=True)).select_related( "domain_tree_node", "device_group").prefetch_related( "monhosttrace_set") } for _host in self.all_hosts_dict.values(): _host.reachable = True # print(_res) # traces in database self.log("traces found in database: {:d}".format( MonHostTrace.objects.all().count())) # read traces self.__host_traces = {} for _trace in MonHostTrace.objects.filter( Q(generation=self.__trace_gen)): self.__host_traces.setdefault(_trace.device_id, []).append(_trace) # import pprint # pprint.pprint(self.__host_traces) # host / service clusters clusters = {} for _obj, _name in [ (mon_host_cluster, SpecialTypesEnum.mon_host_cluster), (mon_service_cluster, SpecialTypesEnum.mon_service_cluster) ]: _lut = {} _query = _obj.objects.all() if _name == SpecialTypesEnum.mon_service_cluster: _query = _query.select_related("mon_check_command") for _co in _query: _lut[_co.pk] = _co.main_device_id _co.devices_list = [] clusters.setdefault(_name, {}).setdefault(_co.main_device_id, []).append(_co) for _entry in _obj.devices.through.objects.all(): if _name == SpecialTypesEnum.mon_host_cluster: _pk = _entry.mon_host_cluster_id else: _pk = _entry.mon_service_cluster_id _tco = [ _co for _co in clusters[_name][_lut[_pk]] if _co.pk == _pk ][0] _tco.devices_list.append(_entry.device_id) # clusters[_name][_entry.] self.__clusters = clusters # host / service dependencies deps = {} for _obj, _name in [ (mon_host_dependency, SpecialTypesEnum.mon_host_dependency), (mon_service_dependency, SpecialTypesEnum.mon_service_dependency) ]: _lut = {} _query = _obj.objects.all().prefetch_related( "devices", "dependent_devices") if _name == SpecialTypesEnum.mon_host_dependency: _query = _query.select_related( "mon_host_dependency_templ", "mon_host_dependency_templ__dependency_period", ) else: _query = _query.select_related( "mon_service_cluster", "mon_check_command", "dependent_mon_check_command", "mon_service_dependency_templ", "mon_service_dependency_templ__dependency_period", ) for _do in _query: # == slaves _do.devices_list = [] # == dependent devices _do.master_list = [] _lut[_do.pk] = [] for _dd in _do.dependent_devices.all(): _lut[_do.pk].append(_dd.pk) deps.setdefault(_name, {}).setdefault(_dd.pk, []).append(_do) for _entry in _obj.devices.through.objects.all(): if _name == SpecialTypesEnum.mon_host_dependency: _pk = _entry.mon_host_dependency_id else: _pk = _entry.mon_service_dependency_id for _devpk in _lut[_pk]: _tdo = [ _do for _do in deps[_name][_devpk] if _do.pk == _pk ][0] _tdo.devices_list.append(_entry.device_id) for _entry in _obj.dependent_devices.through.objects.all(): if _name == SpecialTypesEnum.mon_host_dependency: _pk = _entry.mon_host_dependency_id else: _pk = _entry.mon_service_dependency_id for _devpk in _lut[_pk]: _tdo = [ _do for _do in deps[_name][_devpk] if _do.pk == _pk ][0] _tdo.master_list.append(_entry.device_id) self.__dependencies = deps # init snmp sink self.snmp_sink = SNMPSink(log_com) tm.step("init build_cache")
def contact_server(request, srv_type_enum, send_com, **kwargs): # log lines _log_lines = [] # xml request _xml_req = kwargs.get("xml_request", hasattr(request, "xml_response")) # simple mapping cur_router = routing.SrvTypeRouting() if srv_type_enum.name not in cur_router: # try again harder (rebuild routing table) cur_router = routing.SrvTypeRouting(force=True) if srv_type_enum.name in cur_router: # com = send_com["*command"] # connection id _conn_id = kwargs.get("connection_id", "webfrontend") # memcache key to catch multi-calls to server with this is # mc_key = "$$MCTS_KD_{}".format(_conn_id) # memcache key for connection dict mc_key = "{}_WebConDict".format(settings.ICSW_CACHE_KEY) mc_client = _C_MCC.client # print(dir(mc_client)) # print("c=", _conn_id) # try to set default value (will most likely fail but never mind) _default_c = {"open": {}} # the open dict has the format # conn_id -> (last_time_used, request_pending) mc_client.add(mc_key, _default_c) _cur_time = time.time() _default_time = _cur_time - 3600 _run_idx = 0 while True: _c = mc_client.gets(mc_key) # print("gets={}".format(str(_c))) if _c is None: # should never happen, set default value again mc_client.add(mc_key, _default_c) continue if isinstance(_c["open"], list): _c["open"] = {} while True: _run_idx += 1 cur_conn_id = "{}_{:d}".format(_conn_id, _run_idx) _open_entry = _c["open"].get(cur_conn_id, (_default_time, False)) # connection has to be closed for at least 10 seconds if not _open_entry[1] and _open_entry[0] < _cur_time - 10: # print("reuse") break _c["open"][cur_conn_id] = (_cur_time, True) # import pprint # pprint.pprint(_c["open"]) _ret = mc_client.cas(mc_key, _c) # print("_ret={}".format(_ret)) if _ret: break else: # print("ERRLoop") pass # print("CurConnId={}".format(cur_conn_id)) # print("list='{}' ({})".format(_c["open"], com)) # print send_com.pretty_print() if request.user: send_com["user_id"] = request.user.pk _conn = net_tools.ZMQConnection(cur_conn_id, timeout=kwargs.get("timeout", 10)) # split to node-local servers ? if kwargs.get("split_send", True): send_list = cur_router.check_for_split_send( srv_type_enum.name, send_com) if cur_router.no_bootserver_devices: # for _miss_pk, _miss_name in cur_router.no_bootserver_devices: cur_router._log( request, _log_lines, "no bootserver for {}: {}".format( logging_tools.get_plural( "device", len(cur_router.no_bootserver_devices)), ", ".join( sorted([ _v[1] for _v in cur_router.no_bootserver_devices ])), ), logging_tools.LOG_LEVEL_WARN) else: send_list = [(None, send_com)] if send_list: _conn_strs = [] for _send_id, _send_com in send_list: if _send_id is None: # get send_id from target_server_id _send_id = kwargs.get("target_server_id", None) # no split send, decide based on target_server_id # _conn_str = cur_router.get_connection_string(srv_type, server_id=) # else: # print "*", _send_id _connect_port_enum = kwargs.get("connect_port_enum", None) _conn_str = cur_router.get_connection_string( srv_type_enum, server_id=_send_id, connect_port_enum=_connect_port_enum) _conn_strs.append(_conn_str) _conn.add_connection(_conn_str, _send_com, multi=True, immediate=True) log_result = kwargs.get("log_result", True) log_error = kwargs.get("log_error", True) cur_router.start_result_feed() # merge results [ cur_router.feed_srv_result( send_com, _res, request if _xml_req else None, _conn_str, _log_lines, log_result, log_error, srv_type_enum, ) for _res, _conn_str in zip(_conn.loop(), _conn_strs) ] result = cur_router.result else: result = None # remove cur_conn_id from cache while True: _c = mc_client.gets(mc_key) if _c is None: # should never happen, set default value again mc_client.add(mc_key, _default_c) continue # if cur_conn_id in _c["open"]: # _c["open"].remove(cur_conn_id) _c["open"][cur_conn_id] = (time.time(), False) _ret = mc_client.cas(mc_key, _c) # print("_ret={}".format(_ret)) if _ret: break else: # try again continue # print("done", cur_conn_id) else: result = None _err_str = "ServiceType '{}' not defined in routing".format( srv_type_enum.name) cur_router._log(request, _log_lines, _err_str, logging_tools.LOG_LEVEL_ERROR) if _xml_req: return result else: return result, _log_lines