stackup 1.3.0 → 1.3.1

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
- SHA256:
3
- metadata.gz: 9b2b7a0536a72a652bc20f3e2afaa65db33bb97c03fbc761bae6bebd9c6cd664
4
- data.tar.gz: c6dfbccf6f5428b37af5ba7b93ddd95f5e22f20ee65f3f92f26c1919384763f8
2
+ SHA1:
3
+ metadata.gz: 79c44228b207109b4fc970baa4078e7021e2c963
4
+ data.tar.gz: 2bdb3b3da63d828f7a8fb902422c7eb7c879787f
5
5
  SHA512:
6
- metadata.gz: 46c0107e466288546bc932eda695cf337b16b3e60755090eb16c6fc66654560fdc3126d0cd87d9ab57a8f24b3fe45161bd5874b182dfce5c1e9b2eafe20934d7
7
- data.tar.gz: d461a8ebdc5ad7cf4771e9e86eff852a0af2b513e29bbc46bdf0df10b9536b57711aaf95057062ac1079049a8c74fabb8fd7ea8121a216048128d500cf6335b6
6
+ metadata.gz: 4fc4c397ddb16a2f72236b83917cfee8d52632fb297461135c20cd9e0609ba2aa88966ad420e346c0de66f2d9477151d2d5459dfbceac4f51c57437d32d35b98
7
+ data.tar.gz: 6466ea4ce128111442b8861af45878638b20ab5c01ca884b235da9a71dc933b1e5ca492685068894c6da4942fd451a3cf1540a7f1176df3d64f4ba2ea2ad60b1
data/CHANGES.md CHANGED
@@ -1,3 +1,7 @@
1
+ ## 1.3.1 (2018-06-05)
2
+
3
+ * Dependency upgrades. Notably ruby 2.5 in the docker release, and aws-sdk v3
4
+
1
5
  ## 1.3.0 (2018-05-22)
2
6
 
3
7
  * Fix #53: Add support for CloudFormation Service Role
data/README.md CHANGED
@@ -22,6 +22,7 @@ AWS CloudFormation stacks.
22
22
  - [Programmatic usage](#programmatic-usage)
23
23
  - [Rake integration](#rake-integration)
24
24
  - [Docker image](#docker-image)
25
+ - [Releasing](#releasing)
25
26
 
26
27
  <!-- /TOC -->
27
28
 
@@ -68,6 +69,9 @@ This will:
68
69
  * update (or create) the named CloudFormation stack, using the specified template
69
70
  * monitor events until the stack update is complete
70
71
 
72
+ Requests will retry 3 times by default. After this limit is exceeded, `ERROR: Rate exceeded` failures will be logged.
73
+ You can increase the limit using the `--retry-limit` option, or by setting the `$AWS_RETRY_LIMIT` environment variable.
74
+
71
75
  For more details on usage, see
72
76
 
73
77
  $ stackup STACK up --help
@@ -125,7 +129,7 @@ You can also use the `--with-role` option to temporarily assume a different IAM
125
129
  $ stackup myapp-test up -t template.json \
126
130
  --with-role arn:aws:iam::862905684840:role/deployment
127
131
 
128
- You can use the `--sercvice-role-arn` option to pass a specific IAM service role for CloudFormation to use for stack
132
+ You can use the `--service-role-arn` option to pass a specific IAM service role for CloudFormation to use for stack
129
133
  operations:
130
134
 
131
135
  $ stackup myapp-test up -t template.json \
@@ -254,3 +258,19 @@ This policy grants the principal all actions required by `stackup up` for any cl
254
258
  ]
255
259
  }
256
260
  ```
261
+
262
+ ## Releasing
263
+
264
+ The release process will push tags to GitHub, push the gem to rubygems and push the docker image to DockerHub.
265
+
266
+ Prerequisites:
267
+
268
+ * logged into dockerhub via `docker login`. Your user must have permission to push to `realestate/stackup`
269
+ * logged into rubygems via `gem push`. Your user must have permission to push to the `stackup` gem.
270
+
271
+ To release:
272
+
273
+ ```
274
+ bundle install
275
+ auto/release
276
+ ```
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- $LOAD_PATH << File.expand_path("../../lib", __FILE__)
3
+ $LOAD_PATH << File.expand_path("../lib", __dir__)
4
4
 
5
5
  require "clamp"
6
6
  require "console_logger"
@@ -25,25 +25,23 @@ Clamp do
25
25
  option ["-Y", "--yaml"], :flag, "output data in YAML format"
26
26
 
27
27
  option ["--region"], "REGION", "set region" do |arg|
28
- unless arg =~ /^[a-z]{2}-[a-z]+-\d$/
29
- fail ArgumentError, "#{arg.inspect} doesn't look like a region"
30
- end
28
+ raise ArgumentError, "#{arg.inspect} doesn't look like a region" unless arg =~ /^[a-z]{2}-[a-z]+-\d$/
31
29
  arg
32
30
  end
33
31
 
34
32
  option ["--with-role"], "ROLE_ARN", "assume this role",
35
- :attribute_name => :role_arn
33
+ :attribute_name => :role_arn
36
34
 
37
35
  option ["--retry-limit"], "N", "maximum number of retries for API calls",
38
- :environment_variable => "AWS_API_RETRY_LIMIT" do |arg|
36
+ :environment_variable => "AWS_API_RETRY_LIMIT" do |arg|
39
37
  Integer(arg)
40
38
  end
41
39
 
42
40
  option ["--[no-]wait"], :flag, "wait for stack updates to complete",
43
- :default => true
41
+ :default => true
44
42
 
45
43
  option ["--wait-poll-interval"], "N", "polling interval while waiting for updates",
46
- :default => 5, &method(:Integer)
44
+ :default => 5, &method(:Integer)
47
45
 
48
46
  option "--debug", :flag, "enable debugging"
49
47
 
@@ -85,9 +83,7 @@ Clamp do
85
83
  end
86
84
 
87
85
  def role_arn=(arg)
88
- unless arg =~ %r{^arn:aws:iam::\d+:role/}
89
- fail ArgumentError, "#{arg.inspect} doesn't look like a role ARN"
90
- end
86
+ raise ArgumentError, "#{arg.inspect} doesn't look like a role ARN" unless arg =~ %r{^arn:aws:iam::\d+:role/}
91
87
  @role_arn = arg
92
88
  end
93
89
 
@@ -157,9 +153,9 @@ Clamp do
157
153
  end
158
154
 
159
155
  def parameters_from_files
160
- parameter_sources.map { |src|
156
+ parameter_sources.map do |src|
161
157
  Stackup::Parameters.new(src.data).to_hash
162
- }.inject({}, :merge)
158
+ end.inject({}, :merge)
163
159
  end
164
160
 
165
161
  def parameter_overrides
@@ -193,9 +189,7 @@ Clamp do
193
189
  &Stackup::Source.method(:new)
194
190
 
195
191
  option "--service-role-arn", "SERVICE_ROLE_ARN", "cloudformation service role ARN" do |arg|
196
- unless arg =~ %r{^arn:aws:iam::\d+:role/}
197
- fail ArgumentError, "#{arg.inspect} doesn't look like a role ARN"
198
- end
192
+ raise ArgumentError, "#{arg.inspect} doesn't look like a role ARN" unless arg =~ %r{^arn:aws:iam::\d+:role/}
199
193
  arg
200
194
  end
201
195
 
@@ -20,8 +20,10 @@ module Stackup
20
20
 
21
21
  end
22
22
 
23
- # rubocop:disable Style/MethodName
23
+ # rubocop:disable Naming/MethodName
24
24
 
25
25
  def Stackup(*args)
26
26
  Stackup.service(*args)
27
27
  end
28
+
29
+ # rubocop:enable Naming/MethodName
@@ -56,15 +56,9 @@ module Stackup
56
56
  options[:change_set_name] = name
57
57
  options[:change_set_type] = stack.exists? ? "UPDATE" : "CREATE"
58
58
  force = options.delete(:force)
59
- if (template_data = options.delete(:template))
60
- options[:template_body] = MultiJson.dump(template_data)
61
- end
62
- if (parameters = options[:parameters])
63
- options[:parameters] = Parameters.new(parameters).to_a
64
- end
65
- if (tags = options[:tags])
66
- options[:tags] = normalize_tags(tags)
67
- end
59
+ options[:template_body] = MultiJson.dump(options.delete(:template)) if options[:template]
60
+ options[:parameters] = Parameters.new(options[:parameters]).to_a if options[:parameters]
61
+ options[:tags] = normalize_tags(options[:tags]) if options[:tags]
68
62
  options[:capabilities] ||= ["CAPABILITY_NAMED_IAM"]
69
63
  delete if force
70
64
  handling_cf_errors do
@@ -77,7 +71,7 @@ module Stackup
77
71
  return current.status
78
72
  when "FAILED"
79
73
  logger.error(current.status_reason)
80
- fail StackUpdateError, "change-set creation failed" if status == "FAILED"
74
+ raise StackUpdateError, "change-set creation failed" if status == "FAILED"
81
75
  end
82
76
  sleep(wait_poll_interval)
83
77
  end
@@ -13,7 +13,7 @@ module Stackup
13
13
  #
14
14
  def handling_cf_errors
15
15
  yield
16
- rescue Aws::CloudFormation::Errors::ChangeSetNotFound => e
16
+ rescue Aws::CloudFormation::Errors::ChangeSetNotFound => _e
17
17
  raise NoSuchChangeSet, "no such change-set"
18
18
  rescue Aws::CloudFormation::Errors::ValidationError => e
19
19
  case e.message
@@ -55,15 +55,10 @@ module Stackup
55
55
 
56
56
  def initialize(attributes)
57
57
  attributes.each do |name, value|
58
- if name.respond_to?(:gsub)
59
- name = name.gsub(/([a-z])([A-Z])/, '\1_\2').downcase
60
- end
58
+ name = name.gsub(/([a-z])([A-Z])/, '\1_\2').downcase if name.respond_to?(:gsub)
61
59
  writer = "#{name}="
62
- if respond_to?(writer)
63
- public_send(writer, value)
64
- else
65
- raise ArgumentError, "invalid attribute: #{name.inspect}"
66
- end
60
+ raise(ArgumentError, "invalid attribute: #{name.inspect}") unless respond_to?(writer)
61
+ public_send(writer, value)
67
62
  end
68
63
  end
69
64
 
@@ -71,7 +66,7 @@ module Stackup
71
66
  attr_accessor :parameter_value
72
67
  attr_accessor :use_previous_value
73
68
 
74
- alias_method :key, :parameter_key
69
+ alias key parameter_key
75
70
 
76
71
  def value
77
72
  if use_previous_value
@@ -14,20 +14,20 @@ module Stackup
14
14
  attr_accessor :parameters
15
15
  attr_accessor :tags
16
16
 
17
- alias_method :namespace=, :name=
17
+ alias namespace= name=
18
18
 
19
19
  def initialize(name, template = nil)
20
20
  @name = name
21
21
  @stack = name
22
22
  @template = template
23
23
  yield self if block_given?
24
- fail ArgumentError, "no name provided" unless @name
25
- fail ArgumentError, "no template provided" unless @template
24
+ raise ArgumentError, "no name provided" unless @name
25
+ raise ArgumentError, "no template provided" unless @template
26
26
  define
27
27
  end
28
28
 
29
29
  # path to the "stackup" executable
30
- STACKUP_CLI = File.expand_path("../../../bin/stackup", __FILE__)
30
+ STACKUP_CLI = File.expand_path("../../bin/stackup", __dir__)
31
31
 
32
32
  def stackup(*rest)
33
33
  sh STACKUP_CLI, "-Y", stack, *rest
@@ -16,7 +16,7 @@ module Stackup
16
16
 
17
17
  def s3?
18
18
  uri.scheme == "https" &&
19
- uri.host =~ %r{(^|\.)s3(-\w+-\w+-\d)?\.amazonaws\.com$}
19
+ uri.host =~ /(^|\.)s3(-\w+-\w+-\d)?\.amazonaws\.com$/
20
20
  end
21
21
 
22
22
  def body
@@ -40,7 +40,7 @@ module Stackup
40
40
  #
41
41
  def on_event(event_handler = nil, &block)
42
42
  event_handler ||= block
43
- fail ArgumentError, "no event_handler provided" if event_handler.nil?
43
+ raise ArgumentError, "no event_handler provided" if event_handler.nil?
44
44
  @event_handler = event_handler
45
45
  end
46
46
 
@@ -135,9 +135,9 @@ module Stackup
135
135
  create(options)
136
136
  end
137
137
 
138
- alias_method :up, :create_or_update
138
+ alias up create_or_update
139
139
 
140
- ALMOST_DEAD_STATUSES = %w(CREATE_FAILED ROLLBACK_COMPLETE)
140
+ ALMOST_DEAD_STATUSES = %w[CREATE_FAILED ROLLBACK_COMPLETE].freeze
141
141
 
142
142
  # Delete the stack.
143
143
  #
@@ -159,7 +159,7 @@ module Stackup
159
159
  @stack_id = nil
160
160
  end
161
161
 
162
- alias_method :down, :delete
162
+ alias down delete
163
163
 
164
164
  # Cancel update in-progress.
165
165
  #
@@ -321,7 +321,7 @@ module Stackup
321
321
  def modify_stack(target_status, failure_message, &block)
322
322
  if wait?
323
323
  status = modify_stack_synchronously(&block)
324
- fail StackUpdateError, failure_message unless target_status === status
324
+ raise StackUpdateError, failure_message unless target_status === status
325
325
  status
326
326
  else
327
327
  modify_stack_asynchronously(&block)
@@ -355,7 +355,7 @@ module Stackup
355
355
  handling_cf_errors do
356
356
  yield
357
357
  end
358
- self.status
358
+ status
359
359
  end
360
360
 
361
361
  def normalize_tags(tags)
@@ -14,10 +14,11 @@ module Stackup
14
14
 
15
15
  attr_accessor :stack
16
16
 
17
+ # rubocop:disable Lint/HandleExceptions
18
+
17
19
  # Yield all events since the last call
18
20
  #
19
21
  def each_new_event
20
- # rubocop:disable Lint/HandleExceptions
21
22
  new_events = []
22
23
  stack.events.each do |event|
23
24
  break if event.id == @last_processed_event_id
@@ -27,19 +28,20 @@ module Stackup
27
28
  yield event
28
29
  @last_processed_event_id = event.id
29
30
  end
30
- rescue Aws::CloudFormation::Errors::ValidationError
31
+ rescue Aws::CloudFormation::Errors::ValidationError => _e
31
32
  end
32
33
 
33
34
  # Consume all new events
34
35
  #
35
36
  def zero
36
- # rubocop:disable Lint/HandleExceptions
37
37
  last_event = stack.events.first
38
38
  @last_processed_event_id = last_event.id unless last_event.nil?
39
39
  nil
40
40
  rescue Aws::CloudFormation::Errors::ValidationError
41
41
  end
42
42
 
43
+ # rubocop:enable Lint/HandleExceptions
44
+
43
45
  private
44
46
 
45
47
  attr_accessor :processed_event_ids
@@ -7,10 +7,10 @@ module Stackup
7
7
  def normalize_data(data)
8
8
  case data
9
9
  when Hash
10
- pairs = data.sort.map { |k,v| [k, normalize_data(v)] }
10
+ pairs = data.sort.map { |k, v| [k, normalize_data(v)] }
11
11
  Hash[pairs]
12
12
  when Array
13
- pairs = data.map { |x| normalize_data(x) }
13
+ data.map { |x| normalize_data(x) }
14
14
  else
15
15
  data
16
16
  end
@@ -1,5 +1,5 @@
1
1
  module Stackup
2
2
 
3
- VERSION = "1.3.0"
3
+ VERSION = "1.3.1".freeze
4
4
 
5
5
  end
@@ -32,7 +32,7 @@ module Stackup
32
32
  # Supports CloudFormation extensions as per `load`.
33
33
  #
34
34
  def load_file(filename)
35
- File.open(filename, 'r:bom|utf-8') do |f|
35
+ File.open(filename, "r:bom|utf-8") do |f|
36
36
  load(f, filename)
37
37
  end
38
38
  end
@@ -44,7 +44,9 @@ module Stackup
44
44
  class CloudFormationToRuby < Psych::Visitors::ToRuby
45
45
 
46
46
  class << self
47
- alias_method :create, :new unless method_defined?(:create)
47
+
48
+ alias create new unless method_defined?(:create)
49
+
48
50
  end
49
51
 
50
52
  def accept(target)
@@ -56,7 +58,7 @@ module Stackup
56
58
  when "!GetAZs"
57
59
  { "Fn::GetAZs" => (super || "") }
58
60
  when /^!(\w+)$/
59
- { "Fn::#{$1}" => super }
61
+ { "Fn::#{Regexp.last_match(1)}" => super }
60
62
  else
61
63
  super
62
64
  end
@@ -143,7 +143,7 @@ describe Stackup::Parameters do
143
143
  end
144
144
 
145
145
  end
146
-
146
+
147
147
  context "with empty parameter file" do
148
148
 
149
149
  let(:input_records) { false }
@@ -6,7 +6,7 @@ require "stackup/yaml"
6
6
 
7
7
  describe Stackup::Source do
8
8
 
9
- let(:example_dir) { File.expand_path("../../../examples", __FILE__) }
9
+ let(:example_dir) { File.expand_path("../../examples", __dir__) }
10
10
 
11
11
  context "from a JSON file" do
12
12
 
@@ -69,7 +69,7 @@ describe Stackup::Source do
69
69
  describe "#body" do
70
70
 
71
71
  it "raises a ReadError" do
72
- expect { subject.body }.to raise_error(Stackup::Source::ReadError, %q(no such file: "notreallythere.json"))
72
+ expect { subject.body }.to raise_error(Stackup::Source::ReadError, 'no such file: "notreallythere.json"')
73
73
  end
74
74
 
75
75
  end
@@ -530,11 +530,11 @@ describe Stackup::Stack do
530
530
 
531
531
  it "calls :list_change_sets" do
532
532
  cf_client.stub_responses(:list_change_sets, :summaries => [
533
- { :change_set_name => "take1" },
534
- { :change_set_name => "take2" },
535
- ])
533
+ { :change_set_name => "take1" },
534
+ { :change_set_name => "take2" }
535
+ ])
536
536
  summaries = stack.change_set_summaries
537
- expect(summaries.map(&:change_set_name)).to eql(%w(take1 take2))
537
+ expect(summaries.map(&:change_set_name)).to eql(%w[take1 take2])
538
538
  expect(cf_client).to have_received(:list_change_sets)
539
539
  .with(:stack_name => stack_name)
540
540
  end
@@ -634,7 +634,7 @@ describe Stackup::Stack do
634
634
 
635
635
  end
636
636
 
637
- %w(CREATE_FAILED ROLLBACK_COMPLETE).each do |initial_status|
637
+ %w[CREATE_FAILED ROLLBACK_COMPLETE].each do |initial_status|
638
638
  context "when status is #{initial_status}" do
639
639
 
640
640
  let(:stack_status) { initial_status }
@@ -46,7 +46,7 @@ describe Stackup::StackWatcher do
46
46
 
47
47
  before do
48
48
  allow(stack).to receive(:events) do
49
- fail Aws::CloudFormation::Errors::ValidationError.new("test", "no such stack")
49
+ raise Aws::CloudFormation::Errors::ValidationError.new("test", "no such stack")
50
50
  end
51
51
  end
52
52
 
@@ -183,7 +183,7 @@ describe Stackup::YAML do
183
183
  expect(data).to eql(
184
184
  "Stuff" => [
185
185
  {
186
- "Fn::FindInMap" => ["RegionMap", {"Ref"=>"AWS::Region"}, "AMI"]
186
+ "Fn::FindInMap" => ["RegionMap", { "Ref" => "AWS::Region" }, "AMI"]
187
187
  },
188
188
  {
189
189
  "Fn::If" => ["CreateProdResources", "c1.xlarge", "m1.small"]
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: stackup
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.0
4
+ version: 1.3.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mike Williams
@@ -9,36 +9,50 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2018-05-22 00:00:00.000000000 Z
12
+ date: 2018-06-05 00:00:00.000000000 Z
13
13
  dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: aws-sdk-core
16
+ requirement: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - "~>"
19
+ - !ruby/object:Gem::Version
20
+ version: '3.0'
21
+ type: :runtime
22
+ prerelease: false
23
+ version_requirements: !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - "~>"
26
+ - !ruby/object:Gem::Version
27
+ version: '3.0'
14
28
  - !ruby/object:Gem::Dependency
15
29
  name: aws-sdk-resources
16
30
  requirement: !ruby/object:Gem::Requirement
17
31
  requirements:
18
32
  - - "~>"
19
33
  - !ruby/object:Gem::Version
20
- version: '2.0'
34
+ version: '3.0'
21
35
  type: :runtime
22
36
  prerelease: false
23
37
  version_requirements: !ruby/object:Gem::Requirement
24
38
  requirements:
25
39
  - - "~>"
26
40
  - !ruby/object:Gem::Version
27
- version: '2.0'
41
+ version: '3.0'
28
42
  - !ruby/object:Gem::Dependency
29
43
  name: clamp
30
44
  requirement: !ruby/object:Gem::Requirement
31
45
  requirements:
32
46
  - - "~>"
33
47
  - !ruby/object:Gem::Version
34
- version: '1.0'
48
+ version: '1.2'
35
49
  type: :runtime
36
50
  prerelease: false
37
51
  version_requirements: !ruby/object:Gem::Requirement
38
52
  requirements:
39
53
  - - "~>"
40
54
  - !ruby/object:Gem::Version
41
- version: '1.0'
55
+ version: '1.2'
42
56
  - !ruby/object:Gem::Dependency
43
57
  name: console_logger
44
58
  requirement: !ruby/object:Gem::Requirement
@@ -59,14 +73,14 @@ dependencies:
59
73
  requirements:
60
74
  - - "~>"
61
75
  - !ruby/object:Gem::Version
62
- version: '3.0'
76
+ version: '3.2'
63
77
  type: :runtime
64
78
  prerelease: false
65
79
  version_requirements: !ruby/object:Gem::Requirement
66
80
  requirements:
67
81
  - - "~>"
68
82
  - !ruby/object:Gem::Version
69
- version: '3.0'
83
+ version: '3.2'
70
84
  - !ruby/object:Gem::Dependency
71
85
  name: multi_json
72
86
  requirement: !ruby/object:Gem::Requirement
@@ -134,7 +148,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
134
148
  version: '0'
135
149
  requirements: []
136
150
  rubyforge_project:
137
- rubygems_version: 2.7.6
151
+ rubygems_version: 2.6.14.1
138
152
  signing_key:
139
153
  specification_version: 4
140
154
  summary: Manage CloudFormation stacks