rivet 1.4.0 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.rubocop.yml +18 -0
- data/.travis.yml +3 -5
- data/CHANGELOG.md +7 -0
- data/Gemfile.lock +27 -35
- data/README.md +71 -46
- data/autoscale/defaults.rb +23 -0
- data/bin/rivet +24 -20
- data/example/autoscale/defaults.rb +22 -0
- data/example/autoscale/example_group.rb +10 -0
- data/lib/rivet/autoscale.rb +77 -89
- data/lib/rivet/aws_autoscale_wrapper.rb +82 -0
- data/lib/rivet/aws_utils.rb +10 -8
- data/lib/rivet/bootstrap.rb +13 -58
- data/lib/rivet/client.rb +26 -20
- data/lib/rivet/config.rb +87 -0
- data/lib/rivet/config_proxy.rb +28 -0
- data/lib/rivet/deep_merge.rb +3 -1
- data/lib/rivet/launch_config.rb +45 -34
- data/lib/rivet/logger.rb +3 -1
- data/lib/rivet/open_state.rb +44 -0
- data/lib/rivet/utils.rb +11 -46
- data/lib/rivet/version.rb +3 -1
- data/lib/rivet.rb +12 -6
- data/rivet.gemspec +1 -1
- data/spec/aws_autoscale_wrapper_spec.rb +123 -0
- data/spec/bootstrap_spec.rb +38 -0
- data/spec/config_proxy_spec.rb +34 -0
- data/spec/config_spec.rb +168 -0
- data/spec/launch_config_spec.rb +30 -0
- data/spec/open_state_spec.rb +67 -0
- data/spec/spec_setup.rb +112 -0
- data/spec/util_spec.rb +34 -0
- metadata +28 -12
- data/spec/rivet_bootstrap_spec.rb +0 -80
- data/spec/rivet_launch_config_spec.rb +0 -37
- data/spec/rivet_spec_setup.rb +0 -68
- data/spec/rivet_util_spec.rb +0 -108
data/lib/rivet/launch_config.rb
CHANGED
@@ -1,30 +1,39 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
1
3
|
module Rivet
|
2
4
|
class LaunchConfig
|
3
5
|
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
6
|
+
ATTRIBUTES = [
|
7
|
+
:bootstrap,
|
8
|
+
:iam_instance_profile,
|
9
|
+
:image_id,
|
10
|
+
:instance_type,
|
11
|
+
:key_name,
|
12
|
+
:security_groups,
|
13
|
+
:associate_public_ip_address,
|
14
|
+
:detailed_instance_monitoring,
|
15
|
+
:block_device_mappings,
|
16
|
+
:kernel_id,
|
17
|
+
:ramdisk_id,
|
18
|
+
:spot_price
|
19
|
+
].each { |a| attr_reader a }
|
20
|
+
|
21
|
+
attr_reader :id_prefix, :config
|
22
|
+
|
23
|
+
def initialize(config, id_prefix = 'rivet_')
|
24
|
+
@config = config
|
13
25
|
@id_prefix = id_prefix
|
14
26
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
27
|
+
ATTRIBUTES.each do |a|
|
28
|
+
if config.respond_to?(a)
|
29
|
+
Rivet::Log.debug "Setting LaunchConfig @#{a} to #{config.send(a)}"
|
30
|
+
instance_variable_set("@#{a}", config.send(a))
|
19
31
|
end
|
20
|
-
|
21
|
-
Rivet::Log.debug("Setting LaunchConfig @#{a} to #{spec[a]}")
|
22
|
-
instance_variable_set("@#{a}", spec[a])
|
23
32
|
end
|
24
33
|
end
|
25
34
|
|
26
35
|
def user_data
|
27
|
-
@user_data ||= Bootstrap.new(
|
36
|
+
@user_data ||= Bootstrap.new(@config).user_data
|
28
37
|
end
|
29
38
|
|
30
39
|
def identity
|
@@ -37,16 +46,22 @@ module Rivet
|
|
37
46
|
lc_collection = AWS::AutoScaling.new.launch_configurations
|
38
47
|
|
39
48
|
if lc_collection[identity].exists?
|
40
|
-
Rivet::Log.info
|
49
|
+
Rivet::Log.info "Launch configuration #{identity} already exists in AWS"
|
41
50
|
else
|
42
51
|
options = {}
|
43
|
-
options[:key_pair]
|
44
|
-
options[:security_groups]
|
45
|
-
options[:user_data]
|
46
|
-
options[:iam_instance_profile]
|
47
|
-
|
48
|
-
|
49
|
-
|
52
|
+
options[:key_pair] = key_name unless key_name.nil?
|
53
|
+
options[:security_groups] = security_groups unless security_groups.nil?
|
54
|
+
options[:user_data] = user_data unless user_data.nil?
|
55
|
+
options[:iam_instance_profile] = iam_instance_profile unless iam_instance_profile.nil?
|
56
|
+
options[:associate_public_ip_address] = associate_public_ip_address unless associate_public_ip_address.nil?
|
57
|
+
options[:detailed_instance_monitoring] = detailed_instance_monitoring unless detailed_instance_monitoring.nil?
|
58
|
+
options[:block_device_mappings] = block_device_mappings unless block_device_mappings.nil?
|
59
|
+
options[:kernel_id] = kernel_id unless kernel_id.nil?
|
60
|
+
options[:ramdisk_id] = ramdisk_id unless ramdisk_id.nil?
|
61
|
+
options[:spot_price] = spot_price unless spot_price.nil?
|
62
|
+
|
63
|
+
Rivet::Log.info "Saving launch configuration #{identity} to AWS"
|
64
|
+
Rivet::Log.debug "Launch Config options:\n #{options.inspect}"
|
50
65
|
lc_collection.create(identity, image_id, instance_type, options)
|
51
66
|
end
|
52
67
|
end
|
@@ -54,10 +69,11 @@ module Rivet
|
|
54
69
|
protected
|
55
70
|
|
56
71
|
def build_identity_string
|
57
|
-
identity =
|
58
|
-
if attribute !=
|
59
|
-
attr_value = self.send(attribute
|
60
|
-
attr_value = attr_value.join("\t")
|
72
|
+
identity = ATTRIBUTES.inject('') do |accum, attribute|
|
73
|
+
if attribute != :bootstrap
|
74
|
+
attr_value = self.send(attribute) ? self.send(attribute) : "\0"
|
75
|
+
attr_value = attr_value.join("\t") if attr_value.respond_to? :join
|
76
|
+
attr_value = attr_value.to_s if !!attr_value == attr_value
|
61
77
|
accum << attribute.to_s
|
62
78
|
accum << Base64.encode64(attr_value)
|
63
79
|
else
|
@@ -66,7 +82,6 @@ module Rivet
|
|
66
82
|
end
|
67
83
|
accum
|
68
84
|
end
|
69
|
-
Rivet::Log.debug("Pre SHA1 identity string is #{identity}")
|
70
85
|
identity
|
71
86
|
end
|
72
87
|
|
@@ -74,9 +89,5 @@ module Rivet
|
|
74
89
|
@id_prefix + Digest::SHA1.hexdigest(build_identity_string)
|
75
90
|
end
|
76
91
|
|
77
|
-
def normalize_security_groups(groups)
|
78
|
-
groups.nil? ? groups : groups.sort
|
79
|
-
end
|
80
|
-
|
81
92
|
end
|
82
93
|
end
|
data/lib/rivet/logger.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
1
3
|
module Rivet
|
2
4
|
|
3
5
|
module Log
|
@@ -34,7 +36,7 @@ module Rivet
|
|
34
36
|
def initialize
|
35
37
|
@dev = Logger::LogDevice.new(STDOUT)
|
36
38
|
super @dev
|
37
|
-
@progname =
|
39
|
+
@progname = 'Rivet'
|
38
40
|
@formatter = proc do |sev, datetime, name, msg|
|
39
41
|
"[#{name}] [#{datetime}] [#{sev}]: #{msg}\n"
|
40
42
|
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
module Rivet
|
4
|
+
class OpenState
|
5
|
+
attr_reader :generated_attributes
|
6
|
+
attr_accessor :required_fields
|
7
|
+
|
8
|
+
def initialize
|
9
|
+
@generated_attributes = []
|
10
|
+
end
|
11
|
+
|
12
|
+
def install_get_or_set(name)
|
13
|
+
@generated_attributes << name
|
14
|
+
define_singleton_method(name) do |*args|
|
15
|
+
if args.size < 1
|
16
|
+
instance_variable_get("@#{name}")
|
17
|
+
else
|
18
|
+
instance_variable_set("@#{name}", args[0])
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def validate
|
24
|
+
required_fields.each_pair do |method, default_value|
|
25
|
+
unless respond_to?(method)
|
26
|
+
if default_value.nil?
|
27
|
+
fail "Required field #{method} missing!"
|
28
|
+
else
|
29
|
+
send(method, default_value)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def method_missing(m, *args, &block)
|
36
|
+
if args.size < 1
|
37
|
+
super
|
38
|
+
else
|
39
|
+
install_get_or_set(m)
|
40
|
+
send(m, args[0])
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
data/lib/rivet/utils.rb
CHANGED
@@ -1,58 +1,23 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
1
3
|
module Rivet
|
2
4
|
module Utils
|
3
|
-
|
4
5
|
def self.die(level = 'fatal', message)
|
5
6
|
Rivet::Log.write(level, message)
|
6
7
|
exit
|
7
8
|
end
|
8
9
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
if defaults && group_def
|
16
|
-
group_def = defaults.deep_merge(group_def)
|
17
|
-
end
|
18
|
-
group_def ? group_def : false
|
10
|
+
def self.list_groups(directory)
|
11
|
+
config_file_names = Dir.glob(File.join(directory,'*.rb'))
|
12
|
+
config_file_names.map! {|f| File.basename(f,'.rb')}
|
13
|
+
config_file_names.sort!
|
14
|
+
Rivet::Log.info "Available groups in #{directory}:"
|
15
|
+
config_file_names.each { |n| Rivet::Log.info n }
|
19
16
|
end
|
20
17
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
defaults_file = File.join(autoscale_dir, 'defaults.yml')
|
25
|
-
if File.exists? defaults_file
|
26
|
-
parsed = begin
|
27
|
-
Rivet::Log.debug("Consuming defaults from #{defaults_file}")
|
28
|
-
YAML.load(File.open(defaults_file))
|
29
|
-
rescue ArgumentError => e
|
30
|
-
Rivet::Log.fatal("Could not parse YAML from #{defaults_file}: #{e.message}")
|
31
|
-
end
|
32
|
-
parsed
|
33
|
-
else
|
34
|
-
false
|
35
|
-
end
|
18
|
+
def self.get_config(name, directory)
|
19
|
+
dsl_file = File.join(directory, "#{name}.rb")
|
20
|
+
Rivet::Config.from_file(dsl_file, directory) if File.exists?(dsl_file)
|
36
21
|
end
|
37
|
-
|
38
|
-
# This loads the given definition from it's YML file, returns the hash or
|
39
|
-
# false if empty
|
40
|
-
|
41
|
-
def self.load_definition(name, directory)
|
42
|
-
definition_dir = File.join(directory,name)
|
43
|
-
conf_file = File.join(definition_dir, 'conf.yml')
|
44
|
-
if Dir.exists?(definition_dir) && File.exists?(conf_file)
|
45
|
-
Rivet::Log.debug("Loading definition for #{name} from #{conf_file}")
|
46
|
-
parsed = begin
|
47
|
-
YAML.load(File.open(conf_file))
|
48
|
-
rescue
|
49
|
-
Rivet::Log.fatal("Could not parse YAML from #{conf_file}: #{e.message}")
|
50
|
-
end
|
51
|
-
parsed ? parsed : { }
|
52
|
-
else
|
53
|
-
false
|
54
|
-
end
|
55
|
-
end
|
56
|
-
|
57
22
|
end
|
58
23
|
end
|
data/lib/rivet/version.rb
CHANGED
data/lib/rivet.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
1
3
|
require 'aws-sdk'
|
2
4
|
require 'base64'
|
3
5
|
require 'digest/sha1'
|
@@ -5,14 +7,18 @@ require 'erb'
|
|
5
7
|
require 'json'
|
6
8
|
require 'logger'
|
7
9
|
require 'optparse'
|
10
|
+
require 'ostruct'
|
8
11
|
require 'singleton'
|
9
|
-
require 'yaml'
|
10
12
|
|
11
|
-
require_relative 'rivet/deep_merge'
|
12
|
-
require_relative 'rivet/logger'
|
13
|
-
require_relative 'rivet/utils'
|
14
|
-
require_relative 'rivet/aws_utils'
|
15
|
-
require_relative 'rivet/launch_config'
|
16
13
|
require_relative 'rivet/autoscale'
|
14
|
+
require_relative 'rivet/aws_autoscale_wrapper'
|
15
|
+
require_relative 'rivet/aws_utils'
|
17
16
|
require_relative 'rivet/bootstrap'
|
18
17
|
require_relative 'rivet/client'
|
18
|
+
require_relative 'rivet/open_state'
|
19
|
+
require_relative 'rivet/config'
|
20
|
+
require_relative 'rivet/config_proxy'
|
21
|
+
require_relative 'rivet/deep_merge'
|
22
|
+
require_relative 'rivet/launch_config'
|
23
|
+
require_relative 'rivet/logger'
|
24
|
+
require_relative 'rivet/utils'
|
data/rivet.gemspec
CHANGED
@@ -12,7 +12,7 @@ Gem::Specification.new do |spec|
|
|
12
12
|
spec.email = ['brian.bianco@gmail.com']
|
13
13
|
spec.homepage = 'http://www.github.com/brianbianco/rivet'
|
14
14
|
spec.summary = %q{A tool for managing autoscaling groups}
|
15
|
-
spec.description = %q{Rivet allows you to define autoscaling groups and launch configurations as
|
15
|
+
spec.description = %q{Rivet allows you to define autoscaling groups and launch configurations as configuration and SYNC that to AWS}
|
16
16
|
|
17
17
|
spec.required_ruby_version = '>= 1.9.1'
|
18
18
|
spec.required_rubygems_version = '>= 1.3.6'
|
@@ -0,0 +1,123 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
require_relative './spec_setup'
|
3
|
+
|
4
|
+
include SpecHelpers
|
5
|
+
|
6
|
+
describe 'rivet aws autoscale wrapper' do
|
7
|
+
let(:normalized_values) do
|
8
|
+
{
|
9
|
+
:launch_configuration => 'unit_test_lc',
|
10
|
+
:load_balancers => %w(balancer1 balancer2),
|
11
|
+
:availability_zones => %w(unit-test-1a unit-test-1b),
|
12
|
+
:tags => [
|
13
|
+
{ :propagate_at_launch => true, :key => 'Name', :value => 'Unit Test' },
|
14
|
+
{ :propagate_at_launch => false, :key => 'Sandwich', :value => 'Ham' }
|
15
|
+
],
|
16
|
+
:subnets => %w(subnet-0000000a subnet-0000000b),
|
17
|
+
:termination_policies => %w(policy1 policy2)
|
18
|
+
}
|
19
|
+
end
|
20
|
+
|
21
|
+
let(:aws_mock) do
|
22
|
+
subnet_mock1 = double('Aws EC2 subnet')
|
23
|
+
subnet_mock1.stub(:id).and_return('subnet-0000000b')
|
24
|
+
subnet_mock2 = double('Aws EC2 subnet')
|
25
|
+
subnet_mock2.stub(:id).and_return('subnet-0000000a')
|
26
|
+
|
27
|
+
mock = double('Aws Autoscaling Group')
|
28
|
+
mock.stub(:health_check_type).and_return(:ec2)
|
29
|
+
mock.stub(:desired_capacity).and_return(1)
|
30
|
+
mock.stub(:max_size).and_return(2)
|
31
|
+
mock.stub(:min_size).and_return(0)
|
32
|
+
mock.stub(:launch_configuration_name).and_return('unit_test_lc')
|
33
|
+
mock.stub(:load_balancer_names).and_return(%w(balancer2 balancer1))
|
34
|
+
mock.stub(:availability_zone_names).and_return(%w(unit-test-1b unit-test-1a))
|
35
|
+
mock.stub(:subnets).and_return([subnet_mock1, subnet_mock2])
|
36
|
+
mock.stub(:termination_policies).and_return(%w(policy2 policy1))
|
37
|
+
mock.stub(:default_cooldown).and_return(100)
|
38
|
+
mock.stub(:health_check_grace_period).and_return(300)
|
39
|
+
mock.stub(:placement_group).and_return('donkey')
|
40
|
+
mock.stub(:name).and_return('unit_test_scaling_group')
|
41
|
+
mock.stub(:tags).and_return([
|
42
|
+
{ :resource_id => 'snickers', :propagate_at_launch => true, :key => 'Name', :value => 'Unit Test' },
|
43
|
+
{ :resource_type => 'yogurt', :propagate_at_launch => false, :key => 'Sandwich', :value => 'Ham' }
|
44
|
+
])
|
45
|
+
mock.stub(:exists?).and_return(true)
|
46
|
+
mock
|
47
|
+
end
|
48
|
+
|
49
|
+
let(:groups_mock) do
|
50
|
+
groups_mock = double('groups_mock')
|
51
|
+
groups_mock.stub(:groups).and_return(group_mock)
|
52
|
+
groups_mock
|
53
|
+
end
|
54
|
+
|
55
|
+
let(:group_mock) do
|
56
|
+
group_mock = double('group_mock')
|
57
|
+
group_mock.stub(:[]).with(/unit_test_scaling_group/).and_return(aws_mock)
|
58
|
+
group_mock
|
59
|
+
end
|
60
|
+
|
61
|
+
let(:wrapper) { Rivet::AwsAutoscaleWrapper.new('unit_test_scaling_group') }
|
62
|
+
|
63
|
+
before do
|
64
|
+
AWS::AutoScaling.stub(:new).and_return(groups_mock)
|
65
|
+
end
|
66
|
+
|
67
|
+
describe '#normalize_launch_configuration' do
|
68
|
+
it 'returns launch configuration name' do
|
69
|
+
wrapper.normalize_launch_configuration.should == 'unit_test_lc'
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
describe '#normalize_load_balancers' do
|
74
|
+
it 'returns a normalized array of load balancers' do
|
75
|
+
wrapper.normalize_load_balancers.should == %w(balancer1 balancer2)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
describe '#normalize_availability_zones' do
|
80
|
+
it 'returns a normalized array of availability zones' do
|
81
|
+
wrapper.normalize_availability_zones.should == %w(unit-test-1a unit-test-1b)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
describe '#normalize_tags' do
|
86
|
+
it 'returns a normalized array of tags' do
|
87
|
+
tags = [{ :propagate_at_launch => true, :key => 'Name', :value => 'Unit Test' },
|
88
|
+
{ :propagate_at_launch => false, :key => 'Sandwich', :value => 'Ham' }]
|
89
|
+
wrapper.normalize_tags.should == tags
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
describe '#normalize_subnets' do
|
94
|
+
it 'returns a normalized array of subnets' do
|
95
|
+
wrapper.normalize_subnets.should == %w(subnet-0000000a subnet-0000000b)
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
describe '#normalize_termination_policies' do
|
100
|
+
it 'returns a normalized array of termination policies' do
|
101
|
+
wrapper.normalize_termination_policies.should == %w(policy1 policy2)
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
describe '#normalize_tag' do
|
106
|
+
it 'returns a normalized tag' do
|
107
|
+
tag = { :resource_id => 'yoda', :resource_type => 'chewie',
|
108
|
+
:propagate_at_launch => true, :key => 'place', :value => 'alderaan' }
|
109
|
+
|
110
|
+
normalized_tag = { :propagate_at_launch => true, :key => 'place', :value => 'alderaan' }
|
111
|
+
|
112
|
+
wrapper.send(:normalize_tag, tag).should == normalized_tag
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
describe '#new' do
|
117
|
+
it 'should normalize values if normalize methods exist' do
|
118
|
+
normalized_values.each_pair do |attr, value|
|
119
|
+
wrapper.send(attr).should == value
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
require_relative './spec_setup'
|
3
|
+
|
4
|
+
include SpecHelpers
|
5
|
+
|
6
|
+
describe 'rivet bootstrap' do
|
7
|
+
let(:config) { generate_config_mock(double('config_mock'), DSL_VALUES) }
|
8
|
+
let(:bootstrap) { Rivet::Bootstrap.new(config) }
|
9
|
+
let(:blank_config) do
|
10
|
+
blank_config_mock = double('blank_config_mock')
|
11
|
+
blank_config_mock.stub(:bootstrap).and_return
|
12
|
+
generate_config_mock(blank_config_mock, {})
|
13
|
+
end
|
14
|
+
let(:blank_bootstrap) { Rivet::Bootstrap.new(blank_config) }
|
15
|
+
|
16
|
+
tempdir_context 'with all necessary files in place' do
|
17
|
+
before do
|
18
|
+
FileUtils.mkdir_p AUTOSCALE_DIR
|
19
|
+
File.open(TEMPLATE_FILE, 'w') { |f| f.write(SpecHelpers::BOOTSTRAP_TEMPLATE) }
|
20
|
+
end
|
21
|
+
|
22
|
+
context 'with a tempate file specified' do
|
23
|
+
describe '#user_data' do
|
24
|
+
it 'returns a string of the rendered template' do
|
25
|
+
bootstrap.user_data.should include('bar')
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
context 'without a template specified' do
|
31
|
+
describe '#user_data' do
|
32
|
+
it 'returns a blank string' do
|
33
|
+
blank_bootstrap.user_data.should be_empty
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
require_relative './spec_setup'
|
3
|
+
|
4
|
+
include SpecHelpers
|
5
|
+
|
6
|
+
describe 'Rivet Config Proxy' do
|
7
|
+
let(:config) do
|
8
|
+
config_mock = double('config_mock')
|
9
|
+
config_mock.stub(:normalize_unit_test).and_return('normalized ham sandwich')
|
10
|
+
config_mock.stub(:unit_test).and_return('ham sandwich')
|
11
|
+
config_mock.stub(:goat).and_return('bah')
|
12
|
+
config_mock
|
13
|
+
end
|
14
|
+
|
15
|
+
let(:config_proxy) { Rivet::ConfigProxy.new(config) }
|
16
|
+
|
17
|
+
describe '#send' do
|
18
|
+
it 'it calls normalize for a method if it iss available' do
|
19
|
+
config_proxy.send(:unit_test).should == 'normalized ham sandwich'
|
20
|
+
end
|
21
|
+
it 'it passes on a message sent to it if no normalize method exists' do
|
22
|
+
config_proxy.send(:goat).should == 'bah'
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
describe 'it calls normalize for a method if it is available' do
|
27
|
+
it 'it calls normalize for a method if it is available' do
|
28
|
+
config_proxy.unit_test.should == 'normalized ham sandwich'
|
29
|
+
end
|
30
|
+
it 'it passes on a message sent to it if no normalize method exists' do
|
31
|
+
config_proxy.goat.should == 'bah'
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
data/spec/config_spec.rb
ADDED
@@ -0,0 +1,168 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
require_relative './spec_setup'
|
3
|
+
|
4
|
+
include SpecHelpers
|
5
|
+
|
6
|
+
|
7
|
+
describe 'rivet config' do
|
8
|
+
let(:default_config) { Rivet::Config.new('default_unit_test_config') }
|
9
|
+
let(:config) { Rivet::Config.new('unit_test_config') { eval(DSL_CONFIG_CONTENT) } }
|
10
|
+
|
11
|
+
context 'without DSL content' do
|
12
|
+
describe '#new' do
|
13
|
+
it 'returns a Rivet::Config object' do
|
14
|
+
default_config.should be_an_instance_of Rivet::Config
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
describe '#name' do
|
19
|
+
it 'returns the name' do
|
20
|
+
default_config.name.should == 'default_unit_test_config'
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
describe '#bootstrap' do
|
25
|
+
before do
|
26
|
+
default_config.bootstrap.unit_test 'goat simulator'
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'should allow you to set an arbitrary bootstrap value' do
|
30
|
+
default_config.bootstrap.unit_test.should == 'goat simulator'
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
describe '#path' do
|
35
|
+
context 'with no arguments' do
|
36
|
+
it 'returns the default . path' do
|
37
|
+
default_config.path.should == '.'
|
38
|
+
end
|
39
|
+
end
|
40
|
+
context 'with an argument' do
|
41
|
+
it 'returns the set path joined with the argument' do
|
42
|
+
default_config.path('test').should == './test'
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
describe '#normalize_availability_zones' do
|
48
|
+
before do
|
49
|
+
default_config.region 'us-west-2'
|
50
|
+
default_config.availability_zones %w(c a b)
|
51
|
+
end
|
52
|
+
|
53
|
+
it 'should return a sorted array of zones with the region prepended' do
|
54
|
+
default_config.normalize_availability_zones.should == %w(us-west-2a us-west-2b us-west-2c)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
describe '#normalize_security_groups' do
|
59
|
+
before do
|
60
|
+
default_config.security_groups %w(group2 group1 group3)
|
61
|
+
end
|
62
|
+
|
63
|
+
it 'should return a sorted array of security groups' do
|
64
|
+
default_config.normalize_security_groups.should == %w(group1 group2 group3)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
describe '#normalize_load_balancers' do
|
69
|
+
before do
|
70
|
+
default_config.load_balancers %w(balancer2 balancer1)
|
71
|
+
end
|
72
|
+
|
73
|
+
it 'should return a sorted array of load balancers' do
|
74
|
+
default_config.normalize_load_balancers.should == %w(balancer1 balancer2)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
describe '#normalize_subnets' do
|
79
|
+
before do
|
80
|
+
default_config.subnets %w(192.168.1.2 192.168.1.3 192.168.1.1)
|
81
|
+
end
|
82
|
+
|
83
|
+
it 'should return a sorted array of subnets' do
|
84
|
+
default_config.normalize_subnets.should == %w(192.168.1.1 192.168.1.2 192.168.1.3)
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
describe '#normalize_tags' do
|
89
|
+
before do
|
90
|
+
default_config.tags [
|
91
|
+
{ key: 'Name', value: 'unit test' },
|
92
|
+
{ key: 'Other', value: 'sasquatch', propagate_at_launch: false }
|
93
|
+
]
|
94
|
+
end
|
95
|
+
|
96
|
+
it 'should return a normalized array of hashes' do
|
97
|
+
expected_result = [
|
98
|
+
{ propagate_at_launch: true, key: 'Name', value: 'unit test' },
|
99
|
+
{ propagate_at_launch: false, key: 'Other', value: 'sasquatch' }
|
100
|
+
]
|
101
|
+
default_config.normalize_tags.should == expected_result
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
context 'with DSL content' do
|
107
|
+
|
108
|
+
describe '#new' do
|
109
|
+
it 'returns a Rivet::Config object' do
|
110
|
+
config.should be_an_instance_of Rivet::Config
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
describe '#name' do
|
115
|
+
it 'returns the name' do
|
116
|
+
config.name.should == 'unit_test_config'
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
describe 'generated attributes' do
|
121
|
+
it 'should contain all the attributes defined in the DSL CONTENT' do
|
122
|
+
DSL_VALUES.each_pair do |k, v|
|
123
|
+
# bootstrap is an attribute of the Config class, not a generated one
|
124
|
+
unless k == :bootstrap
|
125
|
+
config.generated_attributes.should include(k)
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
it 'should have all values properly set according to the DSL CONTENT' do
|
131
|
+
DSL_VALUES.each_pair do |k, v|
|
132
|
+
unless k == :bootstrap
|
133
|
+
config.send(k).should == eval(v)
|
134
|
+
end
|
135
|
+
end
|
136
|
+
DSL_VALUES[:bootstrap].each_pair do |k, v|
|
137
|
+
config.bootstrap.send(k).should == eval(v)
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
tempdir_context 'with DSL content inside of a file on disk' do
|
144
|
+
let(:config_from_file) { Rivet::Config.from_file(File.join('.', 'unit_test.rb')) }
|
145
|
+
|
146
|
+
before do
|
147
|
+
File.open('unit_test.rb', 'w') { |f| f.write(DSL_CONFIG_CONTENT) }
|
148
|
+
end
|
149
|
+
|
150
|
+
describe '::from_file' do
|
151
|
+
it 'returns an instance of Rivet::Config' do
|
152
|
+
config_from_file.should be_an_instance_of Rivet::Config
|
153
|
+
end
|
154
|
+
|
155
|
+
it 'should have all values properly set according to the DSL CONTENT' do
|
156
|
+
DSL_VALUES.each_pair do |k, v|
|
157
|
+
unless k == :bootstrap
|
158
|
+
config_from_file.send(k).should == eval(v)
|
159
|
+
end
|
160
|
+
end
|
161
|
+
DSL_VALUES[:bootstrap].each_pair do |k, v|
|
162
|
+
config_from_file.bootstrap.send(k).should == eval(v)
|
163
|
+
end
|
164
|
+
end
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
end
|