From 105ea22295c3b547e9a7122a7d0e72cd97de342e Mon Sep 17 00:00:00 2001 From: Zane Bitter Date: Thu, 6 Dec 2012 20:12:06 +0100 Subject: [PATCH] Use common implementation for fetching templates bug 1072908 Change-Id: Idad06e8c28cbaed121604bb0de5f79edfacb1efb Signed-off-by: Zane Bitter --- heat/api/cfn/v1/stacks.py | 37 +++++--------------- heat/api/openstack/v1/stacks.py | 53 ++++++++--------------------- heat/engine/resources/stack.py | 5 +-- heat/tests/test_api_openstack_v1.py | 11 +++--- 4 files changed, 29 insertions(+), 77 deletions(-) diff --git a/heat/api/cfn/v1/stacks.py b/heat/api/cfn/v1/stacks.py index 6c616633..20ccdf1b 100644 --- a/heat/api/cfn/v1/stacks.py +++ b/heat/api/cfn/v1/stacks.py @@ -17,11 +17,9 @@ Stack endpoint for Heat CloudFormation v1 API. """ -import httplib import json import socket -import urlparse -import errno + from heat.api.aws import exception from heat.api.aws import utils as api_utils from heat.common import wsgi @@ -29,6 +27,7 @@ from heat.rpc import client as rpc_client from heat.common import template_format from heat.rpc import api as engine_api from heat.common import identifier +from heat.common import urlfetch import heat.openstack.common.rpc.common as rpc_common @@ -224,36 +223,16 @@ class StackController(object): Get template file contents, either from local file or URL """ if 'TemplateBody' in req.params: - logger.info('TemplateBody ...') + logger.debug('TemplateBody ...') return req.params['TemplateBody'] elif 'TemplateUrl' in req.params: - logger.info('TemplateUrl %s' % req.params['TemplateUrl']) - url = urlparse.urlparse(req.params['TemplateUrl']) - if url.scheme == 'https': - conn = httplib.HTTPSConnection(url.netloc) - else: - conn = httplib.HTTPConnection(url.netloc) - + url = req.params['TemplateUrl'] + logger.debug('TemplateUrl %s' % url) try: - conn.request("GET", url.path) - except Exception as e: - if e.errno == errno.ECONNREFUSED: - msg = _('Connection refused to %s' % url.netloc) - raise exception.HeatInvalidParameterValueError(detail=msg) - raise - - r1 = conn.getresponse() - logger.info('status %d' % r1.status) - if r1.status == 200: # OK - data = r1.read() - conn.close() - elif r1.status == 404: # NOT_FOUND - msg = _('No match found for %s' % req.params['TemplateUrl']) - raise exception.HeatInvalidParameterValueError(detail=msg) - else: - msg = _('Unexpected error, request returned %d' % r1.status) + return urlfetch.get(url) + except IOError as exc: + msg = _('Failed to fetch template: %s') % str(exc) raise exception.HeatInvalidParameterValueError(detail=msg) - return data return None diff --git a/heat/api/openstack/v1/stacks.py b/heat/api/openstack/v1/stacks.py index 3fef4aa7..c5717a91 100644 --- a/heat/api/openstack/v1/stacks.py +++ b/heat/api/openstack/v1/stacks.py @@ -17,11 +17,7 @@ Stack endpoint for Heat v1 ReST API. """ -import httplib import itertools -import json -import socket -import urlparse from webob import exc from heat.api.openstack.v1 import util @@ -29,6 +25,7 @@ from heat.common import wsgi from heat.common import template_format from heat.rpc import api as engine_api from heat.rpc import client as rpc_client +from heat.common import urlfetch import heat.openstack.common.rpc.common as rpc_common from heat.openstack.common import log as logging @@ -78,49 +75,27 @@ class InstantiationData(object): raise exc.HTTPBadRequest(explanation=_("No stack name specified")) return self.data[self.PARAM_STACK_NAME] - def _load_template(self, template_url): - """ - Retrieve a template from a URL, in JSON - or YAML format. - """ - logger.debug('Template URL %s' % template_url) - url = urlparse.urlparse(template_url) - err_reason = _("Could not retrieve template") - - try: - ConnType = (url.scheme == 'https' and httplib.HTTPSConnection - or httplib.HTTPConnection) - conn = ConnType(url.netloc) - - try: - conn.request("GET", url.path) - resp = conn.getresponse() - logger.info('status %d' % resp.status) - - if resp.status != 200: - raise exc.HTTPBadRequest(explanation=err_reason) - - return self.format_parse(resp.read(), 'Template') - finally: - conn.close() - except socket.gaierror: - raise exc.HTTPBadRequest(explanation=err_reason) - def template(self): """ Get template file contents, either inline or from a URL, in JSON or YAML format. """ if self.PARAM_TEMPLATE in self.data: - tpl = self.data[self.PARAM_TEMPLATE] - if isinstance(tpl, dict): - return tpl - return self.format_parse(self.data[self.PARAM_TEMPLATE], - 'Template') + template_data = self.data[self.PARAM_TEMPLATE] + if isinstance(template_data, dict): + return template_data elif self.PARAM_TEMPLATE_URL in self.data: - return self._load_template(self.data[self.PARAM_TEMPLATE_URL]) + url = self.data[self.PARAM_TEMPLATE_URL] + logger.debug('TemplateUrl %s' % url) + try: + template_data = urlfetch.get(url) + except IOError as ex: + err_reason = _('Could not retrieve template: %s') % str(ex) + raise exc.HTTPBadRequest(explanation=err_reason) + else: + raise exc.HTTPBadRequest(explanation=_("No template specified")) - raise exc.HTTPBadRequest(explanation=_("No template specified")) + return self.format_parse(template_data, 'Template') def user_params(self): """ diff --git a/heat/engine/resources/stack.py b/heat/engine/resources/stack.py index 4f5d8499..ab062a97 100644 --- a/heat/engine/resources/stack.py +++ b/heat/engine/resources/stack.py @@ -20,6 +20,7 @@ from heat.common import exception from heat.common import template_format from heat.engine import resource from heat.engine import parser +from heat.common import urlfetch from heat.openstack.common import log as logging @@ -75,8 +76,8 @@ class Stack(resource.Resource): raise exception.Error(self._nested.state_description) def handle_create(self): - response = urllib2.urlopen(self.properties[PROP_TEMPLATE_URL]) - template = template_format.parse(response.read()) + template_data = urlfetch.get(self.properties[PROP_TEMPLATE_URL]) + template = template_format.parse(template_data) self.create_with_template(template) diff --git a/heat/tests/test_api_openstack_v1.py b/heat/tests/test_api_openstack_v1.py index 03d2832a..3f3efd5a 100644 --- a/heat/tests/test_api_openstack_v1.py +++ b/heat/tests/test_api_openstack_v1.py @@ -14,16 +14,12 @@ import sys -import socket import nose import mox import json -import yaml import unittest from nose.plugins.attrib import attr -import httplib -import urlparse import webob.exc from heat.common import context @@ -32,6 +28,7 @@ from heat.openstack.common import cfg from heat.openstack.common import rpc import heat.openstack.common.rpc.common as rpc_common from heat.common.wsgi import Request +from heat.common import urlfetch import heat.api.openstack.v1.stacks as stacks import heat.api.openstack.v1.resources as resources @@ -103,8 +100,8 @@ blarg: wibble body = {'template_url': url} data = stacks.InstantiationData(body) - self.m.StubOutWithMock(data, '_load_template') - data._load_template(url).AndReturn(template) + self.m.StubOutWithMock(urlfetch, 'get') + urlfetch.get(url).AndReturn(json.dumps(template)) self.m.ReplayAll() self.assertEqual(data.template(), template) @@ -116,7 +113,7 @@ blarg: wibble body = {'template': template, 'template_url': url} data = stacks.InstantiationData(body) - self.m.StubOutWithMock(data, '_load_template') + self.m.StubOutWithMock(urlfetch, 'get') self.m.ReplayAll() self.assertEqual(data.template(), template) -- 2.45.2