예제 #1
0
파일: server.py 프로젝트: bopopescu/icsw
 def _check_uuid(self):
     self.log("uuid checking")
     self.log(" - cluster_device_uuid is '{}'".format(uuid_tools.get_uuid().get_urn()))
     my_dev = device.objects.get(Q(pk=global_config["SERVER_IDX"]))
     file_uuid = uuid_tools.get_uuid().get_urn().split(":")[2]
     if file_uuid != my_dev.uuid:
         self.log(
             "UUID differs from DB entry ({} [file] != {} [DB]), correcting DB entry".format(
                 file_uuid,
                 my_dev.uuid
             ),
             logging_tools.LOG_LEVEL_ERROR
         )
         my_dev.uuid = file_uuid
         my_dev.save()
     # recognize for which devices i am responsible
     dev_r = cluster_location.DeviceRecognition()
     self.device_r = dev_r
     if dev_r.device_dict:
         self.log(
             " - i am also host for {}: {}".format(
                 logging_tools.get_plural("virtual device", len(dev_r.device_dict.keys())),
                 ", ".join(
                     sorted(
                         [
                             cur_dev.name for cur_dev in dev_r.device_dict.itervalues()
                         ]
                     )
                 )
             )
         )
         for cur_dev in dev_r.device_dict.itervalues():
             cluster_location.db_device_variable(cur_dev, "is_virtual", description="Flag set for Virtual Machines", value=1)
예제 #2
0
파일: main.py 프로젝트: walong365/icsw
def upload_command(options):
    if not os.path.exists(options.filename):
        print("File '{}' does not exist".format(options.filename))
        sys.exit(-4)
    _content = open(options.filename, "rb").read()
    _size = len(_content)
    if options.mode == "cjson":
        _structure = server_command.decompress(_content, json=True)
    else:
        print("Unknown filemode '{}'".format(options.mode))
        sys.exit(-5)
    from initat.cluster.backbone.models.internal import BackendConfigFileTypeEnum, \
        BackendConfigFile
    from initat.tools import cluster_location
    _new = BackendConfigFile.store(
        structure=_structure,
        file_size=_size,
        file_type=BackendConfigFileTypeEnum(options.type),
        install_device=cluster_location.DeviceRecognition().device,
    )
    print("Current instance: {}".format(str(_new), _new.idx))
예제 #3
0
    def _call(self, cur_inst):
        file_list = []
        server_idxs = [self.server_idx]
        # get additional idx if host is virtual server

        sc_result = config_tools.icswServerCheck(service_type_enum=icswServiceEnum.cluster_server).get_result()
        if sc_result.effective_device is not None and sc_result.effective_device.idx != self.server_idx:
            server_idxs.append(sc_result.effective_device.idx)
        # recognize for which devices i am responsible
        dev_r = cluster_location.DeviceRecognition()
        server_idxs = list(set(server_idxs) | set(dev_r.device_dict.keys()))
        # get all peers to local machine and local netdevices
        my_idxs = netdevice.objects.exclude(
            Q(enabled=False)
        ).filter(
            Q(device__in=server_idxs) &
            Q(device__enabled=True) &
            Q(device__device_group__enabled=True)
        ).values_list("pk", flat=True)
        # ref_table
        route_obj = config_tools.RouterObject(cur_inst.log)
        all_paths = []
        for s_ndev in my_idxs:
            all_paths.extend(list(networkx.shortest_path(route_obj.nx, s_ndev, weight="weight").values()))
        # pprint.pprint(all_paths)
        nd_lut = {
            cur_nd.pk: cur_nd for cur_nd in netdevice.objects.all().select_related(
                "device"
            ).prefetch_related(
                "net_ip_set", "net_ip_set__network", "net_ip_set__domain_tree_node"
            )
        }
        # fetch key-information
        ssh_vars = device_variable.objects.filter(Q(name="ssh_host_rsa_key_pub")).select_related("device")
        rsa_key_dict = {}
        for _db_rec in ssh_vars:
            pass
        # read pre/post lines from /etc/hosts
        pre_host_lines, post_host_lines = ([], [])
        # parse pre/post host_lines
        try:
            host_lines = [line.strip() for line in codecs.open(ETC_HOSTS_FILENAME, "r", "utf-8").read().split("\n")]
        except:
            self.log(
                "error reading / parsing {}: {}".format(
                    ETC_HOSTS_FILENAME,
                    process_tools.get_except_info()),
                logging_tools.LOG_LEVEL_ERROR)
        else:
            mode, any_modes_found = (0, False)
            for line in host_lines:
                if line.lower().startswith("### aeh-start-pre"):
                    mode, any_modes_found = (1, True)
                elif line.lower().startswith("### aeh-start-post"):
                    mode, any_modes_found = (2, True)
                elif line.lower().startswith("### aeh-end"):
                    mode, any_modes_found = (0, True)
                else:
                    if mode == 1:
                        pre_host_lines.append(line)
                    elif mode == 2:
                        post_host_lines.append(line)
            if not any_modes_found:
                self.log(
                    "no ### aeh-.* stuff found in {}, copying to {}.orig".format(
                        ETC_HOSTS_FILENAME, ETC_HOSTS_FILENAME
                    )
                )
                try:
                    pass
                except:
                    self.log(
                        "error writing {}.orig: {}".format(
                            ETC_HOSTS_FILENAME,
                            process_tools.get_except_info()
                        )
                    )
        # mapping from device_name to all names for ssh_host_keys
        name_dict = {}
        # ip dictionary
        ip_dict = {}
        # min_target_dict
        min_target_dict = {}
        for cur_path in all_paths:
            min_value = route_obj.get_penalty(cur_path)
            target_nd = nd_lut[cur_path[-1]]
            min_target_dict[target_nd] = min(min_target_dict.get(target_nd, 999999999), min_value)
        tl_dtn = domain_tree_node.objects.get(Q(depth=0))
        for cur_path in all_paths:
            target_nd = nd_lut[cur_path[-1]]
            min_value = min_target_dict[target_nd]
            for cur_ip in nd_lut[cur_path[-1]].net_ip_set.all():
                # get names
                host_names = []
                cur_dtn = cur_ip.domain_tree_node or tl_dtn
                if not (cur_ip.alias.strip() and cur_ip.alias_excl):
                    host_names.append("{}{}".format(target_nd.device.name, cur_dtn.node_postfix))
                host_names.extend(["{}".format(cur_entry) for cur_entry in cur_ip.alias.strip().split()])
                if "localhost" in [x.split(".")[0] for x in host_names]:
                    host_names = [host_name for host_name in host_names if host_name.split(".")[0] == "localhost"]
                if cur_dtn.full_name:
                    if cur_dtn.create_short_names:
                        # also create short_names
                        out_names = (
                            " ".join(
                                [
                                    "{}.{} {}".format(host_name, cur_dtn.full_name, host_name) for host_name in host_names if not host_name.count(".")
                                ]
                            )
                        ).split()
                    else:
                        # only print the long names
                        out_names = ["{}.{}".format(host_name, cur_dtn.full_name) for host_name in host_names if not host_name.count(".")]
                else:
                    if cur_dtn.create_short_names:
                        # also create short_names
                        out_names = (" ".join(["{}".format(host_name) for host_name in host_names if not host_name.count(".")])).split()
                    else:
                        # only print the long names
                        out_names = ["{}".format(host_name) for host_name in host_names if not host_name.count(".")]
                # add names with dot
                out_names.extend([host_name for host_name in host_names if host_name.count(".")])
                # name_dict without localhost
                name_dict.setdefault(
                    target_nd.device.name, []
                ).extend(
                    [
                        out_name for out_name in out_names if out_name not in name_dict[target_nd.device.name] and not out_name.startswith("localhost")
                    ]
                )
                ip_dict.setdefault(cur_ip.ip, [])
                if out_names not in [entry[1] for entry in ip_dict[cur_ip.ip]]:
                    if cur_ip.ip != "0.0.0.0":
                        ip_dict[cur_ip.ip].append((min_value, out_names))
        # out_list
        loc_dict = {}
        for ip, h_list in ip_dict.items():
            all_values = sorted([entry[0] for entry in h_list])
            if all_values:
                min_value = all_values[0]
                out_names = []
                for val in all_values:
                    for _act_val, act_list in [(x_value, x_list) for x_value, x_list in h_list if x_value == val]:
                        out_names.extend([value for value in act_list if value not in out_names])
                # print min_value, ip, out_names
                loc_dict.setdefault(min_value, []).append([ipvx_tools.IPv4(ip)] + out_names)
        pen_list = sorted(loc_dict.keys())
        out_file = []
        for pen_value in pen_list:
            act_out_list = logging_tools.NewFormList()
            for entry in sorted(loc_dict[pen_value]):
                act_out_list.append(
                    [
                        logging_tools.form_entry(entry[0])
                    ] + [
                        logging_tools.form_entry(cur_e) for cur_e in entry[1:]
                    ]
                )
            host_lines = str(act_out_list).split("\n")
            out_file.extend(
                [
                    "# penalty {:d}, {}".format(
                        pen_value,
                        logging_tools.get_plural("host entry", len(host_lines))
                    ),
                    ""
                ] + host_lines + [""]
            )
        if not os.path.isdir(GROUP_DIR):
            try:
                os.makedirs(GROUP_DIR)
            except:
                pass
        if os.path.isdir(GROUP_DIR):
            # remove old files
            for file_name in os.listdir(GROUP_DIR):
                try:
                    os.unlink(os.path.join(GROUP_DIR, file_name))
                except:
                    pass
            # get all devices with netips
            all_devs = device.objects.filter(
                Q(enabled=True) &
                Q(device_group__enabled=True) &
                Q(netdevice__net_ip__ip__contains=".")
            ).values_list(
                "name",
                "device_group__name"
            ).order_by(
                "device_group__name",
                "name"
            )
            dg_dict = {}
            for dev_name, dg_name in all_devs:
                dg_dict.setdefault(dg_name, []).append(dev_name)
            for file_name, content in dg_dict.items():
                codecs.open(
                    os.path.join(GROUP_DIR, file_name),
                    "w",
                    "utf-8"
                ).write("\n".join(sorted(set(content)) + [""]))
        file_list.append(ETC_HOSTS_FILENAME)
        codecs.open(ETC_HOSTS_FILENAME, "w+", "utf-8").write(
            "\n".join(
                [
                    "### AEH-START-PRE insert pre-host lines below"
                ] + pre_host_lines +
                [
                    "### AEH-END-PRE insert pre-host lines above",
                    ""
                ] + out_file +
                [
                    "",
                    "### AEH-START-POST insert post-host lines below"
                ] + post_host_lines +
                [
                    "### AEH-END-POST insert post-host lines above",
                    ""
                ]
            )
        )
        # write known_hosts_file
        if os.path.isdir(os.path.dirname(SSH_KNOWN_HOSTS_FILENAME)):
            skh_f = open(SSH_KNOWN_HOSTS_FILENAME, "w")
            for ssh_key_node in sorted(rsa_key_dict.keys()):
                skh_f.write(
                    "{} {}\n".format(
                        ",".join(name_dict.get(ssh_key_node, [ssh_key_node])), rsa_key_dict[ssh_key_node]
                    )
                )
            skh_f.close()
            file_list.append(SSH_KNOWN_HOSTS_FILENAME)
        cur_inst.srv_com.set_result(
            "wrote {}".format(", ".join(sorted(file_list)))
        )
예제 #4
0
 def network_bind(self, **kwargs):
     _need_all_binds = kwargs.get("need_all_binds", False)
     pollin = kwargs.get("pollin", None)
     ext_call = kwargs.get("ext_call", False)
     immediate = kwargs.get("immediate", True)
     if "server_type" in kwargs:
         _inst = InstanceXML(log_com=self.log)
         _srv_type = kwargs["server_type"]
         bind_port = _inst.get_port_dict(_srv_type, ptype="command")
     elif "service_type_enum" in kwargs:
         _inst = InstanceXML(log_com=self.log)
         _srv_type = kwargs["service_type_enum"]
         bind_port = _inst.get_port_dict(_srv_type, ptype="command")
     elif "bind_port" in kwargs:
         bind_port = kwargs["bind_port"]
     else:
         raise KeyError("neither bind_port, service_type_enum nor server_type defined in kwargs")
     main_socket_name = kwargs.get("main_socket_name", "main_socket")
     virtual_sockets_name = kwargs.get("virtual_sockets_name", "virtual_sockets")
     bind_to_localhost = kwargs.get("bind_to_localhost", False)
     _sock_type = kwargs.get("socket_type", "ROUTER")
     if "client_type" in kwargs:
         uuid = uuid_tools.get_uuid().get_urn()
         if not uuid.startswith("urn"):
             uuid = "urn:uuid:{}".format(uuid)
         self.bind_id = "{}:{}:".format(
             uuid,
             InstanceXML(quiet=True).get_uuid_postfix(kwargs["client_type"]),
         )
         dev_r = None
     else:
         from initat.tools import cluster_location
         from initat.cluster.backbone.routing import get_server_uuid
         self.bind_id = get_server_uuid(_srv_type)
         if kwargs.get("simple_server_bind", False):
             dev_r = None
         else:
             # device recognition
             dev_r = cluster_location.DeviceRecognition()
     # virtual sockets
     if hasattr(self, virtual_sockets_name):
         _virtual_sockets = getattr(self, virtual_sockets_name)
     else:
         _virtual_sockets = []
     # main socket
     _main_socket = None
     # create bind list
     if dev_r and dev_r.device_dict:
         _bind_ips = set(
             list(dev_r.local_ips) + sum(
                 [
                     _list for _dev, _list in dev_r.ip_r_lut.iteritems()
                 ],
                 []
             )
         )
         # complex bind
         master_bind_list = [
             (
                 True,
                 [
                     "tcp://{}:{:d}".format(_local_ip, bind_port) for _local_ip in dev_r.local_ips
                 ],
                 self.bind_id,
                 None,
             )
         ]
         _virt_list = []
         for _dev, _ip_list in dev_r.ip_r_lut.iteritems():
             if _dev.pk != dev_r.device.pk:
                 _virt_list.append(
                     (
                         False,
                         [
                             "tcp://{}:{:d}".format(_virtual_ip, bind_port) for _virtual_ip in _ip_list
                         ],
                         # ignore local device
                         get_server_uuid(_srv_type, _dev.uuid),
                         _dev,
                     )
                 )
             else:
                 self.log(
                     "ignoring virtual IP list ({}) (same device)".format(
                         ", ".join(sorted(_ip_list)),
                     )
                 )
         master_bind_list.extend(_virt_list)
         # we have to bind to localhost but localhost is not present in bind_list, add master_bind
         if bind_to_localhost and not any([_ip.startswith("127.") for _ip in _bind_ips]):
             self.log(
                 "bind_to_localhost is set but not IP in range 127.0.0.0/8 found in list, adding virtual_bind",
                 logging_tools.LOG_LEVEL_WARN
             )
             master_bind_list.append(
                 (
                     False,
                     [
                         "tcp://127.0.0.1:{:d}".format(bind_port)
                     ],
                     self.bind_id,
                     None,
                 )
             )
     else:
         # simple bind
         master_bind_list = [
             (
                 True,
                 [
                     "tcp://*:{:d}".format(bind_port)
                 ],
                 self.bind_id,
                 None,
             )
         ]
     _errors = []
     # pprint.pprint(master_bind_list)
     bound_list = set()
     for master_bind, bind_list, bind_id, bind_dev in master_bind_list:
         client = process_tools.get_socket(
             self.zmq_context,
             _sock_type,
             identity=bind_id,
             immediate=immediate
         )
         for _bind_str in bind_list:
             if _bind_str in bound_list:
                 self.log(
                     "bind_str '{}' (for {}) already used, skipping ...".format(
                         _bind_str,
                         " device '{}'".format(bind_dev) if bind_dev is not None else " master device",
                     ),
                     logging_tools.LOG_LEVEL_ERROR
                 )
             else:
                 bound_list.add(_bind_str)
                 try:
                     client.bind(_bind_str)
                 except zmq.ZMQError:
                     self.log(
                         "error binding to {}: {}".format(
                             _bind_str,
                             process_tools.get_except_info(),
                         ),
                         logging_tools.LOG_LEVEL_CRITICAL
                     )
                     _errors.append(_bind_str)
                 else:
                     self.log("bound {} to {} with id {}".format(_sock_type, _bind_str, bind_id))
                     if pollin:
                         self.register_poller(client, zmq.POLLIN, pollin, ext_call=ext_call, bind_id=bind_id)
         if master_bind:
             _main_socket = client
         else:
             _virtual_sockets.append(client)
     setattr(self, main_socket_name, _main_socket)
     setattr(self, virtual_sockets_name, _virtual_sockets)
     if _errors and _need_all_binds:
         raise ValueError("{} went wrong: {}".format(logging_tools.get_plural("bind", len(_errors)), ", ".join(_errors)))