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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +15 -2
- data/Gemfile +1 -3
- data/lib/lono/app/callable_option/concern.rb +12 -0
- data/lib/lono/app/callable_option.rb +56 -0
- data/lib/lono/app.rb +22 -23
- data/lib/lono/autoloader.rb +1 -0
- data/lib/lono/aws_services/helper.rb +0 -2
- data/lib/lono/blueprint.rb +1 -18
- data/lib/lono/builder/allow/base.rb +54 -0
- data/lib/lono/builder/allow/env.rb +17 -0
- data/lib/lono/builder/allow/region.rb +20 -0
- data/lib/lono/builder/allow.rb +8 -0
- data/lib/lono/builder/configset/combiner.rb +145 -0
- data/lib/lono/builder/configset/definition/base.rb +47 -0
- data/lib/lono/builder/configset/definition/context.rb +29 -0
- data/lib/lono/{configset/strategy/helpers/dsl → builder/configset/definition/dsl/syntax}/auth.rb +1 -1
- data/lib/lono/{configset/strategy/helpers/dsl/core.rb → builder/configset/definition/dsl/syntax/content.rb} +12 -4
- data/lib/lono/{configset/strategy/helpers/dsl/syntax.rb → builder/configset/definition/dsl/syntax/core.rb} +15 -9
- data/lib/lono/{configset/strategy/helpers/dsl → builder/configset/definition/dsl/syntax}/package.rb +1 -1
- data/lib/lono/builder/configset/definition/dsl/syntax.rb +5 -0
- data/lib/lono/{configset/strategy → builder/configset/definition}/dsl.rb +10 -14
- data/lib/lono/{configset/strategy → builder/configset/definition}/erb.rb +13 -16
- data/lib/lono/builder/configset/definition.rb +18 -0
- data/lib/lono/builder/configset/evaluator.rb +10 -0
- data/lib/lono/builder/configset/registration.rb +35 -0
- data/lib/lono/builder/context.rb +40 -0
- data/lib/lono/builder/dsl/evaluator.rb +6 -55
- data/lib/lono/builder/dsl/finalizer/base.rb +8 -0
- data/lib/lono/builder/dsl/finalizer/configsets.rb +7 -28
- data/lib/lono/builder/dsl/finalizer/files/base.rb +4 -0
- data/lib/lono/builder/dsl/finalizer/files/build.rb +58 -0
- data/lib/lono/builder/dsl/finalizer/files/replace.rb +31 -0
- data/lib/lono/builder/dsl/finalizer/files.rb +9 -0
- data/lib/lono/builder/dsl/finalizer/parameter_groups.rb +4 -3
- data/lib/lono/builder/dsl/finalizer.rb +4 -2
- data/lib/lono/builder/dsl/helpers/files.rb +7 -0
- data/lib/lono/builder/dsl/helpers/partials.rb +48 -53
- data/lib/lono/builder/dsl/helpers/s3.rb +1 -1
- data/lib/lono/builder/dsl/helpers/ssm/fetcher.rb +3 -1
- data/lib/lono/builder/dsl/helpers/template_file.rb +18 -6
- data/lib/lono/builder/dsl/helpers.rb +1 -11
- data/lib/lono/builder/dsl/syntax/core/resource/property_mover.rb +11 -1
- data/lib/lono/builder/dsl/syntax/core/squeezer.rb +16 -2
- data/lib/lono/builder/dsl.rb +1 -1
- data/lib/lono/builder/param.rb +4 -1
- data/lib/lono/builder/template/upload.rb +2 -15
- data/lib/lono/cfn/cancel.rb +5 -5
- data/lib/lono/cfn/deploy/iam.rb +1 -1
- data/lib/lono/cfn/deploy.rb +32 -3
- data/lib/lono/cfn/download.rb +0 -1
- data/lib/lono/cfn/plan/changeset.rb +2 -2
- data/lib/lono/cfn/plan/diff/data.rb +11 -1
- data/lib/lono/cfn/plan/param.rb +1 -1
- data/lib/lono/cfn/plan/template.rb +2 -2
- data/lib/lono/cfn/plan.rb +1 -0
- data/lib/lono/cli/abstract.rb +0 -6
- data/lib/lono/cli/base.rb +5 -3
- data/lib/lono/cli/build.rb +16 -60
- data/lib/lono/cli/clean.rb +3 -2
- data/lib/lono/cli/code.rb +12 -12
- data/lib/lono/cli/help/new/helper/blueprint.md +17 -0
- data/lib/lono/cli/help/new/helper/project.md +16 -0
- data/lib/lono/cli/list.rb +3 -6
- data/lib/lono/cli/new/blueprint.rb +3 -7
- data/lib/lono/cli/new/configset.rb +11 -44
- data/lib/lono/cli/new/helper/blueprint.rb +26 -0
- data/lib/lono/cli/new/helper/project.rb +24 -0
- data/lib/lono/cli/new/helper.rb +8 -27
- data/lib/lono/cli/new/sequence.rb +6 -1
- data/lib/lono/cli/new.rb +8 -12
- data/lib/lono/cli/status.rb +18 -0
- data/lib/lono/cli.rb +6 -9
- data/lib/lono/command.rb +0 -1
- data/lib/lono/component.rb +29 -0
- data/lib/lono/concerns/aws_info.rb +14 -0
- data/lib/lono/concerns/names.rb +9 -0
- data/lib/lono/configset.rb +17 -0
- data/lib/lono/core.rb +1 -1
- data/lib/lono/ext/bundler.rb +7 -0
- data/lib/lono/ext/core/module.rb +31 -0
- data/lib/lono/ext/core/object.rb +32 -0
- data/lib/lono/ext/core/string.rb +9 -0
- data/lib/lono/ext.rb +4 -0
- data/lib/lono/files/base.rb +12 -0
- data/lib/lono/files/builder.rb +37 -0
- data/lib/lono/files/compressor.rb +53 -0
- data/lib/lono/files/concerns/post_processing.rb +35 -0
- data/lib/lono/files/concerns/registration.rb +13 -0
- data/lib/lono/files/registry.rb +6 -0
- data/lib/lono/files.rb +37 -0
- data/lib/lono/importer/base.rb +1 -1
- data/lib/lono/inspector/summary.rb +0 -3
- data/lib/lono/layering/layer.rb +3 -17
- data/lib/lono/logger.rb +1 -3
- data/lib/lono/names.rb +1 -1
- data/lib/lono/s3/uploader.rb +29 -28
- data/lib/lono/seeder.rb +18 -27
- data/lib/lono/user_data.rb +3 -1
- data/lib/lono/version.rb +1 -1
- data/lib/lono/yamler/validator.rb +7 -22
- data/lib/lono.rb +8 -0
- data/lib/templates/configset/configset.rb +2 -16
- data/lib/templates/examples/configset/configset.rb +16 -0
- data/lib/templates/helper/%underscore_name%_helper.rb.tt +1 -1
- data/lono.gemspec +1 -1
- metadata +52 -39
- data/lib/lono/app_file/base.rb +0 -28
- data/lib/lono/app_file/build/lambda_layer/ruby_packager.rb +0 -153
- data/lib/lono/app_file/build/lambda_layer.rb +0 -20
- data/lib/lono/app_file/build.rb +0 -79
- data/lib/lono/app_file/registry/item.rb +0 -24
- data/lib/lono/app_file/registry.rb +0 -16
- data/lib/lono/app_file/upload.rb +0 -12
- data/lib/lono/builder/context/generic.rb +0 -11
- data/lib/lono/builder/context/loaders/load_files.rb +0 -23
- data/lib/lono/builder/context/loaders.rb +0 -35
- data/lib/lono/builder/context/params.rb +0 -6
- data/lib/lono/builder/context/template.rb +0 -4
- data/lib/lono/configset/builder.rb +0 -59
- data/lib/lono/configset/combiner.rb +0 -164
- data/lib/lono/configset/evaluate_file.rb +0 -8
- data/lib/lono/configset/meta/dsl.rb +0 -12
- data/lib/lono/configset/meta.rb +0 -19
- data/lib/lono/configset/s3_file/build.rb +0 -34
- data/lib/lono/configset/s3_file/item.rb +0 -38
- data/lib/lono/configset/s3_file/registry.rb +0 -12
- data/lib/lono/configset/s3_file/upload.rb +0 -12
- data/lib/lono/configset/strategy/base.rb +0 -83
- data/lib/lono/configset/strategy/helpers/dsl.rb +0 -8
- data/lib/lono/configset/strategy/helpers/erb.rb +0 -9
- data/lib/lono/lookup.rb +0 -12
- data/lib/lono/seeder/service_role.rb +0 -11
- data/lib/lono/utils/contexts.rb +0 -15
- data/lib/lono/utils/item/file_methods.rb +0 -29
- data/lib/lono/utils/item/zip.rb +0 -42
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 99ed66c36726e513ebe394291384f039d6dbbc7beef5a376b28b3b84121f1a42
|
4
|
+
data.tar.gz: ec1902278f840c29539d54fffa9167565a27f1837a4ee2795d8db86badf0030d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 522056fb098c360c2ad59d99dfabaa723aeec157ca5012938c36efcb130e1bf6c2974d158e3c2f864e258c5d4b065d8e949667291f6af7d779bad91d2b451a0f
|
7
|
+
data.tar.gz: 18d17bbf1fcdd0f9d7c59f87b83e463f277958fb34cfb07d5918904b76ae44ecd2995f7e36f09d0a99c15d01070b469abf44bcfc95ec8f413aa54fdb0058fc6c
|
data/CHANGELOG.md
CHANGED
@@ -1,7 +1,20 @@
|
|
1
1
|
# Change Log
|
2
2
|
|
3
|
-
|
4
|
-
|
3
|
+
## [8.0.0.rc3] - 2022-03-06
|
4
|
+
|
5
|
+
* lono files support for lambda functions
|
6
|
+
* new structure: remove Appfile
|
7
|
+
* allow regions and envs support
|
8
|
+
* print friend message with exact line of yaml code in case of aws
|
9
|
+
* cloudformation yaml validation error
|
10
|
+
* improve cli help
|
11
|
+
* configsets new structure
|
12
|
+
* lono new helper blueprint and project commands
|
13
|
+
* project helpers support
|
14
|
+
* include_modules improvements
|
15
|
+
* support vendor level helpers
|
16
|
+
* improve plan params diff
|
17
|
+
* lono plan build all first
|
5
18
|
|
6
19
|
## [8.0.0.rc2] - 2022-02-23
|
7
20
|
|
data/Gemfile
CHANGED
@@ -3,8 +3,6 @@ source "https://rubygems.org"
|
|
3
3
|
# Specify your gem dependencies in lono.gemspec
|
4
4
|
gemspec
|
5
5
|
|
6
|
-
|
7
|
-
gem "rspec-lono", path: "~/boltops-tools/rspec-lono"
|
8
|
-
else
|
6
|
+
group :test do
|
9
7
|
gem "rspec-lono", git: "https://github.com/boltops-tools/rspec-lono", branch: "master"
|
10
8
|
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
class Lono::App::CallableOption
|
2
|
+
module Concern
|
3
|
+
def callable_option(options={})
|
4
|
+
callable_option = Lono::App::CallableOption.new(
|
5
|
+
config_name: options[:config_name],
|
6
|
+
config_value: options[:config_value],
|
7
|
+
passed_args: options[:passed_args],
|
8
|
+
)
|
9
|
+
callable_option.object
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
# Class represents a lono option that is possibly callable. Examples:
|
2
|
+
#
|
3
|
+
# config.allow.envs
|
4
|
+
# config.allow.regions
|
5
|
+
# config.deny.envs
|
6
|
+
# config.deny.regions
|
7
|
+
#
|
8
|
+
# Abstraction is definitely obtuse. Using it to get rid of duplication.
|
9
|
+
#
|
10
|
+
class Lono::App
|
11
|
+
class CallableOption
|
12
|
+
include Lono::Utils::Logging
|
13
|
+
|
14
|
+
def initialize(options={})
|
15
|
+
@options = options
|
16
|
+
# Example:
|
17
|
+
# config_name: config.allow.envs
|
18
|
+
# config_value: ["dev"]
|
19
|
+
# args: [@stack_name] # passed to object.call
|
20
|
+
@config_name = options[:config_name]
|
21
|
+
@config_value = options[:config_value]
|
22
|
+
@passed_args = options[:passed_args]
|
23
|
+
end
|
24
|
+
|
25
|
+
# Returns either an Array or nil
|
26
|
+
def object
|
27
|
+
case @config_value
|
28
|
+
when nil
|
29
|
+
return nil
|
30
|
+
when Array
|
31
|
+
return @config_value
|
32
|
+
when -> (c) { c.respond_to?(:public_instance_methods) && c.public_instance_methods.include?(:call) }
|
33
|
+
object= @config_value.new
|
34
|
+
when -> (c) { c.respond_to?(:call) }
|
35
|
+
object = @config_value
|
36
|
+
else
|
37
|
+
raise "Invalid option for #{@config_name}"
|
38
|
+
end
|
39
|
+
|
40
|
+
if object
|
41
|
+
result = @passed_args.empty? ? object.call : object.call(*@passed_args)
|
42
|
+
unless result.is_a?(Array) || result.is_a?(NilClass)
|
43
|
+
message = "ERROR: The #{@config_name} needs to return an Array or nil"
|
44
|
+
logger.info message.color(:yellow)
|
45
|
+
logger.info <<~EOL
|
46
|
+
The #{@config_name} when assigned a class, object, or proc must implement
|
47
|
+
the call method and return an Array or nil.
|
48
|
+
The current return value is a #{result.class}
|
49
|
+
EOL
|
50
|
+
raise message
|
51
|
+
end
|
52
|
+
end
|
53
|
+
result
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
data/lib/lono/app.rb
CHANGED
@@ -13,6 +13,16 @@ module Lono
|
|
13
13
|
def defaults
|
14
14
|
config = ActiveSupport::OrderedOptions.new
|
15
15
|
|
16
|
+
config.allow = ActiveSupport::OrderedOptions.new
|
17
|
+
config.allow.envs = nil
|
18
|
+
config.allow.regions = nil
|
19
|
+
config.deny = ActiveSupport::OrderedOptions.new
|
20
|
+
config.deny.envs = nil
|
21
|
+
config.deny.regions = nil
|
22
|
+
|
23
|
+
config.layering = ActiveSupport::OrderedOptions.new
|
24
|
+
config.layering.names = {}
|
25
|
+
|
16
26
|
config.log = ActiveSupport::OrderedOptions.new
|
17
27
|
config.log.root = Lono.log_root
|
18
28
|
config.logger = lono_logger
|
@@ -20,16 +30,21 @@ module Lono
|
|
20
30
|
config.logger.level = ENV['LONO_LOG_LEVEL'] || :info
|
21
31
|
|
22
32
|
config.names = ActiveSupport::OrderedOptions.new
|
23
|
-
config.names.stack = ":APP-:BLUEPRINT-:ENV"
|
24
33
|
config.names.output = ActiveSupport::OrderedOptions.new
|
25
|
-
config.names.output.stack = ":BLUEPRINT-:ENV" # does not include APP by default. Think this is more common
|
26
34
|
config.names.output.expand = true
|
35
|
+
config.names.output.stack = ":BLUEPRINT-:ENV" # does not include APP by default. Think this is more common
|
36
|
+
config.names.stack = ":APP-:BLUEPRINT-:ENV"
|
37
|
+
|
38
|
+
config.plan = ActiveSupport::OrderedOptions.new
|
39
|
+
config.plan.changeset = true
|
40
|
+
config.plan.params = "full"
|
41
|
+
config.plan.template = "summary" # summary is same as true
|
27
42
|
|
28
|
-
config.
|
29
|
-
config.
|
30
|
-
|
31
|
-
config.
|
32
|
-
config.
|
43
|
+
config.seed = ActiveSupport::OrderedOptions.new
|
44
|
+
config.seed.where = "config"
|
45
|
+
|
46
|
+
config.test = ActiveSupport::OrderedOptions.new
|
47
|
+
config.test.framework = "rspec"
|
33
48
|
|
34
49
|
config.up = ActiveSupport::OrderedOptions.new
|
35
50
|
config.up.capabilities = nil
|
@@ -37,22 +52,6 @@ module Lono
|
|
37
52
|
config.up.rollback = true
|
38
53
|
config.up.tags = nil
|
39
54
|
|
40
|
-
config.diff = ActiveSupport::OrderedOptions.new
|
41
|
-
config.diff.changeset = true
|
42
|
-
config.diff.params = "full"
|
43
|
-
config.diff.template = "summary" # summary is same as true
|
44
|
-
|
45
|
-
config.extract_scripts = {}
|
46
|
-
|
47
|
-
config.test = ActiveSupport::OrderedOptions.new
|
48
|
-
config.test.framework = "rspec"
|
49
|
-
|
50
|
-
config.layering = ActiveSupport::OrderedOptions.new
|
51
|
-
config.layering.names = {}
|
52
|
-
|
53
|
-
config.seed = ActiveSupport::OrderedOptions.new
|
54
|
-
config.seed.where = "config"
|
55
|
-
|
56
55
|
config
|
57
56
|
end
|
58
57
|
|
data/lib/lono/autoloader.rb
CHANGED
data/lib/lono/blueprint.rb
CHANGED
@@ -1,22 +1,5 @@
|
|
1
1
|
module Lono
|
2
|
-
class Blueprint
|
3
|
-
attr_reader :name
|
4
|
-
def initialize(options={})
|
5
|
-
@options = options
|
6
|
-
@name = options[:blueprint]
|
7
|
-
end
|
8
|
-
|
9
|
-
def exist?
|
10
|
-
!root.nil?
|
11
|
-
end
|
12
|
-
|
13
|
-
def root
|
14
|
-
paths = Dir.glob("#{Lono.root}/{app,vendor}/blueprints/*")
|
15
|
-
paths.find do |path|
|
16
|
-
path.include?("blueprints/#{@name}")
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
2
|
+
class Blueprint < Component
|
20
3
|
def output_path
|
21
4
|
"#{Lono.root}/output/#{@name}/template.yml"
|
22
5
|
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
class Lono::Builder::Allow
|
2
|
+
class Base < Lono::CLI::Base
|
3
|
+
include Lono::App::CallableOption::Concern
|
4
|
+
|
5
|
+
def check!
|
6
|
+
messages = []
|
7
|
+
unless allowed?
|
8
|
+
messages << message # message is interface method
|
9
|
+
end
|
10
|
+
unless messages.empty?
|
11
|
+
puts "ERROR: The configs do not allow this.".color(:red)
|
12
|
+
puts messages
|
13
|
+
exit 1
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def allowed?
|
18
|
+
if allows.nil? && denys.nil?
|
19
|
+
true
|
20
|
+
elsif denys.nil?
|
21
|
+
allows.include?(check_value)
|
22
|
+
elsif allows.nil?
|
23
|
+
!denys.include?(check_value)
|
24
|
+
else
|
25
|
+
allows.include?(check_value) && !denys.include?(check_value)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def allows
|
30
|
+
callable_option(
|
31
|
+
config_name: "config.allow.#{config_name}",
|
32
|
+
config_value: config.dig(:allow, config_name),
|
33
|
+
passed_args: [@blueprint],
|
34
|
+
)
|
35
|
+
end
|
36
|
+
|
37
|
+
def denys
|
38
|
+
callable_option(
|
39
|
+
config_name: "config.deny.#{config_name}",
|
40
|
+
config_value: config.dig(:deny, config_name),
|
41
|
+
passed_args: [@blueprint],
|
42
|
+
)
|
43
|
+
end
|
44
|
+
|
45
|
+
private
|
46
|
+
def config
|
47
|
+
Lono.config
|
48
|
+
end
|
49
|
+
|
50
|
+
def config_name
|
51
|
+
self.class.to_s.split('::').last.underscore.pluralize.to_sym # ActiveSuport::HashWithIndifferentAccess#dig requires symbol
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
class Lono::Builder::Allow
|
2
|
+
class Env < Base
|
3
|
+
# interface method
|
4
|
+
def message
|
5
|
+
messages = []
|
6
|
+
messages << "This env is not allowed to be used: LONO_ENV=#{Lono.env}"
|
7
|
+
messages << "Allow envs: #{allows.join(', ')}" if allows
|
8
|
+
messages << "Deny envs: #{denys.join(', ')}" if denys
|
9
|
+
messages.join("\n")
|
10
|
+
end
|
11
|
+
|
12
|
+
# interface method
|
13
|
+
def check_value
|
14
|
+
Lono.env
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
class Lono::Builder::Allow
|
2
|
+
class Region < Base
|
3
|
+
include Lono::Concerns::AwsInfo
|
4
|
+
|
5
|
+
# interface method
|
6
|
+
def message
|
7
|
+
messages = []
|
8
|
+
word = config_name.to_s # IE: regions or locations
|
9
|
+
messages << "This #{word.singularize} is not allowed to be used: Detected current #{word.singularize}=#{current_region}"
|
10
|
+
messages << "Allow #{word}: #{allows.join(', ')}" if allows
|
11
|
+
messages << "Deny #{word}: #{denys.join(', ')}" if denys
|
12
|
+
messages.join("\n")
|
13
|
+
end
|
14
|
+
|
15
|
+
# interface method
|
16
|
+
def check_value
|
17
|
+
region
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,145 @@
|
|
1
|
+
module Lono::Builder::Configset
|
2
|
+
class Combiner < Lono::CLI::Base
|
3
|
+
def initialize(options={})
|
4
|
+
super
|
5
|
+
@cfn = options[:cfn] # merge from Dsl::Finalizer::Configsets#run
|
6
|
+
@metas = options[:metas] # merge from Configset::Evaluator#evaluate
|
7
|
+
@configsets = []
|
8
|
+
@map = {} # stores resource logical id => metadata cfn-init
|
9
|
+
end
|
10
|
+
|
11
|
+
# Returns metadata map structure
|
12
|
+
#
|
13
|
+
# {"Instance"=>
|
14
|
+
# {"Metadata"=>
|
15
|
+
# {"AWS::CloudFormation::Init"=>
|
16
|
+
#
|
17
|
+
def combine
|
18
|
+
return @map if metas_empty?
|
19
|
+
add_existing
|
20
|
+
add_built
|
21
|
+
build_map # metadata map
|
22
|
+
end
|
23
|
+
|
24
|
+
def metas_empty?
|
25
|
+
@metas.empty?
|
26
|
+
end
|
27
|
+
|
28
|
+
def add_existing
|
29
|
+
existing_configsets.each do |configset|
|
30
|
+
add(configset)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def add_built
|
35
|
+
@metas.each do |meta|
|
36
|
+
definition = Definition.new(@options.merge(meta: meta))
|
37
|
+
configset = definition.evaluate
|
38
|
+
add(configset)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
# Useful for specs
|
43
|
+
def add(configset)
|
44
|
+
found = @configsets.detect { |c| c.name == configset.name && c.resource == configset.resource }
|
45
|
+
@configsets << configset unless found
|
46
|
+
end
|
47
|
+
|
48
|
+
# Each metadata has this structure:
|
49
|
+
#
|
50
|
+
# {"Metadata"=>
|
51
|
+
# {"AWS::CloudFormation::Init"=>
|
52
|
+
# {"configSets"=>{"default"=>["aaa1", "aaa2"]},
|
53
|
+
# "aaa1"=>{"commands"=>{"test"=>{"command"=>"echo from-aaa1 > test1.txt"}}},
|
54
|
+
# "aaa2"=>
|
55
|
+
# {"commands"=>{"test"=>{"command"=>"echo from-aaa2 > test1.txt"}}}}}}
|
56
|
+
#
|
57
|
+
def build_map
|
58
|
+
metadata_map = {}
|
59
|
+
configsets_map = {}
|
60
|
+
|
61
|
+
@configsets.each_with_index do |configset, i|
|
62
|
+
padded_i = "%03d" % i
|
63
|
+
|
64
|
+
name, resource, metadata = configset.name, configset.resource, configset.metadata
|
65
|
+
configsets = configsets_map[resource] ||= {}
|
66
|
+
|
67
|
+
validate_structure!(name, metadata)
|
68
|
+
|
69
|
+
new_metadata = metadata["Metadata"].dup
|
70
|
+
init = new_metadata["AWS::CloudFormation::Init"] # important: adjust data by reference
|
71
|
+
|
72
|
+
if init.key?("configSets")
|
73
|
+
# validate_simple!(name, new_metadata["AWS::CloudFormation::Init"]["configSets"]) # validate original configset for only simple elements
|
74
|
+
|
75
|
+
# 1. expand each config as its own config, flattening to top-level
|
76
|
+
cs = init.delete("configSets") # Only support configSets with simple Array of Strings
|
77
|
+
new_config_set = {}
|
78
|
+
new_config_set[name] = cs["default"].map {|c| "#{padded_i}_#{c}" }
|
79
|
+
init.transform_keys! { |c| "#{padded_i}_#{c}" }
|
80
|
+
|
81
|
+
# Rebuild default configSet, append the new complex ConfigSet structure with each iteration
|
82
|
+
configsets["default"] ||= []
|
83
|
+
configsets["default"] << {"ConfigSet" => name}
|
84
|
+
configsets.merge!(new_config_set) # add each config from #1 to the top-level
|
85
|
+
|
86
|
+
init["configSets"] = configsets # replace new configset
|
87
|
+
else # simple config
|
88
|
+
init["configSets"] = configsets # adjust data by reference
|
89
|
+
configsets["default"] ||= []
|
90
|
+
configsets["default"] << {"ConfigSet" => name}
|
91
|
+
|
92
|
+
# build new config
|
93
|
+
config_key = "#{padded_i}_single_generated"
|
94
|
+
configsets[name] = [config_key]
|
95
|
+
new_config = {config_key => init["config"]}
|
96
|
+
# replace old config with new one
|
97
|
+
init.delete("config") # delete original simple config
|
98
|
+
init.merge!(new_config)
|
99
|
+
end
|
100
|
+
|
101
|
+
metadata_map[resource] ||= {"Metadata" => {}}
|
102
|
+
metadata_map[resource]["Metadata"].deep_merge!(new_metadata)
|
103
|
+
@map[resource] = metadata_map[resource]
|
104
|
+
end
|
105
|
+
@map
|
106
|
+
end
|
107
|
+
|
108
|
+
# Normalized/convert cfn template to mimic the registry format
|
109
|
+
def existing_configsets
|
110
|
+
configsets = []
|
111
|
+
@cfn["Resources"].each do |logical_id, attributes|
|
112
|
+
cloudformation_init = attributes.dig("Metadata", "AWS::CloudFormation::Init")
|
113
|
+
next unless cloudformation_init
|
114
|
+
|
115
|
+
configset = Lono::Configset.new(name: "#{logical_id}OriginalConfigset", resource: logical_id)
|
116
|
+
configset.metadata = {"Metadata" => attributes["Metadata"]} # wrap metadata to create right structure
|
117
|
+
configsets << configset
|
118
|
+
end
|
119
|
+
configsets
|
120
|
+
end
|
121
|
+
|
122
|
+
def validate_structure!(name, metadata)
|
123
|
+
return if metadata.is_a?(Hash) && metadata.dig("Metadata", "AWS::CloudFormation::Init")
|
124
|
+
|
125
|
+
puts "ERROR: The #{name} configset does not appear to have a AWS::CloudFormation::Init key".color(:red)
|
126
|
+
puts "Please double check the #{name} configset.yml structure"
|
127
|
+
exit 1
|
128
|
+
end
|
129
|
+
|
130
|
+
def validate_simple!(name, cs)
|
131
|
+
has_complex_type = cs["default"].detect { |s| !s.is_a?(String) }
|
132
|
+
return unless has_complex_type
|
133
|
+
message =<<~EOL
|
134
|
+
ERROR: The configset #{name} has a configSets property with a complex type.
|
135
|
+
configSets:
|
136
|
+
|
137
|
+
#{cs}
|
138
|
+
|
139
|
+
lono configsets only supports combining configSets with an Array of Strings.
|
140
|
+
EOL
|
141
|
+
puts message.color(:red)
|
142
|
+
exit 1
|
143
|
+
end
|
144
|
+
end
|
145
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
class Lono::Builder::Configset::Definition
|
2
|
+
class Base < Lono::CLI::Base
|
3
|
+
include DslEvaluator
|
4
|
+
include Lono::Builder::Dsl::Syntax
|
5
|
+
include Lono::Utils::Pretty
|
6
|
+
include Context
|
7
|
+
|
8
|
+
# Really only use @path in Configset DSL and ERB evaluation.
|
9
|
+
# However, configsets are built within the CloudFormation template and can use
|
10
|
+
# things instrinic functions like `ref` like would normally have access to.
|
11
|
+
# So configsets need the same context
|
12
|
+
#
|
13
|
+
# Configset::Definition::Base < Lono::CLI::Base
|
14
|
+
#
|
15
|
+
# for
|
16
|
+
#
|
17
|
+
# include Lono::Builder::Dsl::Syntax
|
18
|
+
#
|
19
|
+
def initialize(options={})
|
20
|
+
super
|
21
|
+
@meta = @options[:meta]
|
22
|
+
@configset = Lono::Configset.new(@meta)
|
23
|
+
expose_instance_variables
|
24
|
+
end
|
25
|
+
|
26
|
+
# This context is used by the DSL evaluation. Expose variables so user can use them in configset definitions.
|
27
|
+
# Example:
|
28
|
+
#
|
29
|
+
# "/etc/cfn/hooks.d/cfn-auto-reloader.conf":
|
30
|
+
# content:
|
31
|
+
# Fn::Sub:
|
32
|
+
# ...
|
33
|
+
# path=Resources.<%= @resource %>.Metadata.AWS::CloudFormation::Init
|
34
|
+
#
|
35
|
+
def expose_instance_variables
|
36
|
+
@name = @meta[:name]
|
37
|
+
@resource = @meta[:resource]
|
38
|
+
end
|
39
|
+
|
40
|
+
def wrap_with_metadata(cloudformation_init)
|
41
|
+
full = {"Metadata" => {}}
|
42
|
+
full["Metadata"]["AWS::CloudFormation::Init"] = cloudformation_init["AWS::CloudFormation::Init"]
|
43
|
+
full["Metadata"]["AWS::CloudFormation::Authentication"] = authentication if authentication # only on dsl
|
44
|
+
full.deep_stringify_keys.dup # metadata
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
class Lono::Builder::Configset::Definition
|
2
|
+
module Context
|
3
|
+
include DslEvaluator
|
4
|
+
|
5
|
+
def load_context
|
6
|
+
load_vars
|
7
|
+
load_helpers
|
8
|
+
end
|
9
|
+
|
10
|
+
# Docs: https://lono.cloud/docs/configsets/layering/
|
11
|
+
# Layering is simple enough to keep in this method.
|
12
|
+
def load_vars
|
13
|
+
logger.debug "Layers for configset #{@configset.name}:"
|
14
|
+
evaluate_layer("#{@configset.root}/vars.rb") # source defaults
|
15
|
+
evaluate_layer("#{Lono.root}/config/configsets/#{@configset.name}/vars.rb") # source overrides
|
16
|
+
evaluate_layer("#{@blueprint.root}/config/configsets/vars/#{@configset.name}.rb") # blueprint overrides
|
17
|
+
evaluate_layer("#{Lono.root}/config/blueprints/#{@blueprint.name}/configsets/vars/#{@configset.name}.rb") # user overrides
|
18
|
+
end
|
19
|
+
|
20
|
+
def evaluate_layer(path)
|
21
|
+
logger.debug " #{pretty_path(path)}" if File.exist?(path) || ENV['LONO_SHOW_ALL_LAYERS']
|
22
|
+
evaluate_file(path)
|
23
|
+
end
|
24
|
+
|
25
|
+
def load_helpers
|
26
|
+
load_helper_files("#{@configset.root}/helpers", type: :configset)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -1,7 +1,7 @@
|
|
1
|
-
module Lono::Configset::
|
2
|
-
module
|
1
|
+
module Lono::Builder::Configset::Definition::Dsl::Syntax
|
2
|
+
module Content
|
3
3
|
def content_file(path)
|
4
|
-
content_path = "#{
|
4
|
+
content_path = "#{file_root}/content"
|
5
5
|
file = "#{content_path}/#{path}"
|
6
6
|
if File.exist?(file)
|
7
7
|
IO.read(file)
|
@@ -10,8 +10,16 @@ module Lono::Configset::Strategy::Helpers::Dsl
|
|
10
10
|
end
|
11
11
|
end
|
12
12
|
|
13
|
+
def file_root
|
14
|
+
if @configset
|
15
|
+
@configset.root
|
16
|
+
else
|
17
|
+
@blueprint.root
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
13
21
|
def s3_key(name)
|
14
|
-
Lono::Configset::S3File::Registry.register(name, blueprint: @blueprint
|
22
|
+
Lono::Configset::S3File::Registry.register(name, blueprint: @blueprint, configset: @configset, root: @root)
|
15
23
|
"file://configset/#{@configset}/#{name}"
|
16
24
|
end
|
17
25
|
end
|
@@ -1,7 +1,20 @@
|
|
1
|
-
module Lono::Configset::
|
2
|
-
module
|
1
|
+
module Lono::Builder::Configset::Definition::Dsl::Syntax
|
2
|
+
module Core
|
3
3
|
extend Memoist
|
4
4
|
|
5
|
+
#
|
6
|
+
# The configset method is different with configset registration vs configset definition
|
7
|
+
#
|
8
|
+
# definition: app/configsets/httpd/configset.rb
|
9
|
+
# registration: app/blueprints/demo/configsets.rb
|
10
|
+
#
|
11
|
+
def configset(current)
|
12
|
+
@tracked << current
|
13
|
+
previous, @current = @current, current
|
14
|
+
yield
|
15
|
+
@current = previous
|
16
|
+
end
|
17
|
+
|
5
18
|
%w[package group user file service].each do |meth|
|
6
19
|
section = meth.pluralize
|
7
20
|
define_method(meth) do |k, props={}|
|
@@ -53,13 +66,6 @@ module Lono::Configset::Strategy::Helpers::Dsl
|
|
53
66
|
current_structure(@current)["sources"].deep_merge!(item)
|
54
67
|
end
|
55
68
|
|
56
|
-
def configset(current)
|
57
|
-
@tracked << current
|
58
|
-
previous, @current = @current, current
|
59
|
-
yield
|
60
|
-
@current = previous
|
61
|
-
end
|
62
|
-
|
63
69
|
private
|
64
70
|
def current_structure(configset)
|
65
71
|
@structure[configset] ||= {}
|