stackup 1.3.0 → 1.3.1

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