コード例 #1
0
ファイル: tests.py プロジェクト: noorul/horizon
    def test_create_volume_from_image_invalid_size(self):
        usage_limit = {'maxTotalVolumeGigabytes': 100, 'maxTotalVolumes': 6}
        image = self.images.first()
        formData = {
            'name': u'A Volume I Am Making',
            'description': u'This is a volume I am making for a test.',
            'method': u'CreateForm',
            'size': 1,
            'image_source': image.id
        }

        cinder.volume_type_list(IsA(http.HttpRequest)).\
                                AndReturn(self.volume_types.list())
        cinder.tenant_absolute_limits(IsA(http.HttpRequest)).\
                                AndReturn(usage_limit)
        cinder.volume_list(IsA(http.HttpRequest)).\
                                AndReturn(self.volumes.list())
        api.glance.image_get(IsA(http.HttpRequest),
                             str(image.id)).AndReturn(image)
        cinder.tenant_absolute_limits(IsA(http.HttpRequest)).\
                                AndReturn(usage_limit)
        cinder.volume_list(IsA(http.HttpRequest)).\
                                AndReturn(self.volumes.list())

        self.mox.ReplayAll()

        url = reverse('horizon:project:volumes:create')
        res = self.client.post("?".join([url, "image_id=" + str(image.id)]),
                               formData,
                               follow=True)
        self.assertEqual(res.redirect_chain, [])
        self.assertFormError(
            res, 'form', None, "The volume size cannot be less than the "
            "image size (20.0 GB)")
コード例 #2
0
ファイル: tests.py プロジェクト: 394954369/horizon
    def test_delete_volume(self):
        volumes = self.cinder_volumes.list()
        volume = self.cinder_volumes.first()
        formData = {'action':
                    'volumes__delete__%s' % volume.id}

        cinder.volume_backup_supported(IsA(http.HttpRequest)). \
            MultipleTimes().AndReturn(True)
        cinder.volume_list(IsA(http.HttpRequest), search_opts=None).\
            AndReturn(volumes)
        cinder.volume_delete(IsA(http.HttpRequest), volume.id)
        api.nova.server_list(IsA(http.HttpRequest), search_opts=None).\
            AndReturn([self.servers.list(), False])
        cinder.volume_list(IsA(http.HttpRequest), search_opts=None).\
            AndReturn(volumes)
        api.nova.server_list(IsA(http.HttpRequest), search_opts=None).\
            AndReturn([self.servers.list(), False])
        cinder.tenant_absolute_limits(IsA(http.HttpRequest)).MultipleTimes().\
            AndReturn(self.cinder_limits['absolute'])

        self.mox.ReplayAll()

        url = VOLUME_INDEX_URL
        res = self.client.post(url, formData, follow=True)
        self.assertIn("Scheduled deletion of Volume: Volume name",
                      [m.message for m in res.context['messages']])
コード例 #3
0
ファイル: tests.py プロジェクト: 394954369/horizon
    def test_delete_volume_error_existing_snapshot(self):
        volume = self.cinder_volumes.first()
        volumes = self.cinder_volumes.list()
        formData = {'action':
                    'volumes__delete__%s' % volume.id}
        exc = self.exceptions.cinder.__class__(400,
                                               "error: dependent snapshots")

        cinder.volume_backup_supported(IsA(http.HttpRequest)). \
            MultipleTimes().AndReturn(True)
        cinder.volume_list(IsA(http.HttpRequest), search_opts=None).\
                           AndReturn(volumes)
        cinder.volume_delete(IsA(http.HttpRequest), volume.id).\
                             AndRaise(exc)
        api.nova.server_list(IsA(http.HttpRequest), search_opts=None).\
                             AndReturn([self.servers.list(), False])
        cinder.volume_list(IsA(http.HttpRequest), search_opts=None).\
                           AndReturn(volumes)
        api.nova.server_list(IsA(http.HttpRequest), search_opts=None).\
                             AndReturn([self.servers.list(), False])
        cinder.tenant_absolute_limits(IsA(http.HttpRequest)).MultipleTimes().\
                                   AndReturn(self.cinder_limits['absolute'])
        self.mox.ReplayAll()

        url = VOLUME_INDEX_URL
        res = self.client.post(url, formData, follow=True)
        self.assertEqual(list(res.context['messages'])[0].message,
                         u'Unable to delete volume "%s". '
                         u'One or more snapshots depend on it.' %
                         volume.name)
コード例 #4
0
ファイル: tests.py プロジェクト: cliping/horizon
    def test_create_volume_from_image_invalid_size(self):
        usage_limit = {'maxTotalVolumeGigabytes': 100,
                 'maxTotalVolumes': 6}
        image = self.images.first()
        formData = {'name': u'A Volume I Am Making',
                    'description': u'This is a volume I am making for a test.',
                    'method': u'CreateForm',
                    'size': 1, 'image_source': image.id}

        cinder.volume_type_list(IsA(http.HttpRequest)).\
                                AndReturn(self.volume_types.list())
        cinder.tenant_absolute_limits(IsA(http.HttpRequest)).\
                                AndReturn(usage_limit)
        cinder.volume_list(IsA(http.HttpRequest)).\
                                AndReturn(self.volumes.list())
        api.glance.image_get(IsA(http.HttpRequest),
                             str(image.id)).AndReturn(image)
        cinder.tenant_absolute_limits(IsA(http.HttpRequest)).\
                                AndReturn(usage_limit)
        cinder.volume_list(IsA(http.HttpRequest)).\
                                AndReturn(self.volumes.list())

        self.mox.ReplayAll()

        url = reverse('horizon:project:volumes:create')
        res = self.client.post("?".join([url,
                                         "image_id=" + str(image.id)]),
                               formData, follow=True)
        self.assertEqual(res.redirect_chain, [])
        self.assertFormError(res, 'form', None,
                             "The volume size cannot be less than the "
                             "image size (20.0 GB)")
コード例 #5
0
ファイル: tests.py プロジェクト: 394954369/horizon
    def test_create_button_disabled_when_quota_exceeded(self):
        limits = self.cinder_limits['absolute']
        limits['totalVolumesUsed'] = limits['maxTotalVolumes']
        volumes = self.cinder_volumes.list()

        api.cinder.volume_backup_supported(IsA(http.HttpRequest)). \
            MultipleTimes().AndReturn(True)
        cinder.volume_list(IsA(http.HttpRequest), search_opts=None)\
              .AndReturn(volumes)
        api.nova.server_list(IsA(http.HttpRequest), search_opts=None)\
              .AndReturn([self.servers.list(), False])
        cinder.tenant_absolute_limits(IsA(http.HttpRequest))\
              .MultipleTimes().AndReturn(limits)
        self.mox.ReplayAll()

        res = self.client.get(VOLUME_INDEX_URL)
        self.assertTemplateUsed(res, 'project/volumes/index.html')

        volumes = res.context['volumes_table'].data
        self.assertItemsEqual(volumes, self.cinder_volumes.list())

        create_link = tables.CreateVolume()
        url = create_link.get_link_url()
        classes = list(create_link.get_default_classes())\
                    + list(create_link.classes)
        link_name = "%s (%s)" % (unicode(create_link.verbose_name),
                                 "Quota exceeded")
        expected_string = "<a href='%s' title='%s'  class='%s disabled' "\
            "id='volumes__action_create'  data-update-url=" \
            "'/project/volumes/?action=create&amp;table=volumes'> "\
            "<span class='glyphicon glyphicon-plus'></span>%s</a>" \
            % (url, link_name, " ".join(classes), link_name)
        self.assertContains(res, expected_string, html=True,
                            msg_prefix="The create button is not disabled")
コード例 #6
0
ファイル: tests.py プロジェクト: 394954369/horizon
    def _test_encryption(self, encryption):
        volumes = self.volumes.list()
        for volume in volumes:
            volume.encrypted = encryption
        limits = self.cinder_limits['absolute']

        cinder.volume_backup_supported(IsA(http.HttpRequest))\
            .MultipleTimes('backup_supported').AndReturn(False)
        cinder.volume_list(IsA(http.HttpRequest), search_opts=None)\
            .AndReturn(self.volumes.list())
        api.nova.server_list(IsA(http.HttpRequest), search_opts=None)\
            .AndReturn([self.servers.list(), False])
        cinder.tenant_absolute_limits(IsA(http.HttpRequest))\
            .MultipleTimes('limits').AndReturn(limits)

        self.mox.ReplayAll()

        res = self.client.get(VOLUME_INDEX_URL)
        rows = res.context['volumes_table'].get_rows()

        if encryption:
            column_value = 'Yes'
        else:
            column_value = 'No'

        for row in rows:
            self.assertEqual(row.cells['encryption'].data, column_value)
コード例 #7
0
ファイル: tests.py プロジェクト: noorul/horizon
    def test_create_volume_encrypted(self):
        volume = self.volumes.first()
        volume_type = self.volume_types.first()
        usage_limit = {
            'maxTotalVolumeGigabytes': 250,
            'gigabytesUsed': 20,
            'maxTotalVolumes': 6
        }
        formData = {
            'name': u'An Encrypted Volume',
            'description': u'This volume has metadata for encryption.',
            'method': u'CreateForm',
            'type': volume_type.name,
            'size': 50,
            'snapshot_source': '',
            'encryption': u'LUKS'
        }

        # check normal operation with can_encrypt_volumes = true
        PREV = settings.OPENSTACK_HYPERVISOR_FEATURES['can_encrypt_volumes']
        settings.OPENSTACK_HYPERVISOR_FEATURES['can_encrypt_volumes'] = True

        cinder.volume_type_list(IsA(http.HttpRequest)).\
                                AndReturn(self.volume_types.list())
        cinder.tenant_absolute_limits(IsA(http.HttpRequest)).\
                                AndReturn(usage_limit)
        cinder.volume_list(IsA(http.HttpRequest)).\
                                AndReturn(self.volumes.list())
        cinder.volume_snapshot_list(IsA(http.HttpRequest)).\
                                    AndReturn(self.volume_snapshots.list())
        api.glance.image_list_detailed(IsA(http.HttpRequest),
                                       filters={'is_public': True,
                                                'status': 'active'}) \
                  .AndReturn([self.images.list(), False])
        api.glance.image_list_detailed(IsA(http.HttpRequest),
                            filters={'property-owner_id': self.tenant.id,
                                     'status': 'active'}) \
                  .AndReturn([[], False])
        cinder.volume_create(IsA(http.HttpRequest),
                             formData['size'],
                             formData['name'],
                             formData['description'],
                             formData['type'],
                             metadata={
                                 'encryption': formData['encryption']
                             },
                             snapshot_id=None,
                             image_id=None).AndReturn(volume)

        self.mox.ReplayAll()

        url = reverse('horizon:project:volumes:create')
        res = self.client.post(url, formData)

        redirect_url = reverse('horizon:project:volumes:index')
        self.assertRedirectsNoFollow(res, redirect_url)

        settings.OPENSTACK_HYPERVISOR_FEATURES['can_encrypt_volumes'] = PREV
コード例 #8
0
ファイル: tests.py プロジェクト: nxFelis/horizon
    def test_create_volume_cannot_encrypt(self):
        volume = self.volumes.first()
        volume_type = self.volume_types.first()
        usage = {'gigabytes': {'available': 250}, 'volumes': {'available': 6}}
        formData = {
            'name': u'An Encrypted Volume',
            'description': u'This volume has metadata for encryption.',
            'method': u'CreateForm',
            'type': volume_type.name,
            'size': 50,
            'snapshot_source': '',
            'encryption': u'LUKS'
        }

        # check that widget is hidden if can_encrypt_volumes = false
        PREV = settings.OPENSTACK_HYPERVISOR_FEATURES['can_encrypt_volumes']
        settings.OPENSTACK_HYPERVISOR_FEATURES['can_encrypt_volumes'] = False

        volume = self.volumes.first()
        volume_type = self.volume_types.first()
        usage_limit = {
            'maxTotalVolumeGigabytes': 250,
            'gigabytesUsed': 20,
            'maxTotalVolumes': 6
        }

        cinder.volume_type_list(IsA(http.HttpRequest)).\
                                AndReturn(self.volume_types.list())
        cinder.tenant_absolute_limits(IsA(http.HttpRequest)).\
                                AndReturn(usage_limit)
        cinder.volume_list(IsA(http.HttpRequest)).\
                                AndReturn(self.volumes.list())
        cinder.volume_snapshot_list(IsA(http.HttpRequest)).\
                                    AndReturn(self.volume_snapshots.list())
        api.glance.image_list_detailed(IsA(http.HttpRequest),
                                       filters={'is_public': True,
                                                'status': 'active'}) \
                  .AndReturn([self.images.list(), False])
        api.glance.image_list_detailed(IsA(http.HttpRequest),
                            filters={'property-owner_id': self.tenant.id,
                                     'status': 'active'}) \
                  .AndReturn([[], False])

        self.mox.ReplayAll()

        url = reverse('horizon:project:volumes:create')
        res = self.client.get(url)

        # Assert the encryption field is hidden.
        form = res.context['form']
        self.assertTrue(
            isinstance(form.fields['encryption'].widget, widgets.HiddenInput))

        settings.OPENSTACK_HYPERVISOR_FEATURES['can_encrypt_volumes'] = PREV
コード例 #9
0
ファイル: tests.py プロジェクト: cliping/horizon
    def test_create_volume_encrypted(self):
        volume = self.volumes.first()
        volume_type = self.volume_types.first()
        usage_limit = {'maxTotalVolumeGigabytes': 250,
                 'gigabytesUsed': 20,
                 'maxTotalVolumes': 6}
        formData = {'name': u'An Encrypted Volume',
                    'description': u'This volume has metadata for encryption.',
                    'method': u'CreateForm',
                    'type': volume_type.name,
                    'size': 50,
                    'snapshot_source': '',
                    'encryption': u'LUKS'}

        # check normal operation with can_encrypt_volumes = true
        PREV = settings.OPENSTACK_HYPERVISOR_FEATURES['can_encrypt_volumes']
        settings.OPENSTACK_HYPERVISOR_FEATURES['can_encrypt_volumes'] = True

        cinder.volume_type_list(IsA(http.HttpRequest)).\
                                AndReturn(self.volume_types.list())
        cinder.tenant_absolute_limits(IsA(http.HttpRequest)).\
                                AndReturn(usage_limit)
        cinder.volume_list(IsA(http.HttpRequest)).\
                                AndReturn(self.volumes.list())
        cinder.volume_snapshot_list(IsA(http.HttpRequest)).\
                                    AndReturn(self.volume_snapshots.list())
        api.glance.image_list_detailed(IsA(http.HttpRequest),
                                       filters={'is_public': True,
                                                'status': 'active'}) \
                  .AndReturn([self.images.list(), False])
        api.glance.image_list_detailed(IsA(http.HttpRequest),
                            filters={'property-owner_id': self.tenant.id,
                                     'status': 'active'}) \
                  .AndReturn([[], False])
        cinder.volume_create(IsA(http.HttpRequest),
                             formData['size'],
                             formData['name'],
                             formData['description'],
                             formData['type'],
                             metadata={'encryption': formData['encryption']},
                             snapshot_id=None,
                             image_id=None).AndReturn(volume)

        self.mox.ReplayAll()

        url = reverse('horizon:project:volumes:create')
        res = self.client.post(url, formData)

        redirect_url = reverse('horizon:project:volumes:index')
        self.assertRedirectsNoFollow(res, redirect_url)

        settings.OPENSTACK_HYPERVISOR_FEATURES['can_encrypt_volumes'] = PREV
コード例 #10
0
ファイル: tests.py プロジェクト: noorul/horizon
    def test_create_volume_from_image_dropdown(self):
        volume = self.volumes.first()
        usage_limit = {'maxTotalVolumeGigabytes': 200, 'maxTotalVolumes': 6}
        image = self.images.first()
        formData = {
            'name': u'A Volume I Am Making',
            'description': u'This is a volume I am making for a test.',
            'method': u'CreateForm',
            'size': 30,
            'type': '',
            'volume_source_type': 'image_source',
            'snapshot_source': self.volume_snapshots.first().id,
            'image_source': image.id
        }

        cinder.volume_type_list(IsA(http.HttpRequest)).\
                                AndReturn(self.volume_types.list())
        cinder.volume_snapshot_list(IsA(http.HttpRequest)).\
                                 AndReturn(self.volume_snapshots.list())
        api.glance.image_list_detailed(IsA(http.HttpRequest),
                                       filters={'is_public': True,
                                                'status': 'active'}) \
                  .AndReturn([self.images.list(), False])
        api.glance.image_list_detailed(IsA(http.HttpRequest),
                            filters={'property-owner_id': self.tenant.id,
                                     'status': 'active'}) \
                  .AndReturn([[], False])
        cinder.tenant_absolute_limits(IsA(http.HttpRequest)) \
                  .AndReturn(usage_limit)
        cinder.volume_list(IsA(http.HttpRequest)) \
                  .AndReturn(self.volumes.list())
        api.glance.image_get(IsA(http.HttpRequest),
                             str(image.id)).AndReturn(image)
        cinder.volume_create(IsA(http.HttpRequest),
                             formData['size'],
                             formData['name'],
                             formData['description'],
                             '',
                             metadata={},
                             snapshot_id=None,
                             image_id=image.id).\
                             AndReturn(volume)

        self.mox.ReplayAll()

        # get image from dropdown list
        url = reverse('horizon:project:volumes:create')
        res = self.client.post(url, formData)

        redirect_url = reverse('horizon:project:volumes:index')
        self.assertRedirectsNoFollow(res, redirect_url)
コード例 #11
0
ファイル: tests.py プロジェクト: cliping/horizon
    def test_create_volume_from_image_dropdown(self):
        volume = self.volumes.first()
        usage_limit = {'maxTotalVolumeGigabytes': 200,
                 'maxTotalVolumes': 6}
        image = self.images.first()
        formData = {'name': u'A Volume I Am Making',
                    'description': u'This is a volume I am making for a test.',
                    'method': u'CreateForm',
                    'size': 30,
                    'type': '',
                    'volume_source_type': 'image_source',
                    'snapshot_source': self.volume_snapshots.first().id,
                    'image_source': image.id}

        cinder.volume_type_list(IsA(http.HttpRequest)).\
                                AndReturn(self.volume_types.list())
        cinder.volume_snapshot_list(IsA(http.HttpRequest)).\
                                 AndReturn(self.volume_snapshots.list())
        api.glance.image_list_detailed(IsA(http.HttpRequest),
                                       filters={'is_public': True,
                                                'status': 'active'}) \
                  .AndReturn([self.images.list(), False])
        api.glance.image_list_detailed(IsA(http.HttpRequest),
                            filters={'property-owner_id': self.tenant.id,
                                     'status': 'active'}) \
                  .AndReturn([[], False])
        cinder.tenant_absolute_limits(IsA(http.HttpRequest)) \
                  .AndReturn(usage_limit)
        cinder.volume_list(IsA(http.HttpRequest)) \
                  .AndReturn(self.volumes.list())
        api.glance.image_get(IsA(http.HttpRequest),
                             str(image.id)).AndReturn(image)
        cinder.volume_create(IsA(http.HttpRequest),
                             formData['size'],
                             formData['name'],
                             formData['description'],
                             '',
                             metadata={},
                             snapshot_id=None,
                             image_id=image.id).\
                             AndReturn(volume)

        self.mox.ReplayAll()

        # get image from dropdown list
        url = reverse('horizon:project:volumes:create')
        res = self.client.post(url, formData)

        redirect_url = reverse('horizon:project:volumes:index')
        self.assertRedirectsNoFollow(res, redirect_url)
コード例 #12
0
    def test_create_volume_cannot_encrypt(self):
        volume = self.volumes.first()
        volume_type = self.volume_types.first()
        usage = {'gigabytes': {'available': 250}, 'volumes': {'available': 6}}
        formData = {'name': u'An Encrypted Volume',
                    'description': u'This volume has metadata for encryption.',
                    'method': u'CreateForm',
                    'type': volume_type.name,
                    'size': 50,
                    'snapshot_source': '',
                    'encryption': u'LUKS'}

        # check that widget is hidden if can_encrypt_volumes = false
        PREV = settings.OPENSTACK_HYPERVISOR_FEATURES['can_encrypt_volumes']
        settings.OPENSTACK_HYPERVISOR_FEATURES['can_encrypt_volumes'] = False

        volume = self.volumes.first()
        volume_type = self.volume_types.first()
        usage_limit = {'maxTotalVolumeGigabytes': 250,
                 'gigabytesUsed': 20,
                 'maxTotalVolumes': 6}

        cinder.volume_type_list(IsA(http.HttpRequest)).\
                                AndReturn(self.volume_types.list())
        cinder.tenant_absolute_limits(IsA(http.HttpRequest)).\
                                AndReturn(usage_limit)
        cinder.volume_list(IsA(http.HttpRequest)).\
                                AndReturn(self.volumes.list())
        cinder.volume_snapshot_list(IsA(http.HttpRequest)).\
                                    AndReturn(self.volume_snapshots.list())
        api.glance.image_list_detailed(IsA(http.HttpRequest),
                                       filters={'is_public': True,
                                                'status': 'active'}) \
                  .AndReturn([self.images.list(), False])
        api.glance.image_list_detailed(IsA(http.HttpRequest),
                            filters={'property-owner_id': self.tenant.id,
                                     'status': 'active'}) \
                  .AndReturn([[], False])

        self.mox.ReplayAll()

        url = reverse('horizon:project:volumes:create')
        res = self.client.get(url)

        # Assert the encryption field is hidden.
        form = res.context['form']
        self.assertTrue(isinstance(form.fields['encryption'].widget,
                                   widgets.HiddenInput))

        settings.OPENSTACK_HYPERVISOR_FEATURES['can_encrypt_volumes'] = PREV
コード例 #13
0
ファイル: quotas.py プロジェクト: amotoki/horizon
def tenant_limit_usages(request):
    # TODO(licostan): This method shall be removed from Quota module.
    # ProjectUsage/BaseUsage maybe used instead on volume/image dashboards.
    limits = {}

    try:
        if base.is_service_enabled(request, 'compute'):
            limits.update(nova.tenant_absolute_limits(request, reserved=True))
    except Exception:
        msg = _("Unable to retrieve compute limit information.")
        exceptions.handle(request, msg)

    if cinder.is_volume_service_enabled(request):
        try:
            limits.update(cinder.tenant_absolute_limits(request))
        except cinder.cinder_exception.ClientException:
            msg = _("Unable to retrieve volume limit information.")
            exceptions.handle(request, msg)

    # TODO(amotoki): Support neutron quota details extensions
    # which returns limit/usage/reserved per resource.
    # Note that the data format is different from nova/cinder limit API.
    # https://developer.openstack.org/
    #   api-ref/network/v2/#quotas-details-extension-quota-details

    return limits
コード例 #14
0
def tenant_limit_usages(request):
    # TODO(licostan): This method shall be removed from Quota module.
    # ProjectUsage/BaseUsage maybe used instead on volume/image dashboards.
    limits = {}

    try:
        if base.is_service_enabled(request, 'compute'):
            limits.update(nova.tenant_absolute_limits(request, reserved=True))
    except Exception:
        msg = _("Unable to retrieve compute limit information.")
        exceptions.handle(request, msg)

    if cinder.is_volume_service_enabled(request):
        try:
            limits.update(cinder.tenant_absolute_limits(request))
        except cinder.cinder_exception.ClientException:
            msg = _("Unable to retrieve volume limit information.")
            exceptions.handle(request, msg)

    # TODO(amotoki): Support neutron quota details extensions
    # which returns limit/usage/reserved per resource.
    # Note that the data format is different from nova/cinder limit API.
    # https://developer.openstack.org/
    #   api-ref/network/v2/#quotas-details-extension-quota-details

    return limits
コード例 #15
0
ファイル: quotas.py プロジェクト: jonyale/horizon
def tenant_limit_usages(request):
    # TODO(licostan): This method shall be removed from Quota module.
    # ProjectUsage/BaseUsage maybe used instead on volume/image dashboards.
    limits = {}

    try:
        limits.update(nova.tenant_absolute_limits(request))
    except Exception:
        msg = _("Unable to retrieve compute limit information.")
        exceptions.handle(request, msg)

    if base.is_service_enabled(request, 'volume'):
        try:
            limits.update(cinder.tenant_absolute_limits(request))
            volumes = cinder.volume_list(request)
            snapshots = cinder.volume_snapshot_list(request)
            total_size = sum([getattr(volume, 'size', 0) for volume
                              in volumes])
            limits['gigabytesUsed'] = total_size
            limits['volumesUsed'] = len(volumes)
            limits['snapshotsUsed'] = len(snapshots)
        except Exception:
            msg = _("Unable to retrieve volume limit information.")
            exceptions.handle(request, msg)

    return limits
コード例 #16
0
def tenant_limit_usages(request):
    # TODO(licostan): This method shall be removed from Quota module.
    # ProjectUsage/BaseUsage maybe used instead on volume/image dashboards.
    limits = {}

    try:
        if base.is_service_enabled(request, 'compute'):
            limits.update(nova.tenant_absolute_limits(request, reserved=True))
    except Exception:
        msg = _("Unable to retrieve compute limit information.")
        exceptions.handle(request, msg)

    if cinder.is_volume_service_enabled(request):
        try:
            limits.update(cinder.tenant_absolute_limits(request))
            volumes = cinder.volume_list(request)
            snapshots = cinder.volume_snapshot_list(request)
            # gigabytesUsed should be a total of volumes and snapshots
            #mj - display the correct amount of volume usage in the volume creation panel
            #vol_size = sum([getattr(volume, 'size', 0) for volume
            #                in volumes])
            #snap_size = sum([getattr(snap, 'size', 0) for snap
            #                 in snapshots])
            #limits['gigabytesUsed'] = vol_size + snap_size

            limits['gigabytesUsed'] = limits.get('totalGigabytesUsed', 0)
            limits['volumesUsed'] = limits.get('totalVolumesUsed', 0)
            limits['snapshotsUsed'] = limits.get('totalSnapshotsUsed', 0)
            #limits['volumesUsed'] = len(volumes)
            #limits['snapshotsUsed'] = len(snapshots)
        except cinder.cinder_exception.ClientException:
            msg = _("Unable to retrieve volume limit information.")
            exceptions.handle(request, msg)

    return limits
コード例 #17
0
ファイル: tests.py プロジェクト: noorul/horizon
    def test_create_volume_number_over_alloted_quota(self):
        usage_limit = {
            'maxTotalVolumeGigabytes': 100,
            'maxTotalVolumes': len(self.volumes.list())
        }
        formData = {
            'name': u'Too Many...',
            'description': u'We have no volumes left!',
            'method': u'CreateForm',
            'size': 10
        }

        cinder.volume_type_list(IsA(http.HttpRequest)).\
                                AndReturn(self.volume_types.list())
        cinder.tenant_absolute_limits(IsA(http.HttpRequest)).\
                                AndReturn(usage_limit)
        cinder.volume_list(IsA(http.HttpRequest)).\
                                AndReturn(self.volumes.list())
        cinder.volume_snapshot_list(IsA(http.HttpRequest)).\
                                    AndReturn(self.volume_snapshots.list())
        api.glance.image_list_detailed(IsA(http.HttpRequest),
                                       filters={'is_public': True,
                                                'status': 'active'}) \
                  .AndReturn([self.images.list(), False])
        api.glance.image_list_detailed(IsA(http.HttpRequest),
                            filters={'property-owner_id': self.tenant.id,
                                     'status': 'active'}) \
                  .AndReturn([[], False])
        cinder.tenant_absolute_limits(IsA(http.HttpRequest)).\
                                AndReturn(usage_limit)
        cinder.volume_list(IsA(http.HttpRequest)).\
                                    AndReturn(self.volumes.list())

        self.mox.ReplayAll()

        url = reverse('horizon:project:volumes:create')
        res = self.client.post(url, formData)

        expected_error = [
            u'You are already using all of your available'
            ' volumes.'
        ]
        self.assertEqual(res.context['form'].errors['__all__'], expected_error)
コード例 #18
0
ファイル: tests.py プロジェクト: cliping/horizon
    def test_create_volume_from_snapshot(self):
        volume = self.volumes.first()
        usage_limit = {'maxTotalVolumeGigabytes': 250,
                 'maxTotalVolumes': 6}
        snapshot = self.volume_snapshots.first()
        formData = {'name': u'A Volume I Am Making',
                    'description': u'This is a volume I am making for a test.',
                    'method': u'CreateForm',
                    'size': 50,
                    'type': '',
                    'snapshot_source': snapshot.id}

        cinder.volume_type_list(IsA(http.HttpRequest)).\
                                AndReturn(self.volume_types.list())
        cinder.tenant_absolute_limits(IsA(http.HttpRequest)).\
                                AndReturn(usage_limit)
        cinder.volume_list(IsA(http.HttpRequest)).\
                                    AndReturn(self.volumes.list())
        cinder.volume_snapshot_get(IsA(http.HttpRequest),
                                   str(snapshot.id)).AndReturn(snapshot)
        cinder.volume_get(IsA(http.HttpRequest), snapshot.volume_id).\
                          AndReturn(self.volumes.first())
        cinder.volume_create(IsA(http.HttpRequest),
                             formData['size'],
                             formData['name'],
                             formData['description'],
                             '',
                             metadata={},
                             snapshot_id=snapshot.id,
                             image_id=None).\
                             AndReturn(volume)
        self.mox.ReplayAll()

        # get snapshot from url
        url = reverse('horizon:project:volumes:create')
        res = self.client.post("?".join([url,
                                         "snapshot_id=" + str(snapshot.id)]),
                               formData)

        redirect_url = reverse('horizon:project:volumes:index')
        self.assertRedirectsNoFollow(res, redirect_url)
コード例 #19
0
ファイル: tests.py プロジェクト: noorul/horizon
    def test_create_volume_from_snapshot(self):
        volume = self.volumes.first()
        usage_limit = {'maxTotalVolumeGigabytes': 250, 'maxTotalVolumes': 6}
        snapshot = self.volume_snapshots.first()
        formData = {
            'name': u'A Volume I Am Making',
            'description': u'This is a volume I am making for a test.',
            'method': u'CreateForm',
            'size': 50,
            'type': '',
            'snapshot_source': snapshot.id
        }

        cinder.volume_type_list(IsA(http.HttpRequest)).\
                                AndReturn(self.volume_types.list())
        cinder.tenant_absolute_limits(IsA(http.HttpRequest)).\
                                AndReturn(usage_limit)
        cinder.volume_list(IsA(http.HttpRequest)).\
                                    AndReturn(self.volumes.list())
        cinder.volume_snapshot_get(IsA(http.HttpRequest),
                                   str(snapshot.id)).AndReturn(snapshot)
        cinder.volume_get(IsA(http.HttpRequest), snapshot.volume_id).\
                          AndReturn(self.volumes.first())
        cinder.volume_create(IsA(http.HttpRequest),
                             formData['size'],
                             formData['name'],
                             formData['description'],
                             '',
                             metadata={},
                             snapshot_id=snapshot.id,
                             image_id=None).\
                             AndReturn(volume)
        self.mox.ReplayAll()

        # get snapshot from url
        url = reverse('horizon:project:volumes:create')
        res = self.client.post(
            "?".join([url, "snapshot_id=" + str(snapshot.id)]), formData)

        redirect_url = reverse('horizon:project:volumes:index')
        self.assertRedirectsNoFollow(res, redirect_url)
コード例 #20
0
ファイル: tests.py プロジェクト: noorul/horizon
    def test_create_volume_gb_used_over_alloted_quota(self):
        usage_limit = {'maxTotalVolumeGigabytes': 100, 'maxTotalVolumes': 6}
        formData = {
            'name': u'This Volume Is Huge!',
            'description': u'This is a volume that is just too big!',
            'method': u'CreateForm',
            'size': 5000
        }

        cinder.volume_type_list(IsA(http.HttpRequest)).\
                                AndReturn(self.volume_types.list())
        cinder.tenant_absolute_limits(IsA(http.HttpRequest)).\
                                AndReturn(usage_limit)
        cinder.volume_list(IsA(http.HttpRequest)).\
                                AndReturn(self.volumes.list())
        cinder.volume_snapshot_list(IsA(http.HttpRequest)).\
                                    AndReturn(self.volume_snapshots.list())
        api.glance.image_list_detailed(IsA(http.HttpRequest),
                                       filters={'is_public': True,
                                                'status': 'active'}) \
                  .AndReturn([self.images.list(), False])
        api.glance.image_list_detailed(IsA(http.HttpRequest),
                            filters={'property-owner_id': self.tenant.id,
                                     'status': 'active'}) \
                  .AndReturn([[], False])
        cinder.tenant_absolute_limits(IsA(http.HttpRequest)).\
                                AndReturn(usage_limit)
        cinder.volume_list(IsA(http.HttpRequest)).\
                                AndReturn(self.volumes.list())

        self.mox.ReplayAll()

        url = reverse('horizon:project:volumes:create')
        res = self.client.post(url, formData)

        expected_error = [
            u'A volume of 5000GB cannot be created as you only'
            ' have 20GB of your quota available.'
        ]
        self.assertEqual(res.context['form'].errors['__all__'], expected_error)
コード例 #21
0
ファイル: tests.py プロジェクト: noorul/horizon
    def test_create_volume_cannot_encrypt(self):
        # check that widget is hidden if can_encrypt_volumes = false
        PREV = settings.OPENSTACK_HYPERVISOR_FEATURES['can_encrypt_volumes']
        settings.OPENSTACK_HYPERVISOR_FEATURES['can_encrypt_volumes'] = False

        usage_limit = {
            'maxTotalVolumeGigabytes': 250,
            'gigabytesUsed': 20,
            'maxTotalVolumes': 6
        }

        cinder.volume_type_list(IsA(http.HttpRequest)).\
                                AndReturn(self.volume_types.list())
        cinder.tenant_absolute_limits(IsA(http.HttpRequest)).\
                                AndReturn(usage_limit)
        cinder.volume_list(IsA(http.HttpRequest)).\
                                AndReturn(self.volumes.list())
        cinder.volume_snapshot_list(IsA(http.HttpRequest)).\
                                    AndReturn(self.volume_snapshots.list())
        api.glance.image_list_detailed(IsA(http.HttpRequest),
                                       filters={'is_public': True,
                                                'status': 'active'}) \
                  .AndReturn([self.images.list(), False])
        api.glance.image_list_detailed(IsA(http.HttpRequest),
                            filters={'property-owner_id': self.tenant.id,
                                     'status': 'active'}) \
                  .AndReturn([[], False])

        self.mox.ReplayAll()

        url = reverse('horizon:project:volumes:create')
        res = self.client.get(url)

        # Assert the encryption field is hidden.
        form = res.context['form']
        self.assertTrue(
            isinstance(form.fields['encryption'].widget, widgets.HiddenInput))

        settings.OPENSTACK_HYPERVISOR_FEATURES['can_encrypt_volumes'] = PREV
コード例 #22
0
    def get_context_data(self, **kwargs):
        context = super(CreateView, self).get_context_data(**kwargs)
        try:
            context['usages'] = cinder.tenant_absolute_limits(self.request)
            volumes = cinder.volume_list(self.request)
            total_size = sum(
                [getattr(volume, 'size', 0) for volume in volumes])
            context['usages']['gigabytesUsed'] = total_size
            context['usages']['volumesUsed'] = len(volumes)

        except:
            exceptions.handle(self.request)
        return context
コード例 #23
0
ファイル: views.py プロジェクト: denismakogon/horizon
    def get_context_data(self, **kwargs):
        context = super(CreateView, self).get_context_data(**kwargs)
        try:
            context['usages'] = cinder.tenant_absolute_limits(self.request)
            volumes = cinder.volume_list(self.request)
            total_size = sum([getattr(volume, 'size', 0) for volume
                              in volumes])
            context['usages']['gigabytesUsed'] = total_size
            context['usages']['volumesUsed'] = len(volumes)

        except:
            exceptions.handle(self.request)
        return context
コード例 #24
0
def _get_tenant_volume_usages(request, usages, disabled_quotas, tenant_id):
    enabled_volume_quotas = CINDER_QUOTA_FIELDS - disabled_quotas
    if not enabled_volume_quotas:
        return

    try:
        limits = cinder.tenant_absolute_limits(request, tenant_id)
    except cinder.cinder_exception.ClientException:
        msg = _("Unable to retrieve volume limit information.")
        exceptions.handle(request, msg)

    for quota_name, limit_keys in CINDER_QUOTA_LIMIT_MAP.items():
        _add_limit_and_usage(usages, quota_name, limits[limit_keys['limit']],
                             limits[limit_keys['usage']], disabled_quotas)
コード例 #25
0
ファイル: tests.py プロジェクト: cliping/horizon
    def test_create_volume_number_over_alloted_quota(self):
        usage_limit = {'maxTotalVolumeGigabytes': 100,
                 'maxTotalVolumes': len(self.volumes.list())}
        formData = {'name': u'Too Many...',
                    'description': u'We have no volumes left!',
                    'method': u'CreateForm',
                    'size': 10}

        cinder.volume_type_list(IsA(http.HttpRequest)).\
                                AndReturn(self.volume_types.list())
        cinder.tenant_absolute_limits(IsA(http.HttpRequest)).\
                                AndReturn(usage_limit)
        cinder.volume_list(IsA(http.HttpRequest)).\
                                AndReturn(self.volumes.list())
        cinder.volume_snapshot_list(IsA(http.HttpRequest)).\
                                    AndReturn(self.volume_snapshots.list())
        api.glance.image_list_detailed(IsA(http.HttpRequest),
                                       filters={'is_public': True,
                                                'status': 'active'}) \
                  .AndReturn([self.images.list(), False])
        api.glance.image_list_detailed(IsA(http.HttpRequest),
                            filters={'property-owner_id': self.tenant.id,
                                     'status': 'active'}) \
                  .AndReturn([[], False])
        cinder.tenant_absolute_limits(IsA(http.HttpRequest)).\
                                AndReturn(usage_limit)
        cinder.volume_list(IsA(http.HttpRequest)).\
                                    AndReturn(self.volumes.list())

        self.mox.ReplayAll()

        url = reverse('horizon:project:volumes:create')
        res = self.client.post(url, formData)

        expected_error = [u'You are already using all of your available'
                          ' volumes.']
        self.assertEqual(res.context['form'].errors['__all__'], expected_error)
コード例 #26
0
ファイル: tests.py プロジェクト: cliping/horizon
    def test_create_volume_gb_used_over_alloted_quota(self):
        usage_limit = {'maxTotalVolumeGigabytes': 100,
                 'maxTotalVolumes': 6}
        formData = {'name': u'This Volume Is Huge!',
                    'description': u'This is a volume that is just too big!',
                    'method': u'CreateForm',
                    'size': 5000}

        cinder.volume_type_list(IsA(http.HttpRequest)).\
                                AndReturn(self.volume_types.list())
        cinder.tenant_absolute_limits(IsA(http.HttpRequest)).\
                                AndReturn(usage_limit)
        cinder.volume_list(IsA(http.HttpRequest)).\
                                AndReturn(self.volumes.list())
        cinder.volume_snapshot_list(IsA(http.HttpRequest)).\
                                    AndReturn(self.volume_snapshots.list())
        api.glance.image_list_detailed(IsA(http.HttpRequest),
                                       filters={'is_public': True,
                                                'status': 'active'}) \
                  .AndReturn([self.images.list(), False])
        api.glance.image_list_detailed(IsA(http.HttpRequest),
                            filters={'property-owner_id': self.tenant.id,
                                     'status': 'active'}) \
                  .AndReturn([[], False])
        cinder.tenant_absolute_limits(IsA(http.HttpRequest)).\
                                AndReturn(usage_limit)
        cinder.volume_list(IsA(http.HttpRequest)).\
                                AndReturn(self.volumes.list())

        self.mox.ReplayAll()

        url = reverse('horizon:project:volumes:create')
        res = self.client.post(url, formData)

        expected_error = [u'A volume of 5000GB cannot be created as you only'
                          ' have 20GB of your quota available.']
        self.assertEqual(res.context['form'].errors['__all__'], expected_error)
コード例 #27
0
ファイル: tests.py プロジェクト: cliping/horizon
    def test_create_volume_cannot_encrypt(self):
        # check that widget is hidden if can_encrypt_volumes = false
        PREV = settings.OPENSTACK_HYPERVISOR_FEATURES['can_encrypt_volumes']
        settings.OPENSTACK_HYPERVISOR_FEATURES['can_encrypt_volumes'] = False

        usage_limit = {'maxTotalVolumeGigabytes': 250,
                 'gigabytesUsed': 20,
                 'maxTotalVolumes': 6}

        cinder.volume_type_list(IsA(http.HttpRequest)).\
                                AndReturn(self.volume_types.list())
        cinder.tenant_absolute_limits(IsA(http.HttpRequest)).\
                                AndReturn(usage_limit)
        cinder.volume_list(IsA(http.HttpRequest)).\
                                AndReturn(self.volumes.list())
        cinder.volume_snapshot_list(IsA(http.HttpRequest)).\
                                    AndReturn(self.volume_snapshots.list())
        api.glance.image_list_detailed(IsA(http.HttpRequest),
                                       filters={'is_public': True,
                                                'status': 'active'}) \
                  .AndReturn([self.images.list(), False])
        api.glance.image_list_detailed(IsA(http.HttpRequest),
                            filters={'property-owner_id': self.tenant.id,
                                     'status': 'active'}) \
                  .AndReturn([[], False])

        self.mox.ReplayAll()

        url = reverse('horizon:project:volumes:create')
        res = self.client.get(url)

        # Assert the encryption field is hidden.
        form = res.context['form']
        self.assertTrue(isinstance(form.fields['encryption'].widget,
                                   widgets.HiddenInput))

        settings.OPENSTACK_HYPERVISOR_FEATURES['can_encrypt_volumes'] = PREV
コード例 #28
0
ファイル: quotas.py プロジェクト: amotoki/horizon
def _get_tenant_volume_usages(request, usages, disabled_quotas, tenant_id):
    enabled_volume_quotas = CINDER_QUOTA_FIELDS - disabled_quotas
    if not enabled_volume_quotas:
        return

    try:
        limits = cinder.tenant_absolute_limits(request, tenant_id)
    except cinder.cinder_exception.ClientException:
        msg = _("Unable to retrieve volume limit information.")
        exceptions.handle(request, msg)

    for quota_name, limit_keys in CINDER_QUOTA_LIMIT_MAP.items():
        _add_limit_and_usage(usages, quota_name,
                             limits[limit_keys['limit']],
                             limits[limit_keys['usage']],
                             disabled_quotas)
コード例 #29
0
def tenant_limit_usages(request):
    # TODO(licostan): This method shall be removed from Quota module.
    # ProjectUsage/BaseUsage maybe used instead on volume/image dashboards.
    limits = {}

    try:
        if base.is_service_enabled(request, 'compute'):
            limits.update(nova.tenant_absolute_limits(request, reserved=True))
    except Exception:
        msg = _("Unable to retrieve compute limit information.")
        exceptions.handle(request, msg)

    if cinder.is_volume_service_enabled(request):
        try:
            limits.update(cinder.tenant_absolute_limits(request))
        except cinder.cinder_exception.ClientException:
            msg = _("Unable to retrieve volume limit information.")
            exceptions.handle(request, msg)

    return limits
コード例 #30
0
ファイル: quotas.py プロジェクト: infraredgirl/horizon
def tenant_limit_usages(request):
    # TODO(licostan): This method shall be removed from Quota module.
    # ProjectUsage/BaseUsage maybe used instead on volume/image dashboards.
    limits = {}

    try:
        if base.is_service_enabled(request, 'compute'):
            limits.update(nova.tenant_absolute_limits(request, reserved=True))
    except Exception:
        msg = _("Unable to retrieve compute limit information.")
        exceptions.handle(request, msg)

    if cinder.is_volume_service_enabled(request):
        try:
            limits.update(cinder.tenant_absolute_limits(request))
        except cinder.cinder_exception.ClientException:
            msg = _("Unable to retrieve volume limit information.")
            exceptions.handle(request, msg)

    return limits
コード例 #31
0
def tenant_limit_usages(request):
    # TODO(licostan): This method shall be removed from Quota module.
    # ProjectUsage/BaseUsage maybe used instead on volume/image dashboards.
    limits = {}

    try:
        #limits.update(nova.tenant_absolute_limits(request))
        if is_m1_user_admin(request):
            limits.update(tenant_absolute_limits_nova(request))
        else:
            limits.update(nova.tenant_absolute_limits(request))
    except Exception:
        msg = _("Unable to retrieve compute limit information.")
        exceptions.handle(request, msg)

    if base.is_service_enabled(request, 'volume'):
        try:
            #limits.update(cinder.tenant_absolute_limits(request))
            #volumes = cinder.volume_list(request)
            #snapshots = cinder.volume_snapshot_list(request)
            if is_m1_user_admin(request):
                limits.update(tenant_absolute_limits_cinder(request))
                volumes = get_volume_list(request)
                snapshots = get_volume_snapshot_list(request)
            else:
                limits.update(cinder.tenant_absolute_limits(request))
                volumes = cinder.volume_list(request)
                snapshots = cinder.volume_snapshot_list(request)

            # gigabytesUsed should be a total of volumes and snapshots
            vol_size = sum([getattr(volume, 'size', 0) for volume in volumes])
            snap_size = sum([getattr(snap, 'size', 0) for snap in snapshots])
            limits['gigabytesUsed'] = vol_size + snap_size
            limits['volumesUsed'] = len(volumes)
            limits['snapshotsUsed'] = len(snapshots)
        except cinder.ClientException:
            msg = _("Unable to retrieve volume limit information.")
            exceptions.handle(request, msg)

    return limits
コード例 #32
0
ファイル: quotas.py プロジェクト: AZBob/horizon
def tenant_limit_usages(request):
    limits = {}

    try:
        limits.update(nova.tenant_absolute_limits(request))
    except Exception:
        msg = _("Unable to retrieve compute limit information.")
        exceptions.handle(request, msg)

    if base.is_service_enabled(request, 'volume'):
        try:
            limits.update(cinder.tenant_absolute_limits(request))
            volumes = cinder.volume_list(request)
            total_size = sum([getattr(volume, 'size', 0) for volume
                              in volumes])
            limits['gigabytesUsed'] = total_size
            limits['volumesUsed'] = len(volumes)
        except Exception:
            msg = _("Unable to retrieve volume limit information.")
            exceptions.handle(request, msg)

    return limits
コード例 #33
0
def tenant_limit_usages(request):
    limits = {}

    try:
        limits.update(nova.tenant_absolute_limits(request))
    except Exception:
        msg = _("Unable to retrieve compute limit information.")
        exceptions.handle(request, msg)

    if base.is_service_enabled(request, 'volume'):
        try:
            limits.update(cinder.tenant_absolute_limits(request))
            volumes = cinder.volume_list(request)
            total_size = sum(
                [getattr(volume, 'size', 0) for volume in volumes])
            limits['gigabytesUsed'] = total_size
            limits['volumesUsed'] = len(volumes)
        except Exception:
            msg = _("Unable to retrieve volume limit information.")
            exceptions.handle(request, msg)

    return limits
コード例 #34
0
ファイル: forms.py プロジェクト: StokesB1/horizon
    def handle(self, request, data):
        try:
            usages = cinder.tenant_absolute_limits(self.request)
            volumes = cinder.volume_list(self.request)
            total_size = sum([getattr(volume, 'size', 0) for volume
                              in volumes])
            usages['gigabytesUsed'] = total_size
            usages['volumesUsed'] = len(volumes)
            availableGB = usages['maxTotalVolumeGigabytes'] -\
                usages['gigabytesUsed']
            availableVol = usages['maxTotalVolumes'] - usages['volumesUsed']

            snapshot_id = None
            image_id = None
            source_type = data.get('volume_source_type', None)
            if (data.get("snapshot_source", None) and
                  source_type in [None, 'snapshot_source']):
                # Create from Snapshot
                snapshot = self.get_snapshot(request,
                                             data["snapshot_source"])
                snapshot_id = snapshot.id
                if (data['size'] < snapshot.size):
                    error_message = _('The volume size cannot be less than '
                                      'the snapshot size (%sGB)' %
                                      snapshot.size)
                    raise ValidationError(error_message)
            elif (data.get("image_source", None) and
                  source_type in [None, 'image_source']):
                # Create from Snapshot
                image = self.get_image(request,
                                       data["image_source"])
                image_id = image.id
                image_size = functions.bytes_to_gigabytes(image.size)
                if (data['size'] < image_size):
                    error_message = _('The volume size cannot be less than '
                                      'the image size (%s)' %
                                      filesizeformat(image.size))
                    raise ValidationError(error_message)
            else:
                if type(data['size']) is str:
                    data['size'] = int(data['size'])

            if availableGB < data['size']:
                error_message = _('A volume of %(req)iGB cannot be created as '
                                  'you only have %(avail)iGB of your quota '
                                  'available.')
                params = {'req': data['size'],
                          'avail': availableGB}
                raise ValidationError(error_message % params)
            elif availableVol <= 0:
                error_message = _('You are already using all of your available'
                                  ' volumes.')
                raise ValidationError(error_message)

            metadata = {}

            volume = cinder.volume_create(request,
                                          data['size'],
                                          data['name'],
                                          data['description'],
                                          data['type'],
                                          snapshot_id=snapshot_id,
                                          image_id=image_id,
                                          metadata=metadata)
            message = _('Creating volume "%s"') % data['name']
            messages.info(request, message)
            return volume
        except ValidationError as e:
            self.api_error(e.messages[0])
            return False
        except Exception:
            exceptions.handle(request, ignore=True)
            self.api_error(_("Unable to create volume."))
            return False
コード例 #35
0
    def handle(self, request, data):
        try:
            usages = cinder.tenant_absolute_limits(self.request)
            volumes = cinder.volume_list(self.request)
            total_size = sum(
                [getattr(volume, 'size', 0) for volume in volumes])
            usages['gigabytesUsed'] = total_size
            usages['volumesUsed'] = len(volumes)
            availableGB = usages['maxTotalVolumeGigabytes'] -\
                usages['gigabytesUsed']
            availableVol = usages['maxTotalVolumes'] - usages['volumesUsed']

            snapshot_id = None
            image_id = None
            source_type = data.get('volume_source_type', None)
            if (data.get("snapshot_source", None)
                    and source_type in [None, 'snapshot_source']):
                # Create from Snapshot
                snapshot = self.get_snapshot(request, data["snapshot_source"])
                snapshot_id = snapshot.id
                if (data['size'] < snapshot.size):
                    error_message = _('The volume size cannot be less than '
                                      'the snapshot size (%sGB)' %
                                      snapshot.size)
                    raise ValidationError(error_message)
            elif (data.get("image_source", None)
                  and source_type in [None, 'image_source']):
                # Create from Snapshot
                image = self.get_image(request, data["image_source"])
                image_id = image.id
                image_size = bytes_to_gigabytes(image.size)
                if (data['size'] < image_size):
                    error_message = _('The volume size cannot be less than '
                                      'the image size (%s)' %
                                      filesizeformat(image.size))
                    raise ValidationError(error_message)
            else:
                if type(data['size']) is str:
                    data['size'] = int(data['size'])

            if availableGB < data['size']:
                error_message = _('A volume of %(req)iGB cannot be created as '
                                  'you only have %(avail)iGB of your quota '
                                  'available.')
                params = {'req': data['size'], 'avail': availableGB}
                raise ValidationError(error_message % params)
            elif availableVol <= 0:
                error_message = _('You are already using all of your available'
                                  ' volumes.')
                raise ValidationError(error_message)

            metadata = {}

            if data['encryption']:
                metadata['encryption'] = data['encryption']

            volume = cinder.volume_create(request,
                                          data['size'],
                                          data['name'],
                                          data['description'],
                                          data['type'],
                                          snapshot_id=snapshot_id,
                                          image_id=image_id,
                                          metadata=metadata)
            message = _('Creating volume "%s"') % data['name']
            messages.info(request, message)
            return volume
        except ValidationError as e:
            self.api_error(e.messages[0])
            return False
        except Exception:
            exceptions.handle(request, ignore=True)
            self.api_error(_("Unable to create volume."))
            return False