From 4679fb01c641053d45a197b598e28552144391a9 Mon Sep 17 00:00:00 2001 From: Tomas Sedovic Date: Mon, 2 Apr 2012 18:00:00 +0200 Subject: [PATCH] Allow templates specified from local filesystem Fixes #47 Passing a template file (as opposed to a URL) to the CLI: ./heat -d create wordpress \ --template-file=../templates/WordPress_Single_Instance.template caused a 'URI too long' error. The reason was that we were passing the entire template contents to the Heat API server inside the URL params. This makes sure that templates are passed around inside HTTP body rather than the URL. --- heat/api/v1/__init__.py | 2 +- heat/api/v1/stacks.py | 22 +++++++++++----------- heat/client.py | 20 ++++++++++++-------- heat/common/client.py | 5 +++++ heat/engine/client.py | 21 ++++----------------- 5 files changed, 33 insertions(+), 37 deletions(-) diff --git a/heat/api/v1/__init__.py b/heat/api/v1/__init__.py index 8ce18894..550e3a66 100644 --- a/heat/api/v1/__init__.py +++ b/heat/api/v1/__init__.py @@ -49,6 +49,6 @@ class API(wsgi.Router): mapper.connect("/DescribeStackEvents", controller=stacks_resource, action="events_list", conditions=dict(method=["GET"])) mapper.connect("/ValidateTemplate", controller=stacks_resource, - action="validate_template", conditions=dict(method=["GET"])) + action="validate_template", conditions=dict(method=["POST"])) super(API, self).__init__(mapper) diff --git a/heat/api/v1/stacks.py b/heat/api/v1/stacks.py index d1b9bd4a..6943a578 100644 --- a/heat/api/v1/stacks.py +++ b/heat/api/v1/stacks.py @@ -75,13 +75,13 @@ class StackController(object): return res - def _get_template(self, req): - if req.params.has_key('TemplateBody'): + def _get_template(self, body): + if body.has_key('TemplateBody'): logger.info('TemplateBody ...') - return req.params['TemplateBody'] - elif req.params.has_key('TemplateUrl'): - logger.info('TemplateUrl %s' % req.params['TemplateUrl']) - url = urlparse.urlparse(req.params['TemplateUrl']) + return body['TemplateBody'] + elif body.has_key('TemplateUrl'): + logger.info('TemplateUrl %s' % body['TemplateUrl']) + url = urlparse.urlparse(body['TemplateUrl']) if url.scheme == 'https': conn = httplib.HTTPSConnection(url.netloc) else: @@ -99,14 +99,14 @@ class StackController(object): return None - def create(self, req): + def create(self, req, body): """ Returns the following information for all stacks: """ c = engine.get_engine_client(req.context) try: - templ = self._get_template(req) + templ = self._get_template(body) except socket.gaierror: msg = _('Invalid Template URL') return webob.exc.HTTPBadRequest(explanation=msg) @@ -119,16 +119,16 @@ class StackController(object): except ValueError: msg = _("The Template must be a JSON document.") return webob.exc.HTTPBadRequest(explanation=msg) - stack['StackName'] = req.params['StackName'] + stack['StackName'] = body['StackName'] return c.create_stack(stack, **req.params) - def validate_template(self, req): + def validate_template(self, req, body): client = engine.get_engine_client(req.context) try: - templ = self._get_template(req) + templ = self._get_template(body) except socket.gaierror: msg = _('Invalid Template URL') return webob.exc.HTTPBadRequest(explanation=msg) diff --git a/heat/client.py b/heat/client.py index ed73b7c3..a830a697 100644 --- a/heat/client.py +++ b/heat/client.py @@ -58,25 +58,27 @@ class V1Client(base_client.BaseClient): return data def create_stack(self, **kwargs): - - params = self._extract_params(kwargs, SUPPORTED_PARAMS) + body = self._extract_params(kwargs, SUPPORTED_PARAMS) + params = {} self._insert_common_parameters(params) - res = self.do_request("POST", "/CreateStack", params=params) + res = self.do_request("POST", "/CreateStack", params=params, body=body) data = json.loads(res.read()) return data def update_stack(self, **kwargs): - params = self._extract_params(kwargs, SUPPORTED_PARAMS) + body = self._extract_params(kwargs, SUPPORTED_PARAMS) + params = {} self._insert_common_parameters(params) - res = self.do_request("PUT", "/UpdateStack", params=params) + res = self.do_request("PUT", "/UpdateStack", params=params, body=body) data = json.loads(res.read()) return data def delete_stack(self, **kwargs): params = self._extract_params(kwargs, SUPPORTED_PARAMS) self._insert_common_parameters(params) + res = self.do_request("DELETE", "/DeleteStack", params=params) data = json.loads(res.read()) return data @@ -90,10 +92,12 @@ class V1Client(base_client.BaseClient): return data def validate_template(self, **kwargs): - params = self._extract_params(kwargs, SUPPORTED_PARAMS) + body = self._extract_params(kwargs, SUPPORTED_PARAMS) + params = {} self._insert_common_parameters(params) - - res = self.do_request("GET", "/ValidateTemplate", params=params) + + res = self.do_request("POST", "/ValidateTemplate", params=params, + body=body) data = json.loads(res.read()) return data diff --git a/heat/common/client.py b/heat/common/client.py index a3a49d34..b9a1d3ba 100644 --- a/heat/common/client.py +++ b/heat/common/client.py @@ -21,6 +21,7 @@ import collections import errno import functools import httplib +import json import logging import os import urllib @@ -414,6 +415,10 @@ class BaseClient(object): self._authenticate() url = self._construct_url(action, params) + headers = headers or {} + if body and not isinstance(body, basestring): + body = json.dumps(body) + headers['Content-Type'] = 'application/json' return self._do_request(method=method, url=url, body=body, headers=headers) diff --git a/heat/engine/client.py b/heat/engine/client.py index 2bae31db..d82245e0 100644 --- a/heat/engine/client.py +++ b/heat/engine/client.py @@ -91,13 +91,9 @@ class EngineClient(BaseClient): """ Validate the template """ - headers = { - 'Content-Type': 'application/json', - } - logger.info(template) - res = self.do_request("POST", "/validate_template", body=json.dumps(template), - headers=headers, params=kwargs) + res = self.do_request("POST", "/validate_template", template, + params=kwargs) data = json.loads(res.read()) logger.info(data) return data @@ -106,12 +102,7 @@ class EngineClient(BaseClient): """ Tells engine about an stack's metadata """ - headers = { - 'Content-Type': 'application/json', - } - - res = self.do_request("POST", "/stacks", json.dumps(template), - headers=headers, params=kwargs) + res = self.do_request("POST", "/stacks", template, params=kwargs) data = json.loads(res.read()) return data @@ -119,11 +110,7 @@ class EngineClient(BaseClient): """ Updates Engine's information about an stack """ - headers = { - 'Content-Type': 'application/json', - } - - res = self.do_request("PUT", "/stacks/%s" % (stack_id), json.dumps(template), headers) + res = self.do_request("PUT", "/stacks/%s" % (stack_id), template) data = json.loads(res.read()) stack = data['stack'] return stack -- 2.45.2