krates 1.6.0
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 +7 -0
- data/LICENSE +212 -0
- data/LOGO +10 -0
- data/VERSION +1 -0
- data/bin/krates +23 -0
- data/lib/kontena/autoload_core.rb +19 -0
- data/lib/kontena/callback.rb +60 -0
- data/lib/kontena/callbacks/.gitkeep +0 -0
- data/lib/kontena/callbacks/auth/01_list_and_select_grid_after_master_auth.rb +26 -0
- data/lib/kontena/callbacks/master/01_clear_current_master_after_terminate.rb +19 -0
- data/lib/kontena/callbacks/master/deploy/01_show_logo_before_deploy.rb +14 -0
- data/lib/kontena/callbacks/master/deploy/04_default_master_version.rb +18 -0
- data/lib/kontena/callbacks/master/deploy/05_before_deploy_configuration_wizard.rb +105 -0
- data/lib/kontena/callbacks/master/deploy/40_install_ssl_certificate_after_deploy.rb +32 -0
- data/lib/kontena/callbacks/master/deploy/50_authenticate_after_deploy.rb +66 -0
- data/lib/kontena/callbacks/master/deploy/55_create_initial_grid_after_deploy.rb +21 -0
- data/lib/kontena/callbacks/master/deploy/56_set_server_provider_after_deploy.rb +24 -0
- data/lib/kontena/callbacks/master/deploy/60_configure_auth_provider_after_deploy.rb +31 -0
- data/lib/kontena/callbacks/master/deploy/70_invite_self_after_deploy.rb +95 -0
- data/lib/kontena/callbacks/master/deploy/90_proptip_after_deploy.rb +33 -0
- data/lib/kontena/cli/browser_launcher.rb +61 -0
- data/lib/kontena/cli/bytes_helper.rb +40 -0
- data/lib/kontena/cli/certificate/authorize_command.rb +107 -0
- data/lib/kontena/cli/certificate/common.rb +16 -0
- data/lib/kontena/cli/certificate/domain_authorization/list_command.rb +24 -0
- data/lib/kontena/cli/certificate/domain_authorization/remove_authorization_command.rb +25 -0
- data/lib/kontena/cli/certificate/domain_authorize_command.rb +7 -0
- data/lib/kontena/cli/certificate/export_command.rb +28 -0
- data/lib/kontena/cli/certificate/get_command.rb +33 -0
- data/lib/kontena/cli/certificate/import_command.rb +61 -0
- data/lib/kontena/cli/certificate/list_command.rb +75 -0
- data/lib/kontena/cli/certificate/register_command.rb +30 -0
- data/lib/kontena/cli/certificate/remove_command.rb +23 -0
- data/lib/kontena/cli/certificate/request_command.rb +20 -0
- data/lib/kontena/cli/certificate/show_command.rb +22 -0
- data/lib/kontena/cli/certificate_command.rb +18 -0
- data/lib/kontena/cli/cloud/login_command.rb +186 -0
- data/lib/kontena/cli/cloud/logout_command.rb +14 -0
- data/lib/kontena/cli/cloud/master/add_command.rb +156 -0
- data/lib/kontena/cli/cloud/master/list_command.rb +35 -0
- data/lib/kontena/cli/cloud/master/remove_command.rb +68 -0
- data/lib/kontena/cli/cloud/master/show_command.rb +21 -0
- data/lib/kontena/cli/cloud/master/update_command.rb +52 -0
- data/lib/kontena/cli/cloud/master_command.rb +14 -0
- data/lib/kontena/cli/cloud_command.rb +13 -0
- data/lib/kontena/cli/common.rb +360 -0
- data/lib/kontena/cli/config.rb +662 -0
- data/lib/kontena/cli/container_command.rb +10 -0
- data/lib/kontena/cli/containers/exec_command.rb +31 -0
- data/lib/kontena/cli/containers/inspect_command.rb +16 -0
- data/lib/kontena/cli/containers/list_command.rb +51 -0
- data/lib/kontena/cli/containers/logs_command.rb +19 -0
- data/lib/kontena/cli/etcd/common.rb +8 -0
- data/lib/kontena/cli/etcd/get_command.rb +26 -0
- data/lib/kontena/cli/etcd/health_command.rb +53 -0
- data/lib/kontena/cli/etcd/list_command.rb +36 -0
- data/lib/kontena/cli/etcd/mkdir_command.rb +23 -0
- data/lib/kontena/cli/etcd/remove_command.rb +29 -0
- data/lib/kontena/cli/etcd/set_command.rb +24 -0
- data/lib/kontena/cli/etcd_command.rb +12 -0
- data/lib/kontena/cli/external_registries/add_command.rb +25 -0
- data/lib/kontena/cli/external_registries/list_command.rb +23 -0
- data/lib/kontena/cli/external_registries/remove_command.rb +17 -0
- data/lib/kontena/cli/external_registry_command.rb +9 -0
- data/lib/kontena/cli/grid_command.rb +21 -0
- data/lib/kontena/cli/grid_options.rb +12 -0
- data/lib/kontena/cli/grids/audit_log_command.rb +22 -0
- data/lib/kontena/cli/grids/cloud_config_command.rb +53 -0
- data/lib/kontena/cli/grids/common.rb +182 -0
- data/lib/kontena/cli/grids/create_command.rb +48 -0
- data/lib/kontena/cli/grids/current_command.rb +25 -0
- data/lib/kontena/cli/grids/env_command.rb +32 -0
- data/lib/kontena/cli/grids/events_command.rb +50 -0
- data/lib/kontena/cli/grids/health_command.rb +69 -0
- data/lib/kontena/cli/grids/list_command.rb +59 -0
- data/lib/kontena/cli/grids/logs_command.rb +35 -0
- data/lib/kontena/cli/grids/remove_command.rb +31 -0
- data/lib/kontena/cli/grids/show_command.rb +25 -0
- data/lib/kontena/cli/grids/trusted_subnet_command.rb +10 -0
- data/lib/kontena/cli/grids/trusted_subnets/add_command.rb +18 -0
- data/lib/kontena/cli/grids/trusted_subnets/list_command.rb +18 -0
- data/lib/kontena/cli/grids/trusted_subnets/remove_command.rb +26 -0
- data/lib/kontena/cli/grids/update_command.rb +35 -0
- data/lib/kontena/cli/grids/use_command.rb +26 -0
- data/lib/kontena/cli/grids/user_command.rb +9 -0
- data/lib/kontena/cli/grids/users/add_command.rb +18 -0
- data/lib/kontena/cli/grids/users/list_command.rb +20 -0
- data/lib/kontena/cli/grids/users/remove_command.rb +20 -0
- data/lib/kontena/cli/helpers/exec_helper.rb +209 -0
- data/lib/kontena/cli/helpers/health_helper.rb +65 -0
- data/lib/kontena/cli/helpers/log_helper.rb +113 -0
- data/lib/kontena/cli/helpers/time_helper.rb +29 -0
- data/lib/kontena/cli/localhost_web_server.rb +113 -0
- data/lib/kontena/cli/log_formatters/compact.rb +65 -0
- data/lib/kontena/cli/log_formatters/strip_color.rb +13 -0
- data/lib/kontena/cli/logout_command.rb +10 -0
- data/lib/kontena/cli/master/audit_log_command.rb +19 -0
- data/lib/kontena/cli/master/config/export_command.rb +46 -0
- data/lib/kontena/cli/master/config/get_command.rb +26 -0
- data/lib/kontena/cli/master/config/import_command.rb +67 -0
- data/lib/kontena/cli/master/config/set_command.rb +19 -0
- data/lib/kontena/cli/master/config/unset_command.rb +20 -0
- data/lib/kontena/cli/master/config_command.rb +17 -0
- data/lib/kontena/cli/master/create_command.rb +74 -0
- data/lib/kontena/cli/master/current_command.rb +25 -0
- data/lib/kontena/cli/master/init_cloud_command.rb +45 -0
- data/lib/kontena/cli/master/join_command.rb +22 -0
- data/lib/kontena/cli/master/list_command.rb +24 -0
- data/lib/kontena/cli/master/login_command.rb +331 -0
- data/lib/kontena/cli/master/logout_command.rb +25 -0
- data/lib/kontena/cli/master/remove_command.rb +55 -0
- data/lib/kontena/cli/master/ssh_command.rb +72 -0
- data/lib/kontena/cli/master/token/common.rb +29 -0
- data/lib/kontena/cli/master/token/create_command.rb +50 -0
- data/lib/kontena/cli/master/token/current_command.rb +45 -0
- data/lib/kontena/cli/master/token/list_command.rb +39 -0
- data/lib/kontena/cli/master/token/remove_command.rb +19 -0
- data/lib/kontena/cli/master/token/show_command.rb +34 -0
- data/lib/kontena/cli/master/token_command.rb +13 -0
- data/lib/kontena/cli/master/use_command.rb +31 -0
- data/lib/kontena/cli/master/user/invite_command.rb +51 -0
- data/lib/kontena/cli/master/user/list_command.rb +29 -0
- data/lib/kontena/cli/master/user/remove_command.rb +24 -0
- data/lib/kontena/cli/master/user/role/add_command.rb +29 -0
- data/lib/kontena/cli/master/user/role/remove_command.rb +27 -0
- data/lib/kontena/cli/master/user/role_command.rb +6 -0
- data/lib/kontena/cli/master/user_command.rb +9 -0
- data/lib/kontena/cli/master_command.rb +21 -0
- data/lib/kontena/cli/node_command.rb +17 -0
- data/lib/kontena/cli/nodes/create_command.rb +25 -0
- data/lib/kontena/cli/nodes/env_command.rb +37 -0
- data/lib/kontena/cli/nodes/health_command.rb +47 -0
- data/lib/kontena/cli/nodes/label_command.rb +10 -0
- data/lib/kontena/cli/nodes/labels/add_command.rb +18 -0
- data/lib/kontena/cli/nodes/labels/list_command.rb +19 -0
- data/lib/kontena/cli/nodes/labels/remove_command.rb +32 -0
- data/lib/kontena/cli/nodes/list_command.rb +97 -0
- data/lib/kontena/cli/nodes/remove_command.rb +34 -0
- data/lib/kontena/cli/nodes/reset_token_command.rb +34 -0
- data/lib/kontena/cli/nodes/show_command.rb +56 -0
- data/lib/kontena/cli/nodes/ssh_command.rb +63 -0
- data/lib/kontena/cli/nodes/update_command.rb +31 -0
- data/lib/kontena/cli/plugin_command.rb +12 -0
- data/lib/kontena/cli/plugins/common.rb +8 -0
- data/lib/kontena/cli/plugins/install_command.rb +42 -0
- data/lib/kontena/cli/plugins/list_command.rb +31 -0
- data/lib/kontena/cli/plugins/search_command.rb +25 -0
- data/lib/kontena/cli/plugins/show_command.rb +17 -0
- data/lib/kontena/cli/plugins/uninstall_command.rb +31 -0
- data/lib/kontena/cli/plugins/upgrade_command.rb +60 -0
- data/lib/kontena/cli/registry/create_command.rb +151 -0
- data/lib/kontena/cli/registry/remove_command.rb +21 -0
- data/lib/kontena/cli/registry_command.rb +8 -0
- data/lib/kontena/cli/service_command.rb +28 -0
- data/lib/kontena/cli/services/container_command.rb +8 -0
- data/lib/kontena/cli/services/containers_command.rb +39 -0
- data/lib/kontena/cli/services/create_command.rb +105 -0
- data/lib/kontena/cli/services/deploy_command.rb +25 -0
- data/lib/kontena/cli/services/env_command.rb +9 -0
- data/lib/kontena/cli/services/envs/add_command.rb +21 -0
- data/lib/kontena/cli/services/envs/list_command.rb +22 -0
- data/lib/kontena/cli/services/envs/remove_command.rb +22 -0
- data/lib/kontena/cli/services/events_command.rb +36 -0
- data/lib/kontena/cli/services/exec_command.rb +107 -0
- data/lib/kontena/cli/services/link_command.rb +35 -0
- data/lib/kontena/cli/services/list_command.rb +66 -0
- data/lib/kontena/cli/services/logs_command.rb +33 -0
- data/lib/kontena/cli/services/monitor_command.rb +58 -0
- data/lib/kontena/cli/services/remove_command.rb +60 -0
- data/lib/kontena/cli/services/restart_command.rb +19 -0
- data/lib/kontena/cli/services/scale_command.rb +21 -0
- data/lib/kontena/cli/services/secret_command.rb +8 -0
- data/lib/kontena/cli/services/secrets/link_command.rb +26 -0
- data/lib/kontena/cli/services/secrets/unlink_command.rb +28 -0
- data/lib/kontena/cli/services/services_helper.rb +579 -0
- data/lib/kontena/cli/services/show_command.rb +26 -0
- data/lib/kontena/cli/services/start_command.rb +21 -0
- data/lib/kontena/cli/services/stats_command.rb +87 -0
- data/lib/kontena/cli/services/stop_command.rb +21 -0
- data/lib/kontena/cli/services/unlink_command.rb +30 -0
- data/lib/kontena/cli/services/update_command.rb +94 -0
- data/lib/kontena/cli/spinner.rb +205 -0
- data/lib/kontena/cli/stack_command.rb +21 -0
- data/lib/kontena/cli/stacks/build_command.rb +125 -0
- data/lib/kontena/cli/stacks/common.rb +209 -0
- data/lib/kontena/cli/stacks/deploy_command.rb +37 -0
- data/lib/kontena/cli/stacks/events_command.rb +33 -0
- data/lib/kontena/cli/stacks/inspect_command.rb +17 -0
- data/lib/kontena/cli/stacks/install_command.rb +95 -0
- data/lib/kontena/cli/stacks/label_command.rb +10 -0
- data/lib/kontena/cli/stacks/labels/add_command.rb +21 -0
- data/lib/kontena/cli/stacks/labels/common.rb +19 -0
- data/lib/kontena/cli/stacks/labels/list_command.rb +21 -0
- data/lib/kontena/cli/stacks/labels/remove_command.rb +21 -0
- data/lib/kontena/cli/stacks/list_command.rb +154 -0
- data/lib/kontena/cli/stacks/logs_command.rb +35 -0
- data/lib/kontena/cli/stacks/monitor_command.rb +93 -0
- data/lib/kontena/cli/stacks/registry/create_command.rb +24 -0
- data/lib/kontena/cli/stacks/registry/make_private_command.rb +24 -0
- data/lib/kontena/cli/stacks/registry/make_public_command.rb +24 -0
- data/lib/kontena/cli/stacks/registry/pull_command.rb +28 -0
- data/lib/kontena/cli/stacks/registry/push_command.rb +40 -0
- data/lib/kontena/cli/stacks/registry/remove_command.rb +30 -0
- data/lib/kontena/cli/stacks/registry/search_command.rb +42 -0
- data/lib/kontena/cli/stacks/registry/show_command.rb +65 -0
- data/lib/kontena/cli/stacks/registry_command.rb +12 -0
- data/lib/kontena/cli/stacks/remove_command.rb +80 -0
- data/lib/kontena/cli/stacks/restart_command.rb +24 -0
- data/lib/kontena/cli/stacks/service_generator.rb +131 -0
- data/lib/kontena/cli/stacks/service_generator_v2.rb +27 -0
- data/lib/kontena/cli/stacks/show_command.rb +168 -0
- data/lib/kontena/cli/stacks/stack_name.rb +71 -0
- data/lib/kontena/cli/stacks/stacks_helper.rb +83 -0
- data/lib/kontena/cli/stacks/stop_command.rb +24 -0
- data/lib/kontena/cli/stacks/upgrade_command.rb +264 -0
- data/lib/kontena/cli/stacks/validate_command.rb +75 -0
- data/lib/kontena/cli/stacks/yaml/custom_validators/affinities_validator.rb +19 -0
- data/lib/kontena/cli/stacks/yaml/custom_validators/build_validator.rb +22 -0
- data/lib/kontena/cli/stacks/yaml/custom_validators/certificates_validator.rb +22 -0
- data/lib/kontena/cli/stacks/yaml/custom_validators/extends_validator.rb +22 -0
- data/lib/kontena/cli/stacks/yaml/custom_validators/hooks_validator.rb +102 -0
- data/lib/kontena/cli/stacks/yaml/custom_validators/secrets_validator.rb +22 -0
- data/lib/kontena/cli/stacks/yaml/opto/certificates_resolver.rb +37 -0
- data/lib/kontena/cli/stacks/yaml/opto/prompt_resolver.rb +78 -0
- data/lib/kontena/cli/stacks/yaml/opto/service_instances_resolver.rb +25 -0
- data/lib/kontena/cli/stacks/yaml/opto/service_link_resolver.rb +80 -0
- data/lib/kontena/cli/stacks/yaml/opto/vault_cert_prompt_resolver.rb +39 -0
- data/lib/kontena/cli/stacks/yaml/opto/vault_resolver.rb +13 -0
- data/lib/kontena/cli/stacks/yaml/opto/vault_setter.rb +12 -0
- data/lib/kontena/cli/stacks/yaml/opto.rb +16 -0
- data/lib/kontena/cli/stacks/yaml/reader.rb +525 -0
- data/lib/kontena/cli/stacks/yaml/service_extender.rb +65 -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/stack_file_loader.rb +152 -0
- data/lib/kontena/cli/stacks/yaml/validations.rb +119 -0
- data/lib/kontena/cli/stacks/yaml/validator_v3.rb +164 -0
- data/lib/kontena/cli/subcommand_loader.rb +83 -0
- data/lib/kontena/cli/table_generator.rb +128 -0
- data/lib/kontena/cli/vault/export_command.rb +24 -0
- data/lib/kontena/cli/vault/import_command.rb +75 -0
- data/lib/kontena/cli/vault/list_command.rb +37 -0
- data/lib/kontena/cli/vault/read_command.rb +27 -0
- data/lib/kontena/cli/vault/remove_command.rb +23 -0
- data/lib/kontena/cli/vault/update_command.rb +24 -0
- data/lib/kontena/cli/vault/write_command.rb +23 -0
- data/lib/kontena/cli/vault_command.rb +13 -0
- data/lib/kontena/cli/version.rb +10 -0
- data/lib/kontena/cli/version_command.rb +20 -0
- data/lib/kontena/cli/volume_command.rb +9 -0
- data/lib/kontena/cli/volumes/create_command.rb +42 -0
- data/lib/kontena/cli/volumes/list_command.rb +29 -0
- data/lib/kontena/cli/volumes/remove_command.rb +29 -0
- data/lib/kontena/cli/volumes/show_command.rb +38 -0
- data/lib/kontena/cli/vpn/config_command.rb +27 -0
- data/lib/kontena/cli/vpn/create_command.rb +99 -0
- data/lib/kontena/cli/vpn/remove_command.rb +22 -0
- data/lib/kontena/cli/vpn_command.rb +9 -0
- data/lib/kontena/cli/whoami_command.rb +38 -0
- data/lib/kontena/client.rb +574 -0
- data/lib/kontena/command.rb +251 -0
- data/lib/kontena/debug_instrumentor.rb +80 -0
- data/lib/kontena/errors.rb +50 -0
- data/lib/kontena/light_prompt.rb +103 -0
- data/lib/kontena/machine/cert_helper.rb +43 -0
- data/lib/kontena/machine/cloud_config/cloudinit.yml +82 -0
- data/lib/kontena/machine/cloud_config/node_generator.rb +28 -0
- data/lib/kontena/machine/common.rb +17 -0
- data/lib/kontena/machine/random_name.rb +42 -0
- data/lib/kontena/main_command.rb +66 -0
- data/lib/kontena/plugin_manager/cleaner.rb +33 -0
- data/lib/kontena/plugin_manager/common.rb +89 -0
- data/lib/kontena/plugin_manager/installer.rb +78 -0
- data/lib/kontena/plugin_manager/loader.rb +93 -0
- data/lib/kontena/plugin_manager/rubygems_client.rb +59 -0
- data/lib/kontena/plugin_manager/uninstaller.rb +34 -0
- data/lib/kontena/plugin_manager.rb +26 -0
- data/lib/kontena/presets/github_auth_provider.yml +11 -0
- data/lib/kontena/presets/kontena_auth_provider.yml +11 -0
- data/lib/kontena/scripts/completer +9 -0
- data/lib/kontena/scripts/completer.rb +334 -0
- data/lib/kontena/scripts/init +18 -0
- data/lib/kontena/scripts/kontena.zsh +11 -0
- data/lib/kontena/scripts/krates.bash +8 -0
- data/lib/kontena/stacks/change_resolver.rb +118 -0
- data/lib/kontena/stacks/stack_data.rb +58 -0
- data/lib/kontena/stacks/stack_data_set.rb +51 -0
- data/lib/kontena/stacks_cache.rb +110 -0
- data/lib/kontena/stacks_client.rb +177 -0
- data/lib/kontena/util.rb +116 -0
- data/lib/kontena_cli.rb +190 -0
- metadata +518 -0
@@ -0,0 +1,209 @@
|
|
1
|
+
require_relative 'yaml/reader'
|
2
|
+
require_relative '../services/services_helper'
|
3
|
+
require_relative 'service_generator_v2'
|
4
|
+
require_relative '../../stacks_client'
|
5
|
+
require_relative 'yaml/stack_file_loader'
|
6
|
+
require 'yaml'
|
7
|
+
|
8
|
+
module Kontena::Cli::Stacks
|
9
|
+
module Common
|
10
|
+
include Kontena::Cli::Services::ServicesHelper
|
11
|
+
|
12
|
+
# @return [StackFileLoader] a loader for the stack origin defined through command-line options
|
13
|
+
def loader
|
14
|
+
@loader ||= loader_class.for(source)
|
15
|
+
end
|
16
|
+
|
17
|
+
# @return [YAML::Reader] a YAML reader for the target file
|
18
|
+
def reader
|
19
|
+
@reader ||= loader.reader
|
20
|
+
end
|
21
|
+
|
22
|
+
# Stack name read from -n parameter or the stack file
|
23
|
+
# @return [String]
|
24
|
+
def stack_name
|
25
|
+
@stack_name ||= (self.respond_to?(:name) && self.name) ? self.name : loader.stack_name.stack
|
26
|
+
end
|
27
|
+
|
28
|
+
# An accessor to the YAML Reader outcome. Passes parent name, values from command line and
|
29
|
+
# the stackname to the reader.
|
30
|
+
#
|
31
|
+
# @return [Hash]
|
32
|
+
def stack
|
33
|
+
@stack ||= reader.execute(
|
34
|
+
name: stack_name,
|
35
|
+
parent_name: self.respond_to?(:parent_name) ? self.parent_name : nil,
|
36
|
+
values: (self.respond_to?(:values_from_options) ? self.values_from_options : {})
|
37
|
+
)
|
38
|
+
end
|
39
|
+
|
40
|
+
# @return [Class] an accessor to StackFileLoader constant, for testing purposes
|
41
|
+
def loader_class
|
42
|
+
::Kontena::Cli::Stacks::YAML::StackFileLoader
|
43
|
+
end
|
44
|
+
|
45
|
+
module RegistryNameParam
|
46
|
+
def stack_name
|
47
|
+
@stack_name ||= Kontena::Cli::Stacks::StackName.new(source)
|
48
|
+
end
|
49
|
+
|
50
|
+
def self.included(where)
|
51
|
+
where.parameter "STACK_NAME", "Stack name, for example user/stackname or user/stackname:version", attribute_name: :source
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
module StackNameParam
|
56
|
+
# Include to add a STACK_NAME parameter
|
57
|
+
def self.included(where)
|
58
|
+
where.parameter "STACK_NAME", "Stack name, for example user/stackname or user/stackname:version", attribute_name: :source
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
module StackFileOrNameParam
|
63
|
+
# Include to add a stack file parameter
|
64
|
+
def self.included(where)
|
65
|
+
where.parameter "[FILE]", "Kontena stack file, registry stack name (user/stack or user/stack:version) or URL", default: "kontena.yml", attribute_name: :source
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
module StackNameOption
|
70
|
+
# Include to add a stack name parameter
|
71
|
+
def self.included(where)
|
72
|
+
where.option ['-n', '--name'], 'NAME', 'Define stack name (by default comes from stack file)'
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
module StackValuesToOption
|
77
|
+
attr_accessor :values
|
78
|
+
# Include to add --values-to variable value dumping feature
|
79
|
+
def self.included(where)
|
80
|
+
where.option '--values-to', '[FILE]', 'Output variable values as YAML to file'
|
81
|
+
end
|
82
|
+
|
83
|
+
# Writes a YAML file from the values received from YAML::Reader to a file defined through
|
84
|
+
# the --values-to option
|
85
|
+
def dump_variables
|
86
|
+
File.write(values_to, ::YAML.dump(reader.variable_values, without_defaults: true, without_vault: true))
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
module StackValuesFromOption
|
91
|
+
# Include to add --values-from option to read variable values from a YAML file
|
92
|
+
# and the -v variable=value option that can be used to pass variable values
|
93
|
+
# directly from command line
|
94
|
+
def self.included(where)
|
95
|
+
where.prepend InstanceMethods
|
96
|
+
|
97
|
+
where.option '--values-from', '[FILE]', 'Read variable values from a YAML file', multivalued: true do |filename|
|
98
|
+
values_from_file.merge!(::YAML.safe_load(File.read(filename), [], [], true, filename))
|
99
|
+
filename
|
100
|
+
end
|
101
|
+
|
102
|
+
where.option '--values-from-stack', '[STACK_NAME]', 'Read variable values from an installed stack', multivalued: true do |stackname|
|
103
|
+
variables = read_values_from_stacks(stackname)
|
104
|
+
Kontena.logger.debug { "Received variables from stack #{stackname} on Master: #{variables.inspect}" }
|
105
|
+
warn "Stack #{stackname} does not have any values for variables" if variables.empty?
|
106
|
+
values_from_installed_stacks.merge!(variables)
|
107
|
+
stackname
|
108
|
+
end
|
109
|
+
|
110
|
+
where.option '-v', "VARIABLE=VALUE", "Set stack variable values, example: -v domain=example.com. Can be used multiple times.", multivalued: true, attribute_name: :var_option do |var_pair|
|
111
|
+
var_name, var_value = var_pair.split('=', 2)
|
112
|
+
values_from_value_options.merge!(::YAML.safe_load(::YAML.dump(var_name => var_value)))
|
113
|
+
var_pair
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
module InstanceMethods
|
118
|
+
def read_values_from_stacks(stackname)
|
119
|
+
result = {}
|
120
|
+
response = client.get("stacks/#{current_grid}/#{stackname}")
|
121
|
+
result.merge!(response['variables']) if response['variables']
|
122
|
+
if response['children']
|
123
|
+
response['children'].each do |child_info|
|
124
|
+
result.merge!(
|
125
|
+
read_values_from_stacks(child_info['name']).tap do |child_result|
|
126
|
+
child_result.keys.each do |key|
|
127
|
+
new_key = child_info['name'].dup # foofoo-redis-monitor
|
128
|
+
new_key.sub!("#{stackname}-", '') # monitor
|
129
|
+
new_key.concat ".#{key}" # monitor.foovariable
|
130
|
+
child_result[new_key] = child_result.delete(key)
|
131
|
+
end
|
132
|
+
end
|
133
|
+
)
|
134
|
+
end
|
135
|
+
end
|
136
|
+
result
|
137
|
+
end
|
138
|
+
|
139
|
+
def values_from_file
|
140
|
+
@values_from_file ||= {}
|
141
|
+
end
|
142
|
+
|
143
|
+
def values_from_value_options
|
144
|
+
@values_from_value_options ||= {}
|
145
|
+
end
|
146
|
+
|
147
|
+
def values_from_installed_stacks
|
148
|
+
@values_from_installed_stacks ||= {}
|
149
|
+
end
|
150
|
+
|
151
|
+
def values_from_options
|
152
|
+
@values_from_options ||= values_from_installed_stacks.merge(values_from_file).merge(values_from_value_options)
|
153
|
+
end
|
154
|
+
|
155
|
+
# Transforms a hash
|
156
|
+
# dependency_values_from_options('foo.bar' => 1, 'foo')
|
157
|
+
# => { 'bar' => 1 }
|
158
|
+
# Used for dependency variable injection
|
159
|
+
def dependency_values_from_options(name)
|
160
|
+
name_with_dot = name.to_s + '.'
|
161
|
+
values_from_options.each_with_object({}) do |kv_pair, obj|
|
162
|
+
key = kv_pair.first.to_s
|
163
|
+
value = kv_pair.last
|
164
|
+
next unless key.start_with?(name_with_dot)
|
165
|
+
obj[key.sub(name_with_dot, '')] = value
|
166
|
+
end
|
167
|
+
end
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
# Sets environment variables from parameters
|
172
|
+
# @param stack [String] current stack name
|
173
|
+
# @param grid [String] current grid name
|
174
|
+
# @param platform [String] current platform name, defaults to param grid value
|
175
|
+
def set_env_variables(stack, grid, platform = grid)
|
176
|
+
ENV['STACK'] = stack
|
177
|
+
ENV['GRID'] = grid
|
178
|
+
ENV['PLATFORM'] = platform
|
179
|
+
end
|
180
|
+
|
181
|
+
# @return [String]
|
182
|
+
def current_dir
|
183
|
+
File.basename(Dir.getwd)
|
184
|
+
end
|
185
|
+
|
186
|
+
def display_notifications(messages, color = :yellow)
|
187
|
+
$stderr.puts(pastel.send(color, messages.to_yaml.gsub(/^---$/, '')))
|
188
|
+
end
|
189
|
+
|
190
|
+
def hint_on_validation_notifications(notifications, filename = nil)
|
191
|
+
return if notifications.nil? || notifications.empty?
|
192
|
+
$stderr.puts pastel.yellow("#{"(#{filename}) " if filename}YAML contains the following unsupported options and they were rejected:")
|
193
|
+
display_notifications(notifications)
|
194
|
+
end
|
195
|
+
|
196
|
+
def abort_on_validation_errors(errors, filename = nil)
|
197
|
+
return if errors.nil? || errors.empty?
|
198
|
+
$stderr.puts pastel.red("#{"(#{filename}) " if filename} YAML validation failed! Aborting.")
|
199
|
+
display_notifications(errors, :red)
|
200
|
+
abort
|
201
|
+
end
|
202
|
+
|
203
|
+
# An accessor to stack registry client
|
204
|
+
# @return [Kontena::StacksClient]
|
205
|
+
def stacks_client
|
206
|
+
@stacks_client ||= Kontena::StacksClient.new(current_account.stacks_url, current_account.token, read_requires_token: current_account.stacks_read_authentication)
|
207
|
+
end
|
208
|
+
end
|
209
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require_relative 'stacks_helper'
|
2
|
+
|
3
|
+
module Kontena::Cli::Stacks
|
4
|
+
class DeployCommand < Kontena::Command
|
5
|
+
include Kontena::Cli::Common
|
6
|
+
include Kontena::Cli::GridOptions
|
7
|
+
include StacksHelper
|
8
|
+
|
9
|
+
banner "Deploys all services of a stack"
|
10
|
+
|
11
|
+
parameter "NAME ...", "Stack name", attribute_name: :names
|
12
|
+
|
13
|
+
option '--[no-]wait', :flag, 'Wait for deployment to finish', default: true
|
14
|
+
|
15
|
+
requires_current_master
|
16
|
+
requires_current_master_token
|
17
|
+
|
18
|
+
def execute
|
19
|
+
names.each do |name|
|
20
|
+
deployment = nil
|
21
|
+
spinner "Triggering deployment of stack #{pastel.cyan(name)}" do
|
22
|
+
deployment = deploy_stack(name)
|
23
|
+
end
|
24
|
+
if wait?
|
25
|
+
spinner "Waiting for deployment to start" do
|
26
|
+
wait_for_deployment_to_start(deployment)
|
27
|
+
end
|
28
|
+
wait_for_deploy_to_finish(deployment)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def deploy_stack(name)
|
34
|
+
client.post("stacks/#{current_grid}/#{name}/deploy", {})
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require_relative '../helpers/log_helper'
|
2
|
+
|
3
|
+
module Kontena::Cli::Stacks
|
4
|
+
class EventsCommand < Kontena::Command
|
5
|
+
include Kontena::Cli::Common
|
6
|
+
include Kontena::Cli::GridOptions
|
7
|
+
include Kontena::Cli::Helpers::LogHelper
|
8
|
+
|
9
|
+
parameter "NAME", "Service name"
|
10
|
+
|
11
|
+
def execute
|
12
|
+
require_api_url
|
13
|
+
|
14
|
+
query_params = {}
|
15
|
+
titles = ['TIME', 'TYPE', 'MESSAGE']
|
16
|
+
puts "%-25s %-25s %s" % titles
|
17
|
+
show_logs("stacks/#{current_grid}/#{name}/event_logs", query_params) do |log|
|
18
|
+
show_log(log)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def show_log(log)
|
23
|
+
msg = log['message']
|
24
|
+
node = log['relationships'].find { |r| r['type'] == 'node' }
|
25
|
+
if node
|
26
|
+
msg = "#{msg} (#{node['id'].split('/')[-1]})"
|
27
|
+
end
|
28
|
+
puts '%-25s %-25s %s' % [
|
29
|
+
log['created_at'], log['type'], msg
|
30
|
+
]
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Kontena::Cli::Stacks
|
2
|
+
class InspectCommand < Kontena::Command
|
3
|
+
include Kontena::Cli::Common
|
4
|
+
include Kontena::Cli::GridOptions
|
5
|
+
|
6
|
+
banner "Shows the Stack YAML used to install the stack"
|
7
|
+
|
8
|
+
parameter "NAME", "Stack name"
|
9
|
+
|
10
|
+
requires_current_master
|
11
|
+
requires_current_master_token
|
12
|
+
|
13
|
+
def execute
|
14
|
+
puts client.get("stacks/#{current_grid}/#{name}")['source']
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,95 @@
|
|
1
|
+
require_relative 'common'
|
2
|
+
require_relative 'yaml/stack_file_loader'
|
3
|
+
|
4
|
+
module Kontena::Cli::Stacks
|
5
|
+
class InstallCommand < Kontena::Command
|
6
|
+
include Kontena::Cli::Common
|
7
|
+
include Kontena::Cli::GridOptions
|
8
|
+
include Common
|
9
|
+
|
10
|
+
banner "Installs a stack to a grid on Kontena Master"
|
11
|
+
|
12
|
+
include Common::StackFileOrNameParam
|
13
|
+
|
14
|
+
include Common::StackNameOption
|
15
|
+
option '--[no-]deploy', :flag, 'Trigger deploy after installation', default: true
|
16
|
+
|
17
|
+
include Common::StackValuesToOption
|
18
|
+
include Common::StackValuesFromOption
|
19
|
+
|
20
|
+
option '--parent-name', '[PARENT_NAME]', "Set parent stack name", hidden: true
|
21
|
+
option '--skip-dependencies', :flag, "Do not install any stack dependencies"
|
22
|
+
|
23
|
+
option "--force", :flag, "Force install", default: false, attribute_name: :forced
|
24
|
+
|
25
|
+
requires_current_master
|
26
|
+
requires_current_master_token
|
27
|
+
|
28
|
+
def execute
|
29
|
+
install_dependencies unless skip_dependencies?
|
30
|
+
|
31
|
+
set_env_variables(stack_name, current_grid)
|
32
|
+
|
33
|
+
stack # runs validations
|
34
|
+
|
35
|
+
kontena_requirement = stack.dig('metadata', 'required_kontena_version')
|
36
|
+
unless kontena_requirement.nil?
|
37
|
+
master_version = Gem::Version.new(client.server_version)
|
38
|
+
unless Gem::Requirement.new(kontena_requirement).satisfied_by?(master_version)
|
39
|
+
puts "#{pastel.red("Warning: ")} Stack requires kontena version #{kontena_requirement} but Master version is #{master_version}"
|
40
|
+
confirm("Are you sure? You can skip this prompt by running this command with --force option") unless forced?
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
hint_on_validation_notifications(reader.notifications)
|
45
|
+
abort_on_validation_errors(reader.errors)
|
46
|
+
|
47
|
+
dump_variables if values_to
|
48
|
+
|
49
|
+
create_stack
|
50
|
+
|
51
|
+
if deploy?
|
52
|
+
deploy_dependencies
|
53
|
+
deploy_stack
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def install_dependencies
|
58
|
+
dependencies = loader.dependencies
|
59
|
+
return if dependencies.nil?
|
60
|
+
|
61
|
+
dependencies.each do |dependency|
|
62
|
+
target_name = "#{stack_name}-#{dependency['name']}"
|
63
|
+
caret "Installing dependency #{pastel.cyan(dependency['stack'])} as #{pastel.cyan(target_name)}"
|
64
|
+
cmd = ['stack', 'install', '-n', target_name, '--parent-name', stack_name, '--no-deploy']
|
65
|
+
|
66
|
+
dependency['variables'].merge(dependency_values_from_options(dependency['name'])).each do |key, value|
|
67
|
+
cmd.concat ['-v', "#{key}=#{value}"]
|
68
|
+
end
|
69
|
+
|
70
|
+
cmd << dependency['stack']
|
71
|
+
Kontena.run!(cmd)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
def deploy_dependencies
|
76
|
+
dependencies = loader.dependencies
|
77
|
+
return if dependencies.nil?
|
78
|
+
|
79
|
+
dependencies.each do |dependency|
|
80
|
+
target_name = "#{stack_name}-#{dependency['name']}"
|
81
|
+
Kontena.run!(['stack', 'deploy', target_name])
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def create_stack
|
86
|
+
spinner "Creating stack #{pastel.cyan(stack['name'])} " do
|
87
|
+
client.post("grids/#{current_grid}/stacks", stack)
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
def deploy_stack
|
92
|
+
Kontena.run!(['stack', 'deploy', stack['name']])
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
module Kontena::Cli::Stacks
|
2
|
+
class LabelCommand < Kontena::Command
|
3
|
+
subcommand "add", "Add label to stack", load_subcommand('stacks/labels/add_command')
|
4
|
+
subcommand ["remove", "rm"], "Remove label from stack", load_subcommand('stacks/labels/remove_command')
|
5
|
+
subcommand ["list", "ls"], "List stack labels", load_subcommand('stacks/labels/list_command')
|
6
|
+
|
7
|
+
def execute
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require_relative '../common'
|
2
|
+
require_relative 'common'
|
3
|
+
|
4
|
+
module Kontena::Cli::Stacks::Labels
|
5
|
+
class AddCommand < Kontena::Command
|
6
|
+
include Kontena::Cli::Common
|
7
|
+
include Kontena::Cli::GridOptions
|
8
|
+
include Common
|
9
|
+
|
10
|
+
parameter "NAME", "Stack name"
|
11
|
+
parameter "LABEL ...", "Labels"
|
12
|
+
|
13
|
+
requires_current_master
|
14
|
+
requires_current_master_token
|
15
|
+
|
16
|
+
def execute
|
17
|
+
original_labels = fetch_master_data(name)
|
18
|
+
update_stack(name, { 'labels' => original_labels | label_list })
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Kontena::Cli::Stacks::Labels
|
2
|
+
module Common
|
3
|
+
private
|
4
|
+
|
5
|
+
def update_stack(name, data)
|
6
|
+
client.patch(stack_url(name), data)
|
7
|
+
end
|
8
|
+
|
9
|
+
def stack_url(name)
|
10
|
+
"stacks/#{current_grid}/#{name}"
|
11
|
+
end
|
12
|
+
|
13
|
+
def fetch_master_data(stackname)
|
14
|
+
original_data = client.get(stack_url(stackname))
|
15
|
+
# ensure we always return either labels or an empty array
|
16
|
+
original_data['labels'] || []
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require_relative '../common'
|
2
|
+
require_relative 'common'
|
3
|
+
|
4
|
+
module Kontena::Cli::Stacks::Labels
|
5
|
+
class ListCommand < Kontena::Command
|
6
|
+
include Kontena::Cli::Common
|
7
|
+
include Kontena::Cli::GridOptions
|
8
|
+
include Common
|
9
|
+
|
10
|
+
parameter "NAME", "Stack name"
|
11
|
+
|
12
|
+
requires_current_master
|
13
|
+
requires_current_master_token
|
14
|
+
|
15
|
+
def execute
|
16
|
+
stack = client.get(stack_url(name))
|
17
|
+
# safeguard from nil, since 'labels' field is optional
|
18
|
+
puts Array(stack['labels'] || []).join("\n")
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require_relative '../common'
|
2
|
+
require_relative 'common'
|
3
|
+
|
4
|
+
module Kontena::Cli::Stacks::Labels
|
5
|
+
class RemoveCommand < Kontena::Command
|
6
|
+
include Kontena::Cli::Common
|
7
|
+
include Kontena::Cli::GridOptions
|
8
|
+
include Common
|
9
|
+
|
10
|
+
parameter "NAME", "Stack name"
|
11
|
+
parameter "LABEL ...", "Labels"
|
12
|
+
|
13
|
+
requires_current_master
|
14
|
+
requires_current_master_token
|
15
|
+
|
16
|
+
def execute
|
17
|
+
original_labels = fetch_master_data(name)
|
18
|
+
update_stack(name, { 'labels' => (original_labels - label_list) })
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,154 @@
|
|
1
|
+
require_relative 'common'
|
2
|
+
|
3
|
+
module Kontena::Cli::Stacks
|
4
|
+
class ListCommand < Kontena::Command
|
5
|
+
include Kontena::Cli::Common
|
6
|
+
include Kontena::Cli::GridOptions
|
7
|
+
include Kontena::Cli::TableGenerator::Helper
|
8
|
+
include Common
|
9
|
+
|
10
|
+
banner "Lists all installed stacks on a grid in Kontena Master"
|
11
|
+
|
12
|
+
requires_current_master
|
13
|
+
requires_current_master_token
|
14
|
+
|
15
|
+
HEALTH_ICONS = {
|
16
|
+
unhealthy: Kontena.pastel.red('⊗').freeze,
|
17
|
+
partial: Kontena.pastel.yellow('⊙').freeze,
|
18
|
+
healthy: Kontena.pastel.green('⊛').freeze,
|
19
|
+
default: Kontena.pastel.dim('⊝').freeze
|
20
|
+
}
|
21
|
+
|
22
|
+
def stacks_by_names(stacks, name_list)
|
23
|
+
name_list.map { |name| stacks.find { |stack| stack['name'] == name } }.compact
|
24
|
+
end
|
25
|
+
|
26
|
+
def build_depths(stacks)
|
27
|
+
stacks.sort_by { |s| s['name'] }.each do |stack|
|
28
|
+
stack['depth'] += 1
|
29
|
+
stacks_by_names(stacks, stack['children'].map { |n| n['name'] }).each do |child_stack|
|
30
|
+
child_stack['depth'] += stack['depth']
|
31
|
+
end
|
32
|
+
end
|
33
|
+
stacks
|
34
|
+
end
|
35
|
+
|
36
|
+
def get_stacks
|
37
|
+
client.get("grids/#{current_grid}/stacks")['stacks'].tap { |stacks| stacks.map { |stack| stack['depth'] = 0 } }
|
38
|
+
end
|
39
|
+
|
40
|
+
# Defines a set of columns for the command.
|
41
|
+
def fields
|
42
|
+
return ['name'] if quiet?
|
43
|
+
{
|
44
|
+
name: 'name',
|
45
|
+
stack: 'stack',
|
46
|
+
services: 'services_count',
|
47
|
+
state: 'state',
|
48
|
+
'exposed ports' => 'ports',
|
49
|
+
labels: 'labels'
|
50
|
+
}
|
51
|
+
end
|
52
|
+
|
53
|
+
def execute
|
54
|
+
stacks = build_depths(get_stacks)
|
55
|
+
|
56
|
+
print_table(stacks) do |row|
|
57
|
+
next if quiet?
|
58
|
+
row['name'] = health_icon(stack_health(row)) + " " + tree_icon(row) + " " + row['name']
|
59
|
+
row['stack'] = "#{row['stack']}:#{row['version']}"
|
60
|
+
row['services_count'] = row['services'].size
|
61
|
+
row['ports'] = stack_ports(row).join(',')
|
62
|
+
row['state'] = pastel.send(state_color(row['state']), row['state'])
|
63
|
+
row['labels'] = stack_labels(row)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def state_color(state)
|
68
|
+
case state
|
69
|
+
when 'running' then :green
|
70
|
+
when 'deploying', 'initialized' then :blue
|
71
|
+
when 'stopped' then :red
|
72
|
+
when 'partially_running' then :yellow
|
73
|
+
else :clear
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def health_icon(health)
|
78
|
+
HEALTH_ICONS.fetch(health) { HEALTH_ICONS[:default] }
|
79
|
+
end
|
80
|
+
|
81
|
+
def tree_icon(row)
|
82
|
+
return '' unless $stdout.tty?
|
83
|
+
parent = row['parent']
|
84
|
+
children = row['children'] || []
|
85
|
+
if parent.nil? && children.empty?
|
86
|
+
# solo
|
87
|
+
char = ''
|
88
|
+
elsif parent.nil? && !children.empty?
|
89
|
+
char = ''
|
90
|
+
elsif !parent.nil?
|
91
|
+
char = '┗━'
|
92
|
+
end
|
93
|
+
left_pad = ' ' * (2 * (row['depth'] - 1))
|
94
|
+
left_pad + char
|
95
|
+
end
|
96
|
+
|
97
|
+
# Converts an array of stack labels into a comma-separated string
|
98
|
+
# or '-' when labels field is not defined.
|
99
|
+
#
|
100
|
+
# @param [Hash] stack
|
101
|
+
# @return [<String>]
|
102
|
+
def stack_labels(stack)
|
103
|
+
labels = (stack['labels'] || ['-']).join(',')
|
104
|
+
# trim labels to fit viewport when exceed 43 chars
|
105
|
+
labels.length > 43 && $stdout.isatty ? "#{labels[0..40]}..." : labels
|
106
|
+
end
|
107
|
+
|
108
|
+
# @param [Hash] stack
|
109
|
+
# @return [Array<String>]
|
110
|
+
def stack_ports(stack)
|
111
|
+
ports = []
|
112
|
+
stack['services'].each{|s|
|
113
|
+
service_ports = s['ports'].map{|p|
|
114
|
+
p['ip'] = '*' if p['ip'] == '0.0.0.0'
|
115
|
+
"#{p['ip']}:#{p['node_port']}->#{p['container_port']}/#{p['protocol']}"
|
116
|
+
}
|
117
|
+
ports = ports + service_ports unless service_ports.empty?
|
118
|
+
}
|
119
|
+
ports
|
120
|
+
end
|
121
|
+
|
122
|
+
# @param [Hash] stack
|
123
|
+
# @return [Symbol]
|
124
|
+
def stack_health(stack)
|
125
|
+
services_count = stack['services'].size
|
126
|
+
return :unknown if services_count == 0
|
127
|
+
|
128
|
+
fully_healthy_count = 0
|
129
|
+
partial_healthy_count = 0
|
130
|
+
unhealthy_count = 0
|
131
|
+
unknown_count = 0
|
132
|
+
stack['services'].each { |s|
|
133
|
+
total = s.dig('health_status', 'total').to_i
|
134
|
+
healthy = s.dig('health_status', 'healthy').to_i
|
135
|
+
if total > 0 && healthy == total
|
136
|
+
fully_healthy_count += 1
|
137
|
+
elsif healthy < total && healthy > 0
|
138
|
+
partial_healthy_count += 1
|
139
|
+
elsif healthy == 0 && total > 0
|
140
|
+
unhealthy_count += 1
|
141
|
+
else
|
142
|
+
unknown_count += 1
|
143
|
+
end
|
144
|
+
}
|
145
|
+
return :partial if partial_healthy_count > 0
|
146
|
+
return :partial if unhealthy_count > 0 && fully_healthy_count > 0
|
147
|
+
return :unhealthy if unhealthy_count == services_count
|
148
|
+
return :healthy if fully_healthy_count == services_count
|
149
|
+
return :healthy if fully_healthy_count > 0 && unknown_count > 0
|
150
|
+
|
151
|
+
:unknown
|
152
|
+
end
|
153
|
+
end
|
154
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require_relative '../helpers/log_helper'
|
2
|
+
|
3
|
+
module Kontena::Cli::Stacks
|
4
|
+
class LogsCommand < Kontena::Command
|
5
|
+
include Kontena::Cli::Common
|
6
|
+
include Kontena::Cli::GridOptions
|
7
|
+
include Kontena::Cli::Helpers::LogHelper
|
8
|
+
|
9
|
+
banner "Shows logs from services in a stack"
|
10
|
+
|
11
|
+
parameter "NAME", "Stack name"
|
12
|
+
parameter "[SERVICE] ...", "Service names"
|
13
|
+
|
14
|
+
requires_current_master
|
15
|
+
requires_current_master_token
|
16
|
+
|
17
|
+
def execute
|
18
|
+
if service_list.empty?
|
19
|
+
show_logs("stacks/#{current_grid}/#{name}/container_logs") do |log|
|
20
|
+
show_log(log)
|
21
|
+
end
|
22
|
+
else
|
23
|
+
show_logs("grids/#{current_grid}/container_logs", services: service_list.map {|s| [name, s].join('/')}.join(',')) do |log|
|
24
|
+
show_log(log)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def show_log(log)
|
30
|
+
color = color_for_container(log['name'])
|
31
|
+
prefix = pastel.send(color, "#{log['created_at']} [#{log['name']}]:")
|
32
|
+
puts "#{prefix} #{log['data']}"
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|