tools-cf-plugin 2.0.0 → 2.1.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/lib/tools-cf-plugin/dea-ads.rb +1 -1
- data/lib/tools-cf-plugin/tunnel/multi_line_stream.rb +10 -1
- data/lib/tools-cf-plugin/tunnel/tunnel-nats.rb +4 -0
- data/lib/tools-cf-plugin/tunnel/watch-logs.rb +10 -6
- data/lib/tools-cf-plugin/version.rb +1 -1
- data/lib/tools-cf-plugin/watch.rb +93 -28
- data/spec/dea-ads_spec.rb +29 -13
- data/spec/shell_spec.rb +3 -3
- data/spec/spec_helper.rb +0 -1
- data/spec/tunnel/base_spec.rb +39 -43
- data/spec/tunnel/multi_line_stream_spec.rb +31 -15
- data/spec/tunnel/stream_location_spec.rb +4 -7
- data/spec/tunnel/tunnel-nats_spec.rb +28 -31
- data/spec/tunnel/watch-logs_spec.rb +26 -24
- data/spec/watch_spec.rb +176 -235
- metadata +45 -39
@@ -48,7 +48,7 @@ module CFTools
|
|
48
48
|
|
49
49
|
[ c(idx, :name),
|
50
50
|
list(attrs["stacks"]),
|
51
|
-
diff(attrs, prev) { |x| x["app_id_to_count"].values.inject(&:+) },
|
51
|
+
diff(attrs, prev) { |x| x["app_id_to_count"].values.inject(0, &:+) },
|
52
52
|
diff(attrs, prev, :pretty_memory, :pretty_memory_diff) do |x|
|
53
53
|
x["available_memory"]
|
54
54
|
end
|
@@ -20,7 +20,16 @@ module CFTools
|
|
20
20
|
|
21
21
|
locations.each do |(name, index), locs|
|
22
22
|
Thread.new do
|
23
|
-
|
23
|
+
begin
|
24
|
+
stream_location(name, index, locs, entries)
|
25
|
+
rescue => e
|
26
|
+
entries << LogEntry.new(
|
27
|
+
"#{name}/#{index}",
|
28
|
+
c("failed: #{e.class}: #{e}", :error),
|
29
|
+
:stdout)
|
30
|
+
|
31
|
+
retry
|
32
|
+
end
|
24
33
|
end
|
25
34
|
end
|
26
35
|
|
@@ -30,6 +30,8 @@ module CFTools::Tunnel
|
|
30
30
|
|
31
31
|
director = connected_director(director_host, gateway)
|
32
32
|
|
33
|
+
line "Director: #{director.director_uri}"
|
34
|
+
|
33
35
|
manifest =
|
34
36
|
with_progress("Downloading deployment manifest") do
|
35
37
|
current_deployment_manifest(director)
|
@@ -46,6 +48,8 @@ module CFTools::Tunnel
|
|
46
48
|
login_as_admin(manifest)
|
47
49
|
end
|
48
50
|
|
51
|
+
line "NATS connection: nats://#{nats["user"]}:#{nats["password"]}@127.0.0.1:#{nport}"
|
52
|
+
|
49
53
|
execute(
|
50
54
|
command,
|
51
55
|
args + %W[
|
@@ -16,11 +16,12 @@ module CFTools::Tunnel
|
|
16
16
|
|
17
17
|
desc "Stream logs from the jobs of a deployment"
|
18
18
|
input :director, :argument => :required, :desc => "BOSH director address"
|
19
|
-
input :
|
20
|
-
|
19
|
+
input :components, :argument => :splat, :desc => "Which components to log"
|
20
|
+
input :gateway, :default => proc { "vcap@#{input[:director]}" },
|
21
21
|
:desc => "SSH connection string (default: vcap@director)"
|
22
22
|
def watch_logs
|
23
23
|
director_host = input[:director]
|
24
|
+
components = input[:components]
|
24
25
|
gateway = input[:gateway]
|
25
26
|
|
26
27
|
director = connected_director(director_host, gateway)
|
@@ -32,7 +33,7 @@ module CFTools::Tunnel
|
|
32
33
|
|
33
34
|
locations =
|
34
35
|
with_progress("Finding logs for #{c(deployment["name"], :name)}") do
|
35
|
-
locs = stream_locations(director, deployment["name"])
|
36
|
+
locs = stream_locations(director, deployment["name"], components)
|
36
37
|
|
37
38
|
if locs.empty?
|
38
39
|
fail "No locations found."
|
@@ -69,16 +70,19 @@ module CFTools::Tunnel
|
|
69
70
|
].join(" ")
|
70
71
|
end
|
71
72
|
|
72
|
-
def stream_locations(director, deployment)
|
73
|
+
def stream_locations(director, deployment, components)
|
73
74
|
locations = Hash.new { |h, k| h[k] = [] }
|
74
75
|
|
76
|
+
logs = LOGS.dup
|
77
|
+
logs.select! { |l, _| components.include?(l) } unless components.empty?
|
78
|
+
|
75
79
|
director.fetch_vm_state(deployment, :use_cache => false).each do |vm|
|
76
80
|
name = vm["job_name"]
|
77
81
|
index = vm["index"]
|
78
|
-
next unless
|
82
|
+
next unless logs.key?(name)
|
79
83
|
|
80
84
|
vm["ips"].each do |ip|
|
81
|
-
|
85
|
+
logs[name].each do |file|
|
82
86
|
locations[[name, index]] << StreamLocation.new(file, "#{name}/#{index}")
|
83
87
|
end
|
84
88
|
end
|
@@ -138,7 +138,11 @@ module CFTools
|
|
138
138
|
payload = JSON.parse(msg)
|
139
139
|
dea, _ = payload["id"].split("-", 2)
|
140
140
|
[ d(sub),
|
141
|
-
"dea: #{dea}
|
141
|
+
[ "dea: #{dea}",
|
142
|
+
"stacks: #{list(payload["stacks"])}",
|
143
|
+
"available mem: #{human_mb(payload["available_memory"])}",
|
144
|
+
"apps: #{pretty_app_count(payload["app_id_to_count"] || [])}"
|
145
|
+
].join(", ")
|
142
146
|
]
|
143
147
|
end
|
144
148
|
|
@@ -146,7 +150,10 @@ module CFTools
|
|
146
150
|
payload = JSON.parse(msg)
|
147
151
|
dea, _ = payload["id"].split("-", 2)
|
148
152
|
[ d(sub),
|
149
|
-
"dea: #{dea}
|
153
|
+
[ "dea: #{dea}",
|
154
|
+
"stacks: #{list(payload["stacks"])}",
|
155
|
+
"available mem: #{human_mb(payload["available_memory"])}"
|
156
|
+
].join(", ")
|
150
157
|
]
|
151
158
|
end
|
152
159
|
|
@@ -157,7 +164,10 @@ module CFTools
|
|
157
164
|
def pretty_exited(sub, msg)
|
158
165
|
payload = JSON.parse(msg)
|
159
166
|
[ c(sub, :bad),
|
160
|
-
"app: #{pretty_app(payload["droplet"])}
|
167
|
+
[ "app: #{pretty_app(payload["droplet"])}",
|
168
|
+
"reason: #{payload["reason"]}",
|
169
|
+
"index: #{payload["index"]}"
|
170
|
+
].join(", ")
|
161
171
|
]
|
162
172
|
end
|
163
173
|
|
@@ -187,44 +197,57 @@ module CFTools
|
|
187
197
|
def pretty_register(sub, msg)
|
188
198
|
payload = JSON.parse(msg)
|
189
199
|
|
200
|
+
message = []
|
201
|
+
|
190
202
|
if (dea_id = payload["dea"])
|
191
203
|
dea, _ = dea_id.split("-", 2)
|
192
|
-
message
|
193
|
-
else
|
194
|
-
message = ""
|
204
|
+
message += ["app: #{pretty_app(payload["app"])}", "dea: #{dea}"]
|
195
205
|
end
|
196
206
|
|
197
|
-
message
|
207
|
+
message += [
|
208
|
+
"uris: #{list(payload["uris"])}",
|
209
|
+
"host: #{payload["host"]}",
|
210
|
+
"port: #{payload["port"]}"
|
211
|
+
]
|
198
212
|
|
199
|
-
[c(sub, :neutral), message]
|
213
|
+
[c(sub, :neutral), message.join(", ")]
|
200
214
|
end
|
201
215
|
|
202
216
|
def pretty_unregister(sub, msg)
|
203
217
|
payload = JSON.parse(msg)
|
204
218
|
|
219
|
+
message = []
|
220
|
+
|
205
221
|
if (dea_id = payload["dea"])
|
206
222
|
dea, _ = dea_id.split("-", 2)
|
207
|
-
message
|
208
|
-
else
|
209
|
-
message = ""
|
223
|
+
message += ["app: #{pretty_app(payload["app"])}", "dea: #{dea}"]
|
210
224
|
end
|
211
225
|
|
212
|
-
message
|
226
|
+
message += [
|
227
|
+
"uris: #{list(payload["uris"])}",
|
228
|
+
"host: #{payload["host"]}",
|
229
|
+
"port: #{payload["port"]}"
|
230
|
+
]
|
213
231
|
|
214
|
-
[c(sub, :warning), message]
|
232
|
+
[c(sub, :warning), message.join(", ")]
|
215
233
|
end
|
216
234
|
|
217
235
|
def pretty_start(sub, msg, dea)
|
218
236
|
payload = JSON.parse(msg)
|
219
237
|
[ c("dea.#{dea}.start", :good),
|
220
|
-
"app: #{pretty_app(payload["droplet"])}
|
238
|
+
[ "app: #{pretty_app(payload["droplet"])}",
|
239
|
+
"dea: #{dea}",
|
240
|
+
"index: #{payload["index"]}",
|
241
|
+
"uris: #{list(payload["uris"])}"
|
242
|
+
].join(", ")
|
221
243
|
]
|
222
244
|
end
|
223
245
|
|
224
246
|
def pretty_stop(sub, msg)
|
225
247
|
payload = JSON.parse(msg)
|
226
248
|
|
227
|
-
message = "app: #{pretty_app(payload["droplet"])}
|
249
|
+
message = ["app: #{pretty_app(payload["droplet"])}"]
|
250
|
+
|
228
251
|
if (indices = payload["indices"])
|
229
252
|
message << "scaling down indices: #{indices.join(", ")}"
|
230
253
|
elsif (instances = payload["instances"])
|
@@ -233,18 +256,26 @@ module CFTools
|
|
233
256
|
message << "stopping application"
|
234
257
|
end
|
235
258
|
|
236
|
-
[c(sub, :warning), message]
|
259
|
+
[c(sub, :warning), message.join(", ")]
|
237
260
|
end
|
238
261
|
|
239
262
|
def pretty_dea_update(sub, msg)
|
240
263
|
payload = JSON.parse(msg)
|
241
|
-
[d(sub),
|
264
|
+
[ d(sub),
|
265
|
+
[ "app: #{pretty_app(payload["droplet"])}",
|
266
|
+
"uris: #{list(payload["uris"])}"
|
267
|
+
].join(", ")
|
268
|
+
]
|
242
269
|
end
|
243
270
|
|
244
271
|
def pretty_find_droplet(sub, msg)
|
245
272
|
payload = JSON.parse(msg)
|
246
273
|
states = payload["states"].collect { |s| c(s.downcase, state_color(s))}
|
247
|
-
[d(sub),
|
274
|
+
[ d(sub),
|
275
|
+
[ "app: #{pretty_app(payload["droplet"])}",
|
276
|
+
"querying states: #{states.join(", ")}"
|
277
|
+
].join(", ")
|
278
|
+
]
|
248
279
|
end
|
249
280
|
|
250
281
|
def pretty_find_droplet_response(sub, msg)
|
@@ -254,14 +285,22 @@ module CFTools
|
|
254
285
|
state = payload["state"]
|
255
286
|
time = Time.at(payload["state_timestamp"])
|
256
287
|
[ sub,
|
257
|
-
"dea: #{dea},
|
288
|
+
[ "dea: #{dea}",
|
289
|
+
"index: #{index}",
|
290
|
+
"state: #{c(state.downcase, state_color(state))}",
|
291
|
+
"since: #{time}"
|
292
|
+
].join(", ")
|
258
293
|
]
|
259
294
|
end
|
260
295
|
|
261
296
|
def pretty_healthmanager_status(sub, msg)
|
262
297
|
payload = JSON.parse(msg)
|
263
298
|
state = payload["state"]
|
264
|
-
[d(sub),
|
299
|
+
[ d(sub),
|
300
|
+
[ "app: #{pretty_app(payload["droplet"])}",
|
301
|
+
"querying states: #{c(state.downcase, state_color(state))}"
|
302
|
+
].join(", ")
|
303
|
+
]
|
265
304
|
end
|
266
305
|
|
267
306
|
def pretty_healthmanager_status_response(sub, msg)
|
@@ -277,7 +316,11 @@ module CFTools
|
|
277
316
|
|
278
317
|
def pretty_healthmanager_health_response(sub, msg)
|
279
318
|
payload = JSON.parse(msg)
|
280
|
-
[sub,
|
319
|
+
[ sub,
|
320
|
+
[ "app: #{pretty_app(payload["droplet"])}",
|
321
|
+
"healthy: #{payload["healthy"]}"
|
322
|
+
].join(", ")
|
323
|
+
]
|
281
324
|
end
|
282
325
|
|
283
326
|
def pretty_updated(sub, msg)
|
@@ -303,7 +346,11 @@ module CFTools
|
|
303
346
|
|
304
347
|
op = payload["op"]
|
305
348
|
|
306
|
-
message =
|
349
|
+
message = [
|
350
|
+
"app: #{pretty_app(payload["droplet"])}",
|
351
|
+
"operation: #{pretty_hm_op(op)}",
|
352
|
+
"app last updated: #{last_updated}"
|
353
|
+
]
|
307
354
|
|
308
355
|
case op
|
309
356
|
when "STOP"
|
@@ -312,7 +359,7 @@ module CFTools
|
|
312
359
|
message << "indices: #{list(payload["indices"])}"
|
313
360
|
end
|
314
361
|
|
315
|
-
[c("hm.request", :warning), message]
|
362
|
+
[c("hm.request", :warning), message.join(", ")]
|
316
363
|
end
|
317
364
|
|
318
365
|
def pretty_service_announcement(sub, msg)
|
@@ -324,7 +371,13 @@ module CFTools
|
|
324
371
|
c_avail = payload["available_capacity"]
|
325
372
|
s_versions = payload["supported_versions"]
|
326
373
|
|
327
|
-
[d(sub),
|
374
|
+
[ d(sub),
|
375
|
+
[ "id: #{id}",
|
376
|
+
"plan: #{plan}",
|
377
|
+
"supported versions: #{list(s_versions)}",
|
378
|
+
"capacity: (available: #{c_avail}, max: #{c_max}, unit: #{c_unit})"
|
379
|
+
].join(", ")
|
380
|
+
]
|
328
381
|
end
|
329
382
|
|
330
383
|
def pretty_component_announcement(sub, msg)
|
@@ -334,7 +387,13 @@ module CFTools
|
|
334
387
|
uuid = payload["uuid"]
|
335
388
|
time = payload["start"]
|
336
389
|
|
337
|
-
[d(sub),
|
390
|
+
[ d(sub),
|
391
|
+
[ "type: #{type}",
|
392
|
+
"index: #{index}",
|
393
|
+
"uuid: #{uuid}",
|
394
|
+
"start time: #{time}"
|
395
|
+
].join(", ")
|
396
|
+
]
|
338
397
|
end
|
339
398
|
|
340
399
|
def pretty_component_discover(sub, msg)
|
@@ -346,12 +405,18 @@ module CFTools
|
|
346
405
|
type = payload["type"]
|
347
406
|
index = payload["index"]
|
348
407
|
host = payload["host"]
|
408
|
+
user, pass = payload["credentials"]
|
349
409
|
uptime = payload["uptime"]
|
350
410
|
|
351
|
-
message =
|
352
|
-
|
411
|
+
message = [
|
412
|
+
"type: #{type}",
|
413
|
+
"index: #{index}",
|
414
|
+
"uri: #{user}:#{pass}@#{host}"
|
415
|
+
]
|
416
|
+
|
417
|
+
message << "uptime: #{uptime}" if uptime
|
353
418
|
|
354
|
-
[d(sub), message]
|
419
|
+
[d(sub), message.join(", ")]
|
355
420
|
end
|
356
421
|
|
357
422
|
def pretty_hm_op(op)
|
data/spec/dea-ads_spec.rb
CHANGED
@@ -6,25 +6,25 @@ describe CFTools::DEAAds do
|
|
6
6
|
before { stub_client }
|
7
7
|
|
8
8
|
before do
|
9
|
-
stub(
|
10
|
-
stub(
|
11
|
-
stub(
|
9
|
+
NATS.stub(:start).and_yield
|
10
|
+
NATS.stub(:subscribe)
|
11
|
+
EM.stub(:add_periodic_timer).and_yield
|
12
12
|
end
|
13
13
|
|
14
14
|
it "subscribes to dea.advertise" do
|
15
|
-
|
15
|
+
expect(NATS).to receive(:subscribe).with("dea.advertise")
|
16
16
|
cf %W[dea-ads]
|
17
17
|
end
|
18
18
|
|
19
19
|
it "refreshes every 3 seconds" do
|
20
|
-
|
21
|
-
|
20
|
+
expect(EM).to receive(:add_periodic_timer).with(3).and_yield
|
21
|
+
expect_any_instance_of(described_class).to receive(:render_table)
|
22
22
|
cf %W[dea-ads]
|
23
23
|
end
|
24
24
|
|
25
25
|
context "when no NATS server info is specified" do
|
26
26
|
it "connects on nats:nats@127.0.0.1:4222" do
|
27
|
-
|
27
|
+
expect(NATS).to receive(:start).with(hash_including(
|
28
28
|
:uri => "nats://nats:nats@127.0.0.1:4222"))
|
29
29
|
|
30
30
|
cf %W[dea-ads]
|
@@ -33,7 +33,7 @@ describe CFTools::DEAAds do
|
|
33
33
|
|
34
34
|
context "when NATS server info is specified" do
|
35
35
|
it "connects to the given location using the given credentials" do
|
36
|
-
|
36
|
+
expect(NATS).to receive(:start).with(hash_including(
|
37
37
|
:uri => "nats://someuser:somepass@example.com:4242"))
|
38
38
|
|
39
39
|
cf %W[dea-ads -h example.com -P 4242 -u someuser -p somepass]
|
@@ -64,7 +64,7 @@ describe CFTools::DEAAds do
|
|
64
64
|
PAYLOAD
|
65
65
|
|
66
66
|
before do
|
67
|
-
stub(
|
67
|
+
NATS.stub(:subscribe).and_yield(advertise)
|
68
68
|
end
|
69
69
|
|
70
70
|
it "prints its entry in the table" do
|
@@ -72,12 +72,28 @@ PAYLOAD
|
|
72
72
|
expect(output).to say(/^2\s+lucid64, lucid86\s+6\s+1\.2G$/)
|
73
73
|
end
|
74
74
|
|
75
|
+
context "and it has no apps" do
|
76
|
+
let(:advertise) { <<PAYLOAD }
|
77
|
+
{
|
78
|
+
"app_id_to_count": {},
|
79
|
+
"available_memory": 1256,
|
80
|
+
"stacks": [
|
81
|
+
"lucid64"
|
82
|
+
],
|
83
|
+
"prod": false,
|
84
|
+
"id": "2-1d0cf3bcd994d9f2c5ea22b9b624d77b"
|
85
|
+
}
|
86
|
+
PAYLOAD
|
87
|
+
|
88
|
+
it "prints 0 as the droplet count" do
|
89
|
+
cf %W[dea-ads]
|
90
|
+
expect(output).to say(/^2\s+lucid64\s+0\s+1\.2G$/)
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
75
94
|
context "and another advertise is seen" do
|
76
95
|
before do
|
77
|
-
stub(
|
78
|
-
blk.call(advertise)
|
79
|
-
blk.call(other_advertise)
|
80
|
-
end
|
96
|
+
NATS.stub(:subscribe).and_yield(advertise).and_yield(other_advertise)
|
81
97
|
end
|
82
98
|
|
83
99
|
context "from a different DEA" do
|
data/spec/shell_spec.rb
CHANGED
@@ -6,10 +6,10 @@ describe CFTools::Shell do
|
|
6
6
|
before { stub_client }
|
7
7
|
|
8
8
|
it "starts a pry session with :quiet" do
|
9
|
-
binding =
|
9
|
+
binding = double
|
10
10
|
|
11
|
-
|
12
|
-
|
11
|
+
expect_any_instance_of(described_class).to receive(:binding).and_return(binding)
|
12
|
+
expect(binding).to receive(:pry).with(:quiet => true)
|
13
13
|
|
14
14
|
cf %w[shell]
|
15
15
|
end
|
data/spec/spec_helper.rb
CHANGED
data/spec/tunnel/base_spec.rb
CHANGED
@@ -2,14 +2,12 @@ require "spec_helper"
|
|
2
2
|
|
3
3
|
module CFTools::Tunnel
|
4
4
|
describe Base do
|
5
|
-
before
|
6
|
-
stub(subject).input { { :quiet => true } }
|
7
|
-
end
|
5
|
+
before { subject.stub(:input => {:quiet => true}) }
|
8
6
|
|
9
7
|
describe "#director" do
|
10
8
|
context "when the given director is accessible" do
|
11
9
|
before do
|
12
|
-
stub(
|
10
|
+
subject.stub(:address_reachable?).with("some-director.com", 25555).and_return(true)
|
13
11
|
end
|
14
12
|
|
15
13
|
it "returns the given director" do
|
@@ -21,11 +19,11 @@ module CFTools::Tunnel
|
|
21
19
|
|
22
20
|
context "when the given director is inaccessible" do
|
23
21
|
before do
|
24
|
-
stub(
|
22
|
+
subject.stub(:address_reachable?).with("some-director.com", 25555).and_return(false)
|
25
23
|
end
|
26
24
|
|
27
25
|
it "opens a tunnel through the gateway" do
|
28
|
-
|
26
|
+
expect(subject).to receive(:tunnel_to).with("some-director.com", 25555, "user@some-gateway") do
|
29
27
|
1234
|
30
28
|
end
|
31
29
|
|
@@ -37,63 +35,61 @@ module CFTools::Tunnel
|
|
37
35
|
end
|
38
36
|
|
39
37
|
describe "#login_to_director" do
|
40
|
-
let(:director) {
|
38
|
+
let(:director) { double }
|
41
39
|
|
42
40
|
before do
|
43
|
-
stub(
|
44
|
-
stub(
|
45
|
-
stub(
|
41
|
+
director.stub(:user=)
|
42
|
+
director.stub(:password=)
|
43
|
+
director.stub(:authenticated? => true)
|
46
44
|
end
|
47
45
|
|
48
46
|
it "assigns the given user/pass on the director" do
|
49
|
-
|
50
|
-
|
47
|
+
expect(director).to receive(:user=).with("user")
|
48
|
+
expect(director).to receive(:password=).with("pass")
|
51
49
|
subject.login_to_director(director, "user", "pass")
|
52
50
|
end
|
53
51
|
|
54
52
|
it "returns true iff director.authenticated?" do
|
55
|
-
|
53
|
+
expect(director).to receive(:authenticated?).and_return(true)
|
56
54
|
expect(subject.login_to_director(director, "user", "pass")).to be_true
|
57
55
|
end
|
58
56
|
|
59
57
|
it "returns false iff !director.authenticated?" do
|
60
|
-
|
58
|
+
expect(director).to receive(:authenticated?).and_return(false)
|
61
59
|
expect(subject.login_to_director(director, "user", "pass")).to be_false
|
62
60
|
end
|
63
61
|
end
|
64
62
|
|
65
63
|
describe "#tunnel_to" do
|
66
|
-
let(:gateway) {
|
64
|
+
let(:gateway) { double }
|
67
65
|
|
68
|
-
before
|
69
|
-
stub(gateway).open
|
70
|
-
end
|
66
|
+
before { gateway.stub(:open) }
|
71
67
|
|
72
68
|
it "creates a gateway using the given user/host" do
|
73
|
-
|
69
|
+
expect(Net::SSH::Gateway).to receive(:new).with("ghost", "guser") { gateway }
|
74
70
|
subject.tunnel_to("1.2.3.4", 1234, "guser@ghost")
|
75
71
|
end
|
76
72
|
|
77
73
|
it "opens a local tunnel and returns its port" do
|
78
|
-
|
79
|
-
|
74
|
+
Net::SSH::Gateway.stub(:new).with("ghost", "guser") { gateway }
|
75
|
+
expect(gateway).to receive(:open).with("1.2.3.4", 1234) { 5678 }
|
80
76
|
expect(subject.tunnel_to("1.2.3.4", 1234, "guser@ghost")).to eq(5678)
|
81
77
|
end
|
82
78
|
end
|
83
79
|
|
84
80
|
describe "#authenticate_with_director" do
|
85
|
-
let(:director) {
|
81
|
+
let(:director) { double }
|
86
82
|
|
87
83
|
def self.it_asks_interactively
|
88
84
|
it "asks for the credentials interactively" do
|
89
85
|
if saved_credentials
|
90
|
-
|
86
|
+
expect(subject).to receive(:login_to_director).with(director, "user", "pass").and_return(false).ordered
|
91
87
|
end
|
92
88
|
|
93
|
-
|
94
|
-
|
89
|
+
should_ask("Director Username") { "fizz" }
|
90
|
+
should_ask("Director Password", anything) { "buzz" }
|
95
91
|
|
96
|
-
|
92
|
+
expect(subject).to receive(:login_to_director).with(director, "fizz", "buzz").and_return(true).ordered
|
97
93
|
|
98
94
|
subject.authenticate_with_director(director, "foo", saved_credentials)
|
99
95
|
end
|
@@ -101,13 +97,13 @@ module CFTools::Tunnel
|
|
101
97
|
context "when the interactive user/pass is valid" do
|
102
98
|
it "returns true" do
|
103
99
|
if saved_credentials
|
104
|
-
|
100
|
+
expect(subject).to receive(:login_to_director).with(director, "user", "pass").and_return(false).ordered
|
105
101
|
end
|
106
102
|
|
107
|
-
|
108
|
-
|
103
|
+
should_ask("Director Username") { "fizz" }
|
104
|
+
should_ask("Director Password", anything) { "buzz" }
|
109
105
|
|
110
|
-
|
106
|
+
expect(subject).to receive(:login_to_director).with(director, "fizz", "buzz").and_return(true).ordered
|
111
107
|
|
112
108
|
expect(
|
113
109
|
subject.authenticate_with_director(director, "foo", saved_credentials)
|
@@ -116,15 +112,15 @@ module CFTools::Tunnel
|
|
116
112
|
|
117
113
|
it "saves them to the bosh config" do
|
118
114
|
if saved_credentials
|
119
|
-
|
115
|
+
expect(subject).to receive(:login_to_director).with(director, "user", "pass").and_return(false).ordered
|
120
116
|
end
|
121
117
|
|
122
|
-
|
123
|
-
|
118
|
+
should_ask("Director Username") { "fizz" }
|
119
|
+
should_ask("Director Password", anything) { "buzz" }
|
124
120
|
|
125
|
-
|
121
|
+
expect(subject).to receive(:login_to_director).with(director, "fizz", "buzz").and_return(true).ordered
|
126
122
|
|
127
|
-
|
123
|
+
expect(subject).to receive(:save_auth).with("foo", "username" => "fizz", "password" => "buzz")
|
128
124
|
|
129
125
|
subject.authenticate_with_director(director, "foo", saved_credentials)
|
130
126
|
end
|
@@ -133,18 +129,18 @@ module CFTools::Tunnel
|
|
133
129
|
context "when the interactive user/pass is invalid" do
|
134
130
|
it "asks again" do
|
135
131
|
if saved_credentials
|
136
|
-
|
132
|
+
expect(subject).to receive(:login_to_director).with(director, "user", "pass").and_return(false).ordered
|
137
133
|
end
|
138
134
|
|
139
|
-
|
140
|
-
|
135
|
+
should_ask("Director Username") { "fizz" }
|
136
|
+
should_ask("Director Password", anything) { "buzz" }
|
141
137
|
|
142
|
-
|
138
|
+
expect(subject).to receive(:login_to_director).with(director, "fizz", "buzz").and_return(false).ordered
|
143
139
|
|
144
|
-
|
145
|
-
|
140
|
+
should_ask("Director Username") { "a" }
|
141
|
+
should_ask("Director Password", anything) { "b" }
|
146
142
|
|
147
|
-
|
143
|
+
expect(subject).to receive(:login_to_director).with(director, "a", "b").and_return(true).ordered
|
148
144
|
|
149
145
|
subject.authenticate_with_director(director, "foo", saved_credentials)
|
150
146
|
end
|
@@ -156,7 +152,7 @@ module CFTools::Tunnel
|
|
156
152
|
|
157
153
|
context "and they are valid" do
|
158
154
|
it "returns true" do
|
159
|
-
|
155
|
+
expect(subject).to receive(:login_to_director).with(director, "user", "pass").and_return(true)
|
160
156
|
|
161
157
|
expect(
|
162
158
|
subject.authenticate_with_director(
|