ValidateTemplate API call framework
This is a start on issue #111 While no actual validation is done by this patch, this patch introduces the framework for validating in each of the resource types and returning an appropriate error when a validation error occurs. Signed-off-by: Steven Dake <sdake@redhat.com>
This commit is contained in:
parent
6bae53753b
commit
9e2c35efa8
11
bin/heat
11
bin/heat
|
@ -61,7 +61,8 @@ def template_validate(options, arguments):
|
||||||
it is in the correct format.
|
it is in the correct format.
|
||||||
|
|
||||||
Usage: heat validate \\
|
Usage: heat validate \\
|
||||||
[--template-file=<template file>|--template-url=<template URL>]
|
[--template-file=<template file>|--template-url=<template URL>] \\
|
||||||
|
[options]
|
||||||
|
|
||||||
--template-file: Specify a local template file.
|
--template-file: Specify a local template file.
|
||||||
--template-url: Specify a URL pointing to a stack description template.
|
--template-url: Specify a URL pointing to a stack description template.
|
||||||
|
@ -75,6 +76,14 @@ def template_validate(options, arguments):
|
||||||
logging.error('Please specify a template file or url')
|
logging.error('Please specify a template file or url')
|
||||||
return utils.FAILURE
|
return utils.FAILURE
|
||||||
|
|
||||||
|
if options.parameters:
|
||||||
|
count = 1
|
||||||
|
for p in options.parameters.split(';'):
|
||||||
|
(n, v) = p.split('=')
|
||||||
|
parameters['Parameters.member.%d.ParameterKey' % count] = n
|
||||||
|
parameters['Parameters.member.%d.ParameterValue' % count] = v
|
||||||
|
count = count + 1
|
||||||
|
|
||||||
client = get_client(options)
|
client = get_client(options)
|
||||||
result = client.validate_template(**parameters)
|
result = client.validate_template(**parameters)
|
||||||
print json.dumps(result, indent=2)
|
print json.dumps(result, indent=2)
|
||||||
|
|
|
@ -164,7 +164,10 @@ class StackController(object):
|
||||||
|
|
||||||
logger.info('validate_template')
|
logger.info('validate_template')
|
||||||
try:
|
try:
|
||||||
return con.validate_template(stack, **req.params)
|
return rpc.call(con, 'engine',
|
||||||
|
{'method': 'validate_template',
|
||||||
|
'args': {'template': stack,
|
||||||
|
'params': dict(req.params)}})
|
||||||
except rpc_common.RemoteError as ex:
|
except rpc_common.RemoteError as ex:
|
||||||
return webob.exc.HTTPBadRequest(str(ex))
|
return webob.exc.HTTPBadRequest(str(ex))
|
||||||
|
|
||||||
|
@ -179,6 +182,7 @@ class StackController(object):
|
||||||
{'method': 'delete_stack',
|
{'method': 'delete_stack',
|
||||||
'args': {'stack_name': req.params['StackName'],
|
'args': {'stack_name': req.params['StackName'],
|
||||||
'params': dict(req.params)}})
|
'params': dict(req.params)}})
|
||||||
|
|
||||||
except rpc_common.RemoteError as ex:
|
except rpc_common.RemoteError as ex:
|
||||||
return webob.exc.HTTPBadRequest(str(ex))
|
return webob.exc.HTTPBadRequest(str(ex))
|
||||||
|
|
||||||
|
|
|
@ -45,6 +45,12 @@ class ElasticIp(Resource):
|
||||||
self.instance_id_set(ips.id)
|
self.instance_id_set(ips.id)
|
||||||
self.state_set(self.CREATE_COMPLETE)
|
self.state_set(self.CREATE_COMPLETE)
|
||||||
|
|
||||||
|
def validate(self):
|
||||||
|
'''
|
||||||
|
Validate the ip address here
|
||||||
|
'''
|
||||||
|
return None
|
||||||
|
|
||||||
def reload(self):
|
def reload(self):
|
||||||
'''
|
'''
|
||||||
get the ipaddress here
|
get the ipaddress here
|
||||||
|
|
|
@ -193,6 +193,12 @@ class Instance(Resource):
|
||||||
else:
|
else:
|
||||||
self.state_set(self.CREATE_FAILED)
|
self.state_set(self.CREATE_FAILED)
|
||||||
|
|
||||||
|
def validate(self):
|
||||||
|
'''
|
||||||
|
Validate the server's ip address
|
||||||
|
'''
|
||||||
|
return None
|
||||||
|
|
||||||
def reload(self):
|
def reload(self):
|
||||||
'''
|
'''
|
||||||
re-read the server's ipaddress so FnGetAtt works.
|
re-read the server's ipaddress so FnGetAtt works.
|
||||||
|
|
|
@ -157,21 +157,22 @@ class EngineManager(manager.Manager):
|
||||||
return {'stack': {'id': new_s.id, 'name': new_s.name,\
|
return {'stack': {'id': new_s.id, 'name': new_s.name,\
|
||||||
'created_at': str(new_s.created_at)}}
|
'created_at': str(new_s.created_at)}}
|
||||||
|
|
||||||
def validate_template(self, req, body=None):
|
def validate_template(self, context, template, params):
|
||||||
"""
|
"""
|
||||||
The validate_template method uses the stack parser to check
|
The validate_template method uses the stack parser to check
|
||||||
the validity of a template.
|
the validity of a template.
|
||||||
|
|
||||||
arg1 -> http request params.
|
arg1 -> RPC context.
|
||||||
arg2 -> Template body.
|
arg3 -> Template of stack you want to create.
|
||||||
|
arg4 -> Params passed from API.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
logger.info('validate_template')
|
logger.info('validate_template')
|
||||||
if body is None:
|
if template is None:
|
||||||
msg = _("No Template provided.")
|
msg = _("No Template provided.")
|
||||||
return webob.exc.HTTPBadRequest(explanation=msg)
|
return webob.exc.HTTPBadRequest(explanation=msg)
|
||||||
|
|
||||||
s = parser.Stack('validate', body, 0, req.params)
|
s = parser.Stack('validate', template, 0, params)
|
||||||
res = s.validate()
|
res = s.validate()
|
||||||
|
|
||||||
return res
|
return res
|
||||||
|
|
|
@ -111,10 +111,28 @@ class Stack(object):
|
||||||
http://docs.amazonwebservices.com/AWSCloudFormation/latest/ \
|
http://docs.amazonwebservices.com/AWSCloudFormation/latest/ \
|
||||||
APIReference/API_ValidateTemplate.html
|
APIReference/API_ValidateTemplate.html
|
||||||
'''
|
'''
|
||||||
response = {'ValidateTemplateResult': {
|
|
||||||
'Description': 'bla',
|
|
||||||
'Parameters': []}}
|
|
||||||
|
|
||||||
|
order = self.get_create_order()
|
||||||
|
|
||||||
|
response = None
|
||||||
|
|
||||||
|
for r in order:
|
||||||
|
try:
|
||||||
|
res = self.resources[r].validate()
|
||||||
|
if res:
|
||||||
|
print 'setting response'
|
||||||
|
response = {'ValidateTemplateResult': {
|
||||||
|
'Description': 'Malformed Query Response [%s]' % res,
|
||||||
|
'Parameters': []}}
|
||||||
|
break
|
||||||
|
except Exception as ex:
|
||||||
|
logger.exception('validate')
|
||||||
|
failed = True
|
||||||
|
|
||||||
|
if response == None:
|
||||||
|
response = {'ValidateTemplateResult': {
|
||||||
|
'Description': 'Successfully validated',
|
||||||
|
'Parameters': []}}
|
||||||
for p in self.parms:
|
for p in self.parms:
|
||||||
jp = {'member': {}}
|
jp = {'member': {}}
|
||||||
res = jp['member']
|
res = jp['member']
|
||||||
|
|
|
@ -106,6 +106,13 @@ class Resource(object):
|
||||||
self.stack.resolve_joins(self.t)
|
self.stack.resolve_joins(self.t)
|
||||||
self.stack.resolve_base64(self.t)
|
self.stack.resolve_base64(self.t)
|
||||||
|
|
||||||
|
def validate(self):
|
||||||
|
logger.info('validating %s name:%s' % (self.t['Type'], self.name))
|
||||||
|
|
||||||
|
self.stack.resolve_attributes(self.t)
|
||||||
|
self.stack.resolve_joins(self.t)
|
||||||
|
self.stack.resolve_base64(self.t)
|
||||||
|
|
||||||
def instance_id_set(self, inst):
|
def instance_id_set(self, inst):
|
||||||
self.instance_id = inst
|
self.instance_id = inst
|
||||||
|
|
||||||
|
|
|
@ -73,6 +73,12 @@ class SecurityGroup(Resource):
|
||||||
|
|
||||||
self.state_set(self.CREATE_COMPLETE)
|
self.state_set(self.CREATE_COMPLETE)
|
||||||
|
|
||||||
|
def validate(self):
|
||||||
|
'''
|
||||||
|
Validate the security group
|
||||||
|
'''
|
||||||
|
return None
|
||||||
|
|
||||||
def delete(self):
|
def delete(self):
|
||||||
if self.state == self.DELETE_IN_PROGRESS or \
|
if self.state == self.DELETE_IN_PROGRESS or \
|
||||||
self.state == self.DELETE_COMPLETE:
|
self.state == self.DELETE_COMPLETE:
|
||||||
|
|
|
@ -46,6 +46,12 @@ class Volume(Resource):
|
||||||
else:
|
else:
|
||||||
self.state_set(self.CREATE_FAILED)
|
self.state_set(self.CREATE_FAILED)
|
||||||
|
|
||||||
|
def validate(self):
|
||||||
|
'''
|
||||||
|
Validate the volume
|
||||||
|
'''
|
||||||
|
return None
|
||||||
|
|
||||||
def delete(self):
|
def delete(self):
|
||||||
if self.state == self.DELETE_IN_PROGRESS or \
|
if self.state == self.DELETE_IN_PROGRESS or \
|
||||||
self.state == self.DELETE_COMPLETE:
|
self.state == self.DELETE_COMPLETE:
|
||||||
|
|
|
@ -49,6 +49,12 @@ class WaitConditionHandle(Resource):
|
||||||
|
|
||||||
self.state_set(self.CREATE_COMPLETE)
|
self.state_set(self.CREATE_COMPLETE)
|
||||||
|
|
||||||
|
def validate(self):
|
||||||
|
'''
|
||||||
|
Validate the wait condition
|
||||||
|
'''
|
||||||
|
return None
|
||||||
|
|
||||||
def delete(self):
|
def delete(self):
|
||||||
if self.state == self.DELETE_IN_PROGRESS or \
|
if self.state == self.DELETE_IN_PROGRESS or \
|
||||||
self.state == self.DELETE_COMPLETE:
|
self.state == self.DELETE_COMPLETE:
|
||||||
|
|
Loading…
Reference in New Issue