lono 5.2.8 → 5.3.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e0f1a09d2d9d99ad97a4d8346e67961b193e0adf41f3115a9af315a8db2b6519
4
- data.tar.gz: 2e4b5b91dcf4aef831590fcede27d9fbbf68b3dd764f0c26cbca494693863092
3
+ metadata.gz: 805088c405e44e3e7b228f5d03a893af2a99c2ce990615bb89b906c0c2bb56ee
4
+ data.tar.gz: fff83f7bdae3c28fed272a489e3170d09f803d35a05e943b98db33c89e5d7a9e
5
5
  SHA512:
6
- metadata.gz: 5ded0ebbb676ce87582cee552224ae6fbfd2f6622185c951dc0e3340fa66cda61ed2b4b4cfb99e5e55ee8f93d65bab0f4568676947aafe19253e62dce3a65928
7
- data.tar.gz: 9b1289222f699b107331306ae10e6e03fb253a332660ade6c0b97843def70e2cb28d4b1e0d69c936e917a5a26e1ecce50d2e6e81014a1097473681a9f33c841c
6
+ metadata.gz: bd70ed81d8e4495dff371cd2ec66b519b1002325dac0d17d094a31127ea4e9d186a00001200391f36b9dcece8f85b25f085abeb09c49eedc1f269be457113ad0
7
+ data.tar.gz: 9bb60f3efa20a1c06a0597656f0729e1723380c2af6b20f673f28f4b08fe2ac941876e3252f405864bd488b989b5d7436ce3dad50b65bb059bf51371751b0290
data/CHANGELOG.md CHANGED
@@ -3,6 +3,13 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  This project *tries* to adhere to [Semantic Versioning](http://semver.org/), even before v1.0.
5
5
 
6
+ ## [5.3.0]
7
+ - #8 param preview feature. 3rd type of preview.
8
+ - #9 ssm helper support in configs
9
+ - Simplify param lookup with direct lookup logic.
10
+ - Allow params files to have different extensions. Both.txt and .sh work are auto-inferred conventionally.
11
+ - Allow condition and depends_on to be a properties level and auto-moved to the attributes level.
12
+
6
13
  ## [5.2.8]
7
14
  - add mfa support for normal IAM user
8
15
 
data/README.md CHANGED
@@ -8,6 +8,8 @@
8
8
  [![CircleCI](https://circleci.com/gh/tongueroo/lono.svg?style=svg)](https://circleci.com/gh/tongueroo/lono)
9
9
  [![Support](https://img.shields.io/badge/get-support-blue.svg)](https://boltops.com?utm_source=badge&utm_medium=badge&utm_campaign=lono)
10
10
 
11
+ [![BoltOps Badge](https://img.boltops.com/boltops/badges/boltops-badge.png)](https://www.boltops.com)
12
+
11
13
  Lono is a powerful CloudFormation framework. Lono handles the entire CloudFormation lifecycle. It builds, manages and deploys CloudFormation templates.
12
14
 
13
15
  * Lono generates CloudFormation templates based on a [DSL](http://lono.cloud/docs/dsl/).
data/lib/lono/cfn.rb CHANGED
@@ -22,8 +22,9 @@ module Lono
22
22
  end
23
23
  update_options = Proc.new do
24
24
  option :change_set, type: :boolean, default: true, desc: "Uses generated change set to update the stack. If false, will perform normal update-stack."
25
- option :diff, type: :boolean, default: true, desc: "Show diff of the source code template changes before continuing."
26
- option :preview, type: :boolean, default: true, desc: "Show preview of the stack changes before continuing."
25
+ option :codediff_preview, type: :boolean, default: true, desc: "Show codediff changes preview."
26
+ option :changeset_preview, type: :boolean, default: true, desc: "Show ChangeSet changes preview."
27
+ option :param_preview, type: :boolean, default: true, desc: "Show parameter diff preview."
27
28
  option :sure, type: :boolean, desc: "Skips are you sure prompt"
28
29
  end
29
30
 
@@ -75,20 +76,15 @@ module Lono
75
76
  desc "preview STACK", "Preview a CloudFormation stack update. This is similar to terraform's plan or puppet's dry-run mode."
76
77
  long_desc Lono::Help.text("cfn/preview")
77
78
  option :keep, type: :boolean, desc: "keep the changeset instead of deleting it afterwards"
78
- option :diff, type: :boolean, default: true, desc: "Show diff of the source code template changes also."
79
+ option :param_preview, type: :boolean, default: true, desc: "Show parameter diff preview."
80
+ option :codediff_preview, type: :boolean, default: true, desc: "Show codediff changes preview."
81
+ option :changeset_preview, type: :boolean, default: true, desc: "Show ChangeSet changes preview."
79
82
  base_options.call
80
83
  suffix_option.call
81
84
  def preview(stack_name=:current)
82
- Diff.new(stack_name, options).run if options[:diff]
83
- Preview.new(stack_name, options).run
84
- end
85
-
86
- desc "diff STACK", "Diff newly generated template vs existing template."
87
- long_desc Lono::Help.text("cfn/diff")
88
- base_options.call
89
- suffix_option.call
90
- def diff(stack_name=:current)
91
- Diff.new(stack_name, options).run
85
+ Preview::Param.new(stack_name, options).run if options[:param_preview]
86
+ Preview::Codediff.new(stack_name, options).run if options[:codediff_preview]
87
+ Preview::Changeset.new(stack_name, options).run if options[:changeset_preview]
92
88
  end
93
89
 
94
90
  desc "download STACK", "Download CloudFormation template from existing stack."
@@ -1,151 +1,4 @@
1
1
  class Lono::Cfn
2
- class Preview < Base
3
- # Override run from Base superclass, the run method is different enough with Preview
4
- def run
5
- if @options[:noop]
6
- puts "NOOP CloudFormation preview for #{@stack_name} update"
7
- else
8
- params = generate_all
9
- success = preview_change_set(params)
10
- delete_change_set if success && !@options[:keep] # Clean up and delete the change set
11
- end
12
- end
13
-
14
- def preview_change_set(params)
15
- success = create_change_set(params)
16
- display_change_set if success
17
- end
18
-
19
- def create_change_set(params)
20
- unless stack_exists?(@stack_name)
21
- puts "WARN: Cannot create a change set for the stack because the #{@stack_name} does not exists.".color(:yellow)
22
- return false
23
- end
24
- exit_unless_updatable!(stack_status(@stack_name))
25
-
26
- params = {
27
- change_set_name: change_set_name,
28
- stack_name: @stack_name,
29
- parameters: params,
30
- capabilities: capabilities, # ["CAPABILITY_IAM", "CAPABILITY_NAMED_IAM"],
31
- }
32
- params[:tags] = tags unless tags.empty?
33
- set_template_body!(params)
34
- show_parameters(params, "cfn.create_change_set")
35
- begin
36
- cfn.create_change_set(params)
37
- rescue Aws::CloudFormation::Errors::ValidationError => e
38
- handle_error(e)
39
- end
40
- true
41
- end
42
-
43
- # Example errors:
44
- # "Template error: variable names in Fn::Sub syntax must contain only alphanumeric characters, underscores, periods, and colons"
45
- def handle_error(e)
46
- raise if ENV['FULL_BACKTRACE']
47
-
48
- if e.message =~ /^Parameters: / || e.message =~ /^Template error: /
49
- puts "Error creating CloudFormation preview because invalid CloudFormation parameters. Full error message:".color(:red)
50
- puts e.message
51
- puts "For full backtrace run command again with FULL_BACKTRACE=1"
52
- quit(1)
53
- else
54
- raise
55
- end
56
- end
57
-
58
- def display_change_set
59
- print "Generating CloudFormation Change Set for preview.."
60
- change_set = describe_change_set
61
- until change_set_finished?(change_set) do
62
- change_set = describe_change_set
63
- sleep 1
64
- print '.'
65
- end
66
- puts
67
-
68
- case change_set.status
69
- when "CREATE_COMPLETE"
70
- puts "CloudFormation preview for '#{@stack_name}' stack update. Changes:"
71
- changes = change_set.changes.sort_by do |change|
72
- change["resource_change"]["action"]
73
- end
74
- changes.each do |change|
75
- display_change(change)
76
- end
77
- when "FAILED"
78
- puts "WARN: Fail to create a CloudFormation preview for '#{@stack_name}' stack update. Reason:".color(:yellow)
79
- puts change_set.status_reason
80
- quit(0)
81
- else
82
- raise "hell: never come here"
83
- end
84
- end
85
-
86
- def delete_change_set
87
- cfn.delete_change_set(
88
- change_set_name: change_set_name,
89
- stack_name: @stack_name
90
- )
91
- end
92
-
93
- def execute_change_set
94
- cfn.execute_change_set(
95
- change_set_name: change_set_name,
96
- stack_name: @stack_name
97
- )
98
- end
99
-
100
- # generates a change set name
101
- def change_set_name
102
- @change_set_name ||= "changeset-#{Time.now.strftime("%Y%d%m%H%M%S")}"
103
- end
104
-
105
- private
106
- # Private: formats a Aws::CloudFormation::Types::Change in pretty human readable form
107
- #
108
- # change - Aws::CloudFormation::Types::Change
109
- #
110
- # Examples
111
- #
112
- # display_change(change)
113
- # => Remove AWS::Route53::RecordSet: DnsRecord testsubdomain.sub.tongueroo.com
114
- #
115
- # Returns nil
116
- #
117
- # change.to_h
118
- # {:type=>"Resource",
119
- # :resource_change=>
120
- # {:action=>"Remove",
121
- # :logical_resource_id=>"DnsRecord",
122
- # :physical_resource_id=>"testsubdomain.sub.tongueroo.com",
123
- # :resource_type=>"AWS::Route53::RecordSet",
124
- # :scope=>[],
125
- # :details=>[]}}
126
- def display_change(change)
127
- message = if change.type == "Resource"
128
- c = change.resource_change
129
- "#{c.action} #{c.resource_type}: #{c.logical_resource_id} #{c.physical_resource_id}"
130
- else
131
- change.to_h
132
- end
133
-
134
- colors = { Remove: :red, Add: :green, Modify: :yellow }
135
- action = change.resource_change.action.to_sym
136
- message = message.color(colors[action]) if colors.has_key?(action)
137
- puts message
138
- end
139
-
140
- def change_set_finished?(change_set)
141
- change_set.status =~ /_COMPLETE/ || change_set.status == "FAILED"
142
- end
143
-
144
- def describe_change_set
145
- cfn.describe_change_set(
146
- change_set_name: change_set_name,
147
- stack_name: @stack_name
148
- )
149
- end
2
+ module Preview
150
3
  end
151
- end
4
+ end
@@ -0,0 +1,154 @@
1
+ module Lono::Cfn::Preview
2
+ class Changeset < Lono::Cfn::Base
3
+ # Override run from Base superclass, the run method is different enough with Preview
4
+ def run
5
+ puts "Changeset Preview:".color(:green)
6
+
7
+ if @options[:noop]
8
+ puts "NOOP CloudFormation preview for #{@stack_name} update"
9
+ return
10
+ end
11
+
12
+ params = generate_all
13
+ success = preview_change_set(params)
14
+ delete_change_set if success && !@options[:keep] # Clean up and delete the change set
15
+ end
16
+
17
+ def preview_change_set(params)
18
+ success = create_change_set(params)
19
+ display_change_set if success
20
+ end
21
+
22
+ def create_change_set(params)
23
+ unless stack_exists?(@stack_name)
24
+ puts "WARN: Cannot create a change set for the stack because the #{@stack_name} does not exists.".color(:yellow)
25
+ return false
26
+ end
27
+ exit_unless_updatable!(stack_status(@stack_name))
28
+
29
+ params = {
30
+ change_set_name: change_set_name,
31
+ stack_name: @stack_name,
32
+ parameters: params,
33
+ capabilities: capabilities, # ["CAPABILITY_IAM", "CAPABILITY_NAMED_IAM"],
34
+ }
35
+ params[:tags] = tags unless tags.empty?
36
+ set_template_body!(params)
37
+ show_parameters(params, "cfn.create_change_set")
38
+ begin
39
+ cfn.create_change_set(params)
40
+ rescue Aws::CloudFormation::Errors::ValidationError => e
41
+ handle_error(e)
42
+ end
43
+ true
44
+ end
45
+
46
+ # Example errors:
47
+ # "Template error: variable names in Fn::Sub syntax must contain only alphanumeric characters, underscores, periods, and colons"
48
+ def handle_error(e)
49
+ raise if ENV['FULL_BACKTRACE']
50
+
51
+ if e.message =~ /^Parameters: / || e.message =~ /^Template error: /
52
+ puts "Error creating CloudFormation preview because invalid CloudFormation parameters. Full error message:".color(:red)
53
+ puts e.message
54
+ puts "For full backtrace run command again with FULL_BACKTRACE=1"
55
+ quit(1)
56
+ else
57
+ raise
58
+ end
59
+ end
60
+
61
+ def display_change_set
62
+ print "Generating CloudFormation Change Set for preview.."
63
+ change_set = describe_change_set
64
+ until change_set_finished?(change_set) do
65
+ change_set = describe_change_set
66
+ sleep 1
67
+ print '.'
68
+ end
69
+ puts
70
+
71
+ case change_set.status
72
+ when "CREATE_COMPLETE"
73
+ puts "CloudFormation preview for '#{@stack_name}' stack update. Changes:"
74
+ changes = change_set.changes.sort_by do |change|
75
+ change["resource_change"]["action"]
76
+ end
77
+ changes.each do |change|
78
+ display_change(change)
79
+ end
80
+ when "FAILED"
81
+ puts "WARN: Fail to create a CloudFormation preview for '#{@stack_name}' stack update. Reason:".color(:yellow)
82
+ puts change_set.status_reason
83
+ quit(0)
84
+ else
85
+ raise "hell: never come here"
86
+ end
87
+ end
88
+
89
+ def delete_change_set
90
+ cfn.delete_change_set(
91
+ change_set_name: change_set_name,
92
+ stack_name: @stack_name
93
+ )
94
+ end
95
+
96
+ def execute_change_set
97
+ cfn.execute_change_set(
98
+ change_set_name: change_set_name,
99
+ stack_name: @stack_name
100
+ )
101
+ end
102
+
103
+ # generates a change set name
104
+ def change_set_name
105
+ @change_set_name ||= "changeset-#{Time.now.strftime("%Y%d%m%H%M%S")}"
106
+ end
107
+
108
+ private
109
+ # Private: formats a Aws::CloudFormation::Types::Change in pretty human readable form
110
+ #
111
+ # change - Aws::CloudFormation::Types::Change
112
+ #
113
+ # Examples
114
+ #
115
+ # display_change(change)
116
+ # => Remove AWS::Route53::RecordSet: DnsRecord testsubdomain.sub.tongueroo.com
117
+ #
118
+ # Returns nil
119
+ #
120
+ # change.to_h
121
+ # {:type=>"Resource",
122
+ # :resource_change=>
123
+ # {:action=>"Remove",
124
+ # :logical_resource_id=>"DnsRecord",
125
+ # :physical_resource_id=>"testsubdomain.sub.tongueroo.com",
126
+ # :resource_type=>"AWS::Route53::RecordSet",
127
+ # :scope=>[],
128
+ # :details=>[]}}
129
+ def display_change(change)
130
+ message = if change.type == "Resource"
131
+ c = change.resource_change
132
+ "#{c.action} #{c.resource_type}: #{c.logical_resource_id} #{c.physical_resource_id}"
133
+ else
134
+ change.to_h
135
+ end
136
+
137
+ colors = { Remove: :red, Add: :green, Modify: :yellow }
138
+ action = change.resource_change.action.to_sym
139
+ message = message.color(colors[action]) if colors.has_key?(action)
140
+ puts message
141
+ end
142
+
143
+ def change_set_finished?(change_set)
144
+ change_set.status =~ /_COMPLETE/ || change_set.status == "FAILED"
145
+ end
146
+
147
+ def describe_change_set
148
+ cfn.describe_change_set(
149
+ change_set_name: change_set_name,
150
+ stack_name: @stack_name
151
+ )
152
+ end
153
+ end
154
+ end
@@ -1,8 +1,11 @@
1
- class Lono::Cfn
2
- class Diff < Base
1
+ module Lono::Cfn::Preview
2
+ class Codediff < Lono::Cfn::Base
3
+ include DiffViewer
3
4
  include Lono::AwsServices
4
5
 
5
6
  def run
7
+ puts "Code Diff Preview:".color(:green)
8
+
6
9
  unless stack_exists?(@stack_name)
7
10
  puts "WARN: Cannot create a diff for the stack because the #{@stack_name} does not exists.".color(:yellow)
8
11
  return
@@ -14,7 +17,7 @@ class Lono::Cfn
14
17
  generate_all # from Base superclass. Generates the output lono teplates
15
18
  puts "Generating CloudFormation source code diff..."
16
19
  download_existing_cfn_template
17
- show_changes
20
+ show_diff(existing_template_path, new_cfn_template)
18
21
  end
19
22
  end
20
23
 
@@ -27,22 +30,11 @@ class Lono::Cfn
27
30
  IO.write(existing_template_path, resp.template_body)
28
31
  end
29
32
 
30
- def show_changes
31
- command = "#{diff_viewer} #{existing_template_path} #{new_cfn_template}"
32
- puts "Running: #{command}"
33
- system(command)
34
- end
35
-
36
33
  # for clarity
37
34
  def new_cfn_template
38
35
  @template_path
39
36
  end
40
37
 
41
- def diff_viewer
42
- return ENV['LONO_DIFF'] if ENV['LONO_DIFF']
43
- system("type colordiff > /dev/null") ? "colordiff" : "diff"
44
- end
45
-
46
38
  def existing_template_path
47
39
  "/tmp/existing_cfn_template.yml"
48
40
  end
@@ -0,0 +1,19 @@
1
+ module Lono::Cfn::Preview
2
+ module DiffViewer
3
+ def show_diff(existing_path, new_path)
4
+ command = "#{diff_viewer} #{existing_path} #{new_path}"
5
+ puts "Running: #{command}"
6
+ out = `#{command}`
7
+ if out.strip == ''
8
+ puts "There were no differences."
9
+ else
10
+ puts out
11
+ end
12
+ end
13
+
14
+ def diff_viewer
15
+ return ENV['LONO_DIFF'] if ENV['LONO_DIFF']
16
+ system("type colordiff > /dev/null") ? "colordiff" : "diff"
17
+ end
18
+ end
19
+ end