rivet 1.3.0 → 1.4.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +27 -2
- data/CHANGELOG.md +7 -0
- data/Gemfile +0 -1
- data/README.md +14 -4
- data/lib/rivet/autoscale.rb +28 -30
- data/lib/rivet/aws_utils.rb +5 -5
- data/lib/rivet/bootstrap.rb +33 -21
- data/lib/rivet/client.rb +1 -2
- data/lib/rivet/launch_config.rb +12 -13
- data/lib/rivet/logger.rb +7 -9
- data/lib/rivet/utils.rb +8 -9
- data/lib/rivet/version.rb +1 -2
- data/rivet.gemspec +1 -2
- data/spec/rivet_bootstrap_spec.rb +28 -9
- data/spec/rivet_launch_config_spec.rb +2 -2
- data/spec/rivet_spec_setup.rb +15 -11
- data/spec/rivet_util_spec.rb +14 -15
- metadata +18 -2
data/.gitignore
CHANGED
@@ -1,3 +1,28 @@
|
|
1
|
-
autoscale/
|
2
|
-
*.swp
|
3
1
|
*.gem
|
2
|
+
*.rbc
|
3
|
+
*.swp
|
4
|
+
.bundle
|
5
|
+
.config
|
6
|
+
.DS_Store
|
7
|
+
.envrc
|
8
|
+
.ruby-version
|
9
|
+
.rvmrc
|
10
|
+
coverage
|
11
|
+
InstalledFiles
|
12
|
+
lib/bundler/man
|
13
|
+
pkg
|
14
|
+
rdoc
|
15
|
+
spec/reports
|
16
|
+
test/tmp
|
17
|
+
test/version_tmp
|
18
|
+
tmp
|
19
|
+
|
20
|
+
# YARD artifacts
|
21
|
+
.yardoc
|
22
|
+
_yardoc
|
23
|
+
doc/
|
24
|
+
|
25
|
+
autoscale/
|
26
|
+
|
27
|
+
bin/*
|
28
|
+
!bin/rivet
|
data/CHANGELOG.md
CHANGED
@@ -1,6 +1,13 @@
|
|
1
1
|
Rivet CHANGELOG
|
2
2
|
===
|
3
3
|
|
4
|
+
1.4.0 - Released 11/22/13
|
5
|
+
---
|
6
|
+
* Adds functionality to apply an elastic_ip durning bootstrap
|
7
|
+
* Adds functionality to apply knife commands for a specified chef_username durning bootstrap
|
8
|
+
* Tweaked some of the code styling to adhere to common Ruby styling conventions:
|
9
|
+
https://github.com/bbatsov/ruby-style-guide
|
10
|
+
|
4
11
|
1.3.0 - Released 11/20/13
|
5
12
|
---
|
6
13
|
* Adds functionality to allow chef_command to be specified in group configurations
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -4,7 +4,7 @@ Rivet
|
|
4
4
|
=======
|
5
5
|
Rivet enables you to describe autoscaling groups and their launch configurations as yaml. You can then sync those changes to Amazon Web Services (AWS.)
|
6
6
|
|
7
|
-
You provide a template and it's options to render as user-data for your launch configurations to build a bootstrap script for chef, installed via gems.
|
7
|
+
You provide a template and it's options to render as user-data for your launch configurations to build a bootstrap script for chef, installed via gems.
|
8
8
|
|
9
9
|
Rivet generates unique deterministic names for launch configurations and automatically assigns the proper launch configuration to your
|
10
10
|
autoscaling group based upon it's generated identity.
|
@@ -44,7 +44,7 @@ aws_secret_access_key=<YOUR SECRET_ACCESS KEY>
|
|
44
44
|
region=us-west-2
|
45
45
|
```
|
46
46
|
|
47
|
-
Alternatively you can specify your `AWS_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY` as environment variables.
|
47
|
+
Alternatively you can specify your `AWS_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY` as environment variables.
|
48
48
|
|
49
49
|
You will still need to specify the region to use in your `AWS_CONFIG_FILE`.
|
50
50
|
|
@@ -73,17 +73,27 @@ The yaml file format:
|
|
73
73
|
```yaml
|
74
74
|
min_size: SIZE <integer>
|
75
75
|
max_size: SIZE <integer>
|
76
|
-
region:
|
76
|
+
region: AWS_REGION <string>
|
77
77
|
availability_zones: [ZONE<string>,ZONE...]
|
78
78
|
iam_instance_profile: INSTANCE_PROFILE <string>
|
79
|
-
tags:
|
79
|
+
tags:
|
80
|
+
-
|
81
|
+
key: KEY_NAME<string>
|
82
|
+
value: KEY_VALUE<string>
|
83
|
+
-
|
84
|
+
key: KEY_NAME<string>
|
85
|
+
value: KEY_VALUE<string>
|
80
86
|
|
81
87
|
bootstrap:
|
82
88
|
chef_command: CHEF_COMMAND <string>
|
83
89
|
chef_organization: CHEF_ORGANIZATION <string>
|
90
|
+
chef_username: CHEF_USERNAME <string>
|
84
91
|
template: TEMPLATE <string>
|
85
92
|
config_dir: CONFIGURATION_FILES_DIR <string>
|
86
93
|
environment: CHEF_ENVIRONMENT <string>
|
94
|
+
region: AWS_REGION <string>
|
95
|
+
name: NAME <string>
|
96
|
+
elastic_ip: AWS_ELASTIC_IP <string>
|
87
97
|
gems:
|
88
98
|
- [GEM_NAME<string>,GEM_VERSION<string>]
|
89
99
|
- [GEM_NAME<string>]
|
data/lib/rivet/autoscale.rb
CHANGED
@@ -1,25 +1,25 @@
|
|
1
1
|
module Rivet
|
2
2
|
class Autoscale
|
3
3
|
|
4
|
-
REQUIRED_FIELDS = [:min_size
|
4
|
+
REQUIRED_FIELDS = [:min_size, :max_size, :launch_configuration, :availability_zones]
|
5
5
|
|
6
6
|
attr_reader :min_size, :max_size, :name, :launch_configuration
|
7
7
|
attr_reader :availability_zones, :tags
|
8
8
|
|
9
|
-
def initialize(name,definition)
|
10
|
-
@name
|
11
|
-
@min_size
|
12
|
-
@max_size
|
9
|
+
def initialize(name, definition)
|
10
|
+
@name = name
|
11
|
+
@min_size = definition['min_size']
|
12
|
+
@max_size = definition['max_size']
|
13
13
|
|
14
|
-
if definition.has_key?
|
14
|
+
if definition.has_key? 'tags'
|
15
15
|
definition['tags'].each do |t|
|
16
|
-
unless t.has_key?
|
16
|
+
unless t.has_key? 'propagate_at_launch'
|
17
17
|
t['propagate_at_launch'] = true
|
18
18
|
end
|
19
19
|
end
|
20
20
|
@tags = definition['tags']
|
21
21
|
else
|
22
|
-
@tags =
|
22
|
+
@tags = []
|
23
23
|
end
|
24
24
|
@launch_config = LaunchConfig.new(definition)
|
25
25
|
|
@@ -49,17 +49,17 @@ module Rivet
|
|
49
49
|
|
50
50
|
Rivet::Log.write(level, "Remote and local defintions match") unless differences?
|
51
51
|
|
52
|
-
differences.each_pair do |attr,values|
|
53
|
-
Rivet::Log.write(level,"#{attr}:")
|
54
|
-
Rivet::Log.write(level," remote: #{values['remote']}")
|
55
|
-
Rivet::Log.write(level," local: #{values['local']}")
|
52
|
+
differences.each_pair do |attr, values|
|
53
|
+
Rivet::Log.write(level, "#{attr}:")
|
54
|
+
Rivet::Log.write(level, " remote: #{values['remote']}")
|
55
|
+
Rivet::Log.write(level, " local: #{values['local']}")
|
56
56
|
end
|
57
57
|
end
|
58
58
|
|
59
59
|
def sync
|
60
60
|
if differences?
|
61
61
|
Rivet::Log.info("Syncing autoscale group changes to AWS for #{@name}")
|
62
|
-
autoscale = AWS::AutoScaling.new
|
62
|
+
autoscale = AWS::AutoScaling.new
|
63
63
|
group = autoscale.groups[@name]
|
64
64
|
|
65
65
|
@launch_config.save
|
@@ -77,13 +77,13 @@ module Rivet
|
|
77
77
|
protected
|
78
78
|
|
79
79
|
def get_update_options
|
80
|
-
options =
|
81
|
-
differences.each_pair do |attribute,values|
|
80
|
+
options = {}
|
81
|
+
differences.each_pair do |attribute, values|
|
82
82
|
options[attribute.to_sym] = values['local']
|
83
83
|
end
|
84
84
|
|
85
85
|
REQUIRED_FIELDS.each do |field|
|
86
|
-
unless options.has_key?
|
86
|
+
unless options.has_key? field
|
87
87
|
options[field] = self.send(field)
|
88
88
|
end
|
89
89
|
end
|
@@ -92,8 +92,8 @@ module Rivet
|
|
92
92
|
|
93
93
|
def get_differences
|
94
94
|
remote = get_remote
|
95
|
-
differences =
|
96
|
-
[:min_size
|
95
|
+
differences = {}
|
96
|
+
[:min_size, :max_size, :launch_configuration, :tags].each do |a|
|
97
97
|
if remote[a.to_s] != self.send(a)
|
98
98
|
differences[a.to_s] = { 'remote' => remote[a.to_s], 'local' => self.send(a) }
|
99
99
|
end
|
@@ -101,25 +101,23 @@ module Rivet
|
|
101
101
|
|
102
102
|
if remote['availability_zones'] != availability_zones
|
103
103
|
differences['availability_zones'] = { 'remote' => remote['availability_zones'], 'local' => availability_zones }
|
104
|
-
end if remote.has_key?
|
104
|
+
end if remote.has_key? 'availability_zones'
|
105
105
|
|
106
106
|
differences
|
107
107
|
end
|
108
108
|
|
109
|
-
protected
|
110
|
-
|
111
109
|
def get_remote
|
112
|
-
autoscale = AWS::AutoScaling.new
|
110
|
+
autoscale = AWS::AutoScaling.new
|
113
111
|
remote_group = autoscale.groups[@name]
|
114
112
|
if remote_group.exists?
|
115
113
|
|
116
|
-
remote_hash = [:min_size
|
117
|
-
accum[attr.to_s] = remote_group.send
|
114
|
+
remote_hash = [:min_size, :max_size].inject({}) do |accum, attr|
|
115
|
+
accum[attr.to_s] = remote_group.send attr
|
118
116
|
accum
|
119
117
|
end
|
120
118
|
|
121
119
|
# {:resource_id=>"venus", :propagate_at_launch=>true, :value=>"Venus", :key=>"Name", :resource_type=>"auto-scaling-group"}
|
122
|
-
remote_hash['tags'] = remote_group.tags.to_a.inject(
|
120
|
+
remote_hash['tags'] = remote_group.tags.to_a.inject([]) do |tags, current|
|
123
121
|
tags << normalize_tag(current)
|
124
122
|
end
|
125
123
|
|
@@ -130,22 +128,22 @@ module Rivet
|
|
130
128
|
|
131
129
|
remote_hash
|
132
130
|
else
|
133
|
-
{
|
131
|
+
{}
|
134
132
|
end
|
135
133
|
end
|
136
134
|
|
137
135
|
def create(options)
|
138
|
-
autoscale = AWS::AutoScaling.new
|
136
|
+
autoscale = AWS::AutoScaling.new
|
139
137
|
if autoscale.groups[@name].exists?
|
140
138
|
raise "Cannot create AutoScaling #{@name} group it already exists!"
|
141
139
|
else
|
142
|
-
autoscale.groups.create(@name,options)
|
140
|
+
autoscale.groups.create(@name, options)
|
143
141
|
end
|
144
142
|
end
|
145
143
|
|
146
144
|
def normalize_tag(tag)
|
147
|
-
normalized_tag =
|
148
|
-
tag.each_pair do |k,v|
|
145
|
+
normalized_tag = {}
|
146
|
+
tag.each_pair do |k, v|
|
149
147
|
unless (k == :resource_id || k == :resource_type)
|
150
148
|
normalized_tag[k.to_s] = v
|
151
149
|
end
|
data/lib/rivet/aws_utils.rb
CHANGED
@@ -5,8 +5,8 @@ module Rivet
|
|
5
5
|
return false if groups.nil?
|
6
6
|
Rivet::Log.info("Verifying security groups: #{groups.join(",")}")
|
7
7
|
|
8
|
-
security_groups_collection = AWS::EC2.new
|
9
|
-
filtered_groups =
|
8
|
+
security_groups_collection = AWS::EC2.new.security_groups
|
9
|
+
filtered_groups = []
|
10
10
|
security_groups_collection.filter('group-name', *groups).each do |g|
|
11
11
|
filtered_groups << g.name
|
12
12
|
end
|
@@ -25,13 +25,13 @@ module Rivet
|
|
25
25
|
current_profile = nil
|
26
26
|
profile_matcher = /^\[(profile+\s)?(\w+)\]/
|
27
27
|
option_matcher = /(\w.*)=(\S.*)\s*/
|
28
|
-
aws_config =
|
28
|
+
aws_config = {}
|
29
29
|
|
30
30
|
File.open(ENV['AWS_CONFIG_FILE'],"r").each_line do |line|
|
31
31
|
|
32
32
|
if line =~ profile_matcher
|
33
33
|
current_profile = line.match(profile_matcher)[2]
|
34
|
-
aws_config[current_profile] =
|
34
|
+
aws_config[current_profile] = {} unless aws_config.has_key?(current_profile)
|
35
35
|
end
|
36
36
|
|
37
37
|
if line =~ option_matcher && !current_profile.nil?
|
@@ -49,7 +49,7 @@ module Rivet
|
|
49
49
|
end
|
50
50
|
|
51
51
|
end
|
52
|
-
|
52
|
+
aws_config
|
53
53
|
end
|
54
54
|
end
|
55
55
|
|
data/lib/rivet/bootstrap.rb
CHANGED
@@ -2,22 +2,22 @@ module Rivet
|
|
2
2
|
class Bootstrap
|
3
3
|
TEMPLATE_SUB_DIR = "bootstrap"
|
4
4
|
|
5
|
-
attr_reader :gems, :run_list, :template, :environment
|
6
|
-
attr_reader :template_path, :chef_command, :chef_organization
|
5
|
+
attr_reader :gems, :run_list, :template, :environment, :region, :name, :elastic_ip
|
6
|
+
attr_reader :template_path, :chef_command, :chef_organization, :chef_username
|
7
7
|
|
8
|
-
def initialize(bootstrap_definition =
|
8
|
+
def initialize(bootstrap_definition = {})
|
9
9
|
ivars = [
|
10
|
-
'gems','run_list','template','environment',
|
11
|
-
'config_dir','chef_organization','
|
10
|
+
'gems', 'run_list', 'template', 'environment', 'region', 'name', 'elastic_ip',
|
11
|
+
'config_dir', 'chef_command', 'chef_organization', 'chef_username']
|
12
12
|
|
13
13
|
ivars.each do |i|
|
14
|
-
if bootstrap_definition.has_key?
|
15
|
-
instance_variable_set("@#{i}",bootstrap_definition[i])
|
14
|
+
if bootstrap_definition.has_key? i
|
15
|
+
instance_variable_set("@#{i}", bootstrap_definition[i])
|
16
16
|
end
|
17
17
|
end unless bootstrap_definition.nil?
|
18
18
|
|
19
|
-
@config_dir ||=
|
20
|
-
@template ||=
|
19
|
+
@config_dir ||= '.'
|
20
|
+
@template ||= 'default.erb'
|
21
21
|
|
22
22
|
set_calculated_attrs
|
23
23
|
end
|
@@ -29,31 +29,43 @@ module Rivet
|
|
29
29
|
protected
|
30
30
|
|
31
31
|
def set_calculated_attrs
|
32
|
-
@template_path = File.join(@config_dir,TEMPLATE_SUB_DIR)
|
33
|
-
@secret_file = File.join(@config_dir,"encrypted_data_bag_secret_#{@environment}")
|
34
|
-
@validation_key = File.new(File.join(@config_dir,"#{@chef_organization}-validator.pem")).read
|
32
|
+
@template_path = File.join(@config_dir, TEMPLATE_SUB_DIR)
|
33
|
+
@secret_file = File.join(@config_dir, "encrypted_data_bag_secret_#{@environment}")
|
34
|
+
@validation_key = File.new(File.join(@config_dir, "#{@chef_organization}-validator.pem")).read
|
35
35
|
end
|
36
36
|
|
37
37
|
def generate_user_data
|
38
|
-
config_content =
|
38
|
+
config_content = "log_level :info\n"
|
39
39
|
config_content << "log_location STDOUT\n"
|
40
|
-
config_content << "environment #{environment}\n"
|
41
|
-
config_content << "chef_server_url
|
40
|
+
config_content << "environment '#{environment}'\n"
|
41
|
+
config_content << "chef_server_url 'https://api.opscode.com/organizations/#{chef_organization}'\n"
|
42
42
|
config_content << "validation_client_name '#{chef_organization}-validator'\n"
|
43
43
|
|
44
|
-
|
44
|
+
knife_content = "chef_username = '#{chef_username}'\n"
|
45
|
+
knife_content << "chef_organization = '#{chef_organization}'\n"
|
46
|
+
knife_content << "\n"
|
47
|
+
knife_content << "environment '#{environment}'\n"
|
48
|
+
knife_content << "log_level :info\n"
|
49
|
+
knife_content << "log_location STDOUT\n"
|
50
|
+
knife_content << "node_name \"\#{chef_username}\"\n"
|
51
|
+
knife_content << "client_key \"~/.chef/\#{chef_username}.pem\"\n"
|
52
|
+
knife_content << "chef_server_url \"https://api.opscode.com/organizations/\#{chef_organization}\"\n"
|
53
|
+
knife_content << "cache_type 'BasicFile'\n"
|
54
|
+
knife_content << "puts \"Using \#{environment} environment...\"\n"
|
45
55
|
|
46
|
-
|
47
|
-
|
48
|
-
|
56
|
+
install_gems = ''
|
57
|
+
|
58
|
+
gems.each do |g|
|
59
|
+
if g.size > 1
|
60
|
+
install_gems << "gem install #{g[0]} -v #{g[1]} --no-rdoc --no-ri\n"
|
49
61
|
else
|
50
|
-
install_gems << "gem install #{
|
62
|
+
install_gems << "gem install #{g[0]} --no-rdoc --no-ri\n"
|
51
63
|
end
|
52
64
|
end unless gems.nil?
|
53
65
|
|
54
66
|
first_boot = { :run_list => @run_list.flatten }.to_json unless @run_list.nil?
|
55
67
|
|
56
|
-
template = ERB.new File.new(File.join(@template_path
|
68
|
+
template = ERB.new File.new(File.join(@template_path, @template)).read
|
57
69
|
template.result(binding)
|
58
70
|
end
|
59
71
|
|
data/lib/rivet/client.rb
CHANGED
@@ -20,7 +20,7 @@ module Rivet
|
|
20
20
|
end
|
21
21
|
|
22
22
|
Rivet::Log.info("Checking #{options[:group]} autoscaling definition")
|
23
|
-
autoscale_def = Rivet::Autoscale.new(options[:group],group_def)
|
23
|
+
autoscale_def = Rivet::Autoscale.new(options[:group], group_def)
|
24
24
|
autoscale_def.show_differences
|
25
25
|
|
26
26
|
if options[:sync]
|
@@ -33,4 +33,3 @@ module Rivet
|
|
33
33
|
|
34
34
|
end
|
35
35
|
end
|
36
|
-
|
data/lib/rivet/launch_config.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
module Rivet
|
2
2
|
class LaunchConfig
|
3
3
|
|
4
|
-
LC_ATTRIBUTES =
|
4
|
+
LC_ATTRIBUTES = %w(key_name image_id instance_type security_groups iam_instance_profile bootstrap)
|
5
5
|
|
6
6
|
LC_ATTRIBUTES.each do |a|
|
7
7
|
attr_reader a.to_sym
|
@@ -9,17 +9,17 @@ module Rivet
|
|
9
9
|
|
10
10
|
attr_reader :id_prefix
|
11
11
|
|
12
|
-
def initialize(spec,id_prefix=
|
12
|
+
def initialize(spec,id_prefix = 'rivet_')
|
13
13
|
@id_prefix = id_prefix
|
14
14
|
|
15
15
|
LC_ATTRIBUTES.each do |a|
|
16
16
|
|
17
17
|
if respond_to? "normalize_#{a}".to_sym
|
18
|
-
spec[a] = self.send("normalize_#{a.to_sym}",spec[a])
|
18
|
+
spec[a] = self.send("normalize_#{a.to_sym}", spec[a])
|
19
19
|
end
|
20
20
|
|
21
21
|
Rivet::Log.debug("Setting LaunchConfig @#{a} to #{spec[a]}")
|
22
|
-
instance_variable_set("@#{a}",spec[a])
|
22
|
+
instance_variable_set("@#{a}", spec[a])
|
23
23
|
end
|
24
24
|
end
|
25
25
|
|
@@ -34,30 +34,30 @@ module Rivet
|
|
34
34
|
def save
|
35
35
|
AwsUtils.verify_security_groups(security_groups)
|
36
36
|
|
37
|
-
lc_collection = AWS::AutoScaling.new
|
37
|
+
lc_collection = AWS::AutoScaling.new.launch_configurations
|
38
38
|
|
39
39
|
if lc_collection[identity].exists?
|
40
40
|
Rivet::Log.info("Launch configuration #{identity} already exists in AWS")
|
41
41
|
else
|
42
42
|
options = {}
|
43
|
-
options[:key_pair]
|
44
|
-
options[:security_groups]
|
45
|
-
options[:user_data]
|
46
|
-
options[:iam_instance_profile]
|
43
|
+
options[:key_pair] = key_name unless key_name.nil?
|
44
|
+
options[:security_groups] = security_groups unless security_groups.nil?
|
45
|
+
options[:user_data] = user_data unless user_data.nil?
|
46
|
+
options[:iam_instance_profile] = iam_instance_profile unless iam_instance_profile.nil?
|
47
47
|
|
48
48
|
Rivet::Log.info("Saving launch configuration #{identity} to AWS")
|
49
49
|
Rivet::Log.debug("Launch Config options:\n #{options.inspect}")
|
50
|
-
lc_collection.create(identity,image_id,instance_type, options)
|
50
|
+
lc_collection.create(identity, image_id, instance_type, options)
|
51
51
|
end
|
52
52
|
end
|
53
53
|
|
54
54
|
protected
|
55
55
|
|
56
56
|
def build_identity_string
|
57
|
-
identity = LC_ATTRIBUTES.inject(
|
57
|
+
identity = LC_ATTRIBUTES.inject('') do |accum, attribute|
|
58
58
|
if attribute != 'bootstrap'
|
59
59
|
attr_value = self.send(attribute.to_sym) ? self.send(attribute.to_sym) : "\0"
|
60
|
-
attr_value = attr_value.join("\t") if attr_value.respond_to?
|
60
|
+
attr_value = attr_value.join("\t") if attr_value.respond_to? :join
|
61
61
|
accum << attribute.to_s
|
62
62
|
accum << Base64.encode64(attr_value)
|
63
63
|
else
|
@@ -80,4 +80,3 @@ module Rivet
|
|
80
80
|
|
81
81
|
end
|
82
82
|
end
|
83
|
-
|
data/lib/rivet/logger.rb
CHANGED
@@ -2,25 +2,25 @@ module Rivet
|
|
2
2
|
|
3
3
|
module Log
|
4
4
|
|
5
|
-
def self.write(level,message)
|
5
|
+
def self.write(level, message)
|
6
6
|
@@log ||= SimpleLogger.instance
|
7
7
|
@@log.send(level.to_sym) { message }
|
8
8
|
end
|
9
9
|
|
10
10
|
def self.info(message)
|
11
|
-
write('info',message)
|
11
|
+
write('info', message)
|
12
12
|
end
|
13
13
|
|
14
14
|
def self.debug(message)
|
15
|
-
write('debug',message)
|
15
|
+
write('debug', message)
|
16
16
|
end
|
17
17
|
|
18
18
|
def self.fatal(message)
|
19
|
-
write('fatal',message)
|
19
|
+
write('fatal', message)
|
20
20
|
end
|
21
21
|
|
22
22
|
def self.warn(message)
|
23
|
-
write('warn',message)
|
23
|
+
write('warn', message)
|
24
24
|
end
|
25
25
|
|
26
26
|
def self.level(level)
|
@@ -28,14 +28,14 @@ module Rivet
|
|
28
28
|
@@log.level = level
|
29
29
|
end
|
30
30
|
|
31
|
-
class SimpleLogger< Logger
|
31
|
+
class SimpleLogger < Logger
|
32
32
|
include Singleton
|
33
33
|
|
34
34
|
def initialize
|
35
35
|
@dev = Logger::LogDevice.new(STDOUT)
|
36
36
|
super @dev
|
37
37
|
@progname = "Rivet"
|
38
|
-
@formatter = proc do |sev,datetime,name,msg|
|
38
|
+
@formatter = proc do |sev, datetime, name, msg|
|
39
39
|
"[#{name}] [#{datetime}] [#{sev}]: #{msg}\n"
|
40
40
|
end
|
41
41
|
@datetime_format
|
@@ -48,5 +48,3 @@ module Rivet
|
|
48
48
|
|
49
49
|
end
|
50
50
|
end
|
51
|
-
|
52
|
-
|
data/lib/rivet/utils.rb
CHANGED
@@ -1,16 +1,16 @@
|
|
1
1
|
module Rivet
|
2
2
|
module Utils
|
3
3
|
|
4
|
-
def self.die(level = 'fatal',message)
|
5
|
-
Rivet::Log.write(level,message)
|
4
|
+
def self.die(level = 'fatal', message)
|
5
|
+
Rivet::Log.write(level, message)
|
6
6
|
exit
|
7
7
|
end
|
8
8
|
|
9
9
|
# This returns the merged definition given a group
|
10
10
|
|
11
|
-
def self.get_definition(group,directory)
|
11
|
+
def self.get_definition(group, directory)
|
12
12
|
defaults = consume_defaults(directory)
|
13
|
-
group_def = load_definition(group,directory)
|
13
|
+
group_def = load_definition(group, directory)
|
14
14
|
|
15
15
|
if defaults && group_def
|
16
16
|
group_def = defaults.deep_merge(group_def)
|
@@ -21,8 +21,8 @@ module Rivet
|
|
21
21
|
# Gobbles up the defaults file from YML, returns the hash or false if empty
|
22
22
|
|
23
23
|
def self.consume_defaults(autoscale_dir)
|
24
|
-
defaults_file = File.join(autoscale_dir,
|
25
|
-
if File.exists?
|
24
|
+
defaults_file = File.join(autoscale_dir, 'defaults.yml')
|
25
|
+
if File.exists? defaults_file
|
26
26
|
parsed = begin
|
27
27
|
Rivet::Log.debug("Consuming defaults from #{defaults_file}")
|
28
28
|
YAML.load(File.open(defaults_file))
|
@@ -38,9 +38,9 @@ module Rivet
|
|
38
38
|
# This loads the given definition from it's YML file, returns the hash or
|
39
39
|
# false if empty
|
40
40
|
|
41
|
-
def self.load_definition(name,directory)
|
41
|
+
def self.load_definition(name, directory)
|
42
42
|
definition_dir = File.join(directory,name)
|
43
|
-
conf_file = File.join(definition_dir,
|
43
|
+
conf_file = File.join(definition_dir, 'conf.yml')
|
44
44
|
if Dir.exists?(definition_dir) && File.exists?(conf_file)
|
45
45
|
Rivet::Log.debug("Loading definition for #{name} from #{conf_file}")
|
46
46
|
parsed = begin
|
@@ -56,4 +56,3 @@ module Rivet
|
|
56
56
|
|
57
57
|
end
|
58
58
|
end
|
59
|
-
|
data/lib/rivet/version.rb
CHANGED
data/rivet.gemspec
CHANGED
@@ -24,8 +24,7 @@ Gem::Specification.new do |spec|
|
|
24
24
|
spec.require_paths = ["lib"]
|
25
25
|
|
26
26
|
spec.add_dependency "aws-sdk", ">= 1.11.1"
|
27
|
+
spec.add_development_dependency "pry", "~> 0.9.12"
|
27
28
|
spec.add_development_dependency "rake", ">= 10.1.0"
|
28
29
|
spec.add_development_dependency "rspec", "~> 2.14.1"
|
29
30
|
end
|
30
|
-
|
31
|
-
|
@@ -8,7 +8,7 @@ describe 'rivet bootstrap' do
|
|
8
8
|
|
9
9
|
tempdir_context 'with all necessary files in place' do
|
10
10
|
before do
|
11
|
-
FileUtils.mkdir_p
|
11
|
+
FileUtils.mkdir_p bootstrap_def['config_dir']
|
12
12
|
|
13
13
|
validator_file = File.join(
|
14
14
|
bootstrap_def['config_dir'],
|
@@ -20,21 +20,41 @@ describe 'rivet bootstrap' do
|
|
20
20
|
bootstrap_def['config_dir'],
|
21
21
|
Rivet::Bootstrap::TEMPLATE_SUB_DIR)
|
22
22
|
|
23
|
-
FileUtils.mkdir_p
|
23
|
+
FileUtils.mkdir_p template_dir
|
24
24
|
|
25
|
-
template_file = File.join(template_dir,bootstrap_def['template'])
|
26
|
-
File.open(template_file,'w') { |f| f.write(SpecHelpers::BOOTSTRAP_TEMPLATE) }
|
25
|
+
template_file = File.join(template_dir, bootstrap_def['template'])
|
26
|
+
File.open(template_file, 'w') { |f| f.write(SpecHelpers::BOOTSTRAP_TEMPLATE) }
|
27
27
|
end
|
28
28
|
|
29
29
|
describe "#user_data" do
|
30
30
|
it 'returns a string that contains the chef organization' do
|
31
|
-
org = bootstrap_def['
|
32
|
-
bootstrap.user_data.should =~ /
|
31
|
+
org = bootstrap_def['chef_organization']
|
32
|
+
bootstrap.user_data.should =~ /chef_organization\s+.*\'#{org}\'.*/
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'returns a string that contains the chef username' do
|
36
|
+
org = bootstrap_def['chef_username']
|
37
|
+
bootstrap.user_data.should =~ /chef_username\s+.*\'#{org}\'.*/
|
33
38
|
end
|
34
39
|
|
35
40
|
it 'returns a string that contains the environment' do
|
36
|
-
env = bootstrap_def['
|
37
|
-
bootstrap.user_data.should =~ /environment\s
|
41
|
+
env = bootstrap_def['environment']
|
42
|
+
bootstrap.user_data.should =~ /environment\s+.*\'#{env}\'.*/
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'returns a string that contains the region' do
|
46
|
+
region = bootstrap_def['region']
|
47
|
+
bootstrap.user_data.should =~ /#{region}/
|
48
|
+
end
|
49
|
+
|
50
|
+
it 'returns a string that contains the name' do
|
51
|
+
name = bootstrap_def['name']
|
52
|
+
bootstrap.user_data.should =~ /#{name}/
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'returns a string that contains the elastic_ip' do
|
56
|
+
elastic_ip = bootstrap_def['elastic_ip']
|
57
|
+
bootstrap.user_data.should =~ /#{elastic_ip}/
|
38
58
|
end
|
39
59
|
|
40
60
|
it 'returns a string that contains the run_list as json' do
|
@@ -58,4 +78,3 @@ describe 'rivet bootstrap' do
|
|
58
78
|
end
|
59
79
|
|
60
80
|
end
|
61
|
-
|
@@ -26,9 +26,9 @@ describe "rivet launch config" do
|
|
26
26
|
|
27
27
|
describe "#normalize_security_groups" do
|
28
28
|
it "returns a sorted array of groups" do
|
29
|
-
unsorted_groups =
|
29
|
+
unsorted_groups = %w(group3 group1 group2)
|
30
30
|
sorted_groups = unsorted_groups.sort
|
31
|
-
returned_groups = launch_config.send(:normalize_security_groups,unsorted_groups)
|
31
|
+
returned_groups = launch_config.send(:normalize_security_groups, unsorted_groups)
|
32
32
|
returned_groups.should == sorted_groups
|
33
33
|
end
|
34
34
|
end
|
data/spec/rivet_spec_setup.rb
CHANGED
@@ -7,33 +7,37 @@ require_relative '../lib/rivet'
|
|
7
7
|
|
8
8
|
Rivet::Log.level(Logger::FATAL)
|
9
9
|
|
10
|
-
|
11
10
|
module SpecHelpers
|
12
11
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
12
|
+
BOOTSTRAP_TEMPLATE = '<%= install_gems %>'\
|
13
|
+
'<%= region %>' + "\n"\
|
14
|
+
'<%= name %>' + "\n"\
|
15
|
+
'<%= elastic_ip %>' + "\n"\
|
16
|
+
'<%= knife_content %>'\
|
17
|
+
'<%= first_boot %>'\
|
18
|
+
"\n"\
|
19
|
+
'<%= chef_command %>'
|
20
20
|
|
21
21
|
AUTOSCALE_DEF = {
|
22
22
|
'min_size' => 1,
|
23
23
|
'max_size' => 3,
|
24
24
|
'region' => 'us-west-2',
|
25
|
-
'availability_zones' =>
|
25
|
+
'availability_zones' => %w(a b c),
|
26
26
|
'key_name' => 'UnitTests',
|
27
27
|
'instance_type' => 'm1.large',
|
28
|
-
'security_groups' =>
|
28
|
+
'security_groups' => %w(unit_tests1 unit_tests2),
|
29
29
|
'image_id' => 'ami-12345678',
|
30
30
|
'iam_instance_profile' => 'unit_test_profile',
|
31
31
|
'bootstrap' => {
|
32
32
|
'chef_organization' => 'unit_tests',
|
33
|
+
'chef_username' => 'unit_tests_user',
|
33
34
|
'template' => 'default.erb',
|
34
35
|
'config_dir' => 'unit_tests',
|
35
36
|
'environment' => 'unit_tests',
|
36
|
-
'
|
37
|
+
'region' => 'us-west-2',
|
38
|
+
'name' => 'unit_tests_name',
|
39
|
+
'elastic_ip' => '10.0.0.1',
|
40
|
+
'gems' => [ ['gem1', '0.0.1'], ['gem2', '0.0.2'] ],
|
37
41
|
'run_list' => ['unit_tests']
|
38
42
|
}
|
39
43
|
}
|
data/spec/rivet_util_spec.rb
CHANGED
@@ -2,19 +2,19 @@ require_relative './rivet_spec_setup'
|
|
2
2
|
|
3
3
|
include SpecHelpers
|
4
4
|
|
5
|
-
AUTOSCALE_DIR =
|
6
|
-
DEFINITION_NAME =
|
7
|
-
DEFINITION_DIR = File.join(AUTOSCALE_DIR,DEFINITION_NAME)
|
8
|
-
LAUNCH_CONFIG_PARAMS =
|
5
|
+
AUTOSCALE_DIR = '.'
|
6
|
+
DEFINITION_NAME = 'unit_test'
|
7
|
+
DEFINITION_DIR = File.join(AUTOSCALE_DIR, DEFINITION_NAME)
|
8
|
+
LAUNCH_CONFIG_PARAMS = %w(ssh_key instance_size security_groups ami bootstrap)
|
9
9
|
|
10
10
|
defaults_hash = {
|
11
11
|
'min_size' => 0,
|
12
12
|
'max_size' => 0,
|
13
13
|
'region' => 'us-west-2',
|
14
|
-
'zones' =>
|
14
|
+
'zones' => %w(a b c),
|
15
15
|
'key_name' => 'unit_tests',
|
16
16
|
'instance_type' => 'm1.large',
|
17
|
-
'security_groups' =>
|
17
|
+
'security_groups' => %w(unit_tests),
|
18
18
|
'image_id' => 'ami-unit_tests',
|
19
19
|
'bootstrap' => {
|
20
20
|
'run_list' => ['role[unit_tests]']
|
@@ -32,7 +32,7 @@ unit_test_definition_hash = {
|
|
32
32
|
describe "rivet utils" do
|
33
33
|
tempdir_context "with an autoscaling directory" do
|
34
34
|
before do
|
35
|
-
FileUtils.mkdir_p
|
35
|
+
FileUtils.mkdir_p AUTOSCALE_DIR
|
36
36
|
end
|
37
37
|
|
38
38
|
describe "consume_defaults" do
|
@@ -43,13 +43,13 @@ describe "rivet utils" do
|
|
43
43
|
|
44
44
|
describe "load_definition" do
|
45
45
|
it "should return false" do
|
46
|
-
Rivet::Utils.load_definition(
|
46
|
+
Rivet::Utils.load_definition('unit_test', AUTOSCALE_DIR).should be_false
|
47
47
|
end
|
48
48
|
end
|
49
49
|
|
50
50
|
describe "get_definition" do
|
51
51
|
it "should return false" do
|
52
|
-
Rivet::Utils.get_definition(
|
52
|
+
Rivet::Utils.get_definition('unit_test', AUTOSCALE_DIR)
|
53
53
|
end
|
54
54
|
end
|
55
55
|
|
@@ -60,26 +60,26 @@ describe "rivet utils" do
|
|
60
60
|
|
61
61
|
describe "load_definition" do
|
62
62
|
it "should return false" do
|
63
|
-
Rivet::Utils.load_definition(
|
63
|
+
Rivet::Utils.load_definition('unit_test', AUTOSCALE_DIR).should be_false
|
64
64
|
end
|
65
65
|
end
|
66
66
|
|
67
67
|
context "and with a conf.yml" do
|
68
68
|
before do
|
69
69
|
FileUtils.mkdir_p DEFINITION_DIR
|
70
|
-
File.open(File.join(DEFINITION_DIR,
|
70
|
+
File.open(File.join(DEFINITION_DIR, 'conf.yml'), 'w') do |f|
|
71
71
|
f.write(unit_test_definition_hash.to_yaml)
|
72
72
|
end
|
73
73
|
end
|
74
74
|
describe "load_definition" do
|
75
75
|
it "returns a hash" do
|
76
|
-
loaded_def = Rivet::Utils.load_definition(
|
76
|
+
loaded_def = Rivet::Utils.load_definition('unit_test', AUTOSCALE_DIR)
|
77
77
|
unit_test_definition_hash.each_pair { |k,v| loaded_def.should include(k => v) }
|
78
78
|
end
|
79
79
|
end
|
80
80
|
context "and with a defaults.yml" do
|
81
81
|
before do
|
82
|
-
File.open(File.join(AUTOSCALE_DIR,
|
82
|
+
File.open(File.join(AUTOSCALE_DIR, 'defaults.yml'), 'w') do |f|
|
83
83
|
f.write(defaults_hash.to_yaml)
|
84
84
|
end
|
85
85
|
end
|
@@ -93,7 +93,7 @@ describe "rivet utils" do
|
|
93
93
|
|
94
94
|
describe "get_definition" do
|
95
95
|
it "returns a merged hash" do
|
96
|
-
result = Rivet::Utils.get_definition(DEFINITION_NAME,AUTOSCALE_DIR)
|
96
|
+
result = Rivet::Utils.get_definition(DEFINITION_NAME, AUTOSCALE_DIR)
|
97
97
|
merged_hash = defaults_hash.merge(unit_test_definition_hash)
|
98
98
|
result.should == defaults_hash.merge(unit_test_definition_hash)
|
99
99
|
end
|
@@ -106,4 +106,3 @@ describe "rivet utils" do
|
|
106
106
|
end
|
107
107
|
end
|
108
108
|
end
|
109
|
-
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rivet
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.4.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-
|
12
|
+
date: 2013-12-10 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: aws-sdk
|
@@ -27,6 +27,22 @@ dependencies:
|
|
27
27
|
- - ! '>='
|
28
28
|
- !ruby/object:Gem::Version
|
29
29
|
version: 1.11.1
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: pry
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ~>
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: 0.9.12
|
38
|
+
type: :development
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ~>
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: 0.9.12
|
30
46
|
- !ruby/object:Gem::Dependency
|
31
47
|
name: rake
|
32
48
|
requirement: !ruby/object:Gem::Requirement
|