kontena-cli 1.4.0.pre6 → 1.4.0.pre7
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +1 -1
- data/VERSION +1 -1
- data/bin/kontena +1 -1
- data/kontena-cli.gemspec +3 -3
- data/lib/kontena/cli/certificate/authorize_command.rb +67 -6
- data/lib/kontena/cli/certificate/get_command.rb +7 -0
- data/lib/kontena/cli/certificate/list_command.rb +75 -0
- data/lib/kontena/cli/certificate/register_command.rb +13 -2
- data/lib/kontena/cli/certificate/request_command.rb +20 -0
- data/lib/kontena/cli/certificate/show_command.rb +19 -0
- data/lib/kontena/cli/certificate_command.rb +4 -1
- data/lib/kontena/cli/cloud/master/add_command.rb +1 -1
- data/lib/kontena/cli/common.rb +21 -33
- data/lib/kontena/cli/etcd/health_command.rb +21 -27
- data/lib/kontena/cli/helpers/exec_helper.rb +15 -6
- data/lib/kontena/cli/helpers/health_helper.rb +12 -0
- data/lib/kontena/cli/helpers/log_helper.rb +2 -2
- data/lib/kontena/cli/helpers/time_helper.rb +29 -0
- data/lib/kontena/cli/master/init_cloud_command.rb +19 -0
- data/lib/kontena/cli/master/list_command.rb +1 -1
- data/lib/kontena/cli/master/ssh_command.rb +3 -1
- data/lib/kontena/cli/master/use_command.rb +1 -2
- data/lib/kontena/cli/node_command.rb +1 -0
- data/lib/kontena/cli/nodes/health_command.rb +28 -13
- data/lib/kontena/cli/nodes/list_command.rb +19 -3
- data/lib/kontena/cli/nodes/show_command.rb +4 -2
- data/lib/kontena/cli/nodes/ssh_command.rb +5 -2
- data/lib/kontena/cli/nodes/update_command.rb +2 -0
- data/lib/kontena/cli/plugins/install_command.rb +11 -8
- data/lib/kontena/cli/plugins/list_command.rb +5 -3
- data/lib/kontena/cli/plugins/search_command.rb +4 -2
- data/lib/kontena/cli/plugins/show_command.rb +17 -0
- data/lib/kontena/cli/plugins/uninstall_command.rb +9 -13
- data/lib/kontena/cli/registry/create_command.rb +1 -1
- data/lib/kontena/cli/services/create_command.rb +6 -0
- data/lib/kontena/cli/services/services_helper.rb +33 -6
- data/lib/kontena/cli/services/update_command.rb +6 -0
- data/lib/kontena/cli/stacks/build_command.rb +3 -3
- data/lib/kontena/cli/stacks/common.rb +105 -90
- data/lib/kontena/cli/stacks/deploy_command.rb +7 -3
- data/lib/kontena/cli/stacks/install_command.rb +39 -6
- data/lib/kontena/cli/stacks/list_command.rb +36 -4
- data/lib/kontena/cli/stacks/logs_command.rb +9 -2
- data/lib/kontena/cli/stacks/registry/pull_command.rb +2 -2
- data/lib/kontena/cli/stacks/registry/push_command.rb +20 -9
- data/lib/kontena/cli/stacks/registry/remove_command.rb +4 -4
- data/lib/kontena/cli/stacks/registry/show_command.rb +4 -4
- data/lib/kontena/cli/stacks/remove_command.rb +27 -1
- data/lib/kontena/cli/stacks/service_generator.rb +12 -2
- data/lib/kontena/cli/stacks/show_command.rb +35 -5
- data/lib/kontena/cli/stacks/stack_name.rb +71 -0
- data/lib/kontena/cli/stacks/upgrade_command.rb +127 -14
- data/lib/kontena/cli/stacks/validate_command.rb +38 -10
- data/lib/kontena/cli/stacks/yaml/custom_validators/certificates_validator.rb +22 -0
- data/lib/kontena/cli/stacks/yaml/opto/prompt_resolver.rb +1 -2
- data/lib/kontena/cli/stacks/yaml/reader.rb +211 -185
- data/lib/kontena/cli/stacks/yaml/service_extender.rb +6 -12
- data/lib/kontena/cli/stacks/yaml/stack_file_loader.rb +97 -0
- data/lib/kontena/cli/stacks/yaml/stack_file_loader/file_loader.rb +41 -0
- data/lib/kontena/cli/stacks/yaml/stack_file_loader/registry_loader.rb +24 -0
- data/lib/kontena/cli/stacks/yaml/stack_file_loader/uri_loader.rb +23 -0
- data/lib/kontena/cli/stacks/yaml/validations.rb +16 -0
- data/lib/kontena/cli/stacks/yaml/validator_v3.rb +25 -8
- data/lib/kontena/client.rb +2 -2
- data/lib/kontena/command.rb +11 -0
- data/lib/kontena/main_command.rb +3 -1
- data/lib/kontena/plugin_manager.rb +11 -198
- data/lib/kontena/plugin_manager/cleaner.rb +33 -0
- data/lib/kontena/plugin_manager/common.rb +86 -0
- data/lib/kontena/plugin_manager/installer.rb +54 -0
- data/lib/kontena/plugin_manager/loader.rb +93 -0
- data/lib/kontena/plugin_manager/rubygems_client.rb +42 -23
- data/lib/kontena/plugin_manager/uninstaller.rb +34 -0
- data/lib/kontena/util.rb +24 -0
- data/lib/kontena_cli.rb +1 -0
- data/omnibus/config/projects/kontena.rb +7 -1
- data/omnibus/config/software/{kontena.rb → kontena-cli.rb} +2 -0
- data/spec/fixtures/api/node.json +2 -1
- data/spec/fixtures/stack-internal-extend.yml +6 -1
- data/spec/fixtures/stack-with-dependencies-dep-1-1.yml +8 -0
- data/spec/fixtures/stack-with-dependencies-dep-1.yml +17 -0
- data/spec/fixtures/stack-with-dependencies-dep-2.yml +8 -0
- data/spec/fixtures/stack-with-dependencies-dep-3.yml +5 -0
- data/spec/fixtures/stack-with-dependencies-dep_2-removed.yml +17 -0
- data/spec/fixtures/stack-with-dependencies-dep_3-added.yml +25 -0
- data/spec/fixtures/stack-with-dependencies.yml +22 -0
- data/spec/fixtures/stack-with-variables.yml +3 -0
- data/spec/kontena/cli/etcd/health_command_spec.rb +45 -33
- data/spec/kontena/cli/helpers/exec_helper_spec.rb +2 -1
- data/spec/kontena/cli/master/init_cloud_command_spec.rb +14 -0
- data/spec/kontena/cli/nodes/health_command_spec.rb +74 -10
- data/spec/kontena/cli/nodes/list_command_spec.rb +381 -232
- data/spec/kontena/cli/nodes/show_command_spec.rb +31 -0
- data/spec/kontena/cli/nodes/ssh_command_spec.rb +18 -3
- data/spec/kontena/cli/plugins/install_command_spec.rb +1 -1
- data/spec/kontena/cli/stacks/build_command_spec.rb +6 -12
- data/spec/kontena/cli/stacks/common_spec.rb +42 -69
- data/spec/kontena/cli/stacks/install_command_spec.rb +57 -31
- data/spec/kontena/cli/stacks/list_command_spec.rb +44 -0
- data/spec/kontena/cli/stacks/logs_command_spec.rb +12 -1
- data/spec/kontena/cli/stacks/remove_command_spec.rb +39 -0
- data/spec/kontena/cli/stacks/show_command_spec.rb +16 -0
- data/spec/kontena/cli/stacks/stack_name_spec.rb +21 -0
- data/spec/kontena/cli/stacks/upgrade_command_spec.rb +73 -56
- data/spec/kontena/cli/stacks/validate_command_spec.rb +81 -0
- data/spec/kontena/cli/stacks/yaml/custom_validators/affinities_validator_spec.rb +22 -0
- data/spec/kontena/cli/stacks/yaml/reader_spec.rb +173 -169
- data/spec/kontena/cli/stacks/yaml/service_extender_spec.rb +12 -3
- data/spec/kontena/cli/stacks/yaml/stack_file_loader/file_loader_spec.rb +47 -0
- data/spec/kontena/cli/stacks/yaml/stack_file_loader/registry_loader_spec.rb +53 -0
- data/spec/kontena/cli/stacks/yaml/stack_file_loader/uri_loader_spec.rb +53 -0
- data/spec/kontena/cli/stacks/yaml/stack_file_loader_spec.rb +104 -0
- data/spec/kontena/cli/stacks/yaml/validator_v3_spec.rb +19 -0
- data/spec/kontena/plugin_manager/cleaner_spec.rb +20 -0
- data/spec/kontena/plugin_manager/common_spec.rb +39 -0
- data/spec/kontena/plugin_manager/installer_spec.rb +50 -0
- data/spec/kontena/plugin_manager/loader_spec.rb +5 -0
- data/spec/kontena/plugin_manager/rubygems_client_spec.rb +11 -25
- data/spec/kontena/plugin_manager/uninstaller_spec.rb +19 -0
- data/spec/kontena/plugin_manager_spec.rb +7 -7
- metadata +64 -97
- data/lib/kontena/cli/app_command.rb +0 -22
- data/lib/kontena/cli/apps/build_command.rb +0 -28
- data/lib/kontena/cli/apps/common.rb +0 -172
- data/lib/kontena/cli/apps/config_command.rb +0 -25
- data/lib/kontena/cli/apps/deploy_command.rb +0 -137
- data/lib/kontena/cli/apps/docker_compose_generator.rb +0 -61
- data/lib/kontena/cli/apps/docker_helper.rb +0 -80
- data/lib/kontena/cli/apps/dockerfile_generator.rb +0 -16
- data/lib/kontena/cli/apps/init_command.rb +0 -89
- data/lib/kontena/cli/apps/kontena_yml_generator.rb +0 -105
- data/lib/kontena/cli/apps/list_command.rb +0 -59
- data/lib/kontena/cli/apps/logs_command.rb +0 -37
- data/lib/kontena/cli/apps/monitor_command.rb +0 -93
- data/lib/kontena/cli/apps/remove_command.rb +0 -74
- data/lib/kontena/cli/apps/restart_command.rb +0 -39
- data/lib/kontena/cli/apps/scale_command.rb +0 -33
- data/lib/kontena/cli/apps/service_generator.rb +0 -114
- data/lib/kontena/cli/apps/service_generator_v2.rb +0 -27
- data/lib/kontena/cli/apps/show_command.rb +0 -23
- data/lib/kontena/cli/apps/start_command.rb +0 -40
- data/lib/kontena/cli/apps/stop_command.rb +0 -40
- data/lib/kontena/cli/apps/yaml/custom_validators/affinities_validator.rb +0 -19
- data/lib/kontena/cli/apps/yaml/custom_validators/build_validator.rb +0 -22
- data/lib/kontena/cli/apps/yaml/custom_validators/extends_validator.rb +0 -20
- data/lib/kontena/cli/apps/yaml/custom_validators/hooks_validator.rb +0 -54
- data/lib/kontena/cli/apps/yaml/custom_validators/secrets_validator.rb +0 -22
- data/lib/kontena/cli/apps/yaml/reader.rb +0 -213
- data/lib/kontena/cli/apps/yaml/service_extender.rb +0 -77
- data/lib/kontena/cli/apps/yaml/validations.rb +0 -71
- data/lib/kontena/cli/apps/yaml/validator.rb +0 -38
- data/lib/kontena/cli/apps/yaml/validator_v2.rb +0 -53
- data/spec/fixtures/app.json +0 -42
- data/spec/fixtures/health.yml +0 -26
- data/spec/fixtures/kontena-build.yml +0 -16
- data/spec/fixtures/kontena-internal-extend.yml +0 -8
- data/spec/fixtures/kontena-invalid.yml +0 -4
- data/spec/fixtures/kontena-with-env-file.yml +0 -18
- data/spec/fixtures/kontena-with-variables.yml +0 -19
- data/spec/fixtures/kontena.yml +0 -17
- data/spec/fixtures/kontena_build_v2.yml +0 -26
- data/spec/fixtures/kontena_numeric_version.yml +0 -9
- data/spec/fixtures/kontena_v2.yml +0 -35
- data/spec/fixtures/mysql.yml +0 -3
- data/spec/fixtures/wordpress-scaled.yml +0 -3
- data/spec/fixtures/wordpress.yml +0 -2
- data/spec/kontena/cli/app/build_command_spec.rb +0 -55
- data/spec/kontena/cli/app/common_spec.rb +0 -110
- data/spec/kontena/cli/app/config_command_spec.rb +0 -78
- data/spec/kontena/cli/app/deploy_command_spec.rb +0 -217
- data/spec/kontena/cli/app/docker_helper_spec.rb +0 -155
- data/spec/kontena/cli/app/init_command_spec.rb +0 -109
- data/spec/kontena/cli/app/logs_command_spec.rb +0 -131
- data/spec/kontena/cli/app/scale_spec.rb +0 -51
- data/spec/kontena/cli/app/service_generator_spec.rb +0 -384
- data/spec/kontena/cli/app/service_generator_v2_spec.rb +0 -73
- data/spec/kontena/cli/app/yaml/reader_spec.rb +0 -457
- data/spec/kontena/cli/app/yaml/service_extender_spec.rb +0 -127
- data/spec/kontena/cli/app/yaml/validator_spec.rb +0 -380
- data/spec/kontena/cli/app/yaml/validator_v2_spec.rb +0 -301
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: dd17b046ef3c5df923edb5330692544a30c68f31
|
4
|
+
data.tar.gz: 86ab9db88b8bffe961692ad0c7716aacc450e556
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9ce3ee493ee6919a392b71e4218bc301849caf3d8a0f25a4aa831c81aaeab1a6e57e3d88927cee4e0c9a50bac10ec195476eb5d6b88cb934234d6fc1c09119e2
|
7
|
+
data.tar.gz: 1a257b2cb1d8f72f4c9d69dd4ca1b5530fd1ecf51dac56a7e3b787b3d579e574ba85e625e7e0350d9512d34875778aa02961e0b45623efc2b4bbc8b57b7f5556
|
data/Gemfile
CHANGED
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.4.0.
|
1
|
+
1.4.0.pre7
|
data/bin/kontena
CHANGED
@@ -14,6 +14,6 @@ if ARGV[0] == 'complete'
|
|
14
14
|
else
|
15
15
|
ENV['DEBUG'] ||= "true" if ARGV.any? { |arg| arg == '-D' || arg == '--debug'}
|
16
16
|
require 'kontena_cli'
|
17
|
-
Kontena::PluginManager.
|
17
|
+
Kontena::PluginManager.init unless ENV['NO_PLUGINS']
|
18
18
|
Kontena::MainCommand.run
|
19
19
|
end
|
data/kontena-cli.gemspec
CHANGED
@@ -23,15 +23,15 @@ Gem::Specification.new do |spec|
|
|
23
23
|
spec.add_development_dependency "bundler", "~> 1.7"
|
24
24
|
spec.add_development_dependency "rake", "~> 10.0"
|
25
25
|
spec.add_runtime_dependency "excon", "~> 0.49.0"
|
26
|
-
spec.add_runtime_dependency "tty-prompt", "0.
|
26
|
+
spec.add_runtime_dependency "tty-prompt", "0.13.1"
|
27
27
|
spec.add_runtime_dependency "clamp", "~> 1.1.0"
|
28
28
|
spec.add_runtime_dependency "ruby_dig", "~> 0.0.2"
|
29
29
|
spec.add_runtime_dependency "launchy", "~> 2.4.3"
|
30
30
|
spec.add_runtime_dependency "hash_validator", "~> 0.7.1"
|
31
31
|
spec.add_runtime_dependency "retriable", "~> 2.1.0"
|
32
|
-
spec.add_runtime_dependency "opto", "1.8.
|
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
35
|
spec.add_runtime_dependency "tty-table", "~> 0.8.0"
|
36
|
-
spec.add_runtime_dependency "kontena-websocket-client", "~> 0.1.
|
36
|
+
spec.add_runtime_dependency "kontena-websocket-client", "~> 0.1.1"
|
37
37
|
end
|
@@ -1,22 +1,83 @@
|
|
1
|
+
require_relative '../services/services_helper'
|
1
2
|
|
2
3
|
module Kontena::Cli::Certificate
|
3
4
|
class AuthorizeCommand < Kontena::Command
|
4
5
|
include Kontena::Cli::Common
|
5
6
|
include Kontena::Cli::GridOptions
|
7
|
+
include Kontena::Cli::Services::ServicesHelper
|
6
8
|
|
9
|
+
class DeployFailedError < StandardError; end
|
7
10
|
|
8
11
|
parameter "DOMAIN", "Domain to authorize"
|
9
12
|
|
13
|
+
option '--type', 'AUTHORIZATION_TYPE', 'Authorization type, either tls-sni-01 or dns-01', default: 'dns-01'
|
14
|
+
option '--linked-service', "LINKED_SERVICE", 'A service (usually LB) where the tls-sni-01 challenge certificate is bundled to'
|
15
|
+
|
10
16
|
def execute
|
11
17
|
require_api_url
|
12
18
|
token = require_token
|
13
19
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
+
exit_with_error "Service link needs to be given with tls-sni-01 auth type" if self.type == 'tls-sni-01' && self.linked_service.nil?
|
21
|
+
|
22
|
+
data = {
|
23
|
+
domain: domain,
|
24
|
+
authorization_type: self.type
|
25
|
+
}
|
26
|
+
data['linked_service'] = service_path(self.linked_service) if self.type == 'tls-sni-01'
|
27
|
+
retried = false
|
28
|
+
|
29
|
+
response = nil
|
30
|
+
retry_on_le_registration do
|
31
|
+
response = client(token).post("grids/#{current_grid}/domain_authorizations", data)
|
32
|
+
end
|
33
|
+
|
34
|
+
case self.type
|
35
|
+
when 'dns-01'
|
36
|
+
puts "Authorization successfully created. Use the following details to create necessary validations:"
|
37
|
+
puts "Record name: #{response.dig('challenge_opts', 'record_name')}.#{domain}"
|
38
|
+
puts "Record type: #{response.dig('challenge_opts', 'record_type')}"
|
39
|
+
puts "Record content: #{response.dig('challenge_opts', 'record_content')}"
|
40
|
+
when 'tls-sni-01'
|
41
|
+
state = nil
|
42
|
+
spinner "Waiting for tls-sni-01 certificate to be deployed into #{response.dig('linked_service', 'id').colorize(:cyan)} " do
|
43
|
+
state = wait_for_domain_auth_deployed(token, response['id'])
|
44
|
+
end
|
45
|
+
if state == 'deploy_error'
|
46
|
+
puts "Linked services deploy failed. Check service events for details"
|
47
|
+
else
|
48
|
+
puts "TLS-SNI challenge certificate is deployed, you can now request the actual certificate"
|
49
|
+
end
|
50
|
+
else
|
51
|
+
exit_with_error "Unknown authorization type: #{self.type}"
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
55
|
+
|
56
|
+
def wait_for_domain_auth_deployed(token, domain_auth_id)
|
57
|
+
state = nil
|
58
|
+
Timeout.timeout(300) {
|
59
|
+
sleep 1 until (state = client(token).get("domain_authorizations/#{domain_auth_id}")['status']) != 'deploying'
|
60
|
+
}
|
61
|
+
state
|
62
|
+
end
|
63
|
+
|
64
|
+
def service_path(linked_service)
|
65
|
+
unless linked_service.include?('/')
|
66
|
+
"null/#{linked_service}"
|
67
|
+
else
|
68
|
+
linked_service
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
def retry_on_le_registration
|
73
|
+
yield
|
74
|
+
rescue Kontena::Errors::StandardErrorHash => exc
|
75
|
+
raise unless exc.errors.has_key?('le_registration')
|
76
|
+
# Run through registration
|
77
|
+
puts "Let's Encrypt registration missing, creating one."
|
78
|
+
email = prompt.ask("Email for Let's Encrypt:")
|
79
|
+
Kontena.run!(['certificate', 'register', email])
|
80
|
+
yield
|
20
81
|
end
|
21
82
|
end
|
22
83
|
end
|
@@ -4,6 +4,9 @@ module Kontena::Cli::Certificate
|
|
4
4
|
include Kontena::Cli::Common
|
5
5
|
include Kontena::Cli::GridOptions
|
6
6
|
|
7
|
+
BANNER = "This command is now deprecated in favor of 'kontena certificate request' command".colorize(:red)
|
8
|
+
|
9
|
+
banner BANNER
|
7
10
|
|
8
11
|
option '--secret-name', 'SECRET_NAME', 'The name for the secret to store the certificate in'
|
9
12
|
option '--cert-type', 'CERT_TYPE', 'The type of certificate to get: fullchain, chain or cert', default: 'fullchain'
|
@@ -11,16 +14,20 @@ module Kontena::Cli::Certificate
|
|
11
14
|
|
12
15
|
|
13
16
|
def execute
|
17
|
+
puts BANNER
|
18
|
+
|
14
19
|
require_api_url
|
15
20
|
token = require_token
|
16
21
|
secret = secret_name || "LE_CERTIFICATE_#{domain_list[0].gsub('.', '_')}"
|
17
22
|
data = {domains: domain_list, secret_name: secret}
|
23
|
+
|
18
24
|
response = client(token).post("certificates/#{current_grid}/certificate", data)
|
19
25
|
puts "Certificate successfully received and stored into vault with keys:"
|
20
26
|
response.each do |secret|
|
21
27
|
puts secret.colorize(:green)
|
22
28
|
end
|
23
29
|
puts "Use the #{secret}_BUNDLE with Kontena loadbalancer!"
|
30
|
+
|
24
31
|
end
|
25
32
|
end
|
26
33
|
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
require_relative '../services/services_helper'
|
2
|
+
|
3
|
+
module Kontena::Cli::Certificate
|
4
|
+
class ListCommand < Kontena::Command
|
5
|
+
include Kontena::Cli::Common
|
6
|
+
include Kontena::Cli::GridOptions
|
7
|
+
include Kontena::Cli::TableGenerator::Helper
|
8
|
+
include Kontena::Util
|
9
|
+
|
10
|
+
requires_current_master
|
11
|
+
requires_current_master_token
|
12
|
+
requires_current_grid
|
13
|
+
|
14
|
+
SEVEN_DAYS = 7 * 24 * 60 * 60
|
15
|
+
THREE_DAYS = 3 * 24 * 60 * 60
|
16
|
+
|
17
|
+
def fields
|
18
|
+
quiet? ? ['subject'] : {subject: 'subject', "expiration" => 'expires_in'}
|
19
|
+
end
|
20
|
+
|
21
|
+
def certificates
|
22
|
+
client.get("grids/#{current_grid}/certificates")['certificates']
|
23
|
+
end
|
24
|
+
|
25
|
+
def status_icon(expires_in)
|
26
|
+
icon = '⊛'.freeze
|
27
|
+
|
28
|
+
if expires_in < 0
|
29
|
+
icon.colorize(:red)
|
30
|
+
else
|
31
|
+
icon.colorize(:green)
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
|
36
|
+
def status_color(expires_in)
|
37
|
+
|
38
|
+
if expires_in < 0
|
39
|
+
:red
|
40
|
+
elsif expires_in < THREE_DAYS
|
41
|
+
:bright_yellow
|
42
|
+
elsif expires_in < SEVEN_DAYS
|
43
|
+
:yellow
|
44
|
+
else
|
45
|
+
:green
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
49
|
+
|
50
|
+
def expires_in(certificate)
|
51
|
+
valid_until = Time.parse(certificate['valid_until'])
|
52
|
+
(valid_until - Time.now).to_i
|
53
|
+
end
|
54
|
+
|
55
|
+
def expires_in_human(expires_in)
|
56
|
+
if expires_in > 0
|
57
|
+
text = seconds_to_human(expires_in)
|
58
|
+
else
|
59
|
+
text = seconds_to_human(-1 * expires_in) + ' ago'
|
60
|
+
end
|
61
|
+
|
62
|
+
text.colorize(status_color(expires_in))
|
63
|
+
end
|
64
|
+
|
65
|
+
def execute
|
66
|
+
print_table(certificates) do |certificate|
|
67
|
+
expires_in = expires_in(certificate)
|
68
|
+
certificate['subject'] = status_icon(expires_in) + " " + certificate['subject'] unless quiet?
|
69
|
+
next if quiet? # No need to fiddle with colors when they will not get printed
|
70
|
+
certificate['expires_in'] = expires_in_human(expires_in)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
end
|
75
|
+
end
|
@@ -7,13 +7,24 @@ module Kontena::Cli::Certificate
|
|
7
7
|
|
8
8
|
parameter "EMAIL", "Email to register"
|
9
9
|
|
10
|
+
option '--agree-tos', :flag, "Automatically agree on Let's Encrypt Terms of Service"
|
11
|
+
|
10
12
|
def execute
|
11
13
|
require_api_url
|
12
14
|
token = require_token
|
13
15
|
|
14
16
|
data = {email: email}
|
15
|
-
|
16
|
-
|
17
|
+
|
18
|
+
if self.agree_tos? || ask_continue
|
19
|
+
response = client(token).post("certificates/#{current_grid}/register", data)
|
20
|
+
puts 'Email registered to LetsEncrypt'
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def ask_continue
|
25
|
+
puts "By registering, you agree on Let's Encrypt Terms of Service: https://letsencrypt.org/documents/LE-SA-v1.1.1-August-1-2016.pdf"
|
26
|
+
exit_with_error "Registration canceled!" unless prompt.yes?("Continue?")
|
27
|
+
true
|
17
28
|
end
|
18
29
|
end
|
19
30
|
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
|
2
|
+
module Kontena::Cli::Certificate
|
3
|
+
class RequestCommand < Kontena::Command
|
4
|
+
include Kontena::Cli::Common
|
5
|
+
include Kontena::Cli::GridOptions
|
6
|
+
|
7
|
+
parameter "DOMAIN ...", "Domain(s) to get certificate for"
|
8
|
+
|
9
|
+
def execute
|
10
|
+
require_api_url
|
11
|
+
token = require_token
|
12
|
+
data = {domains: domain_list}
|
13
|
+
|
14
|
+
spinner "Requesting certificate for #{domain_list.join(',').colorize(:cyan)} " do
|
15
|
+
response = client(token).post("grids/#{current_grid}/certificates", data)
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require_relative '../services/services_helper'
|
2
|
+
|
3
|
+
module Kontena::Cli::Certificate
|
4
|
+
class ShowCommand < Kontena::Command
|
5
|
+
include Kontena::Cli::Common
|
6
|
+
include Kontena::Cli::GridOptions
|
7
|
+
|
8
|
+
parameter "SUBJECT", "Certificate subject"
|
9
|
+
|
10
|
+
requires_current_master
|
11
|
+
requires_current_master_token
|
12
|
+
requires_current_grid
|
13
|
+
|
14
|
+
def execute
|
15
|
+
certificate = client.get("certificates/#{current_grid}/#{self.subject}")
|
16
|
+
puts YAML.dump(certificate)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -1,11 +1,14 @@
|
|
1
1
|
|
2
2
|
class Kontena::Cli::CertificateCommand < Kontena::Command
|
3
3
|
|
4
|
-
|
4
|
+
subcommand ["list", "ls"], "List certificates", load_subcommand('certificate/list_command')
|
5
|
+
subcommand "show", "Show certificate details", load_subcommand('certificate/show_command')
|
5
6
|
subcommand "register", "Register to LetsEncrypt", load_subcommand('certificate/register_command')
|
6
7
|
subcommand "authorize", "Create DNS authorization for domain", load_subcommand('certificate/authorize_command')
|
8
|
+
subcommand "request", "Request certificate for domain", load_subcommand('certificate/request_command')
|
7
9
|
subcommand "get", "Get certificate for domain", load_subcommand('certificate/get_command')
|
8
10
|
|
11
|
+
|
9
12
|
def execute
|
10
13
|
end
|
11
14
|
end
|
@@ -47,7 +47,7 @@ module Kontena::Cli::Cloud::Master
|
|
47
47
|
masters = []
|
48
48
|
spinner "Retrieving a list of your registered Kontena Masters in Kontena Cloud" do |spin|
|
49
49
|
begin
|
50
|
-
masters = Kontena.run!(%w(cloud master list --return))
|
50
|
+
masters = Kontena.run!(%w(cloud master list --return --quiet))
|
51
51
|
rescue SystemExit
|
52
52
|
spin.fail
|
53
53
|
end
|
data/lib/kontena/cli/common.rb
CHANGED
@@ -117,6 +117,24 @@ module Kontena
|
|
117
117
|
end
|
118
118
|
end
|
119
119
|
|
120
|
+
# Output a message like: "> Reading foofoo .."
|
121
|
+
# @param message [String] the message to display
|
122
|
+
# @param dots [TrueClass,FalseClass] set to false if you don't want to add ".." after the message
|
123
|
+
def caret(msg, dots: true)
|
124
|
+
puts "#{pastel.green('>')} #{msg}#{" #{pastel.green('..')}" if dots}"
|
125
|
+
end
|
126
|
+
|
127
|
+
# Run a spinner with a message for the block if a truthy value or a proc returns true.
|
128
|
+
# @example
|
129
|
+
# spin_if(proc { prompt.yes?("for real?") }, "Doing as requested") do
|
130
|
+
# # doing stuff
|
131
|
+
# end
|
132
|
+
# spin_if(a == 1, "Value of 'a' is 1, so let's do this") do
|
133
|
+
# # doing stuff
|
134
|
+
# end
|
135
|
+
# @param obj_or_proc [Object,Proc] something that responds to .call or is truthy/falsey
|
136
|
+
# @param message [String] the message to display
|
137
|
+
# @return anything the block returns
|
120
138
|
def spin_if(obj_or_proc, message, &block)
|
121
139
|
if (obj_or_proc.respond_to?(:call) && obj_or_proc.call) || obj_or_proc
|
122
140
|
spinner(message, &block)
|
@@ -244,8 +262,8 @@ module Kontena
|
|
244
262
|
if self.respond_to?(:force?) && self.force?
|
245
263
|
return
|
246
264
|
end
|
247
|
-
exit_with_error 'Command requires --force' unless $stdout.tty? && $stdin.tty?
|
248
265
|
puts message if message
|
266
|
+
exit_with_error 'Command requires --force' unless $stdout.tty? && $stdin.tty?
|
249
267
|
puts "Destructive command. To proceed, type \"#{name}\" or re-run this command with --force option."
|
250
268
|
|
251
269
|
ask("Enter '#{name}' to confirm: ") == name || error("Confirmation did not match #{name}. Aborted command.")
|
@@ -276,44 +294,14 @@ module Kontena
|
|
276
294
|
def any_key_to_continue_with_timeout(timeout=9)
|
277
295
|
return nil if running_silent?
|
278
296
|
return nil unless $stdout.tty?
|
279
|
-
|
280
|
-
end_time = start_time + timeout
|
281
|
-
Thread.main['any_key.timed_out'] = false
|
282
|
-
msg = "Press any key to continue or ctrl-c to cancel.. (Automatically continuing in ? seconds)"
|
283
|
-
|
284
|
-
reader_thread = Thread.new do
|
285
|
-
Thread.main['any_key.char'] = $stdin.getch
|
286
|
-
end
|
287
|
-
|
288
|
-
countdown_thread = Thread.new do
|
289
|
-
time_left = timeout
|
290
|
-
while time_left > 0 && Thread.main['any_key.char'].nil?
|
291
|
-
print "\r#{pastel.bright_white("#{msg.sub("?", time_left.to_s)}")} "
|
292
|
-
time_left = end_time - Time.now.to_i
|
293
|
-
sleep 0.1
|
294
|
-
end
|
295
|
-
print "\r#{' ' * msg.length} \r"
|
296
|
-
reader_thread.kill if reader_thread.alive?
|
297
|
-
end
|
298
|
-
|
299
|
-
countdown_thread.join
|
300
|
-
|
301
|
-
if Thread.main['any_key.char'] == "\u0003"
|
302
|
-
error "Canceled"
|
303
|
-
end
|
297
|
+
prompt.keypress("Press any key to continue or ctrl-c to cancel (Automatically continuing in :countdown seconds) ...", timeout: timeout)
|
304
298
|
end
|
305
299
|
|
306
300
|
def any_key_to_continue(timeout = nil)
|
307
301
|
return nil if running_silent?
|
308
302
|
return nil unless $stdout.tty?
|
309
303
|
return any_key_to_continue_with_timeout(timeout) if timeout
|
310
|
-
|
311
|
-
print pastel.bright_cyan("#{msg}")
|
312
|
-
char = $stdin.getch
|
313
|
-
print "\r#{' ' * msg.length}\r"
|
314
|
-
if char == "\u0003"
|
315
|
-
error "Canceled"
|
316
|
-
end
|
304
|
+
prompt.keypress("Press any key to continue or ctrl-c to cancel.. ")
|
317
305
|
end
|
318
306
|
|
319
307
|
def display_account_login_info
|
@@ -13,47 +13,41 @@ module Kontena::Cli::Etcd
|
|
13
13
|
requires_current_grid
|
14
14
|
|
15
15
|
def execute
|
16
|
-
|
17
|
-
token = require_token
|
18
|
-
|
19
|
-
health = true
|
16
|
+
ret = true
|
20
17
|
|
21
18
|
if self.node
|
22
|
-
|
23
|
-
|
24
|
-
health = show_node_health(node_health)
|
19
|
+
ret = show_etcd_health("#{current_grid}/#{self.node}")
|
25
20
|
else
|
26
21
|
nodes = client.get("grids/#{current_grid}/nodes")['nodes']
|
27
22
|
|
28
23
|
nodes.each do |node|
|
29
|
-
|
30
|
-
|
31
|
-
if !show_node_health(node_health)
|
32
|
-
health = false
|
24
|
+
if !show_etcd_health(node['id'])
|
25
|
+
ret = false
|
33
26
|
end
|
34
27
|
end
|
35
28
|
end
|
36
29
|
|
37
|
-
return
|
30
|
+
return ret
|
38
31
|
end
|
39
32
|
|
33
|
+
# @param id [String] :grid/:node
|
40
34
|
# @return [Boolean]
|
41
|
-
def
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
puts "#{health_icon :error} Node #{node_health['name']} is unhealthy"
|
55
|
-
return false
|
35
|
+
def show_etcd_health(id)
|
36
|
+
node_health = client.get("nodes/#{id}/health")
|
37
|
+
etcd_health, status = node_etcd_health(node_health['etcd_health'])
|
38
|
+
|
39
|
+
puts "#{health_icon etcd_health} Node #{node_health['name']} etcd is #{status}"
|
40
|
+
|
41
|
+
return etcd_health == :ok
|
42
|
+
|
43
|
+
rescue Kontena::Errors::StandardErrorHash => exc
|
44
|
+
raise unless exc.status == 422
|
45
|
+
|
46
|
+
exc.errors.each do |what, error|
|
47
|
+
puts "#{health_icon :offline} Node #{id} #{what} error: #{error}"
|
56
48
|
end
|
49
|
+
|
50
|
+
return false
|
57
51
|
end
|
58
52
|
end
|
59
53
|
end
|