console-vmc-plugin 0.1.0 → 0.1.1
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/console-vmc-plugin/console.rb +2 -7
- data/lib/console-vmc-plugin/plugin.rb +1 -2
- data/lib/console-vmc-plugin/version.rb +1 -1
- data/spec/console_spec.rb +138 -153
- metadata +3 -3
|
@@ -5,11 +5,10 @@ require "tunnel-vmc-plugin/tunnel"
|
|
|
5
5
|
|
|
6
6
|
|
|
7
7
|
class CFConsole < CFTunnel
|
|
8
|
-
def initialize(client, app, port = 10000
|
|
8
|
+
def initialize(client, app, port = 10000)
|
|
9
9
|
@client = client
|
|
10
10
|
@app = app
|
|
11
11
|
@port = port
|
|
12
|
-
@v2 = v2
|
|
13
12
|
end
|
|
14
13
|
|
|
15
14
|
def get_connection_info(auth)
|
|
@@ -28,11 +27,7 @@ class CFConsole < CFTunnel
|
|
|
28
27
|
end
|
|
29
28
|
|
|
30
29
|
def get_credentials
|
|
31
|
-
|
|
32
|
-
YAML.load(@app.file("cf-rails-console", ".consoleaccess"))
|
|
33
|
-
else
|
|
34
|
-
YAML.load(@app.file("app", "cf-rails-console", ".consoleaccess"))
|
|
35
|
-
end
|
|
30
|
+
YAML.load(@app.file("app", "cf-rails-console", ".consoleaccess"))
|
|
36
31
|
end
|
|
37
32
|
|
|
38
33
|
def start_console
|
|
@@ -11,7 +11,7 @@ module VMCConsole
|
|
|
11
11
|
def console
|
|
12
12
|
app = input[:app]
|
|
13
13
|
|
|
14
|
-
console = CFConsole.new(client, app
|
|
14
|
+
console = CFConsole.new(client, app)
|
|
15
15
|
port = console.pick_port!(input[:port])
|
|
16
16
|
|
|
17
17
|
with_progress("Opening console on port #{c(port, :name)}") do
|
|
@@ -24,7 +24,6 @@ module VMCConsole
|
|
|
24
24
|
|
|
25
25
|
filter(:start, :start_app) do |app|
|
|
26
26
|
if app.framework.name == "rails3" || app.framework.name == "buildpack"
|
|
27
|
-
puts "Setting console to true"
|
|
28
27
|
app.console = true
|
|
29
28
|
end
|
|
30
29
|
|
data/spec/console_spec.rb
CHANGED
|
@@ -2,198 +2,183 @@ require "spec_helper"
|
|
|
2
2
|
require "console-vmc-plugin/plugin"
|
|
3
3
|
|
|
4
4
|
describe "CFConsole" do
|
|
5
|
+
before do
|
|
6
|
+
@app = mock("app")
|
|
7
|
+
@console = CFConsole.new(nil, @app)
|
|
8
|
+
end
|
|
5
9
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
end
|
|
10
|
+
it "should return connection info for apps that have a console ip and port" do
|
|
11
|
+
instance = mock("instance")
|
|
12
|
+
mock(@app).instances { [instance] }
|
|
13
|
+
mock(instance).console { {:ip => "192.168.1.1", :port => 3344} }
|
|
11
14
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
15
|
+
@console.get_connection_info(nil).should == {
|
|
16
|
+
"hostname" => "192.168.1.1",
|
|
17
|
+
"port" => 3344
|
|
18
|
+
}
|
|
19
|
+
end
|
|
16
20
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
21
|
+
it "should raise error when no app instances found" do
|
|
22
|
+
mock(@app).instances { [] }
|
|
23
|
+
|
|
24
|
+
expect {
|
|
25
|
+
@console.get_connection_info(nil)
|
|
26
|
+
}.to raise_error("App has no running instances; try starting it.")
|
|
27
|
+
end
|
|
22
28
|
|
|
23
|
-
|
|
24
|
-
|
|
29
|
+
it "should raise error when app does not have console access" do
|
|
30
|
+
instance = mock("instance")
|
|
31
|
+
mock(@app).instances { [instance] }
|
|
32
|
+
mock(instance).console { nil }
|
|
33
|
+
|
|
34
|
+
expect {
|
|
35
|
+
@console.get_connection_info(nil)
|
|
36
|
+
}.to raise_error("App does not have console access; try restarting it.")
|
|
37
|
+
end
|
|
25
38
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
39
|
+
describe "start_console" do
|
|
40
|
+
before do
|
|
41
|
+
@creds = {
|
|
42
|
+
:path => %w(app cf-rails-console .consoleaccess),
|
|
43
|
+
:yaml => "username: cfuser\npassword: testpw",
|
|
44
|
+
:telnet => {"Name" => "cfuser", "Password" => "testpw"}
|
|
45
|
+
}
|
|
29
46
|
end
|
|
30
47
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
mock(instance).console { nil }
|
|
48
|
+
context "when console credentials cannot be obtained" do
|
|
49
|
+
it "should raise error" do
|
|
50
|
+
mock(@app).file(*@creds[:path]) { "username: cfuser" }
|
|
35
51
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
52
|
+
expect {
|
|
53
|
+
@console.start_console
|
|
54
|
+
}.to raise_error("Unable to verify console credentials.")
|
|
55
|
+
end
|
|
39
56
|
end
|
|
40
57
|
|
|
41
|
-
|
|
58
|
+
context "when console credentials can be obtained" do
|
|
42
59
|
before do
|
|
43
|
-
@creds
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
:telnet => {"Name" => "cfuser", "Password" => "testpw"}
|
|
47
|
-
}
|
|
60
|
+
mock(@app).file(*@creds[:path]) { @creds[:yaml] }
|
|
61
|
+
@telnet = Object.new
|
|
62
|
+
mock(@console).telnet_client { @telnet }
|
|
48
63
|
end
|
|
49
64
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
65
|
+
it "should raise error if authentication fails" do
|
|
66
|
+
mock(@telnet).login(@creds[:telnet]) { "Login failed" }
|
|
67
|
+
mock(@telnet).close
|
|
53
68
|
|
|
54
|
-
|
|
55
|
-
@console.start_console
|
|
56
|
-
}.to raise_error("Unable to verify console credentials.")
|
|
57
|
-
end
|
|
69
|
+
expect { @console.start_console }.to raise_error("Login failed")
|
|
58
70
|
end
|
|
59
71
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
mock(@console).telnet_client { @telnet }
|
|
65
|
-
end
|
|
66
|
-
|
|
67
|
-
it "should raise error if authentication fails" do
|
|
68
|
-
mock(@telnet).login(@creds[:telnet]) { "Login failed" }
|
|
69
|
-
mock(@telnet).close
|
|
72
|
+
it "should retry authentication on timeout" do
|
|
73
|
+
mock(@telnet).login(@creds[:telnet]){ raise TimeoutError }
|
|
74
|
+
mock(@telnet).login(@creds[:telnet]) { "Switch to inspect mode\nirb():001:0> " }
|
|
75
|
+
verify_console_exit("irb():001:0> ")
|
|
70
76
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
it "should retry authentication on timeout" do
|
|
75
|
-
mock(@telnet).login(@creds[:telnet]) { raise TimeoutError }
|
|
76
|
-
mock(@telnet).login(@creds[:telnet]) { "Switch to inspect mode\nirb():001:0> " }
|
|
77
|
-
verify_console_exit("irb():001:0> ")
|
|
77
|
+
@console.start_console
|
|
78
|
+
end
|
|
78
79
|
|
|
79
|
-
|
|
80
|
-
|
|
80
|
+
it "should retry authentication on EOF" do
|
|
81
|
+
mock(@console).telnet_client { @telnet }
|
|
82
|
+
mock(@telnet).login(@creds[:telnet]) { raise EOFError }
|
|
83
|
+
mock(@telnet).close
|
|
84
|
+
mock(@telnet).login(@creds[:telnet]) { "irb():001:0> " }
|
|
85
|
+
verify_console_exit("irb():001:0> ")
|
|
81
86
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
mock(@telnet).login(@creds[:telnet]) { raise EOFError }
|
|
85
|
-
mock(@telnet).close
|
|
86
|
-
mock(@telnet).login(@creds[:telnet]) { "irb():001:0> " }
|
|
87
|
-
verify_console_exit("irb():001:0> ")
|
|
87
|
+
@console.start_console
|
|
88
|
+
end
|
|
88
89
|
|
|
89
|
-
|
|
90
|
-
|
|
90
|
+
it "should operate console interactively" do
|
|
91
|
+
mock(@telnet).login(@creds[:telnet]) { "irb():001:0> " }
|
|
92
|
+
mock(Readline).readline("irb():001:0> ") { "puts 'hi'" }
|
|
93
|
+
mock(Readline::HISTORY).push("puts 'hi'")
|
|
94
|
+
mock(@telnet).cmd("puts 'hi'") { "nil" + "\n" + "irb():002:0> " }
|
|
95
|
+
mock(@console).puts("nil")
|
|
96
|
+
verify_console_exit("irb():002:0> ")
|
|
91
97
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
mock(Readline).readline("irb():001:0> ") { "puts 'hi'" }
|
|
95
|
-
mock(Readline::HISTORY).push("puts 'hi'")
|
|
96
|
-
mock(@telnet).cmd("puts 'hi'") { "nil" + "\n" + "irb():002:0> " }
|
|
97
|
-
mock(@console).puts("nil")
|
|
98
|
-
verify_console_exit("irb():002:0> ")
|
|
98
|
+
@console.start_console
|
|
99
|
+
end
|
|
99
100
|
|
|
100
|
-
|
|
101
|
-
|
|
101
|
+
it "should not crash if command times out" do
|
|
102
|
+
mock(@telnet).login(@creds[:telnet]) { "irb():001:0> " }
|
|
103
|
+
mock(Readline).readline("irb():001:0> ") { "puts 'hi'" }
|
|
104
|
+
mock(Readline::HISTORY).push("puts 'hi'")
|
|
105
|
+
mock(@telnet).cmd("puts 'hi'") { raise TimeoutError }
|
|
106
|
+
mock(@console).puts("Timed out sending command to server.")
|
|
107
|
+
verify_console_exit("irb():001:0> ")
|
|
102
108
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
mock(Readline).readline("irb():001:0> ") { "puts 'hi'" }
|
|
106
|
-
mock(Readline::HISTORY).push("puts 'hi'")
|
|
107
|
-
mock(@telnet).cmd("puts 'hi'") { raise TimeoutError }
|
|
108
|
-
mock(@console).puts("Timed out sending command to server.")
|
|
109
|
-
verify_console_exit("irb():001:0> ")
|
|
109
|
+
@console.start_console
|
|
110
|
+
end
|
|
110
111
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
mock(Readline).readline("irb():001:0> ") { "puts 'hi'" }
|
|
117
|
-
mock(Readline::HISTORY).push("puts 'hi'")
|
|
118
|
-
mock(@telnet).cmd("puts 'hi'") { raise EOFError }
|
|
119
|
-
|
|
120
|
-
expect {
|
|
121
|
-
@console.start_console
|
|
122
|
-
}.to raise_error("The console connection has been terminated. Perhaps the app was stopped or deleted?")
|
|
123
|
-
end
|
|
124
|
-
|
|
125
|
-
it "should not keep blank lines in history" do
|
|
126
|
-
mock(@telnet).login(@creds[:telnet]) { "irb():001:0> " }
|
|
127
|
-
mock(Readline).readline("irb():001:0> ") { "" }
|
|
128
|
-
dont_allow(Readline::HISTORY).push("")
|
|
129
|
-
mock(@telnet).cmd("") { "irb():002:0*> " }
|
|
130
|
-
verify_console_exit("irb():002:0*> ")
|
|
112
|
+
it "should raise error if an EOF is received" do
|
|
113
|
+
mock(@telnet).login(@creds[:telnet]) { "Switch to inspect mode\nirb():001:0> " }
|
|
114
|
+
mock(Readline).readline("irb():001:0> ") { "puts 'hi'" }
|
|
115
|
+
mock(Readline::HISTORY).push("puts 'hi'")
|
|
116
|
+
mock(@telnet).cmd("puts 'hi'") { raise EOFError }
|
|
131
117
|
|
|
118
|
+
expect {
|
|
132
119
|
@console.start_console
|
|
133
|
-
|
|
120
|
+
}.to raise_error("The console connection has been terminated. Perhaps the app was stopped or deleted?")
|
|
121
|
+
end
|
|
134
122
|
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
mock(@console).puts("nil")
|
|
142
|
-
verify_console_exit("irb():002:0> ")
|
|
123
|
+
it "should not keep blank lines in history" do
|
|
124
|
+
mock(@telnet).login(@creds[:telnet]) { "irb():001:0> " }
|
|
125
|
+
mock(Readline).readline("irb():001:0> ") { "" }
|
|
126
|
+
dont_allow(Readline::HISTORY).push("")
|
|
127
|
+
mock(@telnet).cmd("") { "irb():002:0*> " }
|
|
128
|
+
verify_console_exit("irb():002:0*> ")
|
|
143
129
|
|
|
144
|
-
|
|
145
|
-
|
|
130
|
+
@console.start_console
|
|
131
|
+
end
|
|
146
132
|
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
133
|
+
it "should not keep identical commands in history" do
|
|
134
|
+
mock(@telnet).login(@creds[:telnet]) { "irb():001:0> " }
|
|
135
|
+
mock(Readline).readline("irb():001:0> ") { "puts 'hi'" }
|
|
136
|
+
mock(Readline::HISTORY).to_a { ["puts 'hi'"] }
|
|
137
|
+
dont_allow(Readline::HISTORY).push("puts 'hi'")
|
|
138
|
+
mock(@telnet).cmd("puts 'hi'") { "nil" + "\n" + "irb():002:0> " }
|
|
139
|
+
mock(@console).puts("nil")
|
|
140
|
+
verify_console_exit("irb():002:0> ")
|
|
151
141
|
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
end
|
|
142
|
+
@console.start_console
|
|
143
|
+
end
|
|
155
144
|
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
145
|
+
it "should return tab completion data" do
|
|
146
|
+
mock(@telnet).login(@creds[:telnet]) { "Switch to inspect mode\nirb():001:0> " }
|
|
147
|
+
mock(@telnet).cmd("String" => "app.\t", "Match" => /\S*\n$/, "Timeout" => 10) { "to_s,nil?\n" }
|
|
148
|
+
verify_console_exit("irb():001:0> ")
|
|
160
149
|
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
150
|
+
@console.start_console
|
|
151
|
+
Readline.completion_proc.call("app.").should == ["to_s","nil?"]
|
|
152
|
+
end
|
|
164
153
|
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
154
|
+
it "should return tab completion data receiving empty completion string" do
|
|
155
|
+
mock(@telnet).login(@creds[:telnet]) { "irb():001:0> " }
|
|
156
|
+
mock(@telnet).cmd("String" => "app.\t", "Match" => /\S*\n$/, "Timeout" => 10) { "\n" }
|
|
157
|
+
verify_console_exit("irb():001:0> ")
|
|
169
158
|
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
159
|
+
@console.start_console
|
|
160
|
+
Readline.completion_proc.call("app.").should == []
|
|
161
|
+
end
|
|
173
162
|
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
mock(Readline).completion_append_character=(nil)
|
|
179
|
-
mock(Readline).completion_proc=(anything)
|
|
180
|
-
verify_console_exit("irb():001:0> ")
|
|
163
|
+
it "should not crash on timeout of remote tab completion data" do
|
|
164
|
+
mock(@telnet).login(@creds[:telnet]) { "Switch to inspect mode\nirb():001:0> " }
|
|
165
|
+
mock(@telnet).cmd("String" => "app.\t", "Match" => /\S*\n$/, "Timeout" => 10) { raise TimeoutError }
|
|
166
|
+
verify_console_exit("irb():001:0> ")
|
|
181
167
|
|
|
182
|
-
|
|
183
|
-
|
|
168
|
+
@console.start_console
|
|
169
|
+
Readline.completion_proc.call("app.").should == []
|
|
184
170
|
end
|
|
185
|
-
end
|
|
186
|
-
end
|
|
187
171
|
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
172
|
+
it "should properly initialize Readline for tab completion" do
|
|
173
|
+
mock(@telnet).login(@creds[:telnet]) { "irb():001:0> " }
|
|
174
|
+
mock(Readline).respond_to?("basic_word_break_characters=") { true }
|
|
175
|
+
mock(Readline).basic_word_break_characters=(" \t\n`><=;|&{(")
|
|
176
|
+
mock(Readline).completion_append_character=(nil)
|
|
177
|
+
mock(Readline).completion_proc=(anything)
|
|
178
|
+
verify_console_exit("irb():001:0> ")
|
|
193
179
|
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
@console.get_credentials
|
|
180
|
+
@console.start_console
|
|
181
|
+
end
|
|
197
182
|
end
|
|
198
183
|
end
|
|
199
184
|
|
metadata
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: console-vmc-plugin
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
hash:
|
|
4
|
+
hash: 25
|
|
5
5
|
prerelease:
|
|
6
6
|
segments:
|
|
7
7
|
- 0
|
|
8
8
|
- 1
|
|
9
|
-
-
|
|
10
|
-
version: 0.1.
|
|
9
|
+
- 1
|
|
10
|
+
version: 0.1.1
|
|
11
11
|
platform: ruby
|
|
12
12
|
authors:
|
|
13
13
|
- Alex Suraci
|