morpheus-cli 4.2.8 → 4.2.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Dockerfile +1 -1
- data/lib/morpheus/api.rb +1 -1
- data/lib/morpheus/api/activity_interface.rb +9 -0
- data/lib/morpheus/api/api_client.rb +83 -27
- data/lib/morpheus/api/apps_interface.rb +21 -0
- data/lib/morpheus/api/dashboard_interface.rb +5 -21
- data/lib/morpheus/api/instances_interface.rb +3 -10
- data/lib/morpheus/api/invoice_line_items_interface.rb +14 -0
- data/lib/morpheus/api/invoices_interface.rb +7 -12
- data/lib/morpheus/api/library_layouts_interface.rb +8 -0
- data/lib/morpheus/api/ping_interface.rb +20 -0
- data/lib/morpheus/api/projects_interface.rb +33 -0
- data/lib/morpheus/api/setup_interface.rb +19 -36
- data/lib/morpheus/api/user_settings_interface.rb +0 -6
- data/lib/morpheus/api/whoami_interface.rb +4 -8
- data/lib/morpheus/benchmarking.rb +16 -26
- data/lib/morpheus/cli.rb +10 -5
- data/lib/morpheus/cli/access_token_command.rb +5 -8
- data/lib/morpheus/cli/activity_command.rb +146 -0
- data/lib/morpheus/cli/apps.rb +312 -121
- data/lib/morpheus/cli/archives_command.rb +1 -1
- data/lib/morpheus/cli/auth_command.rb +4 -11
- data/lib/morpheus/cli/blueprints_command.rb +196 -137
- data/lib/morpheus/cli/change_password_command.rb +1 -1
- data/lib/morpheus/cli/cli_command.rb +225 -72
- data/lib/morpheus/cli/cli_registry.rb +2 -2
- data/lib/morpheus/cli/cloud_datastores_command.rb +1 -1
- data/lib/morpheus/cli/clouds.rb +5 -20
- data/lib/morpheus/cli/clusters.rb +4 -28
- data/lib/morpheus/cli/commands/standard/alias_command.rb +2 -9
- data/lib/morpheus/cli/commands/standard/benchmark_command.rb +2 -0
- data/lib/morpheus/cli/commands/standard/curl_command.rb +2 -3
- data/lib/morpheus/cli/commands/standard/history_command.rb +3 -6
- data/lib/morpheus/cli/commands/standard/man_command.rb +10 -7
- data/lib/morpheus/cli/commands/standard/ssl_verification_command.rb +10 -9
- data/lib/morpheus/cli/containers_command.rb +3 -3
- data/lib/morpheus/cli/credentials.rb +13 -16
- data/lib/morpheus/cli/error_handler.rb +18 -12
- data/lib/morpheus/cli/errors.rb +45 -0
- data/lib/morpheus/cli/execute_schedules_command.rb +1 -1
- data/lib/morpheus/cli/execution_request_command.rb +4 -4
- data/lib/morpheus/cli/groups.rb +84 -132
- data/lib/morpheus/cli/hosts.rb +6 -16
- data/lib/morpheus/cli/instances.rb +100 -183
- data/lib/morpheus/cli/invoices_command.rb +505 -71
- data/lib/morpheus/cli/library_layouts_command.rb +254 -166
- data/lib/morpheus/cli/library_option_lists_command.rb +0 -87
- data/lib/morpheus/cli/library_option_types_command.rb +0 -96
- data/lib/morpheus/cli/license.rb +3 -0
- data/lib/morpheus/cli/login.rb +17 -37
- data/lib/morpheus/cli/logout.rb +9 -5
- data/lib/morpheus/cli/mixins/accounts_helper.rb +83 -7
- data/lib/morpheus/cli/mixins/operations_helper.rb +41 -0
- data/lib/morpheus/cli/mixins/option_source_helper.rb +255 -0
- data/lib/morpheus/cli/mixins/print_helper.rb +18 -4
- data/lib/morpheus/cli/mixins/provisioning_helper.rb +222 -13
- data/lib/morpheus/cli/mixins/remote_helper.rb +139 -0
- data/lib/morpheus/cli/monitoring_checks_command.rb +11 -3
- data/lib/morpheus/cli/network_groups_command.rb +8 -2
- data/lib/morpheus/cli/option_types.rb +1 -1
- data/lib/morpheus/cli/ping.rb +252 -0
- data/lib/morpheus/cli/price_sets_command.rb +16 -27
- data/lib/morpheus/cli/prices_command.rb +34 -27
- data/lib/morpheus/cli/processes_command.rb +81 -7
- data/lib/morpheus/cli/projects_command.rb +607 -0
- data/lib/morpheus/cli/recent_activity_command.rb +87 -65
- data/lib/morpheus/cli/remote.rb +965 -974
- data/lib/morpheus/cli/reports_command.rb +3 -15
- data/lib/morpheus/cli/roles.rb +8 -31
- data/lib/morpheus/cli/service_plans_command.rb +25 -31
- data/lib/morpheus/cli/setup.rb +392 -0
- data/lib/morpheus/cli/shell.rb +144 -56
- data/lib/morpheus/cli/subnets_command.rb +71 -11
- data/lib/morpheus/cli/tasks.rb +3 -3
- data/lib/morpheus/cli/user_sources_command.rb +4 -4
- data/lib/morpheus/cli/users.rb +135 -109
- data/lib/morpheus/cli/version.rb +1 -1
- data/lib/morpheus/cli/whitelabel_settings_command.rb +7 -7
- data/lib/morpheus/cli/whoami.rb +90 -129
- data/lib/morpheus/cli/wiki_command.rb +2 -14
- data/lib/morpheus/ext/rest_client.rb +36 -0
- data/lib/morpheus/formatters.rb +42 -5
- data/lib/morpheus/rest_client.rb +0 -10
- data/lib/morpheus/terminal.rb +41 -1
- data/lib/morpheus/util.rb +24 -0
- metadata +16 -3
- data/lib/morpheus/cli/command_error.rb +0 -22
data/lib/morpheus/cli/whoami.rb
CHANGED
|
@@ -17,26 +17,17 @@ class Morpheus::Cli::Whoami
|
|
|
17
17
|
|
|
18
18
|
# no subcommands, just show()
|
|
19
19
|
|
|
20
|
-
def
|
|
21
|
-
# @
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
def connect(opts)
|
|
25
|
-
#@api_client = establish_remote_appliance_connection(opts)
|
|
26
|
-
# begin
|
|
27
|
-
@api_client = establish_remote_appliance_connection(opts.merge({:no_prompt => true, :skip_verify_access_token => true}))
|
|
28
|
-
@groups_interface = @api_client.groups
|
|
29
|
-
@active_group_id = Morpheus::Cli::Groups.active_groups[@appliance_name]
|
|
30
|
-
# rescue Morpheus::Cli::CommandError => err
|
|
31
|
-
# puts_error err
|
|
32
|
-
# end
|
|
20
|
+
def connect(options)
|
|
21
|
+
# @api_client = establish_remote_appliance_connection(options)
|
|
22
|
+
@api_client = establish_remote_appliance_connection(options.merge({:skip_verify_access_token => true, :skip_login => true}))
|
|
23
|
+
@whoami_interface = @api_client.whoami
|
|
33
24
|
end
|
|
34
25
|
|
|
35
26
|
def handle(args)
|
|
36
|
-
|
|
27
|
+
get(args)
|
|
37
28
|
end
|
|
38
29
|
|
|
39
|
-
def
|
|
30
|
+
def get(args)
|
|
40
31
|
options = {}
|
|
41
32
|
params = {}
|
|
42
33
|
username_only = false
|
|
@@ -46,12 +37,22 @@ class Morpheus::Cli::Whoami
|
|
|
46
37
|
opts.on( '-n', '--name', "Print only your username." ) do
|
|
47
38
|
username_only = true
|
|
48
39
|
end
|
|
49
|
-
opts.on('-a','--all', "Display All Details
|
|
40
|
+
opts.on('-a','--all', "Display All Details") do
|
|
50
41
|
options[:include_feature_access] = true
|
|
42
|
+
options[:include_group_access] = true
|
|
43
|
+
options[:include_cloud_access] = true
|
|
44
|
+
options[:include_instance_type_access] = true
|
|
51
45
|
end
|
|
52
|
-
opts.on('-
|
|
46
|
+
opts.on('-p','--permissions', "Display Permissions") do
|
|
53
47
|
options[:include_feature_access] = true
|
|
48
|
+
# options[:include_group_access] = true
|
|
49
|
+
# options[:include_cloud_access] = true
|
|
50
|
+
# options[:include_instance_type_access] = true
|
|
54
51
|
end
|
|
52
|
+
# opts.on('-f','--feature-access', "Display Feature Access") do
|
|
53
|
+
# options[:include_feature_access] = true
|
|
54
|
+
# end
|
|
55
|
+
# opts.add_hidden_option('--feature-access')
|
|
55
56
|
# these are things that morpheus users get has to display...
|
|
56
57
|
# opts.on(nil,'--group-access', "Display Group Access") do
|
|
57
58
|
# options[:include_group_access] = true
|
|
@@ -62,63 +63,60 @@ class Morpheus::Cli::Whoami
|
|
|
62
63
|
# opts.on(nil,'--instance-type-access', "Display Instance Type Access") do
|
|
63
64
|
# options[:include_instance_type_access] = true
|
|
64
65
|
# end
|
|
65
|
-
opts.on('-a','--all-access', "Display All Access Lists") do
|
|
66
|
-
options[:include_feature_access] = true
|
|
67
|
-
options[:include_group_access] = true
|
|
68
|
-
options[:include_cloud_access] = true
|
|
69
|
-
options[:include_instance_type_access] = true
|
|
70
|
-
end
|
|
71
66
|
opts.on('-t','--token-only', "Print your access token only") do
|
|
72
67
|
access_token_only = true
|
|
73
68
|
end
|
|
74
|
-
|
|
69
|
+
opts.on('--offline', '--offline', "Do this offline without an api request to refresh the remote appliance status.") do
|
|
70
|
+
options[:do_offline] = true
|
|
71
|
+
end
|
|
72
|
+
build_standard_get_options(opts, options)
|
|
73
|
+
opts.footer = <<-EOT
|
|
74
|
+
View information about the current user.
|
|
75
|
+
EOT
|
|
75
76
|
end
|
|
76
77
|
optparse.parse!(args)
|
|
78
|
+
verify_args!(args:args, optparse:optparse, count:0)
|
|
77
79
|
connect(options)
|
|
78
80
|
begin
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
# never gets here..
|
|
83
|
-
#raise_command_error "Please specify a Morpheus Appliance with -r or see the command `remote use`"
|
|
84
|
-
print yellow,"Please specify a Morpheus Appliance with -r or see `remote use`.#{reset}\n"
|
|
85
|
-
return 1
|
|
81
|
+
if @access_token.nil?
|
|
82
|
+
print_error yellow,"You are not currently logged in",reset,"\n"
|
|
83
|
+
return 1, "no current user"
|
|
86
84
|
end
|
|
87
|
-
|
|
85
|
+
@whoami_interface.setopts(options)
|
|
88
86
|
if options[:dry_run]
|
|
89
|
-
print_dry_run @
|
|
87
|
+
print_dry_run @whoami_interface.dry.get(params)
|
|
90
88
|
return 0
|
|
91
89
|
end
|
|
92
90
|
|
|
93
|
-
# todo: fix potential issue here, should be able to use --remote-url or --username
|
|
94
|
-
# in which case you do not have to be logged in (saved credentials)...
|
|
95
|
-
# maybe just update connect() to do @api_client = establish_remote_appliance_connection(opts)
|
|
96
|
-
# wallet = Morpheus::Cli::Credentials.new(@appliance_name, @appliance_url).request_credentials(options)
|
|
97
|
-
wallet = Morpheus::Cli::Credentials.new(@appliance_name, @appliance_url).load_saved_credentials()
|
|
98
|
-
token = wallet ? wallet['access_token'] : nil
|
|
99
|
-
if !token
|
|
100
|
-
if options[:quiet]
|
|
101
|
-
return 1
|
|
102
|
-
elsif access_token_only
|
|
103
|
-
puts_error "(logged out)" # stderr probably
|
|
104
|
-
return 1
|
|
105
|
-
else
|
|
106
|
-
print yellow,"You are not currently logged in to #{display_appliance(@appliance_name, @appliance_url)}",reset,"\n"
|
|
107
|
-
print yellow,"Use the 'login' command.",reset,"\n"
|
|
108
|
-
return 1
|
|
109
|
-
end
|
|
110
|
-
end
|
|
111
|
-
|
|
112
91
|
#json_response = load_whoami()
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
92
|
+
whoami_response = nil
|
|
93
|
+
if options[:do_offline]
|
|
94
|
+
# if @remote_appliance && @remote_appliance[:username]
|
|
95
|
+
# exit_code = 0
|
|
96
|
+
# else
|
|
97
|
+
# exit_code = 1
|
|
98
|
+
# end
|
|
99
|
+
# no permissions, or even name stored atm, we should start storing that.
|
|
100
|
+
# then we can start checking permissions nd restricting command visibility.
|
|
101
|
+
whoami_response = {
|
|
102
|
+
"user": {
|
|
103
|
+
"username" => @remote_appliance ? @remote_appliance[:username] : nil
|
|
104
|
+
},
|
|
105
|
+
# "isMasterAccount" => true,
|
|
106
|
+
"permissions" => [],
|
|
107
|
+
"appliance" => {
|
|
108
|
+
"buildVersion" => @remote_appliance ? @remote_appliance[:build_version] : nil
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
else
|
|
112
|
+
whoami_response = @whoami_interface.get(params)
|
|
113
|
+
end
|
|
116
114
|
json_response = whoami_response
|
|
117
115
|
@current_user = whoami_response["user"]
|
|
118
|
-
if @current_user.
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
end
|
|
116
|
+
# if @current_user.nil?
|
|
117
|
+
# print_red_alert "Unauthenticated. Please login."
|
|
118
|
+
# exit 1
|
|
119
|
+
# end
|
|
122
120
|
@is_master_account = whoami_response["isMasterAccount"]
|
|
123
121
|
@user_permissions = whoami_response["permissions"]
|
|
124
122
|
|
|
@@ -128,62 +126,52 @@ class Morpheus::Cli::Whoami
|
|
|
128
126
|
@appliance_build_verison = nil
|
|
129
127
|
end
|
|
130
128
|
|
|
131
|
-
|
|
132
|
-
if options[:quiet]
|
|
133
|
-
return @current_user ? 0 : 1
|
|
134
|
-
end
|
|
135
|
-
if @access_token.nil?
|
|
136
|
-
print yellow,"\n","No access token. Please login",reset,"\n"
|
|
137
|
-
return false
|
|
138
|
-
end
|
|
139
|
-
print cyan,@access_token.to_s,reset,"\n"
|
|
140
|
-
return 0
|
|
141
|
-
end
|
|
129
|
+
render_response(json_response, options) do
|
|
142
130
|
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
print cyan,@
|
|
131
|
+
if access_token_only
|
|
132
|
+
if options[:quiet]
|
|
133
|
+
return @current_user ? 0 : 1
|
|
134
|
+
end
|
|
135
|
+
if @access_token.nil?
|
|
136
|
+
print yellow,"\n","No access token. Please login",reset,"\n"
|
|
137
|
+
return false
|
|
138
|
+
end
|
|
139
|
+
print cyan,@access_token.to_s,reset,"\n"
|
|
152
140
|
return 0
|
|
153
141
|
end
|
|
154
|
-
end
|
|
155
142
|
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
143
|
+
if username_only
|
|
144
|
+
if options[:quiet]
|
|
145
|
+
return @current_user ? 0 : 1
|
|
146
|
+
end
|
|
147
|
+
if @current_user.nil?
|
|
148
|
+
puts_error "(logged out)" # "(anonymous)" || ""
|
|
149
|
+
return 1
|
|
150
|
+
else
|
|
151
|
+
print cyan,@current_user['username'].to_s,reset,"\n"
|
|
152
|
+
return 0
|
|
153
|
+
end
|
|
163
154
|
end
|
|
164
|
-
end
|
|
165
155
|
|
|
166
|
-
if options[:json]
|
|
167
|
-
print JSON.pretty_generate(json_response)
|
|
168
|
-
print "\n"
|
|
169
|
-
else
|
|
170
156
|
if @current_user.nil?
|
|
171
157
|
print yellow,"\n","No active session. Please login",reset,"\n"
|
|
172
158
|
exit 1
|
|
173
159
|
end
|
|
174
|
-
|
|
175
|
-
|
|
160
|
+
subtitles = []
|
|
161
|
+
#subtitles << "#{display_appliance(@appliance_name, @appliance_url)}"
|
|
162
|
+
print_h1 "Current User", subtitles, options
|
|
176
163
|
print cyan
|
|
177
164
|
print_description_list({
|
|
178
165
|
"ID" => 'id',
|
|
179
|
-
"
|
|
180
|
-
|
|
181
|
-
|
|
166
|
+
"Tenant" => lambda {|it| (it['account'] ? it['account']['name'] : '') + (@is_master_account ? " (Master Account)" : '') },
|
|
167
|
+
"First Name" => 'firstName',
|
|
168
|
+
"Last Name" => 'lastName',
|
|
182
169
|
# "Name" => 'displayName',
|
|
183
|
-
"Name" => lambda {|it| it['firstName'] ? it['displayName'] : '' },
|
|
170
|
+
#"Name" => lambda {|it| it['firstName'] ? it['displayName'] : '' },
|
|
184
171
|
"Username" => 'username',
|
|
185
172
|
"Email" => 'email',
|
|
186
|
-
"Role" => lambda {|it| format_user_role_names(it) }
|
|
173
|
+
"Role" => lambda {|it| format_user_role_names(it) },
|
|
174
|
+
#"Remote" => lambda {|it| display_appliance(@appliance_name, @appliance_url) },
|
|
187
175
|
}, @current_user)
|
|
188
176
|
print cyan
|
|
189
177
|
|
|
@@ -196,12 +184,12 @@ class Morpheus::Cli::Whoami
|
|
|
196
184
|
if @user_permissions.is_a?(Hash)
|
|
197
185
|
# api used to return map like [code:access]
|
|
198
186
|
rows = @user_permissions.collect do |code, access|
|
|
199
|
-
{permission: code, access:
|
|
187
|
+
{permission: code, access: format_access_string(access) }
|
|
200
188
|
end
|
|
201
189
|
else
|
|
202
190
|
# api now returns an array of objects like [[name:"Foo",code:"foo",access:"full"], ...]
|
|
203
191
|
rows = @user_permissions.collect do |it|
|
|
204
|
-
{permission: (it['name'] || it['code']), access:
|
|
192
|
+
{permission: (it['name'] || it['code']), access: format_access_string(it['access']) }
|
|
205
193
|
end
|
|
206
194
|
end
|
|
207
195
|
# api sort sux right now
|
|
@@ -215,34 +203,7 @@ class Morpheus::Cli::Whoami
|
|
|
215
203
|
end
|
|
216
204
|
end
|
|
217
205
|
|
|
218
|
-
|
|
219
|
-
print cyan
|
|
220
|
-
appliance_data = {
|
|
221
|
-
'name' => @appliance_name,
|
|
222
|
-
'url' => @appliance_url,
|
|
223
|
-
'buildVersion' => @appliance_build_verison
|
|
224
|
-
}
|
|
225
|
-
print_description_list({
|
|
226
|
-
"Name" => 'name',
|
|
227
|
-
"URL" => 'url',
|
|
228
|
-
"Version" => 'buildVersion'
|
|
229
|
-
}, appliance_data)
|
|
230
|
-
|
|
231
|
-
if active_group
|
|
232
|
-
print cyan
|
|
233
|
-
# print_h1 "Active Group", options
|
|
234
|
-
# print cyan
|
|
235
|
-
# print_description_list({
|
|
236
|
-
# "ID" => 'id',
|
|
237
|
-
# "Name" => 'name'
|
|
238
|
-
# }, active_group)
|
|
239
|
-
print cyan, "\n# => Currently using group #{active_group['name']}\n", reset
|
|
240
|
-
print reset,"\n"
|
|
241
|
-
else
|
|
242
|
-
print "\n", reset
|
|
243
|
-
print cyan, "No active group. See `groups use`\n",reset
|
|
244
|
-
print reset,"\n"
|
|
245
|
-
end
|
|
206
|
+
print reset, "\n"
|
|
246
207
|
|
|
247
208
|
# save pertinent session info to the appliance
|
|
248
209
|
begin
|
|
@@ -173,23 +173,11 @@ class Morpheus::Cli::WikiCommand
|
|
|
173
173
|
|
|
174
174
|
link = "#{@appliance_url}/login/oauth-redirect?access_token=#{@access_token}\\&redirectUri=/operations/wiki/#{page['urlName']}"
|
|
175
175
|
|
|
176
|
-
open_command = nil
|
|
177
|
-
if RbConfig::CONFIG['host_os'] =~ /mswin|mingw|cygwin/
|
|
178
|
-
open_command = "start #{link}"
|
|
179
|
-
elsif RbConfig::CONFIG['host_os'] =~ /darwin/
|
|
180
|
-
open_command = "open #{link}"
|
|
181
|
-
elsif RbConfig::CONFIG['host_os'] =~ /linux|bsd/
|
|
182
|
-
open_command = "xdg-open #{link}"
|
|
183
|
-
end
|
|
184
|
-
|
|
185
176
|
if options[:dry_run]
|
|
186
|
-
puts
|
|
177
|
+
puts Morpheus::Util.open_url_command(link)
|
|
187
178
|
return 0
|
|
188
179
|
end
|
|
189
|
-
|
|
190
|
-
system(open_command)
|
|
191
|
-
|
|
192
|
-
return 0
|
|
180
|
+
return Morpheus::Util.open_url(link)
|
|
193
181
|
rescue RestClient::Exception => e
|
|
194
182
|
print_rest_exception(e, options)
|
|
195
183
|
exit 1
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# this does some monkey patching of third party RestClient
|
|
2
|
+
# to modify the logging output a bit
|
|
3
|
+
require 'rest-client'
|
|
4
|
+
|
|
5
|
+
module RestClient
|
|
6
|
+
class Request
|
|
7
|
+
|
|
8
|
+
def log_request
|
|
9
|
+
begin
|
|
10
|
+
return unless RestClient.log
|
|
11
|
+
out = []
|
|
12
|
+
# out << "RestClient.#{method} #{redacted_url.inspect}"
|
|
13
|
+
out << "#{method.to_s.upcase} #{redacted_url.inspect}"
|
|
14
|
+
out << payload.short_inspect if payload
|
|
15
|
+
out << processed_headers.to_a.sort.map { |(k, v)| [k.inspect, v.inspect].join("=>") }.join(", ")
|
|
16
|
+
RestClient.log << out.join(', ') + "\n"
|
|
17
|
+
rescue => ex
|
|
18
|
+
# something went wrong, wrong gem version maybe...above is from rest-client 2.0.2
|
|
19
|
+
# do it the old way
|
|
20
|
+
super
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
=begin
|
|
24
|
+
def log_response res
|
|
25
|
+
return unless RestClient.log
|
|
26
|
+
size = if @raw_response
|
|
27
|
+
File.size(@tf.path)
|
|
28
|
+
else
|
|
29
|
+
res.body.nil? ? 0 : res.body.size
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
RestClient.log << "# => #{res.code} #{res.class.to_s.gsub(/^Net::HTTP/, '')} | #{(res['Content-type'] || '').gsub(/;.*$/, '')} #{size} bytes\n"
|
|
33
|
+
end
|
|
34
|
+
=end
|
|
35
|
+
end
|
|
36
|
+
end
|
data/lib/morpheus/formatters.rb
CHANGED
|
@@ -91,6 +91,20 @@ def format_duration(start_time, end_time=nil, format="human")
|
|
|
91
91
|
format_duration_seconds(seconds, format)
|
|
92
92
|
end
|
|
93
93
|
|
|
94
|
+
def format_duration_ago(start_time, end_time=nil)
|
|
95
|
+
if !start_time
|
|
96
|
+
return ""
|
|
97
|
+
end
|
|
98
|
+
start_time = parse_time(start_time)
|
|
99
|
+
if end_time
|
|
100
|
+
end_time = parse_time(end_time)
|
|
101
|
+
else
|
|
102
|
+
end_time = Time.now
|
|
103
|
+
end
|
|
104
|
+
seconds = (end_time - start_time).abs
|
|
105
|
+
format_human_duration(seconds, true)
|
|
106
|
+
end
|
|
107
|
+
|
|
94
108
|
def format_duration_seconds(seconds, format="human")
|
|
95
109
|
seconds = seconds.abs
|
|
96
110
|
out = ""
|
|
@@ -120,7 +134,7 @@ end
|
|
|
120
134
|
|
|
121
135
|
# returns a human readable time duration
|
|
122
136
|
# @param seconds - duration in seconds
|
|
123
|
-
def format_human_duration(seconds)
|
|
137
|
+
def format_human_duration(seconds, show_relative=false)
|
|
124
138
|
out = ""
|
|
125
139
|
#seconds = seconds.round
|
|
126
140
|
days, hours, minutes = (seconds / (60*60*24)).floor, (seconds / (60*60)).floor, (seconds / (60)).floor
|
|
@@ -152,18 +166,30 @@ def format_human_duration(seconds)
|
|
|
152
166
|
ms = (seconds.to_f * 1000).to_i
|
|
153
167
|
out << "#{ms}ms"
|
|
154
168
|
else
|
|
155
|
-
|
|
156
|
-
if seconds == 1
|
|
169
|
+
if seconds.floor == 1
|
|
157
170
|
out << "1 second"
|
|
158
171
|
else
|
|
159
|
-
out << "#{seconds} seconds"
|
|
172
|
+
out << "#{seconds.floor} seconds"
|
|
173
|
+
end
|
|
174
|
+
end
|
|
175
|
+
if show_relative
|
|
176
|
+
if seconds < 1
|
|
177
|
+
out = "just now"
|
|
178
|
+
else
|
|
179
|
+
out << " ago"
|
|
160
180
|
end
|
|
161
181
|
end
|
|
162
182
|
out
|
|
163
183
|
end
|
|
164
184
|
|
|
165
185
|
def display_appliance(name, url)
|
|
166
|
-
"
|
|
186
|
+
if name.to_s == "" || name == 'remote-url'
|
|
187
|
+
# "#{url}"
|
|
188
|
+
"#{url}"
|
|
189
|
+
else
|
|
190
|
+
# "#{name} #{url}"
|
|
191
|
+
"[#{name}] #{url}"
|
|
192
|
+
end
|
|
167
193
|
end
|
|
168
194
|
|
|
169
195
|
def iso8601(dt)
|
|
@@ -321,6 +347,7 @@ def no_colors(str)
|
|
|
321
347
|
str.to_s.gsub /\e\[\d+m/, ""
|
|
322
348
|
end
|
|
323
349
|
|
|
350
|
+
|
|
324
351
|
def format_number(n, opts={})
|
|
325
352
|
delim = opts[:delimiter] || ','
|
|
326
353
|
out = ""
|
|
@@ -338,6 +365,16 @@ def format_number(n, opts={})
|
|
|
338
365
|
return out
|
|
339
366
|
end
|
|
340
367
|
|
|
368
|
+
def format_sig_dig(n, sig_dig=3)
|
|
369
|
+
out = ""
|
|
370
|
+
parts = n.to_f.round(sig_dig).to_s.split(".")
|
|
371
|
+
if parts.size > 1 && sig_dig
|
|
372
|
+
parts[1] = parts[1].ljust(sig_dig, "0")
|
|
373
|
+
end
|
|
374
|
+
out << parts.join(".")
|
|
375
|
+
return out
|
|
376
|
+
end
|
|
377
|
+
|
|
341
378
|
def currency_sym(currency)
|
|
342
379
|
Money::Currency.new((currency || 'usd').to_sym).symbol
|
|
343
380
|
end
|