Class: Highlander::Dsl::Template

Inherits:
DslBase
  • Object
show all
Defined in:
lib/highlander.dsl.rb

Instance Attribute Summary collapse

Attributes inherited from DslBase

#config

Instance Method Summary collapse

Methods inherited from DslBase

#method_missing

Constructor Details

#initialize ⇒ Template

Returns a new instance of Template.



33
34
35
36
37
38
39
40
41
42
43
44
45
46
# File 'lib/highlander.dsl.rb', line 33

def initialize
  @mappings = []
  @components = []
  @config = { 'mappings' => {}, 'component_version' => 'latest' }
  @component_configs = {}
  @version = 'latest'
  @distribute_url = nil
  @distribution_prefix = ''
  @component_sources = []
  @parameters = Parameters.new
  @lambda_functions_keys = []
  @dependson_components_templates = []
  @dependson_components = []
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method in the class Highlander::Dsl::DslBase

Instance Attribute Details

#components ⇒ Object

Returns the value of attribute components.



21
22
23
# File 'lib/highlander.dsl.rb', line 21

def components
  @components
end

#dependson_components ⇒ Object

Returns the value of attribute dependson_components.



21
22
23
# File 'lib/highlander.dsl.rb', line 21

def dependson_components
  @dependson_components
end

#description ⇒ Object

Returns the value of attribute description.



21
22
23
# File 'lib/highlander.dsl.rb', line 21

def description
  @description
end

#distribute_url ⇒ Object

Returns the value of attribute distribute_url.



21
22
23
# File 'lib/highlander.dsl.rb', line 21

def distribute_url
  @distribute_url
end

#distribution_bucket ⇒ Object

Returns the value of attribute distribution_bucket.



21
22
23
# File 'lib/highlander.dsl.rb', line 21

def distribution_bucket
  @distribution_bucket
end

#distribution_prefix ⇒ Object

Returns the value of attribute distribution_prefix.



21
22
23
# File 'lib/highlander.dsl.rb', line 21

def distribution_prefix
  @distribution_prefix
end

#lambda_functions_keys ⇒ Object

Returns the value of attribute lambda_functions_keys.



21
22
23
# File 'lib/highlander.dsl.rb', line 21

def lambda_functions_keys
  @lambda_functions_keys
end

#mappings ⇒ Object

Returns the value of attribute mappings.



21
22
23
# File 'lib/highlander.dsl.rb', line 21

def mappings
  @mappings
end

#name ⇒ Object

Returns the value of attribute name.



21
22
23
# File 'lib/highlander.dsl.rb', line 21

def name
  @name
end

#parameters ⇒ Object

Returns the value of attribute parameters.



21
22
23
# File 'lib/highlander.dsl.rb', line 21

def parameters
  @parameters
end

#version ⇒ Object

Returns the value of attribute version.



21
22
23
# File 'lib/highlander.dsl.rb', line 21

def version
  @version
end

Instance Method Details

#addMapping(name, map) ⇒ Object

DSL statements



50
51
52
53
54
# File 'lib/highlander.dsl.rb', line 50

def addMapping(name, map)
  @mappings << name
  @config['mappings'] = {} unless @config.key?('mappings')
  @config['mappings'][name] = map
end

#apply_config_exports ⇒ Object



266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
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
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
# File 'lib/highlander.dsl.rb', line 266

def apply_config_exports
  # first export from master to all children
  if ((@config.key? 'config_export') and (@config['config_export']['global']))
    @config['config_export']['global'].each { |global_export_key|
      if @config.key? global_export_key
        @config_overrides.each { |cname, co|
          co[global_export_key] = @config[global_export_key]
        }
      end
    }
  end

  @components.each { |component|
    cl = component.component_loaded
    if ((not cl.config.nil?) and (cl.config.key? 'config_export'))

      # global config
      if cl.config['config_export'].key? 'global'
        cl.config['config_export']['global'].each { |global_export_key|

          # global config is exported to parent and every component
          if cl.config.key? global_export_key

            # cname is for component name, co for component override
            @config_overrides.each { |cname, co|

              # if templates are different e.g don't export from vpc to vpc
              config_receiver_component = @named_components[cname]
              if config_receiver_component.template != component.template
                if (not config_receiver_component.export_config.nil?) and (config_receiver_component.export_config.key? component.template)
                  allow_from_component_name = config_receiver_component.export_config[component.template]
                  if allow_from_component_name == component.name
                    puts("Exporting key #{global_export_key} from component #{component.name} to #{cname}")
                    co[global_export_key] = cl.config[global_export_key]
                  end
                else
                  puts("Exporting key #{global_export_key} from component #{component.name} to #{cname}")
                  co[global_export_key] = cl.config[global_export_key]
                end
              end
            }


          else
            STDERR.puts("Trying to export non-existent configuration key #{global_export_key}")
          end
        }
      end

      if cl.config['config_export'].key? 'component'
        cl.config['config_export']['component'].each { |component_name, export_keys|
          # check if there is configuration of export from this component
          # and if there is export configuration for given component name

          if (not component.export_config.nil?) and (component.export_config.key? component_name)
            # if there is component with such name
            if @config_overrides.key? component.export_config[component_name]
              # override the config
              real_component_name = component.export_config[component_name]
              export_keys.each { |export_component_key|
                puts("Exporting config for key=#{export_component_key} from #{component.name} to #{real_component_name}")
                if not @config_overrides[real_component_name].key? export_component_key
                  @config_overrides[real_component_name][export_component_key] = {}
                end
                @config_overrides[real_component_name][export_component_key].extend(cl.config[export_component_key])
              }
            else
              STDERR.puts("Trying to export configuration for non-existant component #{component.export_config[component_name]}")
            end
          elsif @config_overrides.key? component_name
            export_keys.each { |export_component_key|
              puts("Exporting config for key=#{export_component_key} from #{component.name} to #{component_name}")
              if not @config_overrides[component_name].key? export_component_key
                @config_overrides[component_name][export_component_key] = {}
              end
              @config_overrides[component_name][export_component_key].extend(cl.config[export_component_key])
            }
          else
            STDERR.puts("Trying to export configuration for non-existant component #{component_name}")
          end
        }
      end
      # component config
      # loop over keys
      # check if there
    end
  }
end

#apply_config_overrides ⇒ Object



250
251
252
253
254
# File 'lib/highlander.dsl.rb', line 250

def apply_config_overrides
  @config_overrides.each { |component_name, component_override|
    @named_components[component_name].component_loaded.config.extend(component_override)
  }
end

#build_distribution_url ⇒ Object



375
376
377
378
379
380
381
382
383
384
385
386
# File 'lib/highlander.dsl.rb', line 375

def build_distribution_url
  if not (@distribution_bucket.nil? or @distribution_prefix.nil?)
    @distribute_url = "https://#{@distribution_bucket}.s3.amazonaws.com/#{@distribution_prefix}"
    @distribute_url = "#{@distribute_url}/#{@version}" unless @version.nil?
    @components.each { |component|
      component.distribute_bucket = @distribution_bucket unless @distribution_bucket.nil?
      component.distribute_prefix = @distribution_prefix unless @distribution_prefix.nil?
      component.version = @version unless @version.nil?
      component.build_distribution_url
    }
  end
end

#Component(name:, template:, param_values: {}, config: {}, export_config: {}, &block) ⇒ Object



81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
# File 'lib/highlander.dsl.rb', line 81

def Component(name:, template:, param_values: {}, config: {}, export_config: {}, &block)
  puts "Initialize #{name} with template #{template}"

  # load component
  component = Highlander::Dsl::Component.new(self,
      name,
      template,
      param_values,
      @component_sources,
      config,
      export_config
  )
  component.distribute_bucket = @distribution_bucket unless @distribution_bucket.nil?
  component.distribute_prefix = @distribution_prefix unless @distribution_prefix.nil?
  component.version = @version unless @version.nil?
  @component_configs[name] = config
  @components << component
end

#ComponentDistribution(s3_url) ⇒ Object



116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
# File 'lib/highlander.dsl.rb', line 116

def ComponentDistribution(s3_url)
  if s3_url.start_with? 's3://'
    if s3_url.split('/').length < 4
      raise 'Unrecognised distribution url, only supporting s3://bucket/prefix urls'
    end
    parts = s3_url.split('/')
    @distribution_bucket = parts[2]
    @distribution_prefix = parts[3]
    i = 4
    while i < parts.size()
      @distribution_prefix += "/#{parts[i]}"
      i += 1
    end
    @distribution_prefix = @distribution_prefix.chomp('/')

    build_distribution_url
  else
    raise 'Unrecognised distribution url, only supporting s3://bucket/prefix urls'
  end
end

#ComponentSources(sources_array) ⇒ Object



137
138
139
# File 'lib/highlander.dsl.rb', line 137

def ComponentSources(sources_array)
  @component_sources = sources_array
end

#ComponentVersion(version) ⇒ Object



100
101
102
103
104
# File 'lib/highlander.dsl.rb', line 100

def ComponentVersion(version)
  @version = version
  @config['component_version'] = version
  build_distribution_url
end

#DependsOn(template) ⇒ Object



76
77
78
# File 'lib/highlander.dsl.rb', line 76

def DependsOn(template)
  @dependson_components_templates << template
end

#Description(description) ⇒ Object



61
62
63
64
# File 'lib/highlander.dsl.rb', line 61

def Description(description)
  @description = description
  @config['description'] = description
end

#distribute_bucket=(value) ⇒ Object



361
362
363
364
# File 'lib/highlander.dsl.rb', line 361

def distribute_bucket=(value)
  @distribution_bucket = value
  build_distribution_url
end

#distribute_prefix=(value) ⇒ Object



366
367
368
369
# File 'lib/highlander.dsl.rb', line 366

def distribute_prefix=(value)
  @distribution_prefix = value
  build_distribution_url
end

#DistributionBucket(bucket_name) ⇒ Object



111
112
113
114
# File 'lib/highlander.dsl.rb', line 111

def DistributionBucket(bucket_name)
  @distribution_bucket = bucket_name
  build_distribution_url
end

#DistributionPrefix(prefix) ⇒ Object



106
107
108
109
# File 'lib/highlander.dsl.rb', line 106

def DistributionPrefix(prefix)
  @distribution_prefix = prefix
  build_distribution_url
end

#DynamicMappings(providerName) ⇒ Object



71
72
73
74
# File 'lib/highlander.dsl.rb', line 71

def DynamicMappings(providerName)
  maps = mappings_provider_maps(providerName, self.config)
  maps.each { |name, map| addMapping(name, map) } unless maps.nil?
end

#LambdaFunctions(config_key) ⇒ Object



141
142
143
# File 'lib/highlander.dsl.rb', line 141

def LambdaFunctions(config_key)
  @lambda_functions_keys << config_key
end

#load_configfile_component_config ⇒ Object



256
257
258
259
260
261
262
263
264
# File 'lib/highlander.dsl.rb', line 256

def load_configfile_component_config
  if (@config.key? 'components')
    @config['components'].each { |component_name, component_config|
      if component_config.key?('config')
        @config_overrides[component_name].extend(component_config['config'])
      end
    }
  end
end

#load_explicit_component_config ⇒ Object



355
356
357
358
359
# File 'lib/highlander.dsl.rb', line 355

def load_explicit_component_config
  @component_configs.each { |component_name, component_config|
    @config_overrides[component_name].extend(component_config)
  }
end

#load_extension_exports ⇒ Object



230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
# File 'lib/highlander.dsl.rb', line 230

def load_extension_exports
  @components.each do |c|
    component = c.component_loaded
    config = component.config
    if ((config.key? 'lib_export') and (config['lib_export'].key? 'global'))

      global_export_config = config['lib_export']['global']
      if global_export_config.key? 'cfndsl'
        global_export_config['cfndsl'].each do |exported_extension|
          extension_file_path = "#{component.component_dir}/ext/cfndsl/#{exported_extension}.rb"
          @components.each do |cr|
            cr.component_loaded.cfndsl_ext_files << extension_file_path unless cr == c
          end
        end
      end

    end
  end
end

#loadComponents ⇒ Object

Internal and interface functions



147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
# File 'lib/highlander.dsl.rb', line 147

def loadComponents()

  # empty config overrides to start with
  @config_overrides = Hash[@components.collect { |c| [c.name, {}] }]
  @named_components = Hash[@components.collect { |c| [c.name, c] }]

  # populate overrides with master config defined overrides
  load_configfile_component_config

  # populate overrides with config defined explictily
  load_explicit_component_config

  # apply configuration exports
  apply_config_overrides
  apply_config_exports


  # component exports may have overriden some of explicit / configfile configuration, reapply
  load_configfile_component_config
  load_explicit_component_config

  # apply extension exports
  load_extension_exports


  # load components and extract parent stack parameters and mappings
  @components.each { |component|

    component.load @config_overrides[component.name]
    # add all of it's stack parameters unless same template has been already processed
    component
        .component_loaded
        .highlander_dsl
        .parameters
        .param_list.each do |param|

      # add stack parameters
      if param.class == Highlander::Dsl::StackParam
        # sub-component stack param becomes top-level component param
        param_name = param.is_global ? param.name : "#{component.name}#{param.name}"
        stack_param = Highlander::Dsl::ComponentParam.new(
            param_name,
            param.type,
            param.default_value,
            param.no_echo
        )
        @parameters.addParam stack_param
      end unless component.param_values.key? param.name

      # for map parameters add maps
      if param.class == Highlander::Dsl::MappingParam
        if not param.mapProvider.nil?
          maps = param.mapProvider.getMaps(component.component_loaded.config)
          maps.each do |name, map|
            if not @mappings.include? name
              #1. add mapping name to model
              @mappings << name
              #2. add mapping to config to be rendered via cfndsl
              @config['mappings'] = {} if @config['mappings'].nil?
              @config['mappings'][name] = map
            end
          end unless maps.nil?
        end
      end

    end

    # late bind parameter values, once mappings and top level params are extracted
    component.load_parameters
  }

  @dependson_components_templates.each do |template|
    component = Highlander::Dsl::Component.new(self,
        template,
        template,
        {},
        @component_sources
    )
    component.load
    @dependson_components << component
  end
end

#Name(name) ⇒ Object



56
57
58
59
# File 'lib/highlander.dsl.rb', line 56

def Name(name)
  @name = name
  @config['component_name'] = name
end

#Parameters(&block) ⇒ Object



66
67
68
69
# File 'lib/highlander.dsl.rb', line 66

def Parameters(&block)
  @parameters.config = @config
  @parameters.instance_eval(&block)
end