morpheus-cli 6.0.2 → 6.1.1

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.
@@ -544,13 +544,12 @@ EOT
544
544
  def update_cart(args)
545
545
  options = {}
546
546
  params = {}
547
- payload = {}
548
547
  optparse = Morpheus::Cli::OptionParser.new do |opts|
549
548
  opts.banner = subcommand_usage("--name [name]")
550
549
  opts.on('--name [NAME]', String, "Set an optional name for your catalog order") do |val|
551
550
  options[:options]['name'] = val.to_s
552
551
  end
553
- build_standard_update_options(opts, options, [:sigdig])
552
+ build_standard_update_options(opts, options, [:payloads, :sigdig])
554
553
  opts.footer = <<-EOT
555
554
  Update your cart settings, such as name.
556
555
  EOT
@@ -560,29 +559,26 @@ EOT
560
559
  connect(options)
561
560
  # fetch current cart
562
561
  # cart = @service_catalog_interface.get_cart()['cart']
563
- payload = {}
564
562
  update_cart_object_key = 'order'
565
- if options[:payload]
566
- payload = options[:payload]
563
+ payloads = parse_payloads(options, update_cart_object_key) do |payload|
567
564
  payload.deep_merge!({update_cart_object_key => parse_passed_options(options)})
568
- else
569
- payload.deep_merge!({update_cart_object_key => parse_passed_options(options)})
570
- payload.deep_merge!({update_cart_object_key => params})
571
565
  if payload[update_cart_object_key].empty? # || options[:no_prompt]
572
566
  raise_command_error "Specify at least one option to update.\n#{optparse}"
573
567
  end
574
568
  end
575
- @service_catalog_interface.setopts(options)
576
- if options[:dry_run]
577
- print_dry_run @service_catalog_interface.dry.update_cart(payload)
578
- return
579
- end
580
- json_response = @service_catalog_interface.update_cart(payload)
581
- #cart = json_response['cart']
582
- #cart = @service_catalog_interface.get_cart()['cart']
583
- render_response(json_response, options, 'cart') do
584
- print_green_success "Updated cart"
585
- get_cart([] + (options[:remote] ? ["-r",options[:remote]] : []))
569
+ process_payloads(payloads, options) do |payload|
570
+ @service_catalog_interface.setopts(options)
571
+ if options[:dry_run]
572
+ print_dry_run @service_catalog_interface.dry.update_cart(payload)
573
+ next
574
+ end
575
+ json_response = @service_catalog_interface.update_cart(payload)
576
+ #cart = json_response['cart']
577
+ #cart = @service_catalog_interface.get_cart()['cart']
578
+ render_response(json_response, options, 'cart') do
579
+ print_green_success "Updated cart"
580
+ get_cart([] + (options[:remote] ? ["-r",options[:remote]] : []))
581
+ end
586
582
  end
587
583
  return 0, nil
588
584
  end
@@ -590,7 +586,6 @@ EOT
590
586
  def add(args)
591
587
  options = {}
592
588
  params = {}
593
- payload = {}
594
589
  type_id = nil
595
590
  workflow_context = nil
596
591
  workflow_target = nil
@@ -613,7 +608,7 @@ EOT
613
608
  workflow_target = val.to_s
614
609
  end
615
610
  opts.add_hidden_option('--sigdig')
616
- build_standard_update_options(opts, options, [:sigdig])
611
+ build_standard_update_options(opts, options, [:payloads, :sigdig])
617
612
  opts.footer = <<-EOT
618
613
  Add an item to your cart
619
614
  [type] is required, this is name or id of a catalog item type.
@@ -626,13 +621,8 @@ EOT
626
621
  if args.count > 0
627
622
  type_id = args.join(" ")
628
623
  end
629
- payload = {}
630
624
  add_item_object_key = 'item'
631
- payload = {add_item_object_key => {} }
632
- if options[:payload]
633
- payload = options[:payload]
634
- payload.deep_merge!({add_item_object_key => parse_passed_options(options)})
635
- else
625
+ payloads = parse_payloads(options, add_item_object_key) do |payload|
636
626
  payload.deep_merge!({add_item_object_key => parse_passed_options(options)})
637
627
  # prompt for Type
638
628
  if type_id
@@ -725,49 +715,45 @@ EOT
725
715
  if options[:validate_only]
726
716
  params['validate'] = true
727
717
  end
728
- @service_catalog_interface.setopts(options)
729
- if options[:dry_run]
730
- print_dry_run @service_catalog_interface.dry.create_cart_item(payload, params)
731
- return
732
- end
733
- json_response = @service_catalog_interface.create_cart_item(payload, params)
734
- cart_item = json_response['item']
735
- render_response(json_response, options) do
736
- if options[:validate_only]
737
- if json_response['success']
738
- print_h2 "Validated Cart Item", [], options
739
- cart_item_columns = {
740
- "Type" => lambda {|it| it['type']['name'] rescue '' },
741
- #"Qty" => lambda {|it| it['quantity'] },
742
- "Price" => lambda {|it| it['price'] ? format_money(it['price'] , it['currency'], {sigdig:options[:sigdig] || default_sigdig}) : "No pricing configured" },
743
- "Status" => lambda {|it|
744
- status_string = format_catalog_item_status(it)
745
- if it['errorMessage'].to_s != ""
746
- status_string << " - #{it['errorMessage']}"
747
- end
748
- status_string
749
- },
750
- #"Config" => lambda {|it| truncate_string(format_name_values(it['config']), 50) }
751
- }
752
- print as_pretty_table([cart_item], cart_item_columns.upcase_keys!)
753
- print reset, "\n"
754
- print_green_success(json_response['msg'] || "Item is valid")
755
- print reset, "\n"
718
+ process_payloads(payloads, options) do |payload|
719
+ @service_catalog_interface.setopts(options)
720
+ if options[:dry_run]
721
+ print_dry_run @service_catalog_interface.dry.create_cart_item(payload, params)
722
+ next
723
+ end
724
+ json_response = @service_catalog_interface.create_cart_item(payload, params)
725
+ cart_item = json_response['item']
726
+ render_response(json_response, options) do
727
+ if options[:validate_only]
728
+ if json_response['success']
729
+ print_h2 "Validated Cart Item", [], options
730
+ cart_item_columns = {
731
+ "Type" => lambda {|it| it['type']['name'] rescue '' },
732
+ #"Qty" => lambda {|it| it['quantity'] },
733
+ "Price" => lambda {|it| it['price'] ? format_money(it['price'] , it['currency'], {sigdig:options[:sigdig] || default_sigdig}) : "No pricing configured" },
734
+ "Status" => lambda {|it|
735
+ status_string = format_catalog_item_status(it)
736
+ if it['errorMessage'].to_s != ""
737
+ status_string << " - #{it['errorMessage']}"
738
+ end
739
+ status_string
740
+ },
741
+ #"Config" => lambda {|it| truncate_string(format_name_values(it['config']), 50) }
742
+ }
743
+ print as_pretty_table([cart_item], cart_item_columns.upcase_keys!)
744
+ print reset, "\n"
745
+ print_green_success(json_response['msg'] || "Item is valid")
746
+ print reset, "\n"
747
+ else
748
+ # not needed because it will be http 400
749
+ print_rest_errors(json_response, options)
750
+ end
756
751
  else
757
- # not needed because it will be http 400
758
- print_rest_errors(json_response, options)
752
+ print_green_success "Added item to cart"
753
+ get_cart([] + (options[:remote] ? ["-r",options[:remote]] : []))
759
754
  end
760
- else
761
- print_green_success "Added item to cart"
762
- get_cart([] + (options[:remote] ? ["-r",options[:remote]] : []))
763
755
  end
764
756
  end
765
- if json_response['success']
766
- return 0, nil
767
- else
768
- # not needed because it will be http 400
769
- return 1, json_response['msg'] || 'request failed'
770
- end
771
757
  end
772
758
 
773
759
  def update_cart_item(args)
@@ -882,7 +868,6 @@ EOT
882
868
  def checkout(args)
883
869
  options = {}
884
870
  params = {}
885
- payload = {}
886
871
  optparse = Morpheus::Cli::OptionParser.new do |opts|
887
872
  opts.banner = subcommand_usage()
888
873
  build_standard_add_options(opts, options, [:auto_confirm, :sigdig])
@@ -936,7 +921,6 @@ EOT
936
921
  def add_order(args)
937
922
  options = {}
938
923
  params = {}
939
- payload = {}
940
924
  type_id = nil
941
925
  workflow_context = nil
942
926
  workflow_target = nil
@@ -961,7 +945,7 @@ EOT
961
945
  opts.on('--target ID', String, "Target Resource (Instance or Server) for operational workflow types") do |val|
962
946
  workflow_target = val.to_s
963
947
  end
964
- build_standard_add_options(opts, options, [:sigdig])
948
+ build_standard_add_options(opts, options, [:payloads, :sigdig])
965
949
  opts.footer = <<-EOT
966
950
  Place an order for new inventory.
967
951
  This allows creating a new order without using the cart.
@@ -978,14 +962,8 @@ EOT
978
962
  end
979
963
  payload = {}
980
964
  order_object_key = 'order'
981
- payload = {order_object_key => {} }
982
- passed_options = parse_passed_options(options)
983
- if options[:payload]
984
- payload = options[:payload]
985
- payload.deep_merge!({order_object_key => passed_options}) unless passed_options.empty?
986
- else
987
- payload.deep_merge!({order_object_key => passed_options}) unless passed_options.empty?
988
-
965
+ payloads = parse_payloads(options, order_object_key) do |payload|
966
+ payload.deep_merge!({order_object_key => {}})
989
967
  # Prompt for 1-N Types
990
968
  # still_prompting = options[:no_prompt] != true
991
969
  still_prompting = true
@@ -1106,36 +1084,32 @@ EOT
1106
1084
  params['validate'] = true
1107
1085
  #payload['validate'] = true
1108
1086
  end
1109
- @service_catalog_interface.setopts(options)
1110
- if options[:dry_run]
1111
- print_dry_run @service_catalog_interface.dry.create_order(payload, params)
1112
- return
1113
- end
1114
- json_response = @service_catalog_interface.create_order(payload, params)
1115
- order = json_response['order'] || json_response['cart']
1116
- render_response(json_response, options) do
1117
- if options[:validate_only]
1118
- if json_response['success']
1119
- print_h2 "Review Order", [], options
1120
- print_order_details(order, options)
1121
- print_green_success(json_response['msg'] || "Order is valid")
1122
- print reset, "\n"
1087
+ process_payloads(payloads, options) do |payload|
1088
+ @service_catalog_interface.setopts(options)
1089
+ if options[:dry_run]
1090
+ print_dry_run @service_catalog_interface.dry.create_order(payload, params)
1091
+ next
1092
+ end
1093
+ json_response = @service_catalog_interface.create_order(payload, params)
1094
+ order = json_response['order'] || json_response['cart']
1095
+ render_response(json_response, options) do
1096
+ if options[:validate_only]
1097
+ if json_response['success']
1098
+ print_h2 "Review Order", [], options
1099
+ print_order_details(order, options)
1100
+ print_green_success(json_response['msg'] || "Order is valid")
1101
+ print reset, "\n"
1102
+ else
1103
+ # not needed because it will be http 400
1104
+ print_rest_errors(json_response, options)
1105
+ end
1123
1106
  else
1124
- # not needed because it will be http 400
1125
- print_rest_errors(json_response, options)
1107
+ print_green_success "Order placed"
1108
+ print_h2 "Order Details", [], options
1109
+ print_order_details(order, options)
1126
1110
  end
1127
- else
1128
- print_green_success "Order placed"
1129
- print_h2 "Order Details", [], options
1130
- print_order_details(order, options)
1131
1111
  end
1132
1112
  end
1133
- if json_response['success']
1134
- return 0, nil
1135
- else
1136
- # not needed because it will be http 400
1137
- return 1, json_response['msg'] || 'request failed'
1138
- end
1139
1113
  end
1140
1114
 
1141
1115
  def remove(args)
@@ -297,7 +297,29 @@ EOT
297
297
  if access.count > 0
298
298
  access.each {|it| it['access'] = format_access_string(it['access'], available_access_levels)}
299
299
 
300
- if ['features', 'instance_types'].include?(field)
300
+ if ['features'].include?(field)
301
+ if access.find {|it| !it['subCategory'].to_s.empty? }
302
+ rows = access.collect do |it|
303
+ {
304
+ code: it['code'],
305
+ name: it['name'],
306
+ category: it['subCategory'].to_s.titleize,
307
+ access: format_access_string(it['access']),
308
+ }
309
+ end
310
+ if options[:sort]
311
+ rows.sort! {|a,b| a[options[:sort]] <=> b[options[:sort]] }
312
+ else
313
+ rows.sort! {|a,b| [a[:category],a[:name],a[:code]] <=> [b[:category],b[:name],b[:code]] }
314
+ end
315
+ if options[:direction] == 'desc'
316
+ rows.reverse!
317
+ end
318
+ print as_pretty_table(rows, [:category, :name, :code, :access], options)
319
+ else
320
+ print as_pretty_table(access, [:name, :code, :access], options)
321
+ end
322
+ elsif ['instance_types','report_types'].include?(field)
301
323
  print as_pretty_table(access, [:name, :code, :access], options)
302
324
  else
303
325
  print as_pretty_table(access, [:name, :access], options)
@@ -422,7 +444,29 @@ EOT
422
444
  if access.count > 0
423
445
  access.each {|it| it['access'] = format_access_string(it['access'], available_access_levels)}
424
446
 
425
- if ['features', 'instance_types', 'report_types'].include?(field)
447
+ if ['features'].include?(field)
448
+ if access.find {|it| !it['subCategory'].to_s.empty? }
449
+ rows = access.collect do |it|
450
+ {
451
+ code: it['code'],
452
+ name: it['name'],
453
+ category: it['subCategory'].to_s.titleize,
454
+ access: format_access_string(it['access']),
455
+ }
456
+ end
457
+ if options[:sort]
458
+ rows.sort! {|a,b| a[options[:sort]] <=> b[options[:sort]] }
459
+ else
460
+ rows.sort! {|a,b| [a[:category],a[:name],a[:code]] <=> [b[:category],b[:name],b[:code]] }
461
+ end
462
+ if options[:direction] == 'desc'
463
+ rows.reverse!
464
+ end
465
+ print as_pretty_table(rows, [:category, :name, :code, :access], options)
466
+ else
467
+ print as_pretty_table(access, [:name, :code, :access], options)
468
+ end
469
+ elsif ['instance_types','report_types'].include?(field)
426
470
  print as_pretty_table(access, [:name, :code, :access], options)
427
471
  else
428
472
  print as_pretty_table(access, [:name, :access], options)
@@ -12,7 +12,7 @@ module Morpheus::Cli::BackupsHelper
12
12
  @backups_interface
13
13
  end
14
14
 
15
- def backup_jobs_interfaces
15
+ def backup_jobs_interface
16
16
  raise "#{self.class} has not defined @backup_jobs_interface" if @backup_jobs_interface.nil?
17
17
  @backup_jobs_interface
18
18
  end
@@ -719,7 +719,7 @@ module Morpheus::Cli::ProvisioningHelper
719
719
  service_plan = nil
720
720
 
721
721
  prompt_service_plan = -> {
722
- service_plans_json = instances_interface.service_plans({zoneId: cloud_id, layoutId: layout['id'], siteId: group_id}.merge(resource_pool.nil? ? {} : {'resourcePoolId' => resource_pool['id']}))
722
+ service_plans_json = instances_interface.service_plans({zoneId: cloud_id, layoutId: layout['id'], siteId: group_id}.merge(resource_pool.nil? ? {} : {'poolId' => resource_pool['id'], 'resourcePoolId' => resource_pool['id']}))
723
723
  service_plans = service_plans_json["plans"]
724
724
  if locked_fields.include?('plan.id')
725
725
  plan_id = options[:options]['plan']['id'] rescue nil
@@ -773,8 +773,8 @@ module Morpheus::Cli::ProvisioningHelper
773
773
  has_zone_pools = provision_type && provision_type["id"] && provision_type["hasZonePools"]
774
774
  if has_zone_pools
775
775
  # pluck out the resourcePoolId option type to prompt for
776
- resource_pool_option_type = option_type_list.find {|opt| ['resourcePool','resourcePoolId','azureResourceGroupId'].include?(opt['fieldName']) }
777
- option_type_list = option_type_list.reject {|opt| ['resourcePool','resourcePoolId','azureResourceGroupId'].include?(opt['fieldName']) }
776
+ resource_pool_option_type = option_type_list.find {|opt| ['poolId','resourcePool','resourcePoolId','azureResourceGroupId'].include?(opt['fieldName']) }
777
+ option_type_list = option_type_list.reject {|opt| ['poolId','resourcePool','resourcePoolId','azureResourceGroupId'].include?(opt['fieldName']) }
778
778
 
779
779
  resource_pool_options = options_interface.options_for_source('zonePools', {groupId: group_id, siteId: group_id, zoneId: cloud_id, cloudId: cloud_id, instanceTypeId: instance_type['id'], layoutId: layout["id"]}.merge(service_plan.nil? ? {} : {planId: service_plan["id"]}))['data']
780
780
  if options[:resource_pool]
@@ -836,7 +836,7 @@ module Morpheus::Cli::ProvisioningHelper
836
836
  # add selectable datastores for resource pool
837
837
  if options[:select_datastore]
838
838
  begin
839
- selectable_datastores = datastores_interface.list({'zoneId' => cloud_id, 'siteId' => group_id, 'resourcePoolId' => resource_pool['id']})
839
+ selectable_datastores = datastores_interface.list({'zoneId' => cloud_id, 'siteId' => group_id, 'poolId' => resource_pool['id'], 'resourcePoolId' => resource_pool['id']})
840
840
  service_plan['datastores'] = {'clusters' => [], 'datastores' => []}
841
841
  ['clusters', 'datastores'].each do |type|
842
842
  service_plan['datastores'][type] ||= []
@@ -1538,7 +1538,7 @@ module Morpheus::Cli::ProvisioningHelper
1538
1538
 
1539
1539
  if datastore_options.empty? && storage_type['hasDatastore'] != false
1540
1540
  begin
1541
- datastore_res = datastores_interface.list({'resourcePoolId' => current_root_volume['resourcePoolId'], 'zoneId' => options['zoneId'], 'siteId' => options['siteId']})['datastores']
1541
+ datastore_res = datastores_interface.list({'poolId' => current_root_volume['resourcePoolId'], 'resourcePoolId' => current_root_volume['resourcePoolId'], 'zoneId' => options['zoneId'], 'siteId' => options['siteId']})['datastores']
1542
1542
  datastore_res.each do |opt|
1543
1543
  datastore_options << {'name' => opt['name'], 'value' => opt['id']}
1544
1544
  end
@@ -1578,7 +1578,7 @@ module Morpheus::Cli::ProvisioningHelper
1578
1578
  no_prompt = (options[:no_prompt] || (options[:options] && options[:options][:no_prompt]))
1579
1579
  network_interfaces = []
1580
1580
  api_params = {zoneId: zone_id, provisionTypeId: provision_type_id}.merge(options[:api_params] || {})
1581
- if pool_id.to_s =~ /\A\d{1,}\Z/
1581
+ if pool_id
1582
1582
  api_params[:poolId] = pool_id
1583
1583
  end
1584
1584
 
@@ -1,6 +1,6 @@
1
1
 
2
2
  module Morpheus
3
3
  module Cli
4
- VERSION = "6.0.2"
4
+ VERSION = "6.1.1"
5
5
  end
6
6
  end
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: 6.0.2
4
+ version: 6.1.1
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: 2023-04-14 00:00:00.000000000 Z
14
+ date: 2023-05-17 00:00:00.000000000 Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: bundler
@@ -260,7 +260,9 @@ files:
260
260
  - lib/morpheus/api/library_spec_templates_interface.rb
261
261
  - lib/morpheus/api/license_interface.rb
262
262
  - lib/morpheus/api/load_balancer_monitors_interface.rb
263
+ - lib/morpheus/api/load_balancer_pool_nodes_interface.rb
263
264
  - lib/morpheus/api/load_balancer_pools_interface.rb
265
+ - lib/morpheus/api/load_balancer_pools_secondary_interface.rb
264
266
  - lib/morpheus/api/load_balancer_profiles_interface.rb
265
267
  - lib/morpheus/api/load_balancer_types_interface.rb
266
268
  - lib/morpheus/api/load_balancer_virtual_servers_interface.rb
@@ -434,6 +436,7 @@ files:
434
436
  - lib/morpheus/cli/commands/library_upgrades_command.rb
435
437
  - lib/morpheus/cli/commands/license.rb
436
438
  - lib/morpheus/cli/commands/load_balancer_monitors.rb
439
+ - lib/morpheus/cli/commands/load_balancer_pool_nodes.rb
437
440
  - lib/morpheus/cli/commands/load_balancer_pools.rb
438
441
  - lib/morpheus/cli/commands/load_balancer_profiles.rb
439
442
  - lib/morpheus/cli/commands/load_balancer_types.rb