cloud_shaped 0.0.1
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 +7 -0
- data/.gitignore +22 -0
- data/.rspec +1 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +32 -0
- data/Rakefile +10 -0
- data/cloud_shaped.gemspec +29 -0
- data/lib/cloud_shaped.rb +17 -0
- data/lib/cloud_shaped/camelate.rb +31 -0
- data/lib/cloud_shaped/core_methods.rb +85 -0
- data/lib/cloud_shaped/dsl.rb +15 -0
- data/lib/cloud_shaped/function_methods.rb +23 -0
- data/lib/cloud_shaped/sns_methods.rb +27 -0
- data/lib/cloud_shaped/template_builder.rb +45 -0
- data/lib/cloud_shaped/version.rb +3 -0
- data/spec/cloud_shaped/camelate_spec.rb +32 -0
- data/spec/cloud_shaped/core_methods_spec.rb +136 -0
- data/spec/cloud_shaped/function_methods_spec.rb +36 -0
- data/spec/cloud_shaped/sns_methods_spec.rb +60 -0
- data/spec/cloud_shaped/template_builder_spec.rb +81 -0
- data/spec/cloud_shaped_spec.rb +89 -0
- data/spec/spec_helper.rb +0 -0
- metadata +116 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 6170e5e4012e478185904f5e954f66377bee856e
|
4
|
+
data.tar.gz: 69154dcff5fb35c7eec5e335a34404bc54b1b7f8
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: d27e67b31475234deea22c3157f6a89d8b53db9295233d6ec4af52346b6c71d4f73f19ee7dd19bb6d91771ea24c0178ed9fc23a113185a98c2fc4d02ae117bba
|
7
|
+
data.tar.gz: dfce6eb71652b4d01352eb74b4ca7b8c45cb281be4ac312b7d6fb3394339dc2f347f052cc3266bd72e033cec86dfefa1af4feb031263bf68156e9903428bb653
|
data/.gitignore
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
*.gem
|
2
|
+
*.rbc
|
3
|
+
.bundle
|
4
|
+
.config
|
5
|
+
.yardoc
|
6
|
+
Gemfile.lock
|
7
|
+
InstalledFiles
|
8
|
+
_yardoc
|
9
|
+
coverage
|
10
|
+
doc/
|
11
|
+
lib/bundler/man
|
12
|
+
pkg
|
13
|
+
rdoc
|
14
|
+
spec/reports
|
15
|
+
test/tmp
|
16
|
+
test/version_tmp
|
17
|
+
tmp
|
18
|
+
*.bundle
|
19
|
+
*.so
|
20
|
+
*.o
|
21
|
+
*.a
|
22
|
+
mkmf.log
|
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--color
|
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2014 Mike Williams
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
# CloudShaped
|
2
|
+
|
3
|
+
Infrastructure as <del>data</del> code.
|
4
|
+
|
5
|
+
[CloudFormation][cloud_formation] provides a nice way to provision AWS resources in a declarative way. But, programming in JSON can be painful.
|
6
|
+
|
7
|
+
CloudShaped provides a simple, extensible DSL for generating CloudFormation templates.
|
8
|
+
|
9
|
+
## Installation
|
10
|
+
|
11
|
+
Add this line to your application's Gemfile:
|
12
|
+
|
13
|
+
gem 'cloud_shaped'
|
14
|
+
|
15
|
+
## Example
|
16
|
+
|
17
|
+
require 'cloud_shaped'
|
18
|
+
|
19
|
+
template = CloudShaped.template do |t|
|
20
|
+
t.def_parameter "appName"
|
21
|
+
t.def_resource "app", "AWS::Appity:AppApp" do |app|
|
22
|
+
app["Name"] = t.ref("appName")
|
23
|
+
end
|
24
|
+
t.def_output "appAddress", t.ref("app", "address")
|
25
|
+
end
|
26
|
+
|
27
|
+
## Contributing
|
28
|
+
|
29
|
+
It's [on GitHub][cloud_shaped]. Fork it.
|
30
|
+
|
31
|
+
[cloud_formation]: http://aws.amazon.com/cloudformation/
|
32
|
+
[cloud_shaped]: https://github.com/mdub/cloud_shaped
|
data/Rakefile
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'cloud_shaped/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |gem|
|
7
|
+
|
8
|
+
gem.name = "cloud_shaped"
|
9
|
+
gem.version = CloudShaped::VERSION
|
10
|
+
|
11
|
+
gem.summary = %q{DSL for AWS CloudFormation templates.}
|
12
|
+
gem.description = %q{CloudShaped makes it easier to generate CloudFormation templates, using a Builder-like DSL.}
|
13
|
+
|
14
|
+
gem.authors = ["Mike Williams"]
|
15
|
+
gem.email = ["mdub@dogbiscuit.org"]
|
16
|
+
|
17
|
+
gem.homepage = "http://github.com/mdub/cloud_shaped"
|
18
|
+
gem.license = "MIT"
|
19
|
+
|
20
|
+
gem.files = `git ls-files -z`.split("\x0")
|
21
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
22
|
+
|
23
|
+
gem.require_paths = ["lib"]
|
24
|
+
|
25
|
+
gem.add_development_dependency "bundler", "~> 1.6"
|
26
|
+
gem.add_development_dependency "rake"
|
27
|
+
gem.add_development_dependency "rspec"
|
28
|
+
|
29
|
+
end
|
data/lib/cloud_shaped.rb
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
require "cloud_shaped/dsl"
|
2
|
+
require "cloud_shaped/template_builder"
|
3
|
+
require "cloud_shaped/version"
|
4
|
+
|
5
|
+
module CloudShaped
|
6
|
+
|
7
|
+
def self.template(&block)
|
8
|
+
TemplateBuilder.new.tap do |builder|
|
9
|
+
if block.arity.zero?
|
10
|
+
builder.instance_eval(&block)
|
11
|
+
else
|
12
|
+
yield builder
|
13
|
+
end
|
14
|
+
end.template
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module CloudShaped
|
2
|
+
|
3
|
+
module Camelate
|
4
|
+
|
5
|
+
refine Symbol do
|
6
|
+
|
7
|
+
def camelate
|
8
|
+
to_s.split('_').map(&:capitalize).join
|
9
|
+
end
|
10
|
+
|
11
|
+
end
|
12
|
+
|
13
|
+
refine String do
|
14
|
+
|
15
|
+
def camelate
|
16
|
+
self
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
|
21
|
+
refine Hash do
|
22
|
+
|
23
|
+
def camelate_keys
|
24
|
+
Hash[map { |key, value| [key.camelate, value] }]
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
@@ -0,0 +1,85 @@
|
|
1
|
+
require "cloud_shaped/camelate"
|
2
|
+
|
3
|
+
using CloudShaped::Camelate
|
4
|
+
|
5
|
+
module CloudShaped
|
6
|
+
|
7
|
+
module CoreMethods
|
8
|
+
|
9
|
+
# Returns a CloudFormation Resource declaration.
|
10
|
+
#
|
11
|
+
# Properties can be passed in the call, or defined using an optional block.
|
12
|
+
#
|
13
|
+
# @example
|
14
|
+
# resource("AWS::ElasticLoadBalancing::LoadBalancer", "Scheme" => "internal") do |elb|
|
15
|
+
# elb["SecurityGroups"] = [ref("appSecurityGroup")]
|
16
|
+
# end
|
17
|
+
#
|
18
|
+
# @param type [String] the resource type
|
19
|
+
# @param properties [Hash] resource properties
|
20
|
+
#
|
21
|
+
def resource(type, properties = {})
|
22
|
+
properties = properties.camelate_keys
|
23
|
+
yield properties if block_given?
|
24
|
+
properties.select! { |k,v| v != nil }
|
25
|
+
{
|
26
|
+
"Type" => type,
|
27
|
+
"Properties" => properties
|
28
|
+
}
|
29
|
+
end
|
30
|
+
|
31
|
+
# Returns a CloudFormation Parameter declaration.
|
32
|
+
#
|
33
|
+
# @option options [String] :type ("String") the resource type
|
34
|
+
# @option options [String] :description parameter description
|
35
|
+
# @option options [String] :default a default value
|
36
|
+
#
|
37
|
+
def parameter(options = {})
|
38
|
+
defaults = {
|
39
|
+
"Type" => "String"
|
40
|
+
}
|
41
|
+
defaults.merge(options.camelate_keys)
|
42
|
+
end
|
43
|
+
|
44
|
+
# Returns an Output declaration.
|
45
|
+
#
|
46
|
+
# @param value the output value (usually a reference to a resource)
|
47
|
+
#
|
48
|
+
# @example
|
49
|
+
# output(ref("loadBalancer"))
|
50
|
+
#
|
51
|
+
def output(value)
|
52
|
+
{
|
53
|
+
"Value" => value
|
54
|
+
}
|
55
|
+
end
|
56
|
+
|
57
|
+
# Returns a Tag.
|
58
|
+
#
|
59
|
+
# @param name [String] tag name
|
60
|
+
# @param value tag value
|
61
|
+
#
|
62
|
+
def tag(name, value, extra_properties = {})
|
63
|
+
{
|
64
|
+
"Key" => name,
|
65
|
+
"Value" => value
|
66
|
+
}.merge(extra_properties)
|
67
|
+
end
|
68
|
+
|
69
|
+
# Returns a resource reference.
|
70
|
+
#
|
71
|
+
# If attribute_name is specified, we use "Fn::GetAtt"; otherwise, we use "Ref".
|
72
|
+
#
|
73
|
+
# @param resource_name [String] name of the resource
|
74
|
+
# @param attribute_name [String] atttribute of the resource to refer to
|
75
|
+
#
|
76
|
+
def ref(resource_name, attribute_name = nil)
|
77
|
+
if attribute_name
|
78
|
+
{ "Fn::GetAtt" => [resource_name, attribute_name] }
|
79
|
+
else
|
80
|
+
{ "Ref" => resource_name }
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
end
|
85
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'cloud_shaped/core_methods'
|
2
|
+
require 'cloud_shaped/function_methods'
|
3
|
+
require 'cloud_shaped/sns_methods'
|
4
|
+
|
5
|
+
module CloudShaped
|
6
|
+
module DSL
|
7
|
+
|
8
|
+
include CoreMethods
|
9
|
+
include FunctionMethods
|
10
|
+
include SnsMethods
|
11
|
+
|
12
|
+
extend self
|
13
|
+
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module CloudShaped
|
2
|
+
|
3
|
+
module FunctionMethods
|
4
|
+
|
5
|
+
# Syntax sugar for Fn::Base64.
|
6
|
+
#
|
7
|
+
def fn_base64(arg)
|
8
|
+
{ "Fn::Base64" => arg }
|
9
|
+
end
|
10
|
+
|
11
|
+
# Syntax sugar for Fn::Join.
|
12
|
+
#
|
13
|
+
def fn_join(separator, lines)
|
14
|
+
{
|
15
|
+
"Fn::Join" => [
|
16
|
+
separator, lines
|
17
|
+
]
|
18
|
+
}
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'cloud_shaped/core_methods'
|
2
|
+
|
3
|
+
module CloudShaped
|
4
|
+
|
5
|
+
module SnsMethods
|
6
|
+
|
7
|
+
include CoreMethods
|
8
|
+
|
9
|
+
def sns_topic(target)
|
10
|
+
resource "AWS::SNS::Topic", "Subscription" => [
|
11
|
+
{ "Protocol" => sns_protocol(target), "Endpoint" => target }
|
12
|
+
]
|
13
|
+
end
|
14
|
+
|
15
|
+
private
|
16
|
+
|
17
|
+
def sns_protocol(target)
|
18
|
+
case target
|
19
|
+
when /^(https?):/
|
20
|
+
$1.upcase
|
21
|
+
else "email"
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'cloud_shaped/dsl'
|
2
|
+
|
3
|
+
module CloudShaped
|
4
|
+
|
5
|
+
# A TemplateBuilder is an object that can generate a CloudFormation template,
|
6
|
+
# in the form of Ruby data.
|
7
|
+
#
|
8
|
+
class TemplateBuilder
|
9
|
+
|
10
|
+
def initialize(settings = {})
|
11
|
+
@parameters = {}
|
12
|
+
@resources = {}
|
13
|
+
@outputs = {}
|
14
|
+
end
|
15
|
+
|
16
|
+
attr_reader :parameters
|
17
|
+
attr_reader :resources
|
18
|
+
attr_reader :outputs
|
19
|
+
|
20
|
+
def template
|
21
|
+
{
|
22
|
+
"AWSTemplateFormatVersion" => '2010-09-09',
|
23
|
+
"Parameters" => parameters,
|
24
|
+
"Resources" => resources,
|
25
|
+
"Outputs" => outputs
|
26
|
+
}
|
27
|
+
end
|
28
|
+
|
29
|
+
include CloudShaped::DSL
|
30
|
+
|
31
|
+
def def_parameter(name, *args)
|
32
|
+
parameters[name] = parameter(*args)
|
33
|
+
end
|
34
|
+
|
35
|
+
def def_resource(name, type, *args, &block)
|
36
|
+
resources[name] = resource(type, *args, &block)
|
37
|
+
end
|
38
|
+
|
39
|
+
def def_output(name, *args)
|
40
|
+
outputs[name] = output(*args)
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
require 'cloud_shaped/camelate'
|
4
|
+
|
5
|
+
using CloudShaped::Camelate
|
6
|
+
|
7
|
+
describe String, "#camelate" do
|
8
|
+
it "is a no-op" do
|
9
|
+
expect("foobar".camelate).to eq("foobar")
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
describe Symbol, "#camelate" do
|
14
|
+
it "returns a CamelCased string" do
|
15
|
+
expect(:foo_bar.camelate).to eq("FooBar")
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
describe Hash, "#camelate_keys" do
|
20
|
+
|
21
|
+
it "camelates the keys" do
|
22
|
+
original_hash = {
|
23
|
+
:foo_bar => 123,
|
24
|
+
"BlahBlah" => 456
|
25
|
+
}
|
26
|
+
expect(original_hash.camelate_keys).to eq(
|
27
|
+
"FooBar" => 123,
|
28
|
+
"BlahBlah" => 456
|
29
|
+
)
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
@@ -0,0 +1,136 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
require 'cloud_shaped/core_methods'
|
4
|
+
|
5
|
+
describe CloudShaped::CoreMethods do
|
6
|
+
|
7
|
+
include described_class
|
8
|
+
|
9
|
+
describe "#resource" do
|
10
|
+
|
11
|
+
it "generates a Resource" do
|
12
|
+
expect(resource("AWS::Thing", "X" => 1, "Y" => 2)).to eq(
|
13
|
+
"Type" => "AWS::Thing",
|
14
|
+
"Properties" => { "X" => 1, "Y" => 2 }
|
15
|
+
)
|
16
|
+
end
|
17
|
+
|
18
|
+
it "weeds out null properties" do
|
19
|
+
expect(resource("AWS::Thing", "X" => 1, "Y" => nil)).to eq(
|
20
|
+
"Type" => "AWS::Thing",
|
21
|
+
"Properties" => { "X" => 1 }
|
22
|
+
)
|
23
|
+
end
|
24
|
+
|
25
|
+
context "with a block" do
|
26
|
+
|
27
|
+
it "allows properties to be added" do
|
28
|
+
result = resource("AWS::Thing", "MinSize" => 1) do |thing|
|
29
|
+
thing["MaxSize"] = 3
|
30
|
+
end
|
31
|
+
expect(result).to eq(
|
32
|
+
"Type" => "AWS::Thing",
|
33
|
+
"Properties" => { "MinSize" => 1, "MaxSize" => 3 }
|
34
|
+
)
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
40
|
+
|
41
|
+
describe "#parameter" do
|
42
|
+
|
43
|
+
it "generates a Parameter" do
|
44
|
+
expect(parameter(:type => "Numeric")).to eq(
|
45
|
+
"Type" => "Numeric"
|
46
|
+
)
|
47
|
+
end
|
48
|
+
|
49
|
+
context "with no type" do
|
50
|
+
|
51
|
+
it "defaults to 'String'" do
|
52
|
+
expect(parameter()).to eq(
|
53
|
+
"Type" => "String"
|
54
|
+
)
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
58
|
+
|
59
|
+
context "with a :default" do
|
60
|
+
|
61
|
+
it "includes a Default" do
|
62
|
+
expect(parameter(:default => "abc")).to eq(
|
63
|
+
"Type" => "String",
|
64
|
+
"Default" => "abc"
|
65
|
+
)
|
66
|
+
end
|
67
|
+
|
68
|
+
end
|
69
|
+
|
70
|
+
context "with a :description" do
|
71
|
+
|
72
|
+
it "includes a Description" do
|
73
|
+
expect(parameter(:description => "size in Gb")).to eq(
|
74
|
+
"Type" => "String",
|
75
|
+
"Description" => "size in Gb"
|
76
|
+
)
|
77
|
+
end
|
78
|
+
|
79
|
+
end
|
80
|
+
|
81
|
+
end
|
82
|
+
|
83
|
+
describe "#output" do
|
84
|
+
|
85
|
+
it "generates an Output" do
|
86
|
+
expect(output("blah")).to eq(
|
87
|
+
"Value" => "blah"
|
88
|
+
)
|
89
|
+
end
|
90
|
+
|
91
|
+
end
|
92
|
+
|
93
|
+
describe "#tag" do
|
94
|
+
|
95
|
+
it "generates a tag Hash" do
|
96
|
+
expect(tag("name", "foo")).to eq(
|
97
|
+
"Key" => "name",
|
98
|
+
"Value" => "foo"
|
99
|
+
)
|
100
|
+
end
|
101
|
+
|
102
|
+
it "supports extra parameters" do
|
103
|
+
expect(tag("foo", "bar", "PropagateAtLaunch" => "yup")).to eq(
|
104
|
+
"Key" => "foo",
|
105
|
+
"Value" => "bar",
|
106
|
+
"PropagateAtLaunch" => "yup"
|
107
|
+
)
|
108
|
+
end
|
109
|
+
|
110
|
+
end
|
111
|
+
|
112
|
+
describe "#ref" do
|
113
|
+
|
114
|
+
context "with a logical resource name" do
|
115
|
+
|
116
|
+
it "generates a Ref" do
|
117
|
+
expect(ref("thingy")).to eq(
|
118
|
+
"Ref" => "thingy"
|
119
|
+
)
|
120
|
+
end
|
121
|
+
|
122
|
+
end
|
123
|
+
|
124
|
+
context "with a logical resource name, and attribute name" do
|
125
|
+
|
126
|
+
it "generates an Fn::GetAtt" do
|
127
|
+
expect(ref("thingy", "wotsit")).to eq(
|
128
|
+
"Fn::GetAtt" => ["thingy", "wotsit"]
|
129
|
+
)
|
130
|
+
end
|
131
|
+
|
132
|
+
end
|
133
|
+
|
134
|
+
end
|
135
|
+
|
136
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
require 'cloud_shaped/function_methods'
|
4
|
+
|
5
|
+
describe CloudShaped::FunctionMethods do
|
6
|
+
|
7
|
+
include described_class
|
8
|
+
|
9
|
+
describe "#fn_base64" do
|
10
|
+
|
11
|
+
it "is sugar for Fn::Base64" do
|
12
|
+
output = fn_base64("stuff")
|
13
|
+
expect(output).to eq(
|
14
|
+
{
|
15
|
+
"Fn::Base64" => "stuff"
|
16
|
+
}
|
17
|
+
)
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
|
22
|
+
describe "#fn_join" do
|
23
|
+
|
24
|
+
it "is sugar for Fn::Join" do
|
25
|
+
lines = %w(a b c)
|
26
|
+
output = fn_join(",", lines)
|
27
|
+
expect(output).to eq(
|
28
|
+
{
|
29
|
+
"Fn::Join" => [",", lines]
|
30
|
+
}
|
31
|
+
)
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
require 'cloud_shaped/sns_methods'
|
4
|
+
|
5
|
+
describe CloudShaped::SnsMethods do
|
6
|
+
|
7
|
+
include described_class
|
8
|
+
|
9
|
+
describe "#sns_topic" do
|
10
|
+
|
11
|
+
context "with an email address" do
|
12
|
+
|
13
|
+
it "generates an email resource" do
|
14
|
+
output = sns_topic("root@example.com")
|
15
|
+
expect(output).to eq(
|
16
|
+
"Type" => "AWS::SNS::Topic",
|
17
|
+
"Properties" => {
|
18
|
+
"Subscription" => [
|
19
|
+
{ "Protocol" => "email", "Endpoint" => "root@example.com" }
|
20
|
+
]
|
21
|
+
}
|
22
|
+
)
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
|
27
|
+
context "with an HTTP URL" do
|
28
|
+
|
29
|
+
it "generates a webhook" do
|
30
|
+
output = sns_topic("http://example.com/hitme")
|
31
|
+
expect(output).to eq(
|
32
|
+
"Type" => "AWS::SNS::Topic",
|
33
|
+
"Properties" => {
|
34
|
+
"Subscription" => [
|
35
|
+
{ "Protocol" => "HTTP", "Endpoint" => "http://example.com/hitme" }
|
36
|
+
]
|
37
|
+
}
|
38
|
+
)
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
42
|
+
|
43
|
+
context "with an HTTPS URL" do
|
44
|
+
|
45
|
+
it "generates a webhook" do
|
46
|
+
output = sns_topic("https://example.com/hitme")
|
47
|
+
expect(output).to eq(
|
48
|
+
"Type" => "AWS::SNS::Topic",
|
49
|
+
"Properties" => {
|
50
|
+
"Subscription" => [
|
51
|
+
{ "Protocol" => "HTTPS", "Endpoint" => "https://example.com/hitme" }
|
52
|
+
]
|
53
|
+
}
|
54
|
+
)
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
require 'cloud_shaped/template_builder'
|
4
|
+
|
5
|
+
describe CloudShaped::TemplateBuilder do
|
6
|
+
|
7
|
+
subject(:template_builder) { described_class.new }
|
8
|
+
|
9
|
+
let(:template) { template_builder.template }
|
10
|
+
|
11
|
+
describe "#template" do
|
12
|
+
|
13
|
+
it "returns a CloudFormation template" do
|
14
|
+
|
15
|
+
expect(template).to eq(
|
16
|
+
"AWSTemplateFormatVersion" => '2010-09-09',
|
17
|
+
"Parameters" => {},
|
18
|
+
"Resources" => {},
|
19
|
+
"Outputs" => {}
|
20
|
+
)
|
21
|
+
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
|
26
|
+
describe "#def_resource" do
|
27
|
+
|
28
|
+
before do
|
29
|
+
template_builder.def_resource("fooBar", "AWS::Foo::Bar", "foo" => "bar")
|
30
|
+
end
|
31
|
+
|
32
|
+
it "defines a Resource" do
|
33
|
+
|
34
|
+
expect(template["Resources"]).to eq(
|
35
|
+
"fooBar" => {
|
36
|
+
"Type" => "AWS::Foo::Bar",
|
37
|
+
"Properties" => {"foo" => "bar"}
|
38
|
+
}
|
39
|
+
)
|
40
|
+
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
44
|
+
|
45
|
+
describe "#def_parameter" do
|
46
|
+
|
47
|
+
before do
|
48
|
+
template_builder.def_parameter("size")
|
49
|
+
end
|
50
|
+
|
51
|
+
it "defines a Parameter" do
|
52
|
+
|
53
|
+
expect(template["Parameters"]).to eq(
|
54
|
+
"size" => {
|
55
|
+
"Type" => "String"
|
56
|
+
}
|
57
|
+
)
|
58
|
+
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
62
|
+
|
63
|
+
describe "#def_output" do
|
64
|
+
|
65
|
+
before do
|
66
|
+
template_builder.def_output("myName", "bob")
|
67
|
+
end
|
68
|
+
|
69
|
+
it "defines an Output" do
|
70
|
+
|
71
|
+
expect(template["Outputs"]).to eq(
|
72
|
+
"myName" => {
|
73
|
+
"Value" => "bob"
|
74
|
+
}
|
75
|
+
)
|
76
|
+
|
77
|
+
end
|
78
|
+
|
79
|
+
end
|
80
|
+
|
81
|
+
end
|
@@ -0,0 +1,89 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
require "cloud_shaped"
|
4
|
+
|
5
|
+
describe CloudShaped do
|
6
|
+
|
7
|
+
describe ".template" do
|
8
|
+
|
9
|
+
context "with a no-arg block" do
|
10
|
+
|
11
|
+
let!(:template) do
|
12
|
+
CloudShaped.template do
|
13
|
+
def_parameter "appName"
|
14
|
+
def_resource "app", "AWS::Appity:AppApp" do |app|
|
15
|
+
app["Name"] = ref("appName")
|
16
|
+
end
|
17
|
+
def_output "appAddress", ref("app", "address")
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
it "declares a template using instance_eval" do
|
22
|
+
expect(template).to eq(
|
23
|
+
"AWSTemplateFormatVersion" => '2010-09-09',
|
24
|
+
"Parameters" => {
|
25
|
+
"appName" => {
|
26
|
+
"Type" => "String"
|
27
|
+
}
|
28
|
+
},
|
29
|
+
"Resources" => {
|
30
|
+
"app" => {
|
31
|
+
"Type" => "AWS::Appity:AppApp",
|
32
|
+
"Properties" => {
|
33
|
+
"Name" => { "Ref" => "appName" }
|
34
|
+
}
|
35
|
+
}
|
36
|
+
},
|
37
|
+
"Outputs" => {
|
38
|
+
"appAddress" => {
|
39
|
+
"Value" => { "Fn::GetAtt" => ["app", "address"] }
|
40
|
+
}
|
41
|
+
}
|
42
|
+
)
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
|
47
|
+
context "with a block that takes an argument" do
|
48
|
+
|
49
|
+
let(:app_name_parameter) { "appName" }
|
50
|
+
|
51
|
+
let!(:template) do
|
52
|
+
CloudShaped.template do |t|
|
53
|
+
t.def_parameter app_name_parameter
|
54
|
+
t.def_resource "app", "AWS::Appity:AppApp" do |app|
|
55
|
+
app["Name"] = t.ref(app_name_parameter)
|
56
|
+
end
|
57
|
+
t.def_output "appAddress", t.ref("app", "address")
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
it "declares a template without instance_eval" do
|
62
|
+
expect(template).to eq(
|
63
|
+
"AWSTemplateFormatVersion" => '2010-09-09',
|
64
|
+
"Parameters" => {
|
65
|
+
"appName" => {
|
66
|
+
"Type" => "String"
|
67
|
+
}
|
68
|
+
},
|
69
|
+
"Resources" => {
|
70
|
+
"app" => {
|
71
|
+
"Type" => "AWS::Appity:AppApp",
|
72
|
+
"Properties" => {
|
73
|
+
"Name" => { "Ref" => "appName" }
|
74
|
+
}
|
75
|
+
}
|
76
|
+
},
|
77
|
+
"Outputs" => {
|
78
|
+
"appAddress" => {
|
79
|
+
"Value" => { "Fn::GetAtt" => ["app", "address"] }
|
80
|
+
}
|
81
|
+
}
|
82
|
+
)
|
83
|
+
end
|
84
|
+
|
85
|
+
end
|
86
|
+
|
87
|
+
end
|
88
|
+
|
89
|
+
end
|
data/spec/spec_helper.rb
ADDED
File without changes
|
metadata
ADDED
@@ -0,0 +1,116 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: cloud_shaped
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Mike Williams
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-07-13 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ~>
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.6'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ~>
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.6'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - '>='
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - '>='
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rspec
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - '>='
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
description: CloudShaped makes it easier to generate CloudFormation templates, using
|
56
|
+
a Builder-like DSL.
|
57
|
+
email:
|
58
|
+
- mdub@dogbiscuit.org
|
59
|
+
executables: []
|
60
|
+
extensions: []
|
61
|
+
extra_rdoc_files: []
|
62
|
+
files:
|
63
|
+
- .gitignore
|
64
|
+
- .rspec
|
65
|
+
- Gemfile
|
66
|
+
- LICENSE.txt
|
67
|
+
- README.md
|
68
|
+
- Rakefile
|
69
|
+
- cloud_shaped.gemspec
|
70
|
+
- lib/cloud_shaped.rb
|
71
|
+
- lib/cloud_shaped/camelate.rb
|
72
|
+
- lib/cloud_shaped/core_methods.rb
|
73
|
+
- lib/cloud_shaped/dsl.rb
|
74
|
+
- lib/cloud_shaped/function_methods.rb
|
75
|
+
- lib/cloud_shaped/sns_methods.rb
|
76
|
+
- lib/cloud_shaped/template_builder.rb
|
77
|
+
- lib/cloud_shaped/version.rb
|
78
|
+
- spec/cloud_shaped/camelate_spec.rb
|
79
|
+
- spec/cloud_shaped/core_methods_spec.rb
|
80
|
+
- spec/cloud_shaped/function_methods_spec.rb
|
81
|
+
- spec/cloud_shaped/sns_methods_spec.rb
|
82
|
+
- spec/cloud_shaped/template_builder_spec.rb
|
83
|
+
- spec/cloud_shaped_spec.rb
|
84
|
+
- spec/spec_helper.rb
|
85
|
+
homepage: http://github.com/mdub/cloud_shaped
|
86
|
+
licenses:
|
87
|
+
- MIT
|
88
|
+
metadata: {}
|
89
|
+
post_install_message:
|
90
|
+
rdoc_options: []
|
91
|
+
require_paths:
|
92
|
+
- lib
|
93
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
94
|
+
requirements:
|
95
|
+
- - '>='
|
96
|
+
- !ruby/object:Gem::Version
|
97
|
+
version: '0'
|
98
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
99
|
+
requirements:
|
100
|
+
- - '>='
|
101
|
+
- !ruby/object:Gem::Version
|
102
|
+
version: '0'
|
103
|
+
requirements: []
|
104
|
+
rubyforge_project:
|
105
|
+
rubygems_version: 2.3.0
|
106
|
+
signing_key:
|
107
|
+
specification_version: 4
|
108
|
+
summary: DSL for AWS CloudFormation templates.
|
109
|
+
test_files:
|
110
|
+
- spec/cloud_shaped/camelate_spec.rb
|
111
|
+
- spec/cloud_shaped/core_methods_spec.rb
|
112
|
+
- spec/cloud_shaped/function_methods_spec.rb
|
113
|
+
- spec/cloud_shaped/sns_methods_spec.rb
|
114
|
+
- spec/cloud_shaped/template_builder_spec.rb
|
115
|
+
- spec/cloud_shaped_spec.rb
|
116
|
+
- spec/spec_helper.rb
|