Пример #1
0
 def move_user(self, data):
     group = db_api.get_group_with_first({"uuid": data['group_uuid']})
     if not group:
         logger.error("group: %s not exist" % data['group_uuid'])
         return get_error_result("GroupNotExists", name='')
     for user in data['users']:
         user = db_api.get_group_user_with_first({'uuid': user['uuid']})
         if not user:
             logger.error("user %s not exist", user['user_name'])
             return get_error_result("GroupUserNotExists",
                                     name=user['user_name'])
         if user.group_uuid == group.uuid:
             logger.info("user %s already in group %s, skip",
                         user.user_name, group.name)
             continue
         try:
             user.group_uuid = data['group_uuid']
             # 移动后,原先的跟桌面绑定关系要删除
             binds = db_api.get_instance_with_all({"user_uuid": user.uuid})
             for bind in binds:
                 bind.user_uuid = ''
                 bind.soft_update()
             user.soft_update()
         except Exception as e:
             logger.error("move user %s to group %s failed:%s",
                          user.user_name, group.name, e)
             return get_error_result("GroupUserMoveError",
                                     user_name=user.user_name,
                                     group=group.name)
         logger.info("move user %s to group %s success", user.user_name,
                     group.name)
     return get_error_result("Success")
Пример #2
0
    def get_links_num(self):
        count = 0
        instances = db_api.get_instance_with_all({})
        rep_data = dict()
        for instance in instances:
            host_ip = instance.host.ip
            if host_ip not in rep_data:
                rep_data[host_ip] = list()
            if instance.spice_port:
                rep_data[host_ip].append(instance.spice_port)

        for k, v in rep_data.items():
            ports = ",".join(list(set(v)))
            if ports:
                ports_status = monitor_post(k, "/api/v1/monitor/port_status",
                                            {"ports": ports})
            else:
                ports_status = {}
            if ports_status.get('code', -1) != 0:
                logger.error("from node %s get port status:%s", k,
                             ports_status)
                continue
            logger.info("from node %s get port status:%s", k, ports_status)
            for port, link in ports_status.get("data", {}).items():
                if link:
                    count += 1
        logger.info("the instance link count:%s", count)
        return count
Пример #3
0
    def person_instance_close(self, data):
        """ 关闭个人终端的所有桌面 """
        session_id = data.get("session_id", "")
        session = db_api.get_group_user_session_first(
            {"session_id": session_id})
        if not session:
            logger.error(
                "terminal user query desktop group error: %s not exist" %
                session_id)
            return build_result("TerminalUserLogout")

        user = db_api.get_group_user_with_first({"uuid": session.user_uuid})
        if not user:
            logger.error(
                "terminal user query desktop group error: %s not exist" %
                session.user_uuid)
            return build_result("TerminalUserNotExistError")

        if not user.enabled:
            logger.error(
                "terminal user query desktop group error: %s is unenabled" %
                user.user_name)
            return build_result("TerminalUserUnenabledError")

        contraller = BaseController()
        random_instances = db_api.get_user_random_instance_with_all(
            {"user_uuid": user.uuid})

        static_instances = db_api.get_instance_with_all({
            "classify": constants.PERSONAL_DEKSTOP,
            "user_uuid": user.uuid
        })
        for i in random_instances:
            desktop = i.desktop
            instance = i.instance
            # sys_restore = desktop.sys_restore
            if not contraller.stop_instance(instance, desktop):
                logger.error("terminal close personal instance fail: %s" %
                             instance.uuid)
            instance.allocated = 0

        desktop_uuids = list()
        for instance in static_instances:
            desktop_uuid = instance.desktop_uuid
            if desktop_uuid not in desktop_uuids:
                desktop_uuids.append(desktop_uuid)
        desktop_dict = dict()
        desktops = db_api.get_personal_desktop_all_by_uuids(desktop_uuids)
        for desktop in desktops:
            desktop_dict[desktop.uuid] = desktop

        for instance in static_instances:
            desktop = desktop_dict[instance.desktop_uuid]
            if not contraller.stop_instance(instance, desktop):
                logger.error("terminal close personal instance fail: %s" %
                             instance.uuid)

        logger.info("terminal close personal instance success !!!")
        return build_result("Success")
Пример #4
0
    def person_desktop_groups(self, data):
        """ 个人桌面组列表 """
        session_id = data.get("session_id", "")
        session = db_api.get_group_user_session_first(
            {"session_id": session_id})
        if not session:
            logger.error(
                "terminal user query desktop group error: %s not exist" %
                session_id)
            return build_result("TerminalUserLogout")

        user = db_api.get_group_user_with_first({"uuid": session.user_uuid})
        if not user:
            logger.error(
                "terminal user query desktop group error: %s not exist" %
                session.user_uuid)
            return build_result("TerminalUserNotExistError")

        if not user.enabled:
            logger.error(
                "terminal user query desktop group error: %s is unenabled" %
                user.user_name)
            return build_result("TerminalUserUnenabledError")

        # 个人桌面组分为随机桌面组和静态桌面组
        desktop_uuids = list()
        # 随机桌面
        random_desktop_groups = db_api.get_random_desktop_with_all(
            {"group_uuid": user.group_uuid})
        for group in random_desktop_groups:
            desktop_uuids.append(group.desktop_uuid)

        # instance_uuids = list()
        static_instances = db_api.get_instance_with_all(
            {"user_uuid": user.uuid})
        for instance in static_instances:
            desktop_uuids.append(instance.desktop_uuid)

        # instances = db_api.get_instance_all_by_uuids(instance_uuids)
        # for instance in instances:
        #     desktop_uuids.append(instance.desktop_uuid)

        desktop_groups = db_api.get_personal_desktop_all_by_uuids(
            desktop_uuids)
        _groups = list()
        for desktop in desktop_groups:
            _d = {
                "uuid": desktop.uuid,
                "name": desktop.name,
                "desc": desktop.template.desc,
                "maintenance": desktop.maintenance,
                "order_num": desktop.order_num,
                "os_type": desktop.os_type
            }
            _groups.append(_d)

        _groups = sorted(_groups, key=lambda _groups: _groups['order_num'])
        logger.info("person terminal desktop group list: %s" % _groups)
        return build_result("Success", _groups)
Пример #5
0
    def terminal_instance_match(self, data):
        """ 所有终端ip对应的桌面ip"""
        # ips = data.get("ips", "")
        # ips = ips.split(",")
        # terminal_ips = list()
        # for i in ips:
        #     if not is_ip_addr(i):
        #         continue
        #     terminal_ips.append(i)
        # items = {}
        groups = db_api.get_group_with_all(
            {"group_type": constants.EDUCATION_DESKTOP})
        group_dict = dict()
        for group in groups:
            start_ip = group.start_ip
            end_ip = group.end_ip
            uuid = group.uuid
            group_dict[uuid] = find_ips(start_ip, end_ip)

        desktop_group_dict = {}
        desktops = db_api.get_desktop_with_all_by_groups(
            list(group_dict.keys()))
        for i in desktops:
            desktop_group_dict[i.uuid] = i.group_uuid

        terminals = list()
        for i in data:
            terminal_ip = i["terminal_ip"]
            if not is_ip_addr(terminal_ip):
                continue
            for uuid, ips in group_dict.items():
                # start_ip = group.start_ip
                # end_ip = group.end_ip
                # if find_ips(start_ip, end_ip)
                if terminal_ip in ips:
                    i["group_uuid"] = uuid
                    terminals.append(i)
                    break

        # 找到所有云桌面
        ret = list()
        instances = db_api.get_instance_with_all(
            {"classify": constants.EDUCATION_DESKTOP})
        for terminal in terminals:
            group_uuid = terminal["group_uuid"]
            terminal_id = terminal["terminal_id"]
            for instance in instances:
                desktop_uuid = instance.desktop_uuid
                _group_uuid = desktop_group_dict.get(desktop_uuid)
                _terminal_id = instance.terminal_id
                _instance_ip = instance.ipaddr
                if _group_uuid == group_uuid and terminal_id == _terminal_id and _instance_ip:
                    terminal["desktop_ip"] = _instance_ip
                    ret.append(terminal)
                    break

        return build_result("Success", ret)
Пример #6
0
 def delete_user(self, user_uuid):
     user = db_api.get_group_user_with_first({'uuid': user_uuid})
     if not user:
         logger.error("user: %s not exist" % user_uuid)
         return get_error_result("GroupUserNotExists", name='')
     binds = db_api.get_instance_with_all({"user_uuid": user.uuid})
     for bind in binds:
         bind.user_uuid = ''
         bind.soft_update()
     user.soft_delete()
     logger.info("delete group user %s success", user_uuid)
     return get_error_result("Success")
Пример #7
0
    def delete_group(self, group_uuid):
        group = db_api.get_group_with_first({"uuid": group_uuid})
        if not group:
            logger.error("group: %s not exist" % group_uuid)
            return get_error_result("GroupNotExists", name='')

        # 教学分组如果在使用中,不能删除
        if constants.EDUCATION_DESKTOP == group.group_type:
            desktop = db_api.get_desktop_with_all({"group_uuid": group_uuid})
            if desktop:
                logger.error("group already in use", group_uuid)
                return get_error_result("GroupInUse", name=group.name)
            # 教学分组有关联课表时,不能删除
            if db_api.get_course_schedule_with_all({"group_uuid": group_uuid}):
                logger.error("group already in use by course_schedule",
                             group_uuid)
                return get_error_result("GroupInUseByCourseSchedule",
                                        name=group.name)

        # 个人分组删除时需要删除分组中的用户
        if constants.PERSONAL_DEKSTOP == group.group_type:
            users = db_api.get_group_user_with_all({'group_uuid': group.uuid})
            for user in users:
                binds = db_api.get_instance_with_all({"user_uuid": user.uuid})
                for bind in binds:
                    bind.user_uuid = ''
                    bind.soft_update()
                user.soft_delete()
            desktops = db_api.get_personal_desktop_with_all(
                {"group_uuid": group_uuid})
            for desktop in desktops:
                desktop.group_uuid = ""
                desktop.soft_update()
        group.soft_delete()
        logger.info("delete group %s success", group_uuid)
        ret = terminal_post(
            "/api/v1/terminal/task", {
                "handler": "WebTerminalHandler",
                "command": "delete_group",
                "data": {
                    "group_uuid": group_uuid
                }
            })
        return ret
Пример #8
0
    def close_education_instance(self, data):
        """ 关闭教学桌面 """
        terminal_mac = data.get("mac", "")
        instances = db_api.get_instance_with_all(
            {"terminal_mac": terminal_mac})

        desktop_uuids = list()
        for instance in instances:
            desktop_uuid = instance.desktop_uuid
            if desktop_uuid not in desktop_uuids:
                desktop_uuids.append(desktop_uuid)

        contraller = BaseController()
        desktop_dict = dict()
        desktops = db_api.get_desktop_with_all_by_uuids(desktop_uuids)
        for desktop in desktops:
            desktop_dict[desktop.uuid] = desktop

        for instance in instances:
            desktop = desktop_dict[instance.desktop_uuid]
            if not contraller.stop_instance(instance, desktop):
                logger.error("terminal close personal instance fail: %s" %
                             instance.uuid)
        return build_result("Success")
Пример #9
0
def update_instance_info():
    instances = db_api.get_instance_with_all({})
    rep_data = dict()
    instance_dict = dict()
    for instance in instances:
        instance_dict[instance.uuid] = instance
        host_ip = instance.host.ip
        _d = {
            "uuid": instance.uuid,
            "name": instance.name
            # "spice_port": spice_port
        }
        if host_ip not in rep_data:
            rep_data[host_ip] = list()
        rep_data[host_ip].append(_d)

    # link_num = 0
    for k, v in rep_data.items():
        command_data = {
            "command": "get_status_many",
            "handler": "InstanceHandler",
            "data": {
                "instance": v
            }
        }
        logger.debug("get instance state in node %s", k)
        rep_json = compute_post(k, command_data)
        logger.debug("from compute get rep_json:{}".format(rep_json))
        if rep_json.get("code", -1) != 0:
            # 如果节点计算服务连接失败,则桌面都更新为关机状态
            if rep_json.get("code", -1) == 80000:
                for _d in v:
                    if instance_dict[
                            _d["uuid"]].status != constants.STATUS_INACTIVE:
                        instance_dict[_d["uuid"]].update(
                            {"status": constants.STATUS_INACTIVE})
                        logger.info(
                            "compute service unavaiable at node: %s, update instance.status to inactive: %s",
                            k, _d["uuid"])
            continue
        for item in rep_json.get("data", []):
            for instance in instances:
                if item["uuid"] == instance.uuid:
                    if item.get("state") in [
                            constants.DOMAIN_STATE['running']
                    ]:
                        if constants.STATUS_INACTIVE == instance.status:
                            instance.status = constants.STATUS_ACTIVE
                            instance.soft_update()
                    elif item.get('state') in [
                            constants.DOMAIN_STATE['shutdown'],
                            constants.DOMAIN_STATE['shutoff']
                    ]:
                        if constants.STATUS_ACTIVE == instance.status:
                            instance.status = constants.STATUS_INACTIVE
                        # instance.spice_port = ''
                        # instance.spice_link = 0
                        # instance.allocated = 0
                        # instance.link_time = None

                        # 通知终端管理 桌面关闭
                        # 只对绑定了终端的桌面发通知
                        if instance.terminal_mac:
                            if instance.classify == 2:
                                desktop = db_api.get_personal_desktop_with_first(
                                    {'uuid': instance.desktop_uuid})
                            else:
                                desktop = db_api.get_desktop_by_uuid(
                                    desktop_uuid=instance.desktop_uuid)

                            if desktop:
                                data = {
                                    'desktop_name': desktop.name,
                                    'desktop_order': desktop.order_num,
                                    'desktop_uuid': desktop.uuid,
                                    'instance_uuid': instance.uuid,
                                    'instance_name': instance.name,
                                    'host_ip': instance.host.ip,
                                    'port': instance.spice_port,
                                    'token': instance.spice_token,
                                    'os_type': desktop.os_type,
                                    'terminal_mac': instance.terminal_mac
                                }
                                logger.info(
                                    'rtn: instance.classify: %s, data: %s' %
                                    (instance.classify, data))
                                base_controller = BaseController()
                                ret = base_controller.notice_terminal_instance_close(
                                    data)

                                # 通知完成后,清除桌面与终端的绑定关系
                                if ret:
                                    try:
                                        instance.terminal_mac = None
                                    except Exception as e:
                                        logger.error(
                                            "update instance.terminal_mac to None: %s failed: %s",
                                            instance.uuid, e)

                                logger.info(
                                    'rtn: %s, desktop.uuid: %s, instance.terminal_mac: %s'
                                    %
                                    (ret, desktop.uuid, instance.terminal_mac))
                        instance.soft_update()
                    else:
                        pass
                    # instance.soft_update()
                    logger.debug("the instance %s state %s", instance.uuid,
                                 item.get('state', 0))
                    break
        spice_ports = list()
        for instance in instances:
            if instance.spice_port:
                spice_ports.append(instance.spice_port)

        # 查询监控服务端口
        ports = ",".join(list(set(spice_ports)))
        if ports:
            ports_status = monitor_post(k, "/api/v1/monitor/port_status",
                                        {"ports": ports})
        else:
            ports_status = {}
        logger.info("from node %s get port status:%s", k, ports_status)
        for instance in instances:
            if instance.host.ip == k and instance.spice_port:
                instance.spice_link = ports_status.get("data", {}).get(
                    instance.spice_port, False)
                if not instance.spice_link:
                    instance.allocated = 0
                instance.soft_update()
            logger.debug("the instance %s spice_link:%s", instance.uuid,
                         instance.spice_link)
Пример #10
0
    def person_instance(self, data):
        """ 个人桌面的详情 """
        session_id = data.get("session_id", "")
        desktop_uuid = data.get("desktop_uuid", "")
        desktop_name = data.get("desktop_name", "")
        auth_info = LicenseManager().get_auth_info()
        # 0-过期 1-宽限期 2-试用期 3-正式版
        # if 0 == auth_info.get('auth_type') or (1 == auth_info.get('auth_type') and auth_info.get('delay_days', 0) == 0)\
        #         or (2 == auth_info.get('auth_type') and auth_info.get('expire_time', 0) == 0):
        if auth_info.get("auth_type", 0) == 0:
            return build_result("AuthExpired")
        if self.get_links_num() >= auth_info.get('vdi_size', 0):
            return build_result("AuthSizeExpired")
        # 判断用户的登录状态
        session = db_api.get_group_user_session_first(
            {"session_id": session_id})
        if not session:
            logger.error(
                "terminal user query desktop group error: %s not exist" %
                session_id)
            return build_result("TerminalUserLogout")

        user = db_api.get_group_user_with_first({"uuid": session.user_uuid})
        if not user:
            logger.error(
                "terminal user query desktop group error: %s not exist" %
                session.user_uuid)
            return build_result("TerminalUserNotExistError")

        if not user.enabled:
            logger.error(
                "terminal user query desktop group error: %s is unenabled" %
                user.user_name)
            return build_result("TerminalUserUnenabledError")

        desktop_group = db_api.get_personal_desktop_with_first(
            {"uuid": desktop_uuid})
        if not desktop_group:
            logger.error("person desktop not exist: %s" % desktop_uuid)
            return build_result("DesktopNotExist", name=desktop_name)

        # 查找当前用户分配的随机及静态桌面
        instances = list()
        # 静态桌面
        static_instances = db_api.get_instance_with_all(
            {"user_uuid": user.uuid})
        for obj in static_instances:
            instances.append(obj)

        random_instances = db_api.get_user_random_instance_with_all(
            {"user_uuid": user.uuid})
        for obj in random_instances:
            instances.append(obj.instance)

        # 查找桌面的spice链接状态
        host_spice_ports = dict()
        current_instance = None
        for instance in instances:
            host_ip = instance.host.ip
            if host_ip not in host_spice_ports:
                host_spice_ports[host_ip] = []
            if instance.spice_port:
                host_spice_ports[host_ip].append(str(instance.spice_port))
            if instance.desktop_uuid == desktop_uuid:
                current_instance = instance

        # 获取所有个人桌面的链接状态
        ret = self.get_spice_link(host_spice_ports)
        if current_instance:
            host_ip = current_instance.host.ip
            spice_port = current_instance.spice_port
            if spice_port and ret.get(host_ip, {}).get(spice_port):
                logger.info(
                    "terminal user request the same instance: user %s, desktop %s",
                    user.uuid, desktop_uuid)
                instance_info = current_instance.instance_base_info()
                instance_info.update({"os_type": desktop_group.os_type})
                return build_result("Success", instance_info)
            else:
                # 如果是随机桌面,需要释放
                if desktop_group.desktop_type == constants.RANDOM_DESKTOP:
                    for _obj in random_instances:
                        if _obj.instance_uuid == current_instance.uuid:
                            _obj.soft_delete()
                            break
                    current_instance.allocated = 0
                    current_instance.soft_update()

        # 判断已链接数是否大于等于2
        count = 0
        for k, v in ret.items():
            for i, j in v.items():
                if j:
                    count += 1
        if count >= 2:
            logger.error("user %s person desktop instance much 2", user.uuid)
            return build_result("TerminalPersonalInstanceNumError")

        # 如果桌面组状态为维护
        if desktop_group.maintenance:
            logger.error("person desktop is maintenance: %s", desktop_uuid)
            return build_result("TerminalPersonMaintenance")

        subnet = db_api.get_subnet_by_uuid(desktop_group.subnet_uuid)
        # if not subnet:
        #     logger.error("person instance start error: not subnet %s" % desktop_group.subnet_uuid)
        #     return build_result("TerminalPersonStartError")
        # 启动桌面
        controller = BaseController()
        template = db_api.get_instance_template(desktop_group.template_uuid)
        sys_base, data_base = controller._get_storage_path_with_uuid(
            template.sys_storage, template.data_storage)
        if desktop_group.desktop_type == constants.RANDOM_DESKTOP:
            # 随机桌面
            instance = db_api.get_instance_by_desktop_first_alloc(desktop_uuid)
            if not instance:
                logger.error("person desktop not instance to alloc")
                return build_result("TerminalPersonInstanceNotAlloc")

            ret = controller.create_instance(desktop_group, subnet, instance,
                                             sys_base, data_base)
            if ret.get('code') != 0:
                logger.error("person instance start error: %s", instance.uuid)
                return build_result("TerminalPersonStartError")

            # 记录数据库
            instance_binds = db_api.get_user_random_instance_with_all(
                {"instance_uuid": instance.uuid})
            # 清除其他绑定关系
            for random_ins in random_instances:
                if random_ins.desktop_uuid == desktop_uuid:
                    instance = random_ins.instance
                    instance.allocated = 0
                    instance.terminal_mac = None
                    instance.link_time = None
                    instance.soft_update()
                    random_ins.soft_delete()
            for random_ins in instance_binds:
                random_ins.soft_delete()

            values = {
                "uuid": create_uuid(),
                "desktop_uuid": desktop_uuid,
                "user_uuid": user.uuid,
                "instance_uuid": instance.uuid
            }
            db_api.create_user_random_instance(values)
            instance.allocated = 1
            instance.link_time = datetime.now()
            instance.spice_link = 1
            instance.terminal_mac = user.mac
            instance.soft_update()
            logger.info("random person instance start succes: %s",
                        instance.uuid)
        else:
            static_instance_bind = db_api.get_instance_with_first({
                "desktop_uuid":
                desktop_uuid,
                "user_uuid":
                user.uuid
            })
            if not static_instance_bind:
                logger.error(
                    "static person desktop not bind: desktop group %s, user %s",
                    desktop_uuid, user.uuid)
                return build_result("TerminalPersonInstanceNotAlloc")
            instance = static_instance_bind
            ret = controller.create_instance(desktop_group, subnet, instance,
                                             sys_base, data_base)
            if ret.get('code') != 0:
                logger.error("person instance start error: %s", instance.uuid)
                return build_result("TerminalPersonStartError")
            logger.info("static person instance start succes: %s",
                        instance.uuid)
            instance.link_time = datetime.now()
            instance.terminal_mac = user.mac
            instance.spice_link = 1
            instance.soft_update()
        data = {
            "spice_host": instance.host.ip,
            "spice_token": instance.spice_token,
            "spice_port": instance.spice_port,
            "name": instance.name,
            "uuid": instance.uuid,
            "os_type": desktop_group.os_type
        }
        edu_instance = db_api.get_instance_first({
            "terminal_mac":
            user.mac,
            "classify":
            constants.EDUCATION_DESKTOP,
            "status":
            constants.STATUS_ACTIVE
        })
        if edu_instance:
            desktop = db_api.get_desktop_by_uuid(edu_instance.desktop_uuid)
            controller.stop_instance(edu_instance, desktop)

        return build_result("Success", data)