sfn 2.1.0 → 2.1.2
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 +4 -4
- data/CHANGELOG.md +9 -0
- data/docs/callbacks.md +188 -1
- data/lib/sfn/callback.rb +2 -0
- data/lib/sfn/callback/aws_assume_role.rb +93 -0
- data/lib/sfn/callback/aws_mfa.rb +102 -0
- data/lib/sfn/callback/stack_policy.rb +12 -10
- data/lib/sfn/command/inspect.rb +25 -1
- data/lib/sfn/command/list.rb +1 -1
- data/lib/sfn/command/update.rb +12 -6
- data/lib/sfn/command_module/callbacks.rb +4 -4
- data/lib/sfn/command_module/stack.rb +1 -1
- data/lib/sfn/command_module/template.rb +1 -1
- data/lib/sfn/config/inspect.rb +5 -0
- data/lib/sfn/planner/aws.rb +1 -1
- data/lib/sfn/version.rb +1 -1
- data/sfn.gemspec +4 -2
- metadata +48 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ef688f38c0f0be5810c525cd37e77d5a4216756a
|
4
|
+
data.tar.gz: 1f3e4f9a893e376b9c7e77fda5f1e495e27df905
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: be3015b69f844371bff9588753a0cec1b9ca1dfb05cb957106583e62ed8a5a9b4284b052938ddb53ace50c8f85f0a73a4884b0131c2948a5d49693f41d3a88d7
|
7
|
+
data.tar.gz: ae268210135a9b5bbc406a1c7684a5e560f16548b21f2b29bd3c8164c66ffe0668c189f995a4c27f86797047f997c3ef3be12d809135b229f86cf3ac049b9225
|
data/CHANGELOG.md
CHANGED
@@ -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
|
data/docs/callbacks.md
CHANGED
@@ -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
|
-
* `
|
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
|
data/lib/sfn/callback.rb
CHANGED
@@ -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
|
-
#
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
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
|
data/lib/sfn/command/inspect.rb
CHANGED
@@ -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
|
data/lib/sfn/command/list.rb
CHANGED
data/lib/sfn/command/update.rb
CHANGED
@@ -87,12 +87,18 @@ module Sfn
|
|
87
87
|
update_template = stack.template
|
88
88
|
|
89
89
|
if(config[:plan])
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
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
|
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}`"
|
data/lib/sfn/config/inspect.rb
CHANGED
@@ -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',
|
data/lib/sfn/planner/aws.rb
CHANGED
@@ -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
|
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,
|
data/lib/sfn/version.rb
CHANGED
data/sfn.gemspec
CHANGED
@@ -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.
|
15
|
-
s.add_runtime_dependency 'miasma-aws', '>= 0.
|
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.
|
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-
|
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.
|
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.
|
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.
|
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.
|
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
|