# License for the specific language governing permissions and limitations
# under the License.
-from functools import partial
import logging
import routes
WSGI router for Heat v1 API requests.
"""
- def action_match(self, action, environ, result):
- req = Request(environ)
- env_action = req.GET.get("Action")
- return action == env_action
-
- def action(self, name):
- """
- Return a function that matches a request's `Action` query parameter to
- the given value.
- """
- return partial(self.action_match, name)
+ _actions = {
+ 'list': 'ListStacks',
+ 'create': 'CreateStack',
+ 'describe': 'DescribeStacks',
+ 'delete': 'DeleteStack',
+ 'update': 'UpdateStack',
+ 'events_list': 'DescribeStackEvents',
+ 'validate_template': 'ValidateTemplate',
+ }
def __init__(self, conf, **local_conf):
self.conf = conf
stacks_resource = stacks.create_resource(conf)
mapper.resource("stack", "stacks", controller=stacks_resource,
- collection={'detail': 'GET'})
-
- mapper.connect("/", controller=stacks_resource,
- action="list", conditions=dict(function=self.action('ListStacks')))
-
- mapper.connect("/", controller=stacks_resource,
- action="create",
- conditions=dict(function=self.action('CreateStack')))
-
- mapper.connect("/", controller=stacks_resource,
- action="describe",
- conditions=dict(function=self.action('DescribeStacks')))
+ collection={'detail': 'GET'})
- mapper.connect("/", controller=stacks_resource,
- action="delete",
- conditions=dict(function=self.action('DeleteStack')))
+ def conditions(action):
+ api_action = self._actions[action]
- mapper.connect("/", controller=stacks_resource,
- action="update",
- conditions=dict(function=self.action('UpdateStack')))
+ def action_match(environ, result):
+ req = Request(environ)
+ env_action = req.GET.get("Action")
+ return env_action == api_action
- mapper.connect("/", controller=stacks_resource,
- action="events_list",
- conditions=dict(function=self.action('DescribeStackEvents')))
+ return {'function': action_match}
- mapper.connect("/", controller=stacks_resource,
- action="validate_template",
- conditions=dict(function=self.action('ValidateTemplate')
- ))
+ for action in self._actions:
+ mapper.connect("/", controller=stacks_resource, action=action,
+ conditions=conditions(action))
mapper.connect("/", controller=stacks_resource, action="index")
self.state_set(self.CREATE_IN_PROGRESS)
Resource.create(self)
props = self.t['Properties']
- if not 'KeyName' in props:
- raise exception.UserParameterMissing(key='KeyName')
- if not 'InstanceType' in props:
- raise exception.UserParameterMissing(key='InstanceType')
- if not 'ImageId' in props:
- raise exception.UserParameterMissing(key='ImageId')
+ required_props = ('KeyName', 'InstanceType', 'ImageId')
+ for key in required_props:
+ if key not in props:
+ raise exception.UserParameterMissing(key=key)
security_groups = props.get('SecurityGroups')
flavor = self.itype_oflavor[self.t['Properties']['InstanceType']]
key_name = self.t['Properties']['KeyName']
- keypairs = self.nova().keypairs.list()
- key_exists = False
- for k in keypairs:
- if k.name == key_name:
- # cool it exists
- key_exists = True
- break
- if not key_exists:
+ keypairs = [k.name for k in self.nova().keypairs.list()]
+ if key_name not in keypairs:
raise exception.UserKeyPairMissing(key_name=key_name)
image_name = self.t['Properties']['ImageId']
logger = logging.getLogger(__file__)
+(RESOURCE_CLASSES,) = ({
+ 'AWS::EC2::Instance': instance.Instance,
+ 'AWS::EC2::Volume': volume.Volume,
+ 'AWS::EC2::VolumeAttachment': volume.VolumeAttachment,
+ 'AWS::EC2::EIP': eip.ElasticIp,
+ 'AWS::EC2::EIPAssociation': eip.ElasticIpAssociation,
+ 'AWS::EC2::SecurityGroup': security_group.SecurityGroup,
+ 'AWS::CloudFormation::WaitConditionHandle':
+ wait_condition.WaitConditionHandle,
+ 'AWS::CloudFormation::WaitCondition': wait_condition.WaitCondition,
+},)
+
+
class Stack(object):
IN_PROGRESS = 'IN_PROGRESS'
CREATE_FAILED = 'CREATE_FAILED'
self.creds = parms['KeyStoneCreds']
self.resources = {}
- for r in self.t['Resources']:
- type = self.t['Resources'][r]['Type']
- if type == 'AWS::EC2::Instance':
- self.resources[r] = instance.Instance(r,
- self.t['Resources'][r], self)
- elif type == 'AWS::EC2::Volume':
- self.resources[r] = volume.Volume(r,
- self.t['Resources'][r], self)
- elif type == 'AWS::EC2::VolumeAttachment':
- self.resources[r] = volume.VolumeAttachment(r,
- self.t['Resources'][r], self)
- elif type == 'AWS::EC2::EIP':
- self.resources[r] = eip.ElasticIp(r,
- self.t['Resources'][r], self)
- elif type == 'AWS::EC2::EIPAssociation':
- self.resources[r] = eip.ElasticIpAssociation(r,
- self.t['Resources'][r], self)
- elif type == 'AWS::EC2::SecurityGroup':
- self.resources[r] = security_group.SecurityGroup(r,
- self.t['Resources'][r], self)
- elif type == 'AWS::CloudFormation::WaitConditionHandle':
- self.resources[r] = wait_condition.WaitConditionHandle(r,
- self.t['Resources'][r], self)
- elif type == 'AWS::CloudFormation::WaitCondition':
- self.resources[r] = wait_condition.WaitCondition(r,
- self.t['Resources'][r], self)
- else:
- self.resources[r] = resources.GenericResource(r,
- self.t['Resources'][r], self)
+ for rname, res in self.t['Resources'].items():
+ ResourceClass = RESOURCE_CLASSES.get(res['Type'],
+ resources.GenericResource)
+ self.resources[rname] = ResourceClass(rname, res, self)
- self.calulate_dependencies(self.t['Resources'][r],
- self.resources[r])
+ self.calulate_dependencies(res, self.resources[rname])
def validate(self):
'''