sfn 3.0.4 → 3.0.6
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 +7 -0
- data/docs/command-config.md +12 -0
- data/docs/commands.md +39 -1
- data/lib/sfn/command_module/base.rb +21 -5
- data/lib/sfn/command_module/stack.rb +46 -26
- data/lib/sfn/command_module/template.rb +8 -3
- data/lib/sfn/config/update.rb +6 -0
- data/lib/sfn/planner/aws.rb +5 -1
- data/lib/sfn/version.rb +1 -1
- data/sfn.gemspec +1 -1
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e3df819d62b28c079cec72e3d62adb265a83f854
|
4
|
+
data.tar.gz: 49e78edc88c14d463e4bd68e1cacb60acf50680d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 33d2a858b98d1892197885c934830ef146f44e27a48303a3aa29b1b2ca5a6a46b1db3afcf2737d48d49ac5bc65f0a1bc0b96a62008c3382b48391ae2571db217
|
7
|
+
data.tar.gz: f4662e9cc07cbc33464455e57987903b0bfdf054021d705d0ae1b538b8d56ab4833af0155e67cd2a7ea9e7feafbe9f71fae34bb6dd1343e965f4b54d61d112da
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,10 @@
|
|
1
|
+
# v3.0.6
|
2
|
+
* [fix] Cast all value types to String within AWS planner (#194)
|
3
|
+
* [fix] Fix template names on create/update prompting (#197)
|
4
|
+
* [enhancement] Extend validation support for compile time parameters (#199)
|
5
|
+
* [enhancement] Add parameter validation control on stack updates (#198)
|
6
|
+
* [feature] Support remote locations when using apply stack (#196)
|
7
|
+
|
1
8
|
# v3.0.4
|
2
9
|
* [fix] Update parameter values extraction location in planner
|
3
10
|
* [fix] Merge compile time parameters when existing are available
|
data/docs/command-config.md
CHANGED
@@ -109,6 +109,9 @@ $ sfn conf
|
|
109
109
|
| `--parameter` | Description | [DEPRECATED - use `parameters`] Pass template parameters directly (ParamName:ParamValue) |
|
110
110
|
| | Valid | `Bogo::Smash` |
|
111
111
|
| | Default | |
|
112
|
+
| `--parameter-validation` | Description | Stack parameter validation behavior |
|
113
|
+
| | Valid | `String` |
|
114
|
+
| | Default | "default"|
|
112
115
|
| `--parameters` | Description | Pass template parameters directly (Key:Value[,Key:Value,...]) |
|
113
116
|
| | Valid | `Bogo::Smash` |
|
114
117
|
| | Default | |
|
@@ -220,6 +223,9 @@ $ sfn create
|
|
220
223
|
| `--parameter` | Description | [DEPRECATED - use `parameters`] Pass template parameters directly (ParamName:ParamValue) |
|
221
224
|
| | Valid | `Bogo::Smash` |
|
222
225
|
| | Default | |
|
226
|
+
| `--parameter-validation` | Description | Stack parameter validation behavior |
|
227
|
+
| | Valid | `String` |
|
228
|
+
| | Default | "default"|
|
223
229
|
| `--parameters` | Description | Pass template parameters directly (Key:Value[,Key:Value,...]) |
|
224
230
|
| | Valid | `Bogo::Smash` |
|
225
231
|
| | Default | |
|
@@ -433,6 +439,9 @@ $ sfn diff
|
|
433
439
|
| `--parameter` | Description | [DEPRECATED - use `parameters`] Pass template parameters directly (ParamName:ParamValue) |
|
434
440
|
| | Valid | `Bogo::Smash` |
|
435
441
|
| | Default | |
|
442
|
+
| `--parameter-validation` | Description | Stack parameter validation behavior |
|
443
|
+
| | Valid | `String` |
|
444
|
+
| | Default | "default"|
|
436
445
|
| `--parameters` | Description | Pass template parameters directly (Key:Value[,Key:Value,...]) |
|
437
446
|
| | Valid | `Bogo::Smash` |
|
438
447
|
| | Default | |
|
@@ -1165,6 +1174,9 @@ $ sfn update
|
|
1165
1174
|
| `--parameter` | Description | [DEPRECATED - use `parameters`] Pass template parameters directly (ParamName:ParamValue) |
|
1166
1175
|
| | Valid | `Bogo::Smash` |
|
1167
1176
|
| | Default | |
|
1177
|
+
| `--parameter-validation` | Description | Stack parameter validation behavior |
|
1178
|
+
| | Valid | `String` |
|
1179
|
+
| | Default | "default"|
|
1168
1180
|
| `--parameters` | Description | Pass template parameters directly (Key:Value[,Key:Value,...]) |
|
1169
1181
|
| | Valid | `Bogo::Smash` |
|
1170
1182
|
| | Default | |
|
data/docs/commands.md
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
---
|
2
|
-
title: "Commands"
|
2
|
+
title: "CLI Commands"
|
3
3
|
weight: 4
|
4
4
|
anchors:
|
5
5
|
- title: "Lifecycle commands"
|
@@ -53,6 +53,8 @@ status code. The automatic polling behavior can be disabled:
|
|
53
53
|
$ sfn create my-stack --file my_template --no-poll
|
54
54
|
~~~
|
55
55
|
|
56
|
+
##### Apply stack
|
57
|
+
|
56
58
|
The `--apply-stack` option allows providing the name of an existing
|
57
59
|
stack when creating or updating. Applying stacks is simply fetching
|
58
60
|
the outputs from the applied stacks and automatically defaulting the
|
@@ -103,6 +105,42 @@ when prompted for the stack parameters, we will find the parameter
|
|
103
105
|
value for `LoadBalancerAddress` to be filled in with the output
|
104
106
|
provided from StackA.
|
105
107
|
|
108
|
+
##### Remote location apply stack
|
109
|
+
|
110
|
+
Stacks that are defined in a different region, or within a
|
111
|
+
different provider, can be applied by prefixing stack names with
|
112
|
+
the configured location name. Using the defined `.sfn` configuration:
|
113
|
+
|
114
|
+
~~~ruby
|
115
|
+
Configuration.new do
|
116
|
+
...
|
117
|
+
credentials do
|
118
|
+
provider :aws
|
119
|
+
aws_access_key_id ENV['AWS_ACCESS_KEY_ID']
|
120
|
+
aws_secret_access_key ENV['AWS_SECRET_ACCESS_KEY']
|
121
|
+
aws_region 'us-west-2'
|
122
|
+
end
|
123
|
+
locations do
|
124
|
+
ca_west do
|
125
|
+
provider :aws
|
126
|
+
aws_access_key_id ENV['AWS_ACCESS_KEY_ID']
|
127
|
+
aws_secret_access_key ENV['AWS_SECRET_ACCESS_KEY']
|
128
|
+
aws_region 'us-west-1'
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
132
|
+
~~~
|
133
|
+
|
134
|
+
Now, when creating a new stack (which uses the configured credentials
|
135
|
+
targeting `us-west-2`) a stack from the `us-west-1` region can be applied
|
136
|
+
by prefixing the location name to the stack name:
|
137
|
+
|
138
|
+
~~~
|
139
|
+
$ sfn create StackB --apply-stack ca_west__StackA
|
140
|
+
~~~
|
141
|
+
|
142
|
+
_NOTE: Location providers are not required to be common._
|
143
|
+
|
106
144
|
Example of stack creation:
|
107
145
|
|
108
146
|

|
@@ -18,12 +18,24 @@ module Sfn
|
|
18
18
|
[config.fetch(:stack_types, [])].flatten.compact
|
19
19
|
end
|
20
20
|
|
21
|
-
#
|
22
|
-
|
21
|
+
# Build provider connection for given location
|
22
|
+
#
|
23
|
+
# @param location [Symbol, String] name of location
|
24
|
+
# @return [Sfn::Provider]
|
25
|
+
def provider_for(location=nil)
|
26
|
+
key = ['provider', location].compact.map(&:to_s).join('_')
|
27
|
+
if(location)
|
28
|
+
credentials = config.get(:locations, location)
|
29
|
+
unless(credentials)
|
30
|
+
raise ArgumentError.new "Failed to locate provider credentials for location `#{location}`!"
|
31
|
+
end
|
32
|
+
else
|
33
|
+
credentials = config[:credentials]
|
34
|
+
end
|
23
35
|
begin
|
24
|
-
memoize(
|
36
|
+
memoize(key) do
|
25
37
|
result = Sfn::Provider.new(
|
26
|
-
:miasma =>
|
38
|
+
:miasma => credentials,
|
27
39
|
:async => false,
|
28
40
|
:fetch => false
|
29
41
|
)
|
@@ -38,17 +50,21 @@ module Sfn
|
|
38
50
|
config.fetch(:retries, {})
|
39
51
|
)
|
40
52
|
result.connection.data[:retry_ui] = ui
|
53
|
+
result.connection.data[:location] = location.to_s
|
41
54
|
result.connection.data[:locations] = config.fetch(:locations, {})
|
42
55
|
result.connection.data[:retry_type] = retry_config.fetch(:type, :exponential)
|
43
56
|
result.connection.data[:retry_interval] = retry_config.fetch(:interval, 5)
|
44
57
|
result.connection.data[:retry_max] = retry_config.fetch(:max_attempts, 20)
|
45
58
|
result
|
46
59
|
end
|
47
|
-
rescue
|
60
|
+
rescue => e
|
48
61
|
ui.error 'Failed to create remote API connection. Please validate configuration!'
|
62
|
+
ui.error "Connection failure reason - #{e.class} - #{e}"
|
49
63
|
raise
|
50
64
|
end
|
51
65
|
end
|
66
|
+
alias_method :provider, :provider_for
|
67
|
+
|
52
68
|
|
53
69
|
# Write exception information if debug is enabled
|
54
70
|
#
|
@@ -22,7 +22,10 @@ module Sfn
|
|
22
22
|
def apply_stacks!(stack)
|
23
23
|
remote_stacks = [config[:apply_stack]].flatten.compact
|
24
24
|
remote_stacks.each do |stack_name|
|
25
|
-
|
25
|
+
stack_info = stack_name.split('__')
|
26
|
+
stack_info.shift(nil) if stack_info.size == 1
|
27
|
+
stack_location, stack_name = stack_info
|
28
|
+
remote_stack = provider_for(stack_location).stack(stack_name)
|
26
29
|
if(remote_stack)
|
27
30
|
apply_nested_stacks!(remote_stack, stack)
|
28
31
|
mappings = generate_custom_apply_mappings(remote_stack)
|
@@ -60,8 +63,18 @@ module Sfn
|
|
60
63
|
if(config[:apply_mapping])
|
61
64
|
valid_keys = config[:apply_mapping].keys.find_all do |a_key|
|
62
65
|
a_key = a_key.to_s
|
63
|
-
|
64
|
-
|
66
|
+
key_parts = a_key.split('__')
|
67
|
+
case key_parts.size
|
68
|
+
when 3
|
69
|
+
provider_stack.api.data[:location] == key_parts[0] &&
|
70
|
+
provider_stack.name == key_parts[1]
|
71
|
+
when 2
|
72
|
+
provider_stack.name == key_parts[1]
|
73
|
+
when 1
|
74
|
+
true
|
75
|
+
else
|
76
|
+
raise ArgumentError "Invalid name format for apply stack mapping (`#{a_key}`)"
|
77
|
+
end
|
65
78
|
end
|
66
79
|
to_remove = valid_keys.find_all do |key|
|
67
80
|
valid_keys.any?{|v_key| v_key.match(/__#{Regexp.escape(key)}$/)}
|
@@ -69,7 +82,7 @@ module Sfn
|
|
69
82
|
valid_keys -= to_remove
|
70
83
|
Hash[
|
71
84
|
valid_keys.map do |a_key|
|
72
|
-
cut_key = a_key.
|
85
|
+
cut_key = a_key.split('__').last
|
73
86
|
[cut_key, config[:apply_mapping][a_key]]
|
74
87
|
end
|
75
88
|
]
|
@@ -226,32 +239,39 @@ module Sfn
|
|
226
239
|
def validate_stack_parameter(c_stack, p_key, p_ns_key, c_value)
|
227
240
|
stack_value = c_stack.parameters[p_key]
|
228
241
|
p_stack = c_stack.data[:parent_stack]
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
+
unless(config[:parameter_validation] == 'none')
|
243
|
+
if(c_value.is_a?(Hash))
|
244
|
+
case c_value.keys.first
|
245
|
+
when 'Ref'
|
246
|
+
current_value = p_stack.parameters[c_value.values.first]
|
247
|
+
when 'Fn::Att'
|
248
|
+
resource_name, output_name = c_value.values.first.split('.', 2)
|
249
|
+
ref_stack = p_stack.nested_stacks.detect{|i| i.data[:logical_id] == resource_name}
|
250
|
+
if(ref_stack)
|
251
|
+
output = ref_stack.outputs.detect do |o|
|
252
|
+
o.key == output_name
|
253
|
+
end
|
254
|
+
if(output)
|
255
|
+
current_value = output.value
|
256
|
+
end
|
242
257
|
end
|
243
258
|
end
|
259
|
+
else
|
260
|
+
current_value = c_value
|
261
|
+
end
|
262
|
+
if(current_value && current_value.to_s != stack_value.to_s)
|
263
|
+
if(config[:parameter_validation] == 'default')
|
264
|
+
ui.warn 'Nested stack has been altered directly! This update may cause unexpected modifications!'
|
265
|
+
ui.warn "Stack name: #{c_stack.name}. Parameter: #{p_key}. Current value: #{stack_value}. Expected value: #{current_value} (via: #{c_value.inspect})"
|
266
|
+
answer = ui.ask_question("Use current value or expected value for #{p_key} [current/expected]?", :valid => ['current', 'expected'])
|
267
|
+
else
|
268
|
+
answer = config[:parameter_validation]
|
269
|
+
end
|
270
|
+
answer == 'expected'
|
271
|
+
else
|
272
|
+
true
|
244
273
|
end
|
245
274
|
else
|
246
|
-
current_value = c_value
|
247
|
-
end
|
248
|
-
if(current_value && current_value.to_s != stack_value.to_s)
|
249
|
-
ui.warn 'Nested stack has been altered directly! This update may cause unexpected modifications!'
|
250
|
-
ui.warn "Stack name: #{c_stack.name}. Parameter: #{p_key}. Current value: #{stack_value}. Expected value: #{current_value} (via: #{c_value.inspect})"
|
251
|
-
answer = ui.ask_question("Use current value or expected value for #{p_key} [current/expected]?", :valid => ['current', 'expected'])
|
252
|
-
answer == 'expected'
|
253
|
-
else
|
254
|
-
# ui.warn "Unable to check #{p_key} for direct value modification. (Cannot auto-check expected value #{c_value.inspect})"
|
255
275
|
true
|
256
276
|
end
|
257
277
|
end
|
@@ -82,12 +82,17 @@ module Sfn
|
|
82
82
|
else
|
83
83
|
raise ArgumentError.new "Unknown compile time parameter type provided: `#{p_config[:type].inspect}` (Parameter: #{p_name})"
|
84
84
|
end
|
85
|
+
valid = validate_parameter(result, p_config.to_smash)
|
86
|
+
unless(valid == true)
|
87
|
+
result = nil
|
88
|
+
valid.each do |invalid_msg|
|
89
|
+
ui.error invalid_msg.last
|
90
|
+
end
|
91
|
+
end
|
85
92
|
if(result.nil? || (result.respond_to?(:empty?) && result.empty?))
|
86
93
|
if(attempts > MAX_PARAMETER_ATTEMPTS)
|
87
94
|
ui.fatal "Failed to receive allowed parameter! (Parameter: #{p_name})"
|
88
95
|
exit 1
|
89
|
-
else
|
90
|
-
ui.error "Invalid value provided for parameter `#{p_name}`. Must be type: `#{p_config[:type].to_s.capitalize}`"
|
91
96
|
end
|
92
97
|
end
|
93
98
|
end
|
@@ -489,7 +494,7 @@ module Sfn
|
|
489
494
|
t_name.to_s.start_with?(prefix.to_s)
|
490
495
|
end
|
491
496
|
else
|
492
|
-
template_names = sparkle_collection.templates.keys
|
497
|
+
template_names = sparkle_collection.templates.fetch(provider.connection.provider, {}).keys
|
493
498
|
end
|
494
499
|
collections = template_names.map do |t_name|
|
495
500
|
t_name = t_name.to_s.sub(/^#{Regexp.escape(prefix.to_s)}/, '')
|
data/lib/sfn/config/update.rb
CHANGED
@@ -59,6 +59,12 @@ module Sfn
|
|
59
59
|
:description => 'Merge API options defined within configuration on update',
|
60
60
|
:default => false
|
61
61
|
)
|
62
|
+
attribute(
|
63
|
+
:parameter_validation, String,
|
64
|
+
:allowed => ['default', 'none', 'current', 'expected'],
|
65
|
+
:description => 'Stack parameter validation behavior',
|
66
|
+
:default => 'default'
|
67
|
+
)
|
62
68
|
|
63
69
|
end
|
64
70
|
end
|
data/lib/sfn/planner/aws.rb
CHANGED
data/lib/sfn/version.rb
CHANGED
data/sfn.gemspec
CHANGED
@@ -19,7 +19,7 @@ Gem::Specification.new do |s|
|
|
19
19
|
s.add_runtime_dependency 'miasma-rackspace', '>= 0.1.0', '< 0.3'
|
20
20
|
s.add_runtime_dependency 'miasma-google', '>= 0.1.0', '< 0.3'
|
21
21
|
s.add_runtime_dependency 'net-ssh'
|
22
|
-
s.add_runtime_dependency 'sparkle_formation', '>= 3', '< 4'
|
22
|
+
s.add_runtime_dependency 'sparkle_formation', '>= 3.0.3', '< 4'
|
23
23
|
s.add_runtime_dependency 'hashdiff', '~> 0.2.2'
|
24
24
|
s.add_runtime_dependency 'graph', '~> 2.8.1'
|
25
25
|
s.add_development_dependency 'rake', '~> 10'
|
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: 3.0.
|
4
|
+
version: 3.0.6
|
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-05-
|
11
|
+
date: 2016-05-14 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bogo-cli
|
@@ -190,7 +190,7 @@ dependencies:
|
|
190
190
|
requirements:
|
191
191
|
- - ">="
|
192
192
|
- !ruby/object:Gem::Version
|
193
|
-
version:
|
193
|
+
version: 3.0.3
|
194
194
|
- - "<"
|
195
195
|
- !ruby/object:Gem::Version
|
196
196
|
version: '4'
|
@@ -200,7 +200,7 @@ dependencies:
|
|
200
200
|
requirements:
|
201
201
|
- - ">="
|
202
202
|
- !ruby/object:Gem::Version
|
203
|
-
version:
|
203
|
+
version: 3.0.3
|
204
204
|
- - "<"
|
205
205
|
- !ruby/object:Gem::Version
|
206
206
|
version: '4'
|