cfhighlander 0.2.1 → 0.3.0.alpha.1528936037
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +199 -82
- data/bin/cfhighlander +1 -1
- data/bin/{highlander.rb → cfhighlander.rb} +39 -23
- data/cfndsl_ext/sg.rb +29 -2
- data/hl_ext/mapping_helper.rb +6 -4
- data/lib/{highlander.compiler.rb → cfhighlander.compiler.rb} +26 -18
- data/lib/{highlander.dsl.base.rb → cfhighlander.dsl.base.rb} +3 -2
- data/lib/cfhighlander.dsl.params.rb +108 -0
- data/lib/cfhighlander.dsl.subcomponent.rb +274 -0
- data/lib/{highlander.dsl.rb → cfhighlander.dsl.template.rb} +111 -63
- data/lib/cfhighlander.factory.rb +45 -0
- data/lib/cfhighlander.factory.templatefinder.rb +248 -0
- data/lib/{highlander.helper.rb → cfhighlander.helper.rb} +2 -2
- data/lib/{highlander.mapproviders.rb → cfhighlander.mapproviders.rb} +1 -1
- data/lib/cfhighlander.model.component.rb +177 -0
- data/lib/cfhighlander.model.templatemeta.rb +25 -0
- data/lib/{highlander.publisher.rb → cfhighlander.publisher.rb} +3 -3
- data/lib/{highlander.validator.rb → cfhighlander.validator.rb} +1 -1
- data/lib/util/zip.util.rb +1 -1
- data/templates/cfndsl.component.template.erb +15 -14
- metadata +38 -15
- data/lib/highlander.dsl.component.rb +0 -243
- data/lib/highlander.dsl.params.rb +0 -113
- data/lib/highlander.factory.rb +0 -359
data/lib/highlander.factory.rb
DELETED
@@ -1,359 +0,0 @@
|
|
1
|
-
require_relative './highlander.dsl'
|
2
|
-
require 'fileutils'
|
3
|
-
require 'git'
|
4
|
-
|
5
|
-
LOCAL_HIGHLANDER_CACHE_LOCATION = "#{ENV['HOME']}/.highlander/components"
|
6
|
-
|
7
|
-
module Highlander
|
8
|
-
|
9
|
-
module Factory
|
10
|
-
|
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
|
-
:version,
|
22
|
-
:distribution_bucket,
|
23
|
-
:distribution_prefix,
|
24
|
-
:component_files,
|
25
|
-
:cfndsl_ext_files,
|
26
|
-
:lambda_src_files
|
27
|
-
|
28
|
-
def initialize(component_name, component_dir)
|
29
|
-
@name = component_name
|
30
|
-
@component_dir = component_dir
|
31
|
-
@mappings = {}
|
32
|
-
@version = nil
|
33
|
-
@distribution_bucket = nil
|
34
|
-
@distribution_prefix = nil
|
35
|
-
@component_files = []
|
36
|
-
@cfndsl_ext_files = []
|
37
|
-
@lambda_src_files = []
|
38
|
-
end
|
39
|
-
|
40
|
-
def load_config()
|
41
|
-
@config = {} if @config.nil?
|
42
|
-
Dir["#{@component_dir}/*.config.yaml"].each do |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
|
-
|
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
|
-
# @param [Hash] config_override
|
61
|
-
def load(config_override = nil)
|
62
|
-
if @component_dir.start_with? 'http'
|
63
|
-
raise StandardError, 'http(s) sources not supported yet'
|
64
|
-
end
|
65
|
-
|
66
|
-
|
67
|
-
@highlander_dsl_path = "#{@component_dir}/#{@name}.highlander.rb"
|
68
|
-
@cfndsl_path = "#{@component_dir}/#{@name}.cfndsl.rb"
|
69
|
-
candidate_config_path = "#{@component_dir}/#{@name}.config.yaml"
|
70
|
-
candidate_mappings_path = "#{@component_dir}/*.mappings.yaml"
|
71
|
-
candidate_dynamic_mappings_path = "#{@component_dir}/#{@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
|
-
# allow override of components
|
83
|
-
# config_override.each do |key, value|
|
84
|
-
# @config[key] = value
|
85
|
-
# end unless config_override.nil?
|
86
|
-
|
87
|
-
Dir[candidate_mappings_path].each do |mapping_file|
|
88
|
-
mappings = YAML.load(File.read(mapping_file))
|
89
|
-
@component_files << mapping_file
|
90
|
-
mappings.each do |name, map|
|
91
|
-
@mappings[name] = map
|
92
|
-
end unless mappings.nil?
|
93
|
-
end
|
94
|
-
|
95
|
-
if File.exist? candidate_dynamic_mappings_path
|
96
|
-
require candidate_dynamic_mappings_path
|
97
|
-
@component_files << candidate_dynamic_mappings_path
|
98
|
-
end
|
99
|
-
|
100
|
-
# 1st pass - parse the file
|
101
|
-
@component_files << @highlander_dsl_path
|
102
|
-
@highlander_dsl = eval(File.read(@highlander_dsl_path), binding)
|
103
|
-
|
104
|
-
# set version if not defined
|
105
|
-
@highlander_dsl.ComponentVersion(@version) unless @version.nil?
|
106
|
-
|
107
|
-
|
108
|
-
# Handle name and description defaults if they are not specified
|
109
|
-
# in template itself
|
110
|
-
if @highlander_dsl.name.nil?
|
111
|
-
@highlander_dsl.name = @name
|
112
|
-
end
|
113
|
-
|
114
|
-
if @highlander_dsl.description.nil?
|
115
|
-
@highlander_dsl.Description("#{@highlander_dsl.name} - #{@highlander_dsl.version}")
|
116
|
-
end
|
117
|
-
|
118
|
-
# set (override) distribution options
|
119
|
-
@highlander_dsl.DistributionBucket(@distribution_bucket) unless @distribution_bucket.nil?
|
120
|
-
@highlander_dsl.DistributionPrefix(@distribution_prefix) unless @distribution_prefix.nil?
|
121
|
-
|
122
|
-
if File.exist? @cfndsl_path
|
123
|
-
@component_files << @cfndsl_path
|
124
|
-
@cfndsl_content = File.read(@cfndsl_path)
|
125
|
-
@cfndsl_content.strip!
|
126
|
-
# if there is CloudFormation do [content] end extract only contents
|
127
|
-
### Regex \s is whitespace
|
128
|
-
match_data = /^CloudFormation do\s(.*)end\s?$/m.match(@cfndsl_content)
|
129
|
-
if not match_data.nil?
|
130
|
-
@cfndsl_content = match_data[1]
|
131
|
-
end
|
132
|
-
|
133
|
-
else
|
134
|
-
@cfndsl_content = ''
|
135
|
-
end
|
136
|
-
|
137
|
-
loadDepandantExt()
|
138
|
-
end
|
139
|
-
end
|
140
|
-
|
141
|
-
class ComponentFactory
|
142
|
-
|
143
|
-
attr_accessor :component_sources
|
144
|
-
|
145
|
-
|
146
|
-
def initialize(component_sources = [])
|
147
|
-
## First look in local $PWD/components folder
|
148
|
-
## Then search for cached $HOME/.highlander/components
|
149
|
-
## Then search in sources given by dsl
|
150
|
-
default_locations = [
|
151
|
-
LOCAL_HIGHLANDER_CACHE_LOCATION,
|
152
|
-
File.expand_path('components'),
|
153
|
-
File.expand_path('.')
|
154
|
-
]
|
155
|
-
default_locations.each do |predefined_path|
|
156
|
-
component_sources.unshift(predefined_path)
|
157
|
-
end
|
158
|
-
|
159
|
-
@component_sources = component_sources
|
160
|
-
end
|
161
|
-
|
162
|
-
def findComponentDefault(component_name, component_version)
|
163
|
-
default_lookup_url = 'https://github.com/theonestack'
|
164
|
-
default_lookup_url = ENV['HIGHLANDER_DEFAULT_COMPONENT_GIT_LOOKUP'] if ENV.key? 'HIGHLANDER_DEFAULT_COMPONENT_GIT_LOOKUP'
|
165
|
-
|
166
|
-
git_url = "#{default_lookup_url}/hl-component-#{component_name}"
|
167
|
-
|
168
|
-
if component_version.nil? or component_version.empty? or component_version == 'latest'
|
169
|
-
branch = 'master'
|
170
|
-
else
|
171
|
-
branch = component_version
|
172
|
-
end
|
173
|
-
local_path = "#{LOCAL_HIGHLANDER_CACHE_LOCATION}/#{component_name}/#{component_version}"
|
174
|
-
return findComponentGit(local_path, component_name, component_version, git_url, branch)
|
175
|
-
|
176
|
-
end
|
177
|
-
|
178
|
-
def findComponentGit(local_path, component_name, component_version, git_url, branch)
|
179
|
-
begin
|
180
|
-
local_path = "#{local_path}/" unless local_path.end_with? '/'
|
181
|
-
# if this is snapshot, clean local cache
|
182
|
-
if branch.end_with? '.snapshot'
|
183
|
-
branch = branch.gsub('.snapshot', '')
|
184
|
-
FileUtils.rmtree local_path if File.exist? local_path and File.directory? local_path
|
185
|
-
end
|
186
|
-
|
187
|
-
# if local cache exists, return from cache
|
188
|
-
if not Dir.glob("#{local_path}*.highlander.rb").empty?
|
189
|
-
# if cache exists, just return from cache
|
190
|
-
component_name = Dir.glob("#{local_path}*.highlander.rb")[0].gsub(local_path, '').gsub('.highlander.rb','')
|
191
|
-
return component_name, local_path
|
192
|
-
end
|
193
|
-
|
194
|
-
# shallow clone
|
195
|
-
puts "Trying to load #{component_name}/#{component_version} from #{git_url}##{branch} ... "
|
196
|
-
clone_opts = { depth: 1 }
|
197
|
-
clone_opts[:branch] = branch if not (branch.nil? or branch.empty?)
|
198
|
-
Git.clone git_url, local_path, clone_opts
|
199
|
-
puts "\t .. cached in #{local_path}\n"
|
200
|
-
# return from cache once it's cloned
|
201
|
-
return findComponentGit(local_path, component_name, component_version, git_url, branch)
|
202
|
-
rescue Exception => e
|
203
|
-
STDERR.puts "Failed to resolve component #{component_name}@#{component_version} from #{git_url}"
|
204
|
-
STDERR.puts e
|
205
|
-
return nil
|
206
|
-
end
|
207
|
-
end
|
208
|
-
|
209
|
-
def findComponentS3(s3_location, component_name, component_version)
|
210
|
-
parts = s3_location.split('/')
|
211
|
-
bucket = parts[2]
|
212
|
-
prefix = parts[3]
|
213
|
-
s3_key = "#{prefix}/#{component_name}/#{component_version}/#{component_name}.highlander.rb"
|
214
|
-
s3_prefix = "#{prefix}/#{component_name}/#{component_version}/"
|
215
|
-
local_destination = "#{LOCAL_HIGHLANDER_CACHE_LOCATION}/#{component_name}/#{component_version}"
|
216
|
-
begin
|
217
|
-
s3 = Aws::S3::Client.new({ region: s3_bucket_region(bucket) })
|
218
|
-
FileUtils.mkdir_p local_destination unless Dir.exist? local_destination
|
219
|
-
|
220
|
-
hl_content = s3.get_object({ bucket: bucket,
|
221
|
-
key: s3_key,
|
222
|
-
response_target: "#{local_destination}/#{component_name}.highlander.rb"
|
223
|
-
})
|
224
|
-
# if code execution got so far we consider file exists and download it locally
|
225
|
-
component_files = s3.list_objects_v2({ bucket: bucket, prefix: s3_prefix })
|
226
|
-
component_files.contents.each {|s3_object|
|
227
|
-
file_name = s3_object.key.gsub(s3_prefix, '')
|
228
|
-
destination_file = "#{local_destination}/#{file_name}"
|
229
|
-
destination_dir = File.dirname(destination_file)
|
230
|
-
print "Caching #{file_name} of #{component_name}@#{component_version} in #{destination_dir} ... "
|
231
|
-
|
232
|
-
FileUtils.mkpath(destination_dir) unless File.exists?(destination_dir)
|
233
|
-
s3.get_object({ bucket: bucket, key: s3_object.key, response_target: destination_file })
|
234
|
-
print " [OK] \n"
|
235
|
-
}
|
236
|
-
return local_destination
|
237
|
-
rescue => e
|
238
|
-
# this handles both nonexisting key and bucket
|
239
|
-
puts("#{component_name} not found in s3://#{bucket}/#{prefix}")
|
240
|
-
STDERR.puts(e.to_s) unless e.message.include? 'does not exist'
|
241
|
-
return nil
|
242
|
-
end
|
243
|
-
end
|
244
|
-
|
245
|
-
def findComponentGitTemplate(component_name, component_version)
|
246
|
-
if component_name.include? '#'
|
247
|
-
parts = component_name.split('#')
|
248
|
-
component_name = parts[0]
|
249
|
-
component_version = parts[1]
|
250
|
-
end
|
251
|
-
|
252
|
-
# avoid any nres
|
253
|
-
component_version = '' if component_version.nil?
|
254
|
-
|
255
|
-
# if empty or latest branch is empty
|
256
|
-
if component_version.empty? or component_version == 'latest' or component_version == 'latest.snapshot'
|
257
|
-
branch = ''
|
258
|
-
else
|
259
|
-
# otherwise component version is actual branch
|
260
|
-
branch = component_version
|
261
|
-
end
|
262
|
-
|
263
|
-
|
264
|
-
git_url = nil
|
265
|
-
if component_name.start_with? 'git:'
|
266
|
-
git_url = component_name.gsub('git:', '')
|
267
|
-
elsif component_name.start_with? 'github:'
|
268
|
-
git_url = "https://github.com/#{component_name.gsub('github:', '')}"
|
269
|
-
elsif component_name.start_with? 'github.com:'
|
270
|
-
git_url = "https://github.com/#{component_name.gsub('github.com:', '')}"
|
271
|
-
end
|
272
|
-
|
273
|
-
local_path = "#{LOCAL_HIGHLANDER_CACHE_LOCATION}/#{component_name}/#{component_version}"
|
274
|
-
|
275
|
-
if not git_url.nil?
|
276
|
-
component_name, location = findComponentGit(local_path, component_name, component_version, git_url, branch)
|
277
|
-
if location.nil?
|
278
|
-
raise "Could not resolve component #{component_name}@#{component_version}"
|
279
|
-
else
|
280
|
-
return component_name, location
|
281
|
-
end
|
282
|
-
end
|
283
|
-
|
284
|
-
return nil
|
285
|
-
end
|
286
|
-
|
287
|
-
# Find component and given list of sources
|
288
|
-
# @return [Highlander::Factory::Component]
|
289
|
-
def findComponent(component_name, component_version = nil)
|
290
|
-
|
291
|
-
component_version_s = component_version.nil? ? 'latest' : component_version
|
292
|
-
component_version = nil if component_version == 'latest'
|
293
|
-
|
294
|
-
if component_name.include? '@' and (not component_name.start_with? 'git')
|
295
|
-
parts = component_name.split('@')
|
296
|
-
component_name = parts[0]
|
297
|
-
component_version = parts[1]
|
298
|
-
end
|
299
|
-
|
300
|
-
# if component specified as git location
|
301
|
-
new_name, candidate_git = findComponentGitTemplate(component_name, component_version_s)
|
302
|
-
return buildComponent(new_name, candidate_git) unless candidate_git.nil?
|
303
|
-
|
304
|
-
# if not git but has .snapshot lookup in default
|
305
|
-
if (not component_version.nil?) and component_version.end_with? '.snapshot'
|
306
|
-
new_name, default_candidate = findComponentDefault(component_name, component_version_s)
|
307
|
-
return buildComponent(new_name, default_candidate) unless default_candidate.nil?
|
308
|
-
end
|
309
|
-
|
310
|
-
# try in all of the component source
|
311
|
-
@component_sources.each do |source|
|
312
|
-
component_full_name = "#{component_name}@#{component_version.nil? ? 'latest' : component_version}"
|
313
|
-
# TODO handle http(s) sources and their download to local
|
314
|
-
if source.start_with?('http')
|
315
|
-
raise StandardError, 'http(s) sources not supported yet'
|
316
|
-
elsif source.start_with?('s3://')
|
317
|
-
# s3 candidate
|
318
|
-
|
319
|
-
s3_candidate = findComponentS3(source, component_name, component_version_s)
|
320
|
-
if not s3_candidate.nil?
|
321
|
-
# at this point all component files are download to local file system and consumed from there
|
322
|
-
return buildComponent(component_name, s3_candidate)
|
323
|
-
end
|
324
|
-
|
325
|
-
else
|
326
|
-
# file system candidate
|
327
|
-
candidate = "#{source}/#{component_name}"
|
328
|
-
candidate = "#{candidate}/#{component_version}" unless component_version.nil?
|
329
|
-
candidate_hl_path = "#{candidate}/#{component_name}.highlander.rb"
|
330
|
-
candidate2_hl_path = "#{source}/#{component_name}.highlander.rb"
|
331
|
-
puts "Trying to load #{component_full_name} from #{candidate} ... "
|
332
|
-
if File.exist?(candidate_hl_path)
|
333
|
-
return buildComponent(component_name, candidate)
|
334
|
-
end
|
335
|
-
puts "Trying to load #{component_full_name} from #{source} ... "
|
336
|
-
if File.exist?(candidate2_hl_path)
|
337
|
-
return buildComponent(component_name, source)
|
338
|
-
end unless component_version_s != 'latest'
|
339
|
-
end
|
340
|
-
end
|
341
|
-
|
342
|
-
# try default component source on github
|
343
|
-
component_name, default_candidate = findComponentDefault(component_name, component_version_s)
|
344
|
-
return buildComponent(component_name, default_candidate) unless default_candidate.nil?
|
345
|
-
|
346
|
-
raise StandardError, "highlander template #{component_name}@#{component_version_s} not located" +
|
347
|
-
" in sources #{@component_sources}"
|
348
|
-
end
|
349
|
-
|
350
|
-
def buildComponent(component_name, component_dir)
|
351
|
-
component = Component.new(component_name, component_dir)
|
352
|
-
component.load_config
|
353
|
-
return component
|
354
|
-
end
|
355
|
-
|
356
|
-
end
|
357
|
-
end
|
358
|
-
|
359
|
-
end
|