cfncli 0.3.2 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
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