lono 8.0.0.pre.rc2 → 8.0.0.pre.rc5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/ISSUE_TEMPLATE/bug_report.md +84 -0
- data/.github/ISSUE_TEMPLATE/documentation.md +12 -0
- data/.github/ISSUE_TEMPLATE/feature_request.md +64 -0
- data/.github/ISSUE_TEMPLATE/question.md +14 -0
- data/.github/ISSUE_TEMPLATE.md +7 -0
- data/.github/PULL_REQUEST_TEMPLATE.md +50 -0
- data/CHANGELOG.md +56 -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 +56 -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 +70 -0
- data/lib/lono/{configset/strategy/helpers/dsl → builder/configset/definition/dsl/syntax}/auth.rb +1 -1
- data/lib/lono/builder/configset/definition/dsl/syntax/content.rb +22 -0
- 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 +50 -0
- data/lib/lono/builder/dsl/finalizer/files/replace.rb +36 -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/ec2.rb +16 -3
- 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 +5 -7
- data/lib/lono/builder/dsl/helpers/ssm/fetcher.rb +3 -1
- data/lib/lono/builder/dsl/helpers/stack.rb +2 -4
- data/lib/lono/builder/dsl/helpers/template_file.rb +23 -29
- 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 +19 -3
- data/lib/lono/builder/dsl/syntax/fn.rb +0 -2
- data/lib/lono/builder/dsl.rb +2 -2
- data/lib/lono/builder/param.rb +7 -2
- data/lib/lono/builder/template/upload.rb +2 -15
- data/lib/lono/builder/template.rb +1 -3
- data/lib/lono/builder.rb +39 -0
- data/lib/lono/bundler/util/git.rb +18 -16
- data/lib/lono/cfn/base.rb +2 -2
- data/lib/lono/cfn/cancel.rb +5 -5
- data/lib/lono/cfn/concerns/build.rb +1 -1
- data/lib/lono/cfn/delete.rb +5 -2
- data/lib/lono/cfn/deploy/iam.rb +1 -1
- data/lib/lono/cfn/deploy/operable.rb +1 -1
- data/lib/lono/cfn/deploy/rollback.rb +1 -3
- data/lib/lono/cfn/deploy.rb +23 -5
- data/lib/lono/cfn/download.rb +0 -1
- data/lib/lono/cfn/plan/changeset.rb +3 -3
- 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 +26 -0
- data/lib/lono/cli/abstract.rb +0 -6
- data/lib/lono/cli/base.rb +6 -3
- data/lib/lono/cli/clean.rb +3 -2
- data/lib/lono/cli/help/new/helper.md +27 -0
- data/lib/lono/cli/help/new/hook.md +14 -0
- data/lib/lono/cli/help/new/project.md +3 -10
- data/lib/lono/cli/iam.rb +27 -0
- data/lib/lono/cli/list.rb +3 -6
- data/lib/lono/cli/new/blueprint.rb +3 -9
- data/lib/lono/cli/new/configset.rb +11 -44
- data/lib/lono/cli/new/helper.rb +19 -11
- data/lib/lono/cli/new/hook.rb +32 -0
- data/lib/lono/cli/new/sequence.rb +6 -1
- data/lib/lono/cli/new.rb +9 -9
- data/lib/lono/cli/script/build.rb +0 -5
- data/lib/lono/cli/status.rb +18 -0
- data/lib/lono/{inspector → cli}/summary.rb +23 -33
- data/lib/lono/cli.rb +15 -16
- data/lib/lono/command.rb +28 -2
- 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 +11 -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/{utils → files/builder/lambda_layer}/rsync.rb +3 -5
- data/lib/lono/{app_file/build → files/builder}/lambda_layer/ruby_packager.rb +104 -79
- data/lib/lono/files/builder/lambda_layer/ruby_version.rb +38 -0
- data/lib/lono/files/builder/lambda_layer.rb +17 -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 +52 -0
- data/lib/lono/files/concerns/registration.rb +16 -0
- data/lib/lono/files/registry.rb +6 -0
- data/lib/lono/files.rb +41 -0
- data/lib/lono/hooks/builder.rb +50 -0
- data/lib/lono/hooks/concern.rb +9 -0
- data/lib/lono/hooks/dsl.rb +20 -0
- data/lib/lono/hooks/runner.rb +46 -0
- data/lib/lono/layering/layer.rb +64 -56
- data/lib/lono/logger.rb +1 -3
- data/lib/lono/names.rb +7 -10
- data/lib/lono/s3/bucket.rb +17 -11
- data/lib/lono/s3/uploader.rb +33 -28
- data/lib/lono/script/build.rb +0 -5
- data/lib/lono/seeder.rb +19 -28
- data/lib/lono/user_data.rb +3 -1
- data/lib/lono/utils/call_line.rb +9 -0
- data/lib/lono/utils/sh.rb +32 -0
- data/lib/lono/utils.rb +5 -0
- 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/lib/templates/hook/config/hooks.rb.tt +14 -0
- data/lib/templates/project/Gemfile.tt +2 -7
- data/lono.gemspec +1 -1
- metadata +73 -62
- data/lib/lono/app_file/base.rb +0 -28
- 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/builder/template/post_processor.rb +0 -67
- data/lib/lono/cli/build.rb +0 -91
- data/lib/lono/cli/code.rb +0 -22
- data/lib/lono/cli/help/blueprint/new.md +0 -56
- data/lib/lono/cli/new/extension.rb +0 -57
- 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/core.rb +0 -18
- data/lib/lono/configset/strategy/helpers/dsl.rb +0 -8
- data/lib/lono/configset/strategy/helpers/erb.rb +0 -9
- data/lib/lono/importer/base.rb +0 -48
- data/lib/lono/importer/converter.rb +0 -19
- data/lib/lono/importer/download.rb +0 -46
- data/lib/lono/importer/dsl.rb +0 -36
- data/lib/lono/importer/params.rb +0 -56
- data/lib/lono/importer/service/coder.rb +0 -85
- data/lib/lono/inspector/base.rb +0 -32
- 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
- data/lib/templates/extension/lib/%extension_name%/autoloader.rb.tt +0 -23
- data/lib/templates/extension/lib/%extension_name%/helpers/mappings.rb.tt +0 -24
- data/lib/templates/extension/lib/%extension_name%/helpers/outputs.rb.tt +0 -7
- data/lib/templates/extension/lib/%extension_name%/helpers/parameters.rb.tt +0 -10
- data/lib/templates/extension/lib/%extension_name%/helpers/resources/resource.rb.tt +0 -4
- data/lib/templates/extension/lib/%extension_name%/helpers/variables.rb.tt +0 -6
- data/lib/templates/extension/lib/%extension_name%/version.rb.tt +0 -3
- data/lib/templates/extension/lib/%extension_name%.rb.tt +0 -8
@@ -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,70 @@
|
|
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
|
+
# Think layering is simple enough to keep in this method for now.
|
12
|
+
# Consider trying to combine with Lono::Layering::Layer for uniformity though.
|
13
|
+
def load_vars
|
14
|
+
layers.each do |layer|
|
15
|
+
evaluate_file(layer)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def layers
|
20
|
+
paths = [
|
21
|
+
"#{@configset.root}/vars.rb", # source defaults
|
22
|
+
"#{Lono.root}/config/configsets/#{@configset.name}/vars.rb", # source overrides
|
23
|
+
"#{@blueprint.root}/config/configsets/vars/#{@configset.name}.rb", # blueprint overrides
|
24
|
+
"#{Lono.root}/config/blueprints/#{@blueprint.name}/configsets/vars/#{@configset.name}.rb", # user overrides
|
25
|
+
]
|
26
|
+
show_layers(paths)
|
27
|
+
paths
|
28
|
+
end
|
29
|
+
|
30
|
+
def show_layers(paths)
|
31
|
+
if ENV['LONO_LAYERS_ALL']
|
32
|
+
show_all_layers(paths)
|
33
|
+
else
|
34
|
+
show_existing_layers(paths)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def show_all_layers(paths)
|
39
|
+
show_header
|
40
|
+
paths.each do |path|
|
41
|
+
show_layer(path)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def show_existing_layers(paths)
|
46
|
+
existing = paths.select { |path| File.exist?(path) }
|
47
|
+
return if existing.empty?
|
48
|
+
show_header
|
49
|
+
existing.each do |path|
|
50
|
+
show_layer(path)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def show_header
|
55
|
+
logger.info " Configset Layers #{@configset.name}"
|
56
|
+
end
|
57
|
+
|
58
|
+
def show_layer(path)
|
59
|
+
logger.info " #{pretty_path(path)}"
|
60
|
+
end
|
61
|
+
|
62
|
+
def show_layers?
|
63
|
+
Lono.config.layering.show || ENV['LONO_LAYERS']
|
64
|
+
end
|
65
|
+
|
66
|
+
def load_helpers
|
67
|
+
load_helper_files("#{@configset.root}/helpers", type: :configset)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module Lono::Builder::Configset::Definition::Dsl::Syntax
|
2
|
+
module Content
|
3
|
+
def content_file(path)
|
4
|
+
content_path = "#{content_file_root}/content"
|
5
|
+
file = "#{content_path}/#{path}"
|
6
|
+
if File.exist?(file)
|
7
|
+
IO.read(file)
|
8
|
+
else
|
9
|
+
"File not found: #{file}"
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
private
|
14
|
+
def content_file_root
|
15
|
+
if @configset
|
16
|
+
@configset.root
|
17
|
+
else
|
18
|
+
@blueprint.root
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
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] ||= {}
|
@@ -1,29 +1,25 @@
|
|
1
|
-
|
1
|
+
class Lono::Builder::Configset::Definition
|
2
2
|
class Dsl < Base
|
3
|
-
|
4
|
-
include Helpers::Dsl
|
3
|
+
include Syntax
|
5
4
|
|
6
5
|
def initialize(options={})
|
7
6
|
super
|
8
|
-
@structure = {} # holds in memory the configset hash structure to build AWS::CloudFormation::Init
|
9
7
|
@current = "main" # current configset
|
10
|
-
@command_counts = Hash.new(0)
|
11
8
|
@tracked = []
|
9
|
+
@structure = {} # holds in memory the configset hash structure to build AWS::CloudFormation::Init
|
10
|
+
@command_counts = Hash.new(0)
|
12
11
|
# Also support ability to add AWS::CloudFormation::Authentication
|
13
12
|
@authentication = nil # holds IAM policy info to build AWS::CloudFormation::Authentication
|
14
13
|
end
|
15
14
|
|
16
|
-
def
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
def load
|
21
|
-
evaluate_file(@evaluation_path)
|
22
|
-
configsets = @configsets || @tracked.uniq
|
15
|
+
def evaluate
|
16
|
+
load_context
|
17
|
+
evaluate_file(@configset.path)
|
18
|
+
configsets = configsets || @tracked.uniq
|
23
19
|
configsets = ["main"] if configsets.empty?
|
24
20
|
configsets_structure = {"configSets" => {"default" => configsets}}.merge(@structure)
|
25
|
-
|
26
|
-
|
21
|
+
cloudformation_init = { "AWS::CloudFormation::Init" => configsets_structure }
|
22
|
+
wrap_with_metadata(cloudformation_init)
|
27
23
|
end
|
28
24
|
end
|
29
25
|
end
|
@@ -1,29 +1,22 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
module Lono::Configset::Strategy
|
1
|
+
class Lono::Builder::Configset::Definition
|
4
2
|
class Erb < Base
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
paths.find { |p| File.exist?(p) }
|
3
|
+
def evaluate
|
4
|
+
load_context
|
5
|
+
cloudformation_init = build
|
6
|
+
wrap_with_metadata(cloudformation_init)
|
10
7
|
end
|
11
8
|
|
12
|
-
def
|
13
|
-
content = RenderMePretty.result(@
|
14
|
-
|
15
|
-
if File.extname(@evaluation_path) == ".yml"
|
9
|
+
def build
|
10
|
+
content = RenderMePretty.result(@configset.path, context: self)
|
11
|
+
if File.extname(@configset.path) == ".yml"
|
16
12
|
load_yaml(content)
|
17
13
|
else
|
18
14
|
JSON.load(content)
|
19
15
|
end
|
20
16
|
end
|
21
17
|
|
22
|
-
def authentication
|
23
|
-
# noop
|
24
|
-
end
|
25
|
-
|
26
18
|
def load_yaml(content)
|
19
|
+
# init structure
|
27
20
|
# Write to file so can use Yamler::Validator
|
28
21
|
path = "/tmp/lono/configset.yml"
|
29
22
|
FileUtils.mkdir_p(File.dirname(path))
|
@@ -31,5 +24,9 @@ module Lono::Configset::Strategy
|
|
31
24
|
Lono::Yamler::Validator.new(path).validate!
|
32
25
|
Lono::Yamler::Loader.new(content).load
|
33
26
|
end
|
27
|
+
|
28
|
+
def authentication
|
29
|
+
# noop
|
30
|
+
end
|
34
31
|
end
|
35
32
|
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Lono::Builder::Configset
|
2
|
+
class Definition < Lono::CLI::Base
|
3
|
+
attr_reader :configset
|
4
|
+
def initialize(options={})
|
5
|
+
super
|
6
|
+
@meta = options[:meta]
|
7
|
+
@configset = Lono::Configset.new(@meta)
|
8
|
+
end
|
9
|
+
|
10
|
+
def evaluate
|
11
|
+
strategy_class = configset.path.include?('.rb') ? Dsl : Erb
|
12
|
+
strategy = strategy_class.new(@options.merge(path: configset.path))
|
13
|
+
metadata = strategy.evaluate
|
14
|
+
@configset.metadata = metadata
|
15
|
+
@configset
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module Lono::Builder::Configset
|
2
|
+
class Registration
|
3
|
+
include DslEvaluator
|
4
|
+
|
5
|
+
def initialize(blueprint)
|
6
|
+
@blueprint = blueprint
|
7
|
+
end
|
8
|
+
|
9
|
+
cattr_accessor :metas, default: []
|
10
|
+
def metas
|
11
|
+
self.class.metas
|
12
|
+
end
|
13
|
+
|
14
|
+
def evaluate
|
15
|
+
path = "#{@blueprint.root}/configsets.rb" # plural
|
16
|
+
evaluate_file(path)
|
17
|
+
end
|
18
|
+
|
19
|
+
# Only one syntax method so not in separate module.
|
20
|
+
#
|
21
|
+
# Register configset for later processing.
|
22
|
+
# By registering them all up front, can aggregate errors and show them together
|
23
|
+
# for a user-friendly experience.
|
24
|
+
#
|
25
|
+
# The configset method is different with configset registration vs configset definition
|
26
|
+
#
|
27
|
+
# definition: app/configsets/httpd/configset.rb
|
28
|
+
# registration: app/blueprints/demo/configsets.rb
|
29
|
+
#
|
30
|
+
def configset(name, options={})
|
31
|
+
found = metas.detect { |i| i[:name] == name && i[:resource] == options[:resource] }
|
32
|
+
metas << options.merge(name: name) unless found
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
class Lono::Builder
|
2
|
+
module Context
|
3
|
+
include DslEvaluator
|
4
|
+
|
5
|
+
def load_context
|
6
|
+
load_helpers # load helpers before variable so user custom helpers are available in vars files
|
7
|
+
load_variables
|
8
|
+
end
|
9
|
+
|
10
|
+
# Variables in base.rb are overridden by their environment specific variables
|
11
|
+
# file. Example, file LONO_ENV=dev:
|
12
|
+
#
|
13
|
+
# config/vars/base.rb
|
14
|
+
# config/vars/dev.rb - will override any variables in base.rb
|
15
|
+
# config/vars/base.rb
|
16
|
+
# config/vars/dev.rb - will override any variables in base.rb
|
17
|
+
#
|
18
|
+
def load_variables
|
19
|
+
return if seed?
|
20
|
+
layers = Lono::Layering::Layer.new(@blueprint, "vars").paths
|
21
|
+
layers.each do |layer|
|
22
|
+
evaluate_file(layer)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
# Load blueprint helpers
|
27
|
+
# blueprint helpers override extension helpers
|
28
|
+
def load_helpers
|
29
|
+
load_helper_files("#{Lono.root}/vendor/helpers", type: :project)
|
30
|
+
load_helper_files("#{Lono.root}/app/helpers", type: :project)
|
31
|
+
load_helper_files("#{@blueprint.root}/helpers", type: :blueprint) # takes higher precedence
|
32
|
+
end
|
33
|
+
|
34
|
+
# Dont want any existing files to prevent building the blueprint.
|
35
|
+
# This means that parameters cannot be based on vars. It's a trade-off.
|
36
|
+
def seed?
|
37
|
+
ARGV[0] == "seed"
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -1,6 +1,7 @@
|
|
1
1
|
class Lono::Builder::Dsl
|
2
2
|
class Evaluator < Lono::CLI::Base
|
3
|
-
include
|
3
|
+
include DslEvaluator
|
4
|
+
include Lono::Builder::Context
|
4
5
|
include Lono::Builder::Dsl::Syntax
|
5
6
|
include Lono::Utils::Pretty
|
6
7
|
|
@@ -11,10 +12,8 @@ class Lono::Builder::Dsl
|
|
11
12
|
@cfn = {}
|
12
13
|
end
|
13
14
|
|
14
|
-
def
|
15
|
-
|
16
|
-
load_variables unless seed? # both blueprint and project variables
|
17
|
-
load_blueprint_helpers
|
15
|
+
def evaluate
|
16
|
+
load_context
|
18
17
|
evaluate_template_paths(@template_path) # modifies @cfn
|
19
18
|
finalize
|
20
19
|
to_yaml
|
@@ -32,62 +31,14 @@ class Lono::Builder::Dsl
|
|
32
31
|
@cfn = YAML.load(@cfn.to_json)
|
33
32
|
end
|
34
33
|
|
35
|
-
# Dont want any existing files to prevent building the blueprint.
|
36
|
-
# This means that parameters cannot be based on vars. It's a trade-off.
|
37
|
-
def seed?
|
38
|
-
ARGV[0] == "seed"
|
39
|
-
end
|
40
|
-
|
41
34
|
# Example path: /full/path/to/project/app/blueprints/demo/template.rb
|
42
35
|
def evaluate_template_paths(path)
|
43
36
|
ext = File.extname(path)
|
44
37
|
folder = path.sub(ext, '')
|
45
38
|
expr = "#{folder}/**/*.rb"
|
46
|
-
|
39
|
+
evaluate_file(path) # process top-level template.rb first
|
47
40
|
Dir.glob(expr).each do |path|
|
48
|
-
|
49
|
-
end
|
50
|
-
end
|
51
|
-
|
52
|
-
def evaluate_template_path(path)
|
53
|
-
return unless File.exist?(path)
|
54
|
-
instance_eval(File.read(path), path)
|
55
|
-
rescue Exception => e
|
56
|
-
template_evaluation_error(e)
|
57
|
-
exit 1
|
58
|
-
end
|
59
|
-
|
60
|
-
# Prints out a user friendly task_definition error message
|
61
|
-
#
|
62
|
-
# Backtrace lines are different for OSes:
|
63
|
-
#
|
64
|
-
# windows: "C:/Ruby31-x64/lib/ruby/gems/3.1.0/gems/terraspace-1.1.1/lib/terraspace/builder.rb:34:in `build'"
|
65
|
-
# linux: "/home/ec2-user/.rvm/gems/ruby-3.0.3/gems/terraspace-1.1.1/lib/terraspace/compiler/dsl/syntax/mod.rb:4:in `<module:Mod>'"
|
66
|
-
#
|
67
|
-
def template_evaluation_error(e)
|
68
|
-
lines = e.backtrace.reject { |l| l.include?("/lib/lono/") }
|
69
|
-
error_info = lines.first
|
70
|
-
parts = error_info.split(':')
|
71
|
-
windows = error_info.match(/^[a-zA-Z]:/)
|
72
|
-
path = windows ? parts[1] : parts[0]
|
73
|
-
line_no = windows ? parts[2] : parts[1]
|
74
|
-
line_no = line_no.to_i
|
75
|
-
logger.debug e.message
|
76
|
-
logger.error "Error evaluating #{pretty_path(path)}".color(:red)
|
77
|
-
logger.error "Here's the line with the error:\n\n"
|
78
|
-
|
79
|
-
contents = IO.read(path)
|
80
|
-
content_lines = contents.split("\n")
|
81
|
-
context = 5 # lines of context
|
82
|
-
top, bottom = [line_no-context-1, 0].max, line_no+context-1
|
83
|
-
spacing = content_lines.size.to_s.size
|
84
|
-
content_lines[top..bottom].each_with_index do |line_content, index|
|
85
|
-
line_number = top+index+1
|
86
|
-
if line_number == line_no
|
87
|
-
logger.printf("%#{spacing}d %s\n".color(:red), line_number, line_content)
|
88
|
-
else
|
89
|
-
logger.printf("%#{spacing}d %s\n", line_number, line_content)
|
90
|
-
end
|
41
|
+
evaluate_file(path)
|
91
42
|
end
|
92
43
|
end
|
93
44
|
end
|