Showing configuration tab of deployed overcloud

-showing configuration from heat
-test for configuration tab
-test for event logs was missing, so I've added it too
-fixing test for mocking only needed values
-all tabs set to preload=False
-extracting deCamelCase into utils and changed 2 usages

Change-Id: I312bbc6e47137e5184bcb60963472c55388b64e6
This commit is contained in:
Ladislav Smola 2014-02-19 16:22:55 +01:00
parent 1fc6db3187
commit 953fc1bcf7
7 changed files with 126 additions and 24 deletions

View File

@ -28,6 +28,24 @@ class OvercloudRoleNodeTable(nodes_tables.DeployedNodesTable):
row_actions = ()
class ConfigurationTable(tables.DataTable):
key = tables.Column(lambda parameter: parameter[0],
verbose_name=_("Attribute Name"))
value = tables.Column(lambda parameter: parameter[1],
verbose_name=_("Attribute Value"))
class Meta:
name = "configuration"
verbose_name = _("Configuration")
multi_select = False
table_actions = ()
row_actions = ()
def get_object_id(self, datum):
return datum[0]
class LogTable(tables.DataTable):
timestamp = tables.Column('event_time',

View File

@ -13,7 +13,6 @@
# 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 django.utils.translation import ungettext_lazy
@ -22,6 +21,7 @@ from horizon import tabs
from tuskar_ui import api
from tuskar_ui.infrastructure.overcloud import tables
from tuskar_ui import utils
def _get_role_data(overcloud, role):
@ -60,6 +60,7 @@ class OverviewTab(tabs.Tab):
name = _("Overview")
slug = "overview"
template_name = ("infrastructure/overcloud/_detail_overview.html")
preload = False
def get_context_data(self, request, **kwargs):
overcloud = self.tab_group.kwargs['overcloud']
@ -86,13 +87,18 @@ class OverviewTab(tabs.Tab):
}
class ConfigurationTab(tabs.Tab):
class ConfigurationTab(tabs.TableTab):
table_classes = (tables.ConfigurationTable,)
name = _("Configuration")
slug = "configuration"
template_name = ("infrastructure/overcloud/_detail_configuration.html")
template_name = "horizon/common/_detail_table.html"
preload = False
def get_context_data(self, request):
return {}
def get_configuration_data(self):
overcloud = self.tab_group.kwargs['overcloud']
return [(utils.de_camel_case(key), value) for key, value in
overcloud.stack.parameters.items()]
class LogTab(tabs.TableTab):

View File

@ -1,5 +0,0 @@
{% load i18n %}
{% load url from future%}
<div class="row-fluid"><div class="span12">
</div></div>

View File

@ -29,6 +29,9 @@ CREATE_URL = urlresolvers.reverse(
'horizon:infrastructure:overcloud:create')
DETAIL_URL = urlresolvers.reverse(
'horizon:infrastructure:overcloud:detail', args=(1,))
DETAIL_URL_CONFIGURATION_TAB = (DETAIL_URL +
"?tab=detail__configuration")
DETAIL_URL_LOG_TAB = (DETAIL_URL + "?tab=detail__log")
DELETE_URL = urlresolvers.reverse(
'horizon:infrastructure:overcloud:undeploy_confirmation', args=(1,))
TEST_DATA = utils.TestDataContainer()
@ -199,10 +202,75 @@ class OvercloudTests(test.BaseAdminViewTests):
self.assertTemplateUsed(
res, 'infrastructure/overcloud/detail.html')
self.assertTemplateNotUsed(
res, 'horizon/common/_detail_table.html')
self.assertTemplateUsed(
res, 'infrastructure/overcloud/_detail_overview.html')
def test_detail_get_configuration_tab(self):
oc = None
stack = TEST_DATA.heatclient_stacks.first()
with patch('tuskar_ui.api.Overcloud', **{
'spec_set': [
'get',
'id',
'is_deployed',
'is_deploying',
'is_failed',
'resources',
'dashboard_url',
'stack',
],
'id': 1,
'is_deployed': True,
'is_deploying': False,
'is_failed': False,
'get.side_effect': lambda request, overcloud_id: oc,
'resources.return_value': [],
'dashboard_url': '',
'stack': stack,
}) as Overcloud:
oc = Overcloud
res = self.client.get(DETAIL_URL_CONFIGURATION_TAB)
self.assertTemplateUsed(
res, 'infrastructure/overcloud/_detail_configuration.html')
res, 'infrastructure/overcloud/detail.html')
self.assertTemplateNotUsed(
res, 'infrastructure/overcloud/_detail_overview.html')
self.assertTemplateUsed(
res, 'horizon/common/_detail_table.html')
def test_detail_get_log_tab(self):
oc = None
with patch('tuskar_ui.api.Overcloud', **{
'spec_set': [
'get',
'id',
'is_deployed',
'is_deploying',
'is_failed',
'resources',
'dashboard_url',
'stack_events',
],
'id': 1,
'is_deployed': True,
'is_deploying': False,
'is_failed': False,
'get.side_effect': lambda request, overcloud_id: oc,
'resources.return_value': [],
'dashboard_url': '',
'stack_events': [],
}) as Overcloud:
oc = Overcloud
res = self.client.get(DETAIL_URL_LOG_TAB)
self.assertTemplateUsed(
res, 'infrastructure/overcloud/detail.html')
self.assertTemplateNotUsed(
res, 'infrastructure/overcloud/_detail_overview.html')
self.assertTemplateUsed(
res, 'horizon/common/_detail_table.html')
def test_delete_get(self):
res = self.client.get(DELETE_URL)

View File

@ -11,13 +11,11 @@
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import re
import django.forms
from django.utils.translation import ugettext_lazy as _
import horizon.workflows
from tuskar_ui import utils
# TODO(rdopieralski) Get this from the Heat template.
TEMPLATE_DATA = {
@ -221,20 +219,12 @@ TEMPLATE_DATA = {
},
}
CAMEL_RE = re.compile(r'([a-z]|SSL)([A-Z])')
def deCamelCase(text):
"""Convert CamelCase names to human-readable format."""
return CAMEL_RE.sub(lambda m: m.group(1) + ' ' + m.group(2), text)
def make_field(name, Type, NoEcho, Default, Description, AllowedValues=None,
**kwargs):
"""Create a form field using the parameters from a Heat template."""
label = deCamelCase(name)
label = utils.de_camel_case(name)
Widget = django.forms.TextInput
attrs = {}
widget_kwargs = {}

View File

@ -32,7 +32,11 @@ def data(TEST):
stacks.StackManager(None),
{'id': 'stack-id-1',
'stack_name': 'overcloud',
'stack_status': 'RUNNING'})
'stack_status': 'RUNNING',
'parameters': {
'one': 'one',
'two': 'two'
}})
TEST.heatclient_stacks.add(stack_1)
# Events

21
tuskar_ui/utils.py Normal file
View File

@ -0,0 +1,21 @@
# -*- coding: utf8 -*-
#
# 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.
import re
CAMEL_RE = re.compile(r'([a-z]|SSL)([A-Z])')
def de_camel_case(text):
"""Convert CamelCase names to human-readable format."""
return CAMEL_RE.sub(lambda m: m.group(1) + ' ' + m.group(2), text)