morpheus-cli 5.4.0 → 5.4.3.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.
Files changed (92) hide show
  1. checksums.yaml +4 -4
  2. data/Dockerfile +1 -1
  3. data/lib/morpheus/api/account_users_interface.rb +68 -0
  4. data/lib/morpheus/api/api_client.rb +55 -10
  5. data/lib/morpheus/api/audit_interface.rb +9 -0
  6. data/lib/morpheus/api/catalog_item_types_interface.rb +20 -0
  7. data/lib/morpheus/api/instances_interface.rb +49 -0
  8. data/lib/morpheus/api/load_balancer_monitors_interface.rb +9 -0
  9. data/lib/morpheus/api/load_balancer_pools_interface.rb +4 -4
  10. data/lib/morpheus/api/load_balancer_profiles_interface.rb +4 -5
  11. data/lib/morpheus/api/load_balancer_virtual_servers_interface.rb +13 -4
  12. data/lib/morpheus/api/load_balancers_interface.rb +5 -0
  13. data/lib/morpheus/api/network_routers_interface.rb +9 -0
  14. data/lib/morpheus/api/network_static_routes_interface.rb +36 -0
  15. data/lib/morpheus/api/ping_interface.rb +2 -0
  16. data/lib/morpheus/api/read_interface.rb +4 -3
  17. data/lib/morpheus/api/rest_interface.rb +3 -3
  18. data/lib/morpheus/api/secondary_read_interface.rb +1 -1
  19. data/lib/morpheus/api/secondary_rest_interface.rb +19 -19
  20. data/lib/morpheus/api/setup_interface.rb +4 -0
  21. data/lib/morpheus/api/snapshots_interface.rb +19 -0
  22. data/lib/morpheus/api/storage_server_types_interface.rb +14 -0
  23. data/lib/morpheus/api/storage_servers_interface.rb +9 -0
  24. data/lib/morpheus/api/storage_volume_types_interface.rb +9 -0
  25. data/lib/morpheus/api/storage_volumes_interface.rb +9 -0
  26. data/lib/morpheus/api/users_interface.rb +16 -63
  27. data/lib/morpheus/cli/cli_command.rb +253 -5
  28. data/lib/morpheus/cli/cli_registry.rb +1 -1
  29. data/lib/morpheus/cli/commands/alias_command.rb +1 -1
  30. data/lib/morpheus/cli/commands/apps.rb +14 -78
  31. data/lib/morpheus/cli/commands/audit.rb +188 -0
  32. data/lib/morpheus/cli/commands/blueprints_command.rb +1 -1
  33. data/lib/morpheus/cli/commands/catalog_item_types_command.rb +88 -0
  34. data/lib/morpheus/cli/commands/change_password_command.rb +4 -4
  35. data/lib/morpheus/cli/commands/clusters.rb +96 -58
  36. data/lib/morpheus/cli/commands/hosts.rb +27 -15
  37. data/lib/morpheus/cli/commands/image_builder_command.rb +4 -8
  38. data/lib/morpheus/cli/commands/instances.rb +359 -3
  39. data/lib/morpheus/cli/commands/integrations_command.rb +1 -12
  40. data/lib/morpheus/cli/commands/library_instance_types_command.rb +3 -0
  41. data/lib/morpheus/cli/commands/load_balancer_monitors.rb +70 -0
  42. data/lib/morpheus/cli/commands/load_balancer_pools.rb +29 -50
  43. data/lib/morpheus/cli/commands/load_balancer_profiles.rb +64 -0
  44. data/lib/morpheus/cli/commands/load_balancer_types.rb +9 -4
  45. data/lib/morpheus/cli/commands/load_balancer_virtual_servers.rb +69 -58
  46. data/lib/morpheus/cli/commands/load_balancers.rb +109 -6
  47. data/lib/morpheus/cli/commands/network_firewalls_command.rb +22 -5
  48. data/lib/morpheus/cli/commands/network_routers_command.rb +96 -45
  49. data/lib/morpheus/cli/commands/network_static_routes_command.rb +451 -0
  50. data/lib/morpheus/cli/commands/network_transport_zones_command.rb +4 -4
  51. data/lib/morpheus/cli/commands/networks_command.rb +2 -2
  52. data/lib/morpheus/cli/commands/open_command.rb +30 -0
  53. data/lib/morpheus/cli/commands/options.rb +98 -0
  54. data/lib/morpheus/cli/commands/ping.rb +3 -5
  55. data/lib/morpheus/cli/commands/policies_command.rb +2 -2
  56. data/lib/morpheus/cli/commands/prices_command.rb +7 -7
  57. data/lib/morpheus/cli/commands/provisioning_settings_command.rb +1 -0
  58. data/lib/morpheus/cli/commands/remote.rb +20 -12
  59. data/lib/morpheus/cli/commands/roles.rb +1 -1
  60. data/lib/morpheus/cli/commands/security_groups.rb +2 -2
  61. data/lib/morpheus/cli/commands/service_plans_command.rb +1 -1
  62. data/lib/morpheus/cli/commands/setup.rb +1 -1
  63. data/lib/morpheus/cli/commands/shell.rb +2 -2
  64. data/lib/morpheus/cli/commands/snapshots.rb +139 -0
  65. data/lib/morpheus/cli/commands/storage_server_types.rb +50 -0
  66. data/lib/morpheus/cli/commands/storage_servers.rb +122 -0
  67. data/lib/morpheus/cli/commands/storage_volume_types.rb +50 -0
  68. data/lib/morpheus/cli/commands/storage_volumes.rb +103 -0
  69. data/lib/morpheus/cli/commands/tasks.rb +5 -5
  70. data/lib/morpheus/cli/commands/tenants_command.rb +1 -1
  71. data/lib/morpheus/cli/commands/user_groups_command.rb +1 -1
  72. data/lib/morpheus/cli/commands/user_settings_command.rb +3 -2
  73. data/lib/morpheus/cli/commands/user_sources_command.rb +1 -1
  74. data/lib/morpheus/cli/commands/users.rb +28 -28
  75. data/lib/morpheus/cli/commands/view.rb +102 -0
  76. data/lib/morpheus/cli/commands/virtual_images.rb +4 -1
  77. data/lib/morpheus/cli/mixins/accounts_helper.rb +5 -5
  78. data/lib/morpheus/cli/mixins/load_balancers_helper.rb +24 -4
  79. data/lib/morpheus/cli/mixins/print_helper.rb +50 -18
  80. data/lib/morpheus/cli/mixins/processes_helper.rb +1 -2
  81. data/lib/morpheus/cli/mixins/provisioning_helper.rb +96 -6
  82. data/lib/morpheus/cli/mixins/rest_command.rb +148 -74
  83. data/lib/morpheus/cli/mixins/secondary_rest_command.rb +174 -82
  84. data/lib/morpheus/cli/mixins/storage_servers_helper.rb +156 -0
  85. data/lib/morpheus/cli/mixins/storage_volumes_helper.rb +119 -0
  86. data/lib/morpheus/cli/option_types.rb +95 -28
  87. data/lib/morpheus/cli/version.rb +1 -1
  88. data/lib/morpheus/cli.rb +1 -0
  89. data/lib/morpheus/ext/string.rb +29 -6
  90. data/lib/morpheus/routes.rb +238 -0
  91. data/lib/morpheus/util.rb +6 -1
  92. metadata +26 -2
@@ -15,10 +15,10 @@ module Morpheus::Cli::AccountsHelper
15
15
  @accounts_interface
16
16
  end
17
17
 
18
- def users_interface
18
+ def account_users_interface
19
19
  # @api_client.users
20
- raise "#{self.class} has not defined @users_interface" if @users_interface.nil?
21
- @users_interface
20
+ raise "#{self.class} has not defined @account_users_interface" if @account_users_interface.nil?
21
+ @account_users_interface
22
22
  end
23
23
 
24
24
  def user_groups_interface
@@ -244,7 +244,7 @@ module Morpheus::Cli::AccountsHelper
244
244
 
245
245
  def find_user_by_id(account_id, id, params={})
246
246
  begin
247
- json_response = users_interface.get(account_id, id.to_i, params)
247
+ json_response = account_users_interface.get(account_id, id.to_i, params)
248
248
  return json_response['user']
249
249
  rescue RestClient::Exception => e
250
250
  if e.response && e.response.code == 404
@@ -256,7 +256,7 @@ module Morpheus::Cli::AccountsHelper
256
256
  end
257
257
 
258
258
  def find_user_by_username(account_id, username, params={})
259
- users = users_interface.list(account_id, params.merge({username: username.to_s}))['users']
259
+ users = account_users_interface.list(account_id, params.merge({username: username.to_s}))['users']
260
260
  if users.empty?
261
261
  print_red_alert "User not found by username #{username}"
262
262
  return nil
@@ -105,12 +105,32 @@ module Morpheus::Cli::LoadBalancersHelper
105
105
  end
106
106
  end
107
107
 
108
- def load_balancer_type_for_id(id)
109
- return get_available_load_balancer_types().find { |z| z['id'].to_i == id.to_i}
108
+ def load_balancer_type_for_id(val)
109
+ record = get_available_load_balancer_types().find { |z| z['id'].to_i == val.to_i}
110
+ label = "Load Balancer Type"
111
+ if record.nil?
112
+ print_red_alert "#{label.downcase} not found by id #{val}"
113
+ return nil
114
+ end
115
+ return record
110
116
  end
111
117
 
112
- def load_balancer_type_for_name(name)
113
- return get_available_load_balancer_types().find { |z| z['name'].downcase == name.downcase || z['code'].downcase == name.downcase}
118
+ def load_balancer_type_for_name(val)
119
+ records = get_available_load_balancer_types().select { |z| z['name'].downcase == val.downcase || z['code'].downcase == val.downcase}
120
+ label = "Load Balancer Type"
121
+ if records.empty?
122
+ print_red_alert "#{label} not found by name '#{val}'"
123
+ return nil
124
+ elsif records.size > 1
125
+ print_red_alert "More than one #{label.downcase} found by name '#{val}'"
126
+ print_error "\n"
127
+ puts_error as_pretty_table(records, [:id, :name], {color:red})
128
+ print_red_alert "Try using ID instead"
129
+ print_error reset,"\n"
130
+ return nil
131
+ else
132
+ return records[0]
133
+ end
114
134
  end
115
135
 
116
136
  def find_load_balancer_type_by_name_or_id(val)
@@ -202,7 +202,7 @@ module Morpheus::Cli::PrintHelper
202
202
  if options[:outfile]
203
203
  print_result = print_to_file(output, options[:outfile], options[:overwrite])
204
204
  # with_stdout_to_file(options[:outfile], options[:overwrite]) { print output }
205
- print "#{cyan}Wrote output to file #{options[:outfile]} (#{format_bytes File.size(options[:outfile])})\n" unless options[:quiet]
205
+ print "#{cyan}Wrote output to file #{options[:outfile]} (#{format_bytes(File.size(options[:outfile]))})\n" unless options[:quiet]
206
206
  #return print_result
207
207
  return
208
208
  end
@@ -220,6 +220,14 @@ module Morpheus::Cli::PrintHelper
220
220
  return
221
221
  end
222
222
 
223
+ def print_system_command_dry_run(cmd, options={})
224
+ print "\n"
225
+ print "#{cyan}#{bold}#{dark}SYSTEM COMMAND#{reset}\n"
226
+ print cmd
227
+ print reset, "\n"
228
+ return
229
+ end
230
+
223
231
  def format_api_request(http_method, url, headers, payload=nil, options={})
224
232
  out = ""
225
233
  # out << "\n"
@@ -385,33 +393,57 @@ module Morpheus::Cli::PrintHelper
385
393
  if json_response.nil? || json_response.empty?
386
394
  return ""
387
395
  end
388
-
389
- # options = OpenStruct.new(options) # laff, let's do this instead
390
396
  color = options.key?(:color) ? options[:color] : cyan
391
397
  label = options[:label]
392
- n_label = options[:n_label]
393
- # label = n_label if !label && n_label
398
+ n_label = options[:n_label] || (label ? label.to_s.pluralize : nil)
394
399
  message = options[:message] || "Viewing %{start_index}-%{end_index} of %{total} %{label}"
395
400
  blank_message = options[:blank_message] || nil # "No %{label} found"
396
401
 
397
- # support lazy passing of common json_response {"meta": {"size": {25}, "total": 56} }
398
- # otherwise use the root values given
399
- meta = OpenStruct.new(json_response)
400
- if meta.meta
401
- meta = OpenStruct.new(meta.meta)
402
- end
403
- offset, size, total = meta.offset.to_i, meta.size.to_i, meta.total.to_i
404
- #objects = meta.objects || options[:objects_key] ? json_response[options[:objects_key]] : nil
405
- #objects ||= meta.instances || meta.servers || meta.users || meta.roles
406
- #size = objects.size if objects && size == 0
407
- if total == 0
402
+ # support lazy passing of common list json_response {"meta": {"size": 25, "total": 56} }
403
+ # priority is:
404
+ # 1. "meta" that api response contains for list endpoints
405
+ # 2. "total" and "size" values if passed explicitely by the cli (pretty sure symbols are no longer used)
406
+ # 3. examine the first array found in the response
407
+ meta = nil
408
+ records = nil
409
+ # assume records is the first array in the response
410
+ records_key = json_response.keys.find { |k| json_response[k].is_a?(Array) }
411
+ if records_key
412
+ records = json_response[records_key]
413
+ meta = {'offset' => 0, 'size' => records.size, 'total' => records.size}
414
+ end
415
+ if json_response[:meta] || json_response["meta"]
416
+ meta = json_response[:meta] || json_response["meta"]
417
+ elsif json_response.key?('size') || json_response.key?('total')
418
+ meta = json_response
419
+ elsif json_response.key?(:size) || json_response.key?(:total)
420
+ meta = {'size' => json_response[:size], 'total' => json_response[:total], 'offset' => json_response[:offset]}
421
+ elsif records
422
+ # just use the first key in the response
423
+ meta = {'size' => records.size, 'total' => records.size}
424
+ end
425
+ # did not find pagination meta info?
426
+ if meta.nil?
427
+ return ""
428
+ end
429
+ # api should not need to return the size, just use records.size
430
+ if meta["size"].nil? && records
431
+ meta["size"] = records.size
432
+ end
433
+ offset = meta['offset'].to_i
434
+ size = meta['size'].to_i
435
+ total = meta['total'].to_i
436
+ # perhaps no total count returned, let total be equal to size of list
437
+ if total == 0 && size > 0
408
438
  total = size
409
439
  end
440
+ # plural label?
410
441
  if total != 1
411
- label = n_label || label
442
+ label = n_label
412
443
  end
413
444
  out_str = ""
414
- string_key_values = {start_index: format_number(offset + 1), end_index: format_number(offset + size), total: format_number(total), size: format_number(size), offset: format_number(offset), label: label}
445
+ string_key_values = {start_index: format_number(offset + 1), end_index: format_number(offset + size),
446
+ total: format_number(total), size: format_number(size), offset: format_number(offset), label: label}
415
447
  if size > 0
416
448
  if message
417
449
  out_str << message % string_key_values
@@ -1,8 +1,7 @@
1
1
  require 'morpheus/cli/mixins/print_helper'
2
2
 
3
3
  # Mixin for Morpheus::Cli command classes
4
- # Provides common methods for fetching and printing accounts, roles, and users.
5
- # The including class must establish @accounts_interface, @roles_interface, @users_interface
4
+ # Provides common methods for viewing process history
6
5
  module Morpheus::Cli::ProcessesHelper
7
6
 
8
7
  def self.included(klass)
@@ -57,9 +57,9 @@ module Morpheus::Cli::ProvisioningHelper
57
57
  @api_client.accounts
58
58
  end
59
59
 
60
- def get_available_groups(refresh=false)
60
+ def get_available_groups(params = {}, refresh=false)
61
61
  if !@available_groups || refresh
62
- option_results = options_interface.options_for_source('groups',{})
62
+ option_results = options_interface.options_for_source('groups', params)
63
63
  @available_groups = option_results['data'].collect {|it|
64
64
  {"id" => it["value"], "name" => it["name"], "value" => it["value"]}
65
65
  }
@@ -68,9 +68,9 @@ module Morpheus::Cli::ProvisioningHelper
68
68
  return @available_groups
69
69
  end
70
70
 
71
- def get_available_clouds(group_id, refresh=false)
71
+ def get_available_clouds(group_id, params = {}, refresh=false)
72
72
  if !group_id
73
- option_results = options_interface.options_for_source('clouds', {'default' => 'false'})
73
+ option_results = options_interface.options_for_source('clouds', params.merge({'default' => 'false'}))
74
74
  return option_results['data'].collect {|it|
75
75
  {"id" => it["value"], "name" => it["name"], "value" => it["value"], "zoneTypeId" => it["zoneTypeId"]}
76
76
  }
@@ -80,7 +80,7 @@ module Morpheus::Cli::ProvisioningHelper
80
80
  return []
81
81
  end
82
82
  if !group["clouds"] || refresh
83
- option_results = options_interface.options_for_source('clouds', {groupId: group_id})
83
+ option_results = options_interface.options_for_source('clouds', params.merge({groupId: group_id}))
84
84
  group["clouds"] = option_results['data'].collect {|it|
85
85
  {"id" => it["value"], "name" => it["name"], "value" => it["value"], "zoneTypeId" => it["zoneTypeId"]}
86
86
  }
@@ -484,7 +484,7 @@ module Morpheus::Cli::ProvisioningHelper
484
484
  if options[:instance_type_code]
485
485
  instance_type_code = options[:instance_type_code]
486
486
  else
487
- instance_type_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'type', 'type' => 'select', 'fieldLabel' => 'Type', 'optionSource' => 'instanceTypes', 'required' => true, 'description' => 'Select Instance Type.'}],options[:options],api_client,{groupId: group_id}, no_prompt, true)
487
+ instance_type_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'type', 'type' => 'select', 'fieldLabel' => 'Type', 'optionSource' => 'instanceTypes', 'required' => true, 'description' => 'Select Instance Type.'}],options[:options],api_client,{groupId: group_id, cloudId: cloud_id, restrictProvisionType:true}, no_prompt, true)
488
488
  instance_type_code = instance_type_prompt['type']
489
489
  end
490
490
  if instance_type_code.to_s =~ /\A\d{1,}\Z/
@@ -870,6 +870,12 @@ module Morpheus::Cli::ProvisioningHelper
870
870
  end
871
871
  end
872
872
 
873
+ # plan customizations
874
+ plan_opts = prompt_service_plan_options(service_plan, options, api_client, {zoneId: cloud_id, layoutId: layout['id'], siteId: group_id})
875
+ if plan_opts && !plan_opts.empty?
876
+ payload['servicePlanOptions'] = plan_opts
877
+ end
878
+
873
879
  # prompt networks
874
880
  if locked_fields.include?('networks')
875
881
  # payload['networkInterfaces'] = options[:options]['networkInterfaces'] if options[:options]['networkInterfaces']
@@ -942,6 +948,7 @@ module Morpheus::Cli::ProvisioningHelper
942
948
  # prompt for option types
943
949
  api_params['config'] = payload['config'] if payload['config']
944
950
  api_params['poolId'] = payload['config']['resourcePoolId'] if payload['config'] && payload['config']['resourcePoolId']
951
+ api_params['resourcePoolId'] = api_params['poolId']
945
952
 
946
953
  # set option type defaults from config
947
954
  if options[:default_config]
@@ -2093,6 +2100,15 @@ module Morpheus::Cli::ProvisioningHelper
2093
2100
  permissions
2094
2101
  end
2095
2102
 
2103
+ def prompt_permissions_v2(options, excludes = [])
2104
+ perms = prompt_permissions(options, excludes)
2105
+ rtn = {}
2106
+
2107
+ rtn['visibility'] = perms['resourcePool']['visibility'] if !perms['resourcePool'].nil?
2108
+ rtn['tenants'] = ((perms['tenantPermissions'] || {})['accounts'] || []).collect {|it| {'id' => it}}
2109
+ rtn
2110
+ end
2111
+
2096
2112
  def print_permissions(permissions, excludes = [])
2097
2113
  if permissions.nil?
2098
2114
  print_h2 "Permissions"
@@ -2230,6 +2246,80 @@ module Morpheus::Cli::ProvisioningHelper
2230
2246
  return ports
2231
2247
  end
2232
2248
 
2249
+ def prompt_service_plan_options(plan_info, options={}, api_client=nil, api_params={}, instance=nil)
2250
+ plan_opts = {}
2251
+ # provisioning with blueprint can lock fields
2252
+ locked_fields = options[:locked_fields] || []
2253
+ if options[:options]['servicePlanOptions']
2254
+ plan_opts = options[:options]['servicePlanOptions']
2255
+ end
2256
+ default_max_cores = plan_info['maxCores'].to_i != 0 ? plan_info['maxCores'] : 1
2257
+ default_cores_per_socket = plan_info['coresPerSocket'].to_i != 0 ? plan_info['coresPerSocket'] : 1
2258
+ default_max_memory = plan_info['maxMemory'].to_i != 0 ? plan_info['maxMemory'] : nil
2259
+ # use defaults from the instance/server
2260
+ if instance
2261
+ default_max_cores = instance["maxCores"] if instance["maxCores"]
2262
+ default_cores_per_socket = instance["coresPerSocket"] if instance["coresPerSocket"]
2263
+ default_max_memory = instance["maxMemory"] if instance["maxMemory"]
2264
+ end
2265
+ # Core Count
2266
+ if plan_info["customCores"]
2267
+ if locked_fields.include?('servicePlanOptions.maxCores')
2268
+ if options[:options]['servicePlanOptions'] && options[:options]['servicePlanOptions']['maxCores']
2269
+ plan_opts['maxCores'] = options[:options]['servicePlanOptions']['maxCores'].to_i
2270
+ end
2271
+ else
2272
+ v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldContext' => 'servicePlanOptions', 'fieldName' => 'maxCores', 'type' => 'number', 'fieldLabel' => "Core Count", 'required' => true, 'defaultValue' => default_max_cores, 'description' => "Customize service plan options Core Count"}], options[:options])
2273
+ if v_prompt['servicePlanOptions'] && v_prompt['servicePlanOptions']['maxCores']
2274
+ plan_opts['maxCores'] = v_prompt['servicePlanOptions']['maxCores'].to_i
2275
+ end
2276
+ end
2277
+ end
2278
+ # Cores Per Socket
2279
+ if plan_info["customCoresPerSocket"]
2280
+ if locked_fields.include?('servicePlanOptions.coresPerSocket')
2281
+ if options[:options]['servicePlanOptions'] && options[:options]['servicePlanOptions']['coresPerSocket']
2282
+ plan_opts['coresPerSocket'] = options[:options]['servicePlanOptions']['coresPerSocket'].to_i
2283
+ end
2284
+ else
2285
+ v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldContext' => 'servicePlanOptions', 'fieldName' => 'coresPerSocket', 'type' => 'number', 'fieldLabel' => "Cores Per Socket", 'required' => true, 'defaultValue' => default_cores_per_socket, 'description' => "Customize service plan options Cores Per Socket"}], options[:options])
2286
+ if v_prompt['servicePlanOptions'] && v_prompt['servicePlanOptions']['coresPerSocket']
2287
+ plan_opts['coresPerSocket'] = v_prompt['servicePlanOptions']['coresPerSocket'].to_i
2288
+ end
2289
+ end
2290
+ end
2291
+ # Memory
2292
+ if plan_info["customMaxMemory"]
2293
+ if locked_fields.include?('servicePlanOptions.maxMemory')
2294
+ if options[:options]['servicePlanOptions'] && options[:options]['servicePlanOptions']['maxMemory']
2295
+ plan_opts['maxMemory'] = options[:options]['servicePlanOptions']['maxMemory'].to_i
2296
+ end
2297
+ else
2298
+ if options[:options]['servicePlanOptions'] && options[:options]['servicePlanOptions']['maxMemory']
2299
+ plan_opts['maxMemory'] = options[:options]['servicePlanOptions']['maxMemory'].to_i
2300
+ else
2301
+ # prompt for "memoryMB" field as MB or "memoryGB" in GB
2302
+ # always convert maxMemory to bytes
2303
+ if plan_info["memorySizeType"] == "MB" || options[:options]["memoryMB"]
2304
+ v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'memoryMB', 'type' => 'text', 'fieldLabel' => "Memory (MB)", 'required' => true, 'defaultValue' => default_max_memory ? (default_max_memory / (1024 * 1024)) : nil, 'description' => "Customize service plan options Memory (MB). Value is in megabytes."}], options[:options])
2305
+ if v_prompt['memoryMB'].to_s != ""
2306
+ plan_opts['maxMemory'] = v_prompt['memoryMB'].to_i * 1024 * 1024
2307
+ end
2308
+ else
2309
+ v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'memoryGB', 'type' => 'text', 'fieldLabel' => "Memory (GB)", 'required' => true, 'defaultValue' => default_max_memory ? (default_max_memory / (1024 * 1024 * 1024)) : nil, 'description' => "Customize service plan options Memory (GB). Value is in gigabytes."}], options[:options])
2310
+ if v_prompt['memoryGB'].to_s != ""
2311
+ plan_opts['maxMemory'] = v_prompt['memoryGB'].to_i * 1024 * 1024 * 1024
2312
+ end
2313
+ end
2314
+ # remove transient memory field just used for prompting for MB or GB
2315
+ plan_opts.delete("memoryMB")
2316
+ plan_opts.delete("memoryGB")
2317
+ end
2318
+ end
2319
+ end
2320
+ return plan_opts
2321
+ end
2322
+
2233
2323
  def format_instance_status(instance, return_color=cyan)
2234
2324
  out = ""
2235
2325
  status_string = instance['status'].to_s