kontena-cli 0.8.4 → 0.9.0

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.
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