kontena-cli 1.0.6 → 1.1.0.pre1
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.
- checksums.yaml +4 -4
- data/Dockerfile +1 -1
- data/VERSION +1 -1
- data/bin/kontena +4 -1
- data/kontena-cli.gemspec +1 -1
- data/lib/kontena/callback.rb +1 -1
- data/lib/kontena/callbacks/master/01_clear_current_master_after_terminate.rb +1 -1
- data/lib/kontena/callbacks/master/deploy/50_authenticate_after_deploy.rb +5 -5
- data/lib/kontena/callbacks/master/deploy/55_create_initial_grid_after_deploy.rb +1 -1
- data/lib/kontena/callbacks/master/deploy/56_set_server_provider_after_deploy.rb +25 -0
- data/lib/kontena/callbacks/master/deploy/70_invite_self_after_deploy.rb +1 -1
- data/lib/kontena/cli/common.rb +3 -3
- data/lib/kontena/cli/config.rb +1 -1
- data/lib/kontena/cli/grid_command.rb +2 -0
- data/lib/kontena/cli/grids/common.rb +12 -0
- data/lib/kontena/cli/grids/health_command.rb +69 -0
- data/lib/kontena/cli/helpers/health_helper.rb +53 -0
- data/lib/kontena/cli/localhost_web_server.rb +3 -3
- data/lib/kontena/cli/master/users/invite_command.rb +1 -1
- data/lib/kontena/cli/node_command.rb +2 -0
- data/lib/kontena/cli/nodes/health_command.rb +32 -0
- data/lib/kontena/cli/nodes/list_command.rb +40 -26
- data/lib/kontena/cli/nodes/show_command.rb +0 -1
- data/lib/kontena/cli/plugins/install_command.rb +28 -30
- data/lib/kontena/cli/plugins/search_command.rb +6 -14
- data/lib/kontena/cli/plugins/uninstall_command.rb +7 -11
- data/lib/kontena/cli/services/stats_command.rb +4 -2
- data/lib/kontena/cli/spinner.rb +20 -4
- data/lib/kontena/cli/stacks/show_command.rb +5 -1
- data/lib/kontena/cli/stacks/yaml/opto/service_instances_resolver.rb +22 -0
- data/lib/kontena/cli/stacks/yaml/opto/vault_setter.rb +1 -1
- data/lib/kontena/cli/stacks/yaml/reader.rb +1 -0
- data/lib/kontena/cli/vault/export_command.rb +22 -0
- data/lib/kontena/cli/vault/import_command.rb +80 -0
- data/lib/kontena/cli/vault/list_command.rb +4 -0
- data/lib/kontena/cli/vault/read_command.rb +8 -3
- data/lib/kontena/cli/vault/remove_command.rb +2 -1
- data/lib/kontena/cli/vault/update_command.rb +5 -7
- data/lib/kontena/cli/vault_command.rb +5 -1
- data/lib/kontena/client.rb +25 -2
- data/lib/kontena/command.rb +1 -1
- data/lib/kontena/debug_instrumentor.rb +70 -0
- data/lib/kontena/light_prompt.rb +103 -0
- data/lib/kontena/plugin_manager.rb +167 -6
- data/lib/kontena/stacks_cache.rb +1 -1
- data/lib/kontena_cli.rb +23 -6
- data/spec/kontena/cli/grids/health_command_spec.rb +390 -0
- data/spec/kontena/cli/nodes/health_command_spec.rb +206 -0
- data/spec/kontena/cli/nodes/list_command_spec.rb +205 -0
- data/spec/kontena/cli/vault/export_spec.rb +32 -0
- data/spec/kontena/cli/vault/import_spec.rb +69 -0
- data/spec/kontena/client_spec.rb +39 -0
- data/spec/kontena/plugin_manager_spec.rb +7 -7
- data/spec/spec_helper.rb +1 -0
- data/spec/support/output_helpers.rb +51 -0
- metadata +27 -6
data/lib/kontena/stacks_cache.rb
CHANGED
data/lib/kontena_cli.rb
CHANGED
@@ -7,16 +7,16 @@ module Kontena
|
|
7
7
|
# @param [String] command_line
|
8
8
|
# @return [Fixnum] exit_code
|
9
9
|
def self.run(cmdline = "", returning: :status)
|
10
|
-
ENV["DEBUG"] && puts("Running Kontena.run(#{cmdline.inspect}, returning: #{returning}")
|
10
|
+
ENV["DEBUG"] && STDERR.puts("Running Kontena.run(#{cmdline.inspect}, returning: #{returning}")
|
11
11
|
result = Kontena::MainCommand.new(File.basename(__FILE__)).run(cmdline.shellsplit)
|
12
|
-
ENV["DEBUG"] && puts("Command completed, result: #{result.inspect} status: 0")
|
12
|
+
ENV["DEBUG"] && STDERR.puts("Command completed, result: #{result.inspect} status: 0")
|
13
13
|
return 0 if returning == :status
|
14
14
|
return result if returning == :result
|
15
15
|
rescue SystemExit
|
16
|
-
ENV["DEBUG"] && puts("Command completed with failure, result: #{result.inspect} status: #{$!.status}")
|
16
|
+
ENV["DEBUG"] && STDERR.puts("Command completed with failure, result: #{result.inspect} status: #{$!.status}")
|
17
17
|
returning == :status ? $!.status : nil
|
18
18
|
rescue
|
19
|
-
ENV["DEBUG"] && puts("Command raised #{$!} with message: #{$!.message}\n #{$!.backtrace.join(" \n")}")
|
19
|
+
ENV["DEBUG"] && STDERR.puts("Command raised #{$!} with message: #{$!.message}\n #{$!.backtrace.join(" \n")}")
|
20
20
|
returning == :status ? 1 : nil
|
21
21
|
end
|
22
22
|
|
@@ -25,12 +25,29 @@ module Kontena
|
|
25
25
|
"kontena-cli/#{Kontena::Cli::VERSION}"
|
26
26
|
end
|
27
27
|
|
28
|
+
def self.on_windows?
|
29
|
+
ENV['OS'] == 'Windows_NT' && RUBY_PLATFORM !~ /cygwin/
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.simple_terminal?
|
33
|
+
ENV['KONTENA_SIMPLE_TERM'] || !$stdout.tty?
|
34
|
+
end
|
35
|
+
|
28
36
|
def self.pastel
|
29
|
-
@pastel ||= Pastel.new(enabled:
|
37
|
+
@pastel ||= Pastel.new(enabled: !simple_terminal?)
|
30
38
|
end
|
31
39
|
|
32
40
|
def self.prompt
|
33
|
-
@prompt
|
41
|
+
return @prompt if @prompt
|
42
|
+
if simple_terminal?
|
43
|
+
require_relative 'kontena/light_prompt'
|
44
|
+
klass = Kontena::LightPrompt
|
45
|
+
else
|
46
|
+
require 'tty-prompt'
|
47
|
+
klass = TTY::Prompt
|
48
|
+
end
|
49
|
+
|
50
|
+
@prompt = klass.new(
|
34
51
|
active_color: :cyan,
|
35
52
|
help_color: :white,
|
36
53
|
error_color: :red,
|
@@ -0,0 +1,390 @@
|
|
1
|
+
require 'kontena/cli/grids/health_command'
|
2
|
+
|
3
|
+
describe Kontena::Cli::Grids::HealthCommand do
|
4
|
+
include ClientHelpers
|
5
|
+
include OutputHelpers
|
6
|
+
|
7
|
+
before do
|
8
|
+
allow(subject).to receive(:health_icon) {|health| health.inspect }
|
9
|
+
end
|
10
|
+
|
11
|
+
context "For a initial_size=1 grid" do
|
12
|
+
let :grid do
|
13
|
+
{
|
14
|
+
"id" => "test",
|
15
|
+
"name" => "test",
|
16
|
+
"initial_size" => 1,
|
17
|
+
"node_count" => 1,
|
18
|
+
}
|
19
|
+
end
|
20
|
+
|
21
|
+
context "without any nodes" do
|
22
|
+
let :grid_nodes do
|
23
|
+
{ "nodes" => [ ] }
|
24
|
+
end
|
25
|
+
|
26
|
+
describe '#grid_health' do
|
27
|
+
it "returns error" do
|
28
|
+
expect(subject.grid_health(grid, grid_nodes['nodes'])).to eq(:error)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
describe '#show_grid_health' do
|
33
|
+
it "returns false" do
|
34
|
+
expect{subject.show_grid_health(grid, grid_nodes['nodes'])}.to return_and_output false, [
|
35
|
+
":error Grid does not have any initial nodes, and requires at least 1 of 1 initial nodes for operation",
|
36
|
+
]
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
context "with a single offline node" do
|
42
|
+
let :grid_nodes do
|
43
|
+
{ "nodes" => [
|
44
|
+
{
|
45
|
+
"connected" => false,
|
46
|
+
"name" => "node-1",
|
47
|
+
"node_number" => 1,
|
48
|
+
"initial_member" => true,
|
49
|
+
},
|
50
|
+
] }
|
51
|
+
end
|
52
|
+
|
53
|
+
describe '#grid_health' do
|
54
|
+
it "returns error" do
|
55
|
+
expect(subject.grid_health(grid, grid_nodes['nodes'])).to eq(:error)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
describe '#show_grid_health' do
|
60
|
+
it "returns false" do
|
61
|
+
expect{subject.show_grid_health(grid, grid_nodes['nodes'])}.to return_and_output false, [
|
62
|
+
":error Grid does not have any initial nodes online, and requires at least 1 of 1 initial nodes for operation",
|
63
|
+
":error Initial node node-1 is offline",
|
64
|
+
]
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
context "with a single online node" do
|
70
|
+
let :grid_nodes do
|
71
|
+
{ "nodes" => [
|
72
|
+
{
|
73
|
+
"connected" => true,
|
74
|
+
"name" => "node-1",
|
75
|
+
"node_number" => 1,
|
76
|
+
"initial_member" => true,
|
77
|
+
},
|
78
|
+
] }
|
79
|
+
end
|
80
|
+
|
81
|
+
describe '#grid_health' do
|
82
|
+
it "returns ok" do
|
83
|
+
expect(subject.grid_health(grid, grid_nodes['nodes'])).to eq(:ok)
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
describe '#show_grid_health' do
|
88
|
+
it "returns true" do
|
89
|
+
expect{subject.show_grid_health(grid, grid_nodes['nodes'])}.to return_and_output true, [
|
90
|
+
":warning Grid only has 1 initial node, and is not high-availability"
|
91
|
+
]
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
context "For a initial_size=2 grid" do
|
98
|
+
let :grid do
|
99
|
+
{
|
100
|
+
"id" => "test",
|
101
|
+
"name" => "test",
|
102
|
+
"initial_size" => 2,
|
103
|
+
"node_count" => 1,
|
104
|
+
}
|
105
|
+
end
|
106
|
+
|
107
|
+
context "with a single online node" do
|
108
|
+
let :grid_nodes do
|
109
|
+
{ "nodes" => [
|
110
|
+
{
|
111
|
+
"connected" => true,
|
112
|
+
"name" => "node-1",
|
113
|
+
"node_number" => 1,
|
114
|
+
"initial_member" => true,
|
115
|
+
},
|
116
|
+
] }
|
117
|
+
end
|
118
|
+
|
119
|
+
describe '#grid_health' do
|
120
|
+
it "returns error" do
|
121
|
+
expect(subject.grid_health(grid, grid_nodes['nodes'])).to eq(:error)
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
describe '#show_grid_health' do
|
126
|
+
it "returns false" do
|
127
|
+
expect{subject.show_grid_health(grid, grid_nodes['nodes'])}.to return_and_output false, [
|
128
|
+
":error Grid only has 1 initial nodes, and requires at least 2 of 2 initial nodes for operation",
|
129
|
+
]
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
context "with two online nodes" do
|
135
|
+
let :grid_nodes do
|
136
|
+
{ "nodes" => [
|
137
|
+
{
|
138
|
+
"connected" => true,
|
139
|
+
"name" => "node-1",
|
140
|
+
"node_number" => 1,
|
141
|
+
"initial_member" => true,
|
142
|
+
},
|
143
|
+
{
|
144
|
+
"connected" => true,
|
145
|
+
"name" => "node-2",
|
146
|
+
"node_number" => 2,
|
147
|
+
"initial_member" => true,
|
148
|
+
},
|
149
|
+
] }
|
150
|
+
end
|
151
|
+
|
152
|
+
describe '#grid_health' do
|
153
|
+
it "returns ok" do
|
154
|
+
expect(subject.grid_health(grid, grid_nodes['nodes'])).to eq(:ok)
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
describe '#show_grid_health' do
|
159
|
+
it "returns true" do
|
160
|
+
expect{subject.show_grid_health(grid, grid_nodes['nodes'])}.to return_and_output true, [
|
161
|
+
":warning Grid only has 2 initial nodes, and is not high-availability",
|
162
|
+
]
|
163
|
+
end
|
164
|
+
end
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
context "For a initial_size=3 grid" do
|
169
|
+
let :grid do
|
170
|
+
{
|
171
|
+
"id" => "test",
|
172
|
+
"name" => "test",
|
173
|
+
"initial_size" => 3,
|
174
|
+
"node_count" => 1,
|
175
|
+
}
|
176
|
+
end
|
177
|
+
|
178
|
+
context "with a single node" do
|
179
|
+
let :grid_nodes do
|
180
|
+
{ "nodes" => [
|
181
|
+
{
|
182
|
+
"connected" => true,
|
183
|
+
"name" => "node-1",
|
184
|
+
"node_number" => 1,
|
185
|
+
"initial_member" => true,
|
186
|
+
},
|
187
|
+
] }
|
188
|
+
end
|
189
|
+
|
190
|
+
describe '#grid_health' do
|
191
|
+
it "returns error" do
|
192
|
+
expect(subject.grid_health(grid, grid_nodes['nodes'])).to eq(:error)
|
193
|
+
end
|
194
|
+
end
|
195
|
+
|
196
|
+
describe '#show_grid_health' do
|
197
|
+
it "returns false" do
|
198
|
+
expect{subject.show_grid_health(grid, grid_nodes['nodes'])}.to return_and_output false, [
|
199
|
+
":error Grid only has 1 initial nodes, and requires at least 2 of 3 initial nodes for operation",
|
200
|
+
]
|
201
|
+
end
|
202
|
+
end
|
203
|
+
end
|
204
|
+
|
205
|
+
context "with a single online node" do
|
206
|
+
let :grid_nodes do
|
207
|
+
{ "nodes" => [
|
208
|
+
{
|
209
|
+
"connected" => true,
|
210
|
+
"name" => "node-1",
|
211
|
+
"node_number" => 1,
|
212
|
+
"initial_member" => true,
|
213
|
+
},
|
214
|
+
{
|
215
|
+
"connected" => false,
|
216
|
+
"name" => "node-2",
|
217
|
+
"node_number" => 1,
|
218
|
+
"initial_member" => true,
|
219
|
+
},
|
220
|
+
] }
|
221
|
+
end
|
222
|
+
|
223
|
+
describe '#grid_health' do
|
224
|
+
it "returns error" do
|
225
|
+
expect(subject.grid_health(grid, grid_nodes['nodes'])).to eq(:error)
|
226
|
+
end
|
227
|
+
end
|
228
|
+
|
229
|
+
describe '#show_grid_health' do
|
230
|
+
it "returns false" do
|
231
|
+
expect{subject.show_grid_health(grid, grid_nodes['nodes'])}.to return_and_output false, [
|
232
|
+
":error Grid only has 1 initial nodes online, and requires at least 2 of 3 initial nodes for operation",
|
233
|
+
":error Initial node node-2 is offline",
|
234
|
+
]
|
235
|
+
end
|
236
|
+
end
|
237
|
+
end
|
238
|
+
|
239
|
+
context "with two online nodes" do
|
240
|
+
let :grid_nodes do
|
241
|
+
{ "nodes" => [
|
242
|
+
{
|
243
|
+
"connected" => true,
|
244
|
+
"name" => "node-1",
|
245
|
+
"node_number" => 1,
|
246
|
+
"initial_member" => true,
|
247
|
+
},
|
248
|
+
{
|
249
|
+
"connected" => true,
|
250
|
+
"name" => "node-2",
|
251
|
+
"node_number" => 2,
|
252
|
+
"initial_member" => true,
|
253
|
+
},
|
254
|
+
] }
|
255
|
+
end
|
256
|
+
|
257
|
+
describe '#grid_health' do
|
258
|
+
it "returns warning" do
|
259
|
+
expect(subject.grid_health(grid, grid_nodes['nodes'])).to eq(:warning)
|
260
|
+
end
|
261
|
+
end
|
262
|
+
|
263
|
+
describe '#show_grid_health' do
|
264
|
+
it "returns true" do
|
265
|
+
expect{subject.show_grid_health(grid, grid_nodes['nodes'])}.to return_and_output true, [
|
266
|
+
":warning Grid only has 2 initial nodes of 3 required for high-availability",
|
267
|
+
]
|
268
|
+
end
|
269
|
+
end
|
270
|
+
end
|
271
|
+
|
272
|
+
context "with two online nodes and one offline node" do
|
273
|
+
let :grid_nodes do
|
274
|
+
{ "nodes" => [
|
275
|
+
{
|
276
|
+
"connected" => true,
|
277
|
+
"name" => "node-1",
|
278
|
+
"node_number" => 1,
|
279
|
+
"initial_member" => true,
|
280
|
+
},
|
281
|
+
{
|
282
|
+
"connected" => true,
|
283
|
+
"name" => "node-2",
|
284
|
+
"node_number" => 2,
|
285
|
+
"initial_member" => true,
|
286
|
+
},
|
287
|
+
{
|
288
|
+
"connected" => false,
|
289
|
+
"name" => "node-3",
|
290
|
+
"node_number" => 3,
|
291
|
+
"initial_member" => true,
|
292
|
+
},
|
293
|
+
] }
|
294
|
+
end
|
295
|
+
|
296
|
+
describe '#grid_health' do
|
297
|
+
it "returns warning" do
|
298
|
+
expect(subject.grid_health(grid, grid_nodes['nodes'])).to eq(:warning)
|
299
|
+
end
|
300
|
+
end
|
301
|
+
|
302
|
+
describe '#show_grid_health' do
|
303
|
+
it "returns true" do
|
304
|
+
expect{subject.show_grid_health(grid, grid_nodes['nodes'])}.to return_and_output true, [
|
305
|
+
":warning Grid only has 2 initial nodes online of 3 required for high-availability",
|
306
|
+
":warning Initial node node-3 is offline",
|
307
|
+
]
|
308
|
+
end
|
309
|
+
end
|
310
|
+
end
|
311
|
+
|
312
|
+
context "with two online initial nodes and one non-initial node" do
|
313
|
+
let :grid_nodes do
|
314
|
+
{ "nodes" => [
|
315
|
+
{
|
316
|
+
"connected" => true,
|
317
|
+
"name" => "node-1",
|
318
|
+
"node_number" => 1,
|
319
|
+
"initial_member" => true,
|
320
|
+
},
|
321
|
+
{
|
322
|
+
"connected" => true,
|
323
|
+
"name" => "node-2",
|
324
|
+
"node_number" => 2,
|
325
|
+
"initial_member" => true,
|
326
|
+
},
|
327
|
+
{
|
328
|
+
"connected" => true,
|
329
|
+
"name" => "node-4",
|
330
|
+
"node_number" => 4,
|
331
|
+
"initial_member" => false,
|
332
|
+
},
|
333
|
+
] }
|
334
|
+
end
|
335
|
+
|
336
|
+
describe '#grid_health' do
|
337
|
+
it "returns warning" do
|
338
|
+
expect(subject.grid_health(grid, grid_nodes['nodes'])).to eq(:warning)
|
339
|
+
end
|
340
|
+
end
|
341
|
+
|
342
|
+
describe '#show_grid_health' do
|
343
|
+
it "returns true" do
|
344
|
+
expect{subject.show_grid_health(grid, grid_nodes['nodes'])}.to return_and_output true, [
|
345
|
+
":warning Grid only has 2 initial nodes of 3 required for high-availability",
|
346
|
+
]
|
347
|
+
end
|
348
|
+
end
|
349
|
+
end
|
350
|
+
|
351
|
+
context "with three online initial nodes" do
|
352
|
+
let :grid_nodes do
|
353
|
+
{ "nodes" => [
|
354
|
+
{
|
355
|
+
"connected" => true,
|
356
|
+
"name" => "node-1",
|
357
|
+
"node_number" => 1,
|
358
|
+
"initial_member" => true,
|
359
|
+
},
|
360
|
+
{
|
361
|
+
"connected" => true,
|
362
|
+
"name" => "node-2",
|
363
|
+
"node_number" => 2,
|
364
|
+
"initial_member" => true,
|
365
|
+
},
|
366
|
+
{
|
367
|
+
"connected" => true,
|
368
|
+
"name" => "node-3",
|
369
|
+
"node_number" => 3,
|
370
|
+
"initial_member" => true,
|
371
|
+
},
|
372
|
+
] }
|
373
|
+
end
|
374
|
+
|
375
|
+
describe '#grid_health' do
|
376
|
+
it "returns ok" do
|
377
|
+
expect(subject.grid_health(grid, grid_nodes['nodes'])).to eq(:ok)
|
378
|
+
end
|
379
|
+
end
|
380
|
+
|
381
|
+
describe '#show_grid_health' do
|
382
|
+
it "returns true" do
|
383
|
+
expect{subject.show_grid_health(grid, grid_nodes['nodes'])}.to return_and_output true, [
|
384
|
+
":ok Grid has all 3 of 3 initial nodes online",
|
385
|
+
]
|
386
|
+
end
|
387
|
+
end
|
388
|
+
end
|
389
|
+
end
|
390
|
+
end
|