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,662 @@
|
|
1
|
+
require 'ostruct'
|
2
|
+
require 'singleton'
|
3
|
+
require 'forwardable'
|
4
|
+
require 'logger'
|
5
|
+
autoload :JSON, 'json'
|
6
|
+
|
7
|
+
module Kontena
|
8
|
+
module Cli
|
9
|
+
# Helper to access and update the CLI configuration file.
|
10
|
+
#
|
11
|
+
# Also provides a "fake" config hash that behaves just like the file based
|
12
|
+
# config when ENV-variables are used instead of config file.
|
13
|
+
class Config < OpenStruct
|
14
|
+
include Singleton
|
15
|
+
|
16
|
+
module Fields
|
17
|
+
def keys
|
18
|
+
@table.keys
|
19
|
+
end
|
20
|
+
|
21
|
+
def values_at(*fields)
|
22
|
+
(fields.first.is_a?(Array) ? fields.first : fields).map { |field| self[field] }
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
include Fields
|
27
|
+
|
28
|
+
attr_accessor :logger
|
29
|
+
attr_accessor :current_server
|
30
|
+
attr_reader :current_account
|
31
|
+
|
32
|
+
|
33
|
+
def self.reset_instance
|
34
|
+
Singleton.send :__init__, self
|
35
|
+
self
|
36
|
+
end
|
37
|
+
|
38
|
+
TokenExpiredError = Class.new(StandardError)
|
39
|
+
|
40
|
+
def initialize
|
41
|
+
super
|
42
|
+
@logger = Kontena.logger
|
43
|
+
|
44
|
+
load_settings_from_config_file
|
45
|
+
|
46
|
+
override_master_settings_from_env
|
47
|
+
override_cloud_settings_from_env
|
48
|
+
|
49
|
+
debug { "Configuration loaded with #{servers.count} servers and #{accounts.count} accounts." }
|
50
|
+
debug { "Current master: #{current_server || '(not selected)'}" }
|
51
|
+
debug { "Current grid: #{current_grid || '(not selected)'}" }
|
52
|
+
debug { "Current account: #{current_account.nil? ? '(not selected)' : current_account.name}" }
|
53
|
+
end
|
54
|
+
|
55
|
+
def debug(&block)
|
56
|
+
Kontena.logger.add(Logger::DEBUG, nil, 'CONFIG', &block)
|
57
|
+
end
|
58
|
+
|
59
|
+
def override_master_settings_from_env
|
60
|
+
if ENV['KONTENA_URL']
|
61
|
+
server = find_server_by(url: ENV['KONTENA_URL'])
|
62
|
+
if server.nil?
|
63
|
+
debug { 'Using new master url from env KONTENA_URL' }
|
64
|
+
server = Server.new(
|
65
|
+
url: ENV['KONTENA_URL'],
|
66
|
+
name: ENV['KONTENA_MASTER'] || 'default'
|
67
|
+
)
|
68
|
+
servers << server
|
69
|
+
else
|
70
|
+
debug { "Using master #{server.name} in config found via url in env KONTENA_URL" }
|
71
|
+
end
|
72
|
+
elsif ENV['KONTENA_MASTER']
|
73
|
+
server = find_server_by(name: ENV['KONTENA_MASTER'])
|
74
|
+
if server
|
75
|
+
debug { "Using master #{ENV['KONTENA_MASTER']} set via env KONTENA_MASTER" }
|
76
|
+
end
|
77
|
+
elsif current_master
|
78
|
+
server = current_master
|
79
|
+
end
|
80
|
+
|
81
|
+
if server.nil?
|
82
|
+
debug { 'Could not determine a master through config or env' }
|
83
|
+
self.current_master = nil
|
84
|
+
return
|
85
|
+
else
|
86
|
+
self.current_master = server.name
|
87
|
+
end
|
88
|
+
|
89
|
+
if ENV['KONTENA_GRID']
|
90
|
+
debug { "Using grid #{ENV['KONTENA_GRID']} from env KONTENA_GRID" }
|
91
|
+
server.grid = ENV['KONTENA_GRID']
|
92
|
+
end
|
93
|
+
|
94
|
+
if ENV['KONTENA_TOKEN']
|
95
|
+
debug { 'Using master token from env KONTENA_TOKEN' }
|
96
|
+
server.token ||= Token.new(parent_type: :master, parent_name: server.name)
|
97
|
+
server.token.access_token = ENV['KONTENA_TOKEN']
|
98
|
+
server.token.refresh_token = nil
|
99
|
+
server.token.expires_at = nil
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
def override_cloud_settings_from_env
|
104
|
+
if ENV['KONTENA_CLOUD']
|
105
|
+
account = find_account(ENV['KONTENA_CLOUD'])
|
106
|
+
if account
|
107
|
+
debug { "Using cloud account #{ENV['KONTENA_CLOUD']} from config selected by env KONTENA_CLOUD" }
|
108
|
+
self.current_account = account.name
|
109
|
+
else
|
110
|
+
debug { "Using new cloud account #{ENV['KONTENA_CLOUD']} from env" }
|
111
|
+
account = Accout.new(kontena_account_data.merge(name: ENV['KONTENA_CLOUD']))
|
112
|
+
accounts << account
|
113
|
+
end
|
114
|
+
elsif current_account
|
115
|
+
account = current_account
|
116
|
+
end
|
117
|
+
|
118
|
+
if account.nil?
|
119
|
+
debug { 'No account data from config or env' }
|
120
|
+
self.current_account = nil
|
121
|
+
return
|
122
|
+
end
|
123
|
+
|
124
|
+
if ENV['KONTENA_CLOUD_TOKEN']
|
125
|
+
debug { 'Using cloud token from env KONTENA_CLOUD_TOKEN' }
|
126
|
+
account.token ||= Token.new(parent_type: :account, parent_name: account.name)
|
127
|
+
account.token.access_token = ENV['KONTENA_CLOUD_TOKEN']
|
128
|
+
account.token.refresh_token = nil
|
129
|
+
account.token.expires_at = nil
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
def extract_token!(hash={})
|
134
|
+
Token.new(
|
135
|
+
access_token: hash.delete('token'),
|
136
|
+
refresh_token: hash.delete('refresh_token'),
|
137
|
+
expires_at: hash.delete('token_expires_at').to_i
|
138
|
+
)
|
139
|
+
end
|
140
|
+
|
141
|
+
# Load configuration from default location ($HOME/.krates.json)
|
142
|
+
def load_settings_from_config_file
|
143
|
+
settings = config_file_available? ? parse_config_file : default_settings
|
144
|
+
|
145
|
+
Array(settings['servers']).each do |server_data|
|
146
|
+
if server_data['token']
|
147
|
+
token = extract_token!(server_data)
|
148
|
+
token.parent_type = :master
|
149
|
+
token.parent_name = server_data['name']
|
150
|
+
server = Server.new(server_data)
|
151
|
+
server.token = token
|
152
|
+
else
|
153
|
+
server = Server.new(server_data)
|
154
|
+
end
|
155
|
+
server.account ||= 'master'
|
156
|
+
if servers.find { |s| s['name'] == server.name}
|
157
|
+
server.name = "#{server.name}-2"
|
158
|
+
server.name.succ! until servers.find { |s| s['name'] == server.name }.nil?
|
159
|
+
debug { "Renamed server to #{server.name} because a duplicate was found in config" }
|
160
|
+
end
|
161
|
+
servers << server
|
162
|
+
end
|
163
|
+
|
164
|
+
self.current_server = settings['current_server']
|
165
|
+
|
166
|
+
Array(settings['accounts']).each do |account_data|
|
167
|
+
if account_data['token']
|
168
|
+
token = extract_token!(account_data)
|
169
|
+
token.parent_type = :account
|
170
|
+
token.parent_name = account_data['name']
|
171
|
+
account = Account.new(account_data)
|
172
|
+
account.token = token
|
173
|
+
else
|
174
|
+
account = Account.new(account_data)
|
175
|
+
end
|
176
|
+
accounts << account
|
177
|
+
end
|
178
|
+
|
179
|
+
ka = find_account('kontena')
|
180
|
+
if ka
|
181
|
+
kontena_account_data.each {|k,v| ka[k] = v}
|
182
|
+
else
|
183
|
+
accounts << Account.new(kontena_account_data)
|
184
|
+
end
|
185
|
+
|
186
|
+
master_index = find_account_index('master')
|
187
|
+
accounts.delete_at(master_index) if master_index
|
188
|
+
accounts << Account.new(master_account_data)
|
189
|
+
|
190
|
+
self.current_account = settings['current_account'] || 'kontena'
|
191
|
+
end
|
192
|
+
|
193
|
+
def kontena_account_data
|
194
|
+
{
|
195
|
+
name: 'kontena',
|
196
|
+
url: ENV['KONTENA_CLOUD_URL'] || 'https://cloud-api.kontena.io',
|
197
|
+
stacks_url: ENV['KONTENA_STACK_REGISTRY_URL'] || 'https://stacks.kontena.io',
|
198
|
+
token_endpoint: ENV['AUTH_TOKEN_ENDPOINT'] || 'https://cloud-api.kontena.io/oauth2/token',
|
199
|
+
authorization_endpoint: ENV['AUTH_AUTHORIZE_ENDPOINT'] || 'https://cloud.kontena.io/login/oauth/authorize',
|
200
|
+
userinfo_endpoint: ENV['AUTH_USERINFO_ENDPOINT'] || 'https://cloud-api.kontena.io/user',
|
201
|
+
token_post_content_type: ENV['AUTH_TOKEN_POST_CONTENT_TYPE'] || 'application/x-www-form-urlencoded',
|
202
|
+
code_requires_basic_auth: ENV['AUTH_CODE_REQUIRES_BASIC_AUTH'].to_s == true,
|
203
|
+
token_method: ENV['AUTH_TOKEN_METHOD'] || 'post',
|
204
|
+
scope: ENV['AUTH_USERINFO_SCOPE'] || 'user',
|
205
|
+
client_id: nil,
|
206
|
+
stacks_read_authentication: ENV['KONTENA_STACK_REGISTRY_READ_AUTHENTICATION'].to_s == 'true'
|
207
|
+
}
|
208
|
+
end
|
209
|
+
|
210
|
+
def master_account_data
|
211
|
+
{
|
212
|
+
name: 'master',
|
213
|
+
token_endpoint: '/oauth2/token',
|
214
|
+
authorization_endpoint: '/oauth2/authorize',
|
215
|
+
userinfo_endpoint: '/v1/user',
|
216
|
+
token_post_content_type: 'application/json',
|
217
|
+
token_method: 'post',
|
218
|
+
code_requires_basic_auth: false
|
219
|
+
}
|
220
|
+
end
|
221
|
+
|
222
|
+
# Verifies access to existing configuration file
|
223
|
+
#
|
224
|
+
# @return [Boolean]
|
225
|
+
def config_file_available?
|
226
|
+
File.exist?(config_filename) && File.readable?(config_filename)
|
227
|
+
end
|
228
|
+
|
229
|
+
# Default settings hash, used when configuration file does not exist.
|
230
|
+
#
|
231
|
+
# @return [Hash]
|
232
|
+
def default_settings
|
233
|
+
debug { 'Configuration file not found, using default settings.' }
|
234
|
+
{
|
235
|
+
'current_server' => 'default',
|
236
|
+
'servers' => []
|
237
|
+
}
|
238
|
+
end
|
239
|
+
|
240
|
+
# Converts old style settings hash into modern one
|
241
|
+
#
|
242
|
+
# @param [Hash] settings_hash
|
243
|
+
# @return [Hash] migrated_settings_hash
|
244
|
+
def migrate_legacy_settings(settings)
|
245
|
+
debug { "Migrating from legacy style configuration" }
|
246
|
+
{
|
247
|
+
'current_server' => 'default',
|
248
|
+
'servers' => [
|
249
|
+
settings['server'].merge(
|
250
|
+
'name' => 'default',
|
251
|
+
'account' => 'kontena'
|
252
|
+
)
|
253
|
+
],
|
254
|
+
'accounts' => [ kontena_account_data ]
|
255
|
+
}
|
256
|
+
end
|
257
|
+
|
258
|
+
# Read, parse and migrate the configuration file
|
259
|
+
#
|
260
|
+
# @return [Hash] config_data
|
261
|
+
def parse_config_file
|
262
|
+
debug { "Loading configuration from #{config_filename}" }
|
263
|
+
settings = JSON.load(File.read(config_filename))
|
264
|
+
if settings.has_key?('server')
|
265
|
+
settings = migrate_legacy_settings(settings)
|
266
|
+
else
|
267
|
+
settings
|
268
|
+
end
|
269
|
+
end
|
270
|
+
|
271
|
+
# Return the configuration file path. You can override the default
|
272
|
+
# by using KONTENA_CONFIG environment variable.
|
273
|
+
#
|
274
|
+
# @return [String] path
|
275
|
+
def config_filename
|
276
|
+
return @config_filename if @config_filename
|
277
|
+
if ENV['KONTENA_CONFIG']
|
278
|
+
debug { "Using #{ENV['KONTENA_CONFIG']} as config file set through env KONTENA_CONFIG"}
|
279
|
+
@config_filename = ENV['KONTENA_CONFIG']
|
280
|
+
else
|
281
|
+
@config_filename = default_config_filename
|
282
|
+
end
|
283
|
+
end
|
284
|
+
|
285
|
+
# Generate the default configuration filename
|
286
|
+
def default_config_filename
|
287
|
+
File.join(Dir.home, '.krates.json')
|
288
|
+
end
|
289
|
+
|
290
|
+
# List of configured servers
|
291
|
+
#
|
292
|
+
# @return [Array]
|
293
|
+
def servers
|
294
|
+
@servers ||= []
|
295
|
+
end
|
296
|
+
|
297
|
+
# List of configured accounts
|
298
|
+
#
|
299
|
+
# @return [Array]
|
300
|
+
def accounts
|
301
|
+
@accounts ||= []
|
302
|
+
end
|
303
|
+
|
304
|
+
# Add a new server to the configuration
|
305
|
+
#
|
306
|
+
# @param [Hash] server_data
|
307
|
+
def add_server(data)
|
308
|
+
token = Token.new(
|
309
|
+
access_token: data.delete('token'),
|
310
|
+
refresh_token: data.delete('refresh_token'),
|
311
|
+
expires_at: data.delete('token_expires_at'),
|
312
|
+
parent_type: :master,
|
313
|
+
parent_name: data['name'] || data[:name]
|
314
|
+
)
|
315
|
+
server = Server.new(data.merge(token: token))
|
316
|
+
if (existing_index = find_server_index(server.name))
|
317
|
+
servers[existing_index] = server
|
318
|
+
else
|
319
|
+
servers << server
|
320
|
+
end
|
321
|
+
write
|
322
|
+
end
|
323
|
+
|
324
|
+
# Search the server list for a server by field(s) and value(s).
|
325
|
+
# @example
|
326
|
+
# find_server_by(url: 'https://localhost', token: 'abcd')
|
327
|
+
# @param [Hash] search_criteria
|
328
|
+
# @return [Server, NilClass]
|
329
|
+
def find_server_by(criteria = {})
|
330
|
+
servers.find{|s| criteria.none? {|k,v| v != s[k]}}
|
331
|
+
end
|
332
|
+
|
333
|
+
# Search the server list for a server by field(s) and value(s)
|
334
|
+
# and return its index.
|
335
|
+
#
|
336
|
+
# @example
|
337
|
+
# find_server_index(url: 'https://localhost')
|
338
|
+
# @param [Hash] search_criteria
|
339
|
+
# @return [Fixnum, NilClass]
|
340
|
+
def find_server_index_by(criteria = {})
|
341
|
+
servers.find_index{|s| criteria.none? {|k,v| v != s[k]}}
|
342
|
+
end
|
343
|
+
|
344
|
+
# Shortcut to find_server_by(name: name)
|
345
|
+
#
|
346
|
+
# @param [String] server_name
|
347
|
+
# @return [Server, NilClass]
|
348
|
+
def find_server(name)
|
349
|
+
find_server_by(name: name)
|
350
|
+
end
|
351
|
+
|
352
|
+
# Shortcut to find_server_index_by(name: name)
|
353
|
+
#
|
354
|
+
# @param [String] server_name
|
355
|
+
# @return [Fixnum, NilClass]
|
356
|
+
def find_server_index(name)
|
357
|
+
find_server_index_by(name: name)
|
358
|
+
end
|
359
|
+
|
360
|
+
def find_account(name)
|
361
|
+
accounts.find{|a| a['name'] == name.to_s}
|
362
|
+
end
|
363
|
+
|
364
|
+
def find_account_index(name)
|
365
|
+
accounts.find_index{|a| a['name'] == name.to_s}
|
366
|
+
end
|
367
|
+
|
368
|
+
# Currently selected master's configuration data
|
369
|
+
#
|
370
|
+
# @return [Server]
|
371
|
+
def current_master
|
372
|
+
return servers[@current_master_index] if @current_master_index
|
373
|
+
return nil unless current_server
|
374
|
+
@current_master_index = find_server_index(current_server)
|
375
|
+
servers[@current_master_index] if @current_master_index
|
376
|
+
end
|
377
|
+
|
378
|
+
# Raises unless current master has token.
|
379
|
+
#
|
380
|
+
# @return [Token] current_master_token
|
381
|
+
# @raise [ArgumentError] if no token available
|
382
|
+
def require_current_master_token
|
383
|
+
require_current_master
|
384
|
+
token = current_master.token
|
385
|
+
if token && token.access_token
|
386
|
+
return token unless token.expired?
|
387
|
+
raise TokenExpiredError, "The access token has expired and needs to be refreshed."
|
388
|
+
end
|
389
|
+
raise ArgumentError, "You are not logged into a Kontena Master. Use: kontena master login"
|
390
|
+
end
|
391
|
+
|
392
|
+
# Raises unless current master is selected.
|
393
|
+
#
|
394
|
+
# @return [Server] current_master
|
395
|
+
# @raise [ArgumentError] if no account is selected
|
396
|
+
def require_current_master
|
397
|
+
return current_master if current_master
|
398
|
+
raise ArgumentError, "You are not logged into a Kontena Master. Use: kontena master login"
|
399
|
+
end
|
400
|
+
|
401
|
+
# Raises unless current account is selected.
|
402
|
+
#
|
403
|
+
# @return [Account] current_account
|
404
|
+
# @raise [ArgumentError] if no account is selected
|
405
|
+
def require_current_account
|
406
|
+
return @current_account if @current_account
|
407
|
+
raise ArgumentError, "You are not logged into an authorization provider. Use: kontena cloud login"
|
408
|
+
end
|
409
|
+
|
410
|
+
def require_current_account_token
|
411
|
+
account = require_current_account
|
412
|
+
if !account || account.token.nil? || account.token.access_token.nil?
|
413
|
+
raise ArgumentError, "You are not logged in to Kontena Cloud. Use: kontena cloud login"
|
414
|
+
elsif account.token.expired?
|
415
|
+
raise TokenExpiredError, "The cloud access token has expired and needs to be refreshed." unless cloud_client.refresh_token
|
416
|
+
end
|
417
|
+
end
|
418
|
+
|
419
|
+
# Set the current master.
|
420
|
+
#
|
421
|
+
# @param [String] server_name
|
422
|
+
# @raise [ArgumentError] if server by that name doesn't exist
|
423
|
+
def current_master=(name)
|
424
|
+
@current_master_index = nil
|
425
|
+
if name.nil?
|
426
|
+
self.current_server = nil
|
427
|
+
else
|
428
|
+
index = find_server_index(name.respond_to?(:name) ? name.name : name)
|
429
|
+
if index
|
430
|
+
self.current_server = servers[index].name
|
431
|
+
else
|
432
|
+
raise ArgumentError, "Server '#{name}' does not exist, can't add as current master."
|
433
|
+
end
|
434
|
+
end
|
435
|
+
end
|
436
|
+
|
437
|
+
# Raises unless current grid is selected.
|
438
|
+
#
|
439
|
+
# @return [String] current_grid_name
|
440
|
+
# @raise [ArgumentError] if no grid is selected
|
441
|
+
def require_current_grid
|
442
|
+
return current_grid if current_grid
|
443
|
+
raise ArgumentError, "You have not selected a grid. Use: kontena grid"
|
444
|
+
end
|
445
|
+
|
446
|
+
# Name of the currently selected grid. Can override using
|
447
|
+
# KONTENA_GRID environment variable.
|
448
|
+
#
|
449
|
+
# @return [String, NilClass]
|
450
|
+
def current_grid
|
451
|
+
return ENV['KONTENA_GRID'] unless ENV['KONTENA_GRID'].to_s.empty?
|
452
|
+
return nil unless current_master
|
453
|
+
current_master.grid
|
454
|
+
end
|
455
|
+
|
456
|
+
# Set the current grid name.
|
457
|
+
#
|
458
|
+
# @param [String] grid_name
|
459
|
+
# @raise [ArgumentError] if current master hasn't been selected
|
460
|
+
def current_grid=(name)
|
461
|
+
if current_master
|
462
|
+
current_master.grid = name
|
463
|
+
else
|
464
|
+
raise ArgumentError, "Current master not selected, can't set grid."
|
465
|
+
end
|
466
|
+
end
|
467
|
+
|
468
|
+
def current_account=(name)
|
469
|
+
if name.nil?
|
470
|
+
@current_account = nil
|
471
|
+
elsif name == 'master'
|
472
|
+
raise ArgumentError, "The master account can not be used as current account."
|
473
|
+
else
|
474
|
+
account = find_account(name.respond_to?(:name) ? name.name : name)
|
475
|
+
if account
|
476
|
+
@current_account = account
|
477
|
+
else
|
478
|
+
raise ArgumentError, "Account '#{name}' not found in configuration"
|
479
|
+
end
|
480
|
+
end
|
481
|
+
end
|
482
|
+
|
483
|
+
# Returns a cleaned up version of the kontena account data with only the token and name.
|
484
|
+
def kontena_account_hash
|
485
|
+
hash = { name: 'kontena' }
|
486
|
+
acc = find_account('kontena')
|
487
|
+
if acc && acc.token
|
488
|
+
hash[:username] = acc.username if acc.username
|
489
|
+
hash.merge!(acc.token.to_h)
|
490
|
+
end
|
491
|
+
hash
|
492
|
+
end
|
493
|
+
|
494
|
+
# Generate a hash from the current configuration.
|
495
|
+
#
|
496
|
+
# @return [Hash]
|
497
|
+
def to_hash
|
498
|
+
hash = {
|
499
|
+
current_server: (self.current_server && find_server(self.current_server)) ? self.current_server : nil,
|
500
|
+
current_account: self.current_account ? self.current_account.name : nil,
|
501
|
+
servers: servers.map(&:to_h),
|
502
|
+
accounts: accounts.reject{|a| a.name == 'master' || a.name == 'kontena'}.map(&:to_h) + [kontena_account_hash]
|
503
|
+
}
|
504
|
+
hash[:servers].each do |server|
|
505
|
+
server.delete(:account) if server[:account] == 'master'
|
506
|
+
end
|
507
|
+
hash
|
508
|
+
end
|
509
|
+
|
510
|
+
# Generate a JSON string from the current configuration
|
511
|
+
#
|
512
|
+
# @return [String]
|
513
|
+
def to_json
|
514
|
+
JSON.pretty_generate(to_hash)
|
515
|
+
end
|
516
|
+
|
517
|
+
# Write the current configuration to config file.
|
518
|
+
# Does nothing if using settings from environment variables.
|
519
|
+
def write
|
520
|
+
return nil if ENV['KONTENA_URL']
|
521
|
+
debug { "Writing configuration to #{config_filename}" }
|
522
|
+
File.write(config_filename, to_json)
|
523
|
+
end
|
524
|
+
|
525
|
+
class << self
|
526
|
+
extend Forwardable
|
527
|
+
def_delegators :instance, *Config.instance_methods(false)
|
528
|
+
end
|
529
|
+
|
530
|
+
module TokenSerializer
|
531
|
+
# Modified to_h to handle token data serialization
|
532
|
+
#
|
533
|
+
# @return [Hash]
|
534
|
+
def to_h
|
535
|
+
token = delete_field(:token) if respond_to?(:token)
|
536
|
+
result = super
|
537
|
+
if token
|
538
|
+
self.token = token
|
539
|
+
result.merge!(token.to_h)
|
540
|
+
end
|
541
|
+
result
|
542
|
+
end
|
543
|
+
end
|
544
|
+
|
545
|
+
module ConfigurationInstance
|
546
|
+
def config
|
547
|
+
Kontena::Cli::Config.instance
|
548
|
+
end
|
549
|
+
end
|
550
|
+
|
551
|
+
class Account < OpenStruct
|
552
|
+
include Fields
|
553
|
+
include TokenSerializer
|
554
|
+
include ConfigurationInstance
|
555
|
+
|
556
|
+
# Strip token info from master-account, the token is saved with the server.
|
557
|
+
def to_h
|
558
|
+
if self.name == 'master'
|
559
|
+
super.to_h.reject do |k,_|
|
560
|
+
[:url, :token, :refresh_token, :token_expires_at].include?(k)
|
561
|
+
end
|
562
|
+
else
|
563
|
+
super
|
564
|
+
end
|
565
|
+
end
|
566
|
+
end
|
567
|
+
|
568
|
+
class Server < OpenStruct
|
569
|
+
include Fields
|
570
|
+
include TokenSerializer
|
571
|
+
include ConfigurationInstance
|
572
|
+
|
573
|
+
def initialize(*args)
|
574
|
+
super
|
575
|
+
@table[:account] ||= 'master'
|
576
|
+
end
|
577
|
+
|
578
|
+
def uri
|
579
|
+
@uri ||= URI.parse(self.url)
|
580
|
+
end
|
581
|
+
|
582
|
+
# @return [String, nil] path to ~/.kontena/certs/*.pem
|
583
|
+
def ssl_cert_path
|
584
|
+
path = File.join(Dir.home, '.kontena', 'certs', "#{self.uri.host}.pem")
|
585
|
+
|
586
|
+
if File.exist?(path) && File.readable?(path)
|
587
|
+
return path
|
588
|
+
else
|
589
|
+
return nil
|
590
|
+
end
|
591
|
+
end
|
592
|
+
|
593
|
+
# @return [OpenSSL::X509::Certificate, nil]
|
594
|
+
def ssl_cert
|
595
|
+
if path = self.ssl_cert_path
|
596
|
+
return OpenSSL::X509::Certificate.new(File.read(path))
|
597
|
+
else
|
598
|
+
return nil
|
599
|
+
end
|
600
|
+
end
|
601
|
+
|
602
|
+
# @return [String, nil] ssl cert subject CN=
|
603
|
+
def ssl_subject_cn
|
604
|
+
if cert = self.ssl_cert
|
605
|
+
return cert.subject.to_a.select{|name, data, type| name == 'CN' }.map{|name, data, type| data }.first
|
606
|
+
else
|
607
|
+
nil
|
608
|
+
end
|
609
|
+
end
|
610
|
+
end
|
611
|
+
|
612
|
+
class Token < OpenStruct
|
613
|
+
include Fields
|
614
|
+
include ConfigurationInstance
|
615
|
+
|
616
|
+
# Hash representation of token data
|
617
|
+
#
|
618
|
+
# @return [Hash]
|
619
|
+
def to_h
|
620
|
+
{
|
621
|
+
token: self.access_token,
|
622
|
+
token_expires_at: self.expires_at,
|
623
|
+
refresh_token: self.refresh_token
|
624
|
+
}.merge(self.respond_to?(:username) ? {username: self.username} : {})
|
625
|
+
end
|
626
|
+
|
627
|
+
def expires?
|
628
|
+
expires_at.nil? ? false : expires_at.to_i > 0
|
629
|
+
end
|
630
|
+
|
631
|
+
def expired?
|
632
|
+
expires? && expires_at && expires_at.to_i < Time.now.utc.to_i
|
633
|
+
end
|
634
|
+
|
635
|
+
def account
|
636
|
+
return @account if @account
|
637
|
+
return config.find_account('master') unless parent
|
638
|
+
@account =
|
639
|
+
case parent_type
|
640
|
+
when :master then config.find_account(parent.account)
|
641
|
+
when :account then parent
|
642
|
+
else
|
643
|
+
nil
|
644
|
+
end
|
645
|
+
end
|
646
|
+
|
647
|
+
def parent
|
648
|
+
return nil unless parent_type
|
649
|
+
return nil unless parent_name
|
650
|
+
case parent_type
|
651
|
+
when :master
|
652
|
+
config.find_server(parent_name)
|
653
|
+
when :account
|
654
|
+
config.find_account(parent_name)
|
655
|
+
else
|
656
|
+
nil
|
657
|
+
end
|
658
|
+
end
|
659
|
+
end
|
660
|
+
end
|
661
|
+
end
|
662
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
class Kontena::Cli::ContainerCommand < Kontena::Command
|
2
|
+
|
3
|
+
subcommand ["list", "ls"], "List grid containers", load_subcommand('containers/list_command')
|
4
|
+
subcommand "exec", "Execute command inside a container", load_subcommand('containers/exec_command')
|
5
|
+
subcommand "inspect", "Inspect the container", load_subcommand('containers/inspect_command')
|
6
|
+
subcommand "logs", "Show container logs", load_subcommand('containers/logs_command')
|
7
|
+
|
8
|
+
def execute
|
9
|
+
end
|
10
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require_relative '../helpers/exec_helper'
|
2
|
+
|
3
|
+
module Kontena::Cli::Containers
|
4
|
+
class ExecCommand < Kontena::Command
|
5
|
+
include Kontena::Cli::Common
|
6
|
+
include Kontena::Cli::GridOptions
|
7
|
+
include Kontena::Cli::Helpers::ExecHelper
|
8
|
+
|
9
|
+
usage "[OPTIONS] [CONTAINER_ID] -- [CMD] ..."
|
10
|
+
|
11
|
+
parameter "CONTAINER_ID", "Container id"
|
12
|
+
parameter "CMD ...", "Command"
|
13
|
+
|
14
|
+
option ["--shell"], :flag, "Execute as a shell command", default: false
|
15
|
+
option ["-i", "--interactive"], :flag, "Keep stdin open", default: false
|
16
|
+
option ["-t", "--tty"], :flag, "Allocate a pseudo-TTY", default: false
|
17
|
+
|
18
|
+
requires_current_master
|
19
|
+
requires_current_grid
|
20
|
+
|
21
|
+
def execute
|
22
|
+
exit_status = container_exec("#{current_grid}/#{self.container_id}", self.cmd_list,
|
23
|
+
interactive: interactive?,
|
24
|
+
shell: shell?,
|
25
|
+
tty: tty?,
|
26
|
+
)
|
27
|
+
|
28
|
+
exit exit_status unless exit_status.zero?
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|