Implement host detail

Implemented host detail functionality.
Also Added test case for host detail.

Partial-Implements: blueprint masakari-dashboard

Change-Id: I7e62e4a2b1e15ddeb2a592670518d8358f4a6b1c
This commit is contained in:
nirajsingh 2018-01-30 17:46:17 +05:30
parent 9ae3efef6b
commit bef761d1d9
10 changed files with 187 additions and 5 deletions

View File

@ -151,3 +151,8 @@ def get_host_list(request, segment_id, filters):
def delete_host(request, host_id, segment_id): def delete_host(request, host_id, segment_id):
return openstack_connection(request).delete_host( return openstack_connection(request).delete_host(
host_id, segment_id, False) host_id, segment_id, False)
def get_host(request, segment_id, host_id):
"""return single host."""
return openstack_connection(request).get_host(host_id, segment_id)

View File

@ -66,7 +66,8 @@ class DeleteHost(tables.DeleteAction):
class HostTable(tables.DataTable): class HostTable(tables.DataTable):
name = tables.Column('name', verbose_name=_("Name")) name = tables.Column('name', verbose_name=_("Name"),
link="horizon:masakaridashboard:hosts:detail")
uuid = tables.Column('uuid', verbose_name=_("UUID")) uuid = tables.Column('uuid', verbose_name=_("UUID"))
reserved = tables.Column( reserved = tables.Column(
'reserved', verbose_name=_("Reserved")) 'reserved', verbose_name=_("Reserved"))
@ -78,7 +79,8 @@ class HostTable(tables.DataTable):
on_maintenance = tables.Column( on_maintenance = tables.Column(
'on_maintenance', verbose_name=_("On Maintenance")) 'on_maintenance', verbose_name=_("On Maintenance"))
failover_segment_id = tables.Column( failover_segment_id = tables.Column(
'failover_segment_id', verbose_name=_("Failover Segment")) 'failover_segment_id', verbose_name=_("Failover Segment"),
link="horizon:masakaridashboard:segments:detail")
def get_object_id(self, datum): def get_object_id(self, datum):
return datum.uuid + ',' + datum.failover_segment_id return datum.uuid + ',' + datum.failover_segment_id

View File

@ -0,0 +1,31 @@
# Copyright (c) 2018 NTT DATA
#
# 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.utils.translation import ugettext_lazy as _
from horizon import tabs
class OverviewTab(tabs.Tab):
name = _("Hosts")
slug = "hosts"
template_name = ("masakaridashboard/hosts/_detail_overview.html")
def get_context_data(self, request):
return {"host": self.tab_group.kwargs['host']}
class HostDetailTabs(tabs.DetailTabsGroup):
slug = "host_details"
tabs = (OverviewTab,)

View File

@ -0,0 +1,21 @@
{% load i18n sizeformat parse_date %}
<div class="detail">
<h4>{% trans "Host Detail" %}</h4>
<hr class="header_rule">
<dl class="dl-horizontal">
<dt>{% trans "Name" %}</dt>
<dd>{{ host.name }}</dd>
<dt>{% trans "UUID" %}</dt>
<dd>{{ host.uuid }}</dd>
<dt>{% trans "Failover Segment" %}</dt>
<dd>{{ host.failover_segment_id }}</dd>
<dt>{% trans "Reserved" %}</dt>
<dd>{{ host.reserved }}</dd>
<dt>{% trans "On Maintenance" %}</dt>
<dd>{{ host.on_maintenance }}</dd>
<dt>{% trans "Type" %}</dt>
<dd>{{ host.type }}</dd>
<dt>{% trans "Control Attribute" %}</dt>
<dd>{{ host.control_attributes }}</dd>
</dl>
</div>

View File

@ -0,0 +1,32 @@
<span class="masakari-wrapper detail-screen">
{% extends 'masakaridashboard/default/base.html' %}
{% load i18n %}
{% block title %}{% trans "Host Detail" %}{% endblock %}
{% block page_header %}
{% include "horizon/common/_page_header.html" with title=_("Host Detail") %}
{% endblock page_header %}
{% block main %}
{% load i18n sizeformat parse_date %}
<div class="detail">
<h4>{% trans "Host Detail" %}</h4>
<hr class="header_rule">
<dl class="dl-horizontal">
<dt>{% trans "UUID" %}</dt>
<dd>{{ host.uuid }}</dd>
<dt>{% trans "Name" %}</dt>
<dd>{{ host.name }}</dd>
<dt>{% trans "Reserved" %}</dt>
<dd>{{ host.reserved }}</dd>
<dt>{% trans "Type" %}</dt>
<dd>{{ host.type }}</dd>
<dt>{% trans "Control Attribute" %}</dt>
<dd>{{ host.control_attributes }}</dd>
<dt>{% trans "On Maintenance" %}</dt>
<dd>{{ host.on_maintenance }}</dd>
<dt>{% trans "Failover Segment" %}</dt>
<dd>{{ host.failover_segment_id }}</dd>
</dl>
</div>
{% endblock %}
</span>

View File

@ -93,3 +93,17 @@ class HostTest(test.TestCase):
host.uuid, host.uuid,
host.failover_segment_id, host.failover_segment_id,
) )
def test_detail(self):
host = self.masakari_host.list()[0]
id_to_update = host.uuid+','+host.failover_segment_id
detail_url = reverse('horizon:masakaridashboard:hosts:detail',
args=[id_to_update])
with mock.patch('masakaridashboard.api.api.get_host',
return_value=self.masakari_host.list()[0]):
res = self.client.get(detail_url)
self.assertNoFormErrors(res)
self.assertEqual(200, res.status_code)
self.assertTemplateUsed(res, 'horizon/common/_detail.html')
self.assertTemplateUsed(
res, 'masakaridashboard/hosts/_detail_overview.html')

View File

@ -17,6 +17,8 @@ from django.conf.urls import url
from masakaridashboard.hosts import views from masakaridashboard.hosts import views
HOST = r'^(?P<host_id>[^/]+)/%s$'
urlpatterns = [ urlpatterns = [
url(r'^$', views.IndexView.as_view(), name='index'), url(r'^$', views.IndexView.as_view(), name='index'),
url(HOST % 'detail', views.DetailView.as_view(), name='detail'),
] ]

View File

@ -13,10 +13,17 @@
# limitations under the License. # limitations under the License.
from django.conf import settings from django.conf import settings
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 tables
from horizon import tabs
from horizon.utils import memoized
from masakaridashboard.api import api from masakaridashboard.api import api
from masakaridashboard.hosts import tables as masakari_tab from masakaridashboard.hosts import tables as masakari_tab
from masakaridashboard.hosts import tabs as host_tab
class IndexView(tables.DataTableView): class IndexView(tables.DataTableView):
@ -45,3 +52,39 @@ class IndexView(tables.DataTableView):
host_list.append(item) host_list.append(item)
return host_list return host_list
class DetailView(tabs.TabbedTableView):
tab_group_class = host_tab.HostDetailTabs
template_name = 'horizon/common/_detail.html'
page_title = "{{ host.name|default:host.id }}"
def get_context_data(self, **kwargs):
context = super(DetailView, self).get_context_data(**kwargs)
host = self.get_data()
table = masakari_tab.HostTable(self.request)
context["host"] = host
context["url"] = self.get_redirect_url()
context["actions"] = table.render_row_actions(host)
return context
@memoized.memoized_method
def get_data(self):
row_data = self.kwargs['host_id'].split(',')
segment_id = row_data[1]
host_id = row_data[0]
try:
host = api.get_host(self.request, segment_id, host_id)
except Exception:
msg = _('Unable to get host "%s".') % host_id
redirect = reverse('horizon:masakaridashboard:hosts:index')
exceptions.handle(self.request, msg, redirect=redirect)
return host
def get_redirect_url(self):
return reverse('horizon:masakaridashboard:hosts:index')
def get_tabs(self, request, *args, **kwargs):
host = self.get_data()
return self.tab_group_class(request, host=host, **kwargs)

View File

@ -1,4 +1,4 @@
# Copyright (C) 2018 NTT DATA # Copyright (c) 2018 NTT DATA
# #
# Licensed under the Apache License, Version 2.0 (the "License"); you may # 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 # not use this file except in compliance with the License. You may obtain
@ -16,6 +16,9 @@ from django.utils.translation import ugettext_lazy as _
from horizon import tabs from horizon import tabs
from masakaridashboard.api import api
from masakaridashboard.hosts import tables as host_table
class OverviewTab(tabs.Tab): class OverviewTab(tabs.Tab):
name = _("Segments") name = _("Segments")
@ -26,6 +29,30 @@ class OverviewTab(tabs.Tab):
return {"segment": self.tab_group.kwargs['segment']} return {"segment": self.tab_group.kwargs['segment']}
class HostTab(tabs.TableTab):
table_classes = (host_table.HostTable,)
name = _("Hosts")
slug = "host_tab"
template_name = "horizon/common/_detail_table.html"
preload = False
def get_host_data(self):
segment_data = self.tab_group.kwargs['segment_id']
if len(segment_data.split(',')) > 1:
segment_id = segment_data.split(',')[1]
else:
segment_id = segment_data
host_list = []
host_gen = api.get_host_list(self.request, segment_id, filters={})
for item in host_gen:
host_list.append(item)
return host_list
class SegmentDetailTabs(tabs.DetailTabsGroup): class SegmentDetailTabs(tabs.DetailTabsGroup):
slug = "segment_details" slug = "segment_details"
tabs = (OverviewTab,) tabs = (OverviewTab, HostTab)

View File

@ -117,7 +117,12 @@ class DetailView(tabs.TabbedTableView):
@memoized.memoized_method @memoized.memoized_method
def get_data(self): def get_data(self):
try: try:
segment_id = self.kwargs['segment_id'] segment_data = self.kwargs['segment_id']
if len(segment_data.split(',')) > 1:
segment_id = segment_data.split(',')[1]
else:
segment_id = segment_data
segment = api.get_segment(self.request, segment_id) segment = api.get_segment(self.request, segment_id)
except Exception: except Exception:
msg = _('Unable to get segment "%s".') % segment_id msg = _('Unable to get segment "%s".') % segment_id