kontena-cli 1.4.0.pre6 → 1.4.0.pre7
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/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
|