kontena-cli 1.1.0.rc1 → 1.1.0.rc2

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 (41) hide show
  1. checksums.yaml +4 -4
  2. data/VERSION +1 -1
  3. data/lib/kontena/cli/apps/deploy_command.rb +1 -5
  4. data/lib/kontena/cli/cloud/login_command.rb +9 -1
  5. data/lib/kontena/cli/common.rb +2 -2
  6. data/lib/kontena/cli/etcd/health_command.rb +58 -0
  7. data/lib/kontena/cli/etcd_command.rb +2 -0
  8. data/lib/kontena/cli/external_registry_command.rb +0 -2
  9. data/lib/kontena/cli/master/login_command.rb +5 -7
  10. data/lib/kontena/cli/service_command.rb +2 -2
  11. data/lib/kontena/cli/services/deploy_command.rb +1 -5
  12. data/lib/kontena/cli/services/exec_command.rb +84 -0
  13. data/lib/kontena/cli/services/services_helper.rb +4 -1
  14. data/lib/kontena/cli/stacks/common.rb +6 -17
  15. data/lib/kontena/cli/stacks/install_command.rb +2 -10
  16. data/lib/kontena/cli/stacks/show_command.rb +30 -4
  17. data/lib/kontena/cli/stacks/upgrade_command.rb +20 -7
  18. data/lib/kontena/cli/stacks/validate_command.rb +1 -9
  19. data/lib/kontena/cli/stacks/yaml/opto/service_link_resolver.rb +45 -0
  20. data/lib/kontena/cli/stacks/yaml/opto/vault_cert_prompt_resolver.rb +15 -0
  21. data/lib/kontena/cli/stacks/yaml/opto/vault_resolver.rb +1 -0
  22. data/lib/kontena/cli/stacks/yaml/reader.rb +36 -26
  23. data/lib/kontena/command.rb +5 -0
  24. data/lib/kontena/main_command.rb +5 -4
  25. data/lib/kontena_cli.rb +4 -0
  26. data/spec/fixtures/stack-with-prompted-variables.yml +5 -1
  27. data/spec/fixtures/stack-with-variables.yml +5 -1
  28. data/spec/kontena/cli/cloud/login_command_spec.rb +1 -0
  29. data/spec/kontena/cli/etcd/health_command_spec.rb +87 -0
  30. data/spec/kontena/cli/master/login_command_spec.rb +8 -17
  31. data/spec/kontena/cli/services/exec_command_spec.rb +137 -0
  32. data/spec/kontena/cli/stacks/install_command_spec.rb +5 -5
  33. data/spec/kontena/cli/stacks/upgrade_command_spec.rb +39 -32
  34. data/spec/kontena/cli/stacks/yaml/reader_spec.rb +22 -0
  35. data/spec/support/client_helpers.rb +6 -2
  36. data/spec/support/output_helpers.rb +23 -0
  37. metadata +11 -7
  38. data/lib/kontena/cli/external_registries/delete_command.rb +0 -15
  39. data/lib/kontena/cli/login_command.rb +0 -12
  40. data/lib/kontena/cli/register_command.rb +0 -9
  41. data/lib/kontena/cli/services/delete_command.rb +0 -19
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 8e7c1e0f1f4b7150cbb38ae75bd31b5d9c011018
4
- data.tar.gz: 105cd534097a4479c050b0ca174014c61b327677
3
+ metadata.gz: f7edb62c595acf6b8f5aaea89084034682684ff6
4
+ data.tar.gz: c90522985a940d60902b7f817b5e1c1e9c26ebec
5
5
  SHA512:
6
- metadata.gz: c8fb7ead66ba6c861d79544f3955b13eadf8e3ceab55fbf3f3a1c108f7bcf23730ee97fccec1cf74b5d2ea8239af9eeb5ac6453b5892eb4b60ddbeda4392d9de
7
- data.tar.gz: 27978ab4aea44afadff0f59119b993771e36ef3fc4a8688e15d88d3a3cf54525600d70b4d8b5c566790063f8b5a603a25d1a782c0eac8ea81c70805faf2299b1
6
+ metadata.gz: f213b43e9dc53072014b7ded6f3700a4ff3158f1865c7c7c73aa63fd123af5372f8c7c9bf120dde7ae481104b43eef59e8e991e22cb76edc2472b9e1086e9146
7
+ data.tar.gz: 2d2d45f3431164ab8a56ce97b77d5296f6e03788c2e2f9dc0cefbecf2b2672219f377a09c7078a7512e1fead10dff3f721970ca32e4ed764571013d5bbde11b1
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.1.0.rc1
1
+ 1.1.0.rc2
@@ -14,7 +14,6 @@ module Kontena::Cli::Apps
14
14
  option ['-p', '--project-name'], 'NAME', 'Specify an alternate project name (default: directory name)'
15
15
  option '--async', :flag, 'Run deploys async/parallel'
16
16
  option '--force', :flag, 'Force deploy even if service does not have any changes'
17
- option '--force-deploy', :flag, '[DEPRECATED: use --force]'
18
17
 
19
18
  option '--skip-validation', :flag, 'Skip YAML file validation', default: false
20
19
  parameter "[SERVICE] ...", "Services to start"
@@ -46,10 +45,7 @@ module Kontena::Cli::Apps
46
45
  queue.each do |service|
47
46
  name = service['id'].split('/').last
48
47
  options = {}
49
- options[:force] = true if force? || force_deploy? # deprecated
50
- if force_deploy?
51
- warning " --force-deploy will deprecate in the future, use --force"
52
- end
48
+ options[:force] = true if force?
53
49
  spinner "Deploying #{unprefixed_name(name).colorize(:cyan)} " do
54
50
  deployment = deploy_service(token, name, options)
55
51
  unless async?
@@ -51,6 +51,14 @@ module Kontena::Cli::Cloud
51
51
  end
52
52
 
53
53
  def web_flow
54
+ if Kontena.browserless? && !force?
55
+ STDERR.puts "Your current environment does not seem to support opening a local graphical WWW browser."
56
+ STDERR.puts
57
+ STDERR.puts "You can perorm a login on another computer, copy the token and use it with 'kontena cloud login --token <token>'."
58
+ STDERR.puts "There will be an easier way to log in from a browserless environment soon."
59
+ exit_with_error 'Unable to launch a web browser'
60
+ end
61
+
54
62
  require_relative '../localhost_web_server'
55
63
  require 'launchy'
56
64
 
@@ -85,7 +93,7 @@ module Kontena::Cli::Cloud
85
93
 
86
94
  server_thread = Thread.new { Thread.main['response'] = web_server.serve_one }
87
95
  browser_thread = Thread.new { Launchy.open(uri.to_s) }
88
-
96
+
89
97
  spinner "Waiting for browser authorization response" do
90
98
  server_thread.join
91
99
  end
@@ -92,12 +92,12 @@ module Kontena
92
92
 
93
93
  def warning(msg)
94
94
  warning = pastel.yellow('warn')
95
- STDERR.puts " [#{warning}] #{msg}"
95
+ $stderr.puts " [#{warning}] #{msg}"
96
96
  end
97
97
 
98
98
  def exit_with_error(msg, code = 1)
99
99
  error = pastel.red('error')
100
- STDERR.puts " [#{error}] #{msg}"
100
+ $stderr.puts " [#{error}] #{msg}"
101
101
  exit code
102
102
  end
103
103
 
@@ -0,0 +1,58 @@
1
+ require_relative 'common'
2
+
3
+ module Kontena::Cli::Etcd
4
+ class HealthCommand < Kontena::Command
5
+ include Kontena::Cli::Common
6
+ include Kontena::Cli::GridOptions
7
+ include Kontena::Cli::Helpers::HealthHelper
8
+
9
+ parameter "[NODE]", "Show health for specific node"
10
+
11
+ requires_current_master
12
+ requires_current_grid
13
+
14
+ def execute
15
+ require_api_url
16
+ token = require_token
17
+
18
+ health = true
19
+
20
+ if self.node
21
+ node_health = client.get("nodes/#{current_grid}/#{self.node}/health")
22
+
23
+ health = show_node_health(node_health)
24
+ else
25
+ nodes = client.get("grids/#{current_grid}/nodes")['nodes']
26
+
27
+ nodes.each do |node|
28
+ node_health = client.get("nodes/#{current_grid}/#{node['name']}/health")
29
+
30
+ if !show_node_health(node_health)
31
+ health = false
32
+ end
33
+ end
34
+ end
35
+
36
+ return health
37
+ end
38
+
39
+ # @return [Boolean]
40
+ def show_node_health(node_health)
41
+ etcd_health = node_health['etcd_health']
42
+
43
+ if !node_health['connected']
44
+ puts "#{health_icon :offline} Node #{node_health['name']} is offline"
45
+ return false
46
+ elsif etcd_health['health']
47
+ puts "#{health_icon :ok} Node #{node_health['name']} is healthy"
48
+ return true
49
+ elsif etcd_health['error']
50
+ puts "#{health_icon :error} Node #{node_health['name']} is unhealthy: #{etcd_health['error']}"
51
+ return false
52
+ else
53
+ puts "#{health_icon :error} Node #{node_health['name']} is unhealthy"
54
+ return false
55
+ end
56
+ end
57
+ end
58
+ end
@@ -3,6 +3,7 @@ require_relative 'etcd/set_command'
3
3
  require_relative 'etcd/mkdir_command'
4
4
  require_relative 'etcd/list_command'
5
5
  require_relative 'etcd/remove_command'
6
+ require_relative 'etcd/health_command'
6
7
 
7
8
  class Kontena::Cli::EtcdCommand < Kontena::Command
8
9
 
@@ -11,6 +12,7 @@ class Kontena::Cli::EtcdCommand < Kontena::Command
11
12
  subcommand ["mkdir", "mk"], "Create a directory", Kontena::Cli::Etcd::MkdirCommand
12
13
  subcommand ["list", "ls"], "List a directory", Kontena::Cli::Etcd::ListCommand
13
14
  subcommand "rm", "Remove a key or a directory", Kontena::Cli::Etcd::RemoveCommand
15
+ subcommand "health", "Check etcd health", Kontena::Cli::Etcd::HealthCommand
14
16
 
15
17
  def execute
16
18
  end
@@ -1,6 +1,5 @@
1
1
  require_relative 'external_registries/add_command'
2
2
  require_relative 'external_registries/list_command'
3
- require_relative 'external_registries/delete_command'
4
3
  require_relative 'external_registries/remove_command'
5
4
 
6
5
  class Kontena::Cli::ExternalRegistryCommand < Kontena::Command
@@ -8,7 +7,6 @@ class Kontena::Cli::ExternalRegistryCommand < Kontena::Command
8
7
  subcommand "add", "Add external Docker image registry", Kontena::Cli::ExternalRegistries::AddCommand
9
8
  subcommand ["list", "ls"], "List external Docker image registries", Kontena::Cli::ExternalRegistries::ListCommand
10
9
  subcommand ["remove", "rm"], "Remove external Docker image registry", Kontena::Cli::ExternalRegistries::RemoveCommand
11
- subcommand "delete", "[DEPRECATED] Delete external Docker image registry", Kontena::Cli::ExternalRegistries::DeleteCommand
12
10
 
13
11
  def execute
14
12
  end
@@ -9,7 +9,7 @@ module Kontena::Cli::Master
9
9
  option ['-t', '--token'], '[TOKEN]', 'Use a pre-generated access token', environment_variable: 'KONTENA_TOKEN'
10
10
  option ['-n', '--name'], '[NAME]', 'Set server name', environment_variable: 'KONTENA_MASTER'
11
11
  option ['-c', '--code'], '[CODE]', 'Use authorization code generated during master install'
12
- option ['-r', '--remote'], :flag, 'Do not try to open a browser'
12
+ option ['-r', '--[no-]remote'], :flag, 'Login using a browser on another device', default: Kontena.browserless?
13
13
  option ['-e', '--expires-in'], '[SECONDS]', 'Request token with expiration of X seconds. Use 0 to never expire', default: 7200
14
14
  option ['-v', '--verbose'], :flag, 'Increase output verbosity'
15
15
  option ['-f', '--force'], :flag, 'Force reauthentication'
@@ -69,13 +69,14 @@ module Kontena::Cli::Master
69
69
  if self.remote?
70
70
  # no local browser? tell user to launch an external one
71
71
  display_remote_message(server, auth_params)
72
- update_server_to_config(server)
73
- exit 1
72
+ auth_code = prompt.ask("Enter code displayed in browser:")
73
+ use_authorization_code(server, auth_code)
74
74
  else
75
75
  # local web flow
76
76
  web_flow(server, auth_params)
77
- display_login_info(only: :master) unless (running_silent? || self.no_login_info?)
78
77
  end
78
+
79
+ display_login_info(only: :master) unless (running_silent? || self.no_login_info?)
79
80
  end
80
81
 
81
82
  def next_default_name
@@ -170,9 +171,6 @@ module Kontena::Cli::Master
170
171
  else
171
172
  puts "Visit this URL in a browser:"
172
173
  puts "#{url}"
173
- puts
174
- puts "Then complete the authentication by using:"
175
- puts "kontena master login --code <CODE FROM BROWSER> #{server.url}"
176
174
  end
177
175
  end
178
176
 
@@ -7,7 +7,6 @@ require_relative 'services/start_command'
7
7
  require_relative 'services/restart_command'
8
8
  require_relative 'services/create_command'
9
9
  require_relative 'services/scale_command'
10
- require_relative 'services/delete_command'
11
10
  require_relative 'services/remove_command'
12
11
  require_relative 'services/containers_command'
13
12
  require_relative 'services/logs_command'
@@ -19,6 +18,7 @@ require_relative 'services/secret_command'
19
18
 
20
19
  require_relative 'services/link_command'
21
20
  require_relative 'services/unlink_command'
21
+ require_relative 'services/exec_command'
22
22
 
23
23
  class Kontena::Cli::ServiceCommand < Kontena::Command
24
24
 
@@ -32,7 +32,6 @@ class Kontena::Cli::ServiceCommand < Kontena::Command
32
32
  subcommand "restart", "Restart service", Kontena::Cli::Services::RestartCommand
33
33
  subcommand "scale", "Scale service", Kontena::Cli::Services::ScaleCommand
34
34
  subcommand ["remove", "rm"], "Remove service", Kontena::Cli::Services::RemoveCommand
35
- subcommand "delete", "[DEPRECATED] Delete service", Kontena::Cli::Services::DeleteCommand
36
35
  subcommand "containers", "List service containers", Kontena::Cli::Services::ContainersCommand
37
36
  subcommand "logs", "Show service logs", Kontena::Cli::Services::LogsCommand
38
37
  subcommand "stats", "Show service statistics", Kontena::Cli::Services::StatsCommand
@@ -44,6 +43,7 @@ class Kontena::Cli::ServiceCommand < Kontena::Command
44
43
 
45
44
  subcommand "link", "Link service to another service", Kontena::Cli::Services::LinkCommand
46
45
  subcommand "unlink", "Unlink service from another service", Kontena::Cli::Services::UnlinkCommand
46
+ subcommand "exec", "Execute commands in service containers", Kontena::Cli::Services::ExecCommand
47
47
 
48
48
  def execute
49
49
  end
@@ -8,17 +8,13 @@ module Kontena::Cli::Services
8
8
 
9
9
  parameter "NAME", "Service name"
10
10
  option '--force', :flag, 'Force deploy even if service does not have any changes'
11
- option '--force-deploy', :flag, '[DEPRECATED: use --force]'
12
11
 
13
12
  def execute
14
13
  require_api_url
15
14
  token = require_token
16
15
  service_id = name
17
16
  data = {}
18
- data[:force] = true if force? || force_deploy? # deprecated
19
- if force_deploy?
20
- warning "--force-deploy will deprecate in the future, use --force"
21
- end
17
+ data[:force] = true if force?
22
18
  spinner "Deploying service #{name.colorize(:cyan)} " do
23
19
  deployment = deploy_service(token, name, data)
24
20
  wait_for_deploy_to_finish(token, deployment)
@@ -0,0 +1,84 @@
1
+ require_relative 'services_helper'
2
+
3
+ module Kontena::Cli::Services
4
+ class ExecCommand < Kontena::Command
5
+ include Kontena::Cli::Common
6
+ include Kontena::Cli::GridOptions
7
+ include ServicesHelper
8
+
9
+ parameter "NAME", "Service name"
10
+ parameter "CMD ...", "Command"
11
+
12
+ option ["-i", "--instance"], "INSTANCE", "Exec on given numbered instance, default first running" do |value| Integer(value) end
13
+ option ["-a", "--all"], :flag, "Exec on all running instances"
14
+ option ["--shell"], :flag, "Execute as a shell command"
15
+ option ["--skip"], :flag, "Skip failed instances when executing --all"
16
+ option ["--silent"], :flag, "Do not show exec status"
17
+ option ["--verbose"], :flag, "Show exec status"
18
+
19
+ requires_current_master
20
+ requires_current_grid
21
+
22
+ # Exits if exec returns with non-zero
23
+ def exec_container(container)
24
+ if shell?
25
+ cmd = ['sh', '-c', cmd_list.join(' ')]
26
+ else
27
+ cmd = cmd_list
28
+ end
29
+
30
+ stdout = stderr = exit_status = nil
31
+
32
+ if !silent? && (verbose? || all?)
33
+ spinner "Executing command on #{container['name']}" do
34
+ stdout, stderr, exit_status = client.post("containers/#{container['id']}/exec", {cmd: cmd})
35
+
36
+ raise Kontena::Cli::SpinAbort if exit_status != 0
37
+ end
38
+ else
39
+ stdout, stderr, exit_status = client.post("containers/#{container['id']}/exec", {cmd: cmd})
40
+ end
41
+
42
+ stdout.each do |chunk| $stdout.write chunk end
43
+ stderr.each do |chunk| $stderr.write chunk end
44
+
45
+ exit exit_status if exit_status != 0 && !skip?
46
+
47
+ return exit_status == 0
48
+ end
49
+
50
+ def execute
51
+ service_containers = client.get("services/#{parse_service_id(name)}/containers")['containers']
52
+ service_containers.sort_by! { |container| container['instance_number'] }
53
+ running_containers = service_containers.select{|container| container['status'] == 'running' }
54
+
55
+ if running_containers.empty?
56
+ exit_with_error "Service #{name} does not have any running containers"
57
+ end
58
+
59
+ if all?
60
+ ret = true
61
+ service_containers.each do |container|
62
+ if container['status'] == 'running'
63
+ if !exec_container(container)
64
+ ret = false
65
+ end
66
+ else
67
+ warning "Service #{name} container #{container['name']} is #{container['status']}, skipping"
68
+ end
69
+ end
70
+ return ret
71
+ elsif instance
72
+ if !(container = service_containers.find{|container| container['instance_number'] == instance})
73
+ exit_with_error "Service #{name} does not have container instance #{instance}"
74
+ elsif container['status'] != 'running'
75
+ exit_with_error "Service #{name} container #{container['name']} is not running, it is #{container['status']}"
76
+ else
77
+ exec_container(container)
78
+ end
79
+ else
80
+ exec_container(running_containers.first)
81
+ end
82
+ end
83
+ end
84
+ end
@@ -43,10 +43,13 @@ module Kontena
43
43
  service = get_service(token, service_id)
44
44
  grid = service['id'].split('/')[0]
45
45
  puts "#{service['id']}:"
46
+ puts " created: #{service['created_at']}"
47
+ puts " updated: #{service['updated_at']}"
46
48
  puts " stack: #{service['stack']['id'] }"
47
- puts " status: #{service['state'] }"
49
+ puts " state: #{service['state'] }"
48
50
  puts " image: #{service['image']}"
49
51
  puts " revision: #{service['revision']}"
52
+ puts " stack_revision: #{service['stack_revision']}" if service['stack_revision']
50
53
  puts " stateful: #{service['stateful'] == true ? 'yes' : 'no' }"
51
54
  puts " scaling: #{service['instances'] }"
52
55
  puts " strategy: #{service['strategy']}"
@@ -21,18 +21,8 @@ module Kontena::Cli::Stacks
21
21
  end
22
22
 
23
23
  module StackFileOrNameParam
24
- attr_accessor :from_registry
25
-
26
24
  def self.included(where)
27
- where.parameter "[FILE]", "Kontena stack file or a registry stack name (user/stack or user/stack:version)", default: "kontena.yml", attribute_name: :filename do |filename|
28
- if !File.exist?(filename) && filename =~ /\A[a-zA-Z0-9\_\.\-]+\/[a-zA-Z0-9\_\.\-]+(?::.*)?\z/
29
- @from_registry = true
30
- else
31
- @from_registry = false
32
- require_config_file(filename)
33
- end
34
- filename
35
- end
25
+ where.parameter "[FILE]", "Kontena stack file, registry stack name (user/stack or user/stack:version) or URL", default: "kontena.yml", attribute_name: :filename
36
26
  end
37
27
  end
38
28
 
@@ -59,8 +49,8 @@ module Kontena::Cli::Stacks
59
49
  @stack_name ||= self.name || stack_name_from_yaml(filename)
60
50
  end
61
51
 
62
- def reader_from_yaml(filename, from_registry: false, name: nil, values: nil)
63
- reader = Kontena::Cli::Stacks::YAML::Reader.new(filename, from_registry: from_registry, values: values)
52
+ def reader_from_yaml(filename, name: nil, values: nil, defaults: nil)
53
+ reader = Kontena::Cli::Stacks::YAML::Reader.new(filename, values: values, defaults: defaults)
64
54
  if reader.stack_name.nil?
65
55
  exit_with_error "Stack MUST have stack name in YAML top level field 'stack'! Aborting."
66
56
  end
@@ -68,8 +58,8 @@ module Kontena::Cli::Stacks
68
58
  reader
69
59
  end
70
60
 
71
- def stack_from_yaml(filename, from_registry: false, name: nil, values: nil)
72
- reader = reader_from_yaml(filename, from_registry: from_registry, name: name, values: values)
61
+ def stack_from_yaml(filename, name: nil, values: nil, defaults: nil)
62
+ reader = reader_from_yaml(filename, name: name, values: values, defaults: defaults)
73
63
  outcome = reader.execute
74
64
 
75
65
  hint_on_validation_notifications(outcome[:notifications]) if outcome[:notifications].size > 0
@@ -83,8 +73,7 @@ module Kontena::Cli::Stacks
83
73
  'source' => reader.raw_content,
84
74
  'registry' => 'file://',
85
75
  'services' => kontena_services,
86
- 'variables' => outcome[:variables],
87
- 'vault_keys' => outcome[:vault_keys]
76
+ 'variables' => outcome[:variables]
88
77
  }
89
78
  stack
90
79
  end
@@ -11,7 +11,7 @@ module Kontena::Cli::Stacks
11
11
  include Common::StackFileOrNameParam
12
12
 
13
13
  include Common::StackNameOption
14
- option '--deploy', :flag, 'Deploy after installation'
14
+ option '--[no-]deploy', :flag, 'Trigger deploy after installation', default: true
15
15
 
16
16
  include Common::StackValuesFromOption
17
17
 
@@ -20,15 +20,7 @@ module Kontena::Cli::Stacks
20
20
  requires_current_master_token
21
21
 
22
22
  def execute
23
-
24
- if !File.exist?(filename) && filename =~ /\A[a-zA-Z0-9\_\.\-]+\/[a-zA-Z0-9\_\.\-]+(?::.*)?\z/
25
- from_registry = true
26
- else
27
- from_registry = false
28
- require_config_file(filename)
29
- end
30
-
31
- stack = stack_from_yaml(filename, from_registry: from_registry, name: name, values: values)
23
+ stack = stack_from_yaml(filename, name: name, values: values)
32
24
 
33
25
  stack['name'] = name if name
34
26
  spinner "Creating stack #{pastel.cyan(stack['name'])} " do
@@ -25,11 +25,12 @@ module Kontena::Cli::Stacks
25
25
  stack = fetch_stack(name)
26
26
 
27
27
  puts "#{stack['name']}:"
28
+ puts " created: #{stack['created_at']}"
29
+ puts " updated: #{stack['updated_at']}"
28
30
  puts " state: #{stack['state']}"
29
31
  puts " stack: #{stack['stack']}"
30
32
  puts " version: #{stack['version']}"
31
- puts " created_at: #{stack['created_at']}"
32
- puts " updated_at: #{stack['updated_at']}"
33
+ puts " revision: #{stack['revision']}"
33
34
  puts " expose: #{stack['expose'] || '-'}"
34
35
  puts " services:"
35
36
  stack['services'].each do |service|
@@ -43,14 +44,16 @@ module Kontena::Cli::Stacks
43
44
  service = get_service(token, service_id)
44
45
  pad = ' '.freeze
45
46
  puts "#{pad}#{service['name']}:"
47
+ puts "#{pad} created: #{service['created_at']}"
48
+ puts "#{pad} updated: #{service['updated_at']}"
46
49
  puts "#{pad} image: #{service['image']}"
47
- puts "#{pad} status: #{service['state'] }"
50
+ puts "#{pad} revision: #{service['stack_revision']}"
51
+ puts "#{pad} state: #{service['state'] }"
48
52
  if service['health_status']
49
53
  puts "#{pad} health_status:"
50
54
  puts "#{pad} healthy: #{service['health_status']['healthy']}"
51
55
  puts "#{pad} total: #{service['health_status']['total']}"
52
56
  end
53
- puts "#{pad} revision: #{service['revision']}"
54
57
  puts "#{pad} stateful: #{service['stateful'] == true ? 'yes' : 'no' }"
55
58
  puts "#{pad} scaling: #{service['instances'] }"
56
59
  puts "#{pad} strategy: #{service['strategy']}"
@@ -71,6 +74,15 @@ module Kontena::Cli::Stacks
71
74
  end
72
75
  end
73
76
 
77
+ if service['secrets'].to_a.size > 0
78
+ puts "#{pad} secrets: "
79
+ service['secrets'].to_a.each do |s|
80
+ puts "#{pad} - secret: #{s['secret']}"
81
+ puts "#{pad} name: #{s['name']}"
82
+ puts "#{pad} type: #{s['type']}"
83
+ end
84
+ end
85
+
74
86
  unless service['cmd'].to_s.empty?
75
87
  if service['cmd']
76
88
  puts "#{pad} cmd: #{service['cmd'].join(' ')}"
@@ -86,6 +98,20 @@ module Kontena::Cli::Stacks
86
98
  end
87
99
  end
88
100
 
101
+ if service['volumes'].to_a.size > 0
102
+ puts "#{pad} volumes:"
103
+ service['volumes'].to_a.each do |v|
104
+ puts "#{pad} - #{v}"
105
+ end
106
+ end
107
+
108
+ if service['volumes_from'].to_a.size > 0
109
+ puts "#{pad} volumes_from:"
110
+ service['volumes_from'].to_a.each do |v|
111
+ puts "#{pad} - #{v}"
112
+ end
113
+ end
114
+
89
115
  if service['links'].to_a.size > 0
90
116
  puts "#{pad} links: "
91
117
  service['links'].to_a.each do |l|