kontena-cli 1.3.0.pre1 → 1.3.0.pre2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/VERSION +1 -1
- data/bin/kontena +2 -1
- data/lib/kontena/callback.rb +1 -1
- data/lib/kontena/callbacks/auth/01_list_and_select_grid_after_master_auth.rb +1 -2
- data/lib/kontena/callbacks/master/01_clear_current_master_after_terminate.rb +2 -3
- data/lib/kontena/callbacks/master/deploy/01_show_logo_before_deploy.rb +1 -2
- data/lib/kontena/callbacks/master/deploy/05_before_deploy_configuration_wizard.rb +2 -2
- data/lib/kontena/callbacks/master/deploy/40_install_ssl_certificate_after_deploy.rb +2 -2
- data/lib/kontena/callbacks/master/deploy/50_authenticate_after_deploy.rb +9 -9
- data/lib/kontena/callbacks/master/deploy/55_create_initial_grid_after_deploy.rb +2 -2
- data/lib/kontena/callbacks/master/deploy/56_set_server_provider_after_deploy.rb +1 -2
- data/lib/kontena/callbacks/master/deploy/60_configure_auth_provider_after_deploy.rb +1 -2
- data/lib/kontena/callbacks/master/deploy/70_invite_self_after_deploy.rb +2 -3
- data/lib/kontena/callbacks/master/deploy/90_proptip_after_deploy.rb +2 -2
- data/lib/kontena/cli/apps/common.rb +0 -1
- data/lib/kontena/cli/apps/init_command.rb +2 -0
- data/lib/kontena/cli/apps/kontena_yml_generator.rb +2 -1
- data/lib/kontena/cli/apps/list_command.rb +10 -2
- data/lib/kontena/cli/apps/yaml/reader.rb +2 -1
- data/lib/kontena/cli/apps/yaml/service_extender.rb +0 -1
- data/lib/kontena/cli/cloud/login_command.rb +51 -7
- data/lib/kontena/cli/cloud/master/list_command.rb +14 -11
- data/lib/kontena/cli/common.rb +36 -83
- data/lib/kontena/cli/config.rb +46 -29
- data/lib/kontena/cli/containers/list_command.rb +30 -41
- data/lib/kontena/cli/etcd/list_command.rb +12 -7
- data/lib/kontena/cli/external_registries/list_command.rb +14 -8
- data/lib/kontena/cli/grids/list_command.rb +18 -10
- data/lib/kontena/cli/grids/trusted_subnets/list_command.rb +7 -5
- data/lib/kontena/cli/grids/users/list_command.rb +9 -7
- data/lib/kontena/cli/localhost_web_server.rb +3 -3
- 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/master/config/import_command.rb +2 -1
- data/lib/kontena/cli/master/config/set_command.rb +1 -1
- data/lib/kontena/cli/master/list_command.rb +16 -10
- data/lib/kontena/cli/master/token/list_command.rb +23 -12
- data/lib/kontena/cli/master/user/invite_command.rb +1 -1
- data/lib/kontena/cli/master/user/list_command.rb +17 -6
- data/lib/kontena/cli/nodes/labels/list_command.rb +3 -0
- data/lib/kontena/cli/nodes/list_command.rb +58 -37
- data/lib/kontena/cli/nodes/show_command.rb +1 -1
- data/lib/kontena/cli/plugins/install_command.rb +2 -2
- data/lib/kontena/cli/plugins/list_command.rb +19 -5
- data/lib/kontena/cli/plugins/uninstall_command.rb +1 -1
- data/lib/kontena/cli/services/containers_command.rb +7 -0
- data/lib/kontena/cli/services/envs/list_command.rb +6 -4
- data/lib/kontena/cli/services/list_command.rb +47 -36
- data/lib/kontena/cli/services/services_helper.rb +9 -16
- data/lib/kontena/cli/services/stats_command.rb +2 -1
- data/lib/kontena/cli/spinner.rb +3 -5
- data/lib/kontena/cli/stacks/common.rb +4 -4
- data/lib/kontena/cli/stacks/list_command.rb +42 -33
- data/lib/kontena/cli/stacks/registry/search_command.rb +6 -0
- data/lib/kontena/cli/stacks/registry/show_command.rb +2 -0
- data/lib/kontena/cli/stacks/registry_command.rb +1 -2
- data/lib/kontena/cli/stacks/validate_command.rb +1 -0
- data/lib/kontena/cli/stacks/yaml/reader.rb +3 -2
- data/lib/kontena/cli/stacks/yaml/service_extender.rb +0 -1
- data/lib/kontena/cli/stacks/yaml/validations.rb +1 -1
- data/lib/kontena/cli/table_generator.rb +125 -0
- data/lib/kontena/cli/vault/export_command.rb +7 -4
- data/lib/kontena/cli/vault/import_command.rb +3 -0
- data/lib/kontena/cli/vault/list_command.rb +23 -10
- data/lib/kontena/cli/volumes/create_command.rb +8 -4
- data/lib/kontena/cli/volumes/list_command.rb +15 -7
- data/lib/kontena/client.rb +44 -33
- data/lib/kontena/command.rb +7 -4
- data/lib/kontena/debug_instrumentor.rb +10 -9
- data/lib/kontena/main_command.rb +1 -3
- data/lib/kontena/plugin_manager.rb +15 -7
- data/lib/kontena/stacks_cache.rb +7 -7
- data/lib/kontena/stacks_client.rb +24 -5
- data/lib/kontena/util.rb +43 -15
- data/lib/kontena_cli.rb +71 -14
- data/spec/kontena/cli/cloud/login_command_spec.rb +42 -0
- data/spec/kontena/cli/containers/list_command_spec.rb +1 -2
- data/spec/kontena/cli/nodes/list_command_spec.rb +153 -126
- data/spec/kontena/cli/registry/create_spec.rb +22 -0
- data/spec/kontena/cli/services/stats_command_spec.rb +22 -0
- data/spec/kontena/cli/table_generator_spec.rb +118 -0
- data/spec/kontena/cli/version_command_spec.rb +2 -2
- data/spec/kontena/client_spec.rb +4 -3
- data/spec/support/client_helpers.rb +3 -3
- data/spec/support/output_helpers.rb +54 -8
- metadata +11 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3cecf22e1d7197b410494d6fbbc265d052c2cb36
|
4
|
+
data.tar.gz: 84f981033ed64b0ba6a85344544d1981a723fd21
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3dabb9b18fe5a4f0c62bb31686311a6fa65c46cc953fb803a0a53f6dad0ea4a7f36e777c995a0b01957e114eb288517b9ecfd41f1648a2555956ed2751f45cc1
|
7
|
+
data.tar.gz: 8203264603f9bb1c79fefd5ce372a85481531eea3e70d44b0aaad9ac57a27a8f641bc13739cc3684bb9a0ca3a2e5cf974d46bf3c9bcb17bb57e39dd9d277f53d
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.3.0.
|
1
|
+
1.3.0.pre2
|
data/bin/kontena
CHANGED
@@ -12,7 +12,8 @@ if ARGV[0] == 'complete'
|
|
12
12
|
ARGV.delete_at(0)
|
13
13
|
require 'kontena/scripts/completer'
|
14
14
|
else
|
15
|
+
ENV['DEBUG'] ||= "true" if ARGV.any? { |arg| arg == '-D' || arg == '--debug'}
|
15
16
|
require 'kontena_cli'
|
16
|
-
Kontena::PluginManager.instance.init
|
17
|
+
Kontena::PluginManager.instance.init unless ENV['NO_PLUGINS']
|
17
18
|
Kontena::MainCommand.run
|
18
19
|
end
|
data/lib/kontena/callback.rb
CHANGED
@@ -44,7 +44,7 @@ class Kontena::Callback
|
|
44
44
|
if klass.instance_methods.include?(state)
|
45
45
|
cb = klass.new(obj)
|
46
46
|
if cb.send(state).kind_of?(FalseClass)
|
47
|
-
|
47
|
+
Kontena.logger.debug { "Execution aborted by #{klass}" }
|
48
48
|
exit 1
|
49
49
|
end
|
50
50
|
end
|
@@ -2,8 +2,6 @@ module Kontena
|
|
2
2
|
module Callbacks
|
3
3
|
class ListAndSelectGrid < Kontena::Callback
|
4
4
|
|
5
|
-
include Kontena::Cli::Common
|
6
|
-
|
7
5
|
matches_commands 'master login'
|
8
6
|
|
9
7
|
def after_load
|
@@ -15,6 +13,7 @@ module Kontena
|
|
15
13
|
# Runs kontena grids list --use which will auto join the first available
|
16
14
|
# grid
|
17
15
|
def after
|
16
|
+
extend Kontena::Cli::Common
|
18
17
|
return if command.skip_grid_auto_select?
|
19
18
|
return unless current_master
|
20
19
|
return unless command.exit_code == 0
|
@@ -2,15 +2,14 @@ module Kontena
|
|
2
2
|
module Callbacks
|
3
3
|
class ClearCurrentMasterAfterTerminate < Kontena::Callback
|
4
4
|
|
5
|
-
include Kontena::Cli::Common
|
6
|
-
|
7
5
|
matches_commands 'master terminate'
|
8
6
|
|
9
7
|
def after
|
8
|
+
extend Kontena::Cli::Common
|
10
9
|
return unless command.exit_code == 0
|
11
10
|
return unless config.current_master
|
12
11
|
|
13
|
-
|
12
|
+
logger.debug { "Removing current master from config" }
|
14
13
|
config.servers.delete_at(config.find_server_index(config.current_master.name))
|
15
14
|
config.current_server = nil
|
16
15
|
config.write
|
@@ -2,11 +2,11 @@ module Kontena
|
|
2
2
|
module Callbacks
|
3
3
|
class BeforeDeployConfigurationWizard < Kontena::Callback
|
4
4
|
|
5
|
-
include Kontena::Cli::Common
|
6
|
-
|
7
5
|
matches_commands 'master create'
|
8
6
|
|
9
7
|
def after_load
|
8
|
+
extend Kontena::Cli::Common
|
9
|
+
|
10
10
|
command.class_eval do
|
11
11
|
option ['--no-prompt'], :flag, "Don't ask questions"
|
12
12
|
option ['--skip-auth-provider'], :flag, "Skip auth provider configuration (single user mode)"
|
@@ -2,11 +2,11 @@ module Kontena
|
|
2
2
|
module Callbacks
|
3
3
|
class InstallSslCertificateAfterDeploy < Kontena::Callback
|
4
4
|
|
5
|
-
include Kontena::Cli::Common
|
6
|
-
|
7
5
|
matches_commands 'master create'
|
8
6
|
|
9
7
|
def after
|
8
|
+
extend Kontena::Cli::Common
|
9
|
+
|
10
10
|
return unless command.exit_code == 0
|
11
11
|
return unless command.result.kind_of?(Hash)
|
12
12
|
return unless command.result.has_key?(:ssl_certificate)
|
@@ -1,16 +1,16 @@
|
|
1
|
-
require 'securerandom'
|
2
|
-
|
3
1
|
module Kontena
|
4
2
|
module Callbacks
|
5
3
|
class AuthenticateAfterDeploy < Kontena::Callback
|
6
4
|
|
7
|
-
include Kontena::Cli::Common
|
8
|
-
|
9
5
|
matches_commands 'master create'
|
10
6
|
|
11
7
|
def after
|
12
|
-
|
13
|
-
|
8
|
+
extend Kontena::Cli::Common
|
9
|
+
|
10
|
+
require 'securerandom'
|
11
|
+
extend Kontena::Cli::Common
|
12
|
+
logger.debug { "Command result: #{command.result.inspect}" }
|
13
|
+
logger.debug { "Command exit code: #{command.exit_code.inspect}" }
|
14
14
|
return unless command.exit_code == 0
|
15
15
|
return unless command.result.kind_of?(Hash)
|
16
16
|
return unless command.result.has_key?(:public_ip)
|
@@ -36,11 +36,11 @@ module Kontena
|
|
36
36
|
|
37
37
|
# Figure out if HTTPS works, if not, try HTTP
|
38
38
|
begin
|
39
|
-
|
39
|
+
logger.debug { "Trying to request / from #{new_master.url}" }
|
40
40
|
client = Kontena::Client.new(new_master.url, nil, ignore_ssl_errors: true)
|
41
41
|
client.get('/')
|
42
42
|
rescue => ex
|
43
|
-
|
43
|
+
logger.debug { "HTTPS test failed: #{ex.class.name} #{ex.message}" }
|
44
44
|
unless retried
|
45
45
|
new_master.url = "http://#{command.result[:public_ip]}"
|
46
46
|
retried = true
|
@@ -57,7 +57,7 @@ module Kontena
|
|
57
57
|
new_master.url
|
58
58
|
]
|
59
59
|
Retriable.retriable do
|
60
|
-
|
60
|
+
logger.debug { "Running: #{cmd}" }
|
61
61
|
Kontena.run!(cmd)
|
62
62
|
end
|
63
63
|
end
|
@@ -2,11 +2,11 @@ module Kontena
|
|
2
2
|
module Callbacks
|
3
3
|
class CreateInitialGridAfterDeploy < Kontena::Callback
|
4
4
|
|
5
|
-
include Kontena::Cli::Common
|
6
|
-
|
7
5
|
matches_commands 'master create'
|
8
6
|
|
9
7
|
def after
|
8
|
+
extend Kontena::Cli::Common
|
9
|
+
|
10
10
|
return unless command.exit_code == 0
|
11
11
|
return unless config.current_master
|
12
12
|
return unless config.current_master.name == command.result[:name]
|
@@ -2,11 +2,10 @@ module Kontena
|
|
2
2
|
module Callbacks
|
3
3
|
class SetServerProviderAfterDeploy < Kontena::Callback
|
4
4
|
|
5
|
-
include Kontena::Cli::Common
|
6
|
-
|
7
5
|
matches_commands 'master create'
|
8
6
|
|
9
7
|
def after
|
8
|
+
extend Kontena::Cli::Common
|
10
9
|
return unless command.exit_code == 0
|
11
10
|
return unless config.current_master
|
12
11
|
return unless config.current_master.name == command.result[:name]
|
@@ -2,8 +2,6 @@ module Kontena
|
|
2
2
|
module Callbacks
|
3
3
|
class ConfigureAuthProviderAfterDeploy < Kontena::Callback
|
4
4
|
|
5
|
-
include Kontena::Cli::Common
|
6
|
-
|
7
5
|
matches_commands 'master create'
|
8
6
|
|
9
7
|
def init_cloud_args
|
@@ -16,6 +14,7 @@ module Kontena
|
|
16
14
|
end
|
17
15
|
|
18
16
|
def after
|
17
|
+
extend Kontena::Cli::Common
|
19
18
|
return unless command.exit_code == 0
|
20
19
|
return unless command.result.kind_of?(Hash)
|
21
20
|
return unless command.result.has_key?(:name)
|
@@ -2,8 +2,6 @@ module Kontena
|
|
2
2
|
module Callbacks
|
3
3
|
class InviteSelfAfterDeploy < Kontena::Callback
|
4
4
|
|
5
|
-
include Kontena::Cli::Common
|
6
|
-
|
7
5
|
matches_commands 'master create', 'master init_cloud'
|
8
6
|
|
9
7
|
def cloud_user_data
|
@@ -25,6 +23,7 @@ module Kontena
|
|
25
23
|
end
|
26
24
|
|
27
25
|
def after
|
26
|
+
extend Kontena::Cli::Common
|
28
27
|
return unless current_master
|
29
28
|
return unless command.exit_code == 0
|
30
29
|
return nil if command.respond_to?(:skip_auth_provider?) && command.skip_auth_provider?
|
@@ -37,7 +36,7 @@ module Kontena
|
|
37
36
|
end
|
38
37
|
|
39
38
|
return nil unless invite_response
|
40
|
-
|
39
|
+
logger.debug { "Got invite code: #{invite_response['invite_code']}" }
|
41
40
|
|
42
41
|
success = spinner "Adding master_admin role for #{cloud_user_data[:email]}" do |spin|
|
43
42
|
spin.fail! unless Kontena.run(["master", "user", "role", "add", "--silent", "master_admin", cloud_user_data[:email]])
|
@@ -2,11 +2,11 @@ module Kontena
|
|
2
2
|
module Callbacks
|
3
3
|
class SuggestInvitingYourself < Kontena::Callback
|
4
4
|
|
5
|
-
include Kontena::Cli::Common
|
6
|
-
|
7
5
|
matches_commands 'master create'
|
8
6
|
|
9
7
|
def after
|
8
|
+
extend Kontena::Cli::Common
|
9
|
+
|
10
10
|
return unless current_master
|
11
11
|
return unless command.exit_code == 0
|
12
12
|
return if current_master.username.to_s == 'admin'
|
@@ -9,7 +9,9 @@ module Kontena::Cli::Apps
|
|
9
9
|
option ['-f', '--file'], 'FILE', 'Specify an alternate Kontena compose file', attribute_name: :filename, default: 'kontena.yml'
|
10
10
|
option ['-p', '--project-name'], 'NAME', 'Specify an alternate project name (default: directory name)'
|
11
11
|
|
12
|
-
|
12
|
+
option ['-q', '--quiet'], :flag, "Output the identifying column only"
|
13
|
+
|
14
|
+
parameter "[SERVICE] ...", "Services to list"
|
13
15
|
|
14
16
|
attr_reader :services
|
15
17
|
|
@@ -17,6 +19,12 @@ module Kontena::Cli::Apps
|
|
17
19
|
require_config_file(filename)
|
18
20
|
|
19
21
|
@services = services_from_yaml(filename, service_list, service_prefix, true)
|
22
|
+
|
23
|
+
if quiet?
|
24
|
+
puts services.map(&:first).join("\n")
|
25
|
+
exit 0
|
26
|
+
end
|
27
|
+
|
20
28
|
if services.size > 0
|
21
29
|
show_services(services)
|
22
30
|
elsif !service_list.empty?
|
@@ -32,7 +40,7 @@ module Kontena::Cli::Apps
|
|
32
40
|
services.each do |service_name, opts|
|
33
41
|
service = get_service(token, prefixed_name(service_name)) rescue false
|
34
42
|
if service
|
35
|
-
name = service['name'].sub("#{
|
43
|
+
name = service['name'].sub("#{service_prefix}-", '')
|
36
44
|
state = service['stateful'] ? 'yes' : 'no'
|
37
45
|
ports = service['ports'].map{|p|
|
38
46
|
"#{p['ip']}:#{p['node_port']}->#{p['container_port']}/#{p['protocol']}"
|
@@ -4,10 +4,11 @@ module Kontena::Cli::Cloud
|
|
4
4
|
class LoginCommand < Kontena::Command
|
5
5
|
include Kontena::Cli::Common
|
6
6
|
|
7
|
-
option ['-t', '--token'], '[TOKEN]', 'Use a pre-generated access token', environment_variable: '
|
7
|
+
option ['-t', '--token'], '[TOKEN]', 'Use a pre-generated access token', environment_variable: 'KONTENA_CLOUD_TOKEN'
|
8
8
|
option ['-c', '--code'], '[CODE]', 'Use an authorization code'
|
9
9
|
option ['-v', '--verbose'], :flag, 'Increase output verbosity'
|
10
10
|
option ['-f', '--force'], :flag, 'Force reauthentication'
|
11
|
+
option ['-r', '--remote'], :flag, 'Remote login'
|
11
12
|
|
12
13
|
def execute
|
13
14
|
if self.code && self.force?
|
@@ -35,8 +36,11 @@ module Kontena::Cli::Cloud
|
|
35
36
|
finish and return
|
36
37
|
end
|
37
38
|
end
|
38
|
-
|
39
|
-
|
39
|
+
if remote?
|
40
|
+
remote_login
|
41
|
+
else
|
42
|
+
web_flow
|
43
|
+
end
|
40
44
|
finish
|
41
45
|
end
|
42
46
|
|
@@ -51,13 +55,53 @@ module Kontena::Cli::Cloud
|
|
51
55
|
true
|
52
56
|
end
|
53
57
|
|
58
|
+
def remote_login
|
59
|
+
client_id = kontena_account.client_id || Kontena::Client::CLIENT_ID
|
60
|
+
params = {
|
61
|
+
client_id: client_id
|
62
|
+
}
|
63
|
+
cloud_url = kontena_account.url
|
64
|
+
client = Kontena::Client.new(cloud_url, nil)
|
65
|
+
auth_request_response = client.post('/auth_requests', params, {}, { 'Content-Type' => 'application/x-www-form-urlencoded' }) rescue nil
|
66
|
+
if !auth_request_response.kind_of?(Hash)
|
67
|
+
exit_with_error "Remote login request failed"
|
68
|
+
elsif auth_request_response['error']
|
69
|
+
exit_with_error "Remote login request failed: #{auth_request_response['error']}"
|
70
|
+
end
|
71
|
+
begin
|
72
|
+
verification_uri = URI.parse(auth_request_response['verification_uri'])
|
73
|
+
rescue => e
|
74
|
+
exit_with_error "Parsing remote login URL failed."
|
75
|
+
end
|
76
|
+
|
77
|
+
puts "Please visit #{verification_uri.to_s.colorize(:cyan)} and enter the code"
|
78
|
+
puts
|
79
|
+
puts "#{auth_request_response['user_code']}"
|
80
|
+
puts
|
81
|
+
puts "Once the authentication is complete you can close the browser"
|
82
|
+
puts "window or tab and return to this window to continue."
|
83
|
+
puts
|
84
|
+
|
85
|
+
code_request_params = {
|
86
|
+
client_id: client_id,
|
87
|
+
device_code: auth_request_response['device_code']
|
88
|
+
}
|
89
|
+
code_response = nil
|
90
|
+
spinner "Waiting for authentication" do
|
91
|
+
until code_response do
|
92
|
+
code_response = client.post("/auth_requests/code", code_request_params, {}, { 'Content-Type' => 'application/x-www-form-urlencoded' }) rescue nil
|
93
|
+
sleep 1
|
94
|
+
end
|
95
|
+
end
|
96
|
+
update_token(code_response)
|
97
|
+
end
|
98
|
+
|
54
99
|
def web_flow
|
55
100
|
if Kontena.browserless? && !force?
|
56
|
-
$stderr.puts "Your current environment does not seem to support opening a local graphical WWW browser."
|
101
|
+
$stderr.puts "Your current environment does not seem to support opening a local graphical WWW browser. Using remote login instead."
|
57
102
|
$stderr.puts
|
58
|
-
|
59
|
-
|
60
|
-
exit_with_error 'Unable to launch a web browser'
|
103
|
+
remote_login
|
104
|
+
return
|
61
105
|
end
|
62
106
|
|
63
107
|
require_relative '../localhost_web_server'
|
@@ -2,6 +2,7 @@ module Kontena::Cli::Cloud::Master
|
|
2
2
|
class ListCommand < Kontena::Command
|
3
3
|
|
4
4
|
include Kontena::Cli::Common
|
5
|
+
include Kontena::Cli::TableGenerator::Helper
|
5
6
|
|
6
7
|
callback_matcher 'cloud-master', 'list'
|
7
8
|
|
@@ -9,22 +10,24 @@ module Kontena::Cli::Cloud::Master
|
|
9
10
|
|
10
11
|
requires_current_account_token
|
11
12
|
|
13
|
+
def fields
|
14
|
+
quiet? ? ['id'] : %w(id name owner url connected)
|
15
|
+
end
|
16
|
+
|
12
17
|
def execute
|
13
|
-
response =
|
18
|
+
response = spin_if(!quiet?, "Retrieving Master list from Kontena Cloud") do
|
19
|
+
cloud_client.get('user/masters')
|
20
|
+
end
|
21
|
+
|
14
22
|
unless response && response.kind_of?(Hash) && response['data'].kind_of?(Array)
|
15
23
|
abort "Listing masters failed".colorize(:red)
|
16
24
|
end
|
17
25
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
puts '%-26.26s %-24s %-12s %s' % ['ID', 'NAME', 'OWNER', 'URL']
|
24
|
-
response['data'].each do |data|
|
25
|
-
attr = data['attributes']
|
26
|
-
puts '%-26.26s %-24s %-12s %s' % [data['id'], attr['name'], attr['owner'], attr['url']]
|
27
|
-
end
|
26
|
+
return Array(response['data']) if self.return?
|
27
|
+
|
28
|
+
print_table(response['data']) do |row|
|
29
|
+
row.merge!(row['attributes'])
|
30
|
+
row['connected'] = !!row['connected'] ? pastel.green('yes') : pastel.red('no')
|
28
31
|
end
|
29
32
|
end
|
30
33
|
end
|