morpheus-cli 5.5.3.2 → 6.0.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.
- 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
|