kontena-cli 1.2.2 → 1.3.0.pre1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (51) hide show
  1. checksums.yaml +4 -4
  2. data/VERSION +1 -1
  3. data/lib/kontena/callbacks/auth/01_list_and_select_grid_after_master_auth.rb +1 -1
  4. data/lib/kontena/callbacks/master/deploy/05_before_deploy_configuration_wizard.rb +1 -1
  5. data/lib/kontena/callbacks/master/deploy/50_authenticate_after_deploy.rb +7 -2
  6. data/lib/kontena/callbacks/master/deploy/55_create_initial_grid_after_deploy.rb +2 -3
  7. data/lib/kontena/callbacks/master/deploy/56_set_server_provider_after_deploy.rb +2 -2
  8. data/lib/kontena/callbacks/master/deploy/60_configure_auth_provider_after_deploy.rb +5 -10
  9. data/lib/kontena/callbacks/master/deploy/70_invite_self_after_deploy.rb +10 -16
  10. data/lib/kontena/cli/app_command.rb +2 -0
  11. data/lib/kontena/cli/cloud/master/add_command.rb +19 -10
  12. data/lib/kontena/cli/common.rb +2 -32
  13. data/lib/kontena/cli/grids/trusted_subnets/add_command.rb +6 -6
  14. data/lib/kontena/cli/grids/trusted_subnets/list_command.rb +3 -4
  15. data/lib/kontena/cli/grids/trusted_subnets/remove_command.rb +7 -7
  16. data/lib/kontena/cli/master/create_command.rb +2 -3
  17. data/lib/kontena/cli/master/init_cloud_command.rb +1 -1
  18. data/lib/kontena/cli/master/join_command.rb +3 -1
  19. data/lib/kontena/cli/master/ssh_command.rb +2 -6
  20. data/lib/kontena/cli/master/token/current_command.rb +1 -1
  21. data/lib/kontena/cli/master/user/invite_command.rb +2 -2
  22. data/lib/kontena/cli/master/user_command.rb +0 -2
  23. data/lib/kontena/cli/nodes/ssh_command.rb +1 -3
  24. data/lib/kontena/cli/stack_command.rb +2 -0
  25. data/lib/kontena/cli/stacks/common.rb +1 -1
  26. data/lib/kontena/cli/stacks/install_command.rb +1 -1
  27. data/lib/kontena/cli/stacks/restart_command.rb +23 -0
  28. data/lib/kontena/cli/stacks/stop_command.rb +23 -0
  29. data/lib/kontena/cli/stacks/upgrade_command.rb +1 -1
  30. data/lib/kontena/cli/stacks/yaml/validations.rb +1 -1
  31. data/lib/kontena/cli/vault/export_command.rb +2 -2
  32. data/lib/kontena/cli/vault/import_command.rb +4 -10
  33. data/lib/kontena/main_command.rb +1 -1
  34. data/lib/kontena/plugin_manager.rb +16 -1
  35. data/lib/kontena_cli.rb +23 -14
  36. data/spec/kontena/cli/cloud/master/add_command_spec.rb +5 -5
  37. data/spec/kontena/cli/grids/trusted_subnets/add_command_spec.rb +20 -4
  38. data/spec/kontena/cli/grids/trusted_subnets/list_command_spec.rb +12 -7
  39. data/spec/kontena/cli/grids/trusted_subnets/remove_command_spec.rb +20 -4
  40. data/spec/kontena/cli/master/init_cloud_command_spec.rb +1 -1
  41. data/spec/kontena/cli/master/user/invite_command_spec.rb +2 -2
  42. data/spec/kontena/cli/nodes/ssh_command_spec.rb +43 -0
  43. data/spec/kontena/cli/stacks/restart_command_spec.rb +16 -0
  44. data/spec/kontena/cli/stacks/stop_command_spec.rb +16 -0
  45. data/spec/kontena/cli/stacks/upgrade_command_spec.rb +2 -2
  46. data/spec/kontena/cli/stacks/yaml/validator_v3_spec.rb +22 -2
  47. data/spec/kontena/cli/vault/export_spec.rb +6 -6
  48. data/spec/kontena/cli/vault/import_spec.rb +11 -12
  49. data/spec/kontena/kontena_cli_spec.rb +40 -5
  50. data/spec/spec_helper.rb +9 -7
  51. metadata +12 -4
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 0ba6c6982719bd042e6289125deef78e98718195
4
- data.tar.gz: 82bb60f9a2047d1ddc5847edb97803836e31ce5d
3
+ metadata.gz: 94ab10349d6c3c14f160614a1889a8de25719076
4
+ data.tar.gz: 5969036b74c54688c2ced991d4ec63c02f84c539
5
5
  SHA512:
6
- metadata.gz: b880299d9fb59cfbf1bb800dd471411807bb1c170e7f8226781dc2fee1ca8ab4dff42df65c0eee2e628d5965168fa9302d3e1155f59c69abcbf202545249e034
7
- data.tar.gz: 52aa18034fac31b990c3b3d4d45eee5512f51681624e5c6f35dfc4ea241b51246d62d99edb26c87990fda5b3d10eae749086a061cc3d666492e209a939b585e1
6
+ metadata.gz: 8b54fac59b78a266deb4111a1e66841826e43bf41b494f9a63955cb661e9bd5f58c6251625e4f2e8fb62173a975cdc374336d47d4f6368d5076ee1db393da60f
7
+ data.tar.gz: c488fdc913c0806f16deb27c891064c48141c19fd67944f7b80117f946f6b9ad2a61034772e09837261625dab84469eee9606fbd2626aa15e8840b175b0aafdf
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.2.2
1
+ 1.3.0.pre1
@@ -20,7 +20,7 @@ module Kontena
20
20
  return unless command.exit_code == 0
21
21
  return unless current_master.grid.nil?
22
22
 
23
- Kontena.run('grid list --use --verbose')
23
+ Kontena.run(%w(grid list --use --verbose))
24
24
  end
25
25
  end
26
26
  end
@@ -39,7 +39,7 @@ module Kontena
39
39
  puts
40
40
  puts "You don't seem to be logged in to Kontena Cloud"
41
41
  puts
42
- Kontena.run("cloud login --verbose")
42
+ Kontena.run!(%w(cloud login --verbose))
43
43
  config.reset_instance
44
44
  reset_cloud_client
45
45
  result = false
@@ -50,10 +50,15 @@ module Kontena
50
50
  end
51
51
 
52
52
  require 'shellwords'
53
- cmd = "master login --no-login-info --skip-grid-auto-select --verbose --name #{command.result[:name].shellescape} --code #{command.result[:code].shellescape} #{new_master.url.shellescape}"
53
+ cmd = [
54
+ 'master', 'login', '--no-login-info' ,'--skip-grid-auto-select', '--verbose',
55
+ '--name', command.result[:name],
56
+ '--code', command.result[:code],
57
+ new_master.url
58
+ ]
54
59
  Retriable.retriable do
55
60
  ENV["DEBUG"] && $stderr.puts("Running: #{cmd}")
56
- Kontena.run(cmd)
61
+ Kontena.run!(cmd)
57
62
  end
58
63
  end
59
64
  end
@@ -11,10 +11,9 @@ module Kontena
11
11
  return unless config.current_master
12
12
  return unless config.current_master.name == command.result[:name]
13
13
 
14
- cmd = "grid create --silent test"
15
- ENV["DEBUG"] && $stderr.puts("Running: #{cmd}")
14
+ cmd = %w(grid create --silent test)
16
15
  Retriable.retriable do
17
- Kontena.run(cmd)
16
+ Kontena.run!(cmd)
18
17
  end
19
18
  end
20
19
  end
@@ -15,8 +15,8 @@ module Kontena
15
15
  require 'shellwords'
16
16
 
17
17
  cmd = ['master', 'config', 'set', "server.provider=#{command.result[:provider]}"]
18
- spinner "Setting Master configuration server.provider to '#{command.result[:provider]}'" do
19
- Kontena.run(cmd.shelljoin)
18
+ spinner "Setting Master configuration server.provider to '#{command.result[:provider]}'" do |spin|
19
+ spin.fail! unless Kontena.run(cmd)
20
20
  end
21
21
  end
22
22
  end
@@ -8,15 +8,11 @@ module Kontena
8
8
 
9
9
  def init_cloud_args
10
10
  args = []
11
- args << '--force'
11
+ args << '--force'
12
12
  args << "--cloud-master-id #{command.cloud_master_id}" if command.cloud_master_id
13
13
  args << "--provider #{command.result[:provider]}" if command.result[:provider]
14
14
  args << "--version #{command.result[:version]}" if command.result[:version]
15
- args.join(' ')
16
- end
17
-
18
- def configure_auth_provider
19
- Kontena.run("master init-cloud #{init_cloud_args}")
15
+ args
20
16
  end
21
17
 
22
18
  def after
@@ -25,11 +21,10 @@ module Kontena
25
21
  return unless command.result.has_key?(:name)
26
22
  return unless config.current_master
27
23
  return unless config.current_master.name == command.result[:name]
28
- if command.respond_to?(:skip_auth_provider?) && command.skip_auth_provider?
29
- return
30
- end
31
24
 
32
- configure_auth_provider
25
+ unless command.respond_to?(:skip_auth_provider?) && command.skip_auth_provider?
26
+ Kontena.run(['master', 'init-cloud'] + init_cloud_args)
27
+ end
33
28
  end
34
29
  end
35
30
  end
@@ -32,36 +32,30 @@ module Kontena
32
32
 
33
33
  invite_response = nil
34
34
  spinner "Creating user #{cloud_user_data[:email]} into Kontena Master" do |spin|
35
- invite_response = Kontena.run(["master", "user", "invite", "--external-id", cloud_user_data[:id], "--return", cloud_user_data[:email]], returning: :result)
36
- unless invite_response.kind_of?(Hash) && invite_response.has_key?('invite_code')
37
- spin.fail
38
- end
35
+ invite_response = Kontena.run(["master", "user", "invite", "--external-id", cloud_user_data[:id], "--return", cloud_user_data[:email]])
36
+ spin.fail! unless invite_response.kind_of?(Hash) && invite_response.has_key?('invite_code')
39
37
  end
40
38
 
41
39
  return nil unless invite_response
42
40
  ENV["DEBUG"] && $stderr.puts("Got invite code: #{invite_response['invite_code']}")
43
41
 
44
- role_status = nil
45
-
46
- spinner "Adding master_admin role for #{cloud_user_data[:email]}" do |spin|
47
- role_status = Kontena.run(["master", "user", "role", "add", "--silent", "master_admin", cloud_user_data[:email]])
48
- spin.fail if role_status.to_i > 0
42
+ success = spinner "Adding master_admin role for #{cloud_user_data[:email]}" do |spin|
43
+ spin.fail! unless Kontena.run(["master", "user", "role", "add", "--silent", "master_admin", cloud_user_data[:email]])
44
+ true
49
45
  end
50
46
 
51
- return nil if role_status.to_i > 0
47
+ return nil unless success
52
48
 
53
49
  if current_master.grid
54
50
  spinner "Adding #{cloud_user_data[:email]} to grid '#{current_master.grid}'" do |spin|
55
- grid_add_status = Kontena.run(["grid", "user", "add", "--grid", current_master.grid, cloud_user_data[:email]])
56
- spin.fail if grid_add_status.to_i > 0
51
+ spin.fail! unless Kontena.run(["grid", "user", "add", "--grid", current_master.grid, cloud_user_data[:email]])
57
52
  end
58
53
  end
59
54
 
60
- return unless current_master.username.to_s == 'admin'
55
+ return nil unless current_master.username.to_s == 'admin'
61
56
 
62
- new_user_token = nil
63
- spinner "Creating an access token for #{cloud_user_data[:email]}" do |spin|
64
- new_user_token = Kontena.run(["master", "token", "create", "-e", "0", "-s", "user", "--return", "-u", cloud_user_data[:email]], returning: :result)
57
+ new_user_token = spinner "Creating an access token for #{cloud_user_data[:email]}" do |spin|
58
+ Kontena.run!(["master", "token", "create", "-e", "0", "-s", "user", "--return", "-u", cloud_user_data[:email]])
65
59
  end
66
60
 
67
61
  master_name = current_master.name.dup
@@ -1,6 +1,8 @@
1
1
 
2
2
  class Kontena::Cli::AppCommand < Kontena::Command
3
3
 
4
+ warn Kontena.pastel.yellow("[DEPRECATED] The `kontena app` commands are deprecated in favor of `kontena stack` commands and will be removed in future releases")
5
+
4
6
  subcommand "init", "Init Kontena application", load_subcommand('apps/init_command')
5
7
  subcommand "build", "Build Kontena services", load_subcommand('apps/build_command')
6
8
  subcommand "config", "View service configurations", load_subcommand('apps/config_command')
@@ -47,7 +47,7 @@ module Kontena::Cli::Cloud::Master
47
47
  masters = []
48
48
  spinner "Retrieving a list of your registered Kontena Masters in Kontena Cloud" do |spin|
49
49
  begin
50
- masters = Kontena.run("cloud master list --return", returning: :result)
50
+ masters = Kontena.run!(%w(cloud master list --return))
51
51
  rescue SystemExit
52
52
  spin.fail
53
53
  end
@@ -96,12 +96,12 @@ module Kontena::Cli::Cloud::Master
96
96
  end
97
97
  if response && response.kind_of?(Hash) && response.has_key?('data') && response['data']['attributes']
98
98
  if (self.provider && response['data']['attributes']['provider'] != self.provider) || (self.version && response['data']['attributes']['version'] != self.version)
99
- spinner "Updating provider and version attributes to Kontena Cloud master" do
99
+ spinner "Updating provider and version attributes to Kontena Cloud master" do |spin|
100
100
  args = []
101
- args << "--provider #{self.provider.shellescape}" if self.provider
102
- args << "--version #{self.version.shellescape}" if self.version
101
+ args += ['--provider', self.provider] if self.provider
102
+ args += ['--version', self.version] if self.version
103
103
  args << self.cloud_master_id
104
- Kontena.run("cloud master update #{args.join(' ')}")
104
+ spin.fail! unless Kontena.run(['cloud', 'master', 'update'] + args)
105
105
  end
106
106
  end
107
107
  end
@@ -111,18 +111,27 @@ module Kontena::Cli::Cloud::Master
111
111
  end
112
112
  end
113
113
 
114
- spinner "Loading Kontena Cloud auth provider base configuration to Kontena Master" do
115
- Kontena.run('master config import --force --preset kontena_auth_provider')
114
+ spinner "Loading Kontena Cloud auth provider base configuration to Kontena Master" do |spin|
115
+ spin.fail! unless Kontena.run(%w(master config import --force --preset kontena_auth_provider))
116
116
  end
117
117
 
118
- spinner "Updating OAuth2 client-id and client-secret to Kontena Master" do
119
- Kontena.run("master config set oauth2.client_id=#{response['data']['attributes']['client-id'].shellescape} oauth2.client_secret=#{response['data']['attributes']['client-secret'].shellescape} server.root_url=#{current_master.url.shellescape} server.name=#{current_master.name.shellescape} cloud.provider_is_kontena=true")
118
+ spinner "Updating OAuth2 client-id and client-secret to Kontena Master" do |spin|
119
+ spin.fail! unless Kontena.run(
120
+ [
121
+ 'master', 'config', 'set',
122
+ "oauth2.client_id=#{response['data']['attributes']['client-id'].shellescape}",
123
+ "oauth2.client_secret=#{response['data']['attributes']['client-secret'].shellescape}",
124
+ "server.root_url=#{current_master.url.shellescape}",
125
+ "server.name=#{current_master.name.shellescape}",
126
+ "cloud.provider_is_kontena=true"
127
+ ]
128
+ )
120
129
  end
121
130
  end
122
131
 
123
132
  def execute
124
133
  unless cloud_client.authentication_ok?(kontena_account.userinfo_endpoint)
125
- Kontena.run('cloud login')
134
+ Kontena.run!(%w(cloud login))
126
135
  config.reset_instance
127
136
  reset_cloud_client
128
137
  end
@@ -296,44 +296,14 @@ module Kontena
296
296
  def any_key_to_continue_with_timeout(timeout=9)
297
297
  return nil if running_silent?
298
298
  return nil unless $stdout.tty?
299
- start_time = Time.now.to_i
300
- end_time = start_time + timeout
301
- Thread.main['any_key.timed_out'] = false
302
- msg = "Press any key to continue or ctrl-c to cancel.. (Automatically continuing in ? seconds)"
303
-
304
- reader_thread = Thread.new do
305
- Thread.main['any_key.char'] = $stdin.getch
306
- end
307
-
308
- countdown_thread = Thread.new do
309
- time_left = timeout
310
- while time_left > 0 && Thread.main['any_key.char'].nil?
311
- print "\r#{pastel.bright_white("#{msg.sub("?", time_left.to_s)}")} "
312
- time_left = end_time - Time.now.to_i
313
- sleep 0.1
314
- end
315
- print "\r#{' ' * msg.length} \r"
316
- reader_thread.kill if reader_thread.alive?
317
- end
318
-
319
- countdown_thread.join
320
-
321
- if Thread.main['any_key.char'] == "\u0003"
322
- error "Canceled"
323
- end
299
+ prompt.keypress("Press any key to continue or ctrl-c to cancel (Automatically continuing in :countdown seconds) ...", timeout: timeout)
324
300
  end
325
301
 
326
302
  def any_key_to_continue(timeout = nil)
327
303
  return nil if running_silent?
328
304
  return nil unless $stdout.tty?
329
305
  return any_key_to_continue_with_timeout(timeout) if timeout
330
- msg = "Press any key to continue or ctrl-c to cancel.. "
331
- print pastel.bright_cyan("#{msg}")
332
- char = $stdin.getch
333
- print "\r#{' ' * msg.length}\r"
334
- if char == "\u0003"
335
- error "Canceled"
336
- end
306
+ prompt.keypress("Press any key to continue or ctrl-c to cancel..")
337
307
  end
338
308
 
339
309
  def display_account_login_info
@@ -1,17 +1,17 @@
1
1
  module Kontena::Cli::Grids::TrustedSubnets
2
2
  class AddCommand < Kontena::Command
3
3
  include Kontena::Cli::Common
4
+ include Kontena::Cli::GridOptions
4
5
 
5
- parameter "NAME", "Grid name"
6
6
  parameter "SUBNET", "Trusted subnet"
7
7
 
8
+ requires_current_master
9
+
8
10
  def execute
9
- require_api_url
10
- token = require_token
11
- grid = client(token).get("grids/#{name}")
11
+ grid = client.get("grids/#{current_grid}")
12
12
  data = {trusted_subnets: grid['trusted_subnets'] + [self.subnet]}
13
- spinner "Adding #{subnet.colorize(:cyan)} as a trusted subnet in #{name.colorize(:cyan)} grid " do
14
- client(token).put("grids/#{name}", data)
13
+ spinner "Adding #{subnet.colorize(:cyan)} as a trusted subnet in #{current_grid.colorize(:cyan)} grid " do
14
+ client.put("grids/#{current_grid}", data)
15
15
  end
16
16
  end
17
17
  end
@@ -1,13 +1,12 @@
1
1
  module Kontena::Cli::Grids::TrustedSubnets
2
2
  class ListCommand < Kontena::Command
3
3
  include Kontena::Cli::Common
4
+ include Kontena::Cli::GridOptions
4
5
 
5
- parameter "NAME", "Grid name"
6
+ requires_current_master
6
7
 
7
8
  def execute
8
- require_api_url
9
- token = require_token
10
- grid = client(token).get("grids/#{current_grid}")
9
+ grid = client.get("grids/#{current_grid}")
11
10
  trusted_subnets = grid['trusted_subnets'] || []
12
11
  trusted_subnets.each do |subnet|
13
12
  puts subnet
@@ -1,23 +1,23 @@
1
1
  module Kontena::Cli::Grids::TrustedSubnets
2
2
  class RemoveCommand < Kontena::Command
3
3
  include Kontena::Cli::Common
4
+ include Kontena::Cli::GridOptions
4
5
 
5
- parameter "NAME", "Grid name"
6
6
  parameter "SUBNET", "Trusted subnet"
7
7
  option "--force", :flag, "Force remove", default: false, attribute_name: :forced
8
8
 
9
+ requires_current_master
10
+
9
11
  def execute
10
- require_api_url
11
- token = require_token
12
- grid = client(token).get("grids/#{name}")
12
+ grid = client.get("grids/#{current_grid}")
13
13
  confirm_command(subnet) unless forced?
14
14
  trusted_subnets = grid['trusted_subnets'] || []
15
15
  unless trusted_subnets.delete(self.subnet)
16
- exit_with_error("Grid #{name.colorize(:cyan)} does not have trusted subnet #{subnet.colorize(:cyan)}")
16
+ exit_with_error("Grid #{current_grid.colorize(:cyan)} does not have trusted subnet #{subnet.colorize(:cyan)}")
17
17
  end
18
18
  data = {trusted_subnets: trusted_subnets}
19
- spinner "Removing trusted subnet #{subnet.colorize(:cyan)} from #{name.colorize(:cyan)} grid " do
20
- client(token).put("grids/#{name}", data)
19
+ spinner "Removing trusted subnet #{subnet.colorize(:cyan)} from #{current_grid.colorize(:cyan)} grid " do
20
+ client.put("grids/#{current_grid}", data)
21
21
  end
22
22
  end
23
23
  end
@@ -66,9 +66,8 @@ module Kontena::Cli::Master
66
66
  end
67
67
  end
68
68
  end
69
- command = cmd_class.to_s[/Plugin::(.+?)::/, 1].downcase
70
- command << " master create #{options.join(" ")}"
71
- Kontena.run(command)
69
+ cmd = [cmd_class.to_s[/Plugin::(.+?)::/, 1].downcase, 'master', 'create'] + options
70
+ Kontena.run!(cmd)
72
71
  end
73
72
  end
74
73
 
@@ -20,7 +20,7 @@ module Kontena::Cli::Master
20
20
  args += ["--cloud-master-id", self.cloud_master_id.shellescape] if self.cloud_master_id
21
21
  args += ["--provider", self.provider.shellescape] if self.provider
22
22
  args += ["--version", self.version.shellescape] if self.version
23
- Kontena.run("cloud master add #{args.join(' ')}")
23
+ Kontena.run!(['cloud', 'master', 'add'] + args)
24
24
  end
25
25
  end
26
26
  end
@@ -14,7 +14,9 @@ module Kontena::Cli::Master
14
14
  params << "--name #{self.name.shellescape}" if self.name
15
15
  params << "--verbose" if self.verbose?
16
16
 
17
- Kontena.run("master login #{params.join(' ')} #{self.url.shellescape}")
17
+ cmd = ['master', 'login'] + params
18
+ cmd << url
19
+ Kontena.run!(cmd)
18
20
  end
19
21
  end
20
22
  end
@@ -16,20 +16,17 @@ module Kontena::Cli::Master
16
16
  end
17
17
 
18
18
  def master_provider
19
- Kontena.run('master config get --return server.provider', returning: :result)
19
+ Kontena.run!(%w(master config get --return server.provider))
20
20
  end
21
21
 
22
22
  def execute
23
-
24
- commands_list.insert('--') unless commands_list.empty?
25
-
26
23
  if master_provider == 'vagrant'
27
24
  unless Kontena::PluginManager.instance.plugins.find { |plugin| plugin.name == 'kontena-plugin-vagrant' }
28
25
  exit_with_error 'You need to install vagrant plugin to ssh into this node. Use kontena plugin install vagrant'
29
26
  end
30
27
  cmd = ['vagrant', 'master', 'ssh']
31
28
  cmd += commands_list
32
- Kontena.run(cmd)
29
+ Kontena.run!(cmd)
33
30
  else
34
31
  cmd = ['ssh']
35
32
  cmd << "#{user}@#{master_host}"
@@ -40,4 +37,3 @@ module Kontena::Cli::Master
40
37
  end
41
38
  end
42
39
  end
43
-
@@ -33,7 +33,7 @@ module Kontena::Cli::Master::Token
33
33
  exit 0
34
34
  end
35
35
 
36
- Kontena.run("master token show #{current_master.token.access_token}")
36
+ Kontena.run!(['master', 'token', 'show', current_master.token.access_token])
37
37
  end
38
38
  end
39
39
  end
@@ -39,11 +39,11 @@ module Kontena::Cli::Master::User
39
39
  puts " * command: kontena master join #{current_master.url} #{response['invite_code']}"
40
40
  end
41
41
  roles.each do |role|
42
- Kontena.run(["master", "user", "role", "add", role, email])
42
+ raise "Failed to add role" unless Kontena.run(["master", "user", "role", "add", role, email])
43
43
  end
44
44
  rescue => ex
45
- $stderr.puts pastel.red("Failed to invite #{email}")
46
45
  ENV["DEBUG"] && $stderr.puts("#{ex} : #{ex.message}\n#{ex.backtrace.join("\n ")}")
46
+ exit_with_error "Failed to invite #{email} : #{ex.message}"
47
47
  end
48
48
  end
49
49
  end
@@ -1,5 +1,3 @@
1
- require 'kontena/cli/master/user_command'
2
-
3
1
  module Kontena::Cli::Master
4
2
  class UserCommand < Kontena::Command
5
3
  subcommand "invite", "Invite user to Kontena Master", load_subcommand('master/user/invite_command')
@@ -28,14 +28,12 @@ module Kontena::Cli::Nodes
28
28
 
29
29
  provider = Array(node["labels"]).find{ |l| l.start_with?('provider=')}.to_s.split('=').last
30
30
 
31
- commands_list.insert('--') unless commands_list.empty?
32
-
33
31
  if provider == 'vagrant'
34
32
  unless Kontena::PluginManager.instance.plugins.find { |plugin| plugin.name == 'kontena-plugin-vagrant' }
35
33
  exit_with_error 'You need to install vagrant plugin to ssh into this node. Use kontena plugin install vagrant'
36
34
  end
37
35
  cmd = ['vagrant', 'node', 'ssh', node['name']] + commands_list
38
- Kontena.run(cmd)
36
+ Kontena.run!(cmd)
39
37
  else
40
38
  cmd = ['ssh']
41
39
  cmd += ["-i", identity_file] if identity_file
@@ -11,6 +11,8 @@ class Kontena::Cli::StackCommand < Kontena::Command
11
11
  subcommand "build", "Build images listed in a stack file and push them to an image registry", load_subcommand('stacks/build_command')
12
12
  subcommand ["reg", "registry"], "Stack registry related commands", load_subcommand('stacks/registry_command')
13
13
  subcommand "validate", "Process and validate a stack file", load_subcommand('stacks/validate_command')
14
+ subcommand "stop", "Stop stacks services", load_subcommand('stacks/stop_command')
15
+ subcommand "restart", "Restart stacks services", load_subcommand('stacks/restart_command')
14
16
 
15
17
  def execute
16
18
  end
@@ -154,7 +154,7 @@ module Kontena::Cli::Stacks
154
154
 
155
155
  def stacks_client
156
156
  return @stacks_client if @stacks_client
157
- Kontena.run('cloud login') unless cloud_auth?
157
+ Kontena.run!(%w(cloud login)) unless cloud_auth?
158
158
  config.reset_instance
159
159
  @stacks_client = Kontena::StacksClient.new(kontena_account.stacks_url, kontena_account.token)
160
160
  end
@@ -26,7 +26,7 @@ module Kontena::Cli::Stacks
26
26
  spinner "Creating stack #{pastel.cyan(stack['name'])} " do
27
27
  create_stack(stack)
28
28
  end
29
- Kontena.run("stack deploy #{stack['name']}") if deploy?
29
+ Kontena.run!(['stack', 'deploy', stack['name']]) if deploy?
30
30
  end
31
31
 
32
32
  def create_stack(stack)
@@ -0,0 +1,23 @@
1
+ require_relative 'common'
2
+
3
+ module Kontena::Cli::Stacks
4
+ class RestartCommand < Kontena::Command
5
+ include Kontena::Cli::Common
6
+ include Kontena::Cli::GridOptions
7
+ include Common
8
+
9
+ banner "Restarts all services of a stack that has been installed in a grid on Kontena Master"
10
+
11
+ parameter "NAME", "Stack name"
12
+
13
+ requires_current_master
14
+ requires_current_master_token
15
+
16
+ def execute
17
+ spinner "Sending restart signal for stack services" do
18
+ client.post("stacks/#{current_grid}/#{name}/restart", {})
19
+ end
20
+ end
21
+
22
+ end
23
+ end
@@ -0,0 +1,23 @@
1
+ require_relative 'common'
2
+
3
+ module Kontena::Cli::Stacks
4
+ class StopCommand < Kontena::Command
5
+ include Kontena::Cli::Common
6
+ include Kontena::Cli::GridOptions
7
+ include Common
8
+
9
+ banner "Stops all services of a stack that has been installed in a grid on Kontena Master"
10
+
11
+ parameter "NAME", "Stack name"
12
+
13
+ requires_current_master
14
+ requires_current_master_token
15
+
16
+ def execute
17
+ spinner "Sending stop signal for stack services" do
18
+ client.post("stacks/#{current_grid}/#{name}/stop", {})
19
+ end
20
+ end
21
+
22
+ end
23
+ end
@@ -37,7 +37,7 @@ module Kontena::Cli::Stacks
37
37
  update_stack(stack) || spin.fail!
38
38
  end
39
39
 
40
- Kontena.run(['stack', 'deploy', name]) if deploy?
40
+ Kontena.run!(['stack', 'deploy', name]) if deploy?
41
41
  end
42
42
 
43
43
  def update_stack(stack)
@@ -43,7 +43,7 @@ module Kontena::Cli::Stacks::YAML
43
43
  )
44
44
  end
45
45
  elsif value.is_a?(Array)
46
- value.all? { |v| v.kind_of?(String) && v =~ /\A\S+(?<!\\)=.*/ }
46
+ value.all? { |v| v.kind_of?(String) && v =~ /\A[^=]+=/ }
47
47
  else
48
48
  false
49
49
  end
@@ -13,8 +13,8 @@ module Kontena::Cli::Vault
13
13
  require 'shellwords'
14
14
  meth = json? ? :to_json : :to_yaml
15
15
  puts Hash[
16
- *Kontena.run('vault ls --return', returning: :result).sort.flat_map do |secret|
17
- [secret, Kontena.run("vault read --return #{secret.shellescape}", returning: :result)]
16
+ *Kontena.run!(['vault', 'ls', '--return']).sort.flat_map do |secret|
17
+ [secret, Kontena.run!(['vault', 'read', '--return', secret])]
18
18
  end
19
19
  ].send(meth)
20
20
  end
@@ -14,10 +14,6 @@ module Kontena::Cli::Vault
14
14
 
15
15
  requires_current_master
16
16
 
17
- UPDATE_CMD = 'vault update --upsert --silent %{key} %{value}'
18
- DELETE_CMD = 'vault rm --silent --force %{key}'
19
-
20
-
21
17
  def parsed_input
22
18
  json? ? JSON.load(input) : YAML.safe_load(input)
23
19
  end
@@ -60,18 +56,16 @@ module Kontena::Cli::Vault
60
56
 
61
57
  unless updates.empty?
62
58
  spinner "Updating #{updates.size} secrets" do |spin|
63
- updates.each do |pair|
64
- result = Kontena.run(UPDATE_CMD % { key: pair.first.shellescape, value: pair.last.shellescape })
65
- spin.fail! unless result.zero?
59
+ updates.each do |key_value_pair|
60
+ spin.fail! unless Kontena.run(['vault', 'update', '--upsert', '--silent'] + key_value_pair)
66
61
  end
67
62
  end
68
63
  end
69
64
 
70
65
  unless deletes.empty? || skip_null?
71
66
  spinner "Deleting #{deletes.size} secrets" do |spin|
72
- deletes.map(&:shellescape).each do |del|
73
- result = Kontena.run(DELETE_CMD % { key: del })
74
- spin.fail! unless result.zero?
67
+ deletes.map(&:shellescape).each do |key_to_delete|
68
+ spin.fail! unless Kontena.run(['vault', 'rm', '--silent', '--force', key_to_delete])
75
69
  end
76
70
  end
77
71
  end
@@ -51,6 +51,6 @@ class Kontena::MainCommand < Kontena::Command
51
51
  end
52
52
 
53
53
  def known_plugin_subcommand?(name)
54
- ['vagrant', 'packet', 'digitalocean', 'azure', 'upcloud', 'aws'].include?(name)
54
+ ['vagrant', 'packet', 'digitalocean', 'azure', 'upcloud', 'aws', 'shell'].include?(name)
55
55
  end
56
56
  end