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



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

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



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

def flagged
  @flagged
end

Instance Method Details

#apply_condition(name) ⇒ TrueClass, FalseClass

Evaluate given condition

Parameters:

  • name (String)

    condition name

Returns:

  • (TrueClass, FalseClass)


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

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)


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
84
# File 'lib/sfn/planner/aws.rb', line 57

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



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

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)


198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
# File 'lib/sfn/planner/aws.rb', line 198

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


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

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)


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

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)


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

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)


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

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)


179
180
181
182
183
184
185
186
187
188
189
190
191
# File 'lib/sfn/planner/aws.rb', line 179

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



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

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)


171
172
173
# File 'lib/sfn/planner/aws.rb', line 171

def fn_join(value)
  value.last.join(value.first)
end

#fn_not(value) ⇒ TrueClass, FalseClass

Negate given value

Parameters:

  • value (Array<Hash>)

Returns:

  • (TrueClass, FalseClass)


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

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)


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

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