tools-cf-plugin 2.0.0 → 2.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
@@ -2,12 +2,12 @@ require "spec_helper"
|
|
2
2
|
|
3
3
|
module CFTools::Tunnel
|
4
4
|
describe MultiLineStream do
|
5
|
-
let(:director) {
|
5
|
+
let(:director) { double }
|
6
6
|
let(:deployment) { "some-deployment" }
|
7
7
|
let(:gateway_user) { "vcap" }
|
8
8
|
let(:gateway_host) { "vcap.me" }
|
9
9
|
|
10
|
-
let(:gateway) {
|
10
|
+
let(:gateway) { double }
|
11
11
|
let(:entries) { Queue.new }
|
12
12
|
|
13
13
|
subject do
|
@@ -15,10 +15,10 @@ module CFTools::Tunnel
|
|
15
15
|
end
|
16
16
|
|
17
17
|
before do
|
18
|
-
stub(
|
19
|
-
stub(
|
20
|
-
stub(
|
21
|
-
stub(
|
18
|
+
subject.stub(:create_ssh_user => ["1.2.3.4", "some_user_1"])
|
19
|
+
subject.stub(:gateway => gateway)
|
20
|
+
subject.stub(:entry_queue => entries)
|
21
|
+
Thread.stub(:new).and_yield
|
22
22
|
end
|
23
23
|
|
24
24
|
describe "#stream" do
|
@@ -36,14 +36,14 @@ module CFTools::Tunnel
|
|
36
36
|
end
|
37
37
|
|
38
38
|
it "spawns a SSH tunnel for each location" do
|
39
|
-
|
40
|
-
|
39
|
+
expect(Thread).to receive(:new).ordered
|
40
|
+
expect(Thread).to receive(:new).ordered
|
41
41
|
|
42
|
-
|
43
|
-
|
42
|
+
expect(subject).to receive(:create_ssh_user).with("foo", 0, entries) { ["1.2.3.4", "some_user_1"] }
|
43
|
+
expect(subject).to receive(:create_ssh_user).with("bar", 0, entries) { ["1.2.3.5", "some_user_2"] }
|
44
44
|
|
45
|
-
|
46
|
-
|
45
|
+
expect(gateway).to receive(:ssh).with("1.2.3.4", "some_user_1")
|
46
|
+
expect(gateway).to receive(:ssh).with("1.2.3.5", "some_user_2")
|
47
47
|
|
48
48
|
entries << nil
|
49
49
|
|
@@ -51,7 +51,7 @@ module CFTools::Tunnel
|
|
51
51
|
end
|
52
52
|
|
53
53
|
it "streams from each location" do
|
54
|
-
ssh =
|
54
|
+
ssh = double
|
55
55
|
|
56
56
|
locations = {
|
57
57
|
"1.2.3.4" => [
|
@@ -65,16 +65,32 @@ module CFTools::Tunnel
|
|
65
65
|
|
66
66
|
locations.each do |_, locs|
|
67
67
|
locs.each do |loc|
|
68
|
-
|
68
|
+
expect(loc).to receive(:stream_lines).with(ssh)
|
69
69
|
end
|
70
70
|
end
|
71
71
|
|
72
|
-
stub(
|
72
|
+
gateway.stub(:ssh).and_yield(ssh)
|
73
73
|
|
74
74
|
entries << nil
|
75
75
|
|
76
76
|
subject.stream(locations)
|
77
77
|
end
|
78
|
+
|
79
|
+
context "when streaming fails" do
|
80
|
+
it "retries" do
|
81
|
+
called = 0
|
82
|
+
subject.stub(:stream_location) do
|
83
|
+
called += 1
|
84
|
+
raise "boom" if called == 1
|
85
|
+
end
|
86
|
+
|
87
|
+
entries << nil
|
88
|
+
|
89
|
+
subject.stream("1.2.3.4" => [])
|
90
|
+
|
91
|
+
expect(called).to eq(2)
|
92
|
+
end
|
93
|
+
end
|
78
94
|
end
|
79
95
|
end
|
80
96
|
end
|
@@ -23,15 +23,15 @@ describe CFTools::Tunnel::StreamLocation do
|
|
23
23
|
end
|
24
24
|
|
25
25
|
describe "#stream_lines" do
|
26
|
-
let(:ssh) {
|
26
|
+
let(:ssh) { double }
|
27
27
|
|
28
28
|
it "tails the file under /var/vcap/sys/log" do
|
29
|
-
|
29
|
+
expect(ssh).to receive(:exec).with("tail -f /var/vcap/sys/log/#{path}")
|
30
30
|
subject.stream_lines(ssh)
|
31
31
|
end
|
32
32
|
|
33
33
|
it "yields log entries as lines come through the channel" do
|
34
|
-
stub(
|
34
|
+
ssh.stub(:exec).and_yield({}, :stdout, "foo\nbar\n")
|
35
35
|
|
36
36
|
lines = []
|
37
37
|
subject.stream_lines(ssh) do |entry|
|
@@ -43,10 +43,7 @@ describe CFTools::Tunnel::StreamLocation do
|
|
43
43
|
|
44
44
|
it "merges chunks that form a complete line" do
|
45
45
|
channel = {}
|
46
|
-
stub(
|
47
|
-
blk.call(channel, :stdout, "fo")
|
48
|
-
blk.call(channel, :stdout, "o\nbar\n")
|
49
|
-
end
|
46
|
+
ssh.stub(:exec).and_yield(channel, :stdout, "fo").and_yield(channel, :stdout, "o\nbar\n")
|
50
47
|
|
51
48
|
lines = []
|
52
49
|
subject.stream_lines(ssh) do |entry|
|
@@ -2,7 +2,7 @@ require "spec_helper"
|
|
2
2
|
|
3
3
|
module CFTools::Tunnel
|
4
4
|
describe TunnelNATS do
|
5
|
-
let(:director) {
|
5
|
+
let(:director) { double :director, :director_uri => "http://example.com" }
|
6
6
|
|
7
7
|
let(:deployments) do
|
8
8
|
[{ "name" => "some-deployment", "releases" => [{ "name" => "cf-release" }] }]
|
@@ -26,55 +26,46 @@ MANIFEST
|
|
26
26
|
|
27
27
|
let(:tunneled_port) { 65535 }
|
28
28
|
|
29
|
-
let(:initial_client) {
|
29
|
+
let(:initial_client) { double }
|
30
30
|
|
31
31
|
before do
|
32
|
-
stub(
|
32
|
+
initial_client.stub(:token => CFoundry::AuthToken.new("initial token"))
|
33
33
|
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
stub(cli).tunnel_to { tunneled_port }
|
38
|
-
end
|
34
|
+
described_class.any_instance.stub(:connected_director => director)
|
35
|
+
described_class.any_instance.stub(:client => initial_client)
|
36
|
+
described_class.any_instance.stub(:tunnel_to => tunneled_port)
|
39
37
|
|
40
|
-
|
41
|
-
stub(cf).login { CFoundry::AuthToken.new(nil) }
|
42
|
-
end
|
38
|
+
CFoundry::V2::Client.any_instance.stub(:login => CFoundry::AuthToken.new(nil))
|
43
39
|
|
44
|
-
stub(
|
45
|
-
stub(
|
40
|
+
director.stub(:list_deployments => deployments)
|
41
|
+
director.stub(:get_deployment => { "manifest" => deployment })
|
46
42
|
end
|
47
43
|
|
48
44
|
it "connects to the given director" do
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
director
|
53
|
-
end
|
54
|
-
end
|
45
|
+
expect_any_instance_of(described_class).to \
|
46
|
+
receive(:connected_director).with("some-director.com", "someuser@somehost.com").
|
47
|
+
and_return(director)
|
55
48
|
|
56
49
|
cf %W[tunnel-nats some-director.com help --gateway someuser@somehost.com]
|
57
50
|
end
|
58
51
|
|
59
52
|
it "tunnels to the NATS server through the director" do
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
end
|
64
|
-
end
|
53
|
+
expect_any_instance_of(described_class).to \
|
54
|
+
receive(:tunnel_to).with("1.2.3.4", 5678, "someuser@somehost.com").
|
55
|
+
and_return(tunneled_port)
|
65
56
|
|
66
57
|
cf %W[tunnel-nats some-director.com help --gateway someuser@somehost.com]
|
67
58
|
end
|
68
59
|
|
69
60
|
it "logs in as the admin user from the deployment" do
|
70
|
-
client =
|
71
|
-
stub(
|
61
|
+
client = double
|
62
|
+
client.stub(:token => CFoundry::AuthToken.new("bar"))
|
72
63
|
|
73
|
-
|
64
|
+
expect(CFoundry::V2::Client).to receive(:new).with("https://api.cf.museum") do
|
74
65
|
client
|
75
66
|
end
|
76
67
|
|
77
|
-
|
68
|
+
expect(client).to receive(:login).with("someadmin", "somepass") do
|
78
69
|
CFoundry::AuthToken.new("foo")
|
79
70
|
end
|
80
71
|
|
@@ -82,14 +73,20 @@ MANIFEST
|
|
82
73
|
end
|
83
74
|
|
84
75
|
it "invokes the given command with the NATS credentials" do
|
85
|
-
|
86
|
-
|
76
|
+
cmd = described_class.new
|
77
|
+
described_class.stub(:new => cmd)
|
78
|
+
|
79
|
+
cmd.stub(:execute).and_call_original
|
80
|
+
|
81
|
+
expect(cmd).to receive(:execute).with(Mothership.commands[:tunnel_nats], anything, anything)
|
82
|
+
|
83
|
+
expect(cmd).to receive(:execute).with(
|
87
84
|
Mothership.commands[:target],
|
88
85
|
%w[
|
89
86
|
some-arg --flag some-val --user natsuser
|
90
87
|
--password natspass --port 65535
|
91
88
|
],
|
92
|
-
|
89
|
+
anything)
|
93
90
|
|
94
91
|
cf %W[tunnel-nats some-director.com target some-arg --flag some-val]
|
95
92
|
end
|
@@ -6,7 +6,7 @@ module CFTools::Tunnel
|
|
6
6
|
|
7
7
|
let(:director) { Bosh::Cli::Director.new(director_uri) }
|
8
8
|
|
9
|
-
let(:stream) {
|
9
|
+
let(:stream) { double }
|
10
10
|
|
11
11
|
let(:vms) do
|
12
12
|
[ { "ips" => ["1.2.3.4"], "job_name" => "cloud_controller", "index" => 0 },
|
@@ -32,29 +32,29 @@ module CFTools::Tunnel
|
|
32
32
|
end
|
33
33
|
|
34
34
|
before do
|
35
|
-
stub(
|
36
|
-
stub(
|
37
|
-
|
35
|
+
director.stub(:list_deployments => deployments)
|
36
|
+
director.stub(:fetch_vm_state => vms)
|
37
|
+
described_class.any_instance.stub(:connected_director => director)
|
38
38
|
|
39
|
-
stub(stream)
|
40
|
-
|
39
|
+
stream.stub(:stream)
|
40
|
+
described_class.any_instance.stub(:stream_for => stream)
|
41
41
|
end
|
42
42
|
|
43
43
|
it "connects to the given director" do
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
44
|
+
expect_any_instance_of(described_class).to \
|
45
|
+
receive(:connected_director).with(
|
46
|
+
"some-director.com", "someuser@somehost.com").
|
47
|
+
and_return(director)
|
48
48
|
|
49
49
|
cf %W[watch-logs some-director.com --gateway someuser@somehost.com]
|
50
50
|
end
|
51
51
|
|
52
52
|
context "when no gateway user/host is specified" do
|
53
53
|
it "defaults to vcap@director" do
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
54
|
+
expect_any_instance_of(described_class).to \
|
55
|
+
receive(:connected_director).with(
|
56
|
+
"some-director.com", "vcap@some-director.com").
|
57
|
+
and_return(director)
|
58
58
|
|
59
59
|
cf %W[watch-logs some-director.com]
|
60
60
|
end
|
@@ -71,11 +71,10 @@ module CFTools::Tunnel
|
|
71
71
|
|
72
72
|
context "when there are jobs to log" do
|
73
73
|
it "streams their locations" do
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
end
|
74
|
+
expect(stream).to receive(:stream).with(hash_including(
|
75
|
+
["cloud_controller", 0] => anything,
|
76
|
+
["dea_next", 0] => anything,
|
77
|
+
["dea_next", 1] => anything))
|
79
78
|
|
80
79
|
cf %W[watch-logs some-director.com]
|
81
80
|
end
|
@@ -100,11 +99,7 @@ module CFTools::Tunnel
|
|
100
99
|
%Q[{"message":"c","timestamp":#{entry3_time.to_f},"log_level":"error"}],
|
101
100
|
:stdout)
|
102
101
|
|
103
|
-
|
104
|
-
blk.call(entry1)
|
105
|
-
blk.call(entry2)
|
106
|
-
blk.call(entry3)
|
107
|
-
end
|
102
|
+
expect(stream).to receive(:stream).and_yield(entry1).and_yield(entry2).and_yield(entry3)
|
108
103
|
|
109
104
|
cf %W[watch-logs some-director.com]
|
110
105
|
|
@@ -112,6 +107,13 @@ module CFTools::Tunnel
|
|
112
107
|
expect(output).to say("dea_next/1 01:02:04 AM warn b\n")
|
113
108
|
expect(output).to say("dea_next/0 01:02:05 AM error c\n")
|
114
109
|
end
|
110
|
+
|
111
|
+
context "and components were specified" do
|
112
|
+
it "streams their locations" do
|
113
|
+
expect(stream).to receive(:stream).with(["cloud_controller", 0] => anything)
|
114
|
+
cf %W[watch-logs some-director.com cloud_controller]
|
115
|
+
end
|
116
|
+
end
|
115
117
|
end
|
116
118
|
end
|
117
119
|
end
|