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.
Files changed (62) hide show
  1. checksums.yaml +5 -5
  2. data/VERSION +1 -1
  3. data/bin/kontena +2 -1
  4. data/kontena-cli.gemspec +1 -1
  5. data/lib/kontena/cli/certificate/common.rb +16 -0
  6. data/lib/kontena/cli/certificate/export_command.rb +28 -0
  7. data/lib/kontena/cli/certificate/import_command.rb +61 -0
  8. data/lib/kontena/cli/certificate/show_command.rb +5 -2
  9. data/lib/kontena/cli/certificate_command.rb +3 -1
  10. data/lib/kontena/cli/common.rb +5 -1
  11. data/lib/kontena/cli/config.rb +23 -5
  12. data/lib/kontena/cli/external_registries/add_command.rb +2 -0
  13. data/lib/kontena/cli/external_registries/list_command.rb +1 -1
  14. data/lib/kontena/cli/helpers/exec_helper.rb +12 -4
  15. data/lib/kontena/cli/master/config/import_command.rb +1 -1
  16. data/lib/kontena/cli/master/login_command.rb +1 -1
  17. data/lib/kontena/cli/stacks/common.rb +2 -1
  18. data/lib/kontena/cli/stacks/registry/show_command.rb +1 -1
  19. data/lib/kontena/cli/stacks/service_generator.rb +1 -0
  20. data/lib/kontena/cli/stacks/yaml/opto.rb +1 -0
  21. data/lib/kontena/cli/stacks/yaml/opto/certificates_resolver.rb +37 -0
  22. data/lib/kontena/cli/stacks/yaml/opto/vault_cert_prompt_resolver.rb +1 -1
  23. data/lib/kontena/cli/stacks/yaml/reader.rb +5 -2
  24. data/lib/kontena/cli/stacks/yaml/validations.rb +2 -1
  25. data/lib/kontena/cli/vault/import_command.rb +1 -1
  26. data/lib/kontena/client.rb +1 -1
  27. data/lib/kontena/command.rb +7 -5
  28. data/lib/kontena/plugin_manager.rb +1 -1
  29. data/lib/kontena/plugin_manager/cleaner.rb +1 -1
  30. data/lib/kontena/scripts/completer.rb +1 -1
  31. data/lib/kontena/stacks_cache.rb +2 -2
  32. data/lib/kontena_cli.rb +6 -2
  33. data/spec/fixtures/certificates/test/ca-key.pem +10 -0
  34. data/spec/fixtures/certificates/test/ca.pem +10 -0
  35. data/spec/fixtures/certificates/test/ca.srl +1 -0
  36. data/spec/fixtures/certificates/test/cert.pem +8 -0
  37. data/spec/fixtures/certificates/test/csr.pem +7 -0
  38. data/spec/fixtures/certificates/test/key.pem +10 -0
  39. data/spec/fixtures/certificates/test/real-cert.pem +30 -0
  40. data/spec/fixtures/docker-compose_v2.yml +1 -0
  41. data/spec/fixtures/docker-compose_v2_with_variables.yml +12 -0
  42. data/spec/fixtures/kontena_v3_with_compose_variables.yml +11 -0
  43. data/spec/fixtures/stack-with-anchors.yml +13 -0
  44. data/spec/kontena/cli/certificates/export_command_spec.rb +49 -0
  45. data/spec/kontena/cli/certificates/import_command_spec.rb +70 -0
  46. data/spec/kontena/cli/certificates/show_command_spec.rb +57 -0
  47. data/spec/kontena/cli/cloud/login_command_spec.rb +7 -14
  48. data/spec/kontena/cli/helpers/exec_helper_spec.rb +38 -0
  49. data/spec/kontena/cli/master/login_command_spec.rb +12 -24
  50. data/spec/kontena/cli/master/use_command_spec.rb +1 -1
  51. data/spec/kontena/cli/nodes/remove_command_spec.rb +1 -1
  52. data/spec/kontena/cli/registry/{create_spec.rb → create_command_spec.rb} +0 -0
  53. data/spec/kontena/cli/stacks/upgrade_command_spec.rb +1 -1
  54. data/spec/kontena/cli/stacks/yaml/opto/certificates_resolver_spec.rb +81 -0
  55. data/spec/kontena/cli/stacks/yaml/reader_spec.rb +22 -2
  56. data/spec/kontena/cli/stacks/yaml/validator_v3_spec.rb +17 -0
  57. data/spec/kontena/command_spec.rb +54 -0
  58. data/spec/kontena/config_spec.rb +17 -2
  59. data/spec/kontena/main_command_spec.rb +13 -0
  60. data/spec/spec_helper.rb +10 -17
  61. metadata +43 -11
  62. 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(subject).to receive(:exit_with_error).and_throw(:exit_with_error)
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(subject).to receive(:exit_with_error).and_throw(:exit_with_error)
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(subject).to receive(:exit_with_error).and_throw(:exit_with_error)
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(subject).to receive(:exit_with_error).and_throw(:exit_with_error)
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(subject).to receive(:exit_with_error).and_throw(:exit_with_error)
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(subject).to receive(:exit_with_error).and_throw(:exit_with_error)
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(subject).to receive(:exit_with_error).and_throw(:exit_with_error)
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(subject).to receive(:exit_with_error).and_throw(:exit_with_error)
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(subject).to receive(:exit_with_error).and_throw(:exit_with_error)
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(subject).to receive(:exit_with_error).and_throw(:exit_with_error)
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(subject).to receive(:exit_with_error).and_throw(:exit_with_error)
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(subject).to receive(:exit_with_error).and_throw(:exit_with_error)
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(subject).to receive(:exit_with_error).and_throw(:exit_with_error)
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(subject).to receive(:exit_with_error).and_throw(:exit_with_error)
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(subject).to receive(:exit_with_error).and_throw(:exit_with_error)
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(subject).to receive(:exit_with_error).with(/no good/).and_throw(:exit_with_error)
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(subject).to receive(:exit_with_error).and_throw(:exit_with_error)
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(subject).to receive(:exit_with_error).with(/Invalid.+?400/).and_throw(:exit_with_error)
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(subject).to receive(:exit_with_error).and_throw(:exit_with_error)
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 with name: 'not_existing'/).to_stderr
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 online. You must terminate the node before removing it.\n").to_stderr
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
 
@@ -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
@@ -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