kontena-cli 1.3.0.pre1 → 1.3.0.pre2
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.
- checksums.yaml +4 -4
- data/VERSION +1 -1
- data/bin/kontena +2 -1
- data/lib/kontena/callback.rb +1 -1
- data/lib/kontena/callbacks/auth/01_list_and_select_grid_after_master_auth.rb +1 -2
- data/lib/kontena/callbacks/master/01_clear_current_master_after_terminate.rb +2 -3
- data/lib/kontena/callbacks/master/deploy/01_show_logo_before_deploy.rb +1 -2
- data/lib/kontena/callbacks/master/deploy/05_before_deploy_configuration_wizard.rb +2 -2
- data/lib/kontena/callbacks/master/deploy/40_install_ssl_certificate_after_deploy.rb +2 -2
- data/lib/kontena/callbacks/master/deploy/50_authenticate_after_deploy.rb +9 -9
- data/lib/kontena/callbacks/master/deploy/55_create_initial_grid_after_deploy.rb +2 -2
- data/lib/kontena/callbacks/master/deploy/56_set_server_provider_after_deploy.rb +1 -2
- data/lib/kontena/callbacks/master/deploy/60_configure_auth_provider_after_deploy.rb +1 -2
- data/lib/kontena/callbacks/master/deploy/70_invite_self_after_deploy.rb +2 -3
- data/lib/kontena/callbacks/master/deploy/90_proptip_after_deploy.rb +2 -2
- data/lib/kontena/cli/apps/common.rb +0 -1
- data/lib/kontena/cli/apps/init_command.rb +2 -0
- data/lib/kontena/cli/apps/kontena_yml_generator.rb +2 -1
- data/lib/kontena/cli/apps/list_command.rb +10 -2
- data/lib/kontena/cli/apps/yaml/reader.rb +2 -1
- data/lib/kontena/cli/apps/yaml/service_extender.rb +0 -1
- data/lib/kontena/cli/cloud/login_command.rb +51 -7
- data/lib/kontena/cli/cloud/master/list_command.rb +14 -11
- data/lib/kontena/cli/common.rb +36 -83
- data/lib/kontena/cli/config.rb +46 -29
- data/lib/kontena/cli/containers/list_command.rb +30 -41
- data/lib/kontena/cli/etcd/list_command.rb +12 -7
- data/lib/kontena/cli/external_registries/list_command.rb +14 -8
- data/lib/kontena/cli/grids/list_command.rb +18 -10
- data/lib/kontena/cli/grids/trusted_subnets/list_command.rb +7 -5
- data/lib/kontena/cli/grids/users/list_command.rb +9 -7
- data/lib/kontena/cli/localhost_web_server.rb +3 -3
- data/lib/kontena/cli/log_formatters/compact.rb +65 -0
- data/lib/kontena/cli/log_formatters/strip_color.rb +13 -0
- data/lib/kontena/cli/master/config/import_command.rb +2 -1
- data/lib/kontena/cli/master/config/set_command.rb +1 -1
- data/lib/kontena/cli/master/list_command.rb +16 -10
- data/lib/kontena/cli/master/token/list_command.rb +23 -12
- data/lib/kontena/cli/master/user/invite_command.rb +1 -1
- data/lib/kontena/cli/master/user/list_command.rb +17 -6
- data/lib/kontena/cli/nodes/labels/list_command.rb +3 -0
- data/lib/kontena/cli/nodes/list_command.rb +58 -37
- data/lib/kontena/cli/nodes/show_command.rb +1 -1
- data/lib/kontena/cli/plugins/install_command.rb +2 -2
- data/lib/kontena/cli/plugins/list_command.rb +19 -5
- data/lib/kontena/cli/plugins/uninstall_command.rb +1 -1
- data/lib/kontena/cli/services/containers_command.rb +7 -0
- data/lib/kontena/cli/services/envs/list_command.rb +6 -4
- data/lib/kontena/cli/services/list_command.rb +47 -36
- data/lib/kontena/cli/services/services_helper.rb +9 -16
- data/lib/kontena/cli/services/stats_command.rb +2 -1
- data/lib/kontena/cli/spinner.rb +3 -5
- data/lib/kontena/cli/stacks/common.rb +4 -4
- data/lib/kontena/cli/stacks/list_command.rb +42 -33
- data/lib/kontena/cli/stacks/registry/search_command.rb +6 -0
- data/lib/kontena/cli/stacks/registry/show_command.rb +2 -0
- data/lib/kontena/cli/stacks/registry_command.rb +1 -2
- data/lib/kontena/cli/stacks/validate_command.rb +1 -0
- data/lib/kontena/cli/stacks/yaml/reader.rb +3 -2
- data/lib/kontena/cli/stacks/yaml/service_extender.rb +0 -1
- data/lib/kontena/cli/stacks/yaml/validations.rb +1 -1
- data/lib/kontena/cli/table_generator.rb +125 -0
- data/lib/kontena/cli/vault/export_command.rb +7 -4
- data/lib/kontena/cli/vault/import_command.rb +3 -0
- data/lib/kontena/cli/vault/list_command.rb +23 -10
- data/lib/kontena/cli/volumes/create_command.rb +8 -4
- data/lib/kontena/cli/volumes/list_command.rb +15 -7
- data/lib/kontena/client.rb +44 -33
- data/lib/kontena/command.rb +7 -4
- data/lib/kontena/debug_instrumentor.rb +10 -9
- data/lib/kontena/main_command.rb +1 -3
- data/lib/kontena/plugin_manager.rb +15 -7
- data/lib/kontena/stacks_cache.rb +7 -7
- data/lib/kontena/stacks_client.rb +24 -5
- data/lib/kontena/util.rb +43 -15
- data/lib/kontena_cli.rb +71 -14
- data/spec/kontena/cli/cloud/login_command_spec.rb +42 -0
- data/spec/kontena/cli/containers/list_command_spec.rb +1 -2
- data/spec/kontena/cli/nodes/list_command_spec.rb +153 -126
- data/spec/kontena/cli/registry/create_spec.rb +22 -0
- data/spec/kontena/cli/services/stats_command_spec.rb +22 -0
- data/spec/kontena/cli/table_generator_spec.rb +118 -0
- data/spec/kontena/cli/version_command_spec.rb +2 -2
- data/spec/kontena/client_spec.rb +4 -3
- data/spec/support/client_helpers.rb +3 -3
- data/spec/support/output_helpers.rb +54 -8
- metadata +11 -2
|
@@ -6,18 +6,23 @@ module Kontena::Cli::Etcd
|
|
|
6
6
|
include Kontena::Cli::GridOptions
|
|
7
7
|
include Common
|
|
8
8
|
|
|
9
|
-
parameter "KEY", "Etcd key"
|
|
9
|
+
parameter "[KEY]", "Etcd key", default: '/'
|
|
10
10
|
|
|
11
|
-
option
|
|
11
|
+
option ['-r', '--recursive'], :flag, "List keys recursively", default: false
|
|
12
|
+
|
|
13
|
+
# the command outputs id info only anyway, this is here strictly for ignoring purposes
|
|
14
|
+
option ['-q', '--quiet'], :flag, "Output the identifying column only", hidden: true
|
|
15
|
+
|
|
16
|
+
requires_current_master
|
|
17
|
+
requires_current_master_token
|
|
12
18
|
|
|
13
19
|
def execute
|
|
14
|
-
require_api_url
|
|
15
|
-
token = require_token
|
|
16
20
|
validate_key
|
|
17
21
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
22
|
+
response = spin_if(!quiet?, "Retrieving keys from etcd") do
|
|
23
|
+
client.get("etcd/#{current_grid}/#{key}#{'?recursive=true' if recursive?}")
|
|
24
|
+
end
|
|
25
|
+
|
|
21
26
|
if response['children']
|
|
22
27
|
children = response['children'].map{|c| c['key'] }
|
|
23
28
|
puts children.join("\n")
|
|
@@ -2,16 +2,22 @@ module Kontena::Cli::ExternalRegistries
|
|
|
2
2
|
class ListCommand < Kontena::Command
|
|
3
3
|
include Kontena::Cli::Common
|
|
4
4
|
include Kontena::Cli::GridOptions
|
|
5
|
+
include Kontena::Cli::TableGenerator::Helper
|
|
6
|
+
|
|
7
|
+
requires_current_master
|
|
8
|
+
requires_current_master_token
|
|
9
|
+
requires_current_grid
|
|
10
|
+
|
|
11
|
+
def fields
|
|
12
|
+
quiet? ? %(name) : %w(name username email)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def external_registries
|
|
16
|
+
client.get("grids/#{current_grid}/external_registries")['external_registries']
|
|
17
|
+
end
|
|
5
18
|
|
|
6
19
|
def execute
|
|
7
|
-
|
|
8
|
-
require_current_grid
|
|
9
|
-
token = require_token
|
|
10
|
-
result = client(token).get("grids/#{current_grid}/external_registries")
|
|
11
|
-
puts "%-30s %-20s %-30s" % ['Name', 'Username', 'Email']
|
|
12
|
-
result['external_registries'].each { |r|
|
|
13
|
-
puts "%-30.30s %-20.20s %-30.30s" % [r['name'], r['username'], r['email']]
|
|
14
|
-
}
|
|
20
|
+
print_table(external_registries)
|
|
15
21
|
end
|
|
16
22
|
end
|
|
17
23
|
end
|
|
@@ -3,14 +3,25 @@ require_relative 'common'
|
|
|
3
3
|
module Kontena::Cli::Grids
|
|
4
4
|
class ListCommand < Kontena::Command
|
|
5
5
|
include Kontena::Cli::Common
|
|
6
|
+
include Kontena::Cli::TableGenerator::Helper
|
|
6
7
|
include Common
|
|
7
8
|
|
|
8
9
|
option ['-u', '--use'], :flag, 'Automatically use first available grid sorted by user count', hidden: true
|
|
9
10
|
option ['-v', '--verbose'], :flag, 'Use a more verbose output', hidden: true
|
|
10
11
|
|
|
12
|
+
requires_current_master
|
|
13
|
+
requires_current_master_token
|
|
14
|
+
|
|
15
|
+
def fields
|
|
16
|
+
{ name: 'name', nodes: 'node_count', services: 'service_count', users: 'user_count' }
|
|
17
|
+
end
|
|
18
|
+
|
|
11
19
|
def execute
|
|
12
|
-
|
|
13
|
-
|
|
20
|
+
if quiet?
|
|
21
|
+
puts grids['grids'].map { |grid| grid['name'] }.join("\n")
|
|
22
|
+
exit 0
|
|
23
|
+
end
|
|
24
|
+
|
|
14
25
|
vputs
|
|
15
26
|
|
|
16
27
|
gridlist = []
|
|
@@ -28,16 +39,13 @@ module Kontena::Cli::Grids
|
|
|
28
39
|
vputs "You have access to the following grids:"
|
|
29
40
|
vputs
|
|
30
41
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
name = "#{grid['name']} *"
|
|
35
|
-
else
|
|
36
|
-
name = grid['name']
|
|
37
|
-
end
|
|
38
|
-
puts '%-30.30s %-8s %-12s %-10s' % [name, grid['node_count'], grid['service_count'], grid['user_count']]
|
|
42
|
+
if current_grid
|
|
43
|
+
current_grid_entry = gridlist.find { |grid| grid['name'] == current_grid }
|
|
44
|
+
current_grid_entry['name'] += pastel.yellow(' *') if current_grid_entry
|
|
39
45
|
end
|
|
40
46
|
|
|
47
|
+
print_table(gridlist)
|
|
48
|
+
|
|
41
49
|
if self.use?
|
|
42
50
|
vputs
|
|
43
51
|
vspinner "* Selecting '#{gridlist.first['name']}' as the current grid" do
|
|
@@ -1,16 +1,18 @@
|
|
|
1
|
+
require 'kontena/cli/grids/common'
|
|
2
|
+
|
|
1
3
|
module Kontena::Cli::Grids::TrustedSubnets
|
|
2
4
|
class ListCommand < Kontena::Command
|
|
3
5
|
include Kontena::Cli::Common
|
|
4
6
|
include Kontena::Cli::GridOptions
|
|
7
|
+
include Kontena::Cli::Grids::Common
|
|
8
|
+
|
|
9
|
+
# the command outputs id info only anyway, this is here strictly for ignoring purposes
|
|
10
|
+
option ['-q', '--quiet'], :flag, "Output the identifying column only", hidden: true
|
|
5
11
|
|
|
6
12
|
requires_current_master
|
|
7
13
|
|
|
8
14
|
def execute
|
|
9
|
-
|
|
10
|
-
trusted_subnets = grid['trusted_subnets'] || []
|
|
11
|
-
trusted_subnets.each do |subnet|
|
|
12
|
-
puts subnet
|
|
13
|
-
end
|
|
15
|
+
Array(get_grid['trusted_subnets']).map(&method(:puts))
|
|
14
16
|
end
|
|
15
17
|
end
|
|
16
18
|
end
|
|
@@ -4,15 +4,17 @@ module Kontena::Cli::Grids::Users
|
|
|
4
4
|
class ListCommand < Kontena::Command
|
|
5
5
|
include Kontena::Cli::Common
|
|
6
6
|
include Kontena::Cli::Grids::Common
|
|
7
|
+
include Kontena::Cli::TableGenerator::Helper
|
|
8
|
+
include Kontena::Cli::GridOptions
|
|
9
|
+
|
|
10
|
+
requires_current_master
|
|
11
|
+
|
|
12
|
+
def fields
|
|
13
|
+
quiet? ? %w(email) : %w(email name)
|
|
14
|
+
end
|
|
7
15
|
|
|
8
16
|
def execute
|
|
9
|
-
|
|
10
|
-
token = require_token
|
|
11
|
-
result = client(token).get("grids/#{current_grid}/users")
|
|
12
|
-
puts "%-40s %-40s" % ['Email', 'Name']
|
|
13
|
-
result['users'].each { |user|
|
|
14
|
-
puts "%-40.40s %-40.40s" % [user['email'], user['name']]
|
|
15
|
-
}
|
|
17
|
+
print_table(client.get("grids/#{current_grid}/users")['users'])
|
|
16
18
|
end
|
|
17
19
|
end
|
|
18
20
|
end
|
|
@@ -39,7 +39,7 @@ module Kontena
|
|
|
39
39
|
#
|
|
40
40
|
# @return [Hash] query_params
|
|
41
41
|
def serve_one
|
|
42
|
-
|
|
42
|
+
Kontena.logger.debug("LHWS") { "Waiting for connection on port #{port}.." }
|
|
43
43
|
socket = server.accept
|
|
44
44
|
|
|
45
45
|
content = socket.recvfrom(2048).first.split(/(?:\r)?\n/)
|
|
@@ -56,7 +56,7 @@ module Kontena
|
|
|
56
56
|
|
|
57
57
|
body = content.join("\n")
|
|
58
58
|
|
|
59
|
-
|
|
59
|
+
Kontena.logger.debug("LHWS") { "Got request: \"#{request.inspect}\n Headers: #{headers.inspect}\n Body: #{body}\"" }
|
|
60
60
|
|
|
61
61
|
get_request = request[/GET (\/cb.+?) HTTP/, 1]
|
|
62
62
|
if get_request
|
|
@@ -82,7 +82,7 @@ module Kontena
|
|
|
82
82
|
socket.close
|
|
83
83
|
server.close
|
|
84
84
|
uri = URI.parse("http://localhost#{get_request}")
|
|
85
|
-
|
|
85
|
+
Kontena.logger.debug("LHWS") { " * Parsing params: \"#{uri.query}\"" }
|
|
86
86
|
params = {}
|
|
87
87
|
URI.decode_www_form(uri.query).each do |key, value|
|
|
88
88
|
if value.to_s == ''
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
require 'logger'
|
|
2
|
+
|
|
3
|
+
module Kontena
|
|
4
|
+
module Cli
|
|
5
|
+
module LogFormatter
|
|
6
|
+
class Compact < Logger::Formatter
|
|
7
|
+
def self.ms_since_first
|
|
8
|
+
Time.now.to_f - @first_log
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def self.ms_since_last
|
|
12
|
+
((Time.now.to_f - @last_log) * 1000).to_i
|
|
13
|
+
ensure
|
|
14
|
+
@last_log = Time.now.to_f
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def self.__init_timers__
|
|
18
|
+
@first_log = $KONTENA_START_TIME || Time.now.to_f
|
|
19
|
+
@last_log = @first_log
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
__init_timers__
|
|
23
|
+
|
|
24
|
+
DEBUG_INDICATOR = Kontena.pastel.inverse.bright_blue('DEBUG').freeze
|
|
25
|
+
WARN_INDICATOR = Kontena.pastel.inverse.yellow('WARN ').freeze
|
|
26
|
+
INFO_INDICATOR = Kontena.pastel.inverse.cyan('INFO ').freeze
|
|
27
|
+
ERROR_INDICATOR = Kontena.pastel.inverse.red('ERROR').freeze
|
|
28
|
+
|
|
29
|
+
def colorize_severity(severity)
|
|
30
|
+
case severity[0..0]
|
|
31
|
+
when 'D' then DEBUG_INDICATOR
|
|
32
|
+
when 'W' then WARN_INDICATOR
|
|
33
|
+
when 'I' then INFO_INDICATOR
|
|
34
|
+
when 'E', 'F' then ERROR_INDICATOR
|
|
35
|
+
else severity[0..0]
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
TS_FORMAT = '%4d'.freeze
|
|
40
|
+
|
|
41
|
+
def colorized_time
|
|
42
|
+
elapsed = self.class.ms_since_last
|
|
43
|
+
ts = TS_FORMAT % [elapsed]
|
|
44
|
+
if elapsed > 300
|
|
45
|
+
Kontena.pastel.red(ts)
|
|
46
|
+
elsif elapsed > 100
|
|
47
|
+
Kontena.pastel.yellow(ts)
|
|
48
|
+
else
|
|
49
|
+
ts
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
if ENV['DEBUG_PERF']
|
|
54
|
+
define_method :call do |severity, time, progname, msg|
|
|
55
|
+
"#{colorize_severity(severity)} #{colorized_time} #{msg2str(msg)}\n"
|
|
56
|
+
end
|
|
57
|
+
else
|
|
58
|
+
define_method :call do |severity, time, progname, msg|
|
|
59
|
+
"#{colorize_severity(severity)} #{msg2str(msg)}\n"
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
|
@@ -40,7 +40,8 @@ module Kontena::Cli::Master::Config
|
|
|
40
40
|
require 'json'
|
|
41
41
|
JSON.parse(data)
|
|
42
42
|
when 'yaml', 'yml'
|
|
43
|
-
require
|
|
43
|
+
require "safe_yaml"
|
|
44
|
+
SafeYAML::OPTIONS[:default_mode] = :safe
|
|
44
45
|
YAML.safe_load(data)
|
|
45
46
|
else
|
|
46
47
|
exit_with_error "Unknown input format '#{self.format}'"
|
|
@@ -11,7 +11,7 @@ module Kontena::Cli::Master::Config
|
|
|
11
11
|
parameter "KEY_VALUE_PAIR ...", "Key/value pair, for example server.root_url=http://example.com", required: true
|
|
12
12
|
|
|
13
13
|
def execute
|
|
14
|
-
data =
|
|
14
|
+
data = self.key_value_pair_list.map{ |p| p.split('=') }.to_h
|
|
15
15
|
client.patch('config', data)
|
|
16
16
|
end
|
|
17
17
|
end
|
|
@@ -1,18 +1,24 @@
|
|
|
1
1
|
module Kontena::Cli::Master
|
|
2
2
|
class ListCommand < Kontena::Command
|
|
3
3
|
include Kontena::Cli::Common
|
|
4
|
+
include Kontena::Cli::TableGenerator::Helper
|
|
4
5
|
|
|
5
|
-
def
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
6
|
+
def fields
|
|
7
|
+
@fields ||= quiet? ? %w(name) : %w(name url)
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def current_master_name
|
|
11
|
+
@current_master_name ||= current_master.nil? ? nil : current_master.name
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def mark_if_current(row)
|
|
15
|
+
unless quiet?
|
|
16
|
+
row.name.insert(0, pastel.yellow('* ')) if row.name == current_master_name
|
|
15
17
|
end
|
|
16
18
|
end
|
|
19
|
+
|
|
20
|
+
def execute
|
|
21
|
+
print_table(config.servers, fields, &method(:mark_if_current))
|
|
22
|
+
end
|
|
17
23
|
end
|
|
18
24
|
end
|
|
@@ -2,25 +2,36 @@ require_relative 'common'
|
|
|
2
2
|
|
|
3
3
|
module Kontena::Cli::Master::Token
|
|
4
4
|
class ListCommand < Kontena::Command
|
|
5
|
-
|
|
5
|
+
include Kontena::Util
|
|
6
6
|
include Kontena::Cli::Common
|
|
7
|
+
include Kontena::Cli::TableGenerator::Helper
|
|
7
8
|
include Common
|
|
8
9
|
|
|
9
10
|
requires_current_master
|
|
10
11
|
requires_current_master_token
|
|
11
12
|
|
|
13
|
+
def fields
|
|
14
|
+
return ['id'] if quiet?
|
|
15
|
+
{ id: 'id', token_type: 'token_type', token_last4: 'access_token_last_four', expires_in: 'expires_in', scopes: 'scopes' }
|
|
16
|
+
end
|
|
17
|
+
|
|
12
18
|
def execute
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
19
|
+
data = Array(client.get("/oauth2/tokens")["tokens"])
|
|
20
|
+
print_table(data) do |row|
|
|
21
|
+
next if quiet?
|
|
22
|
+
row['expires_in'] = colorize(row['expires_in'].to_i)
|
|
23
|
+
row['token_type'] ||= row['grant_type']
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def colorize(expires_in)
|
|
28
|
+
return expires_in.to_s unless $stdout.tty?
|
|
29
|
+
if expires_in.zero?
|
|
30
|
+
pastel.yellow('never')
|
|
31
|
+
elsif expires_in < 0
|
|
32
|
+
pastel.red(time_ago(Time.now.to_i + expires_in))
|
|
33
|
+
else
|
|
34
|
+
pastel.green(time_until(expires_in))
|
|
24
35
|
end
|
|
25
36
|
end
|
|
26
37
|
end
|
|
@@ -42,7 +42,7 @@ module Kontena::Cli::Master::User
|
|
|
42
42
|
raise "Failed to add role" unless Kontena.run(["master", "user", "role", "add", role, email])
|
|
43
43
|
end
|
|
44
44
|
rescue => ex
|
|
45
|
-
|
|
45
|
+
logger.error(ex)
|
|
46
46
|
exit_with_error "Failed to invite #{email} : #{ex.message}"
|
|
47
47
|
end
|
|
48
48
|
end
|
|
@@ -3,15 +3,26 @@ require_relative '../../common'
|
|
|
3
3
|
module Kontena::Cli::Master::User
|
|
4
4
|
class ListCommand < Kontena::Command
|
|
5
5
|
include Kontena::Cli::Common
|
|
6
|
+
include Kontena::Cli::TableGenerator::Helper
|
|
7
|
+
|
|
8
|
+
requires_current_master
|
|
9
|
+
requires_current_master_token
|
|
10
|
+
|
|
11
|
+
def fields
|
|
12
|
+
quiet? ? ['id'] : { email: 'email', roles: 'role_list' }
|
|
13
|
+
end
|
|
6
14
|
|
|
7
15
|
def execute
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
16
|
+
response = spin_if(!quiet? && $stdout.tty?, "Retrieving user list from Kontena Master") do
|
|
17
|
+
client.get('users')['users']
|
|
18
|
+
end
|
|
11
19
|
|
|
12
|
-
response
|
|
13
|
-
|
|
14
|
-
|
|
20
|
+
print_table(response) do |row|
|
|
21
|
+
if row['roles'].empty?
|
|
22
|
+
row['role_list'] = ''
|
|
23
|
+
else
|
|
24
|
+
row['role_list'] = row['roles'].map { |r| r['name'] }.join(',')
|
|
25
|
+
end
|
|
15
26
|
end
|
|
16
27
|
end
|
|
17
28
|
end
|
|
@@ -4,6 +4,9 @@ module Kontena::Cli::Nodes::Labels
|
|
|
4
4
|
|
|
5
5
|
parameter "NODE_ID", "Node id"
|
|
6
6
|
|
|
7
|
+
# the command outputs id info only anyway, this is here strictly for ignoring purposes
|
|
8
|
+
option ['-q', '--quiet'], :flag, "Output the identifying column only", hidden: true
|
|
9
|
+
|
|
7
10
|
requires_current_master
|
|
8
11
|
requires_current_master_token
|
|
9
12
|
requires_current_grid
|
|
@@ -5,57 +5,78 @@ module Kontena::Cli::Nodes
|
|
|
5
5
|
include Kontena::Cli::Common
|
|
6
6
|
include Kontena::Cli::GridOptions
|
|
7
7
|
include Kontena::Cli::Helpers::HealthHelper
|
|
8
|
+
include Kontena::Cli::TableGenerator::Helper
|
|
8
9
|
|
|
9
|
-
option [
|
|
10
|
+
option ['-a', '--all'], :flag, 'List nodes for all grids', default: false
|
|
11
|
+
|
|
12
|
+
requires_current_master
|
|
13
|
+
requires_current_master_token
|
|
14
|
+
requires_current_grid
|
|
15
|
+
|
|
16
|
+
def node_name(node, grid)
|
|
17
|
+
return node['name'] unless all?
|
|
18
|
+
"#{grid['name']}/#{node['name']}"
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def node_status(node)
|
|
22
|
+
node['connected'] ? pastel.green('online') : pastel.red('offline')
|
|
23
|
+
end
|
|
10
24
|
|
|
11
25
|
def node_initial(node, grid)
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
else
|
|
15
|
-
return "-"
|
|
16
|
-
end
|
|
26
|
+
return '-' unless node['initial_member']
|
|
27
|
+
"#{node['node_number']} / #{grid['initial_size']}"
|
|
17
28
|
end
|
|
18
29
|
|
|
19
30
|
def node_labels(node)
|
|
20
|
-
(node['labels'] || ['-']).join(
|
|
21
|
-
end
|
|
22
|
-
|
|
23
|
-
def show_grid_nodes(grid, nodes, multi: false)
|
|
24
|
-
grid_health = grid_health(grid, nodes)
|
|
25
|
-
|
|
26
|
-
nodes = nodes.sort_by{|n| n['node_number'] }
|
|
27
|
-
nodes.each do |node|
|
|
28
|
-
puts [
|
|
29
|
-
"%s" % health_icon(node_health(node, grid_health)),
|
|
30
|
-
"%-70.70s" % [multi ? "#{grid['name']}/#{node['name']}" : node['name']],
|
|
31
|
-
"%-10s" % node['agent_version'],
|
|
32
|
-
"%-10s" % (node['connected'] ? "online" : "offline"),
|
|
33
|
-
"%-10s" % node_initial(node, grid),
|
|
34
|
-
"%s" % [node_labels(node)],
|
|
35
|
-
].join ' '
|
|
36
|
-
end
|
|
31
|
+
(node['labels'] || ['-']).join(',')
|
|
37
32
|
end
|
|
38
33
|
|
|
39
|
-
def
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
34
|
+
def fields
|
|
35
|
+
return ['name'] if quiet?
|
|
36
|
+
{
|
|
37
|
+
' ' => 'health_icon',
|
|
38
|
+
name: 'name',
|
|
39
|
+
version: 'agent_version',
|
|
40
|
+
status: 'status',
|
|
41
|
+
initial: 'initial',
|
|
42
|
+
labels: 'labels'
|
|
43
|
+
}
|
|
44
|
+
end
|
|
43
45
|
|
|
44
|
-
|
|
46
|
+
def grids
|
|
47
|
+
all? ? client.get("grids")['grids'] : [client.get("grids/#{current_grid}")]
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def grid_nodes(grid_name)
|
|
51
|
+
client.get("grids/#{grid_name}/nodes")['nodes']
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def node_data
|
|
55
|
+
grids.flat_map do |grid|
|
|
56
|
+
grid_nodes = []
|
|
45
57
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
58
|
+
grid_nodes(grid['id']).each do |node|
|
|
59
|
+
node['name'] = node_name(node, grid)
|
|
60
|
+
grid_nodes << node
|
|
61
|
+
next if quiet?
|
|
62
|
+
node['initial'] = node_initial(node, grid)
|
|
63
|
+
node['status'] = node_status(node)
|
|
64
|
+
node['labels'] = node_labels(node)
|
|
65
|
+
end
|
|
50
66
|
|
|
51
|
-
|
|
67
|
+
unless quiet?
|
|
68
|
+
grid_health = grid_health(grid, grid_nodes)
|
|
69
|
+
grid_nodes.each do |node|
|
|
70
|
+
node['health_icon'] = health_icon(node_health(node, grid_health))
|
|
71
|
+
end
|
|
52
72
|
end
|
|
53
|
-
else
|
|
54
|
-
grid = client(token).get("grids/#{current_grid}")
|
|
55
|
-
nodes = client(require_token).get("grids/#{current_grid}/nodes")['nodes']
|
|
56
73
|
|
|
57
|
-
|
|
74
|
+
grid_nodes.sort { |n| n['node_number'] }
|
|
58
75
|
end
|
|
59
76
|
end
|
|
77
|
+
|
|
78
|
+
def execute
|
|
79
|
+
print_table(node_data)
|
|
80
|
+
end
|
|
60
81
|
end
|
|
61
82
|
end
|