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