Class: Sfn::Planner::Aws::Translator

Inherits:
SparkleFormation::Translation
  • Object
show all
Defined in:
lib/sfn/planner/aws.rb

Overview

Customized translator to dereference template

Constant Summary collapse

MAP =
{}
REF_MAPPING =
{}
FN_MAPPING =
{}
UNKNOWN_RUNTIME_RESULT =
"__UNKNOWN_RUNTIME_RESULT__"

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

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

Override to init flagged array



22
23
24
25
# File 'lib/sfn/planner/aws.rb', line 22

def initialize(template_hash, args = {})
  super
  @flagged = []
end

Instance Attribute Details

#flaggedArray<String> (readonly)

Returns flagged items for value replacement

Returns:

  • (Array<String>)

    flagged items for value replacement



19
20
21
# File 'lib/sfn/planner/aws.rb', line 19

def flagged
  @flagged
end

Instance Method Details

#apply_condition(name) ⇒ TrueClass, FalseClass

Evaluate given condition

Parameters:

  • name (String)

    condition name

Returns:

  • (TrueClass, FalseClass)


89
90
91
92
93
94
95
96
# File 'lib/sfn/planner/aws.rb', line 89

def apply_condition(name)
  condition = conditions[name]
  if condition
    apply_function(condition, [:all, "DEREF"])
  else
    raise "Failed to locate condition with name `#{name}`!"
  end
end

#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)


56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
# File 'lib/sfn/planner/aws.rb', line 56

def apply_function(hash, funcs = [])
  if hash.is_a?(Hash)
    k, v = hash.first
    if hash.size == 1 && (k.start_with?("Fn") || k == "Ref") && (funcs.include?(:all) || funcs.empty? || funcs.include?(k) || funcs == ["DEREF"])
      method_name = Bogo::Utility.snake(k.gsub("::", ""))
      if (funcs.include?(k) || funcs.include?(:all)) && respond_to?(method_name)
        apply_function(send(method_name, v), funcs)
      else
        case k
        when "Fn::GetAtt"
          funcs.include?("DEREF") ? dereference(hash) : hash
        when "Ref"
          if funcs.include?("DEREF")
            dereference(hash)
          else
            {"Ref" => self.class.const_get(:REF_MAPPING).fetch(v, v)}
          end
        else
          hash
        end
      end
    else
      hash
    end
  else
    hash
  end
end

#conditionsHash

Returns defined conditions

Returns:

  • (Hash)

    defined conditions



28
29
30
# File 'lib/sfn/planner/aws.rb', line 28

def conditions
  @original.fetch("Conditions", {})
end

#dereference(hash) ⇒ Hash, String

Override the parent dereference behavior to return junk value on flagged resource match

Parameters:

  • hash (Hash)

Returns:

  • (Hash, String)


202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
# File 'lib/sfn/planner/aws.rb', line 202

def dereference(hash)
  result = nil
  if hash.is_a?(Hash)
    if hash.keys.first == "Ref" && flagged?(hash.values.first)
      result = RUNTIME_MODIFIED
    elsif hash.keys.first == "Fn::GetAtt"
      if hash.values.last.last.start_with?("Outputs.")
        if flagged?(hash.values.join("_"))
          result = RUNTIME_MODIFIED
        end
      elsif flagged?(hash.values.first)
        result = RUNTIME_MODIFIED
      end
    end
  end
  result = result.nil? ? super : result
  unless result.is_a?(Enumerable)
    result = result.to_s
  end
  result
end

#flag_ref(ref_name) ⇒ Array<String>

Flag a reference as modified

Parameters:

  • ref_name (String)

Returns:

  • (Array<String>)


36
37
38
39
# File 'lib/sfn/planner/aws.rb', line 36

def flag_ref(ref_name)
  @flagged << ref_name.to_s
  @flagged.uniq!
end

#flagged?(name) ⇒ TrueClass, FalseClass

Check if resource name is flagged

Parameters:

  • name (String)

Returns:

  • (TrueClass, FalseClass)


45
46
47
# File 'lib/sfn/planner/aws.rb', line 45

def flagged?(name)
  @flagged.include?(name.to_s)
end

#fn_and(value) ⇒ TrueClass, FalseClass

Determine if all conditions are true

Parameters:

  • value (Array<String>)

    condition names

Returns:

  • (TrueClass, FalseClass)


116
117
118
119
120
121
122
123
124
125
# File 'lib/sfn/planner/aws.rb', line 116

def fn_and(value)
  result = value.map do |val|
    apply_condition(val)
  end
  if result.to_s.include?(RUNTIME_MODIFIED)
    UNKNOWN_RUNTIME_RESULT
  else
    result.all?
  end
end

#fn_equals(value) ⇒ TrueClass, FalseClass

Determine if values are equal

Parameters:

  • value (Array)

    values

Returns:

  • (TrueClass, FalseClass)


155
156
157
158
159
160
161
162
163
164
# File 'lib/sfn/planner/aws.rb', line 155

def fn_equals(value)
  value = value.map do |val|
    apply_function(val)
  end
  if value.to_s.include?(RUNTIME_MODIFIED)
    UNKNOWN_RUNTIME_RESULT
  else
    value.first == value.last
  end
end

#fn_find_in_map(value) ⇒ String, Fixnum

Lookup value in mappings

Parameters:

  • value (Array)

Returns:

  • (String, Fixnum)


183
184
185
186
187
188
189
190
191
192
193
194
195
# File 'lib/sfn/planner/aws.rb', line 183

def fn_find_in_map(value)
  map_holder = mappings[value[0]]
  if map_holder
    map_item = map_holder[dereference(value[1])]
    if map_item
      map_item[value[2]]
    else
      raise "Failed to find mapping item! (#{value[0]} -> #{value[1]})"
    end
  else
    raise "Failed to find mapping! (#{value[0]})"
  end
end

#fn_if(value) ⇒ Object

Evaluate `if` conditional

Parameters:

  • value (Array)

    condition name, 1: true value, 2: false value

Returns:

  • (Object)

    true or false value



102
103
104
105
106
107
108
109
110
# File 'lib/sfn/planner/aws.rb', line 102

def fn_if(value)
  result = apply_condition(value[0])
  if result != UNKNOWN_RUNTIME_RESULT
    result ? value[1] : value[2]
  else
    UNKNOWN_RUNTIME_RESULT
    result
  end
end

#fn_join(value) ⇒ String

Join values with given delimiter

Parameters:

  • value (Array<String,Array<String>>)

Returns:

  • (String)


170
171
172
173
174
175
176
177
# File 'lib/sfn/planner/aws.rb', line 170

def fn_join(value)
  unless value.last.is_a?(Array)
    val = value.last.to_s.split(",")
  else
    val = value.last
  end
  val.join(value.first)
end

#fn_not(value) ⇒ TrueClass, FalseClass

Negate given value

Parameters:

  • value (Array<Hash>)

Returns:

  • (TrueClass, FalseClass)


146
147
148
149
# File 'lib/sfn/planner/aws.rb', line 146

def fn_not(value)
  result = apply_function(value)
  result == RUNTIME_MODIFIED ? UNKNOWN_RUNTIME_RESULT : !result
end

#fn_or(value) ⇒ TrueClass, FalseClass

Determine if any values are true

Parameters:

  • value (Array<String>)

    condition names

Returns:

  • (TrueClass, FalseClass)


131
132
133
134
135
136
137
138
139
140
# File 'lib/sfn/planner/aws.rb', line 131

def fn_or(value)
  result = value.map do |val|
    apply_condition(val)
  end
  if result.to_s.include?(RUNTIME_MODIFIED)
    UNKNOWN_RUNTIME_RESULT
  else
    result.any?
  end
end