cfer 0.4.2 → 0.5.0.pre.rc1
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/.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
|