morpheus-cli 4.2.22 → 5.2.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (69) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/Dockerfile +1 -1
  4. data/lib/morpheus/api/api_client.rb +30 -0
  5. data/lib/morpheus/api/billing_interface.rb +34 -0
  6. data/lib/morpheus/api/catalog_item_types_interface.rb +9 -0
  7. data/lib/morpheus/api/deploy_interface.rb +1 -1
  8. data/lib/morpheus/api/deployments_interface.rb +20 -1
  9. data/lib/morpheus/api/forgot_password_interface.rb +17 -0
  10. data/lib/morpheus/api/instances_interface.rb +16 -2
  11. data/lib/morpheus/api/rest_interface.rb +0 -6
  12. data/lib/morpheus/api/roles_interface.rb +14 -0
  13. data/lib/morpheus/api/search_interface.rb +13 -0
  14. data/lib/morpheus/api/servers_interface.rb +14 -0
  15. data/lib/morpheus/api/service_catalog_interface.rb +89 -0
  16. data/lib/morpheus/api/usage_interface.rb +18 -0
  17. data/lib/morpheus/cli.rb +7 -3
  18. data/lib/morpheus/cli/apps.rb +6 -27
  19. data/lib/morpheus/cli/backup_jobs_command.rb +3 -0
  20. data/lib/morpheus/cli/backups_command.rb +3 -0
  21. data/lib/morpheus/cli/catalog_item_types_command.rb +622 -0
  22. data/lib/morpheus/cli/cli_command.rb +70 -21
  23. data/lib/morpheus/cli/commands/standard/curl_command.rb +3 -5
  24. data/lib/morpheus/cli/commands/standard/history_command.rb +3 -1
  25. data/lib/morpheus/cli/commands/standard/man_command.rb +74 -40
  26. data/lib/morpheus/cli/commands/standard/source_command.rb +1 -1
  27. data/lib/morpheus/cli/commands/standard/update_command.rb +76 -0
  28. data/lib/morpheus/cli/containers_command.rb +14 -24
  29. data/lib/morpheus/cli/cypher_command.rb +6 -2
  30. data/lib/morpheus/cli/deploy.rb +199 -90
  31. data/lib/morpheus/cli/deployments.rb +341 -28
  32. data/lib/morpheus/cli/deploys.rb +206 -41
  33. data/lib/morpheus/cli/error_handler.rb +7 -0
  34. data/lib/morpheus/cli/forgot_password.rb +133 -0
  35. data/lib/morpheus/cli/groups.rb +1 -1
  36. data/lib/morpheus/cli/health_command.rb +59 -2
  37. data/lib/morpheus/cli/hosts.rb +295 -35
  38. data/lib/morpheus/cli/instances.rb +247 -130
  39. data/lib/morpheus/cli/invoices_command.rb +37 -19
  40. data/lib/morpheus/cli/library_option_lists_command.rb +15 -7
  41. data/lib/morpheus/cli/library_option_types_command.rb +5 -2
  42. data/lib/morpheus/cli/logs_command.rb +9 -6
  43. data/lib/morpheus/cli/mixins/accounts_helper.rb +12 -7
  44. data/lib/morpheus/cli/mixins/backups_helper.rb +2 -4
  45. data/lib/morpheus/cli/mixins/deployments_helper.rb +31 -3
  46. data/lib/morpheus/cli/mixins/option_source_helper.rb +1 -1
  47. data/lib/morpheus/cli/mixins/print_helper.rb +46 -21
  48. data/lib/morpheus/cli/mixins/provisioning_helper.rb +108 -5
  49. data/lib/morpheus/cli/option_types.rb +271 -22
  50. data/lib/morpheus/cli/ping.rb +0 -1
  51. data/lib/morpheus/cli/remote.rb +35 -12
  52. data/lib/morpheus/cli/reports_command.rb +99 -30
  53. data/lib/morpheus/cli/roles.rb +453 -113
  54. data/lib/morpheus/cli/search_command.rb +182 -0
  55. data/lib/morpheus/cli/service_catalog_command.rb +1474 -0
  56. data/lib/morpheus/cli/setup.rb +1 -1
  57. data/lib/morpheus/cli/shell.rb +33 -11
  58. data/lib/morpheus/cli/storage_providers_command.rb +40 -56
  59. data/lib/morpheus/cli/tasks.rb +29 -32
  60. data/lib/morpheus/cli/usage_command.rb +203 -0
  61. data/lib/morpheus/cli/user_settings_command.rb +1 -0
  62. data/lib/morpheus/cli/users.rb +12 -1
  63. data/lib/morpheus/cli/version.rb +1 -1
  64. data/lib/morpheus/cli/virtual_images.rb +429 -254
  65. data/lib/morpheus/cli/whoami.rb +6 -6
  66. data/lib/morpheus/cli/workflows.rb +33 -40
  67. data/lib/morpheus/formatters.rb +75 -7
  68. data/lib/morpheus/terminal.rb +6 -2
  69. metadata +14 -2
@@ -9,7 +9,7 @@ class Morpheus::Cli::Setup
9
9
 
10
10
  set_command_name :setup
11
11
 
12
- register_subcommands :init
12
+ # register_subcommands :init
13
13
 
14
14
  # no authorization needed
15
15
  def connect(options={})
@@ -92,6 +92,13 @@ class Morpheus::Cli::Shell
92
92
  def recalculate_auto_complete_commands
93
93
  @morpheus_commands = Morpheus::Cli::CliRegistry.all.keys.reject {|k| [:shell].include?(k) }
94
94
  @shell_commands = [:clear, :history, :reload, :help, :exit]
95
+ @shell_command_descriptions = {
96
+ :clear => "Clear terminal output and move cursor to the top",
97
+ :history => "View morpheus shell command history",
98
+ :reload => "Reload the shell, can be useful when developing",
99
+ :help => "Print this help",
100
+ :exit => "Exit the morpheus shell"
101
+ }
95
102
  @alias_commands = Morpheus::Cli::CliRegistry.all_aliases.keys
96
103
  @exploded_commands = []
97
104
  Morpheus::Cli::CliRegistry.all.each do |cmd, klass|
@@ -336,6 +343,11 @@ class Morpheus::Cli::Shell
336
343
  #Morpheus::Logging::DarkPrinter.puts "Shell command: #{input}"
337
344
  input = input.to_s.strip
338
345
 
346
+ # allow pasting in commands that have 'morpheus ' prefix
347
+ if input[0..(prog_name.size)] == "#{prog_name} "
348
+ input = input[(prog_name.size + 1)..-1] || ""
349
+ end
350
+
339
351
  if !input.empty?
340
352
 
341
353
  if input == 'exit'
@@ -345,26 +357,36 @@ class Morpheus::Cli::Shell
345
357
  return 0
346
358
  #exit 0
347
359
  elsif input == 'help'
360
+ out = ""
348
361
  if @temporary_shell_mode
349
- puts "You are in a (temporary) morpheus shell"
362
+ out << "You are in a (temporary) morpheus shell\n"
350
363
  else
351
- puts "You are in a morpheus shell."
364
+ out << "You are in a morpheus shell.\n"
352
365
  end
353
- puts "See the available commands below."
366
+ out << "See the available commands below.\n"
354
367
 
355
- puts "\nCommands:"
368
+ out << "\nCommands:"
356
369
  # commands = @morpheus_commands + @shell_commands
357
- @morpheus_commands.sort.each {|cmd|
358
- puts "\t#{cmd.to_s}"
370
+ # @morpheus_commands.sort.each {|cmd|
371
+ # out << "\t#{cmd.to_s}\n"
372
+ # }
373
+ sorted_commands = Morpheus::Cli::CliRegistry.all.values.sort { |x,y| x.command_name.to_s <=> y.command_name.to_s }
374
+ sorted_commands.each {|cmd|
375
+ # JD: not ready to show description yet, gotta finish filling in every command first
376
+ # maybe change 'View and manage' to something more concise like 'Manage'
377
+ # out << "\t#{cmd.command_name.to_s.ljust(28, ' ')} #{cmd.command_description}\n"
378
+ out << "\t#{cmd.command_name.to_s}\n"
359
379
  }
360
380
  #puts "\n"
361
- puts "\nShell Commands:"
381
+ out << "\nShell Commands:\n"
362
382
  @shell_commands.each {|cmd|
363
- puts "\t#{cmd.to_s}"
383
+ # out << "\t#{cmd.to_s.ljust(28, ' ')} #{@shell_command_descriptions ? @shell_command_descriptions[cmd] : ''}\n"
384
+ out << "\t#{cmd.to_s}\n"
364
385
  }
365
- puts "\n"
366
- puts "For more information, see https://github.com/gomorpheus/morpheus-cli/wiki"
367
- #print "\n"
386
+ out << "\n"
387
+ out << "For more information, see https://github.com/gomorpheus/morpheus-cli/wiki"
388
+ out << "\n"
389
+ print out
368
390
  return 0
369
391
  elsif input =~ /^\s*#/
370
392
  Morpheus::Logging::DarkPrinter.puts "ignored comment: #{input}" if Morpheus::Logging.debug?
@@ -42,71 +42,39 @@ class Morpheus::Cli::StorageProvidersCommand
42
42
  def list(args)
43
43
  options = {}
44
44
  params = {}
45
+ ref_ids = []
45
46
  optparse = Morpheus::Cli::OptionParser.new do |opts|
46
- opts.banner = subcommand_usage()
47
- build_common_options(opts, options, [:list, :json, :yaml, :csv, :fields, :json, :dry_run, :remote])
47
+ opts.banner = subcommand_usage("[search]")
48
+ build_standard_list_options(opts, options)
48
49
  opts.footer = "List storage buckets."
49
50
  end
50
51
  optparse.parse!(args)
51
- if args.count != 0
52
- print_error Morpheus::Terminal.angry_prompt
53
- puts_error "wrong number of arguments, expected 0 and got #{args.count}\n#{optparse}"
54
- return 1
55
- end
56
52
  connect(options)
57
- begin
58
- params.merge!(parse_list_options(options))
59
- @storage_providers_interface.setopts(options)
60
- if options[:dry_run]
61
- print_dry_run @storage_providers_interface.dry.list(params)
62
- return
63
- end
64
- json_response = @storage_providers_interface.list(params)
65
- storage_providers = json_response["storageBuckets"]
66
- if options[:json]
67
- puts as_json(json_response, options, "storageBuckets")
68
- return 0
69
- elsif options[:yaml]
70
- puts as_yaml(json_response, options, "storageBuckets")
71
- return 0
72
- elsif options[:csv]
73
- puts records_as_csv(storage_providers, options)
74
- return 0
75
- end
76
- title = "Morpheus Storage Buckets"
77
- subtitles = []
78
- subtitles += parse_list_subtitles(options)
79
- print_h1 title, subtitles
80
- if storage_providers.empty?
53
+ if args.count > 0
54
+ options[:phrase] = args.join(" ")
55
+ end
56
+ params.merge!(parse_list_options(options))
57
+ @storage_providers_interface.setopts(options)
58
+ if options[:dry_run]
59
+ print_dry_run @storage_providers_interface.dry.list(params)
60
+ return
61
+ end
62
+ json_response = @storage_providers_interface.list(params)
63
+ storage_buckets = json_response['storageBuckets']
64
+ render_response(json_response, options, 'storageBuckets') do
65
+ print_h1 "Morpheus Storage Buckets", parse_list_subtitles(options), options
66
+ if storage_buckets.empty?
81
67
  print cyan,"No storage buckets found.",reset,"\n"
82
68
  else
83
- rows = storage_providers.collect {|storage_provider|
84
- row = {
85
- id: storage_provider['id'],
86
- name: storage_provider['name'],
87
- provider: format_storage_provider_type(storage_provider),
88
- bucket: format_bucket_name(storage_provider),
89
- backups: storage_provider['defaultBackupTarget'] ? 'Yes' : 'No',
90
- deployments: storage_provider['defaultDeploymentTarget'] ? 'Yes' : 'No',
91
- virtualImages: storage_provider['defaultVirtualImageTarget'] ? 'Yes' : 'No',
92
- }
93
- row
94
- }
95
- columns = [:id, :name, {:provider => {:display_name => "Provider Type".upcase} }, {:bucket => {:display_name => "Bucket Name".upcase} }, :backups, :deployments]
96
- if options[:include_fields]
97
- columns = options[:include_fields]
98
- rows = storage_providers
99
- end
100
- print cyan
101
- print as_pretty_table(rows, columns, options)
102
- print reset
103
- print_results_pagination(json_response, {:label => "storage bucket", :n_label => "storage buckets"})
69
+ print as_pretty_table(storage_buckets, storage_bucket_column_definitions.upcase_keys!, options)
70
+ print_results_pagination(json_response)
104
71
  end
105
72
  print reset,"\n"
106
- return 0
107
- rescue RestClient::Exception => e
108
- print_rest_exception(e, options)
109
- exit 1
73
+ end
74
+ if storage_buckets.empty?
75
+ return 1, "no storage buckets found"
76
+ else
77
+ return 0, nil
110
78
  end
111
79
  end
112
80
 
@@ -1232,6 +1200,22 @@ class Morpheus::Cli::StorageProvidersCommand
1232
1200
 
1233
1201
  private
1234
1202
 
1203
+ def storage_bucket_column_definitions()
1204
+ {
1205
+ "ID" => 'id',
1206
+ "Name" => 'name',
1207
+ # "Description" => 'description',
1208
+ "Provider Type" => lambda {|it| format_storage_provider_type(it) },
1209
+ "Bucket Name" => lambda {|it| format_bucket_name(it) },
1210
+ # "Source" => lambda {|it| it['source'] },
1211
+ "Backups" => lambda {|it| format_boolean(it['defaultBackupTarget']) },
1212
+ "Deployments" => lambda {|it| format_boolean(it['defaultDeploymentTarget']) },
1213
+ "Virtual Images" => lambda {|it| format_boolean(it['defaultVirtualImageTarget']) },
1214
+ # "Archive Snapshots" => lambda {|it| format_boolean(it['copyToStore']) },
1215
+ # "Created" => lambda {|it| format_local_dt(it['dateCreated']) },
1216
+ # "Updated" => lambda {|it| format_local_dt(it['lastUpdated']) },
1217
+ }
1218
+ end
1235
1219
 
1236
1220
  def get_storage_provider_types()
1237
1221
  [
@@ -27,34 +27,31 @@ class Morpheus::Cli::Tasks
27
27
  params = {}
28
28
  options = {}
29
29
  optparse = Morpheus::Cli::OptionParser.new do |opts|
30
- opts.banner = subcommand_usage()
30
+ opts.banner = subcommand_usage("[search]")
31
31
  opts.on('-t', '--type x,y,z', Array, "Filter by task type code(s)") do |val|
32
32
  params['taskTypeCodes'] = val
33
33
  end
34
- build_common_options(opts, options, [:list, :query, :json, :yaml, :csv, :fields, :dry_run, :remote])
34
+ build_standard_list_options(opts, options)
35
+ opts.footer = "List tasks."
35
36
  end
36
37
  optparse.parse!(args)
38
+ connect(options)
37
39
  if args.count > 0
38
- raise_command_error "wrong number of arguments, expected 0 and got (#{args.count}) #{args.join(' ')}\n#{optparse}"
40
+ options[:phrase] = args.join(" ")
39
41
  end
40
- connect(options)
41
- begin
42
- params.merge!(parse_list_options(options))
43
- @tasks_interface.setopts(options)
44
- if options[:dry_run]
45
- print_dry_run @tasks_interface.dry.list(params)
46
- return
47
- end
48
- json_response = @tasks_interface.list(params)
49
-
50
- render_result = render_with_format(json_response, options, 'tasks')
51
- return 0 if render_result
52
-
42
+ params.merge!(parse_list_options(options))
43
+ @tasks_interface.setopts(options)
44
+ if options[:dry_run]
45
+ print_dry_run @tasks_interface.dry.list(params)
46
+ return
47
+ end
48
+ json_response = @tasks_interface.list(params)
49
+ tasks = json_response['tasks']
50
+ render_response(json_response, options, 'tasks') do
53
51
  title = "Morpheus Tasks"
54
52
  subtitles = []
55
53
  subtitles += parse_list_subtitles(options)
56
54
  print_h1 title, subtitles
57
- tasks = json_response['tasks']
58
55
  if tasks.empty?
59
56
  print cyan,"No tasks found.",reset,"\n"
60
57
  else
@@ -63,11 +60,13 @@ class Morpheus::Cli::Tasks
63
60
  print_results_pagination(json_response)
64
61
  end
65
62
  print reset,"\n"
66
- return 0
67
- rescue RestClient::Exception => e
68
- print_rest_exception(e, options)
69
- exit 1
70
63
  end
64
+ if tasks.empty?
65
+ return 1, "no tasks found"
66
+ else
67
+ return 0, nil
68
+ end
69
+
71
70
  end
72
71
 
73
72
  def get(args)
@@ -334,10 +333,9 @@ class Morpheus::Cli::Tasks
334
333
  build_common_options(opts, options, [:options, :payload, :json, :dry_run, :quiet, :remote])
335
334
  end
336
335
  optparse.parse!(args)
337
- if args.count > 1
338
- raise_command_error "wrong number of arguments, expected 1 and got (#{args.count}) #{args.join(' ')}\n#{optparse}"
339
- end
336
+ #verify_args!(args:args, count:1, optparse:optparse)
340
337
  if args[0]
338
+ # task_name = args[0]
341
339
  task_name = args[0]
342
340
  end
343
341
  # if task_name.nil? || task_type_name.nil?
@@ -425,6 +423,9 @@ class Morpheus::Cli::Tasks
425
423
  has_file_content = true
426
424
  it['fieldContext'] = nil
427
425
  it['fieldName'] = 'file'
426
+ # this should be required right!? fix api optionType data plz
427
+ it['required'] = true
428
+ it['defaultValue'] = 'local'
428
429
  else
429
430
  if it['fieldContext'].nil? || it['fieldContext'] == ''
430
431
  it['fieldContext'] = 'taskOptions'
@@ -658,9 +659,7 @@ class Morpheus::Cli::Tasks
658
659
  build_common_options(opts, options, [:options, :payload, :json, :dry_run, :quiet, :remote])
659
660
  end
660
661
  optparse.parse!(args)
661
- if args.count != 1
662
- raise_command_error "wrong number of arguments, expected 1 and got (#{args.count}) #{args.join(' ')}\n#{optparse}"
663
- end
662
+ verify_args!(args:args, count:1, optparse:optparse)
664
663
  task_name = args[0]
665
664
  connect(options)
666
665
  begin
@@ -734,7 +733,6 @@ class Morpheus::Cli::Tasks
734
733
 
735
734
  def remove(args)
736
735
  params = {}
737
- task_name = args[0]
738
736
  options = {}
739
737
  optparse = Morpheus::Cli::OptionParser.new do |opts|
740
738
  opts.banner = subcommand_usage("[task]")
@@ -744,10 +742,8 @@ class Morpheus::Cli::Tasks
744
742
  end
745
743
  end
746
744
  optparse.parse!(args)
747
- if args.count < 1
748
- puts optparse
749
- exit 1
750
- end
745
+ verify_args!(args:args, count:1, optparse:optparse)
746
+ task_name = args[0]
751
747
  connect(options)
752
748
  begin
753
749
  task = find_task_by_name_or_id(task_name)
@@ -820,6 +816,7 @@ class Morpheus::Cli::Tasks
820
816
  if args.count != 1
821
817
  raise_command_error "wrong number of arguments, expected 1 and got (#{args.count}) #{args.join(' ')}\n#{optparse}"
822
818
  end
819
+ verify_args!(args:args, count:1, optparse:optparse)
823
820
  task_name = args[0]
824
821
  connect(options)
825
822
  begin
@@ -0,0 +1,203 @@
1
+ require 'morpheus/cli/cli_command'
2
+
3
+ # CLI command usages
4
+ # UI is Costing - Usage
5
+ # API is /usage and returns usages
6
+ class Morpheus::Cli::UsageCommand
7
+ include Morpheus::Cli::CliCommand
8
+ include Morpheus::Cli::OptionSourceHelper
9
+
10
+ set_command_name :'usage'
11
+
12
+ register_subcommands :list, :get
13
+
14
+ def connect(opts)
15
+ @api_client = establish_remote_appliance_connection(opts)
16
+ @usage_interface = @api_client.usage
17
+ end
18
+
19
+ def handle(args)
20
+ handle_subcommand(args)
21
+ end
22
+
23
+ def list(args)
24
+ options = {}
25
+ params = {}
26
+ ref_ids = []
27
+ optparse = Morpheus::Cli::OptionParser.new do |opts|
28
+ opts.banner = subcommand_usage("[search]")
29
+ opts.on( '-t', '--type TYPE', "Filter by type" ) do |val|
30
+ params['type'] = parse_usage_type(val)
31
+ end
32
+ opts.on( '-c', '--cloud CLOUD', "Filter by cloud" ) do |val|
33
+ options[:cloud] = val
34
+ end
35
+ opts.on('--start DATE', String, "Start date in the format YYYY-MM-DD.") do |val|
36
+ params['startDate'] = val # parse_time(val).utc.iso8601
37
+ end
38
+ opts.on('--end DATE', String, "End date in the format YYYY-MM-DD. Default is the current date.") do |val|
39
+ params['endDate'] = val # parse_time(val).utc.iso8601
40
+ end
41
+ opts.on('--sigdig DIGITS', "Significant digits when rounding cost values for display as currency. Default is 5.") do |val|
42
+ options[:sigdig] = val.to_i
43
+ end
44
+ build_standard_list_options(opts, options)
45
+ opts.footer = "List usages."
46
+ end
47
+ optparse.parse!(args)
48
+ connect(options)
49
+ # verify_args!(args:args, optparse:optparse, count:0)
50
+ if args.count > 0
51
+ options[:phrase] = args.join(" ")
52
+ end
53
+ params.merge!(parse_list_options(options))
54
+ # --cloud
55
+ if options[:cloud]
56
+ params['cloud'] = parse_id_list(options[:cloud]).collect {|cloud_id|
57
+ if cloud_id.to_s =~ /\A\d{1,}\Z/
58
+ cloud_id
59
+ else
60
+ cloud = find_cloud_option(cloud_id)
61
+ return 1 if cloud.nil?
62
+ cloud['id']
63
+ end
64
+ }
65
+ end
66
+
67
+ @usage_interface.setopts(options)
68
+ if options[:dry_run]
69
+ print_dry_run @usage_interface.dry.list(params)
70
+ return
71
+ end
72
+ json_response = @usage_interface.list(params)
73
+ usages = json_response[usage_list_key]
74
+ render_response(json_response, options, usage_list_key) do
75
+ print_h1 "Morpheus Usages", parse_list_subtitles(options), options
76
+ if usages.empty?
77
+ print cyan,"No usages found.",reset,"\n"
78
+ else
79
+ list_columns = {
80
+ "ID" => 'id',
81
+ "Cloud" => 'zoneName',
82
+ "Type" => lambda {|it| format_usage_type(it) },
83
+ "Name" => 'name',
84
+ "Plan" => 'planName',
85
+ "Start Date" => lambda {|it| format_local_dt(it['startDate']) },
86
+ "End Date" => lambda {|it| format_local_dt(it['endDate']) },
87
+ "Usage Status" => lambda {|it| format_usage_status(it) },
88
+ "Usage Cost" => lambda {|it| format_money(it['costDetails']['cost'], it['currency'] || 'USD', {sigdig: (options[:sigdig] || 5)}) },
89
+ "Usage Price" => lambda {|it| format_money(it['price'], it['currency'] || 'USD', {sigdig: (options[:sigdig] || 5)}) },
90
+ }
91
+ print as_pretty_table(usages, list_columns.upcase_keys!, options)
92
+ print_results_pagination(json_response)
93
+ end
94
+ print reset,"\n"
95
+ end
96
+ if usages.empty?
97
+ return 1, "no usages found"
98
+ else
99
+ return 0, nil
100
+ end
101
+ end
102
+
103
+ def get(args)
104
+ params = {}
105
+ options = {}
106
+ optparse = Morpheus::Cli::OptionParser.new do |opts|
107
+ opts.banner = subcommand_usage("[usage]")
108
+ build_standard_get_options(opts, options)
109
+ opts.footer = <<-EOT
110
+ Get details about a specific usage.
111
+ [usage] is required. This is the id of a usage record.
112
+ EOT
113
+ end
114
+ optparse.parse!(args)
115
+ verify_args!(args:args, optparse:optparse, min:1)
116
+ connect(options)
117
+ id_list = parse_id_list(args)
118
+ return run_command_for_each_arg(id_list) do |arg|
119
+ _get(arg, params, options)
120
+ end
121
+ end
122
+
123
+ def _get(id, params, options)
124
+ usage = nil
125
+ @usage_interface.setopts(options)
126
+ if options[:dry_run]
127
+ print_dry_run @usage_interface.dry.get(id, params)
128
+ return
129
+ end
130
+ json_response = @usage_interface.get(id, params)
131
+ usage = json_response[usage_object_key]
132
+ render_response(json_response, options, usage_object_key) do
133
+ print_h1 "Usage Details", [], options
134
+ print cyan
135
+ show_columns = {
136
+ "ID" => 'id',
137
+ "Cloud" => 'zoneName',
138
+ "Type" => lambda {|it| format_usage_type(it) },
139
+ "Name" => 'name',
140
+ "Plan" => 'planName',
141
+ "Start Date" => lambda {|it| format_local_dt(it['startDate']) },
142
+ "End Date" => lambda {|it| format_local_dt(it['endDate']) },
143
+ "Usage Status" => lambda {|it| format_usage_status(it) },
144
+ "Usage Cost" => lambda {|it| format_money(it['costDetails']['cost'], it['currency'] || 'USD', {sigdig: (options[:sigdig] || 5)}) },
145
+ "Usage Price" => lambda {|it| format_money(it['price'], it['currency'] || 'USD', {sigdig: (options[:sigdig] || 5)}) },
146
+ }
147
+ print_description_list(show_columns, usage)
148
+
149
+ # print_h2 "Applicable Prices"
150
+
151
+ print reset,"\n"
152
+ end
153
+ return 0, nil
154
+ end
155
+
156
+ private
157
+
158
+ def usage_object_key
159
+ 'usage'
160
+ end
161
+
162
+ def usage_list_key
163
+ 'usages'
164
+ end
165
+
166
+ def format_usage_type(usage)
167
+ #return usage['costDetails']['refType']
168
+ ref_type = usage['costDetails'] ? usage['costDetails']['refType'].to_s : ''
169
+ if ref_type == 'discoveredServer'
170
+ 'Discovered'
171
+ elsif ref_type == 'computeServer'
172
+ 'Host'
173
+ elsif ref_type == 'container'
174
+ 'Container'
175
+ else
176
+ ref_type.to_s
177
+ end
178
+ end
179
+
180
+ def parse_usage_type(val)
181
+ type_string = val.to_s.downcase
182
+ if type_string == 'discoveredServer'
183
+ 'discoveredServer'
184
+ elsif type_string == 'host'
185
+ 'computeServer'
186
+ elsif type_string == 'container'
187
+ 'container'
188
+ else
189
+ val
190
+ end
191
+ end
192
+
193
+ def format_usage_status(usage, return_color=cyan)
194
+ #return usage['status'].to_s.capitalize
195
+ status_string = usage['status'].to_s
196
+ if status_string == 'stopped'
197
+ return "#{red}#{status_string.upcase}#{return_color}"
198
+ else
199
+ return "#{green}#{status_string.upcase}#{return_color}"
200
+ end
201
+ end
202
+
203
+ end