From b6d5a749f1604ed3323aff8e27ca376dc71d4973 Mon Sep 17 00:00:00 2001 From: Tatiana Ovchinnikova Date: Fri, 7 Nov 2014 12:26:04 +0300 Subject: [PATCH] 'Stack Template' tab for Heat Stack Details page Once you launch a stack from any template source (using raw data or template file), there is no possibility to check this template later from Horizon. This patch set adds 'Stack Template' tab to Stack Details page. Partially implements blueprint: heat-ui-improvement Change-Id: I27fb687829f9c060ea55d81bcc0344a6e782da06 --- .../dashboards/project/stacks/tabs.py | 16 +++++++++++++++- .../templates/stacks/_stack_template.html | 8 ++++++++ .../dashboards/project/stacks/views.py | 17 ++++++++++++++++- requirements.txt | 1 + 4 files changed, 40 insertions(+), 2 deletions(-) create mode 100644 openstack_dashboard/dashboards/project/stacks/templates/stacks/_stack_template.html diff --git a/openstack_dashboard/dashboards/project/stacks/tabs.py b/openstack_dashboard/dashboards/project/stacks/tabs.py index 53c698e9f0..f21ff12bd5 100644 --- a/openstack_dashboard/dashboards/project/stacks/tabs.py +++ b/openstack_dashboard/dashboards/project/stacks/tabs.py @@ -139,10 +139,24 @@ class StackResourcesTab(tabs.Tab): request, data=resources, stack=stack), } +class StackTemplateTab(tabs.Tab): + name = _("Template") + slug = "stack_template" + template_name = "project/stacks/_stack_template.html" + + def allowed(self, request): + return policy.check( + (("orchestration", "cloudformation:DescribeStacks"),), + request) + + def get_context_data(self, request): + return {"stack_template": self.tab_group.kwargs['stack_template']} + + class StackDetailTabs(tabs.TabGroup): slug = "stack_details" tabs = (StackTopologyTab, StackOverviewTab, StackResourcesTab, - StackEventsTab) + StackEventsTab, StackTemplateTab) sticky = True diff --git a/openstack_dashboard/dashboards/project/stacks/templates/stacks/_stack_template.html b/openstack_dashboard/dashboards/project/stacks/templates/stacks/_stack_template.html new file mode 100644 index 0000000000..085c75fe7a --- /dev/null +++ b/openstack_dashboard/dashboards/project/stacks/templates/stacks/_stack_template.html @@ -0,0 +1,8 @@ +{% load i18n sizeformat %} + +

{% trans "Stack Template" %}

+ +
+
{{ stack_template }}
+  
+
diff --git a/openstack_dashboard/dashboards/project/stacks/views.py b/openstack_dashboard/dashboards/project/stacks/views.py index 53b9bc598c..729aa7010e 100644 --- a/openstack_dashboard/dashboards/project/stacks/views.py +++ b/openstack_dashboard/dashboards/project/stacks/views.py @@ -14,6 +14,8 @@ import json import logging from operator import attrgetter +import yaml + from django.core.urlresolvers import reverse from django.core.urlresolvers import reverse_lazy from django.http import HttpResponse # noqa @@ -216,9 +218,22 @@ class DetailView(tabs.TabView): msg = _("Unable to retrieve stack.") exceptions.handle(request, msg, redirect=self.get_redirect_url()) + @memoized.memoized_method + def get_template(self, request, **kwargs): + try: + stack_template = api.heat.template_get( + request, + kwargs['stack_id']) + return yaml.safe_dump(stack_template, indent=2) + except Exception: + msg = _("Unable to retrieve stack template.") + exceptions.handle(request, msg, redirect=self.get_redirect_url()) + def get_tabs(self, request, **kwargs): stack = self.get_data(request, **kwargs) - return self.tab_group_class(request, stack=stack, **kwargs) + stack_template = self.get_template(request, **kwargs) + return self.tab_group_class( + request, stack=stack, stack_template=stack_template, **kwargs) @staticmethod def get_redirect_url(): diff --git a/requirements.txt b/requirements.txt index f69ca45300..8076b5be48 100644 --- a/requirements.txt +++ b/requirements.txt @@ -38,6 +38,7 @@ python-saharaclient>=0.7.5 python-swiftclient>=2.2.0 python-troveclient>=1.0.7 pytz +PyYAML>=3.1.0 six>=1.7.0 xstatic>=1.0.0 # MIT License xstatic-angular>=1.2.1.1 # MIT License