class Cfhighlander::Dsl::HighlanderTemplate

Attributes

conditions[R]
config_overrides[R]
dependson_components[RW]
description[RW]
distribute_url[RW]
distribution_bucket[RW]
distribution_prefix[RW]
extended_template[R]
lambda_functions_keys[RW]
mappings[RW]
name[RW]
parameters[RW]
publish_artifacts[RW]
subcomponents[R]
template_dir[RW]
version[RW]

Public Class Methods

new() click to toggle source
# File lib/cfhighlander.dsl.template.rb, line 48
def initialize
  @mappings = []
  @subcomponents = []
  @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 = []
  @conditions = []
  @config_overrides = {}
  @extended_template = nil
  # execution blocks for subcomponents
  @subcomponents_exec = {}
  @template_dir = nil
  @publish_artifacts = []
end

Public Instance Methods

Component(template_arg = nil, template: nil, name: template, param_values: {}, config: {}, export_config: {}, conditional: false, condition: nil, enabled: true, dependson: [], render: Cfhighlander::Model::Component::Substack, &block) click to toggle source
# File lib/cfhighlander.dsl.template.rb, line 123
def Component(template_arg = nil, template: nil,
    name: template,
    param_values: {},
    config: {},
    export_config: {},
    conditional: false,
    condition: nil,
    enabled: true,
    dependson: [],
    render: Cfhighlander::Model::Component::Substack,
    &block)
  puts "INFO: Requested subcomponent #{name} with template #{template}"
  if ((not template_arg.nil?) and template.nil?)
    template = template_arg
  elsif (template_arg.nil? and template.nil?)
    raise 'Component must be defined with template name at minimum,' +
        ' passed as first argument, or template: named arguent'
  end

  name = template if name.nil?

  # load component
  component = Cfhighlander::Dsl::Subcomponent.new(self,
      name,
      template,
      param_values,
      @component_sources,
      config,
      export_config,
      conditional,
      condition,
      enabled,
      dependson,
      render == Cfhighlander::Model::Component::Inline
  )
  # component.instance_eval(&block) unless block.nil?
  @subcomponents_exec[name] = block unless block.nil?
  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
  @subcomponents << component
end
ComponentDistribution(s3_url) click to toggle source
# File lib/cfhighlander.dsl.template.rb, line 183
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) click to toggle source
# File lib/cfhighlander.dsl.template.rb, line 204
def ComponentSources(sources_array)
  @component_sources = sources_array
end
ComponentVersion(version) click to toggle source
# File lib/cfhighlander.dsl.template.rb, line 167
def ComponentVersion(version)
  @version = version
  @config['component_version'] = version
  build_distribution_url
end
Condition(name, expression) click to toggle source

def ComponentParam(argc*, argv)

@parameters.ComponentParam(argc, argv)

end

# File lib/cfhighlander.dsl.template.rb, line 106
def Condition(name, expression)
  @conditions << Condition.new(name, expression)
end
DependsOn(template) click to toggle source
# File lib/cfhighlander.dsl.template.rb, line 115
def DependsOn(template)
  @dependson_components_templates << template
end
Description(description) click to toggle source
# File lib/cfhighlander.dsl.template.rb, line 87
def Description(description)
  @description = description
  @config['description'] = description
end
DistributionBucket(bucket_name) click to toggle source
# File lib/cfhighlander.dsl.template.rb, line 178
def DistributionBucket(bucket_name)
  @distribution_bucket = bucket_name
  build_distribution_url
end
DistributionPrefix(prefix) click to toggle source
# File lib/cfhighlander.dsl.template.rb, line 173
def DistributionPrefix(prefix)
  @distribution_prefix = prefix
  build_distribution_url
end
DynamicMappings(providerName) click to toggle source
# File lib/cfhighlander.dsl.template.rb, line 110
def DynamicMappings(providerName)
  maps = mappings_provider_maps(providerName, self.config)
  maps.each { |name, map| addMapping(name, map) } unless maps.nil?
end
Extends(template) click to toggle source
# File lib/cfhighlander.dsl.template.rb, line 119
def Extends(template)
  @extended_template = template
end
LambdaFunctions(config_key) click to toggle source
# File lib/cfhighlander.dsl.template.rb, line 208
def LambdaFunctions(config_key)
  @lambda_functions_keys << config_key
end
Name(name) click to toggle source
# File lib/cfhighlander.dsl.template.rb, line 78
def Name(name)
  # nested components always have their name dictated by parent
  # component, defaulting to template name
  if (not @config.key? 'nested_component')
    @name = name
    @config['component_name'] = name
  end
end
Parameters(&block) click to toggle source
# File lib/cfhighlander.dsl.template.rb, line 97
def Parameters(&block)
  @parameters.config = @config
  @parameters.instance_eval(&block) unless block.nil?
end
PublishArtifact(file: nil, key: key=nil) click to toggle source
# File lib/cfhighlander.dsl.template.rb, line 212
def PublishArtifact(file: nil, key: key=nil)
  puts "INFO: adding artifact #{file} to publishing list"
  @publish_artifacts << {file: file, key: key}
end
addMapping(name, map) click to toggle source

DSL statements

# File lib/cfhighlander.dsl.template.rb, line 72
def addMapping(name, map)
  @mappings << name
  @config['mappings'] = {} unless @config.key?('mappings')
  @config['mappings'][name] = map
end
apply_config_exports() click to toggle source
# File lib/cfhighlander.dsl.template.rb, line 344
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

  @subcomponents.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("INFO: Exporting key #{global_export_key} from component #{component.name} to #{cname}")
                    co[global_export_key] = cl.config[global_export_key]
                  end
                else
                  puts("INFO: 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() click to toggle source
# File lib/cfhighlander.dsl.template.rb, line 324
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() click to toggle source

def name=(value)

self.Name(value)

end

# File lib/cfhighlander.dsl.template.rb, line 454
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?
    @subcomponents.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
distribute_bucket=(value) click to toggle source
# File lib/cfhighlander.dsl.template.rb, line 440
def distribute_bucket=(value)
  @distribution_bucket = value
  build_distribution_url
end
distribute_prefix=(value) click to toggle source
# File lib/cfhighlander.dsl.template.rb, line 445
def distribute_prefix=(value)
  @distribution_prefix = value
  build_distribution_url
end
loadComponents() click to toggle source

Internal and interface functions

# File lib/cfhighlander.dsl.template.rb, line 219
def loadComponents

  # empty config overrides to start with
  @config_overrides = Hash[@subcomponents.collect { |c| [c.name, { 'nested_component' => true }] }]
  @named_components = Hash[@subcomponents.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
  @subcomponents.each do |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|

      # for map parameters add maps
      if param.class == Cfhighlander::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
    if @subcomponents_exec.key? component.name
      component.instance_eval &@subcomponents_exec[component.name]
    end
    component.component_loaded.eval_cfndsl
  end

  # in 2nd pass, load parameters
  # 2nd pass is required as all of cfndsl models need to be populated
  available_outputs = {}
  @subcomponents.each do |c|
    c.component_loaded.outputs.each do |out|
      available_outputs[out.name] = out
    end
  end

  @subcomponents.each do |component|
    component.resolve_parameter_values available_outputs
  end

  @dependson_components_templates.each do |template|
    component = Cfhighlander::Dsl::Subcomponent.new(self,
        template,
        template,
        {},
        @component_sources
    )
    component.load
    @dependson_components << component
  end
end
load_configfile_component_config() click to toggle source
# File lib/cfhighlander.dsl.template.rb, line 330
def load_configfile_component_config
  if (@config.key? 'components')
    @config['components'].each { |component_name, component_config|
      if component_config.key?('config')
        if @config_overrides.key? component_name
          @config_overrides[component_name].extend(component_config['config'])
        else
          STDERR.puts("WARN: Overriding config for non-existing component #{component_name}")
        end
      end
    }
  end
end
load_explicit_component_config() click to toggle source
# File lib/cfhighlander.dsl.template.rb, line 433
def load_explicit_component_config
  @component_configs.each { |component_name, component_config|
    @config_overrides[component_name].extend(component_config)
  }

end
load_extension_exports() click to toggle source
# File lib/cfhighlander.dsl.template.rb, line 304
def load_extension_exports
  @subcomponents.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"
          @subcomponents.each do |cr|
            cr.component_loaded.cfndsl_ext_files << extension_file_path unless cr == c
          end
        end
      end

    end
  end
end
template_dir=(value) click to toggle source
# File lib/cfhighlander.dsl.template.rb, line 92
def template_dir=(value)
  @template_dir = value
  @config['template_dir'] = value
end