Adds basic deployment log API and tab

Change-Id: Iff44fd96f5e4d3f5f12f3dcbf58aa735f2d14d1b
Implements: blueprint tripleo-deployment-log
This commit is contained in:
Tzu-Mainn Chen 2014-01-23 15:52:22 -05:00
parent dcb54f0995
commit 53c59e53eb
5 changed files with 140 additions and 9 deletions

View File

@ -136,6 +136,22 @@ class Overcloud(base.APIDictWrapper):
return stack
return None
@cached_property
def stack_events(self):
"""Return the Heat Events associated with this Overcloud
:return: list of Heat Events associated with this Overcloud;
or an empty list if there is no Stack associated with
this Overcloud, or there are no Events
:rtype: list of heatclient.v1.events.Event
"""
if self.stack_id:
# TODO(Tzu-Mainn Chen): remove test data when possible
# events = heatclient(request).events.get(self.stack_id)
events = test_data().heatclient_events.list()
return events
return []
@cached_property
def is_deployed(self):
"""Check if this Overcloud is successfully deployed.
@ -165,9 +181,9 @@ class Overcloud(base.APIDictWrapper):
# TODO(Tzu-Mainn Chen): uncomment when possible
#resources = tuskarclient(request).overclouds.get_resources(
# self.id, resource_category.id)
resources = [r for r in test_data().heatclient_resources.list()
if r.logical_resource_id == resource_category.name]
if r.logical_resource_id.startswith(
resource_category.name)]
if not with_joins:
return [Resource(r) for r in resources]

View File

@ -44,3 +44,20 @@ class ResourceCategoryInstanceTable(tables.DataTable):
verbose_name = _("Instances")
table_actions = ()
row_actions = ()
class LogTable(tables.DataTable):
timestamp = tables.Column('event_time',
verbose_name=_("Timestamp"))
resource_name = tables.Column('resource_name',
verbose_name=_("Resource Name"))
resource_status = tables.Column('resource_status',
verbose_name=_("Status"))
class Meta:
name = "log"
verbose_name = _("Log")
multi_select = False
table_actions = ()
row_actions = ()

View File

@ -20,6 +20,7 @@ from horizon import exceptions
from horizon import tabs
from tuskar_ui import api
from tuskar_ui.infrastructure.overcloud import tables
class OverviewTab(tabs.Tab):
@ -72,7 +73,18 @@ class ConfigurationTab(tabs.Tab):
return {}
class LogTab(tabs.TableTab):
table_classes = (tables.LogTable,)
name = _("Log")
slug = "log"
template_name = "horizon/common/_detail_table.html"
def get_log_data(self):
overcloud = self.tab_group.kwargs['overcloud']
return overcloud.stack_events
class DetailTabs(tabs.TabGroup):
slug = "detail"
tabs = (OverviewTab, ConfigurationTab)
tabs = (OverviewTab, ConfigurationTab, LogTab)
sticky = True

View File

@ -15,6 +15,7 @@
from __future__ import absolute_import
from glanceclient.v1 import images
from heatclient.v1 import events
from heatclient.v1 import stacks
from tuskar_ui import api
@ -52,6 +53,21 @@ class TuskarAPITests(test.APITestCase):
ret_val = api.Overcloud(overcloud).stack
self.assertIsInstance(ret_val, stacks.Stack)
def test_overcloud_stack_events(self):
overcloud = self.tuskarclient_overclouds.first()
ret_val = api.Overcloud(overcloud).stack_events
for e in ret_val:
self.assertIsInstance(e, events.Event)
self.assertEqual(8, len(ret_val))
def test_overcloud_stack_events_empty(self):
overcloud = self.tuskarclient_overclouds.first()
overcloud['stack_id'] = None
ret_val = api.Overcloud(overcloud).stack_events
self.assertListEqual([], ret_val)
def test_overcloud_is_deployed(self):
overcloud = self.tuskarclient_overclouds.first()

View File

@ -13,6 +13,7 @@
from openstack_dashboard.test.test_data import utils as test_data_utils
from glanceclient.v1 import images
from heatclient.v1 import events
from heatclient.v1 import resources
from heatclient.v1 import stacks
from ironicclient.v1 import node
@ -31,6 +32,75 @@ def data(TEST):
'stack_status': 'RUNNING'})
TEST.heatclient_stacks.add(stack_1)
# Events
TEST.heatclient_events = test_data_utils.TestDataContainer()
event_1 = events.Event(
events.EventManager(None),
{'id': 1,
'stack_id': 'stack-id-1',
'resource_name': 'Controller',
'resource_status': 'CREATE_IN_PROGRESS',
'resource_status_reason': 'state changed',
'event_time': '2014-01-01T07:26:15Z'})
event_2 = events.Event(
events.EventManager(None),
{'id': 2,
'stack_id': 'stack-id-1',
'resource_name': 'Compute0',
'resource_status': 'CREATE_IN_PROGRESS',
'resource_status_reason': 'state changed',
'event_time': '2014-01-01T07:26:27Z'})
event_3 = events.Event(
events.EventManager(None),
{'id': 3,
'stack_id': 'stack-id-1',
'resource_name': 'Compute1',
'resource_status': 'CREATE_IN_PROGRESS',
'resource_status_reason': 'state changed',
'event_time': '2014-01-01T07:26:44Z'})
event_4 = events.Event(
events.EventManager(None),
{'id': 4,
'stack_id': 'stack-id-1',
'resource_name': 'Compute0',
'resource_status': 'CREATE_COMPLETE',
'resource_status_reason': 'state changed',
'event_time': '2014-01-01T07:27:14Z'})
event_5 = events.Event(
events.EventManager(None),
{'id': 5,
'stack_id': 'stack-id-1',
'resource_name': 'Compute2',
'resource_status': 'CREATE_IN_PROGRESS',
'resource_status_reason': 'state changed',
'event_time': '2014-01-01T07:27:31Z'})
event_6 = events.Event(
events.EventManager(None),
{'id': 6,
'stack_id': 'stack-id-1',
'resource_name': 'Compute1',
'resource_status': 'CREATE_COMPLETE',
'resource_status_reason': 'state changed',
'event_time': '2014-01-01T07:28:01Z'})
event_7 = events.Event(
events.EventManager(None),
{'id': 7,
'stack_id': 'stack-id-1',
'resource_name': 'Controller',
'resource_status': 'CREATE_COMPLETE',
'resource_status_reason': 'state changed',
'event_time': '2014-01-01T07:28:59Z'})
event_8 = events.Event(
events.EventManager(None),
{'id': 8,
'stack_id': 'stack-id-1',
'resource_name': 'Compute2',
'resource_status': 'CREATE_COMPLETE',
'resource_status_reason': 'state changed',
'event_time': '2014-01-01T07:29:11Z'})
TEST.heatclient_events.add(event_1, event_2, event_3, event_4,
event_5, event_6, event_7, event_8)
# Node
TEST.ironicclient_nodes = test_data_utils.TestDataContainer()
node_1 = node.Node(
@ -145,8 +215,8 @@ def data(TEST):
resources.ResourceManager(None),
{'id': '1-resource-id',
'stack_id': 'stack-id-1',
'resource_name': 'Compute',
'logical_resource_id': 'Compute',
'resource_name': 'Compute0',
'logical_resource_id': 'Compute0',
'physical_resource_id': 'aa',
'resource_status': 'CREATE_COMPLETE',
'resource_type': 'AWS::EC2::Instance'})
@ -163,8 +233,8 @@ def data(TEST):
resources.ResourceManager(None),
{'id': '3-resource-id',
'stack_id': 'stack-id-1',
'resource_name': 'Compute',
'logical_resource_id': 'Compute',
'resource_name': 'Compute1',
'logical_resource_id': 'Compute1',
'physical_resource_id': 'cc',
'resource_status': 'CREATE_COMPLETE',
'resource_type': 'AWS::EC2::Instance'})
@ -172,8 +242,8 @@ def data(TEST):
resources.ResourceManager(None),
{'id': '4-resource-id',
'stack_id': 'stack-id-4',
'resource_name': 'Compute',
'logical_resource_id': 'Compute',
'resource_name': 'Compute2',
'logical_resource_id': 'Compute2',
'physical_resource_id': 'dd',
'resource_status': 'CREATE_COMPLETE',
'resource_type': 'AWS::EC2::Instance'})