kontena-cli 0.8.4 → 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (90) hide show
  1. checksums.yaml +4 -4
  2. data/VERSION +1 -1
  3. data/bin/kontena +4 -0
  4. data/lib/kontena/cli/app_command.rb +2 -0
  5. data/lib/kontena/cli/apps/build_command.rb +26 -0
  6. data/lib/kontena/cli/apps/common.rb +41 -12
  7. data/lib/kontena/cli/apps/deploy_command.rb +31 -13
  8. data/lib/kontena/cli/apps/docker_helper.rb +34 -0
  9. data/lib/kontena/cli/apps/init_command.rb +130 -10
  10. data/lib/kontena/cli/apps/list_command.rb +4 -2
  11. data/lib/kontena/cli/apps/logs_command.rb +4 -2
  12. data/lib/kontena/cli/apps/remove_command.rb +4 -2
  13. data/lib/kontena/cli/apps/start_command.rb +4 -2
  14. data/lib/kontena/cli/apps/stop_command.rb +4 -2
  15. data/lib/kontena/cli/common.rb +3 -3
  16. data/lib/kontena/cli/container_command.rb +3 -0
  17. data/lib/kontena/cli/containers/inspect_command.rb +16 -0
  18. data/lib/kontena/cli/deploy_command.rb +3 -0
  19. data/lib/kontena/cli/etcd/get_command.rb +21 -0
  20. data/lib/kontena/cli/etcd/list_command.rb +26 -0
  21. data/lib/kontena/cli/etcd/mkdir_command.rb +17 -0
  22. data/lib/kontena/cli/etcd/remove_command.rb +21 -0
  23. data/lib/kontena/cli/etcd/set_command.rb +18 -0
  24. data/lib/kontena/cli/etcd_command.rb +17 -0
  25. data/lib/kontena/cli/grid_command.rb +2 -0
  26. data/lib/kontena/cli/grids/logs_command.rb +71 -0
  27. data/lib/kontena/cli/master/aws/create_command.rb +33 -0
  28. data/lib/kontena/cli/master/aws_command.rb +8 -0
  29. data/lib/kontena/cli/master/azure/create_command.rb +33 -0
  30. data/lib/kontena/cli/master/azure_command.rb +13 -0
  31. data/lib/kontena/cli/master/digital_ocean/create_command.rb +30 -0
  32. data/lib/kontena/cli/master/digital_ocean_command.rb +13 -0
  33. data/lib/kontena/cli/master/vagrant/create_command.rb +19 -0
  34. data/lib/kontena/cli/master/vagrant/restart_command.rb +20 -0
  35. data/lib/kontena/cli/master/vagrant/ssh_command.rb +15 -0
  36. data/lib/kontena/cli/master/vagrant/start_command.rb +20 -0
  37. data/lib/kontena/cli/master/vagrant/stop_command.rb +20 -0
  38. data/lib/kontena/cli/master/vagrant/terminate_command.rb +13 -0
  39. data/lib/kontena/cli/master/vagrant_command.rb +23 -0
  40. data/lib/kontena/cli/master_command.rb +15 -0
  41. data/lib/kontena/cli/node_command.rb +4 -0
  42. data/lib/kontena/cli/nodes/aws/create_command.rb +39 -0
  43. data/lib/kontena/cli/nodes/aws/restart_command.rb +28 -0
  44. data/lib/kontena/cli/nodes/aws/terminate_command.rb +20 -0
  45. data/lib/kontena/cli/nodes/aws_command.rb +15 -0
  46. data/lib/kontena/cli/nodes/azure/create_command.rb +39 -0
  47. data/lib/kontena/cli/nodes/azure/restart_command.rb +31 -0
  48. data/lib/kontena/cli/nodes/azure/terminate_command.rb +20 -0
  49. data/lib/kontena/cli/nodes/azure_command.rb +15 -0
  50. data/lib/kontena/cli/nodes/digital_ocean/create_command.rb +1 -1
  51. data/lib/kontena/cli/nodes/vagrant/create_command.rb +1 -1
  52. data/lib/kontena/cli/service_command.rb +4 -0
  53. data/lib/kontena/cli/services/add_env_command.rb +18 -0
  54. data/lib/kontena/cli/services/create_command.rb +8 -0
  55. data/lib/kontena/cli/services/remove_env_command.rb +17 -0
  56. data/lib/kontena/cli/services/services_helper.rb +20 -1
  57. data/lib/kontena/cli/services/update_command.rb +10 -0
  58. data/lib/kontena/client.rb +22 -1
  59. data/lib/kontena/machine/aws.rb +13 -0
  60. data/lib/kontena/machine/aws/cloudinit.yml +66 -0
  61. data/lib/kontena/machine/aws/cloudinit_master.yml +105 -0
  62. data/lib/kontena/machine/aws/master_provisioner.rb +161 -0
  63. data/lib/kontena/machine/aws/node_destroyer.rb +39 -0
  64. data/lib/kontena/machine/aws/node_provisioner.rb +168 -0
  65. data/lib/kontena/machine/azure.rb +13 -0
  66. data/lib/kontena/machine/azure/cloudinit.yml +59 -0
  67. data/lib/kontena/machine/azure/cloudinit_master.yml +105 -0
  68. data/lib/kontena/machine/azure/logger.rb +27 -0
  69. data/lib/kontena/machine/azure/master_provisioner.rb +126 -0
  70. data/lib/kontena/machine/azure/node_destroyer.rb +53 -0
  71. data/lib/kontena/machine/azure/node_provisioner.rb +128 -0
  72. data/lib/kontena/machine/digital_ocean.rb +1 -0
  73. data/lib/kontena/machine/digital_ocean/cloudinit.yml +1 -0
  74. data/lib/kontena/machine/digital_ocean/cloudinit_master.yml +105 -0
  75. data/lib/kontena/machine/digital_ocean/master_provisioner.rb +94 -0
  76. data/lib/kontena/machine/digital_ocean/node_provisioner.rb +8 -1
  77. data/lib/kontena/machine/vagrant.rb +2 -0
  78. data/lib/kontena/machine/vagrant/Vagrantfile.master.rb.erb +101 -0
  79. data/lib/kontena/machine/vagrant/{Vagrantfile.coreos.rb.erb → Vagrantfile.node.rb.erb} +0 -0
  80. data/lib/kontena/machine/vagrant/cloudinit.yml +2 -1
  81. data/lib/kontena/machine/vagrant/master_destroyer.rb +37 -0
  82. data/lib/kontena/machine/vagrant/master_provisioner.rb +75 -0
  83. data/lib/kontena/machine/vagrant/node_destroyer.rb +4 -0
  84. data/lib/kontena/machine/vagrant/node_provisioner.rb +1 -1
  85. data/lib/kontena/scripts/completer +29 -3
  86. data/spec/kontena/cli/app/common_spec.rb +61 -0
  87. data/spec/kontena/cli/app/deploy_command_spec.rb +25 -6
  88. data/spec/kontena/cli/app/docker_helper_spec.rb +32 -0
  89. data/spec/kontena/cli/common_spec.rb +53 -0
  90. metadata +61 -3
@@ -8,7 +8,7 @@ write_files:
8
8
  KONTENA_TOKEN="<%= grid_token %>"
9
9
  KONTENA_PEER_INTERFACE=eth1
10
10
  KONTENA_VERSION=<%= version %>
11
- - path: /etc/systemd/system/docker.service.d/50-insecure-registry.conf
11
+ - path: /etc/systemd/system/docker.service.d/50-kontena.conf
12
12
  content: |
13
13
  [Service]
14
14
  Environment='DOCKER_OPTS=--insecure-registry="10.81.0.0/19" --bip="172.17.42.1/16"'
@@ -61,5 +61,6 @@ coreos:
61
61
  -e KONTENA_TOKEN=${KONTENA_TOKEN} \
62
62
  -e KONTENA_PEER_INTERFACE=${KONTENA_PEER_INTERFACE} \
63
63
  -v=/var/run/docker.sock:/var/run/docker.sock \
64
+ -v=/etc/kontena-agent.env:/etc/kontena.env \
64
65
  --net=host \
65
66
  kontena/agent:${KONTENA_VERSION}
@@ -0,0 +1,37 @@
1
+ require 'fileutils'
2
+
3
+ module Kontena
4
+ module Machine
5
+ module Vagrant
6
+ class MasterDestroyer
7
+
8
+ attr_reader :client, :api_client
9
+
10
+ # @param [Kontena::Client] api_client Kontena api client
11
+ def initialize(api_client)
12
+ @api_client = api_client
13
+ end
14
+
15
+ def run!
16
+ if api_client.get("grids")['grids'].size > 0
17
+ abort("Cannot remove kontena-master because it has grids".colorize(:red))
18
+ end
19
+
20
+ vagrant_path = "#{Dir.home}/.kontena/vagrant_master"
21
+ Dir.chdir(vagrant_path) do
22
+ ShellSpinner "Terminating Vagrant kontena-master " do
23
+ Open3.popen2('vagrant destroy -f') do |stdin, output, wait|
24
+ while o = output.gets
25
+ puts o if ENV['DEBUG']
26
+ end
27
+ if wait.value == 0
28
+ FileUtils.remove_entry_secure(vagrant_path)
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,75 @@
1
+ require 'fileutils'
2
+ require 'erb'
3
+ require 'open3'
4
+ require 'shell-spinner'
5
+
6
+ module Kontena
7
+ module Machine
8
+ module Vagrant
9
+ class MasterProvisioner
10
+ include RandomName
11
+
12
+ API_URL = 'http://192.168.66.100:8080'
13
+ attr_reader :client
14
+
15
+ def initialize
16
+ @client = Excon.new(API_URL)
17
+ end
18
+
19
+ def run!(opts)
20
+ name = generate_name
21
+ version = opts[:version]
22
+ memory = opts[:memory] || 1024
23
+ auth_server = opts[:auth_server]
24
+ vagrant_path = "#{Dir.home}/.kontena/vagrant_master/"
25
+ if Dir.exist?(vagrant_path)
26
+ abort("Oops... cannot create Kontena Master! You can run only one Kontena Master with Vagrant".colorize(:red))
27
+ end
28
+ FileUtils.mkdir_p(vagrant_path)
29
+
30
+ template = File.join(__dir__ , '/Vagrantfile.master.rb.erb')
31
+ cloudinit_template = File.join(__dir__ , '/cloudinit.yml')
32
+ vars = {
33
+ name: name,
34
+ version: version,
35
+ memory: memory,
36
+ auth_server: auth_server,
37
+ cloudinit: "#{vagrant_path}/cloudinit.yml"
38
+ }
39
+ vagrant_data = erb(File.read(template), vars)
40
+ cloudinit = erb(File.read(cloudinit_template), vars)
41
+ File.write("#{vagrant_path}/Vagrantfile", vagrant_data)
42
+ File.write("#{vagrant_path}/cloudinit.yml", cloudinit)
43
+ Dir.chdir(vagrant_path) do
44
+ ShellSpinner "Creating Vagrant machine #{name.colorize(:cyan)} " do
45
+ Open3.popen2('vagrant box update && vagrant up') do |stdin, output, wait|
46
+ while o = output.gets
47
+ print o if ENV['DEBUG']
48
+ end
49
+ end
50
+ end
51
+ ShellSpinner "Waiting for #{name.colorize(:cyan)} to start " do
52
+ sleep 1 until master_running?
53
+ end
54
+ puts "Kontena Master is now running at #{API_URL}"
55
+ puts "Use #{"kontena login #{API_URL}".colorize(:light_black)} to complete Kontena Master setup"
56
+ end
57
+ end
58
+
59
+ def erb(template, vars)
60
+ ERB.new(template).result(OpenStruct.new(vars).instance_eval { binding })
61
+ end
62
+
63
+ def master_running?
64
+ client.get(path: '/').status == 200
65
+ rescue
66
+ false
67
+ end
68
+
69
+ def generate_name
70
+ "kontena-master-#{super}-#{rand(1..99)}"
71
+ end
72
+ end
73
+ end
74
+ end
75
+ end
@@ -1,3 +1,4 @@
1
+ require 'fileutils'
1
2
 
2
3
  module Kontena
3
4
  module Machine
@@ -20,6 +21,9 @@ module Kontena
20
21
  while o = output.gets
21
22
  puts o if ENV['DEBUG']
22
23
  end
24
+ if wait.value == 0
25
+ FileUtils.remove_entry_secure(vagrant_path)
26
+ end
23
27
  end
24
28
  end
25
29
  end
@@ -23,7 +23,7 @@ module Kontena
23
23
  vagrant_path = "#{Dir.home}/.kontena/#{grid}/#{name}"
24
24
  FileUtils.mkdir_p(vagrant_path)
25
25
 
26
- template = File.join(__dir__ , '/Vagrantfile.coreos.rb.erb')
26
+ template = File.join(__dir__ , '/Vagrantfile.node.rb.erb')
27
27
  cloudinit_template = File.join(__dir__ , '/cloudinit.yml')
28
28
  vars = {
29
29
  name: name,
@@ -3,6 +3,7 @@
3
3
 
4
4
  # resolve bin path, ignoring symlinks
5
5
  require 'pathname'
6
+ require 'yaml'
6
7
  bin_file = Pathname.new(__FILE__).realpath
7
8
 
8
9
  # add self to libpath
@@ -52,6 +53,16 @@ class Helper
52
53
  rescue
53
54
  []
54
55
  end
56
+
57
+ def yml_services
58
+ if File.exist?('kontena.yml')
59
+ services = YAML.load(File.read('kontena.yml'))
60
+ services.keys
61
+ end
62
+ rescue
63
+ []
64
+ end
65
+
55
66
  end
56
67
 
57
68
  helper = Helper.new
@@ -60,7 +71,7 @@ words = ARGV
60
71
  words.delete_at(0)
61
72
 
62
73
  completion = []
63
- completion.push %w(app deploy forgot-password node grid invite service container vpn external-registry registry login logout whoami) if words.size < 2
74
+ completion.push %w(app deploy forgot-password master node grid invite service container vpn external-registry registry login logout whoami) if words.size < 2
64
75
  if words.size > 0
65
76
  case words[0]
66
77
  when 'grid'
@@ -74,13 +85,22 @@ if words.size > 0
74
85
  end
75
86
  when 'node'
76
87
  completion.clear
77
- sub_commands = %w(list show remove vagrant digitalocean)
88
+ sub_commands = %w(list show remove vagrant digitalocean azure aws)
78
89
  if words[1]
79
90
  completion.push(sub_commands) unless sub_commands.include?(words[1])
80
91
  completion.push helper.nodes
81
92
  else
82
93
  completion.push sub_commands
83
94
  end
95
+ when 'master'
96
+ completion.clear
97
+ sub_commands = %w(vagrant digitalocean azure aws)
98
+ if words[1]
99
+ completion.push(sub_commands) unless sub_commands.include?(words[1])
100
+ completion.push %w(create)
101
+ else
102
+ completion.push sub_commands
103
+ end
84
104
  when 'service'
85
105
  completion.clear
86
106
  sub_commands = %w(containers create delete deploy list logs restart scale show start stats stop update)
@@ -107,7 +127,13 @@ if words.size > 0
107
127
  completion.push %w(add list delete)
108
128
  when 'app'
109
129
  completion.clear
110
- completion.push %w(init deploy start stop remove rm ps list)
130
+ sub_commands = %w(init build deploy start stop remove rm ps list logs)
131
+ if words[1]
132
+ completion.push(sub_commands) unless sub_commands.include?(words[1])
133
+ completion.push helper.yml_services
134
+ else
135
+ completion.push sub_commands
136
+ end
111
137
  end
112
138
  end
113
139
 
@@ -0,0 +1,61 @@
1
+ require_relative "../../../spec_helper"
2
+ require "kontena/cli/apps/common"
3
+
4
+ describe Kontena::Cli::Apps::Common do
5
+
6
+ let(:subject) do
7
+ Class.new { include Kontena::Cli::Apps::Common}.new
8
+ end
9
+
10
+ describe '#normalize_env_vars' do
11
+ it 'converts env hash to array' do
12
+ opts = {
13
+ 'environment' => {
14
+ 'FOO' => 'bar',
15
+ 'BAR' => 'baz'
16
+ }
17
+ }
18
+ subject.normalize_env_vars(opts)
19
+ env = opts['environment']
20
+ expect(env).to include('FOO=bar')
21
+ expect(env).to include('BAR=baz')
22
+ end
23
+
24
+ it 'does nothing to env array' do
25
+ opts = {
26
+ 'environment' => [
27
+ 'FOO=bar', 'BAR=baz'
28
+ ]
29
+ }
30
+ subject.normalize_env_vars(opts)
31
+ env = opts['environment']
32
+ expect(env).to include('FOO=bar')
33
+ expect(env).to include('BAR=baz')
34
+ end
35
+ end
36
+
37
+ describe '#extend_env_vars' do
38
+ it 'inherites env vars from upper level' do
39
+ from = {'environment' => ['FOO=bar']}
40
+ to = {}
41
+ env_vars = subject.extend_env_vars(from, to)
42
+ expect(env_vars).to eq(['FOO=bar'])
43
+ end
44
+
45
+ it 'overrides values' do
46
+ from = {'environment' => ['FOO=bar']}
47
+ to = {'environment' => ['FOO=baz']}
48
+ env_vars = subject.extend_env_vars(from, to)
49
+ expect(env_vars).to eq(['FOO=baz'])
50
+ end
51
+
52
+ it 'combines variables' do
53
+ from = {'environment' => ['FOO=bar']}
54
+ to = {'environment' => ['BAR=baz']}
55
+ env_vars = subject.extend_env_vars(from, to)
56
+ expect(env_vars).to eq(['BAR=baz', 'FOO=bar'])
57
+ end
58
+
59
+
60
+ end
61
+ end
@@ -37,7 +37,7 @@ wordpress:
37
37
  service: wordpress
38
38
  stateful: true
39
39
  environment:
40
- - WORDPRESS_DB_PASSWORD=%{prefix}_secret
40
+ - WORDPRESS_DB_PASSWORD=%{project}_secret
41
41
  instances: 2
42
42
  deploy:
43
43
  strategy: ha
@@ -47,7 +47,7 @@ mysql:
47
47
  service: mysql
48
48
  stateful: true
49
49
  environment:
50
- - MYSQL_ROOT_PASSWORD=%{prefix}_secret
50
+ - MYSQL_ROOT_PASSWORD=%{project}_secret
51
51
  yml
52
52
  yml_content
53
53
  end
@@ -105,8 +105,8 @@ yml
105
105
  before(:each) do
106
106
  allow(subject).to receive(:settings).and_return(settings)
107
107
  allow(File).to receive(:exists?).and_return(true)
108
- allow(File).to receive(:read).with('kontena.yml').and_return(kontena_yml)
109
- allow(File).to receive(:read).with('docker-compose.yml').and_return(docker_compose_yml)
108
+ allow(File).to receive(:read).with("#{Dir.getwd}/kontena.yml").and_return(kontena_yml)
109
+ allow(File).to receive(:read).with("#{Dir.getwd}/docker-compose.yml").and_return(docker_compose_yml)
110
110
  allow(subject).to receive(:get_service).and_raise(Kontena::Errors::StandardError.new(404, 'Not Found'))
111
111
  allow(subject).to receive(:create_service).and_return({'id' => 'cli/kontena-test-mysql', 'name' => 'kontena-test-mysql'},{'id' => 'cli/kontena-test-wordpress', 'name' => 'kontena-test-wordpress'})
112
112
  allow(subject).to receive(:current_grid).and_return('1')
@@ -115,17 +115,18 @@ yml
115
115
 
116
116
  it 'reads ./kontena.yml file by default' do
117
117
  allow(subject).to receive(:settings).and_return(settings)
118
- expect(File).to receive(:read).with('kontena.yml').and_return(kontena_yml)
118
+ expect(File).to receive(:read).with("#{Dir.getwd}/kontena.yml").and_return(kontena_yml)
119
119
  subject.run([])
120
120
  end
121
121
 
122
122
  it 'reads given yml file' do
123
- expect(File).to receive(:read).with('custom.yml').and_return(kontena_yml)
123
+ expect(File).to receive(:read).with("#{Dir.getwd}/custom.yml").and_return(kontena_yml)
124
124
  subject.run(["--file", "custom.yml"])
125
125
  end
126
126
 
127
127
  it 'uses current directory as service name prefix by default' do
128
128
  current_dir = '/kontena/tests/stacks'
129
+ allow(Dir).to receive(:chdir).and_return(true)
129
130
  allow(Dir).to receive(:getwd).and_return(current_dir)
130
131
  expect(File).to receive(:basename).with(current_dir).and_return('stacks')
131
132
  subject.run([])
@@ -180,6 +181,24 @@ yml
180
181
  end
181
182
  end
182
183
 
184
+ it 'merges external links to links' do
185
+ allow(subject).to receive(:current_dir).and_return("kontena-test")
186
+ allow(YAML).to receive(:load).and_return(services)
187
+ services['wordpress']['external_links'] = ['loadbalancer:loadbalancer']
188
+ data = {
189
+ :name =>"kontena-test-wordpress",
190
+ :image=>"wordpress:latest",
191
+ :env=> nil,
192
+ :container_count=>2,
193
+ :stateful=>false,
194
+ :links=>[{:name => "kontena-test-mysql", :alias => "db"}, {:name => "loadbalancer", :alias => "loadbalancer"}],
195
+ :ports=>[{:container_port => "80", :node_port => "80", :protocol => "tcp"}]
196
+ }
197
+
198
+ expect(subject).to receive(:create_service).with('1234567', '1', data)
199
+ subject.run([])
200
+ end
201
+
183
202
  it 'creates mysql service before wordpress' do
184
203
  allow(subject).to receive(:current_dir).and_return("kontena-test")
185
204
  data = {:name =>"kontena-test-mysql", :image=>'mysql:5.6', :env=>["MYSQL_ROOT_PASSWORD=kontena-test_secret"], :container_count=>nil, :stateful=>true}
@@ -0,0 +1,32 @@
1
+ require_relative "../../../spec_helper"
2
+ require "kontena/cli/apps/docker_helper"
3
+
4
+ describe Kontena::Cli::Apps::DockerHelper do
5
+
6
+ let(:subject) do
7
+ Class.new { include Kontena::Cli::Apps::DockerHelper}.new
8
+ end
9
+
10
+ describe '#validate_image_name' do
11
+ context 'when image name is valid' do
12
+ it 'returns true' do
13
+ expect(subject.validate_image_name('registry.kontena.local/image-name:latest')).to be_truthy
14
+ expect(subject.validate_image_name('my-registry.com/organization/image_name:latest')).to be_truthy
15
+ expect(subject.validate_image_name('mysql:5.1')).to be_truthy
16
+ expect(subject.validate_image_name('wordpress')).to be_truthy
17
+ end
18
+
19
+ end
20
+ end
21
+
22
+ describe '#validate_image_name' do
23
+ context 'when image name is invalid' do
24
+ it 'returns false' do
25
+ expect(subject.validate_image_name('registry.kontena.local/image-name:')).to be_falsey
26
+ expect(subject.validate_image_name('mysql 5.1')).to be_falsey
27
+ expect(subject.validate_image_name('*.mydomain.com/mysql')).to be_falsey
28
+ end
29
+
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,53 @@
1
+ require_relative "../../spec_helper"
2
+ require "kontena/cli/common"
3
+
4
+ describe Kontena::Cli::Common do
5
+
6
+ let(:subject) do
7
+ Class.new do
8
+ include Kontena::Cli::Common
9
+ end.new
10
+ end
11
+
12
+ before(:each) do
13
+ allow(subject).to receive(:settings).and_return({'server' => {}})
14
+ allow(subject).to receive(:save_settings)
15
+ end
16
+
17
+ describe '#current_grid' do
18
+ it 'returns nil by default' do
19
+ expect(subject.current_grid).to eq(nil)
20
+ end
21
+
22
+ it 'returns grid from env' do
23
+ expect(ENV).to receive(:[]).with('KONTENA_GRID').and_return('foo')
24
+ expect(subject.current_grid).to eq('foo')
25
+ end
26
+ end
27
+
28
+ describe '#api_url' do
29
+ it 'raises error by default' do
30
+ expect {
31
+ subject.api_url
32
+ }.to raise_error(ArgumentError)
33
+ end
34
+
35
+ it 'return url from env' do
36
+ expect(ENV).to receive(:[]).with('KONTENA_URL').and_return('https://domain.com')
37
+ expect(subject.api_url).to eq('https://domain.com')
38
+ end
39
+ end
40
+
41
+ describe '#require_token' do
42
+ it 'raises error by default' do
43
+ expect {
44
+ subject.require_token
45
+ }.to raise_error(ArgumentError)
46
+ end
47
+
48
+ it 'return token from env' do
49
+ expect(ENV).to receive(:[]).with('KONTENA_TOKEN').and_return('secret_token')
50
+ expect(subject.require_token).to eq('secret_token')
51
+ end
52
+ end
53
+ end