diff --git a/requirements.txt b/requirements.txt index 3a7c965af..3bd8985ad 100644 --- a/requirements.txt +++ b/requirements.txt @@ -18,5 +18,6 @@ python-troveclient>=1.2.0 python-ironicclient>=0.9.0 python-swiftclient>=2.5.0 python-designateclient>=1.3.0 +python-heatclient>=0.3.0 dogpile.cache>=0.5.3 diff --git a/shade/__init__.py b/shade/__init__.py index 3a0001fd8..b56ec3ea2 100644 --- a/shade/__init__.py +++ b/shade/__init__.py @@ -29,6 +29,8 @@ import glanceclient import glanceclient.exc from glanceclient.common import utils as glance_utils import ipaddress +from heatclient import client as heat_client +from heatclient.common import template_utils from ironicclient import client as ironic_client from ironicclient import exceptions as ironic_exceptions import jsonpatch @@ -316,6 +318,7 @@ class OpenStackCloud(object): self._designate_client = None self._glance_client = None self._glance_endpoint = None + self._heat_client = None self._ironic_client = None self._keystone_client = None self._neutron_client = None @@ -695,6 +698,24 @@ class OpenStackCloud(object): endpoint=endpoint) return self._glance_client + @property + def heat_client(self): + if self._heat_client is None: + self._heat_client = self._get_client( + 'orchestration', heat_client.Client) + return self._heat_client + + def get_template_contents( + self, template_file=None, template_url=None, + template_object=None, files=None): + try: + return template_utils.get_template_contents( + template_file=template_file, template_url=template_url, + template_object=template_object, files=files) + except Exception as e: + raise OpenStackCloudException( + "Error in processing template files: %s" % str(e)) + @property def swift_client(self): if self._swift_client is None: diff --git a/shade/tests/unit/test_shade.py b/shade/tests/unit/test_shade.py index 767179ae3..87bcae552 100644 --- a/shade/tests/unit/test_shade.py +++ b/shade/tests/unit/test_shade.py @@ -15,6 +15,7 @@ import mock import glanceclient +from heatclient import client as heat_client from keystoneclient.v2_0 import client as k2_client from keystoneclient.v3 import client as k3_client from neutronclient.common import exceptions as n_exc @@ -111,6 +112,20 @@ class TestShade(base.TestCase): service_type='image', session=mock.ANY, ) + @mock.patch.object(shade.OpenStackCloud, 'keystone_session') + @mock.patch.object(heat_client, 'Client') + def test_heat_args(self, mock_client, mock_keystone_session): + mock_keystone_session.return_value = None + self.cloud.heat_client + mock_client.assert_called_with( + endpoint_type='public', + region_name='', + service_name=None, + service_type='orchestration', + session=mock.ANY, + version='1' + ) + @mock.patch.object(shade.OpenStackCloud, 'search_subnets') def test_get_subnet(self, mock_search): subnet = dict(id='123', name='mickey')