kontena-cli 1.4.0 → 1.4.1.pre1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/VERSION +1 -1
- data/bin/kontena +2 -1
- data/kontena-cli.gemspec +1 -1
- data/lib/kontena/cli/certificate/common.rb +16 -0
- data/lib/kontena/cli/certificate/export_command.rb +28 -0
- data/lib/kontena/cli/certificate/import_command.rb +61 -0
- data/lib/kontena/cli/certificate/show_command.rb +5 -2
- data/lib/kontena/cli/certificate_command.rb +3 -1
- data/lib/kontena/cli/common.rb +5 -1
- data/lib/kontena/cli/config.rb +23 -5
- data/lib/kontena/cli/external_registries/add_command.rb +2 -0
- data/lib/kontena/cli/external_registries/list_command.rb +1 -1
- data/lib/kontena/cli/helpers/exec_helper.rb +12 -4
- data/lib/kontena/cli/master/config/import_command.rb +1 -1
- data/lib/kontena/cli/master/login_command.rb +1 -1
- data/lib/kontena/cli/stacks/common.rb +2 -1
- data/lib/kontena/cli/stacks/registry/show_command.rb +1 -1
- data/lib/kontena/cli/stacks/service_generator.rb +1 -0
- data/lib/kontena/cli/stacks/yaml/opto.rb +1 -0
- data/lib/kontena/cli/stacks/yaml/opto/certificates_resolver.rb +37 -0
- data/lib/kontena/cli/stacks/yaml/opto/vault_cert_prompt_resolver.rb +1 -1
- data/lib/kontena/cli/stacks/yaml/reader.rb +5 -2
- data/lib/kontena/cli/stacks/yaml/validations.rb +2 -1
- data/lib/kontena/cli/vault/import_command.rb +1 -1
- data/lib/kontena/client.rb +1 -1
- data/lib/kontena/command.rb +7 -5
- data/lib/kontena/plugin_manager.rb +1 -1
- data/lib/kontena/plugin_manager/cleaner.rb +1 -1
- data/lib/kontena/scripts/completer.rb +1 -1
- data/lib/kontena/stacks_cache.rb +2 -2
- data/lib/kontena_cli.rb +6 -2
- data/spec/fixtures/certificates/test/ca-key.pem +10 -0
- data/spec/fixtures/certificates/test/ca.pem +10 -0
- data/spec/fixtures/certificates/test/ca.srl +1 -0
- data/spec/fixtures/certificates/test/cert.pem +8 -0
- data/spec/fixtures/certificates/test/csr.pem +7 -0
- data/spec/fixtures/certificates/test/key.pem +10 -0
- data/spec/fixtures/certificates/test/real-cert.pem +30 -0
- data/spec/fixtures/docker-compose_v2.yml +1 -0
- data/spec/fixtures/docker-compose_v2_with_variables.yml +12 -0
- data/spec/fixtures/kontena_v3_with_compose_variables.yml +11 -0
- data/spec/fixtures/stack-with-anchors.yml +13 -0
- data/spec/kontena/cli/certificates/export_command_spec.rb +49 -0
- data/spec/kontena/cli/certificates/import_command_spec.rb +70 -0
- data/spec/kontena/cli/certificates/show_command_spec.rb +57 -0
- data/spec/kontena/cli/cloud/login_command_spec.rb +7 -14
- data/spec/kontena/cli/helpers/exec_helper_spec.rb +38 -0
- data/spec/kontena/cli/master/login_command_spec.rb +12 -24
- data/spec/kontena/cli/master/use_command_spec.rb +1 -1
- data/spec/kontena/cli/nodes/remove_command_spec.rb +1 -1
- data/spec/kontena/cli/registry/{create_spec.rb → create_command_spec.rb} +0 -0
- data/spec/kontena/cli/stacks/upgrade_command_spec.rb +1 -1
- data/spec/kontena/cli/stacks/yaml/opto/certificates_resolver_spec.rb +81 -0
- data/spec/kontena/cli/stacks/yaml/reader_spec.rb +22 -2
- data/spec/kontena/cli/stacks/yaml/validator_v3_spec.rb +17 -0
- data/spec/kontena/command_spec.rb +54 -0
- data/spec/kontena/config_spec.rb +17 -2
- data/spec/kontena/main_command_spec.rb +13 -0
- data/spec/spec_helper.rb +10 -17
- metadata +43 -11
- data/spec/kontena/cli/main_command_spec.rb +0 -19
@@ -20,18 +20,15 @@ describe Kontena::Cli::Cloud::LoginCommand do
|
|
20
20
|
end
|
21
21
|
|
22
22
|
it 'should give error if trying to use --code and --force' do
|
23
|
-
expect(
|
24
|
-
subject.run(['--code', 'abcd', '--force'])
|
23
|
+
expect{subject.run(['--code', 'abcd', '--force'])}.to exit_with_error
|
25
24
|
end
|
26
25
|
|
27
26
|
it 'should give error if trying to use --token and --force' do
|
28
|
-
expect(
|
29
|
-
subject.run(['--token', 'abcd', '--force'])
|
27
|
+
expect{subject.run(['--token', 'abcd', '--force'])}.to exit_with_error
|
30
28
|
end
|
31
29
|
|
32
30
|
it 'should give error if trying to use --token and --code' do
|
33
|
-
expect(
|
34
|
-
subject.run(['--token', 'abcd', '--code', 'defg'])
|
31
|
+
expect{subject.run(['--token', 'abcd', '--code', 'defg'])}.to exit_with_error
|
35
32
|
end
|
36
33
|
|
37
34
|
context 'when config has token' do
|
@@ -180,8 +177,7 @@ describe Kontena::Cli::Cloud::LoginCommand do
|
|
180
177
|
'error' => 'foo'
|
181
178
|
})
|
182
179
|
expect(Launchy).to receive(:open).and_return(true)
|
183
|
-
expect(
|
184
|
-
subject.run([])
|
180
|
+
expect{subject.run([])}.to exit_with_error.and output(/Authentication failed: foo/).to_stderr
|
185
181
|
end
|
186
182
|
end
|
187
183
|
end
|
@@ -283,14 +279,12 @@ describe Kontena::Cli::Cloud::LoginCommand do
|
|
283
279
|
|
284
280
|
it 'should exit with error if cloud responds with error' do
|
285
281
|
expect(client).to receive(:get).and_return('error' => 'foo')
|
286
|
-
expect
|
287
|
-
subject.update_userinfo
|
282
|
+
expect{subject.update_userinfo}.to exit_with_error
|
288
283
|
end
|
289
284
|
|
290
285
|
it 'should exit with error if cloud responds with something silly' do
|
291
286
|
expect(client).to receive(:get).and_return('foo')
|
292
|
-
expect
|
293
|
-
subject.update_userinfo
|
287
|
+
expect{subject.update_userinfo}.to exit_with_error
|
294
288
|
end
|
295
289
|
end
|
296
290
|
|
@@ -313,8 +307,7 @@ describe Kontena::Cli::Cloud::LoginCommand do
|
|
313
307
|
end
|
314
308
|
|
315
309
|
it 'should give error when response has error' do
|
316
|
-
expect(
|
317
|
-
subject.update_token('error' => 'fail!')
|
310
|
+
expect{subject.update_token('error' => 'fail!')}.to exit_with_error
|
318
311
|
end
|
319
312
|
|
320
313
|
it 'should raise if response is not a hash' do
|
@@ -57,6 +57,44 @@ describe Kontena::Cli::Helpers::ExecHelper do
|
|
57
57
|
"\n",
|
58
58
|
).and raise_error(EOFError)
|
59
59
|
end
|
60
|
+
|
61
|
+
it 'yields chunks of UTF-8 input that are JSON-encodable' do
|
62
|
+
data = "f\u00e5\u00e5".encode('UTF-8').force_encoding('ASCII-8BIT')
|
63
|
+
|
64
|
+
expect(stdin_raw).to receive(:readpartial).and_return(data[0..2])
|
65
|
+
expect(stdin_raw).to receive(:readpartial).and_return(data[3..4])
|
66
|
+
expect(stdin_raw).to receive(:readpartial).and_raise(EOFError)
|
67
|
+
|
68
|
+
chunks = []
|
69
|
+
|
70
|
+
expect{subject.read_stdin(tty: true) do |chunk|
|
71
|
+
chunks << JSON.dump('stdin' => chunk)
|
72
|
+
end}.to raise_error(EOFError)
|
73
|
+
|
74
|
+
expect(chunks).to eq [
|
75
|
+
'{"stdin":"f' + "\u00e5" + '"}',
|
76
|
+
'{"stdin":"' + "\u00e5" + '"}',
|
77
|
+
]
|
78
|
+
end
|
79
|
+
|
80
|
+
it 'yields tty control characters that are JSON-encodable' do
|
81
|
+
data = "\x03\x04".force_encoding('ASCII-8BIT')
|
82
|
+
|
83
|
+
expect(stdin_raw).to receive(:readpartial).and_return(data[0])
|
84
|
+
expect(stdin_raw).to receive(:readpartial).and_return(data[1])
|
85
|
+
expect(stdin_raw).to receive(:readpartial).and_raise(EOFError)
|
86
|
+
|
87
|
+
chunks = []
|
88
|
+
|
89
|
+
expect{subject.read_stdin(tty: true) do |chunk|
|
90
|
+
chunks << JSON.dump('stdin' => chunk)
|
91
|
+
end}.to raise_error(EOFError)
|
92
|
+
|
93
|
+
expect(chunks).to eq [
|
94
|
+
'{"stdin":"\\u0003"}',
|
95
|
+
'{"stdin":"\\u0004"}',
|
96
|
+
]
|
97
|
+
end
|
60
98
|
end
|
61
99
|
end
|
62
100
|
|
@@ -14,23 +14,19 @@ describe Kontena::Cli::Master::LoginCommand do
|
|
14
14
|
let(:client) { double(:client) }
|
15
15
|
|
16
16
|
it 'should exit with error if --code and --token both given' do
|
17
|
-
expect(
|
18
|
-
subject.run(%w(--code abcd --token defg))
|
17
|
+
expect{subject.run(%w(--code abcd --token defg))}.to exit_with_error
|
19
18
|
end
|
20
19
|
|
21
20
|
it 'should exit with error if --code and --join both given' do
|
22
|
-
expect(
|
23
|
-
subject.run(%w(--code abcd --join defg))
|
21
|
+
expect{subject.run(%w(--code abcd --join defg))}.to exit_with_error
|
24
22
|
end
|
25
23
|
|
26
24
|
it 'should exit with error if --code and --force both given' do
|
27
|
-
expect(
|
28
|
-
subject.run(%w(--code abcd --force))
|
25
|
+
expect{subject.run(%w(--code abcd --force))}.to exit_with_error
|
29
26
|
end
|
30
27
|
|
31
28
|
it 'should exit with error if --token and --force both given' do
|
32
|
-
expect(
|
33
|
-
subject.run(%w(--token abcd --force))
|
29
|
+
expect{subject.run(%w(--token abcd --force))}.to exit_with_error
|
34
30
|
end
|
35
31
|
|
36
32
|
describe '#select_a_server' do
|
@@ -49,8 +45,7 @@ describe Kontena::Cli::Master::LoginCommand do
|
|
49
45
|
|
50
46
|
it 'exits with error if current_master not set' do
|
51
47
|
expect(config).to receive(:current_master).and_return(nil)
|
52
|
-
expect(
|
53
|
-
subject.select_a_server(nil, nil)
|
48
|
+
expect{subject.select_a_server(nil, nil)}.to exit_with_error
|
54
49
|
end
|
55
50
|
end
|
56
51
|
|
@@ -88,8 +83,7 @@ describe Kontena::Cli::Master::LoginCommand do
|
|
88
83
|
it 'should exit with error if a server with that name is found but it does not have an url' do
|
89
84
|
server.url = nil
|
90
85
|
expect(config).to receive(:find_server).with('foo').and_return(server)
|
91
|
-
expect(
|
92
|
-
subject.select_a_server('foo', nil)
|
86
|
+
expect{subject.select_a_server('foo', nil)}.to exit_with_error
|
93
87
|
end
|
94
88
|
end
|
95
89
|
end
|
@@ -119,14 +113,12 @@ describe Kontena::Cli::Master::LoginCommand do
|
|
119
113
|
it 'should exit with error if a server with that name is found but it does not have an url' do
|
120
114
|
server.url = nil
|
121
115
|
expect(config).to receive(:find_server).with('foo').and_return(server)
|
122
|
-
expect(
|
123
|
-
subject.select_a_server(nil, 'foo')
|
116
|
+
expect{subject.select_a_server(nil, 'foo')}.to exit_with_error
|
124
117
|
end
|
125
118
|
|
126
119
|
it 'should exit with error if a server with that name is not found' do
|
127
120
|
expect(config).to receive(:find_server).with('foo').and_return(nil)
|
128
|
-
expect(
|
129
|
-
subject.select_a_server(nil, 'foo')
|
121
|
+
expect{subject.select_a_server(nil, 'foo')}.to exit_with_error
|
130
122
|
end
|
131
123
|
end
|
132
124
|
end
|
@@ -350,24 +342,21 @@ describe Kontena::Cli::Master::LoginCommand do
|
|
350
342
|
allow(Kontena::Client).to receive(:new).and_return(client)
|
351
343
|
expect(client).to receive(:last_response).at_least(:once).and_return(OpenStruct.new(status: 400, headers: {}))
|
352
344
|
expect(client).to receive(:request).and_return('error' => 'no good')
|
353
|
-
expect
|
354
|
-
subject.authentication_url_from_master('https://foo.example.com', remote: true)
|
345
|
+
expect{subject.authentication_url_from_master('https://foo.example.com', remote: true)}.to exit_with_error
|
355
346
|
end
|
356
347
|
|
357
348
|
it 'should exit with error if master returns text' do
|
358
349
|
allow(Kontena::Client).to receive(:new).and_return(client)
|
359
350
|
expect(client).to receive(:last_response).at_least(:once).and_return(OpenStruct.new(status: 400, headers: {}))
|
360
351
|
expect(client).to receive(:request).and_return('Fail!')
|
361
|
-
expect
|
362
|
-
subject.authentication_url_from_master('https://foo.example.com', remote: true)
|
352
|
+
expect{subject.authentication_url_from_master('https://foo.example.com', remote: true)}.to exit_with_error
|
363
353
|
end
|
364
354
|
|
365
355
|
it 'should exit with error if master returns nil' do
|
366
356
|
allow(Kontena::Client).to receive(:new).and_return(client)
|
367
357
|
expect(client).to receive(:last_response).at_least(:once).and_return(OpenStruct.new(status: 400, headers: {}))
|
368
358
|
expect(client).to receive(:request).and_return(nil)
|
369
|
-
expect
|
370
|
-
subject.authentication_url_from_master('https://foo.example.com', remote: true)
|
359
|
+
expect{subject.authentication_url_from_master('https://foo.example.com', remote: true)}.to exit_with_error
|
371
360
|
end
|
372
361
|
end
|
373
362
|
|
@@ -399,8 +388,7 @@ describe Kontena::Cli::Master::LoginCommand do
|
|
399
388
|
end
|
400
389
|
|
401
390
|
it 'should exit with error if response has error' do
|
402
|
-
expect(
|
403
|
-
subject.update_server_token(server, "error" => "abcd")
|
391
|
+
expect{subject.update_server_token(server, "error" => "abcd")}.to exit_with_error
|
404
392
|
end
|
405
393
|
|
406
394
|
it 'should update the token if all is good' do
|
@@ -16,7 +16,7 @@ describe Kontena::Cli::Master::UseCommand do
|
|
16
16
|
end
|
17
17
|
|
18
18
|
it 'should abort with error message if master is not configured' do
|
19
|
-
expect { subject.run(['not_existing']) }.to output(/Could not resolve master
|
19
|
+
expect { subject.run(['not_existing']) }.to exit_with_error.and output(/Could not resolve master by name 'not_existing'/).to_stderr
|
20
20
|
end
|
21
21
|
|
22
22
|
it 'should abort with error message if master is not given' do
|
@@ -49,7 +49,7 @@ describe Kontena::Cli::Nodes::RemoveCommand do
|
|
49
49
|
it 'does not remove the node' do
|
50
50
|
expect(client).not_to receive(:delete)
|
51
51
|
|
52
|
-
expect{subject.run(['node-1'])}.to output(" [error] Node node-1 is still
|
52
|
+
expect{subject.run(['node-1'])}.to exit_with_error.and output(" [error] Node node-1 is still connected using a grid token. You must terminate the node before removing it.\n").to_stderr
|
53
53
|
end
|
54
54
|
end
|
55
55
|
|
File without changes
|
@@ -76,7 +76,7 @@ describe Kontena::Cli::Stacks::UpgradeCommand do
|
|
76
76
|
'stacks/test-grid/stack-a', anything
|
77
77
|
).and_return({})
|
78
78
|
expect(Kontena).not_to receive(:run!).with(['stack', 'deploy', 'stack-a'])
|
79
|
-
subject.run(['--no-deploy', 'stack-a', fixture_path('kontena_v3.yml')])
|
79
|
+
subject.run(['--no-deploy', '--force', 'stack-a', fixture_path('kontena_v3.yml')])
|
80
80
|
end
|
81
81
|
end
|
82
82
|
|
@@ -0,0 +1,81 @@
|
|
1
|
+
require 'opto'
|
2
|
+
require 'kontena/cli/stacks/yaml/opto/certificates_resolver'
|
3
|
+
|
4
|
+
describe Kontena::Cli::Stacks::YAML::Opto::Resolvers::Certificates do
|
5
|
+
let(:client) { instance_double(Kontena::Client) }
|
6
|
+
let(:prompt) { double(:prompt) }
|
7
|
+
let(:prompt_menu) { double(:prompt_menu) }
|
8
|
+
|
9
|
+
let(:option_hint) { "Select SSL certificates" }
|
10
|
+
let(:option_default) { nil }
|
11
|
+
let(:option) { Opto::Option.new(default: option_default) }
|
12
|
+
subject { described_class.new(option_hint, option) }
|
13
|
+
|
14
|
+
before do
|
15
|
+
allow(subject).to receive(:current_master).and_return("test-master")
|
16
|
+
allow(subject).to receive(:current_grid).and_return("test-grid")
|
17
|
+
allow(subject).to receive(:client).and_return(client)
|
18
|
+
allow(subject).to receive(:prompt).and_return(prompt)
|
19
|
+
end
|
20
|
+
|
21
|
+
context 'with grid certificates' do
|
22
|
+
let(:certificates) { [
|
23
|
+
{ 'subject' => 'test.example.com' },
|
24
|
+
{ 'subject' => 'test-2.example.com' },
|
25
|
+
] }
|
26
|
+
|
27
|
+
before do
|
28
|
+
allow(client).to receive(:get).with('grids/test-grid/certificates').and_return('certificates' => certificates)
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'lists grid certificates and prompts' do
|
32
|
+
expect(prompt).to receive(:multi_select).with(option_hint) do |&block|
|
33
|
+
expect(prompt_menu).to_not receive(:default)
|
34
|
+
expect(prompt_menu).to receive(:choice).with('test.example.com')
|
35
|
+
expect(prompt_menu).to receive(:choice).with('test-2.example.com')
|
36
|
+
|
37
|
+
block.call(prompt_menu)
|
38
|
+
|
39
|
+
['test.example.com']
|
40
|
+
end
|
41
|
+
|
42
|
+
expect(subject.resolve).to eq ['test.example.com']
|
43
|
+
end
|
44
|
+
|
45
|
+
context 'with default value' do
|
46
|
+
let(:option_default) { ['test.example.com'] }
|
47
|
+
|
48
|
+
it 'lists grid certificates and prompts' do
|
49
|
+
expect(prompt).to receive(:multi_select).with(option_hint) do |&block|
|
50
|
+
expect(prompt_menu).to receive(:default).with(1)
|
51
|
+
expect(prompt_menu).to receive(:choice).with('test.example.com')
|
52
|
+
expect(prompt_menu).to receive(:choice).with('test-2.example.com')
|
53
|
+
|
54
|
+
block.call(prompt_menu)
|
55
|
+
|
56
|
+
['test.example.com']
|
57
|
+
end
|
58
|
+
|
59
|
+
expect(subject.resolve).to eq ['test.example.com']
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
context 'with default values' do
|
64
|
+
let(:option_default) { ['test.example.com', 'test-2.example.com'] }
|
65
|
+
|
66
|
+
it 'lists grid certificates and prompts' do
|
67
|
+
expect(prompt).to receive(:multi_select).with(option_hint) do |&block|
|
68
|
+
expect(prompt_menu).to receive(:default).with(1, 2)
|
69
|
+
expect(prompt_menu).to receive(:choice).with('test.example.com')
|
70
|
+
expect(prompt_menu).to receive(:choice).with('test-2.example.com')
|
71
|
+
|
72
|
+
block.call(prompt_menu)
|
73
|
+
|
74
|
+
['test.example.com', 'test-2.example.com']
|
75
|
+
end
|
76
|
+
|
77
|
+
expect(subject.resolve).to eq ['test.example.com', 'test-2.example.com']
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
@@ -112,7 +112,21 @@ describe Kontena::Cli::Stacks::YAML::Reader do
|
|
112
112
|
"links"=>[],
|
113
113
|
"ports"=>[],
|
114
114
|
"stateful"=>true,
|
115
|
-
"name"=>"mysql"
|
115
|
+
"name"=>"mysql",
|
116
|
+
"entrypoint" => "test"
|
117
|
+
)
|
118
|
+
)
|
119
|
+
end
|
120
|
+
|
121
|
+
it 'passes variables to extended file' do
|
122
|
+
allow(File).to receive(:exist?).with(fixture_path('docker-compose_v2_with_variables.yml')).and_call_original
|
123
|
+
allow(File).to receive(:read).with(fixture_path('docker-compose_v2_with_variables.yml')).and_call_original
|
124
|
+
allow(File).to receive(:exist?).with(fixture_path('kontena_v3.yml')).and_call_original
|
125
|
+
allow(File).to receive(:read).with(fixture_path('kontena_v3.yml')).and_return(fixture('kontena_v3_with_compose_variables.yml'))
|
126
|
+
expect(subject.execute['services']).to match array_including(
|
127
|
+
hash_including(
|
128
|
+
"name" => 'mysql',
|
129
|
+
"env" => ["ENV_VAR=abcd"]
|
116
130
|
)
|
117
131
|
)
|
118
132
|
end
|
@@ -146,7 +160,6 @@ describe Kontena::Cli::Stacks::YAML::Reader do
|
|
146
160
|
it 'extends services from the same file' do
|
147
161
|
app_svc = subject.execute['services'].find { |s| s['name'] == 'app' }
|
148
162
|
expect(app_svc).not_to be_nil
|
149
|
-
puts app_svc.inspect
|
150
163
|
expect(app_svc).to match hash_including(
|
151
164
|
"image" => "base:latest",
|
152
165
|
"instances" => 2,
|
@@ -514,4 +527,11 @@ describe Kontena::Cli::Stacks::YAML::Reader do
|
|
514
527
|
)
|
515
528
|
end
|
516
529
|
end
|
530
|
+
|
531
|
+
context "yaml with anchors" do
|
532
|
+
subject { described_class.new(fixture_path('stack-with-anchors.yml')) }
|
533
|
+
it 'parses correctly' do
|
534
|
+
expect(subject.execute['services'].all? { |svc| svc['affinity'] == ['abc==dfg']}).to be_truthy
|
535
|
+
end
|
536
|
+
end
|
517
537
|
end
|
@@ -52,6 +52,23 @@ describe Kontena::Cli::Stacks::YAML::ValidatorV3 do
|
|
52
52
|
expect(result.errors.key?('network_mode')).to be_falsey
|
53
53
|
end
|
54
54
|
|
55
|
+
context 'entrypoint' do
|
56
|
+
it 'is optional' do
|
57
|
+
result = subject.validate_options({})
|
58
|
+
expect(result.errors.key?('entrypoint')).to be_falsey
|
59
|
+
end
|
60
|
+
|
61
|
+
it 'passes validation when string' do
|
62
|
+
result = subject.validate_options({'entrypoint' => 'abcd'})
|
63
|
+
expect(result.errors.key?('entrypoint')).to be_falsey
|
64
|
+
end
|
65
|
+
|
66
|
+
it 'fails validation when not a string' do
|
67
|
+
result = subject.validate_options({'entrypoint' => 1})
|
68
|
+
expect(result.errors.key?('entrypoint')).to be_truthy
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
55
72
|
context 'affinity' do
|
56
73
|
it 'is optional' do
|
57
74
|
result = subject.validate_options({})
|
@@ -0,0 +1,54 @@
|
|
1
|
+
require 'kontena/command'
|
2
|
+
|
3
|
+
describe Kontena::Command do
|
4
|
+
let(:subject) { described_class.new('kontena') }
|
5
|
+
|
6
|
+
context 'for a command that raises RuntimeError without including Kontena::Cli::Common' do
|
7
|
+
let(:command_class) { Class.new(Kontena::Command) do
|
8
|
+
def execute
|
9
|
+
fail 'test'
|
10
|
+
end
|
11
|
+
end}
|
12
|
+
|
13
|
+
subject { command_class.new('test') }
|
14
|
+
|
15
|
+
it 'logs an error and aborts' do
|
16
|
+
expect{subject.run([])}.to raise_error(SystemExit).and output(/\[error\] RuntimeError : test\s+See .* or run the command again with environment DEBUG=true set to see the full exception/m).to_stderr
|
17
|
+
end
|
18
|
+
|
19
|
+
context 'with DEBUG' do
|
20
|
+
before do
|
21
|
+
allow(Kontena).to receive(:debug?).and_return(true)
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'lets the error raise through' do
|
25
|
+
expect{subject.run([])}.to raise_error(RuntimeError, 'test')
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
context 'for a command that raises StandardError without including Kontena::Cli::Common' do
|
32
|
+
let(:command_class) { Class.new(Kontena::Command) do
|
33
|
+
def execute
|
34
|
+
raise Kontena::Errors::StandardError.new(404, "Not Found")
|
35
|
+
end
|
36
|
+
end}
|
37
|
+
|
38
|
+
subject { command_class.new('test') }
|
39
|
+
|
40
|
+
it 'logs an error and aborts' do
|
41
|
+
expect{subject.run([])}.to raise_error(SystemExit).and output(" [error] 404 : Not Found\n").to_stderr
|
42
|
+
end
|
43
|
+
|
44
|
+
context 'with DEBUG' do
|
45
|
+
before do
|
46
|
+
allow(Kontena).to receive(:debug?).and_return(true)
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'lets the error raise through' do
|
50
|
+
expect{subject.run([])}.to raise_error(Kontena::Errors::StandardError)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
data/spec/kontena/config_spec.rb
CHANGED
@@ -59,11 +59,11 @@ describe Kontena::Cli::Config do
|
|
59
59
|
allow(File).to receive(:read).and_return <<-EOB
|
60
60
|
{"current_server": "test123",
|
61
61
|
"servers" : [
|
62
|
-
{
|
62
|
+
{
|
63
63
|
"name": "test123",
|
64
64
|
"url": "https://foo.example.com"
|
65
65
|
},
|
66
|
-
{
|
66
|
+
{
|
67
67
|
"name": "test123",
|
68
68
|
"url": "https://foo2.example.com"
|
69
69
|
}
|
@@ -82,6 +82,21 @@ describe Kontena::Cli::Config do
|
|
82
82
|
end
|
83
83
|
end
|
84
84
|
|
85
|
+
context 'environment variables' do
|
86
|
+
it 'sets cloud account on KONTENA_CLOUD_TOKEN' do
|
87
|
+
allow(ENV).to receive(:[]).with('KONTENA_CLOUD_TOKEN').and_return('abc')
|
88
|
+
expect(subject.current_account.token.access_token).to eq('abc')
|
89
|
+
end
|
90
|
+
|
91
|
+
it 'sets master information on KONTENA_URL, KONTENA_TOKEN & KONTENA_GRID' do
|
92
|
+
allow(ENV).to receive(:[]).with('KONTENA_URL').and_return('http://localhost')
|
93
|
+
allow(ENV).to receive(:[]).with('KONTENA_TOKEN').and_return('abc')
|
94
|
+
allow(ENV).to receive(:[]).with('KONTENA_GRID').and_return('test')
|
95
|
+
expect(subject.current_master.url).to eq('http://localhost')
|
96
|
+
expect(subject.current_master.grid).to eq('test')
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
85
100
|
describe 'Token' do
|
86
101
|
let(:subject) { Kontena::Cli::Config::Token.new(access_token: 'abcd', expires_at: Time.now.utc - 100) }
|
87
102
|
|