morpheus-cli 3.6.38 → 4.0.0
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/lib/morpheus/api/api_client.rb +8 -0
- data/lib/morpheus/api/network_domain_records_interface.rb +47 -0
- data/lib/morpheus/api/network_pool_ips_interface.rb +47 -0
- data/lib/morpheus/cli/apps.rb +70 -15
- data/lib/morpheus/cli/cli_command.rb +36 -24
- data/lib/morpheus/cli/containers_command.rb +4 -3
- data/lib/morpheus/cli/execution_request_command.rb +3 -2
- data/lib/morpheus/cli/file_copy_request_command.rb +3 -3
- data/lib/morpheus/cli/hosts.rb +154 -30
- data/lib/morpheus/cli/instances.rb +16 -8
- data/lib/morpheus/cli/mixins/print_helper.rb +84 -26
- data/lib/morpheus/cli/mixins/provisioning_helper.rb +99 -33
- data/lib/morpheus/cli/network_domains_command.rb +338 -0
- data/lib/morpheus/cli/network_pools_command.rb +376 -4
- data/lib/morpheus/cli/option_parser.rb +2 -2
- data/lib/morpheus/cli/reports_command.rb +3 -3
- data/lib/morpheus/cli/version.rb +1 -1
- data/lib/morpheus/cli/wiki_command.rb +0 -3
- metadata +4 -2
@@ -387,13 +387,42 @@ module Morpheus::Cli::ProvisioningHelper
|
|
387
387
|
payload['plan'] = {'id' => service_plan["id"], 'code' => service_plan["code"], 'name' => service_plan["name"]}
|
388
388
|
payload['instance']['plan'] = {'id' => service_plan["id"], 'code' => service_plan["code"], 'name' => service_plan["name"]}
|
389
389
|
|
390
|
+
|
391
|
+
|
392
|
+
# build option types
|
393
|
+
option_type_list = []
|
394
|
+
if !layout['optionTypes'].nil? && !layout['optionTypes'].empty?
|
395
|
+
option_type_list += layout['optionTypes']
|
396
|
+
end
|
397
|
+
if !instance_type['optionTypes'].nil? && !instance_type['optionTypes'].empty?
|
398
|
+
option_type_list += instance_type['optionTypes']
|
399
|
+
end
|
400
|
+
if !layout['provisionType'].nil? && !layout['provisionType']['optionTypes'].nil? && !layout['provisionType']['optionTypes'].empty?
|
401
|
+
option_type_list += layout['provisionType']['optionTypes']
|
402
|
+
end
|
403
|
+
if !payload['volumes'].empty?
|
404
|
+
option_type_list = reject_volume_option_types(option_type_list)
|
405
|
+
end
|
406
|
+
# remove networkId option if networks were configured above
|
407
|
+
if !payload['networkInterfaces'].empty?
|
408
|
+
option_type_list = reject_networking_option_types(option_type_list)
|
409
|
+
end
|
410
|
+
|
390
411
|
# prompt for resource pool
|
412
|
+
pool_id = nil
|
391
413
|
has_zone_pools = layout["provisionType"] && layout["provisionType"]["id"] && layout["provisionType"]["hasZonePools"]
|
392
414
|
if has_zone_pools
|
393
|
-
|
394
|
-
|
395
|
-
|
396
|
-
|
415
|
+
# pluck out the resourcePoolId option type to prompt for..why the heck is this even needed?
|
416
|
+
resource_pool_option_type = option_type_list.find {|opt| ['resourcePool','resourcePoolId','azureResourceGroupId'].include?(opt['fieldName']) }
|
417
|
+
option_type_list = option_type_list.reject {|opt| ['resourcePool','resourcePoolId','azureResourceGroupId'].include?(opt['fieldName']) }
|
418
|
+
resource_pool_option_type ||= {'fieldContext' => 'config', 'fieldName' => 'resourcePoolId', 'type' => 'select', 'fieldLabel' => 'Resource Pool', 'optionSource' => 'zonePools', 'required' => true, 'skipSingleOption' => true, 'description' => 'Select resource pool.'}
|
419
|
+
resource_pool_prompt = Morpheus::Cli::OptionTypes.prompt([resource_pool_option_type],options[:options],api_client,{groupId: group_id, siteId: group_id, zoneId: cloud_id, cloudId: cloud_id, instanceTypeId: instance_type['id'], planId: service_plan["id"], layoutId: layout["id"]})
|
420
|
+
resource_pool_prompt.deep_compact!
|
421
|
+
payload.deep_merge!(resource_pool_prompt)
|
422
|
+
if resource_pool_option_type['fieldContext'] && resource_pool_prompt[resource_pool_option_type['fieldContext']]
|
423
|
+
pool_id = resource_pool_prompt[resource_pool_option_type['fieldContext']][resource_pool_option_type['fieldName']]
|
424
|
+
elsif resource_pool_prompt[resource_pool_option_type['fieldName']]
|
425
|
+
pool_id = resource_pool_prompt[resource_pool_option_type['fieldName']]
|
397
426
|
end
|
398
427
|
end
|
399
428
|
|
@@ -413,7 +442,7 @@ module Morpheus::Cli::ProvisioningHelper
|
|
413
442
|
if layout["provisionType"] && layout["provisionType"]["id"] && layout["provisionType"]["hasNetworks"]
|
414
443
|
# prompt for network interfaces (if supported)
|
415
444
|
begin
|
416
|
-
network_interfaces = prompt_network_interfaces(cloud_id, layout["provisionType"]["id"], options)
|
445
|
+
network_interfaces = prompt_network_interfaces(cloud_id, layout["provisionType"]["id"], pool_id, options)
|
417
446
|
if !network_interfaces.empty?
|
418
447
|
payload['networkInterfaces'] = network_interfaces
|
419
448
|
end
|
@@ -424,37 +453,41 @@ module Morpheus::Cli::ProvisioningHelper
|
|
424
453
|
end
|
425
454
|
# end
|
426
455
|
|
427
|
-
#
|
428
|
-
|
429
|
-
|
430
|
-
|
431
|
-
|
432
|
-
if
|
433
|
-
|
434
|
-
|
435
|
-
|
436
|
-
option_type_list += layout['provisionType']['optionTypes']
|
437
|
-
end
|
438
|
-
if !payload['volumes'].empty?
|
439
|
-
option_type_list = reject_volume_option_types(option_type_list)
|
440
|
-
end
|
441
|
-
# remove networkId option if networks were configured above
|
442
|
-
if !payload['networkInterfaces'].empty?
|
443
|
-
option_type_list = reject_networking_option_types(option_type_list)
|
456
|
+
# Security Groups
|
457
|
+
# prompt for multiple security groups
|
458
|
+
sg_option_type = option_type_list.find {|opt| ((opt['code'] == 'provisionType.amazon.securityId') || (opt['name'] == 'securityId')) }
|
459
|
+
option_type_list = option_type_list.reject {|opt| ((opt['code'] == 'provisionType.amazon.securityId') || (opt['name'] == 'securityId')) }
|
460
|
+
# ok.. seed data has changed and serverTypes do not have this optionType anymore...
|
461
|
+
if sg_option_type.nil?
|
462
|
+
if layout["provisionType"] && (layout["provisionType"]["code"] == 'amazon')
|
463
|
+
sg_option_type = {'fieldContext' => 'config', 'fieldName' => 'securityId', 'type' => 'select', 'fieldLabel' => 'Security Group', 'optionSource' => 'amazonSecurityGroup', 'required' => true, 'description' => 'Select security group.'}
|
464
|
+
end
|
444
465
|
end
|
445
|
-
|
446
|
-
if
|
447
|
-
|
466
|
+
has_security_groups = !!sg_option_type
|
467
|
+
if options[:security_groups]
|
468
|
+
payload['securityGroups'] = options[:security_groups].collect {|sg_id| {'id' => sg_id} }
|
469
|
+
else
|
470
|
+
if has_security_groups
|
471
|
+
security_groups_array = prompt_security_groups(sg_option_type, {zoneId: cloud_id, poolId: pool_id}, options)
|
472
|
+
if !security_groups_array.empty?
|
473
|
+
payload['securityGroups'] = security_groups_array.collect {|sg_id| {'id' => sg_id} }
|
474
|
+
end
|
475
|
+
end
|
448
476
|
end
|
449
477
|
|
450
|
-
|
478
|
+
|
479
|
+
# prompt for option types
|
480
|
+
api_params = {groupId: group_id, cloudId: cloud_id, zoneId: cloud_id, instanceTypeId: instance_type['id'], version: version_value}
|
481
|
+
api_params['config'] = payload['config'] if payload['config']
|
482
|
+
api_params['poolId'] = payload['config']['resourcePoolId'] if payload['config'] && payload['config']['resourcePoolId']
|
483
|
+
|
484
|
+
instance_config_payload = Morpheus::Cli::OptionTypes.prompt(option_type_list, options[:options], @api_client, api_params)
|
451
485
|
payload.deep_merge!(instance_config_payload)
|
452
486
|
|
453
487
|
## Advanced Options
|
454
488
|
|
455
489
|
# scale factor
|
456
490
|
|
457
|
-
|
458
491
|
# prompt for environment variables
|
459
492
|
evars = prompt_evars(options)
|
460
493
|
if !evars.empty?
|
@@ -482,10 +515,9 @@ module Morpheus::Cli::ProvisioningHelper
|
|
482
515
|
if plan_info['maxStorage']
|
483
516
|
plan_size = plan_info['maxStorage'].to_i / (1024 * 1024 * 1024)
|
484
517
|
end
|
485
|
-
|
486
518
|
root_storage_types = []
|
487
519
|
if plan_info['rootStorageTypes']
|
488
|
-
plan_info['rootStorageTypes'].each do |opt|
|
520
|
+
plan_info['rootStorageTypes'].sort {|x,y| x['displayOrder'] <=> y['displayOrder'] }.each do |opt|
|
489
521
|
if !opt.nil?
|
490
522
|
root_storage_types << {'name' => opt['name'], 'value' => opt['id']}
|
491
523
|
end
|
@@ -494,7 +526,7 @@ module Morpheus::Cli::ProvisioningHelper
|
|
494
526
|
|
495
527
|
storage_types = []
|
496
528
|
if plan_info['storageTypes']
|
497
|
-
plan_info['storageTypes'].each do |opt|
|
529
|
+
plan_info['storageTypes'].sort {|x,y| x['displayOrder'] <=> y['displayOrder'] }.each do |opt|
|
498
530
|
if !opt.nil?
|
499
531
|
storage_types << {'name' => opt['name'], 'value' => opt['id']}
|
500
532
|
end
|
@@ -956,12 +988,15 @@ module Morpheus::Cli::ProvisioningHelper
|
|
956
988
|
# This recreates the behavior of multi_networks.js
|
957
989
|
# This is used by both `instances add` and `hosts add`
|
958
990
|
# returns array of networkInterfaces based on provision type and cloud settings
|
959
|
-
def prompt_network_interfaces(zone_id, provision_type_id, options={})
|
991
|
+
def prompt_network_interfaces(zone_id, provision_type_id, pool_id, options={})
|
960
992
|
#puts "Configure Networks:"
|
961
993
|
no_prompt = (options[:no_prompt] || (options[:options] && options[:options][:no_prompt]))
|
962
994
|
network_interfaces = []
|
963
|
-
|
964
|
-
|
995
|
+
api_params = {zoneId: zone_id, provisionTypeId: provision_type_id}
|
996
|
+
if pool_id.to_s =~ /\A\d{1,}\Z/
|
997
|
+
api_params[:poolId] = pool_id
|
998
|
+
end
|
999
|
+
zone_network_options_json = api_client.options.options_for_source('zoneNetworkOptions', api_params)
|
965
1000
|
# puts "zoneNetworkOptions JSON"
|
966
1001
|
# puts JSON.pretty_generate(zone_network_options_json)
|
967
1002
|
zone_network_data = zone_network_options_json['data'] || {}
|
@@ -1122,6 +1157,37 @@ module Morpheus::Cli::ProvisioningHelper
|
|
1122
1157
|
return metadata_array
|
1123
1158
|
end
|
1124
1159
|
|
1160
|
+
def prompt_security_groups(sg_option_type, api_params, options)
|
1161
|
+
no_prompt = (options[:no_prompt] || (options[:options] && options[:options][:no_prompt]))
|
1162
|
+
security_groups_array = []
|
1163
|
+
|
1164
|
+
sg_required = sg_option_type['required']
|
1165
|
+
sg_index = 0
|
1166
|
+
add_another_sg = sg_required || (!no_prompt && Morpheus::Cli::OptionTypes.confirm("Add a security group?", {default: false}))
|
1167
|
+
while add_another_sg do
|
1168
|
+
cur_sg_option_type = sg_option_type.merge({'required' => (sg_index == 0 ? sg_required : false)})
|
1169
|
+
field_context = cur_sg_option_type['fieldContext']
|
1170
|
+
field_name = cur_sg_option_type['fieldName']
|
1171
|
+
v_prompt = Morpheus::Cli::OptionTypes.prompt([cur_sg_option_type], options[:options], api_client, api_params)
|
1172
|
+
has_another_sg = false
|
1173
|
+
if field_context
|
1174
|
+
if v_prompt[field_context] && !v_prompt[field_context][field_name].to_s.empty?
|
1175
|
+
security_groups_array << v_prompt[field_context][field_name]
|
1176
|
+
end
|
1177
|
+
has_another_sg = options[:options] && options[:options][field_context] && options[:options][field_context]["#{field_name}#{sg_index+2}"]
|
1178
|
+
else
|
1179
|
+
if !v_prompt[field_name].to_s.empty?
|
1180
|
+
security_groups_array << v_prompt[field_name]
|
1181
|
+
end
|
1182
|
+
has_another_sg = options[:options] && options[:options]["#{field_name}#{sg_index+2}"]
|
1183
|
+
end
|
1184
|
+
add_another_sg = has_another_sg || (!no_prompt && Morpheus::Cli::OptionTypes.confirm("Add another security group?", {default: false}))
|
1185
|
+
sg_index += 1
|
1186
|
+
end
|
1187
|
+
|
1188
|
+
return security_groups_array
|
1189
|
+
end
|
1190
|
+
|
1125
1191
|
# Prompts user for load balancer settings
|
1126
1192
|
# returns Hash of parameters like {loadBalancerId: "-1", etc}
|
1127
1193
|
def prompt_instance_load_balancer(instance, default_lb_id, options)
|
@@ -11,6 +11,7 @@ class Morpheus::Cli::NetworkDomainsCommand
|
|
11
11
|
set_command_name :'network-domains'
|
12
12
|
|
13
13
|
register_subcommands :list, :get, :add, :update, :remove
|
14
|
+
register_subcommands :list_records, :get_record, :add_record, :remove_record
|
14
15
|
|
15
16
|
# set_default_subcommand :list
|
16
17
|
|
@@ -21,6 +22,7 @@ class Morpheus::Cli::NetworkDomainsCommand
|
|
21
22
|
def connect(opts)
|
22
23
|
@api_client = establish_remote_appliance_connection(opts)
|
23
24
|
@network_domains_interface = @api_client.network_domains
|
25
|
+
@network_domain_records_interface = @api_client.network_domain_records
|
24
26
|
@clouds_interface = @api_client.clouds
|
25
27
|
@options_interface = @api_client.options
|
26
28
|
end
|
@@ -515,6 +517,298 @@ class Morpheus::Cli::NetworkDomainsCommand
|
|
515
517
|
end
|
516
518
|
end
|
517
519
|
|
520
|
+
def list_records(args)
|
521
|
+
options = {}
|
522
|
+
params = {}
|
523
|
+
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
524
|
+
opts.banner = subcommand_usage("[network-domain]")
|
525
|
+
build_common_options(opts, options, [:list, :json, :yaml, :csv, :fields, :json, :dry_run, :remote])
|
526
|
+
opts.footer = "List network domain records.\n" +
|
527
|
+
"[network-domain] is required. This is the name or id of a network domain."
|
528
|
+
end
|
529
|
+
optparse.parse!(args)
|
530
|
+
connect(options)
|
531
|
+
if args.count != 1
|
532
|
+
raise_command_error "wrong number of arguments, expected 1 and got (#{args.count}) #{args}\n#{optparse}"
|
533
|
+
end
|
534
|
+
begin
|
535
|
+
network_domain = find_network_domain_by_name_or_id(args[0])
|
536
|
+
return 1 if network_domain.nil?
|
537
|
+
network_domain_id = network_domain['id']
|
538
|
+
|
539
|
+
params.merge!(parse_list_options(options))
|
540
|
+
@network_domain_records_interface.setopts(options)
|
541
|
+
if options[:dry_run]
|
542
|
+
print_dry_run @network_domain_records_interface.dry.list(network_domain_id, params)
|
543
|
+
return
|
544
|
+
end
|
545
|
+
json_response = @network_domain_records_interface.list(network_domain_id, params)
|
546
|
+
network_domain_records = json_response["networkDomainRecords"]
|
547
|
+
if options[:json]
|
548
|
+
puts as_json(json_response, options, "networkDomainRecords")
|
549
|
+
return 0
|
550
|
+
elsif options[:yaml]
|
551
|
+
puts as_yaml(json_response, options, "networkDomainRecords")
|
552
|
+
return 0
|
553
|
+
elsif options[:csv]
|
554
|
+
puts records_as_csv(network_domain_records, options)
|
555
|
+
return 0
|
556
|
+
end
|
557
|
+
title = "Morpheus Network Domain Records"
|
558
|
+
subtitles = []
|
559
|
+
subtitles += parse_list_subtitles(options)
|
560
|
+
print_h1 title, subtitles
|
561
|
+
if network_domain_records.empty?
|
562
|
+
print cyan,"No network domain records found.",reset,"\n"
|
563
|
+
else
|
564
|
+
columns = [
|
565
|
+
{"ID" => lambda {|it| it['id'] } },
|
566
|
+
{"NAME" => lambda {|it| it['name'] } },
|
567
|
+
#{"FQDN" => lambda {|it| it['fqdn'] } },
|
568
|
+
{"TYPE" => lambda {|it| it['type'] } },
|
569
|
+
# {"CONTENT" => lambda {|it| it['content'] } },
|
570
|
+
{"CONTENT" => lambda {|it| it['content'].to_s.split.join(",") } },
|
571
|
+
# {"COMMENT" => lambda {|it| it['comment'] } },
|
572
|
+
#{"CREATED BY" => lambda {|it| it['createdBy'] ? it['createdBy']['username'] : '' } },
|
573
|
+
#{"CREATED" => lambda {|it| format_local_dt(it['dateCreated']) } },
|
574
|
+
#{"UPDATED" => lambda {|it| format_local_dt(it['lastUpdated']) } },
|
575
|
+
]
|
576
|
+
if options[:include_fields]
|
577
|
+
columns = options[:include_fields]
|
578
|
+
end
|
579
|
+
print as_pretty_table(network_domain_records, columns, options)
|
580
|
+
print_results_pagination(json_response)
|
581
|
+
end
|
582
|
+
print reset,"\n"
|
583
|
+
return 0
|
584
|
+
rescue RestClient::Exception => e
|
585
|
+
print_rest_exception(e, options)
|
586
|
+
exit 1
|
587
|
+
end
|
588
|
+
end
|
589
|
+
|
590
|
+
def get_record(args)
|
591
|
+
options = {}
|
592
|
+
params = {}
|
593
|
+
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
594
|
+
opts.banner = subcommand_usage("[network-domain] [record]")
|
595
|
+
build_common_options(opts, options, [:query, :json, :yaml, :csv, :fields, :dry_run, :remote])
|
596
|
+
opts.footer = "Get details about a network domain record.\n" +
|
597
|
+
"[network-domain] is required. This is the name or id of a network domain.\n" +
|
598
|
+
"[record] is required. This is the name or id of a network domain record."
|
599
|
+
end
|
600
|
+
optparse.parse!(args)
|
601
|
+
connect(options)
|
602
|
+
if args.count != 2
|
603
|
+
raise_command_error "wrong number of arguments, expected 2 and got (#{args.count}) #{args}\n#{optparse}"
|
604
|
+
end
|
605
|
+
begin
|
606
|
+
network_domain = find_network_domain_by_name_or_id(args[0])
|
607
|
+
return 1 if network_domain.nil?
|
608
|
+
network_domain_id = network_domain['id']
|
609
|
+
|
610
|
+
params.merge!(parse_list_options(options))
|
611
|
+
@network_domain_records_interface.setopts(options)
|
612
|
+
if options[:dry_run]
|
613
|
+
if args[1].to_s =~ /\A\d{1,}\Z/
|
614
|
+
print_dry_run @network_domain_records_interface.dry.get(network_domain_id, args[1].to_i)
|
615
|
+
else
|
616
|
+
print_dry_run @network_domain_records_interface.dry.list(network_domain_id, {name:args[1]})
|
617
|
+
end
|
618
|
+
return
|
619
|
+
end
|
620
|
+
network_domain_record = find_network_domain_record_by_name_or_id(network_domain_id, args[1])
|
621
|
+
return 1 if network_domain_record.nil?
|
622
|
+
json_response = {'networkDomainRecord' => network_domain_record} # skip redundant request
|
623
|
+
# json_response = @network_domain_records_interface.get(network_domain_id, args[1])
|
624
|
+
#network_domain_record = json_response['networkDomainRecord']
|
625
|
+
if options[:json]
|
626
|
+
puts as_json(json_response, options, "networkDomainRecord")
|
627
|
+
return 0
|
628
|
+
elsif options[:yaml]
|
629
|
+
puts as_yaml(json_response, options, "networkDomainRecord")
|
630
|
+
return 0
|
631
|
+
elsif options[:csv]
|
632
|
+
puts records_as_csv([network_domain_record], options)
|
633
|
+
return 0
|
634
|
+
end
|
635
|
+
print_h1 "Network Domain Record Details"
|
636
|
+
print cyan
|
637
|
+
description_cols = {
|
638
|
+
"ID" => 'id',
|
639
|
+
"Name" => lambda {|it| it['name'] },
|
640
|
+
"FQDN" => lambda {|it| it['fqdn'] },
|
641
|
+
"Type" => lambda {|it| it['type'] },
|
642
|
+
"Content" => lambda {|it| it['content'] },
|
643
|
+
"Comment" => lambda {|it| it['Comment'] },
|
644
|
+
"TTL" => lambda {|it| it['ttl'] },
|
645
|
+
"Domain" => lambda {|it| network_domain['name'] },
|
646
|
+
"Source" => lambda {|it| it['source'] },
|
647
|
+
"Created By" => lambda {|it| it['createdBy'] ? it['createdBy']['username'] : '' },
|
648
|
+
#"Created" => lambda {|it| format_local_dt(it['dateCreated']) },
|
649
|
+
#"Updated" => lambda {|it| format_local_dt(it['lastUpdated']) },
|
650
|
+
#"Status" => lambda {|it| it['statusMessage'].to_s.empty? ? it['status'] : "#{it['status']} - #{it['statusMessage']}" },
|
651
|
+
}
|
652
|
+
print_description_list(description_cols, network_domain_record)
|
653
|
+
|
654
|
+
print reset,"\n"
|
655
|
+
return 0
|
656
|
+
rescue RestClient::Exception => e
|
657
|
+
print_rest_exception(e, options)
|
658
|
+
exit 1
|
659
|
+
end
|
660
|
+
end
|
661
|
+
|
662
|
+
def add_record(args)
|
663
|
+
options = {}
|
664
|
+
params = {}
|
665
|
+
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
666
|
+
opts.banner = subcommand_usage("[network-domain] [record]")
|
667
|
+
opts.on('--name VALUE', String, "Name") do |val|
|
668
|
+
options[:options]['name'] = val
|
669
|
+
end
|
670
|
+
opts.on('--type VALUE', String, "Domain Record Type. Default is 'A'") do |val|
|
671
|
+
options[:options]['type'] = val
|
672
|
+
end
|
673
|
+
# opts.on('--fqdn VALUE', String, "FQDN") do |val|
|
674
|
+
# options[:options]['hostname'] = val
|
675
|
+
# end
|
676
|
+
opts.on('--content VALUE', String, "Content") do |val|
|
677
|
+
options[:options]['content'] = val
|
678
|
+
end
|
679
|
+
opts.on('--comment VALUE', String, "Comment") do |val|
|
680
|
+
options[:options]['comment'] = val
|
681
|
+
end
|
682
|
+
opts.on('--ttl SECONDS', String, "TTL in seconds. Default is 86400.") do |val|
|
683
|
+
options[:options]['ttl'] = val
|
684
|
+
end
|
685
|
+
build_common_options(opts, options, [:options, :payload, :json, :dry_run, :quiet, :remote])
|
686
|
+
opts.footer = "Create a new network domain record." + "\n" +
|
687
|
+
"[network-domain] is required. This is the name or id of a network domain.\n" +
|
688
|
+
"[record] is required. This is the name of the domain record and can be passed as --name instead."
|
689
|
+
end
|
690
|
+
optparse.parse!(args)
|
691
|
+
if args.count < 1 || args.count > 2
|
692
|
+
raise_command_error "wrong number of arguments, expected 1-2 and got (#{args.count}) #{args}\n#{optparse}"
|
693
|
+
end
|
694
|
+
connect(options)
|
695
|
+
begin
|
696
|
+
network_domain = find_network_domain_by_name_or_id(args[0])
|
697
|
+
return 1 if network_domain.nil?
|
698
|
+
network_domain_id = network_domain['id']
|
699
|
+
|
700
|
+
# support [name] as first argument
|
701
|
+
if args[1]
|
702
|
+
options[:options]['name'] = args[1]
|
703
|
+
end
|
704
|
+
|
705
|
+
# construct payload
|
706
|
+
payload = nil
|
707
|
+
if options[:payload]
|
708
|
+
payload = options[:payload]
|
709
|
+
else
|
710
|
+
# prompt for network options
|
711
|
+
payload = {
|
712
|
+
'networkDomainRecord' => {
|
713
|
+
#'networkDomain' => {'id' => network_domain['id']}
|
714
|
+
}
|
715
|
+
}
|
716
|
+
|
717
|
+
# allow arbitrary -O options
|
718
|
+
payload['networkDomainRecord'].deep_merge!(options[:options].reject {|k,v| k.is_a?(Symbol) }) if options[:options]
|
719
|
+
|
720
|
+
# Name
|
721
|
+
v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'name', 'fieldLabel' => 'Name', 'type' => 'text', 'required' => true, 'description' => 'Name of this domain record.'}], options[:options])
|
722
|
+
payload['networkDomainRecord']['name'] = v_prompt['name'] unless v_prompt['name'].to_s.empty?
|
723
|
+
|
724
|
+
# Type
|
725
|
+
v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'content', 'fieldLabel' => 'Type', 'type' => 'select', 'required' => true, 'optionSource' => 'dnsRecordType', 'description' => 'Type for this domain record.', 'defaultValue' => 'A'}], options[:options], @api_client)
|
726
|
+
payload['networkDomainRecord']['type'] = v_prompt['type'] unless v_prompt['type'].to_s.empty?
|
727
|
+
|
728
|
+
# Content
|
729
|
+
v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'content', 'fieldLabel' => 'Content', 'type' => 'textarea', 'required' => true, 'description' => 'Content for this domain record.'}], options[:options])
|
730
|
+
payload['networkDomainRecord']['content'] = v_prompt['content'] unless v_prompt['content'].to_s.empty?
|
731
|
+
|
732
|
+
# TTL
|
733
|
+
if options[:options]['ttl'] == 'null'
|
734
|
+
payload['networkDomainRecord']['ttl'] = nil
|
735
|
+
else
|
736
|
+
v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'ttl', 'fieldLabel' => 'TTL', 'type' => 'text', 'required' => false, 'description' => 'TTL in seconds for this domain record. Default is 86400.'}], options[:options])
|
737
|
+
payload['networkDomainRecord']['ttl'] = v_prompt['ttl'].to_i unless v_prompt['ttl'].to_s.empty?
|
738
|
+
end
|
739
|
+
|
740
|
+
# Comment
|
741
|
+
# v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'comment', 'fieldLabel' => 'Comment', 'type' => 'text', 'required' => true, 'description' => 'Comment for this domain record.'}], options[:options])
|
742
|
+
# payload['networkDomainRecord']['comment'] = v_prompt['comment'] unless v_prompt['comment'].to_s.empty?
|
743
|
+
|
744
|
+
end
|
745
|
+
|
746
|
+
@network_domain_records_interface.setopts(options)
|
747
|
+
if options[:dry_run]
|
748
|
+
print_dry_run @network_domain_records_interface.dry.create(network_domain_id, payload)
|
749
|
+
return
|
750
|
+
end
|
751
|
+
json_response = @network_domain_records_interface.create(network_domain_id, payload)
|
752
|
+
if options[:json]
|
753
|
+
print JSON.pretty_generate(json_response)
|
754
|
+
print "\n"
|
755
|
+
elsif !options[:quiet]
|
756
|
+
network_domain_record = json_response['networkDomainRecord']
|
757
|
+
print_green_success "Added network domain record #{network_domain_record['name']}"
|
758
|
+
get_record([network_domain['id'], network_domain_record['id']])
|
759
|
+
end
|
760
|
+
return 0
|
761
|
+
rescue RestClient::Exception => e
|
762
|
+
print_rest_exception(e, options)
|
763
|
+
exit 1
|
764
|
+
end
|
765
|
+
end
|
766
|
+
|
767
|
+
def remove_record(args)
|
768
|
+
options = {}
|
769
|
+
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
770
|
+
opts.banner = subcommand_usage("[network-domain] [record]")
|
771
|
+
build_common_options(opts, options, [:account, :auto_confirm, :json, :dry_run, :remote])
|
772
|
+
opts.footer = "Delete a network domain record." + "\n" +
|
773
|
+
"[network-domain] is required. This is the name or id of a network domain.\n" +
|
774
|
+
"[record] is required. This is the name or id of a network domain record."
|
775
|
+
end
|
776
|
+
optparse.parse!(args)
|
777
|
+
if args.count != 2
|
778
|
+
raise_command_error "wrong number of arguments, expected 2 and got (#{args.count}) #{args}\n#{optparse}"
|
779
|
+
end
|
780
|
+
connect(options)
|
781
|
+
begin
|
782
|
+
network_domain = find_network_domain_by_name_or_id(args[0])
|
783
|
+
return 1 if network_domain.nil?
|
784
|
+
network_domain_id = network_domain['id']
|
785
|
+
|
786
|
+
network_domain_record = find_network_domain_record_by_name_or_id(network_domain_id, args[1])
|
787
|
+
return 1 if network_domain_record.nil?
|
788
|
+
|
789
|
+
unless options[:yes] || Morpheus::Cli::OptionTypes.confirm("Are you sure you want to delete the networkd domain record: #{network_domain_record['name']}?")
|
790
|
+
return 9, "aborted command"
|
791
|
+
end
|
792
|
+
@network_domain_records_interface.setopts(options)
|
793
|
+
if options[:dry_run]
|
794
|
+
print_dry_run @network_domain_records_interface.dry.destroy(network_domain['id'], network_domain_record['id'])
|
795
|
+
return 0
|
796
|
+
end
|
797
|
+
json_response = @network_domain_records_interface.destroy(network_domain['id'], network_domain_record['id'])
|
798
|
+
if options[:json]
|
799
|
+
print JSON.pretty_generate(json_response)
|
800
|
+
print "\n"
|
801
|
+
else
|
802
|
+
print_green_success "Removed network domain record #{network_domain_record['name']}"
|
803
|
+
# list([])
|
804
|
+
end
|
805
|
+
return 0
|
806
|
+
rescue RestClient::Exception => e
|
807
|
+
print_rest_exception(e, options)
|
808
|
+
return 1
|
809
|
+
end
|
810
|
+
end
|
811
|
+
|
518
812
|
private
|
519
813
|
|
520
814
|
|
@@ -559,4 +853,48 @@ class Morpheus::Cli::NetworkDomainsCommand
|
|
559
853
|
end
|
560
854
|
end
|
561
855
|
|
856
|
+
def find_network_domain_record_by_name_or_id(network_domain_id, val)
|
857
|
+
if val.to_s =~ /\A\d{1,}\Z/
|
858
|
+
return find_network_domain_record_by_id(network_domain_id, val)
|
859
|
+
else
|
860
|
+
return find_network_domain_record_by_name(network_domain_id, val)
|
861
|
+
end
|
862
|
+
end
|
863
|
+
|
864
|
+
def find_network_domain_record_by_id(network_domain_id, id)
|
865
|
+
begin
|
866
|
+
json_response = @network_domain_records_interface.get(network_domain_id, id.to_i)
|
867
|
+
return json_response['networkDomainRecord']
|
868
|
+
rescue RestClient::Exception => e
|
869
|
+
if e.response && e.response.code == 404
|
870
|
+
print_red_alert "Network Domain Record not found by id #{id}"
|
871
|
+
return nil
|
872
|
+
else
|
873
|
+
raise e
|
874
|
+
end
|
875
|
+
end
|
876
|
+
end
|
877
|
+
|
878
|
+
def find_network_domain_record_by_name(network_domain_id, name)
|
879
|
+
json_response = @network_domain_records_interface.list(network_domain_id, {name: name.to_s})
|
880
|
+
network_domain_records = json_response['networkDomainRecords']
|
881
|
+
if network_domain_records.empty?
|
882
|
+
print_red_alert "Network Domain Record not found by name #{name}"
|
883
|
+
return nil
|
884
|
+
elsif network_domain_records.size > 1
|
885
|
+
print_red_alert "#{network_domain_records.size} network domain records found by name #{name}"
|
886
|
+
columns = [
|
887
|
+
{"ID" => lambda {|it| it['id'] } },
|
888
|
+
{"NAME" => lambda {|it| it['name'] } },
|
889
|
+
#{"FQDN" => lambda {|it| it['fqdn'] } },
|
890
|
+
{"TYPE" => lambda {|it| it['type'] } },
|
891
|
+
{"CONTENT" => lambda {|it| it['content'] } }
|
892
|
+
]
|
893
|
+
puts as_pretty_table(network_domain_records, columns, {color:red})
|
894
|
+
return nil
|
895
|
+
else
|
896
|
+
return network_domain_records[0]
|
897
|
+
end
|
898
|
+
end
|
899
|
+
|
562
900
|
end
|