morpheus-cli 5.5.3.2 → 6.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Dockerfile +1 -1
- data/lib/morpheus/api/api_client.rb +8 -0
- data/lib/morpheus/api/cloud_resource_pools_interface.rb +28 -3
- data/lib/morpheus/api/containers_interface.rb +10 -0
- data/lib/morpheus/api/doc_interface.rb +1 -10
- data/lib/morpheus/api/jobs_interface.rb +2 -2
- data/lib/morpheus/api/key_pairs_interface.rb +9 -0
- data/lib/morpheus/api/network_floating_ips_interface.rb +37 -0
- data/lib/morpheus/api/resource_pool_groups_interface.rb +51 -0
- data/lib/morpheus/cli/cli_command.rb +17 -11
- data/lib/morpheus/cli/commands/appliance_settings_command.rb +5 -0
- data/lib/morpheus/cli/commands/apps.rb +12 -6
- data/lib/morpheus/cli/commands/catalog_item_types_command.rb +44 -12
- data/lib/morpheus/cli/commands/clusters.rb +23 -2
- data/lib/morpheus/cli/commands/containers_command.rb +129 -4
- data/lib/morpheus/cli/commands/doc.rb +14 -13
- data/lib/morpheus/cli/commands/hosts.rb +2 -0
- data/lib/morpheus/cli/commands/instances.rb +9 -3
- data/lib/morpheus/cli/commands/jobs_command.rb +50 -3
- data/lib/morpheus/cli/commands/key_pairs.rb +94 -33
- data/lib/morpheus/cli/commands/network_floating_ips.rb +109 -0
- data/lib/morpheus/cli/commands/reports_command.rb +8 -1
- data/lib/morpheus/cli/commands/resource_pool_groups_command.rb +586 -0
- data/lib/morpheus/cli/commands/roles.rb +10 -10
- data/lib/morpheus/cli/commands/service_catalog_command.rb +40 -2
- data/lib/morpheus/cli/commands/service_plans_command.rb +51 -22
- data/lib/morpheus/cli/commands/shell.rb +1 -1
- data/lib/morpheus/cli/commands/tasks.rb +130 -35
- data/lib/morpheus/cli/commands/workflows.rb +109 -23
- data/lib/morpheus/cli/mixins/infrastructure_helper.rb +148 -0
- data/lib/morpheus/cli/mixins/jobs_helper.rb +30 -3
- data/lib/morpheus/cli/mixins/processes_helper.rb +2 -26
- data/lib/morpheus/cli/mixins/provisioning_helper.rb +2 -1
- data/lib/morpheus/cli/option_types.rb +2 -2
- data/lib/morpheus/cli/version.rb +1 -1
- data/test/cli/doc_test.rb +1 -1
- metadata +6 -2
@@ -594,11 +594,15 @@ EOT
|
|
594
594
|
type_id = nil
|
595
595
|
workflow_context = nil
|
596
596
|
workflow_target = nil
|
597
|
+
quantity = nil
|
597
598
|
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
598
599
|
opts.banner = subcommand_usage("[type] [options]")
|
599
600
|
opts.on('-t', '--type TYPE', String, "Catalog Item Type Name or ID") do |val|
|
600
601
|
type_id = val.to_s
|
601
602
|
end
|
603
|
+
opts.on('--quantity QUANTITY', String, "Quantity for this catalog item. Will be overridden to 1 if quantity not allowed.") do |val|
|
604
|
+
quantity = val.to_s
|
605
|
+
end
|
602
606
|
opts.on('--validate','--validate', "Validate Only. Validates the configuration and skips adding the item.") do
|
603
607
|
options[:validate_only] = true
|
604
608
|
end
|
@@ -648,6 +652,16 @@ EOT
|
|
648
652
|
payload[add_item_object_key]['type'] = {'name' => catalog_item_type['name']}
|
649
653
|
#payload[add_item_object_key]['type'] = {'id' => catalog_item_type['id']}
|
650
654
|
|
655
|
+
if quantity
|
656
|
+
payload[add_item_object_key].deep_merge!({'quantity' => quantity})
|
657
|
+
else
|
658
|
+
if catalog_item_type['allowQuantity']
|
659
|
+
quantity_option_type = {'fieldName' => 'quantity', 'fieldLabel' => 'Quantity', 'type' => 'number', 'defaultValue' => 1, 'required' => true, 'displayOrder' => 1}
|
660
|
+
quantity_prompt = Morpheus::Cli::OptionTypes.prompt( [quantity_option_type], options[:options], @api_client, options[:params])['quantity']
|
661
|
+
payload[add_item_object_key].deep_merge!({'quantity' => quantity_prompt})
|
662
|
+
end
|
663
|
+
end
|
664
|
+
|
651
665
|
# this is silly, need to load by id to get optionTypes
|
652
666
|
# maybe do ?name=foo&includeOptionTypes=true
|
653
667
|
if catalog_item_type['optionTypes'].nil?
|
@@ -926,11 +940,15 @@ EOT
|
|
926
940
|
type_id = nil
|
927
941
|
workflow_context = nil
|
928
942
|
workflow_target = nil
|
943
|
+
quantity = nil
|
929
944
|
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
930
945
|
opts.banner = subcommand_usage("[type] [options]")
|
931
946
|
opts.on('-t', '--type TYPE', String, "Catalog Item Type Name or ID") do |val|
|
932
947
|
type_id = val.to_s
|
933
948
|
end
|
949
|
+
opts.on('--quantity QUANTITY', String, "Quantity for this catalog item. Will be overridden to 1 if quantity not allowed.") do |val|
|
950
|
+
quantity = val.to_s
|
951
|
+
end
|
934
952
|
opts.on('--validate','--validate', "Validate Only. Validates the configuration and skips creating the order.") do
|
935
953
|
options[:validate_only] = true
|
936
954
|
end
|
@@ -991,6 +1009,17 @@ EOT
|
|
991
1009
|
item_payload['type'] = {'name' => catalog_item_type['name']}
|
992
1010
|
#payload[add_item_object_key]['type'] = {'id' => catalog_item_type['id']}
|
993
1011
|
|
1012
|
+
if quantity
|
1013
|
+
item_payload.deep_merge!({'quantity' => quantity})
|
1014
|
+
else
|
1015
|
+
if catalog_item_type['allowQuantity']
|
1016
|
+
quantity_option_type = {'fieldName' => 'quantity', 'fieldLabel' => 'Quantity', 'type' => 'number', 'defaultValue' => 1, 'required' => true, 'displayOrder' => 1}
|
1017
|
+
quantity_prompt = Morpheus::Cli::OptionTypes.prompt( [quantity_option_type], options[:options], @api_client, options[:params])['quantity']
|
1018
|
+
item_payload.deep_merge!({'quantity' => quantity_prompt})
|
1019
|
+
end
|
1020
|
+
end
|
1021
|
+
|
1022
|
+
|
994
1023
|
# this is silly, need to load by id to get optionTypes
|
995
1024
|
# maybe do ?name=foo&includeOptionTypes=true
|
996
1025
|
if catalog_item_type['optionTypes'].nil?
|
@@ -1126,6 +1155,14 @@ EOT
|
|
1126
1155
|
opts.on('--releaseEIPs [true|false]', String, "Release EIPs. Default is on. Applies to Amazon only.") do |val|
|
1127
1156
|
params[:releaseEIPs] = ['true','on','1',''].include?(val.to_s.downcase)
|
1128
1157
|
end
|
1158
|
+
opts.on('--release-ips [on|off]', ['on','off'], "Release Floating IPs. Default is on. Applies to certain types only.") do |val|
|
1159
|
+
params[:releaseFloatingIps] = ['true','on','1',''].include?(val.to_s.downcase)
|
1160
|
+
params[:releaseEIPs] = params[:releaseFloatingIps] # old parameter before 6.0
|
1161
|
+
end
|
1162
|
+
opts.on('--releaseEIPs [on|off]', ['on','off'], "Alias for Release Floating IPs") do |val|
|
1163
|
+
params[:releaseFloatingIps] = ['true','on','1',''].include?(val.to_s.downcase)
|
1164
|
+
params[:releaseEIPs] = params[:releaseFloatingIps] # old parameter before 6.0
|
1165
|
+
end
|
1129
1166
|
opts.on( '-f', '--force', "Force Delete" ) do
|
1130
1167
|
params[:force] = true
|
1131
1168
|
end
|
@@ -1192,6 +1229,7 @@ EOT
|
|
1192
1229
|
# "Blueprint" => lambda {|it| it['blueprint'] ? it['blueprint']['name'] : nil },
|
1193
1230
|
# "Enabled" => lambda {|it| format_boolean(it['enabled']) },
|
1194
1231
|
"Featured" => lambda {|it| format_boolean(it['featured']) },
|
1232
|
+
"Allow Quantity" => lambda {|it| format_boolean(it['allowQuantity']) },
|
1195
1233
|
#"Config" => lambda {|it| it['config'] },
|
1196
1234
|
# "Created" => lambda {|it| format_local_dt(it['dateCreated']) },
|
1197
1235
|
# "Updated" => lambda {|it| format_local_dt(it['lastUpdated']) },
|
@@ -1400,7 +1438,7 @@ EOT
|
|
1400
1438
|
{"ID" => lambda {|it| it['id'] } },
|
1401
1439
|
#{"NAME" => lambda {|it| it['name'] } },
|
1402
1440
|
{"Type" => lambda {|it| it['type']['name'] rescue '' } },
|
1403
|
-
|
1441
|
+
{"Qty" => lambda {|it| it['quantity'] } },
|
1404
1442
|
{"Price" => lambda {|it| it['price'] ? format_money(it['price'] , it['currency'], {sigdig:options[:sigdig] || default_sigdig}) : "No pricing configured" } },
|
1405
1443
|
{"Status" => lambda {|it|
|
1406
1444
|
status_string = format_catalog_item_status(it)
|
@@ -1430,7 +1468,7 @@ EOT
|
|
1430
1468
|
{"ID" => lambda {|it| it['id'] } },
|
1431
1469
|
#{"NAME" => lambda {|it| it['name'] } },
|
1432
1470
|
{"TYPE" => lambda {|it| it['type']['name'] rescue '' } },
|
1433
|
-
|
1471
|
+
{"QTY" => lambda {|it| it['quantity'] } },
|
1434
1472
|
{"PRICE" => lambda {|it| it['price'] ? format_money(it['price'] , it['currency'], {sigdig:options[:sigdig] || default_sigdig}) : "No pricing configured" } },
|
1435
1473
|
{"STATUS" => lambda {|it|
|
1436
1474
|
status_string = format_catalog_item_status(it)
|
@@ -171,13 +171,21 @@ class Morpheus::Cli::ServicePlanCommand
|
|
171
171
|
ranges = (service_plan['config'] ? service_plan['config']['ranges'] : nil) || {}
|
172
172
|
|
173
173
|
if (ranges['minStorage'] && ranges['minStorage'] != '') || (ranges['maxStorage'] && ranges['maxStorage'] != '')
|
174
|
-
description_cols['Custom Storage Range'] = lambda {|it|
|
174
|
+
description_cols['Custom Total Storage Range'] = lambda {|it|
|
175
175
|
get_range(
|
176
176
|
ranges['minStorage'] && ranges['minStorage'] != '' ? "#{ranges['minStorage']} #{(it['config'] && it['config']['storageSizeType'] ? it['config']['storageSizeType'] : 'GB').upcase}" : nil,
|
177
177
|
ranges['maxStorage'] && ranges['maxStorage'] != '' ? "#{ranges['maxStorage']} #{(it['config'] && it['config']['storageSizeType'] ? it['config']['storageSizeType'] : 'GB').upcase}" : nil,
|
178
178
|
)
|
179
179
|
}
|
180
180
|
end
|
181
|
+
if (ranges['minPerDiskSize'] && ranges['minPerDiskSize'] != '') || (ranges['maxPerDiskSize'] && ranges['maxPerDiskSize'] != '')
|
182
|
+
description_cols['Custom Per Disk Range'] = lambda {|it|
|
183
|
+
get_range(
|
184
|
+
ranges['minPerDiskSize'] && ranges['minPerDiskSize'] != '' ? "#{ranges['minPerDiskSize']} GB" : nil,
|
185
|
+
ranges['maxPerDiskSize'] && ranges['maxPerDiskSize'] != '' ? "#{ranges['maxPerDiskSize']} GB" : nil
|
186
|
+
)
|
187
|
+
}
|
188
|
+
end
|
181
189
|
if (ranges['minMemory'] && ranges['minMemory'] != '') || (ranges['maxMemory'] && ranges['maxMemory'] != '')
|
182
190
|
description_cols['Custom Memory Range'] = lambda {|it|
|
183
191
|
get_range(
|
@@ -264,6 +272,9 @@ class Morpheus::Cli::ServicePlanCommand
|
|
264
272
|
opts.on('--disks [NUMBER]', Integer, "Max disks allowed" ) do |val|
|
265
273
|
params['maxDisks'] = val.to_i || 1
|
266
274
|
end
|
275
|
+
opts.on('--cores-per-socket [NUMBER]', Integer, "Cores Per Socket") do |val|
|
276
|
+
params['coresPerSocket'] = val.to_i || 1
|
277
|
+
end
|
267
278
|
opts.on('--custom-cores [on|off]', String, "Can be used to enable / disable customizable cores. Default is on") do |val|
|
268
279
|
params['customCores'] = val.to_s == 'on' || val.to_s == 'true' || val.to_s == '1' || val.to_s == ''
|
269
280
|
end
|
@@ -285,17 +296,17 @@ class Morpheus::Cli::ServicePlanCommand
|
|
285
296
|
opts.on('--price-sets [LIST]', Array, 'Price set(s), comma separated list of price set IDs') do |list|
|
286
297
|
params['priceSets'] = list.collect {|it| it.to_s.strip.empty? || !it.to_i ? nil : it.to_s.strip}.compact.uniq.collect {|it| {'id' => it.to_i}}
|
287
298
|
end
|
288
|
-
opts.on('--min-storage NUMBER', String, "Min storage
|
289
|
-
|
290
|
-
bytes = parse_bytes_param(val, '--min-storage', 'GB', true)
|
291
|
-
((params['config'] ||= {})['ranges'] ||= {})['minStorage'] = bytes[:number]
|
292
|
-
(params['config'] ||= {})['storageSizeType'] = bytes[:unit].downcase
|
299
|
+
opts.on('--min-storage NUMBER', String, "Min total storage in GB.") do |val|
|
300
|
+
((params['config'] ||= {})['ranges'] ||= {})['minStorage'] = val.to_i
|
293
301
|
end
|
294
|
-
opts.on('--max-storage NUMBER', String, "Max storage
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
(params['config'] ||= {})['
|
302
|
+
opts.on('--max-storage NUMBER', String, "Max total storage in GB.") do |val|
|
303
|
+
((params['config'] ||= {})['ranges'] ||= {})['maxStorage'] = val.to_i
|
304
|
+
end
|
305
|
+
opts.on('--min-per-disk-size NUMBER', String, "Min per disk size in GB.") do |val|
|
306
|
+
((params['config'] ||= {})['ranges'] ||= {})['minPerDiskSize'] = val.to_i
|
307
|
+
end
|
308
|
+
opts.on('--max-per-disk-size NUMBER', String, "Max per disk size in GB.") do |val|
|
309
|
+
((params['config'] ||= {})['ranges'] ||= {})['maxPerDiskSize'] = val.to_i
|
299
310
|
end
|
300
311
|
opts.on('--min-memory NUMBER', String, "Min memory. Assumes MB unless optional modifier specified, ex: 1GB") do |val|
|
301
312
|
# Memory does get converted to bytes
|
@@ -396,13 +407,31 @@ class Morpheus::Cli::ServicePlanCommand
|
|
396
407
|
true
|
397
408
|
)
|
398
409
|
params['maxMemory'] = bytes[:bytes]
|
399
|
-
# (params['config'] ||= {})['memorySizeType'] = bytes[:unit].downcase
|
400
410
|
rescue
|
401
411
|
print "Invalid Value... Please try again.\n"
|
402
412
|
end
|
413
|
+
params['customMaxMemory'] = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'customMaxMemory', 'type' => 'checkbox', 'fieldLabel' => 'Custom Max Memory', 'required' => false, 'description' => 'Custom Max Memory', 'defaultValue' => false}],options[:options],@api_client,{}, options[:no_prompt])['customMaxMemory']
|
403
414
|
end
|
404
415
|
end
|
405
416
|
|
417
|
+
# add'n options
|
418
|
+
addn_options = [
|
419
|
+
{'fieldName' => 'maxCores', 'fieldLabel' => 'Core Count', 'type' => 'number', 'required' => true, 'defaultValue' => 1, 'displayOrder' => 1},
|
420
|
+
{'fieldName' => 'customCores', 'fieldLabel' => 'Custom Cores', 'type' => 'checkbox', 'defaultValue' => false, 'displayOrder' => 2},
|
421
|
+
{'fieldName' => 'coresPerSocket', 'fieldLabel' => 'Cores Per Socket', 'type' => 'number', 'required' => true, 'defaultValue' => 1, 'displayOrder' => 3},
|
422
|
+
{'fieldContext' => 'config.ranges', 'fieldGroup' => 'Custom Ranges', 'fieldName' => 'minStorage', 'fieldLabel' => 'Min Total Storage (GB)', 'type' => 'number', 'displayOrder' => 1},
|
423
|
+
{'fieldContext' => 'config.ranges', 'fieldGroup' => 'Custom Ranges', 'fieldName' => 'maxStorage', 'fieldLabel' => 'Max Total Storage (GB)', 'type' => 'number', 'displayOrder' => 2},
|
424
|
+
{'fieldContext' => 'config.ranges', 'fieldGroup' => 'Custom Ranges', 'fieldName' => 'minPerDiskSize', 'fieldLabel' => 'Min Per Disk Size (GB)', 'type' => 'number', 'displayOrder' => 3},
|
425
|
+
{'fieldContext' => 'config.ranges', 'fieldGroup' => 'Custom Ranges', 'fieldName' => 'maxPerDiskSize', 'fieldLabel' => 'Max Per Disk Size (GB)', 'type' => 'number', 'displayOrder' => 4},
|
426
|
+
{'fieldContext' => 'config.ranges', 'fieldGroup' => 'Custom Ranges', 'fieldName' => 'minMemory', 'fieldLabel' => 'Min Memory (GB)', 'type' => 'number', 'displayOrder' => 5},
|
427
|
+
{'fieldContext' => 'config.ranges', 'fieldGroup' => 'Custom Ranges', 'fieldName' => 'maxMemory', 'fieldLabel' => 'Max Memory (GB)', 'type' => 'number', 'displayOrder' => 6},
|
428
|
+
{'fieldContext' => 'config.ranges', 'fieldGroup' => 'Custom Ranges', 'fieldName' => 'minCores', 'fieldLabel' => 'Min Cores', 'type' => 'number', 'displayOrder' => 7},
|
429
|
+
{'fieldContext' => 'config.ranges', 'fieldGroup' => 'Custom Ranges', 'fieldName' => 'maxCores', 'fieldLabel' => 'Max Cores', 'type' => 'number', 'displayOrder' => 8}
|
430
|
+
]
|
431
|
+
|
432
|
+
v_prompt = Morpheus::Cli::OptionTypes.prompt(addn_options, options[:options], @api_client, params)
|
433
|
+
params.deep_merge!(v_prompt)
|
434
|
+
|
406
435
|
# price sets
|
407
436
|
if params['priceSets'].nil? && !options[:no_prompt]
|
408
437
|
price_sets = []
|
@@ -517,17 +546,17 @@ class Morpheus::Cli::ServicePlanCommand
|
|
517
546
|
opts.on('--price-sets [LIST]', Array, 'Price set(s), comma separated list of price set IDs') do |list|
|
518
547
|
params['priceSets'] = list.collect {|it| it.to_s.strip.empty? || !it.to_i ? nil : it.to_s.strip}.compact.uniq.collect {|it| {'id' => it.to_i}}
|
519
548
|
end
|
520
|
-
opts.on('--min-storage NUMBER', String, "Min storage
|
521
|
-
|
522
|
-
bytes = parse_bytes_param(val, '--min-storage', 'GB')
|
523
|
-
((params['config'] ||= {})['ranges'] ||= {})['minStorage'] = bytes[:number]
|
524
|
-
(params['config'] ||= {})['storageSizeType'] = bytes[:unit].downcase
|
549
|
+
opts.on('--min-storage NUMBER', String, "Min total storage in GB.") do |val|
|
550
|
+
((params['config'] ||= {})['ranges'] ||= {})['minStorage'] = val.to_i
|
525
551
|
end
|
526
|
-
opts.on('--max-storage NUMBER', String, "Max storage
|
527
|
-
|
528
|
-
|
529
|
-
|
530
|
-
(params['config'] ||= {})['
|
552
|
+
opts.on('--max-storage NUMBER', String, "Max total storage in GB.") do |val|
|
553
|
+
((params['config'] ||= {})['ranges'] ||= {})['maxStorage'] = val.to_i
|
554
|
+
end
|
555
|
+
opts.on('--min-per-disk-size NUMBER', String, "Min per disk size in GB.") do |val|
|
556
|
+
((params['config'] ||= {})['ranges'] ||= {})['minPerDiskSize'] = val.to_i
|
557
|
+
end
|
558
|
+
opts.on('--max-per-disk-size NUMBER', String, "Max per disk size in GB.") do |val|
|
559
|
+
((params['config'] ||= {})['ranges'] ||= {})['maxPerDiskSize'] = val.to_i
|
531
560
|
end
|
532
561
|
opts.on('--min-memory NUMBER', String, "Min memory. Assumes MB unless optional modifier specified, ex: 1GB") do |val|
|
533
562
|
# Memory does get converted to bytes
|
@@ -359,7 +359,7 @@ class Morpheus::Cli::Shell
|
|
359
359
|
end
|
360
360
|
out << "See the available commands below.\n"
|
361
361
|
|
362
|
-
out << "\nCommands
|
362
|
+
out << "\nCommands:\n"
|
363
363
|
# commands = @morpheus_commands + @shell_commands
|
364
364
|
# @morpheus_commands.sort.each {|cmd|
|
365
365
|
# out << "\t#{cmd.to_s}\n"
|
@@ -442,7 +442,7 @@ class Morpheus::Cli::Tasks
|
|
442
442
|
# Result Type
|
443
443
|
if options[:options]['resultType']
|
444
444
|
payload['task']['resultType'] = options[:options]['resultType']
|
445
|
-
|
445
|
+
elsif task_type['hasResults']
|
446
446
|
result_types_dropdown = [{"name" => "Value", "value" => "value"}, {"name" => "Exit Code", "value" => "exitCode"}, {"name" => "Key Value", "value" => "keyValue"}, {"name" => "JSON", "value" => "json"}]
|
447
447
|
v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'resultType', 'fieldLabel' => 'Result Type', 'type' => 'select', 'selectOptions' => result_types_dropdown}], options[:options], @api_client)
|
448
448
|
payload['task']['resultType'] = v_prompt['resultType'] unless v_prompt['resultType'].to_s.empty?
|
@@ -471,6 +471,7 @@ class Morpheus::Cli::Tasks
|
|
471
471
|
end
|
472
472
|
end
|
473
473
|
end
|
474
|
+
process_special_task_option_typeaheads(task_option_types)
|
474
475
|
# inject file_params into options for file-content prompt
|
475
476
|
# or into taskOptions.script for types not yet using file-content
|
476
477
|
unless file_params.empty?
|
@@ -859,38 +860,99 @@ class Morpheus::Cli::Tasks
|
|
859
860
|
target_type = nil
|
860
861
|
instance_ids = []
|
861
862
|
instances = []
|
863
|
+
instance_label = nil
|
862
864
|
server_ids = []
|
863
865
|
servers = []
|
864
|
-
|
866
|
+
server_label = nil
|
867
|
+
default_refresh_interval = 5
|
868
|
+
all_target_types = ['appliance', 'instance', 'instance-label', 'server', 'server-label']
|
865
869
|
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
866
|
-
opts.banner = subcommand_usage("[task]
|
867
|
-
opts.on('--
|
870
|
+
opts.banner = subcommand_usage("[task] [options]")
|
871
|
+
opts.on('--context-type VALUE', String, "Context Type, #{ored_list(all_target_types)}") do |val|
|
872
|
+
val = val.downcase
|
873
|
+
val = 'appliance' if val == 'none'
|
874
|
+
if target_type && target_type != val
|
875
|
+
raise ::OptionParser::InvalidOption.new("cannot be combined with another context (#{target_type})")
|
876
|
+
end
|
877
|
+
if !all_target_types.include?(val)
|
878
|
+
raise ::OptionParser::InvalidOption.new("'#{val}' is invalid. It must be one of the following: instance, instance-label, server, server-label or appliance")
|
879
|
+
end
|
880
|
+
target_type = val
|
881
|
+
end
|
882
|
+
opts.on('--target-type VALUE', String, "alias for context-type") do |val|
|
883
|
+
val = val.downcase
|
884
|
+
val = 'appliance' if val == 'none'
|
885
|
+
if target_type && target_type != val
|
886
|
+
raise ::OptionParser::InvalidOption.new("cannot be combined with another context (#{target_type})")
|
887
|
+
end
|
888
|
+
if !all_target_types.include?(val)
|
889
|
+
raise ::OptionParser::InvalidOption.new("'#{val}' is invalid. It must be one of the following: instance, instance-label, server, server-label or appliance")
|
890
|
+
end
|
891
|
+
target_type = val
|
892
|
+
end
|
893
|
+
opts.add_hidden_option('--target-type')
|
894
|
+
opts.on('--instance INSTANCE', String, "Instance name or id to target for execution. This option can be passed more than once.") do |val|
|
895
|
+
if target_type && target_type != 'instance'
|
896
|
+
raise ::OptionParser::InvalidOption.new("cannot be combined with another context (#{target_type})")
|
897
|
+
end
|
868
898
|
target_type = 'instance'
|
869
899
|
instance_ids << val
|
870
900
|
end
|
871
|
-
opts.on('--instances
|
901
|
+
opts.on('--instances LIST', Array, "Instances, comma separated list of instance names or IDs.") do |list|
|
902
|
+
if target_type && target_type != 'instance'
|
903
|
+
raise ::OptionParser::InvalidOption.new("cannot be combined with another context (#{target_type})")
|
904
|
+
end
|
872
905
|
target_type = 'instance'
|
873
906
|
instance_ids = list.collect {|it| it.to_s.strip.empty? ? nil : it.to_s.strip }.compact.uniq
|
874
907
|
end
|
875
|
-
opts.on('--
|
908
|
+
opts.on('--instance-label LABEL', String, "Instance Label") do |val|
|
909
|
+
if target_type && target_type != 'instance-label'
|
910
|
+
raise ::OptionParser::InvalidOption.new("cannot be combined with another context (#{target_type})")
|
911
|
+
end
|
912
|
+
target_type = 'instance-label'
|
913
|
+
instance_label = val
|
914
|
+
end
|
915
|
+
opts.on('--server SERVER', String, "Server name or id to target for execution. This option can be passed more than once.") do |val|
|
916
|
+
if target_type && target_type != 'server'
|
917
|
+
raise ::OptionParser::InvalidOption.new("cannot be combined with another context (#{target_type})")
|
918
|
+
end
|
876
919
|
target_type = 'server'
|
877
920
|
server_ids << val
|
878
921
|
end
|
879
|
-
opts.on('--
|
922
|
+
opts.on('--servers LIST', Array, "Servers, comma separated list of host names or IDs.") do |list|
|
923
|
+
if target_type && target_type != 'server'
|
924
|
+
raise ::OptionParser::InvalidOption.new("cannot be combined with another context (#{target_type})")
|
925
|
+
end
|
880
926
|
target_type = 'server'
|
881
927
|
server_ids = list.collect {|it| it.to_s.strip.empty? ? nil : it.to_s.strip }.compact.uniq
|
882
928
|
end
|
883
|
-
opts.on('--server
|
929
|
+
opts.on('--server-label LABEL', String, "Server Label") do |val|
|
930
|
+
if target_type && target_type != 'server-label'
|
931
|
+
raise ::OptionParser::InvalidOption.new("cannot be combined with another context (#{target_type})")
|
932
|
+
end
|
933
|
+
target_type = 'server-label'
|
934
|
+
server_label = val
|
935
|
+
end
|
936
|
+
opts.on('--host HOST', String, "alias for --server") do |val|
|
937
|
+
if target_type && target_type != 'server'
|
938
|
+
raise ::OptionParser::InvalidOption.new("cannot be combined with another context (#{target_type})")
|
939
|
+
end
|
884
940
|
target_type = 'server'
|
885
941
|
server_ids << val
|
886
942
|
end
|
887
|
-
opts.
|
943
|
+
opts.add_hidden_option('--host')
|
944
|
+
opts.on('--hosts HOSTS', Array, "alias for --servers") do |list|
|
945
|
+
if target_type && target_type != 'server'
|
946
|
+
raise ::OptionParser::InvalidOption.new("The --hosts option cannot be combined with another context (#{target_type})")
|
947
|
+
end
|
888
948
|
target_type = 'server'
|
889
949
|
server_ids = list.collect {|it| it.to_s.strip.empty? ? nil : it.to_s.strip }.compact.uniq
|
890
950
|
end
|
891
|
-
opts.add_hidden_option('--
|
892
|
-
opts.add_hidden_option('--servers')
|
951
|
+
opts.add_hidden_option('--hosts')
|
893
952
|
opts.on('-a', '--appliance', "Execute on the appliance, the target is the appliance itself.") do
|
953
|
+
if target_type && target_type != 'appliance'
|
954
|
+
raise ::OptionParser::InvalidOption.new("The --appliance option cannot be combined with another context (#{target_type})")
|
955
|
+
end
|
894
956
|
target_type = 'appliance'
|
895
957
|
end
|
896
958
|
opts.on('--config [TEXT]', String, "Custom config") do |val|
|
@@ -902,7 +964,7 @@ class Morpheus::Cli::Tasks
|
|
902
964
|
opts.on(nil, '--no-refresh', "Do not refresh" ) do
|
903
965
|
options[:no_refresh] = true
|
904
966
|
end
|
905
|
-
|
967
|
+
build_standard_post_options(opts, options)
|
906
968
|
end
|
907
969
|
optparse.parse!(args)
|
908
970
|
if args.count != 1
|
@@ -921,46 +983,59 @@ class Morpheus::Cli::Tasks
|
|
921
983
|
payload = options[:payload]
|
922
984
|
payload.deep_merge!({'job' => passed_options}) unless passed_options.empty?
|
923
985
|
else
|
924
|
-
#
|
925
|
-
if
|
926
|
-
|
927
|
-
|
986
|
+
# prompt for target type and target
|
987
|
+
if target_type.nil?
|
988
|
+
# todo: Need api to fetch available Context Types for taskId/workflowId
|
989
|
+
available_target_types = get_available_contexts_for_task(task)
|
990
|
+
default_target_type = available_target_types.first ? available_target_types.first['name'] : nil
|
991
|
+
if !available_target_types.empty?
|
992
|
+
default_target_type = available_target_types.first ? available_target_types.first['name'] : nil
|
993
|
+
target_type = Morpheus::Cli::OptionTypes.prompt([{'switch' => 'context-type', 'fieldName' => 'targetType', 'fieldLabel' => 'Context Type', 'type' => 'select', 'selectOptions' => available_target_types, 'defaultValue' => default_target_type, 'required' => true, 'description' => 'Context Type determines the type of target(s) for the execution'}], options[:options], @api_client)['targetType']
|
994
|
+
end
|
995
|
+
end
|
996
|
+
if target_type
|
997
|
+
params['targetType'] = target_type
|
998
|
+
end
|
999
|
+
if target_type == 'instance'
|
1000
|
+
if instance_ids.empty?
|
1001
|
+
instance_ids_value = Morpheus::Cli::OptionTypes.prompt([{'switch' => 'instances', 'fieldName' => 'instances', 'fieldLabel' => 'Instance(s)', 'type' => 'text', 'required' => true, 'description' => 'Instances, comma separated list of instance names or IDs.'}], options[:options], @api_client)['instances']
|
1002
|
+
instance_ids = parse_array(instance_ids_value)
|
1003
|
+
end
|
928
1004
|
instance_ids.each do |instance_id|
|
929
1005
|
instance = find_instance_by_name_or_id(instance_id)
|
930
1006
|
return 1 if instance.nil?
|
931
1007
|
instances << instance
|
932
1008
|
end
|
933
1009
|
params['instances'] = instances.collect {|it| it['id'] }
|
934
|
-
elsif
|
1010
|
+
elsif target_type == 'instance-label'
|
1011
|
+
if instance_label.nil?
|
1012
|
+
instance_label = Morpheus::Cli::OptionTypes.prompt([{'switch' => 'instance-label', 'fieldName' => 'instanceLabel', 'fieldLabel' => 'Instance Label', 'type' => 'text', 'required' => true, 'description' => 'Instance Label'}], options[:options], @api_client)['instanceLabel']
|
1013
|
+
end
|
1014
|
+
# params['config'] ||= {}
|
1015
|
+
# params['config']['instanceLabel'] = instance_label
|
1016
|
+
params['instanceLabel'] = instance_label
|
1017
|
+
elsif target_type == 'server'
|
1018
|
+
if server_ids.empty?
|
1019
|
+
server_ids_value = Morpheus::Cli::OptionTypes.prompt([{'switch' => 'servers', 'fieldName' => 'servers', 'fieldLabel' => 'Server(s)', 'type' => 'text', 'required' => true, 'description' => 'Servers, comma separated list of server names or IDs.'}], options[:options], @api_client)['servers']
|
1020
|
+
server_ids = parse_array(server_ids_value)
|
1021
|
+
end
|
935
1022
|
server_ids.each do |server_id|
|
936
1023
|
server = find_server_by_name_or_id(server_id)
|
937
1024
|
return 1 if server.nil?
|
938
1025
|
servers << server
|
939
1026
|
end
|
940
1027
|
params['servers'] = servers.collect {|it| it['id'] }
|
941
|
-
|
942
|
-
|
943
|
-
|
944
|
-
if instance_ids.empty? && server_ids.empty?
|
945
|
-
# todo: prompt for Context: None,Instance,Server and then Instance(s) or Server(s)
|
946
|
-
raise_command_error "missing required option: --instance or --host\n#{optparse}"
|
1028
|
+
elsif target_type == 'server-label'
|
1029
|
+
if server_label.nil?
|
1030
|
+
server_label = Morpheus::Cli::OptionTypes.prompt([{'switch' => 'server-label', 'fieldName' => 'serverLabel', 'fieldLabel' => 'Server Label', 'type' => 'text', 'required' => true, 'description' => 'Server Label'}], options[:options], @api_client)['serverLabel']
|
947
1031
|
end
|
948
|
-
|
949
|
-
#
|
950
|
-
|
951
|
-
# not sure about this one
|
952
|
-
else
|
953
|
-
# unknown executeTarget
|
1032
|
+
# params['config'] ||= {}
|
1033
|
+
# params['config']['serverLabel'] = server_label
|
1034
|
+
params['serverLabel'] = server_label
|
954
1035
|
end
|
955
|
-
|
956
|
-
|
957
|
-
|
958
1036
|
# todo: prompt to task optionTypes for customOptions
|
959
1037
|
if task['optionTypes']
|
960
1038
|
|
961
|
-
end
|
962
|
-
if target_type
|
963
|
-
params['targetType'] = target_type
|
964
1039
|
end
|
965
1040
|
job_payload = {}
|
966
1041
|
job_payload.deep_merge!(params)
|
@@ -1293,4 +1368,24 @@ class Morpheus::Cli::Tasks
|
|
1293
1368
|
end
|
1294
1369
|
end
|
1295
1370
|
|
1371
|
+
def process_special_task_option_typeaheads(option_types)
|
1372
|
+
# massage special task typeaheads options
|
1373
|
+
# this makes us all sad
|
1374
|
+
option_types.each do |option_type|
|
1375
|
+
if option_type['type'] == 'typeahead'
|
1376
|
+
if ['operationalWorkflowName','containerScript','containerTemplate'].include?(option_type['code'])
|
1377
|
+
option_type.deep_merge!({'config' => {'valueField' => 'name'}})
|
1378
|
+
end
|
1379
|
+
elsif option_type['type'] == 'hidden'
|
1380
|
+
if ['operationalWorkflowId','containerScriptId','containerTemplateId'].include?(option_type['code'])
|
1381
|
+
option_type['processValue'] = lambda {|val|
|
1382
|
+
if val.to_s.empty?
|
1383
|
+
selected_option = Morpheus::Cli::OptionTypes.get_last_select()
|
1384
|
+
selected_option ? selected_option['value'] : nil
|
1385
|
+
end
|
1386
|
+
}
|
1387
|
+
end
|
1388
|
+
end
|
1389
|
+
end
|
1390
|
+
end
|
1296
1391
|
end
|