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):
return openstack_connection(request).delete_host(
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):
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"))
reserved = tables.Column(
'reserved', verbose_name=_("Reserved"))
@ -78,7 +79,8 @@ class HostTable(tables.DataTable):
on_maintenance = tables.Column(
'on_maintenance', verbose_name=_("On Maintenance"))
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):
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.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
HOST = r'^(?P<host_id>[^/]+)/%s$'
urlpatterns = [
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.
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 tabs
from horizon.utils import memoized
from masakaridashboard.api import api
from masakaridashboard.hosts import tables as masakari_tab
from masakaridashboard.hosts import tabs as host_tab
class IndexView(tables.DataTableView):
@ -45,3 +52,39 @@ class IndexView(tables.DataTableView):
host_list.append(item)
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
# 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 masakaridashboard.api import api
from masakaridashboard.hosts import tables as host_table
class OverviewTab(tabs.Tab):
name = _("Segments")
@ -26,6 +29,30 @@ class OverviewTab(tabs.Tab):
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):
slug = "segment_details"
tabs = (OverviewTab,)
tabs = (OverviewTab, HostTab)

View File

@ -117,7 +117,12 @@ class DetailView(tabs.TabbedTableView):
@memoized.memoized_method
def get_data(self):
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)
except Exception:
msg = _('Unable to get segment "%s".') % segment_id