Class: Cfhighlander::Model::Component

Inherits:
Object
  • Object
show all
Defined in:
lib/cfhighlander.model.component.rb

Constant Summary collapse

Inline =
'inline'
Substack =
'substack'

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(template_meta, component_name, factory) ⇒ Component

Returns a new instance of Component.



40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
# File 'lib/cfhighlander.model.component.rb', line 40

def initialize(template_meta, component_name, factory)
  @template = template_meta
  @name = component_name
  @component_dir = template_meta.template_location
  @mappings = {}
  @version = template_meta.template_version
  @distribution_bucket = nil
  @distribution_prefix = nil
  @component_files = []
  @cfndsl_ext_files = []
  @lambda_src_files = []
  @factory = factory
  @extended_component = nil
  @parent_dsl = nil
  @potential_subcomponent_overrides = {}
  @is_parent_component = false
end

Instance Attribute Details

#cfn_modelObject (readonly)

Returns the value of attribute cfn_model.



32
33
34
# File 'lib/cfhighlander.model.component.rb', line 32

def cfn_model
  @cfn_model
end

#cfn_model_rawObject (readonly)

Returns the value of attribute cfn_model_raw.



32
33
34
# File 'lib/cfhighlander.model.component.rb', line 32

def cfn_model_raw
  @cfn_model_raw
end

#cfndsl_contentObject

Returns the value of attribute cfndsl_content.



12
13
14
# File 'lib/cfhighlander.model.component.rb', line 12

def cfndsl_content
  @cfndsl_content
end

#cfndsl_ext_filesObject

Returns the value of attribute cfndsl_ext_files.



12
13
14
# File 'lib/cfhighlander.model.component.rb', line 12

def cfndsl_ext_files
  @cfndsl_ext_files
end

#cfndsl_pathObject

Returns the value of attribute cfndsl_path.



12
13
14
# File 'lib/cfhighlander.model.component.rb', line 12

def cfndsl_path
  @cfndsl_path
end

#component_dirObject

Returns the value of attribute component_dir.



12
13
14
# File 'lib/cfhighlander.model.component.rb', line 12

def component_dir
  @component_dir
end

#component_filesObject

Returns the value of attribute component_files.



12
13
14
# File 'lib/cfhighlander.model.component.rb', line 12

def component_files
  @component_files
end

#configObject

Returns the value of attribute config.



12
13
14
# File 'lib/cfhighlander.model.component.rb', line 12

def config
  @config
end

#distribution_bucketObject

Returns the value of attribute distribution_bucket.



12
13
14
# File 'lib/cfhighlander.model.component.rb', line 12

def distribution_bucket
  @distribution_bucket
end

#distribution_prefixObject

Returns the value of attribute distribution_prefix.



12
13
14
# File 'lib/cfhighlander.model.component.rb', line 12

def distribution_prefix
  @distribution_prefix
end

#extended_componentObject

Returns the value of attribute extended_component.



12
13
14
# File 'lib/cfhighlander.model.component.rb', line 12

def extended_component
  @extended_component
end

#factoryObject

Returns the value of attribute factory.



12
13
14
# File 'lib/cfhighlander.model.component.rb', line 12

def factory
  @factory
end

#highlander_dslObject

Returns the value of attribute highlander_dsl.



12
13
14
# File 'lib/cfhighlander.model.component.rb', line 12

def highlander_dsl
  @highlander_dsl
end

#highlander_dsl_pathObject

Returns the value of attribute highlander_dsl_path.



12
13
14
# File 'lib/cfhighlander.model.component.rb', line 12

def highlander_dsl_path
  @highlander_dsl_path
end

#is_parent_componentObject

Returns the value of attribute is_parent_component.



12
13
14
# File 'lib/cfhighlander.model.component.rb', line 12

def is_parent_component
  @is_parent_component
end

#lambda_src_filesObject

Returns the value of attribute lambda_src_files.



12
13
14
# File 'lib/cfhighlander.model.component.rb', line 12

def lambda_src_files
  @lambda_src_files
end

#mappingsObject

Returns the value of attribute mappings.



12
13
14
# File 'lib/cfhighlander.model.component.rb', line 12

def mappings
  @mappings
end

#nameObject

Returns the value of attribute name.



12
13
14
# File 'lib/cfhighlander.model.component.rb', line 12

def name
  @name
end

#outputsObject (readonly)

Returns the value of attribute outputs.



32
33
34
# File 'lib/cfhighlander.model.component.rb', line 32

def outputs
  @outputs
end

#parent_templateObject

Returns the value of attribute parent_template.



12
13
14
# File 'lib/cfhighlander.model.component.rb', line 12

def parent_template
  @parent_template
end

#potential_subcomponent_overridesObject (readonly)

Returns the value of attribute potential_subcomponent_overrides.



32
33
34
# File 'lib/cfhighlander.model.component.rb', line 32

def potential_subcomponent_overrides
  @potential_subcomponent_overrides
end

#templateObject

Returns the value of attribute template.



12
13
14
# File 'lib/cfhighlander.model.component.rb', line 12

def template
  @template
end

#template_finderObject

Returns the value of attribute template_finder.



12
13
14
# File 'lib/cfhighlander.model.component.rb', line 12

def template_finder
  @template_finder
end

#versionObject

Returns the value of attribute version.



12
13
14
# File 'lib/cfhighlander.model.component.rb', line 12

def version
  @version
end

Instance Method Details

#eval_cfndslObject



242
243
244
245
246
247
248
249
250
251
252
253
254
255
# File 'lib/cfhighlander.model.component.rb', line 242

def eval_cfndsl
  compiler = Cfhighlander::Compiler::ComponentCompiler.new self
  compiler.lambda_mock_resolve = true
  @cfn_model = compiler.evaluateCloudFormation().as_json
  @cfn_model_raw = JSON.parse(@cfn_model.to_json)
  @outputs = (
  if @cfn_model.key? 'Outputs'
  then
    @cfn_model['Outputs'].map { |k, v| ComponentOutput.new self, k, v }
  else
    []
  end
  )
end

#evaluateHiglanderTemplateObject



216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
# File 'lib/cfhighlander.model.component.rb', line 216

def evaluateHiglanderTemplate
  loadCfndslContent

  cfhl_script = ''
  @config.each do |key, val|
    cfhl_script += ("\n#{key} = #{val.inspect}\n")
  end
  cfhl_script += File.read(@highlander_dsl_path)

  cfhl_dsl = eval(cfhl_script, binding)
  if not cfhl_dsl.extended_template.nil?
    @parent_template = cfhl_dsl.extended_template
    inheritParentTemplate
    puts "INFO: #{@template} extends #{@parent_template}, loading parent definition..."
    # 2nd pass, template instance is already created from parent
    @highlander_dsl = eval(cfhl_script, binding)
  else
    @highlander_dsl = cfhl_dsl
  end
end

#inheritParentTemplateObject



177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
# File 'lib/cfhighlander.model.component.rb', line 177

def inheritParentTemplate
  if not @parent_template.nil?
    extended_component = @factory.loadComponentFromTemplate(@parent_template)
    extended_component.is_parent_component = true
    extended_component.load(@config)

    @config = extended_component.config.extend(@config)
    @mappings = extended_component.mappings.extend(@mappings)
    @cfndsl_ext_files += extended_component.cfndsl_ext_files
    @lambda_src_files += extended_component.lambda_src_files
    @extended_component = extended_component

    # extend cfndsl, first comes parent, than child
    # this allows for child component to shadow parent component
    # defined resources
    @cfndsl_content = extended_component.cfndsl_content + @cfndsl_content

    @parent_dsl = extended_component.highlander_dsl

  end
end

#load(config_override = nil) ⇒ Object

evaluate components template

Parameters:

  • config_override (Hash) (defaults to: nil)


103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
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
# File 'lib/cfhighlander.model.component.rb', line 103

def load(config_override = nil)
  if @component_dir.start_with? 'http'
    raise StandardError, 'http(s) sources not supported yet'
  end

  legacy_cfhighlander_path = "#{@component_dir}/#{@template.template_name}.highlander.rb"
  if File.exist? legacy_cfhighlander_path
    STDERR.puts "DEPRECATED: #{legacy_cfhighlander_path} - Use *.cfhighlander.rb"
    @highlander_dsl_path = legacy_cfhighlander_path
    ENV['CF_COMPONENT_PATH'] = @component_dir
  else
    @highlander_dsl_path = "#{@component_dir}/#{@template.template_name}.cfhighlander.rb"
    ENV['CF_COMPONENT_PATH'] = @component_dir
  end

  @cfndsl_path = "#{@component_dir}/#{@template.template_name}.cfndsl.rb"
  candidate_mappings_path = "#{@component_dir}/*.mappings.yaml"
  candidate_dynamic_mappings_path = "#{@component_dir}/#{@template.template_name}.mappings.rb"

  @cfndsl_ext_files += Dir["#{@component_dir}/ext/cfndsl/*.rb"]
  @lambda_src_files += Dir["#{@component_dir}/lambdas/**/*"].find_all { |p| not File.directory? p }
  @component_files += @cfndsl_ext_files
  @component_files += @lambda_src_files

  @config = {} if @config.nil?

  @config.extend config_override unless config_override.nil?
  @config['component_version'] = @version unless @version.nil?
  @config['component_name'] = @name
  @config['template_name'] = @template.template_name
  @config['template_version'] = @template.template_version

  Dir[candidate_mappings_path].each do |mapping_file|
    mappings = YAML.load(File.read(mapping_file))
    @component_files << mapping_file
    mappings.each do |name, map|
      @mappings[name] = map
    end unless mappings.nil?
  end

  if File.exist? candidate_dynamic_mappings_path
    require candidate_dynamic_mappings_path
    @component_files << candidate_dynamic_mappings_path
  end

  @component_files << @highlander_dsl_path


  # evaluate template file and load parent if defined
  evaluateHiglanderTemplate

  # set version if not defined
  @highlander_dsl.ComponentVersion(@version) unless @version.nil?


  if @highlander_dsl.description.nil?
    if template.template_name == @name
      description = "#{@name}@#{template.template_version} - v#{@highlander_dsl.version}"
    else
      description = "#{@name} - v#{@highlander_dsl.version}"
      description += " (#{template.template_name}@#{template.template_version})"
    end

    @highlander_dsl.Description(description)
  end unless @is_parent_component

  # set (override) distribution options
  @highlander_dsl.DistributionBucket(@distribution_bucket) unless @distribution_bucket.nil?
  @highlander_dsl.DistributionPrefix(@distribution_prefix) unless @distribution_prefix.nil?


  loadDepandantExt()
end

#load_configObject

load component configuration files



73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
# File 'lib/cfhighlander.model.component.rb', line 73

def load_config()
  @config = {} if @config.nil?
  Dir["#{@component_dir}/*.config.yaml"].each do |config_file|
    puts "INFO Loading config for #{@name}: read file:#{config_file} "
    partial_config = YAML.load(File.read(config_file))
    if (not partial_config)
      STDERR.puts "WARNING: Configuration file #{config_file} could not be loaded"
      next
    end
    unless (partial_config.nil? or partial_config.key? 'subcomponent_config_file')
      @config.extend(partial_config)
      @component_files << config_file
    end
    fname = File.basename(config_file)
    potential_component_name = fname.gsub('.config.yaml', '')
    @potential_subcomponent_overrides[potential_component_name] = partial_config
  end
end

#loadCfndslContentObject



199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
# File 'lib/cfhighlander.model.component.rb', line 199

def loadCfndslContent
  if File.exist? @cfndsl_path
    @component_files << @cfndsl_path
    @cfndsl_content = File.read(@cfndsl_path)
    @cfndsl_content.strip!
    # if there is CloudFormation do [content] end extract only contents
    ### Regex \s is whitespace
    match_data = /^CloudFormation do\s(.*)end\s?$/m.match(@cfndsl_content)
    if not match_data.nil?
      @cfndsl_content = match_data[1]
    end

  else
    @cfndsl_content = ''
  end
end

#loadDepandantExtObject

load extensions



93
94
95
96
97
98
99
# File 'lib/cfhighlander.model.component.rb', line 93

def loadDepandantExt()
  @highlander_dsl.dependson_components.each do |requirement|
    requirement.component_loaded.cfndsl_ext_files.each do |file|
      @cfndsl_ext_files << file
    end
  end
end

#set_cfndsl_model(value) ⇒ Object

evaluates cfndsl with current config



238
239
240
241
# File 'lib/cfhighlander.model.component.rb', line 238

def set_cfndsl_model(value)
  @cfn_model = value.as_json
  @cfn_model_raw = JSON.parse(@cfn_model.to_json)
end