예제 #1
0
 def get_snapshots_for_instance(self, request):
     instance_uuid = request.GET.get('instance_uuid', None)
     # check if the user requests snapshots for an instance that he owns
     instance = Instance.objects.filter(id=instance_uuid).first()
     if not instance:
         raise APIBadRequest(
             _('Cannot get snapshots for non existing instance.'))
     client_project = Project.objects.filter(
         service__client__in=request.user.clients.all()).first(
         )  # type: Project
     if not client_project:
         raise APIBadRequest(_('Client does not have any project.'))
     if instance.project.project_id != client_project.project_id:
         raise ObjectNotFound()
     volume_attachments = VolumeAttachments.objects.filter(
         server_id=instance_uuid).values('volume_id')
     volumes = Volume.objects.filter(id__in=volume_attachments)
     volume_snapshots_qs = VolumeSnapshot.objects.filter(volume__in=volumes)
     volume_snapshots_count = volume_snapshots_qs.count()
     volume_snapshots_uuids = volume_snapshots_qs.values('id')
     image_snapshots = Image.objects.get_images_for_project(
         project_id=client_project.project_id).filter(
             Q(volume_snapshot_uuid__in=volume_snapshots_uuids)
             | Q(instance_uuid=instance_uuid))
     serializer = ImageSerializer(image_snapshots, many=True)
     return Response({
         'objects': serializer.data,
         'volume_snapshots_count': volume_snapshots_count,
     })
예제 #2
0
    def enable_sfa_method(self, request):
        verification_code = request.data.get('verification_code')
        try:
            int(verification_code)
        except Exception as e:
            del e  # unused
            raise APIBadRequest(_('Code has to be a number'))
        try:
            sfa_type = self.get_sfa_type()
        except Exception as e:
            raise e
        # sfa_method should already be here added through add_sfa_method action
        sfa_method = SecondFactorAuthMethod.objects.filter(
            user=self.request.user, type=sfa_type).first()
        if not sfa_method:
            raise SFAMethodNotAdded()
        if sfa_method.enabled:
            raise APIBadRequest(_('This method is already enabled'))
        google_auth_data = self.get_google_auth_data(sfa_method=sfa_method,
                                                     create=True)
        secret_key = google_auth_data.get_secret_key()
        totp_code = pyotp.totp.TOTP(secret_key)
        allowed_to_enable = totp_code.verify(verification_code)
        if allowed_to_enable:
            sfa_method.enabled = True
            # if no other method is set as default, set this one
            default_method = SecondFactorAuthMethod.objects.filter(
                user=self.request.user, default=True).first()
            if not default_method:
                sfa_method.default = True
            sfa_method.save()
        else:
            raise APIBadRequest(_('Verification code is invalid.'))

        return Response({'detail': _('Operation completed')})
예제 #3
0
 def get_groups_available_for_user(self, request):
     """
     Gets user groups where a given user is not associated with them
     :param request:
     :return:
     """
     user_id = request.query_params.get('user_id', None)
     search = request.query_params.get('search', None)
     if not user_id:
         raise APIBadRequest(_('Missing user id to get groups for.'))
     try:
         user = AppUser.objects.get(id=user_id)
     except AppUser.DoesNotExist:
         raise APIBadRequest(_('User with provided id not found.'))
     if search:
         qs = UserGroup.objects.filter(name=search)
     else:
         qs = UserGroup.objects.all()
     qs = qs.exclude(users__in=[user])
     page = self.paginate_queryset(qs)
     if page is not None:
         serializer = UserGroupSerializer(page, many=True)
         return self.get_paginated_response(serializer.data)
     serializer = UserGroupSerializer(qs, many=True)
     return Response(serializer.data)
예제 #4
0
 def send_verification_code(self, request):
     if not request.user.mobile_phone_number:
         raise APIBadRequest(
             _('You need to set your mobile phone number first on your profile.'
               ))
     try:
         provider_class_caller = import_string(
             'fleio.core.sms_providers.{}.{}.get_sms_provider_class'.format(
                 sms_authenticator_settings.provider,
                 sms_authenticator_settings.provider))
     except ImportError as e:
         del e  # unused
         raise APIBadRequest(_('Could not find SMS provider.'))
     provider_class = provider_class_caller()
     try:
         sfa_type = self.get_sfa_type()
     except Exception as e:
         raise e
     # sfa_method should already be here added through add_sfa_method action
     sfa_method = SecondFactorAuthMethod.objects.filter(
         user=self.request.user, type=sfa_type).first()
     if not sfa_method:
         raise SFAMethodNotAdded()
     sms_auth_data = self.get_sms_auth_data(sfa_method=sfa_method,
                                            create=True)
     secret_key = sms_auth_data.get_secret_key()
     code = pyotp.hotp.HOTP(secret_key).at(count=sms_auth_data.counter)
     provider_class.send_sms(
         phone_number=self.request.user.mobile_phone_number,
         message=sms_authenticator_settings.message.format(code),
         subject=sms_authenticator_settings.subject,
     )
     return Response({'detail': _('Verification code was sent.')})
예제 #5
0
    def available_to_client(self, request, pk):
        del pk  # unused

        image = self.get_object()
        client_id = request.data.get('client', None)
        if not client_id:
            raise APIBadRequest(detail=_('Client ID required'))
        try:
            client = Client.objects.get(pk=client_id)
        except (Client.DoesNotExist, ValueError, TypeError):
            raise APIBadRequest(detail=_('Client does not exist'))
        needs_sharing = False
        sharing_message = None
        client_first_project = client.first_project  # Replace when multiple projects per client are supported
        # client.services.filter(openstack_project__project_id=image.owner).exists()
        if client_first_project and client_first_project.project_id != image.owner:
            # Image.owner is not in Client's project
            if image.visibility == OpenStackImageVisibility.PRIVATE:
                # Private images with owner different than Client need sharing
                needs_sharing = True
                sharing_message = _('Image is private and owned by another project')
            elif image.visibility == OpenStackImageVisibility.SHARED:
                # Shared image with owner different and client not in members need sharing
                if not image.members.filter(member=client_first_project).exists():
                    needs_sharing = False
                    sharing_message = _('Image is owned by another project')
        return Response({'needsSharing': needs_sharing,
                         'sharingMessage': sharing_message})
예제 #6
0
    def create(self, request, *args, **kwargs):
        if not request.FILES.get('data'):
            error_map = {
                'FILE_TOO_BIG':
                _('Could not upload attachment. File size is too large.'),
                'NO_SPACE_ON_DISK':
                _('Could not upload attachment. Not enough free space on destination file system.'
                  )
            }
            if self.request.META.get('FILE_TOO_BIG'):
                raise APIBadRequest(detail=error_map.get('FILE_TOO_BIG'))
            elif self.request.META.get('NO_SPACE_ON_DISK'):
                raise APIBadRequest(detail=error_map.get('NO_SPACE_ON_DISK'))
            else:
                raise APIBadRequest(detail='Missing data')

        attachment_data = request.FILES.get('data').read()
        params = {
            'file_name': request.POST.get('file_name'),
            'content_type': request.FILES.get('data').content_type
        }
        attachment_storage = AttachmentsStorage.get_attachments_storage()
        disk_file_name = attachment_storage.create_disk_file_name(
            params['file_name'])
        params['disk_file'] = disk_file_name
        attachment_storage.save_attachment(disk_file_name=disk_file_name,
                                           attachment_data=attachment_data)
        obj = Attachment.objects.create(**params)
        return Response(data=AttachmentSerializerDetail(obj).data)
예제 #7
0
    def update_image_member_status(self, request, pk):
        del pk  # unused
        image = self.get_object()
        member_status = request.data.get('member_status', None)

        if not member_status or (
                member_status != ImageMemberStatus.PENDING
                and member_status != ImageMemberStatus.ACCEPTED
                and member_status != ImageMemberStatus.REJECTED):
            raise APIBadRequest(_('Invalid member status received.'))

        try:
            project = request.user.clients.first().first_project
        except (Exception, AttributeError) as e:
            del e  # unused
            raise APIBadRequest(
                _('Could not find related client OpenStack project.'))
        api_session = IdentityUserApi(project.project_id,
                                      project.project_domain_id,
                                      cache=request.session).session
        api_image = APIImage(db_image=image, api_session=api_session)
        try:
            api_image.update_member(member_project_id=project.project_id,
                                    member_status=member_status)
        except Exception as e:
            raise APIBadRequest(str(e))
        return Response({'detail': _('Image member status update sent.')})
예제 #8
0
 def perform_update(self, serializer):
     sfa_type = self.get_object()
     enabled_to_staff = serializer.validated_data.get('enabled_to_staff', None)
     enabled_to_enduser = serializer.validated_data.get('enabled_to_enduser', None)
     no_other_option_msg = _(
         'Second factor authentication is required and users have no other option than the one you want to disable.'
     )
     staff_users = AppUser.objects.filter(is_staff=True)
     if enabled_to_staff is False:
         # check if other method is available if sfa is required
         staff_other_types_count = SecondFactorAuthType.objects.filter(
             enabled_to_staff=True
         ).exclude(id=sfa_type.id).count()
         if staff_other_types_count == 0 and (sfa_settings.require_staff_users_to_use_sfa is True or
                                              sfa_settings.require_end_users_to_use_sfa is True):
             raise APIBadRequest(no_other_option_msg)
         # disable methods only for staff-users
         SecondFactorAuthMethod.objects.filter(type=sfa_type, user__in=staff_users).update(
             enabled=False, default=False
         )
     if enabled_to_enduser is False:
         enduser_other_types_count = SecondFactorAuthType.objects.filter(
             enabled_to_enduser=True
         ).exclude(id=sfa_type.id).count()
         # check if other method is available if sfa is required
         if enduser_other_types_count == 0 and sfa_settings.require_end_users_to_use_sfa is True:
             raise APIBadRequest(no_other_option_msg)
         # disable methods only for end-users
         SecondFactorAuthMethod.objects.filter(
             type=sfa_type
         ).exclude(
             user__in=staff_users
         ).update(enabled=False, default=False)
     return super().perform_update(serializer=serializer)
예제 #9
0
 def create_options(self, request):
     network_id = request.query_params.get('network_id', None)
     if not network_id:
         raise APIBadRequest(_('Network id required in request'))
     try:
         network = Network.objects.get(id=network_id)
         pools = SubnetPool.objects.filter(region=network.region)
         ipv6_modes = ['slaac', 'dhcpv6-stateful', 'dhcpv6-stateless']
         return Response({'pools': SubnetPoolSerializer(instance=pools, many=True).data, 'ipv6_modes': ipv6_modes})
     except Network.DoesNotExist:
         raise APIBadRequest(_('Network not found'))
예제 #10
0
 def reset_state(self, request, pk):
     del pk  # unused
     os_volume_snapshot = self.get_openstack_volume_snapshot()
     state = request.data.get('state')
     if not state:
         raise APIBadRequest(
             _('Cannot reset state because new state was not provided.'))
     try:
         os_volume_snapshot.reset_state(state=state)
     except Exception as e:
         raise APIBadRequest(_(str(e)))
     return Response({'detail': _('State reset scheduled.')})
예제 #11
0
def get_applicable_tax_rules(request: Request):
    client_id = request.query_params.get('client_id', None)
    if not client_id:
        raise APIBadRequest(_('No client id provided'))
    client = Client.objects.filter(id=client_id, users__in=[request.user]).first()
    if not client:
        raise APIBadRequest(_('No client found for provided id'))
    applicable_tax_rules = TaxRule.for_country_and_state(country=client.country_name, state=client.state)
    if len(applicable_tax_rules) == 0:
        return Response({})
    else:
        return Response(EndUserTaxRuleSerializer(instance=applicable_tax_rules, many=True).data)
예제 #12
0
 def dissociate_configurable_option(self, request, pk):
     del pk  # unused
     product = self.get_object()
     option_id = request.data.get('option', None)
     if option_id is None:
         raise APIBadRequest(_('No option provided'))
     try:
         option_id = int(option_id)
     except ValueError:
         raise APIBadRequest(_('Option does not exist'))
     if product.configurable_options.filter(id=option_id).exists() == 0:
         raise APIConflict(_('Option not associated with product'))
     ProductConfigurableOption.objects.filter(
         product=product, configurable_option__id=option_id).delete()
     return Response({'detail': _('Option dissociated')})
예제 #13
0
 def get_available_flavor_groups_for_image(self, request):
     image_id = request.query_params.get('image_id')
     search = request.query_params.get('search')
     if not image_id:
         raise APIBadRequest(_('Missing image id to filter flavor groups against it'))
     try:
         Image.objects.get(id=image_id)
     except Image.DoesNotExist:
         raise APIBadRequest(_('No image to filter against'))
     queryset = FlavorGroup.objects.all()
     queryset = queryset.exclude(images__id=image_id)
     if search:
         queryset = queryset.filter(name__icontains=search)
     objects = AdminFlavorGroupSerializer(instance=queryset, many=True, read_only=True).data
     return Response({'objects': objects})
예제 #14
0
 def update_billing_plan(self, request, pk):
     del pk  # unused
     if not staff_active_features.is_enabled('openstack.plans'):
         raise APIBadRequest(detail=_('Cannot update os plan because openstack plans feature is disabled'))
     service = self.get_object()  # type: Service
     if service.status in [
         ServiceStatus.terminated,
         ServiceStatus.canceled,
         ServiceStatus.fraud
     ]:
         raise APIBadRequest(_('Cannot change pricing plan for service in this state.'))
     new_plan_id = request.data.get('plan')
     billing_module = module_factory.get_module_instance(service=service)
     billing_module.change_pricing_plan(service=service, new_plan_id=new_plan_id)
     return Response({'detail': _('Pricing plan updated')})
예제 #15
0
 def assign_client_group_to_flavor(self, request, pk):
     """assigns a client group to a flavor"""
     flavor = self.get_object()
     client_group_id = request.data.get('client_group', None)
     if not client_group_id:
         raise APIBadRequest(_('No client group id specified.'))
     client_group = ClientGroup.objects.filter(id=client_group_id).first()
     if not client_group:
         raise APIBadRequest(_('No client group found for assignment.'))
     if client_group in flavor.show_to_groups.all():
         raise APIBadRequest(
             _('Client group already assigned to this flavor.'))
     flavor.show_to_groups.add(client_group)
     return Response(
         {'detail': _('Successfully assigned client group to flavor.')})
예제 #16
0
def process_login_with_sfa(request) -> (bool, Optional[str]):
    sfa_params = request.data.get('sfa_params')
    sfa_completed = False
    cookies = request.stream.COOKIES or {}
    remember_sfa_token = cookies.get('rSFA')
    user = auth.authenticate(username=request.data.get('username'),
                             password=request.data.get('password'))
    if remember_sfa_token and RememberSfa(user=user).check_token(
            token=remember_sfa_token):
        sfa_completed = True
    if sfa_params:
        del request.data['sfa_params']
        sfa_method_name = sfa_params.get('sfa_method_name')
        remember_sfa = sfa_params.get('rememberSFA', False)
        try:
            confirm_method = import_string(
                'plugins.{}.common.base_views.confirm_login'.format(
                    sfa_method_name))
        except ImportError:
            LOG.debug('Could not find sfa confirm method for {}'.format(
                sfa_method_name))
            raise APIBadRequest(_('Could not find confirmation method'))
        sfa_args = sfa_params.get('args')
        if sfa_args:
            try:
                remember_sfa_token = confirm_method(user=user,
                                                    remember=remember_sfa,
                                                    **sfa_args)
                sfa_completed = True
            except Exception as e:
                raise e
    return sfa_completed, remember_sfa_token
예제 #17
0
 def perform_update(self, serializer):
     db_subnet = self.get_object()
     serializer.is_valid(raise_exception=True)
     # do not send allocation pools to openstack if they were not changed
     existing_allocation_pools = db_subnet.allocation_pools
     provided_allocation_pools = serializer.validated_data.get(
         'allocation_pools')
     if len(existing_allocation_pools) == len(provided_allocation_pools):
         allocation_pools_matched = 0
         for e_ap in existing_allocation_pools:
             for p_ap in provided_allocation_pools:
                 if p_ap.get('start') == e_ap.get('start') and p_ap.get(
                         'end') == e_ap.get('end'):
                     allocation_pools_matched += 1
         if allocation_pools_matched == len(existing_allocation_pools):
             del serializer.validated_data['allocation_pools']
     os_api = OSApi.from_request(request=self.request)
     try:
         os_api.subnets.update(old_values=serializer.instance,
                               new_values=serializer.validated_data)
     except BadRequest as e:
         raise APIBadRequest(force_text(e))
     except Conflict as e:
         raise APIConflict(force_text(e))
     except Exception as e:
         LOG.error(e)
         handle(self.request, message=_('Unable to update subnet'))
예제 #18
0
 def create(self, request, *args, **kwargs):
     serializer = self.get_serializer(data=request.data)
     serializer.is_valid(raise_exception=True)
     if not validate_cloud_objects_limit():
         raise APIBadRequest(_('Licence cloud objects limit reached. Please check your license.'))
     try:
         os_image_api = Images(api_session=self.os_admin_api.session)
         image = os_image_api.create(owner=self.os_admin_api.project_id, **serializer.validated_data)
     except Exception as e:
         LOG.error(e)
         handle(self.request, message='Unable to create the image')
     else:
         headers = self.get_success_headers(serializer.data)
         data = serializer.data
         data['id'] = image.id
         reseller_resources = user_reseller_resources(self.request.user)
         if reseller_resources:
             Image.objects.update_or_create(
                 defaults={
                     'reseller_resources': reseller_resources,
                     'min_disk': serializer.validated_data.get('min_disk', 0),
                     'min_ram': serializer.validated_data.get('min_ram', 0),
                     'region': serializer.validated_data.get('region')
                 },
                 id=image.id,
             )
         return Response(data, status=status.HTTP_201_CREATED, headers=headers)
예제 #19
0
 def update(self, request, *args, **kwargs):
     UpdateSerializer = self.get_serializer_class()
     serializer = UpdateSerializer(data=request.data,
                                   context=self.get_serializer_context())
     serializer.is_valid(raise_exception=True)
     plan = self.get_object()
     default_plans = self.get_queryset().filter(
         is_default=True, reseller_resources=plan.reseller_resources)
     if not plan.is_default and serializer.validated_data.get('is_default'):
         for df_plan in default_plans:
             df_plan.is_default = False
             df_plan.save()
     elif not default_plans.exclude(
             id=plan.id) and not serializer.validated_data.get(
                 'is_default'):
         other_default = serializer.validated_data.get('other_default')
         if not other_default:
             raise APIBadRequest(_('There must be a default billing plan'))
         else:
             other_default.is_default = True
             other_default.save()
     plan.is_default = serializer.validated_data.get('is_default')
     plan.name = serializer.validated_data['name']
     plan.currency = serializer.validated_data['currency']
     plan.save()
     return Response({'plan': self.serializer_class(plan).data})
예제 #20
0
    def save_auto_create_network_options(self, request):
        if 'region' not in request.data:
            raise APIBadRequest(_('Must be called with region parameter'))

        network_admin_api = Networks(
            api_session=self.identity_admin_api.session)
        subnetpool_admin_api = SubnetPools(
            api_session=self.identity_admin_api.session)
        options = network_admin_api.config_auto_create_network_options(
            region=request.data['region'])
        options['config'] = dict()

        if 'network_id' in request.data:
            network = network_admin_api.set_network_as_default(
                request.data['region'], request.data['network_id'])
            if network:
                options['config']['network'] = network

        if 'ipv4_subnetpool' in request.data:
            ipv4_subnetpool = subnetpool_admin_api.set_subnetpool_as_default(
                request.data['region'],
                request.data['ipv4_subnetpool'],
                ip_version=4)
            if ipv4_subnetpool:
                options['config']['ipv4_subnetpool'] = ipv4_subnetpool

        if 'ipv6_subnetpool' in request.data:
            ipv6_subnetpool = subnetpool_admin_api.set_subnetpool_as_default(
                request.data['region'],
                request.data['ipv6_subnetpool'],
                ip_version=6)
            if ipv6_subnetpool:
                options['config']['ipv6_subnetpool'] = ipv6_subnetpool

        return Response({'options': options})
예제 #21
0
    def create(self, request):
        """Create a dns zone"""

        if not validate_cloud_objects_limit():
            raise APIBadRequest(_('Licence cloud objects limit reached. Please check your license.'))

        serializer = DnsCreateSerializer(data=request.data)
        serializer.is_valid(raise_exception=True)

        designate = designate_client(self.identity_admin_api.session,
                                     region_name=serializer.validated_data.pop('region_name', None),
                                     sudo_project_id=serializer.validated_data.pop('sudo_project_id', None),
                                     all_projects=serializer.validated_data.pop('all_projects', None))
        serializer.validated_data.pop('client', None)
        try:
            zone = designate.zones.create(**serializer.validated_data)
        except designate_exceptions.Conflict as e:
            LOG.error('Unable to create zone, reason {0}'.format(e))
            raise ValidationError(
                {'detail': _('Unable to create zone. A zone with the same domain name already exists')}
            )
        except designate_exceptions.Base as e:
            LOG.error('Unable to create zone, reason {0}'.format(e))
            raise ValidationError({'detail': _('Unable to create zone. Please see logs for more info')})
        else:
            return Response(zone, status=HTTP_201_CREATED)
예제 #22
0
 def remove_ip(self, request, pk):
     del pk  # unused
     port = self.get_port()
     serializer = self.get_serializer(data=request.data)
     serializer.is_valid(raise_exception=True)
     try:
         port = port.remove_ip(kwargs=serializer.validated_data)
         user = self.request.user
         instance_detach_ips.send(
             sender=__name__,
             user=user,
             user_id=user.id,
             port_id=port['port']['id'],
             instance_id=port['port']['device_id'],
             ips=', '.join([
                 f_ip['ip_address']
                 for f_ip in serializer.validated_data['fixed_ips']
             ]),
             network_id=port['port']['network_id'],
             username=user.username,
             request=self.request)
         serializer.validated_data.update(port['port'])
     except BadRequest as e:
         raise APIBadRequest(e)
     except Exception as e:
         LOG.error(e)
         handle(self.request, message=_('Unable to remove ip'))
     return Response({'detail': _('IP removed')})
예제 #23
0
 def get_certificate(self, request, pk):
     cluster = self.get_object()
     if cluster.project.project_id != self.get_project_id():
         raise APIBadRequest(
             _('If you want to get certificate for cluster, impersonate the owner.'
               ))
     return super().get_certificate(request=request, pk=pk)
예제 #24
0
    def upgrade(self, request, pk):
        del pk  # unused
        service = self.get_object()

        if not service.next_invoice_date:
            raise APIBadRequest(
                detail=_('Unpaid service cannot be upgraded/downgraded'))

        ser = ServiceUpgOptionsSerializer(data=request.data,
                                          context={'service': service})
        ser.is_valid(raise_exception=True)
        configurable_options = ser.validated_data.get('configurable_options')
        confirmation = ser.validated_data.get('confirm', False)

        upgrade_summary = ServiceManager.estimate_new_service_cycle_cost(
            service=service,
            product=ser.validated_data['product'],
            cycle=ser.validated_data['cycle'],
            start_date=utcnow(),
            configurable_options=configurable_options)
        if confirmation:
            order_metadata = OrderMetadata.from_request(request).to_json()
            invoice = ServiceManager.create_service_upgrade_order(
                user=request.user,
                client=request.user.clients.first(),
                service=service,
                product=ser.validated_data['product'],
                cycle=ser.validated_data['cycle'],
                start_date=utcnow(),
                configurable_options=configurable_options,
                metadata=order_metadata)
            return Response({'invoice': invoice.pk})
        else:
            return Response(upgrade_summary)
예제 #25
0
 def mark_billing_histories_as_invoiced(self, request):
     """Method called from external module (fleio-whmcs) to mark billing histories as invoiced"""
     client_external_billing_id = request.data.get('client_external_billing_id', None)
     if not client_external_billing_id:
         raise APIBadRequest(_('Client external billing id is required to fulfill this request.'))
     try:
         client = Client.objects.get(external_billing_id=client_external_billing_id)
     except Client.DoesNotExist:
         raise APIBadRequest(_('Could not find client related to given external billing id.'))
     for service in client.services.all():
         billing_module = module_factory.get_module_instance(service=service)
         # this will mark unsettled service dynamic usage histories to invoiced
         billing_module.get_unsettled_usage(service=service, end_datetime=utcnow())
     return Response({
         'detail': _('Successfully marked client {} billing histories states as invoiced.').format(client.id)
     })
예제 #26
0
 def update(self, name=None, description=None):
     if APIVersion(plugin_settings.VOLUME_API_VERSION) < APIVersion('3.9'):
         raise APIBadRequest(
             _('Volume update is not found in this volume api version'))
     return self.cinder_api.backups.update(backup=self.volume_backup,
                                           description=description,
                                           name=name)
예제 #27
0
    def get_active_tos(self, request, *args, **kwargs):
        del request, args, kwargs  # unused
        latest_version_tos = TermsOfService.objects.filter(
            draft=False).order_by('-version').first()
        if not latest_version_tos:
            return Response({'tos_data': None})
        try:
            tos_agreement = TermsOfServiceAgreement.objects.get_or_create(
                terms_of_service=latest_version_tos,
                user=self.request.user,
            )[0]  # type: TermsOfServiceAgreement
        except Exception as e:
            raise APIBadRequest(str(e))

        remind_later_button_available = True
        if tos_settings.forbid_access_after:
            forbid_after_datetime = datetime.datetime.strptime(
                tos_settings.forbid_access_after, '%Y-%m-%d %H:%M:%S')
            forbid_after_datetime = forbid_after_datetime.replace(
                tzinfo=pytz.utc)
            if utcnow() > forbid_after_datetime:
                remind_later_button_available = False
        return Response({
            'tos_data': {
                'agreement_id': tos_agreement.id,
                'title': tos_agreement.terms_of_service.title,
                'version': tos_agreement.terms_of_service.version,
                'content': tos_agreement.terms_of_service.content,
                'agreed': tos_agreement.agreed,
                'remind_later_button_available': remind_later_button_available,
            }
        })
예제 #28
0
 def get_subnet_pools(self, request):
     region = request.query_params.get('region', None)
     if not region:
         raise APIBadRequest(_('Region required in request'))
     pools = SubnetPool.objects.filter(region=region)
     return Response(
         {'pools': SubnetPoolSerializer(instance=pools, many=True).data})
예제 #29
0
 def automatic_add_ips(self, request, pk):
     del pk  # unused
     port = self.get_port()
     serializer = self.get_serializer(data=request.data)
     serializer.is_valid(raise_exception=True)
     try:
         openstack_port = port.add_ips(
             kwargs=serializer.validated_data)['port']
         user = self.request.user
         instance_attach_ips.send(
             sender=__name__,
             user=user,
             user_id=user.id,
             port_id=openstack_port['id'],
             instance_id=openstack_port['device_id'],
             ips=', '.join([
                 f_ip['ip_address'] for f_ip in openstack_port['fixed_ips']
                 if f_ip not in port.port.fixed_ips
             ]),
             network_id=openstack_port['network_id'],
             username=user.username,
             request=self.request)
         serializer.validated_data.update(openstack_port)
     except BadRequest as e:
         raise APIBadRequest(e)
     except Exception as e:
         LOG.error(e)
         handle(self.request, message=_('Unable to add IP(s)'))
     return Response({'detail': _('IP(s) added')})
예제 #30
0
    def get_member_status(self, request, pk):
        del pk  # unused
        image = self.get_object()
        try:
            project = request.user.clients.first().first_project
        except (Exception, AttributeError) as e:
            del e  # unused
            raise APIBadRequest(
                _('Could not find related client OpenStack project.'))

        member = ImageMembers.objects.filter(image=image,
                                             member=project).first()
        if not member:
            raise APIBadRequest(
                _('Could not find details about image member.'))
        return Response({'status': member.status})