Merge "Add a detailed view of a Host"

This commit is contained in:
Zuul 2017-11-02 09:35:11 +00:00 committed by Gerrit Code Review
commit 640af94061
9 changed files with 166 additions and 5 deletions

View File

@ -42,12 +42,24 @@ class Lease(base.APIDictWrapper):
class Host(base.APIDictWrapper):
"""Represents one Blazar host."""
_attrs = ['id', 'hypervisor_hostname', 'hypervisor_type', 'vcpus',
'cpu_info', 'memory_mb', 'local_gb']
_attrs = ['id', 'hypervisor_hostname', 'hypervisor_type',
'hypervisor_version', 'vcpus', 'cpu_info', 'memory_mb',
'local_gb', 'status', 'created_at', 'updated_at',
'service_name', 'trust_id']
def __init__(self, apiresource):
super(Host, self).__init__(apiresource)
def cpu_info_dict(self):
return eval(getattr(self, 'cpu_info', ""))
def extra_capabilities(self):
excaps = {}
for k, v in self._apidict.items():
if k not in self._attrs:
excaps[k] = v
return excaps
@memoized
def blazarclient(request):
@ -98,3 +110,9 @@ def host_list(request):
"""List hosts."""
hosts = blazarclient(request).host.list()
return [Host(h) for h in hosts]
def host_get(request, host_id):
"""Get a host."""
host = blazarclient(request).host.get(host_id)
return Host(host)

View File

@ -16,7 +16,8 @@ from horizon.templatetags import sizeformat
class HostsTable(tables.DataTable):
name = tables.Column("hypervisor_hostname", verbose_name=_("Host name"))
name = tables.Column("hypervisor_hostname", verbose_name=_("Host name"),
link="horizon:admin:hosts:detail")
vcpus = tables.Column("vcpus", verbose_name=_("VCPUs"))
memory_mb = tables.Column("memory_mb", verbose_name=_("RAM"),
filters=(sizeformat.mb_float_format,))

View File

@ -0,0 +1,43 @@
# Copyright 2014 Intel Corporation
# All Rights Reserved.
#
# 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.
from django.core.urlresolvers import reverse
from django.utils.translation import ugettext_lazy as _
from horizon import exceptions
from horizon import tabs
from blazar_dashboard.api import client
class OverviewTab(tabs.Tab):
name = _("Overview")
slug = "overview"
template_name = "admin/hosts/_detail_overview.html"
def get_context_data(self, request):
host_id = self.tab_group.kwargs['host_id']
try:
host = client.host_get(self.request, host_id)
except Exception:
redirect = reverse('horizon:admin:hosts:index')
msg = _('Unable to retrieve host details.')
exceptions.handle(request, msg, redirect=redirect)
return {'host': host}
class HostDetailTabs(tabs.TabGroup):
slug = "host_details"
tabs = (OverviewTab,)

View File

@ -0,0 +1,49 @@
{% load i18n sizeformat %}
<div class="detail">
<div class="info detail">
<dl class="dl-horizontal">
<dt>{% trans "Host name" %}</dt>
<dd>{{ host.hypervisor_hostname }}</dd>
<dt>{% trans "Id" %}</dt>
<dd>{{ host.id }}</dd>
<dt>{% trans "Status" %}</dt>
<dd>{{ host.status }}</dd> <dt>{% trans "Created at" %}</dt>
<dd>{{ host.created_at|parse_isotime|date:"Y-m-d H:i T"|default:"-" }}</dd>
<dt>{% trans "Updated at" %}</dt>
<dd>{{ host.updated_at|parse_isotime|date:"Y-m-d H:i T"|default:"-" }}</dd>
</dl>
</div>
<div>
<h4>{% trans "CPU Specs" %}</h4>
<hr class="header_rule">
<dl class="dl-horizontal">
<dt>{% trans "VCPUs" %}</dt>
<dd>{{ host.vcpus|default:_("None") }}</dd>
{% for key, value in host.cpu_info_dict.items %}
<dt>{{ key }}</dt>
<dd>{{ value }}</dd>
{% endfor %}
</dl>
</div>
<div>
<h4>{% trans "Other Specs" %}</h4>
<hr class="header_rule">
<dl class="dl-horizontal">
<dt>{% trans "RAM" %}</dt>
<dd>{{ host.memory_mb|mb_float_format }}</dd>
<dt>{% trans "Local storage" %}</dt>
<dd>{{ host.local_gb|diskgbformat }}</dd>
<dt>{% trans "Hypervisor type" %}</dt>
<dd>{{ host.hypervisor_type }}</dd>
<dt>{% trans "Hypervisor version" %}</dt>
<dd>{{ host.hypervisor_version }}</dd>
{% for key, value in host.extra_capabilities.items %}
<dt>{{ key }}</dt>
<dd>{{ value }}</dd>
{% endfor %}
</dl>
</div>
</div>

View File

@ -0,0 +1,15 @@
{% extends 'base.html' %}
{% load i18n %}
{% block title %}{% trans "Host Details"%}{% endblock %}
{% block page_header %}
{% include "horizon/common/_page_header.html" with title=_("Host Details") %}
{% endblock page_header %}
{% block main %}
<div class="row">
<div class="col-md-12">
{{ tab_group.render }}
</div>
</div>
{% endblock %}

View File

@ -22,6 +22,8 @@ LOG = logging.getLogger(__name__)
INDEX_TEMPLATE = 'admin/hosts/index.html'
INDEX_URL = reverse('horizon:admin:hosts:index')
DETAIL_TEMPLATE = 'admin/hosts/detail.html'
DETAIL_URL_BASE = 'horizon:admin:hosts:detail'
class HostsTests(test.BaseAdminViewTests):
@ -57,3 +59,26 @@ class HostsTests(test.BaseAdminViewTests):
res = self.client.get(INDEX_URL)
self.assertTemplateUsed(res, INDEX_TEMPLATE)
self.assertMessageCount(res, error=1)
@test.create_stubs({api.client: ('host_get',)})
def test_host_detail(self):
host = self.hosts.get(hypervisor_hostname='compute-1')
api.client.host_get(IsA(http.HttpRequest),
host['id']).AndReturn(host)
self.mox.ReplayAll()
res = self.client.get(reverse(DETAIL_URL_BASE, args=[host['id']]))
self.assertTemplateUsed(res, DETAIL_TEMPLATE)
self.assertContains(res, 'compute-1')
self.assertContains(res, 'ex1')
@test.create_stubs({api.client: ('host_get',)})
def test_host_detail_error(self):
api.client.host_get(IsA(http.HttpRequest),
'invalid').AndRaise(self.exceptions.blazar)
self.mox.ReplayAll()
res = self.client.get(reverse(DETAIL_URL_BASE, args=['invalid']))
self.assertTemplateNotUsed(res, DETAIL_TEMPLATE)
self.assertMessageCount(error=1)
self.assertRedirectsNoFollow(res, INDEX_URL)

View File

@ -17,4 +17,5 @@ from blazar_dashboard.content.hosts import views
urlpatterns = [
url(r'^$', views.IndexView.as_view(), name='index'),
url(r'^(?P<host_id>[^/]+)/$', views.DetailView.as_view(), name='detail')
]

View File

@ -13,9 +13,11 @@
from django.utils.translation import ugettext_lazy as _
from horizon import exceptions
from horizon import tables
from horizon import tabs
from blazar_dashboard import api
from blazar_dashboard.content.hosts import tables as project_tables
from blazar_dashboard.content.hosts import tabs as project_tabs
class IndexView(tables.DataTableView):
@ -30,3 +32,8 @@ class IndexView(tables.DataTableView):
msg = _('Unable to retrieve host information.')
exceptions.handle(self.request, msg)
return hosts
class DetailView(tabs.TabView):
tab_group_class = project_tabs.HostDetailTabs
template_name = 'admin/hosts/detail.html'

View File

@ -146,7 +146,8 @@ host_sample1 = {
"hypervisor_version": 2005000,
"local_gb": 128,
"id": "1",
"trust_id": "dummy"
"trust_id": "dummy",
"ex1": "dummy"
}
host_sample2 = {
@ -162,7 +163,8 @@ host_sample2 = {
"hypervisor_version": 2005000,
"local_gb": 128,
"id": "2",
"trust_id": "dummy"
"trust_id": "dummy",
"ex2": "dummy"
}