def update_voi_desktop(self, data): """ :param data: { "uuid": "", "value": { "name": "", ... } } :return: """ desktop_uuid = data.get('uuid', '') desktop = db_api.get_item_with_first(models.YzyVoiDesktop, {"uuid": desktop_uuid}) if not desktop: logger.error("desktop %s not exist", desktop_uuid) return get_error_result("DesktopNotExist", name="") try: if data['value'].get('ip_detail'): data['value']['ip_detail'] = json.dumps(data['value']['ip_detail']) else: data['value']['ip_detail'] = '' desktop.update(data['value']) desktop.soft_update() terminal_desktop_binds = db_api.get_item_with_all(models.YzyVoiTerminalToDesktops, {"desktop_group_uuid": desktop_uuid}) for bind in terminal_desktop_binds: bind.soft_delete() logger.info("update voi desktop, clear terminal desktop bind success!!") except Exception as e: logger.error("update voi desktop %s failed:%s", desktop_uuid, e, exc_info=True) return get_error_result("DesktopUpdateFail", name=desktop.name) logger.info("update voi desktop %s success", desktop_uuid) return get_error_result("Success")
def delete_voi_desktop(self, desktop_uuid): """ 删除桌面组 """ desktop = db_api.get_item_with_first(models.YzyVoiDesktop, {"uuid": desktop_uuid}) if not desktop: logger.error("desktop %s not exist", desktop_uuid) return get_error_result("DesktopNotExist", name="") try: # 清除桌面组与终端的绑定关系 terminal_desktop_binds = db_api.get_item_with_all(models.YzyVoiTerminalToDesktops, {"desktop_group_uuid": desktop_uuid}) for bind in terminal_desktop_binds: # type: 0-upload, 1-download bt_task = db_api.get_item_with_first(models.YzyVoiTorrentTask, {"terminal_mac": bind.terminal_mac, "type": 1}) # status == 1, task running if bt_task and bt_task.status == 1: return get_error_result("TerminalTorrentDownloading") bind.soft_delete() logger.info("delete voi desktop, clear terminal desktop bind success!!") desktop.soft_delete() logger.info("delete voi desktop, uuid:%s, name:%s", desktop.uuid, desktop.name) if desktop.default: default_one = db_api.get_item_with_first(models.YzyVoiDesktop, {}) if default_one: default_one.default = True default_one.soft_update() logger.info("the delete desktop is default, set %s as default", default_one.name) return get_error_result("Success") except Exception as e: logger.error("delete voi desktop failed:%s", e, exc_info=True) return get_error_result("DesktopDeleteFail")
def ha_sync_task(): """ 通知备控检查文件同步情况,下载缺少的,删除多余的 范围:iso库、数据库备份文件、VOI模板的实际启动盘、base盘、差异盘、种子文件 """ ha_info_obj = db_api.get_ha_info_first() if ha_info_obj: paths = list() for iso in db_api.get_item_with_all(models.YzyIso, {}): paths.append({"path": iso.path, "md5": iso.md5_sum}) if paths: notify_backup_sync_file(ha_info_obj.master_ip, ha_info_obj.backup_ip, paths, check_path=os.path.dirname( paths[0]["path"])) backs = list() for backup in db_api.get_item_with_all(models.YzyDatabaseBack, {}): backs.append({"path": backup.path, "md5": backup.md5_sum}) if backs: notify_backup_sync_file(ha_info_obj.master_ip, ha_info_obj.backup_ip, backs, check_path=os.path.dirname( backs[0]["path"])) templates = list() sys_base, data_base = get_template_storage_path( ha_info_obj.master_uuid) for dir_path in [ sys_base, os.path.join(sys_base, constants.IMAGE_CACHE_DIRECTORY_NAME), data_base, os.path.join(data_base, constants.IMAGE_CACHE_DIRECTORY_NAME) ]: find_file_to_sync(dir_path, templates) find_xml_to_sync("/etc/libvirt/qemu/", templates) if templates: # 模板不删除多余的,容易导致正在刚创建的模板磁盘文件被删除 notify_backup_sync_file(ha_info_obj.master_ip, ha_info_obj.backup_ip, templates)
def get_history_perf(self, data): logger.info("get data: {}".format(data)) node_uuid = data.get("node_uuid") statis_hours = data.get("statis_hours") step_minutes = data.get("step_minutes") if not (node_uuid and statis_hours and step_minutes): return build_result("ParamError") node = db_api.get_item_with_all(models.YzyNodes, {"uuid": node_uuid}) if not node: return build_result("ParamError") _data = self.get_perf_info(node_uuid, statis_hours, step_minutes) _data.update({"node_uuid": node_uuid}) return build_result("Success", data=_data)
def education_group(self, data): logger.info("get data: {}".format(data)) terminal_ip = data.get("terminal_ip", "") if not is_ip_addr(terminal_ip): return build_result("ParamError") _group = None edu_groups = db_api.get_item_with_all( models.YzyVoiGroup, {"group_type": constants.EDUCATION_DESKTOP}) for group in edu_groups: start_ip = group.start_ip end_ip = group.end_ip if terminal_ip in find_ips(start_ip, end_ip): _group = group break if not _group: return build_result("Success") ret = { "name": _group.name, "uuid": _group.uuid, } logger.info("return data: {}".format(ret)) return build_result("Success", ret)
def education_config_groups(self): """ 获取所有组的ip段信息 { "code": 0, "msg": "success" "data": { "groups": { "uuid": ["ips"] } } } :return: """ groups_dict = dict() edu_groups = db_api.get_item_with_all( models.YzyVoiGroup, {"group_type": constants.EDUCATION_DESKTOP}) for group in edu_groups: start_ip = group.start_ip end_ip = group.end_ip ips = find_ips(start_ip, end_ip) groups_dict.update({group.uuid: ips}) logger.info("terminal desktop group dict: %s" % groups_dict) return build_result("Success", data={"groups": groups_dict})
def update_template_disk_usage(): """更新模板的磁盘使用,目前暂时只适配windows""" templates = db_api.get_template_with_all({}) voi_templates = db_api.get_item_with_all(models.YzyVoiTemplate, {}) if templates or voi_templates: node = db_api.get_controller_node() node_uuid = node.uuid template_sys = db_api.get_template_sys_storage(node_uuid) template_data = db_api.get_template_data_storage(node_uuid) if not (template_sys and template_data): logging.error("there is not storage path, skip") sys_path = os.path.join(template_sys.path, 'instances') data_path = os.path.join(template_data.path, 'datas') for template in templates: if constants.STATUS_INACTIVE == template.status: devices = db_api.get_devices_by_instance(template.uuid) for disk in devices: if constants.IMAGE_TYPE_SYSTEM == disk.type: instance_dir = os.path.join(sys_path, template.uuid) elif constants.IMAGE_TYPE_DATA == disk.type: instance_dir = os.path.join(data_path, template.uuid) else: continue file_path = os.path.join( instance_dir, constants.DISK_FILE_PREFIX + disk.uuid) try: stdout, stderror = cmdutils.execute('virt-df -a %s' % file_path, shell=True, timeout=20, run_as_root=True) logger.info("virt-df execute end, stdout:%s, stderror:%s", stdout, stderror) result = [ int(item) for item in stdout.split(' ') if item.strip() and item.isdigit() ] if result: # 一个磁盘分区包括三个数字,总数、使用数和剩余数。windows系统盘默认有个保留分区 logger.info("get disk %s result:%s", disk.device_name, result) if constants.IMAGE_TYPE_SYSTEM == disk.type: used = result[4] else: used = result[1] size_gb = round(used / (1024 * 1024), 2) logger.info("get template %s disk %s used size:%s", template.name, disk.device_name, size_gb) disk.used = size_gb disk.soft_update() except: pass for template in voi_templates: if constants.STATUS_INACTIVE == template.status: devices = db_api.get_item_with_all( models.YzyVoiDeviceInfo, {'instance_uuid': template.uuid}) for disk in devices: base_path = sys_path if disk.type == constants.IMAGE_TYPE_SYSTEM else data_path file_path = os.path.join(base_path, constants.VOI_FILE_PREFIX + disk.uuid) try: stdout, stderror = cmdutils.execute('virt-df -a %s' % file_path, shell=True, timeout=20, run_as_root=True) logger.info("virt-df execute end, stdout:%s, stderror:%s", stdout, stderror) result = [ int(item) for item in stdout.split(' ') if item.strip() and item.isdigit() ] if result: # 一个磁盘分区包括三个数字,总数、使用数和剩余数。windows系统盘默认有个保留分区 logger.info("get disk %s result:%s", disk.device_name, result) if constants.IMAGE_TYPE_SYSTEM == disk.type: used = result[4] else: used = result[1] size_gb = round(used / (1024 * 1024), 2) logger.info("get template %s disk %s used size:%s", template.name, disk.device_name, size_gb) disk.used = size_gb disk.soft_update() except: pass
def update_template_info(): templates = db_api.get_template_with_all({}) voi_templates = db_api.get_item_with_all(models.YzyVoiTemplate, {}) rep_data = dict() for item in templates: host_ip = item.host.ip _d = {"uuid": item.uuid, "name": item.name} if host_ip not in rep_data: rep_data[host_ip] = list() rep_data[host_ip].append(_d) for item in voi_templates: host_ip = item.host.ip _d = {"uuid": item.uuid, "name": item.name} if host_ip not in rep_data: rep_data[host_ip] = list() rep_data[host_ip].append(_d) for k, v in rep_data.items(): command_data = { "command": "get_status_many", "handler": "InstanceHandler", "data": { "instance": v } } logger.debug("get template state in node %s", k) rep_json = compute_post(k, command_data) logger.debug("from compute get template rep_json:{}".format(rep_json)) if rep_json.get("code", -1) != 0: continue for template in templates: for item in rep_json.get("data", []): if item["uuid"] == template.uuid: if template.status in [ constants.STATUS_ACTIVE, constants.STATUS_INACTIVE ]: if 1 == item.get("state"): status = constants.STATUS_ACTIVE else: status = constants.STATUS_INACTIVE if template.status != status: logger.info( "the template %s status change from %s to %s", template.name, template.status, status) template.status = status template.soft_update() break for template in voi_templates: for item in rep_json.get("data", []): if item["uuid"] == template.uuid: if template.status in [ constants.STATUS_ACTIVE, constants.STATUS_INACTIVE ]: if 1 == item.get("state"): status = constants.STATUS_ACTIVE else: status = constants.STATUS_INACTIVE if template.status != status: logger.info( "the template %s status change from %s to %s", template.name, template.status, status) template.status = status template.soft_update() break
def education_groups(self): edu_groups = db_api.get_item_with_all( models.YzyVoiGroup, {"group_type": constants.EDUCATION_DESKTOP}) ret = {"groups": [x.uuid for x in edu_groups]} return build_result("Success", ret)
def update_share_disk(self, data): """ 更新共享数据盘 { "uuid": "xxxxxxxxxx", "enable": 0, "disk_size": 8, "restore": 1, "share_desktop": [ {"uuid": "xxxxxxx", "name": "xxxxx", "choice": 0}, {"uuid": "xxxxxxx", "name": "xxxxx", "choice": 0} ] } :param data: :return: """ """ { "command": "create_share", "handler": "VoiHandler", "data": { "disk_info": { 'uuid': '2f110de8-78d8-11ea-ad5d-000c29e84b9c', 'base_path': '/opt/slow/instances' } "version": 0 } } """ logger.info("terminal share disk update data: {}".format(data)) try: # disk_uuid = create_uuid() version = 0 disk_uuid = data["uuid"] sys_base, data_base = self._get_template_storage() share_disk = db_api.get_item_with_first( models.YzyVoiTerminalShareDisk, {"uuid": disk_uuid}) disk_info = dict() disk_info["uuid"] = share_disk.uuid disk_info["base_path"] = sys_base['path'] disk_info["size"] = data["disk_size"] # 判断是否大小有更新 if data["disk_size"] != share_disk.disk_size: # 需要重新删除创建 # pass node = db_api.get_controller_node() delete_command = { "command": "delete_share", "handler": "VoiHandler", "data": { "disk_info": { "uuid": share_disk.uuid, "base_path": sys_base['path'], }, "version": version } } ret = compute_post(node.ip, delete_command) if ret.get("code", -1) != 0: logger.error( "terminal share disk update fail, delete old fail") return build_result("ShareDiskUpdateFail") # 创建新的容量盘 command_data = { "command": "create_share", "handler": "VoiHandler", "data": { "disk_info": disk_info, "version": version } } ret_json = compute_post(node.ip, command_data) if ret_json.get("code", -1) != 0: logger.error( "terminal share disk update fail, create new fail") return build_result("ShareDiskUpdateFail") share_disk.disk_size = data["disk_size"] share_disk.version += 1 # todo 维护桌面组的绑定关系 # import pdb; pdb.set_trace() desktops = db_api.get_item_with_all( models.YzyVoiDesktop, {"group_uuid": share_disk.group_uuid}) desktop_binds = db_api.get_item_with_all( models.YzyVoiShareToDesktops, {"disk_uuid": disk_uuid}) share_desktops = data["share_desktop"] copy_share_desktops = share_desktops[:] for desktop in share_desktops: # is_exist = False for bind in desktop_binds: if desktop["uuid"] == bind.desktop_uuid: # is_exist = True if not int(desktop.get("choice", 0)): bind.soft_delete() copy_share_desktops.remove(desktop) insert_binds = list() if copy_share_desktops: for desktop in copy_share_desktops: if desktop["choice"]: for _d in desktops: if desktop["uuid"] == _d.uuid: insert_binds.append({ "uuid": create_uuid(), "group_uuid": share_disk.group_uuid, "disk_uuid": disk_uuid, "desktop_uuid": desktop["uuid"], "desktop_name": desktop["name"] }) # 更新数据库绑定记录 if insert_binds: db_api.insert_with_many(models.YzyVoiShareToDesktops, insert_binds) # 更新数据库记录 share_disk.restore = data["restore"] share_disk.enable = data["enable"] share_disk.soft_update() # todo 生成bt种子 # 生成种子文件 task = Thread(target=self.create_share_disk_torrent, args=(disk_info, version)) task.start() logger.info( "update terminal voi share disk data: {} success".format( share_disk)) return build_result("Success") except Exception as e: logger.error("", exc_info=True) return build_result("OtherError")
def order_terminal_desktop_ip(self, data): """ "terminal_id_list": terminal_id_list, "group_uuid": group_uuid, "terminal_mac_list": terminal_mac_list """ logger.info("order terminal desktop ip data: {}".format(data)) try: group_uuid = data.get("group_uuid", "") terminal_mac_list = data.get("terminal_mac_list", "") terminal_id_list = data.get("terminal_id_list", "") if terminal_mac_list: terminals_list = list(zip(terminal_id_list, terminal_mac_list)) terminals_list = sorted(terminals_list, key=lambda x: x[0]) else: logger.warning( 'request terminal_mac_list is null, please check!!1') return build_result("Success") # group_uuid get all desktop groups qry_desktop_groups = db_api.get_item_with_all( models.YzyVoiDesktop, {'group_uuid': group_uuid}) for desktop_group in qry_desktop_groups: if not desktop_group.use_bottom_ip and desktop_group.ip_detail: ip_detail = json.loads(desktop_group.ip_detail) desktop_is_dhcp = ip_detail.get("auto", True) if not desktop_is_dhcp: desktop_start_ip = ip_detail.get("start_ip", "") desktop_mask = ip_detail.get("netmask", "") desktop_gateway = ip_detail.get("gateway", "") desktop_dns1 = ip_detail.get("dns_master", "") desktop_dns2 = ip_detail.get("dns_slave", "") netmask_bits = netaddr.IPAddress( desktop_mask).netmask_bits() network = ipaddress.ip_interface( desktop_start_ip + '/' + str(netmask_bits)).network desktop_ip_pool = [ x for x in network.hosts() if x >= ipaddress.IPv4Address(desktop_start_ip) ] if desktop_ip_pool: for terminal_id, terminal_mac in terminals_list: set_ip_detail = {} if desktop_ip_pool: desktop_ip = min(desktop_ip_pool) set_ip_detail = { "desktop_is_dhcp": 0, "desktop_ip": desktop_ip.compressed, "desktop_mask": desktop_mask, "desktop_gateway": desktop_gateway, "desktop_dns1": desktop_dns1, "desktop_dns2": desktop_dns2, } desktop_ip_pool.remove(desktop_ip) logger.debug( 'terminal_id: {}, terminal_mac: {}, ip: {}' .format(terminal_id, terminal_mac, desktop_ip)) else: # no more available ip, set desktop ip use bottom ip requst_data = { "handler": "WebTerminalHandler", "command": "get_terminal_ip", "data": { 'mac': terminal_mac } } ret = voi_terminal_post( "/api/v1/voi/terminal/command/", requst_data) if ret.get("code", -1) != 0: logger.error( "voi_terminal_post request: {}, ret: {}" .format(requst_data, ret)) return ret bottom_ip = ret.get("data", None) set_ip_detail = { "desktop_is_dhcp": 0, "desktop_ip": bottom_ip['ip'], "desktop_mask": bottom_ip['mask'], "desktop_gateway": bottom_ip['gateway'], "desktop_dns1": bottom_ip['dns1'], "desktop_dns2": bottom_ip['dns2'], } # update database table set_ip_detail db_api.update_voi_terminal_desktop_bind( desktop_group.uuid, terminal_mac, set_ip_detail) else: logger.warning( 'desktop group ip setup error, no available ip' ) return build_result("Success") except Exception as e: logger.error("", exc_info=True) return build_result("OtherError")
def create_terminal_desktop_bind_bak(self, data): """ 'group_uuid','terminal_uuid','terminal_id','mac', 'ip','mask','gateway','dns1','dns2','is_dhcp', """ logger.info("create terminal desktop bind data: {}".format(data)) try: terminal_uuid = data.get("terminal_uuid", "") terminal_id = data.get("terminal_id", "") group_uuid = data.get("group_uuid", "") terminal_mac = data.get("mac", "") bind_info = {} # group_uuid != input group_uuid, then delete all old data db_api.delete_voi_terminal_desktops(group_uuid, terminal_uuid) # get all desktop groups qry_desktop_groups = db_api.get_item_with_all( models.YzyVoiDesktop, {"group_uuid": group_uuid}) # 查找所有该终端、桌面组对应关系 for qry in qry_desktop_groups: desktop_group_uuid = qry.uuid # one (desktop_group_uuid, terminal_id) only one row qry_exists = db_api.get_item_with_first( models.YzyVoiTerminalToDesktops, { "desktop_group_uuid": desktop_group_uuid, "terminal_uuid": terminal_uuid }) if qry_exists: logger.info('continue: {}'.format(terminal_mac)) continue logger.info('desktop_group_uuid: {}, qry.ip_detail: {}'.format( desktop_group_uuid, qry.ip_detail)) desktop_is_dhcp = 0 if qry.ip_detail: ip_detail = json.loads(qry.ip_detail) desktop_is_dhcp = int(ip_detail.get("auto", True)) desktop_start_ip = ip_detail.get("start_ip", "") desktop_mask = ip_detail.get("netmask", "") desktop_gateway = ip_detail.get("gateway", "") desktop_dns1 = ip_detail.get("dns_master", "") desktop_dns2 = ip_detail.get("dns_slave", "") desktop_ip_info = {} if bool(qry.use_bottom_ip): logger.info( 'desktop_group_uuid: {}, qry.use_bottom_ip: {}'.format( desktop_group_uuid, qry.use_bottom_ip)) desktop_ip_info = { "desktop_is_dhcp": data.get("is_dhcp", ""), "desktop_ip": data.get("ip", ""), "desktop_mask": data.get("mask", ""), "desktop_gateway": data.get("gateway", ""), "desktop_dns1": data.get("dns1", ""), "desktop_dns2": data.get("dns2", ""), } elif desktop_is_dhcp: logger.info( 'desktop_group_uuid: {}, desktop_is_dhcp: {}'.format( desktop_group_uuid, desktop_is_dhcp)) desktop_ip_info = { "desktop_is_dhcp": 1, "desktop_ip": "", "desktop_mask": "", "desktop_gateway": "", "desktop_dns1": "", "desktop_dns2": "", } else: logger.info('desktop_group_uuid: {}, static ip'.format( desktop_group_uuid)) # get ip pool use start_ip and netmask, filter yzy_voi_terminal_desktops ips, get least ip netmask_bits = netaddr.IPAddress( desktop_mask).netmask_bits() network = ipaddress.ip_interface(desktop_start_ip + '/' + str(netmask_bits)).network original_ip_pool = [ x for x in network.hosts() if x >= ipaddress.IPv4Address(desktop_start_ip) ] # get used ip in this desktop_group_uuid qry_ips = db_api.get_item_with_all( models.YzyVoiTerminalToDesktops, {"desktop_group_uuid": desktop_group_uuid}) used_ip_pool = [ ipaddress.IPv4Address(qry.desktop_ip) for qry in qry_ips ] available_ip_pool = [ ip for ip in original_ip_pool if ip not in used_ip_pool ] if available_ip_pool: desktop_ip = min(available_ip_pool).compressed desktop_ip_info = { "desktop_is_dhcp": 0, "desktop_ip": desktop_ip, "desktop_mask": desktop_mask, "desktop_gateway": desktop_gateway, "desktop_dns1": desktop_dns1, "desktop_dns2": desktop_dns2, } else: # use use_bottom_ip logger.info( 'desktop_group_uuid: {}, no availabel_ip'.format( desktop_group_uuid)) desktop_ip_info = { "desktop_is_dhcp": data.get("is_dhcp", ""), "desktop_ip": data.get("ip", ""), "desktop_mask": data.get("mask", ""), "desktop_gateway": data.get("gateway", ""), "desktop_dns1": data.get("dns1", ""), "desktop_dns2": data.get("dns2", ""), } bind_info = { "uuid": create_uuid(), "group_uuid": group_uuid, "terminal_uuid": terminal_uuid, "desktop_group_uuid": desktop_group_uuid, "terminal_mac": terminal_mac, } bind_info.update(desktop_ip_info) db_api.create_voi_terminal_desktop_bind(bind_info) logger.info( "terminal desktop bind data: {} success".format(bind_info)) return build_result("Success") except Exception as e: logger.error("", exc_info=True) return build_result("OtherError")
def create_terminal_desktop_bind(self, data): """ 'group_uuid','terminal_uuid','terminal_id','mac', 'ip','mask','gateway','dns1','dns2','is_dhcp', {'group_uuid': 'a0cd32c9-9502-4ddc-b7a2-115203e4df0c', 'terminal_uuid': '891fa480-8f9b-4d25-8df3-a59798e302c4', 'terminal_id': 210, 'mac': 'E4:3A:6E:35:5C:A4', 'ip': '10.100.20.150', 'mask': '255.255.255.0', 'gateway': '10.100.20.254', 'dns1': '10.10.0.2', 'dns2': '', 'is_dhcp': 1} """ logger.info("create terminal desktop bind data: {}".format(data)) try: terminal_uuid = data.get("terminal_uuid", "") terminal_id = data.get("terminal_id", "") group_uuid = data.get("group_uuid", "") terminal_mac = data.get("mac", "") bind_info = {} # group_uuid != input group_uuid, then delete all old data with redis_lock.Lock(self._redis.rds, 'create_terminal_desktop_bind_lock', 2): db_api.delete_voi_terminal_desktops(group_uuid, terminal_uuid) # get all desktop groups qry_desktop_groups = db_api.get_item_with_all( models.YzyVoiDesktop, {"group_uuid": group_uuid}) # 查找所有该终端、桌面组对应关系 terminal_desktop_relations = db_api.get_item_with_all( models.YzyVoiTerminalToDesktops, {"terminal_uuid": terminal_uuid}) for qry in qry_desktop_groups: desktop_group_uuid = qry.uuid # one (desktop_group_uuid, terminal_id) only one row # qry_exists = db_api.get_item_with_first(models.YzyVoiTerminalToDesktops, # {"desktop_group_uuid": desktop_group_uuid, # "terminal_uuid": terminal_uuid}) relation_exists = False for relation in terminal_desktop_relations: if relation.desktop_group_uuid == desktop_group_uuid: relation_exists = True break if relation_exists: logger.info('continue: {}'.format(terminal_mac)) continue logger.info( 'desktop_group_uuid: {}, qry.ip_detail: {}'.format( desktop_group_uuid, qry.ip_detail)) if bool(qry.use_bottom_ip): logger.info( 'desktop_group_uuid: {}, qry.use_bottom_ip: {}'. format(desktop_group_uuid, qry.use_bottom_ip)) desktop_ip_info = { "desktop_is_dhcp": data.get("is_dhcp", ""), "desktop_ip": data.get("ip", ""), "desktop_mask": data.get("mask", ""), "desktop_gateway": data.get("gateway", ""), "desktop_dns1": data.get("dns1", ""), "desktop_dns2": data.get("dns2", ""), } else: desktop_is_dhcp = 0 if qry.ip_detail: ip_detail = json.loads(qry.ip_detail) desktop_is_dhcp = int(ip_detail.get("auto", True)) desktop_start_ip = ip_detail.get("start_ip", "") desktop_mask = ip_detail.get("netmask", "") desktop_gateway = ip_detail.get("gateway", "") desktop_dns1 = ip_detail.get("dns_master", "") desktop_dns2 = ip_detail.get("dns_slave", "") if desktop_is_dhcp: logger.info( 'desktop_group_uuid: {}, desktop_is_dhcp: {}'. format(desktop_group_uuid, desktop_is_dhcp)) desktop_ip_info = { "desktop_is_dhcp": 1, "desktop_ip": "", "desktop_mask": "", "desktop_gateway": "", "desktop_dns1": "", "desktop_dns2": "", } else: logger.info( 'desktop_group_uuid: {}, static ip'.format( desktop_group_uuid)) # get ip pool use start_ip and netmask, filter yzy_voi_terminal_desktops ips, get least ip netmask_bits = netaddr.IPAddress( desktop_mask).netmask_bits() network = ipaddress.ip_interface( desktop_start_ip + '/' + str(netmask_bits)).network original_ip_pool = [ x for x in network.hosts() if x >= ipaddress.IPv4Address(desktop_start_ip) ] # get used ip in this desktop_group_uuid # with redis_lock.Lock(self._redis.rds, 'create_terminal_desktop_bind_lock', 2): qry_ips = db_api.get_item_with_all( models.YzyVoiTerminalToDesktops, {"desktop_group_uuid": desktop_group_uuid}) used_ip_pool = [ ipaddress.IPv4Address(qry.desktop_ip) for qry in qry_ips ] available_ip_pool = [ ip for ip in original_ip_pool if ip not in used_ip_pool ] if available_ip_pool: desktop_ip = min(available_ip_pool).compressed desktop_ip_info = { "desktop_is_dhcp": 0, "desktop_ip": desktop_ip, "desktop_mask": desktop_mask, "desktop_gateway": desktop_gateway, "desktop_dns1": desktop_dns1, "desktop_dns2": desktop_dns2, } else: # use use_bottom_ip logger.info( 'desktop_group_uuid: {}, no availabel_ip'. format(desktop_group_uuid)) desktop_ip_info = { "desktop_is_dhcp": data.get("is_dhcp", ""), "desktop_ip": data.get("ip", ""), "desktop_mask": data.get("mask", ""), "desktop_gateway": data.get("gateway", ""), "desktop_dns1": data.get("dns1", ""), "desktop_dns2": data.get("dns2", ""), } bind_info = { "uuid": create_uuid(), "group_uuid": group_uuid, "terminal_uuid": terminal_uuid, "desktop_group_uuid": desktop_group_uuid, "terminal_mac": terminal_mac, } bind_info.update(desktop_ip_info) db_api.create_voi_terminal_desktop_bind(bind_info) logger.info( "terminal desktop bind data: {} success".format(bind_info)) return build_result("Success") except Exception as e: logger.error("", exc_info=True) return build_result("OtherError")