As an operator, I want to have list of ungrouped hosts on Resources index page
Change-Id: I30f93d6c4a477420498322fa249241087a998390
This commit is contained in:
committed by
Tomas Sedovic
parent
fe5525c476
commit
569da84db0
@@ -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__:
|
||||
|
||||
@@ -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"}},
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
|
||||
@@ -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 = ()
|
||||
|
||||
@@ -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)
|
||||
@@ -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'),
|
||||
)
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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,)
|
||||
|
||||
@@ -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 %}
|
||||
@@ -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>
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user