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,75 @@
|
|
1
|
+
module Kontena::Cli::Vault
|
2
|
+
class ImportCommand < Kontena::Command
|
3
|
+
include Kontena::Cli::Common
|
4
|
+
include Kontena::Cli::GridOptions
|
5
|
+
|
6
|
+
banner "Imports secrets to Vault from a YAML file. Secrets with a null value will be deleted from Vault."
|
7
|
+
|
8
|
+
option "--force", :flag, "Force import", default: false, attribute_name: :forced
|
9
|
+
option '--json', :flag, "Input JSON instead of YAML"
|
10
|
+
option '--skip-null', :flag, "Do not remove keys with null values"
|
11
|
+
option '--empty-is-null', :flag, "Treat empty values as null"
|
12
|
+
|
13
|
+
parameter '[PATH]', "Input from file in PATH (default: STDIN)"
|
14
|
+
|
15
|
+
requires_current_master
|
16
|
+
|
17
|
+
def parsed_input
|
18
|
+
require "json"
|
19
|
+
json? ? JSON.load(input) : YAML.safe_load(input, [], [], true, path)
|
20
|
+
end
|
21
|
+
|
22
|
+
def input
|
23
|
+
path ? File.read(path) : stdin_input("Enter secrets YAML", :multiline)
|
24
|
+
end
|
25
|
+
|
26
|
+
def execute
|
27
|
+
require_current_grid
|
28
|
+
|
29
|
+
updates = []
|
30
|
+
deletes = []
|
31
|
+
|
32
|
+
parsed_input.map do |k,v|
|
33
|
+
case v
|
34
|
+
when String, Numeric, TrueClass, FalseClass
|
35
|
+
if empty_is_null? && v.to_s.empty?
|
36
|
+
deletes << k.to_s
|
37
|
+
else
|
38
|
+
updates << [k.to_s, v.to_s]
|
39
|
+
end
|
40
|
+
when NilClass
|
41
|
+
deletes << k.to_s
|
42
|
+
else
|
43
|
+
exit_with_error "Invalid value type #{v.class} for #{k}."
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
if updates.empty? && deletes.empty?
|
48
|
+
exit_with_error "No secrets loaded"
|
49
|
+
end
|
50
|
+
|
51
|
+
unless forced?
|
52
|
+
puts "About to.."
|
53
|
+
puts " * #{Kontena.pastel.yellow("IMPORT")} #{updates.size} secret#{"s" if updates.size > 1}" unless updates.empty?
|
54
|
+
puts " * #{Kontena.pastel.red("DELETE")} #{deletes.size} secret#{"s" if deletes.size > 1}" unless deletes.empty?
|
55
|
+
confirm
|
56
|
+
end
|
57
|
+
|
58
|
+
unless updates.empty?
|
59
|
+
spinner "Updating #{updates.size} secrets" do |spin|
|
60
|
+
updates.each do |key_value_pair|
|
61
|
+
spin.fail! unless Kontena.run(['vault', 'update', '--upsert', '--silent'] + key_value_pair)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
unless deletes.empty? || skip_null?
|
67
|
+
spinner "Deleting #{deletes.size} secrets" do |spin|
|
68
|
+
deletes.map(&:shellescape).each do |key_to_delete|
|
69
|
+
spin.fail! unless Kontena.run(['vault', 'rm', '--silent', '--force', key_to_delete])
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module Kontena::Cli::Vault
|
2
|
+
class ListCommand < Kontena::Command
|
3
|
+
include Kontena::Util
|
4
|
+
include Kontena::Cli::Common
|
5
|
+
include Kontena::Cli::GridOptions
|
6
|
+
include Kontena::Cli::TableGenerator::Helper
|
7
|
+
|
8
|
+
option '--return', :flag, "Return the keys", hidden: true
|
9
|
+
option ['--[no-]long', '-l'], :flag, "Show full dates", default: !$stdout.tty?
|
10
|
+
|
11
|
+
requires_current_master
|
12
|
+
requires_current_master_token
|
13
|
+
requires_current_grid
|
14
|
+
|
15
|
+
def secrets
|
16
|
+
client.get("grids/#{current_grid}/secrets")['secrets'].sort_by { |s| s['name'] }
|
17
|
+
end
|
18
|
+
|
19
|
+
def fields
|
20
|
+
return['name'] if quiet?
|
21
|
+
%w(name created_at updated_at)
|
22
|
+
end
|
23
|
+
|
24
|
+
def execute
|
25
|
+
return secrets.map { |s| s['name'] } if return?
|
26
|
+
print_table(secrets) do |row|
|
27
|
+
next if quiet? || long?
|
28
|
+
row['updated_at'] = updated?(row) ? pastel.blue('never') : time_ago(row['updated_at'])
|
29
|
+
row['created_at'] = time_ago(row['created_at'])
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def updated?(row)
|
34
|
+
row['created_at'] == row['updated_at']
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Kontena::Cli::Vault
|
2
|
+
class ReadCommand < Kontena::Command
|
3
|
+
include Kontena::Cli::Common
|
4
|
+
include Kontena::Cli::GridOptions
|
5
|
+
|
6
|
+
parameter "NAME", "Secret name"
|
7
|
+
|
8
|
+
option '--value', :flag, 'Just output the value'
|
9
|
+
option '--return', :flag, 'Return the value', hidden: true
|
10
|
+
|
11
|
+
def execute
|
12
|
+
require_api_url
|
13
|
+
require_current_grid
|
14
|
+
|
15
|
+
token = require_token
|
16
|
+
result = client(token).get("secrets/#{current_grid}/#{name}")
|
17
|
+
return result['value'] if self.return?
|
18
|
+
if self.value?
|
19
|
+
puts result['value']
|
20
|
+
else
|
21
|
+
puts "#{result['name']}:"
|
22
|
+
puts " created_at: #{result['created_at']}"
|
23
|
+
puts " value: #{result['value']}"
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Kontena::Cli::Vault
|
2
|
+
class RemoveCommand < Kontena::Command
|
3
|
+
include Kontena::Cli::Common
|
4
|
+
include Kontena::Cli::GridOptions
|
5
|
+
|
6
|
+
parameter "NAME ...", "Secret name", attribute_name: :names
|
7
|
+
option "--force", :flag, "Force remove", default: false, attribute_name: :forced
|
8
|
+
option "--silent", :flag, "Reduce output verbosity"
|
9
|
+
|
10
|
+
def execute
|
11
|
+
require_api_url
|
12
|
+
require_current_grid
|
13
|
+
names.each do |name|
|
14
|
+
confirm_command(name) unless forced?
|
15
|
+
|
16
|
+
token = require_token
|
17
|
+
vspinner "Removing #{pastel.cyan(name)} from the vault " do
|
18
|
+
client(token).delete("secrets/#{current_grid}/#{name}")
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module Kontena::Cli::Vault
|
2
|
+
class UpdateCommand < Kontena::Command
|
3
|
+
include Kontena::Cli::Common
|
4
|
+
include Kontena::Cli::GridOptions
|
5
|
+
|
6
|
+
parameter 'NAME', 'Secret name'
|
7
|
+
parameter '[VALUE]', 'Secret value (default: STDIN)'
|
8
|
+
|
9
|
+
option ['-u', '--upsert'], :flag, 'Create secret unless already exists', default: false
|
10
|
+
option '--silent', :flag, "Reduce output verbosity"
|
11
|
+
|
12
|
+
requires_current_master
|
13
|
+
|
14
|
+
def default_value
|
15
|
+
stdin_input("Enter value for secret '#{name}'", :mask)
|
16
|
+
end
|
17
|
+
|
18
|
+
def execute
|
19
|
+
vspinner "Updating #{pastel.cyan(name)} value in the vault " do
|
20
|
+
client.put("secrets/#{current_grid}/#{name}", {name: name, value: value, upsert: upsert? })
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Kontena::Cli::Vault
|
2
|
+
class WriteCommand < Kontena::Command
|
3
|
+
include Kontena::Cli::Common
|
4
|
+
include Kontena::Cli::GridOptions
|
5
|
+
|
6
|
+
parameter 'NAME', 'Secret name'
|
7
|
+
parameter '[VALUE]', 'Secret value (default: STDIN)'
|
8
|
+
|
9
|
+
option '--silent', :flag, "Reduce output verbosity"
|
10
|
+
|
11
|
+
requires_current_master
|
12
|
+
|
13
|
+
def default_value
|
14
|
+
stdin_input("Enter value for secret '#{name}'", :mask)
|
15
|
+
end
|
16
|
+
|
17
|
+
def execute
|
18
|
+
vspinner "Writing #{pastel.cyan(name)} to the vault " do
|
19
|
+
client.post("grids/#{current_grid}/secrets", { name: name, value: value })
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
class Kontena::Cli::VaultCommand < Kontena::Command
|
2
|
+
|
3
|
+
subcommand ["list", "ls"], "List secrets", load_subcommand('vault/list_command')
|
4
|
+
subcommand "write", "Write a secret", load_subcommand('vault/write_command')
|
5
|
+
subcommand "read", "Read secret", load_subcommand('vault/read_command')
|
6
|
+
subcommand "update", "Update secret", load_subcommand('vault/update_command')
|
7
|
+
subcommand ["remove", "rm"], "Remove secret", load_subcommand('vault/remove_command')
|
8
|
+
subcommand "export", "Export secrets to STDOUT", load_subcommand('vault/export_command')
|
9
|
+
subcommand "import", "Import secrets from a file or STDIN", load_subcommand('vault/import_command')
|
10
|
+
|
11
|
+
def execute
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
module Kontena
|
2
|
+
module Cli
|
3
|
+
unless const_defined?(:VERSION)
|
4
|
+
require 'pathname'
|
5
|
+
version_file = Pathname.new(__FILE__).dirname.join('../../../VERSION').realpath
|
6
|
+
is_head = ENV["KONTENA_EXTRA_BUILDTAGS"].to_s.include?('head')
|
7
|
+
VERSION = "#{version_file.read.strip}#{"-head" if is_head}"
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'kontena/cli/version'
|
2
|
+
|
3
|
+
class Kontena::Cli::VersionCommand < Kontena::Command
|
4
|
+
include Kontena::Cli::Common
|
5
|
+
|
6
|
+
option "--cli", :flag, "Only CLI version"
|
7
|
+
|
8
|
+
def execute
|
9
|
+
puts "cli: #{Kontena::Cli::VERSION}"
|
10
|
+
return if cli?
|
11
|
+
|
12
|
+
url = api_url rescue nil
|
13
|
+
if url
|
14
|
+
resp = JSON.parse(client.http_client.get(path: '/').body) rescue nil
|
15
|
+
if resp
|
16
|
+
puts "master: #{resp['version']} (#{url})"
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,9 @@
|
|
1
|
+
|
2
|
+
class Kontena::Cli::VolumeCommand < Kontena::Command
|
3
|
+
|
4
|
+
subcommand "create", "Create a managed volume", load_subcommand('volumes/create_command')
|
5
|
+
subcommand "show", "Show details of a volume", load_subcommand('volumes/show_command')
|
6
|
+
subcommand ["remove", "rm"], "Remove a managed volume", load_subcommand('volumes/remove_command')
|
7
|
+
subcommand ["list", "ls"], "List managed volumes", load_subcommand('volumes/list_command')
|
8
|
+
|
9
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
|
2
|
+
module Kontena::Cli::Volumes
|
3
|
+
class CreateCommand < Kontena::Command
|
4
|
+
include Kontena::Cli::Common
|
5
|
+
include Kontena::Cli::GridOptions
|
6
|
+
|
7
|
+
banner "Creates a volume"
|
8
|
+
parameter 'NAME', 'Volume name'
|
9
|
+
|
10
|
+
SCOPES = %w(grid stack instance)
|
11
|
+
|
12
|
+
option '--driver', 'DRIVER', 'Volume driver to be used', required: true
|
13
|
+
option '--driver-opt', 'DRIVER_OPT', 'Volume driver options', multivalued: true
|
14
|
+
option '--scope', 'SCOPE', "Volume scope (#{SCOPES.join(',')})", required: true do |scope|
|
15
|
+
exit_with_error "Unknown scope '#{scope}, must be one of #{SCOPES.join(',')}" unless SCOPES.include?(scope)
|
16
|
+
scope
|
17
|
+
end
|
18
|
+
|
19
|
+
requires_current_master
|
20
|
+
requires_current_master_token
|
21
|
+
|
22
|
+
def execute
|
23
|
+
volume = {
|
24
|
+
name: name,
|
25
|
+
scope: scope,
|
26
|
+
driver: driver,
|
27
|
+
driver_opts: parse_driver_opts
|
28
|
+
}
|
29
|
+
spinner "Creating volume #{pastel.cyan(name)} " do
|
30
|
+
create_volume(volume)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def parse_driver_opts
|
35
|
+
driver_opt_list.map{ |opt| opt.split('=', 2) }.to_h
|
36
|
+
end
|
37
|
+
|
38
|
+
def create_volume(volume)
|
39
|
+
client.post("volumes/#{current_grid}", volume)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
|
2
|
+
module Kontena::Cli::Volumes
|
3
|
+
class ListCommand < Kontena::Command
|
4
|
+
include Kontena::Util
|
5
|
+
include Kontena::Cli::Common
|
6
|
+
include Kontena::Cli::GridOptions
|
7
|
+
include Kontena::Cli::TableGenerator::Helper
|
8
|
+
|
9
|
+
option ['--[no-]long', '-l'], :flag, "Show full dates", default: !$stdout.tty?
|
10
|
+
|
11
|
+
requires_current_master
|
12
|
+
requires_current_master_token
|
13
|
+
|
14
|
+
def volumes
|
15
|
+
client.get("volumes/#{current_grid}")['volumes']
|
16
|
+
end
|
17
|
+
|
18
|
+
def fields
|
19
|
+
quiet? ? ['name'] : %w(name scope driver created_at)
|
20
|
+
end
|
21
|
+
|
22
|
+
def execute
|
23
|
+
print_table(volumes) do |row|
|
24
|
+
next if long? || quiet?
|
25
|
+
row['created_at'] = time_ago(row['created_at'])
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
|
2
|
+
module Kontena::Cli::Volumes
|
3
|
+
class RemoveCommand < Kontena::Command
|
4
|
+
include Kontena::Cli::Common
|
5
|
+
include Kontena::Cli::GridOptions
|
6
|
+
|
7
|
+
|
8
|
+
banner "Removes a volume"
|
9
|
+
parameter 'VOLUME ...', 'Volume name', attribute_name: :volumes
|
10
|
+
option "--force", :flag, "Force remove", default: false, attribute_name: :forced
|
11
|
+
|
12
|
+
requires_current_master
|
13
|
+
requires_current_master_token
|
14
|
+
|
15
|
+
def execute
|
16
|
+
volumes.each do |volume|
|
17
|
+
confirm_command(volume) unless forced?
|
18
|
+
|
19
|
+
spinner "Removing volume #{pastel.cyan(volume)} " do
|
20
|
+
remove_volume(volume)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def remove_volume(volume)
|
26
|
+
client.delete("volumes/#{current_grid}/#{volume}")
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
|
2
|
+
module Kontena::Cli::Volumes
|
3
|
+
class ShowCommand < Kontena::Command
|
4
|
+
include Kontena::Cli::Common
|
5
|
+
include Kontena::Cli::GridOptions
|
6
|
+
|
7
|
+
banner "Show details of a volume"
|
8
|
+
|
9
|
+
parameter 'VOLUME', 'Volume'
|
10
|
+
|
11
|
+
requires_current_master
|
12
|
+
requires_current_master_token
|
13
|
+
|
14
|
+
def execute
|
15
|
+
vol = client.get("volumes/#{current_grid}/#{volume}")
|
16
|
+
puts "#{vol['name']}:"
|
17
|
+
puts " id: #{vol['id']}"
|
18
|
+
puts " created: #{vol['created_at']}"
|
19
|
+
puts " scope: #{vol['scope']}"
|
20
|
+
puts " driver: #{vol['driver']}"
|
21
|
+
puts " driver_opts:"
|
22
|
+
vol['driver_opts'].each do |k,v|
|
23
|
+
puts " #{k}: #{v}"
|
24
|
+
end
|
25
|
+
puts " instances:"
|
26
|
+
vol['instances'].each do |instance|
|
27
|
+
puts " - name: #{instance['name']}"
|
28
|
+
puts " node: #{instance['node']}"
|
29
|
+
end
|
30
|
+
puts " services:"
|
31
|
+
vol['services'].each do |service|
|
32
|
+
puts " - #{service['id']}"
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Kontena::Cli::Vpn
|
2
|
+
class ConfigCommand < Kontena::Command
|
3
|
+
include Kontena::Cli::Common
|
4
|
+
include Kontena::Cli::GridOptions
|
5
|
+
|
6
|
+
def execute
|
7
|
+
require 'rbconfig'
|
8
|
+
require_api_url
|
9
|
+
payload = {cmd: ['/usr/local/bin/ovpn_getclient', 'KONTENA_VPN_CLIENT']}
|
10
|
+
service = client(require_token).get("services/#{current_grid}/vpn/server/containers")['containers'][0]
|
11
|
+
stdout, stderr = client(require_token).post("containers/#{service['id']}/exec", payload)
|
12
|
+
if linux?
|
13
|
+
stdout << "\n"
|
14
|
+
stdout << "script-security 2 system\n"
|
15
|
+
stdout << "up /etc/openvpn/update-resolv-conf\n"
|
16
|
+
stdout << "down /etc/openvpn/update-resolv-conf\n"
|
17
|
+
end
|
18
|
+
puts stdout
|
19
|
+
end
|
20
|
+
|
21
|
+
# @return [Boolean]
|
22
|
+
def linux?
|
23
|
+
host_os = RbConfig::CONFIG['host_os']
|
24
|
+
host_os.include?('linux')
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,99 @@
|
|
1
|
+
require_relative '../stacks/stacks_helper'
|
2
|
+
|
3
|
+
module Kontena::Cli::Vpn
|
4
|
+
class CreateCommand < Kontena::Command
|
5
|
+
include Kontena::Cli::Common
|
6
|
+
include Kontena::Cli::GridOptions
|
7
|
+
include Kontena::Cli::Stacks::StacksHelper
|
8
|
+
|
9
|
+
option '--node', 'NODE', 'Node name where VPN is deployed'
|
10
|
+
option '--ip', 'IP', 'Node ip-address to use in VPN service configuration'
|
11
|
+
|
12
|
+
def execute
|
13
|
+
require_api_url
|
14
|
+
token = require_token
|
15
|
+
preferred_node = node
|
16
|
+
|
17
|
+
name = 'vpn'
|
18
|
+
vpn = client(token).get("stacks/#{current_grid}/#{name}") rescue nil
|
19
|
+
exit_with_error('Vpn stack already exists') if vpn
|
20
|
+
|
21
|
+
node = find_node(token, preferred_node)
|
22
|
+
|
23
|
+
vpn_ip = node_vpn_ip(node)
|
24
|
+
data = {
|
25
|
+
name: name,
|
26
|
+
stack: 'kontena/vpn',
|
27
|
+
version: Kontena::Cli::VERSION,
|
28
|
+
registry: 'file://',
|
29
|
+
source: '---',
|
30
|
+
expose: 'server',
|
31
|
+
services: [
|
32
|
+
name: 'server',
|
33
|
+
stateful: true,
|
34
|
+
image: 'kontena/openvpn:ethwe',
|
35
|
+
ports: [
|
36
|
+
{
|
37
|
+
container_port: '1194',
|
38
|
+
node_port: '1194',
|
39
|
+
protocol: 'udp'
|
40
|
+
}
|
41
|
+
],
|
42
|
+
cap_add: ['NET_ADMIN'],
|
43
|
+
env: ["OVPN_SERVER_URL=udp://#{vpn_ip}:1194"],
|
44
|
+
affinity: ["node==#{node['name']}"]
|
45
|
+
]
|
46
|
+
}
|
47
|
+
|
48
|
+
client(token).post("grids/#{current_grid}/stacks", data)
|
49
|
+
deployment = client(token).post("stacks/#{current_grid}/#{name}/deploy", {})
|
50
|
+
spinner "Deploying #{pastel.cyan(name)} service " do
|
51
|
+
wait_for_deploy_to_finish(deployment)
|
52
|
+
end
|
53
|
+
spinner "Generating #{pastel.cyan(name)} keys (this will take a while) " do
|
54
|
+
wait_for_configuration_to_finish(token)
|
55
|
+
end
|
56
|
+
puts "#{pastel.cyan(name)} service is now started (udp://#{vpn_ip}:1194)."
|
57
|
+
puts "use 'kontena vpn config' to fetch OpenVPN client config to your machine."
|
58
|
+
end
|
59
|
+
|
60
|
+
def wait_for_configuration_to_finish(token)
|
61
|
+
finished = false
|
62
|
+
payload = {cmd: ['/usr/local/bin/ovpn_getclient', 'KONTENA_VPN_CLIENT']}
|
63
|
+
service = client(require_token).get("services/#{current_grid}/vpn/server/containers", payload)['containers'][0]
|
64
|
+
until finished
|
65
|
+
sleep 3
|
66
|
+
stdout, stderr = client(require_token).post("containers/#{service['id']}/exec", payload)
|
67
|
+
finished = true if stdout.join('').include?('BEGIN PRIVATE KEY'.freeze)
|
68
|
+
end
|
69
|
+
|
70
|
+
finished
|
71
|
+
end
|
72
|
+
|
73
|
+
def find_node(token, preferred_node = nil)
|
74
|
+
nodes = client(token).get("grids/#{current_grid}/nodes")
|
75
|
+
|
76
|
+
if preferred_node.nil?
|
77
|
+
node = nodes['nodes'].find{|n| n['connected'] && !n['public_ip'].to_s.empty?}
|
78
|
+
exit_with_error('Cannot find any online nodes with public ip. If you want to connect with private address, please use --node and/or --ip options.') if node.nil?
|
79
|
+
else
|
80
|
+
node = nodes['nodes'].find{|n| n['connected'] && n['name'] == preferred_node }
|
81
|
+
exit_with_error('Node not found') if node.nil?
|
82
|
+
end
|
83
|
+
node
|
84
|
+
end
|
85
|
+
|
86
|
+
# @param [Hash] node
|
87
|
+
# @return [String]
|
88
|
+
def node_vpn_ip(node)
|
89
|
+
return ip unless ip.nil?
|
90
|
+
|
91
|
+
# vagrant
|
92
|
+
if node['labels'] && node['labels'].include?('provider=vagrant')
|
93
|
+
node['private_ip'].to_s
|
94
|
+
else
|
95
|
+
node['public_ip'].to_s.empty? ? node['private_ip'].to_s : node['public_ip'].to_s
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module Kontena::Cli::Vpn
|
2
|
+
class RemoveCommand < Kontena::Command
|
3
|
+
include Kontena::Cli::Common
|
4
|
+
include Kontena::Cli::GridOptions
|
5
|
+
|
6
|
+
option "--force", :flag, "Force remove", default: false, attribute_name: :forced
|
7
|
+
|
8
|
+
def execute
|
9
|
+
require_api_url
|
10
|
+
token = require_token
|
11
|
+
confirm unless forced?
|
12
|
+
name = 'vpn'
|
13
|
+
|
14
|
+
vpn = client(token).get("stacks/#{current_grid}/#{name}") rescue nil
|
15
|
+
exit_with_error("VPN stack does not exist") if vpn.nil?
|
16
|
+
|
17
|
+
spinner "Removing #{pastel.cyan(name)} service " do
|
18
|
+
client(token).delete("stacks/#{current_grid}/#{name}")
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,9 @@
|
|
1
|
+
class Kontena::Cli::VpnCommand < Kontena::Command
|
2
|
+
|
3
|
+
subcommand "create", "Create VPN service", load_subcommand('vpn/create_command')
|
4
|
+
subcommand "config", "Show/Export VPN config", load_subcommand('vpn/config_command')
|
5
|
+
subcommand ["remove", "rm"], "Remove VPN service", load_subcommand('vpn/remove_command')
|
6
|
+
|
7
|
+
def execute
|
8
|
+
end
|
9
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
class Kontena::Cli::WhoamiCommand < Kontena::Command
|
2
|
+
include Kontena::Cli::Common
|
3
|
+
|
4
|
+
option '--bash-completion-path', :flag, 'Show bash completion path', hidden: true
|
5
|
+
option '--token', :flag, 'Show current master token', hidden: true
|
6
|
+
|
7
|
+
def execute
|
8
|
+
if bash_completion_path?
|
9
|
+
puts File.realpath(File.join(__dir__, '../scripts/init'))
|
10
|
+
exit 0
|
11
|
+
end
|
12
|
+
|
13
|
+
if self.token?
|
14
|
+
if config.current_master && config.current_master.token
|
15
|
+
puts config.current_master.token.access_token
|
16
|
+
exit 0
|
17
|
+
else
|
18
|
+
exit 1
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
require_api_url
|
23
|
+
puts "Master: #{ENV['KONTENA_URL'] || self.current_master['name']}"
|
24
|
+
puts "URL: #{ENV['KONTENA_URL'] || api_url}"
|
25
|
+
puts "Grid: #{ENV['KONTENA_GRID'] || current_grid}"
|
26
|
+
unless ENV['KONTENA_URL']
|
27
|
+
if current_master['username']
|
28
|
+
puts "User: #{current_master['username']}"
|
29
|
+
else # In case local storage doesn't have the user email yet
|
30
|
+
token = require_token
|
31
|
+
user = client.get('user')
|
32
|
+
puts "User: #{user['email']}"
|
33
|
+
current_master['username'] = user['email']
|
34
|
+
config.write
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|