lono 5.2.8 → 5.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +7 -0
- data/README.md +2 -0
- data/lib/lono/cfn.rb +9 -13
- data/lib/lono/cfn/preview.rb +2 -149
- data/lib/lono/cfn/preview/changeset.rb +154 -0
- data/lib/lono/cfn/{diff.rb → preview/codediff.rb} +6 -14
- data/lib/lono/cfn/preview/diff_viewer.rb +19 -0
- data/lib/lono/cfn/preview/param.rb +73 -0
- data/lib/lono/cfn/update.rb +15 -8
- data/lib/lono/inspector.rb +1 -1
- data/lib/lono/inspector/base.rb +30 -36
- data/lib/lono/inspector/graph.rb +100 -99
- data/lib/lono/inspector/summary.rb +48 -59
- data/lib/lono/output_template.rb +35 -0
- data/lib/lono/param/generator.rb +38 -9
- data/lib/lono/seed/base.rb +5 -3
- data/lib/lono/template/context.rb +2 -0
- data/lib/lono/template/context/helpers.rb +14 -0
- data/lib/lono/template/context/ssm_fetcher.rb +23 -0
- data/lib/lono/template/dsl/builder/parameter.rb +4 -4
- data/lib/lono/template/dsl/builder/resource.rb +10 -5
- data/lib/lono/template/dsl/builder/resource/property_mover.rb +19 -0
- data/lib/lono/version.rb +1 -1
- data/lono.gemspec +1 -0
- metadata +24 -4
- data/lib/lono/help/cfn/diff.md +0 -24
@@ -0,0 +1,35 @@
|
|
1
|
+
module Lono
|
2
|
+
class OutputTemplate
|
3
|
+
def initialize(blueprint, template)
|
4
|
+
@blueprint, @template = blueprint, template
|
5
|
+
end
|
6
|
+
|
7
|
+
def data
|
8
|
+
template_path = "#{Lono.config.output_path}/#{@blueprint}/templates/#{@template}.yml"
|
9
|
+
check_template_exists(template_path)
|
10
|
+
YAML.load(IO.read(template_path))
|
11
|
+
end
|
12
|
+
|
13
|
+
# Check if the template exists and print friendly error message. Exits if it
|
14
|
+
# does not exist.
|
15
|
+
def check_template_exists(template_path)
|
16
|
+
unless File.exist?(template_path)
|
17
|
+
puts "The template #{template_path} does not exist. Are you sure you use the right template name? The template name does not require the extension.".color(:red)
|
18
|
+
exit 1
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def required_parameters
|
23
|
+
parameters.reject { |logical_id, p| p["Default"] }
|
24
|
+
end
|
25
|
+
|
26
|
+
def optional_parameters
|
27
|
+
parameters.select { |logical_id, p| p["Default"] }
|
28
|
+
end
|
29
|
+
|
30
|
+
def parameters
|
31
|
+
data["Parameters"] || []
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
end
|
data/lib/lono/param/generator.rb
CHANGED
@@ -13,9 +13,9 @@ class Lono::Param
|
|
13
13
|
def puts_param_message(type)
|
14
14
|
path = send("#{type}_path")
|
15
15
|
return unless path
|
16
|
-
if
|
16
|
+
if param_file?(path)
|
17
17
|
pretty_path = path.sub("#{Lono.root}/",'')
|
18
|
-
puts "Using param: #{pretty_path}".color(:yellow)
|
18
|
+
puts "Using param for #{type}: #{pretty_path}".color(:yellow)
|
19
19
|
end
|
20
20
|
end
|
21
21
|
|
@@ -26,34 +26,63 @@ class Lono::Param
|
|
26
26
|
# configs/BLUEPRINT/params/development.txt
|
27
27
|
#
|
28
28
|
def lookup_param_file(root: Lono.root, env: Lono.env)
|
29
|
-
|
30
|
-
|
31
|
-
|
29
|
+
# The docs conver direct_absolute_form and direct_relative_form as the "Direct Form"
|
30
|
+
unless env == "base"
|
31
|
+
direct_absolute_form = @param # user provided the absolute full path
|
32
|
+
direct_relative_form = "#{root}/#{@param}" # user provided the full path within the lono project
|
33
|
+
direct_env_form = "#{root}/configs/#{@blueprint}/params/#{env}/#{@param}" # direct lookup is simple
|
34
|
+
direct_simple_form = "#{root}/configs/#{@blueprint}/params/#{@param}" # direct lookup is simple
|
35
|
+
end
|
36
|
+
long_form = "#{root}/configs/#{@blueprint}/params/#{env}/#{@template}/#{@param}"
|
37
|
+
medium_form = "#{root}/configs/#{@blueprint}/params/#{env}/#{@param}"
|
38
|
+
short_form = "#{root}/configs/#{@blueprint}/params/#{env}"
|
32
39
|
|
33
40
|
if ENV['LONO_PARAM_DEBUG']
|
34
41
|
puts "Lono.blueprint_root #{Lono.blueprint_root}"
|
42
|
+
puts "direct_absolute_form #{direct_absolute_form}"
|
43
|
+
puts "direct_relative_form #{direct_relative_form}"
|
44
|
+
puts "direct_env_form #{direct_env_form}"
|
45
|
+
puts "direct_simple_form #{direct_simple_form}"
|
35
46
|
puts "long_form #{long_form}"
|
36
47
|
puts "medium_form #{medium_form}"
|
37
48
|
puts "short_form #{short_form}"
|
38
49
|
end
|
39
50
|
|
40
|
-
|
51
|
+
unless env == "base"
|
52
|
+
return param_file(direct_absolute_form) if param_file?(direct_absolute_form)
|
53
|
+
return param_file(direct_relative_form) if param_file?(direct_relative_form)
|
54
|
+
return param_file(direct_env_form) if param_file?(direct_env_form) # consider this first its simple and direct but is scope to env so it's more specific
|
55
|
+
return param_file(direct_simple_form) if param_file?(direct_simple_form) # consider this first its simple and direct but is scope to env so it's more specific
|
56
|
+
end
|
57
|
+
return param_file(long_form) if param_file?(long_form) # consider this first because its more explicit
|
41
58
|
|
42
59
|
# All 3 are the same
|
43
60
|
# Also, blueprint and template the same and explicitly specified param
|
44
61
|
if @blueprint == @template
|
45
|
-
return medium_form if
|
46
|
-
return short_form if
|
62
|
+
return param_file(medium_form) if param_file?(medium_form) # higher precedence between longer but short form should be encouraged
|
63
|
+
return param_file(short_form) if param_file?(short_form)
|
47
64
|
return # cannot find a param file
|
48
65
|
end
|
49
66
|
|
50
67
|
# Only template and param are the same
|
51
68
|
if @template == @param
|
52
|
-
return medium_form if
|
69
|
+
return param_file(medium_form) if param_file?(medium_form) # only consider medium form
|
53
70
|
return # cannot find a param file
|
54
71
|
end
|
55
72
|
end
|
56
73
|
|
74
|
+
# Allows user to specify the .txt extension or not to.
|
75
|
+
# Also allows user to use other extensions like .sh if they are explicit about it.
|
76
|
+
def param_file?(path)
|
77
|
+
File.file?(path) || File.file?("#{path}.txt") || File.file?("#{path}.sh")
|
78
|
+
end
|
79
|
+
|
80
|
+
def param_file(path)
|
81
|
+
return path if File.file?(path)
|
82
|
+
return "#{path}.txt" if File.file?("#{path}.txt")
|
83
|
+
return "#{path}.sh" if File.file?("#{path}.sh")
|
84
|
+
end
|
85
|
+
|
57
86
|
def lookup_paths
|
58
87
|
@base_path = lookup_param_file(env: "base")
|
59
88
|
@env_path = lookup_param_file(env: Lono.env)
|
data/lib/lono/seed/base.rb
CHANGED
@@ -133,7 +133,9 @@ class Lono::Seed
|
|
133
133
|
|
134
134
|
def default_value(data)
|
135
135
|
value = data["Default"]
|
136
|
-
|
136
|
+
# Dont use !blank? since there can be false optional values
|
137
|
+
# Also dont use .empty? since value can be an Integer
|
138
|
+
if value.nil? || value == ''
|
137
139
|
description_example(data["Description"])
|
138
140
|
else
|
139
141
|
value
|
@@ -148,11 +150,11 @@ class Lono::Seed
|
|
148
150
|
memoize :parameters
|
149
151
|
|
150
152
|
def required(parameters)
|
151
|
-
parameters.
|
153
|
+
parameters.select { |logical_id, p| p["Default"].nil? } # allow for false
|
152
154
|
end
|
153
155
|
|
154
156
|
def optional(parameters)
|
155
|
-
parameters.select { |logical_id, p| p["Default"] }
|
157
|
+
parameters.select { |logical_id, p| !p["Default"].nil? } # allow for false
|
156
158
|
end
|
157
159
|
|
158
160
|
private
|
@@ -1,8 +1,10 @@
|
|
1
1
|
# Encapsulates helper methods and instance variables to be rendered in the ERB templates.
|
2
2
|
class Lono::Template
|
3
3
|
class Context
|
4
|
+
extend Memoist
|
4
5
|
include Lono::Template::Helper
|
5
6
|
include Loader
|
7
|
+
include Helpers
|
6
8
|
|
7
9
|
def initialize(blueprint, options={})
|
8
10
|
@blueprint, @options = blueprint, options
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'aws-sdk-ssm'
|
2
|
+
|
3
|
+
class Lono::Template::Context
|
4
|
+
class SsmFetcher
|
5
|
+
extend Memoist
|
6
|
+
|
7
|
+
def get(name)
|
8
|
+
fetch_ssm_value(name)
|
9
|
+
end
|
10
|
+
|
11
|
+
def fetch_ssm_value(name)
|
12
|
+
resp = ssm.get_parameter(name: name, with_decryption: true)
|
13
|
+
resp.parameter.value
|
14
|
+
rescue Aws::SSM::Errors::ParameterNotFound
|
15
|
+
'SSM-PARAM-NOT-FOUND'
|
16
|
+
end
|
17
|
+
|
18
|
+
def ssm
|
19
|
+
Aws::SSM::Client.new
|
20
|
+
end
|
21
|
+
memoize :ssm
|
22
|
+
end
|
23
|
+
end
|
@@ -16,10 +16,10 @@ class Lono::Template::Dsl::Builder
|
|
16
16
|
elsif definition.size == 2 && second.is_a?(Hash) # medium form
|
17
17
|
logical_id, properties = first, second
|
18
18
|
{ logical_id => properties }
|
19
|
-
elsif (definition.size == 2 &&
|
19
|
+
elsif (definition.size == 2 && valid_value?(second)) || # short form
|
20
20
|
definition.size == 1
|
21
21
|
logical_id = first
|
22
|
-
properties =
|
22
|
+
properties = valid_value?(second) ? { default: second } : {}
|
23
23
|
{ logical_id => properties }
|
24
24
|
else # I dont know what form
|
25
25
|
raise "Invalid form provided. definition #{definition.inspect}"
|
@@ -32,8 +32,8 @@ class Lono::Template::Dsl::Builder
|
|
32
32
|
attributes
|
33
33
|
end
|
34
34
|
|
35
|
-
def
|
36
|
-
o.is_a?(Float) || o.is_a?(Integer) || o.is_a?(String)
|
35
|
+
def valid_value?(o)
|
36
|
+
o.is_a?(Float) || o.is_a?(Integer) || o.is_a?(String) || o.is_a?(TrueClass) || o.is_a?(FalseClass)
|
37
37
|
end
|
38
38
|
end
|
39
39
|
end
|
@@ -17,19 +17,24 @@ class Lono::Template::Dsl::Builder
|
|
17
17
|
logical_id, attributes = first, second
|
18
18
|
attributes.delete(:properties) if attributes[:properties].nil? || attributes[:properties].empty?
|
19
19
|
{ logical_id => attributes }
|
20
|
-
elsif definition.size == 2 && second.is_a?(String) # short form
|
20
|
+
elsif definition.size == 2 && second.is_a?(String) # short form with no properties
|
21
21
|
logical_id, type = first, second
|
22
22
|
{ logical_id => {
|
23
23
|
type: type
|
24
24
|
}}
|
25
|
-
elsif definition.size == 3 && (second.is_a?(String) || second.is_a?(NilClass))# short form
|
25
|
+
elsif definition.size == 3 && (second.is_a?(String) || second.is_a?(NilClass)) # short form
|
26
26
|
logical_id, type, properties = first, second, third
|
27
|
-
|
27
|
+
resource = { logical_id => {
|
28
28
|
type: type
|
29
29
|
}}
|
30
|
-
|
30
|
+
|
31
|
+
attributes = resource.values.first
|
32
|
+
|
33
|
+
property_mover = PropertyMover.new(resource, logical_id, properties)
|
34
|
+
property_mover.move!
|
35
|
+
|
31
36
|
attributes[:properties] = properties unless properties.empty?
|
32
|
-
|
37
|
+
resource
|
33
38
|
else # Dont understand this form
|
34
39
|
raise "Invalid form provided. definition #{definition.inspect}"
|
35
40
|
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
class Lono::Template::Dsl::Builder::Resource
|
2
|
+
# Moves the property to the top-level attributes *destructively*
|
3
|
+
class PropertyMover
|
4
|
+
def initialize(resource, logical_id, properties)
|
5
|
+
@resource, @logical_id, @properties = resource, logical_id, properties
|
6
|
+
end
|
7
|
+
|
8
|
+
def move!
|
9
|
+
%w[depends_on condition].each do |attribute_name|
|
10
|
+
move(attribute_name.to_sym)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def move(attribute_name)
|
15
|
+
attribute_value = @properties.delete(attribute_name)
|
16
|
+
@resource[@logical_id][attribute_name] = attribute_value if attribute_value
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
data/lib/lono/version.rb
CHANGED
data/lono.gemspec
CHANGED
@@ -26,6 +26,7 @@ Gem::Specification.new do |gem|
|
|
26
26
|
gem.add_dependency "aws-sdk-ec2" # lono seed
|
27
27
|
gem.add_dependency "aws-sdk-iam" # lono seed
|
28
28
|
gem.add_dependency "aws-sdk-s3"
|
29
|
+
gem.add_dependency "aws-sdk-ssm"
|
29
30
|
gem.add_dependency "cfn_camelizer"
|
30
31
|
gem.add_dependency "filesize"
|
31
32
|
gem.add_dependency "graph" # lono xgraph command dependency
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: lono
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 5.
|
4
|
+
version: 5.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tung Nguyen
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-11-
|
11
|
+
date: 2019-11-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -94,6 +94,20 @@ dependencies:
|
|
94
94
|
- - ">="
|
95
95
|
- !ruby/object:Gem::Version
|
96
96
|
version: '0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: aws-sdk-ssm
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ">="
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
type: :runtime
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
97
111
|
- !ruby/object:Gem::Dependency
|
98
112
|
name: cfn_camelizer
|
99
113
|
requirement: !ruby/object:Gem::Requirement
|
@@ -453,9 +467,12 @@ files:
|
|
453
467
|
- lib/lono/cfn/current.rb
|
454
468
|
- lib/lono/cfn/delete.rb
|
455
469
|
- lib/lono/cfn/deploy.rb
|
456
|
-
- lib/lono/cfn/diff.rb
|
457
470
|
- lib/lono/cfn/download.rb
|
458
471
|
- lib/lono/cfn/preview.rb
|
472
|
+
- lib/lono/cfn/preview/changeset.rb
|
473
|
+
- lib/lono/cfn/preview/codediff.rb
|
474
|
+
- lib/lono/cfn/preview/diff_viewer.rb
|
475
|
+
- lib/lono/cfn/preview/param.rb
|
459
476
|
- lib/lono/cfn/rollback.rb
|
460
477
|
- lib/lono/cfn/status.rb
|
461
478
|
- lib/lono/cfn/suffix.rb
|
@@ -481,7 +498,6 @@ files:
|
|
481
498
|
- lib/lono/help/cfn/current.md
|
482
499
|
- lib/lono/help/cfn/delete.md
|
483
500
|
- lib/lono/help/cfn/deploy.md
|
484
|
-
- lib/lono/help/cfn/diff.md
|
485
501
|
- lib/lono/help/cfn/download.md
|
486
502
|
- lib/lono/help/cfn/preview.md
|
487
503
|
- lib/lono/help/cfn/status.md
|
@@ -509,6 +525,7 @@ files:
|
|
509
525
|
- lib/lono/md5.rb
|
510
526
|
- lib/lono/new.rb
|
511
527
|
- lib/lono/new/helper.rb
|
528
|
+
- lib/lono/output_template.rb
|
512
529
|
- lib/lono/param.rb
|
513
530
|
- lib/lono/param/generator.rb
|
514
531
|
- lib/lono/project_checker.rb
|
@@ -527,7 +544,9 @@ files:
|
|
527
544
|
- lib/lono/template/base.rb
|
528
545
|
- lib/lono/template/bashify.rb
|
529
546
|
- lib/lono/template/context.rb
|
547
|
+
- lib/lono/template/context/helpers.rb
|
530
548
|
- lib/lono/template/context/loader.rb
|
549
|
+
- lib/lono/template/context/ssm_fetcher.rb
|
531
550
|
- lib/lono/template/dsl.rb
|
532
551
|
- lib/lono/template/dsl/builder.rb
|
533
552
|
- lib/lono/template/dsl/builder/base.rb
|
@@ -538,6 +557,7 @@ files:
|
|
538
557
|
- lib/lono/template/dsl/builder/output.rb
|
539
558
|
- lib/lono/template/dsl/builder/parameter.rb
|
540
559
|
- lib/lono/template/dsl/builder/resource.rb
|
560
|
+
- lib/lono/template/dsl/builder/resource/property_mover.rb
|
541
561
|
- lib/lono/template/dsl/builder/section.rb
|
542
562
|
- lib/lono/template/dsl/builder/syntax.rb
|
543
563
|
- lib/lono/template/erb.rb
|
data/lib/lono/help/cfn/diff.md
DELETED
@@ -1,24 +0,0 @@
|
|
1
|
-
Displays code diff of the generated CloudFormation template locally vs the existing template on AWS. You can set a desired diff viewer by setting the `LONO_DIFF` environment variable.
|
2
|
-
|
3
|
-
## Examples
|
4
|
-
|
5
|
-
$ lono cfn diff ec2
|
6
|
-
Using template: output/templates/ec2.yml
|
7
|
-
Using parameters: config/params/development/ec2.txt
|
8
|
-
No detected app/scripts
|
9
|
-
Generating CloudFormation templates:
|
10
|
-
output/templates/ec2.yml
|
11
|
-
output/params/ec2.json
|
12
|
-
Generating CloudFormation source code diff...
|
13
|
-
Running: colordiff /tmp/existing_cfn_template.yml output/templates/ec2.yml
|
14
|
-
19c19
|
15
|
-
< Default: t2.small
|
16
|
-
---
|
17
|
-
> Default: t2.medium
|
18
|
-
$
|
19
|
-
|
20
|
-
Here's a screenshot of the output with the colored diff:
|
21
|
-
|
22
|
-
<img src="/img/reference/lono-cfn-diff.png" alt="Stack Update" class="doc-photo">
|
23
|
-
|
24
|
-
A `lono cfn diff` is perform automatically as part of `lono cfn update`.
|