diff --git a/horizon/dashboards/syspanel/instances/tables.py b/horizon/dashboards/syspanel/instances/tables.py index e0584c2e4..5550dc37a 100644 --- a/horizon/dashboards/syspanel/instances/tables.py +++ b/horizon/dashboards/syspanel/instances/tables.py @@ -59,7 +59,7 @@ class SyspanelInstancesTable(tables.DataTable): TASK_DISPLAY_CHOICES = ( ("image_snapshot", "Snapshotting"), ) - tenant = tables.Column("tenant_name", verbose_name=_("Tenant")) + tenant = tables.Column("tenant_name", verbose_name=_("Project Name")) # NOTE(gabriel): Commenting out the user column because all we have # is an ID, and correlating that at production scale using our current # techniques isn't practical. It can be added back in when we have names diff --git a/horizon/dashboards/syspanel/overview/tests.py b/horizon/dashboards/syspanel/overview/tests.py new file mode 100644 index 000000000..b6131cd66 --- /dev/null +++ b/horizon/dashboards/syspanel/overview/tests.py @@ -0,0 +1,92 @@ +# vim: tabstop=4 shiftwidth=4 softtabstop=4 + +# Copyright 2012 United States Government as represented by the +# Administrator of the National Aeronautics and Space Administration. +# All Rights Reserved. +# +# Copyright 2012 Nebula, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +import datetime + +from django import http +from django.core.urlresolvers import reverse +from mox import IsA + +from horizon import api +from horizon import test +from horizon import usage +from horizon.templatetags.sizeformat import mbformat + + +INDEX_URL = reverse('horizon:nova:overview:index') + + +class UsageViewTests(test.BaseAdminViewTests): + def tearDown(self): + super(UsageViewTests, self).tearDown() + self.reset_times() # override_times is called in the tests + + @test.create_stubs({api: ('usage_list',), + api.keystone: ('tenant_list',)}) + def test_usage(self): + now = self.override_times() + usage_obj = api.nova.Usage(self.usages.first()) + api.keystone.tenant_list(IsA(http.HttpRequest), admin=True) \ + .AndReturn(self.tenants.list()) + api.usage_list(IsA(http.HttpRequest), + datetime.datetime(now.year, now.month, 1, + now.hour, now.minute, now.second), + datetime.datetime(now.year, now.month, now.day, now.hour, + now.minute, now.second)) \ + .AndReturn([usage_obj]) + self.mox.ReplayAll() + res = self.client.get(reverse('horizon:syspanel:overview:index')) + self.assertTemplateUsed(res, 'syspanel/overview/usage.html') + self.assertTrue(isinstance(res.context['usage'], usage.GlobalUsage)) + self.assertContains(res, 'test_tenant' + '%s%s' + '%s%.2f' + '%.2f' % + (usage_obj.vcpus, + usage_obj.disk_gb_hours, + mbformat(usage_obj.memory_mb), + usage_obj.vcpu_hours, + usage_obj.total_local_gb_usage)) + + @test.create_stubs({api: ('usage_list',), + api.keystone: ('tenant_list',)}) + def test_usage_csv(self): + now = self.override_times() + usage_obj = api.nova.Usage(self.usages.first()) + api.keystone.tenant_list(IsA(http.HttpRequest), admin=True) \ + .AndReturn(self.tenants.list()) + api.usage_list(IsA(http.HttpRequest), + datetime.datetime(now.year, now.month, 1, + now.hour, now.minute, now.second), + datetime.datetime(now.year, now.month, now.day, now.hour, + now.minute, now.second)) \ + .AndReturn([usage_obj]) + self.mox.ReplayAll() + csv_url = reverse('horizon:syspanel:overview:index') + "?format=csv" + res = self.client.get(csv_url) + self.assertTemplateUsed(res, 'syspanel/overview/usage.csv') + self.assertTrue(isinstance(res.context['usage'], usage.GlobalUsage)) + self.assertContains(res, 'Tenant,VCPUs,RamMB,DiskGB,Usage(Hours)\n' + '%s,%s,%s,%s,%f' % + (usage_obj.tenant_id, + usage_obj.vcpus, + usage_obj.memory_mb, + usage_obj.disk_gb_hours, + usage_obj.vcpu_hours)) diff --git a/horizon/dashboards/syspanel/overview/views.py b/horizon/dashboards/syspanel/overview/views.py index 92f38d99e..0d25578eb 100644 --- a/horizon/dashboards/syspanel/overview/views.py +++ b/horizon/dashboards/syspanel/overview/views.py @@ -20,6 +20,7 @@ from django.conf import settings +from horizon import api from horizon import usage @@ -32,3 +33,16 @@ class GlobalOverview(usage.UsageView): context = super(GlobalOverview, self).get_context_data(**kwargs) context['monitoring'] = getattr(settings, 'EXTERNAL_MONITORING', []) return context + + def get_data(self): + data = super(GlobalOverview, self).get_data() + # Pre-fill tenant names + tenants = api.keystone.tenant_list(self.request, + admin=True) + for instance in data: + tenant = filter(lambda t: t.id == instance.tenant_id, tenants) + if tenant: + instance.tenant_name = getattr(tenant[0], "name", None) + else: + instance.tenant_name = None + return data diff --git a/horizon/usage/tables.py b/horizon/usage/tables.py index 02dff1182..2cd38f48a 100644 --- a/horizon/usage/tables.py +++ b/horizon/usage/tables.py @@ -25,7 +25,7 @@ class BaseUsageTable(tables.DataTable): class GlobalUsageTable(BaseUsageTable): - tenant = tables.Column('tenant_id', verbose_name=_("Project ID")) + tenant = tables.Column('tenant_name', verbose_name=_("Project Name")) disk_hours = tables.Column('disk_gb_hours', verbose_name=_("Disk GB Hours"), filters=(lambda v: floatformat(v, 2),))