lono 5.2.8 → 5.3.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
@@ -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 File.exist?(path)
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
- long_form = "#{root}/configs/#{@blueprint}/params/#{env}/#{@template}/#{@param}.txt"
30
- medium_form = "#{root}/configs/#{@blueprint}/params/#{env}/#{@param}.txt"
31
- short_form = "#{root}/configs/#{@blueprint}/params/#{env}.txt"
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
- return long_form if File.exist?(long_form) # always consider this first because its so explicit
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 File.exist?(medium_form) # higher precedence between longer but short form should be encouraged
46
- return short_form if File.exist?(short_form)
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 File.exist?(medium_form) # only consider medium form
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)
@@ -133,7 +133,9 @@ class Lono::Seed
133
133
 
134
134
  def default_value(data)
135
135
  value = data["Default"]
136
- if value.blank?
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.reject { |logical_id, p| p["Default"] }
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,14 @@
1
+ class Lono::Template::Context
2
+ module Helpers
3
+ extend Memoist
4
+
5
+ def ssm(name)
6
+ ssm_fetcher.get(name)
7
+ end
8
+
9
+ def ssm_fetcher
10
+ SsmFetcher.new
11
+ end
12
+ memoize :ssm_fetcher
13
+ end
14
+ end
@@ -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 && num_or_str?(second)) || # short form
19
+ elsif (definition.size == 2 && valid_value?(second)) || # short form
20
20
  definition.size == 1
21
21
  logical_id = first
22
- properties = num_or_str?(second) ? { default: second } : {}
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 num_or_str?(o)
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
- template = { logical_id => {
27
+ resource = { logical_id => {
28
28
  type: type
29
29
  }}
30
- attributes = template.values.first
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
- template
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
@@ -1,3 +1,3 @@
1
1
  module Lono
2
- VERSION = "5.2.8"
2
+ VERSION = "5.3.0"
3
3
  end
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.2.8
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-10 00:00:00.000000000 Z
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
@@ -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`.