kontena-cli 1.1.0 → 1.1.1.rc1
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/kontena-cli.gemspec +1 -1
- data/lib/kontena/callbacks/master/deploy/70_invite_self_after_deploy.rb +9 -6
- data/lib/kontena/cli/common.rb +2 -0
- data/lib/kontena/cli/plugins/install_command.rb +4 -0
- data/lib/kontena/cli/services/link_command.rb +12 -4
- data/lib/kontena/cli/services/unlink_command.rb +11 -5
- data/lib/kontena/cli/stacks/service_generator.rb +10 -7
- data/lib/kontena/cli/stacks/yaml/opto.rb +15 -0
- data/lib/kontena/cli/stacks/yaml/opto/prompt_resolver.rb +13 -5
- data/lib/kontena/cli/stacks/yaml/opto/service_instances_resolver.rb +1 -1
- data/lib/kontena/cli/stacks/yaml/opto/service_link_resolver.rb +66 -35
- data/lib/kontena/cli/stacks/yaml/opto/vault_cert_prompt_resolver.rb +33 -10
- data/lib/kontena/cli/stacks/yaml/opto/vault_resolver.rb +1 -1
- data/lib/kontena/cli/stacks/yaml/opto/vault_setter.rb +1 -2
- data/lib/kontena/cli/stacks/yaml/reader.rb +7 -8
- data/lib/kontena/plugin_manager.rb +1 -2
- data/lib/kontena_cli.rb +1 -1
- data/spec/kontena/cli/cloud/master/add_command_spec.rb +0 -1
- data/spec/kontena/cli/common_spec.rb +28 -21
- data/spec/kontena/cli/master/init_cloud_command_spec.rb +28 -0
- data/spec/kontena/cli/services/link_command_spec.rb +2 -2
- data/spec/kontena/cli/services/unlink_command_spec.rb +1 -1
- data/spec/kontena/cli/stacks/service_generator_spec.rb +7 -3
- data/spec/kontena/cli/stacks/yaml/opto/prompt_resolver_spec.rb +27 -0
- data/spec/kontena/cli/stacks/yaml/opto/service_link_resolver_spec.rb +54 -0
- data/spec/kontena/cli/stacks/yaml/opto/vault_cert_prompt_resolver_spec.rb +73 -0
- data/spec/kontena/kontena_cli_spec.rb +15 -6
- data/spec/kontena/main_command_spec.rb +16 -0
- metadata +19 -8
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 76963be4ff231516ea09ffc1261b2945f7728f78
|
|
4
|
+
data.tar.gz: ea1f2e4fa944e33af0d7c5b9abea939485805346
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 66580e1af2b505487e82ae8458f5fed6f2965438df752e0ae8581108fe067932dc8205276117f3fc0a00bba46ddb17f3c5b19f8d224b82c78cd2e90af8853b0c
|
|
7
|
+
data.tar.gz: ce4aef539d02fb0ee56f6850a7657d8d0b2466bca5db2d7633ae4d01c28e75ce36330ef1df8a7c46644abd6df79cd8fa9ffbe7d716595bc0155ad71466e8e27f
|
data/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
1.1.
|
|
1
|
+
1.1.1.rc1
|
data/kontena-cli.gemspec
CHANGED
|
@@ -29,7 +29,7 @@ Gem::Specification.new do |spec|
|
|
|
29
29
|
spec.add_runtime_dependency "launchy", "~> 2.4.3"
|
|
30
30
|
spec.add_runtime_dependency "hash_validator", "~> 0.7.0"
|
|
31
31
|
spec.add_runtime_dependency "retriable", "~> 2.1.0"
|
|
32
|
-
spec.add_runtime_dependency "opto", "
|
|
32
|
+
spec.add_runtime_dependency "opto", "1.8.3"
|
|
33
33
|
spec.add_runtime_dependency "semantic", "~> 1.5"
|
|
34
34
|
spec.add_runtime_dependency "safe_yaml", "~> 1.0"
|
|
35
35
|
spec.add_runtime_dependency "liquid", "~> 4.0.0"
|
|
@@ -4,7 +4,7 @@ module Kontena
|
|
|
4
4
|
|
|
5
5
|
include Kontena::Cli::Common
|
|
6
6
|
|
|
7
|
-
matches_commands 'master create'
|
|
7
|
+
matches_commands 'master create', 'master init_cloud'
|
|
8
8
|
|
|
9
9
|
def cloud_user_data
|
|
10
10
|
return @cloud_user_data if @cloud_user_data
|
|
@@ -27,8 +27,7 @@ module Kontena
|
|
|
27
27
|
def after
|
|
28
28
|
return unless current_master
|
|
29
29
|
return unless command.exit_code == 0
|
|
30
|
-
return
|
|
31
|
-
return nil if command.skip_auth_provider?
|
|
30
|
+
return nil if command.respond_to?(:skip_auth_provider?) && command.skip_auth_provider?
|
|
32
31
|
return nil unless cloud_user_data
|
|
33
32
|
|
|
34
33
|
invite_response = nil
|
|
@@ -51,11 +50,15 @@ module Kontena
|
|
|
51
50
|
|
|
52
51
|
return nil if role_status.to_i > 0
|
|
53
52
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
53
|
+
if current_master.grid
|
|
54
|
+
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].shellescape}")
|
|
56
|
+
spin.fail if grid_add_status.to_i > 0
|
|
57
|
+
end
|
|
57
58
|
end
|
|
58
59
|
|
|
60
|
+
return unless current_master.username.to_s == 'admin'
|
|
61
|
+
|
|
59
62
|
new_user_token = nil
|
|
60
63
|
spinner "Creating an access token for #{cloud_user_data[:email]}" do |spin|
|
|
61
64
|
new_user_token = Kontena.run("master token create -e 0 -s user --return -u #{cloud_user_data[:email].shellescape}", returning: :result)
|
data/lib/kontena/cli/common.rb
CHANGED
|
@@ -247,6 +247,7 @@ module Kontena
|
|
|
247
247
|
if self.respond_to?(:force?) && self.force?
|
|
248
248
|
return
|
|
249
249
|
end
|
|
250
|
+
exit_with_error 'Command requires --force' unless $stdout.tty? && $stdin.tty?
|
|
250
251
|
puts message if message
|
|
251
252
|
puts "Destructive command. To proceed, type \"#{name}\" or re-run this command with --force option."
|
|
252
253
|
|
|
@@ -257,6 +258,7 @@ module Kontena
|
|
|
257
258
|
if self.respond_to?(:force?) && self.force?
|
|
258
259
|
return
|
|
259
260
|
end
|
|
261
|
+
exit_with_error 'Command requires --force' unless $stdout.tty? && $stdin.tty?
|
|
260
262
|
prompt.yes?(message) || error('Aborted command.')
|
|
261
263
|
end
|
|
262
264
|
|
|
@@ -23,6 +23,10 @@ module Kontena::Cli::Plugins
|
|
|
23
23
|
spin.fail!
|
|
24
24
|
end
|
|
25
25
|
end
|
|
26
|
+
|
|
27
|
+
spinner "Running cleanup" do |spin|
|
|
28
|
+
Kontena::PluginManager.instance.cleanup_plugin(name)
|
|
29
|
+
end
|
|
26
30
|
else
|
|
27
31
|
installed = spinner "Installing plugin #{name.colorize(:cyan)}" do |spin|
|
|
28
32
|
begin
|
|
@@ -13,12 +13,20 @@ module Kontena::Cli::Services
|
|
|
13
13
|
def execute
|
|
14
14
|
require_api_url
|
|
15
15
|
token = require_token
|
|
16
|
+
target_service = target
|
|
17
|
+
|
|
18
|
+
target_service = "null/#{target_service}" unless target_service.include?('/')
|
|
16
19
|
|
|
17
20
|
service = client(token).get("services/#{parse_service_id(name)}")
|
|
18
|
-
existing_targets = service['links'].map{|l| l['
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
21
|
+
existing_targets = service['links'].map{ |l| l['id'].split('/', 2)[1] }
|
|
22
|
+
if existing_targets.include?(target_service.to_s)
|
|
23
|
+
exit_with_error("Service is already linked to #{target.to_s}")
|
|
24
|
+
end
|
|
25
|
+
links = service['links'].map{ |l|
|
|
26
|
+
{ name: l['id'].split('/', 2)[1], alias: l['alias'] }
|
|
27
|
+
}
|
|
28
|
+
links << {name: target_service.to_s, alias: target.to_s}
|
|
29
|
+
links.compact!
|
|
22
30
|
data = {links: links}
|
|
23
31
|
spinner "Linking #{name.colorize(:cyan)} to #{target.colorize(:cyan)} " do
|
|
24
32
|
update_service(token, name, data)
|
|
@@ -13,13 +13,19 @@ module Kontena::Cli::Services
|
|
|
13
13
|
def execute
|
|
14
14
|
require_api_url
|
|
15
15
|
token = require_token
|
|
16
|
-
|
|
16
|
+
target_service = target
|
|
17
|
+
target_service = "null/#{target_service}" unless target_service.include?('/')
|
|
18
|
+
target_id = "#{current_grid}/#{target_service}"
|
|
17
19
|
service = client(token).get("services/#{parse_service_id(name)}")
|
|
18
|
-
links = service['links']
|
|
19
|
-
|
|
20
|
-
|
|
20
|
+
links = service['links']
|
|
21
|
+
unless links.find { |l| l['id'] == target_id }
|
|
22
|
+
exit_with_error("Service is not linked to #{target.to_s}")
|
|
23
|
+
end
|
|
24
|
+
links.delete_if { |l| l['id'] == target_id }
|
|
21
25
|
data = {links: links}
|
|
22
|
-
|
|
26
|
+
spinner "Unlinking #{name.colorize(:cyan)} from #{target.colorize(:cyan)} " do
|
|
27
|
+
update_service(token, name, data)
|
|
28
|
+
end
|
|
23
29
|
end
|
|
24
30
|
end
|
|
25
31
|
end
|
|
@@ -49,13 +49,16 @@ module Kontena::Cli::Stacks
|
|
|
49
49
|
data['log_opts'] = options['log_opt'] if options['log_opt'] && !options['log_opt'].empty?
|
|
50
50
|
deploy_opts = options['deploy'] || {}
|
|
51
51
|
data['strategy'] = deploy_opts['strategy'] if deploy_opts['strategy']
|
|
52
|
-
deploy = {
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
52
|
+
deploy = {
|
|
53
|
+
'wait_for_port' => deploy_opts['wait_for_port'],
|
|
54
|
+
'min_health' => deploy_opts['min_health']
|
|
55
|
+
}
|
|
56
|
+
if deploy_opts.has_key?('interval')
|
|
57
|
+
deploy['interval'] = parse_relative_time(deploy_opts['interval'])
|
|
58
|
+
else
|
|
59
|
+
deploy['interval'] = nil
|
|
60
|
+
end
|
|
61
|
+
data['deploy_opts'] = deploy
|
|
59
62
|
data['hooks'] = options['hooks'] || {}
|
|
60
63
|
data['secrets'] = options['secrets'] if options['secrets']
|
|
61
64
|
data['build'] = parse_build_options(options) if options['build']
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
module Kontena::Cli::Stacks
|
|
2
|
+
module YAML
|
|
3
|
+
module Opto
|
|
4
|
+
module Resolvers; end
|
|
5
|
+
module Setters; end
|
|
6
|
+
end
|
|
7
|
+
end
|
|
8
|
+
end
|
|
9
|
+
require 'opto'
|
|
10
|
+
require_relative 'opto/vault_setter'
|
|
11
|
+
require_relative 'opto/vault_resolver'
|
|
12
|
+
require_relative 'opto/prompt_resolver'
|
|
13
|
+
require_relative 'opto/service_instances_resolver'
|
|
14
|
+
require_relative 'opto/vault_cert_prompt_resolver'
|
|
15
|
+
require_relative 'opto/service_link_resolver'
|
|
@@ -1,9 +1,12 @@
|
|
|
1
|
+
require 'kontena/cli/stacks/yaml/opto'
|
|
2
|
+
require 'kontena/cli/common'
|
|
3
|
+
|
|
1
4
|
module Kontena::Cli::Stacks
|
|
2
5
|
module YAML
|
|
3
|
-
class Prompt < Opto::Resolver
|
|
6
|
+
class Prompt < ::Opto::Resolver
|
|
4
7
|
include Kontena::Cli::Common
|
|
5
8
|
|
|
6
|
-
using Opto::Extension::HashStringOrSymbolKey
|
|
9
|
+
using ::Opto::Extension::HashStringOrSymbolKey
|
|
7
10
|
|
|
8
11
|
def enum?
|
|
9
12
|
option.type == 'enum'
|
|
@@ -50,10 +53,16 @@ module Kontena::Cli::Stacks
|
|
|
50
53
|
prompt.yes?(question_text, default: option.default == false ? false : true)
|
|
51
54
|
end
|
|
52
55
|
|
|
53
|
-
def
|
|
54
|
-
|
|
56
|
+
def echo?
|
|
57
|
+
return true if option.handler.nil?
|
|
58
|
+
return true if option.handler.options.nil?
|
|
59
|
+
return true if option.handler.options[:echo].nil?
|
|
60
|
+
option.handler.options[:echo]
|
|
55
61
|
end
|
|
56
62
|
|
|
63
|
+
def ask
|
|
64
|
+
prompt.ask(question_text, default: option.default, echo: echo?)
|
|
65
|
+
end
|
|
57
66
|
|
|
58
67
|
def resolve
|
|
59
68
|
return nil if option.skip?
|
|
@@ -68,4 +77,3 @@ module Kontena::Cli::Stacks
|
|
|
68
77
|
end
|
|
69
78
|
end
|
|
70
79
|
end
|
|
71
|
-
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
module Kontena::Cli::Stacks
|
|
2
2
|
module YAML
|
|
3
|
-
class Opto::Resolvers::ServiceInstances < Opto::Resolver
|
|
3
|
+
class Opto::Resolvers::ServiceInstances < ::Opto::Resolver
|
|
4
4
|
def resolve
|
|
5
5
|
read_command = Kontena::Cli::Stacks::ShowCommand.new([self.stack])
|
|
6
6
|
stack = read_command.fetch_stack(self.stack)
|
|
@@ -1,45 +1,76 @@
|
|
|
1
|
-
module Kontena::Cli::Stacks
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
else
|
|
21
|
-
name = "#{s.dig('stack', 'name')}/#{s['name']}"
|
|
22
|
-
end
|
|
23
|
-
menu.choice name, "#{s.dig('stack', 'name')}/#{s['name']}"
|
|
24
|
-
end
|
|
1
|
+
module Kontena::Cli::Stacks::YAML::Opto::Resolvers
|
|
2
|
+
class ServiceLink < ::Opto::Resolver
|
|
3
|
+
include Kontena::Cli::Common
|
|
4
|
+
|
|
5
|
+
def resolve
|
|
6
|
+
message = hint['prompt']
|
|
7
|
+
name_filter = hint['name']
|
|
8
|
+
image_filter = hint['image']
|
|
9
|
+
raise "prompt missing" unless message
|
|
10
|
+
|
|
11
|
+
services = get_services
|
|
12
|
+
services = filter_by_image(services, image_filter) if image_filter
|
|
13
|
+
services = filter_by_name(services, name_filter) if name_filter
|
|
14
|
+
return nil if services.size == 0
|
|
15
|
+
prompt.select(message) do |menu|
|
|
16
|
+
menu.default(default_index(services)) if option.default
|
|
17
|
+
menu.choice "<none>", nil unless option.required?
|
|
18
|
+
services.each do |s|
|
|
19
|
+
menu.choice service_name(s), service_link(s)
|
|
25
20
|
end
|
|
26
21
|
end
|
|
22
|
+
end
|
|
27
23
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
24
|
+
# @return [Array<Hash>]
|
|
25
|
+
def get_services
|
|
26
|
+
client.get("grids/#{current_grid}/services")['services']
|
|
27
|
+
rescue
|
|
28
|
+
[]
|
|
29
|
+
end
|
|
33
30
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
31
|
+
# @param [Array<Hash>] services
|
|
32
|
+
# @return [Integer]
|
|
33
|
+
def default_index(services)
|
|
34
|
+
index = services.index {|s| service_link(s) == option.default }
|
|
35
|
+
if index
|
|
36
|
+
index.to_i + 1
|
|
37
|
+
else
|
|
38
|
+
0
|
|
38
39
|
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
# @param [Hash] service
|
|
43
|
+
# @return [String]
|
|
44
|
+
def service_link(service)
|
|
45
|
+
grid, stack, service = service['id'].split('/')
|
|
46
|
+
"#{stack}/#{service}"
|
|
47
|
+
end
|
|
39
48
|
|
|
40
|
-
|
|
41
|
-
|
|
49
|
+
# @param [Hash] service
|
|
50
|
+
# @return [String]
|
|
51
|
+
def service_name(service)
|
|
52
|
+
grid, stack, service = service['id'].split('/')
|
|
53
|
+
if stack == 'null'.freeze
|
|
54
|
+
service
|
|
55
|
+
else
|
|
56
|
+
"#{stack}/#{service}"
|
|
42
57
|
end
|
|
43
58
|
end
|
|
59
|
+
|
|
60
|
+
def filter_by_image(services, image)
|
|
61
|
+
services.select { |s|
|
|
62
|
+
s['image'].include?(image)
|
|
63
|
+
}
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def filter_by_name(services, name)
|
|
67
|
+
services.select { |s|
|
|
68
|
+
s['name'].include?(name)
|
|
69
|
+
}
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def stack
|
|
73
|
+
ENV['STACK']
|
|
74
|
+
end
|
|
44
75
|
end
|
|
45
76
|
end
|
|
@@ -1,15 +1,38 @@
|
|
|
1
|
-
module Kontena::Cli::Stacks
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
include Kontena::Cli::Common
|
|
1
|
+
module Kontena::Cli::Stacks::YAML::Opto::Resolvers
|
|
2
|
+
class VaultCertPrompt < ::Opto::Resolver
|
|
3
|
+
include Kontena::Cli::Common
|
|
5
4
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
5
|
+
def resolve
|
|
6
|
+
message = hint || 'Select SSL certs'
|
|
7
|
+
secrets = get_secrets.select{ |s|
|
|
8
|
+
s['name'].match(/(ssl|cert)/i)
|
|
9
|
+
}
|
|
10
|
+
if secrets.size > 0
|
|
11
|
+
prompt.multi_select(hint) do |menu|
|
|
12
|
+
menu.default(*default_indexes(secrets)) if option.default
|
|
13
|
+
secrets.each do |s|
|
|
14
|
+
menu.choice s['name']
|
|
15
|
+
end
|
|
16
|
+
end
|
|
12
17
|
end
|
|
13
18
|
end
|
|
19
|
+
|
|
20
|
+
# @return [Array<Hash>] secrets
|
|
21
|
+
def get_secrets
|
|
22
|
+
client.get("grids/#{current_grid}/secrets")['secrets']
|
|
23
|
+
rescue
|
|
24
|
+
[]
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# @param [Array<Hash>] secrets
|
|
28
|
+
# @return [Array<Integer>]
|
|
29
|
+
def default_indexes(secrets)
|
|
30
|
+
indexes = []
|
|
31
|
+
option.default.to_a.each do |name|
|
|
32
|
+
index = secrets.index { |s| s['name'] == name }
|
|
33
|
+
indexes << index.to_i + 1 if index
|
|
34
|
+
end
|
|
35
|
+
indexes
|
|
36
|
+
end
|
|
14
37
|
end
|
|
15
38
|
end
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
module Kontena::Cli::Stacks
|
|
2
2
|
module YAML
|
|
3
|
-
class Opto::Setters::Vault < Opto::Setter
|
|
3
|
+
class Opto::Setters::Vault < ::Opto::Setter
|
|
4
4
|
def set(value)
|
|
5
5
|
require 'shellwords'
|
|
6
6
|
ENV["DEBUG"] && STDERR.puts("Setting to vault: #{hint}")
|
|
@@ -9,4 +9,3 @@ module Kontena::Cli::Stacks
|
|
|
9
9
|
end
|
|
10
10
|
end
|
|
11
11
|
end
|
|
12
|
-
|
|
@@ -2,6 +2,11 @@ require_relative '../../../util'
|
|
|
2
2
|
|
|
3
3
|
module Kontena::Cli::Stacks
|
|
4
4
|
module YAML
|
|
5
|
+
module Opto
|
|
6
|
+
module Resolvers; end
|
|
7
|
+
module Setters; end
|
|
8
|
+
end
|
|
9
|
+
|
|
5
10
|
class Reader
|
|
6
11
|
include Kontena::Util
|
|
7
12
|
include Kontena::Cli::Common
|
|
@@ -12,13 +17,7 @@ module Kontena::Cli::Stacks
|
|
|
12
17
|
require 'yaml'
|
|
13
18
|
require_relative 'service_extender'
|
|
14
19
|
require_relative 'validator_v3'
|
|
15
|
-
|
|
16
|
-
require_relative 'opto/vault_setter'
|
|
17
|
-
require_relative 'opto/vault_resolver'
|
|
18
|
-
require_relative 'opto/prompt_resolver'
|
|
19
|
-
require_relative 'opto/service_instances_resolver'
|
|
20
|
-
require_relative 'opto/vault_cert_prompt_resolver'
|
|
21
|
-
require_relative 'opto/service_link_resolver'
|
|
20
|
+
require_relative 'opto'
|
|
22
21
|
require 'liquid'
|
|
23
22
|
|
|
24
23
|
@file = file
|
|
@@ -88,7 +87,7 @@ module Kontena::Cli::Stacks
|
|
|
88
87
|
# @return [Opto::Group]
|
|
89
88
|
def variables
|
|
90
89
|
return @variables if @variables
|
|
91
|
-
@variables = Opto::Group.new(
|
|
90
|
+
@variables = ::Opto::Group.new(
|
|
92
91
|
(internals_interpolated_yaml['variables'] || {}).merge('STACK' => { type: :string, value: env['STACK']}, 'GRID' => {type: :string, value: env['GRID']}),
|
|
93
92
|
defaults: {
|
|
94
93
|
from: :env,
|
|
@@ -33,7 +33,6 @@ module Kontena
|
|
|
33
33
|
)
|
|
34
34
|
plugin_version = version.nil? ? Gem::Requirement.default : Gem::Requirement.new(version)
|
|
35
35
|
without_safe { cmd.install(prefix(plugin_name), plugin_version) }
|
|
36
|
-
cleanup_plugin(plugin_name)
|
|
37
36
|
cmd.installed_gems
|
|
38
37
|
end
|
|
39
38
|
|
|
@@ -123,7 +122,7 @@ module Kontena
|
|
|
123
122
|
def cleanup_plugin(plugin_name)
|
|
124
123
|
require 'rubygems/commands/cleanup_command'
|
|
125
124
|
cmd = Gem::Commands::CleanupCommand.new
|
|
126
|
-
options = [
|
|
125
|
+
options = []
|
|
127
126
|
options += ['-q', '--no-verbose'] unless ENV["DEBUG"]
|
|
128
127
|
cmd.handle_options options
|
|
129
128
|
without_safe { cmd.execute }
|
data/lib/kontena_cli.rb
CHANGED
|
@@ -128,35 +128,42 @@ describe Kontena::Cli::Common do
|
|
|
128
128
|
end
|
|
129
129
|
end
|
|
130
130
|
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
expect(subject.confirm_command('name-to-confirm')).to be_truthy
|
|
136
|
-
expect{subject.confirm_command('name-to-confirm')}.to_not raise_error
|
|
131
|
+
context 'confirm' do
|
|
132
|
+
before(:each) do
|
|
133
|
+
expect($stdout).to receive(:tty?).at_least(:once).and_return(true)
|
|
134
|
+
expect($stdin).to receive(:tty?).at_least(:once).and_return(true)
|
|
137
135
|
end
|
|
138
136
|
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
137
|
+
describe '#confirm_command' do
|
|
138
|
+
it 'returns true if input matches' do
|
|
139
|
+
allow(subject).to receive(:ask).and_return('name-to-confirm')
|
|
142
140
|
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
141
|
+
expect(subject.confirm_command('name-to-confirm')).to be_truthy
|
|
142
|
+
expect{subject.confirm_command('name-to-confirm')}.to_not raise_error
|
|
143
|
+
end
|
|
146
144
|
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
145
|
+
it 'raises error unless input matches' do
|
|
146
|
+
expect(subject).to receive(:ask).and_return('wrong-name')
|
|
147
|
+
expect(subject).to receive(:error).with(/did not match/)
|
|
150
148
|
|
|
151
|
-
|
|
152
|
-
|
|
149
|
+
subject.confirm_command('name-to-confirm')
|
|
150
|
+
end
|
|
153
151
|
end
|
|
154
152
|
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
153
|
+
describe '#confirm' do
|
|
154
|
+
it 'returns true if confirmed' do
|
|
155
|
+
allow(subject.prompt).to receive(:yes?).and_return(true)
|
|
158
156
|
|
|
159
|
-
|
|
157
|
+
expect(subject.confirm).to be_truthy
|
|
158
|
+
expect{subject.confirm}.to_not raise_error
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
it 'raises error unless confirmed' do
|
|
162
|
+
expect(subject.prompt).to receive(:yes?).and_return(false)
|
|
163
|
+
expect(subject).to receive(:error).with(/Aborted/)
|
|
164
|
+
|
|
165
|
+
subject.confirm
|
|
166
|
+
end
|
|
160
167
|
end
|
|
161
168
|
end
|
|
162
169
|
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
require_relative "../../../spec_helper"
|
|
2
|
+
require "kontena/cli/master/init_cloud_command"
|
|
3
|
+
|
|
4
|
+
describe Kontena::Cli::Master::InitCloudCommand do
|
|
5
|
+
|
|
6
|
+
include ClientHelpers
|
|
7
|
+
include RequirementsHelper
|
|
8
|
+
|
|
9
|
+
mock_current_master
|
|
10
|
+
|
|
11
|
+
let(:cloud_client) { double(:cc) }
|
|
12
|
+
|
|
13
|
+
before(:each) do
|
|
14
|
+
allow(subject).to receive(:current_account).and_return('foo')
|
|
15
|
+
allow(subject).to receive(:cloud_auth?).and_return(true)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
describe '#execute' do
|
|
19
|
+
expect_to_require_current_master
|
|
20
|
+
expect_to_require_current_master_token
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
it 'runs the invite self after deploy callback' do
|
|
24
|
+
expect(Kontena).to receive(:run).with('cloud master add --current --force').and_return(true)
|
|
25
|
+
expect_any_instance_of(Kontena::Callbacks::InviteSelfAfterDeploy).to receive(:after).and_return(true)
|
|
26
|
+
subject.run(['--force'])
|
|
27
|
+
end
|
|
28
|
+
end
|
|
@@ -25,7 +25,7 @@ describe Kontena::Cli::Services::LinkCommand do
|
|
|
25
25
|
it 'aborts if service is already linked' do
|
|
26
26
|
allow(client).to receive(:get).and_return({
|
|
27
27
|
'links' => [
|
|
28
|
-
{'alias' => 'service-b', '
|
|
28
|
+
{'alias' => 'service-b', 'id' => "grid/null/service-b"}
|
|
29
29
|
]
|
|
30
30
|
})
|
|
31
31
|
expect {
|
|
@@ -35,7 +35,7 @@ describe Kontena::Cli::Services::LinkCommand do
|
|
|
35
35
|
|
|
36
36
|
it 'sends link to master' do
|
|
37
37
|
expect(client).to receive(:put).with(
|
|
38
|
-
'services/test-grid/null/service-a', {links: [{name: 'service-b', alias: 'service-b'}]}
|
|
38
|
+
'services/test-grid/null/service-a', {links: [{name: 'null/service-b', alias: 'service-b'}]}
|
|
39
39
|
)
|
|
40
40
|
subject.run(['service-a', 'service-b'])
|
|
41
41
|
end
|
|
@@ -9,7 +9,7 @@ describe Kontena::Cli::Services::UnlinkCommand do
|
|
|
9
9
|
before(:each) do
|
|
10
10
|
allow(client).to receive(:get).and_return({
|
|
11
11
|
'links' => [
|
|
12
|
-
{'alias' => 'service-b', '
|
|
12
|
+
{'alias' => 'service-b', 'id' => "test-grid/null/service-b", 'name' => 'service-b'}
|
|
13
13
|
]
|
|
14
14
|
})
|
|
15
15
|
end
|
|
@@ -335,12 +335,16 @@ describe Kontena::Cli::Stacks::ServiceGenerator do
|
|
|
335
335
|
expect(result['deploy_opts']['interval']).to eq(60)
|
|
336
336
|
end
|
|
337
337
|
|
|
338
|
-
it '
|
|
338
|
+
it 'returns nil values if no deploy options are defined' do
|
|
339
339
|
data = {
|
|
340
340
|
'image' => 'foo/bar:latest'
|
|
341
341
|
}
|
|
342
342
|
result = subject.send(:parse_data, data)
|
|
343
|
-
expect(result['deploy_opts']).to
|
|
343
|
+
expect(result['deploy_opts']).to eq({
|
|
344
|
+
'interval' => nil,
|
|
345
|
+
'min_health' => nil,
|
|
346
|
+
'wait_for_port' => nil
|
|
347
|
+
})
|
|
344
348
|
end
|
|
345
349
|
end
|
|
346
350
|
|
|
@@ -381,5 +385,5 @@ describe Kontena::Cli::Stacks::ServiceGenerator do
|
|
|
381
385
|
expect(result['secrets']).to be_nil
|
|
382
386
|
end
|
|
383
387
|
end
|
|
384
|
-
end
|
|
388
|
+
end
|
|
385
389
|
end
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
require 'opto'
|
|
2
|
+
require 'kontena_cli'
|
|
3
|
+
require 'kontena/cli/stacks/yaml/opto'
|
|
4
|
+
|
|
5
|
+
describe Kontena::Cli::Stacks::YAML::Prompt do
|
|
6
|
+
|
|
7
|
+
describe 'echoing' do
|
|
8
|
+
let(:option_without_echo) { Opto::Option.new(type: 'string', name: 'foo', from: 'prompt', echo: false) }
|
|
9
|
+
let(:option_with_echo) { Opto::Option.new(type: 'string', name: 'foo', from: 'prompt') }
|
|
10
|
+
let(:prompt) { double(:prompt) }
|
|
11
|
+
|
|
12
|
+
before(:each) do
|
|
13
|
+
allow(Kontena).to receive(:prompt).and_return(prompt)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
it 'turns echo off when variable has "echo: false"' do
|
|
17
|
+
expect(prompt).to receive(:ask).with(/Enter/, hash_including(echo: false))
|
|
18
|
+
option_without_echo.value
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
it 'keeps echo on when variable does not have "echo: false"' do
|
|
22
|
+
expect(prompt).to receive(:ask).with(/Enter/, hash_not_including(echo: false))
|
|
23
|
+
option_with_echo.value
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
require 'opto'
|
|
2
|
+
require 'kontena/cli/stacks/yaml/opto/service_link_resolver'
|
|
3
|
+
|
|
4
|
+
describe Kontena::Cli::Stacks::YAML::Opto::Resolvers::ServiceLink do
|
|
5
|
+
let(:subject) do
|
|
6
|
+
described_class.new({'prompt' => 'foo'})
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
describe '#resolve' do
|
|
10
|
+
it 'returns nil if no matching services' do
|
|
11
|
+
expect(subject).to receive(:get_services).and_return([])
|
|
12
|
+
expect(subject).not_to receive(:prompt)
|
|
13
|
+
expect(subject.resolve).to be_nil
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
it 'prompts user if matching services' do
|
|
17
|
+
prompt = double(:prompt)
|
|
18
|
+
allow(subject).to receive(:prompt).and_return(prompt)
|
|
19
|
+
expect(prompt).to receive(:select).and_return('null/bar')
|
|
20
|
+
expect(subject).to receive(:get_services).and_return([
|
|
21
|
+
{'id' => 'foo/null/bar'}
|
|
22
|
+
])
|
|
23
|
+
expect(subject.resolve).to eq('null/bar')
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
describe '#default_index' do
|
|
28
|
+
let(:option) do
|
|
29
|
+
::Opto::Option.new(default: 'foo/bar')
|
|
30
|
+
end
|
|
31
|
+
let(:subject) do
|
|
32
|
+
described_class.new({'prompt' => 'foo'}, option)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
it 'returns matching index' do
|
|
36
|
+
services = [
|
|
37
|
+
{'id' => 'test/foo/foo'},
|
|
38
|
+
{'id' => 'test/foo/bar'},
|
|
39
|
+
{'id' => 'test/asd/asd'}
|
|
40
|
+
]
|
|
41
|
+
index = subject.default_index(services)
|
|
42
|
+
expect(index).to eq(2)
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
it 'returns 0 if no matches' do
|
|
46
|
+
services = [
|
|
47
|
+
{'id' => 'test/foo/foo'},
|
|
48
|
+
{'id' => 'test/asd/asd'}
|
|
49
|
+
]
|
|
50
|
+
index = subject.default_index(services)
|
|
51
|
+
expect(index).to eq(0)
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
require 'opto'
|
|
2
|
+
require 'kontena/cli/stacks/yaml/opto/vault_cert_prompt_resolver'
|
|
3
|
+
|
|
4
|
+
describe Kontena::Cli::Stacks::YAML::Opto::Resolvers::VaultCertPrompt do
|
|
5
|
+
describe '#resolve' do
|
|
6
|
+
it 'returns nil if no matching secrets' do
|
|
7
|
+
expect(subject).to receive(:get_secrets).and_return([])
|
|
8
|
+
expect(subject).not_to receive(:prompt)
|
|
9
|
+
expect(subject.resolve).to be_nil
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
it 'prompts user if matching secrets' do
|
|
13
|
+
prompt = double(:prompt)
|
|
14
|
+
allow(subject).to receive(:prompt).and_return(prompt)
|
|
15
|
+
expect(prompt).to receive(:multi_select).and_return('ssl-cert')
|
|
16
|
+
expect(subject).to receive(:get_secrets).and_return([{'name' => 'ssl-cert'}])
|
|
17
|
+
subject.resolve
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
describe '#default_indexes' do
|
|
22
|
+
let(:option) do
|
|
23
|
+
Opto::Option.new(default: ['ssl-cert-1', 'ssl-cert-3'])
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
let(:subject) do
|
|
27
|
+
described_class.new('foo', option)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
it 'returns all default indexes if found' do
|
|
31
|
+
secrets = [
|
|
32
|
+
{'name' => 'ssl-cert-1'},
|
|
33
|
+
{'name' => 'ssl-cert-2'},
|
|
34
|
+
{'name' => 'ssl-cert-3'}
|
|
35
|
+
]
|
|
36
|
+
indexes = subject.default_indexes(secrets)
|
|
37
|
+
expect(indexes).to eq([1, 3])
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
it 'returns partially found defaults' do
|
|
41
|
+
secrets = [
|
|
42
|
+
{'name' => 'ssl-cert-a'},
|
|
43
|
+
{'name' => 'ssl-cert-b'},
|
|
44
|
+
{'name' => 'ssl-cert-3'}
|
|
45
|
+
]
|
|
46
|
+
indexes = subject.default_indexes(secrets)
|
|
47
|
+
expect(indexes).to eq([3])
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
it 'returns empty array if no matches' do
|
|
51
|
+
secrets = [
|
|
52
|
+
{'name' => 'ssl-cert-a'}
|
|
53
|
+
]
|
|
54
|
+
indexes = subject.default_indexes(secrets)
|
|
55
|
+
expect(indexes).to eq([])
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
it 'returns empty array if no secrets' do
|
|
59
|
+
secrets = []
|
|
60
|
+
indexes = subject.default_indexes(secrets)
|
|
61
|
+
expect(indexes).to eq([])
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
it 'returns empty array if no defaults' do
|
|
65
|
+
secrets = [
|
|
66
|
+
{'name' => 'ssl-cert-a'}
|
|
67
|
+
]
|
|
68
|
+
allow(subject.option).to receive(:default).and_return([])
|
|
69
|
+
indexes = subject.default_indexes(secrets)
|
|
70
|
+
expect(indexes).to eq([])
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
end
|
|
@@ -1,28 +1,37 @@
|
|
|
1
1
|
require_relative '../spec_helper'
|
|
2
2
|
require 'kontena_cli'
|
|
3
|
+
require 'kontena/light_prompt'
|
|
3
4
|
|
|
4
5
|
describe Kontena do
|
|
5
|
-
|
|
6
|
+
context 'prompt' do
|
|
7
|
+
it 'uses light prompt on windows' do
|
|
8
|
+
allow(ENV).to receive(:[]).with('OS').and_return('Windows_NT')
|
|
9
|
+
expect(Kontena.prompt).to be_kind_of(Kontena::LightPrompt)
|
|
10
|
+
end
|
|
11
|
+
end
|
|
6
12
|
|
|
7
13
|
describe '#run' do
|
|
8
|
-
let(:whoami) { double(:
|
|
14
|
+
let(:whoami) { double(:whoami) }
|
|
9
15
|
|
|
10
16
|
before(:each) do
|
|
11
|
-
expect(Kontena::MainCommand).to receive(:new).and_call_original
|
|
12
17
|
expect(Kontena::Cli::WhoamiCommand).to receive(:new).and_return(whoami)
|
|
13
18
|
expect(whoami).to receive(:run).with(['--bash-completion-path']).and_return(true)
|
|
14
19
|
end
|
|
15
20
|
|
|
16
21
|
it 'accepts a command line as string' do
|
|
17
|
-
|
|
22
|
+
|
|
23
|
+
Kontena.run('whoami --bash-completion-path')
|
|
18
24
|
end
|
|
19
25
|
|
|
20
26
|
it 'accepts a command line as a list of parameters' do
|
|
21
|
-
|
|
27
|
+
Kontena.run('whoami', '--bash-completion-path')
|
|
22
28
|
end
|
|
23
29
|
|
|
24
30
|
it 'accepts a command line as an array' do
|
|
25
|
-
|
|
31
|
+
Kontena.run(['whoami', '--bash-completion-path'])
|
|
26
32
|
end
|
|
27
33
|
end
|
|
28
34
|
end
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
require_relative '../spec_helper'
|
|
2
|
+
require 'kontena/main_command'
|
|
3
|
+
|
|
4
|
+
describe Kontena::MainCommand do
|
|
5
|
+
let(:subject) { described_class.new('kontena') }
|
|
6
|
+
|
|
7
|
+
describe '--version' do
|
|
8
|
+
it 'outputs the version number and exits' do
|
|
9
|
+
expect do
|
|
10
|
+
expect{subject.run(['--version'])}.to output(/kontena-cli #{Kontena::Cli::VERSION}/).to_stdout
|
|
11
|
+
end.to raise_error(SystemExit) do |exc|
|
|
12
|
+
expect(exc.status).to eq 0
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: kontena-cli
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.1.
|
|
4
|
+
version: 1.1.1.rc1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Kontena, Inc
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2017-02-
|
|
11
|
+
date: 2017-02-08 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: bundler
|
|
@@ -140,16 +140,16 @@ dependencies:
|
|
|
140
140
|
name: opto
|
|
141
141
|
requirement: !ruby/object:Gem::Requirement
|
|
142
142
|
requirements:
|
|
143
|
-
- -
|
|
143
|
+
- - '='
|
|
144
144
|
- !ruby/object:Gem::Version
|
|
145
|
-
version: 1.8.
|
|
145
|
+
version: 1.8.3
|
|
146
146
|
type: :runtime
|
|
147
147
|
prerelease: false
|
|
148
148
|
version_requirements: !ruby/object:Gem::Requirement
|
|
149
149
|
requirements:
|
|
150
|
-
- -
|
|
150
|
+
- - '='
|
|
151
151
|
- !ruby/object:Gem::Version
|
|
152
|
-
version: 1.8.
|
|
152
|
+
version: 1.8.3
|
|
153
153
|
- !ruby/object:Gem::Dependency
|
|
154
154
|
name: semantic
|
|
155
155
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -433,6 +433,7 @@ files:
|
|
|
433
433
|
- lib/kontena/cli/stacks/yaml/custom_validators/extends_validator.rb
|
|
434
434
|
- lib/kontena/cli/stacks/yaml/custom_validators/hooks_validator.rb
|
|
435
435
|
- lib/kontena/cli/stacks/yaml/custom_validators/secrets_validator.rb
|
|
436
|
+
- lib/kontena/cli/stacks/yaml/opto.rb
|
|
436
437
|
- lib/kontena/cli/stacks/yaml/opto/prompt_resolver.rb
|
|
437
438
|
- lib/kontena/cli/stacks/yaml/opto/service_instances_resolver.rb
|
|
438
439
|
- lib/kontena/cli/stacks/yaml/opto/service_link_resolver.rb
|
|
@@ -555,6 +556,7 @@ files:
|
|
|
555
556
|
- spec/kontena/cli/helpers/log_helper_spec.rb
|
|
556
557
|
- spec/kontena/cli/main_command_spec.rb
|
|
557
558
|
- spec/kontena/cli/master/current_command_spec.rb
|
|
559
|
+
- spec/kontena/cli/master/init_cloud_command_spec.rb
|
|
558
560
|
- spec/kontena/cli/master/login_command_spec.rb
|
|
559
561
|
- spec/kontena/cli/master/logout_command_spec.rb
|
|
560
562
|
- spec/kontena/cli/master/use_command_spec.rb
|
|
@@ -582,6 +584,9 @@ files:
|
|
|
582
584
|
- spec/kontena/cli/stacks/service_generator_v2_spec.rb
|
|
583
585
|
- spec/kontena/cli/stacks/show_command_spec.rb
|
|
584
586
|
- spec/kontena/cli/stacks/upgrade_command_spec.rb
|
|
587
|
+
- spec/kontena/cli/stacks/yaml/opto/prompt_resolver_spec.rb
|
|
588
|
+
- spec/kontena/cli/stacks/yaml/opto/service_link_resolver_spec.rb
|
|
589
|
+
- spec/kontena/cli/stacks/yaml/opto/vault_cert_prompt_resolver_spec.rb
|
|
585
590
|
- spec/kontena/cli/stacks/yaml/reader_spec.rb
|
|
586
591
|
- spec/kontena/cli/stacks/yaml/service_extender_spec.rb
|
|
587
592
|
- spec/kontena/cli/stacks/yaml/validator_v3_spec.rb
|
|
@@ -592,6 +597,7 @@ files:
|
|
|
592
597
|
- spec/kontena/client_spec.rb
|
|
593
598
|
- spec/kontena/config_spec.rb
|
|
594
599
|
- spec/kontena/kontena_cli_spec.rb
|
|
600
|
+
- spec/kontena/main_command_spec.rb
|
|
595
601
|
- spec/kontena/plugin_manager_spec.rb
|
|
596
602
|
- spec/spec_helper.rb
|
|
597
603
|
- spec/support/client_helpers.rb
|
|
@@ -615,9 +621,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
615
621
|
version: 2.1.0
|
|
616
622
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
617
623
|
requirements:
|
|
618
|
-
- - "
|
|
624
|
+
- - ">"
|
|
619
625
|
- !ruby/object:Gem::Version
|
|
620
|
-
version:
|
|
626
|
+
version: 1.3.1
|
|
621
627
|
requirements: []
|
|
622
628
|
rubyforge_project:
|
|
623
629
|
rubygems_version: 2.6.8
|
|
@@ -683,6 +689,7 @@ test_files:
|
|
|
683
689
|
- spec/kontena/cli/helpers/log_helper_spec.rb
|
|
684
690
|
- spec/kontena/cli/main_command_spec.rb
|
|
685
691
|
- spec/kontena/cli/master/current_command_spec.rb
|
|
692
|
+
- spec/kontena/cli/master/init_cloud_command_spec.rb
|
|
686
693
|
- spec/kontena/cli/master/login_command_spec.rb
|
|
687
694
|
- spec/kontena/cli/master/logout_command_spec.rb
|
|
688
695
|
- spec/kontena/cli/master/use_command_spec.rb
|
|
@@ -710,6 +717,9 @@ test_files:
|
|
|
710
717
|
- spec/kontena/cli/stacks/service_generator_v2_spec.rb
|
|
711
718
|
- spec/kontena/cli/stacks/show_command_spec.rb
|
|
712
719
|
- spec/kontena/cli/stacks/upgrade_command_spec.rb
|
|
720
|
+
- spec/kontena/cli/stacks/yaml/opto/prompt_resolver_spec.rb
|
|
721
|
+
- spec/kontena/cli/stacks/yaml/opto/service_link_resolver_spec.rb
|
|
722
|
+
- spec/kontena/cli/stacks/yaml/opto/vault_cert_prompt_resolver_spec.rb
|
|
713
723
|
- spec/kontena/cli/stacks/yaml/reader_spec.rb
|
|
714
724
|
- spec/kontena/cli/stacks/yaml/service_extender_spec.rb
|
|
715
725
|
- spec/kontena/cli/stacks/yaml/validator_v3_spec.rb
|
|
@@ -720,6 +730,7 @@ test_files:
|
|
|
720
730
|
- spec/kontena/client_spec.rb
|
|
721
731
|
- spec/kontena/config_spec.rb
|
|
722
732
|
- spec/kontena/kontena_cli_spec.rb
|
|
733
|
+
- spec/kontena/main_command_spec.rb
|
|
723
734
|
- spec/kontena/plugin_manager_spec.rb
|
|
724
735
|
- spec/spec_helper.rb
|
|
725
736
|
- spec/support/client_helpers.rb
|