As an operator, I want to have list of ungrouped hosts on Resources index page

Change-Id: I30f93d6c4a477420498322fa249241087a998390
This commit is contained in:
Jiri Tomasek
2013-06-17 14:33:05 +02:00
committed by Tomas Sedovic
parent fe5525c476
commit 569da84db0
12 changed files with 147 additions and 6 deletions

View File

@@ -77,6 +77,11 @@ class Host(StringIdAPIResourceWrapper):
def get(cls, request, host_id):
return cls(dummymodels.Host.objects.get(id=host_id))
@classmethod
def list_unracked(cls, request):
return [cls(h) for h in dummymodels.Host.objects.all() if (
h.rack is None)]
@property
def capacities(self):
if "_capacities" not in self.__dict__:

View File

@@ -10,6 +10,7 @@
{"pk": 2, "model": "infrastructure.host", "fields": {"name": "host2", "rack": 1, "mac_address": "00-B0-D0-86-AB-F8", "ip_address": "192.168.191.12", "status": "active", "usage": "30"}},
{"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": 5, "model": "infrastructure.host", "fields": {"name": "Unracked Host", "mac_address": "00-B0-D0-86-AB-F1"}},
{"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"}},

View File

@@ -44,10 +44,10 @@ class Host(models.Model):
name = models.CharField(max_length=50, unique=True)
mac_address = models.CharField(max_length=50, unique=True)
ip_address = models.CharField(max_length=50, unique=True)
status = models.CharField(max_length=50)
usage = models.IntegerField(max_length=50)
rack = models.ForeignKey('Rack')
ip_address = models.CharField(max_length=50, unique=True, null=True)
status = models.CharField(max_length=50, null=True)
usage = models.IntegerField(max_length=50, null=True)
rack = models.ForeignKey('Rack', null=True)
capacities = generic.GenericRelation(Capacity)

View File

@@ -57,3 +57,12 @@ class HostsTable(tables.DataTable):
verbose_name = _("Hosts")
table_actions = (DeleteHosts, HostsFilterAction)
row_actions = (DeleteHosts,)
class UnrackedHostsTable(HostsTable):
class Meta:
name = "unracked_hosts"
verbose_name = _("Unracked Hosts")
table_actions = ()
row_actions = ()

View File

@@ -0,0 +1,28 @@
from django.core.urlresolvers import reverse
from openstack_dashboard.test import helpers as test
from openstack_dashboard import api
from mox import IsA
from django import http
class ResourceViewTests(test.BaseAdminViewTests):
unracked_page = reverse('horizon:infrastructure:'
'resource_management:hosts:unracked')
@test.create_stubs({api.management.Host: ('list_unracked',), })
def test_unracked(self):
unracked_hosts = self.management_racks.list()
api.management.Host.list_unracked(IsA(http.HttpRequest)) \
.AndReturn(unracked_hosts)
self.mox.ReplayAll()
res = self.client.get(self.unracked_page)
self.assertTemplateUsed(res,
'infrastructure/resource_management/hosts/unracked.html')
unracked_hosts_table = res.context['unracked_hosts_table'].data
self.assertItemsEqual(unracked_hosts_table, unracked_hosts)

View File

@@ -15,6 +15,7 @@
from django.conf.urls.defaults import patterns, url
from .views import DetailView
from .views import UnrackedView
HOSTS = r'^(?P<host_id>[^/]+)/%s$'
@@ -24,4 +25,5 @@ VIEW_MOD = 'openstack_dashboard.dashboards.infrastructure.' \
urlpatterns = patterns(VIEW_MOD,
url(HOSTS % 'detail', DetailView.as_view(), name='detail'),
url(r'^unracked/$', UnrackedView.as_view(), name='unracked'),
)

View File

@@ -16,11 +16,27 @@ from django.core.urlresolvers import reverse
from django.utils.translation import ugettext_lazy as _
from horizon import exceptions
from horizon import tables
from horizon import tabs
from openstack_dashboard import api
from .tabs import HostDetailTabs
from .tables import UnrackedHostsTable
class UnrackedView(tables.DataTableView):
table_class = UnrackedHostsTable
template_name = 'infrastructure/resource_management/hosts/unracked.html'
def get_data(self):
try:
hosts = api.management.Host.list_unracked(self.request)
except:
hosts = []
exceptions.handle(self.request,
_('Unable to retrieve hosts.'))
return hosts
class DetailView(tabs.TabView):

View File

@@ -31,7 +31,8 @@ class RacksTab(tabs.TableTab):
table_classes = (RacksTable,)
name = _("Resources")
slug = "racks_tab"
template_name = "horizon/common/_detail_table.html"
template_name = ("infrastructure/resource_management/"
"racks/_index_table.html")
def get_racks_data(self):
try:
@@ -42,6 +43,16 @@ class RacksTab(tabs.TableTab):
_('Unable to retrieve racks.'))
return racks
def get_context_data(self, request):
context = super(RacksTab, self).get_context_data(request)
try:
context["hosts"] = management.Host.list_unracked(self.request)
except:
context["hosts"] = []
exceptions.handle(request,
_('Unable to retrieve hosts.'))
return context
class FlavorsTab(tabs.TableTab):
table_classes = (FlavorsTable,)

View File

@@ -0,0 +1,15 @@
{% extends 'infrastructure/base.html' %}
{% load i18n %}
{% block title %}{% trans "Resource Management" %}{% endblock %}
{% block page_header %}
{% include "horizon/common/_page_header.html" with title=_("Resource Management") %}
{% endblock page_header %}
{% block main %}
<div class="row-fluid">
<div class="span12">
{{ table.render }}
</div>
</div>
{% endblock %}

View File

@@ -0,0 +1,3 @@
{% load i18n %}
{{ racks_table.render }}
<a href="{% url 'horizon:infrastructure:resource_management:hosts:unracked' %}">{% trans "View Unracked Hosts"%} ({{hosts|length}})</a>

View File

@@ -33,6 +33,8 @@ class ResourceManagementTests(test.BaseAdminViewTests):
'racks',
'hosts'),
api.management.Flavor: (
'list',),
api.management.Rack: (
'list',)})
def test_index(self):
# Flavor stubs
@@ -54,6 +56,12 @@ class ResourceManagementTests(test.BaseAdminViewTests):
AndReturn(all_resource_classes)
# ResourceClass stubs end
# Rack stubs
racks = self.management_racks.list()
api.management.Rack.list(IsA(http.HttpRequest)).AndReturn(racks)
# Rack stubs end
self.mox.ReplayAll()
url = reverse('horizon:infrastructure:resource_management:index')
@@ -69,3 +77,7 @@ class ResourceManagementTests(test.BaseAdminViewTests):
self.assertItemsEqual(res.context['resource_classes_table'].data,
all_resource_classes)
# ResourceClass asserts end
# Rack asserts
self.assertItemsEqual(res.context['racks_table'].data, racks)
# Rack asserts end

View File

@@ -11,7 +11,7 @@
# under the License.
from openstack_dashboard.api.management import (
Flavor, ResourceClass,
Flavor, ResourceClass, Host,
Rack, ResourceClassFlavor)
import openstack_dashboard.dashboards.infrastructure.models as dummymodels
@@ -88,3 +88,42 @@ def data(TEST):
flavor_id=1))
TEST.management_resource_class_flavors.add(resource_class_flavor_1)
# Hosts
TEST.hosts = TestDataContainer()
TEST.unracked_hosts = TestDataContainer()
host_1 = Host(dummymodels.Host(id="1",
name="host1",
rack_id=1,
mac_address="00-B0-D0-86-AB-F7",
ip_address="192.168.191.11",
status="active",
usage="20"))
host_2 = Host(dummymodels.Host(id="2",
name="host2",
rack_id=1,
mac_address="00-B0-D0-86-AB-F8",
ip_address="192.168.191.12",
status="active",
usage="20"))
host_3 = Host(dummymodels.Host(id="3",
name="host3",
rack_id=1,
mac_address="00-B0-D0-86-AB-F9",
ip_address="192.168.191.13",
status="active",
usage="20"))
host_4 = Host(dummymodels.Host(id="4",
name="host4",
rack_id=1,
mac_address="00-B0-D0-86-AB-F0",
ip_address="192.168.191.14",
status="active",
usage="20"))
host_5 = Host(dummymodels.Host(id="5",
name="host5",
mac_address="00-B0-D0-86-AB-F1"))
TEST.hosts.add(host_1, host_2, host_3, host_4)
TEST.unracked_hosts.add(host_5)