Ejemplo n.º 1
0
    def get(self, request, *args, **kwargs):
        center_id = str_to_int_or_default(request.GET.get('center_id', 0), 0)

        groups = None
        images = None
        try:
            c_manager = CenterManager()
            centers = c_manager.get_center_queryset()
            if center_id == 0:
                if len(centers) > 0:
                    center_id = centers.first().id

            if center_id > 0:
                images = ImageManager().get_image_queryset_by_center(
                    center_id).filter(tag=Image.TAG_BASE)
                groups = c_manager.get_user_group_queryset_by_center(
                    center_id, user=request.user)
        except (ComputeError, ImageError) as e:
            return render(request, 'error.html',
                          {'errors': ['查询分中心列表时错误', str(e)]})

        context = {}
        context['center_id'] = center_id if center_id > 0 else None
        context['centers'] = centers
        context['groups'] = groups
        context['image_tags'] = Image.CHOICES_TAG
        context['images'] = images
        context['flavors'] = FlavorManager().get_user_flaver_queryset(
            user=request.user)
        return render(request, 'vms_create.html', context=context)
Ejemplo n.º 2
0
    def get(self, request, *args, **kwargs):
        center_id = str_to_int_or_default(request.GET.get('center', 0), 0)
        group_id = str_to_int_or_default(request.GET.get('group', 0), 0)
        host_id = str_to_int_or_default(request.GET.get('host', 0), 0)
        user_id = str_to_int_or_default(request.GET.get('user', 0), 0)
        search = request.GET.get('search', '')

        # 超级用户可以有用户下拉框选项
        auth = request.user
        if auth.is_superuser:
            users = User.objects.all()
        else:  # 普通用户只能查看自己的虚拟机,无用户下拉框选项
            users = None
            user_id = auth.id

        v_manager = VmManager()
        try:
            queryset = v_manager.filter_vms_queryset(
                center_id=center_id,
                group_id=group_id,
                host_id=host_id,
                search=search,
                user_id=user_id,
                all_no_filters=auth.is_superuser)
        except VmError as e:
            return render(request, 'error.html',
                          {'errors': ['查询虚拟机时错误', str(e)]})

        queryset = queryset.prefetch_related('vdisk_set')  # 反向预查询硬盘(避免多次访问数据库)
        try:
            c_manager = CenterManager()
            g_manager = GroupManager()
            centers = c_manager.get_center_queryset()
            if center_id > 0:
                groups = c_manager.get_group_queryset_by_center(center_id)
            else:
                groups = g_manager.get_group_queryset()

            if group_id > 0:
                hosts = g_manager.get_all_host_queryset_by_group(group_id)
            else:
                hosts = None
        except ComputeError as e:
            return render(request, 'error.html',
                          {'errors': ['查询虚拟机时错误', str(e)]})

        context = {
            'center_id': center_id if center_id > 0 else None,
            'centers': centers,
            'groups': groups,
            'group_id': group_id if group_id > 0 else None,
            'hosts': hosts,
            'host_id': host_id if host_id > 0 else None,
            'search': search,
            'users': users,
            'user_id': user_id
        }
        context = self.get_vms_list_context(request, queryset, context)
        return render(request, 'vms_list.html', context=context)
Ejemplo n.º 3
0
    def get(self, request, *args, **kwargs):
        center_id = str_to_int_or_default(request.GET.get('center', 0), 0)
        group_id = str_to_int_or_default(request.GET.get('group', 0), 0)
        quota_id = str_to_int_or_default(request.GET.get('quota', 0), 0)
        user_id = str_to_int_or_default(request.GET.get('user', 0), 0)
        search = request.GET.get('search', '')

        # 超级用户可以有用户下拉框选项
        auth = request.user
        if auth.is_superuser:
            users = User.objects.all()
        else:  # 普通用户只能查看自己的虚拟机,无用户下拉框选项
            users = None
            user_id = auth.id

        manager = VdiskManager()
        try:
            queryset = manager.filter_vdisk_queryset(
                center_id=center_id,
                group_id=group_id,
                quota_id=quota_id,
                search=search,
                user_id=user_id,
                all_no_filters=auth.is_superuser)
        except VdiskError as e:
            return render(request, 'error.html',
                          {'errors': ['查询云硬盘时错误', str(e)]})

        try:
            c_manager = CenterManager()
            centers = c_manager.get_center_queryset()
            if center_id > 0:
                groups = c_manager.get_group_queryset_by_center(center_id)
            else:
                groups = GroupManager().get_group_queryset()
        except ComputeError as e:
            return render(request, 'error.html',
                          {'errors': ['查询机组时错误', str(e)]})

        if group_id > 0:
            quotas = manager.get_quota_queryset_by_group(group_id)
        else:
            quotas = None

        context = {}
        context['center_id'] = center_id if center_id > 0 else None
        context['centers'] = centers
        context['groups'] = groups
        context['group_id'] = group_id if group_id > 0 else None
        context['quotas'] = quotas
        context['quota_id'] = quota_id if quota_id > 0 else None
        context['search'] = search
        context['users'] = users
        context['user_id'] = user_id
        context = self.get_disks_list_context(request, queryset, context)
        return render(request, 'vdisk_list.html', context=context)
Ejemplo n.º 4
0
    def get_center_vlan_queryset(self, center):
        """
        分中心的vlan查询集

        :param center: 分中心实例,或id
        :return:
            QuerySet()
        """
        groups = CenterManager().get_group_queryset_by_center(center)
        queryset = self.get_vlan_queryset()
        return queryset.filter(group__in=Subquery(groups.values('id'))).all()
Ejemplo n.º 5
0
    def get(self, request, *args, **kwargs):
        center_id = str_to_int_or_default(request.GET.get('center', 0), 0)
        group_id = str_to_int_or_default(request.GET.get('group', 0), 0)
        host_id = str_to_int_or_default(request.GET.get('host', 0), 0)
        type_id = str_to_int_or_default(request.GET.get('type', 0), 0)
        search = request.GET.get('search', '')
        user = request.user

        c_manager = CenterManager()
        g_manager = GroupManager()
        p_manager = PCIDeviceManager()
        p_manager._group_manager = g_manager
        try:
            queryset = p_manager.filter_pci_queryset(center_id=center_id,
                                                     group_id=group_id,
                                                     host_id=host_id,
                                                     search=search,
                                                     type_id=type_id,
                                                     user=user,
                                                     all_no_filters=True)
        except DeviceError as e:
            return render(request, 'error.html',
                          {'errors': ['查询PCI设备时错误', str(e)]})

        try:
            centers = c_manager.get_center_queryset()
            if center_id > 0:
                groups = c_manager.get_user_group_queryset_by_center(
                    center_or_id=center_id, user=user)
            else:
                groups = c_manager.get_user_group_queryset(user=user)

            if group_id > 0:
                hosts = g_manager.get_all_host_queryset_by_group(group_id)
            else:
                hosts = None
        except ComputeError as e:
            return render(request, 'error.html',
                          {'errors': ['查询PCI设备时错误', str(e)]})

        context = {
            'center_id': center_id if center_id > 0 else None,
            'centers': centers,
            'groups': groups,
            'group_id': group_id if group_id > 0 else None,
            'hosts': hosts,
            'host_id': host_id if host_id > 0 else None,
            'search': search,
            'types': PCIDevice.CHOICES_TYPE,
            'type_id': type_id
        }
        context = self.get_vms_list_context(request, queryset, context)
        return render(request, 'pci_list.html', context=context)
Ejemplo n.º 6
0
    def get(self, request, *args, **kwargs):
        center_id = str_to_int_or_default(request.GET.get('center', 0), 0)
        tag = str_to_int_or_default(request.GET.get('tag', 0), 0)
        sys_type = str_to_int_or_default(request.GET.get('sys_type', 0), 0)
        search = request.GET.get('search', '')

        try:
            api = ImageManager()
            queryset = api.filter_image_queryset(center_id=center_id,
                                                 tag=tag,
                                                 sys_type=sys_type,
                                                 search=search,
                                                 all_no_filters=True)
        except ImageError as e:
            return render(request, 'error.html',
                          {'errors': ['查询镜像时错误', str(e)]})

        try:
            centers = CenterManager().get_center_queryset()
        except ComputeError as e:
            return render(request, 'error.html',
                          {'errors': ['查询分中心时错误', str(e)]})

        context = {}
        context['center_id'] = center_id if center_id > 0 else None
        context['centers'] = centers
        context['tag_value'] = tag
        context['tags'] = Image.CHOICES_TAG
        context['sys_type_value'] = sys_type
        context['sys_types'] = Image.CHOICES_SYS_TYPE
        context['search'] = search
        context = self.get_page_context(request, queryset, context)
        return render(request, 'image_list.html', context=context)
Ejemplo n.º 7
0
    def get(self, request, *args, **kwargs):
        center_id = str_to_int_or_default(request.GET.get('center_id', 0), 0)

        try:
            c_manager = CenterManager()
            centers = c_manager.get_center_queryset()
            groups = None
            if center_id > 0:
                groups = c_manager.get_user_group_queryset_by_center(
                    center_id, user=request.user)
        except ComputeError as e:
            return render(request, 'error.html',
                          {'errors': ['查询分中心列表时错误', str(e)]})

        context = {}
        context['center_id'] = center_id if center_id > 0 else None
        context['centers'] = centers
        context['groups'] = groups
        return render(request, 'vdisk_create.html', context=context)
Ejemplo n.º 8
0
    def get_image_queryset_by_center(self, center_or_id):
        '''
        获取一个分中心下的所有镜像查询集

        :param center_or_id: 分中心对象或id
        :return:
             images: QuerySet   # success
        :raise ImageError
        '''
        try:
            pool_ids = CenterManager().get_pool_ids_by_center(center_or_id)
        except ComputeError as e:
            raise ImageError(msg=str(e))
        return self.get_image_queryset().filter(ceph_pool__in=pool_ids).all()
Ejemplo n.º 9
0
    def get_vdisk_queryset_by_center(self, center):
        '''
        分中心下的硬盘查询集

        :param center: 分中心对象或id
        :return:
            QuerySet()

        :raises: VdiskError
        '''
        try:
            group_ids = CenterManager().get_group_ids_by_center(center)
        except ComputeError as e:
            raise VdiskError(msg=str(e))
        quota_ids = self.get_quota_ids_by_group_ids(group_ids)
        qs = self.get_vdisk_queryset_by_quota_ids(quota_ids)
        return qs
Ejemplo n.º 10
0
    def filter_vlan_queryset(self,
                             center: int = None,
                             group: int = None,
                             is_public: bool = None,
                             user=None):
        """
        筛选vlan查询集

        :param center: 分中心id
        :param group: 宿主机组id
        :param is_public: 公网或私网
        :param user: 用户实例,用于过滤用户有权限使用的vlan
        :return:
            QuerySet()
        """
        group_set = None
        if user:
            group_set = user.group_set.all()

        if group:
            if not group_set:
                group_set = GroupManager().get_group_queryset()

            group_set = group_set.filter(id=group)
        elif center:
            if group_set:
                group_set = group_set.filter(center=center)
            else:
                group_set = CenterManager().get_group_queryset_by_center(
                    center)

        queryset = self.get_vlan_queryset()
        if is_public is True:
            queryset = queryset.filter(tag=Vlan.NET_TAG_PUBLIC)
        elif is_public is False:
            queryset = queryset.filter(tag=Vlan.NET_TAG_PRIVATE)

        if group_set:
            queryset = queryset.filter(
                group__in=Subquery(group_set.values('id'))).all()

        return queryset
Ejemplo n.º 11
0
    def get(self, request, *args, **kwargs):
        if not request.user.is_superuser:
            return HttpResponse('您无权访问此页面')

        centers = CenterManager().get_stat_center_queryset().values(
            'id', 'name', 'mem_total', 'mem_allocated', 'real_cpu',
            'vcpu_total', 'vcpu_allocated', 'vm_created')
        groups = GroupManager().get_stat_group_queryset().values(
            'id', 'name', 'center__name', 'mem_total', 'mem_allocated',
            'real_cpu', 'vcpu_total', 'vcpu_allocated', 'vm_created')
        hosts = Host.objects.select_related('group').values(
            'id', 'ipv4', 'group__name', 'mem_total', 'mem_allocated',
            'real_cpu', 'vcpu_total', 'vcpu_allocated', 'vm_created').all()
        return render(request,
                      'reports_list.html',
                      context={
                          'centers': centers,
                          'groups': groups,
                          'hosts': hosts
                      })
Ejemplo n.º 12
0
class PCIDeviceManager:
    DeviceError = DeviceError

    def __init__(self):
        self._center_manager = CenterManager()
        self._group_manager = GroupManager()
        self._host_manager = HostManager()

    def get_device_queryset(self):
        '''
        获取所有PCI设备的查询集
        :return: QuerySet()
        '''
        return PCIDevice.objects.all()

    def get_device_by_id(self, device_id: int, related_fields=('host', )):
        '''
        :return:
            PCIDevice()     # success
            None            # not exists
        :raises:  DeviceError
        '''
        qs = self.get_device_queryset()
        try:
            if related_fields:
                qs = qs.select_related(*related_fields).all()
            return qs.filter(pk=device_id).first()
        except Exception as e:
            raise DeviceError(msg=str(e))

    def get_device_by_address(self, address: str):
        '''
        :return:
            PCIDevice()     # success
            None            # not exists
        '''
        return self.get_device_queryset().filter(address=address).first()

    def get_user_pci_queryset(self, user):
        """
        用户有访问权限的PCI设备查询集

        :param user: 用户对象
        :return:
            QuerySet()

        :raises: DeviceError
        """
        try:
            h_ids = GroupManager().get_user_host_ids(user=user)
            qs = self.get_device_queryset().filter(id__in=h_ids).all()
        except ComputeError as e:
            raise DeviceError(msg=str(e))
        return qs

    def get_pci_queryset_by_center(self, center):
        """
        分中心下的PCI设备查询集

        :param center: Center对象或id
        :return:
            QuerySet()

        :raises: DeviceError
        """
        try:
            group_ids = self._center_manager.get_group_ids_by_center(center)
            host_ids = self._group_manager.get_host_ids_by_group_ids(group_ids)
        except ComputeError as e:
            raise DeviceError(msg=str(e))

        return self.get_device_queryset().filter(host__in=host_ids).all()

    def get_user_pci_queryset_by_center(self, center, user):
        """
        用户有访问权限的,分中心下的PCI设备查询集

        :param center: Center对象或id
        :param user: 用户对象
        :return:
            QuerySet()

        :raises: DeviceError
        """
        try:
            group_ids = self._center_manager.get_user_group_ids_by_center(
                center=center, user=user)
            host_ids = self._group_manager.get_host_ids_by_group_ids(group_ids)
        except ComputeError as e:
            raise DeviceError(msg=str(e))

        return self.get_device_queryset().filter(host__in=host_ids).all()

    def get_pci_queryset_by_group(self, group):
        '''
        宿主机组下的PCI设备查询集

        :param group: Group对象或id
        :return:
            QuerySet()

        :raises: DeviceError
        '''
        try:
            ids = self._group_manager.get_host_ids_by_group(group_or_id=group)
        except ComputeError as e:
            raise DeviceError(msg=str(e))

        return self.get_device_queryset().filter(host__in=ids).all()

    def get_user_pci_queryset_by_group(self, group, user):
        '''
        用户有访问权限的,机组下的PCI设备查询集

        :param group: Group对象或id
        :param user: 用户对象
        :return:
            QuerySet()

        :raises: DeviceError
        '''
        gm = self._group_manager

        try:
            group = gm.enforce_group_obj(group)
            if not group.user_has_perms(user=user):
                raise DeviceError(msg='无宿主机组的访问权限')
            ids = gm.get_host_ids_by_group(group_or_id=group)
        except ComputeError as e:
            raise DeviceError(msg=str(e))

        return self.get_device_queryset().filter(host__in=ids).all()

    def get_pci_queryset_by_host(self, host):
        """
        宿主机的PCI设备查询集

        :param host: Host对象或id
        :return:
            QuerySet()

        :raises: DeviceError
        """
        return self.get_device_queryset().filter(host=host).all()

    def get_user_pci_queryset_by_host(self, host, user):
        """
        用户有访问权限的,宿主机的PCI设备查询集

        :param host: Host对象或id
        :param user: 用户对象
        :return:
            QuerySet()

        :raises: DeviceError
        """
        try:
            host = self._host_manager.enforce_host_obj(host)
        except ComputeError as e:
            raise DeviceError(msg=str(e))

        if not host.user_has_perms(user=user):
            raise DeviceError(msg='无宿主机的访问权限')

        return self.get_device_queryset().filter(host=host).all()

    def device_wrapper(self, device: PCIDevice):
        '''
        PCI设备对象的包装器

        :param device:PCI设备对象
        :return:
            BasePCIDevice子类     # GPUDevice

        :raises:  DeviceError
        '''
        if device.type == device.TYPE_GPU:
            return GPUDevice(db=device)

        return DeviceError(msg='未知设备')

    def mount_to_vm(self, device: PCIDevice, vm):
        '''
        挂载设备到虚拟机

        :param device: pci设备对象
        :param vm: 虚拟机对象
        :return:
            True    # success

        :raises: DeviceError
        '''
        host = vm.host
        dev = self.device_wrapper(device)
        if dev.need_in_same_host():
            if dev.host_id != host.id:
                raise DeviceError(msg='设备和虚拟机不在同一宿主机')

        try:
            dev.mount(vm=vm)
        except DeviceError as e:
            raise DeviceError(msg=f'与虚拟机建立挂载关系失败, {str(e)}')

        xml_desc = dev.xml_desc
        try:
            if VirtAPI().attach_device(host_ipv4=host.ipv4,
                                       vm_uuid=vm.hex_uuid,
                                       xml=xml_desc):
                return True
            raise VirtError(msg='挂载到虚拟机失败')
        except VirtError as e:
            try:
                dev.umount()
            except:
                pass
            raise DeviceError(msg=str(e))

    def umount_from_vm(self, device: PCIDevice):
        '''
        卸载设备从虚拟机

        :param device: pci设备对象
        :return:
            True    # success

        :raises: DeviceError
        '''
        dev = self.device_wrapper(device)
        vm = dev.vm
        if not vm:
            return True

        host = vm.host
        xml_desc = dev.xml_desc
        v_api = VirtAPI()
        try:
            if not v_api.detach_device(
                    host_ipv4=host.ipv4, vm_uuid=vm.hex_uuid, xml=xml_desc):
                raise VirtError(msg='从虚拟机卸载设备失败')
        except VirtError as e:
            raise DeviceError(msg=str(e))

        try:
            dev.umount()
        except DeviceError as e:
            v_api.attach_device(host_ipv4=host.ipv4,
                                vm_uuid=vm.hex_uuid,
                                xml=xml_desc)
            raise DeviceError(msg=f'与虚拟机解除挂载关系失败, {str(e)}')

        return True

    def filter_pci_queryset(self,
                            center_id: int = 0,
                            group_id: int = 0,
                            host_id: int = 0,
                            type_id: int = 0,
                            search: str = '',
                            user=None,
                            all_no_filters: bool = False,
                            related_fields: tuple = ()):
        """
        通过条件筛选虚拟机查询集

        :param center_id: 分中心id,大于0有效
        :param group_id: 机组id,大于0有效
        :param host_id: 宿主机id,大于0有效
        :param type_id: 设备类型id,大于0有效
        :param search: 关键字筛选条件
        :param user: 用户对象
        :param all_no_filters: 筛选条件都无效时;True: 返回所有; False: 抛出错误
        :param related_fields: 外键字段;外键字段直接一起获取,而不是惰性的用时再获取
        :return:
            QuerySet    # success

        :raise: DeviceError
        """
        if not related_fields:
            related_fields = ('host__group', 'vm__mac_ip')

        if center_id <= 0 and group_id <= 0 and host_id <= 0 and type_id <= 0 and not search:
            if user and user.id:
                return self.get_user_pci_queryset(user=user)

            if not all_no_filters:
                raise DeviceError(msg='无有效的查询条件')

            return self.get_device_queryset().select_related(
                *related_fields).all()

        queryset = None
        if host_id > 0:
            queryset = self.get_user_pci_queryset_by_host(host=host_id,
                                                          user=user)
        elif group_id > 0:
            queryset = self.get_user_pci_queryset_by_group(group_id, user=user)
        elif center_id > 0:
            queryset = self.get_user_pci_queryset_by_center(center=center_id,
                                                            user=user)

        if type_id > 0:
            if queryset is not None:
                queryset = queryset.filter(type=type_id).all()
            else:
                queryset = self.get_device_queryset().filter(
                    type=type_id).all()

        if search:
            if queryset is not None:
                queryset = queryset.filter(
                    Q(remarks__icontains=search)
                    | Q(host__ipv4__icontains=search)).all()
            else:
                queryset = self.get_device_queryset().filter(
                    Q(remarks__icontains=search)
                    | Q(host__ipv4__icontains=search)).all()

        return queryset.select_related(*related_fields).all()
Ejemplo n.º 13
0
 def __init__(self):
     self._center_manager = CenterManager()
     self._group_manager = GroupManager()
     self._host_manager = HostManager()