diff options
author | Matt Wagner <matt.wagner@redhat.com> | 2013-06-19 14:28:39 -0400 |
---|---|---|
committer | Tomas Sedovic <tomas@sedovic.cz> | 2013-08-01 16:18:55 +0200 |
commit | 5b7a349c21ff3d6592749041c96a5e35efb18a91 (patch) | |
tree | 8f3df2142377818fbfb9cdc6d9707a7318971702 | |
parent | 30ef02b3f292e19d879959d2eb272cf99b4083bb (diff) | |
download | tuskar-ui-5b7a349c21ff3d6592749041c96a5e35efb18a91.tar.gz |
Missing attributes added to Racks
Adds Location and IP/subnet attributes; updates create
and edit forms, index table, tests to use.
Also implements Rack.update method.
Change-Id: I42b576f9868d8d64a4feec1dcebeb40a35cd4db6
7 files changed, 78 insertions, 15 deletions
diff --git a/openstack_dashboard/api/management.py b/openstack_dashboard/api/management.py index 245ceabe..a5be3d83 100644 --- a/openstack_dashboard/api/management.py +++ b/openstack_dashboard/api/management.py @@ -89,12 +89,13 @@ class Rack(StringIdAPIResourceWrapper): """Wrapper for the Rack object returned by the dummy model. """ - _attrs = ['name', 'resource_class_id'] + _attrs = ['name', 'resource_class_id', 'location', 'subnet'] @classmethod - def create(cls, request, name, resource_class_id): + def create(cls, request, name, resource_class_id, location, subnet): rack = dummymodels.Rack(name=name, - resource_class_id=resource_class_id) + resource_class_id=resource_class_id, + location=location, subnet=subnet) rack.save() @classmethod @@ -129,6 +130,16 @@ class Rack(StringIdAPIResourceWrapper): def hosts_count(self): return len(self.hosts) + @classmethod + def update(self, request, rack_id, **kwargs): + rack = dummymodels.Rack.objects.get(id=rack_id) + rack.name = kwargs['name'] + rack.location = kwargs['location'] + rack.subnet = kwargs['subnet'] + rack.resource_class_id = kwargs['resource_class_id'] + rack.save() + return self(rack) + ########################################################################## # ResourceClass diff --git a/openstack_dashboard/dashboards/infrastructure/fixtures/initial_data.json b/openstack_dashboard/dashboards/infrastructure/fixtures/initial_data.json index 4e76b9b0..36d61cab 100644 --- a/openstack_dashboard/dashboards/infrastructure/fixtures/initial_data.json +++ b/openstack_dashboard/dashboards/infrastructure/fixtures/initial_data.json @@ -11,8 +11,8 @@ {"pk": 3, "model": "infrastructure.host", "fields": {"name": "host3", "rack": 2, "mac_address": "00-B0-D0-86-AB-F9", "ip_address": "192.168.191.13", "status": "active", "usage": "40"}}, {"pk": 4, "model": "infrastructure.host", "fields": {"name": "host4", "rack": 2, "mac_address": "00-B0-D0-86-AB-F0", "ip_address": "192.168.191.14", "status": "active", "usage": "50"}}, - {"pk": 1, "model": "infrastructure.rack", "fields": {"name": "rack1", "resource_class": 1}}, - {"pk": 2, "model": "infrastructure.rack", "fields": {"name": "rack2", "resource_class": 1}}, + {"pk": 1, "model": "infrastructure.rack", "fields": {"name": "rack1", "resource_class": 1, "location": "Boston DC 1", "subnet": "10.16.25.0/24"}}, + {"pk": 2, "model": "infrastructure.rack", "fields": {"name": "rack2", "resource_class": 1, "location": "Toronto - 151 Front St.", "subnet": "24.50.60.0/22"}}, {"pk": 1, "model": "infrastructure.resourceclass", "fields": {"service_type": "compute", "name": "rclass1", "status": "warning"}}, {"pk": 2, "model": "infrastructure.resourceclass", "fields": {"service_type": "compute", "name": "rclass2"}}, diff --git a/openstack_dashboard/dashboards/infrastructure/models.py b/openstack_dashboard/dashboards/infrastructure/models.py index ad089b16..0e85bc23 100644 --- a/openstack_dashboard/dashboards/infrastructure/models.py +++ b/openstack_dashboard/dashboards/infrastructure/models.py @@ -58,6 +58,8 @@ class Rack(models.Model): name = models.CharField(max_length=50, unique=True) resource_class = models.ForeignKey('ResourceClass', blank=True, null=True) capacities = generic.GenericRelation(Capacity) + location = models.CharField(max_length=50) + subnet = models.CharField(max_length=50, unique=True) class ResourceClass(models.Model): diff --git a/openstack_dashboard/dashboards/infrastructure/resource_management/racks/forms.py b/openstack_dashboard/dashboards/infrastructure/resource_management/racks/forms.py index 33d10730..954e5d3f 100644 --- a/openstack_dashboard/dashboards/infrastructure/resource_management/racks/forms.py +++ b/openstack_dashboard/dashboards/infrastructure/resource_management/racks/forms.py @@ -20,6 +20,37 @@ class CreateRack(forms.SelfHandlingForm): 'contain letters, numbers, underscores, ' 'periods and hyphens.')}) resource_class_id = forms.ChoiceField(label=_("Resource Class")) + location = forms.CharField(label=_("Location")) + subnet = forms.CharField(label=_("IP Subnet")) + + def clean(self): + cleaned_data = super(CreateRack, self).clean() + name = cleaned_data.get('name') + rack_id = self.initial.get('rack_id', None) + resource_class_id = cleaned_data.get('resource_class_id') + location = cleaned_data.get('location') + subnet = cleaned_data.get('subnet') + try: + racks = api.management.Rack.list(self.request) + except: + racks = [] + exceptions.check_message(['Connection', 'refused'], + _("Unable to retrieve rack list.")) + raise + + # Validations: detect duplicates + for rack in racks: + other_record = rack_id != rack.id + if rack.name == name and other_record: + raise forms.ValidationError( + _('The name %s is already used by another rack.') + % name) + if rack.subnet == subnet and other_record: + raise forms.ValidationError( + _('The subnet %s is already assigned to rack %s.') + % (subnet, rack.name)) + + return cleaned_data def __init__(self, request, *args, **kwargs): super(CreateRack, self).__init__(request, *args, **kwargs) @@ -31,7 +62,9 @@ class CreateRack(forms.SelfHandlingForm): def handle(self, request, data): try: rack = api.management.Rack.create(request, data['name'], - data['resource_class_id']) + data['resource_class_id'], + data['location'], + data['subnet']) msg = _('Created rack "%s".') % data['name'] messages.success(request, msg) return True @@ -44,9 +77,12 @@ class EditRack(CreateRack): def handle(self, request, data): try: - # FIXME: This method needs implementation - # api.management.rack_edit(request, data['rack_id'], - # data['name'], data['resource_class_id']) + api.management.Rack.update(request, data['rack_id'], + name=data['name'], + subnet=data['subnet'], + resource_class_id= + data['resource_class_id'], + location=data['location']) msg = _('Updated rack "%s".') % data["name"] messages.success(request, msg) return True diff --git a/openstack_dashboard/dashboards/infrastructure/resource_management/racks/tables.py b/openstack_dashboard/dashboards/infrastructure/resource_management/racks/tables.py index 29e759ed..e0a788da 100644 --- a/openstack_dashboard/dashboards/infrastructure/resource_management/racks/tables.py +++ b/openstack_dashboard/dashboards/infrastructure/resource_management/racks/tables.py @@ -60,6 +60,9 @@ class RacksTable(tables.DataTable): link=("horizon:infrastructure:resource_management" ":racks:detail"), verbose_name=_("Rack Name")) + location = tables.Column('location', verbose_name=_("Location")) + subnet = tables.Column('subnet', verbose_name=_("IP Subnet")) + host_count = tables.Column('hosts_count', verbose_name=_("Hosts")) class Meta: name = "racks" diff --git a/openstack_dashboard/dashboards/infrastructure/resource_management/racks/tests.py b/openstack_dashboard/dashboards/infrastructure/resource_management/racks/tests.py index ef107449..2440d069 100644 --- a/openstack_dashboard/dashboards/infrastructure/resource_management/racks/tests.py +++ b/openstack_dashboard/dashboards/infrastructure/resource_management/racks/tests.py @@ -20,10 +20,10 @@ from django import http class ResourceViewTests(test.BaseAdminViewTests): index_page = reverse('horizon:infrastructure:resource_management:index') - @test.create_stubs({api.management.Rack: ('create',), }) + @test.create_stubs({api.management.Rack: ('create',)}) def test_create_rack(self): api.management.Rack.create(IsA(http.request.HttpRequest), 'New Rack', - u'2').AndReturn(None) + u'2', 'Tokyo', '1.2.3.4').AndReturn(None) self.mox.ReplayAll() url = reverse('horizon:infrastructure:resource_management:' @@ -35,12 +35,20 @@ class ResourceViewTests(test.BaseAdminViewTests): 'infrastructure/resource_management/racks/' + 'create.html') - data = {'name': 'New Rack', 'resource_class_id': u'2'} + data = {'name': 'New Rack', 'resource_class_id': u'2', + 'location': 'Tokyo', 'subnet': '1.2.3.4'} resp = self.client.post(url, data) self.assertRedirectsNoFollow(resp, self.index_page) - # FIXME: The 'edit' action currently has no API call + @test.create_stubs({api.management.Rack: ('update',)}) def test_edit_rack(self): + api.management.Rack.update(IsA(http.request.HttpRequest), + u'1', name='Updated Rack', + subnet='127.10.10.0/24', + location='New Location', + resource_class_id='1') + self.mox.ReplayAll() + url = reverse('horizon:infrastructure:resource_management:' + 'racks:edit', args=[1]) resource = self.client.get(url) @@ -49,7 +57,8 @@ class ResourceViewTests(test.BaseAdminViewTests): 'infrastructure/resource_management/racks/' + 'edit.html') - data = {'name': 'Updated Rack', 'resource_class_id': 1, 'rack_id': 1} + data = {'name': 'Updated Rack', 'resource_class_id': 1, 'rack_id': 1, + 'location': 'New Location', 'subnet': '127.10.10.0/24'} response = self.client.post(url, data) self.assertNoFormErrors(response) self.assertMessageCount(success=1) diff --git a/openstack_dashboard/dashboards/infrastructure/resource_management/racks/views.py b/openstack_dashboard/dashboards/infrastructure/resource_management/racks/views.py index 3666ecb6..037e2074 100644 --- a/openstack_dashboard/dashboards/infrastructure/resource_management/racks/views.py +++ b/openstack_dashboard/dashboards/infrastructure/resource_management/racks/views.py @@ -57,7 +57,9 @@ class EditView(forms.ModalFormView): _("Unable to retrieve rack data.")) return {'rack_id': rack.id, 'name': rack.name, - 'resource_class_id': rack.resource_class_id} + 'resource_class_id': rack.resource_class_id, + 'location': rack.location, + 'subnet': rack.subnet} class DetailView(tabs.TabView): |