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
|
@@ -3,14 +3,18 @@ require 'date'
|
|
|
3
3
|
|
|
4
4
|
class Morpheus::Cli::InvoicesCommand
|
|
5
5
|
include Morpheus::Cli::CliCommand
|
|
6
|
+
include Morpheus::Cli::ProvisioningHelper
|
|
7
|
+
include Morpheus::Cli::OptionSourceHelper
|
|
6
8
|
|
|
7
9
|
set_command_name :'invoices'
|
|
8
10
|
|
|
9
|
-
register_subcommands :list, :get
|
|
11
|
+
register_subcommands :list, :get, :refresh,
|
|
12
|
+
:list_line_items, :get_line_item
|
|
10
13
|
|
|
11
14
|
def connect(opts)
|
|
12
15
|
@api_client = establish_remote_appliance_connection(opts)
|
|
13
16
|
@invoices_interface = @api_client.invoices
|
|
17
|
+
@invoice_line_items_interface = @api_client.invoice_line_items
|
|
14
18
|
end
|
|
15
19
|
|
|
16
20
|
def handle(args)
|
|
@@ -24,17 +28,17 @@ class Morpheus::Cli::InvoicesCommand
|
|
|
24
28
|
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
|
25
29
|
opts.banner = subcommand_usage()
|
|
26
30
|
opts.on('-a', '--all', "Display all costs, prices and raw data" ) do
|
|
27
|
-
options[:
|
|
28
|
-
options[:show_costs] = true
|
|
31
|
+
options[:show_estimates] = true
|
|
32
|
+
# options[:show_costs] = true
|
|
29
33
|
options[:show_prices] = true
|
|
30
34
|
options[:show_raw_data] = true
|
|
31
35
|
end
|
|
32
|
-
opts.on('--
|
|
33
|
-
options[:
|
|
34
|
-
end
|
|
35
|
-
opts.on('--costs', '--costs', "Display all costs: Compute, Memory, Storage, etc." ) do
|
|
36
|
-
options[:show_costs] = true
|
|
36
|
+
opts.on('--estimates', '--estimates', "Display all estimated costs, from usage info: Compute, Memory, Storage, etc." ) do
|
|
37
|
+
options[:show_estimates] = true
|
|
37
38
|
end
|
|
39
|
+
# opts.on('--costs', '--costs', "Display all costs: Compute, Memory, Storage, etc." ) do
|
|
40
|
+
# options[:show_costs] = true
|
|
41
|
+
# end
|
|
38
42
|
opts.on('--prices', '--prices', "Display prices: Total, Compute, Memory, Storage, etc." ) do
|
|
39
43
|
options[:show_prices] = true
|
|
40
44
|
end
|
|
@@ -63,28 +67,32 @@ class Morpheus::Cli::InvoicesCommand
|
|
|
63
67
|
end
|
|
64
68
|
opts.add_hidden_option('--ref-id')
|
|
65
69
|
opts.on('--group ID', String, "Filter by Group") do |val|
|
|
66
|
-
|
|
67
|
-
|
|
70
|
+
options[:groups] ||= []
|
|
71
|
+
options[:groups] << val
|
|
68
72
|
end
|
|
69
|
-
opts.on('--cloud
|
|
70
|
-
|
|
71
|
-
|
|
73
|
+
opts.on( '-c', '--cloud CLOUD', "Filter by Cloud" ) do |val|
|
|
74
|
+
options[:clouds] ||= []
|
|
75
|
+
options[:clouds] << val
|
|
72
76
|
end
|
|
73
77
|
opts.on('--instance ID', String, "Filter by Instance") do |val|
|
|
74
|
-
|
|
75
|
-
|
|
78
|
+
options[:instances] ||= []
|
|
79
|
+
options[:instances] << val
|
|
76
80
|
end
|
|
77
81
|
opts.on('--container ID', String, "Filter by Container") do |val|
|
|
78
82
|
params['containerId'] ||= []
|
|
79
83
|
params['containerId'] << val
|
|
80
84
|
end
|
|
81
85
|
opts.on('--server ID', String, "Filter by Server (Host)") do |val|
|
|
82
|
-
|
|
83
|
-
|
|
86
|
+
options[:servers] ||= []
|
|
87
|
+
options[:servers] << val
|
|
84
88
|
end
|
|
85
89
|
opts.on('--user ID', String, "Filter by User") do |val|
|
|
86
|
-
|
|
87
|
-
|
|
90
|
+
options[:users] ||= []
|
|
91
|
+
options[:users] << val
|
|
92
|
+
end
|
|
93
|
+
opts.on('--project PROJECT', String, "View invoices for a project.") do |val|
|
|
94
|
+
options[:projects] ||= []
|
|
95
|
+
options[:projects] << val
|
|
88
96
|
end
|
|
89
97
|
# opts.on('--cluster ID', String, "Filter by Cluster") do |val|
|
|
90
98
|
# params['clusterId'] ||= []
|
|
@@ -116,15 +124,45 @@ class Morpheus::Cli::InvoicesCommand
|
|
|
116
124
|
end
|
|
117
125
|
optparse.parse!(args)
|
|
118
126
|
connect(options)
|
|
127
|
+
# verify_args!(args:args, optparse:optparse, count:0)
|
|
119
128
|
if args.count > 0
|
|
120
|
-
|
|
121
|
-
puts_error "wrong number of arguments, expected 0 and got (#{args.count}) #{args.join(', ')}\n#{optparse}"
|
|
122
|
-
return 1
|
|
129
|
+
options[:phrase] = args.join(" ")
|
|
123
130
|
end
|
|
124
131
|
begin
|
|
132
|
+
# construct params
|
|
133
|
+
params.merge!(parse_list_options(options))
|
|
134
|
+
if options[:clouds]
|
|
135
|
+
cloud_ids = parse_cloud_id_list(options[:clouds])
|
|
136
|
+
return 1, "clouds not found for #{options[:clouds]}" if cloud_ids.nil?
|
|
137
|
+
params['zoneId'] = cloud_ids
|
|
138
|
+
end
|
|
139
|
+
if options[:groups]
|
|
140
|
+
group_ids = parse_group_id_list(options[:groups])
|
|
141
|
+
return 1, "groups not found for #{options[:groups]}" if group_ids.nil?
|
|
142
|
+
params['siteId'] = group_ids
|
|
143
|
+
end
|
|
144
|
+
if options[:instances]
|
|
145
|
+
instance_ids = parse_instance_id_list(options[:instances])
|
|
146
|
+
return 1, "instances not found for #{options[:instances]}" if instance_ids.nil?
|
|
147
|
+
params['instanceId'] = instance_ids
|
|
148
|
+
end
|
|
149
|
+
if options[:servers]
|
|
150
|
+
server_ids = parse_server_id_list(options[:servers])
|
|
151
|
+
return 1, "servers not found for #{options[:servers]}" if server_ids.nil?
|
|
152
|
+
params['serverId'] = server_ids
|
|
153
|
+
end
|
|
154
|
+
if options[:users]
|
|
155
|
+
user_ids = parse_user_id_list(options[:users])
|
|
156
|
+
return 1, "users not found for #{options[:users]}" if user_ids.nil?
|
|
157
|
+
params['userId'] = user_ids
|
|
158
|
+
end
|
|
159
|
+
if options[:projects]
|
|
160
|
+
project_ids = parse_project_id_list(options[:projects])
|
|
161
|
+
return 1, "projects not found for #{options[:projects]}" if project_ids.nil?
|
|
162
|
+
params['projectId'] = project_ids
|
|
163
|
+
end
|
|
125
164
|
params['rawData'] = true if options[:show_raw_data]
|
|
126
165
|
params['refId'] = ref_ids unless ref_ids.empty?
|
|
127
|
-
params.merge!(parse_list_options(options))
|
|
128
166
|
@invoices_interface.setopts(options)
|
|
129
167
|
if options[:dry_run]
|
|
130
168
|
print_dry_run @invoices_interface.dry.list(params)
|
|
@@ -136,12 +174,6 @@ class Morpheus::Cli::InvoicesCommand
|
|
|
136
174
|
invoices = json_response['invoices']
|
|
137
175
|
title = "Morpheus Invoices"
|
|
138
176
|
subtitles = []
|
|
139
|
-
if params['status']
|
|
140
|
-
subtitles << "Status: #{params['status']}"
|
|
141
|
-
end
|
|
142
|
-
if params['alarmStatus'] == 'acknowledged'
|
|
143
|
-
subtitles << "(Acknowledged)"
|
|
144
|
-
end
|
|
145
177
|
if params['startDate']
|
|
146
178
|
subtitles << "Start Date: #{params['startDate']}"
|
|
147
179
|
end
|
|
@@ -155,11 +187,17 @@ class Morpheus::Cli::InvoicesCommand
|
|
|
155
187
|
else
|
|
156
188
|
# current_date = Time.now
|
|
157
189
|
# current_period = "#{current_date.year}#{current_date.month.to_s.rjust(2, '0')}"
|
|
190
|
+
show_projects = invoices.find {|it| it['project'] } || (params['projectId'] || params['projectName'] || params['projectTag'])
|
|
158
191
|
columns = [
|
|
159
192
|
{"INVOICE ID" => lambda {|it| it['id'] } },
|
|
160
193
|
{"TYPE" => lambda {|it| format_invoice_ref_type(it) } },
|
|
161
194
|
{"REF ID" => lambda {|it| it['refId'] } },
|
|
162
|
-
{"REF NAME" => lambda {|it| it['refName'] } }
|
|
195
|
+
{"REF NAME" => lambda {|it| it['refName'] } }
|
|
196
|
+
] + (show_projects ? [
|
|
197
|
+
{"PROJECT ID" => lambda {|it| it['project'] ? it['project']['id'] : '' } },
|
|
198
|
+
{"PROJECT NAME" => lambda {|it| it['project'] ? it['project']['name'] : '' } },
|
|
199
|
+
{"PROJECT TAGS" => lambda {|it| it['project'] ? truncate_string(format_metadata(it['project']['tags']), 50) : '' } }
|
|
200
|
+
] : []) + [
|
|
163
201
|
#{"INTERVAL" => lambda {|it| it['interval'] } },
|
|
164
202
|
{"CLOUD" => lambda {|it| it['cloud'] ? it['cloud']['name'] : '' } },
|
|
165
203
|
{"ACCOUNT" => lambda {|it| it['account'] ? it['account']['name'] : '' } },
|
|
@@ -176,35 +214,16 @@ class Morpheus::Cli::InvoicesCommand
|
|
|
176
214
|
else
|
|
177
215
|
format_money(it['totalCost'])
|
|
178
216
|
end
|
|
179
|
-
} },
|
|
180
|
-
{"ACTUAL MTD" => lambda {|it| format_money(it['actualRunningCost']) } },
|
|
181
|
-
{"ACTUAL TOTAL" => lambda {|it|
|
|
182
|
-
if it['runningMultiplier'] && it['runningMultiplier'].to_i != 1 && it['actualTotalCost'].to_f > 0
|
|
183
|
-
format_money(it['actualTotalCost']) + " (Projected)"
|
|
184
|
-
else
|
|
185
|
-
format_money(it['actualTotalCost'])
|
|
186
|
-
end
|
|
187
217
|
} }
|
|
188
218
|
]
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
end
|
|
198
|
-
if options[:show_actual_costs]
|
|
199
|
-
columns += [
|
|
200
|
-
{"ACTUAL COMPUTE" => lambda {|it| format_money(it['actualComputeCost']) } },
|
|
201
|
-
# {"ACTUAL MEMORY" => lambda {|it| format_money(it['actualMemoryCost']) } },
|
|
202
|
-
{"ACTUAL STORAGE" => lambda {|it| format_money(it['actualStorageCost']) } },
|
|
203
|
-
{"ACTUAL NETWORK" => lambda {|it| format_money(it['actualNetworkCost']) } },
|
|
204
|
-
{"ACTUAL OTHER" => lambda {|it| format_money(it['actualExtraCost']) } },
|
|
205
|
-
]
|
|
206
|
-
end
|
|
207
|
-
|
|
219
|
+
|
|
220
|
+
columns += [
|
|
221
|
+
{"COMPUTE" => lambda {|it| format_money(it['computeCost']) } },
|
|
222
|
+
# {"MEMORY" => lambda {|it| format_money(it['memoryCost']) } },
|
|
223
|
+
{"STORAGE" => lambda {|it| format_money(it['storageCost']) } },
|
|
224
|
+
{"NETWORK" => lambda {|it| format_money(it['networkCost']) } },
|
|
225
|
+
{"OTHER" => lambda {|it| format_money(it['extraCost']) } },
|
|
226
|
+
]
|
|
208
227
|
if options[:show_prices]
|
|
209
228
|
columns += [
|
|
210
229
|
{"COMPUTE PRICE" => lambda {|it| format_money(it['computePrice']) } },
|
|
@@ -222,7 +241,23 @@ class Morpheus::Cli::InvoicesCommand
|
|
|
222
241
|
} }
|
|
223
242
|
]
|
|
224
243
|
end
|
|
225
|
-
|
|
244
|
+
if options[:show_estimates]
|
|
245
|
+
columns += [
|
|
246
|
+
{"MTD EST." => lambda {|it| format_money(it['estimatedRunningCost']) } },
|
|
247
|
+
{"TOTAL EST." => lambda {|it|
|
|
248
|
+
if it['runningMultiplier'] && it['runningMultiplier'].to_i != 1 && it['estimatedTotalCost'].to_f > 0
|
|
249
|
+
format_money(it['estimatedTotalCost']) + " (Projected)"
|
|
250
|
+
else
|
|
251
|
+
format_money(it['estimatedTotalCost'])
|
|
252
|
+
end
|
|
253
|
+
} },
|
|
254
|
+
{"COMPUTE EST." => lambda {|it| format_money(it['estimatedComputeCost']) } },
|
|
255
|
+
# {"MEMORY EST." => lambda {|it| format_money(it['estimatedMemoryCost']) } },
|
|
256
|
+
{"STORAGE EST." => lambda {|it| format_money(it['estimatedStorageCost']) } },
|
|
257
|
+
{"NETWORK EST." => lambda {|it| format_money(it['estimatedNetworkCost']) } },
|
|
258
|
+
{"OTHER EST." => lambda {|it| format_money(it['estimatedExtraCost']) } },
|
|
259
|
+
]
|
|
260
|
+
end
|
|
226
261
|
if options[:show_raw_data]
|
|
227
262
|
columns += [{"RAW DATA" => lambda {|it| truncate_string(it['rawData'].to_s, 10) } }]
|
|
228
263
|
end
|
|
@@ -240,17 +275,30 @@ class Morpheus::Cli::InvoicesCommand
|
|
|
240
275
|
options = {}
|
|
241
276
|
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
|
242
277
|
opts.banner = subcommand_usage("[id]")
|
|
278
|
+
opts.on('-a', '--all', "Display all costs, prices and raw data" ) do
|
|
279
|
+
options[:show_estimates] = true
|
|
280
|
+
# options[:show_costs] = true
|
|
281
|
+
options[:show_prices] = true
|
|
282
|
+
options[:show_raw_data] = true
|
|
283
|
+
end
|
|
284
|
+
opts.on('--estimates', '--estimates', "Display all estimated costs, from usage info: Compute, Memory, Storage, etc." ) do
|
|
285
|
+
options[:show_estimates] = true
|
|
286
|
+
end
|
|
243
287
|
opts.on('--raw-data', '--raw-data', "Display Raw Data, the cost data from the cloud provider's API.") do |val|
|
|
244
288
|
options[:show_raw_data] = true
|
|
245
289
|
end
|
|
290
|
+
opts.on('--no-line-items', '--no-line-items', "Do not display line items.") do |val|
|
|
291
|
+
options[:hide_line_items] = true
|
|
292
|
+
end
|
|
246
293
|
build_standard_get_options(opts, options)
|
|
247
294
|
opts.footer = "Get details about a specific invoice."
|
|
295
|
+
opts.footer = <<-EOT
|
|
296
|
+
Get details about a specific invoice.
|
|
297
|
+
[id] is required. This is the id of an invoice.
|
|
298
|
+
EOT
|
|
248
299
|
end
|
|
249
300
|
optparse.parse!(args)
|
|
250
|
-
|
|
251
|
-
puts optparse
|
|
252
|
-
return 1
|
|
253
|
-
end
|
|
301
|
+
verify_args!(args:args, optparse:optparse, min:1)
|
|
254
302
|
connect(options)
|
|
255
303
|
id_list = parse_id_list(args)
|
|
256
304
|
return run_command_for_each_arg(id_list) do |arg|
|
|
@@ -284,21 +332,31 @@ class Morpheus::Cli::InvoicesCommand
|
|
|
284
332
|
"Ref ID" => lambda {|it| it['refId'] },
|
|
285
333
|
"Ref Name" => lambda {|it| it['refName'] },
|
|
286
334
|
"Plan" => lambda {|it| it['plan'] ? it['plan']['name'] : '' },
|
|
335
|
+
"Project ID" => lambda {|it| it['project'] ? it['project']['id'] : '' },
|
|
336
|
+
"Project Name" => lambda {|it| it['project'] ? it['project']['name'] : '' },
|
|
337
|
+
"Project Tags" => lambda {|it| it['project'] ? format_metadata(it['project']['tags']) : '' },
|
|
287
338
|
"Power State" => lambda {|it| format_server_power_state(it) },
|
|
288
339
|
"Account" => lambda {|it| it['account'] ? it['account']['name'] : '' },
|
|
289
340
|
"Active" => lambda {|it| format_boolean(it['active']) },
|
|
290
341
|
"Period" => lambda {|it| format_invoice_period(it) },
|
|
342
|
+
"Estimate" => lambda {|it| format_boolean(it['estimate']) },
|
|
291
343
|
#"Interval" => lambda {|it| it['interval'] },
|
|
292
344
|
"Start" => lambda {|it| format_date(it['startDate']) },
|
|
293
345
|
"End" => lambda {|it| it['endDate'] ? format_date(it['endDate']) : '' },
|
|
294
|
-
"
|
|
346
|
+
"Ref Start" => lambda {|it| format_local_dt(it['refStart']) },
|
|
347
|
+
"Ref End" => lambda {|it| it['refEnd'] ? format_local_dt(it['refEnd']) : '' },
|
|
295
348
|
"Created" => lambda {|it| format_local_dt(it['dateCreated']) },
|
|
296
349
|
"Updated" => lambda {|it| format_local_dt(it['lastUpdated']) }
|
|
297
350
|
}
|
|
298
351
|
# remove columns that do not apply
|
|
299
|
-
if
|
|
352
|
+
if invoice['plan'].nil?
|
|
300
353
|
description_cols.delete("Plan")
|
|
301
354
|
end
|
|
355
|
+
if invoice['project'].nil?
|
|
356
|
+
description_cols.delete("Project ID")
|
|
357
|
+
description_cols.delete("Project Name")
|
|
358
|
+
description_cols.delete("Project Tags")
|
|
359
|
+
end
|
|
302
360
|
if !['ComputeServer','Instance','Container'].include?(invoice['refType'])
|
|
303
361
|
description_cols.delete("Power State")
|
|
304
362
|
end
|
|
@@ -337,10 +395,15 @@ class Morpheus::Cli::InvoicesCommand
|
|
|
337
395
|
print "\n"
|
|
338
396
|
# print_h2 "Costs"
|
|
339
397
|
cost_rows = [
|
|
340
|
-
{label: '
|
|
341
|
-
{label: '
|
|
342
|
-
{label: 'Actual Cost'.upcase, compute: invoice['actualComputeCost'], memory: invoice['actualMemoryCost'], storage: invoice['actualStorageCost'], network: invoice['actualNetworkCost'], license: invoice['actualLicenseCost'], extra: invoice['actualExtraCost'], running: invoice['actualRunningCost'], total: invoice['actualTotalCost']},
|
|
398
|
+
{label: 'Price'.upcase, compute: invoice['computePrice'], memory: invoice['memoryPrice'], storage: invoice['storagePrice'], network: invoice['networkPrice'], license: invoice['licensePrice'], extra: invoice['extraPrice'], running: invoice['runningPrice'], total: invoice['totalPrice']},
|
|
399
|
+
{label: 'Cost'.upcase, compute: invoice['computeCost'], memory: invoice['memoryCost'], storage: invoice['storageCost'], network: invoice['networkCost'], license: invoice['licenseCost'], extra: invoice['extraCost'], running: invoice['runningCost'], total: invoice['totalCost']},
|
|
343
400
|
]
|
|
401
|
+
if options[:show_estimates]
|
|
402
|
+
cost_rows += [
|
|
403
|
+
{label: 'Estimated Cost'.upcase, compute: invoice['estimatedComputeCost'], memory: invoice['estimatedMemoryCost'], storage: invoice['estimatedStorageCost'], network: invoice['estimatedNetworkCost'], license: invoice['estimatedLicenseCost'], extra: invoice['estimatedExtraCost'], running: invoice['estimatedRunningCost'], total: invoice['estimatedTotalCost']},
|
|
404
|
+
{label: 'Estimated Price'.upcase, compute: invoice['estimatedComputeCost'], memory: invoice['estimatedMemoryCost'], storage: invoice['estimatedStorageCost'], network: invoice['estimatedNetworkCost'], license: invoice['estimatedLicenseCost'], extra: invoice['estimatedExtraCost'], running: invoice['estimatedRunningCost'], total: invoice['estimatedTotalCost']},
|
|
405
|
+
]
|
|
406
|
+
end
|
|
344
407
|
cost_columns = {
|
|
345
408
|
"" => lambda {|it| it[:label] },
|
|
346
409
|
"Compute".upcase => lambda {|it| format_money(it[:compute]) },
|
|
@@ -375,6 +438,38 @@ class Morpheus::Cli::InvoicesCommand
|
|
|
375
438
|
puts invoice['rawData']
|
|
376
439
|
end
|
|
377
440
|
|
|
441
|
+
# Line Items
|
|
442
|
+
line_items = invoice['lineItems']
|
|
443
|
+
if line_items && line_items.size > 0 && options[:hide_line_items] != true
|
|
444
|
+
|
|
445
|
+
line_items_columns = [
|
|
446
|
+
{"INVOICE ID" => lambda {|it| it['invoiceId'] } },
|
|
447
|
+
{"TYPE" => lambda {|it| format_invoice_ref_type(it) } },
|
|
448
|
+
{"REF ID" => lambda {|it| it['refId'] } },
|
|
449
|
+
{"REF NAME" => lambda {|it| it['refName'] } },
|
|
450
|
+
#{"REF CATEGORY" => lambda {|it| it['refCategory'] } },
|
|
451
|
+
{"START" => lambda {|it| format_date(it['startDate']) } },
|
|
452
|
+
{"END" => lambda {|it| it['endDate'] ? format_date(it['endDate']) : '' } },
|
|
453
|
+
{"USAGE TYPE" => lambda {|it| it['usageType'] } },
|
|
454
|
+
{"USAGE CATEGORY" => lambda {|it| it['usageCategory'] } },
|
|
455
|
+
{"USAGE" => lambda {|it| it['itemUsage'] } },
|
|
456
|
+
{"RATE" => lambda {|it| it['itemRate'] } },
|
|
457
|
+
{"COST" => lambda {|it| format_money(it['itemCost']) } },
|
|
458
|
+
{"PRICE" => lambda {|it| format_money(it['itemPrice']) } },
|
|
459
|
+
{"TAX" => lambda {|it| format_money(it['itemTax']) } },
|
|
460
|
+
# {"TERM" => lambda {|it| it['itemTerm'] } },
|
|
461
|
+
"CREATED" => lambda {|it| format_local_dt(it['dateCreated']) },
|
|
462
|
+
"UPDATED" => lambda {|it| format_local_dt(it['lastUpdated']) }
|
|
463
|
+
]
|
|
464
|
+
|
|
465
|
+
if options[:show_raw_data]
|
|
466
|
+
columns += [{"RAW DATA" => lambda {|it| truncate_string(it['rawData'].to_s, 10) } }]
|
|
467
|
+
end
|
|
468
|
+
|
|
469
|
+
print_h2 "Line Items"
|
|
470
|
+
print as_pretty_table(line_items, line_items_columns, options)
|
|
471
|
+
print_results_pagination({total: line_items.size, size: line_items.size})
|
|
472
|
+
end
|
|
378
473
|
|
|
379
474
|
print reset,"\n"
|
|
380
475
|
return 0
|
|
@@ -384,6 +479,347 @@ class Morpheus::Cli::InvoicesCommand
|
|
|
384
479
|
end
|
|
385
480
|
end
|
|
386
481
|
|
|
482
|
+
def refresh(args)
|
|
483
|
+
options = {}
|
|
484
|
+
params = {}
|
|
485
|
+
payload = {}
|
|
486
|
+
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
|
487
|
+
opts.banner = subcommand_usage("[--daily] [--costing] [--current] [-c CLOUD]")
|
|
488
|
+
opts.on( '--daily', "Refresh Daily Invoices" ) do
|
|
489
|
+
payload[:daily] = true
|
|
490
|
+
end
|
|
491
|
+
opts.on( '--costing', "Refresh Costing Data" ) do
|
|
492
|
+
payload[:costing] = true
|
|
493
|
+
end
|
|
494
|
+
opts.on( '--current', "Collect the most up to date costing data." ) do
|
|
495
|
+
payload[:current] = true
|
|
496
|
+
end
|
|
497
|
+
opts.on( '--date DATE', String, "Date to collect costing for. By default the cost data is collected for the end of the previous period." ) do |val|
|
|
498
|
+
payload[:date] = val.to_s
|
|
499
|
+
end
|
|
500
|
+
opts.on( '-c', '--cloud CLOUD', "Specify cloud(s) to refresh costing for." ) do |val|
|
|
501
|
+
payload[:clouds] ||= []
|
|
502
|
+
payload[:clouds] << val
|
|
503
|
+
end
|
|
504
|
+
opts.on( '--all', "Refresh costing for all clouds." ) do
|
|
505
|
+
payload[:all] = true
|
|
506
|
+
end
|
|
507
|
+
# opts.on( '-f', '--force', "Force Refresh" ) do
|
|
508
|
+
# query_params[:force] = 'true'
|
|
509
|
+
# end
|
|
510
|
+
build_standard_update_options(opts, options, [:query, :auto_confirm])
|
|
511
|
+
opts.footer = <<-EOT
|
|
512
|
+
Refresh invoices.
|
|
513
|
+
By default, nothing is changed.
|
|
514
|
+
Include --daily to regenerate invoice records.
|
|
515
|
+
Include --costing to refresh actual costing data.
|
|
516
|
+
Include --current to refresh costing data for the actual current time.
|
|
517
|
+
To get the latest invoice costing data, include --daily --costing --current --all
|
|
518
|
+
EOT
|
|
519
|
+
end
|
|
520
|
+
optparse.parse!(args)
|
|
521
|
+
verify_args!(args:args, optparse:optparse, count:0)
|
|
522
|
+
connect(options)
|
|
523
|
+
params.merge!(parse_query_options(options))
|
|
524
|
+
if options[:payload]
|
|
525
|
+
payload = options[:payload]
|
|
526
|
+
end
|
|
527
|
+
payload.deep_merge!(parse_passed_options(options))
|
|
528
|
+
# --clouds
|
|
529
|
+
if payload[:clouds]
|
|
530
|
+
payload[:clouds] = parse_id_list(payload[:clouds]).collect {|cloud_id|
|
|
531
|
+
if cloud_id.to_s =~ /\A\d{1,}\Z/
|
|
532
|
+
cloud_id
|
|
533
|
+
else
|
|
534
|
+
cloud = find_cloud_option(cloud_id)
|
|
535
|
+
return 1 if cloud.nil?
|
|
536
|
+
cloud['id']
|
|
537
|
+
end
|
|
538
|
+
}
|
|
539
|
+
end
|
|
540
|
+
# are you sure?
|
|
541
|
+
unless options[:yes] || Morpheus::Cli::OptionTypes.confirm("Are you sure you want to refresh invoices?")
|
|
542
|
+
return 9, "aborted command"
|
|
543
|
+
end
|
|
544
|
+
# ok, make the request
|
|
545
|
+
@invoices_interface.setopts(options)
|
|
546
|
+
if options[:dry_run]
|
|
547
|
+
print_dry_run @invoices_interface.dry.refresh(params, payload)
|
|
548
|
+
return
|
|
549
|
+
end
|
|
550
|
+
json_response = @invoices_interface.refresh(params, payload)
|
|
551
|
+
# render the result
|
|
552
|
+
render_result = render_with_format(json_response, options)
|
|
553
|
+
return 0 if render_result
|
|
554
|
+
# print output
|
|
555
|
+
print_green_success(json_response['msg'] || "Refreshing invoices")
|
|
556
|
+
return 0
|
|
557
|
+
end
|
|
558
|
+
|
|
559
|
+
def list_line_items(args)
|
|
560
|
+
options = {}
|
|
561
|
+
params = {}
|
|
562
|
+
ref_ids = []
|
|
563
|
+
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
|
564
|
+
opts.banner = subcommand_usage()
|
|
565
|
+
opts.on('-a', '--all', "Display all costs, prices and raw data" ) do
|
|
566
|
+
options[:show_actual_costs] = true
|
|
567
|
+
options[:show_costs] = true
|
|
568
|
+
options[:show_prices] = true
|
|
569
|
+
options[:show_raw_data] = true
|
|
570
|
+
end
|
|
571
|
+
# opts.on('--actuals', '--actuals', "Display all actual costs: Compute, Memory, Storage, etc." ) do
|
|
572
|
+
# options[:show_actual_costs] = true
|
|
573
|
+
# end
|
|
574
|
+
# opts.on('--costs', '--costs', "Display all costs: Compute, Memory, Storage, etc." ) do
|
|
575
|
+
# options[:show_costs] = true
|
|
576
|
+
# end
|
|
577
|
+
# opts.on('--prices', '--prices', "Display prices: Total, Compute, Memory, Storage, etc." ) do
|
|
578
|
+
# options[:show_prices] = true
|
|
579
|
+
# end
|
|
580
|
+
opts.on('--type TYPE', String, "Filter by Ref Type eg. ComputeSite (Group), ComputeZone (Cloud), ComputeServer (Host), Instance, Container, User") do |val|
|
|
581
|
+
if val.to_s.downcase == 'cloud' || val.to_s.downcase == 'zone'
|
|
582
|
+
params['refType'] = 'ComputeZone'
|
|
583
|
+
elsif val.to_s.downcase == 'instance'
|
|
584
|
+
params['refType'] = 'Instance'
|
|
585
|
+
elsif val.to_s.downcase == 'server' || val.to_s.downcase == 'host'
|
|
586
|
+
params['refType'] = 'ComputeServer'
|
|
587
|
+
elsif val.to_s.downcase == 'cluster'
|
|
588
|
+
params['refType'] = 'ComputeServerGroup'
|
|
589
|
+
elsif val.to_s.downcase == 'group'
|
|
590
|
+
params['refType'] = 'ComputeSite'
|
|
591
|
+
elsif val.to_s.downcase == 'user'
|
|
592
|
+
params['refType'] = 'User'
|
|
593
|
+
else
|
|
594
|
+
params['refType'] = val
|
|
595
|
+
end
|
|
596
|
+
end
|
|
597
|
+
opts.on('--id ID', String, "Filter by Ref ID") do |val|
|
|
598
|
+
ref_ids << val
|
|
599
|
+
end
|
|
600
|
+
opts.on('--ref-id ID', String, "Filter by Ref ID") do |val|
|
|
601
|
+
ref_ids << val
|
|
602
|
+
end
|
|
603
|
+
opts.add_hidden_option('--ref-id')
|
|
604
|
+
opts.on('--group ID', String, "Filter by Group") do |val|
|
|
605
|
+
options[:groups] ||= []
|
|
606
|
+
options[:groups] << val
|
|
607
|
+
end
|
|
608
|
+
opts.on( '-c', '--cloud CLOUD', "Filter by Cloud" ) do |val|
|
|
609
|
+
options[:clouds] ||= []
|
|
610
|
+
options[:clouds] << val
|
|
611
|
+
end
|
|
612
|
+
opts.on('--instance ID', String, "Filter by Instance") do |val|
|
|
613
|
+
options[:instances] ||= []
|
|
614
|
+
options[:instances] << val
|
|
615
|
+
end
|
|
616
|
+
opts.on('--container ID', String, "Filter by Container") do |val|
|
|
617
|
+
params['containerId'] ||= []
|
|
618
|
+
params['containerId'] << val
|
|
619
|
+
end
|
|
620
|
+
opts.on('--server ID', String, "Filter by Server (Host)") do |val|
|
|
621
|
+
options[:servers] ||= []
|
|
622
|
+
options[:servers] << val
|
|
623
|
+
end
|
|
624
|
+
opts.on('--user ID', String, "Filter by User") do |val|
|
|
625
|
+
options[:users] ||= []
|
|
626
|
+
options[:users] << val
|
|
627
|
+
end
|
|
628
|
+
opts.on('--project PROJECT', String, "View invoices for a project.") do |val|
|
|
629
|
+
options[:projects] ||= []
|
|
630
|
+
options[:projects] << val
|
|
631
|
+
end
|
|
632
|
+
# opts.on('--cluster ID', String, "Filter by Cluster") do |val|
|
|
633
|
+
# params['clusterId'] ||= []
|
|
634
|
+
# params['clusterId'] << val
|
|
635
|
+
# end
|
|
636
|
+
opts.on('--start DATE', String, "Start date in the format YYYY-MM-DD.") do |val|
|
|
637
|
+
params['startDate'] = val #parse_time(val).utc.iso8601
|
|
638
|
+
end
|
|
639
|
+
opts.on('--end DATE', String, "End date in the format YYYY-MM-DD. Default is now.") do |val|
|
|
640
|
+
params['endDate'] = val #parse_time(val).utc.iso8601
|
|
641
|
+
end
|
|
642
|
+
opts.on('--period PERIOD', String, "Period in the format YYYYMM. This can be used instead of start/end.") do |val|
|
|
643
|
+
params['period'] = parse_period(val)
|
|
644
|
+
end
|
|
645
|
+
opts.on('--active [true|false]',String, "Filter by active.") do |val|
|
|
646
|
+
params['active'] = (val.to_s != 'false' && val.to_s != 'off')
|
|
647
|
+
end
|
|
648
|
+
opts.on('--estimate [true|false]',String, "Filter by estimate.") do |val|
|
|
649
|
+
params['estimate'] = (val.to_s != 'false' && val.to_s != 'off')
|
|
650
|
+
end
|
|
651
|
+
opts.on('--tenant ID', String, "View invoice line items for a tenant. Default is your own account.") do |val|
|
|
652
|
+
params['accountId'] = val
|
|
653
|
+
end
|
|
654
|
+
opts.on('--raw-data', '--raw-data', "Display Raw Data, the cost data from the cloud provider's API.") do |val|
|
|
655
|
+
options[:show_raw_data] = true
|
|
656
|
+
end
|
|
657
|
+
build_standard_list_options(opts, options)
|
|
658
|
+
opts.footer = "List invoice line items."
|
|
659
|
+
end
|
|
660
|
+
optparse.parse!(args)
|
|
661
|
+
connect(options)
|
|
662
|
+
# verify_args!(args:args, optparse:optparse, count:0)
|
|
663
|
+
if args.count > 0
|
|
664
|
+
options[:phrase] = args.join(" ")
|
|
665
|
+
end
|
|
666
|
+
|
|
667
|
+
# construct params
|
|
668
|
+
params.merge!(parse_list_options(options))
|
|
669
|
+
if options[:clouds]
|
|
670
|
+
cloud_ids = parse_cloud_id_list(options[:clouds])
|
|
671
|
+
return 1, "clouds not found for #{options[:clouds]}" if cloud_ids.nil?
|
|
672
|
+
params['zoneId'] = cloud_ids
|
|
673
|
+
end
|
|
674
|
+
if options[:groups]
|
|
675
|
+
group_ids = parse_group_id_list(options[:groups])
|
|
676
|
+
return 1, "groups not found for #{options[:groups]}" if group_ids.nil?
|
|
677
|
+
params['siteId'] = group_ids
|
|
678
|
+
end
|
|
679
|
+
if options[:instances]
|
|
680
|
+
instance_ids = parse_instance_id_list(options[:instances])
|
|
681
|
+
return 1, "instances not found for #{options[:instances]}" if instance_ids.nil?
|
|
682
|
+
params['instanceId'] = instance_ids
|
|
683
|
+
end
|
|
684
|
+
if options[:servers]
|
|
685
|
+
server_ids = parse_server_id_list(options[:servers])
|
|
686
|
+
return 1, "servers not found for #{options[:servers]}" if server_ids.nil?
|
|
687
|
+
params['serverId'] = server_ids
|
|
688
|
+
end
|
|
689
|
+
if options[:users]
|
|
690
|
+
user_ids = parse_user_id_list(options[:users])
|
|
691
|
+
return 1, "users not found for #{options[:users]}" if user_ids.nil?
|
|
692
|
+
params['userId'] = user_ids
|
|
693
|
+
end
|
|
694
|
+
if options[:projects]
|
|
695
|
+
project_ids = parse_project_id_list(options[:projects])
|
|
696
|
+
return 1, "projects not found for #{options[:projects]}" if project_ids.nil?
|
|
697
|
+
params['projectId'] = project_ids
|
|
698
|
+
end
|
|
699
|
+
params['rawData'] = true if options[:show_raw_data]
|
|
700
|
+
params['refId'] = ref_ids unless ref_ids.empty?
|
|
701
|
+
@invoice_line_items_interface.setopts(options)
|
|
702
|
+
if options[:dry_run]
|
|
703
|
+
print_dry_run @invoice_line_items_interface.dry.list(params)
|
|
704
|
+
return
|
|
705
|
+
end
|
|
706
|
+
json_response = @invoice_line_items_interface.list(params)
|
|
707
|
+
line_items = json_response['lineItems']
|
|
708
|
+
render_response(json_response, options, 'lineItems') do
|
|
709
|
+
title = "Morpheus Line Items"
|
|
710
|
+
subtitles = []
|
|
711
|
+
if params['startDate']
|
|
712
|
+
subtitles << "Start Date: #{params['startDate']}"
|
|
713
|
+
end
|
|
714
|
+
if params['endDate']
|
|
715
|
+
subtitles << "End Date: #{params['endDate']}"
|
|
716
|
+
end
|
|
717
|
+
subtitles += parse_list_subtitles(options)
|
|
718
|
+
print_h1 title, subtitles
|
|
719
|
+
if line_items.empty?
|
|
720
|
+
print yellow,"No line items found.",reset,"\n"
|
|
721
|
+
else
|
|
722
|
+
# current_date = Time.now
|
|
723
|
+
# current_period = "#{current_date.year}#{current_date.month.to_s.rjust(2, '0')}"
|
|
724
|
+
columns = [
|
|
725
|
+
{"INVOICE ID" => lambda {|it| it['invoiceId'] } },
|
|
726
|
+
{"TYPE" => lambda {|it| format_invoice_ref_type(it) } },
|
|
727
|
+
{"REF ID" => lambda {|it| it['refId'] } },
|
|
728
|
+
{"REF NAME" => lambda {|it| it['refName'] } },
|
|
729
|
+
#{"REF CATEGORY" => lambda {|it| it['refCategory'] } },
|
|
730
|
+
{"START" => lambda {|it| format_date(it['startDate']) } },
|
|
731
|
+
{"END" => lambda {|it| it['endDate'] ? format_date(it['endDate']) : '' } },
|
|
732
|
+
{"USAGE TYPE" => lambda {|it| it['usageType'] } },
|
|
733
|
+
{"USAGE CATEGORY" => lambda {|it| it['usageCategory'] } },
|
|
734
|
+
{"USAGE" => lambda {|it| it['itemUsage'] } },
|
|
735
|
+
{"RATE" => lambda {|it| it['itemRate'] } },
|
|
736
|
+
{"COST" => lambda {|it| format_money(it['itemCost']) } },
|
|
737
|
+
{"PRICE" => lambda {|it| format_money(it['itemPrice']) } },
|
|
738
|
+
{"TAX" => lambda {|it| format_money(it['itemTax']) } },
|
|
739
|
+
# {"TERM" => lambda {|it| it['itemTerm'] } },
|
|
740
|
+
"CREATED" => lambda {|it| format_local_dt(it['dateCreated']) },
|
|
741
|
+
"UPDATED" => lambda {|it| format_local_dt(it['lastUpdated']) }
|
|
742
|
+
]
|
|
743
|
+
|
|
744
|
+
if options[:show_raw_data]
|
|
745
|
+
columns += [{"RAW DATA" => lambda {|it| truncate_string(it['rawData'].to_s, 10) } }]
|
|
746
|
+
end
|
|
747
|
+
print as_pretty_table(line_items, columns, options)
|
|
748
|
+
print_results_pagination(json_response, {:label => "line item", :n_label => "line items"})
|
|
749
|
+
end
|
|
750
|
+
print reset,"\n"
|
|
751
|
+
end
|
|
752
|
+
if line_items.empty?
|
|
753
|
+
return 1, "no line items found"
|
|
754
|
+
else
|
|
755
|
+
return 0, nil
|
|
756
|
+
end
|
|
757
|
+
end
|
|
758
|
+
|
|
759
|
+
def get_line_item(args)
|
|
760
|
+
options = {}
|
|
761
|
+
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
|
762
|
+
opts.banner = subcommand_usage("[id]")
|
|
763
|
+
opts.on('--raw-data', '--raw-data', "Display Raw Data, the cost data from the cloud provider's API.") do |val|
|
|
764
|
+
options[:show_raw_data] = true
|
|
765
|
+
end
|
|
766
|
+
build_standard_get_options(opts, options)
|
|
767
|
+
opts.footer = "Get details about a specific invoice line item."
|
|
768
|
+
opts.footer = <<-EOT
|
|
769
|
+
Get details about a specific invoice line item.
|
|
770
|
+
[id] is required. This is the id of an invoice line item.
|
|
771
|
+
EOT
|
|
772
|
+
end
|
|
773
|
+
optparse.parse!(args)
|
|
774
|
+
verify_args!(args:args, optparse:optparse, min:1)
|
|
775
|
+
connect(options)
|
|
776
|
+
id_list = parse_id_list(args)
|
|
777
|
+
return run_command_for_each_arg(id_list) do |arg|
|
|
778
|
+
_get(arg, options)
|
|
779
|
+
end
|
|
780
|
+
end
|
|
781
|
+
|
|
782
|
+
def _get_line_item(id, options)
|
|
783
|
+
params = {}
|
|
784
|
+
if options[:show_raw_data]
|
|
785
|
+
params['rawData'] = true
|
|
786
|
+
end
|
|
787
|
+
@invoice_line_items_interface.setopts(options)
|
|
788
|
+
if options[:dry_run]
|
|
789
|
+
print_dry_run @invoice_line_items_interface.dry.get(id, params)
|
|
790
|
+
return
|
|
791
|
+
end
|
|
792
|
+
json_response = @invoice_line_items_interface.get(id, params)
|
|
793
|
+
line_item = json_response['lineItem']
|
|
794
|
+
render_response(json_response, options, 'lineItem') do
|
|
795
|
+
print_h1 "Line Item Details"
|
|
796
|
+
print cyan
|
|
797
|
+
description_cols = {
|
|
798
|
+
"ID" => lambda {|it| it['id'] },
|
|
799
|
+
"Invoice ID" => lambda {|it| it['invoiceId'] },
|
|
800
|
+
"Type" => lambda {|it| format_invoice_ref_type(it) },
|
|
801
|
+
"Ref ID" => lambda {|it| it['refId'] },
|
|
802
|
+
"Ref Name" => lambda {|it| it['refName'] },
|
|
803
|
+
"Start" => lambda {|it| format_date(it['startDate']) },
|
|
804
|
+
"End" => lambda {|it| it['endDate'] ? format_date(it['endDate']) : '' },
|
|
805
|
+
"Usage Type" => lambda {|it| it['usageType'] },
|
|
806
|
+
"Usage Category" => lambda {|it| it['usageCategory'] },
|
|
807
|
+
"Item Usage" => lambda {|it| it['itemUsage'] },
|
|
808
|
+
"Item Rate" => lambda {|it| it['itemRate'] },
|
|
809
|
+
"Item Cost" => lambda {|it| format_money(it['itemCost']) },
|
|
810
|
+
"Item Price" => lambda {|it| format_money(it['itemrPrice']) },
|
|
811
|
+
"Item Tax" => lambda {|it| format_money(it['itemTax']) },
|
|
812
|
+
"Item Term" => lambda {|it| it['itemTerm'] },
|
|
813
|
+
#"Tax Type" => lambda {|it| it['taxType'] },
|
|
814
|
+
"Created" => lambda {|it| format_local_dt(it['dateCreated']) },
|
|
815
|
+
"Updated" => lambda {|it| format_local_dt(it['lastUpdated']) }
|
|
816
|
+
}
|
|
817
|
+
print_description_list(description_cols, line_item, options)
|
|
818
|
+
print reset,"\n"
|
|
819
|
+
end
|
|
820
|
+
return 0, nil
|
|
821
|
+
end
|
|
822
|
+
|
|
387
823
|
private
|
|
388
824
|
|
|
389
825
|
# def find_invoice_by_name_or_id(val)
|
|
@@ -426,10 +862,8 @@ class Morpheus::Cli::InvoicesCommand
|
|
|
426
862
|
def format_invoice_ref_type(it)
|
|
427
863
|
if it['refType'] == 'ComputeZone'
|
|
428
864
|
"Cloud"
|
|
429
|
-
elsif it['refType'] == '
|
|
430
|
-
|
|
431
|
-
elsif it['refType'] == 'ComputeServer'
|
|
432
|
-
"Host"
|
|
865
|
+
# elsif it['refType'] == 'ComputeServer'
|
|
866
|
+
# "Host"
|
|
433
867
|
elsif it['refType'] == 'ComputeServerGroup'
|
|
434
868
|
"Cluster"
|
|
435
869
|
elsif it['refType'] == 'ComputeSite'
|