def result(self): template = function.resolve(self._string) mapping = function.resolve(self._mapping) if not isinstance(template, six.string_types): raise TypeError(_('"%s" template must be a string') % self.fn_name) if not isinstance(mapping, collections.Mapping): raise TypeError(_('"%s" params must be a map') % self.fn_name) def replace(string, change): placeholder, value = change if not isinstance(placeholder, six.string_types): raise TypeError( _('"%s" param placeholders must be strings') % self.fn_name) if value is None: value = '' if not isinstance( value, (six.string_types, six.integer_types, float, bool)): raise TypeError( _('"%s" params must be strings or numbers') % self.fn_name) return string.replace(placeholder, six.text_type(value)) mapping = collections.OrderedDict( sorted(mapping.items(), key=lambda t: len(t[0]), reverse=True)) return six.moves.reduce(replace, six.iteritems(mapping), template)
def result(self): attr = function.resolve(self.args) if attr == self.METADATA: return self.stack.parent_resource.metadata_get() elif attr == self.UPDATE_POLICY: up = self.stack.parent_resource.t.get('UpdatePolicy', {}) return function.resolve(up) elif attr == self.DELETION_POLICY: dp = self.stack.parent_resource.t.deletion_policy() return function.resolve(dp)
def result(self): path_components = function.resolve(self._path_components) attribute = function.resolve(self._attribute) r = self._resource() if (r.status in (r.IN_PROGRESS, r.COMPLETE) and r.action in (r.CREATE, r.ADOPT, r.SUSPEND, r.RESUME, r.UPDATE, r.CHECK, r.SNAPSHOT)): return r.FnGetAtt(attribute, *path_components) else: return None
def result(self): for_each = function.resolve(self._for_each) if not all(self._valid_list(l) for l in for_each.values()): raise TypeError(_('The values of the "for_each" argument to ' '"%s" must be lists') % self.fn_name) template = function.resolve(self._template) keys, lists = six.moves.zip(*for_each.items()) return [self._do_replacement(keys, replacements, template) for replacements in itertools.product(*lists)]
def dep_attrs(self, resource_name): if self._resource().name == resource_name: path = function.resolve(self._path_components) attr = [function.resolve(self._attribute)] if path: attrs = [tuple(attr + path)] else: attrs = attr else: attrs = [] return itertools.chain(function.dep_attrs(self.args, resource_name), attrs)
def rsrc_defn_item(name, snippet): data = self.parse(stack, snippet) depends = data.get(RES_DEPENDS_ON) if isinstance(depends, six.string_types): depends = [depends] deletion_policy = function.resolve(data.get(RES_DELETION_POLICY)) if deletion_policy is not None: if deletion_policy not in six.iterkeys(self.deletion_policies): msg = _('Invalid deletion policy "%s"') % deletion_policy raise exception.StackValidationFailed(message=msg) else: deletion_policy = self.deletion_policies[deletion_policy] kwargs = { 'resource_type': data.get(RES_TYPE), 'properties': data.get(RES_PROPERTIES), 'metadata': data.get(RES_METADATA), 'depends': depends, 'deletion_policy': deletion_policy, 'update_policy': data.get(RES_UPDATE_POLICY), 'description': data.get(RES_DESCRIPTION) or '' } defn = rsrc_defn.ResourceDefinition(name, **kwargs) return name, defn
def result(self): attribute = super(GetAttThenSelect, self).result() if attribute is None: return None path_components = function.resolve(self._path_components) return attributes.select_from_attribute(attribute, path_components)
def result(self): args = function.resolve(self.args) try: delim = args.pop(0) str_to_split = args.pop(0) except (AttributeError, IndexError): raise ValueError(_('Incorrect arguments to "%(fn_name)s" ' 'should be: %(example)s') % self.fmt_data) if str_to_split is None: return None split_list = str_to_split.split(delim) # Optionally allow an index to be specified if args: try: index = int(args.pop(0)) except ValueError: raise ValueError(_('Incorrect index to "%(fn_name)s" ' 'should be: %(example)s') % self.fmt_data) else: try: res = split_list[index] except IndexError: raise ValueError(_('Incorrect index to "%(fn_name)s" ' 'should be between 0 and ' '%(max_index)s') % {'fn_name': self.fn_name, 'max_index': len(split_list) - 1}) else: res = split_list return res
def rsrc_defn_item(name, snippet): data = self.parse(stack, snippet) depends = data.get(RES_DEPENDS_ON) if isinstance(depends, six.string_types): depends = [depends] deletion_policy = function.resolve(data.get(RES_DELETION_POLICY)) if deletion_policy is not None: if deletion_policy not in six.iterkeys( self.deletion_policies): msg = _('Invalid deletion policy "%s"') % deletion_policy raise exception.StackValidationFailed(message=msg) else: deletion_policy = self.deletion_policies[deletion_policy] kwargs = { 'resource_type': data.get(RES_TYPE), 'properties': data.get(RES_PROPERTIES), 'metadata': data.get(RES_METADATA), 'depends': depends, 'deletion_policy': deletion_policy, 'update_policy': data.get(RES_UPDATE_POLICY), 'description': data.get(RES_DESCRIPTION) or '' } defn = rsrc_defn.ResourceDefinition(name, **kwargs) return name, defn
def dep_attrs(self, resource_name): if self._resource().name == resource_name: attrs = [function.resolve(self._attribute)] else: attrs = [] return itertools.chain( super(GetAtt, self).dep_attrs(resource_name), attrs)
def result(self): param_name = function.resolve(self.args) try: return self.parameters[param_name] except KeyError: raise exception.InvalidTemplateReference(resource=param_name, key='unknown')
def _resource(self, path='unknown'): resource_name = function.resolve(self._resource_name) try: return self.stack[resource_name] except KeyError: raise exception.InvalidTemplateReference(resource=resource_name, key=path)
def result(self): index = function.resolve(self._lookup) strings = function.resolve(self._strings) if strings == '': # an empty string is a common response from other # functions when result is not currently available. # Handle by returning an empty string return '' if isinstance(strings, six.string_types): # might be serialized json. try: strings = jsonutils.loads(strings) except ValueError as json_ex: fmt_data = {'fn_name': self.fn_name, 'err': json_ex} raise ValueError(_('"%(fn_name)s": %(err)s') % fmt_data) if isinstance(strings, collections.Mapping): if not isinstance(index, six.string_types): raise TypeError( _('Index to "%s" must be a string') % self.fn_name) return strings.get(index, '') try: index = int(index) except (ValueError, TypeError): pass if (isinstance(strings, collections.Sequence) and not isinstance(strings, six.string_types)): if not isinstance(index, six.integer_types): raise TypeError( _('Index to "%s" must be an integer') % self.fn_name) try: return strings[index] except IndexError: return '' if strings is None: return '' raise TypeError(_('Arguments to %s not fully resolved') % self.fn_name)
def result(self): template = function.resolve(self._string) mapping = function.resolve(self._mapping) if not isinstance(template, six.string_types): raise TypeError(_('"%s" template must be a string') % self.fn_name) if not isinstance(mapping, collections.Mapping): raise TypeError(_('"%s" params must be a map') % self.fn_name) def replace(string, change): placeholder, value = change if not isinstance(placeholder, six.string_types): raise TypeError(_('"%s" param placeholders must be strings') % self.fn_name) if value is None: value = '' if not isinstance(value, (six.string_types, six.integer_types, float, bool)): if isinstance(value, (collections.Mapping, collections.Sequence)): try: value = jsonutils.dumps(value, default=None) except TypeError: raise TypeError(_('"%(name)s" params must be strings, ' 'numbers, list or map. ' 'Failed to json serialize %(value)s' ) % {'name': self.fn_name, 'value': value}) else: raise TypeError(_('"%s" params must be strings, numbers, ' 'list or map.') % self.fn_name) return string.replace(placeholder, six.text_type(value)) mapping = collections.OrderedDict(sorted(mapping.items(), key=lambda t: len(t[0]), reverse=True)) return six.moves.reduce(replace, six.iteritems(mapping), template)
def arg_item(attr_name): name = attr_name.lstrip('_') if name in overrides: value = overrides[name] if not value and getattr(self, attr_name) is None: value = None else: value = function.resolve(getattr(self, attr_name)) return name, value
def result(self): strings = function.resolve(self._strings) if not isinstance(self._delim, six.string_types): raise TypeError( _("Delimiter for %s must be string") % self.fn_name) if not isinstance(strings, six.string_types): raise TypeError( _("String to split must be string; got %s") % type(strings)) return strings.split(self._delim)
def resolve_and_find(translation_data, translation_value): if isinstance(translation_value, cfn_funcs.ResourceRef): return if isinstance(translation_value, function.Function): translation_value = function.resolve(translation_value) if translation_value: finder = getattr(self.client_plugin, self.finder) if self.entity: value = finder(self.entity, translation_value) else: value = finder(translation_value) translation_data[translation_key] = value
def resolve_and_find(translation_data, translation_value): if isinstance(translation_value, cfn_funcs.ResourceRef): return if isinstance(translation_value, function.Function): translation_value = function.resolve(translation_value) if translation_value: finder = getattr(self.client_plugin, self.finder) if self.entity: value = finder(self.entity, translation_value) else: value = finder(translation_value) translation_data[translation_key] = value
def _get_conf_properties(self): conf_refid = self.properties[self.LAUNCH_CONFIGURATION_NAME] conf = self.stack.resource_by_refid(conf_refid) props = function.resolve(conf.properties.data) if 'InstanceId' in props: props = conf.rebuild_lc_properties(props['InstanceId']) props['Tags'] = self._tags() # if the launch configuration is created from an existing instance. # delete the 'InstanceId' property props.pop('InstanceId', None) return conf, props
def result(self): args = function.resolve(self.args) if not (isinstance(args, six.string_types)): raise TypeError(_('Argument to "%s" must be a string') % self.fn_name) f = self.files.get(args) if f is None: fmt_data = {'fn_name': self.fn_name, 'file_key': args} raise ValueError(_('No content found in the "files" section for ' '%(fn_name)s path: %(file_key)s') % fmt_data) return f
def _get_conf_properties(self): conf_refid = self.properties[self.LAUNCH_CONFIGURATION_NAME] conf = self.stack.resource_by_refid(conf_refid) props = function.resolve(conf.properties.data) if 'InstanceId' in props: props = conf.rebuild_lc_properties(props['InstanceId']) props['Tags'] = self._tags() # if the launch configuration is created from an existing instance. # delete the 'InstanceId' property props.pop('InstanceId', None) return conf, props
def handle_restore(self, defn, restore_data): snapshot_id = restore_data['resource_data']['snapshot_id'] snapshot = self.heat().stacks.snapshot_show(self.resource_id, snapshot_id) s_data = snapshot['snapshot']['data'] env = environment.Environment(s_data['environment']) files = s_data['files'] tmpl = template.Template(s_data['template'], env=env, files=files) props = function.resolve(self.properties.data) props[self.TEMPLATE] = jsonutils.dumps(tmpl.t) props[self.PARAMETERS] = env.params return defn.freeze(properties=props)
def handle_restore(self, defn, restore_data): snapshot_id = restore_data['resource_data']['snapshot_id'] snapshot = self.heat().stacks.snapshot_show(self.resource_id, snapshot_id) s_data = snapshot['snapshot']['data'] env = environment.Environment(s_data['environment']) files = s_data['files'] tmpl = template.Template(s_data['template'], env=env, files=files) props = function.resolve(self.properties.data) props[self.TEMPLATE] = jsonutils.dumps(tmpl.t) props[self.PARAMETERS] = env.params return defn.freeze(properties=props)
def result(self): attribute = function.resolve(self._attribute) r = self._resource() if r.action in (r.CREATE, r.ADOPT, r.SUSPEND, r.RESUME, r.UPDATE, r.ROLLBACK, r.SNAPSHOT, r.CHECK): return r.FnGetAtt(attribute) # NOTE(sirushtim): Add r.INIT to states above once convergence # is the default. elif r.stack.has_cache_data(r.name) and r.action == r.INIT: return r.FnGetAtt(attribute) else: return None
def result(self): args = function.resolve(self.args) if not args: raise ValueError(_('Function "%s" must have arguments') % self.fn_name) if isinstance(args, six.string_types): param_name = args path_components = [] elif isinstance(args, collections.Sequence): param_name = args[0] path_components = args[1:] else: raise TypeError(_('Argument to "%s" must be string or list') % self.fn_name) if not isinstance(param_name, six.string_types): raise TypeError(_('Parameter name in "%s" must be string') % self.fn_name) try: parameter = self.parameters[param_name] except KeyError: raise exception.UserParameterMissing(key=param_name) def get_path_component(collection, key): if not isinstance(collection, (collections.Mapping, collections.Sequence)): raise TypeError(_('"%s" can\'t traverse path') % self.fn_name) if not isinstance(key, (six.string_types, int)): raise TypeError(_('Path components in "%s" ' 'must be strings') % self.fn_name) if isinstance(collection, collections.Sequence ) and isinstance(key, six.string_types): try: key = int(key) except ValueError: raise TypeError(_("Path components in '%s' " "must be a string that can be " "parsed into an " "integer.") % self.fn_name) return collection[key] try: return six.moves.reduce(get_path_component, path_components, parameter) except (KeyError, IndexError, TypeError): return ''
def result(self): strings = function.resolve(self._strings) if strings is None: strings = [] if (isinstance(strings, six.string_types) or not isinstance(strings, collections.Sequence)): raise TypeError(_('"%s" must operate on a list') % self.fn_name) delim = function.resolve(self._delim) if not isinstance(delim, six.string_types): raise TypeError( _('"%s" delimiter must be a string') % self.fn_name) def ensure_string(s): if s is None: return '' if not isinstance(s, six.string_types): raise TypeError( _('Items to join must be strings not %s') % (repr(s)[:200])) return s return delim.join(ensure_string(s) for s in strings)
def result(self): r_joinlists = function.resolve(self._joinlists) strings = [] for jl in r_joinlists: if jl: if (isinstance(jl, six.string_types) or not isinstance(jl, collections.Sequence)): raise TypeError(_('"%s" must operate on ' 'a list') % self.fn_name) strings += jl delim = function.resolve(self._delim) if not isinstance(delim, six.string_types): raise TypeError(_('"%s" delimiter must be a string') % self.fn_name) def ensure_string(s): msg = _('Items to join must be string, map or list not %s' ) % (repr(s)[:200]) if s is None: return '' elif isinstance(s, six.string_types): return s elif isinstance(s, (collections.Mapping, collections.Sequence)): try: return jsonutils.dumps(s, default=None) except TypeError: msg = _('Items to join must be string, map or list. ' '%s failed json serialization' ) % (repr(s)[:200]) raise TypeError(msg) return delim.join(ensure_string(s) for s in strings)
def _get_instance_definition(self): conf_refid = self.properties[self.LAUNCH_CONFIGURATION_NAME] conf = self.stack.resource_by_refid(conf_refid) props = function.resolve(conf.properties.data) props['Tags'] = self._tags() vpc_zone_ids = self.properties.get(AutoScalingGroup.VPCZONE_IDENTIFIER) if vpc_zone_ids: props['SubnetId'] = vpc_zone_ids[0] azs = self.properties.get(self.AVAILABILITY_ZONES) if azs: props['AvailabilityZone'] = azs[0] return rsrc_defn.ResourceDefinition(None, SCALED_RESOURCE_TYPE, props, conf.t.metadata())
def result(self): member_list = function.resolve(self._list) if not isinstance(member_list, collections.Iterable): raise TypeError(_('Member list must be a list')) def item(s): if not isinstance(s, six.string_types): raise TypeError(_("Member list items must be strings")) return s.split('=', 1) partials = dict(item(s) for s in member_list) return extract_param_pairs(partials, prefix='', keyname=self._keyname, valuename=self._valuename)
def rebuild_lc_properties(self, instance_id): server = self.client_plugin('nova').get_server(instance_id) instance_props = { self.IMAGE_ID: server.image['id'], self.INSTANCE_TYPE: server.flavor['id'], self.KEY_NAME: server.key_name, self.SECURITY_GROUPS: [sg['name'] for sg in server.security_groups] } lc_props = function.resolve(self.properties.data) for key, value in six.iteritems(instance_props): # the properties which are specified in launch configuration, # will override the attributes from the instance lc_props.setdefault(key, value) return lc_props
def validate(self): super(GetAtt, self).validate() res = self._resource() if self._allow_without_attribute_name(): # if allow without attribute_name, then don't check # when attribute_name is None if self._attribute is None: return attr = function.resolve(self._attribute) from conveyor.conveyorheat.engine import resource if (type(res).get_attribute == resource.Resource.get_attribute and attr not in six.iterkeys(res.attributes_schema)): raise exception.InvalidTemplateAttribute( resource=self._resource_name, key=attr)
def _get_instance_definition(self): conf_refid = self.properties[self.LAUNCH_CONFIGURATION_NAME] conf = self.stack.resource_by_refid(conf_refid) props = function.resolve(conf.properties.data) props['Tags'] = self._tags() vpc_zone_ids = self.properties.get(AutoScalingGroup.VPCZONE_IDENTIFIER) if vpc_zone_ids: props['SubnetId'] = vpc_zone_ids[0] azs = self.properties.get(self.AVAILABILITY_ZONES) if azs: props['AvailabilityZone'] = azs[0] return rsrc_defn.ResourceDefinition(None, SCALED_RESOURCE_TYPE, props, conf.t.metadata())
def resolve_param(param): """Check whether if given item is param and resolve, if it is.""" # NOTE(prazumovsky): If property uses removed in HOT function, # we should not translate it for correct validating and raising # validation error. if isinstance(param, hot_funcs.Removed): raise AttributeError(_('Property uses removed function.')) if isinstance(param, (hot_funcs.GetParam, cfn_funcs.ParamRef)): try: return function.resolve(param) except exception.UserParameterMissing as ex: # We can't resolve parameter now. Abort translation. err_msg = encodeutils.exception_to_unicode(ex) raise AttributeError( _('Can not resolve parameter ' 'due to: %s') % err_msg) elif isinstance(param, list): return [resolve_param(param_item) for param_item in param] else: return param
def result(self): args = function.resolve(self.args) if not isinstance(args, collections.Sequence): raise TypeError(_('Incorrect arguments to "%(fn_name)s" ' 'should be: %(example)s') % self.fmt_data) def ensure_map(m): if m is None: return {} elif isinstance(m, collections.Mapping): return m else: msg = _('Incorrect arguments: Items to merge must be maps.') raise TypeError(msg) ret_map = {} for m in args: ret_map.update(ensure_map(m)) return ret_map
def resolve_param(param): """Check whether if given item is param and resolve, if it is.""" # NOTE(prazumovsky): If property uses removed in HOT function, # we should not translate it for correct validating and raising # validation error. if isinstance(param, hot_funcs.Removed): raise AttributeError(_('Property uses removed function.')) if isinstance(param, (hot_funcs.GetParam, cfn_funcs.ParamRef)): try: return function.resolve(param) except exception.UserParameterMissing as ex: # We can't resolve parameter now. Abort translation. err_msg = encodeutils.exception_to_unicode(ex) raise AttributeError( _('Can not resolve parameter ' 'due to: %s') % err_msg) elif isinstance(param, list): return [resolve_param(param_item) for param_item in param] else: return param
def _get_conf_properties(self): instance_id = self.properties.get(self.INSTANCE_ID) if instance_id: server = self.client_plugin('nova').get_server(instance_id) instance_props = { 'ImageId': server.image['id'], 'InstanceType': server.flavor['id'], 'KeyName': server.key_name, 'SecurityGroups': [sg['name'] for sg in server.security_groups] } conf = self._make_launch_config_resource(self.name, instance_props) props = function.resolve(conf.properties.data) else: conf, props = super(AutoScalingGroup, self)._get_conf_properties() vpc_zone_ids = self.properties.get(self.VPCZONE_IDENTIFIER) if vpc_zone_ids: props['SubnetId'] = vpc_zone_ids[0] return conf, props
def _get_conf_properties(self): instance_id = self.properties.get(self.INSTANCE_ID) if instance_id: server = self.client_plugin('nova').get_server(instance_id) instance_props = { 'ImageId': server.image['id'], 'InstanceType': server.flavor['id'], 'KeyName': server.key_name, 'SecurityGroups': [sg['name'] for sg in server.security_groups] } conf = self._make_launch_config_resource(self.name, instance_props) props = function.resolve(conf.properties.data) else: conf, props = super(AutoScalingGroup, self)._get_conf_properties() vpc_zone_ids = self.properties.get(self.VPCZONE_IDENTIFIER) if vpc_zone_ids: props['SubnetId'] = vpc_zone_ids[0] return conf, props
def deletion_policy(self): """Return the deletion policy for the resource. The policy will be one of those listed in DELETION_POLICIES. """ return function.resolve(self._deletion_policy) or self.DELETE
def metadata(self): """Return the resource metadata.""" return function.resolve(self._metadata) or {}