sfn 3.0.4 → 3.0.6

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: b5dbbdec8d298bd67a3aefc4165d871d263619df
4
- data.tar.gz: 5170f01c227cf78fd58342c21487fa4d6793fecb
3
+ metadata.gz: e3df819d62b28c079cec72e3d62adb265a83f854
4
+ data.tar.gz: 49e78edc88c14d463e4bd68e1cacb60acf50680d
5
5
  SHA512:
6
- metadata.gz: 00763fc81a15a13447d6b1f72088b2231801d44512445c2e4046f4b0df1ccfd48018183a3f6e6581c237cb093cf8b9a8f0ba3292788add746de39fd9c07b0a55
7
- data.tar.gz: 05238e596ac34dec5ccada596e7cfae2251af646600a44c3e0a20af94892664771251376035f0bba56b09826022b27b8f7acd313c2c0bcc7e5543c5e36dc828d
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
@@ -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
  ![stack create](./images/d_create.png)
@@ -18,12 +18,24 @@ module Sfn
18
18
  [config.fetch(:stack_types, [])].flatten.compact
19
19
  end
20
20
 
21
- # @return [KnifeCloudformation::Provider]
22
- def provider
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(:provider) do
36
+ memoize(key) do
25
37
  result = Sfn::Provider.new(
26
- :miasma => config[:credentials],
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
- remote_stack = provider.stack(stack_name)
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
- !a_key.include?('__') ||
64
- a_key.split('__').first == provider_stack.name
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.include?('__') ? a_key.slice(a_key.index('__') + 2, a_key.length) : 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
- if(c_value.is_a?(Hash))
230
- case c_value.keys.first
231
- when 'Ref'
232
- current_value = p_stack.parameters[c_value.values.first]
233
- when 'Fn::Att'
234
- resource_name, output_name = c_value.values.first.split('.', 2)
235
- ref_stack = p_stack.nested_stacks.detect{|i| i.data[:logical_id] == resource_name}
236
- if(ref_stack)
237
- output = ref_stack.outputs.detect do |o|
238
- o.key == output_name
239
- end
240
- if(output)
241
- current_value = output.value
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)}/, '')
@@ -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
@@ -101,7 +101,11 @@ module Sfn
101
101
  end
102
102
  end
103
103
  end
104
- result.nil? ? super : result
104
+ result = result.nil? ? super : result
105
+ unless(result.is_a?(Enumerable))
106
+ result = result.to_s
107
+ end
108
+ result
105
109
  end
106
110
 
107
111
  end
data/lib/sfn/version.rb CHANGED
@@ -1,4 +1,4 @@
1
1
  module Sfn
2
2
  # Current library version
3
- VERSION = Gem::Version.new('3.0.4')
3
+ VERSION = Gem::Version.new('3.0.6')
4
4
  end
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
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 00:00:00.000000000 Z
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: '3'
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: '3'
203
+ version: 3.0.3
204
204
  - - "<"
205
205
  - !ruby/object:Gem::Version
206
206
  version: '4'