sfn 2.1.0 → 2.1.2

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
  SHA1:
3
- metadata.gz: 4dc5791789b8e7f511712d9d81e8352f8e4780db
4
- data.tar.gz: e98faf54dde7e50b2677e6cd8eb11cb5f07c55b1
3
+ metadata.gz: ef688f38c0f0be5810c525cd37e77d5a4216756a
4
+ data.tar.gz: 1f3e4f9a893e376b9c7e77fda5f1e495e27df905
5
5
  SHA512:
6
- metadata.gz: e6d304c36c90b3776397d17a940a3e3a8eab174c9492f84151f6f96f2a78b8d176b3db05a204bf08c447603ed39ea5af65a7d4f1ef54ac6230e6c69312967ff7
7
- data.tar.gz: 1d25448614c1252fd5d66644e33d028c9b4eef596347ea7c373758ca0bfebf68dcec906424d83b06083c7253abd8efda1b280e37716531e234065679f80a15af
6
+ metadata.gz: be3015b69f844371bff9588753a0cec1b9ca1dfb05cb957106583e62ed8a5a9b4284b052938ddb53ace50c8f85f0a73a4884b0131c2948a5d49693f41d3a88d7
7
+ data.tar.gz: ae268210135a9b5bbc406a1c7684a5e560f16548b21f2b29bd3c8164c66ffe0668c189f995a4c27f86797047f997c3ef3be12d809135b229f86cf3ac049b9225
@@ -1,3 +1,12 @@
1
+ # v2.1.2
2
+ * [enhancement] Include parameter name on error output when failed to receive (#116)
3
+ * [enhancement] Rescue planner errors and notify user. Allow update to proceed (#124)
4
+ * [feature] Add built-in callback for AWS MFA support (#123)
5
+ * [fix] Compare parameters values on updates as String type (#126)
6
+ * [fix] Remove policy modification on stack delete within AWS (#127)
7
+ * [feature] Support optional stack policy removal prior to update (#127)
8
+ * [feature] Add built-in callback for AWS Assume Role credential caching (#128)
9
+
1
10
  # v2.1.0
2
11
  * [fix] Use SparkleFormation::Collection helper to ensure proper pack ordering (#115)
3
12
  * [fix] Set minimum constraint on sparkle_formation library to 2.1.2
@@ -6,6 +6,10 @@ anchors:
6
6
  url: "#enabling-callbacks"
7
7
  - title: "Builtin Callbacks"
8
8
  url: "#builtin-callbacks"
9
+ - title: "Custom Callbacks"
10
+ url: "#custom-callbacks"
11
+ - title: "Addon Callbacks"
12
+ url: "#addon-callbacks"
9
13
  ---
10
14
 
11
15
  ## Callbacks
@@ -20,7 +24,7 @@ are generally invoked in two places:
20
24
  There are also callbacks available prior to the execution
21
25
  of a command. These can also be isolated to specific commands:
22
26
 
23
- * `before_config` - Prior to the execution of the command.
27
+ * `after_config` - Prior to the execution of the command.
24
28
 
25
29
  ### Enabling Callbacks
26
30
 
@@ -76,8 +80,127 @@ end
76
80
 
77
81
  Builtin callbacks distributed with `sfn`:
78
82
 
83
+ * AWS Assume Role
84
+ * AWS MFA
79
85
  * Stack Policy
80
86
 
87
+ #### AWS Assume Role
88
+
89
+ When assuming a role via STS on AWS a temporary set of credentials and token
90
+ are generated for use. This callback will cache these credentials for re-use
91
+ to prevent re-generation of temporary credentials on every command request.
92
+
93
+ To enable the callback:
94
+
95
+ ~~~ruby
96
+ Configuration.new do
97
+ callbacks do
98
+ default ['aws_assume_role']
99
+ end
100
+ end
101
+ ~~~
102
+
103
+ Once temporary credentials have been generated, the callback will store the credentials
104
+ within a file in the working directory named `.sfn-aws`. This path can be modified via
105
+ configuration:
106
+
107
+ ~~~ruby
108
+ Configuration.new do
109
+ aws_assume_role do
110
+ cache_file '/custom/path/to/file'
111
+ end
112
+ end
113
+ ~~~
114
+
115
+ Loading and storage of credentials will only occur if a role is provided to assume. Given
116
+ a configuration of:
117
+
118
+ ~~~ruby
119
+ Configuration.new do
120
+ callbacks.default 'aws_assume_role'
121
+ credentials do
122
+ aws_sts_role_arn ENV['AWS_STS_ROLE']
123
+ end
124
+ end
125
+ ~~~
126
+
127
+ The callback will be enabled when the environment variable is provided:
128
+
129
+ ~~~
130
+ $ AWS_STS_ROLE="arn:...MY_ROLE" sfn list
131
+ ~~~
132
+
133
+ and will not be enabled when the environment variable is not provided:
134
+
135
+ ~~~
136
+ $ sfn list
137
+ ~~~
138
+
139
+ It can also be disabled/enabled via configuration setting:
140
+
141
+ ~~~ruby
142
+ Configuration.new do
143
+ aws_assume_role.status 'enabled'
144
+ end
145
+ ~~~
146
+
147
+ #### AWS Multifactor Authentication
148
+
149
+ Support for MFA within AWS can be provided using the AWS MFA callback. It will
150
+ prompt for an MFA token code which is then used to generate the new session.
151
+
152
+ To enable the callback:
153
+
154
+ ~~~ruby
155
+ Configuration.new do
156
+ callbacks do
157
+ default ['aws_mfa']
158
+ end
159
+ end
160
+ ~~~
161
+
162
+ The default virtual MFA device ARN will be used when creating the new session. If a
163
+ non-default virutal MFA device or a hardware device is being used, set the device
164
+ serial number with the configuration:
165
+
166
+ ~~~ruby
167
+ Configuration.new do
168
+ credentials do
169
+ provider :aws
170
+ aws_sts_mfa_serial_number 'DEVICE_IDENTIFIER'
171
+ end
172
+ end
173
+ ~~~
174
+
175
+ After a session has been successfully created, the callback will store the session
176
+ token and credentials within a file in the working directory named `.sfn-aws`. This
177
+ path can be configured via configuration:
178
+
179
+ ~~~ruby
180
+ Configuration.new do
181
+ aws_mfa do
182
+ cache_file '/custom/path/to/file'
183
+ end
184
+ end
185
+ ~~~
186
+
187
+ Use of MFA may be conditional based on actions performed. For easier toggling of
188
+ MFA usage, a configuration value can be used to enable or disable MFA:
189
+
190
+ ~~~ruby
191
+ Configuration.new do
192
+ aws_mfa do
193
+ cache_file ENV.fetch('SFN_MFA', 'enabled')
194
+ end
195
+ end
196
+ ~~~
197
+
198
+ With this configuration, MFA usage can be easily disabled:
199
+
200
+ ~~~
201
+ $ SFN_MFA=disabled sfn list
202
+ ~~~
203
+
81
204
  #### Stack Policy Callback
82
205
 
83
206
  The Stack Policy Callback utilizes the [policy feature](http://www.sparkleformation.io/docs/sparkle_formation/stack-policies.html)
@@ -94,6 +217,18 @@ Configuration.new do
94
217
  end
95
218
  ~~~
96
219
 
220
+ By default a stack policy is not disabled when an update command is run. This may
221
+ require multiple update commands to be run first disabling the existing policy, then
222
+ running the actual update. Stack policies can be automatically removed prior to update
223
+ allowing the stack to be properly updated with the newly generated policy applied on
224
+ completion. To disable the stack policy on update, add this to your configuration:
225
+
226
+ ~~~ruby
227
+ Configuration.new do
228
+ stack_policy.update 'defenseless'
229
+ end
230
+ ~~~
231
+
97
232
  ### Custom Callbacks
98
233
 
99
234
  To create a custom callback define a new class within the callback namespace
@@ -156,3 +291,55 @@ Configuration.new do
156
291
  callbacks.after ['custom_callback']
157
292
  end
158
293
  ~~~
294
+
295
+ The sfn command will output a notification to the user before a callback is
296
+ run, and after it has completed. This may be too verbose for some callbacks.
297
+ A callback may disable this output using the `quiet` method:
298
+
299
+ ```ruby
300
+ module Sfn
301
+ class Callback
302
+ class MyCallback < Callback
303
+
304
+ def quiet
305
+ true
306
+ end
307
+
308
+ end
309
+ end
310
+ end
311
+ ```
312
+
313
+ ### Addon Callbacks
314
+
315
+ #### Usage
316
+
317
+ Addon callbacks must be installed to the local bundle, or the system depending
318
+ on usage type.
319
+
320
+ For bundle usage, add the callback to the Gemfile:
321
+
322
+ ~~~ruby
323
+ gem 'sfn-callback-name'
324
+ ~~~
325
+
326
+ For system usage, install the gem:
327
+
328
+ ~~~
329
+ $ gem install sfn-callback-name
330
+ ~~~
331
+
332
+ #### Callbacks
333
+
334
+ ##### sfn-parameters
335
+
336
+ Manage stack parameters via files within the project repository.
337
+
338
+ * https://github.com/sparkleformation/sfn-parameters
339
+
340
+ ##### sfn-serverspec
341
+
342
+ Define Serverspec rules directly on resources within templates
343
+ and automatically run after success stack creation or update.
344
+
345
+ * https://github.com/sparkleformation/sfn-serverspec
@@ -4,6 +4,8 @@ module Sfn
4
4
  # Interface for injecting custom functionality
5
5
  class Callback
6
6
 
7
+ autoload :AwsAssumeRole, 'sfn/callback/aws_assume_role'
8
+ autoload :AwsMfa, 'sfn/callback/aws_mfa'
7
9
  autoload :StackPolicy, 'sfn/callback/stack_policy'
8
10
 
9
11
  # @return [Bogo::Ui]
@@ -0,0 +1,93 @@
1
+ require 'sfn'
2
+
3
+ module Sfn
4
+ class Callback
5
+ # Support for AWS STS role credential caching
6
+ class AwsAssumeRole < Callback
7
+
8
+ # Items to cache in local file
9
+ STS_STORE_ITEMS = [
10
+ :aws_sts_token,
11
+ :aws_sts_access_key_id,
12
+ :aws_sts_secret_access_key,
13
+ :aws_sts_token_expires
14
+ ]
15
+
16
+ # Prevent callback output to user
17
+ def quiet
18
+ true
19
+ end
20
+
21
+ # Inject STS related configuration into
22
+ # API provider credentials
23
+ def after_config(*_)
24
+ if(enabled? && config.fetch(:credentials, :aws_sts_role_arn))
25
+ load_stored_session
26
+ end
27
+ end
28
+
29
+ # Store session token if available for
30
+ # later use
31
+ def after(*_)
32
+ if(enabled?)
33
+ if(api.connection.aws_sts_role_arn && api.connection.aws_sts_token)
34
+ path = config.fetch(:aws_assume_role, :cache_file, '.sfn-aws')
35
+ FileUtils.touch(path)
36
+ File.chmod(0600, path)
37
+ values = load_stored_values(path)
38
+ STS_STORE_ITEMS.map do |key|
39
+ values[key] = api.connection.data[key]
40
+ end
41
+ File.open(path, 'w') do |file|
42
+ file.puts MultiJson.dump(values)
43
+ end
44
+ end
45
+ end
46
+ end
47
+
48
+ # @return [TrueClass, FalseClass]
49
+ def enabled?
50
+ config.fetch(:aws_assume_role, :status, 'enabled').to_s == 'enabled'
51
+ end
52
+
53
+ # Load stored configuration data into the api connection
54
+ #
55
+ # @return [TrueClass, FalseClass]
56
+ def load_stored_session
57
+ path = config.fetch(:aws_assume_role, :cache_file, '.sfn-aws')
58
+ if(File.exists?(path))
59
+ values = load_stored_values(path)
60
+ STS_STORE_ITEMS.each do |key|
61
+ api.connection.data[key] = values[key]
62
+ end
63
+ if(values[:aws_sts_token_expires])
64
+ begin
65
+ api.connection.data[:aws_sts_token_expires] = Time.parse(values[:aws_sts_token_expires])
66
+ rescue
67
+ end
68
+ end
69
+ true
70
+ else
71
+ false
72
+ end
73
+ end
74
+
75
+ # Load stored values
76
+ #
77
+ # @param path [String]
78
+ # @return [Hash]
79
+ def load_stored_values(path)
80
+ begin
81
+ if(File.exists?(path))
82
+ MultiJson.load(File.read(path)).to_smash
83
+ else
84
+ Smash.new
85
+ end
86
+ rescue MultiJson::ParseError
87
+ Smash.new
88
+ end
89
+ end
90
+
91
+ end
92
+ end
93
+ end
@@ -0,0 +1,102 @@
1
+ require 'sfn'
2
+
3
+ module Sfn
4
+ class Callback
5
+ # Support for AWS MFA
6
+ class AwsMfa < Callback
7
+
8
+ # Items to cache in local file
9
+ SESSION_STORE_ITEMS = [
10
+ :aws_sts_session_token,
11
+ :aws_sts_session_access_key_id,
12
+ :aws_sts_session_secret_access_key,
13
+ :aws_sts_session_token_expires
14
+ ]
15
+
16
+ # Prevent callback output to user
17
+ def quiet
18
+ true
19
+ end
20
+
21
+ # Inject MFA related configuration into
22
+ # API provider credentials
23
+ def after_config(*_)
24
+ if(enabled?)
25
+ load_stored_session
26
+ api.connection.aws_sts_session_token_code = method(:prompt_for_code)
27
+ end
28
+ end
29
+
30
+ # Store session token if available for
31
+ # later use
32
+ def after(*_)
33
+ if(enabled?)
34
+ if(api.connection.aws_sts_session_token)
35
+ path = config.fetch(:aws_mfa, :cache_file, '.sfn-aws')
36
+ FileUtils.touch(path)
37
+ File.chmod(0600, path)
38
+ values = load_stored_values(path)
39
+ SESSION_STORE_ITEMS.map do |key|
40
+ values[key] = api.connection.data[key]
41
+ end
42
+ File.open(path, 'w') do |file|
43
+ file.puts MultiJson.dump(values)
44
+ end
45
+ end
46
+ end
47
+ end
48
+
49
+ # @return [TrueClass, FalseClass]
50
+ def enabled?
51
+ config.fetch(:aws_mfa, :status, 'enabled').to_s == 'enabled'
52
+ end
53
+
54
+ # Load stored configuration data into the api connection
55
+ #
56
+ # @return [TrueClass, FalseClass]
57
+ def load_stored_session
58
+ path = config.fetch(:aws_mfa, :cache_file, '.sfn-aws')
59
+ if(File.exists?(path))
60
+ values = load_stored_values(path)
61
+ SESSION_STORE_ITEMS.each do |key|
62
+ api.connection.data[key] = values[key]
63
+ end
64
+ if(values[:aws_sts_session_token_expires])
65
+ begin
66
+ api.connection.data[:aws_sts_session_token_expires] = Time.parse(values[:aws_sts_session_token_expires])
67
+ rescue
68
+ end
69
+ end
70
+ true
71
+ else
72
+ false
73
+ end
74
+ end
75
+
76
+ # Load stored values
77
+ #
78
+ # @param path [String]
79
+ # @return [Hash]
80
+ def load_stored_values(path)
81
+ begin
82
+ if(File.exists?(path))
83
+ MultiJson.load(File.read(path)).to_smash
84
+ else
85
+ Smash.new
86
+ end
87
+ rescue MultiJson::ParseError
88
+ Smash.new
89
+ end
90
+ end
91
+
92
+ # Request MFA code from user
93
+ #
94
+ # @return [String]
95
+ def prompt_for_code
96
+ result = ui.ask 'AWS MFA code', :valid => /^\d{6}$/
97
+ result.strip
98
+ end
99
+
100
+ end
101
+ end
102
+ end
@@ -41,18 +41,20 @@ module Sfn
41
41
  alias_method :after_create, :submit_policy
42
42
  alias_method :after_update, :submit_policy
43
43
 
44
- # Update all policies to allow resource destruction
45
- def before_destroy(args)
46
- ui.warn 'All policies will be disabled for stack destruction!'
47
- ui.confirm 'Continue with stack destruction'
48
- stack = args[:api_stack]
49
- ([stack] + stack.nested_stacks).compact.each do |p_stack|
50
- @policies[p_stack.name] = DEFENSELESS_POLICY
51
- run_action "Disabling stack policy for #{ui.color(p_stack.name, :yellow)}" do
52
- save_stack_policy(p_stack)
44
+ # Disable all existing policies prior to update
45
+ #
46
+ # @param args [Hash]
47
+ def before_update(args)
48
+ if(config.get(:stack_policy, :update).to_s == 'defenseless')
49
+ ui.warn 'Disabling all stack policies for update.'
50
+ stack = args[:api_stack]
51
+ ([stack] + stack.nested_stacks).compact.each do |p_stack|
52
+ @policies[p_stack.name] = DEFENSELESS_POLICY
53
+ run_action "Disabling stack policy for #{ui.color(p_stack.name, :yellow)}" do
54
+ save_stack_policy(p_stack)
55
+ end
53
56
  end
54
57
  end
55
- ui.warn "Policy modification for deletion not currently enabled!"
56
58
  end
57
59
 
58
60
  # Generate stack policy for stack and cache for the after hook
@@ -15,7 +15,7 @@ module Sfn
15
15
  stack = provider.connection.stacks.get(stack_name)
16
16
  ui.info "Stack inspection #{ui.color(stack_name, :bold)}:"
17
17
  outputs = api_action!(:api_stack => stack) do
18
- [:attribute, :nodes, :instance_failure].map do |key|
18
+ [:attribute, :nodes, :load_balancers, :instance_failure].map do |key|
19
19
  if(config.has_key?(key))
20
20
  send("display_#{key}", stack)
21
21
  key
@@ -160,6 +160,30 @@ module Sfn
160
160
  end
161
161
  end
162
162
 
163
+ def display_load_balancers(stack)
164
+ load_balancers = Smash[
165
+ stack.resources.all.find_all do |resource|
166
+ resource.within?(:load_balancer, :balancers)
167
+ end.map do |lb|
168
+ exp_lb = lb.expand
169
+ lb_pub_addrs = exp_lb.public_addresses.nil? ? nil : exp_lb.public_addresses.map(&:address)
170
+ lb_priv_addrs = exp_lb.private_addresses.nil? ? nil : exp_lb.private_addresses.map(&:address)
171
+ [lb.id, Smash.new(
172
+ :name => exp_lb.name,
173
+ :state => exp_lb.state,
174
+ :public_addresses => lb_pub_addrs,
175
+ :private_addresses => lb_priv_addrs,
176
+ :server_states => exp_lb.server_states
177
+ ).delete_if {|k,v| v.nil?}
178
+ ]
179
+ end
180
+ ]
181
+ unless load_balancers.empty?
182
+ ui.info ' Load Balancer Instances:'
183
+ ui.puts MultiJson.dump(load_balancers, :pretty => true)
184
+ end
185
+ end
186
+
163
187
  end
164
188
  end
165
189
  end
@@ -11,7 +11,7 @@ module Sfn
11
11
  def execute!
12
12
  ui.table(self) do
13
13
  table(:border => false) do
14
- stacks = get_stacks
14
+ stacks = api_action!{ get_stacks }
15
15
  row(:header => true) do
16
16
 
17
17
  allowed_attributes.each do |attr|
@@ -87,12 +87,18 @@ module Sfn
87
87
  update_template = stack.template
88
88
 
89
89
  if(config[:plan])
90
- stack.template = original_template
91
- stack.parameters = original_parameters
92
- plan = build_planner(stack)
93
- if(plan)
94
- result = plan.generate_plan(file, config_root_parameters)
95
- display_plan_information(result)
90
+ begin
91
+ stack.template = original_template
92
+ stack.parameters = original_parameters
93
+ plan = build_planner(stack)
94
+ if(plan)
95
+ result = plan.generate_plan(file, config_root_parameters)
96
+ display_plan_information(result)
97
+ end
98
+ rescue => e
99
+ ui.error "Unexpected error when generating plan information: #{e.class} - #{e}"
100
+ ui.debug "#{e.class}: #{e}\n#{e.backtrace.join("\n")}"
101
+ ui.confirm 'Continue with stack update?'
96
102
  end
97
103
  end
98
104
 
@@ -31,14 +31,14 @@ module Sfn
31
31
  clbks = types.map do |c_type|
32
32
  callbacks_for(c_type)
33
33
  end.flatten(1).compact.uniq.each do |item|
34
- callback_name, callback = item
35
- ui.info "Callback #{ui.color(type.to_s, :bold)} #{callback_name}: #{ui.color('starting', :yellow)}"
34
+ callback_name, callback, quiet = item
35
+ ui.info "Callback #{ui.color(type.to_s, :bold)} #{callback_name}: #{ui.color('starting', :yellow)}" unless quiet
36
36
  if(args.empty?)
37
37
  callback.call
38
38
  else
39
39
  callback.call(*args)
40
40
  end
41
- ui.info "Callback #{ui.color(type.to_s, :bold)} #{callback_name}: #{ui.color('complete', :green)}"
41
+ ui.info "Callback #{ui.color(type.to_s, :bold)} #{callback_name}: #{ui.color('complete', :green)}" unless quiet
42
42
  end
43
43
  nil
44
44
  end
@@ -59,7 +59,7 @@ module Sfn
59
59
  end
60
60
  end
61
61
  if(instance.respond_to?(type))
62
- [c_name, instance.method(type)]
62
+ [c_name, instance.method(type), instance.respond_to?(:quiet) ? instance.quiet : false]
63
63
  end
64
64
  end.compact
65
65
  end
@@ -257,7 +257,7 @@ module Sfn
257
257
  else
258
258
  current_value = c_value
259
259
  end
260
- if(current_value && current_value != stack_value)
260
+ if(current_value && current_value.to_s != stack_value.to_s)
261
261
  ui.warn 'Nested stack has been altered directly! This update may cause unexpected modifications!'
262
262
  ui.warn "Stack name: #{c_stack.name}. Parameter: #{p_key}. Current value: #{stack_value}. Expected value: #{current_value} (via: #{c_value.inspect})"
263
263
  answer = ui.ask_question("Use current value or expected value for #{p_key} [current/expected]?", :valid => ['current', 'expected'])
@@ -67,7 +67,7 @@ module Sfn
67
67
  end
68
68
  if(result.nil? || (result.respond_to?(:empty?) && result.empty?))
69
69
  if(attempts > MAX_PARAMETER_ATTEMPTS)
70
- ui.fatal 'Failed to receive allowed parameter!'
70
+ ui.fatal "Failed to receive allowed parameter! (Parameter: #{p_name})"
71
71
  exit 1
72
72
  else
73
73
  ui.error "Invalid value provided for parameter. Must be type: `#{p_config[:type].to_s.capitalize}`"
@@ -16,6 +16,11 @@ module Sfn
16
16
  :description => 'Locate all instances and display addresses',
17
17
  :short_flag => 'n'
18
18
  )
19
+ attribute(
20
+ :load_balancers, [TrueClass, FalseClass],
21
+ :description => 'Locate all load balancers, display addresses and server states',
22
+ :short_flag => 'l'
23
+ )
19
24
  attribute(
20
25
  :instance_failure, [TrueClass, FalseClass],
21
26
  :description => 'Display log file error from failed not if possible',
@@ -335,7 +335,7 @@ module Sfn
335
335
  resource_name = p_path[1]
336
336
  property_name = p_path[3].sub(/\[\d+\]$/, '')
337
337
  type = templates[:origin]['Resources'][resource_name]['Type']
338
- info = SfnAws.registry[type]
338
+ info = SfnAws.registry.fetch(type, {})
339
339
  effect = info[:full_properties].fetch(property_name, {}).fetch(:update_causes, :unknown).to_sym
340
340
  resource = Smash.new(
341
341
  :name => resource_name,
@@ -1,4 +1,4 @@
1
1
  module Sfn
2
2
  # Current library version
3
- VERSION = Gem::Version.new('2.1.0')
3
+ VERSION = Gem::Version.new('2.1.2')
4
4
  end
@@ -11,9 +11,11 @@ Gem::Specification.new do |s|
11
11
  s.license = 'Apache-2.0'
12
12
  s.require_path = 'lib'
13
13
  s.add_runtime_dependency 'bogo-cli', '>= 0.2.0', '< 0.4'
14
- s.add_runtime_dependency 'miasma', '>= 0.2.27', '< 0.4'
15
- s.add_runtime_dependency 'miasma-aws', '>= 0.2.0', '< 0.4'
14
+ s.add_runtime_dependency 'miasma', '>= 0.3.0', '< 0.4'
15
+ s.add_runtime_dependency 'miasma-aws', '>= 0.3.0', '< 0.4'
16
16
  s.add_runtime_dependency 'miasma-azure', '>= 0.1.0', '< 0.3'
17
+ s.add_runtime_dependency 'miasma-open-stack', '>= 0.1.0', '< 0.3'
18
+ s.add_runtime_dependency 'miasma-rackspace', '>= 0.1.0', '< 0.3'
17
19
  s.add_runtime_dependency 'net-ssh'
18
20
  s.add_runtime_dependency 'sparkle_formation', '>= 2.1.2', '< 3'
19
21
  s.add_runtime_dependency 'hashdiff', '~> 0.2.2'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sfn
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.1.0
4
+ version: 2.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Chris Roberts
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-02-05 00:00:00.000000000 Z
11
+ date: 2016-02-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bogo-cli
@@ -36,7 +36,7 @@ dependencies:
36
36
  requirements:
37
37
  - - ">="
38
38
  - !ruby/object:Gem::Version
39
- version: 0.2.27
39
+ version: 0.3.0
40
40
  - - "<"
41
41
  - !ruby/object:Gem::Version
42
42
  version: '0.4'
@@ -46,7 +46,7 @@ dependencies:
46
46
  requirements:
47
47
  - - ">="
48
48
  - !ruby/object:Gem::Version
49
- version: 0.2.27
49
+ version: 0.3.0
50
50
  - - "<"
51
51
  - !ruby/object:Gem::Version
52
52
  version: '0.4'
@@ -56,7 +56,7 @@ dependencies:
56
56
  requirements:
57
57
  - - ">="
58
58
  - !ruby/object:Gem::Version
59
- version: 0.2.0
59
+ version: 0.3.0
60
60
  - - "<"
61
61
  - !ruby/object:Gem::Version
62
62
  version: '0.4'
@@ -66,7 +66,7 @@ dependencies:
66
66
  requirements:
67
67
  - - ">="
68
68
  - !ruby/object:Gem::Version
69
- version: 0.2.0
69
+ version: 0.3.0
70
70
  - - "<"
71
71
  - !ruby/object:Gem::Version
72
72
  version: '0.4'
@@ -90,6 +90,46 @@ dependencies:
90
90
  - - "<"
91
91
  - !ruby/object:Gem::Version
92
92
  version: '0.3'
93
+ - !ruby/object:Gem::Dependency
94
+ name: miasma-open-stack
95
+ requirement: !ruby/object:Gem::Requirement
96
+ requirements:
97
+ - - ">="
98
+ - !ruby/object:Gem::Version
99
+ version: 0.1.0
100
+ - - "<"
101
+ - !ruby/object:Gem::Version
102
+ version: '0.3'
103
+ type: :runtime
104
+ prerelease: false
105
+ version_requirements: !ruby/object:Gem::Requirement
106
+ requirements:
107
+ - - ">="
108
+ - !ruby/object:Gem::Version
109
+ version: 0.1.0
110
+ - - "<"
111
+ - !ruby/object:Gem::Version
112
+ version: '0.3'
113
+ - !ruby/object:Gem::Dependency
114
+ name: miasma-rackspace
115
+ requirement: !ruby/object:Gem::Requirement
116
+ requirements:
117
+ - - ">="
118
+ - !ruby/object:Gem::Version
119
+ version: 0.1.0
120
+ - - "<"
121
+ - !ruby/object:Gem::Version
122
+ version: '0.3'
123
+ type: :runtime
124
+ prerelease: false
125
+ version_requirements: !ruby/object:Gem::Requirement
126
+ requirements:
127
+ - - ">="
128
+ - !ruby/object:Gem::Version
129
+ version: 0.1.0
130
+ - - "<"
131
+ - !ruby/object:Gem::Version
132
+ version: '0.3'
93
133
  - !ruby/object:Gem::Dependency
94
134
  name: net-ssh
95
135
  requirement: !ruby/object:Gem::Requirement
@@ -220,6 +260,8 @@ files:
220
260
  - lib/sfn.rb
221
261
  - lib/sfn/cache.rb
222
262
  - lib/sfn/callback.rb
263
+ - lib/sfn/callback/aws_assume_role.rb
264
+ - lib/sfn/callback/aws_mfa.rb
223
265
  - lib/sfn/callback/stack_policy.rb
224
266
  - lib/sfn/command.rb
225
267
  - lib/sfn/command/conf.rb