cfhighlander 0.2.1.alpha.29 → 0.2.1.alpha.32

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 243c9e2f57eb637952b598302942a48d166a3189e0a4a7698d918224cd3193ce
4
- data.tar.gz: d20c212d3b8a47a6f64e530ec412644a49f5c6ea3d0c93e506b7aa87cc6347f8
3
+ metadata.gz: 8270727d240fc67a59aee1024d65559ba511a6e4fc8cddcbb92cfbca8f596d5d
4
+ data.tar.gz: 9ef339afe459632b9f894f064f1f008e202d0572329009e762e385939e0e2a76
5
5
  SHA512:
6
- metadata.gz: afbb5e1be2f09e04e577f335a6f3e1155a7ef1688064966253b594199cbe48491e7fb5d49c8efcc9780b736471f51d290b2c510b1718efc3f40f479b94e16648
7
- data.tar.gz: 23d771ecf5399a83d25bfd77f3ac3d1c6d5d0989f1f455d54c23a0f04b11015726446f38b1e0645339465735efdfe09d2ccb5cefae9a7f63817598aa56af33d7
6
+ metadata.gz: 0e083c0ba93e947c211de515119588558e70c6308b495fed0f3513a5fada0b359a0fac540ea02a180a0fca3526be5997fc05983bdc2c0af3720e0c15e4ed22af
7
+ data.tar.gz: 5971ab0b2b99eb615f923a39bbee02656cbed12b6cbc3f22df91dc83ac2d8fdfef56c559bef8ff3935cd4b1331395cf3b9c0ceb4f212f0db38f8bc513a11052f
data/bin/cfhighlander.rb CHANGED
@@ -103,7 +103,7 @@ class HighlanderCli < Thor
103
103
 
104
104
  def cfpublish(component_name)
105
105
  compiler = cfcompile(component_name)
106
- publisher = Highlander::Publisher::Component.new(compiler.component, false)
106
+ publisher = Highlander::Publisher::ComponentPublisher.new(compiler.component, false)
107
107
  publisher.publishFiles(compiler.cfn_template_paths + compiler.lambda_src_paths)
108
108
  end
109
109
 
@@ -130,7 +130,7 @@ class HighlanderCli < Thor
130
130
  component.distribution_prefix = distribution_prefix unless distribution_prefix.nil?
131
131
  component.load
132
132
 
133
- publisher = Highlander::Publisher::Component.new(component, true)
133
+ publisher = Highlander::Publisher::ComponentPublisher.new(component, true)
134
134
  publisher.publishComponent
135
135
  end
136
136
 
@@ -16,7 +16,7 @@ module Highlander
16
16
  end
17
17
 
18
18
 
19
- class Component < DslBase
19
+ class Subcomponent < DslBase
20
20
 
21
21
  attr_accessor :name,
22
22
  :template,
@@ -16,7 +16,7 @@ module Highlander
16
16
 
17
17
  module Dsl
18
18
 
19
- class Template < DslBase
19
+ class HighlanderTemplate < DslBase
20
20
 
21
21
  attr_accessor :mappings,
22
22
  :parameters,
@@ -86,7 +86,7 @@ module Highlander
86
86
  puts "Initialize #{name} with template #{template}"
87
87
 
88
88
  # load component
89
- component = Highlander::Dsl::Component.new(self,
89
+ component = Highlander::Dsl::Subcomponent.new(self,
90
90
  name,
91
91
  template,
92
92
  param_values,
@@ -220,7 +220,7 @@ module Highlander
220
220
  }
221
221
 
222
222
  @dependson_components_templates.each do |template|
223
- component = Highlander::Dsl::Component.new(self,
223
+ component = Highlander::Dsl::Subcomponent.new(self,
224
224
  template,
225
225
  template,
226
226
  {},
@@ -400,7 +400,7 @@ module Highlander
400
400
  end
401
401
 
402
402
  def HighlanderComponent(&block)
403
- instance = Highlander::Dsl::Template.new
403
+ instance = Highlander::Dsl::HighlanderTemplate.new
404
404
 
405
405
  puts "Processing higlander component #{@name}\n\tLocation:#{@highlander_dsl_path}" +
406
406
  "\n\tConfig:#{@config}"
@@ -424,7 +424,7 @@ def HighlanderComponent(&block)
424
424
  instance.DistributionPrefix(@distribution_prefix)
425
425
  end
426
426
 
427
- instance.name = @template
427
+ instance.name = @template.template_name
428
428
  instance.instance_eval(&block)
429
429
 
430
430
 
@@ -1,359 +1,38 @@
1
1
  require_relative './highlander.dsl'
2
+ require_relative './highlander.factory.templatefinder'
3
+ require_relative './highlander.model.component'
2
4
  require 'fileutils'
3
5
  require 'git'
4
6
 
5
- LOCAL_HIGHLANDER_CACHE_LOCATION = "#{ENV['HOME']}/.cfhighlander/components"
6
7
 
7
8
  module Highlander
8
9
 
9
10
  module Factory
10
11
 
11
- class Component
12
-
13
- attr_accessor :component_dir,
14
- :config,
15
- :highlander_dsl_path,
16
- :cfndsl_path,
17
- :highlander_dsl,
18
- :cfndsl_content,
19
- :mappings,
20
- :name,
21
- :template,
22
- :version,
23
- :distribution_bucket,
24
- :distribution_prefix,
25
- :component_files,
26
- :cfndsl_ext_files,
27
- :lambda_src_files
28
-
29
- def initialize(component_template_name,
30
- component_template_version,
31
- component_name, component_dir)
32
- @template = component_template_name
33
- @name = component_name
34
- @component_dir = component_dir
35
- @mappings = {}
36
- @version = component_template_version
37
- @distribution_bucket = nil
38
- @distribution_prefix = nil
39
- @component_files = []
40
- @cfndsl_ext_files = []
41
- @lambda_src_files = []
42
- end
43
-
44
- def load_config()
45
- @config = {} if @config.nil?
46
- Dir["#{@component_dir}/*.config.yaml"].each do |config_file|
47
- puts "Loading config for #{@name}:\n\tread #{config_file} "
48
- partial_config = YAML.load(File.read(config_file))
49
- unless partial_config.nil?
50
- @config.extend(partial_config)
51
- @component_files << config_file
52
- end
53
- end
54
- end
55
-
56
-
57
- def loadDepandantExt()
58
- @highlander_dsl.dependson_components.each do |requirement|
59
- requirement.component_loaded.cfndsl_ext_files.each do |file|
60
- cfndsl_ext_files << file
61
- end
62
- end
63
- end
64
-
65
- # @param [Hash] config_override
66
- def load(config_override = nil)
67
- if @component_dir.start_with? 'http'
68
- raise StandardError, 'http(s) sources not supported yet'
69
- end
70
-
71
-
72
- @highlander_dsl_path = "#{@component_dir}/#{@template}.highlander.rb"
73
- @cfndsl_path = "#{@component_dir}/#{@template}.cfndsl.rb"
74
- candidate_mappings_path = "#{@component_dir}/*.mappings.yaml"
75
- candidate_dynamic_mappings_path = "#{@component_dir}/#{@template}.mappings.rb"
76
-
77
- @cfndsl_ext_files += Dir["#{@component_dir}/ext/cfndsl/*.rb"]
78
- @lambda_src_files += Dir["#{@component_dir}/lambdas/**/*"].find_all {|p| not File.directory? p}
79
- @component_files += @cfndsl_ext_files
80
- @component_files += @lambda_src_files
81
-
82
- @config = {} if @config.nil?
83
-
84
- @config.extend config_override unless config_override.nil?
85
- @config['component_version'] = @version unless @version.nil?
86
- @config['component_name'] = @name
87
- # allow override of components
88
- # config_override.each do |key, value|
89
- # @config[key] = value
90
- # end unless config_override.nil?
91
-
92
- Dir[candidate_mappings_path].each do |mapping_file|
93
- mappings = YAML.load(File.read(mapping_file))
94
- @component_files << mapping_file
95
- mappings.each do |name, map|
96
- @mappings[name] = map
97
- end unless mappings.nil?
98
- end
99
-
100
- if File.exist? candidate_dynamic_mappings_path
101
- require candidate_dynamic_mappings_path
102
- @component_files << candidate_dynamic_mappings_path
103
- end
104
-
105
- # 1st pass - parse the file
106
- @component_files << @highlander_dsl_path
107
- @highlander_dsl = eval(File.read(@highlander_dsl_path), binding)
108
- # set version if not defined
109
- @highlander_dsl.ComponentVersion(@version) unless @version.nil?
110
-
111
-
112
- if @highlander_dsl.description.nil?
113
- @highlander_dsl.Description("#{@highlander_dsl.name} - #{@highlander_dsl.version}")
114
- end
115
-
116
- # set (override) distribution options
117
- @highlander_dsl.DistributionBucket(@distribution_bucket) unless @distribution_bucket.nil?
118
- @highlander_dsl.DistributionPrefix(@distribution_prefix) unless @distribution_prefix.nil?
119
-
120
- if File.exist? @cfndsl_path
121
- @component_files << @cfndsl_path
122
- @cfndsl_content = File.read(@cfndsl_path)
123
- @cfndsl_content.strip!
124
- # if there is CloudFormation do [content] end extract only contents
125
- ### Regex \s is whitespace
126
- match_data = /^CloudFormation do\s(.*)end\s?$/m.match(@cfndsl_content)
127
- if not match_data.nil?
128
- @cfndsl_content = match_data[1]
129
- end
130
-
131
- else
132
- @cfndsl_content = ''
133
- end
134
-
135
- loadDepandantExt()
136
- end
137
- end
138
-
139
12
  class ComponentFactory
140
13
 
141
14
  attr_accessor :component_sources
142
15
 
143
-
144
16
  def initialize(component_sources = [])
145
- ## First look in local $PWD/components folder
146
- ## Then search for cached $HOME/.highlander/components
147
- ## Then search in sources given by dsl
148
- default_locations = [
149
- LOCAL_HIGHLANDER_CACHE_LOCATION,
150
- File.expand_path('components'),
151
- File.expand_path('.')
152
- ]
153
- default_locations.each do |predefined_path|
154
- component_sources.unshift(predefined_path)
155
- end
156
-
157
- @component_sources = component_sources
158
- end
159
-
160
- def findTemplateDefault(template_name, component_version)
161
- default_lookup_url = 'https://github.com/theonestack'
162
- default_lookup_url = ENV['HIGHLANDER_DEFAULT_COMPONENT_GIT_LOOKUP'] if ENV.key? 'HIGHLANDER_DEFAULT_COMPONENT_GIT_LOOKUP'
163
-
164
- git_url = "#{default_lookup_url}/hl-component-#{template_name}"
165
-
166
- if component_version.nil? or component_version.empty? or component_version == 'latest'
167
- branch = 'master'
168
- else
169
- branch = component_version
170
- end
171
- local_path = "#{LOCAL_HIGHLANDER_CACHE_LOCATION}/#{template_name}/#{component_version}"
172
- return findTemplateGit(local_path, template_name, component_version, git_url, branch)
173
-
174
- end
175
-
176
- def findTemplateGit(cache_path, component_name, component_version, git_url, branch)
177
- begin
178
- cache_path = "#{cache_path}/" unless cache_path.end_with? '/'
179
- # if this is snapshot, clean local cache
180
- if branch.end_with? '.snapshot'
181
- branch = branch.gsub('.snapshot', '')
182
- FileUtils.rmtree cache_path if File.exist? cache_path and File.directory? cache_path
183
- end
184
-
185
- # if local cache exists, return from cache
186
- if not Dir.glob("#{cache_path}*.highlander.rb").empty?
187
- # if cache exists, just return from cache
188
- component_name = Dir.glob("#{cache_path}*.highlander.rb")[0].gsub(cache_path, '').gsub('.highlander.rb', '')
189
- return component_name, cache_path
190
- end
191
-
192
- # shallow clone
193
- puts "Trying to load #{component_name}/#{component_version} from #{git_url}##{branch} ... "
194
- clone_opts = { depth: 1 }
195
- clone_opts[:branch] = branch if not (branch.nil? or branch.empty?)
196
- Git.clone git_url, cache_path, clone_opts
197
- puts "\t .. cached in #{cache_path}\n"
198
- # return from cache once it's cloned
199
- return findTemplateGit(cache_path, component_name, component_version, git_url, branch)
200
- rescue Exception => e
201
- STDERR.puts "Failed to resolve component #{component_name}@#{component_version} from #{git_url}"
202
- STDERR.puts e
203
- return nil
204
- end
205
- end
206
-
207
- def findTemplateS3(s3_location, component_name, component_version)
208
- parts = s3_location.split('/')
209
- bucket = parts[2]
210
- prefix = parts[3]
211
- s3_key = "#{prefix}/#{component_name}/#{component_version}/#{component_name}.highlander.rb"
212
- s3_prefix = "#{prefix}/#{component_name}/#{component_version}/"
213
- local_destination = "#{LOCAL_HIGHLANDER_CACHE_LOCATION}/#{component_name}/#{component_version}"
214
- begin
215
- s3 = Aws::S3::Client.new({ region: s3_bucket_region(bucket) })
216
- FileUtils.mkdir_p local_destination unless Dir.exist? local_destination
217
-
218
- hl_content = s3.get_object({ bucket: bucket,
219
- key: s3_key,
220
- response_target: "#{local_destination}/#{component_name}.highlander.rb"
221
- })
222
- # if code execution got so far we consider file exists and download it locally
223
- component_files = s3.list_objects_v2({ bucket: bucket, prefix: s3_prefix })
224
- component_files.contents.each {|s3_object|
225
- file_name = s3_object.key.gsub(s3_prefix, '')
226
- destination_file = "#{local_destination}/#{file_name}"
227
- destination_dir = File.dirname(destination_file)
228
- print "Caching #{file_name} of #{component_name}@#{component_version} in #{destination_dir} ... "
229
-
230
- FileUtils.mkpath(destination_dir) unless File.exists?(destination_dir)
231
- s3.get_object({ bucket: bucket, key: s3_object.key, response_target: destination_file })
232
- print " [OK] \n"
233
- }
234
- return local_destination
235
- rescue => e
236
- # this handles both nonexisting key and bucket
237
- puts("#{component_name} not found in s3://#{bucket}/#{prefix}")
238
- STDERR.puts(e.to_s) unless e.message.include? 'does not exist'
239
- return nil
240
- end
241
- end
242
-
243
- # will try and locate template based on git template location
244
- # if template location is not git repo, returns nil
245
- def tryFindTemplateGit(template_location, template_version)
246
- if template_location.include? '#'
247
- parts = template_location.split('#')
248
- template_location = parts[0]
249
- template_version = parts[1]
250
- end
251
-
252
- # avoid any nres
253
- template_version = '' if template_version.nil?
254
-
255
- # if empty or latest branch is empty
256
- if template_version.empty? or template_version == 'latest' or template_version == 'latest.snapshot'
257
- branch = ''
258
- else
259
- # otherwise component version is actual branch
260
- branch = template_version
261
- end
262
-
263
-
264
- git_url = nil
265
- if template_location.start_with? 'git:'
266
- git_url = template_location.gsub('git:', '')
267
- elsif template_location.start_with? 'github:'
268
- git_url = "https://github.com/#{template_location.gsub('github:', '')}"
269
- elsif template_location.start_with? 'github.com:'
270
- git_url = "https://github.com/#{template_location.gsub('github.com:', '')}"
271
- end
272
-
273
- local_path = "#{LOCAL_HIGHLANDER_CACHE_LOCATION}/#{template_location}/#{template_version}"
274
-
275
- if not git_url.nil?
276
- template_name, location = findTemplateGit(local_path, template_location, template_version, git_url, branch)
277
- if location.nil?
278
- raise "Could not resolve component #{template_location}@#{template_version}"
279
- else
280
- return template_name, template_version, location
281
- end
282
- end
283
-
284
- return nil
17
+ @template_finder = Highlander::Factory::TemplateFinder.new(component_sources)
285
18
  end
286
19
 
287
20
  # Find component and given list of sources
288
21
  # @return [Highlander::Factory::Component]
289
22
  def loadComponentFromTemplate(template_name, template_version = nil, component_name = nil)
290
23
 
291
- component_version_s = template_version.nil? ? 'latest' : template_version
292
- template_version = nil if template_version == 'latest'
293
- component_name = template_name if component_name.nil?
294
-
295
- if template_name.include? '@' and (not template_name.start_with? 'git')
296
- parts = template_name.split('@')
297
- template_name = parts[0]
298
- template_version = parts[1]
299
- component_version_s = template_version
300
- end
24
+ template_meta = @template_finder.findTemplate(template_name, template_version)
301
25
 
302
- # if component specified as git location
303
- new_template_name, new_version, candidate_git = tryFindTemplateGit(template_name, component_version_s)
304
- return buildComponentFromLocation(new_template_name, new_version, component_name, candidate_git) unless candidate_git.nil?
305
-
306
- # if not git but has .snapshot lookup in default
307
- if (not template_version.nil?) and template_version.end_with? '.snapshot'
308
- new_template_name, default_candidate = findTemplateDefault(template_name, component_version_s)
309
- return buildComponentFromLocation(new_template_name, template_version, component_name, default_candidate) unless default_candidate.nil?
310
- end
311
-
312
- # try in all of the component source
313
- @component_sources.each do |source|
314
- component_full_name = "#{template_name}@#{template_version.nil? ? 'latest' : template_version}"
315
- # TODO handle http(s) sources and their download to local
316
- if source.start_with?('http')
317
- raise StandardError, 'http(s) sources not supported yet'
318
- elsif source.start_with?('s3://')
319
- # s3 candidate
320
-
321
- s3_candidate = findTemplateS3(source, template_name, component_version_s)
322
- if not s3_candidate.nil?
323
- # at this point all component files are download to local file system and consumed from there
324
- return buildComponentFromLocation(template_name, template_version, component_name, s3_candidate)
325
- end
326
-
327
- else
328
- # file system candidate
329
- candidate = "#{source}/#{template_name}"
330
- candidate = "#{candidate}/#{template_version}" unless template_version.nil?
331
- candidate_hl_path = "#{candidate}/#{template_name}.highlander.rb"
332
- candidate2_hl_path = "#{source}/#{template_name}.highlander.rb"
333
- puts "Trying to load #{component_full_name} from #{candidate} ... "
334
- if File.exist?(candidate_hl_path)
335
- return buildComponentFromLocation(template_name, template_version, component_name, candidate)
336
- end
337
- puts "Trying to load #{component_full_name} from #{source} ... "
338
- if File.exist?(candidate2_hl_path)
339
- return buildComponentFromLocation(template_name, template_version, component_name, source)
340
- end unless component_version_s != 'latest'
341
- end
342
- end
26
+ raise StandardError, "highlander template #{template_name}@#{component_version_s} not located" +
27
+ " in sources #{@component_sources}" if template_meta.nil?
343
28
 
344
- # try default component source on github
345
- template_name, default_candidate = findTemplateDefault(template_name, component_version_s)
346
- return buildComponentFromLocation(template_name, template_version, component_name, default_candidate) unless default_candidate.nil?
29
+ return buildComponentFromLocation(template_meta, component_name)
347
30
 
348
- raise StandardError, "highlander template #{template_name}@#{component_version_s} not located" +
349
- " in sources #{@component_sources}"
350
31
  end
351
32
 
352
- def buildComponentFromLocation(template_name,
353
- template_version,
354
- component_name,
355
- template_location)
356
- component = Component.new(template_name, template_version, component_name, template_location)
33
+
34
+ def buildComponentFromLocation(template_meta, component_name)
35
+ component = Model::Component.new(template_meta, component_name)
357
36
  component.load_config
358
37
  return component
359
38
  end
@@ -0,0 +1,231 @@
1
+ LOCAL_HIGHLANDER_CACHE_LOCATION = "#{ENV['HOME']}/.cfhighlander/components"
2
+
3
+ require_relative './highlander.model.templatemeta'
4
+
5
+ module Highlander
6
+
7
+ module Factory
8
+
9
+ class TemplateFinder
10
+
11
+ def initialize(component_sources = [])
12
+ ## First look in local $PWD/components folder
13
+ ## Then search for cached $HOME/.highlander/components
14
+ ## Then search in sources given by dsl
15
+ default_locations = [
16
+ LOCAL_HIGHLANDER_CACHE_LOCATION,
17
+ File.expand_path('components'),
18
+ File.expand_path('.')
19
+ ]
20
+ default_locations.each do |predefined_path|
21
+ component_sources.unshift(predefined_path)
22
+ end
23
+
24
+ @component_sources = component_sources
25
+ end
26
+
27
+ def findTemplateDefault(template_name, component_version)
28
+ default_lookup_url = 'https://github.com/theonestack'
29
+ default_lookup_url = ENV['HIGHLANDER_DEFAULT_COMPONENT_GIT_LOOKUP'] if ENV.key? 'HIGHLANDER_DEFAULT_COMPONENT_GIT_LOOKUP'
30
+
31
+ git_url = "#{default_lookup_url}/hl-component-#{template_name}"
32
+
33
+ if component_version.nil? or component_version.empty? or component_version == 'latest'
34
+ branch = 'master'
35
+ else
36
+ branch = component_version
37
+ end
38
+ local_path = "#{LOCAL_HIGHLANDER_CACHE_LOCATION}/#{template_name}/#{component_version}"
39
+ return findTemplateGit(local_path, template_name, component_version, git_url, branch)
40
+
41
+ end
42
+
43
+ def findTemplateGit(cache_path, component_name, component_version, git_url, branch)
44
+ begin
45
+ cache_path = "#{cache_path}/" unless cache_path.end_with? '/'
46
+ # if this is snapshot, clean local cache
47
+ if branch.end_with? '.snapshot'
48
+ branch = branch.gsub('.snapshot', '')
49
+ FileUtils.rmtree cache_path if File.exist? cache_path and File.directory? cache_path
50
+ end
51
+
52
+ # if local cache exists, return from cache
53
+ if not Dir.glob("#{cache_path}*.highlander.rb").empty?
54
+ # if cache exists, just return from cache
55
+ component_name = Dir.glob("#{cache_path}*.highlander.rb")[0].gsub(cache_path, '').gsub('.highlander.rb', '')
56
+ return component_name, cache_path
57
+ end
58
+
59
+ # shallow clone
60
+ puts "Trying to load #{component_name}/#{component_version} from #{git_url}##{branch} ... "
61
+ clone_opts = { depth: 1 }
62
+ clone_opts[:branch] = branch if not (branch.nil? or branch.empty?)
63
+ Git.clone git_url, cache_path, clone_opts
64
+ puts "\t .. cached in #{cache_path}\n"
65
+ # return from cache once it's cloned
66
+ return findTemplateGit(cache_path, component_name, component_version, git_url, branch)
67
+ rescue Exception => e
68
+ STDERR.puts "Failed to resolve component #{component_name}@#{component_version} from #{git_url}"
69
+ STDERR.puts e
70
+ return nil
71
+ end
72
+ end
73
+
74
+ def findTemplateS3(s3_location, component_name, component_version)
75
+ parts = s3_location.split('/')
76
+ bucket = parts[2]
77
+ prefix = parts[3]
78
+ s3_key = "#{prefix}/#{component_name}/#{component_version}/#{component_name}.highlander.rb"
79
+ s3_prefix = "#{prefix}/#{component_name}/#{component_version}/"
80
+ local_destination = "#{LOCAL_HIGHLANDER_CACHE_LOCATION}/#{component_name}/#{component_version}"
81
+ begin
82
+ s3 = Aws::S3::Client.new({ region: s3_bucket_region(bucket) })
83
+ FileUtils.mkdir_p local_destination unless Dir.exist? local_destination
84
+
85
+ hl_content = s3.get_object({ bucket: bucket,
86
+ key: s3_key,
87
+ response_target: "#{local_destination}/#{component_name}.highlander.rb"
88
+ })
89
+ # if code execution got so far we consider file exists and download it locally
90
+ component_files = s3.list_objects_v2({ bucket: bucket, prefix: s3_prefix })
91
+ component_files.contents.each {|s3_object|
92
+ file_name = s3_object.key.gsub(s3_prefix, '')
93
+ destination_file = "#{local_destination}/#{file_name}"
94
+ destination_dir = File.dirname(destination_file)
95
+ print "Caching #{file_name} of #{component_name}@#{component_version} in #{destination_dir} ... "
96
+
97
+ FileUtils.mkpath(destination_dir) unless File.exists?(destination_dir)
98
+ s3.get_object({ bucket: bucket, key: s3_object.key, response_target: destination_file })
99
+ print " [OK] \n"
100
+ }
101
+ return local_destination
102
+ rescue => e
103
+ # this handles both nonexisting key and bucket
104
+ puts("#{component_name} not found in s3://#{bucket}/#{prefix}")
105
+ STDERR.puts(e.to_s) unless e.message.include? 'does not exist'
106
+ return nil
107
+ end
108
+ end
109
+
110
+ # will try and locate template based on git template location
111
+ # if template location is not git repo, returns nil
112
+ def tryFindTemplateGit(template_location, template_version)
113
+
114
+ # avoid any nres
115
+ template_version = '' if template_version.nil?
116
+
117
+ # if empty or latest branch is empty
118
+ if template_version.empty? or template_version == 'latest' or template_version == 'latest.snapshot'
119
+ branch = ''
120
+ else
121
+ # otherwise component version is actual branch
122
+ branch = template_version
123
+ end
124
+
125
+
126
+ git_url = nil
127
+ if template_location.start_with? 'git:'
128
+ git_url = template_location.gsub('git:', '')
129
+ elsif template_location.start_with? 'github:'
130
+ git_url = "https://github.com/#{template_location.gsub('github:', '')}"
131
+ elsif template_location.start_with? 'github.com:'
132
+ git_url = "https://github.com/#{template_location.gsub('github.com:', '')}"
133
+ end
134
+
135
+
136
+ if not git_url.nil?
137
+ local_path = "#{LOCAL_HIGHLANDER_CACHE_LOCATION}/#{template_location.gsub(':', '_').gsub(/\/+/, '/')}/#{template_version}"
138
+ template_name, location = findTemplateGit(local_path, template_location, template_version, git_url, branch)
139
+ if location.nil?
140
+ raise "Could not resolve component #{template_location}@#{template_version}"
141
+ else
142
+ return template_name, template_version, location
143
+ end
144
+ end
145
+
146
+ return nil
147
+ end
148
+
149
+ def findTemplate(template_name, template_version)
150
+ template_version_s = template_version.nil? ? 'latest' : template_version
151
+ template_version = nil if template_version == 'latest'
152
+ is_git_template = template_name.start_with? 'git'
153
+
154
+ if template_name.include? '@' and (not template_name.start_with? 'git')
155
+ parts = template_name.split('@')
156
+ template_name = parts[0]
157
+ template_version = parts[1]
158
+ template_version_s = template_version
159
+ end
160
+
161
+ if template_name.include? '#' and (is_git_template)
162
+ parts = template_name.split('#')
163
+ template_name = parts[0]
164
+ template_version = parts[1]
165
+ template_version_s = template_version
166
+ end
167
+
168
+ # if component specified as git location
169
+ if is_git_template
170
+ new_template_name, new_version, candidate_git = tryFindTemplateGit(template_name, template_version_s)
171
+ return build_meta(new_template_name, new_version, candidate_git) unless candidate_git.nil?
172
+ end
173
+
174
+ # if not git but has .snapshot lookup in default, it is allowed to reference default
175
+ # snapshots
176
+ if (not template_version.nil?) and template_version.end_with? '.snapshot'
177
+ new_template_name, snapshot_candidate_location = findTemplateDefault(template_name, template_version_s)
178
+ return build_meta(new_template_name, template_version, snapshot_candidate_location) unless snapshot_candidate_location.nil?
179
+ end
180
+
181
+ # try in all of the component sources
182
+ @component_sources.each do |source|
183
+ template_full_name = "#{template_name}@#{template_version.nil? ? 'latest' : template_version}"
184
+ # TODO handle http(s) sources and their download to local
185
+ if source.start_with?('http')
186
+ raise StandardError, 'http(s) sources not supported yet'
187
+ elsif source.start_with?('s3://')
188
+ # s3 candidate
189
+
190
+ s3_candidate = findTemplateS3(source, template_name, template_version_s)
191
+ # at this point all component files are download to local file system and consumed from there
192
+ return build_meta(template_name, template_version_s, s3_candidate) unless s3_candidate.nil?
193
+
194
+ else
195
+ # file system candidate
196
+ candidate = "#{source}/#{template_name}"
197
+ candidate = "#{candidate}/#{template_version}" unless template_version.nil?
198
+ candidate_hl_path = "#{candidate}/#{template_name}.highlander.rb"
199
+ candidate2_hl_path = "#{source}/#{template_name}.highlander.rb"
200
+ puts "TRACE: Trying to load #{template_full_name} from #{candidate} ... "
201
+ if File.exist?(candidate_hl_path)
202
+ return build_meta(template_name, template_version_s, candidate)
203
+ end
204
+ puts "TRACE: Trying to load #{template_full_name} from #{source} ... "
205
+ # if component version is latest it is allowed to search in path
206
+ # with no version component in it
207
+ if File.exist?(candidate2_hl_path)
208
+ return build_meta(template_name, 'latest', source)
209
+ end unless template_version_s != 'latest'
210
+ end
211
+ end
212
+
213
+ # try default component source on github
214
+ template_name, default_candidate = findTemplateDefault(template_name, template_version_s)
215
+ return build_meta(template_name, template_version_s, default_candidate) unless default_candidate.nil?
216
+
217
+ return nil
218
+ end
219
+
220
+ def build_meta(template_name, template_version, template_location)
221
+ return Highlander::Model::TemplateMetadata.new(
222
+ template_name: template_name,
223
+ template_version: template_version,
224
+ template_location: template_location)
225
+ end
226
+
227
+ end
228
+
229
+ end
230
+
231
+ end
@@ -0,0 +1,147 @@
1
+ require 'yaml'
2
+
3
+ module Highlander
4
+
5
+ module Model
6
+
7
+ class Component
8
+
9
+ attr_accessor :component_dir,
10
+ :config,
11
+ :highlander_dsl_path,
12
+ :cfndsl_path,
13
+ :highlander_dsl,
14
+ :cfndsl_content,
15
+ :mappings,
16
+ :name,
17
+ :template,
18
+ :version,
19
+ :distribution_bucket,
20
+ :distribution_prefix,
21
+ :component_files,
22
+ :cfndsl_ext_files,
23
+ :lambda_src_files
24
+
25
+ def initialize(template_meta, component_name)
26
+ @template = template_meta
27
+ @name = component_name
28
+ @component_dir = template_meta.template_location
29
+ @mappings = {}
30
+ @version = template_meta.template_version
31
+ @distribution_bucket = nil
32
+ @distribution_prefix = nil
33
+ @component_files = []
34
+ @cfndsl_ext_files = []
35
+ @lambda_src_files = []
36
+ end
37
+
38
+ # load component configuration files
39
+ def load_config()
40
+ @config = {} if @config.nil?
41
+ Dir["#{@component_dir}/*.config.yaml"].each do |config_file|
42
+ puts "Loading config for #{@name}:\n\tread #{config_file} "
43
+ partial_config = YAML.load(File.read(config_file))
44
+ unless partial_config.nil?
45
+ @config.extend(partial_config)
46
+ @component_files << config_file
47
+ end
48
+ end
49
+ end
50
+
51
+ # load extensions
52
+ def loadDepandantExt()
53
+ @highlander_dsl.dependson_components.each do |requirement|
54
+ requirement.component_loaded.cfndsl_ext_files.each do |file|
55
+ cfndsl_ext_files << file
56
+ end
57
+ end
58
+ end
59
+
60
+ # evaluate components template
61
+ # @param [Hash] config_override
62
+ def load(config_override = nil)
63
+ if @component_dir.start_with? 'http'
64
+ raise StandardError, 'http(s) sources not supported yet'
65
+ end
66
+
67
+
68
+ @highlander_dsl_path = "#{@component_dir}/#{@template.template_name}.highlander.rb"
69
+ @cfndsl_path = "#{@component_dir}/#{@template.template_name}.cfndsl.rb"
70
+ candidate_mappings_path = "#{@component_dir}/*.mappings.yaml"
71
+ candidate_dynamic_mappings_path = "#{@component_dir}/#{@template.template_name}.mappings.rb"
72
+
73
+ @cfndsl_ext_files += Dir["#{@component_dir}/ext/cfndsl/*.rb"]
74
+ @lambda_src_files += Dir["#{@component_dir}/lambdas/**/*"].find_all {|p| not File.directory? p}
75
+ @component_files += @cfndsl_ext_files
76
+ @component_files += @lambda_src_files
77
+
78
+ @config = {} if @config.nil?
79
+
80
+ @config.extend config_override unless config_override.nil?
81
+ @config['component_version'] = @version unless @version.nil?
82
+ @config['component_name'] = @name
83
+ @config['template_name'] = @template.template_name
84
+ @config['template_version'] = @template.template_version
85
+ # allow override of components
86
+ # config_override.each do |key, value|
87
+ # @config[key] = value
88
+ # end unless config_override.nil?
89
+
90
+ Dir[candidate_mappings_path].each do |mapping_file|
91
+ mappings = YAML.load(File.read(mapping_file))
92
+ @component_files << mapping_file
93
+ mappings.each do |name, map|
94
+ @mappings[name] = map
95
+ end unless mappings.nil?
96
+ end
97
+
98
+ if File.exist? candidate_dynamic_mappings_path
99
+ require candidate_dynamic_mappings_path
100
+ @component_files << candidate_dynamic_mappings_path
101
+ end
102
+
103
+ # 1st pass - parse the file
104
+ @component_files << @highlander_dsl_path
105
+ @highlander_dsl = eval(File.read(@highlander_dsl_path), binding)
106
+ # set version if not defined
107
+ @highlander_dsl.ComponentVersion(@version) unless @version.nil?
108
+
109
+
110
+ if @highlander_dsl.description.nil?
111
+ if template.template_name == @name
112
+ description = "#{@name}@#{template.template_version} - v#{@highlander_dsl.version}"
113
+ else
114
+ description = "#{@name} - v#{@highlander_dsl.version}"
115
+ description += " (#{template.template_name}@#{template.template_version})"
116
+ end
117
+
118
+ @highlander_dsl.Description(description)
119
+ end
120
+
121
+ # set (override) distribution options
122
+ @highlander_dsl.DistributionBucket(@distribution_bucket) unless @distribution_bucket.nil?
123
+ @highlander_dsl.DistributionPrefix(@distribution_prefix) unless @distribution_prefix.nil?
124
+
125
+ if File.exist? @cfndsl_path
126
+ @component_files << @cfndsl_path
127
+ @cfndsl_content = File.read(@cfndsl_path)
128
+ @cfndsl_content.strip!
129
+ # if there is CloudFormation do [content] end extract only contents
130
+ ### Regex \s is whitespace
131
+ match_data = /^CloudFormation do\s(.*)end\s?$/m.match(@cfndsl_content)
132
+ if not match_data.nil?
133
+ @cfndsl_content = match_data[1]
134
+ end
135
+
136
+ else
137
+ @cfndsl_content = ''
138
+ end
139
+
140
+ loadDepandantExt()
141
+ end
142
+ end
143
+
144
+ end
145
+
146
+ end
147
+
@@ -0,0 +1,25 @@
1
+ module Highlander
2
+
3
+ module Model
4
+
5
+ class TemplateMetadata
6
+
7
+ @template_name
8
+ @template_version
9
+ @template_location
10
+
11
+ attr_reader :template_location,
12
+ :template_version,
13
+ :template_name
14
+
15
+ def initialize(template_name:, template_version:, template_location:)
16
+ @template_name = template_name
17
+ @template_version = template_version
18
+ @template_location = template_location
19
+ end
20
+
21
+ end
22
+
23
+ end
24
+
25
+ end
@@ -5,7 +5,7 @@ module Highlander
5
5
 
6
6
  module Publisher
7
7
 
8
- class Component
8
+ class ComponentPublisher
9
9
 
10
10
  def initialize(component, cleanup)
11
11
  @component = component
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cfhighlander
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1.alpha.29
4
+ version: 0.2.1.alpha.32
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nikola Tosic
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2018-06-04 00:00:00.000000000 Z
12
+ date: 2018-06-05 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: highline
@@ -249,8 +249,11 @@ files:
249
249
  - lib/highlander.dsl.params.rb
250
250
  - lib/highlander.dsl.rb
251
251
  - lib/highlander.factory.rb
252
+ - lib/highlander.factory.templatefinder.rb
252
253
  - lib/highlander.helper.rb
253
254
  - lib/highlander.mapproviders.rb
255
+ - lib/highlander.model.component.rb
256
+ - lib/highlander.model.templatemeta.rb
254
257
  - lib/highlander.publisher.rb
255
258
  - lib/highlander.validator.rb
256
259
  - lib/util/zip.util.rb