cfncli 0.3.2 → 0.4.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,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- OTY0N2JmZDcxYzkxMGZkNjhlOThlMzgxOTgyMzczYWNiZGQzNDgyZA==
4
+ YjNiNjlmM2JmYzE1YTY1MWE5MjYyNjQ4MDcwZWNkNDFjNzM0MGVjNA==
5
5
  data.tar.gz: !binary |-
6
- YjZiNDFiMDY4MWVhNWQ4NDEyN2FhZmViYWIzZjljZTI0YTBiZTJlNQ==
6
+ MzVhNzQ1MzExYjZjOTJlNTgyZjczZDliMTUxZjdjOTQyMTVhYzY2ZA==
7
7
  SHA512:
8
8
  metadata.gz: !binary |-
9
- NjExNTMyNWQ3YzhiYjk2NTNhZDg3MWEwNTRmMTYwNDA0ZjY3OTFjNGEzMTNm
10
- YzI3ZDRiZTE5NGRhNWY0ZTA2Yjg4OTFiNjg4OGQ0NmJlNGU0OWY0NmNlZDMz
11
- YWFlZDRhMWE4YWM5Njk1MzUzNjhmNDVjYTE2M2IyODIwZWRiYzA=
9
+ ZjRlZDA3YzA3MmY5ZWUyOGE5ZTRhNjQ3YWNlNTBiNmE0Y2E4MTFiMTc1ZWM4
10
+ Y2VhZGQ5ZDdlYjU4YjJjYjBlMTlhZmNkZmNkOWJhYTMyMzc2N2Y2YTdlYjg1
11
+ NGI5NGRjYjljOGJmMmJiZjkxYTZlNWNkZmYxOGEwZTQyZmQxNjI=
12
12
  data.tar.gz: !binary |-
13
- ZGE0ZTVhZGY0MzQ3MTUyMWNjN2M2OTNhM2Y1NDY3OWE4ZjhhNzE3ODBhOGEz
14
- Mzg4MWI0OThkMTc4Y2JiYWNmMTU5NzdhYTAyNDdjYjU1MzUyODI2YjQzMTdm
15
- ZDcxZWNiY2M2MTM5Mzg4NmVhNmQ1NTJmOTlmN2UzNDBmYzQ2NzE=
13
+ ODRkMGE3ZGI5NGY4MWI1NGJkYTllN2IwMmFmMjNkYWZiZTUwYTQ2ZGIxMDFh
14
+ OTAzZmE5NzEzMDM1MGQxMTViZDYxZjBjNDM0OTQ1NTNiM2QwN2E1NjYzNzI0
15
+ MWE1MWVkZjEyZTcyNjAwYTkxOGIwOGY1NzRlYjYxZjNlNjAzMTI=
data/.travis.yml CHANGED
@@ -1,6 +1,6 @@
1
1
  language: ruby
2
2
  rvm:
3
- - 2.2
3
+ - 2.3.1
4
4
  sudo: false
5
5
  before_install:
6
6
  - gem install bundler -v '~> 1.10'
data/cfncli.gemspec CHANGED
@@ -31,4 +31,5 @@ Gem::Specification.new do |spec|
31
31
  spec.add_dependency "waiting", "~> 0"
32
32
  spec.add_dependency "activesupport", "~> 4"
33
33
  spec.add_dependency "colorize", "~> 0"
34
+ spec.add_dependency "concurrent-ruby", "~> 1.0"
34
35
  end
@@ -43,7 +43,10 @@ module CfnCli
43
43
  logger.debug "Creating stack #{options['stack_name']}"
44
44
  stack = create_or_update_stack(options, config)
45
45
 
46
- events(stack.stack_id, config)
46
+ events(stack, config)
47
+ Waiting.wait(interval: config.interval || default_config.interval, max_attempts: config.retries || default_config.retries) do |waiter|
48
+ waiter.done if stack.finished? && !stack.listing_events?
49
+ end
47
50
  end
48
51
 
49
52
  # List stack events
@@ -85,6 +88,10 @@ module CfnCli
85
88
  end
86
89
  end
87
90
 
91
+ def default_config
92
+ Config::CfnClient.new
93
+ end
94
+
88
95
  private
89
96
 
90
97
  # Creates a new stack object
data/lib/cfncli/event.rb CHANGED
@@ -6,6 +6,9 @@ module CfnCli
6
6
 
7
7
  attr_reader :event
8
8
 
9
+ RESOURCE_CREATE_INITIATED = 'Resource creation Initiated'.freeze
10
+ AWS_STACK_RESOURCE = 'AWS::CloudFormation::Stack'.freeze
11
+
9
12
  def initialize(event)
10
13
  @event = event
11
14
  end
@@ -20,6 +23,14 @@ module CfnCli
20
23
  return :red if failed?
21
24
  end
22
25
 
26
+ # Check if the current event has the signature of a child stack creation
27
+ def child_stack_create_event?
28
+ return false unless in_progress?
29
+ return false unless event.resource_type == AWS_STACK_RESOURCE
30
+ return false unless event.resource_status_reason == RESOURCE_CREATE_INITIATED
31
+ true
32
+ end
33
+
23
34
  def to_s
24
35
  "#{event.timestamp} #{event.resource_status} #{event.resource_type} #{event.logical_resource_id} #{event.resource_status_reason}"
25
36
  end
@@ -1,17 +1,27 @@
1
1
  require 'colorize'
2
2
  require 'cfncli/event'
3
+ require 'thread'
3
4
 
4
5
  module CfnCli
5
6
  class EventPoller
7
+
6
8
  def initialize
9
+ @mutex = Mutex.new
10
+ end
11
+
12
+ def event(event, prefix = nil)
13
+ colorize Event.new(event), prefix
7
14
  end
8
15
 
9
- def event(event)
10
- colorize Event.new(event)
16
+ def colorize(event, prefix = nil)
17
+ @mutex.synchronize do
18
+ puts add_prefix(event.to_s, prefix).colorize(event.color)
19
+ end
11
20
  end
12
21
 
13
- def colorize(event)
14
- puts event.to_s.colorize(event.color)
22
+ def add_prefix(message, prefix = nil)
23
+ message = "#{prefix} - #{message}" unless prefix.nil?
24
+ message
15
25
  end
16
26
  end
17
27
  end
@@ -1,5 +1,7 @@
1
1
  module CfnCli
2
2
  class EventStreamer
3
+ require 'cfncli/config'
4
+
3
5
  attr_reader :stack
4
6
  attr_reader :config
5
7
 
@@ -19,13 +21,14 @@ module CfnCli
19
21
  def each_event(&block)
20
22
  Waiting.wait(interval: config.interval, max_attempts: config.retries) do |waiter|
21
23
  list_events(&block)
22
-
23
24
  waiter.done if stack.finished?
24
25
  end
25
26
  end
26
27
 
27
28
  def list_events(&block)
28
- @next_token = stack.events(@next_token).each do |event|
29
+ events = []
30
+ @next_token = stack.events(@next_token).each { |event| events << event }
31
+ events.sort { |a, b| a.timestamp <=> b.timestamp }.each do |event|
29
32
  yield event unless seen?(event) if block_given?
30
33
  end
31
34
  end
data/lib/cfncli/stack.rb CHANGED
@@ -2,8 +2,10 @@ require 'cfncli/cfn_client'
2
2
  require 'cfncli/logger'
3
3
  require 'cfncli/config'
4
4
  require 'cfncli/event_streamer'
5
+ require 'cfncli/event'
5
6
  require 'cfncli/states'
6
-
7
+ require 'thread'
8
+ require 'concurrent/array'
7
9
  require 'waiting'
8
10
 
9
11
  module CfnCli
@@ -13,6 +15,7 @@ module CfnCli
13
15
  include Loggable
14
16
 
15
17
  attr_reader :stack_name
18
+ attr_reader :child_stacks
16
19
 
17
20
  class StackNotFoundError < StandardError; end
18
21
 
@@ -21,6 +24,7 @@ module CfnCli
21
24
  @stack_id = nil
22
25
  @stack_name = stack_name
23
26
  @config = config || default_config
27
+ @child_stacks = Concurrent::Array.new
24
28
  end
25
29
 
26
30
  def default_config
@@ -88,10 +92,15 @@ module CfnCli
88
92
 
89
93
  # List all events in real time
90
94
  # @param poller [CfnCli::Poller] Poller class to display events
91
- def list_events(poller, streamer = nil, config = nil)
92
- streamer ||= EventStreamer.new(self, config)
93
- streamer.each_event do |event|
94
- poller.event(event)
95
+ def list_events(poller, streamer = nil, config = nil, event_prefix = nil)
96
+ @event_listing_thread = Thread.new do
97
+ streamer ||= EventStreamer.new(self, config)
98
+ streamer.each_event do |event|
99
+ if Event.new(event).child_stack_create_event?
100
+ track_child_stack(event.physical_resource_id, event.logical_resource_id, poller)
101
+ end
102
+ poller.event(event, event_prefix)
103
+ end
95
104
  end
96
105
  end
97
106
 
@@ -100,10 +109,15 @@ module CfnCli
100
109
  stack.events(next_token)
101
110
  end
102
111
 
112
+ # Is this stack currently listing events
113
+ def listing_events?
114
+ !@event_listing_thread.nil? && @event_listing_thread.alive?
115
+ end
116
+
103
117
  # Indicates if the stack is in a finished state
104
118
  def finished?
105
119
  return false if stack.nil?
106
- finished_states.include? stack.stack_status
120
+ finished_states.include?(stack.stack_status)
107
121
  end
108
122
 
109
123
  # Indicates if the stack is in a successful state
@@ -133,5 +147,12 @@ module CfnCli
133
147
  @stack = cfn.stack(stack_id)
134
148
  @stack
135
149
  end
150
+
151
+ def track_child_stack(child_stack_id, logical_id, poller)
152
+ child_stack = Stack.new child_stack_id, @config
153
+ @child_stacks << child_stack
154
+ logger.debug "Listing events for child stack #{stack.stack_name}"
155
+ child_stack.list_events poller, nil, @config, logical_id
156
+ end
136
157
  end
137
158
  end
@@ -1,3 +1,3 @@
1
1
  module CfnCli
2
- VERSION = "0.3.2"
2
+ VERSION = "0.4.0"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cfncli
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.2
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - lethalpaga
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2016-04-14 00:00:00.000000000 Z
11
+ date: 2016-06-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -178,6 +178,20 @@ dependencies:
178
178
  - - ~>
179
179
  - !ruby/object:Gem::Version
180
180
  version: '0'
181
+ - !ruby/object:Gem::Dependency
182
+ name: concurrent-ruby
183
+ requirement: !ruby/object:Gem::Requirement
184
+ requirements:
185
+ - - ~>
186
+ - !ruby/object:Gem::Version
187
+ version: '1.0'
188
+ type: :runtime
189
+ prerelease: false
190
+ version_requirements: !ruby/object:Gem::Requirement
191
+ requirements:
192
+ - - ~>
193
+ - !ruby/object:Gem::Version
194
+ version: '1.0'
181
195
  description: Creates a Cloudformation stack synchronously
182
196
  email:
183
197
  - lethalpaga@gmail.com