humidifier-reservoir 0.1.0 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +3 -3
- data/README.md +94 -0
- data/docs/Humidifier.html +2 -2
- data/docs/Humidifier/Reservoir.html +3 -3
- data/docs/Humidifier/Reservoir/BaseMapper.html +61 -23
- data/docs/Humidifier/Reservoir/CLI.html +89 -23
- data/docs/Humidifier/Reservoir/Config.html +6 -6
- data/docs/Humidifier/Reservoir/Error.html +2 -2
- data/docs/Humidifier/Reservoir/Mapping.html +20 -12
- data/docs/Humidifier/Reservoir/Stack.html +272 -60
- data/docs/Humidifier/Reservoir/Stack/Export.html +322 -0
- data/docs/_index.html +9 -2
- data/docs/class_list.html +1 -1
- data/docs/file.LICENSE.html +2 -2
- data/docs/file.README.html +121 -2
- data/docs/index.html +121 -2
- data/docs/method_list.html +52 -4
- data/docs/top-level-namespace.html +2 -2
- data/humidifier-reservoir.gemspec +1 -3
- data/lib/humidifier/reservoir/base_mapper.rb +26 -3
- data/lib/humidifier/reservoir/cli.rb +21 -4
- data/lib/humidifier/reservoir/config.rb +2 -2
- data/lib/humidifier/reservoir/mapping.rb +23 -3
- data/lib/humidifier/reservoir/stack.rb +49 -8
- data/lib/humidifier/reservoir/version.rb +1 -1
- metadata +5 -4
data/docs/index.html
CHANGED
@@ -215,6 +215,125 @@ if you're deploying from an instance. For more information, see the <a
|
|
215
215
|
href="http://docs.aws.amazon.com/sdkforruby/api/">AWS docs</a> under the
|
216
216
|
“Configuration” section.</p>
|
217
217
|
|
218
|
+
<h4 id="label--prefix">–prefix</h4>
|
219
|
+
|
220
|
+
<p>The <code>deploy</code> command also allows a <code>--prefix</code> command
|
221
|
+
line argument that will override the default prefix (if one is configured)
|
222
|
+
for the stack that is being deployed. This is especially useful when
|
223
|
+
you're deploying multiple copies of the same stack (for instance,
|
224
|
+
multiple autoscaling groups) that have different purposes or semantically
|
225
|
+
mean newer versions of resources.</p>
|
226
|
+
|
227
|
+
<h3 id="label-Shortcuts">Shortcuts</h3>
|
228
|
+
|
229
|
+
<p>A couple of convenient shortcuts are built into
|
230
|
+
<code>humidifier-reservoir</code> so that writing templates and mappers
|
231
|
+
both can be more concise.</p>
|
232
|
+
|
233
|
+
<h4 id="label-Automatic+id+properties">Automatic id properties</h4>
|
234
|
+
|
235
|
+
<p>There are a lot of properties in the AWS CloudFormation resource
|
236
|
+
specification that are simply pointers to other entities within the AWS
|
237
|
+
ecosystem. For example, an <code>AWS::EC2::VPCGatewayAttachment</code>
|
238
|
+
entity has a <code>VpcId</code> property that represents the ID of the
|
239
|
+
associated <code>AWS::EC2::VPC</code>.</p>
|
240
|
+
|
241
|
+
<p>Because this pattern is so common, <code>humidifier-reservoir</code>
|
242
|
+
detects all properties ending in <code>Id</code> and allows you to specify
|
243
|
+
them without the suffix. If you choose to use this format,
|
244
|
+
<code>humidifier-reservoir</code> will automatically turn that value into a
|
245
|
+
<a
|
246
|
+
href="http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-ref.html">CloudFormation
|
247
|
+
resource reference</a>.</p>
|
248
|
+
|
249
|
+
<h4 id="label-Anonymous+mappers">Anonymous mappers</h4>
|
250
|
+
|
251
|
+
<p>A lot of the time, mappers that you create will not be overly complicated,
|
252
|
+
especially if you're using the aforementioned automatic id properties.
|
253
|
+
Therefore, the <code>config.map</code> method takes a block, and allows you
|
254
|
+
to specify the mapper inline. This is recommended for mappers that
|
255
|
+
aren't too complicates as to warrant their own class (for instance, for
|
256
|
+
testing purposes). An example of this using the <code>UserMapper</code>
|
257
|
+
from above is below:</p>
|
258
|
+
|
259
|
+
<pre class="code ruby"><code class="ruby"><span class='const'><span class='object_link'><a href="Humidifier.html" title="Humidifier (module)">Humidifier</a></span></span><span class='op'>::</span><span class='const'><span class='object_link'><a href="Humidifier/Reservoir.html" title="Humidifier::Reservoir (module)">Reservoir</a></span></span><span class='period'>.</span><span class='id identifier rubyid_configure'><span class='object_link'><a href="Humidifier/Reservoir.html#configure-class_method" title="Humidifier::Reservoir.configure (method)">configure</a></span></span> <span class='kw'>do</span> <span class='op'>|</span><span class='id identifier rubyid_config'>config</span><span class='op'>|</span>
|
260
|
+
<span class='id identifier rubyid_config'>config</span><span class='period'>.</span><span class='id identifier rubyid_map'>map</span> <span class='symbol'>:users</span><span class='comma'>,</span> <span class='label'>to:</span> <span class='tstring'><span class='tstring_beg'>'</span><span class='tstring_content'>AWS::IAM::User</span><span class='tstring_end'>'</span></span> <span class='kw'>do</span>
|
261
|
+
<span class='const'>GROUPS</span> <span class='op'>=</span> <span class='lbrace'>{</span>
|
262
|
+
<span class='tstring'><span class='tstring_beg'>'</span><span class='tstring_content'>eng</span><span class='tstring_end'>'</span></span> <span class='op'>=></span> <span class='qwords_beg'>%w[</span><span class='tstring_content'>Engineering</span><span class='words_sep'> </span><span class='tstring_content'>Testing</span><span class='words_sep'> </span><span class='tstring_content'>Deployment</span><span class='words_sep'>]</span><span class='comma'>,</span>
|
263
|
+
<span class='tstring'><span class='tstring_beg'>'</span><span class='tstring_content'>admin</span><span class='tstring_end'>'</span></span> <span class='op'>=></span> <span class='qwords_beg'>%w[</span><span class='tstring_content'>Management</span><span class='words_sep'> </span><span class='tstring_content'>Administration</span><span class='words_sep'>]</span>
|
264
|
+
<span class='rbrace'>}</span>
|
265
|
+
|
266
|
+
<span class='id identifier rubyid_defaults'>defaults</span> <span class='kw'>do</span> <span class='op'>|</span><span class='id identifier rubyid_logical_name'>logical_name</span><span class='op'>|</span>
|
267
|
+
<span class='lbrace'>{</span> <span class='label'>path:</span> <span class='tstring'><span class='tstring_beg'>'</span><span class='tstring_content'>/reservoir/</span><span class='tstring_end'>'</span></span><span class='comma'>,</span> <span class='label'>user_name:</span> <span class='id identifier rubyid_logical_name'>logical_name</span> <span class='rbrace'>}</span>
|
268
|
+
<span class='kw'>end</span>
|
269
|
+
|
270
|
+
<span class='id identifier rubyid_attribute'>attribute</span> <span class='symbol'>:group</span> <span class='kw'>do</span> <span class='op'>|</span><span class='id identifier rubyid_group'>group</span><span class='op'>|</span>
|
271
|
+
<span class='id identifier rubyid_groups'>groups</span> <span class='op'>=</span> <span class='const'>GROUPS</span><span class='lbracket'>[</span><span class='id identifier rubyid_group'>group</span><span class='rbracket'>]</span>
|
272
|
+
<span class='id identifier rubyid_groups'>groups</span><span class='period'>.</span><span class='id identifier rubyid_any?'>any?</span> <span class='op'>?</span> <span class='lbrace'>{</span> <span class='label'>groups:</span> <span class='const'>GROUPS</span><span class='lbracket'>[</span><span class='id identifier rubyid_group'>group</span><span class='rbracket'>]</span> <span class='rbrace'>}</span> <span class='op'>:</span> <span class='lbrace'>{</span><span class='rbrace'>}</span>
|
273
|
+
<span class='kw'>end</span>
|
274
|
+
<span class='kw'>end</span>
|
275
|
+
<span class='kw'>end</span>
|
276
|
+
</code></pre>
|
277
|
+
|
278
|
+
<h4 id="label-Cross-stack+references">Cross-stack references</h4>
|
279
|
+
|
280
|
+
<p>AWS allows cross-stack references through the <a
|
281
|
+
href="http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-importvalue.html">intrinsic
|
282
|
+
Fn::ImportValue function</a>. You can take advantage of this with
|
283
|
+
<code>humidifier-reservoir</code> by using the <code>export: true</code>
|
284
|
+
option on resources in your stacks. For instance, if in one stack you have
|
285
|
+
a subnet that you need to reference in another, you could
|
286
|
+
(<code>stacks/vpc/subnets.yml</code>):</p>
|
287
|
+
|
288
|
+
<pre class="code ruby"><code class="ruby">ProductionPrivateSubnet2a:
|
289
|
+
vpc: ProductionVPC
|
290
|
+
cidr_block: 10.0.0.0/19
|
291
|
+
availability_zone: us-west-2a
|
292
|
+
export: true
|
293
|
+
|
294
|
+
ProductionPrivateSubnet2b:
|
295
|
+
vpc: ProductionVPC
|
296
|
+
cidr_block: 10.0.64.0/19
|
297
|
+
availability_zone: us-west-2b
|
298
|
+
export: true
|
299
|
+
|
300
|
+
ProductionPrivateSubnet2c:
|
301
|
+
vpc: ProductionVPC
|
302
|
+
cidr_block: 10.0.128.0/19
|
303
|
+
availability_zone: us-west-2c
|
304
|
+
export: true</code></pre>
|
305
|
+
|
306
|
+
<p>And then in another stack, you could reference those values
|
307
|
+
(<code>stacks/rds/db_subnets_groups.yml</code>):</p>
|
308
|
+
|
309
|
+
<pre class="code ruby"><code class="ruby">ProductionDBSubnetGroup:
|
310
|
+
db_subnet_group_description: Production DB private subnet group
|
311
|
+
subnets:
|
312
|
+
- ProductionPrivateSubnet2a
|
313
|
+
- ProductionPrivateSubnet2b
|
314
|
+
- ProductionPrivateSubnet2c</code></pre>
|
315
|
+
|
316
|
+
<p>Within the configuration, you would specify to use the
|
317
|
+
<code>Fn::ImportValue</code> function like so:</p>
|
318
|
+
|
319
|
+
<pre class="code ruby"><code class="ruby"><span class='const'><span class='object_link'><a href="Humidifier.html" title="Humidifier (module)">Humidifier</a></span></span><span class='op'>::</span><span class='const'><span class='object_link'><a href="Humidifier/Reservoir.html" title="Humidifier::Reservoir (module)">Reservoir</a></span></span><span class='period'>.</span><span class='id identifier rubyid_configure'><span class='object_link'><a href="Humidifier/Reservoir.html#configure-class_method" title="Humidifier::Reservoir.configure (method)">configure</a></span></span> <span class='kw'>do</span> <span class='op'>|</span><span class='id identifier rubyid_config'>config</span><span class='op'>|</span>
|
320
|
+
<span class='id identifier rubyid_config'>config</span><span class='period'>.</span><span class='id identifier rubyid_stack_path'>stack_path</span> <span class='op'>=</span> <span class='tstring'><span class='tstring_beg'>'</span><span class='tstring_content'>stacks</span><span class='tstring_end'>'</span></span>
|
321
|
+
|
322
|
+
<span class='id identifier rubyid_config'>config</span><span class='period'>.</span><span class='id identifier rubyid_map'>map</span> <span class='symbol'>:subnets</span><span class='comma'>,</span> <span class='label'>to:</span> <span class='tstring'><span class='tstring_beg'>'</span><span class='tstring_content'>EC2::Subnet</span><span class='tstring_end'>'</span></span>
|
323
|
+
|
324
|
+
<span class='id identifier rubyid_config'>config</span><span class='period'>.</span><span class='id identifier rubyid_map'>map</span> <span class='symbol'>:db_subnet_groups</span><span class='comma'>,</span> <span class='label'>to:</span> <span class='tstring'><span class='tstring_beg'>'</span><span class='tstring_content'>RDS::DBSubnetGroup</span><span class='tstring_end'>'</span></span> <span class='kw'>do</span>
|
325
|
+
<span class='id identifier rubyid_attribute'>attribute</span> <span class='symbol'>:subnets</span> <span class='kw'>do</span> <span class='op'>|</span><span class='id identifier rubyid_subnet_names'>subnet_names</span><span class='op'>|</span>
|
326
|
+
<span class='id identifier rubyid_subnet_ids'>subnet_ids</span> <span class='op'>=</span>
|
327
|
+
<span class='id identifier rubyid_subnet_names'>subnet_names</span><span class='period'>.</span><span class='id identifier rubyid_map'>map</span> <span class='kw'>do</span> <span class='op'>|</span><span class='id identifier rubyid_subnet_name'>subnet_name</span><span class='op'>|</span>
|
328
|
+
<span class='const'><span class='object_link'><a href="Humidifier.html" title="Humidifier (module)">Humidifier</a></span></span><span class='period'>.</span><span class='id identifier rubyid_fn'>fn</span><span class='period'>.</span><span class='id identifier rubyid_import_value'>import_value</span><span class='lparen'>(</span><span class='id identifier rubyid_subnet_name'>subnet_name</span><span class='rparen'>)</span>
|
329
|
+
<span class='kw'>end</span>
|
330
|
+
|
331
|
+
<span class='lbrace'>{</span> <span class='label'>subnet_ids:</span> <span class='id identifier rubyid_subnet_ids'>subnet_ids</span> <span class='rbrace'>}</span>
|
332
|
+
<span class='kw'>end</span>
|
333
|
+
<span class='kw'>end</span>
|
334
|
+
<span class='kw'>end</span>
|
335
|
+
</code></pre>
|
336
|
+
|
218
337
|
<h2 id="label-Development">Development</h2>
|
219
338
|
|
220
339
|
<p>After checking out the repo, run <code>bin/setup</code> to install
|
@@ -241,9 +360,9 @@ href="http://opensource.org/licenses/MIT">MIT License</a>.</p>
|
|
241
360
|
</div></div>
|
242
361
|
|
243
362
|
<div id="footer">
|
244
|
-
Generated on
|
363
|
+
Generated on Wed Nov 8 13:26:15 2017 by
|
245
364
|
<a href="http://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
|
246
|
-
0.9.9 (ruby-2.4.
|
365
|
+
0.9.9 (ruby-2.4.2).
|
247
366
|
</div>
|
248
367
|
|
249
368
|
</div>
|
data/docs/method_list.html
CHANGED
@@ -45,6 +45,14 @@
|
|
45
45
|
|
46
46
|
|
47
47
|
<li class="odd ">
|
48
|
+
<div class="item">
|
49
|
+
<span class='object_link'><a href="Humidifier/Reservoir/Stack/Export.html#attribute-instance_method" title="Humidifier::Reservoir::Stack::Export#attribute (method)">#attribute</a></span>
|
50
|
+
<small>Humidifier::Reservoir::Stack::Export</small>
|
51
|
+
</div>
|
52
|
+
</li>
|
53
|
+
|
54
|
+
|
55
|
+
<li class="even ">
|
48
56
|
<div class="item">
|
49
57
|
<span class='object_link'><a href="Humidifier/Reservoir/BaseMapper.html#attribute-class_method" title="Humidifier::Reservoir::BaseMapper.attribute (method)">attribute</a></span>
|
50
58
|
<small>Humidifier::Reservoir::BaseMapper</small>
|
@@ -52,7 +60,7 @@
|
|
52
60
|
</li>
|
53
61
|
|
54
62
|
|
55
|
-
<li class="
|
63
|
+
<li class="odd ">
|
56
64
|
<div class="item">
|
57
65
|
<span class='object_link'><a href="Humidifier/Reservoir/BaseMapper.html#attribute_methods-class_method" title="Humidifier::Reservoir::BaseMapper.attribute_methods (method)">attribute_methods</a></span>
|
58
66
|
<small>Humidifier::Reservoir::BaseMapper</small>
|
@@ -60,6 +68,14 @@
|
|
60
68
|
</li>
|
61
69
|
|
62
70
|
|
71
|
+
<li class="even ">
|
72
|
+
<div class="item">
|
73
|
+
<span class='object_link'><a href="Humidifier/Reservoir/CLI.html#change-instance_method" title="Humidifier::Reservoir::CLI#change (method)">#change</a></span>
|
74
|
+
<small>Humidifier::Reservoir::CLI</small>
|
75
|
+
</div>
|
76
|
+
</li>
|
77
|
+
|
78
|
+
|
63
79
|
<li class="odd ">
|
64
80
|
<div class="item">
|
65
81
|
<span class='object_link'><a href="Humidifier/Reservoir/Mapping.html#clazz-instance_method" title="Humidifier::Reservoir::Mapping#clazz (method)">#clazz</a></span>
|
@@ -85,6 +101,14 @@
|
|
85
101
|
|
86
102
|
|
87
103
|
<li class="even ">
|
104
|
+
<div class="item">
|
105
|
+
<span class='object_link'><a href="Humidifier/Reservoir/Stack.html#create_change_set-instance_method" title="Humidifier::Reservoir::Stack#create_change_set (method)">#create_change_set</a></span>
|
106
|
+
<small>Humidifier::Reservoir::Stack</small>
|
107
|
+
</div>
|
108
|
+
</li>
|
109
|
+
|
110
|
+
|
111
|
+
<li class="odd ">
|
88
112
|
<div class="item">
|
89
113
|
<span class='object_link'><a href="Humidifier/Reservoir/BaseMapper.html#defaults-class_method" title="Humidifier::Reservoir::BaseMapper.defaults (method)">defaults</a></span>
|
90
114
|
<small>Humidifier::Reservoir::BaseMapper</small>
|
@@ -92,7 +116,7 @@
|
|
92
116
|
</li>
|
93
117
|
|
94
118
|
|
95
|
-
<li class="
|
119
|
+
<li class="even ">
|
96
120
|
<div class="item">
|
97
121
|
<span class='object_link'><a href="Humidifier/Reservoir/CLI.html#deploy-instance_method" title="Humidifier::Reservoir::CLI#deploy (method)">#deploy</a></span>
|
98
122
|
<small>Humidifier::Reservoir::CLI</small>
|
@@ -100,7 +124,7 @@
|
|
100
124
|
</li>
|
101
125
|
|
102
126
|
|
103
|
-
<li class="
|
127
|
+
<li class="odd ">
|
104
128
|
<div class="item">
|
105
129
|
<span class='object_link'><a href="Humidifier/Reservoir/Stack.html#deploy-instance_method" title="Humidifier::Reservoir::Stack#deploy (method)">#deploy</a></span>
|
106
130
|
<small>Humidifier::Reservoir::Stack</small>
|
@@ -108,7 +132,7 @@
|
|
108
132
|
</li>
|
109
133
|
|
110
134
|
|
111
|
-
<li class="
|
135
|
+
<li class="even ">
|
112
136
|
<div class="item">
|
113
137
|
<span class='object_link'><a href="Humidifier/Reservoir/CLI.html#display-instance_method" title="Humidifier::Reservoir::CLI#display (method)">#display</a></span>
|
114
138
|
<small>Humidifier::Reservoir::CLI</small>
|
@@ -116,6 +140,14 @@
|
|
116
140
|
</li>
|
117
141
|
|
118
142
|
|
143
|
+
<li class="odd ">
|
144
|
+
<div class="item">
|
145
|
+
<span class='object_link'><a href="Humidifier/Reservoir/Stack.html#exports-instance_method" title="Humidifier::Reservoir::Stack#exports (method)">#exports</a></span>
|
146
|
+
<small>Humidifier::Reservoir::Stack</small>
|
147
|
+
</div>
|
148
|
+
</li>
|
149
|
+
|
150
|
+
|
119
151
|
<li class="even ">
|
120
152
|
<div class="item">
|
121
153
|
<span class='object_link'><a href="Humidifier/Reservoir/Config.html#files_for-instance_method" title="Humidifier::Reservoir::Config#files_for (method)">#files_for</a></span>
|
@@ -205,6 +237,14 @@
|
|
205
237
|
|
206
238
|
|
207
239
|
<li class="odd ">
|
240
|
+
<div class="item">
|
241
|
+
<span class='object_link'><a href="Humidifier/Reservoir/Stack/Export.html#name-instance_method" title="Humidifier::Reservoir::Stack::Export#name (method)">#name</a></span>
|
242
|
+
<small>Humidifier::Reservoir::Stack::Export</small>
|
243
|
+
</div>
|
244
|
+
</li>
|
245
|
+
|
246
|
+
|
247
|
+
<li class="even ">
|
208
248
|
<div class="item">
|
209
249
|
<span class='object_link'><a href="Humidifier/Reservoir/Stack.html#pattern-instance_method" title="Humidifier::Reservoir::Stack#pattern (method)">#pattern</a></span>
|
210
250
|
<small>Humidifier::Reservoir::Stack</small>
|
@@ -212,6 +252,14 @@
|
|
212
252
|
</li>
|
213
253
|
|
214
254
|
|
255
|
+
<li class="odd ">
|
256
|
+
<div class="item">
|
257
|
+
<span class='object_link'><a href="Humidifier/Reservoir/Stack.html#prefix-instance_method" title="Humidifier::Reservoir::Stack#prefix (method)">#prefix</a></span>
|
258
|
+
<small>Humidifier::Reservoir::Stack</small>
|
259
|
+
</div>
|
260
|
+
</li>
|
261
|
+
|
262
|
+
|
215
263
|
<li class="even ">
|
216
264
|
<div class="item">
|
217
265
|
<span class='object_link'><a href="Humidifier/Reservoir/BaseMapper.html#resource_for-instance_method" title="Humidifier::Reservoir::BaseMapper#resource_for (method)">#resource_for</a></span>
|
@@ -100,9 +100,9 @@
|
|
100
100
|
</div>
|
101
101
|
|
102
102
|
<div id="footer">
|
103
|
-
Generated on
|
103
|
+
Generated on Wed Nov 8 13:26:15 2017 by
|
104
104
|
<a href="http://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
|
105
|
-
0.9.9 (ruby-2.4.
|
105
|
+
0.9.9 (ruby-2.4.2).
|
106
106
|
</div>
|
107
107
|
|
108
108
|
</div>
|
@@ -1,5 +1,3 @@
|
|
1
|
-
# coding: utf-8
|
2
|
-
|
3
1
|
lib = File.expand_path('../lib', __FILE__)
|
4
2
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
5
3
|
require 'humidifier/reservoir/version'
|
@@ -28,7 +26,7 @@ Gem::Specification.new do |spec| # rubocop:disable Metrics/BlockLength
|
|
28
26
|
|
29
27
|
spec.add_dependency 'aws-sdk-cloudformation', '~> 1.2'
|
30
28
|
spec.add_dependency 'aws-sdk-s3', '~> 1.4'
|
31
|
-
spec.add_dependency 'humidifier', '~> 1.
|
29
|
+
spec.add_dependency 'humidifier', '~> 1.8', '>= 1.7'
|
32
30
|
spec.add_dependency 'thor', '~> 0.19'
|
33
31
|
spec.add_dependency 'thor-hollaback', '~> 0.1'
|
34
32
|
|
@@ -6,6 +6,10 @@ module Humidifier
|
|
6
6
|
# class provides an easy-to-extend DSL that allows for default attributes
|
7
7
|
# specifying custom attributes.
|
8
8
|
class BaseMapper
|
9
|
+
# The list of attributes that are common to all resources that need to be
|
10
|
+
# handles separately.
|
11
|
+
COMMON_ATTRIBUTES = Resource::COMMON_ATTRIBUTES.values
|
12
|
+
|
9
13
|
class << self
|
10
14
|
# Defines a custom attribute. The given block will receive the
|
11
15
|
# user-provided value for the attribute. The block should return a hash
|
@@ -47,17 +51,36 @@ module Humidifier
|
|
47
51
|
# the logical name for the resource, and the user-specified attributes.
|
48
52
|
def resource_for(clazz, name, attributes)
|
49
53
|
mapped = respond_to?(:attribute_defaults) ? attribute_defaults(name) : {}
|
50
|
-
|
51
|
-
|
54
|
+
|
55
|
+
attributes.each do |key, value|
|
56
|
+
mapped.merge!(mapped_from(clazz, key, value))
|
57
|
+
end
|
58
|
+
|
59
|
+
common_attributes = common_attributes_from(mapped)
|
60
|
+
|
61
|
+
resource = clazz.new(mapped)
|
62
|
+
resource.update_attributes(common_attributes)
|
63
|
+
resource
|
52
64
|
end
|
53
65
|
|
54
66
|
private
|
55
67
|
|
56
|
-
def
|
68
|
+
def common_attributes_from(mapped)
|
69
|
+
COMMON_ATTRIBUTES.each_with_object({}) do |common_attribute, extract|
|
70
|
+
extracted = mapped.delete(common_attribute)
|
71
|
+
extract[common_attribute] = extracted if extracted
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
def mapped_from(clazz, key, value) # rubocop:disable Metrics/MethodLength
|
57
76
|
if self.class.attribute_methods.include?(key.to_sym)
|
58
77
|
public_send(:"attribute_#{key}", value)
|
59
78
|
elsif clazz.prop?(key)
|
60
79
|
{ key.to_sym => value }
|
80
|
+
elsif clazz.prop?("#{key}_id")
|
81
|
+
{ :"#{key}_id" => Humidifier.ref(value) }
|
82
|
+
elsif COMMON_ATTRIBUTES.include?(key.to_sym)
|
83
|
+
{ key.to_sym => value }
|
61
84
|
else
|
62
85
|
raise Error, "Invalid attribute: #{key}"
|
63
86
|
end
|
@@ -8,14 +8,27 @@ module Humidifier
|
|
8
8
|
class_option :debug, desc: 'Sets up debug mode', aliases: ['-d']
|
9
9
|
class_around :safe_execute
|
10
10
|
|
11
|
+
desc 'change [?stack]', 'Create changesets for one or all stacks'
|
12
|
+
def change(name = nil)
|
13
|
+
stack_names = stack_names_from(name)
|
14
|
+
authorize
|
15
|
+
|
16
|
+
stack_names.each do |stack_name|
|
17
|
+
stack = Stack.new(stack_name)
|
18
|
+
puts "Creating a changeset for #{stack.stack_name}"
|
19
|
+
stack.create_change_set
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
11
23
|
desc 'deploy [?stack]', 'Update one or all stacks'
|
12
24
|
option :wait, desc: 'Wait for the stack to create/update', type: :boolean, default: false
|
25
|
+
option :prefix, desc: 'The prefix to use for the stack'
|
13
26
|
def deploy(name = nil)
|
14
|
-
stack_names = name
|
27
|
+
stack_names = stack_names_from(name)
|
15
28
|
authorize
|
16
29
|
|
17
30
|
stack_names.each do |stack_name|
|
18
|
-
stack = Stack.new(stack_name)
|
31
|
+
stack = Stack.new(stack_name, prefix: options[:prefix])
|
19
32
|
puts "Deploying #{stack.stack_name}"
|
20
33
|
stack.deploy(options[:wait])
|
21
34
|
end
|
@@ -23,12 +36,12 @@ module Humidifier
|
|
23
36
|
|
24
37
|
desc 'display [stack] [?pattern]', 'Display the CloudFormation JSON for a given stack'
|
25
38
|
def display(name, pattern = nil)
|
26
|
-
puts Stack.new(name, pattern && /#{pattern}/i).to_cf
|
39
|
+
puts Stack.new(name, pattern: pattern && /#{pattern}/i).to_cf
|
27
40
|
end
|
28
41
|
|
29
42
|
desc 'validate [?stack]', 'Validate that one or all stacks are valid with CloudFormation'
|
30
43
|
def validate(name = nil)
|
31
|
-
stack_names = name
|
44
|
+
stack_names = stack_names_from(name)
|
32
45
|
authorize
|
33
46
|
|
34
47
|
print 'Validating... '
|
@@ -48,6 +61,10 @@ module Humidifier
|
|
48
61
|
puts error.message
|
49
62
|
exit 1
|
50
63
|
end
|
64
|
+
|
65
|
+
def stack_names_from(name)
|
66
|
+
name ? [name] : Reservoir.stacks
|
67
|
+
end
|
51
68
|
end
|
52
69
|
end
|
53
70
|
end
|
@@ -14,8 +14,8 @@ module Humidifier
|
|
14
14
|
Dir["#{stack_path}/#{name}/*.yml"]
|
15
15
|
end
|
16
16
|
|
17
|
-
def map(type, opts = {})
|
18
|
-
mappings[type.to_sym] = Mapping.new(opts)
|
17
|
+
def map(type, opts = {}, &block)
|
18
|
+
mappings[type.to_sym] = Mapping.new(opts, &block)
|
19
19
|
end
|
20
20
|
|
21
21
|
def mapping_for(type)
|
@@ -6,16 +6,36 @@ module Humidifier
|
|
6
6
|
class Mapping
|
7
7
|
attr_reader :clazz, :mapper
|
8
8
|
|
9
|
-
def initialize(opts = {})
|
10
|
-
@clazz = Humidifier[opts[:to]]
|
9
|
+
def initialize(opts = {}, &block)
|
10
|
+
@clazz = Humidifier[normalized(opts[:to])]
|
11
11
|
raise Error, "Invalid resource: #{opts[:to].inspect}" if @clazz.nil?
|
12
12
|
|
13
|
-
|
13
|
+
if opts[:using] && block_given?
|
14
|
+
raise Error, 'Cannot specify :using and provide an anonymous mapper'
|
15
|
+
end
|
16
|
+
|
17
|
+
@mapper = mapper_from(opts, &block)
|
14
18
|
end
|
15
19
|
|
16
20
|
def resource_for(name, attributes)
|
17
21
|
mapper.resource_for(clazz, name, attributes)
|
18
22
|
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
def mapper_from(opts, &block)
|
27
|
+
if opts[:using]
|
28
|
+
opts[:using].new
|
29
|
+
elsif block_given?
|
30
|
+
Class.new(BaseMapper, &block).new
|
31
|
+
else
|
32
|
+
BaseMapper.new
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def normalized(to)
|
37
|
+
to.start_with?('AWS') ? to : "AWS::#{to}"
|
38
|
+
end
|
19
39
|
end
|
20
40
|
end
|
21
41
|
end
|
@@ -4,18 +4,38 @@ module Humidifier
|
|
4
4
|
# interfacing with humidifier to deploy stacks, validate them, and display
|
5
5
|
# them.
|
6
6
|
class Stack
|
7
|
-
|
7
|
+
# Represents an exported resource in a stack for use in cross-stack
|
8
|
+
# references.
|
9
|
+
Export =
|
10
|
+
Struct.new(:name, :attribute) do
|
11
|
+
def value
|
12
|
+
if attribute.is_a?(String)
|
13
|
+
Humidifier.fn.get_att([name, attribute])
|
14
|
+
else
|
15
|
+
Humidifier.ref(name)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
attr_reader :name, :pattern, :prefix, :exports
|
8
21
|
|
9
|
-
def initialize(name, pattern
|
22
|
+
def initialize(name, pattern: nil, prefix: nil)
|
10
23
|
@name = name
|
11
24
|
@pattern = pattern
|
25
|
+
@prefix = prefix
|
26
|
+
@exports = []
|
27
|
+
end
|
28
|
+
|
29
|
+
def create_change_set
|
30
|
+
return unless ensure_resources
|
31
|
+
valid?
|
32
|
+
|
33
|
+
opts = { capabilities: %w[CAPABILITY_IAM CAPABILITY_NAMED_IAM] }
|
34
|
+
humidifier_stack.create_change_set(opts)
|
12
35
|
end
|
13
36
|
|
14
37
|
def deploy(wait = false)
|
15
|
-
|
16
|
-
puts "Refusing to deploy stack #{humidifier_stack.name} with no resources"
|
17
|
-
return
|
18
|
-
end
|
38
|
+
return unless ensure_resources
|
19
39
|
valid?
|
20
40
|
|
21
41
|
opts = { capabilities: %w[CAPABILITY_IAM CAPABILITY_NAMED_IAM] }
|
@@ -29,7 +49,7 @@ module Humidifier
|
|
29
49
|
end
|
30
50
|
|
31
51
|
def stack_name
|
32
|
-
@stack_name ||= "#{Reservoir.stack_prefix}#{name}"
|
52
|
+
@stack_name ||= "#{prefix || Reservoir.stack_prefix}#{name}"
|
33
53
|
end
|
34
54
|
|
35
55
|
def to_cf
|
@@ -47,14 +67,31 @@ MSG
|
|
47
67
|
|
48
68
|
private
|
49
69
|
|
70
|
+
def ensure_resources
|
71
|
+
return true if humidifier_stack.resources.any?
|
72
|
+
puts "Refusing to deploy stack #{humidifier_stack.name} with no resources"
|
73
|
+
false
|
74
|
+
end
|
75
|
+
|
50
76
|
def humidifier_stack
|
51
77
|
Humidifier::Stack.new(
|
52
78
|
name: stack_name,
|
53
79
|
description: "Resources for #{stack_name}",
|
54
|
-
resources: resources
|
80
|
+
resources: resources,
|
81
|
+
outputs: outputs
|
55
82
|
)
|
56
83
|
end
|
57
84
|
|
85
|
+
def outputs
|
86
|
+
exports.each_with_object({}) do |export, exported|
|
87
|
+
exported[export.name] =
|
88
|
+
Humidifier::Output.new(
|
89
|
+
value: export.value,
|
90
|
+
export_name: export.name
|
91
|
+
)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
58
95
|
def parse(filepath, type)
|
59
96
|
mapping = Reservoir.mapping_for(type)
|
60
97
|
return {} if mapping.nil?
|
@@ -64,6 +101,10 @@ MSG
|
|
64
101
|
|
65
102
|
loaded.each_with_object({}) do |(name, attributes), resources|
|
66
103
|
next if pattern && name !~ pattern
|
104
|
+
|
105
|
+
attribute = attributes.delete('export')
|
106
|
+
exports << Export.new(name, attribute) if attribute
|
107
|
+
|
67
108
|
resources[name] = mapping.resource_for(name, attributes)
|
68
109
|
end
|
69
110
|
end
|