From 936eb61b66c9d0c8590698f394994385361d9a7d Mon Sep 17 00:00:00 2001 From: Tzu-Mainn Chen Date: Thu, 25 Jul 2013 00:50:07 -0400 Subject: API fix for resource class flavors * you'll want to drop and recreate the horizon database * the tuskar api expects a few specific capacity names: cpu, memory, and storage. I've renamed these capacities, but left their UI labels alone * flavors are now processed in resource_classes/workflows.py instead of the api client; the workflow sends in a flavors dict to the api * resource_classes.create passes in flavors when creating a resource class, allowing all to be created with a single api call * resource_class.update doesn't allow flavors to be updated so easily, so we delete/re-create Change-Id: I756f418a22564d9ee64929798ba173087ba65368 --- openstack_dashboard/api/tuskar.py | 109 +++++++++------------ .../infrastructure/fixtures/initial_data.json | 42 ++++---- .../resource_management/flavors/forms.py | 26 ++--- .../resource_management/flavors/tables.py | 12 +-- .../resource_management/flavors/tests.py | 12 +-- .../resource_management/flavors/views.py | 6 +- .../resource_management/resource_classes/tests.py | 41 +++----- .../resource_classes/workflows.py | 31 ++++-- .../flavors/_detail_overview.html | 30 +++--- openstack_dashboard/test/test_data/tuskar_data.py | 6 +- 10 files changed, 153 insertions(+), 162 deletions(-) diff --git a/openstack_dashboard/api/tuskar.py b/openstack_dashboard/api/tuskar.py index 964f3d61..3f09219d 100644 --- a/openstack_dashboard/api/tuskar.py +++ b/openstack_dashboard/api/tuskar.py @@ -385,11 +385,12 @@ class ResourceClass(StringIdAPIResourceWrapper): return rc @classmethod - def create(self, request, name, service_type): + def create(self, request, name, service_type, flavors): return ResourceClass( tuskarclient(request).resource_classes.create( name=name, - service_type=service_type)) + service_type=service_type, + flavors=flavors)) @classmethod def list(cls, request): @@ -398,9 +399,17 @@ class ResourceClass(StringIdAPIResourceWrapper): @classmethod def update(cls, request, resource_class_id, **kwargs): - return cls(tuskarclient(request).resource_classes.update( + resource_class = cls(tuskarclient(request).resource_classes.update( resource_class_id, **kwargs)) + ## FIXME: flavors have to be updated separately, seems less than ideal + for flavor_id in resource_class.flavors_ids: + Flavor.delete(request, resource_class.id, flavor_id) + for flavor in kwargs['flavors']: + Flavor.create(request, resource_class.id, **flavor) + + return resource_class + @classmethod def delete(cls, request, resource_class_id): tuskarclient(request).resource_classes.delete(resource_class_id) @@ -583,27 +592,6 @@ class ResourceClass(StringIdAPIResourceWrapper): self._vm_capacity = Capacity(vm_capacity) return self._vm_capacity - def set_flavors(self, request, flavors_ids, max_vms=None): - # FIXME: tuskar currently doesn't support setting flavors through - # resource class update (as it's done with set_racks), we have to - # delete/create them one by one - for fid in self.flavors_ids: - Flavor.delete(self.request, self.id, fid) - - # FIXME: for now, we just generate flavors from flavor templates - for ftemplate_id in flavors_ids: - ftemplate = FlavorTemplate.get(request, ftemplate_id) - capacities = [] - for c in ftemplate.capacities: - capacities.append({'name': c.name, - 'value': str(c.value), - 'unit': c.unit}) - # FIXME: tuskar uses resrouce-class-name prefix for flavors, - # e.g. m1.large, we add rc name to the template name: - tpl_name = "%s.%s" % (self.name, ftemplate.name) - Flavor.create(self.request, self.id, tpl_name, - max_vms.get(ftemplate.id, None), capacities) - def set_racks(self, request, racks_ids): # FIXME: there is a bug now in tuskar, we have to remove all racks at # first and then add new ones: @@ -636,15 +624,15 @@ class FlavorTemplate(StringIdAPIResourceWrapper): @classmethod def create(cls, request, - name, vcpu, ram, root_disk, ephemeral_disk, swap_disk): - flavor = dummymodels.FlavorTemplate(name=name) - flavor.save() - Capacity.create(request, flavor, 'vcpu', vcpu, '') - Capacity.create(request, flavor, 'ram', ram, 'MB') - Capacity.create(request, flavor, 'root_disk', root_disk, 'GB') + name, cpu, memory, storage, ephemeral_disk, swap_disk): + template = dummymodels.FlavorTemplate(name=name) + template.save() + Capacity.create(request, template, 'cpu', cpu, '') + Capacity.create(request, template, 'memory', memory, 'MB') + Capacity.create(request, template, 'storage', storage, 'GB') Capacity.create(request, - flavor, 'ephemeral_disk', ephemeral_disk, 'GB') - Capacity.create(request, flavor, 'swap_disk', swap_disk, 'MB') + template, 'ephemeral_disk', ephemeral_disk, 'GB') + Capacity.create(request, template, 'swap_disk', swap_disk, 'MB') @property def capacities(self): @@ -669,16 +657,16 @@ class FlavorTemplate(StringIdAPIResourceWrapper): return getattr(self, key) @property - def vcpu(self): - return self.capacity('vcpu') + def cpu(self): + return self.capacity('cpu') @property - def ram(self): - return self.capacity('ram') + def memory(self): + return self.capacity('memory') @property - def root_disk(self): - return self.capacity('root_disk') + def storage(self): + return self.capacity('storage') @property def ephemeral_disk(self): @@ -707,27 +695,28 @@ class FlavorTemplate(StringIdAPIResourceWrapper): return values @classmethod - def update(cls, request, flavor_id, name, vcpu, ram, root_disk, + def update(cls, request, template_id, name, cpu, memory, storage, ephemeral_disk, swap_disk): - f = dummymodels.FlavorTemplate.objects.get(id=flavor_id) - f.name = name - f.save() - flavor = cls(f) - Capacity.update(request, flavor.vcpu.id, flavor._apiresource, - 'vcpu', vcpu, '') - Capacity.update(request, flavor.ram.id, flavor._apiresource, + t = dummymodels.FlavorTemplate.objects.get(id=template_id) + t.name = name + t.save() + template = cls(t) + Capacity.update(request, template.cpu.id, template._apiresource, + 'cpu', cpu, '') + Capacity.update(request, template.memory.id, template._apiresource, 'ram', ram, 'MB') - Capacity.update(request, flavor.root_disk.id, flavor._apiresource, - 'root_disk', root_disk, 'GB') - Capacity.update(request, flavor.ephemeral_disk.id, flavor._apiresource, - 'ephemeral_disk', ephemeral_disk, 'GB') - Capacity.update(request, flavor.swap_disk.id, flavor._apiresource, + Capacity.update(request, template.storage.id, template._apiresource, + 'storage', storage, 'GB') + Capacity.update(request, template.ephemeral_disk.id, + template._apiresource, 'ephemeral_disk', + ephemeral_disk, 'GB') + Capacity.update(request, template.swap_disk.id, template._apiresource, 'swap_disk', swap_disk, 'MB') - return flavor + return template @classmethod - def delete(cls, request, flavor_id): - dummymodels.FlavorTemplate.objects.get(id=flavor_id).delete() + def delete(cls, request, template_id): + dummymodels.FlavorTemplate.objects.get(id=template_id).delete() class Flavor(StringIdAPIResourceWrapper): @@ -784,16 +773,16 @@ class Flavor(StringIdAPIResourceWrapper): return getattr(self, key) @property - def vcpu(self): - return self.capacity('vcpu') + def cpu(self): + return self.capacity('cpu') @property - def ram(self): - return self.capacity('ram') + def memory(self): + return self.capacity('memory') @property - def root_disk(self): - return self.capacity('root_disk') + def storage(self): + return self.capacity('storage') @property def ephemeral_disk(self): diff --git a/openstack_dashboard/dashboards/infrastructure/fixtures/initial_data.json b/openstack_dashboard/dashboards/infrastructure/fixtures/initial_data.json index 627e676c..870f3dc5 100644 --- a/openstack_dashboard/dashboards/infrastructure/fixtures/initial_data.json +++ b/openstack_dashboard/dashboards/infrastructure/fixtures/initial_data.json @@ -47,45 +47,45 @@ {"pk": 19, "model": "infrastructure.capacity", "fields": {"value": 90, "unit": "Gbps", "object_id": 4, "content_type": ["infrastructure", "node"], "name": "network"}}, {"pk": 20, "model": "infrastructure.capacity", "fields": {"value": 90, "unit": "Gbps", "object_id": 5, "content_type": ["infrastructure", "node"], "name": "network"}}, - {"pk": 21, "model": "infrastructure.capacity", "fields": {"value": 1, "unit": "", "object_id": 1, "content_type": ["infrastructure", "flavortemplate"], "name": "vcpu"}}, - {"pk": 22, "model": "infrastructure.capacity", "fields": {"value": 64, "unit": "MB", "object_id": 1, "content_type": ["infrastructure", "flavortemplate"], "name": "ram"}}, - {"pk": 23, "model": "infrastructure.capacity", "fields": {"value": 0, "unit": "GB", "object_id": 1, "content_type": ["infrastructure", "flavortemplate"], "name": "root_disk"}}, + {"pk": 21, "model": "infrastructure.capacity", "fields": {"value": 1, "unit": "", "object_id": 1, "content_type": ["infrastructure", "flavortemplate"], "name": "cpu"}}, + {"pk": 22, "model": "infrastructure.capacity", "fields": {"value": 64, "unit": "MB", "object_id": 1, "content_type": ["infrastructure", "flavortemplate"], "name": "memory"}}, + {"pk": 23, "model": "infrastructure.capacity", "fields": {"value": 0, "unit": "GB", "object_id": 1, "content_type": ["infrastructure", "flavortemplate"], "name": "storage"}}, {"pk": 24, "model": "infrastructure.capacity", "fields": {"value": 0, "unit": "GB", "object_id": 1, "content_type": ["infrastructure", "flavortemplate"], "name": "ephemeral_disk"}}, {"pk": 25, "model": "infrastructure.capacity", "fields": {"value": 0, "unit": "MB", "object_id": 1, "content_type": ["infrastructure", "flavortemplate"], "name": "swap_disk"}}, - {"pk": 26, "model": "infrastructure.capacity", "fields": {"value": 1, "unit": "", "object_id": 2, "content_type": ["infrastructure", "flavortemplate"], "name": "vcpu"}}, - {"pk": 27, "model": "infrastructure.capacity", "fields": {"value": 128, "unit": "MB", "object_id": 2, "content_type": ["infrastructure", "flavortemplate"], "name": "ram"}}, - {"pk": 28, "model": "infrastructure.capacity", "fields": {"value": 0, "unit": "GB", "object_id": 2, "content_type": ["infrastructure", "flavortemplate"], "name": "root_disk"}}, + {"pk": 26, "model": "infrastructure.capacity", "fields": {"value": 1, "unit": "", "object_id": 2, "content_type": ["infrastructure", "flavortemplate"], "name": "cpu"}}, + {"pk": 27, "model": "infrastructure.capacity", "fields": {"value": 128, "unit": "MB", "object_id": 2, "content_type": ["infrastructure", "flavortemplate"], "name": "memory"}}, + {"pk": 28, "model": "infrastructure.capacity", "fields": {"value": 0, "unit": "GB", "object_id": 2, "content_type": ["infrastructure", "flavortemplate"], "name": "storage"}}, {"pk": 29, "model": "infrastructure.capacity", "fields": {"value": 0, "unit": "GB", "object_id": 2, "content_type": ["infrastructure", "flavortemplate"], "name": "ephemeral_disk"}}, {"pk": 30, "model": "infrastructure.capacity", "fields": {"value": 0, "unit": "MB", "object_id": 2, "content_type": ["infrastructure", "flavortemplate"], "name": "swap_disk"}}, - {"pk": 31, "model": "infrastructure.capacity", "fields": {"value": 1, "unit": "", "object_id": 3, "content_type": ["infrastructure", "flavortemplate"], "name": "vcpu"}}, - {"pk": 32, "model": "infrastructure.capacity", "fields": {"value": 512, "unit": "MB", "object_id": 3, "content_type": ["infrastructure", "flavortemplate"], "name": "ram"}}, - {"pk": 33, "model": "infrastructure.capacity", "fields": {"value": 1, "unit": "GB", "object_id": 3, "content_type": ["infrastructure", "flavortemplate"], "name": "root_disk"}}, + {"pk": 31, "model": "infrastructure.capacity", "fields": {"value": 1, "unit": "", "object_id": 3, "content_type": ["infrastructure", "flavortemplate"], "name": "cpu"}}, + {"pk": 32, "model": "infrastructure.capacity", "fields": {"value": 512, "unit": "MB", "object_id": 3, "content_type": ["infrastructure", "flavortemplate"], "name": "memory"}}, + {"pk": 33, "model": "infrastructure.capacity", "fields": {"value": 1, "unit": "GB", "object_id": 3, "content_type": ["infrastructure", "flavortemplate"], "name": "storage"}}, {"pk": 34, "model": "infrastructure.capacity", "fields": {"value": 0, "unit": "GB", "object_id": 3, "content_type": ["infrastructure", "flavortemplate"], "name": "ephemeral_disk"}}, {"pk": 35, "model": "infrastructure.capacity", "fields": {"value": 0, "unit": "MB", "object_id": 3, "content_type": ["infrastructure", "flavortemplate"], "name": "swap_disk"}}, - {"pk": 36, "model": "infrastructure.capacity", "fields": {"value": 1, "unit": "", "object_id": 4, "content_type": ["infrastructure", "flavortemplate"], "name": "vcpu"}}, - {"pk": 37, "model": "infrastructure.capacity", "fields": {"value": 2048, "unit": "MB", "object_id": 4, "content_type": ["infrastructure", "flavortemplate"], "name": "ram"}}, - {"pk": 38, "model": "infrastructure.capacity", "fields": {"value": 20, "unit": "GB", "object_id": 4, "content_type": ["infrastructure", "flavortemplate"], "name": "root_disk"}}, + {"pk": 36, "model": "infrastructure.capacity", "fields": {"value": 1, "unit": "", "object_id": 4, "content_type": ["infrastructure", "flavortemplate"], "name": "cpu"}}, + {"pk": 37, "model": "infrastructure.capacity", "fields": {"value": 2048, "unit": "MB", "object_id": 4, "content_type": ["infrastructure", "flavortemplate"], "name": "memory"}}, + {"pk": 38, "model": "infrastructure.capacity", "fields": {"value": 20, "unit": "GB", "object_id": 4, "content_type": ["infrastructure", "flavortemplate"], "name": "storage"}}, {"pk": 39, "model": "infrastructure.capacity", "fields": {"value": 0, "unit": "GB", "object_id": 4, "content_type": ["infrastructure", "flavortemplate"], "name": "ephemeral_disk"}}, {"pk": 40, "model": "infrastructure.capacity", "fields": {"value": 0, "unit": "MB", "object_id": 4, "content_type": ["infrastructure", "flavortemplate"], "name": "swap_disk"}}, - {"pk": 41, "model": "infrastructure.capacity", "fields": {"value": 2, "unit": "", "object_id": 5, "content_type": ["infrastructure", "flavortemplate"], "name": "vcpu"}}, - {"pk": 42, "model": "infrastructure.capacity", "fields": {"value": 4096, "unit": "MB", "object_id": 5, "content_type": ["infrastructure", "flavortemplate"], "name": "ram"}}, - {"pk": 43, "model": "infrastructure.capacity", "fields": {"value": 40, "unit": "GB", "object_id": 5, "content_type": ["infrastructure", "flavortemplate"], "name": "root_disk"}}, + {"pk": 41, "model": "infrastructure.capacity", "fields": {"value": 2, "unit": "", "object_id": 5, "content_type": ["infrastructure", "flavortemplate"], "name": "cpu"}}, + {"pk": 42, "model": "infrastructure.capacity", "fields": {"value": 4096, "unit": "MB", "object_id": 5, "content_type": ["infrastructure", "flavortemplate"], "name": "memory"}}, + {"pk": 43, "model": "infrastructure.capacity", "fields": {"value": 40, "unit": "GB", "object_id": 5, "content_type": ["infrastructure", "flavortemplate"], "name": "storage"}}, {"pk": 44, "model": "infrastructure.capacity", "fields": {"value": 0, "unit": "GB", "object_id": 5, "content_type": ["infrastructure", "flavortemplate"], "name": "ephemeral_disk"}}, {"pk": 45, "model": "infrastructure.capacity", "fields": {"value": 0, "unit": "MB", "object_id": 5, "content_type": ["infrastructure", "flavortemplate"], "name": "swap_disk"}}, - {"pk": 46, "model": "infrastructure.capacity", "fields": {"value": 4, "unit": "", "object_id": 6, "content_type": ["infrastructure", "flavortemplate"], "name": "vcpu"}}, - {"pk": 47, "model": "infrastructure.capacity", "fields": {"value": 8192, "unit": "MB", "object_id": 6, "content_type": ["infrastructure", "flavortemplate"], "name": "ram"}}, - {"pk": 48, "model": "infrastructure.capacity", "fields": {"value": 80, "unit": "GB", "object_id": 6, "content_type": ["infrastructure", "flavortemplate"], "name": "root_disk"}}, + {"pk": 46, "model": "infrastructure.capacity", "fields": {"value": 4, "unit": "", "object_id": 6, "content_type": ["infrastructure", "flavortemplate"], "name": "cpu"}}, + {"pk": 47, "model": "infrastructure.capacity", "fields": {"value": 8192, "unit": "MB", "object_id": 6, "content_type": ["infrastructure", "flavortemplate"], "name": "memory"}}, + {"pk": 48, "model": "infrastructure.capacity", "fields": {"value": 80, "unit": "GB", "object_id": 6, "content_type": ["infrastructure", "flavortemplate"], "name": "storage"}}, {"pk": 49, "model": "infrastructure.capacity", "fields": {"value": 0, "unit": "GB", "object_id": 6, "content_type": ["infrastructure", "flavortemplate"], "name": "ephemeral_disk"}}, {"pk": 50, "model": "infrastructure.capacity", "fields": {"value": 0, "unit": "MB", "object_id": 6, "content_type": ["infrastructure", "flavortemplate"], "name": "swap_disk"}}, - {"pk": 51, "model": "infrastructure.capacity", "fields": {"value": 8, "unit": "", "object_id": 7, "content_type": ["infrastructure", "flavortemplate"], "name": "vcpu"}}, - {"pk": 52, "model": "infrastructure.capacity", "fields": {"value": 16384, "unit": "MB", "object_id": 7, "content_type": ["infrastructure", "flavortemplate"], "name": "ram"}}, - {"pk": 53, "model": "infrastructure.capacity", "fields": {"value": 160, "unit": "GB", "object_id": 7, "content_type": ["infrastructure", "flavortemplate"], "name": "root_disk"}}, + {"pk": 51, "model": "infrastructure.capacity", "fields": {"value": 8, "unit": "", "object_id": 7, "content_type": ["infrastructure", "flavortemplate"], "name": "cpu"}}, + {"pk": 52, "model": "infrastructure.capacity", "fields": {"value": 16384, "unit": "MB", "object_id": 7, "content_type": ["infrastructure", "flavortemplate"], "name": "memory"}}, + {"pk": 53, "model": "infrastructure.capacity", "fields": {"value": 160, "unit": "GB", "object_id": 7, "content_type": ["infrastructure", "flavortemplate"], "name": "storage"}}, {"pk": 54, "model": "infrastructure.capacity", "fields": {"value": 0, "unit": "GB", "object_id": 7, "content_type": ["infrastructure", "flavortemplate"], "name": "ephemeral_disk"}}, {"pk": 55, "model": "infrastructure.capacity", "fields": {"value": 0, "unit": "MB", "object_id": 7, "content_type": ["infrastructure", "flavortemplate"], "name": "swap_disk"}} ] diff --git a/openstack_dashboard/dashboards/infrastructure/resource_management/flavors/forms.py b/openstack_dashboard/dashboards/infrastructure/resource_management/flavors/forms.py index aed17d17..ef84a261 100644 --- a/openstack_dashboard/dashboards/infrastructure/resource_management/flavors/forms.py +++ b/openstack_dashboard/dashboards/infrastructure/resource_management/flavors/forms.py @@ -32,15 +32,15 @@ class CreateFlavor(forms.SelfHandlingForm): error_messages={'invalid': _('Name may only ' 'contain letters, numbers, underscores, ' 'periods and hyphens.')}) - vcpu = forms.IntegerField(label=_("VCPU"), - min_value=0, - initial=0) - ram = forms.IntegerField(label=_("RAM (MB)"), + cpu = forms.IntegerField(label=_("VCPU"), min_value=0, initial=0) - root_disk = forms.IntegerField(label=_("Root Disk (GB)"), - min_value=0, - initial=0) + memory = forms.IntegerField(label=_("RAM (MB)"), + min_value=0, + initial=0) + storage = forms.IntegerField(label=_("Root Disk (GB)"), + min_value=0, + initial=0) ephemeral_disk = forms.IntegerField(label=_("Ephemeral Disk (GB)"), min_value=0, initial=0) @@ -73,9 +73,9 @@ class CreateFlavor(forms.SelfHandlingForm): flavor = api.tuskar.FlavorTemplate.create( request, data['name'], - data['vcpu'], - data['ram'], - data['root_disk'], + data['cpu'], + data['memory'], + data['storage'], data['ephemeral_disk'], data['swap_disk'] ) @@ -94,9 +94,9 @@ class EditFlavor(CreateFlavor): self.request, self.initial['flavor_id'], data['name'], - data['vcpu'], - data['ram'], - data['root_disk'], + data['cpu'], + data['memory'], + data['storage'], data['ephemeral_disk'], data['swap_disk'] ) diff --git a/openstack_dashboard/dashboards/infrastructure/resource_management/flavors/tables.py b/openstack_dashboard/dashboards/infrastructure/resource_management/flavors/tables.py index 973074a6..bbf48c3c 100644 --- a/openstack_dashboard/dashboards/infrastructure/resource_management/flavors/tables.py +++ b/openstack_dashboard/dashboards/infrastructure/resource_management/flavors/tables.py @@ -61,18 +61,18 @@ class FlavorsTable(tables.DataTable): link=("horizon:infrastructure:" "resource_management:flavors:detail"), verbose_name=_('Flavor Name')) - vcpu = tables.Column( - "vcpu", + cpu = tables.Column( + "cpu", verbose_name=_('VCPU'), filters=(lambda x: getattr(x, 'value', ''),) ) - ram = tables.Column( - "ram", + memory = tables.Column( + "memory", verbose_name=_('RAM (MB)'), filters=(lambda x: getattr(x, 'value', ''),) ) - root_disk = tables.Column( - "root_disk", + storage = tables.Column( + "storage", verbose_name=_('Root Disk (GB)'), filters=(lambda x: getattr(x, 'value', ''),) ) diff --git a/openstack_dashboard/dashboards/infrastructure/resource_management/flavors/tests.py b/openstack_dashboard/dashboards/infrastructure/resource_management/flavors/tests.py index 9ad4b1e2..fbedce8f 100644 --- a/openstack_dashboard/dashboards/infrastructure/resource_management/flavors/tests.py +++ b/openstack_dashboard/dashboards/infrastructure/resource_management/flavors/tests.py @@ -27,9 +27,9 @@ class FlavorTemplatesTests(test.BaseAdminViewTests): resp, "infrastructure/resource_management/flavors/create.html") data = {'name': template.name, - 'vcpu': 0, - 'ram': 0, - 'root_disk': 0, + 'cpu': 0, + 'memory': 0, + 'storage': 0, 'ephemeral_disk': 0, 'swap_disk': 0} resp = self.client.post(url, data) @@ -68,9 +68,9 @@ class FlavorTemplatesTests(test.BaseAdminViewTests): data = {'flavor_id': template.id, 'name': template.name, - 'vcpu': 0, - 'ram': 0, - 'root_disk': 0, + 'cpu': 0, + 'memory': 0, + 'storage': 0, 'ephemeral_disk': 0, 'swap_disk': 0} url = reverse( diff --git a/openstack_dashboard/dashboards/infrastructure/resource_management/flavors/views.py b/openstack_dashboard/dashboards/infrastructure/resource_management/flavors/views.py index 3b9e3436..77c86c71 100644 --- a/openstack_dashboard/dashboards/infrastructure/resource_management/flavors/views.py +++ b/openstack_dashboard/dashboards/infrastructure/resource_management/flavors/views.py @@ -64,9 +64,9 @@ class EditView(forms.ModalFormView): _("Unable to retrieve flavor data.")) return {'flavor_id': flavor.id, 'name': flavor.name, - 'vcpu': flavor.vcpu.value, - 'ram': flavor.ram.value, - 'root_disk': flavor.root_disk.value, + 'cpu': flavor.cpu.value, + 'memory': flavor.memory.value, + 'storage': flavor.storage.value, 'ephemeral_disk': flavor.ephemeral_disk.value, 'swap_disk': flavor.swap_disk.value} diff --git a/openstack_dashboard/dashboards/infrastructure/resource_management/resource_classes/tests.py b/openstack_dashboard/dashboards/infrastructure/resource_management/resource_classes/tests.py index 3679a3fd..67ec51f6 100644 --- a/openstack_dashboard/dashboards/infrastructure/resource_management/resource_classes/tests.py +++ b/openstack_dashboard/dashboards/infrastructure/resource_management/resource_classes/tests.py @@ -42,15 +42,13 @@ class ResourceClassViewTests(test.BaseAdminViewTests): self.assertEqual(res.status_code, 200) @test.create_stubs({ - api.tuskar.ResourceClass: ('list', 'create', - 'set_flavors', 'set_racks'), + api.tuskar.ResourceClass: ('list', 'create', 'set_racks'), }) def test_create_resource_class_post(self): new_resource_class = self.tuskar_resource_classes.first() new_unique_name = "unique_name_for_sure" + new_flavors = [] - add_flavors_ids = [] - add_max_vms = {} add_racks_ids = [] api.tuskar.ResourceClass.list( @@ -58,12 +56,11 @@ class ResourceClassViewTests(test.BaseAdminViewTests): self.tuskar_resource_classes.list()) api.tuskar.ResourceClass.\ create(IsA(http.HttpRequest), name=new_unique_name, - service_type=new_resource_class.service_type).\ + service_type=new_resource_class.service_type, + flavors=new_flavors).\ AndReturn(new_resource_class) api.tuskar.ResourceClass.\ set_racks(IsA(http.HttpRequest), add_racks_ids) - api.tuskar.ResourceClass.\ - set_flavors(IsA(http.HttpRequest), add_flavors_ids, add_max_vms) self.mox.ReplayAll() url = reverse('horizon:infrastructure:resource_management:' @@ -106,14 +103,11 @@ class ResourceClassViewTests(test.BaseAdminViewTests): self.assertEqual(res.status_code, 200) @test.create_stubs({ - api.tuskar.ResourceClass: ('get', 'list', 'update', 'set_racks', - 'set_flavors') + api.tuskar.ResourceClass: ('get', 'list', 'update', 'set_racks') }) def test_edit_resource_class_post(self): resource_class = self.tuskar_resource_classes.first() - add_flavors_ids = [] - add_max_vms = {} add_racks_ids = [] api.tuskar.ResourceClass.get( @@ -126,12 +120,11 @@ class ResourceClassViewTests(test.BaseAdminViewTests): api.tuskar.ResourceClass.\ update(IsA(http.HttpRequest), resource_class.id, name=resource_class.name, - service_type=resource_class.service_type).\ + service_type=resource_class.service_type, + flavors=[]).\ AndReturn(resource_class) api.tuskar.ResourceClass.\ set_racks(IsA(http.HttpRequest), add_racks_ids) - api.tuskar.ResourceClass.\ - set_flavors(IsA(http.HttpRequest), add_flavors_ids, add_max_vms) self.mox.ReplayAll() form_data = {'resource_class_id': resource_class.id, @@ -223,14 +216,11 @@ class ResourceClassViewTests(test.BaseAdminViewTests): self.assertEqual(res.status_code, 200) @test.create_stubs({ - api.tuskar.ResourceClass: ('get', 'list', 'update', 'set_racks', - 'set_flavors') + api.tuskar.ResourceClass: ('get', 'list', 'update', 'set_racks') }) def test_detail_edit_racks_post(self): resource_class = self.tuskar_resource_classes.first() - add_flavors_ids = [] - add_max_vms = {} add_racks_ids = [] api.tuskar.ResourceClass.get( @@ -243,12 +233,11 @@ class ResourceClassViewTests(test.BaseAdminViewTests): api.tuskar.ResourceClass.\ update(IsA(http.HttpRequest), resource_class.id, name=resource_class.name, - service_type=resource_class.service_type).\ + service_type=resource_class.service_type, + flavors=[]).\ AndReturn(resource_class) api.tuskar.ResourceClass.\ set_racks(IsA(http.HttpRequest), add_racks_ids) - api.tuskar.ResourceClass.\ - set_flavors(IsA(http.HttpRequest), add_flavors_ids, add_max_vms) self.mox.ReplayAll() form_data = {'resource_class_id': resource_class.id, @@ -295,14 +284,11 @@ class ResourceClassViewTests(test.BaseAdminViewTests): self.assertEqual(res.status_code, 200) @test.create_stubs({ - api.tuskar.ResourceClass: ('get', 'list', 'update', 'set_racks', - 'set_flavors') + api.tuskar.ResourceClass: ('get', 'list', 'update', 'set_racks') }) def test_detail_edit_flavors_post(self): resource_class = self.tuskar_resource_classes.first() - add_flavors_ids = [] - add_max_vms = {} add_racks_ids = [] api.tuskar.ResourceClass.get( @@ -315,12 +301,11 @@ class ResourceClassViewTests(test.BaseAdminViewTests): api.tuskar.ResourceClass.\ update(IsA(http.HttpRequest), resource_class.id, name=resource_class.name, - service_type=resource_class.service_type).\ + service_type=resource_class.service_type, + flavors=[]).\ AndReturn(resource_class) api.tuskar.ResourceClass.\ set_racks(IsA(http.HttpRequest), add_racks_ids) - api.tuskar.ResourceClass.\ - set_flavors(IsA(http.HttpRequest), add_flavors_ids, add_max_vms) self.mox.ReplayAll() form_data = {'resource_class_id': resource_class.id, diff --git a/openstack_dashboard/dashboards/infrastructure/resource_management/resource_classes/workflows.py b/openstack_dashboard/dashboards/infrastructure/resource_management/resource_classes/workflows.py index 87c920a5..700d47bb 100644 --- a/openstack_dashboard/dashboards/infrastructure/resource_management/resource_classes/workflows.py +++ b/openstack_dashboard/dashboards/infrastructure/resource_management/resource_classes/workflows.py @@ -197,10 +197,25 @@ class ResourceClassWorkflowMixin: name = self.context.get('name') return message % name - def _add_flavors(self, request, data, resource_class): - ids_to_add = data.get('flavors_object_ids') or [] + def _get_flavors(self, request, data): + flavors = [] + flavor_ids = data.get('flavors_object_ids') or [] max_vms = data.get('max_vms') - resource_class.set_flavors(request, ids_to_add, max_vms) + resource_class_name = data['name'] + for template_id in flavor_ids: + template = api.tuskar.FlavorTemplate.get(request, template_id) + capacities = [] + for c in template.capacities: + capacities.append({'name': c.name, + 'value': str(c.value), + 'unit': c.unit}) + # FIXME: tuskar uses resource-class-name prefix for flavors, + # e.g. m1.large, we add rc name to the template name: + flavor_name = "%s.%s" % (resource_class_name, template.name) + flavors.append({'name': flavor_name, + 'max_vms': max_vms.get(template.id, None), + 'capacities': capacities}) + return flavors def _add_racks(self, request, data, resource_class): ids_to_add = data.get('racks_object_ids') or [] @@ -219,10 +234,12 @@ class CreateResourceClass(ResourceClassWorkflowMixin, workflows.Workflow): def _create_resource_class_info(self, request, data): try: + flavors = self._get_flavors(request, data) return api.tuskar.ResourceClass.create( request, name=data['name'], - service_type=data['service_type']) + service_type=data['service_type'], + flavors=flavors) except: redirect = self.get_failure_url() exceptions.handle(request, @@ -233,7 +250,6 @@ class CreateResourceClass(ResourceClassWorkflowMixin, workflows.Workflow): def handle(self, request, data): resource_class = self._create_resource_class_info(request, data) self._add_racks(request, data, resource_class) - self._add_flavors(request, data, resource_class) return True @@ -257,11 +273,13 @@ class UpdateResourceClass(ResourceClassWorkflowMixin, workflows.Workflow): def _update_resource_class_info(self, request, data): try: + flavors = self._get_flavors(request, data) return api.tuskar.ResourceClass.update( request, data['resource_class_id'], name=data['name'], - service_type=data['service_type']) + service_type=data['service_type'], + flavors=flavors) except: redirect = self.get_failure_url() exceptions.handle(request, @@ -272,7 +290,6 @@ class UpdateResourceClass(ResourceClassWorkflowMixin, workflows.Workflow): def handle(self, request, data): resource_class = self._update_resource_class_info(request, data) self._add_racks(request, data, resource_class) - self._add_flavors(request, data, resource_class) return True diff --git a/openstack_dashboard/dashboards/infrastructure/resource_management/templates/resource_management/flavors/_detail_overview.html b/openstack_dashboard/dashboards/infrastructure/resource_management/templates/resource_management/flavors/_detail_overview.html index fd31a776..0b676742 100644 --- a/openstack_dashboard/dashboards/infrastructure/resource_management/templates/resource_management/flavors/_detail_overview.html +++ b/openstack_dashboard/dashboards/infrastructure/resource_management/templates/resource_management/flavors/_detail_overview.html @@ -24,11 +24,11 @@
{% trans "VCPU" %}
-
{{ flavor.vcpu.value }}
+
{{ flavor.cpu.value }}
{% trans "RAM" %}
-
{{ flavor.ram.value }} {{ flavor.ram.unit }}
+
{{ flavor.memory.value }} {{ flavor.memory.unit }}
{% trans "Root Disk" %}
-
{{ flavor.root_disk.value }} {{ flavor.root_disk.unit }}
+
{{ flavor.storage.value }} {{ flavor.storage.unit }}
{% trans "Ephemeral Disk" %}
{{ flavor.ephemeral_disk.value }} {{ flavor.ephemeral_disk.unit }}
{% trans "Swap Disk" %}
@@ -46,13 +46,13 @@
+ data-capacity-limit="{{ flavor.cpu.value }}" + data-capacity-used="{{ flavor.cpu.usage }}" + data-average-capacity-used="{{ flavor.cpu.average }}">
- {{ flavor.vcpu.usage }}/{{ flavor.vcpu.value }} {{ flavor.vcpu.unit }} + {{ flavor.cpu.usage }}/{{ flavor.cpu.value }} {{ flavor.cpu.unit }} @@ -61,13 +61,13 @@
+ data-capacity-limit="{{ flavor.memory.value }}" + data-capacity-used="{{ flavor.memory.usage }}" + data-average-capacity-used="{{ flavor.memory.average }}">
- {{ flavor.ram.usage }}/{{ flavor.ram.value }} {{ flavor.ram.unit }} + {{ flavor.memory.usage }}/{{ flavor.memory.value }} {{ flavor.memory.unit }} @@ -76,13 +76,13 @@
+ data-capacity-limit="{{ flavor.storage.value }}" + data-capacity-used="{{ flavor.storage.usage }}" + data-average-capacity-used="{{ flavor.storage.average }}">
- {{ flavor.root_disk.usage }}/{{ flavor.root_disk.value }} {{ flavor.root_disk.unit }} + {{ flavor.storage.usage }}/{{ flavor.storage.value }} {{ flavor.storage.unit }} diff --git a/openstack_dashboard/test/test_data/tuskar_data.py b/openstack_dashboard/test/test_data/tuskar_data.py index 936a2081..6615ee88 100644 --- a/openstack_dashboard/test/test_data/tuskar_data.py +++ b/openstack_dashboard/test/test_data/tuskar_data.py @@ -30,15 +30,15 @@ def data(TEST): name='m1.tiny', capacities=[ Capacity(CapacityStruct( - name='vcpu', + name='cpu', unit='', value='1')), Capacity(CapacityStruct( - name='ram', + name='memory', unit='MB', value='64')), Capacity(CapacityStruct( - name='root_disk', + name='storage', unit='MB', value='128')), Capacity(CapacityStruct( -- cgit v1.2.1