morpheus-cli 8.0.1 → 8.0.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c8074c5d41cd8ca2aa6f199a0b85f22f7c2b8d3647b2788604d42424b7abbd9b
4
- data.tar.gz: 8176b21a71b63466b537ca4d43933e06411ae374cbb159ab451f4e37042299e5
3
+ metadata.gz: 06ea65156f0a57e7af971494347aae4844608a6cb877087dc9394a127841a75e
4
+ data.tar.gz: a93ddec1dc9e647e23a111a168126dbfc3b683d04844731f5bc53a461305b140
5
5
  SHA512:
6
- metadata.gz: 05414d569b3e9d323ca0ebf0ff86778e9656f84b92af1a2e6520e826351dc444eb1c6d6721ef7137ffbe603be703832dcd15f4e14c31f28005b6de7c2cc454f8
7
- data.tar.gz: fca09ddb93cf6cc58401d1652803a61d220fe9999427a931b0fed515c5a8e0a2933013299323722739a7f65c9b9b42edffe4a62972cad85e9b5651a4fcded2df
6
+ metadata.gz: 9ca9b136bd006211eed46cd89103c2e7af9157d8111595f4e90b09a7a1e014570405256d64401c78311503e3d4b0aaecf5690526b2014985d79c515e0093eba3
7
+ data.tar.gz: f1355c6ec99b7a05e068e215ba4581a75a712bef545b661a04e7a31ad0b1711071d7f65c316e938171da60d66d0a297898068f5efb70e750a7dc987b2f12014e
data/Dockerfile CHANGED
@@ -1,5 +1,5 @@
1
1
  FROM ruby:2.7.5
2
2
 
3
- RUN gem install morpheus-cli -v 8.0.1
3
+ RUN gem install morpheus-cli -v 8.0.2
4
4
 
5
5
  ENTRYPOINT ["morpheus"]
@@ -1278,7 +1278,7 @@ module Morpheus
1278
1278
  elsif options[:remote_url]
1279
1279
  credentials = Morpheus::Cli::Credentials.new(@appliance_name, @appliance_url)
1280
1280
  unless options[:skip_login]
1281
- @wallet = credentials.request_credentials(options, @do_save_credentials)
1281
+ @wallet = credentials.request_credentials(options.merge({dry_run:false}), @do_save_credentials)
1282
1282
  end
1283
1283
  else
1284
1284
  credentials = Morpheus::Cli::Credentials.new(@appliance_name, @appliance_url)
@@ -1293,7 +1293,7 @@ module Morpheus
1293
1293
 
1294
1294
  if @wallet.nil? || @wallet['access_token'].nil?
1295
1295
  unless options[:skip_login]
1296
- @wallet = credentials.request_credentials(options, @do_save_credentials)
1296
+ @wallet = credentials.request_credentials(options.merge({dry_run:false}), @do_save_credentials)
1297
1297
  end
1298
1298
  end
1299
1299
 
@@ -1767,7 +1767,22 @@ module Morpheus
1767
1767
  output = records.collect { |record|
1768
1768
  options[:select_fields].collect { |field|
1769
1769
  value = get_object_value(record, field)
1770
- value.is_a?(String) ? value : JSON.fast_generate(value)
1770
+ if value.is_a?(String)
1771
+ value
1772
+ else
1773
+ if options[:json]
1774
+ as_json(value, options)
1775
+ elsif options[:yaml]
1776
+ output = as_yaml(value, options)
1777
+ elsif options[:csv]
1778
+ as_csv(value, nil, options)
1779
+ else
1780
+ # default behavior
1781
+ # value.is_a?(String) ? value : as_json(value, options)
1782
+ do_pretty = options.key?(:pretty_json) ? options[:pretty_json] : false # or true?
1783
+ do_pretty ? JSON.pretty_generate(value) : JSON.fast_generate(value)
1784
+ end
1785
+ end
1771
1786
  }.join(options[:delim] || ",")
1772
1787
  }.join(options[:newline] || "\n")
1773
1788
  elsif options[:json]
@@ -6,6 +6,7 @@ class Morpheus::Cli::Clusters
6
6
  include Morpheus::Cli::ProcessesHelper
7
7
  include Morpheus::Cli::WhoamiHelper
8
8
  include Morpheus::Cli::AccountsHelper
9
+ include Morpheus::Cli::ExecutionRequestHelper
9
10
 
10
11
  register_subcommands :list, :count, :get, :view, :add, :update, :remove, :logs, :history, {:'history-details' => :history_details}, {:'history-event' => :history_event_details}
11
12
  register_subcommands :list_workers, :add_worker, :remove_worker, :update_worker_count
@@ -607,7 +608,7 @@ class Morpheus::Cli::Clusters
607
608
  end
608
609
 
609
610
  # Controller type
610
- server_types = @server_types_interface.list({computeTypeId: cluster_type['controllerTypes'].first['id'], zoneTypeId: cloud['zoneType']['id'], useZoneProvisionTypes: true})['serverTypes'].reject {|it| it['provisionType']['code'] == 'manual'}
611
+ server_types = @server_types_interface.list({computeTypeId: cluster_type['controllerTypes'].first['id'], zoneTypeId: cloud['zoneType']['id'], useZoneProvisionTypes: true})['serverTypes'].reject {|it| it['provisionType']['code'] == 'manual'} unless ['kubernetes-cluster', 'mvm-cluster'].include?(cluster_type_code)
611
612
  controller_provision_type = nil
612
613
  resource_pool = nil
613
614
 
@@ -802,6 +803,9 @@ class Morpheus::Cli::Clusters
802
803
  opts.on('--managed [on|off]', String, "Can be used to enable / disable managed cluster. Default is on") do |val|
803
804
  options[:managed] = val.to_s == 'on' || val.to_s == 'true' || val.to_s == '1' || val.to_s == ''
804
805
  end
806
+ opts.on('--useAgent [on|off]', String, "Use the Agent to relay communications for the Kubernetes API instead of direct.") do |val|
807
+ options[:useAgent] = val.to_s
808
+ end
805
809
  opts.on('--autoRecoverPowerState [on|off]', String, "Automatically Power On VMs") do |val|
806
810
  options[:autoRecoverPowerState] = val.to_s == 'on' || val.to_s == 'true' || val.to_s == '1' || val.to_s == ''
807
811
  end
@@ -855,6 +859,7 @@ class Morpheus::Cli::Clusters
855
859
  cluster_payload['refresh'] = options[:refresh] if options[:refresh] == true
856
860
  cluster_payload['tenant'] = options[:tenant] if !options[:tenant].nil?
857
861
  cluster_payload['integrations'] = options[:integrations] if !options[:integrations].nil?
862
+ cluster_payload['useAgent'] = options[:useAgent] if !options[:useAgent].nil?
858
863
  payload = {"cluster" => cluster_payload}
859
864
  end
860
865
 
@@ -3004,6 +3009,12 @@ class Morpheus::Cli::Clusters
3004
3009
  options = {}
3005
3010
  optparse = Morpheus::Cli::OptionParser.new do |opts|
3006
3011
  opts.banner = subcommand_usage( "[cluster] [options]")
3012
+ opts.on('--refresh [SECONDS]', String, "Refresh until execution is complete. Default interval is #{default_refresh_interval} seconds.") do |val|
3013
+ options[:refresh_interval] = val.to_s.empty? ? default_refresh_interval : val.to_f
3014
+ end
3015
+ opts.on(nil, '--no-refresh', "Do not refresh" ) do
3016
+ options[:no_refresh] = true
3017
+ end
3007
3018
  build_option_type_options(opts, options, add_datastore_option_types)
3008
3019
  build_common_options(opts, options, [:options, :payload, :json, :dry_run, :remote])
3009
3020
  opts.footer = "Add datastore to a cluster.\n" +
@@ -3059,11 +3070,19 @@ class Morpheus::Cli::Clusters
3059
3070
  json_response = @clusters_interface.create_datastore(cluster['id'], payload)
3060
3071
  if options[:json]
3061
3072
  puts as_json(json_response)
3062
- elsif json_response['success']
3063
- if json_response['msg'] == nil
3064
- print_green_success "Added datastore to cluster #{cluster['name']}"
3073
+ else
3074
+ if json_response['success']
3075
+ if json_response['msg'] == nil
3076
+ print_green_success "Adding datastore to cluster #{cluster['name']}"
3077
+ else
3078
+ print_green_success json_response['msg']
3079
+ end
3080
+ execution_id = json_response['executionId']
3081
+ if !options[:no_refresh] && execution_id
3082
+ wait_for_execution_request(json_response['executionId'], options.merge({waiting_status:['new', 'pending', 'executing']}))
3083
+ end
3065
3084
  else
3066
- print_green_success json_response['msg']
3085
+ print_red_alert "Failed to create cluster datastore #{json_response['msg']}"
3067
3086
  end
3068
3087
  end
3069
3088
  return 0
@@ -3074,6 +3093,7 @@ class Morpheus::Cli::Clusters
3074
3093
  end
3075
3094
 
3076
3095
  def remove_datastore(args)
3096
+ default_refresh_interval = 5
3077
3097
  params = {}
3078
3098
  options = {}
3079
3099
  optparse = Morpheus::Cli::OptionParser.new do |opts|
@@ -3081,6 +3101,12 @@ class Morpheus::Cli::Clusters
3081
3101
  opts.on( '-f', '--force', "Force Delete" ) do
3082
3102
  params[:force] = 'on'
3083
3103
  end
3104
+ opts.on('--refresh [SECONDS]', String, "Refresh until execution is complete. Default interval is #{default_refresh_interval} seconds.") do |val|
3105
+ options[:refresh_interval] = val.to_s.empty? ? default_refresh_interval : val.to_f
3106
+ end
3107
+ opts.on(nil, '--no-refresh', "Do not refresh" ) do
3108
+ options[:no_refresh] = true
3109
+ end
3084
3110
  build_standard_remove_options(opts, options)
3085
3111
  opts.footer = "Delete a datastore from a cluster.\n" +
3086
3112
  "[cluster] is required. This is the name or id of an existing cluster.\n" +
@@ -3114,12 +3140,18 @@ class Morpheus::Cli::Clusters
3114
3140
  return
3115
3141
  end
3116
3142
  json_response = @clusters_interface.destroy_datastore(cluster['id'], datastore['id'], params)
3117
- render_response(json_response, options) do
3118
- msg = "Datastore #{datastore['name']} is being removed from cluster #{cluster['name']}..."
3119
- if json_response['msg']
3120
- msg = json_response['msg']
3143
+ if options[:json]
3144
+ puts as_json(json_response)
3145
+ else
3146
+ if json_response['success']
3147
+ print_green_success "Datastore #{datastore['name']} is being removed from cluster #{cluster['name']}"
3148
+ execution_id = json_response['executionId']
3149
+ if !options[:no_refresh] && execution_id
3150
+ wait_for_execution_request(execution_id, options.merge({waiting_status:['new', 'pending', 'executing']}))
3151
+ end
3152
+ else
3153
+ print_red_alert "Failed to remove cluster datastore #{json_response['msg']}"
3121
3154
  end
3122
- print_green_success msg
3123
3155
  end
3124
3156
  return 0, nil
3125
3157
  end
@@ -4535,7 +4567,12 @@ class Morpheus::Cli::Clusters
4535
4567
  elsif resource_pool_options.count > 1 && !options[:no_prompt]
4536
4568
  resource_pool_id = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'resourcePool', 'type' => 'select', 'fieldLabel' => 'Resource Pool', 'selectOptions' => resource_pool_options, 'required' => true, 'skipSingleOption' => true, 'description' => 'Select resource pool.'}],options[:options],api_client, {})['resourcePool']
4537
4569
  else
4538
- resource_pool_id = resource_pool_options.first['id']
4570
+ first_option = resource_pool_options.find {|it| !it['id'].nil? }
4571
+ if first_option.nil?
4572
+ print_red_alert "Cloud #{cloud['name']} has no available resource pools"
4573
+ exit 1
4574
+ end
4575
+ resource_pool_id = first_option['id']
4539
4576
  end
4540
4577
  if resource_pool_id.to_s["poolGroup-"]
4541
4578
  resource_pool = @resource_pool_groups_interface.get(resource_pool_id)['resourcePoolGroup']
@@ -1337,14 +1337,20 @@ class Morpheus::Cli::Hosts
1337
1337
  payload[:server][:plan] = {id: service_plan["id"]}
1338
1338
 
1339
1339
  # fetch volumes
1340
- volumes_response = @servers_interface.volumes(server['id'])
1341
- current_volumes = volumes_response['volumes'].sort {|x,y| x['displayOrder'] <=> y['displayOrder'] }
1340
+ current_volumes = nil
1341
+ if server['volumes']
1342
+ current_volumes = server['volumes'].sort {|x,y| x['displayOrder'] <=> y['displayOrder'] }
1343
+ else
1344
+ volumes_response = @servers_interface.volumes(server['id'])
1345
+ current_volumes = volumes_response['volumes'].sort {|x,y| x['displayOrder'] <=> y['displayOrder'] }
1346
+ end
1342
1347
 
1343
1348
  # prompt for volumes
1344
1349
  vol_options = options
1345
1350
  vol_options['siteId'] = group_id
1346
1351
  vol_options['zoneId'] = cloud_id
1347
- volumes = prompt_resize_volumes(current_volumes, service_plan, provision_type, vol_options)
1352
+ vol_options['resourcePoolId'] = server['resourcePool']['id'] if server['resourcePool']
1353
+ volumes = prompt_resize_volumes(current_volumes, service_plan, provision_type, vol_options, server)
1348
1354
  if !volumes.empty?
1349
1355
  payload[:volumes] = volumes
1350
1356
  end
@@ -2756,7 +2756,10 @@ class Morpheus::Cli::Instances
2756
2756
  connect(options)
2757
2757
  instance = find_instance_by_name_or_id(args[0])
2758
2758
  return 1, "instance not found" if instance.nil?
2759
-
2759
+ # need to load full instance details in case fetched by name
2760
+ if instance['containerDetails'].nil?
2761
+ instance = find_instance_by_id(instance['id'])
2762
+ end
2760
2763
  payload = {}
2761
2764
  if options[:payload]
2762
2765
  payload = options[:payload]
@@ -2811,13 +2814,24 @@ class Morpheus::Cli::Instances
2811
2814
  payload["instance"]["plan"] = {"id" => service_plan["id"]}
2812
2815
 
2813
2816
  volumes_response = @instances_interface.volumes(instance['id'])
2814
- current_volumes = volumes_response['volumes'].sort {|x,y| x['displayOrder'] <=> y['displayOrder'] }
2817
+ current_volumes = nil
2815
2818
 
2816
2819
  # prompt for volumes
2817
2820
  vol_options = options
2818
2821
  vol_options['siteId'] = group_id
2819
2822
  vol_options['zoneId'] = cloud_id
2820
- volumes = prompt_resize_volumes(current_volumes, service_plan, provision_type, vol_options)
2823
+ vol_options['resourcePoolId'] = resource_pool_id # server['resourcePool']['id'] if server['resourcePool']
2824
+ server = instance['containerDetails'][0]['server'] rescue nil
2825
+ if server.nil?
2826
+ Morpheus::Logging::DarkPrinter.puts "Failed to load server info"
2827
+ volumes_response = @instances_interface.volumes(instance['id'])
2828
+ current_volumes = volumes_response['volumes'].sort {|x,y| x['displayOrder'] <=> y['displayOrder'] }
2829
+ else
2830
+ # or just use instance['volumes'] ?
2831
+ current_volumes = server['volumes'].sort {|x,y| x['displayOrder'] <=> y['displayOrder'] }
2832
+ end
2833
+ vol_options['resourcePoolId'] = server['resourcePool']['id'] if server && server['resourcePool']
2834
+ volumes = prompt_resize_volumes(current_volumes, service_plan, provision_type, vol_options, server)
2821
2835
  if !volumes.empty?
2822
2836
  payload["volumes"] = volumes
2823
2837
  end
@@ -845,7 +845,7 @@ class Morpheus::Cli::LibraryClusterLayoutsCommand
845
845
  end
846
846
 
847
847
  def find_layout_by_name(name)
848
- layouts = @library_cluster_layouts_interface.list(instance_type_id, {name: name.to_s})['layouts']
848
+ layouts = @library_cluster_layouts_interface.list({name: name.to_s})['layouts']
849
849
  if layouts.empty?
850
850
  print_red_alert "Cluster layout not found by name #{name}"
851
851
  return nil
@@ -635,8 +635,8 @@ class Morpheus::Cli::Shell
635
635
  # @return Hash like {:commands => [], :command_count => total}
636
636
  def load_history_commands(options={})
637
637
  phrase = options[:phrase]
638
- sort_key = options[:sort] ? options[:sort].to_sym : nil
639
-
638
+ #sort_key = options[:sort] ? options[:sort].to_sym : nil
639
+ #direction = options[:direction] # default sort is reversed to get newest first
640
640
  offset = options[:offset].to_i > 0 ? options[:offset].to_i : 0
641
641
  max = options[:max].to_i > 0 ? options[:max].to_i : 25
642
642
 
@@ -648,40 +648,21 @@ class Morpheus::Cli::Shell
648
648
  # collect records as [{:number => 1, :command => "instances list"}, etc]
649
649
  history_records = []
650
650
  history_count = 0
651
-
652
- # sort is a bit different for this command, the default sort is by number
653
- # it sorts oldest -> newest, but shows the very last page by default.
654
- if options[:sort] && ![:number, :command].include?(options[:sort])
655
- sort_key = :number # nil
656
- end
657
651
 
658
- if options[:phrase] || sort_key || options[:direction] || options[:offset]
659
- # this could be a large object...need to index our shell_history file lol
660
- sort_key ||= :number
661
- history_records = @history.keys.collect { |k| {number: k, command: @history[k]} }
662
- if options[:direction] == 'desc'
663
- history_records = history_records.sort {|x,y| y[sort_key] <=> x[sort_key] }
664
- else
665
- history_records = history_records.sort {|x,y| x[sort_key] <=> y[sort_key] }
666
- end
667
- if phrase
668
- history_records = history_records.select {|it| it[:command].include?(phrase) || it[:number].to_s == phrase }
669
- end
670
- command_count = history_records.size
671
- history_records = history_records[offset..(max-1)]
672
- else
673
- # default should try to be as fast as possible..
674
- # no searching or sorting, default order by :number works
675
- if offset != 0
676
- cmd_numbers = @history.keys.last(max + offset).first(max)
677
- else
678
- cmd_numbers = @history.keys.last(max)
679
- end
680
- history_records = cmd_numbers.collect { |k| {number: k, command: @history[k]} }
681
- command_count = @history.size
652
+ # only go so far back in command history, 1 million commands
653
+ # this could be a large object...need to index our shell_history file lol
654
+ # todo: this max needs to be done in load_history_from_log_file()
655
+ history_keys = @history.keys.last(1000000).reverse
656
+ # filter by phrase
657
+ if phrase
658
+ history_keys = history_keys.select {|k| (@history[k] && @history[k].include?(phrase)) || k.to_s == phrase }
682
659
  end
660
+ # no offset, just max
661
+ history_records = history_keys.first(max).collect { |k| {number: k, command: @history[k]} }
662
+ command_count = history_keys.size
663
+
683
664
  meta = {size:history_records.size, total:command_count.to_i, max:max, offset:offset}
684
- return {:commands => history_records, :command_count => command_count, :meta => meta}
665
+ return {commands: history_records, command_count: command_count, meta: meta}
685
666
  end
686
667
 
687
668
  def print_history(options={})
@@ -696,16 +677,14 @@ class Morpheus::Cli::Shell
696
677
  end
697
678
  else
698
679
  print cyan
680
+ # by default show old->new as the shell history should bash history
681
+ history_records.reverse! unless options[:direction] == "desc"
699
682
  history_records.each do |history_record|
700
683
  puts "#{history_record[:number].to_s.rjust(3, ' ')} #{history_record[:command]}"
701
684
  end
702
685
  if options[:show_pagination]
703
- if options[:phrase] || options[:sort] || options[:direction] || options[:offset]
704
- print_results_pagination(history_result[:meta])
705
- else
706
- # default order is weird, it's the last page of results, 1-25 is misleading and showing the indexes is stranger
707
- print_results_pagination(history_result[:meta], {:message =>"Viewing most recent %{size} of %{total} %{label}"})
708
- end
686
+ pagination_msg = options[:phrase] ? "Viewing most recent %{size} of %{total} commands matching '#{options[:phrase]}'" : "Viewing most recent %{size} of %{total} commands"
687
+ print_results_pagination(history_result[:meta], {:message =>pagination_msg})
709
688
  print reset, "\n"
710
689
  else
711
690
  print reset
@@ -172,11 +172,8 @@ EOT
172
172
  id
173
173
  else
174
174
  image = find_virtual_image_by_name_or_id(id)
175
- if image
176
- image['id']
177
- else
178
- raise_command_error "virtual image not found for name '#{id}'"
179
- end
175
+ return 1, "virtual image not found for name '#{id}'" if image.nil?
176
+ image['id']
180
177
  end
181
178
  end
182
179
  return run_command_for_each_arg(id_list) do |arg|
@@ -383,15 +380,16 @@ EOT
383
380
  # storageProviderId, format, name
384
381
  optparse = Morpheus::Cli::OptionParser.new do |opts|
385
382
  opts.banner = subcommand_usage("[image] [options]")
386
- opts.on('-n', '--name NAME', String, "Name (optional) of the new converted image. Default is name of the original image.") do |val|
387
- options[:options]['name'] = val
388
- end
389
- opts.on('-f', '--format FORMAT', String, "Format (optional). Default is 'qcow2'") do |val|
390
- options[:options]['format'] = val
391
- end
392
- opts.on('--storageProvider VALUE', String, "Storage Provider ID (optional). Default is storage provider of the original image.") do |val|
393
- options[:options]['storageProvider'] = val.to_s
394
- end
383
+ # opts.on('-n', '--name NAME', String, "Name (optional) of the new converted image. Default is name of the original image.") do |val|
384
+ # options[:options]['name'] = val
385
+ # end
386
+ # opts.on('-f', '--format FORMAT', String, "Format (optional). Default is 'qcow2'") do |val|
387
+ # options[:options]['format'] = val
388
+ # end
389
+ # opts.on('--storageProvider VALUE', String, "Storage Provider ID (optional). Default is storage provider of the original image.") do |val|
390
+ # options[:options]['storageProvider'] = val.to_s
391
+ # end
392
+ build_option_type_options(opts, options, convert_virtual_image_option_types)
395
393
  build_common_options(opts, options, [:options, :payload, :json, :dry_run, :remote])
396
394
  opts.footer = "Convert a virtual image to a new format." + "\n" +
397
395
  "[image] is required. This is the name or id of a virtual image."
@@ -411,7 +409,18 @@ EOT
411
409
  payload.deep_merge!({virtual_image_object_key => passed_options}) unless passed_options.empty?
412
410
  else
413
411
  virtual_image_payload = passed_options
414
- virtual_image_payload['storageProvider'] = {'id' => virtual_image_payload['storageProvider']} unless virtual_image_payload['storageProvider'].nil?
412
+ source_format = virtual_image['imageType']
413
+ v_prompt = Morpheus::Cli::OptionTypes.prompt(convert_virtual_image_option_types(source_format), options[:options], @api_client, {'virtualImageId': virtual_image['id']})
414
+ v_prompt.deep_compact!
415
+ virtual_image_payload.deep_merge!(v_prompt)
416
+ # support "storageProviderId" too
417
+ if virtual_image_payload['storageProviderId']
418
+ virtual_image_payload['storageProvider'] = virtual_image_payload.delete('storageProviderId')
419
+ end
420
+ # convert "storageProvider":1 to "storageProvider": {"id":1}
421
+ if virtual_image_payload['storageProvider'] && !virtual_image_payload['storageProvider'].is_a?(Hash)
422
+ virtual_image_payload['storageProvider'] = {'id' => virtual_image_payload['storageProvider'].to_i }
423
+ end
415
424
  payload = virtual_image_payload
416
425
  end
417
426
  @virtual_images_interface.setopts(options)
@@ -990,11 +999,20 @@ EOT
990
999
 
991
1000
  def find_virtual_image_by_name(name)
992
1001
  json_results = @virtual_images_interface.list({name: name.to_s})
993
- if json_results['virtualImages'].empty?
1002
+ records = json_results['virtualImages']
1003
+ if records.empty?
994
1004
  print_red_alert "Virtual Image not found by name #{name}"
995
1005
  return nil
1006
+ elsif records.size > 1
1007
+ print_red_alert "More than one Virtual Image found by name '#{name}'"
1008
+ print_error "\n"
1009
+ puts_error as_pretty_table(records, [:id, :name], {color:red})
1010
+ print_red_alert "Try using ID instead"
1011
+ print_error reset,"\n"
1012
+ return nil
1013
+ else
1014
+ virtual_image = records[0]
996
1015
  end
997
- virtual_image = json_results['virtualImages'][0]
998
1016
  return virtual_image
999
1017
  end
1000
1018
 
@@ -1074,6 +1092,42 @@ EOT
1074
1092
  list
1075
1093
  end
1076
1094
 
1095
+ def convert_virtual_image_option_types(source_format=nil)
1096
+ [
1097
+ {'shorthand' => '-f', 'fieldName' => 'format', 'type' => 'select', 'fieldLabel' => 'Format', 'selectOptions' => get_convert_image_formats(source_format), 'required' => true, 'defaultValue' => (source_format == 'qcow2' ? nil : 'qcow2')},
1098
+ {'shorthand' => '-b', 'fieldName' => 'storageProviderId', 'type' => 'select', 'fieldLabel' => 'Bucket', 'optionSource' => 'storageProviders', 'required' => false, 'description' => 'Select Storage Provider Bucket or File Share.'},
1099
+ {'shorthand' => '-n', 'fieldName' => 'name', 'fieldLabel' => 'Name', 'type' => 'text', 'required' => false}
1100
+ ]
1101
+ end
1102
+
1103
+ def convert_source_types
1104
+ ["raw","qcow2","vmdk",'vmware', "vhd","ovf"]
1105
+ end
1106
+
1107
+ def convert_destination_types
1108
+ #["raw", "qcow2", "vmdk",'vmware',"vhd","ovf"]
1109
+ convert_source_types
1110
+ end
1111
+
1112
+ def get_convert_image_formats(source_format=nil)
1113
+ categories = [
1114
+ {'name' => 'QCOW2', 'value' => 'qcow2'},
1115
+ {'name' => 'VMDK', 'value' => 'ovf'},
1116
+ {'name' => 'VHD', 'value' => 'vhd'},
1117
+ {'name' => 'Raw', 'value' => 'raw'}
1118
+ ]
1119
+ # if source format (imageType) is not in the list, then no options
1120
+ # else reject the current value
1121
+ if source_format
1122
+ if !convert_source_types.include?(source_format.to_s.downcase)
1123
+ categories = []
1124
+ else
1125
+ categories = categories.select {|it| it['value'] != source_format.to_s.downcase }
1126
+ end
1127
+ end
1128
+ return categories
1129
+ end
1130
+
1077
1131
  def format_tenants(accounts)
1078
1132
  if accounts && accounts.size > 0
1079
1133
  accounts = accounts.sort {|a,b| a['name'] <=> b['name'] }.uniq {|it| it['id'] }
@@ -29,7 +29,7 @@ module Morpheus::Cli::ExecutionRequestHelper
29
29
  # unless options[:quiet]
30
30
  # print cyan, "Execution request has not yet finished. Refreshing every #{refresh_display_seconds} seconds...", "\n", reset
31
31
  # end
32
- while execution_request['status'] == 'pending' || execution_request['status'] == 'new' do
32
+ while (options[:waiting_status] || ['new', 'pending']).include?(execution_request['status']) do
33
33
  sleep(refresh_interval)
34
34
  execution_request = execution_request_interface.get(execution_request_id)['executionRequest']
35
35
  end