Implementing the validate is still a TODO.
Re: issue #1
Signed-off-by: Angus Salkeld <asalkeld@redhat.com>
def template_validate(options, arguments):
'''
'''
- pass
+ parameters = {}
+ if options.template_file:
+ parameters['TemplateBody'] = open(options.template_file).read()
+ elif options.template_url:
+ parameters['TemplateUrl'] = options.template_url
+ else:
+ print 'Please specify a template file or url'
+ return FAILURE
+
+ c = get_client(options)
+ result = c.validate_template(**parameters)
+ print json.dumps(result, indent=2)
@catch_error('gettemplate')
def get_template(options, arguments):
action="update", conditions=dict(method=["PUT"]))
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"]))
super(API, self).__init__(mapper)
return c.create_stack(stack, **req.params)
+ def validate_template(self, req):
+
+ c = engine.get_engine_client(req.context)
+
+ try:
+ templ = self._get_template(req)
+ except socket.gaierror:
+ msg = _('Invalid Template URL')
+ return webob.exc.HTTPBadRequest(explanation=msg)
+ if templ is None:
+ msg = _("TemplateBody or TemplateUrl were not given.")
+ return webob.exc.HTTPBadRequest(explanation=msg)
+
+ try:
+ stack = json.loads(templ)
+ except ValueError:
+ msg = _("The Template must be a JSON document.")
+ return webob.exc.HTTPBadRequest(explanation=msg)
+
+ logger.info('validate_template')
+ return c.validate_template(stack, **req.params)
+
def delete(self, req):
"""
Returns the following information for all stacks:
data = json.loads(res.read())
return data
+ def validate_template(self, **kwargs):
+ params = self._extract_params(kwargs, SUPPORTED_PARAMS)
+ self._insert_common_parameters(params)
+
+ res = self.do_request("GET", "/ValidateTemplate", params=params)
+ data = json.loads(res.read())
+ return data
+
HeatClient = V1Client
mapper.resource("stack", "stacks", controller=stacks_resource,
collection={'detail': 'GET'})
mapper.connect("/", controller=stacks_resource, action="index")
+ mapper.connect("/validate_template", controller=stacks_resource,
+ action="validate_template", conditions=dict(method=["POST"]))
+
events_resource = events.create_resource(conf)
mapper.resource("event", "events", controller=events_resource,
return {'stack': {'id': body['StackName']}}
+ def validate_template(self, req, body=None):
+
+ logger.info('validate_template')
+ if body is None:
+ msg = _("No Template provided.")
+ return webob.exc.HTTPBadRequest(explanation=msg)
+
+ s = parser.Stack('validate', body, req.params)
+ res = s.validate()
+
+ return res
+
def delete(self, req, id):
if not stack_db.has_key(id):
return webob.exc.HTTPNotFound('No stack by that name')
data = json.loads(res.read())['stacks']
return data
+ def validate_template(self, template, **kwargs):
+ """
+ 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)
+ data = json.loads(res.read())
+ logger.info(data)
+ return data
def create_stack(self, template, **kwargs):
"""
logger = logging.getLogger('heat.engine.parser')
-
class Stack:
def __init__(self, stack_name, template, parms=None):
self.calulate_dependancies(self.t['Resources'][r], self.resources[r])
+ def validate(self):
+ '''
+ If you are wondering where the actual validation is, me too.
+ it is just not obvious how to respond to validation failures.
+ http://docs.amazonwebservices.com/AWSCloudFormation/latest/APIReference/API_ValidateTemplate.html
+ '''
+ response = { 'ValidateTemplateResult': {
+ 'Description': 'bla',
+ 'Parameters': []
+ }
+ }
+
+ for p in self.parms:
+ jp = {'member': {}}
+ res = jp['member']
+ res['NoEcho'] = 'false'
+ res['ParameterKey'] = p
+ if self.parms[p].has_key('Description'):
+ res['Description'] = self.parms[p]['Description']
+ else:
+ res['Description'] = ''
+ if self.parms[p].has_key('Default'):
+ res['DefaultValue'] = self.parms[p]['Default']
+ else:
+ res['DefaultValue'] = ''
+ response['ValidateTemplateResult']['Parameters'].append(res)
+ return response
+
def start(self):
# start Volumes first.
for r in self.t['Resources']:
for index, item in enumerate(s):
self.calulate_dependancies(item, r)
-
def _apply_user_parameter(self, key, value):
- logger.info('_apply_user_parameter %s=%s ' % (key, value))
- if not self.t.has_key('Parameters'):
- self.t['Parameters'] = {}
-
- if not self.t['Parameters'].has_key(key):
- self.t['Parameters'][key] = {}
+ logger.debug('appling user parameter %s=%s ' % (key, value))
- self.t['Parameters'][key]['Value'] = value
+ if not self.parms.has_key(key):
+ self.parms[key] = {}
+ self.parms[key]['Value'] = value
def _apply_user_parameters(self, parms):
for p in parms:
value_name = 'Parameters.member.%s.ParameterValue' % s[2]
self._apply_user_parameter(parms[key_name], parms[value_name])
except:
- logger.error('could not apply parameter %s' % p)
-
+ logger.error('Could not apply parameter %s' % p)
def parameter_get(self, key):
if self.parms[key] == None:
- #print 'None Ref: %s' % key
- return '=EMPTY='
+ logger.warn('Trying to reference parameter: %s, but it is empty' % key)
+ return ''
elif self.parms[key].has_key('Value'):
return self.parms[key]['Value']
elif self.parms[key].has_key('Default'):
return self.parms[key]['Default']
else:
- #print 'Missing Ref: %s' % key
- return '=EMPTY='
-
+ logger.warn('Trying to reference parameter: %s, but no Value or Default' % key)
+ return ''
def resolve_static_refs(self, s):
'''