tools-cf-plugin 2.1.1 → 2.2.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/tunnel/tunnel-nats.rb +0 -3
- data/lib/tools-cf-plugin/version.rb +1 -1
- data/lib/tools-cf-plugin/watch.rb +96 -47
- data/spec/watch_spec.rb +133 -48
- metadata +22 -23
@@ -3,17 +3,18 @@ require "nats/client"
|
|
3
3
|
|
4
4
|
module CFTools
|
5
5
|
class Watch < CF::App::Base
|
6
|
-
def precondition
|
7
|
-
check_target
|
8
|
-
end
|
6
|
+
def precondition; end
|
9
7
|
|
10
8
|
REPLY_PREFIX = "`- reply to "
|
11
9
|
COLUMN_WIDTH = 30
|
12
10
|
|
13
11
|
desc "Watch messages going over NATS relevant to an application"
|
14
12
|
group :admin
|
15
|
-
input :app, :argument => :optional, :from_given => by_name(:
|
13
|
+
input :app, :argument => :optional, :from_given => by_name(:apps),
|
16
14
|
:desc => "Application to watch"
|
15
|
+
input :subjects, :aliases => %w[-s --subject],
|
16
|
+
:from_given => proc { |s| s.split(",") },
|
17
|
+
:desc => "NATS subject to subscribe to"
|
17
18
|
input :host, :alias => "-h", :default => "127.0.0.1",
|
18
19
|
:desc => "NATS server address"
|
19
20
|
input :port, :alias => "-P", :default => 4222, :type => :integer,
|
@@ -23,11 +24,12 @@ module CFTools
|
|
23
24
|
input :password, :alias => "-p", :default => "nats",
|
24
25
|
:desc => "NATS server password"
|
25
26
|
def watch
|
26
|
-
app = input[:app]
|
27
|
+
app = get_app(input[:app])
|
27
28
|
host = input[:host]
|
28
29
|
port = input[:port]
|
29
30
|
user = input[:user]
|
30
31
|
pass = input[:password]
|
32
|
+
subjects = input[:subjects] || [">"]
|
31
33
|
|
32
34
|
@requests = {}
|
33
35
|
@seen_apps = {}
|
@@ -35,7 +37,7 @@ module CFTools
|
|
35
37
|
|
36
38
|
$stdout.sync = true
|
37
39
|
|
38
|
-
watching_nats("nats://#{user}:#{pass}@#{host}:#{port}") do |msg, reply, sub|
|
40
|
+
watching_nats("nats://#{user}:#{pass}@#{host}:#{port}", subjects) do |msg, reply, sub|
|
39
41
|
begin
|
40
42
|
if @requests.include?(sub)
|
41
43
|
process_response(sub, reply, msg, app)
|
@@ -65,7 +67,7 @@ module CFTools
|
|
65
67
|
def process_message(sub, reply, msg, app)
|
66
68
|
register_request(sub, reply) if reply
|
67
69
|
|
68
|
-
payload = JSON.parse(msg)
|
70
|
+
payload = JSON.parse(msg) rescue msg
|
69
71
|
|
70
72
|
case sub
|
71
73
|
when "dea.advertise"
|
@@ -81,7 +83,6 @@ module CFTools
|
|
81
83
|
when "router.start"
|
82
84
|
sub, payload = pretty_router_start(sub, payload)
|
83
85
|
when "router.register"
|
84
|
-
return if !app && payload.has_key?("dea")
|
85
86
|
sub, payload = pretty_register(sub, payload)
|
86
87
|
when "router.unregister"
|
87
88
|
sub, payload = pretty_unregister(sub, payload)
|
@@ -101,8 +102,10 @@ module CFTools
|
|
101
102
|
sub, payload = pretty_healthmanager_health(sub, payload)
|
102
103
|
when "dea.shutdown"
|
103
104
|
sub, payload = pretty_dea_shutdown(sub, payload)
|
104
|
-
when
|
105
|
-
sub, payload =
|
105
|
+
when "health.start"
|
106
|
+
sub, payload = pretty_health_start(sub, payload)
|
107
|
+
when "health.stop"
|
108
|
+
sub, payload = pretty_health_stop(sub, payload)
|
106
109
|
when /^([^.]+)\.announce$/
|
107
110
|
sub, payload = pretty_service_announcement(sub, payload)
|
108
111
|
when "vcap.component.announce"
|
@@ -168,13 +171,13 @@ module CFTools
|
|
168
171
|
[ c(sub, :bad),
|
169
172
|
[ "app: #{pretty_app(payload["droplet"])}",
|
170
173
|
"reason: #{payload["reason"]}",
|
171
|
-
"index: #{payload["index"]}"
|
174
|
+
"index: #{payload["index"]}",
|
175
|
+
"version: #{pretty_version(payload["version"])}"
|
172
176
|
].join(", ")
|
173
177
|
]
|
174
178
|
end
|
175
179
|
|
176
180
|
def pretty_heartbeat(sub, payload, app)
|
177
|
-
|
178
181
|
dea, _ = payload["dea"].split("-", 2)
|
179
182
|
|
180
183
|
states = Hash.new(0)
|
@@ -233,7 +236,8 @@ module CFTools
|
|
233
236
|
[ "app: #{pretty_app(payload["droplet"])}",
|
234
237
|
"dea: #{dea}",
|
235
238
|
"index: #{payload["index"]}",
|
236
|
-
"
|
239
|
+
"version: #{pretty_version(payload["version"])}",
|
240
|
+
"uris: #{list(Array(payload["uris"]))}"
|
237
241
|
].join(", ")
|
238
242
|
]
|
239
243
|
end
|
@@ -241,6 +245,10 @@ module CFTools
|
|
241
245
|
def pretty_stop(sub, payload)
|
242
246
|
message = ["app: #{pretty_app(payload["droplet"])}"]
|
243
247
|
|
248
|
+
if (version = payload["version"])
|
249
|
+
message << "version: #{pretty_version(version)}"
|
250
|
+
end
|
251
|
+
|
244
252
|
if (indices = payload["indices"])
|
245
253
|
message << "scaling down indices: #{indices.join(", ")}"
|
246
254
|
elsif (instances = payload["instances"])
|
@@ -261,10 +269,14 @@ module CFTools
|
|
261
269
|
end
|
262
270
|
|
263
271
|
def pretty_find_droplet(sub, payload)
|
264
|
-
states = payload["states"].collect
|
272
|
+
states = (payload["states"] || []).collect do |s|
|
273
|
+
c(s.downcase, state_color(s))
|
274
|
+
end
|
275
|
+
|
265
276
|
[ d(sub),
|
266
277
|
[ "app: #{pretty_app(payload["droplet"])}",
|
267
|
-
"
|
278
|
+
"version: #{pretty_version(payload["version"])}",
|
279
|
+
"querying states: #{list(states)}"
|
268
280
|
].join(", ")
|
269
281
|
]
|
270
282
|
end
|
@@ -273,20 +285,25 @@ module CFTools
|
|
273
285
|
dea, _ = payload["dea"].split("-", 2)
|
274
286
|
index = payload["index"]
|
275
287
|
state = payload["state"]
|
276
|
-
|
288
|
+
version = payload["version"]
|
289
|
+
since = Time.at(payload["state_timestamp"])
|
277
290
|
[ sub,
|
278
291
|
[ "dea: #{dea}",
|
279
292
|
"index: #{index}",
|
280
293
|
"state: #{c(state.downcase, state_color(state))}",
|
281
|
-
"
|
294
|
+
"version: #{pretty_version(version)}",
|
295
|
+
"since: #{since}"
|
282
296
|
].join(", ")
|
283
297
|
]
|
284
298
|
end
|
285
299
|
|
286
300
|
def pretty_healthmanager_status(sub, payload)
|
287
301
|
state = payload["state"]
|
302
|
+
version = payload["version"]
|
303
|
+
|
288
304
|
[ d(sub),
|
289
305
|
[ "app: #{pretty_app(payload["droplet"])}",
|
306
|
+
"version: #{pretty_version(version)}",
|
290
307
|
"querying states: #{c(state.downcase, state_color(state))}"
|
291
308
|
].join(", ")
|
292
309
|
]
|
@@ -297,13 +314,17 @@ module CFTools
|
|
297
314
|
end
|
298
315
|
|
299
316
|
def pretty_healthmanager_health(sub, payload)
|
300
|
-
apps = payload["droplets"].collect
|
317
|
+
apps = payload["droplets"].collect do |d|
|
318
|
+
"#{pretty_app(d["droplet"])} (#{pretty_version(d["version"])})"
|
319
|
+
end
|
320
|
+
|
301
321
|
[d(sub), "querying health for: #{list(apps)}"]
|
302
322
|
end
|
303
323
|
|
304
324
|
def pretty_healthmanager_health_response(sub, payload)
|
305
325
|
[ sub,
|
306
326
|
[ "app: #{pretty_app(payload["droplet"])}",
|
327
|
+
"version: #{pretty_version(payload["version"])}",
|
307
328
|
"healthy: #{payload["healthy"]}"
|
308
329
|
].join(", ")
|
309
330
|
]
|
@@ -323,25 +344,23 @@ module CFTools
|
|
323
344
|
[c(sub, :error), "dea: #{dea}, apps: #{list(apps)}"]
|
324
345
|
end
|
325
346
|
|
326
|
-
def
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
"
|
333
|
-
"operation: #{pretty_hm_op(op)}",
|
334
|
-
"app last updated: #{last_updated}"
|
347
|
+
def pretty_health_start(sub, payload)
|
348
|
+
[ c(sub, :good),
|
349
|
+
[ "app: #{pretty_app(payload["droplet"])}",
|
350
|
+
"version: #{pretty_version(payload["version"])}",
|
351
|
+
"indices: #{list(payload["indices"])}",
|
352
|
+
"running: #{pretty_running_counts(payload["running"])}"
|
353
|
+
].join(", ")
|
335
354
|
]
|
355
|
+
end
|
336
356
|
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
[c("hm.request", :warning), message.join(", ")]
|
357
|
+
def pretty_health_stop(sub, payload)
|
358
|
+
[ c(sub, :bad),
|
359
|
+
[ "app: #{pretty_app(payload["droplet"])}",
|
360
|
+
"instances: #{pretty_instance_breakdown(payload["instances"])}",
|
361
|
+
"running: #{pretty_running_counts(payload["running"])}"
|
362
|
+
].join(", ")
|
363
|
+
]
|
345
364
|
end
|
346
365
|
|
347
366
|
def pretty_service_announcement(sub, payload)
|
@@ -398,18 +417,25 @@ module CFTools
|
|
398
417
|
[d(sub), message.join(", ")]
|
399
418
|
end
|
400
419
|
|
401
|
-
def
|
402
|
-
|
403
|
-
|
404
|
-
|
405
|
-
|
406
|
-
|
407
|
-
|
408
|
-
|
409
|
-
|
420
|
+
def pretty_running_counts(running)
|
421
|
+
running.collect do |ver, num|
|
422
|
+
"#{num} x #{pretty_version(ver)}"
|
423
|
+
end.join(", ")
|
424
|
+
end
|
425
|
+
|
426
|
+
def pretty_instance_breakdown(instances)
|
427
|
+
instances.collect do |inst, ver|
|
428
|
+
"#{inst} (#{pretty_version(ver)})"
|
429
|
+
end.join(", ")
|
430
|
+
end
|
431
|
+
|
432
|
+
def pretty_version(guid)
|
433
|
+
guid.split("-").first
|
410
434
|
end
|
411
435
|
|
412
436
|
def pretty_app(guid)
|
437
|
+
return guid unless client
|
438
|
+
|
413
439
|
existing_app =
|
414
440
|
if @seen_apps.key?(guid)
|
415
441
|
@seen_apps[guid]
|
@@ -419,22 +445,45 @@ module CFTools
|
|
419
445
|
end
|
420
446
|
|
421
447
|
if existing_app
|
422
|
-
|
448
|
+
@seen_apps[guid] = existing_app
|
423
449
|
c(existing_app.name, :name)
|
424
450
|
else
|
425
451
|
@seen_apps[guid] = nil
|
426
452
|
d("unknown (#{guid})")
|
427
453
|
end
|
454
|
+
rescue CFoundry::TargetRefused, CFoundry::InvalidAuthToken
|
455
|
+
guid
|
428
456
|
end
|
429
457
|
|
430
|
-
def watching_nats(uri, &blk)
|
458
|
+
def watching_nats(uri, subjects, &blk)
|
431
459
|
NATS.start(:uri => uri) do
|
432
|
-
|
460
|
+
subjects.each do |subject|
|
461
|
+
NATS.subscribe(subject, &blk)
|
462
|
+
end
|
433
463
|
end
|
434
464
|
end
|
435
465
|
|
436
466
|
def register_request(sub, reply)
|
437
467
|
@requests[reply] = [sub, @request_ticker += 1]
|
438
468
|
end
|
469
|
+
|
470
|
+
def get_app(apps)
|
471
|
+
return unless apps
|
472
|
+
|
473
|
+
if apps.empty?
|
474
|
+
fail "Unknown app '#{input.given[:app]}'."
|
475
|
+
elsif apps.size == 1
|
476
|
+
apps.first
|
477
|
+
else
|
478
|
+
disambiguate_app(apps)
|
479
|
+
end
|
480
|
+
end
|
481
|
+
|
482
|
+
def disambiguate_app(apps)
|
483
|
+
ask("Which application?", :choices => apps,
|
484
|
+
:display => proc do |a|
|
485
|
+
"#{a.name} (#{a.space.organization.name}/#{a.space.name})"
|
486
|
+
end)
|
487
|
+
end
|
439
488
|
end
|
440
489
|
end
|
data/spec/watch_spec.rb
CHANGED
@@ -33,6 +33,21 @@ describe CFTools::Watch do
|
|
33
33
|
cf %W[watch]
|
34
34
|
end
|
35
35
|
|
36
|
+
context "when a subject is given" do
|
37
|
+
it "subscribes to the given subject on NATS" do
|
38
|
+
expect(NATS).to receive(:subscribe).with("some.subject")
|
39
|
+
cf %W[watch --subject some.subject]
|
40
|
+
end
|
41
|
+
|
42
|
+
context "when multiple subjects are given" do
|
43
|
+
it "subscribes to all of them on NATS" do
|
44
|
+
expect(NATS).to receive(:subscribe).with("some.subject")
|
45
|
+
expect(NATS).to receive(:subscribe).with("some.other.subject")
|
46
|
+
cf %W[watch --subjects some.subject,some.other.subject]
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
36
51
|
context "when no application is given" do
|
37
52
|
around { |example| Timecop.freeze(&example) }
|
38
53
|
|
@@ -104,6 +119,25 @@ describe CFTools::Watch do
|
|
104
119
|
end
|
105
120
|
end
|
106
121
|
|
122
|
+
context "and multiple apps with the sane name are found" do
|
123
|
+
let!(:org1) { fake :organization, :name => "org1" }
|
124
|
+
let!(:org2) { fake :organization, :name => "org2" }
|
125
|
+
let!(:space1) { fake :space, :name => "space1", :organization => org1 }
|
126
|
+
let!(:space2) { fake :space, :name => "space2", :organization => org2 }
|
127
|
+
let!(:app1) { fake :app, :name => "myapp", :guid => "myappguid", :space => space1 }
|
128
|
+
let!(:app2) { fake :app, :name => "myapp", :guid => "myappguid", :space => space2 }
|
129
|
+
|
130
|
+
let(:client) { fake_client :apps => [app1, app2] }
|
131
|
+
|
132
|
+
it "asks to disambiguate" do
|
133
|
+
should_ask("Which application?", hash_including(:choices => [app1, app2])) do |_, opts|
|
134
|
+
expect(opts[:display].call(app1)).to eq("myapp (org1/space1)")
|
135
|
+
end
|
136
|
+
|
137
|
+
cf %W[watch myapp]
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
107
141
|
context "and a message containing the app's GUID is seen" do
|
108
142
|
around { |example| Timecop.freeze(&example) }
|
109
143
|
|
@@ -146,7 +180,7 @@ PAYLOAD
|
|
146
180
|
it "pretty-prints the message body" do
|
147
181
|
cf %W[watch]
|
148
182
|
|
149
|
-
expect(output).to say("app: myapp, reason: STOPPED, index: 0")
|
183
|
+
expect(output).to say("app: myapp, reason: STOPPED, index: 0, version: aaca113b")
|
150
184
|
end
|
151
185
|
end
|
152
186
|
|
@@ -172,7 +206,7 @@ PAYLOAD
|
|
172
206
|
"state": "CRASHED",
|
173
207
|
"index": 1,
|
174
208
|
"instance": "some other app instance",
|
175
|
-
"version": "
|
209
|
+
"version": "deadbeef-8384-4a35-915e-872fe91ffb95",
|
176
210
|
"droplet": "#{app.guid}",
|
177
211
|
"cc_partition": "default"
|
178
212
|
},
|
@@ -453,10 +487,42 @@ PAYLOAD
|
|
453
487
|
expect(output).to say("dea.42.start")
|
454
488
|
end
|
455
489
|
|
456
|
-
it "prints the
|
490
|
+
it "prints the app, dea, index, version, and uris" do
|
457
491
|
cf %W[watch]
|
458
492
|
|
459
|
-
expect(output).to say("app: myapp, dea: 42, index: 2, uris: myapp.com")
|
493
|
+
expect(output).to say("app: myapp, dea: 42, index: 2, version: ce1da6af, uris: myapp.com")
|
494
|
+
end
|
495
|
+
|
496
|
+
context "when a single uri is given as a string" do
|
497
|
+
let(:payload) { <<PAYLOAD }
|
498
|
+
{
|
499
|
+
"index": 2,
|
500
|
+
"debug": null,
|
501
|
+
"console": true,
|
502
|
+
"env": [],
|
503
|
+
"cc_partition": "default",
|
504
|
+
"limits": {
|
505
|
+
"fds": 16384,
|
506
|
+
"disk": 1024,
|
507
|
+
"mem": 128
|
508
|
+
},
|
509
|
+
"services": [],
|
510
|
+
"droplet": "#{app.guid}",
|
511
|
+
"name": "hello-sinatra",
|
512
|
+
"uris": "myapp.com",
|
513
|
+
"prod": false,
|
514
|
+
"sha1": "9c8f36ee81b535a7d9b4efcd9d629e8cf8a2645f",
|
515
|
+
"executableFile": "deprecated",
|
516
|
+
"executableUri": "https://a1-cf-app-com-cc-droplets.s3.amazonaws.com/ac/cf/accf1078-e7e1-439a-bd32-77296390c406?AWSAccessKeyId=AKIAIMGCF7E5F6M5RV3A&Signature=1lyIotK3cZ2VUyK3H8YrlT82B8c%3D&Expires=1369259081",
|
517
|
+
"version": "ce1da6af-59b1-4fea-9e39-64c19440a671"
|
518
|
+
}
|
519
|
+
PAYLOAD
|
520
|
+
|
521
|
+
it "prints the app, dea, index, version, and uris" do
|
522
|
+
cf %W[watch]
|
523
|
+
|
524
|
+
expect(output).to say("app: myapp, dea: 42, index: 2, version: ce1da6af, uris: myapp.com")
|
525
|
+
end
|
460
526
|
end
|
461
527
|
end
|
462
528
|
|
@@ -497,7 +563,7 @@ PAYLOAD
|
|
497
563
|
it "prints that it's scaling down, and the affected indices" do
|
498
564
|
cf %W[watch]
|
499
565
|
|
500
|
-
expect(output).to say("app: myapp, scaling down indices: 1, 2")
|
566
|
+
expect(output).to say("app: myapp, version: ce1da6af, scaling down indices: 1, 2")
|
501
567
|
end
|
502
568
|
end
|
503
569
|
|
@@ -568,6 +634,8 @@ PAYLOAD
|
|
568
634
|
}
|
569
635
|
PAYLOAD
|
570
636
|
|
637
|
+
let(:state_timestamp) { "1369262704.3337305" }
|
638
|
+
|
571
639
|
let(:response_payload) { <<PAYLOAD }
|
572
640
|
{
|
573
641
|
"console_port": 61016,
|
@@ -579,11 +647,11 @@ PAYLOAD
|
|
579
647
|
],
|
580
648
|
"dea": "1-c0d2928b36c524153cdc8cfb51d80f75",
|
581
649
|
"droplet": "#{app.guid}",
|
582
|
-
"version": "
|
650
|
+
"version": "878318bf-0cf4-403d-a54d-1c0970dca50d",
|
583
651
|
"instance": "7cc4f4fe64c7a0fbfaacf71e9e222a35",
|
584
652
|
"index": 0,
|
585
653
|
"state": "RUNNING",
|
586
|
-
"state_timestamp":
|
654
|
+
"state_timestamp": #{state_timestamp},
|
587
655
|
"file_uri": "http://10.10.17.1:12345/instances"
|
588
656
|
}
|
589
657
|
PAYLOAD
|
@@ -591,7 +659,22 @@ PAYLOAD
|
|
591
659
|
it "prints the states being queried" do
|
592
660
|
cf %W[watch]
|
593
661
|
|
594
|
-
expect(output).to say("app: myapp, querying states: starting, running")
|
662
|
+
expect(output).to say("app: myapp, version: 878318bf, querying states: starting, running")
|
663
|
+
end
|
664
|
+
|
665
|
+
context "when there are no states being queried" do
|
666
|
+
let(:payload) { <<PAYLOAD }
|
667
|
+
{
|
668
|
+
"version": "878318bf-64a0-4055-b79b-46871292ceb8",
|
669
|
+
"droplet": "#{app.guid}"
|
670
|
+
}
|
671
|
+
PAYLOAD
|
672
|
+
|
673
|
+
it "prints them as 'none'" do
|
674
|
+
cf %W[watch]
|
675
|
+
|
676
|
+
expect(output).to say("app: myapp, version: 878318bf, querying states: none")
|
677
|
+
end
|
595
678
|
end
|
596
679
|
|
597
680
|
context "and we see the response" do
|
@@ -604,7 +687,7 @@ PAYLOAD
|
|
604
687
|
it "pretty-prints the response" do
|
605
688
|
cf %W[watch]
|
606
689
|
|
607
|
-
expect(output).to say("reply to dea.find.droplet (1)\tdea: 1, index: 0, state: running,
|
690
|
+
expect(output).to say("reply to dea.find.droplet (1)\tdea: 1, index: 0, state: running, version: 878318bf, since: #{Time.at(state_timestamp.to_f)}")
|
608
691
|
end
|
609
692
|
end
|
610
693
|
end
|
@@ -632,7 +715,7 @@ PAYLOAD
|
|
632
715
|
it "prints the states being queried" do
|
633
716
|
cf %W[watch]
|
634
717
|
|
635
|
-
expect(output).to say("app: myapp, querying states: flapping")
|
718
|
+
expect(output).to say("app: myapp, version: 50512eed, querying states: flapping")
|
636
719
|
end
|
637
720
|
|
638
721
|
context "and we see the response" do
|
@@ -661,11 +744,11 @@ PAYLOAD
|
|
661
744
|
{
|
662
745
|
"droplets": [
|
663
746
|
{
|
664
|
-
"version": "
|
747
|
+
"version": "deadbeef-foo",
|
665
748
|
"droplet": "#{app.guid}"
|
666
749
|
},
|
667
750
|
{
|
668
|
-
"version": "
|
751
|
+
"version": "beefdead-foo",
|
669
752
|
"droplet": "#{other_app.guid}"
|
670
753
|
}
|
671
754
|
]
|
@@ -675,7 +758,7 @@ PAYLOAD
|
|
675
758
|
let(:response_payload) { <<PAYLOAD }
|
676
759
|
{
|
677
760
|
"healthy": 2,
|
678
|
-
"version": "
|
761
|
+
"version": "deadbeef-foo",
|
679
762
|
"droplet": "#{app.guid}"
|
680
763
|
}
|
681
764
|
PAYLOAD
|
@@ -683,7 +766,7 @@ PAYLOAD
|
|
683
766
|
let(:other_response_payload) { <<PAYLOAD }
|
684
767
|
{
|
685
768
|
"healthy": 3,
|
686
|
-
"version": "
|
769
|
+
"version": "beefdead-foo",
|
687
770
|
"droplet": "#{other_app.guid}"
|
688
771
|
}
|
689
772
|
PAYLOAD
|
@@ -693,7 +776,7 @@ PAYLOAD
|
|
693
776
|
it "prints the apps whose health being queried" do
|
694
777
|
cf %W[watch]
|
695
778
|
|
696
|
-
expect(output).to say("querying health for: myapp, otherapp")
|
779
|
+
expect(output).to say("querying health for: myapp (deadbeef), otherapp (beefdead)")
|
697
780
|
end
|
698
781
|
|
699
782
|
context "and we see the response" do
|
@@ -707,8 +790,8 @@ PAYLOAD
|
|
707
790
|
it "pretty-prints the response" do
|
708
791
|
cf %W[watch]
|
709
792
|
|
710
|
-
expect(output).to say("reply to healthmanager.health (1)\tapp: myapp, healthy: 2")
|
711
|
-
expect(output).to say("reply to healthmanager.health (1)\tapp: otherapp, healthy: 3")
|
793
|
+
expect(output).to say("reply to healthmanager.health (1)\tapp: myapp, version: deadbeef, healthy: 2")
|
794
|
+
expect(output).to say("reply to healthmanager.health (1)\tapp: otherapp, version: beefdead, healthy: 3")
|
712
795
|
end
|
713
796
|
end
|
714
797
|
end
|
@@ -760,58 +843,60 @@ PAYLOAD
|
|
760
843
|
end
|
761
844
|
end
|
762
845
|
|
763
|
-
context "when a message is seen with subject
|
764
|
-
let(:subject) { "
|
846
|
+
context "when a message is seen with subject health.start" do
|
847
|
+
let(:subject) { "health.start" }
|
765
848
|
|
766
849
|
let(:last_updated) { Time.now }
|
767
850
|
|
768
|
-
|
769
|
-
let(:payload) { <<PAYLOAD }
|
851
|
+
let(:payload) { <<PAYLOAD }
|
770
852
|
{
|
771
|
-
"
|
772
|
-
|
773
|
-
|
853
|
+
"indices": [
|
854
|
+
1,
|
855
|
+
3
|
774
856
|
],
|
857
|
+
"running": {
|
858
|
+
"deadbeef-version": 1,
|
859
|
+
"beefdead-version": 2
|
860
|
+
},
|
861
|
+
"version": "deadbeef-foo",
|
775
862
|
"last_updated": #{last_updated.to_i},
|
776
|
-
"op": "STOP",
|
777
863
|
"droplet": "#{app.guid}"
|
778
864
|
}
|
779
865
|
PAYLOAD
|
780
866
|
|
781
|
-
|
782
|
-
|
867
|
+
it "prints the operation, last updated timestamp, and instances" do
|
868
|
+
cf %W[watch]
|
783
869
|
|
784
|
-
|
785
|
-
|
870
|
+
expect(output).to say(
|
871
|
+
"app: myapp, version: deadbeef, indices: 1, 3, running: 1 x deadbeef, 2 x beefdead")
|
872
|
+
end
|
873
|
+
end
|
786
874
|
|
787
|
-
|
788
|
-
|
875
|
+
context "when a message is seen with subject health.stop" do
|
876
|
+
let(:subject) { "health.stop" }
|
789
877
|
|
790
|
-
|
791
|
-
"app: myapp, operation: stop, app last updated: #{last_updated}, instances: some-instance, some-other-instance")
|
792
|
-
end
|
793
|
-
end
|
878
|
+
let(:last_updated) { Time.now }
|
794
879
|
|
795
|
-
|
796
|
-
let(:payload) { <<PAYLOAD }
|
880
|
+
let(:payload) { <<PAYLOAD }
|
797
881
|
{
|
798
|
-
"
|
799
|
-
|
800
|
-
|
801
|
-
|
802
|
-
"
|
882
|
+
"instances": {
|
883
|
+
"some-instance": "deadbeef-version",
|
884
|
+
"some-other-instance": "beefdead-version"
|
885
|
+
},
|
886
|
+
"running": {
|
887
|
+
"deadbeef-version": 1,
|
888
|
+
"beefdead-version": 2
|
889
|
+
},
|
803
890
|
"last_updated": #{last_updated.to_i},
|
804
|
-
"op": "START",
|
805
891
|
"droplet": "#{app.guid}"
|
806
892
|
}
|
807
893
|
PAYLOAD
|
808
894
|
|
809
|
-
|
810
|
-
|
895
|
+
it "prints the operation, last updated timestamp, and instances" do
|
896
|
+
cf %W[watch]
|
811
897
|
|
812
|
-
|
813
|
-
|
814
|
-
end
|
898
|
+
expect(output).to say(
|
899
|
+
"app: myapp, instances: some-instance (deadbeef), some-other-instance (beefdead), running: 1 x deadbeef, 2 x beefdead")
|
815
900
|
end
|
816
901
|
end
|
817
902
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: tools-cf-plugin
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.2.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-06-
|
12
|
+
date: 2013-06-26 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: cfoundry
|
@@ -271,29 +271,29 @@ extensions: []
|
|
271
271
|
extra_rdoc_files: []
|
272
272
|
files:
|
273
273
|
- Rakefile
|
274
|
-
- lib/tools-cf-plugin/dea-ads.rb
|
275
|
-
- lib/tools-cf-plugin/dea-apps.rb
|
276
274
|
- lib/tools-cf-plugin/plugin.rb
|
277
|
-
- lib/tools-cf-plugin/
|
278
|
-
- lib/tools-cf-plugin/tunnel/
|
275
|
+
- lib/tools-cf-plugin/version.rb
|
276
|
+
- lib/tools-cf-plugin/tunnel/watch-logs.rb
|
279
277
|
- lib/tools-cf-plugin/tunnel/log_entry.rb
|
280
|
-
- lib/tools-cf-plugin/tunnel/multi_line_stream.rb
|
281
|
-
- lib/tools-cf-plugin/tunnel/stream_location.rb
|
282
278
|
- lib/tools-cf-plugin/tunnel/tunnel-nats.rb
|
283
|
-
- lib/tools-cf-plugin/tunnel/
|
284
|
-
- lib/tools-cf-plugin/
|
279
|
+
- lib/tools-cf-plugin/tunnel/stream_location.rb
|
280
|
+
- lib/tools-cf-plugin/tunnel/base.rb
|
281
|
+
- lib/tools-cf-plugin/tunnel/multi_line_stream.rb
|
285
282
|
- lib/tools-cf-plugin/watch.rb
|
286
|
-
-
|
287
|
-
-
|
283
|
+
- lib/tools-cf-plugin/dea-apps.rb
|
284
|
+
- lib/tools-cf-plugin/shell.rb
|
285
|
+
- lib/tools-cf-plugin/dea-ads.rb
|
288
286
|
- spec/shell_spec.rb
|
287
|
+
- spec/watch_spec.rb
|
289
288
|
- spec/spec_helper.rb
|
290
|
-
- spec/
|
289
|
+
- spec/dea-apps_spec.rb
|
290
|
+
- spec/dea-ads_spec.rb
|
291
291
|
- spec/tunnel/log_entry_spec.rb
|
292
|
-
- spec/tunnel/
|
292
|
+
- spec/tunnel/watch-logs_spec.rb
|
293
|
+
- spec/tunnel/base_spec.rb
|
293
294
|
- spec/tunnel/stream_location_spec.rb
|
295
|
+
- spec/tunnel/multi_line_stream_spec.rb
|
294
296
|
- spec/tunnel/tunnel-nats_spec.rb
|
295
|
-
- spec/tunnel/watch-logs_spec.rb
|
296
|
-
- spec/watch_spec.rb
|
297
297
|
homepage: http://github.com/cloudfoundry/tools-cf-plugin
|
298
298
|
licenses: []
|
299
299
|
post_install_message:
|
@@ -319,15 +319,14 @@ signing_key:
|
|
319
319
|
specification_version: 3
|
320
320
|
summary: Cloud Foundry tooling commands.
|
321
321
|
test_files:
|
322
|
-
- spec/dea-ads_spec.rb
|
323
|
-
- spec/dea-apps_spec.rb
|
324
322
|
- spec/shell_spec.rb
|
323
|
+
- spec/watch_spec.rb
|
325
324
|
- spec/spec_helper.rb
|
326
|
-
- spec/
|
325
|
+
- spec/dea-apps_spec.rb
|
326
|
+
- spec/dea-ads_spec.rb
|
327
327
|
- spec/tunnel/log_entry_spec.rb
|
328
|
-
- spec/tunnel/
|
328
|
+
- spec/tunnel/watch-logs_spec.rb
|
329
|
+
- spec/tunnel/base_spec.rb
|
329
330
|
- spec/tunnel/stream_location_spec.rb
|
331
|
+
- spec/tunnel/multi_line_stream_spec.rb
|
330
332
|
- spec/tunnel/tunnel-nats_spec.rb
|
331
|
-
- spec/tunnel/watch-logs_spec.rb
|
332
|
-
- spec/watch_spec.rb
|
333
|
-
has_rdoc:
|