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 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