def test_create_volume_number_over_alloted_quota(self): usage_limit = { "maxTotalVolumeGigabytes": 100, "gigabytesUsed": 20, "volumesUsed": len(self.cinder_volumes.list()), "maxTotalVolumes": len(self.cinder_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()) quotas.tenant_limit_usages(IsA(http.HttpRequest)).AndReturn(usage_limit) cinder.volume_snapshot_list(IsA(http.HttpRequest)).AndReturn(self.cinder_volume_snapshots.list()) api.glance.image_list_detailed( IsA(http.HttpRequest), filters={"is_public": True, "status": "active"} ).AndReturn([self.images.list(), False, False]) api.glance.image_list_detailed( IsA(http.HttpRequest), filters={"property-owner_id": self.tenant.id, "status": "active"} ).AndReturn([[], False, False]) cinder.volume_list(IsA(http.HttpRequest)).AndReturn(self.cinder_volumes.list()) cinder.extension_supported(IsA(http.HttpRequest), "AvailabilityZones").AndReturn(True) cinder.availability_zone_list(IsA(http.HttpRequest)).AndReturn(self.cinder_availability_zones.list()) quotas.tenant_limit_usages(IsA(http.HttpRequest)).AndReturn(usage_limit) self.mox.ReplayAll() url = reverse("horizon:project:volumes: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)
def test_index(self): cinder.volume_list(IsA(http.HttpRequest), search_opts={ 'all_tenants': True}).AndReturn(self.cinder_volumes.list()) api.nova.server_list(IsA(http.HttpRequest), search_opts={ 'all_tenants': True}) \ .AndReturn([self.servers.list(), False]) cinder.volume_type_list(IsA(http.HttpRequest)).\ AndReturn(self.volume_types.list()) keystone.tenant_list(IsA(http.HttpRequest)) \ .AndReturn([self.tenants.list(), False]) cinder.volume_snapshot_list(IsA(http.HttpRequest), search_opts={ 'all_tenants': True}).\ AndReturn(self.cinder_volume_snapshots.list()) cinder.volume_list(IsA(http.HttpRequest), search_opts={ 'all_tenants': True}).\ AndReturn(self.cinder_volumes.list()) keystone.tenant_list(IsA(http.HttpRequest)). \ AndReturn([self.tenants.list(), False]) self.mox.ReplayAll() res = self.client.get(reverse('horizon:admin:volumes:index')) self.assertTemplateUsed(res, 'admin/volumes/index.html') volumes = res.context['volumes_table'].data self.assertItemsEqual(volumes, self.cinder_volumes.list())
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']])
def test_create_button_disabled_when_quota_exceeded(self): quota_usages = self.quota_usages.first() quota_usages['volumes']['available'] = 0 volumes = self.cinder_volumes.list() 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.volume_snapshot_list(IsA(http.HttpRequest))\ .AndReturn(self.cinder_volume_snapshots.list()) cinder.volume_list(IsA(http.HttpRequest)).AndReturn(volumes) quotas.tenant_quota_usages(IsA(http.HttpRequest))\ .MultipleTimes().AndReturn(quota_usages) 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'>%s</a>" \ % (url, link_name, " ".join(classes), link_name) self.assertContains(res, expected_string, html=True, msg_prefix="The create button is not disabled")
def test_snapshot_tab(self): cinder.volume_list(IsA(http.HttpRequest), search_opts={ 'all_tenants': True}).\ AndReturn(self.cinder_volumes.list()) api.nova.server_list(IsA(http.HttpRequest), search_opts={ 'all_tenants': True}).\ AndReturn([self.servers.list(), False]) cinder.volume_type_list(IsA(http.HttpRequest)).\ AndReturn(self.volume_types.list()) keystone.tenant_list(IsA(http.HttpRequest)). \ AndReturn([self.tenants.list(), False]) cinder.volume_snapshot_list(IsA(http.HttpRequest), search_opts={ 'all_tenants': True}). \ AndReturn(self.cinder_volume_snapshots.list()) cinder.volume_list(IsA(http.HttpRequest), search_opts={ 'all_tenants': True}).\ AndReturn(self.cinder_volumes.list()) keystone.tenant_list(IsA(http.HttpRequest)). \ AndReturn([self.tenants.list(), False]) self.mox.ReplayAll() res = self.client.get(reverse('horizon:admin:volumes:snapshots_tab')) self.assertEqual(res.status_code, 200) self.assertTemplateUsed(res, 'horizon/common/_detail_table.html')
def test_delete_volume_error_existing_snapshot(self): volume = self.volumes.first() formData = {'action': 'volumes__delete__%s' % volume.id} exc = self.exceptions.cinder.__class__(400, "error: dependent snapshots") cinder.volume_list(IsA(http.HttpRequest), search_opts=None).\ AndReturn(self.volumes.list()) 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(self.volumes.list()) api.nova.server_list(IsA(http.HttpRequest), search_opts=None).\ AndReturn([self.servers.list(), False]) quotas.tenant_quota_usages(IsA(http.HttpRequest)).MultipleTimes().\ AndReturn(self.quota_usages.first()) self.mox.ReplayAll() url = reverse('horizon:project:volumes:index') res = self.client.post(url, formData, follow=True) self.assertMessageCount(res, error=1) self.assertEqual(list(res.context['messages'])[0].message, u'Unable to delete volume "%s". ' u'One or more snapshots depend on it.' % volume.display_name)
def _test_encryption(self, encryption): volumes = self.volumes.list() for volume in volumes: volume.encrypted = encryption quota_usages = self.quota_usages.first() cinder.volume_list(IsA(http.HttpRequest), search_opts=None)\ .MultipleTimes().AndReturn(self.volumes.list()) cinder.volume_list(IsA(http.HttpRequest)).AndReturn([]) cinder.volume_snapshot_list(IsA(http.HttpRequest)).AndReturn([]) api.nova.server_list(IsA(http.HttpRequest), search_opts=None)\ .AndReturn([self.servers.list(), False]) quotas.tenant_quota_usages(IsA(http.HttpRequest))\ .MultipleTimes().AndReturn(quota_usages) 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)
def test_tenant_quota_usages(self): quotas.is_service_enabled(IsA(http.HttpRequest), 'volume').AndReturn(True) api.nova.flavor_list(IsA(http.HttpRequest)) \ .AndReturn(self.flavors.list()) api.nova.tenant_quota_get(IsA(http.HttpRequest), '1') \ .AndReturn(self.quotas.first()) api.nova.tenant_floating_ip_list(IsA(http.HttpRequest)) \ .AndReturn(self.floating_ips.list()) api.nova.server_list(IsA(http.HttpRequest)) \ .AndReturn(self.servers.list()) cinder.volume_list(IsA(http.HttpRequest)) \ .AndReturn(self.volumes.list()) cinder.tenant_quota_get(IsA(http.HttpRequest), '1') \ .AndReturn(self.quotas.first()) self.mox.ReplayAll() quota_usages = quotas.tenant_quota_usages(self.request) expected_output = { 'injected_file_content_bytes': {'quota': 1}, 'metadata_items': {'quota': 1}, 'injected_files': {'quota': 1}, 'gigabytes': {'available': 920, 'used': 80, 'quota': 1000}, 'ram': {'available': 8976, 'used': 1024, 'quota': 10000}, 'floating_ips': {'available': 0, 'used': 2, 'quota': 1}, 'instances': {'available': 8, 'used': 2, 'quota': 10}, 'volumes': {'available': 0, 'used': 3, 'quota': 1}, 'cores': {'available': 8, 'used': 2, 'quota': 10} } # Compare internal structure of usages to expected. self.assertEquals(quota_usages.usages, expected_output)
def test_launch_flavorlist_error(self): cinder.volume_list(IsA(http.HttpRequest)).AndReturn(self.volumes.list()) cinder.volume_snapshot_list(IsA(http.HttpRequest)).AndReturn(self.volumes.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]) api.quantum.network_list(IsA(http.HttpRequest), tenant_id=self.tenant.id, shared=False).AndReturn( self.networks.list()[:1] ) api.quantum.network_list(IsA(http.HttpRequest), shared=True).AndReturn(self.networks.list()[1:]) quotas.tenant_quota_usages(IsA(http.HttpRequest)).AndReturn(self.quota_usages.first()) api.nova.flavor_list(IsA(http.HttpRequest)).AndRaise(self.exceptions.nova) api.nova.flavor_list(IsA(http.HttpRequest)).AndRaise(self.exceptions.nova) api.nova.keypair_list(IsA(http.HttpRequest)).AndReturn(self.keypairs.list()) api.nova.security_group_list(IsA(http.HttpRequest)).AndReturn(self.security_groups.list()) self.mox.ReplayAll() url = reverse("horizon:project:instances:launch") res = self.client.get(url) self.assertTemplateUsed(res, "project/instances/launch.html")
def test_launch_form_keystone_exception(self): flavor = self.flavors.first() image = self.images.first() keypair = self.keypairs.first() server = self.servers.first() sec_group = self.security_groups.first() customization_script = "userData" nics = [{"net-id": self.networks.first().id, "v4-fixed-ip": ""}] cinder.volume_snapshot_list(IsA(http.HttpRequest)).AndReturn(self.volumes.list()) api.nova.flavor_list(IgnoreArg()).AndReturn(self.flavors.list()) api.nova.keypair_list(IgnoreArg()).AndReturn(self.keypairs.list()) api.nova.security_group_list(IsA(http.HttpRequest)).AndReturn(self.security_groups.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]) api.quantum.network_list(IsA(http.HttpRequest), tenant_id=self.tenant.id, shared=False).AndReturn( self.networks.list()[:1] ) api.quantum.network_list(IsA(http.HttpRequest), shared=True).AndReturn(self.networks.list()[1:]) cinder.volume_list(IgnoreArg()).AndReturn(self.volumes.list()) api.nova.server_create( IsA(http.HttpRequest), server.name, image.id, flavor.id, keypair.name, customization_script, [sec_group.name], None, nics=nics, instance_count=IsA(int), admin_pass="******", ).AndRaise(self.exceptions.keystone) self.mox.ReplayAll() form_data = { "flavor": flavor.id, "source_type": "image_id", "image_id": image.id, "keypair": keypair.name, "name": server.name, "customization_script": customization_script, "project_id": self.tenants.first().id, "user_id": self.user.id, "groups": sec_group.name, "volume_type": "", "network": self.networks.first().id, "count": 1, "admin_pass": "******", "confirm_admin_pass": "******", } url = reverse("horizon:project:instances:launch") res = self.client.post(url, form_data) self.assertRedirectsNoFollow(res, INDEX_URL)
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)
def test_tenant_quota_usages(self): quotas.is_service_enabled(IsA(http.HttpRequest), "volume").AndReturn(True) api.nova.flavor_list(IsA(http.HttpRequest)).AndReturn(self.flavors.list()) api.nova.tenant_quota_get(IsA(http.HttpRequest), "1").AndReturn(self.quotas.first()) api.network.tenant_floating_ip_list(IsA(http.HttpRequest)).AndReturn(self.floating_ips.list()) api.nova.server_list(IsA(http.HttpRequest)).AndReturn(self.servers.list()) cinder.volume_list(IsA(http.HttpRequest)).AndReturn(self.volumes.list()) cinder.tenant_quota_get(IsA(http.HttpRequest), "1").AndReturn(self.quotas.first()) self.mox.ReplayAll() quota_usages = quotas.tenant_quota_usages(self.request) expected_output = { "injected_file_content_bytes": {"quota": 1}, "metadata_items": {"quota": 1}, "injected_files": {"quota": 1}, "gigabytes": {"available": 920, "used": 80, "quota": 1000}, "ram": {"available": 8976, "used": 1024, "quota": 10000}, "floating_ips": {"available": 0, "used": 2, "quota": 1}, "instances": {"available": 8, "used": 2, "quota": 10}, "volumes": {"available": 0, "used": 3, "quota": 1}, "cores": {"available": 8, "used": 2, "quota": 10}, } # Compare internal structure of usages to expected. self.assertEquals(quota_usages.usages, expected_output)
def test_tenant_quota_usages_neutron_fip_disabled(self): servers = [s for s in self.servers.list() if s.tenant_id == self.request.user.tenant_id] api.base.is_service_enabled(IsA(http.HttpRequest), 'volume').AndReturn(True) api.base.is_service_enabled(IsA(http.HttpRequest), 'network').AndReturn(False) api.nova.flavor_list(IsA(http.HttpRequest)) \ .AndReturn(self.flavors.list()) api.nova.tenant_quota_get(IsA(http.HttpRequest), '1') \ .AndReturn(self.quotas.first()) api.network.floating_ip_supported(IsA(http.HttpRequest)) \ .AndReturn(False) search_opts = {'tenant_id': self.request.user.tenant_id} api.nova.server_list(IsA(http.HttpRequest), search_opts=search_opts, all_tenants=True) \ .AndReturn([servers, False]) opts = {'all_tenants': 1, 'project_id': self.request.user.tenant_id} cinder.volume_list(IsA(http.HttpRequest), opts) \ .AndReturn(self.volumes.list()) cinder.volume_snapshot_list(IsA(http.HttpRequest), opts) \ .AndReturn(self.cinder_volume_snapshots.list()) cinder.tenant_quota_get(IsA(http.HttpRequest), '1') \ .AndReturn(self.cinder_quotas.first()) self.mox.ReplayAll() quota_usages = quotas.tenant_quota_usages(self.request) expected_output = self.get_usages() expected_output['floating_ips']['used'] = 0 expected_output['floating_ips']['available'] = 1 # Compare internal structure of usages to expected. self.assertItemsEqual(expected_output, quota_usages.usages)
def test_tenant_quota_usages_unlimited_quota(self): inf_quota = self.quotas.first() inf_quota['ram'] = -1 servers = [s for s in self.servers.list() if s.tenant_id == self.request.user.tenant_id] api.base.is_service_enabled(IsA(http.HttpRequest), 'volume').AndReturn(True) api.base.is_service_enabled(IsA(http.HttpRequest), 'network').AndReturn(False) api.nova.flavor_list(IsA(http.HttpRequest)) \ .AndReturn(self.flavors.list()) api.nova.tenant_quota_get(IsA(http.HttpRequest), '1') \ .AndReturn(inf_quota) api.network.tenant_floating_ip_list(IsA(http.HttpRequest)) \ .AndReturn(self.floating_ips.list()) api.nova.server_list(IsA(http.HttpRequest)) \ .AndReturn([servers, False]) cinder.volume_list(IsA(http.HttpRequest)) \ .AndReturn(self.volumes.list()) cinder.volume_snapshot_list(IsA(http.HttpRequest)) \ .AndReturn(self.snapshots.list()) cinder.tenant_quota_get(IsA(http.HttpRequest), '1') \ .AndReturn(self.cinder_quotas.first()) self.mox.ReplayAll() quota_usages = quotas.tenant_quota_usages(self.request) expected_output = self.get_usages() expected_output.update({'ram': {'available': float("inf"), 'used': 1024, 'quota': float("inf")}}) # Compare internal structure of usages to expected. self.assertEquals(quota_usages.usages, expected_output)
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)
def test_tenant_quota_usages(self): servers = [s for s in self.servers.list() if s.tenant_id == self.request.user.tenant_id] api.base.is_service_enabled(IsA(http.HttpRequest), 'volume').AndReturn(True) api.base.is_service_enabled(IsA(http.HttpRequest), 'network').AndReturn(False) api.nova.flavor_list(IsA(http.HttpRequest)) \ .AndReturn(self.flavors.list()) api.nova.tenant_quota_get(IsA(http.HttpRequest), '1') \ .AndReturn(self.quotas.first()) api.network.floating_ip_supported(IsA(http.HttpRequest)) \ .AndReturn(True) api.network.tenant_floating_ip_list(IsA(http.HttpRequest)) \ .AndReturn(self.floating_ips.list()) api.nova.server_list(IsA(http.HttpRequest)) \ .AndReturn([servers, False]) cinder.volume_list(IsA(http.HttpRequest)) \ .AndReturn(self.volumes.list()) cinder.volume_snapshot_list(IsA(http.HttpRequest)) \ .AndReturn(self.snapshots.list()) cinder.tenant_quota_get(IsA(http.HttpRequest), '1') \ .AndReturn(self.cinder_quotas.first()) self.mox.ReplayAll() quota_usages = quotas.tenant_quota_usages(self.request) expected_output = self.get_usages() # Compare internal structure of usages to expected. self.assertEqual(expected_output, quota_usages.usages)
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&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")
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)")
def test_select_default_keypair_if_only_one(self): keypair = self.keypairs.first() quota_usages = self.quota_usages.first() image = self.images.first() cinder.volume_list(IsA(http.HttpRequest)).AndReturn(self.volumes.list()) cinder.volume_snapshot_list(IsA(http.HttpRequest)).AndReturn(self.volumes.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]) api.quantum.network_list(IsA(http.HttpRequest), tenant_id=self.tenant.id, shared=False).AndReturn( self.networks.list()[:1] ) api.quantum.network_list(IsA(http.HttpRequest), shared=True).AndReturn(self.networks.list()[1:]) quotas.tenant_quota_usages(IsA(http.HttpRequest)).AndReturn(quota_usages) api.nova.flavor_list(IsA(http.HttpRequest)).AndReturn(self.flavors.list()) api.nova.flavor_list(IsA(http.HttpRequest)).AndReturn(self.flavors.list()) api.nova.keypair_list(IsA(http.HttpRequest)).AndReturn([keypair]) api.nova.security_group_list(IsA(http.HttpRequest)).AndReturn(self.security_groups.list()) self.mox.ReplayAll() url = reverse("horizon:project:instances:launch") res = self.client.get(url) self.assertContains( res, "<option selected='selected' value='%(key)s'>" "%(key)s</option>" % {"key": keypair.name}, html=True, msg_prefix="The default keypair was not selected.", )
def test_create_volume_gb_used_over_alloted_quota(self): usage_limit = { "maxTotalVolumeGigabytes": 100, "gigabytesUsed": 80, "volumesUsed": len(self.cinder_volumes.list()), "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()) quotas.tenant_limit_usages(IsA(http.HttpRequest)).AndReturn(usage_limit) cinder.volume_snapshot_list(IsA(http.HttpRequest)).AndReturn(self.cinder_volume_snapshots.list()) api.glance.image_list_detailed( IsA(http.HttpRequest), filters={"is_public": True, "status": "active"} ).AndReturn([self.images.list(), False, False]) api.glance.image_list_detailed( IsA(http.HttpRequest), filters={"property-owner_id": self.tenant.id, "status": "active"} ).AndReturn([[], False, False]) cinder.volume_list(IsA(http.HttpRequest)).AndReturn(self.cinder_volumes.list()) cinder.extension_supported(IsA(http.HttpRequest), "AvailabilityZones").AndReturn(True) cinder.availability_zone_list(IsA(http.HttpRequest)).AndReturn(self.cinder_availability_zones.list()) quotas.tenant_limit_usages(IsA(http.HttpRequest)).AndReturn(usage_limit) self.mox.ReplayAll() url = reverse("horizon:project:volumes: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)
def test_launch_form_instance_count_error(self): flavor = self.flavors.first() image = self.images.first() keypair = self.keypairs.first() server = self.servers.first() volume = self.volumes.first() sec_group = self.security_groups.first() customization_script = 'user data' device_name = u'vda' volume_choice = "%s:vol" % volume.id api.nova.flavor_list(IsA(http.HttpRequest)) \ .AndReturn(self.flavors.list()) api.nova.keypair_list(IsA(http.HttpRequest)) \ .AndReturn(self.keypairs.list()) api.nova.security_group_list(IsA(http.HttpRequest)) \ .AndReturn(self.security_groups.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]) api.quantum.network_list(IsA(http.HttpRequest), tenant_id=self.tenant.id, shared=False) \ .AndReturn(self.networks.list()[:1]) api.quantum.network_list(IsA(http.HttpRequest), shared=True) \ .AndReturn(self.networks.list()[1:]) cinder.volume_list(IsA(http.HttpRequest)) \ .AndReturn(self.volumes.list()) cinder.volume_snapshot_list(IsA(http.HttpRequest)).AndReturn([]) api.nova.flavor_list(IsA(http.HttpRequest)) \ .AndReturn(self.flavors.list()) quotas.tenant_quota_usages(IsA(http.HttpRequest)) \ .AndReturn(self.quota_usages.first()) self.mox.ReplayAll() form_data = {'flavor': flavor.id, 'source_type': 'image_id', 'image_id': image.id, 'keypair': keypair.name, 'name': server.name, 'customization_script': customization_script, 'project_id': self.tenants.first().id, 'user_id': self.user.id, 'groups': sec_group.name, 'volume_type': 'volume_id', 'volume_id': volume_choice, 'device_name': device_name, 'count': 0} url = reverse('horizon:project:instances:launch') res = self.client.post(url, form_data) self.assertContains(res, "greater than or equal to 1")
def test_create_volume_from_image_dropdown(self): volume = self.cinder_volumes.first() usage_limit = {'maxTotalVolumeGigabytes': 200, 'gigabytesUsed': 20, 'volumesUsed': len(self.cinder_volumes.list()), '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.cinder_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.cinder_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_list(IsA( http.HttpRequest)).AndReturn(self.cinder_volumes.list()) quotas.tenant_limit_usages(IsA(http.HttpRequest)) \ .AndReturn(usage_limit) api.glance.image_get(IsA(http.HttpRequest), str(image.id)).AndReturn(image) cinder.extension_supported(IsA(http.HttpRequest), 'AvailabilityZones')\ .AndReturn(True) cinder.availability_zone_list(IsA(http.HttpRequest)).AndReturn( self.cinder_availability_zones.list()) cinder.volume_create(IsA(http.HttpRequest), formData['size'], formData['name'], formData['description'], '', metadata={}, snapshot_id=None, image_id=image.id, availability_zone=None, source_volid=None).AndReturn(volume) self.mox.ReplayAll() # get image from dropdown list url = reverse('horizon:project:volumes:volumes:create') res = self.client.post(url, formData) redirect_url = VOLUME_VOLUMES_TAB_URL self.assertRedirectsNoFollow(res, redirect_url)
def test_get_tenant_volume_usages_cinder_exception(self): cinder.volume_list(IsA(http.HttpRequest)) \ .AndRaise(cinder.cinder_exception.ClientException('test')) exceptions.handle(IsA(http.HttpRequest), _("Unable to retrieve volume limit information.")) self.mox.ReplayAll() quotas._get_tenant_volume_usages(self.request, {}, set(), None)
def test_create_volume_from_volume(self): volume = self.volumes.first() usage_limit = {'maxTotalVolumeGigabytes': 250, 'gigabytesUsed': 20, 'volumesUsed': len(self.volumes.list()), 'maxTotalVolumes': 6} formData = {'name': u'A copy of a volume', 'description': u'This is a volume I am making for a test.', 'method': u'CreateForm', 'size': 50, 'type': '', 'volume_source_type': 'volume_source', 'volume_source': volume.id} cinder.volume_list(IsA(http.HttpRequest)).\ AndReturn(self.volumes.list()) cinder.volume_type_list(IsA(http.HttpRequest)).\ AndReturn(self.volume_types.list()) cinder.volume_snapshot_list(IsA(http.HttpRequest)).\ AndReturn(self.volume_snapshots.list()) quotas.tenant_limit_usages(IsA(http.HttpRequest)).\ AndReturn(usage_limit) cinder.volume_get(IsA(http.HttpRequest), volume.id).AndReturn(self.volumes.first()) cinder.extension_supported(IsA(http.HttpRequest), 'AvailabilityZones').AndReturn(True) cinder.availability_zone_list(IsA(http.HttpRequest)).AndReturn( self.cinder_availability_zones.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'], '', metadata={}, snapshot_id=None, image_id=None, availability_zone=None, source_volid=volume.id).AndReturn(volume) self.mox.ReplayAll() url = reverse('horizon:project:volumes:volumes:create') redirect_url = reverse('horizon:project:volumes:index') res = self.client.post(url, formData) self.assertNoFormErrors(res) self.assertMessageCount(info=1) self.assertRedirectsNoFollow(res, redirect_url)
def test_launch_instance_post_no_images_available(self): flavor = self.flavors.first() keypair = self.keypairs.first() server = self.servers.first() volume = self.volumes.first() sec_group = self.security_groups.first() customization_script = "user data" device_name = u"vda" volume_choice = "%s:vol" % volume.id api.nova.flavor_list(IsA(http.HttpRequest)).AndReturn(self.flavors.list()) quotas.tenant_quota_usages(IsA(http.HttpRequest)).AndReturn({}) api.glance.image_list_detailed( IsA(http.HttpRequest), filters={"is_public": True, "status": "active"} ).AndReturn([[], False]) api.glance.image_list_detailed( IsA(http.HttpRequest), filters={"property-owner_id": self.tenant.id, "status": "active"} ).AndReturn([[], False]) api.quantum.network_list(IsA(http.HttpRequest), tenant_id=self.tenant.id, shared=False).AndReturn( self.networks.list()[:1] ) api.quantum.network_list(IsA(http.HttpRequest), shared=True).AndReturn(self.networks.list()[1:]) api.nova.flavor_list(IsA(http.HttpRequest)).AndReturn(self.flavors.list()) api.nova.keypair_list(IsA(http.HttpRequest)).AndReturn(self.keypairs.list()) api.nova.security_group_list(IsA(http.HttpRequest)).AndReturn(self.security_groups.list()) cinder.volume_list(IsA(http.HttpRequest)).AndReturn(self.volumes.list()) cinder.volume_snapshot_list(IsA(http.HttpRequest)).AndReturn([]) self.mox.ReplayAll() form_data = { "flavor": flavor.id, "source_type": "image_id", "image_id": "", "keypair": keypair.name, "name": server.name, "customization_script": customization_script, "project_id": self.tenants.first().id, "user_id": self.user.id, "groups": sec_group.name, "volume_type": "volume_id", "volume_id": volume_choice, "device_name": device_name, "count": 1, } url = reverse("horizon:project:instances:launch") res = self.client.post(url, form_data) self.assertFormErrors( res, 1, "There are no image sources available; " "you must first create an image before " "attempting to launch an instance.", ) self.assertTemplateUsed(res, "project/instances/launch.html")
def test_create_volume_from_image_dropdown(self): volume = self.cinder_volumes.first() usage_limit = { "maxTotalVolumeGigabytes": 200, "gigabytesUsed": 20, "volumesUsed": len(self.cinder_volumes.list()), "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.cinder_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.cinder_volume_snapshots.list()) api.glance.image_list_detailed( IsA(http.HttpRequest), filters={"is_public": True, "status": "active"} ).AndReturn([self.images.list(), False, False]) api.glance.image_list_detailed( IsA(http.HttpRequest), filters={"property-owner_id": self.tenant.id, "status": "active"} ).AndReturn([[], False, False]) cinder.volume_list(IsA(http.HttpRequest)).AndReturn(self.cinder_volumes.list()) quotas.tenant_limit_usages(IsA(http.HttpRequest)).AndReturn(usage_limit) api.glance.image_get(IsA(http.HttpRequest), str(image.id)).AndReturn(image) cinder.extension_supported(IsA(http.HttpRequest), "AvailabilityZones").AndReturn(True) cinder.availability_zone_list(IsA(http.HttpRequest)).AndReturn(self.cinder_availability_zones.list()) cinder.volume_create( IsA(http.HttpRequest), formData["size"], formData["name"], formData["description"], "", metadata={}, snapshot_id=None, image_id=image.id, availability_zone=None, source_volid=None, ).AndReturn(volume) self.mox.ReplayAll() # get image from dropdown list url = reverse("horizon:project:volumes:volumes:create") res = self.client.post(url, formData) redirect_url = VOLUME_VOLUMES_TAB_URL self.assertRedirectsNoFollow(res, redirect_url)
def test_launch_instance_get(self): quota_usages = self.quota_usages.first() image = self.images.first() cinder.volume_list(IsA(http.HttpRequest)) \ .AndReturn(self.volumes.list()) cinder.volume_snapshot_list(IsA(http.HttpRequest)) \ .AndReturn(self.volumes.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]) api.quantum.network_list(IsA(http.HttpRequest), tenant_id=self.tenant.id, shared=False) \ .AndReturn(self.networks.list()[:1]) api.quantum.network_list(IsA(http.HttpRequest), shared=True) \ .AndReturn(self.networks.list()[1:]) quotas.tenant_quota_usages(IsA(http.HttpRequest)) \ .AndReturn(quota_usages) api.nova.flavor_list(IsA(http.HttpRequest)) \ .AndReturn(self.flavors.list()) api.nova.flavor_list(IsA(http.HttpRequest)) \ .AndReturn(self.flavors.list()) api.nova.keypair_list(IsA(http.HttpRequest)) \ .AndReturn(self.keypairs.list()) api.nova.security_group_list(IsA(http.HttpRequest)) \ .AndReturn(self.security_groups.list()) self.mox.ReplayAll() url = reverse('horizon:project:instances:launch') params = urlencode({"source_type": "image_id", "source_id": image.id}) res = self.client.get("%s?%s" % (url, params)) workflow = res.context['workflow'] self.assertTemplateUsed(res, 'project/instances/launch.html') self.assertEqual(res.context['workflow'].name, LaunchInstance.name) step = workflow.get_step("setinstancedetailsaction") self.assertEqual(step.action.initial['image_id'], image.id) self.assertQuerysetEqual(workflow.steps, ['<SetInstanceDetails: setinstancedetailsaction>', '<SetAccessControls: setaccesscontrolsaction>', '<SetNetwork: setnetworkaction>', '<VolumeOptions: volumeoptionsaction>', '<PostCreationStep: customizeaction>'])
def _get_tenant_volume_usages(request, usages, disabled_quotas, tenant_id): if 'volumes' not in disabled_quotas: if tenant_id: opts = {'all_tenants': 1, 'project_id': tenant_id} volumes = cinder.volume_list(request, opts) snapshots = cinder.volume_snapshot_list(request, opts) else: volumes = cinder.volume_list(request) snapshots = cinder.volume_snapshot_list(request) usages.tally('gigabytes', sum([int(v.size) for v in volumes])) usages.tally('volumes', len(volumes)) usages.tally('snapshots', len(snapshots))
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
def test_launch_form_instance_count_error(self): flavor = self.flavors.first() image = self.images.first() keypair = self.keypairs.first() server = self.servers.first() volume = self.volumes.first() sec_group = self.security_groups.first() customization_script = "user data" device_name = u"vda" volume_choice = "%s:vol" % volume.id api.nova.flavor_list(IsA(http.HttpRequest)).AndReturn(self.flavors.list()) api.nova.keypair_list(IsA(http.HttpRequest)).AndReturn(self.keypairs.list()) api.nova.security_group_list(IsA(http.HttpRequest)).AndReturn(self.security_groups.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]) api.quantum.network_list(IsA(http.HttpRequest), tenant_id=self.tenant.id, shared=False).AndReturn( self.networks.list()[:1] ) api.quantum.network_list(IsA(http.HttpRequest), shared=True).AndReturn(self.networks.list()[1:]) cinder.volume_list(IsA(http.HttpRequest)).AndReturn(self.volumes.list()) cinder.volume_snapshot_list(IsA(http.HttpRequest)).AndReturn([]) api.nova.flavor_list(IsA(http.HttpRequest)).AndReturn(self.flavors.list()) quotas.tenant_quota_usages(IsA(http.HttpRequest)).AndReturn(self.quota_usages.first()) self.mox.ReplayAll() form_data = { "flavor": flavor.id, "source_type": "image_id", "image_id": image.id, "keypair": keypair.name, "name": server.name, "customization_script": customization_script, "project_id": self.tenants.first().id, "user_id": self.user.id, "groups": sec_group.name, "volume_type": "volume_id", "volume_id": volume_choice, "device_name": device_name, "count": 0, } url = reverse("horizon:project:instances:launch") res = self.client.post(url, form_data) self.assertContains(res, "greater than or equal to 1")
def test_index(self): cinder.volume_list(IsA(http.HttpRequest), search_opts={ 'all_tenants': True }).AndReturn(self.cinder_volumes.list()) cinder.volume_snapshot_list(IsA(http.HttpRequest), search_opts={ 'all_tenants': True }).AndReturn([]) api.nova.server_list(IsA(http.HttpRequest), search_opts={ 'all_tenants': True}) \ .AndReturn([self.servers.list(), False]) keystone.tenant_list(IsA(http.HttpRequest)) \ .AndReturn([self.tenants.list(), False]) self.mox.ReplayAll() res = self.client.get(reverse('horizon:admin:volumes:index')) self.assertTemplateUsed(res, 'admin/volumes/index.html') volumes = res.context['volumes_table'].data self.assertItemsEqual(volumes, self.cinder_volumes.list())
def test_delete_volume(self): volume = self.volumes.first() formData = {'action': 'volumes__delete__%s' % volume.id} cinder.volume_list(IsA(http.HttpRequest), search_opts=None).\ AndReturn(self.volumes.list()) 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(self.volumes.list()) api.nova.server_list(IsA(http.HttpRequest), search_opts=None).\ AndReturn([self.servers.list(), False]) quotas.tenant_quota_usages(IsA(http.HttpRequest)).MultipleTimes().\ AndReturn(self.quota_usages.first()) self.mox.ReplayAll() url = reverse('horizon:project:volumes:index') res = self.client.post(url, formData, follow=True) self.assertIn("Scheduled deletion of Volume: Volume name", [m.message for m in res.context['messages']])
def _test_snapshots_index_paginated(self, marker, sort_dir, snapshots, url, has_more, has_prev): cinder.volume_snapshot_list_paged( IsA(http.HttpRequest), paginate=True, marker=marker, sort_dir=sort_dir, search_opts={'all_tenants': True}) \ .AndReturn([snapshots, has_more, has_prev]) cinder.volume_list(IsA(http.HttpRequest), search_opts={ 'all_tenants': True}).\ AndReturn(self.cinder_volumes.list()) keystone.tenant_list(IsA(http.HttpRequest)) \ .AndReturn([self.tenants.list(), False]) self.mox.ReplayAll() res = self.client.get(url) self.assertTemplateUsed(res, 'admin/volumes/index.html') self.assertEqual(res.status_code, 200) self.mox.UnsetStubs() return res
def test_tenant_quota_usages_unlimited_quota(self): inf_quota = self.quotas.first() inf_quota['ram'] = -1 servers = [s for s in self.servers.list() if s.tenant_id == self.request.user.tenant_id] api.base.is_service_enabled(IsA(http.HttpRequest), 'volume').AndReturn(True) api.base.is_service_enabled(IsA(http.HttpRequest), 'network').AndReturn(False) api.nova.flavor_list(IsA(http.HttpRequest)) \ .AndReturn(self.flavors.list()) api.nova.tenant_quota_get(IsA(http.HttpRequest), '1') \ .AndReturn(inf_quota) api.network.floating_ip_supported(IsA(http.HttpRequest)) \ .AndReturn(True) api.network.tenant_floating_ip_list(IsA(http.HttpRequest)) \ .AndReturn(self.floating_ips.list()) search_opts = {'tenant_id': self.request.user.tenant_id} api.nova.server_list(IsA(http.HttpRequest), search_opts=search_opts, all_tenants=True) \ .AndReturn([servers, False]) opts = {'alltenants': 1, 'tenant_id': self.request.user.tenant_id} cinder.volume_list(IsA(http.HttpRequest), opts) \ .AndReturn(self.volumes.list()) cinder.volume_snapshot_list(IsA(http.HttpRequest), opts) \ .AndReturn(self.cinder_volume_snapshots.list()) cinder.tenant_quota_get(IsA(http.HttpRequest), '1') \ .AndReturn(self.cinder_quotas.first()) self.mox.ReplayAll() quota_usages = quotas.tenant_quota_usages(self.request) expected_output = self.get_usages() expected_output.update({'ram': {'available': float("inf"), 'used': 1024, 'quota': float("inf")}}) # Compare internal structure of usages to expected. self.assertItemsEqual(expected_output, quota_usages.usages)
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_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.volume_snapshot_list(IsA(http.HttpRequest))\ .AndReturn(self.cinder_volume_snapshots.list()) cinder.volume_list(IsA(http.HttpRequest)).AndReturn(volumes) quotas.tenant_quota_usages(IsA(http.HttpRequest)).MultipleTimes().\ AndReturn(self.quota_usages.first()) 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)
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)
def test_create_volume_from_image(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': 40, 'type': '', '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.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 url url = reverse('horizon:project:volumes:create') res = self.client.post("?".join([url, "image_id=" + str(image.id)]), formData) redirect_url = reverse('horizon:project:volumes:index') self.assertRedirectsNoFollow(res, redirect_url)
def tenant_quota_usages(request): # Get our quotas and construct our usage object. disabled_quotas = get_disabled_quotas(request) usages = QuotaUsage() for quota in get_tenant_quota_data(request, disabled_quotas=disabled_quotas): usages.add_quota(quota) # Get our usages. floating_ips = [] try: if network.floating_ip_supported(request): floating_ips = network.tenant_floating_ip_list(request) except Exception: pass flavors = dict([(f.id, f) for f in nova.flavor_list(request)]) instances, has_more = nova.server_list(request) # Fetch deleted flavors if necessary. missing_flavors = [ instance.flavor['id'] for instance in instances if instance.flavor['id'] not in flavors ] for missing in missing_flavors: if missing not in flavors: try: flavors[missing] = nova.flavor_get(request, missing) except Exception: flavors[missing] = {} exceptions.handle(request, ignore=True) usages.tally('instances', len(instances)) usages.tally('floating_ips', len(floating_ips)) if 'volumes' not in disabled_quotas: volumes = cinder.volume_list(request) snapshots = cinder.volume_snapshot_list(request) usages.tally('gigabytes', sum([int(v.size) for v in volumes])) usages.tally('volumes', len(volumes)) usages.tally('snapshots', len(snapshots)) # Sum our usage based on the flavors of the instances. for flavor in [flavors[instance.flavor['id']] for instance in instances]: usages.tally('cores', getattr(flavor, 'vcpus', None)) usages.tally('ram', getattr(flavor, 'ram', None)) # Initialise the tally if no instances have been launched yet if len(instances) == 0: usages.tally('cores', 0) usages.tally('ram', 0) return usages
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
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
def _get_tenant_volume_usages(request, usages, disabled_quotas, tenant_id): if CINDER_QUOTA_FIELDS - disabled_quotas: try: if tenant_id: opts = {'all_tenants': 1, 'project_id': tenant_id} volumes = cinder.volume_list(request, opts) snapshots = cinder.volume_snapshot_list(request, opts) else: volumes = cinder.volume_list(request) snapshots = cinder.volume_snapshot_list(request) volume_usage = sum([int(v.size) for v in volumes]) snapshot_usage = sum([int(s.size) for s in snapshots]) _add_usage_if_quota_enabled(usages, 'gigabytes', (snapshot_usage + volume_usage), disabled_quotas) _add_usage_if_quota_enabled(usages, 'volumes', len(volumes), disabled_quotas) _add_usage_if_quota_enabled(usages, 'snapshots', len(snapshots), disabled_quotas) except cinder.cinder_exception.ClientException: msg = _("Unable to retrieve volume limit information.") exceptions.handle(request, msg)
def populate_volume_id_choices(self, request, context): volume_options = [("", _("Select Volume"))] try: volumes = [ v for v in cinder.volume_list(self.request) if v.status == api.cinder.VOLUME_STATE_AVAILABLE ] volume_options.extend( [self._get_volume_display_name(vol) for vol in volumes]) except Exception: exceptions.handle(self.request, _('Unable to retrieve list of volumes.')) return volume_options
def get_volumes(self, request): volumes = [] try: volume_list = cinder.volume_list(self.request) if volume_list is not None: volumes = [ v for v in volume_list if v.status == api.cinder.VOLUME_STATE_AVAILABLE ] except Exception: exceptions.handle(request, _('Unable to retrieve list of volumes.')) return volumes
def test_tenant_quota_usages_neutron_fip_disabled(self): servers = [ s for s in self.servers.list() if s.tenant_id == self.request.user.tenant_id ] cinder.is_volume_service_enabled(IsA(http.HttpRequest)).AndReturn(True) api.base.is_service_enabled(IsA(http.HttpRequest), 'network').AndReturn(False) api.base.is_service_enabled(IsA(http.HttpRequest), 'compute').MultipleTimes().AndReturn(True) api.nova.flavor_list(IsA(http.HttpRequest)) \ .AndReturn(self.flavors.list()) api.nova.tenant_quota_get(IsA(http.HttpRequest), '1') \ .AndReturn(self.quotas.first()) api.network.floating_ip_supported(IsA(http.HttpRequest)) \ .AndReturn(False) search_opts = {'tenant_id': self.request.user.tenant_id} api.nova.server_list(IsA(http.HttpRequest), search_opts=search_opts, all_tenants=True) \ .AndReturn([servers, False]) opts = {'all_tenants': 1, 'project_id': self.request.user.tenant_id} cinder.volume_list(IsA(http.HttpRequest), opts) \ .AndReturn(self.volumes.list()) cinder.volume_snapshot_list(IsA(http.HttpRequest), opts) \ .AndReturn(self.cinder_volume_snapshots.list()) cinder.tenant_quota_get(IsA(http.HttpRequest), '1') \ .AndReturn(self.cinder_quotas.first()) self.mox.ReplayAll() quota_usages = quotas.tenant_quota_usages(self.request) expected_output = self.get_usages() expected_output['floating_ips']['used'] = 0 expected_output['floating_ips']['available'] = 1 # Compare internal structure of usages to expected. self.assertItemsEqual(expected_output, quota_usages.usages)
def test_tenant_quota_usages_with_id(self): tenant_id = 3 cinder.is_volume_service_enabled(IsA(http.HttpRequest)).AndReturn(True) api.base.is_service_enabled(IsA(http.HttpRequest), 'network').AndReturn(False) api.base.is_service_enabled(IsA(http.HttpRequest), 'compute') \ .MultipleTimes().AndReturn(True) servers = [s for s in self.servers.list() if s.tenant_id == tenant_id] api.nova.flavor_list(IsA(http.HttpRequest)) \ .AndReturn(self.flavors.list()) opts = {'tenant_id': tenant_id, 'all_tenants': True} api.nova.server_list(IsA(http.HttpRequest), search_opts=opts) \ .AndReturn([servers, False]) api.nova.tenant_quota_get(IsA(http.HttpRequest), tenant_id) \ .AndReturn(self.quotas.first()) opts = {'all_tenants': 1, 'project_id': tenant_id} cinder.volume_list(IsA(http.HttpRequest), opts) \ .AndReturn(self.volumes.list()) cinder.volume_snapshot_list(IsA(http.HttpRequest), opts) \ .AndReturn(self.cinder_volume_snapshots.list()) cinder.tenant_quota_get(IsA(http.HttpRequest), tenant_id) \ .AndReturn(self.cinder_quotas.first()) self.mox.ReplayAll() quota_usages = quotas.tenant_quota_usages(self.request, tenant_id=tenant_id) expected_output = self.get_usages( nova_quotas_enabled=True, with_volume=True, with_compute=True, tenant_id=tenant_id) # Compare internal structure of usages to expected. self.assertItemsEqual(expected_output, quota_usages.usages) # Compare available resources self.assertAvailableQuotasEqual(expected_output, quota_usages.usages)
def test_launch_flavorlist_error(self): cinder.volume_list(IsA(http.HttpRequest)) \ .AndReturn(self.volumes.list()) cinder.volume_snapshot_list(IsA(http.HttpRequest)) \ .AndReturn(self.volumes.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]) api.quantum.network_list(IsA(http.HttpRequest), tenant_id=self.tenant.id, shared=False) \ .AndReturn(self.networks.list()[:1]) api.quantum.network_list(IsA(http.HttpRequest), shared=True) \ .AndReturn(self.networks.list()[1:]) quotas.tenant_quota_usages(IsA(http.HttpRequest)) \ .AndReturn(self.quota_usages.first()) api.nova.flavor_list(IsA(http.HttpRequest)) \ .AndRaise(self.exceptions.nova) api.nova.flavor_list(IsA(http.HttpRequest)) \ .AndRaise(self.exceptions.nova) api.nova.keypair_list(IsA(http.HttpRequest)) \ .AndReturn(self.keypairs.list()) api.nova.security_group_list(IsA(http.HttpRequest)) \ .AndReturn(self.security_groups.list()) self.mox.ReplayAll() url = reverse('horizon:project:instances:launch') res = self.client.get(url) self.assertTemplateUsed(res, 'project/instances/launch.html')
def test_delete_volume_type(self): volume_type = self.volume_types.first() formData = {'action': 'volume_types__delete__%s' % volume_type.id} cinder.volume_list(IsA(http.HttpRequest), search_opts={ 'all_tenants': True}).AndReturn(self.volumes.list()) api.nova.server_list(IsA(http.HttpRequest), search_opts={ 'all_tenants': True}) \ .AndReturn([self.servers.list(), False]) cinder.volume_type_list(IsA(http.HttpRequest)).\ AndReturn(self.volume_types.list()) cinder.volume_type_delete(IsA(http.HttpRequest), str(volume_type.id)) keystone.tenant_list(IsA(http.HttpRequest)) \ .AndReturn([self.tenants.list(), False]) self.mox.ReplayAll() res = self.client.post(reverse('horizon:admin:volumes:index'), formData) redirect = reverse('horizon:admin:volumes:index') self.assertNoFormErrors(res) self.assertRedirectsNoFollow(res, redirect)
def test_tenant_quota_usages(self): quotas.is_service_enabled(IsA(http.HttpRequest), 'volume').AndReturn(True) api.nova.flavor_list(IsA(http.HttpRequest)) \ .AndReturn(self.flavors.list()) api.nova.tenant_quota_get(IsA(http.HttpRequest), '1') \ .AndReturn(self.quotas.first()) api.network.tenant_floating_ip_list(IsA(http.HttpRequest)) \ .AndReturn(self.floating_ips.list()) api.nova.server_list(IsA(http.HttpRequest)) \ .AndReturn([self.servers.list(), False]) cinder.volume_list(IsA(http.HttpRequest)) \ .AndReturn(self.volumes.list()) cinder.tenant_quota_get(IsA(http.HttpRequest), '1') \ .AndReturn(self.quotas.first()) self.mox.ReplayAll() quota_usages = quotas.tenant_quota_usages(self.request) expected_output = self.get_usages() # Compare internal structure of usages to expected. self.assertEquals(quota_usages.usages, expected_output)
def populate_volume_id_choices(self, request, context): try: volumes = [self._get_volume_display_name(v) for v in cinder.volume_list(self.request) if v.status == api.cinder.VOLUME_STATE_AVAILABLE] except Exception: volumes = [] exceptions.handle(self.request, _('Unable to retrieve list of volumes.')) if volumes: volumes.insert(0, ("", _("Select Volume"))) else: volumes.insert(0, ("", _("No volumes available."))) return volumes
def test_snapshots_tab(self): cinder.volume_snapshot_list_paged( IsA(http.HttpRequest), paginate=True, marker=None, sort_dir='desc', search_opts={ 'all_tenants': True }, ).AndReturn([self.cinder_volume_snapshots.list(), False, False]) cinder.volume_list(IsA(http.HttpRequest), search_opts={ 'all_tenants': True}).\ AndReturn(self.cinder_volumes.list()) keystone.tenant_list(IsA(http.HttpRequest)). \ AndReturn([self.tenants.list(), False]) self.mox.ReplayAll() res = self.client.get(reverse('horizon:admin:volumes:snapshots_tab')) self.assertEqual(res.status_code, 200) self.assertTemplateUsed(res, 'horizon/common/_detail_table.html') snapshots = res.context['volume_snapshots_table'].data self.assertItemsEqual(snapshots, self.cinder_volume_snapshots.list())
def __init__(self, request, *args, **kwargs): super(CreateSnapshotAdvanced, self).__init__(request, *args, **kwargs) instance_id = kwargs.get('initial', {}).get('instance_id', []) search_opts = {'status': 'in-use'} volumes = cinder.volume_list(self.request, search_opts) volumes = getfileteredvolume(instance_id, volumes) VOL_CHOICES = getVolumeList(volumes) #self.fields['volume_radio'] = forms.ChoiceField(widget=forms.RadioSelect(), # choices=VOL_CHOICES,label="cloud disk") self.fields['volume_select'] = forms.ChoiceField(widget=forms.Select(), choices=VOL_CHOICES, label=_("cloud disk"))
def test_create_volume_from_snapshot_invalid_size(self): usage_limit = {'maxTotalVolumeGigabytes': 100, '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': 20, '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.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, "snapshot_id=" + str(snapshot.id)]), formData, follow=True) self.assertEqual(res.redirect_chain, []) self.assertFormError( res, 'form', None, "The volume size cannot be less than the " "snapshot size (40GB)")
def get_context_data(self, **kwargs): context = super(CreateView, self).get_context_data(**kwargs) try: context['usages'] = quotas.tenant_limit_usages(self.request) _volume_types = self._get_volume_types() _volumes = cinder.volume_list(self.request) _snapshots = cinder.volume_snapshot_list(self.request) volume_types = {} volume_type_size = {} for volume_type in _volume_types: if volume_type['name'] == 'no_type': continue volume_type_size[volume_type['name']] = 0 for volume in _volumes: volume_types[volume.id] = volume.volume_type volume_type_size[volume.volume_type] = (volume_type_size.get( volume.volume_type) or 0) + volume.size for snapshot in cinder.volume_snapshot_list(self.request): volume_type_size[volume_types[snapshot.volume_id]] = ( volume_type_size.get(volume_types.get(snapshot.volume_id)) or 0) + snapshot.size tenant_quotas = {} for quota in cinder.tenant_quota_get(self.request, self.request.user.tenant_id): if quota.name.startswith('gigabytes_'): tenant_quotas[quota.name[10:]] = quota.limit volume_type_usage = [] for volume_type, total_size in volume_type_size.iteritems(): volume_type_usage.append({ 'name': volume_type, 'usage': total_size, 'quota': tenant_quotas.get(volume_type) or -1 }) context['usages']['volume_type'] = volume_type_usage context['volume_types'] = json.dumps(_volume_types) except Exception: exceptions.handle(self.request) return context
def test_create_button_disabled_when_quota_exceeded(self): quota_usages = self.quota_usages.first() quota_usages['volumes']['available'] = 0 volumes = self.volumes.list() 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.volume_snapshot_list(IsA(http.HttpRequest))\ .AndReturn(self.volume_snapshots.list()) cinder.volume_list(IsA(http.HttpRequest)).AndReturn(volumes) quotas.tenant_quota_usages(IsA(http.HttpRequest))\ .MultipleTimes().AndReturn(quota_usages) self.mox.ReplayAll() res = self.client.get(reverse('horizon:project:volumes:index')) self.assertTemplateUsed(res, 'project/volumes/index.html') volumes = res.context['volumes_table'].data self.assertItemsEqual(volumes, self.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'>%s</a>" \ % (url, link_name, " ".join(classes), link_name) self.assertContains(res, expected_string, html=True, msg_prefix="The create button is not disabled")
def test_detail_view(self): cg_snapshot = self.cinder_cg_snapshots.first() cgroup = self.cinder_consistencygroups.first() volume_type = self.cinder_volume_types.first() volumes = self.cinder_volumes.list() cinder.volume_cg_snapshot_get(IsA(http.HttpRequest), cg_snapshot.id).\ AndReturn(cg_snapshot) cinder.volume_cgroup_get(IsA(http.HttpRequest), cgroup.id).\ AndReturn(cgroup) cinder.volume_type_get(IsA(http.HttpRequest), volume_type.id).\ MultipleTimes().AndReturn(volume_type) search_opts = {'consistencygroup_id': cgroup.id} cinder.volume_list(IsA(http.HttpRequest), search_opts=search_opts).\ AndReturn(volumes) self.mox.ReplayAll() url = reverse( 'horizon:project:cg_snapshots:cg_snapshot_detail', args=[cg_snapshot.id]) res = self.client.get(url) self.assertNoFormErrors(res) self.assertEqual(res.status_code, 200)
def handle(self, request, context): cgroup_id = context['cgroup_id'] add_vols = [] remove_vols = [] try: selected_volumes = context['volumes'] volumes = cinder.volume_list(request) # scan all volumes and make correct consistency group is set for volume in volumes: selected = False for selection in selected_volumes: if selection == volume.id: selected = True break if selected: # ensure this volume is in this consistency group if hasattr(volume, 'consistencygroup_id'): if volume.consistencygroup_id != cgroup_id: add_vols.append(volume.id) else: add_vols.append(volume.id) else: # ensure this volume is not in our consistency group if hasattr(volume, 'consistencygroup_id'): if volume.consistencygroup_id == cgroup_id: # remove from this CG remove_vols.append(volume.id) add_vols_str = ",".join(add_vols) remove_vols_str = ",".join(remove_vols) if not add_vols_str and not remove_vols_str: # nothing to change return True cinder.volume_cgroup_update(request, cgroup_id, name=context['name'], add_vols=add_vols_str, remove_vols=remove_vols_str) except Exception: # error message supplied by form return False return True
def populate_volume_id_choices(self, request, context): volumes = [] try: if cinder.is_volume_service_enabled(request): available = api.cinder.VOLUME_STATE_AVAILABLE volumes = [self._get_volume_display_name(v) for v in cinder.volume_list(self.request, search_opts=dict(status=available, bootable=True))] except Exception: exceptions.handle(self.request, _('Unable to retrieve list of volumes.')) if volumes: volumes.insert(0, ("", _("Select Volume"))) else: volumes.insert(0, ("", _("No volumes available"))) return volumes
def _verify_changes(self, request, cgroup_id, add_vols, remove_vols): search_opts = {'consistencygroup_id': cgroup_id} done = False while not done: done = True volumes = cinder.volume_list(request, search_opts=search_opts) assigned_vols = [] for volume in volumes: assigned_vols.append(volume.id) for add_vol in add_vols: if add_vol not in assigned_vols: done = False for remove_vol in remove_vols: if remove_vol in assigned_vols: done = False
def populate_volume_id_choices(self, request, context): volumes = [] try: if base.is_service_enabled(request, 'volume'): volumes = [ self._get_volume_display_name(v) for v in cinder.volume_list(self.request) if (v.status == api.cinder.VOLUME_STATE_AVAILABLE and v.bootable == 'true') ] except Exception: exceptions.handle(self.request, _('Unable to retrieve list of volumes.')) if volumes: volumes.insert(0, ("", _("Select Volume"))) else: volumes.insert(0, ("", _("No volumes available"))) return volumes
def get_data(self): snapshots = [] volumes = {} needs_gs = False if cinder.is_volume_service_enabled(self.request): try: marker, sort_dir = self._get_marker() snapshots, self._has_more_data, self._has_prev_data = \ cinder.volume_snapshot_list_paged( self.request, paginate=True, marker=marker, sort_dir=sort_dir) except Exception: exceptions.handle(self.request, _("Unable to retrieve volume snapshots.")) try: volumes = cinder.volume_list(self.request) volumes = dict((v.id, v) for v in volumes) except Exception: exceptions.handle(self.request, _("Unable to retrieve volumes.")) needs_gs = any( getattr(snapshot, 'group_snapshot_id', None) for snapshot in snapshots) if needs_gs: try: group_snapshots = cinder.group_snapshot_list(self.request) group_snapshots = dict( (gs.id, gs) for gs in group_snapshots) except Exception: group_snapshots = {} exceptions.handle(self.request, _("Unable to retrieve group snapshots.")) for snapshot in snapshots: volume = volumes.get(snapshot.volume_id) setattr(snapshot, '_volume', volume) if needs_gs: group_snapshot = group_snapshots.get( snapshot.group_snapshot_id) snapshot.group_snapshot = group_snapshot else: snapshot.group_snapshot = None return snapshots