kontena-cli 1.4.0 → 1.4.1.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 +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
|
|