kontena-cli 1.4.0 → 1.4.1.pre1
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 +5 -5
- data/VERSION +1 -1
- data/bin/kontena +2 -1
- data/kontena-cli.gemspec +1 -1
- data/lib/kontena/cli/certificate/common.rb +16 -0
- data/lib/kontena/cli/certificate/export_command.rb +28 -0
- data/lib/kontena/cli/certificate/import_command.rb +61 -0
- data/lib/kontena/cli/certificate/show_command.rb +5 -2
- data/lib/kontena/cli/certificate_command.rb +3 -1
- data/lib/kontena/cli/common.rb +5 -1
- data/lib/kontena/cli/config.rb +23 -5
- data/lib/kontena/cli/external_registries/add_command.rb +2 -0
- data/lib/kontena/cli/external_registries/list_command.rb +1 -1
- data/lib/kontena/cli/helpers/exec_helper.rb +12 -4
- data/lib/kontena/cli/master/config/import_command.rb +1 -1
- data/lib/kontena/cli/master/login_command.rb +1 -1
- data/lib/kontena/cli/stacks/common.rb +2 -1
- data/lib/kontena/cli/stacks/registry/show_command.rb +1 -1
- data/lib/kontena/cli/stacks/service_generator.rb +1 -0
- data/lib/kontena/cli/stacks/yaml/opto.rb +1 -0
- data/lib/kontena/cli/stacks/yaml/opto/certificates_resolver.rb +37 -0
- data/lib/kontena/cli/stacks/yaml/opto/vault_cert_prompt_resolver.rb +1 -1
- data/lib/kontena/cli/stacks/yaml/reader.rb +5 -2
- data/lib/kontena/cli/stacks/yaml/validations.rb +2 -1
- data/lib/kontena/cli/vault/import_command.rb +1 -1
- data/lib/kontena/client.rb +1 -1
- data/lib/kontena/command.rb +7 -5
- data/lib/kontena/plugin_manager.rb +1 -1
- data/lib/kontena/plugin_manager/cleaner.rb +1 -1
- data/lib/kontena/scripts/completer.rb +1 -1
- data/lib/kontena/stacks_cache.rb +2 -2
- data/lib/kontena_cli.rb +6 -2
- data/spec/fixtures/certificates/test/ca-key.pem +10 -0
- data/spec/fixtures/certificates/test/ca.pem +10 -0
- data/spec/fixtures/certificates/test/ca.srl +1 -0
- data/spec/fixtures/certificates/test/cert.pem +8 -0
- data/spec/fixtures/certificates/test/csr.pem +7 -0
- data/spec/fixtures/certificates/test/key.pem +10 -0
- data/spec/fixtures/certificates/test/real-cert.pem +30 -0
- data/spec/fixtures/docker-compose_v2.yml +1 -0
- data/spec/fixtures/docker-compose_v2_with_variables.yml +12 -0
- data/spec/fixtures/kontena_v3_with_compose_variables.yml +11 -0
- data/spec/fixtures/stack-with-anchors.yml +13 -0
- data/spec/kontena/cli/certificates/export_command_spec.rb +49 -0
- data/spec/kontena/cli/certificates/import_command_spec.rb +70 -0
- data/spec/kontena/cli/certificates/show_command_spec.rb +57 -0
- data/spec/kontena/cli/cloud/login_command_spec.rb +7 -14
- data/spec/kontena/cli/helpers/exec_helper_spec.rb +38 -0
- data/spec/kontena/cli/master/login_command_spec.rb +12 -24
- data/spec/kontena/cli/master/use_command_spec.rb +1 -1
- data/spec/kontena/cli/nodes/remove_command_spec.rb +1 -1
- data/spec/kontena/cli/registry/{create_spec.rb → create_command_spec.rb} +0 -0
- data/spec/kontena/cli/stacks/upgrade_command_spec.rb +1 -1
- data/spec/kontena/cli/stacks/yaml/opto/certificates_resolver_spec.rb +81 -0
- data/spec/kontena/cli/stacks/yaml/reader_spec.rb +22 -2
- data/spec/kontena/cli/stacks/yaml/validator_v3_spec.rb +17 -0
- data/spec/kontena/command_spec.rb +54 -0
- data/spec/kontena/config_spec.rb +17 -2
- data/spec/kontena/main_command_spec.rb +13 -0
- data/spec/spec_helper.rb +10 -17
- metadata +43 -11
- data/spec/kontena/cli/main_command_spec.rb +0 -19
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: b214db2a1e9aa6a1bcdc8987786facfac926a094bc617ae1ed2786c90e206c2e
|
4
|
+
data.tar.gz: bd38e299c9bad45f7d54990e761036a33a3608ca067166fa2991583c1cc0ef5e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 13ee888f1151a74792b424fc796b89d5d2ff2319635bc4801bd11017227698f861cd16c2ba087330689a3ebc107fa2432364f08948f6cd55947f77a5977634f2
|
7
|
+
data.tar.gz: 70471db05d252ea9e9bc01be0a07513f83ae840342a619f4fe69cea5292f1cac5fc7bbc6df9465577a66700d0dc97ce8ef3dc101bdff42d951bafaac5b0e1fce
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.4.
|
1
|
+
1.4.1.pre1
|
data/bin/kontena
CHANGED
@@ -12,7 +12,8 @@ if ARGV[0] == 'complete'
|
|
12
12
|
ARGV.delete_at(0)
|
13
13
|
require 'kontena/scripts/completer'
|
14
14
|
else
|
15
|
-
ENV['DEBUG']
|
15
|
+
ENV['DEBUG'] = "true" if ARGV.any? { |arg| arg == '-D' || arg == '--debug'}
|
16
|
+
ENV['DEBUG'] = "false" if ARGV.any? { |arg| arg == '--no-debug' }
|
16
17
|
require 'kontena_cli'
|
17
18
|
Kontena::PluginManager.init unless ENV['NO_PLUGINS']
|
18
19
|
Kontena::MainCommand.run
|
data/kontena-cli.gemspec
CHANGED
@@ -32,6 +32,6 @@ Gem::Specification.new do |spec|
|
|
32
32
|
spec.add_runtime_dependency "opto", "1.8.7"
|
33
33
|
spec.add_runtime_dependency "semantic", "~> 1.5"
|
34
34
|
spec.add_runtime_dependency "liquid", "~> 4.0.0"
|
35
|
-
spec.add_runtime_dependency "tty-table", "~> 0.
|
35
|
+
spec.add_runtime_dependency "tty-table", "~> 0.9.0"
|
36
36
|
spec.add_runtime_dependency "kontena-websocket-client", "~> 0.1.1"
|
37
37
|
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module Kontena::Cli::Certificate
|
2
|
+
module Common
|
3
|
+
def show_certificate(cert)
|
4
|
+
puts "#{cert['id']}:"
|
5
|
+
puts " subject: #{cert['subject']}"
|
6
|
+
puts " valid until: #{Time.parse(cert['valid_until']).utc.strftime("%FT%TZ")}"
|
7
|
+
if cert['alt_names'] && !cert['alt_names'].empty?
|
8
|
+
puts " alt names:"
|
9
|
+
cert['alt_names'].each do |alt_name|
|
10
|
+
puts " - #{alt_name}"
|
11
|
+
end
|
12
|
+
end
|
13
|
+
puts " auto renewable: #{cert['auto_renewable']}"
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module Kontena::Cli::Certificate
|
2
|
+
class ExportCommand < Kontena::Command
|
3
|
+
include Kontena::Cli::Common
|
4
|
+
include Kontena::Cli::GridOptions
|
5
|
+
|
6
|
+
parameter "SUBJECT", "Certificate subject"
|
7
|
+
|
8
|
+
requires_current_master
|
9
|
+
requires_current_master_token
|
10
|
+
requires_current_grid
|
11
|
+
|
12
|
+
option ['--certificate', '--cert'], :flag, "Output certificate"
|
13
|
+
option ['--chain'], :flag, "Output chain"
|
14
|
+
option ['--private-key', '--key'], :flag, "Output private key"
|
15
|
+
|
16
|
+
def bundle?
|
17
|
+
![certificate?, chain?, private_key?].any?
|
18
|
+
end
|
19
|
+
|
20
|
+
def execute
|
21
|
+
certificate = client.get("certificates/#{current_grid}/#{self.subject}/export")
|
22
|
+
|
23
|
+
puts certificate['certificate'] if certificate? || bundle?
|
24
|
+
puts certificate['chain'] if chain? || bundle?
|
25
|
+
puts certificate['private_key'] if private_key? || bundle?
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
require 'openssl'
|
2
|
+
require_relative './common'
|
3
|
+
|
4
|
+
module Kontena::Cli::Certificate
|
5
|
+
class ImportCommand < Kontena::Command
|
6
|
+
include Kontena::Cli::Common
|
7
|
+
include Kontena::Cli::GridOptions
|
8
|
+
include Common
|
9
|
+
|
10
|
+
# @raise [ArgumentError]
|
11
|
+
def open_file(path)
|
12
|
+
File.open(path)
|
13
|
+
rescue Errno::ENOENT
|
14
|
+
raise ArgumentError, "File not found: #{path}"
|
15
|
+
end
|
16
|
+
|
17
|
+
parameter 'CERT_FILE', "Path to PEM-encoded X.509 certificate file" do |path|
|
18
|
+
open_file(path)
|
19
|
+
end
|
20
|
+
option '--subject', 'SUBJECT', "Import cert specific subject"
|
21
|
+
option ['--private-key', '--key'], 'KEY_FILE', "Path to private key file", :required => true, :attribute_name => :key_file do |path|
|
22
|
+
open_file(path)
|
23
|
+
end
|
24
|
+
option ['--chain'], 'CHAIN_FILE', "Path to CA cert chain file", :multivalued => true, :attribute_name => :chain_file_list do |path|
|
25
|
+
open_file(path)
|
26
|
+
end
|
27
|
+
|
28
|
+
requires_current_master
|
29
|
+
requires_current_master_token
|
30
|
+
requires_current_grid
|
31
|
+
|
32
|
+
def load_certificate
|
33
|
+
OpenSSL::X509::Certificate.new(self.cert_file)
|
34
|
+
rescue OpenSSL::OpenSSLError => exc
|
35
|
+
exit_with_error "Invalid certificate at #{self.cert_file.path}: #{exc.class}: #{exc.message}"
|
36
|
+
end
|
37
|
+
|
38
|
+
def certificate_subject(cert)
|
39
|
+
cert.subject.to_a.each do |name, data|
|
40
|
+
return data if name == 'CN'
|
41
|
+
end
|
42
|
+
|
43
|
+
exit_with_error "No CN in certificate subject: #{cert.subject}"
|
44
|
+
end
|
45
|
+
|
46
|
+
def execute
|
47
|
+
cert = load_certificate
|
48
|
+
subject = self.subject || self.certificate_subject(cert)
|
49
|
+
|
50
|
+
certificate = spinner "Importing certificate from #{cert_file.path}..." do
|
51
|
+
client.put("certificates/#{current_grid}/#{subject}",
|
52
|
+
certificate: cert.to_pem,
|
53
|
+
private_key: self.key_file.read(),
|
54
|
+
chain: chain_file_list.map{|chain_file| chain_file.read() },
|
55
|
+
)
|
56
|
+
end
|
57
|
+
|
58
|
+
show_certificate(certificate)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -1,9 +1,11 @@
|
|
1
1
|
require_relative '../services/services_helper'
|
2
|
+
require_relative './common'
|
2
3
|
|
3
4
|
module Kontena::Cli::Certificate
|
4
5
|
class ShowCommand < Kontena::Command
|
5
6
|
include Kontena::Cli::Common
|
6
7
|
include Kontena::Cli::GridOptions
|
8
|
+
include Common
|
7
9
|
|
8
10
|
parameter "SUBJECT", "Certificate subject"
|
9
11
|
|
@@ -12,8 +14,9 @@ module Kontena::Cli::Certificate
|
|
12
14
|
requires_current_grid
|
13
15
|
|
14
16
|
def execute
|
15
|
-
|
16
|
-
|
17
|
+
cert = client.get("certificates/#{current_grid}/#{self.subject}")
|
18
|
+
|
19
|
+
show_certificate(cert)
|
17
20
|
end
|
18
21
|
end
|
19
22
|
end
|
@@ -3,13 +3,15 @@ class Kontena::Cli::CertificateCommand < Kontena::Command
|
|
3
3
|
|
4
4
|
subcommand ["list", "ls"], "List certificates", load_subcommand('certificate/list_command')
|
5
5
|
subcommand "show", "Show certificate details", load_subcommand('certificate/show_command')
|
6
|
+
subcommand "export", "Export certificate to file", load_subcommand('certificate/export_command')
|
6
7
|
subcommand "register", "Register to LetsEncrypt", load_subcommand('certificate/register_command')
|
7
8
|
subcommand "authorize", "Create DNS authorization for domain", load_subcommand('certificate/authorize_command')
|
8
9
|
subcommand "request", "Request certificate for domain", load_subcommand('certificate/request_command')
|
9
10
|
subcommand "get", "Get certificate for domain", load_subcommand('certificate/get_command')
|
11
|
+
subcommand "import", "Import certificate from file", load_subcommand('certificate/import_command')
|
10
12
|
subcommand ["remove", "rm"], "Remove certificate for domain", load_subcommand('certificate/remove_command')
|
11
13
|
|
12
14
|
|
13
15
|
def execute
|
14
16
|
end
|
15
|
-
end
|
17
|
+
end
|
data/lib/kontena/cli/common.rb
CHANGED
@@ -40,6 +40,10 @@ module Kontena
|
|
40
40
|
Kontena::Cli::Config.instance
|
41
41
|
end
|
42
42
|
|
43
|
+
def debug?
|
44
|
+
Kontena.debug?
|
45
|
+
end
|
46
|
+
|
43
47
|
# Read from STDIN. If stdin is a console, use prompt to ask.
|
44
48
|
# @param [String] message
|
45
49
|
# @param [Symbol] mode (prompt method: :ask, :multiline, etc)
|
@@ -100,7 +104,7 @@ module Kontena
|
|
100
104
|
def vputs(msg = nil)
|
101
105
|
if running_verbose?
|
102
106
|
puts msg
|
103
|
-
elsif
|
107
|
+
elsif debug? && msg
|
104
108
|
logger.debug msg
|
105
109
|
end
|
106
110
|
end
|
data/lib/kontena/cli/config.rb
CHANGED
@@ -53,21 +53,39 @@ module Kontena
|
|
53
53
|
|
54
54
|
# Craft a regular looking configuration based on ENV variables
|
55
55
|
def load_settings_from_env
|
56
|
+
load_cloud_settings_from_env
|
57
|
+
load_master_settings_from_env
|
58
|
+
end
|
59
|
+
|
60
|
+
def load_master_settings_from_env
|
56
61
|
return nil unless ENV['KONTENA_URL']
|
57
|
-
|
62
|
+
|
63
|
+
debug { 'Loading master configuration from ENV' }
|
58
64
|
servers << Server.new(
|
59
65
|
url: ENV['KONTENA_URL'],
|
60
66
|
name: 'default',
|
61
|
-
token: Token.new(
|
67
|
+
token: Token.new(
|
68
|
+
access_token: ENV['KONTENA_TOKEN'],
|
69
|
+
parent_type: :master, parent_name: 'default'
|
70
|
+
),
|
62
71
|
grid: ENV['KONTENA_GRID'],
|
63
72
|
parent_type: :master,
|
64
73
|
parent_name: 'default'
|
65
74
|
)
|
66
|
-
accounts << Account.new(kontena_account_data.merge(
|
67
|
-
token: Token.new(access_token: ENV['KONTENA_CLOUD_TOKEN'], parent_type: :account, parent_name: 'default')
|
68
|
-
))
|
69
75
|
|
70
76
|
self.current_master = 'default'
|
77
|
+
end
|
78
|
+
|
79
|
+
def load_cloud_settings_from_env
|
80
|
+
return unless ENV['KONTENA_CLOUD_TOKEN']
|
81
|
+
|
82
|
+
debug { 'Loading cloud configuration from ENV' }
|
83
|
+
accounts << Account.new(kontena_account_data.merge(
|
84
|
+
token: Token.new(
|
85
|
+
access_token: ENV['KONTENA_CLOUD_TOKEN'],
|
86
|
+
parent_type: :account, parent_name: 'default'
|
87
|
+
)
|
88
|
+
))
|
71
89
|
self.current_account = 'kontena'
|
72
90
|
end
|
73
91
|
|
@@ -14,6 +14,8 @@ module Kontena::Cli::ExternalRegistries
|
|
14
14
|
require_current_grid
|
15
15
|
token = require_token
|
16
16
|
|
17
|
+
self.url = "https://#{self.url}" unless self.url.start_with?('http')
|
18
|
+
|
17
19
|
data = { username: username, password: password, email: email, url: url }
|
18
20
|
spinner "Adding #{url.colorize(:cyan)} to external registries " do
|
19
21
|
client(token).post("grids/#{current_grid}/external_registries", data)
|
@@ -6,7 +6,7 @@ module Kontena::Cli::Helpers
|
|
6
6
|
|
7
7
|
websocket_log_level = if ENV["DEBUG"] == 'websocket'
|
8
8
|
Logger::DEBUG
|
9
|
-
elsif
|
9
|
+
elsif Kontena.debug?
|
10
10
|
Logger::INFO
|
11
11
|
else
|
12
12
|
Logger::WARN
|
@@ -27,7 +27,7 @@ module Kontena::Cli::Helpers
|
|
27
27
|
# @param tty [Boolean] read stdin in raw mode, sending tty escapes for remote pty
|
28
28
|
# @raise [ArgumentError] not a tty
|
29
29
|
# @yield [data]
|
30
|
-
# @yieldparam data [String] data from stdin
|
30
|
+
# @yieldparam data [String] unicode data from stdin
|
31
31
|
# @raise [ArgumentError] not a tty
|
32
32
|
# @return EOF on stdin (!tty)
|
33
33
|
def read_stdin(tty: nil)
|
@@ -38,11 +38,18 @@ module Kontena::Cli::Helpers
|
|
38
38
|
# we do not expect EOF on a TTY, ^D sends a tty escape to close the pty instead
|
39
39
|
loop do
|
40
40
|
# raises EOFError, SyscallError or IOError
|
41
|
-
|
41
|
+
chunk = io.readpartial(1024)
|
42
|
+
|
43
|
+
# STDIN.raw does not use the ruby external_encoding, it returns binary strings (ASCII-8BIT encoding)
|
44
|
+
# however, we use websocket text frames with JSON, which expects unicode strings encodable as UTF-8, and does not handle arbitrary binary data
|
45
|
+
# assume all stdin input is using ruby's external_encoding... the JSON.dump will fail if not.
|
46
|
+
chunk.force_encoding(Encoding.default_external)
|
47
|
+
|
48
|
+
yield chunk
|
42
49
|
end
|
43
50
|
}
|
44
51
|
else
|
45
|
-
# line-buffered
|
52
|
+
# line-buffered, using the default external_encoding (probably UTF-8)
|
46
53
|
while line = STDIN.gets
|
47
54
|
yield line
|
48
55
|
end
|
@@ -106,6 +113,7 @@ module Kontena::Cli::Helpers
|
|
106
113
|
})
|
107
114
|
end
|
108
115
|
read_stdin(tty: tty) do |stdin|
|
116
|
+
logger.debug "websocket exec stdin with encoding=#{stdin.encoding}: #{stdin.inspect}"
|
109
117
|
websocket_exec_write(ws, 'stdin' => stdin)
|
110
118
|
end
|
111
119
|
websocket_exec_write(ws, 'stdin' => nil) # EOF
|
@@ -159,7 +159,7 @@ module Kontena::Cli::Master
|
|
159
159
|
elsif response.kind_of?(String) && response.length > 1
|
160
160
|
exit_with_error response
|
161
161
|
else
|
162
|
-
exit_with_error "Invalid response to authentication request : HTTP#{client.last_response.status} #{client.last_response.body if
|
162
|
+
exit_with_error "Invalid response to authentication request : HTTP#{client.last_response.status} #{client.last_response.body if debug?}"
|
163
163
|
end
|
164
164
|
end
|
165
165
|
end
|
@@ -95,7 +95,7 @@ module Kontena::Cli::Stacks
|
|
95
95
|
where.prepend InstanceMethods
|
96
96
|
|
97
97
|
where.option '--values-from', '[FILE]', 'Read variable values from a YAML file', multivalued: true do |filename|
|
98
|
-
values_from_file.merge!(::YAML.safe_load(File.read(filename)))
|
98
|
+
values_from_file.merge!(::YAML.safe_load(File.read(filename), [], [], true, filename))
|
99
99
|
filename
|
100
100
|
end
|
101
101
|
|
@@ -110,6 +110,7 @@ module Kontena::Cli::Stacks
|
|
110
110
|
where.option '-v', "VARIABLE=VALUE", "Set stack variable values, example: -v domain=example.com. Can be used multiple times.", multivalued: true, attribute_name: :var_option do |var_pair|
|
111
111
|
var_name, var_value = var_pair.split('=', 2)
|
112
112
|
values_from_value_options.merge!(::YAML.safe_load(::YAML.dump(var_name => var_value)))
|
113
|
+
var_pair
|
113
114
|
end
|
114
115
|
end
|
115
116
|
|
@@ -15,7 +15,7 @@ module Kontena::Cli::Stacks::Registry
|
|
15
15
|
def execute
|
16
16
|
require 'semantic'
|
17
17
|
unless versions?
|
18
|
-
stack = ::YAML.safe_load(stacks_client.show(stack_name.stack_name, stack_name.version))
|
18
|
+
stack = ::YAML.safe_load(stacks_client.show(stack_name.stack_name, stack_name.version), [], [], true)
|
19
19
|
puts "#{stack['stack']}:"
|
20
20
|
puts " #{"latest_" unless stack_name.version}version: #{stack['version']}"
|
21
21
|
puts " expose: #{stack['expose'] || '-'}"
|
@@ -69,6 +69,7 @@ module Kontena::Cli::Stacks
|
|
69
69
|
data['stop_signal'] = options['stop_signal'] if options['stop_signal']
|
70
70
|
data['stop_grace_period'] = options['stop_grace_period'] if options['stop_grace_period']
|
71
71
|
data['read_only'] = options['read_only'] || false
|
72
|
+
data['entrypoint'] = options['entrypoint'] if options['entrypoint']
|
72
73
|
data
|
73
74
|
end
|
74
75
|
|
@@ -12,4 +12,5 @@ require_relative 'opto/vault_resolver'
|
|
12
12
|
require_relative 'opto/prompt_resolver'
|
13
13
|
require_relative 'opto/service_instances_resolver'
|
14
14
|
require_relative 'opto/vault_cert_prompt_resolver'
|
15
|
+
require_relative 'opto/certificates_resolver'
|
15
16
|
require_relative 'opto/service_link_resolver'
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module Kontena::Cli::Stacks::YAML::Opto::Resolvers
|
2
|
+
class Certificates < ::Opto::Resolver
|
3
|
+
include Kontena::Cli::Common
|
4
|
+
|
5
|
+
def resolve
|
6
|
+
return nil unless current_master && current_grid
|
7
|
+
message = hint || 'Select SSL certificates'
|
8
|
+
certificates = get_certificates
|
9
|
+
if certificates.size > 0
|
10
|
+
prompt.multi_select(message) do |menu|
|
11
|
+
menu.default(*default_indexes(certificates)) if option.default
|
12
|
+
certificates.each do |s|
|
13
|
+
menu.choice s['subject']
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
# @return [Array<Hash>] certificates
|
20
|
+
def get_certificates
|
21
|
+
client.get("grids/#{current_grid}/certificates")['certificates']
|
22
|
+
rescue
|
23
|
+
[]
|
24
|
+
end
|
25
|
+
|
26
|
+
# @param certificates [Array<Hash>]
|
27
|
+
# @return [Array<Integer>]
|
28
|
+
def default_indexes(certificates)
|
29
|
+
indexes = []
|
30
|
+
option.default.to_a.each do |subject|
|
31
|
+
index = certificates.index { |s| s['subject'] == subject }
|
32
|
+
indexes << index.to_i + 1 if index
|
33
|
+
end
|
34
|
+
indexes
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -9,7 +9,7 @@ module Kontena::Cli::Stacks::YAML::Opto::Resolvers
|
|
9
9
|
s['name'].match(/(ssl|cert)/i)
|
10
10
|
}
|
11
11
|
if secrets.size > 0
|
12
|
-
prompt.multi_select(
|
12
|
+
prompt.multi_select(message) do |menu|
|
13
13
|
menu.default(*default_indexes(secrets)) if option.default
|
14
14
|
secrets.each do |s|
|
15
15
|
menu.choice s['name']
|
@@ -83,7 +83,7 @@ module Kontena::Cli::Stacks
|
|
83
83
|
substitutions: default_envs,
|
84
84
|
warnings: false
|
85
85
|
)
|
86
|
-
)
|
86
|
+
), [], [], true, file
|
87
87
|
)
|
88
88
|
rescue Psych::SyntaxError => ex
|
89
89
|
raise ex, "Error while parsing #{file} : #{ex.message}"
|
@@ -104,7 +104,7 @@ module Kontena::Cli::Stacks
|
|
104
104
|
use_opto: true,
|
105
105
|
raise_on_unknown: true
|
106
106
|
)
|
107
|
-
)
|
107
|
+
), [], [], true, file
|
108
108
|
)
|
109
109
|
rescue Psych::SyntaxError => ex
|
110
110
|
raise ex, "Error while parsing #{file} : #{ex.message}"
|
@@ -350,6 +350,9 @@ module Kontena::Cli::Stacks
|
|
350
350
|
|
351
351
|
def from_external_file(filename, service_name)
|
352
352
|
external_reader = FileLoader.new(filename, loader).reader
|
353
|
+
variables.to_a(with_value: true).each do |var|
|
354
|
+
external_reader.variables.build_option(var)
|
355
|
+
end
|
353
356
|
outcome = external_reader.execute(service_name)
|
354
357
|
errors.concat external_reader.errors unless external_reader.errors.empty? || errors.include?(external_reader.errors)
|
355
358
|
notifications.concat external_reader.notifications unless external_reader.notifications.empty? || notifications.include?(external_reader.notifications)
|