Class: SparkleFormation::Translation

Inherits:
Object
  • Object
show all
Includes:
SparkleAttribute, Utils::AnimalStrings
Defined in:
lib/sparkle_formation/translation.rb,
lib/sparkle_formation/translation/heat.rb,
lib/sparkle_formation/translation/rackspace.rb

Overview

Translator

Direct Known Subclasses

Heat

Defined Under Namespace

Classes: Heat, Rackspace

Constant Summary collapse

REF_MAPPING =

Returns mapping for pseudo-parameters

Returns:

  • (Hash)

    mapping for pseudo-parameters

{}
FN_MAPPING =

Returns mapping for intrinsic functions

Returns:

  • (Hash)

    mapping for intrinsic functions

{}

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(template_hash, args = {}) ⇒ Translation

Create new instance

Parameters:

  • template_hash (Hash)

    stack template

  • args (Hash) (defaults to: {})

Options Hash (args):

  • :logger (Logger)

    custom logger

  • :parameters (Hash)

    parameters for stack creation

  • :options (Hash)

    options for translation



32
33
34
35
36
37
38
39
# File 'lib/sparkle_formation/translation.rb', line 32

def initialize(template_hash, args = {})
  @original = template_hash.dup
  @template = template_hash.to_smash
  @translated = {}
  @logger = args.fetch(:logger, Logger.new($stdout))
  @parameters = args[:parameters] || {}
  @options = args[:options] || {}
end

Instance Attribute Details

#loggerLogger (readonly)

Returns current logger

Returns:

  • (Logger)

    current logger



21
22
23
# File 'lib/sparkle_formation/translation.rb', line 21

def logger
  @logger
end

#optionsHash (readonly)

Returns extra options (generally used by translation implementations)

Returns:

  • (Hash)

    extra options (generally used by translation implementations)



23
24
25
# File 'lib/sparkle_formation/translation.rb', line 23

def options
  @options
end

#originalHash (readonly)

Returns original template

Returns:

  • (Hash)

    original template



15
16
17
# File 'lib/sparkle_formation/translation.rb', line 15

def original
  @original
end

#templateHash (readonly)

Returns duplicated template (full deep copy)

Returns:

  • (Hash)

    duplicated template (full deep copy)



19
20
21
# File 'lib/sparkle_formation/translation.rb', line 19

def template
  @template
end

#translatedHash (readonly)

Returns current translation

Returns:

  • (Hash)

    current translation



17
18
19
# File 'lib/sparkle_formation/translation.rb', line 17

def translated
  @translated
end

Instance Method Details

#__attribute_key(key) ⇒ String Originally defined in module SparkleAttribute

Format the provided key. If symbol type is provided formatting is forced. Otherwise the default formatting is applied

Parameters:

  • key (String, Symbol)

    given key

Returns:

  • (String)

    formatted key

#_dynamic(resource_type, custom_name, options = {}) ⇒ self #_dynamic(dynamic_name, custom_name, options = {}) ⇒ self Also known as: dynamic! Originally defined in module SparkleAttribute

Overloads:

  • #_dynamic(resource_type, custom_name, options = {}) ⇒ self
    Note:

    All other options are set into the new resource's properties

    Insert builtin resource

    Parameters:

    • resource_type (String, Symbol)

      provider resource type

    • custom_name (String, Symbol)

      custom name used for resource name generation

    • options (Hash) (defaults to: {})

    Options Hash (options):

    • :resource_name_suffix (String, NilClass)

      custom suffix to use for name generation (defaults to resource_type)

  • #_dynamic(dynamic_name, custom_name, options = {}) ⇒ self
    Note:

    All options are passed to dynamic with custom_name

    Call custom dynamic from available sparkle packs

    Parameters:

    • dynamic_name (Symbol)

      name of registered dynamic

    • custom_name (Symbol, String)

      unique name passed directly to registered dynamic

    • options (Hash) (defaults to: {})

    Options Hash (options):

    • :provider (String, Symbol)

      override provider restriction when fetching dynamic

Yields:

  • (new_struct)

    Provides newly inserted structure

Yield Parameters:

  • new_struct (SparkleStruct)

    newly inserted structure which can be modified

Yield Returns:

  • (Object)

    discarded

Returns:

  • (self)

#_method(sym) ⇒ Method Also known as: method! Originally defined in module SparkleAttribute

Note:

usually used as puts! method!(:foo).source_location

Lookup a method definition on self

Parameters:

  • sym (Symbol)

    name of method

Returns:

  • (Method)

See Also:

  • Object#method

#_nest(template, *names, options = {}) ⇒ self Also known as: nest! Originally defined in module SparkleAttribute

Nest a stack resource

Parameters:

  • template (String, Symbol)

    name of desired template

  • names (String, Symbol)

    list of optional string/symbol values for resource name generation

  • options (Hash) (defaults to: {})

Options Hash (options):

  • :provider (String, Symbol)

    override provider restriction when fetching template

  • :overwrite_name (Truthy, Falsey)

    when set to true, will not include template name in resource name

  • :parameters (Hash)

    compile time parameter values to pass to nested template

Yields:

  • (new_struct)

    Provides newly inserted structure

Yield Parameters:

  • new_struct (SparkleStruct)

    newly inserted structure which can be modified

Yield Returns:

  • (Object)

    discarded

Returns:

  • (self)

#_puts(obj, ...) ⇒ NilClass Also known as: puts! Originally defined in module SparkleAttribute

Print to stdout

Parameters:

  • obj (Object)

    object to print

Returns:

  • (NilClass)

See Also:

  • Kernel.puts

#_raise(*args) ⇒ Object Also known as: raise! Originally defined in module SparkleAttribute

Raise an exception

See Also:

  • Kernel.raise

#_registry(name) ⇒ Object #_registry(name, *args, options = {}) ⇒ Object Also known as: registry! Originally defined in module SparkleAttribute

Return value of registry item

Overloads:

  • #_registry(name) ⇒ Object

    Return value from registry item with given name

    Parameters:

    • name (String, Symbol)

      registry item name

  • #_registry(name, *args, options = {}) ⇒ Object
    Note:

    args and options will be passed directly to registry item when called

    Pass given parameters to registry item with given name and return the value

    Parameters:

    • name (String, Symbol)

      registry item name

    • options (Hash) (defaults to: {})
    • options (Hash) (defaults to: {})

      :provider override provider restriction when fetching registry item

    • args (Object)

      argument list

Returns:

  • (Object)

    return value of registry item

#_resource_nameString Also known as: resource_name! Originally defined in module SparkleAttribute

Return current resource name

Returns:

  • (String)

#_system(command) ⇒ String Also known as: system! Originally defined in module SparkleAttribute

Execute system command

Parameters:

  • command (String)

Returns:

  • (String)

    result

#apply_function(hash, funcs = []) ⇒ Hash

Note:

also allows 'Ref' within funcs to provide mapping replacements using the REF_MAPPING constant

Apply function if possible

Parameters:

  • hash (Hash)
  • funcs (Array) (defaults to: [])

    allowed functions

Returns:

  • (Hash)


300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
# File 'lib/sparkle_formation/translation.rb', line 300

def apply_function(hash, funcs = [])
  k, v = hash.first
  if hash.size == 1 && (k.start_with?("Fn") || k == "Ref") && (funcs.empty? || funcs.include?(k))
    case k
    when "Fn::Join"
      v.last.join(v.first)
    when "Fn::FindInMap"
      map_holder = mappings[v[0]]
      if map_holder
        map_item = map_holder[dereference(v[1])]
        if map_item
          map_item[v[2]]
        else
          raise "Failed to find mapping item! (#{v[0]} -> #{v[1]})"
        end
      else
        raise "Failed to find mapping! (#{v[0]})"
      end
    when "Ref"
      {"Ref" => self.class.const_get(:REF_MAPPING).fetch(v, v)}
    else
      hash
    end
  else
    hash
  end
end

#apply_rename(hash, names = []) ⇒ Hash

Note:

remapping references to constants: REF_MAPPING for Ref maps FN_MAPPING for Fn maps

Apply function if possible

Parameters:

  • hash (Hash)
  • names (Array<Symbol>) (defaults to: [])

    enable renaming (:ref, :fn)

Returns:

  • (Hash)


258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
# File 'lib/sparkle_formation/translation.rb', line 258

def apply_rename(hash, names = [])
  k, v = hash.first
  if hash.size == 1
    if k.start_with?("Fn::")
      {self.class.const_get(:FN_MAPPING).fetch(k, k) => attr_mapping(*v)}
    elsif k == "Ref"
      if resources.key?(v)
        {"get_resource" => v}
      else
        {"get_param" => self.class.const_get(:REF_MAPPING).fetch(v, v)}
      end
    else
      hash
    end
  else
    hash
  end
end

#attr_mapping(resource_name, value) ⇒ Array

Apply GetAttr mapping if available

Parameters:

  • resource_name (String)
  • value (String)

Returns:

  • (Array)


282
283
284
285
286
287
288
289
290
291
# File 'lib/sparkle_formation/translation.rb', line 282

def attr_mapping(resource_name, value)
  result = [resource_name, value]
  if r = resources[resource_name]
    attr_map = self.class.const_get(:FN_ATT_MAPPING)
    if attr_map[r["Type"]] && replacement = attr_map[r["Type"]][value]
      result = [resource_name, *[replacement].flatten.compact]
    end
  end
  result
end

#camel(string) ⇒ String Originally defined in module Utils::AnimalStrings

Camel case string

Parameters:

  • string (String)

Returns:

  • (String)

#default_key_format(key) ⇒ String, Symbol

Default formatting for keys

Parameters:

  • key (String, Symbol)

Returns:

  • (String, Symbol)


177
178
179
# File 'lib/sparkle_formation/translation.rb', line 177

def default_key_format(key)
  key
end

#dereference(obj) ⇒ Object

Attempt to dereference name

Parameters:

  • obj (Object)

Returns:

  • (Object)


185
186
187
188
189
190
191
192
193
194
195
196
197
# File 'lib/sparkle_formation/translation.rb', line 185

def dereference(obj)
  result = obj
  if obj.is_a?(Hash)
    name = obj["Ref"] || obj["get_param"]
    if name
      p_val = parameters[name.to_s]
      if p_val
        result = p_val
      end
    end
  end
  result
end

#dereference_processor(obj, funcs = []) ⇒ Object

Process object through dereferencer. This will dereference names and apply functions if possible.

Parameters:

  • obj (Object)

Returns:

  • (Object)


217
218
219
220
221
222
223
224
225
226
227
228
229
# File 'lib/sparkle_formation/translation.rb', line 217

def dereference_processor(obj, funcs = [])
  case obj
  when Array
    obj = obj.map { |v| dereference_processor(v, funcs) }
  when Hash
    new_hash = {}
    obj.each do |k, v|
      new_hash[k] = dereference_processor(v, funcs)
    end
    obj = apply_function(new_hash, funcs)
  end
  obj
end

#format_properties(args) ⇒ Hash

Format the properties of the new resource

Parameters:

  • args (Hash)

Options Hash (args):

  • :original_properties (Hash)
  • :property_map (Hash)
  • :new_resource (Hash)
  • :original_resource (Hash)

Returns:

  • (Hash)


132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
# File 'lib/sparkle_formation/translation.rb', line 132

def format_properties(args)
  args[:new_resource]["Properties"] = {}.tap do |new_properties|
    args[:original_properties].each do |property_name, property_value|
      new_key = args[:property_map][property_name]
      if new_key
        if new_key.is_a?(Symbol)
          unless new_key == :delete
            new_key, new_value = send(new_key, property_value,
                                      :new_resource => args[:new_resource],
                                      :new_properties => new_properties,
                                      :original_resource => args[:original_resource])
            new_properties[new_key] = new_value
          end
        else
          new_properties[new_key] = property_value
        end
      else
        logger.warn "Failed to locate property conversion for `#{property_name}` on " \
                    "resource type `#{args[:new_resource]["Type"]}`. Passing directly."
        new_properties[default_key_format(property_name)] = property_value
      end
    end
  end
end

#mapHash

Returns resource mapping

Returns:

  • (Hash)

    resource mapping



66
67
68
# File 'lib/sparkle_formation/translation.rb', line 66

def map
  self.class.const_get(:MAP)
end

#mappingsHash

Returns mappings for template

Returns:

  • (Hash)

    mappings for template



51
52
53
# File 'lib/sparkle_formation/translation.rb', line 51

def mappings
  @original.fetch("Mappings", {})
end

#outputsHash

Returns outputs for template

Returns:

  • (Hash)

    outputs for template



61
62
63
# File 'lib/sparkle_formation/translation.rb', line 61

def outputs
  @original.fetch("Outputs", {})
end

#parametersHash

Returns parameters for template

Returns:

  • (Hash)

    parameters for template



42
43
44
45
46
47
48
# File 'lib/sparkle_formation/translation.rb', line 42

def parameters
  Hash[
    @original.fetch("Parameters", {}).map do |k, v|
      [k, v.fetch("Default", "")]
    end
  ].merge(@parameters)
end

#rename_processor(obj, names = []) ⇒ Object

Process object through name mapping

Parameters:

  • obj (Object)
  • names (Array<Symbol>) (defaults to: [])

    enable renaming (:ref, :fn)

Returns:

  • (Object)


236
237
238
239
240
241
242
243
244
245
246
247
248
# File 'lib/sparkle_formation/translation.rb', line 236

def rename_processor(obj, names = [])
  case obj
  when Array
    obj = obj.map { |v| rename_processor(v, names) }
  when Hash
    new_hash = {}
    obj.each do |k, v|
      new_hash[k] = rename_processor(v, names)
    end
    obj = apply_rename(new_hash, names)
  end
  obj
end

#resource_name(obj) ⇒ String

Provide name of resource

Parameters:

  • obj (Object)

Returns:

  • (String)

    name



203
204
205
206
207
208
209
210
# File 'lib/sparkle_formation/translation.rb', line 203

def resource_name(obj)
  case obj
  when Hash
    obj["Ref"] || obj["get_resource"]
  else
    obj.to_s
  end
end

#resource_translation(resource_name, resource_args) ⇒ Hash, NilClass

Translate resource

Parameters:

  • resource_name (String)
  • resource_args (Hash)

Returns:

  • (Hash, NilClass)

    new resource Hash or nil



97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
# File 'lib/sparkle_formation/translation.rb', line 97

def resource_translation(resource_name, resource_args)
  new_resource = {}
  lookup = map[:resources][resource_args["Type"]]
  if lookup.nil?
    logger.warn "Failed to locate resource type: #{resource_args["Type"]}"
    nil
  elsif lookup == :delete
    logger.warn "Deleting resource #{resource_name} due to configuration"
    nil
  else
    new_resource["Type"] = lookup[:name]
    if resource_args["Properties"]
      new_resource["Properties"] = format_properties(
        :original_properties => resource_args["Properties"],
        :property_map => lookup[:properties],
        :new_resource => new_resource,
        :original_resource => resource_args,
      )
    end
    if lookup[:finalizer]
      send(lookup[:finalizer], resource_name, new_resource, resource_args)
    end
    resource_finalizer(resource_name, new_resource, resource_args)
    new_resource
  end
end

#resourcesHash

Returns resources for template

Returns:

  • (Hash)

    resources for template



56
57
58
# File 'lib/sparkle_formation/translation.rb', line 56

def resources
  @original.fetch("Resources", {})
end

#snake(string) ⇒ String Originally defined in module Utils::AnimalStrings

Snake case (underscore) string

Parameters:

  • string (String)

Returns:

  • (String)

#translate!TrueClass

Translate stack definition

Returns:

  • (TrueClass)


73
74
75
76
77
78
79
80
81
82
83
# File 'lib/sparkle_formation/translation.rb', line 73

def translate!
  template.each do |key, value|
    translate_method = "translate_#{snake(key.to_s)}".to_sym
    if respond_to?(translate_method)
      send(translate_method, value)
    else
      translate_default(key, value)
    end
  end
  true
end

#translate_default(key, value) ⇒ Object

Default translation action if no mapping is provided

Returns:

  • (Object)

    value



88
89
90
# File 'lib/sparkle_formation/translation.rb', line 88

def translate_default(key, value)
  translated[key] = value
end

#translate_resources(value) ⇒ Hash

Translate provided resources

Parameters:

  • value (Hash)

    resources hash

Returns:

  • (Hash)


161
162
163
164
165
166
167
168
169
170
171
# File 'lib/sparkle_formation/translation.rb', line 161

def translate_resources(value)
  translated["Resources"] = {}
  translated["Resources"].tap do |modified_resources|
    value.each do |resource_name, resource_args|
      new_resource = resource_translation(resource_name, resource_args)
      if new_resource
        modified_resources[resource_name] = new_resource
      end
    end
  end
end