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
|
@@ -25,7 +25,8 @@ module Kontena::Cli::Stacks
|
|
|
25
25
|
attr_reader :file, :raw_content, :errors, :notifications, :defaults, :values, :registry
|
|
26
26
|
|
|
27
27
|
def initialize(file, skip_validation: false, skip_variables: false, variables: nil, values: nil, defaults: nil)
|
|
28
|
-
require
|
|
28
|
+
require "safe_yaml"
|
|
29
|
+
SafeYAML::OPTIONS[:default_mode] = :safe
|
|
29
30
|
require_relative 'service_extender'
|
|
30
31
|
require_relative 'validator_v3'
|
|
31
32
|
require_relative 'opto'
|
|
@@ -165,7 +166,7 @@ module Kontena::Cli::Stacks
|
|
|
165
166
|
template = Liquid::Template.parse(content)
|
|
166
167
|
|
|
167
168
|
# Wrap nil values in LiquidNull to not have Liquid consider them as undefined
|
|
168
|
-
vars =
|
|
169
|
+
vars = vars.map {|key, value| [key, value.nil? ? LiquidNull.new : value]}.to_h
|
|
169
170
|
|
|
170
171
|
template.render!(vars, strict_variables: true, strict_filters: true)
|
|
171
172
|
end
|
|
@@ -51,7 +51,7 @@ module Kontena::Cli::Stacks::YAML
|
|
|
51
51
|
'env_file' => optional(-> (value) { value.is_a?(String) || value.is_a?(Array) }),
|
|
52
52
|
'instances' => optional('integer'),
|
|
53
53
|
'links' => optional(-> (value) { value.is_a?(Array) || value.nil? }),
|
|
54
|
-
'ports' => optional(
|
|
54
|
+
'ports' => optional(-> (value) { value.is_a?(Array) && value.all? { |v| v.is_a?(String) && v.match(/\A(\d+\.\d+\.\d+\.\d+)?:?(\d+)\:(\d+)\/?(\w+)?\z/) } }),
|
|
55
55
|
'pid' => optional('string'),
|
|
56
56
|
'privileged' => optional('boolean'),
|
|
57
57
|
'user' => optional('string'),
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
require 'tty-table'
|
|
2
|
+
|
|
3
|
+
module Kontena
|
|
4
|
+
module Cli
|
|
5
|
+
class TableGenerator
|
|
6
|
+
|
|
7
|
+
attr_reader :data
|
|
8
|
+
attr_reader :fields
|
|
9
|
+
attr_reader :header
|
|
10
|
+
attr_reader :row_format_proc, :header_format_proc, :render_options, :render_mode
|
|
11
|
+
|
|
12
|
+
DEFAULT_HEADER_FORMAT_PROC = lambda { |header| header.to_s.capitalize }
|
|
13
|
+
|
|
14
|
+
module Helper
|
|
15
|
+
def self.included(base)
|
|
16
|
+
if base.respond_to?(:option)
|
|
17
|
+
base.option ['-q', '--quiet'], :flag, "Output the identifying column only"
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def table_generator
|
|
22
|
+
Kontena::Cli::TableGenerator
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def generate_table(array, fields = nil, &block)
|
|
26
|
+
fields ||= self.fields if self.respond_to?(:fields)
|
|
27
|
+
table_generator.new(
|
|
28
|
+
array,
|
|
29
|
+
fields,
|
|
30
|
+
row_format_proc: block_given? ? block.to_proc : nil,
|
|
31
|
+
header_format_proc: lambda { |item| pastel.blue(item.to_s.capitalize) },
|
|
32
|
+
render_options: self.respond_to?(:render_options) ? self.render_options : nil
|
|
33
|
+
).render
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def print_table(array, fields = nil, &block)
|
|
37
|
+
puts generate_table(array, fields, &block)
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
# @param data [Array<Hash>,Array<Array>] an array of hashes or arrays
|
|
42
|
+
# @param fields [Array] an array of field names found in the data hashes.
|
|
43
|
+
# @param fields [Hash] a hash of field_title => field_name_in_the_data_hash, for example 'Users' => 'user_count'
|
|
44
|
+
# @param fields [NilClass] try to auto detect fields (all fields!) from the data hashes
|
|
45
|
+
# @return [TTY::Table]
|
|
46
|
+
def initialize(data, fields = nil, row_format_proc: nil, header_format_proc: nil, render_options: nil)
|
|
47
|
+
@data = data
|
|
48
|
+
@render_options = render_options || { }
|
|
49
|
+
@render_mode = @render_options.delete(:mode) || :basic
|
|
50
|
+
@row_format_proc = row_format_proc
|
|
51
|
+
@header_format_proc = header_format_proc || DEFAULT_HEADER_FORMAT_PROC
|
|
52
|
+
@fields = parse_fields(fields)
|
|
53
|
+
@header = generate_header(fields || @fields)
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def create_table(header, rows)
|
|
57
|
+
TTY::Table.new(
|
|
58
|
+
header: header,
|
|
59
|
+
rows: rows
|
|
60
|
+
)
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def table
|
|
64
|
+
create_table(header, rows)
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def render
|
|
68
|
+
if data.empty?
|
|
69
|
+
fields.map(&method(:format_header_item)).join(' ')
|
|
70
|
+
else
|
|
71
|
+
table.render(render_mode, render_options)
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def format_row(row)
|
|
76
|
+
return row if row_format_proc.nil?
|
|
77
|
+
row_clone = row.dup
|
|
78
|
+
row_format_proc.call(row_clone)
|
|
79
|
+
row_clone
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def format_header_item(field_name)
|
|
83
|
+
header_format_proc.call(field_name)
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
def rows
|
|
87
|
+
fields.empty? ? data.map { |row| format_row(row).map(&:values) } : data.map { |row| format_row(row).values_at(*fields) }
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
# Collect all the unique keys from the hashes if the data
|
|
91
|
+
# is an array of hashes.
|
|
92
|
+
def detect_fields
|
|
93
|
+
if data.first.respond_to?(:keys)
|
|
94
|
+
data.flat_map(&:keys).uniq
|
|
95
|
+
else
|
|
96
|
+
[]
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
def parse_fields(fields)
|
|
101
|
+
if fields.nil? || fields.empty?
|
|
102
|
+
detect_fields
|
|
103
|
+
elsif fields.kind_of?(Hash)
|
|
104
|
+
fields.values
|
|
105
|
+
else
|
|
106
|
+
fields
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
def generate_header(fields)
|
|
111
|
+
if fields.kind_of?(Hash)
|
|
112
|
+
header = fields.keys
|
|
113
|
+
else
|
|
114
|
+
header = Array(fields)
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
if header.size < 2
|
|
118
|
+
nil
|
|
119
|
+
else
|
|
120
|
+
header.map { |head| format_header_item(head) }
|
|
121
|
+
end
|
|
122
|
+
end
|
|
123
|
+
end
|
|
124
|
+
end
|
|
125
|
+
end
|
|
@@ -11,12 +11,15 @@ module Kontena::Cli::Vault
|
|
|
11
11
|
|
|
12
12
|
def execute
|
|
13
13
|
require 'shellwords'
|
|
14
|
+
require 'json'
|
|
15
|
+
require "safe_yaml"
|
|
16
|
+
SafeYAML::OPTIONS[:default_mode] = :safe
|
|
14
17
|
meth = json? ? :to_json : :to_yaml
|
|
15
|
-
puts
|
|
16
|
-
|
|
18
|
+
puts(
|
|
19
|
+
Kontena.run!(['vault', 'ls', '--return']).sort.map do |secret|
|
|
17
20
|
[secret, Kontena.run!(['vault', 'read', '--return', secret])]
|
|
18
|
-
end
|
|
19
|
-
|
|
21
|
+
end.to_h.send(meth)
|
|
22
|
+
)
|
|
20
23
|
end
|
|
21
24
|
end
|
|
22
25
|
end
|
|
@@ -1,24 +1,37 @@
|
|
|
1
1
|
module Kontena::Cli::Vault
|
|
2
2
|
class ListCommand < Kontena::Command
|
|
3
|
+
include Kontena::Util
|
|
3
4
|
include Kontena::Cli::Common
|
|
4
5
|
include Kontena::Cli::GridOptions
|
|
6
|
+
include Kontena::Cli::TableGenerator::Helper
|
|
5
7
|
|
|
6
8
|
option '--return', :flag, "Return the keys", hidden: true
|
|
9
|
+
option ['--[no-]long', '-l'], :flag, "Show full dates", default: !$stdout.tty?
|
|
7
10
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
+
requires_current_master
|
|
12
|
+
requires_current_master_token
|
|
13
|
+
requires_current_grid
|
|
11
14
|
|
|
12
|
-
|
|
13
|
-
|
|
15
|
+
def secrets
|
|
16
|
+
client.get("grids/#{current_grid}/secrets")['secrets'].sort_by { |s| s['name'] }
|
|
17
|
+
end
|
|
14
18
|
|
|
15
|
-
|
|
19
|
+
def fields
|
|
20
|
+
return['name'] if quiet?
|
|
21
|
+
%w(name created_at updated_at)
|
|
22
|
+
end
|
|
16
23
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
24
|
+
def execute
|
|
25
|
+
return secrets.map { |s| s['name'] } if return?
|
|
26
|
+
print_table(secrets) do |row|
|
|
27
|
+
next if quiet? || long?
|
|
28
|
+
row['updated_at'] = updated?(row) ? pastel.blue('never') : time_ago(row['updated_at'])
|
|
29
|
+
row['created_at'] = time_ago(row['created_at'])
|
|
21
30
|
end
|
|
22
31
|
end
|
|
32
|
+
|
|
33
|
+
def updated?(row)
|
|
34
|
+
row['created_at'] == row['updated_at']
|
|
35
|
+
end
|
|
23
36
|
end
|
|
24
37
|
end
|
|
@@ -4,13 +4,17 @@ module Kontena::Cli::Volumes
|
|
|
4
4
|
include Kontena::Cli::Common
|
|
5
5
|
include Kontena::Cli::GridOptions
|
|
6
6
|
|
|
7
|
-
|
|
8
7
|
banner "Creates a volume"
|
|
9
8
|
parameter 'NAME', 'Volume name'
|
|
10
9
|
|
|
11
|
-
|
|
10
|
+
SCOPES = %w(grid stack instance)
|
|
11
|
+
|
|
12
|
+
option '--driver', 'DRIVER', 'Volume driver to be used', required: true
|
|
12
13
|
option '--driver-opt', 'DRIVER_OPT', 'Volume driver options', multivalued: true
|
|
13
|
-
option '--scope', 'SCOPE',
|
|
14
|
+
option '--scope', 'SCOPE', "Volume scope (#{SCOPES.join(',')})", required: true do |scope|
|
|
15
|
+
exit_with_error "Unknown scope '#{scope}, must be one of #{SCOPES.join(',')}" unless SCOPES.include?(scope)
|
|
16
|
+
scope
|
|
17
|
+
end
|
|
14
18
|
|
|
15
19
|
requires_current_master
|
|
16
20
|
requires_current_master_token
|
|
@@ -28,7 +32,7 @@ module Kontena::Cli::Volumes
|
|
|
28
32
|
end
|
|
29
33
|
|
|
30
34
|
def parse_driver_opts
|
|
31
|
-
|
|
35
|
+
driver_opt_list.map{|opt| opt.split '='}.to_h
|
|
32
36
|
end
|
|
33
37
|
|
|
34
38
|
def create_volume(volume)
|
|
@@ -1,21 +1,29 @@
|
|
|
1
1
|
|
|
2
2
|
module Kontena::Cli::Volumes
|
|
3
3
|
class ListCommand < Kontena::Command
|
|
4
|
+
include Kontena::Util
|
|
4
5
|
include Kontena::Cli::Common
|
|
5
6
|
include Kontena::Cli::GridOptions
|
|
7
|
+
include Kontena::Cli::TableGenerator::Helper
|
|
6
8
|
|
|
9
|
+
option ['--[no-]long', '-l'], :flag, "Show full dates", default: !$stdout.tty?
|
|
7
10
|
|
|
8
11
|
requires_current_master
|
|
9
12
|
requires_current_master_token
|
|
10
13
|
|
|
14
|
+
def volumes
|
|
15
|
+
client.get("volumes/#{current_grid}")['volumes']
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def fields
|
|
19
|
+
quiet? ? ['id'] : %w(name scope driver created_at)
|
|
20
|
+
end
|
|
21
|
+
|
|
11
22
|
def execute
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
[volume['name'], volume['scope'], volume['driver'], volume['created_at']]
|
|
17
|
-
}
|
|
18
|
-
puts table.render(:basic)
|
|
23
|
+
print_table(volumes) do |row|
|
|
24
|
+
next if long? || quiet?
|
|
25
|
+
row['created_at'] = time_ago(row['created_at'])
|
|
26
|
+
end
|
|
19
27
|
end
|
|
20
28
|
|
|
21
29
|
end
|
data/lib/kontena/client.rb
CHANGED
|
@@ -1,15 +1,3 @@
|
|
|
1
|
-
require 'json'
|
|
2
|
-
require 'excon'
|
|
3
|
-
require 'uri'
|
|
4
|
-
require 'base64'
|
|
5
|
-
require 'socket'
|
|
6
|
-
require 'openssl'
|
|
7
|
-
require 'uri'
|
|
8
|
-
require 'time'
|
|
9
|
-
require 'kontena/errors'
|
|
10
|
-
require 'kontena/cli/version'
|
|
11
|
-
require 'kontena/cli/config'
|
|
12
|
-
|
|
13
1
|
module Kontena
|
|
14
2
|
class Client
|
|
15
3
|
|
|
@@ -40,13 +28,23 @@ module Kontena
|
|
|
40
28
|
# @param [Kontena::Cli::Config::Token,Hash] access_token
|
|
41
29
|
# @param [Hash] options
|
|
42
30
|
def initialize(api_url, token = nil, options = {})
|
|
31
|
+
require 'json'
|
|
32
|
+
require 'excon'
|
|
33
|
+
require 'uri'
|
|
34
|
+
require 'base64'
|
|
35
|
+
require 'socket'
|
|
36
|
+
require 'openssl'
|
|
37
|
+
require 'uri'
|
|
38
|
+
require 'time'
|
|
39
|
+
require 'kontena/errors'
|
|
40
|
+
require 'kontena/cli/version'
|
|
41
|
+
require 'kontena/cli/config'
|
|
42
|
+
|
|
43
43
|
@api_url, @token, @options = api_url, token, options
|
|
44
44
|
uri = URI.parse(@api_url)
|
|
45
45
|
@host = uri.host
|
|
46
46
|
|
|
47
|
-
@logger =
|
|
48
|
-
@logger.level = ENV["DEBUG"].nil? ? Logger::INFO : Logger::DEBUG
|
|
49
|
-
@logger.progname = 'CLIENT'
|
|
47
|
+
@logger = Kontena.logger
|
|
50
48
|
|
|
51
49
|
@options[:default_headers] ||= {}
|
|
52
50
|
|
|
@@ -67,12 +65,12 @@ module Kontena
|
|
|
67
65
|
excon_opts[:ssl_ca_file] = cert_file
|
|
68
66
|
key = OpenSSL::X509::Certificate.new(File.read(cert_file))
|
|
69
67
|
if key.issuer.to_s == "/C=FI/O=Test/OU=Test/CN=Test"
|
|
70
|
-
|
|
68
|
+
debug { "Key looks like a self-signed cert made by Kontena CLI, setting verify_peer_host to 'Test'" }
|
|
71
69
|
excon_opts[:ssl_verify_peer_host] = 'Test'
|
|
72
70
|
end
|
|
73
71
|
end
|
|
74
72
|
|
|
75
|
-
|
|
73
|
+
debug { "Excon opts: #{excon_opts.inspect}" }
|
|
76
74
|
|
|
77
75
|
@http_client = Excon.new(api_url, excon_opts)
|
|
78
76
|
|
|
@@ -88,13 +86,20 @@ module Kontena
|
|
|
88
86
|
else
|
|
89
87
|
@token = token
|
|
90
88
|
end
|
|
91
|
-
@default_headers.merge!('Authorization' => "Bearer #{@token['access_token']}")
|
|
92
89
|
end
|
|
93
90
|
|
|
94
91
|
@api_url = api_url
|
|
95
92
|
@path_prefix = options[:prefix] || '/v1/'
|
|
96
93
|
end
|
|
97
94
|
|
|
95
|
+
def debug(&block)
|
|
96
|
+
logger.debug("CLIENT", &block)
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
def error(&block)
|
|
100
|
+
logger.error("CLIENT", &block)
|
|
101
|
+
end
|
|
102
|
+
|
|
98
103
|
# Generates a header hash for HTTP basic authentication.
|
|
99
104
|
# Defaults to using client_id and client_secret as user/pass
|
|
100
105
|
#
|
|
@@ -133,11 +138,12 @@ module Kontena
|
|
|
133
138
|
return false unless token_verify_path
|
|
134
139
|
|
|
135
140
|
final_path = token_verify_path.gsub(/\:access\_token/, token['access_token'])
|
|
136
|
-
|
|
141
|
+
debug { "Requesting user info from #{final_path}" }
|
|
137
142
|
request(path: final_path)
|
|
138
143
|
true
|
|
139
144
|
rescue => ex
|
|
140
|
-
|
|
145
|
+
error { "Authentication verification exception" }
|
|
146
|
+
error { ex }
|
|
141
147
|
false
|
|
142
148
|
end
|
|
143
149
|
|
|
@@ -170,7 +176,8 @@ module Kontena
|
|
|
170
176
|
def server_version
|
|
171
177
|
request(auth: false, expects: 200)['version']
|
|
172
178
|
rescue => ex
|
|
173
|
-
|
|
179
|
+
error { "Server version exception" }
|
|
180
|
+
error { ex }
|
|
174
181
|
nil
|
|
175
182
|
end
|
|
176
183
|
|
|
@@ -328,7 +335,7 @@ module Kontena
|
|
|
328
335
|
parse_response(@last_response)
|
|
329
336
|
rescue Excon::Errors::Unauthorized
|
|
330
337
|
if token
|
|
331
|
-
|
|
338
|
+
debug { 'Server reports access token expired' }
|
|
332
339
|
|
|
333
340
|
if retried || !token || !token['refresh_token']
|
|
334
341
|
raise Kontena::Errors::StandardError.new(401, 'The access token has expired and needs to be refreshed')
|
|
@@ -339,7 +346,7 @@ module Kontena
|
|
|
339
346
|
end
|
|
340
347
|
raise Kontena::Errors::StandardError.new(401, 'Unauthorized')
|
|
341
348
|
rescue Excon::Errors::HTTPStatusError => error
|
|
342
|
-
|
|
349
|
+
debug { "Request #{error.request[:method].upcase} #{error.request[:path]}: #{error.response.status} #{error.response.reason_phrase}: #{error.response.body}" }
|
|
343
350
|
|
|
344
351
|
handle_error_response(error.response)
|
|
345
352
|
end
|
|
@@ -367,7 +374,8 @@ module Kontena
|
|
|
367
374
|
{}
|
|
368
375
|
end
|
|
369
376
|
rescue => ex
|
|
370
|
-
|
|
377
|
+
error { "Access token refresh exception" }
|
|
378
|
+
error { ex }
|
|
371
379
|
false
|
|
372
380
|
end
|
|
373
381
|
|
|
@@ -378,7 +386,7 @@ module Kontena
|
|
|
378
386
|
# @param [Boolean] use_basic_auth? When true, use basic auth authentication header
|
|
379
387
|
# @return [Boolean] success?
|
|
380
388
|
def refresh_token
|
|
381
|
-
|
|
389
|
+
debug { "Performing token refresh" }
|
|
382
390
|
return false if token.nil?
|
|
383
391
|
return false if token['refresh_token'].nil?
|
|
384
392
|
uri = URI.parse(token_account['token_endpoint'])
|
|
@@ -386,7 +394,7 @@ module Kontena
|
|
|
386
394
|
endpoint_data[:host] = uri.host if uri.host
|
|
387
395
|
endpoint_data[:port] = uri.port if uri.port
|
|
388
396
|
|
|
389
|
-
|
|
397
|
+
debug { "Token refresh endpoint: #{endpoint_data.inspect}" }
|
|
390
398
|
|
|
391
399
|
return false unless endpoint_data[:path]
|
|
392
400
|
|
|
@@ -405,18 +413,19 @@ module Kontena
|
|
|
405
413
|
)
|
|
406
414
|
|
|
407
415
|
if response && response['access_token']
|
|
408
|
-
|
|
416
|
+
debug { "Got response to refresh request" }
|
|
409
417
|
token['access_token'] = response['access_token']
|
|
410
418
|
token['refresh_token'] = response['refresh_token']
|
|
411
419
|
token['expires_at'] = in_to_at(response['expires_in'])
|
|
412
420
|
token.config.write if token.respond_to?(:config)
|
|
413
421
|
true
|
|
414
422
|
else
|
|
415
|
-
|
|
423
|
+
debug { "Got null or bad response to refresh request: #{last_response.inspect}" }
|
|
416
424
|
false
|
|
417
425
|
end
|
|
418
426
|
rescue => ex
|
|
419
|
-
|
|
427
|
+
error { "Access token refresh exception" }
|
|
428
|
+
error { ex }
|
|
420
429
|
false
|
|
421
430
|
end
|
|
422
431
|
|
|
@@ -507,7 +516,7 @@ module Kontena
|
|
|
507
516
|
def parse_json(json)
|
|
508
517
|
JSON.parse(json)
|
|
509
518
|
rescue => ex
|
|
510
|
-
|
|
519
|
+
debug { "JSON parse exception: #{ex.class.name} : #{ex.message}" }
|
|
511
520
|
nil
|
|
512
521
|
end
|
|
513
522
|
|
|
@@ -528,14 +537,16 @@ module Kontena
|
|
|
528
537
|
def handle_error_response(response)
|
|
529
538
|
data = parse_response(response)
|
|
530
539
|
|
|
540
|
+
request_path = " (#{response.path})"
|
|
541
|
+
|
|
531
542
|
if data.is_a?(Hash) && data.has_key?('error') && data['error'].is_a?(Hash)
|
|
532
543
|
raise Kontena::Errors::StandardErrorHash.new(response.status, response.reason_phrase, data['error'])
|
|
533
544
|
elsif data.is_a?(Hash) && data.has_key?('error')
|
|
534
|
-
raise Kontena::Errors::StandardError.new(response.status, data['error'])
|
|
545
|
+
raise Kontena::Errors::StandardError.new(response.status, data['error'] + request_path)
|
|
535
546
|
elsif data.is_a?(String) && !data.empty?
|
|
536
|
-
raise Kontena::Errors::StandardError.new(response.status, data)
|
|
547
|
+
raise Kontena::Errors::StandardError.new(response.status, data + request_path)
|
|
537
548
|
else
|
|
538
|
-
raise Kontena::Errors::StandardError.new(response.status, response.reason_phrase)
|
|
549
|
+
raise Kontena::Errors::StandardError.new(response.status, response.reason_phrase + request_path)
|
|
539
550
|
end
|
|
540
551
|
end
|
|
541
552
|
|