morpheus-cli 5.0.0 → 5.2.2

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.
Files changed (61) 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 +16 -0
  5. data/lib/morpheus/api/billing_interface.rb +1 -0
  6. data/lib/morpheus/api/deploy_interface.rb +1 -1
  7. data/lib/morpheus/api/deployments_interface.rb +20 -1
  8. data/lib/morpheus/api/forgot_password_interface.rb +17 -0
  9. data/lib/morpheus/api/instances_interface.rb +16 -2
  10. data/lib/morpheus/api/invoices_interface.rb +12 -3
  11. data/lib/morpheus/api/search_interface.rb +13 -0
  12. data/lib/morpheus/api/servers_interface.rb +14 -0
  13. data/lib/morpheus/api/service_catalog_interface.rb +89 -0
  14. data/lib/morpheus/api/usage_interface.rb +18 -0
  15. data/lib/morpheus/cli.rb +6 -2
  16. data/lib/morpheus/cli/apps.rb +3 -23
  17. data/lib/morpheus/cli/budgets_command.rb +389 -319
  18. data/lib/morpheus/cli/{catalog_command.rb → catalog_item_types_command.rb} +182 -67
  19. data/lib/morpheus/cli/cli_command.rb +51 -10
  20. data/lib/morpheus/cli/commands/standard/curl_command.rb +26 -13
  21. data/lib/morpheus/cli/commands/standard/history_command.rb +9 -3
  22. data/lib/morpheus/cli/commands/standard/man_command.rb +74 -40
  23. data/lib/morpheus/cli/containers_command.rb +0 -24
  24. data/lib/morpheus/cli/cypher_command.rb +6 -2
  25. data/lib/morpheus/cli/dashboard_command.rb +260 -20
  26. data/lib/morpheus/cli/deploy.rb +199 -90
  27. data/lib/morpheus/cli/deployments.rb +341 -28
  28. data/lib/morpheus/cli/deploys.rb +206 -41
  29. data/lib/morpheus/cli/error_handler.rb +7 -0
  30. data/lib/morpheus/cli/forgot_password.rb +133 -0
  31. data/lib/morpheus/cli/groups.rb +1 -1
  32. data/lib/morpheus/cli/health_command.rb +59 -2
  33. data/lib/morpheus/cli/hosts.rb +271 -39
  34. data/lib/morpheus/cli/instances.rb +228 -129
  35. data/lib/morpheus/cli/invoices_command.rb +100 -20
  36. data/lib/morpheus/cli/jobs_command.rb +94 -92
  37. data/lib/morpheus/cli/library_option_lists_command.rb +1 -1
  38. data/lib/morpheus/cli/library_option_types_command.rb +10 -5
  39. data/lib/morpheus/cli/logs_command.rb +9 -6
  40. data/lib/morpheus/cli/mixins/accounts_helper.rb +5 -1
  41. data/lib/morpheus/cli/mixins/deployments_helper.rb +31 -2
  42. data/lib/morpheus/cli/mixins/print_helper.rb +13 -27
  43. data/lib/morpheus/cli/mixins/provisioning_helper.rb +108 -5
  44. data/lib/morpheus/cli/option_types.rb +271 -22
  45. data/lib/morpheus/cli/remote.rb +35 -10
  46. data/lib/morpheus/cli/reports_command.rb +99 -30
  47. data/lib/morpheus/cli/roles.rb +193 -155
  48. data/lib/morpheus/cli/search_command.rb +182 -0
  49. data/lib/morpheus/cli/service_catalog_command.rb +1474 -0
  50. data/lib/morpheus/cli/setup.rb +1 -1
  51. data/lib/morpheus/cli/shell.rb +33 -11
  52. data/lib/morpheus/cli/tasks.rb +29 -32
  53. data/lib/morpheus/cli/usage_command.rb +64 -11
  54. data/lib/morpheus/cli/version.rb +1 -1
  55. data/lib/morpheus/cli/virtual_images.rb +429 -254
  56. data/lib/morpheus/cli/whoami.rb +6 -6
  57. data/lib/morpheus/cli/workflows.rb +33 -40
  58. data/lib/morpheus/formatters.rb +75 -18
  59. data/lib/morpheus/terminal.rb +6 -2
  60. metadata +10 -4
  61. data/lib/morpheus/cli/mixins/catalog_helper.rb +0 -66
@@ -160,15 +160,15 @@ EOT
160
160
  print cyan
161
161
  print_description_list({
162
162
  "ID" => 'id',
163
- "Tenant" => lambda {|it| (it['account'] ? it['account']['name'] : '') + (@is_master_account ? " (Master Tenant)" : '') },
164
- "First Name" => 'firstName',
165
- "Last Name" => 'lastName',
166
- # "Name" => 'displayName',
167
- #"Name" => lambda {|it| it['firstName'] ? it['displayName'] : '' },
168
163
  "Username" => 'username',
164
+ # "First Name" => 'firstName',
165
+ # "Last Name" => 'lastName',
166
+ # "Name" => 'displayName',
167
+ "Name" => lambda {|it| "#{it['firstName']} #{it['lastName']}".strip },
169
168
  "Email" => 'email',
169
+ "Tenant" => lambda {|it| (it['account'] ? it['account']['name'] : '') + (@is_master_account ? " (Master Tenant)" : '') },
170
170
  "Role" => lambda {|it| format_user_role_names(it) },
171
- #"Remote" => lambda {|it| display_appliance(@appliance_name, @appliance_url) },
171
+ "Remote" => lambda {|it| display_appliance(@appliance_name, @appliance_url) },
172
172
  }, @current_user)
173
173
  print cyan
174
174
 
@@ -32,7 +32,7 @@ class Morpheus::Cli::Workflows
32
32
  params = {}
33
33
  options = {}
34
34
  optparse = Morpheus::Cli::OptionParser.new do |opts|
35
- opts.banner = subcommand_usage()
35
+ opts.banner = subcommand_usage("[search]")
36
36
  opts.on("-t", "--type TYPE", "Type of workflow. i.e. provision or operation. Default is provision.") do |val|
37
37
  workflow_type = val.to_s.downcase
38
38
  if workflow_type.include?('provision')
@@ -42,50 +42,43 @@ class Morpheus::Cli::Workflows
42
42
  end
43
43
  params['type'] = workflow_type
44
44
  end
45
- build_common_options(opts, options, [:list, :query, :json, :yaml, :csv, :fields, :dry_run, :remote])
45
+ build_standard_list_options(opts, options)
46
+ opts.footer = "List workflows."
46
47
  end
47
48
  optparse.parse!(args)
48
49
  connect(options)
49
- begin
50
- params.merge!(parse_list_options(options))
51
- @task_sets_interface.setopts(options)
52
- if options[:dry_run]
53
- print_dry_run @task_sets_interface.dry.get(params)
54
- return
55
- end
56
- json_response = @task_sets_interface.get(params)
57
- task_sets = json_response['taskSets']
58
- # print result and return output
59
- if options[:json]
60
- puts as_json(json_response, options, "taskSets")
61
- return 0
62
- elsif options[:csv]
63
- puts records_as_csv(json_response['taskSets'], options)
64
- return 0
65
- elsif options[:yaml]
66
- puts as_yaml(json_response, options, "taskSets")
67
- return 0
50
+ if args.count > 0
51
+ options[:phrase] = args.join(" ")
52
+ end
53
+ params.merge!(parse_list_options(options))
54
+ @task_sets_interface.setopts(options)
55
+ if options[:dry_run]
56
+ print_dry_run @task_sets_interface.dry.get(params)
57
+ return
58
+ end
59
+ json_response = @task_sets_interface.get(params)
60
+ task_sets = json_response['taskSets']
61
+ render_response(json_response, options, 'taskSets') do
62
+ title = "Morpheus Workflows"
63
+ subtitles = []
64
+ subtitles += parse_list_subtitles(options)
65
+ if params['type']
66
+ subtitles << "Type: #{params['type']}"
67
+ end
68
+ print_h1 title, subtitles
69
+ if task_sets.empty?
70
+ print cyan,"No workflows found.",reset,"\n"
68
71
  else
69
- task_sets = json_response['taskSets']
70
- title = "Morpheus Workflows"
71
- subtitles = []
72
- subtitles += parse_list_subtitles(options)
73
- if params['type']
74
- subtitles << "Type: #{params['type']}"
75
- end
76
- print_h1 title, subtitles
77
- if task_sets.empty?
78
- print cyan,"No workflows found.",reset,"\n"
79
- else
80
- print cyan
81
- print_workflows_table(task_sets)
82
- print_results_pagination(json_response)
83
- end
84
- print reset,"\n"
72
+ print cyan
73
+ print_workflows_table(task_sets)
74
+ print_results_pagination(json_response)
85
75
  end
86
- rescue RestClient::Exception => e
87
- print_rest_exception(e, options)
88
- exit 1
76
+ print reset,"\n"
77
+ end
78
+ if task_sets.empty?
79
+ return 1, "no workflows found"
80
+ else
81
+ return 0, nil
89
82
  end
90
83
  end
91
84
 
@@ -15,11 +15,7 @@ def parse_time(dt, format=nil)
15
15
  elsif dt.is_a?(String)
16
16
  result = nil
17
17
  err = nil
18
- begin
19
- result = Time.parse(dt)
20
- rescue => e
21
- err = e
22
- end
18
+
23
19
  if !result
24
20
  format ||= DEFAULT_TIME_FORMAT
25
21
  if format
@@ -29,12 +25,26 @@ def parse_time(dt, format=nil)
29
25
  err = e
30
26
  end
31
27
  end
32
- if !result
33
- begin
34
- result = Time.strptime(dt, ALTERNATE_TIME_FORMAT)
35
- rescue => e
36
- err = e
37
- end
28
+ end
29
+ if !result
30
+ begin
31
+ result = Time.strptime(dt, ALTERNATE_TIME_FORMAT)
32
+ rescue => e
33
+ # err = e
34
+ end
35
+ end
36
+ if !result
37
+ begin
38
+ result = Time.strptime(dt, DEFAULT_DATE_FORMAT)
39
+ rescue => e
40
+ # err = e
41
+ end
42
+ end
43
+ if !result
44
+ begin
45
+ result = Time.parse(dt)
46
+ rescue => e
47
+ err = e
38
48
  end
39
49
  end
40
50
  if result
@@ -352,7 +362,7 @@ def format_number(n, opts={})
352
362
  delim = opts[:delimiter] || ','
353
363
  out = ""
354
364
  parts = n.to_s.split(".")
355
- whole_number = parts[0]
365
+ whole_number = parts[0].to_s
356
366
  decimal = parts[1] ? parts[1..-1].join('.') : nil
357
367
  i = 0
358
368
  whole_number.reverse.each_char do |c|
@@ -366,10 +376,16 @@ def format_number(n, opts={})
366
376
  end
367
377
 
368
378
  def format_sig_dig(n, sigdig=3, min_sigdig=nil, pad_zeros=false)
369
- v = sprintf("%.#{sigdig}f", n)
370
- if pad_zeros != true
371
- v = v.to_f.to_s
379
+ v = ""
380
+ if sigdig && sigdig > 0
381
+ # v = n.to_i.round(sigdig).to_s
382
+ v = sprintf("%.#{sigdig}f", n)
383
+ else
384
+ v = n.to_i.round().to_s
372
385
  end
386
+ # if pad_zeros != true
387
+ # v = v.to_f.to_s
388
+ # end
373
389
  if min_sigdig
374
390
  v_parts = v.split(".")
375
391
  decimal_str = v_parts[1]
@@ -383,12 +399,18 @@ def format_sig_dig(n, sigdig=3, min_sigdig=nil, pad_zeros=false)
383
399
  end
384
400
 
385
401
  def currency_sym(currency)
386
- Money::Currency.new((currency || 'usd').to_sym).symbol
402
+ Money::Currency.new((currency || 'USD').to_sym).symbol
387
403
  end
388
404
 
389
405
  # returns currency amount formatted like "$4,5123.00". 0.00 is formatted as "$0"
390
406
  # this is not ideal
391
- def format_currency(amount, currency='usd', opts={})
407
+ def format_currency(amount, currency='USD', opts={})
408
+ # currency '' should probably error, like money gem does
409
+ if currency.to_s.empty?
410
+ currency = 'USD'
411
+ end
412
+ currency = currency.to_s.upcase
413
+
392
414
  amount = amount.to_f
393
415
  if amount == 0
394
416
  return currency_sym(currency).to_s + "0"
@@ -397,8 +419,9 @@ def format_currency(amount, currency='usd', opts={})
397
419
  # return currency_sym(currency).to_s + "#{amount}"
398
420
  else
399
421
  sigdig = opts[:sigdig] ? opts[:sigdig].to_i : 2 # max decimal digits
400
- min_sigdig = opts[:min_sigdig] ? opts[:min_sigdig].to_i : 2 # min decimal digits
422
+ min_sigdig = opts[:min_sigdig] ? opts[:min_sigdig].to_i : (sigdig || 2) # min decimal digits
401
423
  display_value = format_sig_dig(amount, sigdig, min_sigdig, opts[:pad_zeros])
424
+ display_value = format_number(display_value) # commas
402
425
  rtn = currency_sym(currency).to_s + display_value
403
426
  if amount.to_i < 0
404
427
  rtn = "(#{rtn})"
@@ -415,3 +438,37 @@ alias :format_money :format_currency
415
438
  # def format_money(amount, currency='usd', opts={})
416
439
  # format_currency(amount, currency, opts)
417
440
  # end
441
+
442
+ def format_list(items, conjunction="", limit=nil)
443
+ items = items ? items.clone : []
444
+ num_items = items.size
445
+ if limit
446
+ items = items.first(limit)
447
+ end
448
+ last_item = items.pop
449
+ if items.empty?
450
+ return "#{last_item}"
451
+ else
452
+ if limit && limit < num_items
453
+ items << last_item
454
+ last_item = "(#{num_items - items.size} more)"
455
+ end
456
+ return items.join(", ") + (conjunction.to_s.empty? ? ", " : " #{conjunction} ") + "#{last_item}"
457
+ end
458
+ end
459
+
460
+ def anded_list(items, limit=nil)
461
+ format_list(items, "and", limit)
462
+ end
463
+
464
+ def ored_list(items, limit=nil)
465
+ format_list(items, "or", limit)
466
+ end
467
+
468
+ def format_name_values(obj)
469
+ if obj.is_a?(Hash)
470
+ obj.collect {|k,v| "#{k}: #{v}"}.join(", ")
471
+ else
472
+ ""
473
+ end
474
+ end
@@ -277,8 +277,12 @@ module Morpheus
277
277
  end
278
278
  end
279
279
  out << "Commands:\n"
280
- Morpheus::Cli::CliRegistry.all.keys.sort.each {|cmd|
281
- out << "\t#{cmd.to_s}\n"
280
+ sorted_commands = Morpheus::Cli::CliRegistry.all.values.sort { |x,y| x.command_name.to_s <=> y.command_name.to_s }
281
+ sorted_commands.each {|cmd|
282
+ # JD: not ready to show description yet, gotta finish filling in every command first
283
+ # maybe change 'View and manage' to something more concise like 'Manage'
284
+ # out << "\t#{cmd.command_name.to_s.ljust(28, ' ')} #{cmd.command_description}\n"
285
+ out << "\t#{cmd.command_name.to_s}\n"
282
286
  }
283
287
  # out << "Options:\n"
284
288
  out << optparse.to_s
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: morpheus-cli
3
3
  version: !ruby/object:Gem::Version
4
- version: 5.0.0
4
+ version: 5.2.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - David Estes
@@ -11,7 +11,7 @@ authors:
11
11
  autorequire:
12
12
  bindir: bin
13
13
  cert_chain: []
14
- date: 2020-09-29 00:00:00.000000000 Z
14
+ date: 2020-12-15 00:00:00.000000000 Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: bundler
@@ -207,6 +207,7 @@ files:
207
207
  - lib/morpheus/api/execute_schedules_interface.rb
208
208
  - lib/morpheus/api/execution_request_interface.rb
209
209
  - lib/morpheus/api/file_copy_request_interface.rb
210
+ - lib/morpheus/api/forgot_password_interface.rb
210
211
  - lib/morpheus/api/group_policies_interface.rb
211
212
  - lib/morpheus/api/groups_interface.rb
212
213
  - lib/morpheus/api/guidance_interface.rb
@@ -273,10 +274,12 @@ files:
273
274
  - lib/morpheus/api/reports_interface.rb
274
275
  - lib/morpheus/api/rest_interface.rb
275
276
  - lib/morpheus/api/roles_interface.rb
277
+ - lib/morpheus/api/search_interface.rb
276
278
  - lib/morpheus/api/security_group_rules_interface.rb
277
279
  - lib/morpheus/api/security_groups_interface.rb
278
280
  - lib/morpheus/api/server_types_interface.rb
279
281
  - lib/morpheus/api/servers_interface.rb
282
+ - lib/morpheus/api/service_catalog_interface.rb
280
283
  - lib/morpheus/api/service_plans_interface.rb
281
284
  - lib/morpheus/api/setup_interface.rb
282
285
  - lib/morpheus/api/storage_providers_interface.rb
@@ -284,6 +287,7 @@ files:
284
287
  - lib/morpheus/api/subnets_interface.rb
285
288
  - lib/morpheus/api/task_sets_interface.rb
286
289
  - lib/morpheus/api/tasks_interface.rb
290
+ - lib/morpheus/api/usage_interface.rb
287
291
  - lib/morpheus/api/user_groups_interface.rb
288
292
  - lib/morpheus/api/user_settings_interface.rb
289
293
  - lib/morpheus/api/user_sources_interface.rb
@@ -307,7 +311,7 @@ files:
307
311
  - lib/morpheus/cli/blueprints_command.rb
308
312
  - lib/morpheus/cli/boot_scripts_command.rb
309
313
  - lib/morpheus/cli/budgets_command.rb
310
- - lib/morpheus/cli/catalog_command.rb
314
+ - lib/morpheus/cli/catalog_item_types_command.rb
311
315
  - lib/morpheus/cli/change_password_command.rb
312
316
  - lib/morpheus/cli/cli_command.rb
313
317
  - lib/morpheus/cli/cli_registry.rb
@@ -354,6 +358,7 @@ files:
354
358
  - lib/morpheus/cli/execution_request_command.rb
355
359
  - lib/morpheus/cli/expression_parser.rb
356
360
  - lib/morpheus/cli/file_copy_request_command.rb
361
+ - lib/morpheus/cli/forgot_password.rb
357
362
  - lib/morpheus/cli/groups.rb
358
363
  - lib/morpheus/cli/guidance_command.rb
359
364
  - lib/morpheus/cli/health_command.rb
@@ -384,7 +389,6 @@ files:
384
389
  - lib/morpheus/cli/logs_command.rb
385
390
  - lib/morpheus/cli/mixins/accounts_helper.rb
386
391
  - lib/morpheus/cli/mixins/backups_helper.rb
387
- - lib/morpheus/cli/mixins/catalog_helper.rb
388
392
  - lib/morpheus/cli/mixins/deployments_helper.rb
389
393
  - lib/morpheus/cli/mixins/infrastructure_helper.rb
390
394
  - lib/morpheus/cli/mixins/library_helper.rb
@@ -428,8 +432,10 @@ files:
428
432
  - lib/morpheus/cli/remote.rb
429
433
  - lib/morpheus/cli/reports_command.rb
430
434
  - lib/morpheus/cli/roles.rb
435
+ - lib/morpheus/cli/search_command.rb
431
436
  - lib/morpheus/cli/security_group_rules.rb
432
437
  - lib/morpheus/cli/security_groups.rb
438
+ - lib/morpheus/cli/service_catalog_command.rb
433
439
  - lib/morpheus/cli/service_plans_command.rb
434
440
  - lib/morpheus/cli/setup.rb
435
441
  - lib/morpheus/cli/shell.rb
@@ -1,66 +0,0 @@
1
- require 'morpheus/cli/mixins/print_helper'
2
- # Mixin for Morpheus::Cli command classes
3
- # Provides common methods for infrastructure management
4
- module Morpheus::Cli::CatalogHelper
5
-
6
- def self.included(klass)
7
- klass.send :include, Morpheus::Cli::PrintHelper
8
- end
9
-
10
- def catalog_item_types_interface
11
- raise "#{self.class} has not defined @catalog_item_types_interface" if @catalog_item_types_interface.nil?
12
- @catalog_item_types_interface
13
- end
14
-
15
- # def service_catalog_interface
16
- # raise "#{self.class} has not defined @service_catalog_interface" if @service_catalog_interface.nil?
17
- # @service_catalog_interface
18
- # end
19
-
20
- def catalog_item_type_object_key
21
- 'catalogItemType'
22
- end
23
-
24
- def catalog_item_type_list_key
25
- 'catalogItemTypes'
26
- end
27
-
28
- def find_catalog_item_type_by_name_or_id(val)
29
- if val.to_s =~ /\A\d{1,}\Z/
30
- return find_catalog_item_type_by_id(val)
31
- else
32
- return find_catalog_item_type_by_name(val)
33
- end
34
- end
35
-
36
- def find_catalog_item_type_by_id(id)
37
- begin
38
- json_response = catalog_item_types_interface.get(id.to_i)
39
- return json_response[catalog_item_type_object_key]
40
- rescue RestClient::Exception => e
41
- if e.response && e.response.code == 404
42
- print_red_alert "catalog_item_type not found by id '#{id}'"
43
- else
44
- raise e
45
- end
46
- end
47
- end
48
-
49
- def find_catalog_item_type_by_name(name)
50
- json_response = catalog_item_types_interface.list({name: name.to_s})
51
- catalog_item_types = json_response[catalog_item_type_list_key]
52
- if catalog_item_types.empty?
53
- print_red_alert "catalog_item_type not found by name '#{name}'"
54
- return nil
55
- elsif catalog_item_types.size > 1
56
- print_red_alert "#{catalog_item_types.size} catalog_item_types found by name '#{name}'"
57
- puts_error as_pretty_table(catalog_item_types, [:id, :name], {color:red})
58
- print_red_alert "Try using ID instead"
59
- print reset,"\n"
60
- return nil
61
- else
62
- return catalog_item_types[0]
63
- end
64
- end
65
-
66
- end