From bef761d1d936440e82136871c84d996af51de1c6 Mon Sep 17 00:00:00 2001 From: nirajsingh Date: Tue, 30 Jan 2018 17:46:17 +0530 Subject: [PATCH] Implement host detail Implemented host detail functionality. Also Added test case for host detail. Partial-Implements: blueprint masakari-dashboard Change-Id: I7e62e4a2b1e15ddeb2a592670518d8358f4a6b1c --- masakaridashboard/api/api.py | 5 +++ masakaridashboard/hosts/tables.py | 6 ++- masakaridashboard/hosts/tabs.py | 31 +++++++++++++ .../templates/hosts/_detail_overview.html | 21 +++++++++ .../hosts/templates/hosts/detail.html | 32 ++++++++++++++ masakaridashboard/hosts/tests.py | 14 ++++++ masakaridashboard/hosts/urls.py | 2 + masakaridashboard/hosts/views.py | 43 +++++++++++++++++++ masakaridashboard/segments/tabs.py | 31 ++++++++++++- masakaridashboard/segments/views.py | 7 ++- 10 files changed, 187 insertions(+), 5 deletions(-) create mode 100644 masakaridashboard/hosts/tabs.py create mode 100644 masakaridashboard/hosts/templates/hosts/_detail_overview.html create mode 100644 masakaridashboard/hosts/templates/hosts/detail.html diff --git a/masakaridashboard/api/api.py b/masakaridashboard/api/api.py index 2e7904e..3dbd3f0 100644 --- a/masakaridashboard/api/api.py +++ b/masakaridashboard/api/api.py @@ -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) diff --git a/masakaridashboard/hosts/tables.py b/masakaridashboard/hosts/tables.py index c5b0633..a8c4731 100644 --- a/masakaridashboard/hosts/tables.py +++ b/masakaridashboard/hosts/tables.py @@ -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 diff --git a/masakaridashboard/hosts/tabs.py b/masakaridashboard/hosts/tabs.py new file mode 100644 index 0000000..c0d5c25 --- /dev/null +++ b/masakaridashboard/hosts/tabs.py @@ -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,) diff --git a/masakaridashboard/hosts/templates/hosts/_detail_overview.html b/masakaridashboard/hosts/templates/hosts/_detail_overview.html new file mode 100644 index 0000000..75be33b --- /dev/null +++ b/masakaridashboard/hosts/templates/hosts/_detail_overview.html @@ -0,0 +1,21 @@ +{% load i18n sizeformat parse_date %} +
+

{% trans "Host Detail" %}

+
+
+
{% trans "Name" %}
+
{{ host.name }}
+
{% trans "UUID" %}
+
{{ host.uuid }}
+
{% trans "Failover Segment" %}
+
{{ host.failover_segment_id }}
+
{% trans "Reserved" %}
+
{{ host.reserved }}
+
{% trans "On Maintenance" %}
+
{{ host.on_maintenance }}
+
{% trans "Type" %}
+
{{ host.type }}
+
{% trans "Control Attribute" %}
+
{{ host.control_attributes }}
+
+
\ No newline at end of file diff --git a/masakaridashboard/hosts/templates/hosts/detail.html b/masakaridashboard/hosts/templates/hosts/detail.html new file mode 100644 index 0000000..dc4186f --- /dev/null +++ b/masakaridashboard/hosts/templates/hosts/detail.html @@ -0,0 +1,32 @@ + +{% 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 %} +
+

{% trans "Host Detail" %}

+
+
+
{% trans "UUID" %}
+
{{ host.uuid }}
+
{% trans "Name" %}
+
{{ host.name }}
+
{% trans "Reserved" %}
+
{{ host.reserved }}
+
{% trans "Type" %}
+
{{ host.type }}
+
{% trans "Control Attribute" %}
+
{{ host.control_attributes }}
+
{% trans "On Maintenance" %}
+
{{ host.on_maintenance }}
+
{% trans "Failover Segment" %}
+
{{ host.failover_segment_id }}
+
+
+{% endblock %} +
diff --git a/masakaridashboard/hosts/tests.py b/masakaridashboard/hosts/tests.py index 3ca7eff..9752bc0 100644 --- a/masakaridashboard/hosts/tests.py +++ b/masakaridashboard/hosts/tests.py @@ -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') diff --git a/masakaridashboard/hosts/urls.py b/masakaridashboard/hosts/urls.py index 3ba7aa3..496cd81 100644 --- a/masakaridashboard/hosts/urls.py +++ b/masakaridashboard/hosts/urls.py @@ -17,6 +17,8 @@ from django.conf.urls import url from masakaridashboard.hosts import views +HOST = r'^(?P[^/]+)/%s$' urlpatterns = [ url(r'^$', views.IndexView.as_view(), name='index'), + url(HOST % 'detail', views.DetailView.as_view(), name='detail'), ] diff --git a/masakaridashboard/hosts/views.py b/masakaridashboard/hosts/views.py index c2e7b28..d249cd6 100644 --- a/masakaridashboard/hosts/views.py +++ b/masakaridashboard/hosts/views.py @@ -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) diff --git a/masakaridashboard/segments/tabs.py b/masakaridashboard/segments/tabs.py index 3abd828..905a5d5 100644 --- a/masakaridashboard/segments/tabs.py +++ b/masakaridashboard/segments/tabs.py @@ -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) diff --git a/masakaridashboard/segments/views.py b/masakaridashboard/segments/views.py index 9bf7f94..bf60c1f 100644 --- a/masakaridashboard/segments/views.py +++ b/masakaridashboard/segments/views.py @@ -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