Beispiel #1
0
 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")
Beispiel #2
0
 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),
                 )
             )
Beispiel #3
0
 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
Beispiel #4
0
    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")
Beispiel #5
0
 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)
Beispiel #6
0
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
Beispiel #7
0
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")
Beispiel #8
0
    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")
Beispiel #9
0
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