191
191
user_params=user_params,
192
192
param_defaults=param_defaults)
194
def validate_resource_definitions(self, stack):
195
resources = self.t.get(self.RESOURCES) or {}
196
allowed_keys = set(_RESOURCE_KEYS)
199
for name, snippet in resources.items():
200
data = self.parse(stack, snippet)
202
if not self.validate_resource_key_type(RES_TYPE,
207
args = {'name': name, 'type_key': RES_TYPE}
208
msg = _('Resource %(name)s is missing '
209
'"%(type_key)s"') % args
212
self.validate_resource_key_type(
214
(collections.Mapping, function.Function),
215
'object', allowed_keys, name, data)
216
self.validate_resource_key_type(
218
(collections.Mapping, function.Function),
219
'object', allowed_keys, name, data)
220
self.validate_resource_key_type(
222
collections.Sequence,
223
'list or string', allowed_keys, name, data)
224
self.validate_resource_key_type(
227
'string', allowed_keys, name, data)
228
self.validate_resource_key_type(
230
(collections.Mapping, function.Function),
231
'object', allowed_keys, name, data)
232
except (TypeError, ValueError) as ex:
233
raise exception.StackValidationFailed(message=six.text_type(ex))
194
235
def resource_definitions(self, stack):
195
allowed_keys = set(_RESOURCE_KEYS)
236
resources = self.t.get(self.RESOURCES) or {}
197
238
def rsrc_defn_item(name, snippet):
198
239
data = self.parse(stack, snippet)
200
def get_check_type(key, valid_types, typename, default=None):
203
if not isinstance(field, valid_types):
204
args = {'name': name, 'key': key, 'typename': typename}
205
msg = _('Resource %(name)s %(key)s type '
206
'must be %(typename)s') % args
212
resource_type = get_check_type(RES_TYPE,
215
if resource_type is None:
216
args = {'name': name, 'type_key': RES_TYPE}
217
msg = _('Resource %(name)s is missing "%(type_key)s"') % args
220
properties = get_check_type(RES_PROPERTIES,
221
(collections.Mapping,
225
metadata = get_check_type(RES_METADATA,
226
(collections.Mapping,
230
depends = get_check_type(RES_DEPENDS_ON,
231
collections.Sequence,
234
if isinstance(depends, six.string_types):
241
depends = data.get(RES_DEPENDS_ON)
244
elif isinstance(depends, six.string_types):
235
245
depends = [depends]
237
deletion_policy = get_check_type(RES_DELETION_POLICY,
241
update_policy = get_check_type(RES_UPDATE_POLICY,
242
(collections.Mapping,
247
if key not in allowed_keys:
248
raise ValueError(_('"%s" is not a valid keyword '
249
'inside a resource definition') % key)
251
defn = rsrc_defn.ResourceDefinition(
253
properties=properties,
256
deletion_policy=deletion_policy,
257
update_policy=update_policy,
248
'resource_type': data.get(RES_TYPE),
249
'properties': data.get(RES_PROPERTIES),
250
'metadata': data.get(RES_METADATA),
252
'deletion_policy': data.get(RES_DELETION_POLICY),
253
'update_policy': data.get(RES_UPDATE_POLICY),
257
defn = rsrc_defn.ResourceDefinition(name, **kwargs)
259
258
return name, defn
261
resources = self.t.get(self.RESOURCES) or {}
262
260
return dict(rsrc_defn_item(name, data)
263
261
for name, data in resources.items())
293
291
'Fn::ResourceFacade': hot_funcs.Removed,
294
292
'Ref': hot_funcs.Removed,
296
class HOTemplate20150430(HOTemplate20141016):
298
'digest': hot_funcs.Digest,
299
'get_attr': hot_funcs.GetAtt,
300
'get_file': hot_funcs.GetFile,
301
'get_param': hot_funcs.GetParam,
302
'get_resource': cfn_funcs.ResourceRef,
303
'list_join': hot_funcs.Join,
304
'repeat': hot_funcs.Repeat,
305
'resource_facade': hot_funcs.ResourceFacade,
306
'str_replace': hot_funcs.Replace,
308
'Fn::Select': cfn_funcs.Select,
310
# functions removed from 20130523
311
'Fn::GetAZs': hot_funcs.Removed,
312
'Fn::Join': hot_funcs.Removed,
313
'Fn::Split': hot_funcs.Removed,
314
'Fn::Replace': hot_funcs.Removed,
315
'Fn::Base64': hot_funcs.Removed,
316
'Fn::MemberListToMap': hot_funcs.Removed,
317
'Fn::ResourceFacade': hot_funcs.Removed,
318
'Ref': hot_funcs.Removed,