rivet 1.4.0 → 2.0.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.
- 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
|