rivet 1.3.0 → 1.4.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/.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
|