chemtrail 0.2.0 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +14 -0
- data/bin/chemtrail +0 -1
- data/examples/.rspec +2 -0
- data/examples/Guardfile +8 -0
- data/examples/lib/templates/config/mappings.yml +53 -0
- data/examples/lib/templates/config/parameters.yml +18 -0
- data/examples/lib/templates/opsworks_vpc_template.rb +44 -0
- data/examples/spec/lib/templates/opsworks_vpc_template_spec.rb +30 -0
- data/examples/spec/spec_helper.rb +15 -0
- data/lib/chemtrail/cli.rb +1 -0
- data/lib/chemtrail/mapping.rb +2 -1
- data/lib/chemtrail/parameter.rb +5 -5
- data/lib/chemtrail/rspec.rb +131 -0
- data/lib/chemtrail/version.rb +1 -1
- data/spec/lib/chemtrail/cli_spec.rb +3 -2
- data/spec/lib/chemtrail/mapping_spec.rb +9 -3
- data/spec/lib/chemtrail/parameter_spec.rb +5 -5
- metadata +9 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0b457fc52081b5875c31d1d124429aa6d438b31a
|
4
|
+
data.tar.gz: 77706788871003cba5307760765b907f986a80e4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cf6193b91a72aeafb284aa0c928c599a04796379af5d90005fa67caed9b5283f442eb076bf0dd22acbb4f773bb151f505975ac82e095ab7a9f39a3d9bfc8ff7b
|
7
|
+
data.tar.gz: d81f93f39b399601bfd3cb96f1bef9314df9e4360f327651a36b9baae7f4635ec11a6c5542fd68d890d88cd894823fad0e7d8d0ad9172d47c7dcb477c14e2a11
|
data/README.md
CHANGED
@@ -33,6 +33,20 @@ Or install it yourself as:
|
|
33
33
|
Usage
|
34
34
|
-----
|
35
35
|
|
36
|
+
See the `examples/` directory for examples of subclassing and testing templates.
|
37
|
+
|
38
|
+
Listing all available templates in `lib/templates`:
|
39
|
+
|
40
|
+
$ chemtrail list
|
41
|
+
|
42
|
+
Listing templates in a different path:
|
43
|
+
|
44
|
+
$ chemtrail list --path lib/taco/panic
|
45
|
+
|
46
|
+
Building a template:
|
47
|
+
|
48
|
+
$ chemtrail build crazy:cat:pants
|
49
|
+
|
36
50
|
|
37
51
|
Contributing
|
38
52
|
------------
|
data/bin/chemtrail
CHANGED
data/examples/.rspec
ADDED
data/examples/Guardfile
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
AWSNATAMI:
|
2
|
+
us-east-1:
|
3
|
+
AMI: ami-c6699baf
|
4
|
+
us-west-2:
|
5
|
+
AMI: ami-52ff7262
|
6
|
+
us-west-1:
|
7
|
+
AMI: ami-3bcc9e7e
|
8
|
+
eu-west-1:
|
9
|
+
AMI: ami-0b5b6c7f
|
10
|
+
ap-southeast-1:
|
11
|
+
AMI: ami-02eb9350
|
12
|
+
ap-southeast-2:
|
13
|
+
AMI: ami-ab990e91
|
14
|
+
ap-northeast-1:
|
15
|
+
AMI: ami-14d86d15
|
16
|
+
sa-east-1:
|
17
|
+
AMI: ami-0439e619
|
18
|
+
|
19
|
+
AWSInstanceType2Arch:
|
20
|
+
t1.micro:
|
21
|
+
Arch: "64"
|
22
|
+
m1.small:
|
23
|
+
Arch: "64"
|
24
|
+
m1.medium:
|
25
|
+
Arch: "64"
|
26
|
+
m1.large:
|
27
|
+
Arch: "64"
|
28
|
+
m1.xlarge:
|
29
|
+
Arch: "64"
|
30
|
+
m2.xlarge:
|
31
|
+
Arch: "64"
|
32
|
+
m2.2xlarge:
|
33
|
+
Arch: "64"
|
34
|
+
m2.4xlarge:
|
35
|
+
Arch: "64"
|
36
|
+
c1.medium:
|
37
|
+
Arch: "64"
|
38
|
+
c1.xlarge:
|
39
|
+
Arch: "64"
|
40
|
+
cc1.4xlarge:
|
41
|
+
Arch: 64Cluster
|
42
|
+
cc2.8xlarge:
|
43
|
+
Arch: 64Cluster
|
44
|
+
cg1.4xlarge:
|
45
|
+
Arch: 64GPU
|
46
|
+
|
47
|
+
SubnetConfig:
|
48
|
+
VPC:
|
49
|
+
CIDR: 10.0.0.0/16
|
50
|
+
Public:
|
51
|
+
CIDR: 10.0.0.0/24
|
52
|
+
Private:
|
53
|
+
CIDR: 10.0.1.0/24
|
@@ -0,0 +1,18 @@
|
|
1
|
+
NATInstanceType:
|
2
|
+
Default: m1.small
|
3
|
+
Description: NAT Device EC2 instance type
|
4
|
+
ConstraintDescription: must be a valid EC2 instance type.
|
5
|
+
AllowedValues:
|
6
|
+
- t1.micro
|
7
|
+
- m1.small
|
8
|
+
- m1.medium
|
9
|
+
- m1.large
|
10
|
+
- m1.xlarge
|
11
|
+
- m2.xlarge
|
12
|
+
- m2.2xlarge
|
13
|
+
- m2.4xlarge
|
14
|
+
- c1.medium
|
15
|
+
- c1.xlarge
|
16
|
+
- cc1.4xlarge
|
17
|
+
- cc2.8xlarge
|
18
|
+
- cg1.4xlarge
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require "chemtrail"
|
2
|
+
require "yaml"
|
3
|
+
|
4
|
+
class OpsworksVpc < Chemtrail::Template
|
5
|
+
def description
|
6
|
+
<<-DESCRIPTION.strip.gsub!(/\s+/, ' ')
|
7
|
+
Sample template showing how to create a VPC environment for AWS OpsWorks.
|
8
|
+
The stack contains 2 subnets: the first subnet is public and contains the
|
9
|
+
load balancer, a NAT device for internet access from the private subnet.
|
10
|
+
The second subnet is private.
|
11
|
+
|
12
|
+
You will be billed for the AWS resources used if you create a stack from
|
13
|
+
this template.
|
14
|
+
DESCRIPTION
|
15
|
+
end
|
16
|
+
|
17
|
+
def parameters
|
18
|
+
[
|
19
|
+
Chemtrail::Parameter.new("NATInstanceType", "String", parameters_config["NATInstanceType"])
|
20
|
+
]
|
21
|
+
end
|
22
|
+
|
23
|
+
def mappings
|
24
|
+
[
|
25
|
+
Chemtrail::Mapping.new("AWSNATAMI", mappings_config["AWSNATAMI"]),
|
26
|
+
Chemtrail::Mapping.new("AWSInstanceType2Arch", mappings_config["AWSInstanceType2Arch"]),
|
27
|
+
Chemtrail::Mapping.new("SubnetConfig", mappings_config["SubnetConfig"])
|
28
|
+
]
|
29
|
+
end
|
30
|
+
|
31
|
+
protected
|
32
|
+
|
33
|
+
def parameters_config
|
34
|
+
@parameters_config ||= YAML.load_file(File.expand_path("../config/parameters.yml", __FILE__))
|
35
|
+
end
|
36
|
+
|
37
|
+
def mappings_config
|
38
|
+
@mappings_config ||= YAML.load_file(File.expand_path("../config/mappings.yml", __FILE__))
|
39
|
+
end
|
40
|
+
|
41
|
+
def resources_config
|
42
|
+
@resources_config ||= YAML.load_file(File.expand_path("../config/resources.yml", __FILE__))
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe OpsworksVpc do
|
4
|
+
subject(:template) { OpsworksVpc.new }
|
5
|
+
|
6
|
+
its(:description) { should include("VPC environment for AWS OpsWorks") }
|
7
|
+
|
8
|
+
describe "#parameters" do
|
9
|
+
it { should have_parameter("NATInstanceType").with_type("String") }
|
10
|
+
|
11
|
+
it { should have_field("Default").with_value("m1.small").on("NATInstanceType") }
|
12
|
+
it { should have_field("AllowedValues").including("t1.micro").on("NATInstanceType") }
|
13
|
+
it { should have_field("ConstraintDescription").including("valid EC2 instance").on("NATInstanceType") }
|
14
|
+
end
|
15
|
+
|
16
|
+
describe "#mappings" do
|
17
|
+
it { should have_mapping("AWSNATAMI") }
|
18
|
+
it { should have_mapping("AWSInstanceType2Arch") }
|
19
|
+
it { should have_mapping("SubnetConfig") }
|
20
|
+
|
21
|
+
it { should have_mapping_key("us-east-1").including("AMI" => "ami-c6699baf").on("AWSNATAMI") }
|
22
|
+
it { should have_mapping_key("m1.medium").including("Arch" => "64").on("AWSInstanceType2Arch") }
|
23
|
+
it { should have_mapping_key("VPC").including("CIDR" => "10.0.0.0/16").on("SubnetConfig") }
|
24
|
+
it { should have_mapping_key("Public").including("CIDR" => "10.0.0.0/24").on("SubnetConfig") }
|
25
|
+
it { should have_mapping_key("Private").including("CIDR" => "10.0.1.0/24").on("SubnetConfig") }
|
26
|
+
end
|
27
|
+
|
28
|
+
describe "#resources" do
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
$:<< File.expand_path("../../../lib", __FILE__)
|
2
|
+
|
3
|
+
require "chemtrail"
|
4
|
+
require "chemtrail/rspec"
|
5
|
+
|
6
|
+
Dir.glob(File.expand_path("../../lib/templates/**/*_template.rb", __FILE__)).each { |t| require t }
|
7
|
+
|
8
|
+
RSpec.configure do |config|
|
9
|
+
config.include Chemtrail::RSpec
|
10
|
+
config.treat_symbols_as_metadata_keys_with_true_values = true
|
11
|
+
config.run_all_when_everything_filtered = true
|
12
|
+
config.filter_run :focus
|
13
|
+
config.order = 'random'
|
14
|
+
end
|
15
|
+
|
data/lib/chemtrail/cli.rb
CHANGED
data/lib/chemtrail/mapping.rb
CHANGED
data/lib/chemtrail/parameter.rb
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
class Chemtrail::Parameter
|
2
2
|
attr_reader :id, :type
|
3
3
|
|
4
|
-
def initialize(id, type,
|
4
|
+
def initialize(id, type, fields = {})
|
5
5
|
@id = id
|
6
6
|
@type = type
|
7
|
-
@
|
7
|
+
@fields = fields
|
8
8
|
end
|
9
9
|
|
10
|
-
def
|
11
|
-
@
|
10
|
+
def fields
|
11
|
+
@fields ||= {}
|
12
12
|
end
|
13
13
|
|
14
14
|
def to_reference
|
@@ -21,7 +21,7 @@ class Chemtrail::Parameter
|
|
21
21
|
{
|
22
22
|
id => {
|
23
23
|
"Type" => type
|
24
|
-
}.merge(
|
24
|
+
}.merge(fields)
|
25
25
|
}
|
26
26
|
end
|
27
27
|
end
|
@@ -0,0 +1,131 @@
|
|
1
|
+
require "chemtrail"
|
2
|
+
require "rspec/expectations"
|
3
|
+
|
4
|
+
module Chemtrail::RSpec
|
5
|
+
extend RSpec::Matchers::DSL
|
6
|
+
|
7
|
+
matcher :have_parameter do |parameter_id|
|
8
|
+
define_method :parameter_for do |actual|
|
9
|
+
actual.parameters.detect { |param| param.id == parameter_id }
|
10
|
+
end
|
11
|
+
|
12
|
+
define_method :matches_type? do |actual|
|
13
|
+
@type.nil? || parameter_for(actual).type == @type
|
14
|
+
end
|
15
|
+
|
16
|
+
match do |actual|
|
17
|
+
!parameter_for(actual).nil? && matches_type?(actual)
|
18
|
+
end
|
19
|
+
|
20
|
+
chain :with_type do |type|
|
21
|
+
@type = type
|
22
|
+
end
|
23
|
+
|
24
|
+
failure_message_for_should do |actual|
|
25
|
+
if parameter = parameter_for(actual)
|
26
|
+
%(expected parameter #{parameter_id.inspect} to have type #{@type.inspect}, but got #{parameter.type.inspect})
|
27
|
+
else
|
28
|
+
%(expected to find parameter #{parameter_id.inspect}, but got nothing)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
matcher :have_field do |field_name|
|
34
|
+
define_method :parameter_for do |actual|
|
35
|
+
actual.parameters.detect { |p| p.id == @parameter_id }
|
36
|
+
end
|
37
|
+
|
38
|
+
define_method :field_for do |parameter|
|
39
|
+
parameter.fields[field_name]
|
40
|
+
end
|
41
|
+
|
42
|
+
define_method :matches_value? do |field|
|
43
|
+
if @value
|
44
|
+
field == @value
|
45
|
+
elsif @included_value
|
46
|
+
field.include?(@included_value)
|
47
|
+
else
|
48
|
+
true
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
match do |actual|
|
53
|
+
parameter = parameter_for(actual)
|
54
|
+
field = field_for(parameter)
|
55
|
+
!parameter.nil? && !field.nil? && matches_value?(field)
|
56
|
+
end
|
57
|
+
|
58
|
+
chain :on do |parameter_id|
|
59
|
+
@parameter_id = parameter_id
|
60
|
+
end
|
61
|
+
|
62
|
+
chain :with_value do |value|
|
63
|
+
@value = value
|
64
|
+
end
|
65
|
+
|
66
|
+
chain :including do |value|
|
67
|
+
@included_value = value
|
68
|
+
end
|
69
|
+
|
70
|
+
failure_message_for_should do |actual|
|
71
|
+
if parameter = parameter_for(actual)
|
72
|
+
if field = field_for(parameter)
|
73
|
+
expected_field = @value || @included_value
|
74
|
+
%(expected parameter #{@parameter_id.inspect} field #{field_name.inspect} to have value #{expected_field.inspect}, but got #{field.inspect})
|
75
|
+
else
|
76
|
+
%(expected parameter #{@parameter_id.inspect} to have type #{field_name.inspect})
|
77
|
+
end
|
78
|
+
else
|
79
|
+
%(expected to find parameter #{@parameter_id.inspect}, but got nothing)
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
matcher :have_mapping do |expected|
|
85
|
+
match { |actual| actual.mappings.any? { |m| m.id == expected } }
|
86
|
+
end
|
87
|
+
|
88
|
+
matcher :have_mapping_key do |entry_name|
|
89
|
+
define_method :mapping_for do |actual|
|
90
|
+
actual.mappings.detect { |m| m.id == @mapping_id }
|
91
|
+
end
|
92
|
+
|
93
|
+
define_method :entry_for do |mapping|
|
94
|
+
mapping.entries[entry_name]
|
95
|
+
end
|
96
|
+
|
97
|
+
define_method :matches_value? do |entry|
|
98
|
+
if @included_value
|
99
|
+
entry.values_at(*@included_value.keys) == @included_value.values
|
100
|
+
else
|
101
|
+
true
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
match do |actual|
|
106
|
+
mapping = mapping_for(actual)
|
107
|
+
entry = entry_for(mapping)
|
108
|
+
!mapping.nil? && !entry.nil? && matches_value?(entry)
|
109
|
+
end
|
110
|
+
|
111
|
+
chain :on do |mapping_id|
|
112
|
+
@mapping_id = mapping_id
|
113
|
+
end
|
114
|
+
|
115
|
+
chain :including do |value|
|
116
|
+
@included_value = value
|
117
|
+
end
|
118
|
+
|
119
|
+
failure_message_for_should do |actual|
|
120
|
+
if mapping = mapping_for(actual)
|
121
|
+
if entry = entry_for(mapping)
|
122
|
+
%(expected mapping #{@mapping_id.inspect} field #{entry_name.inspect} to have value #{@included_value.inspect}, but got #{entry.inspect})
|
123
|
+
else
|
124
|
+
%(expected mapping #{@mapping_id.inspect} to have type #{entry_name.inspect})
|
125
|
+
end
|
126
|
+
else
|
127
|
+
%(expected to find mapping #{@mapping_id.inspect}, but got nothing)
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
data/lib/chemtrail/version.rb
CHANGED
@@ -5,8 +5,9 @@ describe Chemtrail::Cli do
|
|
5
5
|
|
6
6
|
describe "#list" do
|
7
7
|
it "lists available templates" do
|
8
|
-
|
9
|
-
|
8
|
+
got_tacos = false
|
9
|
+
Kernel.stub(:puts) { |string| got_tacos ||= (string == "tacos") }
|
10
|
+
expect { cli.list }.to change{ got_tacos }.to(true)
|
10
11
|
end
|
11
12
|
end
|
12
13
|
|
@@ -5,13 +5,19 @@ describe Chemtrail::Mapping do
|
|
5
5
|
|
6
6
|
describe "#to_hash" do
|
7
7
|
context "when there are no entries" do
|
8
|
-
its(:to_hash) { should
|
8
|
+
its(:to_hash) { should == {"atlas" => {}} }
|
9
9
|
end
|
10
10
|
|
11
11
|
context "when an entry has been added" do
|
12
|
-
before { mapping.entries[
|
12
|
+
before { mapping.entries[:teeth] = {} }
|
13
13
|
|
14
|
-
specify { mapping.to_hash["atlas"].should
|
14
|
+
specify { mapping.to_hash["atlas"].should == {teeth: {}} }
|
15
|
+
end
|
16
|
+
|
17
|
+
context "when an entry is passed into the initializer" do
|
18
|
+
subject(:mapping) { Chemtrail::Mapping.new("atlas", charles: {}) }
|
19
|
+
|
20
|
+
specify { mapping.to_hash["atlas"].should == {charles: {}} }
|
15
21
|
end
|
16
22
|
end
|
17
23
|
|
@@ -3,15 +3,15 @@ require "spec_helper"
|
|
3
3
|
describe Chemtrail::Parameter do
|
4
4
|
subject(:parameter) { Chemtrail::Parameter.new("parmesan", "String") }
|
5
5
|
|
6
|
-
describe "#
|
7
|
-
context "when there are no
|
8
|
-
its(:
|
6
|
+
describe "#fields" do
|
7
|
+
context "when there are no fields" do
|
8
|
+
its(:fields) { should be_empty }
|
9
9
|
end
|
10
10
|
|
11
11
|
context "when a specification has been passed into the initializer" do
|
12
12
|
subject(:parameter) { Chemtrail::Parameter.new("parmesan", "String", ok: "great") }
|
13
13
|
|
14
|
-
its(:
|
14
|
+
its(:fields) { should == {ok: "great"} }
|
15
15
|
end
|
16
16
|
end
|
17
17
|
|
@@ -24,7 +24,7 @@ describe Chemtrail::Parameter do
|
|
24
24
|
specify { parameter.to_hash["parmesan"].should include("Type" => "String") }
|
25
25
|
|
26
26
|
context "when there is a specification" do
|
27
|
-
before { parameter.
|
27
|
+
before { parameter.fields[:ducks] = "amazing" }
|
28
28
|
|
29
29
|
specify { parameter.to_hash["parmesan"].should include(ducks: "amazing") }
|
30
30
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: chemtrail
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Doc Ritezel
|
@@ -99,6 +99,13 @@ files:
|
|
99
99
|
- README.md
|
100
100
|
- bin/chemtrail
|
101
101
|
- chemtrail.gemspec
|
102
|
+
- examples/.rspec
|
103
|
+
- examples/Guardfile
|
104
|
+
- examples/lib/templates/config/mappings.yml
|
105
|
+
- examples/lib/templates/config/parameters.yml
|
106
|
+
- examples/lib/templates/opsworks_vpc_template.rb
|
107
|
+
- examples/spec/lib/templates/opsworks_vpc_template_spec.rb
|
108
|
+
- examples/spec/spec_helper.rb
|
102
109
|
- lib/chemtrail.rb
|
103
110
|
- lib/chemtrail/class_name_inflector.rb
|
104
111
|
- lib/chemtrail/cli.rb
|
@@ -109,6 +116,7 @@ files:
|
|
109
116
|
- lib/chemtrail/property_list.rb
|
110
117
|
- lib/chemtrail/reference_presenter.rb
|
111
118
|
- lib/chemtrail/resource.rb
|
119
|
+
- lib/chemtrail/rspec.rb
|
112
120
|
- lib/chemtrail/section_presenter.rb
|
113
121
|
- lib/chemtrail/template.rb
|
114
122
|
- lib/chemtrail/version.rb
|