lono 8.0.0.pre.rc2 → 8.0.0.pre.rc3

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.
Files changed (136) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +15 -2
  3. data/Gemfile +1 -3
  4. data/lib/lono/app/callable_option/concern.rb +12 -0
  5. data/lib/lono/app/callable_option.rb +56 -0
  6. data/lib/lono/app.rb +22 -23
  7. data/lib/lono/autoloader.rb +1 -0
  8. data/lib/lono/aws_services/helper.rb +0 -2
  9. data/lib/lono/blueprint.rb +1 -18
  10. data/lib/lono/builder/allow/base.rb +54 -0
  11. data/lib/lono/builder/allow/env.rb +17 -0
  12. data/lib/lono/builder/allow/region.rb +20 -0
  13. data/lib/lono/builder/allow.rb +8 -0
  14. data/lib/lono/builder/configset/combiner.rb +145 -0
  15. data/lib/lono/builder/configset/definition/base.rb +47 -0
  16. data/lib/lono/builder/configset/definition/context.rb +29 -0
  17. data/lib/lono/{configset/strategy/helpers/dsl → builder/configset/definition/dsl/syntax}/auth.rb +1 -1
  18. data/lib/lono/{configset/strategy/helpers/dsl/core.rb → builder/configset/definition/dsl/syntax/content.rb} +12 -4
  19. data/lib/lono/{configset/strategy/helpers/dsl/syntax.rb → builder/configset/definition/dsl/syntax/core.rb} +15 -9
  20. data/lib/lono/{configset/strategy/helpers/dsl → builder/configset/definition/dsl/syntax}/package.rb +1 -1
  21. data/lib/lono/builder/configset/definition/dsl/syntax.rb +5 -0
  22. data/lib/lono/{configset/strategy → builder/configset/definition}/dsl.rb +10 -14
  23. data/lib/lono/{configset/strategy → builder/configset/definition}/erb.rb +13 -16
  24. data/lib/lono/builder/configset/definition.rb +18 -0
  25. data/lib/lono/builder/configset/evaluator.rb +10 -0
  26. data/lib/lono/builder/configset/registration.rb +35 -0
  27. data/lib/lono/builder/context.rb +40 -0
  28. data/lib/lono/builder/dsl/evaluator.rb +6 -55
  29. data/lib/lono/builder/dsl/finalizer/base.rb +8 -0
  30. data/lib/lono/builder/dsl/finalizer/configsets.rb +7 -28
  31. data/lib/lono/builder/dsl/finalizer/files/base.rb +4 -0
  32. data/lib/lono/builder/dsl/finalizer/files/build.rb +58 -0
  33. data/lib/lono/builder/dsl/finalizer/files/replace.rb +31 -0
  34. data/lib/lono/builder/dsl/finalizer/files.rb +9 -0
  35. data/lib/lono/builder/dsl/finalizer/parameter_groups.rb +4 -3
  36. data/lib/lono/builder/dsl/finalizer.rb +4 -2
  37. data/lib/lono/builder/dsl/helpers/files.rb +7 -0
  38. data/lib/lono/builder/dsl/helpers/partials.rb +48 -53
  39. data/lib/lono/builder/dsl/helpers/s3.rb +1 -1
  40. data/lib/lono/builder/dsl/helpers/ssm/fetcher.rb +3 -1
  41. data/lib/lono/builder/dsl/helpers/template_file.rb +18 -6
  42. data/lib/lono/builder/dsl/helpers.rb +1 -11
  43. data/lib/lono/builder/dsl/syntax/core/resource/property_mover.rb +11 -1
  44. data/lib/lono/builder/dsl/syntax/core/squeezer.rb +16 -2
  45. data/lib/lono/builder/dsl.rb +1 -1
  46. data/lib/lono/builder/param.rb +4 -1
  47. data/lib/lono/builder/template/upload.rb +2 -15
  48. data/lib/lono/cfn/cancel.rb +5 -5
  49. data/lib/lono/cfn/deploy/iam.rb +1 -1
  50. data/lib/lono/cfn/deploy.rb +32 -3
  51. data/lib/lono/cfn/download.rb +0 -1
  52. data/lib/lono/cfn/plan/changeset.rb +2 -2
  53. data/lib/lono/cfn/plan/diff/data.rb +11 -1
  54. data/lib/lono/cfn/plan/param.rb +1 -1
  55. data/lib/lono/cfn/plan/template.rb +2 -2
  56. data/lib/lono/cfn/plan.rb +1 -0
  57. data/lib/lono/cli/abstract.rb +0 -6
  58. data/lib/lono/cli/base.rb +5 -3
  59. data/lib/lono/cli/build.rb +16 -60
  60. data/lib/lono/cli/clean.rb +3 -2
  61. data/lib/lono/cli/code.rb +12 -12
  62. data/lib/lono/cli/help/new/helper/blueprint.md +17 -0
  63. data/lib/lono/cli/help/new/helper/project.md +16 -0
  64. data/lib/lono/cli/list.rb +3 -6
  65. data/lib/lono/cli/new/blueprint.rb +3 -7
  66. data/lib/lono/cli/new/configset.rb +11 -44
  67. data/lib/lono/cli/new/helper/blueprint.rb +26 -0
  68. data/lib/lono/cli/new/helper/project.rb +24 -0
  69. data/lib/lono/cli/new/helper.rb +8 -27
  70. data/lib/lono/cli/new/sequence.rb +6 -1
  71. data/lib/lono/cli/new.rb +8 -12
  72. data/lib/lono/cli/status.rb +18 -0
  73. data/lib/lono/cli.rb +6 -9
  74. data/lib/lono/command.rb +0 -1
  75. data/lib/lono/component.rb +29 -0
  76. data/lib/lono/concerns/aws_info.rb +14 -0
  77. data/lib/lono/concerns/names.rb +9 -0
  78. data/lib/lono/configset.rb +17 -0
  79. data/lib/lono/core.rb +1 -1
  80. data/lib/lono/ext/bundler.rb +7 -0
  81. data/lib/lono/ext/core/module.rb +31 -0
  82. data/lib/lono/ext/core/object.rb +32 -0
  83. data/lib/lono/ext/core/string.rb +9 -0
  84. data/lib/lono/ext.rb +4 -0
  85. data/lib/lono/files/base.rb +12 -0
  86. data/lib/lono/files/builder.rb +37 -0
  87. data/lib/lono/files/compressor.rb +53 -0
  88. data/lib/lono/files/concerns/post_processing.rb +35 -0
  89. data/lib/lono/files/concerns/registration.rb +13 -0
  90. data/lib/lono/files/registry.rb +6 -0
  91. data/lib/lono/files.rb +37 -0
  92. data/lib/lono/importer/base.rb +1 -1
  93. data/lib/lono/inspector/summary.rb +0 -3
  94. data/lib/lono/layering/layer.rb +3 -17
  95. data/lib/lono/logger.rb +1 -3
  96. data/lib/lono/names.rb +1 -1
  97. data/lib/lono/s3/uploader.rb +29 -28
  98. data/lib/lono/seeder.rb +18 -27
  99. data/lib/lono/user_data.rb +3 -1
  100. data/lib/lono/version.rb +1 -1
  101. data/lib/lono/yamler/validator.rb +7 -22
  102. data/lib/lono.rb +8 -0
  103. data/lib/templates/configset/configset.rb +2 -16
  104. data/lib/templates/examples/configset/configset.rb +16 -0
  105. data/lib/templates/helper/%underscore_name%_helper.rb.tt +1 -1
  106. data/lono.gemspec +1 -1
  107. metadata +52 -39
  108. data/lib/lono/app_file/base.rb +0 -28
  109. data/lib/lono/app_file/build/lambda_layer/ruby_packager.rb +0 -153
  110. data/lib/lono/app_file/build/lambda_layer.rb +0 -20
  111. data/lib/lono/app_file/build.rb +0 -79
  112. data/lib/lono/app_file/registry/item.rb +0 -24
  113. data/lib/lono/app_file/registry.rb +0 -16
  114. data/lib/lono/app_file/upload.rb +0 -12
  115. data/lib/lono/builder/context/generic.rb +0 -11
  116. data/lib/lono/builder/context/loaders/load_files.rb +0 -23
  117. data/lib/lono/builder/context/loaders.rb +0 -35
  118. data/lib/lono/builder/context/params.rb +0 -6
  119. data/lib/lono/builder/context/template.rb +0 -4
  120. data/lib/lono/configset/builder.rb +0 -59
  121. data/lib/lono/configset/combiner.rb +0 -164
  122. data/lib/lono/configset/evaluate_file.rb +0 -8
  123. data/lib/lono/configset/meta/dsl.rb +0 -12
  124. data/lib/lono/configset/meta.rb +0 -19
  125. data/lib/lono/configset/s3_file/build.rb +0 -34
  126. data/lib/lono/configset/s3_file/item.rb +0 -38
  127. data/lib/lono/configset/s3_file/registry.rb +0 -12
  128. data/lib/lono/configset/s3_file/upload.rb +0 -12
  129. data/lib/lono/configset/strategy/base.rb +0 -83
  130. data/lib/lono/configset/strategy/helpers/dsl.rb +0 -8
  131. data/lib/lono/configset/strategy/helpers/erb.rb +0 -9
  132. data/lib/lono/lookup.rb +0 -12
  133. data/lib/lono/seeder/service_role.rb +0 -11
  134. data/lib/lono/utils/contexts.rb +0 -15
  135. data/lib/lono/utils/item/file_methods.rb +0 -29
  136. data/lib/lono/utils/item/zip.rb +0 -42
@@ -1,153 +0,0 @@
1
- class Lono::AppFile::Build::LambdaLayer
2
- # Based on jets
3
- class RubyPackager
4
- include Lono::Utils::Rsync
5
-
6
- def initialize(blueprint, registry_item)
7
- @blueprint.name, @registry_item = blueprint, registry_item
8
-
9
- @registry_name = @registry_item.name.sub(/\/$/,'')
10
- @app_root = "#{@blueprint.root}/app/files/#{@registry_name}"
11
- end
12
-
13
- def build
14
- return unless gemfile_exist?
15
-
16
- bundle_install
17
- package
18
- end
19
-
20
- # We consolidate all gems to opt
21
- def package
22
- setup_bundle_config(output_area)
23
- # copy_cache_gems # TODO: might not need this cache
24
- consolidate_gems_to_opt
25
- end
26
-
27
- # Also restructure the folder from:
28
- # vendor/gems/ruby/2.5.0
29
- # To:
30
- # ruby/gems/2.5.0
31
- #
32
- # For Lambda Layer structure
33
- def consolidate_gems_to_opt
34
- src = "#{cache_area}/vendor/gems/ruby/#{ruby_folder}"
35
- dest = "#{opt_area}/ruby/gems/#{ruby_folder}"
36
- rsync_and_link(src, dest)
37
- end
38
-
39
- def rsync_and_link(src, dest)
40
- FileUtils.mkdir_p(dest)
41
- rsync(src, dest)
42
-
43
- # create symlink in output path not the cache path
44
- symlink_dest = "#{output_area}/vendor/gems/ruby/#{ruby_folder}"
45
- logger.info "symlink_dest #{symlink_dest}"
46
- FileUtils.rm_rf(symlink_dest) # blow away original 2.5.0 folder
47
-
48
- # Create symlink that will point to the gems in the Lambda Layer:
49
- # stage/opt/ruby/gems/2.5.0 -> /opt/ruby/gems/2.5.0
50
- FileUtils.mkdir_p(File.dirname(symlink_dest))
51
- FileUtils.ln_sf("/opt/ruby/gems/#{ruby_folder}", symlink_dest)
52
- end
53
-
54
- def ruby_folder
55
- major, minor, _ = RUBY_VERSION.split('.')
56
- [major, minor, '0'].join('.') # 2.5.1 => 2.5.0
57
- end
58
-
59
- # Installs gems on the current target system: both compiled and non-compiled.
60
- # If user is on a macosx machine, macosx gems will be installed.
61
- # If user is on a linux machine, linux gems will be installed.
62
- #
63
- # Copies Gemfile* to /tmp/jets/demo/cache folder and installs
64
- # gems with bundle install from there.
65
- #
66
- # We take the time to copy Gemfile and bundle into a separate directory
67
- # because it gets left around to act as a 'cache'. So, when the builds the
68
- # project gets built again not all the gems from get installed from the
69
- # beginning.
70
- def bundle_install
71
- logger.info "Bundling: running bundle install in cache area: #{cache_area}."
72
-
73
- rsync(output_area, cache_area)
74
-
75
- # Uncomment out to always remove the cache/vendor/gems to debug
76
- # FileUtils.rm_rf("#{cache_area}/vendor/gems")
77
-
78
- # Remove .bundle folder so .bundle/config doesnt affect how gems are packages
79
- # Not using BUNDLE_IGNORE_CONFIG=1 to allow home ~/.bundle/config to affect bundling though.
80
- # This is useful if you have private gems sources that require authentication. Example:
81
- #
82
- # bundle config gems.myprivatesource.com user:pass
83
- #
84
-
85
- FileUtils.rm_rf("#{cache_area}/.bundle")
86
- require "bundler" # dynamically require bundler so user can use any bundler
87
- setup_bundle_config(cache_area)
88
- ::Bundler.with_unbundled_env do
89
- sh "cd #{cache_area} && env bundle install"
90
- end
91
-
92
- remove_bundled_with("#{cache_area}/Gemfile.lock")
93
- # Fixes really tricky bug where Gemfile and Gemfile.lock is out-of-sync. Details: https://gist.github.com/tongueroo/b5b0d0c924a4a1633eee514795e4b04b
94
- FileUtils.cp("#{cache_area}/Gemfile.lock", "#{Lono.root}/output/#{@blueprint.name}/files/#{@registry_name}/Gemfile.lock")
95
-
96
- logger.info 'Bundle install success.'
97
- end
98
-
99
- # Remove the BUNDLED WITH line since we don't control the bundler gem version on AWS Lambda
100
- # And this can cause issues with require 'bundler/setup'
101
- def remove_bundled_with(gemfile_lock)
102
- lines = IO.readlines(gemfile_lock)
103
-
104
- # amount is the number of lines to remove
105
- new_lines, capture, count, amount = [], true, 0, 2
106
- lines.each do |l|
107
- capture = false if l.include?('BUNDLED WITH')
108
- if capture
109
- new_lines << l
110
- end
111
- if capture == false
112
- count += 1
113
- capture = count > amount # renable capture
114
- end
115
- end
116
-
117
- content = new_lines.join('')
118
- IO.write(gemfile_lock, content)
119
- end
120
-
121
- def setup_bundle_config(dir)
122
- text =<<-EOL
123
- ---
124
- BUNDLE_PATH: "vendor/gems"
125
- BUNDLE_WITHOUT: "development:test"
126
- EOL
127
- bundle_config = "#{dir}/.bundle/config"
128
- FileUtils.mkdir_p(File.dirname(bundle_config))
129
- IO.write(bundle_config, text)
130
- end
131
-
132
- def output_area
133
- "#{Lono.root}/output/#{@blueprint.name}/files/#{@registry_name}"
134
- end
135
-
136
- def build_area
137
- "#{Lono.root}/output/#{@blueprint.name}/lambda_layers/#{@registry_name}"
138
- end
139
-
140
- def cache_area
141
- "#{build_area}/cache"
142
- end
143
-
144
- def opt_area
145
- "#{build_area}/opt"
146
- end
147
-
148
- def gemfile_exist?
149
- gemfile_path = "#{@app_root}/Gemfile"
150
- File.exist?(gemfile_path)
151
- end
152
- end
153
- end
@@ -1,20 +0,0 @@
1
- class Lono::AppFile::Build
2
- class LambdaLayer
3
- def initialize(blueprint, registry_item)
4
- @blueprint.name, @registry_item = blueprint, registry_item
5
- end
6
-
7
- def build
8
- lang = @registry_item.options[:lang]
9
- unless lang =~ /ruby/
10
- logger.info "WARN: Currently only support ruby lambda layers".color(:yellow)
11
- return
12
- end
13
-
14
- klass_name = "Lono::AppFile::Build::LambdaLayer::#{lang.camelize}Packager"
15
- klass = klass_name.constantize
16
- packager = klass.new(@blueprint.name, @registry_item)
17
- packager.build
18
- end
19
- end
20
- end
@@ -1,79 +0,0 @@
1
- require "thor"
2
-
3
- module Lono::AppFile
4
- class Build < Base
5
- include Lono::Utils::Item::Zip
6
-
7
- def initialize_variables
8
- @output_files_path = "#{Lono.root}/output/#{@blueprint.name}/files"
9
- end
10
-
11
- def run
12
- return unless detect_files?
13
- logger.info "Building app/files"
14
- build_all
15
- end
16
-
17
- def build_all
18
- clean_output
19
- validate_files!
20
- copy_to_output
21
- build_layers
22
- compress_output
23
- end
24
-
25
- def validate_files!
26
- items = Registry.items + Registry.layers
27
- missing = items.select do |item|
28
- !File.exist?(item.src_path)
29
- end
30
- missing_paths = missing.map { |item| item.src_path }.uniq
31
- unless missing_paths.empty?
32
- logger.info "ERROR: These app/files are missing were used by the s3_key method but are missing".color(:red)
33
- missing_paths.each do |path|
34
- logger.info " #{path}"
35
- end
36
- logger.info "Please double check that they exist."
37
- exit 1
38
- end
39
- end
40
-
41
- def build_layers
42
- layer_items = Registry.layers
43
- layer_items.each do |item|
44
- LambdaLayer.new(@blueprint, item).build
45
- end
46
- end
47
-
48
- def compress_output
49
- Registry.items.each do |item|
50
- # type can be lambda_layer or file
51
- if item.type == "lambda_layer" || item.exist?
52
- zip(item)
53
- else
54
- logger.info "WARN: #{item.src_path} does not exist. Double check that the path is correct in the s3_key call.".color(:yellow)
55
- end
56
- end
57
- end
58
-
59
- def copy_to_output
60
- override_source_paths("#{@blueprint.root}/app/files")
61
- self.destination_root = @output_files_path
62
- directory(".", verbose: false, context: template_context.get_binding) # Thor::Action
63
- end
64
-
65
- def clean_output
66
- FileUtils.rm_rf(@output_files_path)
67
- end
68
-
69
- def detect_files?
70
- app_files = Dir["#{@blueprint.root}/app/files/*"]
71
- if app_files.empty?
72
- false
73
- else
74
- logger.info "Detected app/files"
75
- true
76
- end
77
- end
78
- end
79
- end
@@ -1,24 +0,0 @@
1
- class Lono::AppFile::Registry
2
- # Holds metadata about the item in the regsitry.
3
- class Item
4
- include Lono::Utils::Item::FileMethods
5
-
6
- attr_reader :name, :options, :type
7
- def initialize(name, blueprint, options={})
8
- @name, @blueprint.name, @options = name, blueprint, options
9
- @type = options[:type] || "file"
10
- end
11
-
12
- def src_path
13
- "#{@blueprint.root}/app/files/#{@name}"
14
- end
15
-
16
- def output_path
17
- if @type == "file"
18
- "#{Lono.root}/output/#{@blueprint.name}/files/#{@name}"
19
- else
20
- "#{Lono.root}/output/#{@blueprint.name}/lambda_layers/#{@name}/opt"
21
- end
22
- end
23
- end
24
- end
@@ -1,16 +0,0 @@
1
- module Lono::AppFile
2
- class Registry
3
- cattr_reader :items
4
- @@items = []
5
-
6
- class << self
7
- def register(name, blueprint, options={})
8
- @@items << Item.new(name, blueprint, options) unless @@items.detect { |i| i.name == name && i.type == options[:type] }
9
- end
10
-
11
- def layers
12
- @@items.select { |i| i.type == "lambda_layer" }
13
- end
14
- end
15
- end
16
- end
@@ -1,12 +0,0 @@
1
- module Lono::AppFile
2
- class Upload < Base
3
- def upload
4
- return unless Registry.items.size > 0
5
- logger.info "Uploading app/files..."
6
-
7
- Registry.items.each do |item|
8
- Lono::S3::Uploader.new(item.zip_file_path).upload
9
- end
10
- end
11
- end
12
- end
@@ -1,11 +0,0 @@
1
- module Lono::Builder::Context
2
- class Generic < Lono::CLI::Base
3
- include Lono::Builder::Dsl::Syntax
4
-
5
- # For Lono::AppFile::Build usage of Thor::Action directory
6
- # For some reason a send(:binding) doesnt work but get_binding like this works.
7
- def get_binding
8
- binding
9
- end
10
- end
11
- end
@@ -1,23 +0,0 @@
1
- module Lono::Builder::Context::Loaders
2
- module LoadFiles
3
- # Load custom helper methods from project
4
- def load_files(dir)
5
- paths = Dir.glob("#{dir}/**/*.rb")
6
- paths.sort_by! { |p| p.size } # so namespaces are loaded first
7
- paths.each do |path|
8
- # helpers = blueprint or project extensions
9
- filename = path.sub(%r{.*/helpers/},'').sub('.rb','')
10
- module_name = filename.camelize
11
-
12
- # Prepend a period so require works LONO_ROOT is set to a relative path without a period.
13
- #
14
- # Example: LONO_ROOT=tmp/lono_project
15
- first_char = path[0..0]
16
- path = "./#{path}" unless %w[. /].include?(first_char)
17
-
18
- require path
19
- self.class.send :include, module_name.constantize
20
- end
21
- end
22
- end
23
- end
@@ -1,35 +0,0 @@
1
- module Lono::Builder::Context
2
- module Loaders
3
- include LoadFiles
4
-
5
- # Variables in base.rb are overridden by their environment specific variables
6
- # file. Example, file LONO_ENV=dev:
7
- #
8
- # config/vars/base.rb
9
- # config/vars/dev.rb - will override any variables in base.rb
10
- # config/vars/base.rb
11
- # config/vars/dev.rb - will override any variables in base.rb
12
- #
13
- def load_variables
14
- layers = Lono::Layering::Layer.new(@blueprint, "vars").paths
15
- layers.each do |layer|
16
- evaluate_variables_file(layer)
17
- end
18
- end
19
-
20
- # Load the variables defined in config/vars/* to make available in lono scope.
21
- #
22
- # NOTE: Was only able to make instance variables avaialble with instance_eval, wasnt able to make local variables
23
- # available.
24
- def evaluate_variables_file(path)
25
- return unless File.exist?(path)
26
- instance_eval(IO.read(path), path)
27
- end
28
-
29
- # Load blueprint helpers
30
- # blueprint helpers override extension helpers
31
- def load_blueprint_helpers
32
- load_files("#{@blueprint.root}/#{Lono.config.paths.helpers}")
33
- end
34
- end
35
- end
@@ -1,6 +0,0 @@
1
- module Lono::Builder::Context
2
- class Params < Generic
3
- # Overriding output resource DSL method
4
- alias_method :output, :stack_output
5
- end
6
- end
@@ -1,4 +0,0 @@
1
- module Lono::Builder::Context
2
- class Template < Generic
3
- end
4
- end
@@ -1,59 +0,0 @@
1
- module Lono::Configset
2
- class Builder
3
- include Lono::Utils::Logging
4
-
5
- def initialize(options)
6
- @options = options
7
- @configset = options[:configset]
8
- @type = options[:type] || "project"
9
- end
10
-
11
- def run
12
- check_configset_exist!
13
- structure = build
14
- logger.info YAML.dump(structure)
15
- end
16
-
17
- def check_configset_exist!
18
- exist = !!Lono::Finder::Configset.find(@configset)
19
- unless exist
20
- logger.info "configset #{@configset.color(:green)} not found."
21
- exit 1
22
- end
23
- end
24
-
25
- def build
26
- # Examples:
27
- # Erb.new(options).build
28
- # Dsl.new(options).build
29
- builder_class = "Lono::Configset::Strategy::#{strategy.camelize}"
30
- builder_class = Object.const_get(builder_class)
31
- full = builder_class.new(@options.merge(root: configset_root)).build
32
- if @options[:cli]
33
- full["Metadata"] # contains AWS::CloudFormation::Init and optional AWS::CloudFormation::Authentication
34
- else
35
- full # Combiner uses full metadata structure
36
- end
37
- end
38
-
39
- def strategy
40
- jadespec = Lono::Jadespec.new(configset_root, "unknown") # abusing Jadespec to get strategy
41
- jadespec.lono_strategy
42
- end
43
-
44
- def configset_root
45
- finder = finder_class.new
46
- found = finder.find(@configset, local_only: false)
47
- found.root if found
48
- end
49
-
50
- def finder_class
51
- case @type
52
- when "project"
53
- Lono::Finder::Configset
54
- when "blueprint"
55
- Lono::Finder::Blueprint::Configset
56
- end
57
- end
58
- end
59
- end
@@ -1,164 +0,0 @@
1
- require "yaml"
2
-
3
- module Lono::Configset
4
- class Combiner
5
- include Lono::Utils::Logging
6
-
7
- def initialize(cfn, options={})
8
- @cfn, @options = cfn, options
9
-
10
- @sets = []
11
- @map = {} # stores resource logical id => metadata cfn-init
12
- end
13
-
14
- def generator_options(registry, options={})
15
- o = @options.merge(configset: registry.name, resource: registry.resource)
16
- o.merge(options)
17
- end
18
-
19
- def metadata_map
20
- return {} unless additional_configsets?
21
-
22
- existing_configsets.each do |data|
23
- add(data[:registry], data[:metdata_configset])
24
- end
25
-
26
- Register::Blueprint.configsets.each do |registry|
27
- generator = Lono::Configset::Generator.new(generator_options(registry, type: "blueprint"))
28
- cloudformation_init = generator.build
29
- add(registry, cloudformation_init)
30
- end
31
- Register::Project.configsets.each do |registry|
32
- generator = Lono::Configset::Generator.new(generator_options(registry, type: "project"))
33
- cloudformation_init = generator.build
34
- add(registry, cloudformation_init)
35
- end
36
-
37
- combine
38
- Register::Blueprint.clear! # in case of lono build for all templates
39
- Register::Project.clear! # in case of lono build for all templates
40
- @map
41
- end
42
-
43
- def add(registry, metadata)
44
- @sets << [registry, metadata.dup]
45
- end
46
-
47
- def additional_configsets?
48
- !Register::Blueprint.configsets.empty? || !Register::Project.configsets.empty?
49
- end
50
-
51
- # Normalized/convert cfn template to mimic the registry format
52
- def existing_configsets
53
- configsets = []
54
- @cfn["Resources"].each do |logical_id, attributes|
55
- init = attributes.dig("Metadata", "AWS::CloudFormation::Init")
56
-
57
- next unless init
58
-
59
- data = {
60
- registry: Lono::Jade::Registry.new(["#{logical_id}OriginalConfigset"], resource: logical_id),
61
- metdata_configset: {"Metadata" => attributes["Metadata"]} # # wrap metadata to create right structure
62
- }
63
- configsets << data
64
- end
65
- configsets
66
- end
67
-
68
- def combine
69
- # Remove duplicate configsets. Can happen if same configset is in blueprint and project.
70
- # Ugly because of the sets structure.
71
- @sets.uniq! do |array|
72
- registry, _ = array
73
- registry.name
74
- end
75
-
76
- metadata_map = {}
77
- configsets_map = {}
78
-
79
- @sets.each_with_index do |array, i|
80
- padded_i = "%03d" % i
81
- registry, metadata = array
82
-
83
- # metadata example (full structure):
84
- #
85
- # {"Metadata"=>
86
- # {"AWS::CloudFormation::Init"=>
87
- # {"configSets"=>{"default"=>["aaa1", "aaa2"]},
88
- # "aaa1"=>{"commands"=>{"test"=>{"command"=>"echo from-aaa1 > test1.txt"}}},
89
- # "aaa2"=>
90
- # {"commands"=>{"test"=>{"command"=>"echo from-aaa2 > test1.txt"}}}}}}
91
-
92
- name, resource = registry.name, registry.resource
93
- configsets = configsets_map[resource] ||= {}
94
-
95
- validate_structure!(name, metadata)
96
-
97
- new_metadata = metadata["Metadata"].dup
98
- init = new_metadata["AWS::CloudFormation::Init"] # important: adjust data by reference
99
-
100
- if init.key?("configSets")
101
- validate_simple!(registry, new_metadata["AWS::CloudFormation::Init"]["configSets"]) # validate original configset for only simple elements
102
-
103
- # 1. expand each config as its own config, flattening to top-level
104
- cs = init.delete("configSets") # Only support configSets with simple Array of Strings
105
- new_config_set = {}
106
- new_config_set[name] = cs["default"].map {|c| "#{padded_i}_#{c}" }
107
- init.transform_keys! { |c| "#{padded_i}_#{c}" }
108
-
109
- # Rebuild default configSet, append the new complex ConfigSet structure with each iteration
110
- configsets["default"] ||= []
111
- configsets["default"] << {"ConfigSet" => name}
112
- configsets.merge!(new_config_set) # add each config from #1 to the top-level
113
-
114
- init["configSets"] = configsets # replace new configset
115
- else # simple config
116
- init["configSets"] = configsets # adjust data by reference
117
- configsets["default"] ||= []
118
- configsets["default"] << {"ConfigSet" => name}
119
-
120
- # build new config
121
- config_key = "#{padded_i}_single_generated"
122
- configsets[name] = [config_key]
123
- new_config = {config_key => init["config"]}
124
- # replace old config with new one
125
- init.delete("config") # delete original simple config
126
- init.merge!(new_config)
127
- end
128
-
129
- metadata_map[resource] ||= {"Metadata" => {}}
130
- metadata_map[resource]["Metadata"].deep_merge!(new_metadata)
131
- @map[resource] = metadata_map[resource]
132
- end
133
- @map
134
- end
135
-
136
- def validate_structure!(name, metadata)
137
- return if metadata.is_a?(Hash) && metadata.dig("Metadata", "AWS::CloudFormation::Init")
138
-
139
- logger.info "ERROR: The #{name} configset does not appear to have a AWS::CloudFormation::Init key".color(:red)
140
- logger.info "Please double check the #{name} configset.yml structure"
141
- exit 1
142
- end
143
-
144
- def validate_simple!(registry, cs)
145
- has_complex_type = cs["default"].detect { |s| !s.is_a?(String) }
146
- if has_complex_type
147
- message =<<~EOL
148
- ERROR: The configset #{registry.name} has a configSets property with a complex type.
149
- configSets:
150
-
151
- #{cs}
152
-
153
- lono configsets only supports combining configSets with an Array of Strings.
154
- EOL
155
- if ENV['LONO_TEST']
156
- raise message
157
- else
158
- logger.info message.color(:red)
159
- exit 1
160
- end
161
- end
162
- end
163
- end
164
- end
@@ -1,8 +0,0 @@
1
- module Lono::Configset
2
- module EvaluateFile
3
- def evaluate_file(path)
4
- return unless path && File.exist?(path)
5
- instance_eval(IO.read(path), path)
6
- end
7
- end
8
- end
@@ -1,12 +0,0 @@
1
- class Lono::Configset::Meta
2
- module Dsl
3
- def depends_on(*args)
4
- options = args.last.is_a?(Hash) ? args.pop : {}
5
- registry = Lono::Jade::Registry.new(args, options)
6
- registry.depends_on = args.first
7
- registry.parent = @jade
8
- already_has = @jade.depends_ons.detect { |d| d.name == registry.name && d.args == registry.args }
9
- @jade.depends_ons << registry unless already_has
10
- end
11
- end
12
- end
@@ -1,19 +0,0 @@
1
- module Lono::Configset
2
- class Meta
3
- extend Memoist
4
- include EvaluateFile
5
- include Dsl
6
-
7
- class_attribute :registries
8
- self.registries = []
9
-
10
- def initialize(jade)
11
- @jade = jade
12
- end
13
-
14
- def evaluate
15
- path = "#{@jade.root}/lib/meta.rb"
16
- evaluate_file(path) # DSL depends_on sets @jade.depends_on decorated options
17
- end
18
- end
19
- end