cfer 0.4.2 → 0.5.0.pre.rc1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +3 -0
- data/.travis.yml +3 -3
- data/CHANGELOG.md +68 -0
- data/Dockerfile +3 -1
- data/README.md +1 -41
- data/bin/json-to-cfer +82 -0
- data/cfer.gemspec +11 -9
- data/lib/cfer.rb +44 -8
- data/lib/cfer/block.rb +23 -5
- data/lib/cfer/cfn/client.rb +23 -12
- data/lib/cfer/core/functions.rb +86 -0
- data/lib/cfer/core/hooks.rb +42 -0
- data/lib/cfer/core/resource.rb +32 -6
- data/lib/cfer/core/stack.rb +18 -56
- data/lib/cfer/version.rb +1 -1
- data/lib/cferext/aws/cloud_formation/wait_condition.rb +6 -0
- data/lib/cferext/aws/iam/policy_generator.rb +2 -2
- data/lib/cferext/aws/kms/key.rb +7 -0
- data/lib/cferext/aws/rds/db_instance.rb +5 -0
- data/lib/cferext/cfer/stack_validation.rb +52 -0
- metadata +30 -62
- data/lib/cfer/cfn/aws.rb +0 -29
- data/lib/cfer/core/fn.rb +0 -55
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5d9d002adc64d106f800cb61545ae2a62644cdf6
|
4
|
+
data.tar.gz: e6c08b6a6f4d011d23f2b0567f65febb1ebf1a8b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6eb2bd6ddf3bc719faaeb11361662bbd7ac938b5ac2d4e37583e144b6cbdf7a59aa43c585f48f1117d2ace34be4a85d9f38a5b237f338231d84e03b9ce75aac5
|
7
|
+
data.tar.gz: d342f24e5c9329cee1088aed994555be198efea702c063e6a62ef5f5b20843c7319c6c055fe92dc6f00ba821694545e3420507ece940e083d1fc25009ad07431
|
data/.gitignore
CHANGED
data/.travis.yml
CHANGED
data/CHANGELOG.md
ADDED
@@ -0,0 +1,68 @@
|
|
1
|
+
# Cfer Change Log
|
2
|
+
|
3
|
+
## 0.5.0
|
4
|
+
|
5
|
+
### Enhancements
|
6
|
+
* Adds support for Pre-build and Post-build hooks for resources and stacks.
|
7
|
+
* Adds `json-to-cfer` script to automatically convert json templates to Cfer DSL code.
|
8
|
+
* Adds support for directly converging JSON files.
|
9
|
+
* Relaxes some version constraints to make it easier to integrate with older Rails projects.
|
10
|
+
* Pulled stack validation out into an extension using post-build hooks.
|
11
|
+
* Adds some extension methods to improve usability of certain resources.
|
12
|
+
* Namespace cleanup.
|
13
|
+
* Supports reading ruby template from stdin by specifying the filename `-`
|
14
|
+
* Adds exponential backoff to `tail` command.
|
15
|
+
* `--on-failure` flag is now case insensitive.
|
16
|
+
* Various test improvements.
|
17
|
+
|
18
|
+
### Bugfixes
|
19
|
+
* Fixes "Stack does not exist" error being reported when stack creation fails and `--on-failure=DELETE` is specified.
|
20
|
+
|
21
|
+
## 0.4.2
|
22
|
+
|
23
|
+
### Bugfixes
|
24
|
+
* Templates now uploaded to S3 in all cases where they should be.
|
25
|
+
* Fixes extensions (should be `class_eval`, not `instance_eval`)
|
26
|
+
|
27
|
+
## 0.4.0
|
28
|
+
|
29
|
+
### **BREAKING CHANGES**
|
30
|
+
* Provisioning is removed from Cfer core and moved to [cfer-provisioning](https://github.com/seanedwards/cfer-provisioning)
|
31
|
+
|
32
|
+
### Enhancements
|
33
|
+
* Adds support for assume-role authentication with MFA (see: https://docs.aws.amazon.com/cli/latest/userguide/cli-roles.html)
|
34
|
+
* Adds support for yml-format parameter files with environment-specific sections.
|
35
|
+
* Adds a DSL for IAM policies.
|
36
|
+
* Adds `cfer estimate` command to estimate the cost of a template using the AWS CloudFormation cost estimation API.
|
37
|
+
* Enhancements to chef provisioner to allow for references in chef attributes. (Thanks to @eropple)
|
38
|
+
* Adds continue/rollback/quit selection when `^C` is caught during a converge.
|
39
|
+
* Stores Cfer version and Git repo information in the Repo metadata.
|
40
|
+
* Added support for uploading templates to S3 with the `--s3-path` and `--force-s3` options.
|
41
|
+
* Added new way of extending resources, making plugins easier.
|
42
|
+
* Added support for [CloudFormation Change Sets](https://aws.amazon.com/blogs/aws/new-change-sets-for-aws-cloudformation/) via the `--change` option.
|
43
|
+
|
44
|
+
### Bugfixes
|
45
|
+
|
46
|
+
## 0.3.0
|
47
|
+
|
48
|
+
### Enhancements:
|
49
|
+
* `parameters` hash now includes parameters that are set on the existing stack, but not passed in via CLI during a stack update.
|
50
|
+
* `parameters` hash now includes defaults for parameters that were not passed on the CLI during a stack creation.
|
51
|
+
* Adds a `lookup_output` function, for looking up outputs of stacks in the same account+region. (See #8)
|
52
|
+
* Adds provisioning for cfn-init and chef-solo, including resource signaling.
|
53
|
+
* Adds support for stack policies.
|
54
|
+
* Cfer no longer validates parameters itself. CloudFormation will throw an error if something is wrong.
|
55
|
+
* Adds release notes to the README.
|
56
|
+
|
57
|
+
### Bugfixes:
|
58
|
+
* Removes automatic parameter mapping in favor of an explicit function available to resources. (Fixes Issue #8)
|
59
|
+
* No more double-printing the stack summary when converging a stack with tailing enabled.
|
60
|
+
* Update demo to only use 2 AZs, since us-west-1 only has two.
|
61
|
+
* `AllowedValues` attribute on parameters is now an array, not a CSV string. (Thanks to @rlister)
|
62
|
+
|
63
|
+
## 0.2.0
|
64
|
+
|
65
|
+
### Enhancements:
|
66
|
+
* Adds support for including other files via `include_template` function.
|
67
|
+
* Adds basic Dockerfile
|
68
|
+
|
data/Dockerfile
CHANGED
data/README.md
CHANGED
@@ -298,45 +298,5 @@ This project also contains a [Code of Conduct](https://github.com/seanedwards/cf
|
|
298
298
|
|
299
299
|
# Release Notes
|
300
300
|
|
301
|
-
|
302
|
-
|
303
|
-
### **BREAKING CHANGES**
|
304
|
-
* Provisioning is removed from Cfer core and moved to [cfer-provisioning](https://github.com/seanedwards/cfer-provisioning)
|
305
|
-
|
306
|
-
### Enhancements
|
307
|
-
* Adds support for assume-role authentication with MFA (see: https://docs.aws.amazon.com/cli/latest/userguide/cli-roles.html)
|
308
|
-
* Adds support for yml-format parameter files with environment-specific sections.
|
309
|
-
* Adds a DSL for IAM policies.
|
310
|
-
* Adds `cfer estimate` command to estimate the cost of a template using the AWS CloudFormation cost estimation API.
|
311
|
-
* Enhancements to chef provisioner to allow for references in chef attributes. (Thanks to @eropple)
|
312
|
-
* Adds continue/rollback/quit selection when `^C` is caught during a converge.
|
313
|
-
* Stores Cfer version and Git repo information in the Repo metadata.
|
314
|
-
* Added support for uploading templates to S3 with the `--s3-path` and `--force-s3` options.
|
315
|
-
* Added new way of extending resources, making plugins easier.
|
316
|
-
* Added support for [CloudFormation Change Sets](https://aws.amazon.com/blogs/aws/new-change-sets-for-aws-cloudformation/) via the `--change` option.
|
317
|
-
|
318
|
-
### Bugfixes
|
319
|
-
|
320
|
-
## 0.3.0
|
321
|
-
|
322
|
-
### Enhancements:
|
323
|
-
* `parameters` hash now includes parameters that are set on the existing stack, but not passed in via CLI during a stack update.
|
324
|
-
* `parameters` hash now includes defaults for parameters that were not passed on the CLI during a stack creation.
|
325
|
-
* Adds a `lookup_output` function, for looking up outputs of stacks in the same account+region. (See #8)
|
326
|
-
* Adds provisioning for cfn-init and chef-solo, including resource signaling.
|
327
|
-
* Adds support for stack policies.
|
328
|
-
* Cfer no longer validates parameters itself. CloudFormation will throw an error if something is wrong.
|
329
|
-
* Adds release notes to the README.
|
330
|
-
|
331
|
-
### Bugfixes:
|
332
|
-
* Removes automatic parameter mapping in favor of an explicit function available to resources. (Fixes Issue #8)
|
333
|
-
* No more double-printing the stack summary when converging a stack with tailing enabled.
|
334
|
-
* Update demo to only use 2 AZs, since us-west-1 only has two.
|
335
|
-
* `AllowedValues` attribute on parameters is now an array, not a CSV string. (Thanks to @rlister)
|
336
|
-
|
337
|
-
## 0.2.0
|
338
|
-
|
339
|
-
### Enhancements:
|
340
|
-
* Adds support for including other files via `include_template` function.
|
341
|
-
* Adds basic Dockerfile
|
301
|
+
[Change Log](https://github.com/seanedwards/cfer/CHANGELOG.md)
|
342
302
|
|
data/bin/json-to-cfer
ADDED
@@ -0,0 +1,82 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require 'json'
|
3
|
+
require 'pp'
|
4
|
+
require 'active_support/inflector'
|
5
|
+
|
6
|
+
template = JSON.parse(STDIN.read)
|
7
|
+
|
8
|
+
def indent(str, prefix = ' ')
|
9
|
+
prefix + str.gsub("\n", "\n#{prefix}")
|
10
|
+
end
|
11
|
+
|
12
|
+
def serialize_arg(arg, indent=0)
|
13
|
+
ret = ""
|
14
|
+
PP.pp(arg, ret)
|
15
|
+
ret.strip
|
16
|
+
end
|
17
|
+
|
18
|
+
def serialize_args(*args)
|
19
|
+
options = args.last.is_a?(Hash) ? args.pop : {}
|
20
|
+
args_str = []
|
21
|
+
|
22
|
+
args.each do |arg|
|
23
|
+
args_str << serialize_arg(arg)
|
24
|
+
end
|
25
|
+
|
26
|
+
opts_str = []
|
27
|
+
options.each do |k, v|
|
28
|
+
opts_str << "#{serialize_arg(k)}: #{serialize_arg(v)}"
|
29
|
+
end
|
30
|
+
args_str << indent(opts_str.join(",\n"), ' ') unless opts_str.empty?
|
31
|
+
|
32
|
+
args_str.join(', ').strip
|
33
|
+
end
|
34
|
+
|
35
|
+
description = template.delete('Description')
|
36
|
+
parameters = template.delete('Parameters') || {}
|
37
|
+
resources = template.delete('Resources') || {}
|
38
|
+
outputs = template.delete('Outputs') || {}
|
39
|
+
version = template.delete('AWSTemplateFormatVersion')
|
40
|
+
|
41
|
+
if description
|
42
|
+
puts "description #{serialize_arg(description)}"
|
43
|
+
puts ""
|
44
|
+
end
|
45
|
+
|
46
|
+
puts "##############"
|
47
|
+
puts "# Parameters #"
|
48
|
+
puts "##############"
|
49
|
+
|
50
|
+
parameters.each do |k, param|
|
51
|
+
puts "parameter #{serialize_args(k, param)}"
|
52
|
+
puts ""
|
53
|
+
end
|
54
|
+
|
55
|
+
puts "#############"
|
56
|
+
puts "# Resources #"
|
57
|
+
puts "#############"
|
58
|
+
|
59
|
+
resources.each do |k, attrs|
|
60
|
+
properties = attrs.delete('Properties') || {}
|
61
|
+
type = attrs.delete('Type')
|
62
|
+
|
63
|
+
puts "resource #{serialize_args(k, type, attrs)} do"
|
64
|
+
properties.each do |k, v|
|
65
|
+
puts indent("#{k.underscore} #{serialize_args(v)}", ' ')
|
66
|
+
end
|
67
|
+
puts "end"
|
68
|
+
puts ""
|
69
|
+
end
|
70
|
+
|
71
|
+
outputs.each do |k, out|
|
72
|
+
value = out.delete('Value')
|
73
|
+
|
74
|
+
puts "output #{serialize_args(k, value, out)}"
|
75
|
+
end
|
76
|
+
|
77
|
+
puts ""
|
78
|
+
|
79
|
+
template.each do |k, v|
|
80
|
+
puts "self[#{serialize_arg(k)}] = #{serialize_arg(v)}"
|
81
|
+
end
|
82
|
+
|
data/cfer.gemspec
CHANGED
@@ -14,23 +14,25 @@ Gem::Specification.new do |spec|
|
|
14
14
|
spec.homepage = "https://github.com/seanedwards/cfer"
|
15
15
|
spec.license = "MIT"
|
16
16
|
|
17
|
+
spec.required_ruby_version = ['~> 2.2', '>= 2.2.5']
|
18
|
+
|
17
19
|
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
18
20
|
spec.bindir = 'bin'
|
19
|
-
spec.executables = 'cfer'
|
21
|
+
spec.executables = ['cfer', 'json-to-cfer']
|
20
22
|
spec.require_paths = ["lib"]
|
21
23
|
|
22
|
-
spec.add_runtime_dependency 'docile', '~> 1.1'
|
24
|
+
spec.add_runtime_dependency 'docile', '~> 1.1'
|
23
25
|
spec.add_runtime_dependency 'thor', '~> 0.19.1'
|
24
|
-
spec.add_runtime_dependency 'activesupport', '
|
25
|
-
spec.add_runtime_dependency 'aws-sdk', '~> 2.2'
|
26
|
-
spec.add_runtime_dependency 'aws-sdk-resources', '~> 2.2'
|
26
|
+
spec.add_runtime_dependency 'activesupport', '>= 3'
|
27
|
+
spec.add_runtime_dependency 'aws-sdk', '~> 2.2'
|
28
|
+
spec.add_runtime_dependency 'aws-sdk-resources', '~> 2.2'
|
27
29
|
spec.add_runtime_dependency 'preconditions', '~> 0.3.0'
|
28
|
-
spec.add_runtime_dependency 'semantic', '~> 1.4'
|
30
|
+
spec.add_runtime_dependency 'semantic', '~> 1.4'
|
29
31
|
spec.add_runtime_dependency 'rainbow', '~> 2.1'
|
30
|
-
spec.add_runtime_dependency 'highline', '~> 1.7'
|
31
|
-
spec.add_runtime_dependency 'table_print', '~> 1.5'
|
32
|
+
spec.add_runtime_dependency 'highline', '~> 1.7'
|
33
|
+
spec.add_runtime_dependency 'table_print', '~> 1.5'
|
32
34
|
spec.add_runtime_dependency "git", '~> 1.3'
|
33
|
-
spec.add_runtime_dependency "bundler"
|
34
35
|
|
35
36
|
spec.add_development_dependency "yard", '~> 0.8.7.6'
|
37
|
+
spec.add_development_dependency "rake"
|
36
38
|
end
|
data/lib/cfer.rb
CHANGED
@@ -14,9 +14,11 @@ end
|
|
14
14
|
|
15
15
|
# Contains the core Cfer logic
|
16
16
|
module Cfer
|
17
|
+
# Code relating to working with Amazon CloudFormation
|
17
18
|
module Cfn
|
18
19
|
end
|
19
20
|
|
21
|
+
# Code relating to building the CloudFormation document out of the Ruby DSL
|
20
22
|
module Core
|
21
23
|
end
|
22
24
|
|
@@ -50,8 +52,12 @@ module Cfer
|
|
50
52
|
|
51
53
|
class << self
|
52
54
|
|
55
|
+
# Creates or updates a CloudFormation stack
|
56
|
+
# @param stack_name [String] The name of the stack to update
|
57
|
+
# @param options [Hash]
|
53
58
|
def converge!(stack_name, options = {})
|
54
59
|
config(options)
|
60
|
+
options[:on_failure].upcase! if options[:on_failure]
|
55
61
|
tmpl = options[:template] || "#{stack_name}.rb"
|
56
62
|
cfn = options[:aws_options] || {}
|
57
63
|
|
@@ -85,19 +91,29 @@ module Cfer
|
|
85
91
|
end
|
86
92
|
end
|
87
93
|
end
|
94
|
+
describe! stack_name, options rescue nil # It's fine if we can't do this.
|
88
95
|
rescue Aws::CloudFormation::Errors::ValidationError => e
|
89
96
|
Cfer::LOGGER.info "CFN validation error: #{e.message}"
|
90
97
|
end
|
91
|
-
|
98
|
+
stack
|
92
99
|
end
|
93
100
|
|
94
101
|
def describe!(stack_name, options = {})
|
95
102
|
config(options)
|
96
103
|
cfn = options[:aws_options] || {}
|
97
104
|
cfn_stack = options[:cfer_client] || Cfer::Cfn::Client.new(cfn.merge(stack_name: stack_name))
|
105
|
+
cfn_metadata = cfn_stack.fetch_metadata
|
98
106
|
cfn_stack = cfn_stack.fetch_stack
|
99
107
|
|
108
|
+
cfer_version = cfn_metadata.fetch("Cfer", {}).fetch("Version", nil)
|
109
|
+
if cfer_version
|
110
|
+
cfer_version_str = [cfer_version["major"], cfer_version["minor"], cfer_version["patch"]].join '.'
|
111
|
+
cfer_version_str << '-' << cfer_version["pre"] unless cfer_version["pre"].nil?
|
112
|
+
cfer_version_str << '+' << cfer_version["pre"] unless cfer_version["pre"].nil?
|
113
|
+
end
|
114
|
+
|
100
115
|
Cfer::LOGGER.debug "Describe stack: #{cfn_stack}"
|
116
|
+
Cfer::LOGGER.debug "Describe metadata: #{cfn_metadata}"
|
101
117
|
|
102
118
|
case options[:output_format]
|
103
119
|
when 'json'
|
@@ -105,6 +121,7 @@ module Cfer
|
|
105
121
|
when 'table', nil
|
106
122
|
puts "Status: #{cfn_stack[:stack_status]}"
|
107
123
|
puts "Description: #{cfn_stack[:description]}" if cfn_stack[:description]
|
124
|
+
puts "Created with Cfer version: #{Semantic::Version.new(cfer_version_str).to_s} (current: #{Cfer::SEMANTIC_VERSION.to_s})" if cfer_version
|
108
125
|
puts ""
|
109
126
|
def tablify(list, type)
|
110
127
|
list ||= []
|
@@ -122,6 +139,7 @@ module Cfer
|
|
122
139
|
else
|
123
140
|
raise Cfer::Util::CferError, "Invalid output format #{options[:output_format]}."
|
124
141
|
end
|
142
|
+
cfn_stack
|
125
143
|
end
|
126
144
|
|
127
145
|
def tail!(stack_name, options = {}, &block)
|
@@ -135,7 +153,6 @@ module Cfer
|
|
135
153
|
Cfer::LOGGER.info "%s %-30s %-40s %-20s %s" % [event.timestamp, color_map(event.resource_status), event.resource_type, event.logical_resource_id, event.resource_status_reason]
|
136
154
|
end
|
137
155
|
end
|
138
|
-
describe! stack_name, options
|
139
156
|
end
|
140
157
|
|
141
158
|
def generate!(tmpl, options = {})
|
@@ -163,6 +180,10 @@ module Cfer
|
|
163
180
|
cfn = options[:aws_options] || {}
|
164
181
|
cfn_stack = options[:cfer_client] || cfn_stack = Cfer::Cfn::Client.new(cfn.merge(stack_name: stack_name))
|
165
182
|
cfn_stack.delete_stack(stack_name)
|
183
|
+
|
184
|
+
if options[:follow]
|
185
|
+
tail! stack_name, options.merge(cfer_client: cfn_stack)
|
186
|
+
end
|
166
187
|
end
|
167
188
|
|
168
189
|
# Builds a Cfer::Core::Stack from a Ruby block
|
@@ -181,13 +202,31 @@ module Cfer
|
|
181
202
|
|
182
203
|
# Builds a Cfer::Core::Stack from a ruby script
|
183
204
|
#
|
184
|
-
# @param file [String] The file containing the Cfn DSL
|
205
|
+
# @param file [String] The file containing the Cfn DSL or plain JSON
|
185
206
|
# @param options [Hash] (see #stack_from_block)
|
186
207
|
# @return [Cfer::Core::Stack] The assembled stack object
|
187
208
|
def stack_from_file(file, options = {})
|
209
|
+
return stack_from_stdin(options) if file == '-'
|
210
|
+
|
211
|
+
s = Cfer::Core::Stack.new(options)
|
212
|
+
if file.ends_with?('.json')
|
213
|
+
s.deep_merge! JSON.parse(File.read(file))
|
214
|
+
else
|
215
|
+
templatize_errors(file) do
|
216
|
+
s.build_from_file file
|
217
|
+
end
|
218
|
+
end
|
219
|
+
s
|
220
|
+
end
|
221
|
+
|
222
|
+
# Builds a Cfer::Core::Stack from stdin
|
223
|
+
#
|
224
|
+
# @param options [Hash] (see #stack_from_block)
|
225
|
+
# @return [Cfer::Core::Stack] The assembled stack object
|
226
|
+
def stack_from_stdin(options = {})
|
188
227
|
s = Cfer::Core::Stack.new(options)
|
189
|
-
templatize_errors(
|
190
|
-
s.
|
228
|
+
templatize_errors('STDIN') do
|
229
|
+
s.build_from_string STDIN.read, 'STDIN'
|
191
230
|
end
|
192
231
|
s
|
193
232
|
end
|
@@ -198,9 +237,6 @@ module Cfer
|
|
198
237
|
Cfer::LOGGER.debug "Options: #{options}"
|
199
238
|
Cfer::LOGGER.level = Logger::DEBUG if options[:verbose]
|
200
239
|
|
201
|
-
require 'rubygems'
|
202
|
-
require 'bundler/setup'
|
203
|
-
|
204
240
|
Aws.config.update region: options[:region] if options[:region]
|
205
241
|
Aws.config.update credentials: Cfer::Cfn::CferCredentialsProvider.new(profile_name: options[:profile]) if options[:profile]
|
206
242
|
end
|
data/lib/cfer/block.rb
CHANGED
@@ -12,14 +12,22 @@ module Cfer
|
|
12
12
|
self
|
13
13
|
end
|
14
14
|
|
15
|
+
# Evaluates a DSL from a Ruby string
|
16
|
+
# @param args [Array<Object>] Extra arguments to be passed into the block
|
17
|
+
# @param str [String] The Cfer source template to evaluate
|
18
|
+
# @param file [File] The file that will be reported in any error messages
|
19
|
+
def build_from_string(*args, str, file)
|
20
|
+
build_from_block(*args) do
|
21
|
+
instance_eval str, file
|
22
|
+
end
|
23
|
+
self
|
24
|
+
end
|
25
|
+
|
15
26
|
# Evaluates a DSL from a Ruby script file
|
16
27
|
# @param args [Array<Object>] (see: #build_from_block)
|
17
28
|
# @param file [File] The Ruby script to evaluate
|
18
29
|
def build_from_file(*args, file)
|
19
|
-
|
20
|
-
instance_eval File.read(file), file
|
21
|
-
end
|
22
|
-
self
|
30
|
+
build_from_string File.read(file), file
|
23
31
|
end
|
24
32
|
|
25
33
|
# Executed just before the DSL is evaluated
|
@@ -31,13 +39,23 @@ module Cfer
|
|
31
39
|
end
|
32
40
|
end
|
33
41
|
|
42
|
+
# BlockHash is a Block that responds to DSL-style properties.
|
34
43
|
class BlockHash < Block
|
35
|
-
NON_PROXIED_METHODS = [
|
44
|
+
NON_PROXIED_METHODS = [
|
45
|
+
:parameters,
|
46
|
+
:options,
|
47
|
+
:lookup_output,
|
48
|
+
:lookup_outputs
|
49
|
+
].freeze
|
36
50
|
|
51
|
+
# Directly sets raw properties in the underlying CloudFormation structure.
|
52
|
+
# @param keyvals [Hash] The properties to set on this object.
|
37
53
|
def properties(keyvals = {})
|
38
54
|
self.merge!(keyvals)
|
39
55
|
end
|
40
56
|
|
57
|
+
# Gets the current value of a given property
|
58
|
+
# @param key [String] The name of the property to fetch
|
41
59
|
def get_property(key)
|
42
60
|
self.fetch key
|
43
61
|
end
|
data/lib/cfer/cfn/client.rb
CHANGED
@@ -157,6 +157,9 @@ module Cfer::Cfn
|
|
157
157
|
# @param options [Hash] The options hash
|
158
158
|
# @option options [Fixnum] :number The maximum number of already-existing CloudFormation events to yield.
|
159
159
|
# @option options [Boolean] :follow Set to true to wait until the stack enters a `COMPLETE` or `FAILED` state, yielding events as they occur.
|
160
|
+
# @option options [Boolean] :no_sleep Don't pause between polling. This is used for tests, and shouldn't be when polling the AWS API.
|
161
|
+
# @option options [Fixnum] :backoff The exponential backoff factor (default 1.5)
|
162
|
+
# @option options [Fixnum] :backoff_max_wait The maximum amount of time that exponential backoff will wait before polling agian (default 15s)
|
160
163
|
def tail(options = {})
|
161
164
|
q = []
|
162
165
|
event_id_highwater = nil
|
@@ -173,30 +176,38 @@ module Cfer::Cfn
|
|
173
176
|
event_id_highwater = event.event_id
|
174
177
|
end
|
175
178
|
|
179
|
+
sleep_time = 1
|
180
|
+
|
176
181
|
running = true
|
177
182
|
if options[:follow]
|
178
183
|
while running
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
184
|
+
sleep_time = [sleep_time * (options[:backoff] || 1), options[:backoff_max_wait] || 15].min
|
185
|
+
begin
|
186
|
+
stack_status = describe_stacks(stack_name: name).stacks.first.stack_status
|
187
|
+
running = running && (/.+_(COMPLETE|FAILED)$/.match(stack_status) == nil)
|
188
|
+
|
189
|
+
yielding = true
|
190
|
+
for_each_event name do |fetched_event|
|
191
|
+
if event_id_highwater == fetched_event.event_id
|
192
|
+
yielding = false
|
193
|
+
end
|
194
|
+
|
195
|
+
if yielding
|
196
|
+
q.unshift fetched_event
|
197
|
+
end
|
190
198
|
end
|
199
|
+
rescue Aws::CloudFormation::Errors::ValidationError
|
200
|
+
running = false
|
191
201
|
end
|
192
202
|
|
193
203
|
while q.size > 0
|
194
204
|
event = q.shift
|
195
205
|
yield event
|
196
206
|
event_id_highwater = event.event_id
|
207
|
+
sleep_time = 1
|
197
208
|
end
|
198
209
|
|
199
|
-
sleep
|
210
|
+
sleep sleep_time if running unless options[:no_sleep]
|
200
211
|
end
|
201
212
|
end
|
202
213
|
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
# Utility methods to make CloudFormation functions feel more like Ruby
|
2
|
+
module Cfer::Core::Functions
|
3
|
+
def join(sep, *args)
|
4
|
+
{"Fn::Join" => [sep, [ *args ].flatten ]}
|
5
|
+
end
|
6
|
+
|
7
|
+
def ref(r)
|
8
|
+
{"Ref" => r}
|
9
|
+
end
|
10
|
+
|
11
|
+
def get_att(r, att)
|
12
|
+
{"Fn::GetAtt" => [r, att]}
|
13
|
+
end
|
14
|
+
|
15
|
+
def find_in_map(map_name, key1, key2)
|
16
|
+
{"Fn::FindInMap" => [map_name, key1, key2]}
|
17
|
+
end
|
18
|
+
|
19
|
+
def select(i, o)
|
20
|
+
{"Fn::Select" => [i, o]}
|
21
|
+
end
|
22
|
+
|
23
|
+
def base64(v)
|
24
|
+
{"Fn::Base64" => v}
|
25
|
+
end
|
26
|
+
|
27
|
+
def condition(cond)
|
28
|
+
{"Condition" => cond}
|
29
|
+
end
|
30
|
+
|
31
|
+
def and(*conds)
|
32
|
+
{"Fn::And" => conds}
|
33
|
+
end
|
34
|
+
|
35
|
+
def or(*conds)
|
36
|
+
{"Fn::Or" => conds}
|
37
|
+
end
|
38
|
+
|
39
|
+
def equals(a, b)
|
40
|
+
{"Fn::Equals" => [a, b]}
|
41
|
+
end
|
42
|
+
|
43
|
+
def if(cond, t, f)
|
44
|
+
{"Fn::If" => [cond, t, f]}
|
45
|
+
end
|
46
|
+
|
47
|
+
def not(cond)
|
48
|
+
{"Fn::Not" => [cond]}
|
49
|
+
end
|
50
|
+
|
51
|
+
def get_azs(region)
|
52
|
+
{"Fn::GetAZs" => region}
|
53
|
+
end
|
54
|
+
|
55
|
+
def account_id
|
56
|
+
Fn::ref 'AWS::AccountId'
|
57
|
+
end
|
58
|
+
|
59
|
+
def notification_arns
|
60
|
+
Fn::ref 'AWS::NotificationARNs'
|
61
|
+
end
|
62
|
+
|
63
|
+
def no_value
|
64
|
+
Fn::ref 'AWS::NoValue'
|
65
|
+
end
|
66
|
+
|
67
|
+
def region
|
68
|
+
Fn::ref 'AWS::Region'
|
69
|
+
end
|
70
|
+
|
71
|
+
def stack_id
|
72
|
+
Fn::ref 'AWS::StackId'
|
73
|
+
end
|
74
|
+
|
75
|
+
def stack_name
|
76
|
+
Fn::ref 'AWS::StackName'
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
module Cfer::Core::Functions::AWS
|
81
|
+
extend Cfer::Core::Functions
|
82
|
+
end
|
83
|
+
|
84
|
+
module Cfer::Core::Functions::Fn
|
85
|
+
extend Cfer::Core::Functions
|
86
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module Cfer::Core
|
2
|
+
# Provides support for hooking into resource types, and evaluating code before or after properties are set
|
3
|
+
module Hooks
|
4
|
+
def pre_block
|
5
|
+
self.class.pre_hooks.each do |hook|
|
6
|
+
instance_eval &hook
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
def post_block
|
11
|
+
self.class.post_hooks.each do |hook|
|
12
|
+
instance_eval &hook
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.included(base)
|
17
|
+
base.extend(ClassMethods)
|
18
|
+
end
|
19
|
+
|
20
|
+
module ClassMethods
|
21
|
+
def before(&block)
|
22
|
+
self.pre_hooks << block
|
23
|
+
end
|
24
|
+
|
25
|
+
def after(&block)
|
26
|
+
self.post_hooks << block
|
27
|
+
end
|
28
|
+
|
29
|
+
def pre_hooks
|
30
|
+
@pre_hooks ||= []
|
31
|
+
end
|
32
|
+
|
33
|
+
def post_hooks
|
34
|
+
@post_hooks ||= []
|
35
|
+
end
|
36
|
+
|
37
|
+
def inherited(subclass)
|
38
|
+
subclass.include Cfer::Core::Hooks
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
data/lib/cfer/core/resource.rb
CHANGED
@@ -1,41 +1,67 @@
|
|
1
1
|
module Cfer::Core
|
2
2
|
class Resource < Cfer::BlockHash
|
3
|
+
include Cfer::Core::Hooks
|
4
|
+
|
3
5
|
@@types = {}
|
4
6
|
|
5
|
-
|
7
|
+
attr_reader :stack
|
8
|
+
|
9
|
+
def initialize(name, type, stack, **options, &block)
|
6
10
|
@name = name
|
11
|
+
@stack = stack
|
7
12
|
|
8
13
|
self[:Type] = type
|
9
14
|
self.merge!(options)
|
10
15
|
self[:Properties] = HashWithIndifferentAccess.new
|
11
16
|
build_from_block(&block)
|
12
|
-
|
13
17
|
end
|
14
18
|
|
15
|
-
|
19
|
+
# Sets a tag on this resource. The resource must support the CloudFormation `Tags` property.
|
20
|
+
# @param k [String] The name of the tag to set
|
21
|
+
# @param v [String] The value for this tag
|
22
|
+
# @param options [Hash] An arbitrary set of additional properties to be added to this tag, for example `PropagateOnLaunch` on `AWS::AutoScaling::AutoScalingGroup`
|
16
23
|
def tag(k, v, **options)
|
17
24
|
self[:Properties][:Tags] ||= []
|
18
25
|
self[:Properties][:Tags].unshift({"Key" => k, "Value" => v}.merge(options))
|
19
26
|
end
|
20
27
|
|
28
|
+
# Directly sets raw properties in the underlying CloudFormation structure.
|
29
|
+
# @param keyvals [Hash] The properties to set on this object.
|
21
30
|
def properties(keyvals = {})
|
22
31
|
self[:Properties].merge!(keyvals)
|
23
32
|
end
|
24
33
|
|
34
|
+
# Gets the current value of a given property
|
35
|
+
# @param key [String] The name of the property to fetch
|
25
36
|
def get_property(key)
|
26
37
|
self[:Properties].fetch key
|
27
38
|
end
|
28
39
|
|
29
40
|
class << self
|
41
|
+
# Fetches the DSL class for a CloudFormation resource type
|
42
|
+
# @param type [String] The type of resource, for example `AWS::EC2::Instance`
|
43
|
+
# @return [Class] The DSL class representing this resource type, including all extensions
|
30
44
|
def resource_class(type)
|
31
45
|
@@types[type] ||= "CferExt::#{type}".split('::').inject(Object) { |o, c| o.const_get c if o && o.const_defined?(c) } || Class.new(Cfer::Core::Resource)
|
32
46
|
end
|
33
47
|
|
48
|
+
# Patches code into DSL classes for CloudFormation resources
|
49
|
+
# @param type [String] The type of resource, for example `AWS::EC2::Instance`
|
34
50
|
def extend_resource(type, &block)
|
35
|
-
resource_class(type).
|
51
|
+
resource_class(type).class_eval(&block)
|
36
52
|
end
|
37
|
-
end
|
38
53
|
|
39
|
-
|
54
|
+
# Registers a hook that will be run before properties are set on a resource
|
55
|
+
# @param type [String] The type of resource, for example `AWS::EC2::Instance`
|
56
|
+
def before(type, &block)
|
57
|
+
resource_class(type).pre_hooks << block
|
58
|
+
end
|
59
|
+
|
60
|
+
# Registers a hook that will be run after properties have been set on a resource
|
61
|
+
# @param type [String] The type of resource, for example `AWS::EC2::Instance`
|
62
|
+
def after(type, &block)
|
63
|
+
resource_class(type).post_hooks << block
|
64
|
+
end
|
65
|
+
end
|
40
66
|
end
|
41
67
|
end
|
data/lib/cfer/core/stack.rb
CHANGED
@@ -2,8 +2,8 @@ module Cfer::Core
|
|
2
2
|
|
3
3
|
# Defines the structure of a CloudFormation stack
|
4
4
|
class Stack < Cfer::Block
|
5
|
-
include Cfer::Core
|
6
|
-
include Cfer::
|
5
|
+
include Cfer::Core::Functions
|
6
|
+
include Cfer::Core::Hooks
|
7
7
|
|
8
8
|
# The parameters strictly as passed via command line
|
9
9
|
attr_reader :input_parameters
|
@@ -137,7 +137,7 @@ module Cfer::Core
|
|
137
137
|
Preconditions.check_argument(/[[:alnum:]]+/ =~ name, "Resource name must be alphanumeric")
|
138
138
|
|
139
139
|
clazz = Cfer::Core::Resource.resource_class(type)
|
140
|
-
rc = clazz.new(name, type, options, &block)
|
140
|
+
rc = clazz.new(name, type, self, options, &block)
|
141
141
|
|
142
142
|
self[:Resources][name] = rc
|
143
143
|
rc
|
@@ -158,6 +158,7 @@ module Cfer::Core
|
|
158
158
|
to_h.to_json
|
159
159
|
end
|
160
160
|
|
161
|
+
# Gets the Cfn client, if one exists, or throws an error if one does not
|
161
162
|
def client
|
162
163
|
@options[:client] || raise(Cfer::Util::CferError, "Stack has no associated client.")
|
163
164
|
end
|
@@ -168,71 +169,32 @@ module Cfer::Core
|
|
168
169
|
include_base = options[:include_base] || File.dirname(caller.first.split(/:\d/,2).first)
|
169
170
|
files.each do |file|
|
170
171
|
path = File.join(include_base, file)
|
171
|
-
|
172
|
+
if path.ends_with?('.json')
|
173
|
+
self.deep_merge! JSON.parse(File.read(path))
|
174
|
+
else
|
175
|
+
instance_eval(File.read(path), path)
|
176
|
+
end
|
172
177
|
end
|
173
178
|
end
|
174
179
|
|
180
|
+
# Looks up a specific output of another CloudFormation stack in the same region.
|
181
|
+
# @param stack [String] The name of the stack to fetch an output from
|
182
|
+
# @param out [String] The name of the output to fetch from the stack
|
175
183
|
def lookup_output(stack, out)
|
176
|
-
|
177
|
-
client.fetch_output(stack, out)
|
184
|
+
lookup_outputs(stack).fetch(out)
|
178
185
|
end
|
179
186
|
|
187
|
+
# Looks up a hash of all outputs from another CloudFormation stack in the same region.
|
188
|
+
# @param stack [String] The name of the stack to fetch outputs from
|
180
189
|
def lookup_outputs(stack)
|
181
190
|
client = @options[:client] || raise(Cfer::Util::CferError, "Can not fetch stack outputs without a client")
|
182
191
|
client.fetch_outputs(stack)
|
183
192
|
end
|
184
193
|
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
begin
|
189
|
-
validate_stack!(self)
|
190
|
-
rescue Cfer::Util::CferValidationError => e
|
191
|
-
Cfer::LOGGER.error "Cfer detected #{e.errors.size > 1 ? 'errors' : 'an error'} when generating the stack:"
|
192
|
-
e.errors.each do |err|
|
193
|
-
Cfer::LOGGER.error "* #{err[:error]} in Stack#{validation_contextualize(err[:context])}"
|
194
|
-
end
|
195
|
-
raise e
|
196
|
-
end
|
197
|
-
end
|
198
|
-
|
199
|
-
def validate_stack!(hash)
|
200
|
-
errors = []
|
201
|
-
context = []
|
202
|
-
_inner_validate_stack!(hash, errors, context)
|
203
|
-
|
204
|
-
raise Cfer::Util::CferValidationError, errors unless errors.empty?
|
205
|
-
end
|
206
|
-
|
207
|
-
def _inner_validate_stack!(hash, errors = [], context = [])
|
208
|
-
case hash
|
209
|
-
when Hash
|
210
|
-
hash.each do |k, v|
|
211
|
-
_inner_validate_stack!(v, errors, context + [k])
|
212
|
-
end
|
213
|
-
when Array
|
214
|
-
hash.each_index do |i|
|
215
|
-
_inner_validate_stack!(hash[i], errors, context + [i])
|
216
|
-
end
|
217
|
-
when nil
|
218
|
-
errors << {
|
219
|
-
error: "CloudFormation does not allow nulls in templates",
|
220
|
-
context: context
|
221
|
-
}
|
222
|
-
end
|
223
|
-
end
|
224
|
-
|
225
|
-
def validation_contextualize(err_ctx)
|
226
|
-
err_ctx.inject("") do |err_str, ctx|
|
227
|
-
err_str <<
|
228
|
-
case ctx
|
229
|
-
when String
|
230
|
-
".#{ctx}"
|
231
|
-
when Numeric
|
232
|
-
"[#{ctx}]"
|
233
|
-
end
|
194
|
+
class << self
|
195
|
+
def extend_stack(&block)
|
196
|
+
class_eval(&block)
|
234
197
|
end
|
235
198
|
end
|
236
199
|
end
|
237
|
-
|
238
200
|
end
|
data/lib/cfer/version.rb
CHANGED
@@ -10,7 +10,7 @@ module CferExt
|
|
10
10
|
end
|
11
11
|
|
12
12
|
def statement(options = {}, &block)
|
13
|
-
statement = Cfer::BlockHash.new(&block)
|
13
|
+
statement = ::Cfer::BlockHash.new(&block)
|
14
14
|
statement.merge! options
|
15
15
|
statement.build_from_block(&block)
|
16
16
|
self[:Statement].unshift statement
|
@@ -34,7 +34,7 @@ module CferExt
|
|
34
34
|
doc = CferExt::AWS::IAM.generate_policy(&block) if doc == nil
|
35
35
|
get_property(:Policies) << {
|
36
36
|
PolicyName: name,
|
37
|
-
PolicyDocument: doc
|
37
|
+
PolicyDocument: doc
|
38
38
|
}
|
39
39
|
end
|
40
40
|
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
Cfer::Core::Stack.extend_stack do
|
2
|
+
def validate_stack!(hash)
|
3
|
+
errors = []
|
4
|
+
context = []
|
5
|
+
_inner_validate_stack!(hash, errors, context)
|
6
|
+
|
7
|
+
raise Cfer::Util::CferValidationError, errors unless errors.empty?
|
8
|
+
end
|
9
|
+
|
10
|
+
def _inner_validate_stack!(hash, errors = [], context = [])
|
11
|
+
case hash
|
12
|
+
when Hash
|
13
|
+
hash.each do |k, v|
|
14
|
+
_inner_validate_stack!(v, errors, context + [k])
|
15
|
+
end
|
16
|
+
when Array
|
17
|
+
hash.each_index do |i|
|
18
|
+
_inner_validate_stack!(hash[i], errors, context + [i])
|
19
|
+
end
|
20
|
+
when nil
|
21
|
+
errors << {
|
22
|
+
error: "CloudFormation does not allow nulls in templates",
|
23
|
+
context: context
|
24
|
+
}
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def validation_contextualize(err_ctx)
|
29
|
+
err_ctx.inject("") do |err_str, ctx|
|
30
|
+
err_str <<
|
31
|
+
case ctx
|
32
|
+
when String
|
33
|
+
".#{ctx}"
|
34
|
+
when Numeric
|
35
|
+
"[#{ctx}]"
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
Cfer::Core::Stack.after do
|
42
|
+
begin
|
43
|
+
validate_stack!(self)
|
44
|
+
rescue Cfer::Util::CferValidationError => e
|
45
|
+
Cfer::LOGGER.error "Cfer detected #{e.errors.size > 1 ? 'errors' : 'an error'} when generating the stack:"
|
46
|
+
e.errors.each do |err|
|
47
|
+
Cfer::LOGGER.error "* #{err[:error]} in Stack#{validation_contextualize(err[:context])}"
|
48
|
+
end
|
49
|
+
raise e
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cfer
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.5.0.pre.rc1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sean Edwards
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-
|
11
|
+
date: 2016-08-29 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: docile
|
@@ -17,9 +17,6 @@ dependencies:
|
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
19
|
version: '1.1'
|
20
|
-
- - ">="
|
21
|
-
- !ruby/object:Gem::Version
|
22
|
-
version: 1.1.5
|
23
20
|
type: :runtime
|
24
21
|
prerelease: false
|
25
22
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -27,9 +24,6 @@ dependencies:
|
|
27
24
|
- - "~>"
|
28
25
|
- !ruby/object:Gem::Version
|
29
26
|
version: '1.1'
|
30
|
-
- - ">="
|
31
|
-
- !ruby/object:Gem::Version
|
32
|
-
version: 1.1.5
|
33
27
|
- !ruby/object:Gem::Dependency
|
34
28
|
name: thor
|
35
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -48,22 +42,16 @@ dependencies:
|
|
48
42
|
name: activesupport
|
49
43
|
requirement: !ruby/object:Gem::Requirement
|
50
44
|
requirements:
|
51
|
-
- - "~>"
|
52
|
-
- !ruby/object:Gem::Version
|
53
|
-
version: '4.2'
|
54
45
|
- - ">="
|
55
46
|
- !ruby/object:Gem::Version
|
56
|
-
version:
|
47
|
+
version: '3'
|
57
48
|
type: :runtime
|
58
49
|
prerelease: false
|
59
50
|
version_requirements: !ruby/object:Gem::Requirement
|
60
51
|
requirements:
|
61
|
-
- - "~>"
|
62
|
-
- !ruby/object:Gem::Version
|
63
|
-
version: '4.2'
|
64
52
|
- - ">="
|
65
53
|
- !ruby/object:Gem::Version
|
66
|
-
version:
|
54
|
+
version: '3'
|
67
55
|
- !ruby/object:Gem::Dependency
|
68
56
|
name: aws-sdk
|
69
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -71,9 +59,6 @@ dependencies:
|
|
71
59
|
- - "~>"
|
72
60
|
- !ruby/object:Gem::Version
|
73
61
|
version: '2.2'
|
74
|
-
- - ">="
|
75
|
-
- !ruby/object:Gem::Version
|
76
|
-
version: 2.2.33
|
77
62
|
type: :runtime
|
78
63
|
prerelease: false
|
79
64
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -81,9 +66,6 @@ dependencies:
|
|
81
66
|
- - "~>"
|
82
67
|
- !ruby/object:Gem::Version
|
83
68
|
version: '2.2'
|
84
|
-
- - ">="
|
85
|
-
- !ruby/object:Gem::Version
|
86
|
-
version: 2.2.33
|
87
69
|
- !ruby/object:Gem::Dependency
|
88
70
|
name: aws-sdk-resources
|
89
71
|
requirement: !ruby/object:Gem::Requirement
|
@@ -91,9 +73,6 @@ dependencies:
|
|
91
73
|
- - "~>"
|
92
74
|
- !ruby/object:Gem::Version
|
93
75
|
version: '2.2'
|
94
|
-
- - ">="
|
95
|
-
- !ruby/object:Gem::Version
|
96
|
-
version: 2.2.33
|
97
76
|
type: :runtime
|
98
77
|
prerelease: false
|
99
78
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -101,9 +80,6 @@ dependencies:
|
|
101
80
|
- - "~>"
|
102
81
|
- !ruby/object:Gem::Version
|
103
82
|
version: '2.2'
|
104
|
-
- - ">="
|
105
|
-
- !ruby/object:Gem::Version
|
106
|
-
version: 2.2.33
|
107
83
|
- !ruby/object:Gem::Dependency
|
108
84
|
name: preconditions
|
109
85
|
requirement: !ruby/object:Gem::Requirement
|
@@ -125,9 +101,6 @@ dependencies:
|
|
125
101
|
- - "~>"
|
126
102
|
- !ruby/object:Gem::Version
|
127
103
|
version: '1.4'
|
128
|
-
- - ">="
|
129
|
-
- !ruby/object:Gem::Version
|
130
|
-
version: 1.4.1
|
131
104
|
type: :runtime
|
132
105
|
prerelease: false
|
133
106
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -135,9 +108,6 @@ dependencies:
|
|
135
108
|
- - "~>"
|
136
109
|
- !ruby/object:Gem::Version
|
137
110
|
version: '1.4'
|
138
|
-
- - ">="
|
139
|
-
- !ruby/object:Gem::Version
|
140
|
-
version: 1.4.1
|
141
111
|
- !ruby/object:Gem::Dependency
|
142
112
|
name: rainbow
|
143
113
|
requirement: !ruby/object:Gem::Requirement
|
@@ -159,9 +129,6 @@ dependencies:
|
|
159
129
|
- - "~>"
|
160
130
|
- !ruby/object:Gem::Version
|
161
131
|
version: '1.7'
|
162
|
-
- - ">="
|
163
|
-
- !ruby/object:Gem::Version
|
164
|
-
version: 1.7.8
|
165
132
|
type: :runtime
|
166
133
|
prerelease: false
|
167
134
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -169,9 +136,6 @@ dependencies:
|
|
169
136
|
- - "~>"
|
170
137
|
- !ruby/object:Gem::Version
|
171
138
|
version: '1.7'
|
172
|
-
- - ">="
|
173
|
-
- !ruby/object:Gem::Version
|
174
|
-
version: 1.7.8
|
175
139
|
- !ruby/object:Gem::Dependency
|
176
140
|
name: table_print
|
177
141
|
requirement: !ruby/object:Gem::Requirement
|
@@ -179,9 +143,6 @@ dependencies:
|
|
179
143
|
- - "~>"
|
180
144
|
- !ruby/object:Gem::Version
|
181
145
|
version: '1.5'
|
182
|
-
- - ">="
|
183
|
-
- !ruby/object:Gem::Version
|
184
|
-
version: 1.5.6
|
185
146
|
type: :runtime
|
186
147
|
prerelease: false
|
187
148
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -189,9 +150,6 @@ dependencies:
|
|
189
150
|
- - "~>"
|
190
151
|
- !ruby/object:Gem::Version
|
191
152
|
version: '1.5'
|
192
|
-
- - ">="
|
193
|
-
- !ruby/object:Gem::Version
|
194
|
-
version: 1.5.6
|
195
153
|
- !ruby/object:Gem::Dependency
|
196
154
|
name: git
|
197
155
|
requirement: !ruby/object:Gem::Requirement
|
@@ -207,38 +165,39 @@ dependencies:
|
|
207
165
|
- !ruby/object:Gem::Version
|
208
166
|
version: '1.3'
|
209
167
|
- !ruby/object:Gem::Dependency
|
210
|
-
name:
|
168
|
+
name: yard
|
211
169
|
requirement: !ruby/object:Gem::Requirement
|
212
170
|
requirements:
|
213
|
-
- - "
|
171
|
+
- - "~>"
|
214
172
|
- !ruby/object:Gem::Version
|
215
|
-
version:
|
216
|
-
type: :
|
173
|
+
version: 0.8.7.6
|
174
|
+
type: :development
|
217
175
|
prerelease: false
|
218
176
|
version_requirements: !ruby/object:Gem::Requirement
|
219
177
|
requirements:
|
220
|
-
- - "
|
178
|
+
- - "~>"
|
221
179
|
- !ruby/object:Gem::Version
|
222
|
-
version:
|
180
|
+
version: 0.8.7.6
|
223
181
|
- !ruby/object:Gem::Dependency
|
224
|
-
name:
|
182
|
+
name: rake
|
225
183
|
requirement: !ruby/object:Gem::Requirement
|
226
184
|
requirements:
|
227
|
-
- - "
|
185
|
+
- - ">="
|
228
186
|
- !ruby/object:Gem::Version
|
229
|
-
version: 0
|
187
|
+
version: '0'
|
230
188
|
type: :development
|
231
189
|
prerelease: false
|
232
190
|
version_requirements: !ruby/object:Gem::Requirement
|
233
191
|
requirements:
|
234
|
-
- - "
|
192
|
+
- - ">="
|
235
193
|
- !ruby/object:Gem::Version
|
236
|
-
version: 0
|
194
|
+
version: '0'
|
237
195
|
description: Toolkit for automating infrastructure using AWS CloudFormation
|
238
196
|
email:
|
239
197
|
- stedwards87+cfer@gmail.com
|
240
198
|
executables:
|
241
199
|
- cfer
|
200
|
+
- json-to-cfer
|
242
201
|
extensions: []
|
243
202
|
extra_rdoc_files: []
|
244
203
|
files:
|
@@ -248,6 +207,7 @@ files:
|
|
248
207
|
- ".rubocop.yml"
|
249
208
|
- ".travis.yml"
|
250
209
|
- ".yardopts"
|
210
|
+
- CHANGELOG.md
|
251
211
|
- CODE_OF_CONDUCT.md
|
252
212
|
- Dockerfile
|
253
213
|
- Gemfile
|
@@ -257,6 +217,7 @@ files:
|
|
257
217
|
- bin/cfer
|
258
218
|
- bin/cfer-dbg
|
259
219
|
- bin/console
|
220
|
+
- bin/json-to-cfer
|
260
221
|
- bin/setup
|
261
222
|
- cfer.gemspec
|
262
223
|
- doc/cfer-demo.gif
|
@@ -265,19 +226,23 @@ files:
|
|
265
226
|
- examples/vpc.rb
|
266
227
|
- lib/cfer.rb
|
267
228
|
- lib/cfer/block.rb
|
268
|
-
- lib/cfer/cfn/aws.rb
|
269
229
|
- lib/cfer/cfn/cfer_credentials_provider.rb
|
270
230
|
- lib/cfer/cfn/client.rb
|
271
231
|
- lib/cfer/cli.rb
|
272
232
|
- lib/cfer/core/client.rb
|
273
|
-
- lib/cfer/core/
|
233
|
+
- lib/cfer/core/functions.rb
|
234
|
+
- lib/cfer/core/hooks.rb
|
274
235
|
- lib/cfer/core/resource.rb
|
275
236
|
- lib/cfer/core/stack.rb
|
276
237
|
- lib/cfer/util/error.rb
|
277
238
|
- lib/cfer/version.rb
|
278
239
|
- lib/cferext/aws/auto_scaling/auto_scaling_group.rb
|
240
|
+
- lib/cferext/aws/cloud_formation/wait_condition.rb
|
279
241
|
- lib/cferext/aws/iam/policy.rb
|
280
242
|
- lib/cferext/aws/iam/policy_generator.rb
|
243
|
+
- lib/cferext/aws/kms/key.rb
|
244
|
+
- lib/cferext/aws/rds/db_instance.rb
|
245
|
+
- lib/cferext/cfer/stack_validation.rb
|
281
246
|
homepage: https://github.com/seanedwards/cfer
|
282
247
|
licenses:
|
283
248
|
- MIT
|
@@ -288,14 +253,17 @@ require_paths:
|
|
288
253
|
- lib
|
289
254
|
required_ruby_version: !ruby/object:Gem::Requirement
|
290
255
|
requirements:
|
256
|
+
- - "~>"
|
257
|
+
- !ruby/object:Gem::Version
|
258
|
+
version: '2.2'
|
291
259
|
- - ">="
|
292
260
|
- !ruby/object:Gem::Version
|
293
|
-
version:
|
261
|
+
version: 2.2.5
|
294
262
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
295
263
|
requirements:
|
296
|
-
- - "
|
264
|
+
- - ">"
|
297
265
|
- !ruby/object:Gem::Version
|
298
|
-
version:
|
266
|
+
version: 1.3.1
|
299
267
|
requirements: []
|
300
268
|
rubyforge_project:
|
301
269
|
rubygems_version: 2.5.1
|
data/lib/cfer/cfn/aws.rb
DELETED
@@ -1,29 +0,0 @@
|
|
1
|
-
module Cfer::Cfn::AWS
|
2
|
-
class << self
|
3
|
-
include Cfer::Core
|
4
|
-
def account_id
|
5
|
-
Fn::ref 'AWS::AccountId'
|
6
|
-
end
|
7
|
-
|
8
|
-
def notification_arns
|
9
|
-
Fn::ref 'AWS::NotificationARNs'
|
10
|
-
end
|
11
|
-
|
12
|
-
def no_value
|
13
|
-
Fn::ref 'AWS::NoValue'
|
14
|
-
end
|
15
|
-
|
16
|
-
def region
|
17
|
-
Fn::ref 'AWS::Region'
|
18
|
-
end
|
19
|
-
|
20
|
-
def stack_id
|
21
|
-
Fn::ref 'AWS::StackId'
|
22
|
-
end
|
23
|
-
|
24
|
-
def stack_name
|
25
|
-
Fn::ref 'AWS::StackName'
|
26
|
-
end
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
data/lib/cfer/core/fn.rb
DELETED
@@ -1,55 +0,0 @@
|
|
1
|
-
module Cfer::Core::Fn
|
2
|
-
class << self
|
3
|
-
def join(sep, *args)
|
4
|
-
{"Fn::Join" => [sep, [ *args ].flatten ]}
|
5
|
-
end
|
6
|
-
|
7
|
-
def ref(r)
|
8
|
-
{"Ref" => r}
|
9
|
-
end
|
10
|
-
|
11
|
-
def get_att(r, att)
|
12
|
-
{"Fn::GetAtt" => [r, att]}
|
13
|
-
end
|
14
|
-
|
15
|
-
def find_in_map(map_name, key1, key2)
|
16
|
-
{"Fn::FindInMap" => [map_name, key1, key2]}
|
17
|
-
end
|
18
|
-
|
19
|
-
def select(i, o)
|
20
|
-
{"Fn::Select" => [i, o]}
|
21
|
-
end
|
22
|
-
|
23
|
-
def base64(v)
|
24
|
-
{"Fn::Base64" => v}
|
25
|
-
end
|
26
|
-
|
27
|
-
def condition(cond)
|
28
|
-
{"Condition" => cond}
|
29
|
-
end
|
30
|
-
|
31
|
-
def and(*conds)
|
32
|
-
{"Fn::And" => conds}
|
33
|
-
end
|
34
|
-
|
35
|
-
def or(*conds)
|
36
|
-
{"Fn::Or" => conds}
|
37
|
-
end
|
38
|
-
|
39
|
-
def equals(a, b)
|
40
|
-
{"Fn::Equals" => [a, b]}
|
41
|
-
end
|
42
|
-
|
43
|
-
def if(cond, t, f)
|
44
|
-
{"Fn::If" => [cond, t, f]}
|
45
|
-
end
|
46
|
-
|
47
|
-
def not(cond)
|
48
|
-
{"Fn::Not" => [cond]}
|
49
|
-
end
|
50
|
-
|
51
|
-
def get_azs(region)
|
52
|
-
{"Fn::GetAZs" => region}
|
53
|
-
end
|
54
|
-
end
|
55
|
-
end
|