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