rouster 0.57 → 0.61
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +2 -0
- data/Gemfile +16 -0
- data/Gemfile.lock +67 -0
- data/README.md +179 -2
- data/Rakefile +8 -7
- data/Vagrantfile +24 -9
- data/examples/aws.rb +85 -0
- data/lib/rouster.rb +128 -61
- data/lib/rouster/deltas.rb +266 -130
- data/lib/rouster/puppet.rb +2 -2
- data/lib/rouster/testing.rb +28 -6
- data/lib/rouster/vagrant.rb +52 -16
- data/path_helper.rb +3 -4
- data/plugins/aws.rb +347 -0
- data/test/functional/deltas/test_get_packages.rb +50 -6
- data/test/functional/test_caching.rb +2 -2
- data/test/functional/test_new.rb +45 -4
- data/test/functional/test_passthroughs.rb +2 -2
- data/test/puppet/test_apply.rb +1 -1
- data/test/unit/test_new.rb +65 -0
- data/test/unit/testing/resources/osx-launchd +285 -0
- data/test/unit/testing/resources/rhel-systemv +40 -0
- data/test/unit/testing/resources/rhel-upstart +20 -0
- data/test/unit/testing/test_get_services.rb +151 -0
- data/test/unit/testing/test_validate_package.rb +36 -10
- metadata +11 -4
- data/test/puppet/test_roles.rb +0 -186
data/lib/rouster/puppet.rb
CHANGED
@@ -459,7 +459,7 @@ class Rouster
|
|
459
459
|
opts[:manifest_file].each do |file|
|
460
460
|
raise InternalError.new(sprintf('invalid manifest file specified[%s]', file)) unless self.is_file?(file)
|
461
461
|
|
462
|
-
cmd = 'puppet apply'
|
462
|
+
cmd = 'puppet apply --detailed-exitcodes'
|
463
463
|
cmd << sprintf(' --modulepath=%s', opts[:module_dir]) unless opts[:module_dir].nil?
|
464
464
|
cmd << sprintf(' --hiera_config=%s', opts[:hiera_config]) unless opts[:hiera_config].nil? or puppet_version < '3.0'
|
465
465
|
cmd << sprintf(' --environment %s', opts[:environment]) unless opts[:environment].nil?
|
@@ -481,7 +481,7 @@ class Rouster
|
|
481
481
|
|
482
482
|
manifests.each do |m|
|
483
483
|
|
484
|
-
cmd = 'puppet apply'
|
484
|
+
cmd = 'puppet apply --detailed-exitcodes'
|
485
485
|
cmd << sprintf(' --modulepath=%s', opts[:module_dir]) unless opts[:module_dir].nil?
|
486
486
|
cmd << sprintf(' --hiera_config=%s', opts[:hiera_config]) unless opts[:hiera_config].nil? or puppet_version < '3.0'
|
487
487
|
cmd << sprintf(' --environment %s', opts[:environment]) unless opts[:environment].nil?
|
data/lib/rouster/testing.rb
CHANGED
@@ -459,17 +459,39 @@ class Rouster
|
|
459
459
|
local = v.to_s.match(/absent|false/).nil? ? false : true
|
460
460
|
end
|
461
461
|
when :version
|
462
|
+
# TODO support determination based on multiple versions of the same package installed (?)
|
462
463
|
if packages.has_key?(name)
|
463
|
-
|
464
|
-
|
465
|
-
|
466
|
-
|
467
|
-
|
468
|
-
|
464
|
+
|
465
|
+
lps = packages[name].is_a?(Array) ? packages[name] : [ packages[name] ]
|
466
|
+
|
467
|
+
lps.each do |lp|
|
468
|
+
if v.split("\s").size > 1
|
469
|
+
## generic comparator functionality
|
470
|
+
comp, expectation = v.split("\s")
|
471
|
+
local = generic_comparator(lp[:version], comp, expectation)
|
472
|
+
break unless local.eql?(true)
|
473
|
+
else
|
474
|
+
local = ! v.to_s.match(/#{lp[:version]}/).nil?
|
475
|
+
break unless local.eql?(true)
|
476
|
+
end
|
469
477
|
end
|
470
478
|
else
|
471
479
|
local = false
|
472
480
|
end
|
481
|
+
when :arch, :architecture
|
482
|
+
if packages.has_key?(name)
|
483
|
+
archs = []
|
484
|
+
lps = packages[name].is_a?(Array) ? packages[name] : [ packages[name] ]
|
485
|
+
lps.each { |p| archs << p[:arch] }
|
486
|
+
if v.is_a?(Array)
|
487
|
+
v.each do |arch|
|
488
|
+
local = archs.member?(arch)
|
489
|
+
break unless local.eql?(true) # fail fast - if we are looking for an arch that DNE, bail out
|
490
|
+
end
|
491
|
+
else
|
492
|
+
local = archs.member?(v)
|
493
|
+
end
|
494
|
+
end
|
473
495
|
when :type
|
474
496
|
# noop allowing parse_catalog() output to be passed directly
|
475
497
|
else
|
data/lib/rouster/vagrant.rb
CHANGED
@@ -42,23 +42,52 @@ class Rouster
|
|
42
42
|
|
43
43
|
##
|
44
44
|
# up
|
45
|
-
# runs `vagrant up
|
45
|
+
# runs `vagrant up <name>` from the Vagrantfile path
|
46
46
|
# if :sshtunnel is passed to the object during instantiation, the tunnel is created here as well
|
47
47
|
def up
|
48
48
|
@logger.info('up()')
|
49
|
-
|
49
|
+
|
50
|
+
# don't like putting this here, may be refactored
|
51
|
+
if self.is_passthrough? and (self.passthrough[:type].equal?(:aws) or self.passthrough[:type].equal?(:raiden))
|
52
|
+
self.aws_up()
|
53
|
+
else
|
54
|
+
self.vagrant(sprintf('up %s', @name))
|
55
|
+
end
|
50
56
|
|
51
57
|
@ssh_info = nil # in case the ssh-info has changed, a la destroy/rebuild
|
52
58
|
self.connect_ssh_tunnel() if @sshtunnel
|
53
59
|
end
|
54
60
|
|
61
|
+
##
|
62
|
+
# halt
|
63
|
+
# runs `vagrant halt <name>` from the Vagrantfile path
|
64
|
+
def halt
|
65
|
+
@logger.info('halt()')
|
66
|
+
self.vagrant(sprintf('halt %s', @name))
|
67
|
+
end
|
68
|
+
|
69
|
+
##
|
70
|
+
# package -- though vagrant docs still refer to 'repackage'
|
71
|
+
# runs `vagrant package <name> <provider>`
|
72
|
+
def package(provider='virtualbox') # TODO get the provider as a first class citizen on the rouster object
|
73
|
+
@logger.info(sprintf('package(%s)', provider))
|
74
|
+
self.vagrant(sprintf('package %s %s', @name, provider))
|
75
|
+
end
|
76
|
+
|
55
77
|
##
|
56
78
|
# destroy
|
57
79
|
# runs `vagrant destroy <name>` from the Vagrantfile path
|
58
80
|
def destroy
|
59
81
|
@logger.info('destroy()')
|
82
|
+
|
83
|
+
# don't like putting this here, may be refactored
|
84
|
+
if self.is_passthrough? and (self.passthrough[:type].equal?(:aws) or self.passthrough[:type].equal?(:raiden))
|
85
|
+
self.aws_destroy()
|
86
|
+
else
|
87
|
+
self.vagrant(sprintf('destroy -f %s', @name))
|
88
|
+
end
|
89
|
+
|
60
90
|
disconnect_ssh_tunnel
|
61
|
-
self.vagrant(sprintf('destroy -f %s', @name))
|
62
91
|
end
|
63
92
|
|
64
93
|
##
|
@@ -78,21 +107,28 @@ class Rouster
|
|
78
107
|
end
|
79
108
|
end
|
80
109
|
|
110
|
+
# don't like putting this here, may be refactored
|
81
111
|
@logger.info('status()')
|
82
|
-
self.
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
112
|
+
if self.is_passthrough? and (self.passthrough[:type].equal?(:aws) or self.passthrough[:type].equal?(:raiden))
|
113
|
+
status = self.aws_status()
|
114
|
+
else
|
115
|
+
self.vagrant(sprintf('status %s', @name))
|
116
|
+
|
117
|
+
# else case here (both for nil/non-matching output) is handled by non-0 exit code
|
118
|
+
output = self.get_output()
|
119
|
+
if output.nil?
|
120
|
+
if self.is_passthrough?() and self.passthrough[:type].eql?(:local)
|
121
|
+
status = 'running'
|
122
|
+
else
|
123
|
+
status = 'not-created'
|
124
|
+
end
|
125
|
+
elsif output.match(/^#{@name}\s*(.*\s?\w+)\s\((.+)\)$/)
|
126
|
+
# vagrant 1.2+, $1 = status, $2 = provider
|
127
|
+
status = $1
|
128
|
+
elsif output.match(/^#{@name}\s+(.+)$/)
|
129
|
+
# vagrant 1.2-, $1 = status
|
130
|
+
status = $1
|
89
131
|
end
|
90
|
-
elsif output.match(/^#{@name}\s*(.*\s?\w+)\s\((.+)\)$/)
|
91
|
-
# vagrant 1.2+, $1 = status, $2 = provider
|
92
|
-
status = $1
|
93
|
-
elsif output.match(/^#{@name}\s+(.+)$/)
|
94
|
-
# vagrant 1.2-, $1 = status
|
95
|
-
status = $1
|
96
132
|
end
|
97
133
|
|
98
134
|
if @cache_timeout
|
data/path_helper.rb
CHANGED
@@ -2,14 +2,13 @@
|
|
2
2
|
|
3
3
|
# this gets us Rouster, still need to figure out how to find vagrant
|
4
4
|
$LOAD_PATH << File.join([File.dirname(__FILE__), 'lib'])
|
5
|
+
$LOAD_PATH << File.join([File.dirname(__FILE__), 'plugins'])
|
6
|
+
$LOAD_PATH << File.expand_path(sprintf('%s/..', File.dirname(__FILE__)))
|
7
|
+
$LOAD_PATH << File.dirname(__FILE__)
|
5
8
|
|
6
9
|
require 'rubygems'
|
7
10
|
|
8
11
|
# debugging help
|
9
|
-
begin
|
10
|
-
require 'debugger'
|
11
|
-
rescue LoadError
|
12
|
-
end
|
13
12
|
|
14
13
|
class Object
|
15
14
|
def my_methods
|
data/plugins/aws.rb
ADDED
@@ -0,0 +1,347 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
## plugins/aws.rb - provide helper functions for Rouster objects running on AWS/EC2
|
3
|
+
|
4
|
+
require sprintf('%s/../%s', File.dirname(File.expand_path(__FILE__)), 'path_helper')
|
5
|
+
|
6
|
+
require 'fog'
|
7
|
+
require 'uri'
|
8
|
+
|
9
|
+
class Rouster
|
10
|
+
|
11
|
+
attr_reader :ec2, :elb # expose AWS workers
|
12
|
+
attr_reader :instance_data # the result of the runInstances request
|
13
|
+
|
14
|
+
def aws_get_url(url)
|
15
|
+
# convenience method to run curls from inside the VM
|
16
|
+
self.run(sprintf('curl -s %s', url))
|
17
|
+
end
|
18
|
+
|
19
|
+
# TODO should this be 'aws_ip'?
|
20
|
+
def aws_get_ip (method = :internal, type = :public)
|
21
|
+
# allowed methods: :internal (check meta-data inside VM), :aws (ask API)
|
22
|
+
# allowed types: :public, :private
|
23
|
+
self.aws_describe_instance
|
24
|
+
|
25
|
+
if method.equal?(:internal)
|
26
|
+
key = type.equal?(:public) ? 'public-ipv4' : 'local-ipv4'
|
27
|
+
murl = sprintf('http://169.254.169.254/latest/meta-data/%s', key)
|
28
|
+
result = self.aws_get_url(murl)
|
29
|
+
else
|
30
|
+
key = type.equal?(:public) ? 'ipAddress' : 'privateIpAddress'
|
31
|
+
result = @instance_data[key]
|
32
|
+
end
|
33
|
+
|
34
|
+
result
|
35
|
+
end
|
36
|
+
|
37
|
+
def aws_get_userdata
|
38
|
+
murl = 'http://169.254.169.254/latest/user-data/'
|
39
|
+
result = self.aws_get_url(murl)
|
40
|
+
|
41
|
+
if result.match(/\S=\S/)
|
42
|
+
# TODO should we really be doing this?
|
43
|
+
userdata = Hash.new()
|
44
|
+
result.split("\n").each do |line|
|
45
|
+
if line.match(/^(.*?)=(.*)/)
|
46
|
+
userdata[$1] = $2
|
47
|
+
end
|
48
|
+
end
|
49
|
+
else
|
50
|
+
userdata = result
|
51
|
+
end
|
52
|
+
|
53
|
+
userdata
|
54
|
+
end
|
55
|
+
|
56
|
+
# return a hash containing meta-data items
|
57
|
+
def aws_get_metadata
|
58
|
+
murl = 'http://169.254.169.254/latest/meta-data/'
|
59
|
+
result = self.aws_get_url(murl)
|
60
|
+
metadata = Hash.new()
|
61
|
+
|
62
|
+
# TODO this isn't entirely right.. if the element ends in '/', it's actually another level of hash..
|
63
|
+
result.split("\n").each do |element|
|
64
|
+
metadata[element] = self.aws_get_url(sprintf('%s%s', murl, element))
|
65
|
+
end
|
66
|
+
|
67
|
+
metadata
|
68
|
+
end
|
69
|
+
|
70
|
+
def aws_get_hostname (method = :internal, type = :public)
|
71
|
+
# allowed methods: :internal (check meta-data inside VM), :aws (ask API)
|
72
|
+
# allowed types: :public, :private
|
73
|
+
self.aws_describe_instance
|
74
|
+
|
75
|
+
result = nil
|
76
|
+
|
77
|
+
if method.equal?(:internal)
|
78
|
+
key = type.equal?(:public) ? 'public-hostname' : 'local-hostname'
|
79
|
+
murl = sprintf('http://169.254.169.254/latest/meta-data/%s', key)
|
80
|
+
result = self.aws_get_url(murl)
|
81
|
+
else
|
82
|
+
key = type.equal?(:public) ? 'dnsName' : 'privateDnsName'
|
83
|
+
result = @instance_data[key]
|
84
|
+
end
|
85
|
+
|
86
|
+
result
|
87
|
+
end
|
88
|
+
|
89
|
+
def aws_get_instance ()
|
90
|
+
if ! @instance_data.nil? and @instance_data.has_key?('instanceId')
|
91
|
+
return @instance_data['instanceId'] # we already know the id
|
92
|
+
elsif @passthrough.has_key?(:instance)
|
93
|
+
return @passthrough[:instance] # we know the id we want
|
94
|
+
else
|
95
|
+
@logger.debug(sprintf('unable to determine ami-id from instance_data[%s] or passthrough specification[%s]', @instance_data, @passthrough))
|
96
|
+
return nil # we don't have an id yet, likely a up() call
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
def aws_get_ami ()
|
101
|
+
if ! @instance_data.nil? and @instance_data.has_key?('ami')
|
102
|
+
return @instance_data['ami']
|
103
|
+
else
|
104
|
+
return @passthrough[:ami]
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
def aws_up
|
109
|
+
# wait for machine to transition to running state and become sshable (TODO maybe make the second half optional)
|
110
|
+
self.aws_connect
|
111
|
+
|
112
|
+
status = self.status()
|
113
|
+
|
114
|
+
if status.eql?('running')
|
115
|
+
self.connect_ssh_tunnel
|
116
|
+
self.passthrough[:instance] = self.aws_get_instance
|
117
|
+
return self.aws_get_instance
|
118
|
+
end
|
119
|
+
|
120
|
+
# TODO provide more context
|
121
|
+
@logger.info(sprintf('calling RunInstances ami[%s], size[%s], keypair[%s]',
|
122
|
+
self.passthrough[:ami],
|
123
|
+
self.passthrough[:size],
|
124
|
+
self.passthrough[:keypair]
|
125
|
+
))
|
126
|
+
|
127
|
+
server = @ec2.run_instances(
|
128
|
+
self.passthrough[:ami],
|
129
|
+
self.passthrough[:min_count],
|
130
|
+
self.passthrough[:max_count],
|
131
|
+
{
|
132
|
+
'InstanceType' => self.passthrough[:size],
|
133
|
+
'KeyName' => self.passthrough[:keypair],
|
134
|
+
'SecurityGroup' => self.passthrough[:security_groups],
|
135
|
+
'UserData' => self.passthrough[:userdata],
|
136
|
+
},
|
137
|
+
)
|
138
|
+
|
139
|
+
@instance_data = server.data[:body]['instancesSet'][0]
|
140
|
+
|
141
|
+
# wait until the machine starts
|
142
|
+
ceiling = 9
|
143
|
+
sleep_time = 20
|
144
|
+
status = nil
|
145
|
+
0.upto(ceiling) do |try|
|
146
|
+
status = self.aws_status
|
147
|
+
|
148
|
+
@logger.debug(sprintf('describeInstances[%s]: [%s] [#%s]', self.aws_get_instance, status, try))
|
149
|
+
|
150
|
+
if status.eql?('running') or status.eql?('16')
|
151
|
+
@logger.info(sprintf('[%s] transitioned to state[%s]', self.aws_get_instance, self.aws_status))
|
152
|
+
break
|
153
|
+
end
|
154
|
+
|
155
|
+
sleep sleep_time
|
156
|
+
end
|
157
|
+
|
158
|
+
raise sprintf('instance[%s] did not transition to running state, stopped trying at[%s]', self.aws_get_instance, status) unless status.eql?('running') or status.eql?('16')
|
159
|
+
|
160
|
+
# TODO don't be this hacky
|
161
|
+
self.aws_describe_instance # the server.data response doesn't include public hostname/ip
|
162
|
+
if @passthrough[:type].eql?(:aws)
|
163
|
+
@passthrough[:host] = @instance_data['dnsName']
|
164
|
+
else
|
165
|
+
@passthrough[:host] = self.find_ssh_elb(true)
|
166
|
+
end
|
167
|
+
|
168
|
+
self.connect_ssh_tunnel
|
169
|
+
|
170
|
+
self.passthrough[:instance] = self.aws_get_instance
|
171
|
+
self.passthrough[:instance]
|
172
|
+
end
|
173
|
+
|
174
|
+
def aws_destroy
|
175
|
+
self.aws_connect
|
176
|
+
|
177
|
+
server = @ec2.terminate_instances(self.aws_get_instance)
|
178
|
+
|
179
|
+
if @passthrough.has_key?(:created_elb)
|
180
|
+
elb = @passthrough[:created_elb]
|
181
|
+
|
182
|
+
@logger.info(sprintf('deleting ELB[%s]', elb))
|
183
|
+
@elb.delete_load_balancer(elb)
|
184
|
+
end
|
185
|
+
|
186
|
+
self.aws_status
|
187
|
+
end
|
188
|
+
|
189
|
+
def aws_describe_instance(instance = aws_get_instance)
|
190
|
+
|
191
|
+
if @cache_timeout
|
192
|
+
if @cache.has_key?(:aws_describe_instance)
|
193
|
+
if (Time.now.to_i - @cache[:aws_describe_instance][:time]) < @cache_timeout
|
194
|
+
@logger.debug(sprintf('using cached aws_describe_instance?[%s] from [%s]', @cache[:aws_describe_instance][:instance], @cache[:aws_describe_instance][:time]))
|
195
|
+
return @cache[:aws_describe_instance][:instance]
|
196
|
+
end
|
197
|
+
end
|
198
|
+
end
|
199
|
+
|
200
|
+
return nil if instance.nil?
|
201
|
+
|
202
|
+
self.aws_connect
|
203
|
+
server = @ec2.describe_instances('instance-id' => [ instance ])
|
204
|
+
response = server.data[:body]['reservationSet'][0]['instancesSet'][0]
|
205
|
+
|
206
|
+
if instance.eql?(self.aws_get_instance)
|
207
|
+
@instance_data = response
|
208
|
+
end
|
209
|
+
|
210
|
+
if @cache_timeout
|
211
|
+
@cache[:aws_describe_instance] = Hash.new unless @cache[:aws_describe_instance].class.eql?(Hash)
|
212
|
+
@cache[:aws_describe_instance][:time] = Time.now.to_i
|
213
|
+
@cache[:aws_describe_instance][:instance] = response
|
214
|
+
@logger.debug(sprintf('caching is_available_via_ssh?[%s] at [%s]', @cache[:aws_describe_instance][:instance], @cache[:aws_decribe_instance][:time]))
|
215
|
+
end
|
216
|
+
|
217
|
+
response
|
218
|
+
end
|
219
|
+
|
220
|
+
def aws_status
|
221
|
+
self.aws_describe_instance
|
222
|
+
return 'not-created' if @instance_data.nil?
|
223
|
+
@instance_data['instanceState']['name'].nil? ? @instance_data['instanceState']['code'] : @instance_data['instanceState']['name']
|
224
|
+
end
|
225
|
+
|
226
|
+
def aws_connect_to_elb (id, elbname, listeners = [{ 'InstancePort' => 22, 'LoadBalancerPort' => 22, 'Protocol' => 'TCP' }])
|
227
|
+
self.elb_connect
|
228
|
+
|
229
|
+
# allow either hash or array of hash specification for listeners
|
230
|
+
listeners = [ listeners ] unless listeners.is_a?(Array)
|
231
|
+
required_params = [ 'InstancePort', 'LoadBalancerPort', 'Protocol' ] # figure out plan re: InstanceProtocol/LoadbalancerProtocol vs. Protocol
|
232
|
+
|
233
|
+
listeners.each do |l|
|
234
|
+
required_params.each do |r|
|
235
|
+
raise sprintf('listener[%s] does not include required parameter[%s]', l, r) unless l[r]
|
236
|
+
end
|
237
|
+
|
238
|
+
end
|
239
|
+
|
240
|
+
@logger.debug(sprintf('confirming ELB name uniqueness[%s]', elbname))
|
241
|
+
response = @elb.describe_load_balancers()
|
242
|
+
response.body['DescribeLoadBalancersResult']['LoadBalancerDescriptions'].each do |elb|
|
243
|
+
if elb['LoadBalancerName'].eql?(elbname)
|
244
|
+
# terminate
|
245
|
+
@logger.debug(sprintf('terminating ELB[%s]', elbname))
|
246
|
+
@elb.delete_load_balancer(elbname)
|
247
|
+
end
|
248
|
+
end
|
249
|
+
|
250
|
+
# create the ELB/VIP
|
251
|
+
@logger.debug(sprintf('creating a load balancer[%s] with listeners[%s]', elbname, listeners))
|
252
|
+
response = @elb.create_load_balancer(
|
253
|
+
[], # availability zones not needed on raiden
|
254
|
+
elbname,
|
255
|
+
listeners
|
256
|
+
)
|
257
|
+
|
258
|
+
dnsname = response.body['CreateLoadBalancerResult']['DNSName']
|
259
|
+
|
260
|
+
# string it up to the id passed
|
261
|
+
response = @elb.register_instances_with_load_balancer(id, elbname)
|
262
|
+
|
263
|
+
# i hate this so much.
|
264
|
+
@logger.debug(sprintf('sleeping[%s] to allow DNS propagation', self.passthrough[:dns_propagation_sleep]))
|
265
|
+
sleep self.passthrough[:dns_propagation_sleep]
|
266
|
+
|
267
|
+
return dnsname
|
268
|
+
end
|
269
|
+
|
270
|
+
# TODO this will throw at the first error - should we catch?
|
271
|
+
# run some commands, return an array of the output
|
272
|
+
def aws_bootstrap (commands)
|
273
|
+
self.aws_connect
|
274
|
+
commands = (commands.is_a?(Array)) ? commands : [ commands ]
|
275
|
+
output = Array.new
|
276
|
+
|
277
|
+
commands.each do |command|
|
278
|
+
output << self.run(command)
|
279
|
+
end
|
280
|
+
|
281
|
+
return output
|
282
|
+
end
|
283
|
+
|
284
|
+
def aws_connect
|
285
|
+
return @ec2 unless @ec2.nil?
|
286
|
+
|
287
|
+
config = {
|
288
|
+
:provider => 'AWS',
|
289
|
+
:region => self.passthrough[:region],
|
290
|
+
:aws_access_key_id => self.passthrough[:key_id],
|
291
|
+
:aws_secret_access_key => self.passthrough[:secret_key],
|
292
|
+
}
|
293
|
+
|
294
|
+
config[:endpoint] = self.passthrough[:ec2_endpoint] unless self.passthrough[:ec2_endpoint].nil?
|
295
|
+
@ec2 = Fog::Compute.new(config)
|
296
|
+
end
|
297
|
+
|
298
|
+
def elb_connect
|
299
|
+
return @elb unless @elb.nil?
|
300
|
+
|
301
|
+
if self.passthrough[:elb_endpoint]
|
302
|
+
endpoint = URI.parse(self.passthrough[:elb_endpoint])
|
303
|
+
elsif self.passthrough[:ec2_endpoint]
|
304
|
+
endpoint = URI.parse(self.passthrough[:ec2_endpoint])
|
305
|
+
end
|
306
|
+
|
307
|
+
config = {
|
308
|
+
:region => self.passthrough[:region],
|
309
|
+
:aws_access_key_id => self.passthrough[:key_id],
|
310
|
+
:aws_secret_access_key => self.passthrough[:secret_key],
|
311
|
+
}
|
312
|
+
|
313
|
+
unless endpoint.nil?
|
314
|
+
# if not specifying an endpoint, don't add to the config
|
315
|
+
config[:host] = endpoint.host
|
316
|
+
config[:path] = endpoint.path
|
317
|
+
config[:port] = endpoint.port
|
318
|
+
config[:scheme] = endpoint.scheme
|
319
|
+
end
|
320
|
+
|
321
|
+
@elb = Fog::AWS::ELB.new(config)
|
322
|
+
end
|
323
|
+
|
324
|
+
def find_ssh_elb (create_if_not_found = false, instance = aws_get_instance)
|
325
|
+
# given an instance, see if there is already an ELB that it is connected to - and potentially create one
|
326
|
+
self.elb_connect
|
327
|
+
result = nil
|
328
|
+
|
329
|
+
response = @elb.describe_load_balancers
|
330
|
+
elbs = response.body['DescribeLoadBalancersResult']['LoadBalancerDescriptions']
|
331
|
+
|
332
|
+
elbs.each do |elb|
|
333
|
+
if elb['Instances'].member?(instance)
|
334
|
+
result = elb['DNSName']
|
335
|
+
break
|
336
|
+
end
|
337
|
+
end
|
338
|
+
|
339
|
+
if create_if_not_found and result.nil?
|
340
|
+
result = self.aws_connect_to_elb(instance, sprintf('%s-ssh', self.name))
|
341
|
+
end
|
342
|
+
|
343
|
+
result
|
344
|
+
|
345
|
+
end
|
346
|
+
|
347
|
+
end
|