cloud_shaped 1.0.0 → 1.1.0
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/.rubocop.yml +47 -0
- data/.travis.yml +5 -0
- data/Gemfile +1 -1
- data/README.md +45 -0
- data/Rakefile +1 -1
- data/cloud_shaped.gemspec +5 -5
- data/examples/buckets.rb +2 -2
- data/examples/macro.rb +2 -2
- data/examples/simple.rb +3 -3
- data/lib/cloud_shaped/camelate.rb +1 -1
- data/lib/cloud_shaped/core_methods.rb +2 -2
- data/lib/cloud_shaped/dsl.rb +4 -4
- data/lib/cloud_shaped/function_methods.rb +40 -0
- data/lib/cloud_shaped/interpolation.rb +15 -8
- data/lib/cloud_shaped/sns_methods.rb +5 -6
- data/lib/cloud_shaped/template_builder.rb +22 -6
- data/lib/cloud_shaped/version.rb +1 -1
- data/spec/cloud_shaped/camelate_spec.rb +2 -2
- data/spec/cloud_shaped/core_methods_spec.rb +4 -4
- data/spec/cloud_shaped/function_methods_spec.rb +59 -8
- data/spec/cloud_shaped/interpolation_spec.rb +64 -52
- data/spec/cloud_shaped/sns_methods_spec.rb +2 -3
- data/spec/cloud_shaped/template_builder_spec.rb +28 -12
- data/spec/cloud_shaped_spec.rb +3 -3
- metadata +19 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 267754ee0088b83995297f3751b2318b38c081d2
|
4
|
+
data.tar.gz: 5a66197c33f5dc4e1b116592c4a1f867e212e311
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a9b79759612fa41c182b3bd3831dbc7e89278fd97438ef69831467882c5bcaf85c7c4be3644964110ba73ff2d533d0d6728087e107bcfd52e203457a29e16160
|
7
|
+
data.tar.gz: 40c8fc91d0edfe90a57e7ee568694982b6effb3e2de3604da5108fc0c8881c28c30918241261dc8ef60d9cd5fe0cc7051981f5c96aa44e1a2be8c29a635ec608
|
data/.rubocop.yml
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
Eval:
|
2
|
+
Exclude:
|
3
|
+
- "Rakefile"
|
4
|
+
|
5
|
+
Metrics/AbcSize:
|
6
|
+
Enabled: false
|
7
|
+
|
8
|
+
Metrics/LineLength:
|
9
|
+
Max: 120
|
10
|
+
|
11
|
+
Metrics/MethodLength:
|
12
|
+
Max: 30
|
13
|
+
|
14
|
+
Style/ClassAndModuleChildren:
|
15
|
+
EnforcedStyle: nested
|
16
|
+
Exclude:
|
17
|
+
- "spec/**/*"
|
18
|
+
|
19
|
+
Style/Documentation:
|
20
|
+
Exclude:
|
21
|
+
- "spec/**/*"
|
22
|
+
|
23
|
+
Style/EmptyLinesAroundBlockBody:
|
24
|
+
Enabled: false
|
25
|
+
|
26
|
+
Style/EmptyLinesAroundClassBody:
|
27
|
+
EnforcedStyle: empty_lines
|
28
|
+
|
29
|
+
Style/EmptyLinesAroundModuleBody:
|
30
|
+
Enabled: false
|
31
|
+
|
32
|
+
Style/Encoding:
|
33
|
+
EnforcedStyle: when_needed
|
34
|
+
Enabled: true
|
35
|
+
|
36
|
+
Style/FileName:
|
37
|
+
Exclude:
|
38
|
+
- "bin/*"
|
39
|
+
|
40
|
+
Style/HashSyntax:
|
41
|
+
EnforcedStyle: hash_rockets
|
42
|
+
|
43
|
+
Style/StringLiterals:
|
44
|
+
EnforcedStyle: double_quotes
|
45
|
+
|
46
|
+
Style/WordArray:
|
47
|
+
Enabled: false
|
data/.travis.yml
ADDED
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -1,5 +1,8 @@
|
|
1
1
|
# CloudShaped
|
2
2
|
|
3
|
+
[](http://badge.fury.io/rb/cloud_shaped)
|
4
|
+
[](http://travis-ci.org/mdub/cloud_shaped)
|
5
|
+
|
3
6
|
Infrastructure as <del>data</del> code.
|
4
7
|
|
5
8
|
[CloudFormation][cloud_formation] provides a nice way to provision AWS resources in a declarative way. But, programming in JSON can be painful.
|
@@ -79,6 +82,48 @@ Typically, the "type" argument will be a string specifying a CloudFormation reso
|
|
79
82
|
|
80
83
|
t.def_resource "adminEmail", :email_topic, "mdub@example.com"
|
81
84
|
|
85
|
+
### Text interpolation
|
86
|
+
|
87
|
+
Sometimes it's necessary to embed files or even scripts in a CloudFormation template, but include references to stack parameters or resources; the resulting mess of "Fn::Join" and "Fn::GetAtt" can be hard to follow.
|
88
|
+
|
89
|
+
CloudShaped's `interpolate` function makes it easier; it detects references of the form `{{RESOURCE}}` or `{{RESOURCE.ATTRIBUTE}}` in a string, and generates "Ref" and "Fn::GetAtt" as appropriate, e.g.
|
90
|
+
|
91
|
+
```ruby
|
92
|
+
script = <<-'BASH'
|
93
|
+
#!/bin/sh
|
94
|
+
... stuff ...
|
95
|
+
/usr/local/bin/cfn-signal -e 0 \
|
96
|
+
--stack {{AWS::StackName}} --region {{AWS::Region}} \
|
97
|
+
--resource thisHereInstance
|
98
|
+
BASH
|
99
|
+
|
100
|
+
t.interpolate(script) #=> ...
|
101
|
+
{
|
102
|
+
"Fn::Join" =>
|
103
|
+
[
|
104
|
+
"\n",
|
105
|
+
[
|
106
|
+
"#!/bin/sh",
|
107
|
+
"... stuff ...",
|
108
|
+
"/usr/local/bin/cfn-signal -e 0 \\",
|
109
|
+
{
|
110
|
+
"Fn::Join" => [
|
111
|
+
"",
|
112
|
+
[
|
113
|
+
" --stack ",
|
114
|
+
{ "Ref" => "AWS::StackName" },
|
115
|
+
" --region ",
|
116
|
+
{ "Ref" => "AWS::Region" },
|
117
|
+
" \\"
|
118
|
+
]
|
119
|
+
]
|
120
|
+
},
|
121
|
+
" --resource thisHereInstance"
|
122
|
+
]
|
123
|
+
]
|
124
|
+
}
|
125
|
+
```
|
126
|
+
|
82
127
|
## Full documentation
|
83
128
|
|
84
129
|
For more info on the DSL, see:
|
data/Rakefile
CHANGED
data/cloud_shaped.gemspec
CHANGED
@@ -1,15 +1,14 @@
|
|
1
|
-
|
2
|
-
lib = File.expand_path('../lib', __FILE__)
|
1
|
+
lib = File.expand_path("../lib", __FILE__)
|
3
2
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
-
require
|
3
|
+
require "cloud_shaped/version"
|
5
4
|
|
6
5
|
Gem::Specification.new do |gem|
|
7
6
|
|
8
7
|
gem.name = "cloud_shaped"
|
9
8
|
gem.version = CloudShaped::VERSION
|
10
9
|
|
11
|
-
gem.summary =
|
12
|
-
gem.description =
|
10
|
+
gem.summary = "DSL for AWS CloudFormation templates."
|
11
|
+
gem.description = "CloudShaped makes it easier to generate CloudFormation templates, using a Builder-like DSL."
|
13
12
|
|
14
13
|
gem.authors = ["Mike Williams"]
|
15
14
|
gem.email = ["mdub@dogbiscuit.org"]
|
@@ -25,5 +24,6 @@ Gem::Specification.new do |gem|
|
|
25
24
|
gem.add_development_dependency "bundler", "~> 1.6"
|
26
25
|
gem.add_development_dependency "rake"
|
27
26
|
gem.add_development_dependency "rspec"
|
27
|
+
gem.add_development_dependency "rubocop", "~> 0.32"
|
28
28
|
|
29
29
|
end
|
data/examples/buckets.rb
CHANGED
data/examples/macro.rb
CHANGED
data/examples/simple.rb
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
#! /usr/bin/env ruby
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
3
|
+
require "cloud_shaped"
|
4
|
+
require "yaml"
|
5
5
|
|
6
6
|
template = CloudShaped.template do
|
7
7
|
|
8
8
|
self.description = "Make a bucket"
|
9
9
|
|
10
|
-
|
10
|
+
metadata["foo"] = {
|
11
11
|
"bar" => "baz"
|
12
12
|
}
|
13
13
|
|
@@ -20,7 +20,7 @@ module CloudShaped
|
|
20
20
|
def resource(type, properties = {}, attributes = {})
|
21
21
|
properties = properties.camelate_keys
|
22
22
|
yield properties, attributes if block_given?
|
23
|
-
properties.select! { |
|
23
|
+
properties.select! { |_k, v| !v.nil? }
|
24
24
|
attributes.merge(
|
25
25
|
"Type" => type,
|
26
26
|
"Properties" => properties
|
@@ -77,7 +77,7 @@ module CloudShaped
|
|
77
77
|
# tags("application" => "atlas", "version" => "1.2.3")
|
78
78
|
#
|
79
79
|
def tags(tag_map, extra_properties = {})
|
80
|
-
tag_map.map { |k,v| tag(k,v, extra_properties) }
|
80
|
+
tag_map.map { |k, v| tag(k, v, extra_properties) }
|
81
81
|
end
|
82
82
|
|
83
83
|
# Returns a resource reference.
|
data/lib/cloud_shaped/dsl.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
|
-
require
|
2
|
-
require
|
3
|
-
require
|
4
|
-
require
|
1
|
+
require "cloud_shaped/core_methods"
|
2
|
+
require "cloud_shaped/function_methods"
|
3
|
+
require "cloud_shaped/interpolation"
|
4
|
+
require "cloud_shaped/sns_methods"
|
5
5
|
|
6
6
|
module CloudShaped
|
7
7
|
module DSL
|
@@ -18,6 +18,46 @@ module CloudShaped
|
|
18
18
|
}
|
19
19
|
end
|
20
20
|
|
21
|
+
# Syntax sugar for Fn::And.
|
22
|
+
#
|
23
|
+
def fn_and(*conditions)
|
24
|
+
{
|
25
|
+
"Fn::And" => conditions
|
26
|
+
}
|
27
|
+
end
|
28
|
+
|
29
|
+
# Syntax sugar for Fn::Equals.
|
30
|
+
#
|
31
|
+
def fn_equals(v1, v2)
|
32
|
+
{
|
33
|
+
"Fn::Equals" => [v1, v2]
|
34
|
+
}
|
35
|
+
end
|
36
|
+
|
37
|
+
# Syntax sugar for Fn::If.
|
38
|
+
#
|
39
|
+
def fn_if(condition, when_true, when_false)
|
40
|
+
{
|
41
|
+
"Fn::If" => [condition, when_true, when_false]
|
42
|
+
}
|
43
|
+
end
|
44
|
+
|
45
|
+
# Syntax sugar for Fn::Not.
|
46
|
+
#
|
47
|
+
def fn_not(cond)
|
48
|
+
{
|
49
|
+
"Fn::Not" => [cond]
|
50
|
+
}
|
51
|
+
end
|
52
|
+
|
53
|
+
# Syntax sugar for Fn::Or.
|
54
|
+
#
|
55
|
+
def fn_or(*conditions)
|
56
|
+
{
|
57
|
+
"Fn::Or" => conditions
|
58
|
+
}
|
59
|
+
end
|
60
|
+
|
21
61
|
end
|
22
62
|
|
23
63
|
end
|
@@ -1,5 +1,5 @@
|
|
1
|
-
require
|
2
|
-
require
|
1
|
+
require "cloud_shaped/core_methods"
|
2
|
+
require "cloud_shaped/function_methods"
|
3
3
|
|
4
4
|
module CloudShaped
|
5
5
|
|
@@ -8,7 +8,7 @@ module CloudShaped
|
|
8
8
|
include CoreMethods
|
9
9
|
include FunctionMethods
|
10
10
|
|
11
|
-
DEFAULT_DELIMITERS =[
|
11
|
+
DEFAULT_DELIMITERS = ["{{", "}}"].freeze
|
12
12
|
|
13
13
|
# Interpolates a String, inserting calls to "Ref" and "Fn::GetAtt".
|
14
14
|
#
|
@@ -16,10 +16,10 @@ module CloudShaped
|
|
16
16
|
# @param delimiters [Array] opening and closing delimter
|
17
17
|
#
|
18
18
|
def interpolate(string, delimiters = DEFAULT_DELIMITERS)
|
19
|
-
|
19
|
+
interpolated_lines = string.split("\n", -1).map do |line|
|
20
20
|
interpolate_line(line, delimiters)
|
21
|
-
end
|
22
|
-
|
21
|
+
end
|
22
|
+
join("\n", interpolated_lines)
|
23
23
|
end
|
24
24
|
|
25
25
|
private
|
@@ -28,13 +28,20 @@ module CloudShaped
|
|
28
28
|
open, close = delimiters
|
29
29
|
tokens = line.split(/(#{Regexp.quote(open)}[\w:.]+#{Regexp.quote(close)})/)
|
30
30
|
tokens.reject!(&:empty?)
|
31
|
-
tokens.map do |token|
|
31
|
+
fragments = tokens.map do |token|
|
32
32
|
if token =~ /^#{Regexp.quote(open)}([\w:]+)(?:\.(\w+))?#{Regexp.quote(close)}$/
|
33
|
-
ref(
|
33
|
+
ref(Regexp.last_match(1), Regexp.last_match(2))
|
34
34
|
else
|
35
35
|
token
|
36
36
|
end
|
37
37
|
end
|
38
|
+
join("", fragments)
|
39
|
+
end
|
40
|
+
|
41
|
+
def join(delimiter, parts)
|
42
|
+
return "" if parts.empty?
|
43
|
+
return parts.first if parts.one?
|
44
|
+
fn_join(delimiter, parts)
|
38
45
|
end
|
39
46
|
|
40
47
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require
|
1
|
+
require "cloud_shaped/core_methods"
|
2
2
|
|
3
3
|
module CloudShaped
|
4
4
|
# Methods to create sns topics
|
@@ -7,8 +7,8 @@ module CloudShaped
|
|
7
7
|
|
8
8
|
def sns_topic(endpoint)
|
9
9
|
proto, target = sns_proto_target(endpoint)
|
10
|
-
resource
|
11
|
-
{
|
10
|
+
resource "AWS::SNS::Topic", "Subscription" => [
|
11
|
+
{ "Protocol" => proto, "Endpoint" => target }
|
12
12
|
]
|
13
13
|
end
|
14
14
|
|
@@ -19,10 +19,9 @@ module CloudShaped
|
|
19
19
|
when /^(https?):/
|
20
20
|
[Regexp.last_match[1].upcase, target]
|
21
21
|
when /^(mailto):(.*)/
|
22
|
-
[
|
23
|
-
else [
|
22
|
+
["email", Regexp.last_match[2]]
|
23
|
+
else ["email", target]
|
24
24
|
end
|
25
25
|
end
|
26
26
|
end
|
27
27
|
end
|
28
|
-
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require
|
1
|
+
require "cloud_shaped/dsl"
|
2
2
|
|
3
3
|
module CloudShaped
|
4
4
|
|
@@ -10,6 +10,7 @@ module CloudShaped
|
|
10
10
|
@metadata = {}
|
11
11
|
@parameters = {}
|
12
12
|
@mappings = {}
|
13
|
+
@conditions = {}
|
13
14
|
@resources = {}
|
14
15
|
@outputs = {}
|
15
16
|
end
|
@@ -18,11 +19,12 @@ module CloudShaped
|
|
18
19
|
#
|
19
20
|
def template
|
20
21
|
{}.tap do |template|
|
21
|
-
template["AWSTemplateFormatVersion"] =
|
22
|
+
template["AWSTemplateFormatVersion"] = "2010-09-09"
|
22
23
|
template["Description"] = description if description
|
23
24
|
template["Metadata"] = metadata unless metadata.empty?
|
24
25
|
template["Parameters"] = parameters unless parameters.empty?
|
25
26
|
template["Mappings"] = mappings unless mappings.empty?
|
27
|
+
template["Conditions"] = conditions unless conditions.empty?
|
26
28
|
template["Resources"] = resources
|
27
29
|
template["Outputs"] = outputs unless outputs.empty?
|
28
30
|
end
|
@@ -42,6 +44,7 @@ module CloudShaped
|
|
42
44
|
# def_parameter "minInstances", :type => "Number"
|
43
45
|
#
|
44
46
|
def def_parameter(name, options = {})
|
47
|
+
yield options if block_given?
|
45
48
|
parameters[name] = parameter(options)
|
46
49
|
end
|
47
50
|
|
@@ -58,6 +61,18 @@ module CloudShaped
|
|
58
61
|
mappings[name] = mapping
|
59
62
|
end
|
60
63
|
|
64
|
+
# Declares a Condition.
|
65
|
+
#
|
66
|
+
# @param name [String] the condition name
|
67
|
+
# @param condition [Hash] the condition body
|
68
|
+
#
|
69
|
+
# @example
|
70
|
+
# def_mapping "inProd", fn_equals(ref("Env"), "prod")
|
71
|
+
#
|
72
|
+
def def_condition(name, body)
|
73
|
+
conditions[name] = body
|
74
|
+
end
|
75
|
+
|
61
76
|
# Declares a Resource.
|
62
77
|
#
|
63
78
|
# @param name [String] the resource name
|
@@ -66,10 +81,10 @@ module CloudShaped
|
|
66
81
|
#
|
67
82
|
def def_resource(name, type, *args, &block)
|
68
83
|
definition = if type.is_a?(Symbol)
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
84
|
+
send(type, *args, &block)
|
85
|
+
else
|
86
|
+
resource(type, *args, &block)
|
87
|
+
end
|
73
88
|
resources[name] = definition if definition
|
74
89
|
end
|
75
90
|
|
@@ -92,6 +107,7 @@ module CloudShaped
|
|
92
107
|
|
93
108
|
attr_reader :parameters
|
94
109
|
attr_reader :mappings
|
110
|
+
attr_reader :conditions
|
95
111
|
attr_reader :resources
|
96
112
|
attr_reader :outputs
|
97
113
|
|
data/lib/cloud_shaped/version.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
|
-
require
|
1
|
+
require "spec_helper"
|
2
2
|
|
3
|
-
require
|
3
|
+
require "cloud_shaped/core_methods"
|
4
4
|
|
5
5
|
describe CloudShaped::CoreMethods do
|
6
6
|
|
@@ -58,7 +58,7 @@ describe CloudShaped::CoreMethods do
|
|
58
58
|
context "with a block that sets attributes" do
|
59
59
|
|
60
60
|
let(:result) do
|
61
|
-
resource("AWS::Thing") do |
|
61
|
+
resource("AWS::Thing") do |_props, attrs|
|
62
62
|
attrs["DeletionPolicy"] = "Retain"
|
63
63
|
end
|
64
64
|
end
|
@@ -86,7 +86,7 @@ describe CloudShaped::CoreMethods do
|
|
86
86
|
context "with no type" do
|
87
87
|
|
88
88
|
it "defaults to 'String'" do
|
89
|
-
expect(parameter
|
89
|
+
expect(parameter).to eq(
|
90
90
|
"Type" => "String"
|
91
91
|
)
|
92
92
|
end
|
@@ -1,6 +1,6 @@
|
|
1
|
-
require
|
1
|
+
require "spec_helper"
|
2
2
|
|
3
|
-
require
|
3
|
+
require "cloud_shaped/function_methods"
|
4
4
|
|
5
5
|
describe CloudShaped::FunctionMethods do
|
6
6
|
|
@@ -11,9 +11,7 @@ describe CloudShaped::FunctionMethods do
|
|
11
11
|
it "is sugar for Fn::Base64" do
|
12
12
|
output = fn_base64("stuff")
|
13
13
|
expect(output).to eq(
|
14
|
-
|
15
|
-
"Fn::Base64" => "stuff"
|
16
|
-
}
|
14
|
+
"Fn::Base64" => "stuff"
|
17
15
|
)
|
18
16
|
end
|
19
17
|
|
@@ -25,9 +23,62 @@ describe CloudShaped::FunctionMethods do
|
|
25
23
|
lines = %w(a b c)
|
26
24
|
output = fn_join(",", lines)
|
27
25
|
expect(output).to eq(
|
28
|
-
|
29
|
-
|
30
|
-
|
26
|
+
"Fn::Join" => [",", lines]
|
27
|
+
)
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
|
32
|
+
describe "#fn_and" do
|
33
|
+
|
34
|
+
it "is sugar for Fn::And" do
|
35
|
+
output = fn_and("cond1", "cond2", "cond3")
|
36
|
+
expect(output).to eq(
|
37
|
+
"Fn::And" => ["cond1", "cond2", "cond3"]
|
38
|
+
)
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
42
|
+
|
43
|
+
describe "#fn_equals" do
|
44
|
+
|
45
|
+
it "is sugar for Fn::And" do
|
46
|
+
output = fn_equals("val1", "val2")
|
47
|
+
expect(output).to eq(
|
48
|
+
"Fn::Equals" => ["val1", "val2"]
|
49
|
+
)
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
53
|
+
|
54
|
+
describe "#fn_if" do
|
55
|
+
|
56
|
+
it "is sugar for Fn::If" do
|
57
|
+
output = fn_if("cond", "when_true", "when_false")
|
58
|
+
expect(output).to eq(
|
59
|
+
"Fn::If" => ["cond", "when_true", "when_false"]
|
60
|
+
)
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
64
|
+
|
65
|
+
describe "#fn_not" do
|
66
|
+
|
67
|
+
it "is sugar for Fn::Not" do
|
68
|
+
output = fn_not("cond")
|
69
|
+
expect(output).to eq(
|
70
|
+
"Fn::Not" => ["cond"]
|
71
|
+
)
|
72
|
+
end
|
73
|
+
|
74
|
+
end
|
75
|
+
|
76
|
+
describe "#fn_or" do
|
77
|
+
|
78
|
+
it "is sugar for Fn::Or" do
|
79
|
+
output = fn_or("cond1", "cond2", "cond3")
|
80
|
+
expect(output).to eq(
|
81
|
+
"Fn::Or" => ["cond1", "cond2", "cond3"]
|
31
82
|
)
|
32
83
|
end
|
33
84
|
|
@@ -1,6 +1,6 @@
|
|
1
|
-
require
|
1
|
+
require "spec_helper"
|
2
2
|
|
3
|
-
require
|
3
|
+
require "cloud_shaped/interpolation"
|
4
4
|
|
5
5
|
describe CloudShaped::Interpolation do
|
6
6
|
|
@@ -16,15 +16,32 @@ describe CloudShaped::Interpolation do
|
|
16
16
|
|
17
17
|
it "generates a Ref" do
|
18
18
|
expect(output).to eq(
|
19
|
-
|
20
|
-
"
|
21
|
-
"",
|
22
|
-
|
23
|
-
|
24
|
-
"-suffix"
|
25
|
-
]
|
19
|
+
"Fn::Join" => [
|
20
|
+
"", [
|
21
|
+
"prefix-",
|
22
|
+
{ "Ref" => "myResource" },
|
23
|
+
"-suffix"
|
26
24
|
]
|
27
|
-
|
25
|
+
]
|
26
|
+
)
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
|
31
|
+
context "with multiple lines" do
|
32
|
+
|
33
|
+
let(:input) { "line1\nline2\nline3\n" }
|
34
|
+
|
35
|
+
it "uses Fn::Join to join lines" do
|
36
|
+
expect(output).to eq(
|
37
|
+
"Fn::Join" => [
|
38
|
+
"\n", [
|
39
|
+
"line1",
|
40
|
+
"line2",
|
41
|
+
"line3",
|
42
|
+
""
|
43
|
+
]
|
44
|
+
]
|
28
45
|
)
|
29
46
|
end
|
30
47
|
|
@@ -36,13 +53,7 @@ describe CloudShaped::Interpolation do
|
|
36
53
|
|
37
54
|
it "generates a Ref" do
|
38
55
|
expect(output).to eq(
|
39
|
-
|
40
|
-
"Fn::Join" => [
|
41
|
-
"", [
|
42
|
-
{ "Ref" => "AWS::StackName" }
|
43
|
-
]
|
44
|
-
]
|
45
|
-
}
|
56
|
+
"Ref" => "AWS::StackName"
|
46
57
|
)
|
47
58
|
end
|
48
59
|
|
@@ -54,15 +65,13 @@ describe CloudShaped::Interpolation do
|
|
54
65
|
|
55
66
|
it "generates a Ref" do
|
56
67
|
expect(output).to eq(
|
57
|
-
|
58
|
-
"
|
59
|
-
"",
|
60
|
-
|
61
|
-
|
62
|
-
"-suffix"
|
63
|
-
]
|
68
|
+
"Fn::Join" => [
|
69
|
+
"", [
|
70
|
+
"prefix-",
|
71
|
+
{ "Ref" => "AWS::StackName" },
|
72
|
+
"-suffix"
|
64
73
|
]
|
65
|
-
|
74
|
+
]
|
66
75
|
)
|
67
76
|
end
|
68
77
|
|
@@ -74,15 +83,13 @@ describe CloudShaped::Interpolation do
|
|
74
83
|
|
75
84
|
it "generates an Fn::GetAtt" do
|
76
85
|
expect(output).to eq(
|
77
|
-
|
78
|
-
"
|
79
|
-
"",
|
80
|
-
|
81
|
-
|
82
|
-
"-suffix"
|
83
|
-
]
|
86
|
+
"Fn::Join" => [
|
87
|
+
"", [
|
88
|
+
"prefix-",
|
89
|
+
{ "Fn::GetAtt" => ["loadBalancer", "cname"] },
|
90
|
+
"-suffix"
|
84
91
|
]
|
85
|
-
|
92
|
+
]
|
86
93
|
)
|
87
94
|
end
|
88
95
|
|
@@ -90,15 +97,15 @@ describe CloudShaped::Interpolation do
|
|
90
97
|
|
91
98
|
it "supports alternate delimiters" do
|
92
99
|
double_square_brackets = ["[[", "]]"]
|
93
|
-
expect(interpolate("[[foo]]", double_square_brackets)).to eq(
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
100
|
+
expect(interpolate("blah[[foo]]blah", double_square_brackets)).to eq(
|
101
|
+
"Fn::Join" => [
|
102
|
+
"", [
|
103
|
+
"blah",
|
104
|
+
{ "Ref" => "foo" },
|
105
|
+
"blah"
|
106
|
+
]
|
107
|
+
]
|
108
|
+
)
|
102
109
|
end
|
103
110
|
|
104
111
|
context "with a mix of stuff" do
|
@@ -107,17 +114,22 @@ describe CloudShaped::Interpolation do
|
|
107
114
|
|
108
115
|
it "all just works" do
|
109
116
|
expect(output).to eq(
|
110
|
-
|
111
|
-
"
|
112
|
-
"",
|
113
|
-
|
114
|
-
|
115
|
-
"
|
116
|
-
|
117
|
-
|
118
|
-
|
117
|
+
"Fn::Join" => [
|
118
|
+
"\n", [
|
119
|
+
"#!/bin/foo",
|
120
|
+
"",
|
121
|
+
{
|
122
|
+
"Fn::Join" => [
|
123
|
+
"", [
|
124
|
+
"prefix-",
|
125
|
+
{ "Ref" => "myResource" },
|
126
|
+
"-suffix"
|
127
|
+
]
|
128
|
+
]
|
129
|
+
},
|
130
|
+
""
|
119
131
|
]
|
120
|
-
|
132
|
+
]
|
121
133
|
)
|
122
134
|
end
|
123
135
|
|
@@ -1,6 +1,6 @@
|
|
1
|
-
require
|
1
|
+
require "spec_helper"
|
2
2
|
|
3
|
-
require
|
3
|
+
require "cloud_shaped/template_builder"
|
4
4
|
|
5
5
|
describe CloudShaped::TemplateBuilder do
|
6
6
|
|
@@ -13,7 +13,7 @@ describe CloudShaped::TemplateBuilder do
|
|
13
13
|
it "returns a CloudFormation template" do
|
14
14
|
|
15
15
|
expect(template).to eq(
|
16
|
-
"AWSTemplateFormatVersion" =>
|
16
|
+
"AWSTemplateFormatVersion" => "2010-09-09",
|
17
17
|
"Resources" => {}
|
18
18
|
)
|
19
19
|
|
@@ -23,7 +23,7 @@ describe CloudShaped::TemplateBuilder do
|
|
23
23
|
|
24
24
|
describe "#description=" do
|
25
25
|
|
26
|
-
it "sets the Description"
|
26
|
+
it "sets the Description" do
|
27
27
|
template_builder.description = "My awesome template"
|
28
28
|
expect(template["Description"]).to eq("My awesome template")
|
29
29
|
end
|
@@ -39,7 +39,7 @@ describe CloudShaped::TemplateBuilder do
|
|
39
39
|
expect(template["Resources"]).to eq(
|
40
40
|
"fooBar" => {
|
41
41
|
"Type" => "AWS::Foo::Bar",
|
42
|
-
"Properties" => {"foo" => "bar"}
|
42
|
+
"Properties" => { "foo" => "bar" }
|
43
43
|
}
|
44
44
|
)
|
45
45
|
|
@@ -60,7 +60,7 @@ describe CloudShaped::TemplateBuilder do
|
|
60
60
|
expect(template["Resources"]).to eq(
|
61
61
|
"fooBar" => {
|
62
62
|
"Type" => "AWS::Fnord::Fnord",
|
63
|
-
"Properties" => {"Size" => "3"}
|
63
|
+
"Properties" => { "Size" => "3" }
|
64
64
|
}
|
65
65
|
)
|
66
66
|
|
@@ -71,7 +71,7 @@ describe CloudShaped::TemplateBuilder do
|
|
71
71
|
context "when resource macro-method returns nil" do
|
72
72
|
|
73
73
|
before do
|
74
|
-
def template_builder.nada(*
|
74
|
+
def template_builder.nada(*_args)
|
75
75
|
nil
|
76
76
|
end
|
77
77
|
end
|
@@ -130,11 +130,11 @@ describe CloudShaped::TemplateBuilder do
|
|
130
130
|
|
131
131
|
let(:region_map) do
|
132
132
|
{
|
133
|
-
"us-east-1" => { "32" => "ami-6411e20d"},
|
134
|
-
"us-west-1" => { "32" => "ami-c9c7978c"},
|
135
|
-
"eu-west-1" => { "32" => "ami-37c2f643"},
|
136
|
-
"ap-southeast-1" => { "32" => "ami-66f28c34"},
|
137
|
-
"ap-northeast-1" => { "32" => "ami-9c03a89d"}
|
133
|
+
"us-east-1" => { "32" => "ami-6411e20d" },
|
134
|
+
"us-west-1" => { "32" => "ami-c9c7978c" },
|
135
|
+
"eu-west-1" => { "32" => "ami-37c2f643" },
|
136
|
+
"ap-southeast-1" => { "32" => "ami-66f28c34" },
|
137
|
+
"ap-northeast-1" => { "32" => "ami-9c03a89d" }
|
138
138
|
}
|
139
139
|
end
|
140
140
|
|
@@ -169,6 +169,22 @@ describe CloudShaped::TemplateBuilder do
|
|
169
169
|
|
170
170
|
end
|
171
171
|
|
172
|
+
describe "#def_condition" do
|
173
|
+
|
174
|
+
let(:condition_body) do
|
175
|
+
{ "Fn::Equals" => [{ "Ref" => "Env" }, "prod"] }
|
176
|
+
end
|
177
|
+
|
178
|
+
before do
|
179
|
+
template_builder.def_condition("InProd", condition_body)
|
180
|
+
end
|
181
|
+
|
182
|
+
it "defines a Condition" do
|
183
|
+
expect(template["Conditions"]).to eq("InProd" => condition_body)
|
184
|
+
end
|
185
|
+
|
186
|
+
end
|
187
|
+
|
172
188
|
describe "#metadata" do
|
173
189
|
|
174
190
|
it "allows attachment of stack metadata" do
|
data/spec/cloud_shaped_spec.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
require
|
1
|
+
require "spec_helper"
|
2
2
|
|
3
3
|
require "cloud_shaped"
|
4
4
|
|
@@ -20,7 +20,7 @@ describe CloudShaped do
|
|
20
20
|
|
21
21
|
it "declares a template using instance_eval" do
|
22
22
|
expect(template).to eq(
|
23
|
-
"AWSTemplateFormatVersion" =>
|
23
|
+
"AWSTemplateFormatVersion" => "2010-09-09",
|
24
24
|
"Parameters" => {
|
25
25
|
"appName" => {
|
26
26
|
"Type" => "String"
|
@@ -60,7 +60,7 @@ describe CloudShaped do
|
|
60
60
|
|
61
61
|
it "declares a template without instance_eval" do
|
62
62
|
expect(template).to eq(
|
63
|
-
"AWSTemplateFormatVersion" =>
|
63
|
+
"AWSTemplateFormatVersion" => "2010-09-09",
|
64
64
|
"Parameters" => {
|
65
65
|
"appName" => {
|
66
66
|
"Type" => "String"
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cloud_shaped
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Mike Williams
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2016-04-14 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -52,6 +52,20 @@ dependencies:
|
|
52
52
|
- - ">="
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rubocop
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0.32'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0.32'
|
55
69
|
description: CloudShaped makes it easier to generate CloudFormation templates, using
|
56
70
|
a Builder-like DSL.
|
57
71
|
email:
|
@@ -62,6 +76,8 @@ extra_rdoc_files: []
|
|
62
76
|
files:
|
63
77
|
- ".gitignore"
|
64
78
|
- ".rspec"
|
79
|
+
- ".rubocop.yml"
|
80
|
+
- ".travis.yml"
|
65
81
|
- Gemfile
|
66
82
|
- LICENSE.txt
|
67
83
|
- README.md
|
@@ -107,7 +123,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
107
123
|
version: '0'
|
108
124
|
requirements: []
|
109
125
|
rubyforge_project:
|
110
|
-
rubygems_version: 2.
|
126
|
+
rubygems_version: 2.5.1
|
111
127
|
signing_key:
|
112
128
|
specification_version: 4
|
113
129
|
summary: DSL for AWS CloudFormation templates.
|