morpheus-cli 5.3.2 → 5.3.2.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/accounts_interface.rb +4 -30
- data/lib/morpheus/api/api_client.rb +12 -0
- data/lib/morpheus/api/load_balancer_pools_interface.rb +9 -0
- data/lib/morpheus/api/load_balancer_types_interface.rb +9 -0
- data/lib/morpheus/api/load_balancer_virtual_servers_interface.rb +9 -0
- data/lib/morpheus/api/load_balancers_interface.rb +4 -53
- data/lib/morpheus/api/network_routers_interface.rb +56 -0
- data/lib/morpheus/api/secondary_read_interface.rb +25 -0
- data/lib/morpheus/api/secondary_rest_interface.rb +42 -0
- data/lib/morpheus/cli.rb +1 -0
- data/lib/morpheus/cli/cli_command.rb +9 -9
- data/lib/morpheus/cli/instances.rb +33 -33
- data/lib/morpheus/cli/load_balancer_types.rb +37 -0
- data/lib/morpheus/cli/load_balancers.rb +149 -314
- data/lib/morpheus/cli/log_settings_command.rb +7 -3
- data/lib/morpheus/cli/mixins/load_balancers_helper.rb +156 -0
- data/lib/morpheus/cli/mixins/print_helper.rb +11 -0
- data/lib/morpheus/cli/mixins/rest_command.rb +657 -0
- data/lib/morpheus/cli/network_routers_command.rb +1183 -185
- data/lib/morpheus/cli/networks_command.rb +194 -101
- data/lib/morpheus/cli/option_types.rb +29 -39
- data/lib/morpheus/cli/tenants_command.rb +18 -20
- data/lib/morpheus/cli/version.rb +1 -1
- data/lib/morpheus/ext/string.rb +41 -0
- data/lib/morpheus/formatters.rb +4 -0
- metadata +11 -2
@@ -11,10 +11,12 @@ class Morpheus::Cli::NetworkRoutersCommand
|
|
11
11
|
include Morpheus::Cli::WhoamiHelper
|
12
12
|
|
13
13
|
set_command_name :'network-routers'
|
14
|
-
register_subcommands :list, :get, :firewall, :dhcp, :
|
15
|
-
register_subcommands :
|
16
|
-
register_subcommands :
|
14
|
+
register_subcommands :list, :get, :firewall, :dhcp, :types, :type, :add, :update, :remove
|
15
|
+
register_subcommands :add_firewall_rule_group, :update_firewall_rule_group, :remove_firewall_rule_group, :firewall_rule_groups, :firewall_rule_group
|
16
|
+
register_subcommands :add_firewall_rule, :update_firewall_rule, :remove_firewall_rule, :firewall_rules, :firewall_rule
|
17
|
+
register_subcommands :add_route, :remove_route, :routes
|
17
18
|
register_subcommands :update_permissions
|
19
|
+
register_subcommands :add_nat, :update_nat, :remove_nat, :nats, :nat
|
18
20
|
|
19
21
|
def initialize()
|
20
22
|
end
|
@@ -107,7 +109,7 @@ class Morpheus::Cli::NetworkRoutersCommand
|
|
107
109
|
options = {}
|
108
110
|
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
109
111
|
opts.banner = subcommand_usage("[router]")
|
110
|
-
opts.on('--details', "Display details: firewall, DHCP, and
|
112
|
+
opts.on('--details', "Display details: firewall, DHCP, routing, and NATs." ) do
|
111
113
|
options[:details] = true
|
112
114
|
end
|
113
115
|
build_common_options(opts, options, [:json, :yaml, :csv, :fields, :dry_run, :remote])
|
@@ -192,7 +194,7 @@ class Morpheus::Cli::NetworkRoutersCommand
|
|
192
194
|
if router['type']['hasFirewall']
|
193
195
|
print_h2 "Firewall"
|
194
196
|
print cyan
|
195
|
-
print_firewall(router, options
|
197
|
+
print_firewall(router, options)
|
196
198
|
end
|
197
199
|
if router['type']['hasDhcp']
|
198
200
|
print_h2 "DHCP"
|
@@ -204,6 +206,11 @@ class Morpheus::Cli::NetworkRoutersCommand
|
|
204
206
|
print cyan
|
205
207
|
print_routes(router)
|
206
208
|
end
|
209
|
+
if router['type']['hasNat'] && options[:details]
|
210
|
+
print_h2 "NATs"
|
211
|
+
print cyan
|
212
|
+
print_nats(router)
|
213
|
+
end
|
207
214
|
if router['permissions'] && options[:details]
|
208
215
|
print_h2 "Tenant Permissions"
|
209
216
|
print cyan
|
@@ -360,9 +367,15 @@ class Morpheus::Cli::NetworkRoutersCommand
|
|
360
367
|
params = {}
|
361
368
|
optparse = Morpheus::Cli::OptionParser.new do|opts|
|
362
369
|
opts.banner = subcommand_usage("[router]")
|
363
|
-
opts.on('-
|
370
|
+
opts.on('-n', '--name VALUE', String, "Name for this network") do |val|
|
371
|
+
params['name'] = val
|
372
|
+
end
|
373
|
+
opts.on('-D', '--description VALUE', String, "Description for this network") do |val|
|
364
374
|
params['description'] = val
|
365
375
|
end
|
376
|
+
opts.on('--enabled [on|off]', String, "Can be used to enable / disable the network router. Default is on") do |val|
|
377
|
+
options[:enabled] = val.to_s == 'on' || val.to_s == 'true' || val.to_s == '1' || val.to_s == ''
|
378
|
+
end
|
366
379
|
build_common_options(opts, options, [:options, :payload, :json, :dry_run, :remote])
|
367
380
|
opts.footer = "Update a network router."
|
368
381
|
end
|
@@ -388,7 +401,7 @@ class Morpheus::Cli::NetworkRoutersCommand
|
|
388
401
|
end
|
389
402
|
|
390
403
|
if options[:options]
|
391
|
-
params.deep_merge!(options[:options].reject {|k,v| k.is_a?(Symbol) || ['name', 'routerType'].include?(k)})
|
404
|
+
params.deep_merge!(options[:options].reject {|k,v| k.is_a?(Symbol) || ['name', 'routerType', 'enabled', 'description'].include?(k)})
|
392
405
|
end
|
393
406
|
payload = {'networkRouter' => params}
|
394
407
|
end
|
@@ -468,6 +481,9 @@ class Morpheus::Cli::NetworkRoutersCommand
|
|
468
481
|
options = {}
|
469
482
|
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
470
483
|
opts.banner = subcommand_usage("[router]")
|
484
|
+
opts.on('--details', "Display details." ) do
|
485
|
+
options[:details] = true
|
486
|
+
end
|
471
487
|
build_common_options(opts, options, [:json, :yaml, :csv, :fields, :dry_run, :remote])
|
472
488
|
opts.footer = "Display network router firewall details." + "\n" +
|
473
489
|
"[router] is required. This is the name or id of a network router."
|
@@ -480,21 +496,18 @@ class Morpheus::Cli::NetworkRoutersCommand
|
|
480
496
|
puts optparse
|
481
497
|
return 1
|
482
498
|
end
|
483
|
-
_firewall(args[0], options)
|
484
|
-
end
|
485
499
|
|
486
|
-
def _firewall(router_id, options)
|
487
500
|
begin
|
488
501
|
@network_routers_interface.setopts(options)
|
489
502
|
if options[:dry_run]
|
490
503
|
if args[0].to_s =~ /\A\d{1,}\Z/
|
491
|
-
print_dry_run @network_routers_interface.dry.get(
|
504
|
+
print_dry_run @network_routers_interface.dry.get(args[0].to_i)
|
492
505
|
else
|
493
|
-
print_dry_run @network_routers_interface.dry.list({name:
|
506
|
+
print_dry_run @network_routers_interface.dry.list({name:args[0]})
|
494
507
|
end
|
495
508
|
return
|
496
509
|
end
|
497
|
-
router = find_router(
|
510
|
+
router = find_router(args[0])
|
498
511
|
if router.nil?
|
499
512
|
return 1
|
500
513
|
end
|
@@ -512,34 +525,930 @@ class Morpheus::Cli::NetworkRoutersCommand
|
|
512
525
|
return 0
|
513
526
|
end
|
514
527
|
|
515
|
-
|
516
|
-
print_h1 "Network Router Firewall Details for: #{router['name']}"
|
517
|
-
end
|
518
|
-
|
528
|
+
print_h1 "Network Router Firewall Details For: #{router['name']}"
|
519
529
|
print cyan
|
520
530
|
|
521
531
|
if router['type']['hasFirewall']
|
522
|
-
print_firewall(router,
|
532
|
+
print_firewall(router, options)
|
523
533
|
else
|
524
534
|
print_red_alert "Firewall not supported for #{router['type']['name']}"
|
525
535
|
end
|
526
|
-
println reset
|
527
|
-
rescue RestClient::Exception => e
|
528
|
-
print_rest_exception(e, options)
|
529
|
-
return 1
|
530
|
-
end
|
531
|
-
end
|
532
|
-
|
533
|
-
def
|
534
|
-
options = {
|
535
|
-
|
536
|
-
|
537
|
-
opts
|
538
|
-
opts.
|
539
|
-
|
536
|
+
println reset
|
537
|
+
rescue RestClient::Exception => e
|
538
|
+
print_rest_exception(e, options)
|
539
|
+
return 1
|
540
|
+
end
|
541
|
+
end
|
542
|
+
|
543
|
+
def firewall_rule_groups(args)
|
544
|
+
options = {}
|
545
|
+
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
546
|
+
opts.banner = subcommand_usage("[router]")
|
547
|
+
build_common_options(opts, options, [:json, :yaml, :csv, :fields, :dry_run, :remote])
|
548
|
+
opts.footer = "Display network router firewall rule groups.\n" +
|
549
|
+
"[router] is required. This is the name or id of a network router."
|
550
|
+
end
|
551
|
+
|
552
|
+
optparse.parse!(args)
|
553
|
+
connect(options)
|
554
|
+
|
555
|
+
if args.count < 1
|
556
|
+
puts optparse
|
557
|
+
return 1
|
558
|
+
end
|
559
|
+
|
560
|
+
begin
|
561
|
+
@network_routers_interface.setopts(options)
|
562
|
+
if options[:dry_run]
|
563
|
+
if router_id.to_s =~ /\A\d{1,}\Z/
|
564
|
+
print_dry_run @network_routers_interface.dry.get(router_id.to_i)
|
565
|
+
else
|
566
|
+
print_dry_run @network_routers_interface.dry.list({name:router_id})
|
567
|
+
end
|
568
|
+
return
|
569
|
+
end
|
570
|
+
|
571
|
+
router = find_router(args[0])
|
572
|
+
if router.nil?
|
573
|
+
return 1
|
574
|
+
end
|
575
|
+
_firewall_rule_groups(router, options)
|
576
|
+
rescue RestClient::Exception => e
|
577
|
+
print_rest_exception(e, options)
|
578
|
+
return 1
|
579
|
+
end
|
580
|
+
end
|
581
|
+
|
582
|
+
def _firewall_rule_groups(router, options)
|
583
|
+
if router['type']['hasFirewallGroups']
|
584
|
+
json_response = {'ruleGroups' => router['firewall']['ruleGroups'] || []}
|
585
|
+
|
586
|
+
if options[:json]
|
587
|
+
puts as_json(json_response, options, "ruleGroups")
|
588
|
+
return 0
|
589
|
+
elsif options[:yaml]
|
590
|
+
puts as_yaml(json_response, options, "ruleGroups")
|
591
|
+
return 0
|
592
|
+
elsif options[:csv]
|
593
|
+
puts records_as_csv(json_response['ruleGroups'], options)
|
594
|
+
return 0
|
595
|
+
end
|
596
|
+
|
597
|
+
if (router['firewall']['ruleGroups'] || []).count > 0
|
598
|
+
print_h1 "Firewall Rule Groups For: #{router['name']}"
|
599
|
+
rows = router['firewall']['ruleGroups'].collect do |rule_group|
|
600
|
+
{
|
601
|
+
id: rule_group['id'],
|
602
|
+
name: rule_group['name'],
|
603
|
+
description: rule_group['description'],
|
604
|
+
priority: rule_group['priority'],
|
605
|
+
category: rule_group['groupLayer']
|
606
|
+
}
|
607
|
+
end
|
608
|
+
rows = rows.reject {|it| it[:id].to_s != options[:rule_group_id].to_s} if options[:rule_group_id]
|
609
|
+
puts as_pretty_table(rows, [:id, :name, :description, :priority, :category])
|
610
|
+
else
|
611
|
+
print_h1 "No Firewall Rule Groups"
|
612
|
+
end
|
613
|
+
else
|
614
|
+
print_red_alert "Firewall rule groups not supported for #{router['type']['name']}"
|
615
|
+
end
|
616
|
+
println reset
|
617
|
+
end
|
618
|
+
|
619
|
+
def firewall_rule_group(args)
|
620
|
+
options = {}
|
621
|
+
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
622
|
+
opts.banner = subcommand_usage("[router]")
|
623
|
+
build_common_options(opts, options, [:json, :yaml, :csv, :fields, :dry_run, :remote])
|
624
|
+
opts.footer = "Display network router firewall rule group details." + "\n" +
|
625
|
+
"[router] is required. This is the name or id of a network router.\n" +
|
626
|
+
"[group] is required. This is the name or id of a firewall rule group.\n"
|
627
|
+
end
|
628
|
+
|
629
|
+
optparse.parse!(args)
|
630
|
+
connect(options)
|
631
|
+
|
632
|
+
if args.count < 2
|
633
|
+
puts optparse
|
634
|
+
return 1
|
635
|
+
end
|
636
|
+
_firewall_rule_group(args[0], args[1], options)
|
637
|
+
end
|
638
|
+
|
639
|
+
def _firewall_rule_group(router_id, group_id, options)
|
640
|
+
begin
|
641
|
+
@network_routers_interface.setopts(options)
|
642
|
+
if options[:dry_run]
|
643
|
+
if args[0].to_s =~ /\A\d{1,}\Z/
|
644
|
+
print_dry_run @network_routers_interface.dry.get(router_id.to_i)
|
645
|
+
else
|
646
|
+
print_dry_run @network_routers_interface.dry.list({name:router_id})
|
647
|
+
end
|
648
|
+
return
|
649
|
+
end
|
650
|
+
router = find_router(router_id)
|
651
|
+
if router.nil?
|
652
|
+
return 1
|
653
|
+
end
|
654
|
+
|
655
|
+
if router['type']['hasFirewallGroups']
|
656
|
+
group = (router['firewall']['ruleGroups'] || []).find {|it| it['id'].to_s == group_id.to_s || it['name'] == group_id.to_s}
|
657
|
+
|
658
|
+
if group
|
659
|
+
json_response = {'ruleGroup' => group}
|
660
|
+
|
661
|
+
if options[:json]
|
662
|
+
puts as_json(json_response, options, "ruleGroup")
|
663
|
+
return 0
|
664
|
+
elsif options[:yaml]
|
665
|
+
puts as_yaml(json_response, options, "ruleGroup")
|
666
|
+
return 0
|
667
|
+
elsif options[:csv]
|
668
|
+
puts records_as_csv([json_response['ruleGroup']], options)
|
669
|
+
return 0
|
670
|
+
end
|
671
|
+
|
672
|
+
print_h1 "Firewall Rule Group Details"
|
673
|
+
print cyan
|
674
|
+
description_cols = {
|
675
|
+
"ID" => lambda {|it| it['id'] },
|
676
|
+
"Name" => lambda {|it| it['name'] },
|
677
|
+
"Description" => lambda {|it| it['description']},
|
678
|
+
"Priority" => lambda {|it| it['priority']},
|
679
|
+
"Category" => lambda {|it| it['groupLayer']}
|
680
|
+
}
|
681
|
+
print_description_list(description_cols, group)
|
682
|
+
else
|
683
|
+
print_red_alert "Firewall rule group #{group_id} not found for router #{router['name']}"
|
684
|
+
end
|
685
|
+
else
|
686
|
+
print_h1 "No Firewall Rule Groups"
|
687
|
+
end
|
688
|
+
println reset
|
689
|
+
rescue RestClient::Exception => e
|
690
|
+
print_rest_exception(e, options)
|
691
|
+
return 1
|
692
|
+
end
|
693
|
+
end
|
694
|
+
|
695
|
+
def add_firewall_rule_group(args)
|
696
|
+
options = {:options=>{}}
|
697
|
+
params = {}
|
698
|
+
optparse = Morpheus::Cli::OptionParser.new do|opts|
|
699
|
+
opts.banner = subcommand_usage("[router] [name]")
|
700
|
+
opts.on('-n', '--name VALUE', String, "Name for this firewall rule group") do |val|
|
701
|
+
params['name'] = val
|
702
|
+
end
|
703
|
+
opts.on('-D', '--description VALUE', String, "Description for this firewall rule group") do |val|
|
704
|
+
params['description'] = val
|
705
|
+
end
|
706
|
+
opts.on('--priority VALUE', Integer, "Priority for this firewall rule group (not applicable to all firewall types)") do |val|
|
707
|
+
params['priority'] = val
|
708
|
+
end
|
709
|
+
build_common_options(opts, options, [:options, :payload, :json, :dry_run, :remote])
|
710
|
+
opts.footer = "Create a network router firewall rule group."
|
711
|
+
end
|
712
|
+
optparse.parse!(args)
|
713
|
+
connect(options)
|
714
|
+
if args.count < 1 || args.count > 2
|
715
|
+
print_error Morpheus::Terminal.angry_prompt
|
716
|
+
puts_error "wrong number of arguments, expected 1-2 and got (#{args.count}) #{args.inspect}\n#{optparse}"
|
717
|
+
return 1
|
718
|
+
end
|
719
|
+
if args.count > 1
|
720
|
+
params['name'] = args[1]
|
721
|
+
end
|
722
|
+
begin
|
723
|
+
router = find_router(args[0])
|
724
|
+
|
725
|
+
if router.nil?
|
726
|
+
return 1
|
727
|
+
end
|
728
|
+
|
729
|
+
if !router['type']['hasFirewallGroups']
|
730
|
+
print_red_alert "Firewall rule groups not supported for #{router['type']['name']}"
|
731
|
+
return 1
|
732
|
+
end
|
733
|
+
|
734
|
+
if options[:payload]
|
735
|
+
payload = options[:payload]
|
736
|
+
else
|
737
|
+
params['name'] ||= Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'name', 'type' => 'text', 'fieldLabel' => 'Group Name', 'required' => true}], options[:options], @api_client, params)['name']
|
738
|
+
params['description'] ||= Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'description', 'type' => 'text', 'fieldLabel' => 'Description', 'required' => false}], options[:options], @api_client, params)['description']
|
739
|
+
|
740
|
+
if router['type']['hasSecurityGroupPriority']
|
741
|
+
params['priority'] ||= Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'priority', 'type' => 'number', 'fieldLabel' => 'Priority', 'required' => false}], options[:options], @api_client, params)['priority']
|
742
|
+
end
|
743
|
+
|
744
|
+
option_types = router['type']['ruleGroupOptionTypes'].reject {|it| ['name'].include?(it['fieldName'])}.sort {|it| it['displayOrder']}
|
745
|
+
|
746
|
+
# prompt options
|
747
|
+
option_result = Morpheus::Cli::OptionTypes.prompt(option_types, options[:options].deep_merge({:context_map => {'group' => ''}}), @api_client, {}, nil, true)
|
748
|
+
payload = {'ruleGroup' => params.deep_merge(option_result)}
|
749
|
+
end
|
750
|
+
|
751
|
+
@network_routers_interface.setopts(options)
|
752
|
+
if options[:dry_run]
|
753
|
+
print_dry_run @network_routers_interface.dry.create_firewall_rule_group(router['id'], payload)
|
754
|
+
return
|
755
|
+
end
|
756
|
+
|
757
|
+
json_response = @network_routers_interface.create_firewall_rule_group(router['id'], payload)
|
758
|
+
|
759
|
+
if options[:json]
|
760
|
+
print JSON.pretty_generate(json_response), "\n"
|
761
|
+
return
|
762
|
+
end
|
763
|
+
print_green_success "\nAdded Network Router Firewall Rule Group #{payload['ruleGroup']['name']}\n"
|
764
|
+
_firewall_rule_group(router['id'], json_response['id'], options)
|
765
|
+
rescue RestClient::Exception => e
|
766
|
+
print_rest_exception(e, options)
|
767
|
+
exit 1
|
768
|
+
end
|
769
|
+
end
|
770
|
+
|
771
|
+
def update_firewall_rule_group(args)
|
772
|
+
options = {:options=>{}}
|
773
|
+
params = {}
|
774
|
+
optparse = Morpheus::Cli::OptionParser.new do|opts|
|
775
|
+
opts.banner = subcommand_usage("[router] [name]")
|
776
|
+
opts.on('-n', '--name VALUE', String, "Name for this firewall rule group") do |val|
|
777
|
+
params['name'] = val
|
778
|
+
end
|
779
|
+
opts.on('-D', '--description VALUE', String, "Description for this firewall rule group") do |val|
|
780
|
+
params['description'] = val
|
781
|
+
end
|
782
|
+
opts.on('--priority VALUE', Integer, "Priority for this firewall rule group (not applicable to all firewall types)") do |val|
|
783
|
+
params['priority'] = val
|
784
|
+
end
|
785
|
+
build_common_options(opts, options, [:options, :payload, :json, :dry_run, :remote])
|
786
|
+
opts.footer = "Update a network router firewall rule group.\n" +
|
787
|
+
"[router] is required. This is the name or id of an existing network router.\n" +
|
788
|
+
"[name] is required. This is the name or id of an existing network router firewall rule group."
|
789
|
+
end
|
790
|
+
|
791
|
+
optparse.parse!(args)
|
792
|
+
if args.count != 2
|
793
|
+
raise_command_error "wrong number of arguments, expected 2 and got (#{args.count}) #{args}\n#{optparse}"
|
794
|
+
end
|
795
|
+
connect(options)
|
796
|
+
|
797
|
+
begin
|
798
|
+
router = find_router(args[0])
|
799
|
+
|
800
|
+
if router.nil?
|
801
|
+
return 1
|
802
|
+
end
|
803
|
+
|
804
|
+
if !router['type']['hasFirewallGroups']
|
805
|
+
print_red_alert "Firewall rule group not supported for #{router['type']['name']}"
|
806
|
+
return 1
|
807
|
+
end
|
808
|
+
|
809
|
+
group = router['firewall'] && router['firewall']['ruleGroups'] ? router['firewall']['ruleGroups'].find {|it| it['name'] == args[1] || it['id'] == args[1].to_i} : nil
|
810
|
+
|
811
|
+
if !group
|
812
|
+
print_red_alert "Firewall rule group #{args[1]} not found for router #{router['name']}"
|
813
|
+
exit 1
|
814
|
+
end
|
815
|
+
|
816
|
+
payload = parse_payload(options) || {'ruleGroup' => params}
|
817
|
+
payload['ruleGroup'].deep_merge!(options[:options].reject {|k,v| k.is_a?(Symbol) }) if options[:options]
|
818
|
+
|
819
|
+
if payload['ruleGroup'].empty?
|
820
|
+
print_green_success "Nothing to update"
|
821
|
+
exit 1
|
822
|
+
end
|
823
|
+
|
824
|
+
@network_routers_interface.setopts(options)
|
825
|
+
if options[:dry_run]
|
826
|
+
print_dry_run @network_routers_interface.dry.update_firewall_rule_group(router['id'], group['id'], payload)
|
827
|
+
return
|
828
|
+
end
|
829
|
+
|
830
|
+
json_response = @network_routers_interface.update_firewall_rule_group(router['id'], group['id'], payload)
|
831
|
+
|
832
|
+
if options[:json]
|
833
|
+
print JSON.pretty_generate(json_response), "\n"
|
834
|
+
return
|
835
|
+
end
|
836
|
+
print_green_success "\nUpdated Network Router Firewall Rule Group #{payload['ruleGroup']['name']}\n"
|
837
|
+
_firewall_rule_group(router['id'], args[1], options)
|
838
|
+
rescue RestClient::Exception => e
|
839
|
+
print_rest_exception(e, options)
|
840
|
+
exit 1
|
841
|
+
end
|
842
|
+
end
|
843
|
+
|
844
|
+
def remove_firewall_rule_group(args)
|
845
|
+
options = {}
|
846
|
+
query_params = {}
|
847
|
+
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
848
|
+
opts.banner = subcommand_usage("[router] [group]")
|
849
|
+
build_common_options(opts, options, [:auto_confirm, :json, :dry_run, :quiet, :remote])
|
850
|
+
opts.footer = "Delete a network router firewall rule group.\n" +
|
851
|
+
"[router] is required. This is the name or id of an existing network router."
|
852
|
+
"[group] is required. This is the name or id of an existing network router firewall rule group."
|
853
|
+
end
|
854
|
+
optparse.parse!(args)
|
855
|
+
if args.count != 2
|
856
|
+
raise_command_error "wrong number of arguments, expected 2 and got (#{args.count}) #{args}\n#{optparse}"
|
857
|
+
end
|
858
|
+
connect(options)
|
859
|
+
|
860
|
+
begin
|
861
|
+
router = find_router(args[0])
|
862
|
+
return if !router
|
863
|
+
|
864
|
+
group = router['firewall'] && router['firewall']['ruleGroups'] ? router['firewall']['ruleGroups'].find {|it| it['name'] == args[1] || it['id'] == args[1].to_i} : nil
|
865
|
+
|
866
|
+
if !group
|
867
|
+
print_red_alert "Firewall rule group #{args[1]} not found for router #{router['name']}"
|
868
|
+
exit 1
|
869
|
+
end
|
870
|
+
|
871
|
+
unless options[:yes] || ::Morpheus::Cli::OptionTypes::confirm("Are you sure you would like to remove the firewall rule group '#{group['name']}' from router '#{router['name']}'?", options)
|
872
|
+
return 9, "aborted command"
|
873
|
+
end
|
874
|
+
@network_routers_interface.setopts(options)
|
875
|
+
if options[:dry_run]
|
876
|
+
print_dry_run @network_routers_interface.dry.destroy_firewall_rule_group(router['id'], group['id'])
|
877
|
+
return
|
878
|
+
end
|
879
|
+
json_response = @network_routers_interface.destroy_firewall_rule_group(router['id'], group['id'])
|
880
|
+
if options[:json]
|
881
|
+
print JSON.pretty_generate(json_response)
|
882
|
+
print "\n"
|
883
|
+
elsif !options[:quiet]
|
884
|
+
print_green_success "\nFirewall rule group #{group['name']} for router #{router['name']} is being removed...\n"
|
885
|
+
_firewall_rule_groups(find_router(router['id']), options)
|
886
|
+
end
|
887
|
+
rescue RestClient::Exception => e
|
888
|
+
print_rest_exception(e, options)
|
889
|
+
exit 1
|
890
|
+
end
|
891
|
+
end
|
892
|
+
|
893
|
+
def firewall_rules(args)
|
894
|
+
options = {}
|
895
|
+
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
896
|
+
opts.banner = subcommand_usage("[router]")
|
897
|
+
build_common_options(opts, options, [:json, :yaml, :csv, :fields, :dry_run, :remote])
|
898
|
+
opts.footer = "Display network router firewall rules.\n" +
|
899
|
+
"[router] is required. This is the name or id of a network router."
|
900
|
+
end
|
901
|
+
|
902
|
+
optparse.parse!(args)
|
903
|
+
connect(options)
|
904
|
+
|
905
|
+
if args.count < 1
|
906
|
+
puts optparse
|
907
|
+
return 1
|
908
|
+
end
|
909
|
+
|
910
|
+
begin
|
911
|
+
@network_routers_interface.setopts(options)
|
912
|
+
if options[:dry_run]
|
913
|
+
if args[0].to_s =~ /\A\d{1,}\Z/
|
914
|
+
print_dry_run @network_routers_interface.dry.get(args[0].to_i)
|
915
|
+
else
|
916
|
+
print_dry_run @network_routers_interface.dry.list({name:args[0]})
|
917
|
+
end
|
918
|
+
return
|
919
|
+
end
|
920
|
+
router = find_router(args[0])
|
921
|
+
if router.nil?
|
922
|
+
return 1
|
923
|
+
end
|
924
|
+
|
925
|
+
_firewall_rules(router, options)
|
926
|
+
rescue RestClient::Exception => e
|
927
|
+
print_rest_exception(e, options)
|
928
|
+
return 1
|
929
|
+
end
|
930
|
+
end
|
931
|
+
|
932
|
+
def _firewall_rules(router, options)
|
933
|
+
if router['type']['hasFirewall']
|
934
|
+
rules = router['type']['hasFirewallGroups'] ? (router['firewall']['ruleGroups'] || []).collect {|it| it['rules']}.flatten : router['firewall']['rules']
|
935
|
+
|
936
|
+
json_response = {'rules' => rules}
|
937
|
+
|
938
|
+
if options[:json]
|
939
|
+
puts as_json(json_response, options, "rules")
|
940
|
+
return 0
|
941
|
+
elsif options[:yaml]
|
942
|
+
puts as_yaml(json_response, options, "rules")
|
943
|
+
return 0
|
944
|
+
elsif options[:csv]
|
945
|
+
puts records_as_csv(json_response['rules'], options)
|
946
|
+
return 0
|
947
|
+
end
|
948
|
+
|
949
|
+
if router['type']['hasFirewallGroups']
|
950
|
+
rules = []
|
951
|
+
(router['firewall']['ruleGroups'] || []).each do |rule_group|
|
952
|
+
(rule_group['rules'] || []).each do |rule|
|
953
|
+
rule['groupId'] = rule_group['id']
|
954
|
+
rule['groupName'] ||= rule_group['name']
|
955
|
+
rules << rule
|
956
|
+
end
|
957
|
+
end
|
958
|
+
end
|
959
|
+
|
960
|
+
if rules.count > 0
|
961
|
+
print_h1 "Firewall Rules For: #{router['name']}"
|
962
|
+
rows = rules.collect do |it|
|
963
|
+
{
|
964
|
+
id: it['id'],
|
965
|
+
group_name: it['groupName'],
|
966
|
+
name: it['name'],
|
967
|
+
type: it['ruleType'],
|
968
|
+
policy: it['policy'],
|
969
|
+
direction: it['direction'] || 'any',
|
970
|
+
source: it['source'].kind_of?(Array) && it['source'].count > 0 ? it['source'].join(', ') : (it['source'].nil? || it['source'].empty? ? 'any' : it['source']),
|
971
|
+
destination: it['destination'].kind_of?(Array) && it['destination'].count > 0 ? it['destination'].join(', ') : (it['destination'].nil? || it['destination'].empty? ? 'any' : it['destination']),
|
972
|
+
application: it['applications'].count > 0 ? it['applications'][0]['name'] : "#{(it['protocol'] || 'any')} #{it['portRange'] || ''}"
|
973
|
+
}
|
974
|
+
end
|
975
|
+
|
976
|
+
if router['type']['hasFirewallGroups']
|
977
|
+
puts as_pretty_table(rows, [:id, :group_name, :name, :type, :policy, :direction, :source, :destination, :application])
|
978
|
+
else
|
979
|
+
puts as_pretty_table(rows, [:id, :name, :type, :policy, :direction, :source, :destination, :application])
|
980
|
+
end
|
981
|
+
else
|
982
|
+
print_h1 "No Firewall Rules"
|
983
|
+
end
|
984
|
+
else
|
985
|
+
print_red_alert "Firewall not supported for #{router['type']['name']}"
|
986
|
+
end
|
987
|
+
println reset
|
988
|
+
end
|
989
|
+
|
990
|
+
def firewall_rule(args)
|
991
|
+
options = {}
|
992
|
+
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
993
|
+
opts.banner = subcommand_usage("[router] [rule]")
|
994
|
+
build_common_options(opts, options, [:json, :yaml, :csv, :fields, :dry_run, :remote])
|
995
|
+
opts.footer = "Display network router firewall rule details." + "\n" +
|
996
|
+
"[router] is required. This is the name or id of a network router.\n" +
|
997
|
+
"[rule] is required. This is the name or id of a firewall rule.\n"
|
998
|
+
end
|
999
|
+
|
1000
|
+
optparse.parse!(args)
|
1001
|
+
connect(options)
|
1002
|
+
|
1003
|
+
if args.count < 2
|
1004
|
+
puts optparse
|
1005
|
+
return 1
|
1006
|
+
end
|
1007
|
+
_firewall_rule(args[0], args[1], options)
|
1008
|
+
end
|
1009
|
+
|
1010
|
+
def _firewall_rule(router_id, rule_id, options)
|
1011
|
+
begin
|
1012
|
+
@network_routers_interface.setopts(options)
|
1013
|
+
if options[:dry_run]
|
1014
|
+
if args[0].to_s =~ /\A\d{1,}\Z/
|
1015
|
+
print_dry_run @network_routers_interface.dry.get(router_id.to_i)
|
1016
|
+
else
|
1017
|
+
print_dry_run @network_routers_interface.dry.list({name:router_id})
|
1018
|
+
end
|
1019
|
+
return
|
1020
|
+
end
|
1021
|
+
router = find_router(router_id)
|
1022
|
+
if router.nil?
|
1023
|
+
return 1
|
1024
|
+
end
|
1025
|
+
|
1026
|
+
if router['type']['hasFirewall']
|
1027
|
+
rule = find_firewall_rule(router, rule_id)
|
1028
|
+
|
1029
|
+
if rule
|
1030
|
+
json_response = {'rule' => rule}
|
1031
|
+
|
1032
|
+
if options[:json]
|
1033
|
+
puts as_json(json_response, options, "rule")
|
1034
|
+
return 0
|
1035
|
+
elsif options[:yaml]
|
1036
|
+
puts as_yaml(json_response, options, "rule")
|
1037
|
+
return 0
|
1038
|
+
elsif options[:csv]
|
1039
|
+
puts records_as_csv([json_response['rule']], options)
|
1040
|
+
return 0
|
1041
|
+
end
|
1042
|
+
|
1043
|
+
print_h1 "Firewall Rule Details"
|
1044
|
+
print cyan
|
1045
|
+
description_cols = {
|
1046
|
+
"ID" => lambda {|it| it['id'] },
|
1047
|
+
"Enabled" => lambda {|it| format_boolean(it['enabled'])},
|
1048
|
+
"Priority" => lambda {|it| it['priority']},
|
1049
|
+
"Name" => lambda {|it| it['name'] },
|
1050
|
+
"Type" => lambda {|it| it['ruleType'] },
|
1051
|
+
"Policy" => lambda {|it| it['policy'] },
|
1052
|
+
"Direction" => lambda {|it| it['direction'] || 'any' },
|
1053
|
+
"Source" => lambda {|it| it['source'].kind_of?(Array) && it['source'].count > 0 ? it['source'].join(', ') : (it['source'].nil? || it['source'].empty? ? 'any' : it['source']) },
|
1054
|
+
"Destination" => lambda {|it| it['destination'].kind_of?(Array) && it['destination'].count > 0 ? it['destination'].join(', ') : (it['destination'].nil? || it['destination'].empty? ? 'any' : it['destination'])},
|
1055
|
+
"Application" => lambda {|it| it['applications'].count > 0 ? it['applications'][0]['name'] : "#{(it['protocol'] || 'any')} #{it['portRange'] || ''}"}
|
1056
|
+
}
|
1057
|
+
print_description_list(description_cols, rule)
|
1058
|
+
else
|
1059
|
+
print_red_alert "Firewall rule #{rule_id} not found for router #{router['name']}"
|
1060
|
+
end
|
1061
|
+
else
|
1062
|
+
print_red_alert "Firewall not supported for #{router['type']['name']}"
|
1063
|
+
end
|
1064
|
+
println reset
|
1065
|
+
rescue RestClient::Exception => e
|
1066
|
+
print_rest_exception(e, options)
|
1067
|
+
return 1
|
1068
|
+
end
|
1069
|
+
end
|
1070
|
+
|
1071
|
+
def add_firewall_rule(args)
|
1072
|
+
options = {:options=>{}}
|
1073
|
+
params = {}
|
1074
|
+
optparse = Morpheus::Cli::OptionParser.new do|opts|
|
1075
|
+
opts.banner = subcommand_usage("[router] [name]")
|
1076
|
+
opts.on('-n', '--name VALUE', String, "Name for this firewall rule") do |val|
|
1077
|
+
params['name'] = val
|
1078
|
+
end
|
1079
|
+
opts.on('--enabled [on|off]', String, "Can be used to enable / disable the rule. Default is on") do |val|
|
1080
|
+
params['enabled'] = val.to_s == 'on' || val.to_s == 'true' || val.to_s == '1' || val.to_s == ''
|
1081
|
+
end
|
1082
|
+
opts.on( '-g', '--group GROUP', "Firewall rule group name or ID (not applicable to all firewall types)" ) do |val|
|
1083
|
+
options[:group] = val
|
1084
|
+
end
|
1085
|
+
opts.on('--priority VALUE', Integer, "Priority for this rule (not applicable to all firewall types)") do |val|
|
1086
|
+
params['priority'] = val
|
1087
|
+
end
|
1088
|
+
build_common_options(opts, options, [:options, :payload, :json, :dry_run, :remote])
|
1089
|
+
opts.footer = "Create a network router firewall rule."
|
1090
|
+
end
|
1091
|
+
optparse.parse!(args)
|
1092
|
+
connect(options)
|
1093
|
+
if args.count < 1 || args.count > 2
|
1094
|
+
print_error Morpheus::Terminal.angry_prompt
|
1095
|
+
puts_error "wrong number of arguments, expected 1-2 and got (#{args.count}) #{args.inspect}\n#{optparse}"
|
1096
|
+
return 1
|
1097
|
+
end
|
1098
|
+
if args.count > 1
|
1099
|
+
params['name'] = args[1]
|
1100
|
+
end
|
1101
|
+
begin
|
1102
|
+
router = find_router(args[0])
|
1103
|
+
|
1104
|
+
if router.nil?
|
1105
|
+
return 1
|
1106
|
+
end
|
1107
|
+
|
1108
|
+
if !router['type']['hasFirewall']
|
1109
|
+
print_red_alert "Firewall not supported for #{router['type']['name']}"
|
1110
|
+
return 1
|
1111
|
+
end
|
1112
|
+
|
1113
|
+
if options[:payload]
|
1114
|
+
payload = options[:payload]
|
1115
|
+
else
|
1116
|
+
params['name'] ||= Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'name', 'type' => 'text', 'fieldLabel' => 'Rule Name', 'required' => true}], options[:options], @api_client, params)['name']
|
1117
|
+
|
1118
|
+
if router['type']['hasFirewallGroups']
|
1119
|
+
if !router['firewall']['ruleGroups'].count
|
1120
|
+
print_red_alert "No firewall rule group found for #{router['type']['name']}"
|
1121
|
+
return 1
|
1122
|
+
end
|
1123
|
+
|
1124
|
+
if options[:group]
|
1125
|
+
group = router['firewall']['ruleGroups'].find {|it| it['name'] == options[:group] || it['id'] == options[:group].to_i}
|
1126
|
+
if !group
|
1127
|
+
print_red_alert "Firewall rule group #{options[:group]} not found for #{router['type']['name']}"
|
1128
|
+
return 1
|
1129
|
+
end
|
1130
|
+
group_id = group['id']
|
1131
|
+
else
|
1132
|
+
group_id = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'group', 'type' => 'select', 'fieldLabel' => 'Rule Group', 'required' => true, 'selectOptions' => router['firewall']['ruleGroups'].collect {|it| {'name' => it['name'], 'value' => it['id']}}}])['group']
|
1133
|
+
end
|
1134
|
+
|
1135
|
+
params['config'] = {} if params['config'].nil?
|
1136
|
+
params['config']['parentId'] = "group-#{group_id}"
|
1137
|
+
end
|
1138
|
+
|
1139
|
+
params['enabled'] ||= Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'enabled', 'fieldLabel' => 'Enabled', 'type' => 'checkbox', 'description' => 'Enable Rule.', 'defaultValue' => true, 'required' => false}], options, @api_client, {})['enabled'] == 'on'
|
1140
|
+
|
1141
|
+
if router['type']['code'].start_with?('nsx-t')
|
1142
|
+
params['priority'] ||= Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'priority', 'type' => 'number', 'fieldLabel' => 'Priority', 'required' => false}], options[:options], @api_client, params)['priority']
|
1143
|
+
end
|
1144
|
+
|
1145
|
+
option_types = router['type']['ruleOptionTypes'].reject {|it| ['name'].include?(it['fieldName'])}.sort {|it| it['displayOrder']}
|
1146
|
+
|
1147
|
+
# prompt options
|
1148
|
+
api_params = {}
|
1149
|
+
api_params['networkServerId'] = router['networkServer']['id'] if router['networkServer']
|
1150
|
+
api_params['zoneId'] = router['zone']['id'] if router['networkServer'].nil?
|
1151
|
+
api_params['groupId'] = options[:group] if !options[:group].nil?
|
1152
|
+
option_result = Morpheus::Cli::OptionTypes.prompt(option_types, options[:options].deep_merge({:context_map => {'rule' => ''}}), @api_client, api_params, nil, true)
|
1153
|
+
payload = {'rule' => params.deep_merge(option_result)}
|
1154
|
+
end
|
1155
|
+
|
1156
|
+
@network_routers_interface.setopts(options)
|
1157
|
+
if options[:dry_run]
|
1158
|
+
print_dry_run @network_routers_interface.dry.create_firewall_rule(router['id'], payload)
|
1159
|
+
return
|
1160
|
+
end
|
1161
|
+
|
1162
|
+
json_response = @network_routers_interface.create_firewall_rule(router['id'], payload)
|
1163
|
+
|
1164
|
+
if options[:json]
|
1165
|
+
print JSON.pretty_generate(json_response), "\n"
|
1166
|
+
return
|
1167
|
+
end
|
1168
|
+
print_green_success "\nAdded Network Router Firewall Rule #{payload['rule']['name']}\n"
|
1169
|
+
_firewall_rule(router['id'], json_response['id'], options)
|
1170
|
+
rescue RestClient::Exception => e
|
1171
|
+
print_rest_exception(e, options)
|
1172
|
+
exit 1
|
1173
|
+
end
|
1174
|
+
end
|
1175
|
+
|
1176
|
+
def update_firewall_rule(args)
|
1177
|
+
options = {:options=>{}}
|
1178
|
+
params = {}
|
1179
|
+
optparse = Morpheus::Cli::OptionParser.new do|opts|
|
1180
|
+
opts.banner = subcommand_usage("[router] [name]")
|
1181
|
+
opts.on('-n', '--name VALUE', String, "Name for this firewall rule") do |val|
|
1182
|
+
params['name'] = val
|
1183
|
+
end
|
1184
|
+
opts.on('--enabled [on|off]', String, "Can be used to enable / disable the rule. Default is on") do |val|
|
1185
|
+
params['enabled'] = val.to_s == 'on' || val.to_s == 'true' || val.to_s == '1' || val.to_s == ''
|
1186
|
+
end
|
1187
|
+
opts.on('--priority VALUE', Integer, "Priority for this rule (not applicable to all firewall types)") do |val|
|
1188
|
+
params['priority'] = val
|
1189
|
+
end
|
1190
|
+
build_common_options(opts, options, [:options, :payload, :json, :dry_run, :remote])
|
1191
|
+
opts.footer = "Update a network router firewall rule.\n" +
|
1192
|
+
"[router] is required. This is the name or id of an existing network router.\n" +
|
1193
|
+
"[name] is required. This is the name or id of an existing network router firewall rule."
|
1194
|
+
end
|
1195
|
+
|
1196
|
+
optparse.parse!(args)
|
1197
|
+
if args.count != 2
|
1198
|
+
raise_command_error "wrong number of arguments, expected 2 and got (#{args.count}) #{args}\n#{optparse}"
|
1199
|
+
end
|
1200
|
+
connect(options)
|
1201
|
+
|
1202
|
+
begin
|
1203
|
+
router = find_router(args[0])
|
1204
|
+
|
1205
|
+
if router.nil?
|
1206
|
+
return 1
|
1207
|
+
end
|
1208
|
+
|
1209
|
+
if !router['type']['hasFirewall']
|
1210
|
+
print_red_alert "Firewall not supported for #{router['type']['name']}"
|
1211
|
+
return 1
|
1212
|
+
end
|
1213
|
+
|
1214
|
+
rule = find_firewall_rule(router, args[1])
|
1215
|
+
|
1216
|
+
if !rule
|
1217
|
+
print_red_alert "Firewall rule #{args[1]} not found for router #{router['name']}"
|
1218
|
+
exit 1
|
1219
|
+
end
|
1220
|
+
|
1221
|
+
payload = parse_payload(options) || {'rule' => params}
|
1222
|
+
payload['rule'].deep_merge!(options[:options].reject {|k,v| k.is_a?(Symbol) }) if options[:options]
|
1223
|
+
|
1224
|
+
if payload['rule'].empty?
|
1225
|
+
print_green_success "Nothing to update"
|
1226
|
+
exit 1
|
1227
|
+
end
|
1228
|
+
|
1229
|
+
@network_routers_interface.setopts(options)
|
1230
|
+
if options[:dry_run]
|
1231
|
+
print_dry_run @network_routers_interface.dry.update_firewall_rule(router['id'], rule['id'], payload)
|
1232
|
+
return
|
1233
|
+
end
|
1234
|
+
|
1235
|
+
json_response = @network_routers_interface.update_firewall_rule(router['id'], rule['id'], payload)
|
1236
|
+
|
1237
|
+
if options[:json]
|
1238
|
+
print JSON.pretty_generate(json_response), "\n"
|
1239
|
+
return
|
1240
|
+
end
|
1241
|
+
print_green_success "\nUpdated Network Router Firewall Rule #{payload['rule']['name']}\n"
|
1242
|
+
_firewall_rule(router['id'], args[1], options)
|
1243
|
+
rescue RestClient::Exception => e
|
1244
|
+
print_rest_exception(e, options)
|
1245
|
+
exit 1
|
1246
|
+
end
|
1247
|
+
end
|
1248
|
+
|
1249
|
+
def remove_firewall_rule(args)
|
1250
|
+
options = {}
|
1251
|
+
query_params = {}
|
1252
|
+
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
1253
|
+
opts.banner = subcommand_usage("[router] [rule]")
|
1254
|
+
build_common_options(opts, options, [:auto_confirm, :json, :dry_run, :quiet, :remote])
|
1255
|
+
opts.footer = "Delete a network router firewall rule.\n" +
|
1256
|
+
"[router] is required. This is the name or id of an existing network router."
|
1257
|
+
"[rule] is required. This is the name or id of an existing network router firewall rule."
|
1258
|
+
end
|
1259
|
+
optparse.parse!(args)
|
1260
|
+
if args.count != 2
|
1261
|
+
raise_command_error "wrong number of arguments, expected 2 and got (#{args.count}) #{args}\n#{optparse}"
|
1262
|
+
end
|
1263
|
+
connect(options)
|
1264
|
+
|
1265
|
+
begin
|
1266
|
+
router = find_router(args[0])
|
1267
|
+
return if !router
|
1268
|
+
|
1269
|
+
rule = find_firewall_rule(router, args[1])
|
1270
|
+
|
1271
|
+
if !rule
|
1272
|
+
print_red_alert "Firewall rule #{args[1]} not found for router #{router['name']}"
|
1273
|
+
exit 1
|
1274
|
+
end
|
1275
|
+
|
1276
|
+
unless options[:yes] || ::Morpheus::Cli::OptionTypes::confirm("Are you sure you would like to remove the firewall rule '#{rule['name']}' from router '#{router['name']}'?", options)
|
1277
|
+
return 9, "aborted command"
|
1278
|
+
end
|
1279
|
+
@network_routers_interface.setopts(options)
|
1280
|
+
if options[:dry_run]
|
1281
|
+
print_dry_run @network_routers_interface.dry.destroy_firewall_rule(router['id'], rule['id'])
|
1282
|
+
return
|
1283
|
+
end
|
1284
|
+
json_response = @network_routers_interface.destroy_firewall_rule(router['id'], rule['id'])
|
1285
|
+
if options[:json]
|
1286
|
+
print JSON.pretty_generate(json_response)
|
1287
|
+
print "\n"
|
1288
|
+
elsif !options[:quiet]
|
1289
|
+
print_green_success "\nFirewall rule #{rule['name']} for router #{router['name']} is being removed...\n"
|
1290
|
+
_firewall_rules(find_router(router['id']), options)
|
1291
|
+
end
|
1292
|
+
rescue RestClient::Exception => e
|
1293
|
+
print_rest_exception(e, options)
|
1294
|
+
exit 1
|
1295
|
+
end
|
1296
|
+
end
|
1297
|
+
|
1298
|
+
def dhcp(args)
|
1299
|
+
options = {}
|
1300
|
+
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
1301
|
+
opts.banner = subcommand_usage("[router]")
|
1302
|
+
build_common_options(opts, options, [:json, :yaml, :csv, :fields, :dry_run, :remote])
|
1303
|
+
opts.footer = "Display network router DHCP details." + "\n" +
|
1304
|
+
"[router] is required. This is the name or id of a network router."
|
1305
|
+
end
|
1306
|
+
|
1307
|
+
optparse.parse!(args)
|
1308
|
+
connect(options)
|
1309
|
+
|
1310
|
+
if args.count < 1
|
1311
|
+
puts optparse
|
1312
|
+
return 1
|
1313
|
+
end
|
1314
|
+
|
1315
|
+
begin
|
1316
|
+
@network_routers_interface.setopts(options)
|
1317
|
+
if options[:dry_run]
|
1318
|
+
if args[0].to_s =~ /\A\d{1,}\Z/
|
1319
|
+
print_dry_run @network_routers_interface.dry.get(args[0].to_i)
|
1320
|
+
else
|
1321
|
+
print_dry_run @network_routers_interface.dry.list({name:args[0]})
|
1322
|
+
end
|
1323
|
+
return
|
1324
|
+
end
|
1325
|
+
router = find_router(args[0])
|
1326
|
+
if router.nil?
|
1327
|
+
return 1
|
1328
|
+
end
|
1329
|
+
|
1330
|
+
json_response = {'networkRouter' => router}
|
1331
|
+
|
1332
|
+
if options[:json]
|
1333
|
+
puts as_json(json_response, options, "networkRouter")
|
1334
|
+
return 0
|
1335
|
+
elsif options[:yaml]
|
1336
|
+
puts as_yaml(json_response, options, "networkRouter")
|
1337
|
+
return 0
|
1338
|
+
elsif options[:csv]
|
1339
|
+
puts records_as_csv([json_response['networkRouter']], options)
|
1340
|
+
return 0
|
1341
|
+
end
|
1342
|
+
|
1343
|
+
print_h1 "Network Router DHCP Details For: #{router['name']}"
|
1344
|
+
print cyan
|
1345
|
+
|
1346
|
+
if router['type']['hasDhcp']
|
1347
|
+
print_dhcp(router, true)
|
1348
|
+
else
|
1349
|
+
print_red_alert "DHCP not supported for #{router['type']['name']}"
|
1350
|
+
end
|
1351
|
+
println reset
|
1352
|
+
rescue RestClient::Exception => e
|
1353
|
+
print_rest_exception(e, options)
|
1354
|
+
return 1
|
1355
|
+
end
|
1356
|
+
end
|
1357
|
+
|
1358
|
+
def routes(args)
|
1359
|
+
options = {}
|
1360
|
+
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
1361
|
+
opts.banner = subcommand_usage("[router]")
|
1362
|
+
build_common_options(opts, options, [:json, :yaml, :csv, :fields, :dry_run, :remote])
|
1363
|
+
opts.footer = "List network router routes." + "\n" +
|
1364
|
+
"[router] is required. This is the name or id of a network router."
|
1365
|
+
end
|
1366
|
+
|
1367
|
+
optparse.parse!(args)
|
1368
|
+
connect(options)
|
1369
|
+
|
1370
|
+
if args.count < 1
|
1371
|
+
puts optparse
|
1372
|
+
return 1
|
1373
|
+
end
|
1374
|
+
_routes(args[0], options)
|
1375
|
+
end
|
1376
|
+
|
1377
|
+
def _routes(router_id, options)
|
1378
|
+
begin
|
1379
|
+
@network_routers_interface.setopts(options)
|
1380
|
+
if options[:dry_run]
|
1381
|
+
if args[0].to_s =~ /\A\d{1,}\Z/
|
1382
|
+
print_dry_run @network_routers_interface.dry.get(router_id.to_i)
|
1383
|
+
else
|
1384
|
+
print_dry_run @network_routers_interface.dry.list({name:router_id})
|
1385
|
+
end
|
1386
|
+
return
|
1387
|
+
end
|
1388
|
+
router = find_router(router_id)
|
1389
|
+
if router.nil?
|
1390
|
+
return 1
|
1391
|
+
end
|
1392
|
+
|
1393
|
+
json_response = {'networkRoutes' => router['routes']}
|
1394
|
+
|
1395
|
+
if options[:json]
|
1396
|
+
puts as_json(json_response, options, "networkRoutes")
|
1397
|
+
return 0
|
1398
|
+
elsif options[:yaml]
|
1399
|
+
puts as_yaml(json_response, options, "networkRoutes")
|
1400
|
+
return 0
|
1401
|
+
elsif options[:csv]
|
1402
|
+
puts records_as_csv(json_response['networkRoutes'], options)
|
1403
|
+
return 0
|
1404
|
+
end
|
1405
|
+
|
1406
|
+
print_h1 "Network Router Routes For: #{router['name']}"
|
1407
|
+
print cyan
|
1408
|
+
|
1409
|
+
if router['type']['hasRouting']
|
1410
|
+
print_routes(router)
|
1411
|
+
else
|
1412
|
+
print_red_alert "Routes not supported for #{router['type']['name']}"
|
1413
|
+
end
|
1414
|
+
print reset
|
1415
|
+
rescue RestClient::Exception => e
|
1416
|
+
print_rest_exception(e, options)
|
1417
|
+
return 1
|
1418
|
+
end
|
1419
|
+
end
|
1420
|
+
|
1421
|
+
def add_route(args)
|
1422
|
+
options = {:options=>{}}
|
1423
|
+
params = {}
|
1424
|
+
optparse = Morpheus::Cli::OptionParser.new do|opts|
|
1425
|
+
opts.banner = subcommand_usage("[router] [name]")
|
1426
|
+
opts.on('-n', '--name VALUE', String, "Name for this route") do |val|
|
1427
|
+
params['name'] = val
|
1428
|
+
end
|
1429
|
+
opts.on('-D', '--description VALUE', String, "Description") do |val|
|
1430
|
+
params['description'] = val
|
1431
|
+
end
|
1432
|
+
opts.on('--enabled [on|off]', String, "Can be used to enable / disable the route. Default is on") do |val|
|
1433
|
+
options[:enabled] = val.to_s == 'on' || val.to_s == 'true' || val.to_s == '1' || val.to_s == ''
|
1434
|
+
end
|
1435
|
+
opts.on('--default [on|off]', String, "Can be used to enable / disable as default route. Default is off") do |val|
|
1436
|
+
options[:defaultRoute] = val.to_s == 'on' || val.to_s == 'true' || val.to_s == '1' || val.to_s == ''
|
1437
|
+
end
|
1438
|
+
opts.on('--source VALUE', String, "Network for this route") do |val|
|
1439
|
+
params['source'] = val
|
1440
|
+
end
|
1441
|
+
opts.on('--destination VALUE', String, "Next hop for this route") do |val|
|
1442
|
+
params['destination'] = val
|
1443
|
+
end
|
1444
|
+
opts.on('--mtu VALUE', String, "MTU for this route") do |val|
|
1445
|
+
params['networkMtu'] = val
|
1446
|
+
end
|
1447
|
+
opts.on('--priority VALUE', Integer, "Priority for this route") do |val|
|
1448
|
+
params['priority'] = val
|
540
1449
|
end
|
541
1450
|
build_common_options(opts, options, [:options, :payload, :json, :dry_run, :remote])
|
542
|
-
opts.footer = "Create a network router
|
1451
|
+
opts.footer = "Create a network router route."
|
543
1452
|
end
|
544
1453
|
optparse.parse!(args)
|
545
1454
|
connect(options)
|
@@ -558,55 +1467,61 @@ class Morpheus::Cli::NetworkRoutersCommand
|
|
558
1467
|
return 1
|
559
1468
|
end
|
560
1469
|
|
561
|
-
if !router['type']['
|
562
|
-
print_red_alert "
|
1470
|
+
if !router['type']['hasRouting']
|
1471
|
+
print_red_alert "Routes not supported for #{router['type']['name']}"
|
563
1472
|
return 1
|
564
1473
|
end
|
565
1474
|
|
566
1475
|
if options[:payload]
|
567
1476
|
payload = options[:payload]
|
1477
|
+
payload = {'networkRoute' => payload['route']} if payload['route']
|
568
1478
|
else
|
569
|
-
params['name'] ||= Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'name', 'type' => 'text', 'fieldLabel' => '
|
1479
|
+
params['name'] ||= Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'name', 'type' => 'text', 'fieldLabel' => 'Name', 'required' => true}], options[:options], @api_client, params)['name']
|
1480
|
+
params['description'] ||= Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'description', 'type' => 'text', 'fieldLabel' => 'Description', 'required' => false}], options[:options], @api_client, params)['description']
|
570
1481
|
|
571
|
-
|
1482
|
+
# prompt for enabled if not set
|
1483
|
+
params['enabled'] = options[:enabled].nil? ? Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'enabled', 'fieldLabel' => 'Enabled', 'type' => 'checkbox', 'description' => 'Enabling Route.', 'defaultValue' => true, 'required' => false}], options, @api_client, {})['enabled'] == 'on' : options[:enabled]
|
572
1484
|
|
573
|
-
#
|
574
|
-
|
575
|
-
|
576
|
-
|
577
|
-
|
578
|
-
|
1485
|
+
# default route
|
1486
|
+
params['defaultRoute'] = options[:defaultRoute].nil? ? Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'defaultRoute', 'fieldLabel' => 'Default Route', 'type' => 'checkbox', 'description' => 'Default Route.', 'defaultValue' => false, 'required' => false}], options, @api_client, {})['defaultRoute'] == 'on' : options[:defaultRoute]
|
1487
|
+
|
1488
|
+
params['source'] ||= Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'source', 'type' => 'text', 'fieldLabel' => 'Network', 'required' => true}], options[:options], @api_client, params)['source']
|
1489
|
+
params['destination'] ||= Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'destination', 'type' => 'text', 'fieldLabel' => 'Next Hop', 'required' => true}], options[:options], @api_client, params)['destination']
|
1490
|
+
params['networkMtu'] ||= Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'networkMtu', 'type' => 'text', 'fieldLabel' => 'MTU', 'required' => false}], options[:options], @api_client, params)['networkMtu']
|
1491
|
+
params['priority'] ||= Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'priority', 'type' => 'number', 'fieldLabel' => 'Priority', 'required' => false}], options[:options], @api_client, params)['priority']
|
1492
|
+
|
1493
|
+
payload = {'networkRoute' => params}
|
579
1494
|
end
|
580
1495
|
|
581
1496
|
@network_routers_interface.setopts(options)
|
582
1497
|
if options[:dry_run]
|
583
|
-
print_dry_run @network_routers_interface.dry.
|
1498
|
+
print_dry_run @network_routers_interface.dry.create_route(router['id'], payload)
|
584
1499
|
return
|
585
1500
|
end
|
586
1501
|
|
587
|
-
json_response = @network_routers_interface.
|
1502
|
+
json_response = @network_routers_interface.create_route(router['id'], payload)
|
588
1503
|
|
589
1504
|
if options[:json]
|
590
1505
|
print JSON.pretty_generate(json_response), "\n"
|
591
1506
|
return
|
592
1507
|
end
|
593
|
-
print_green_success "\nAdded Network Router
|
594
|
-
|
1508
|
+
print_green_success "\nAdded Network Router Route #{payload['networkRoute']['name']}"
|
1509
|
+
_routes(router['id'], options)
|
595
1510
|
rescue RestClient::Exception => e
|
596
1511
|
print_rest_exception(e, options)
|
597
1512
|
exit 1
|
598
1513
|
end
|
599
1514
|
end
|
600
1515
|
|
601
|
-
def
|
1516
|
+
def remove_route(args)
|
602
1517
|
options = {}
|
603
1518
|
query_params = {}
|
604
1519
|
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
605
1520
|
opts.banner = subcommand_usage("[router] [rule]")
|
606
1521
|
build_common_options(opts, options, [:auto_confirm, :json, :dry_run, :quiet, :remote])
|
607
|
-
opts.footer = "Delete a network router
|
1522
|
+
opts.footer = "Delete a network router route.\n" +
|
608
1523
|
"[router] is required. This is the name or id of an existing network router."
|
609
|
-
|
1524
|
+
"[route] is required. This is the name or id of an existing network router route."
|
610
1525
|
end
|
611
1526
|
optparse.parse!(args)
|
612
1527
|
if args.count != 2
|
@@ -618,28 +1533,28 @@ class Morpheus::Cli::NetworkRoutersCommand
|
|
618
1533
|
router = find_router(args[0])
|
619
1534
|
return if !router
|
620
1535
|
|
621
|
-
|
1536
|
+
route = router['routes'] ? router['routes'].find {|it| it['name'] == args[1] || it['id'] == args[1].to_i} : nil
|
622
1537
|
|
623
|
-
if !
|
624
|
-
print_red_alert "
|
1538
|
+
if !route
|
1539
|
+
print_red_alert "Route #{args[1]} not found for router #{router['name']}"
|
625
1540
|
exit 1
|
626
1541
|
end
|
627
1542
|
|
628
|
-
unless options[:yes] || ::Morpheus::Cli::OptionTypes::confirm("Are you sure you would like to remove the
|
1543
|
+
unless options[:yes] || ::Morpheus::Cli::OptionTypes::confirm("Are you sure you would like to remove the route '#{route['name']}' from router '#{router['name']}'?", options)
|
629
1544
|
return 9, "aborted command"
|
630
1545
|
end
|
631
1546
|
@network_routers_interface.setopts(options)
|
632
1547
|
if options[:dry_run]
|
633
|
-
print_dry_run @network_routers_interface.dry.
|
1548
|
+
print_dry_run @network_routers_interface.dry.destroy_route(router['id'], route['id'])
|
634
1549
|
return
|
635
1550
|
end
|
636
|
-
json_response = @network_routers_interface.
|
1551
|
+
json_response = @network_routers_interface.destroy_route(router['id'], route['id'])
|
637
1552
|
if options[:json]
|
638
1553
|
print JSON.pretty_generate(json_response)
|
639
1554
|
print "\n"
|
640
1555
|
elsif !options[:quiet]
|
641
|
-
print_green_success "\
|
642
|
-
|
1556
|
+
print_green_success "\nRoute #{route['name']} for router #{router['name']} is being removed..."
|
1557
|
+
_routes(router['id'], options)
|
643
1558
|
end
|
644
1559
|
rescue RestClient::Exception => e
|
645
1560
|
print_rest_exception(e, options)
|
@@ -647,13 +1562,13 @@ class Morpheus::Cli::NetworkRoutersCommand
|
|
647
1562
|
end
|
648
1563
|
end
|
649
1564
|
|
650
|
-
def
|
1565
|
+
def nats(args)
|
651
1566
|
options = {}
|
652
1567
|
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
653
1568
|
opts.banner = subcommand_usage("[router]")
|
654
1569
|
build_common_options(opts, options, [:json, :yaml, :csv, :fields, :dry_run, :remote])
|
655
|
-
opts.footer = "
|
656
|
-
|
1570
|
+
opts.footer = "List network router NATs." + "\n" +
|
1571
|
+
"[router] is required. This is the name or id of a network router."
|
657
1572
|
end
|
658
1573
|
|
659
1574
|
optparse.parse!(args)
|
@@ -663,144 +1578,141 @@ class Morpheus::Cli::NetworkRoutersCommand
|
|
663
1578
|
puts optparse
|
664
1579
|
return 1
|
665
1580
|
end
|
1581
|
+
_nats(args[0], options)
|
1582
|
+
end
|
666
1583
|
|
1584
|
+
def _nats(router_id, options)
|
667
1585
|
begin
|
668
1586
|
@network_routers_interface.setopts(options)
|
669
1587
|
if options[:dry_run]
|
670
1588
|
if args[0].to_s =~ /\A\d{1,}\Z/
|
671
|
-
print_dry_run @network_routers_interface.dry.get(
|
1589
|
+
print_dry_run @network_routers_interface.dry.get(router_id.to_i)
|
672
1590
|
else
|
673
|
-
print_dry_run @network_routers_interface.dry.list({name:
|
1591
|
+
print_dry_run @network_routers_interface.dry.list({name:router_id})
|
674
1592
|
end
|
675
1593
|
return
|
676
1594
|
end
|
677
|
-
router = find_router(
|
1595
|
+
router = find_router(router_id)
|
678
1596
|
if router.nil?
|
679
1597
|
return 1
|
680
1598
|
end
|
681
1599
|
|
682
|
-
json_response = {'
|
1600
|
+
json_response = {'networkRouterNATs' => router['nats']}
|
683
1601
|
|
684
1602
|
if options[:json]
|
685
|
-
puts as_json(json_response, options, "
|
1603
|
+
puts as_json(json_response, options, "networkRouterNATs")
|
686
1604
|
return 0
|
687
1605
|
elsif options[:yaml]
|
688
|
-
puts as_yaml(json_response, options, "
|
1606
|
+
puts as_yaml(json_response, options, "networkRouterNATs")
|
689
1607
|
return 0
|
690
1608
|
elsif options[:csv]
|
691
|
-
puts records_as_csv(
|
1609
|
+
puts records_as_csv(json_response['networkRouterNATs'], options)
|
692
1610
|
return 0
|
693
1611
|
end
|
694
1612
|
|
695
|
-
print_h1 "Network Router
|
1613
|
+
print_h1 "Network Router NATs For: #{router['name']}"
|
696
1614
|
print cyan
|
697
1615
|
|
698
|
-
if router['type']['
|
699
|
-
|
1616
|
+
if router['type']['hasNat']
|
1617
|
+
print_nats(router)
|
700
1618
|
else
|
701
|
-
print_red_alert "
|
1619
|
+
print_red_alert "NATs not supported for #{router['type']['name']}"
|
702
1620
|
end
|
703
|
-
|
1621
|
+
print reset
|
704
1622
|
rescue RestClient::Exception => e
|
705
1623
|
print_rest_exception(e, options)
|
706
1624
|
return 1
|
707
1625
|
end
|
708
1626
|
end
|
709
1627
|
|
710
|
-
def
|
1628
|
+
def nat(args)
|
711
1629
|
options = {}
|
712
1630
|
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
713
|
-
opts.banner = subcommand_usage("[router]")
|
1631
|
+
opts.banner = subcommand_usage("[router] [rule]")
|
714
1632
|
build_common_options(opts, options, [:json, :yaml, :csv, :fields, :dry_run, :remote])
|
715
|
-
opts.footer = "
|
716
|
-
|
1633
|
+
opts.footer = "Display network router firewall rule details." + "\n" +
|
1634
|
+
"[router] is required. This is the name or id of a network router.\n" +
|
1635
|
+
"[rule] is required. This is the name or id of a firewall rule.\n"
|
717
1636
|
end
|
718
1637
|
|
719
1638
|
optparse.parse!(args)
|
720
1639
|
connect(options)
|
721
1640
|
|
722
|
-
if args.count <
|
1641
|
+
if args.count < 2
|
723
1642
|
puts optparse
|
724
1643
|
return 1
|
725
1644
|
end
|
726
|
-
_routes(args[0], options)
|
727
|
-
end
|
728
1645
|
|
729
|
-
def _routes(router_id, options)
|
730
1646
|
begin
|
731
1647
|
@network_routers_interface.setopts(options)
|
732
1648
|
if options[:dry_run]
|
733
1649
|
if args[0].to_s =~ /\A\d{1,}\Z/
|
734
|
-
print_dry_run @network_routers_interface.dry.get(
|
1650
|
+
print_dry_run @network_routers_interface.dry.get(args[0].to_i)
|
735
1651
|
else
|
736
|
-
print_dry_run @network_routers_interface.dry.list({name:
|
1652
|
+
print_dry_run @network_routers_interface.dry.list({name:args[0]})
|
737
1653
|
end
|
738
1654
|
return
|
739
1655
|
end
|
740
|
-
router = find_router(
|
1656
|
+
router = find_router(args[0])
|
741
1657
|
if router.nil?
|
742
1658
|
return 1
|
743
1659
|
end
|
744
1660
|
|
745
|
-
|
1661
|
+
if router['type']['hasNat']
|
1662
|
+
nat = (router['nats'] || []).find {|it| it['id'] == args[1].to_i || it['name'] == args[1]}
|
746
1663
|
|
747
|
-
|
748
|
-
|
749
|
-
return 0
|
750
|
-
elsif options[:yaml]
|
751
|
-
puts as_yaml(json_response, options, "networkRouter")
|
752
|
-
return 0
|
753
|
-
elsif options[:csv]
|
754
|
-
puts records_as_csv([json_response['networkRouter']], options)
|
755
|
-
return 0
|
756
|
-
end
|
1664
|
+
if nat
|
1665
|
+
json_response = {'networkRouterNAT' => nat}
|
757
1666
|
|
758
|
-
|
759
|
-
|
1667
|
+
if options[:json]
|
1668
|
+
puts as_json(json_response, options, "networkRouterNAT")
|
1669
|
+
return 0
|
1670
|
+
elsif options[:yaml]
|
1671
|
+
puts as_yaml(json_response, options, "networkRouterNAT")
|
1672
|
+
return 0
|
1673
|
+
elsif options[:csv]
|
1674
|
+
puts records_as_csv([json_response['networkRouterNAT']], options)
|
1675
|
+
return 0
|
1676
|
+
end
|
760
1677
|
|
761
|
-
|
762
|
-
|
1678
|
+
print_h1 "Network Router NAT Details"
|
1679
|
+
print cyan
|
1680
|
+
|
1681
|
+
description_cols = {
|
1682
|
+
"ID" => lambda {|it| it['id'] },
|
1683
|
+
"Name" => lambda {|it| it['name'] },
|
1684
|
+
"Description" => lambda {|it| it['description'] },
|
1685
|
+
"Enabled" => lambda {|it| format_boolean(it['enabled'])},
|
1686
|
+
"Source Network" => lambda {|it| it['sourceNetwork']},
|
1687
|
+
"Destination Network" => lambda {|it| it['destinationNetwork']},
|
1688
|
+
"Translated Network" => lambda {|it| it['translatedNetwork']},
|
1689
|
+
"Translated Port" => lambda {|it| it['translatedPorts']},
|
1690
|
+
"Priority" => lambda {|it| it['priority'] }
|
1691
|
+
}
|
1692
|
+
print_description_list(description_cols, nat)
|
1693
|
+
else
|
1694
|
+
print_red_alert "NAT #{args[1]} not found for router #{router['name']}"
|
1695
|
+
end
|
763
1696
|
else
|
764
|
-
print_red_alert "
|
1697
|
+
print_red_alert "NATs not supported for #{router['type']['name']}"
|
765
1698
|
end
|
766
|
-
|
1699
|
+
println reset
|
767
1700
|
rescue RestClient::Exception => e
|
768
1701
|
print_rest_exception(e, options)
|
769
1702
|
return 1
|
770
1703
|
end
|
771
1704
|
end
|
772
1705
|
|
773
|
-
def
|
1706
|
+
def add_nat(args)
|
774
1707
|
options = {:options=>{}}
|
775
1708
|
params = {}
|
776
1709
|
optparse = Morpheus::Cli::OptionParser.new do|opts|
|
777
1710
|
opts.banner = subcommand_usage("[router] [name]")
|
778
|
-
opts.on('-n', '--name VALUE', String, "Name for this
|
1711
|
+
opts.on('-n', '--name VALUE', String, "Name for this NAT") do |val|
|
779
1712
|
params['name'] = val
|
780
1713
|
end
|
781
|
-
opts.on('-D', '--description VALUE', String, "Description") do |val|
|
782
|
-
params['description'] = val
|
783
|
-
end
|
784
|
-
opts.on('--enabled [on|off]', String, "Can be used to enable / disable the route. Default is on") do |val|
|
785
|
-
options[:enabled] = val.to_s == 'on' || val.to_s == 'true' || val.to_s == '1' || val.to_s == ''
|
786
|
-
end
|
787
|
-
opts.on('--default [on|off]', String, "Can be used to enable / disable as default route. Default is off") do |val|
|
788
|
-
options[:defaultRoute] = val.to_s == 'on' || val.to_s == 'true' || val.to_s == '1' || val.to_s == ''
|
789
|
-
end
|
790
|
-
opts.on('--source VALUE', String, "Network for this route") do |val|
|
791
|
-
params['source'] = val
|
792
|
-
end
|
793
|
-
opts.on('--destination VALUE', String, "Next hop for this route") do |val|
|
794
|
-
params['destination'] = val
|
795
|
-
end
|
796
|
-
opts.on('--mtu VALUE', String, "MTU for this route") do |val|
|
797
|
-
params['networkMtu'] = val
|
798
|
-
end
|
799
|
-
opts.on('--priority VALUE', Integer, "Priority for this route") do |val|
|
800
|
-
params['priority'] = val
|
801
|
-
end
|
802
1714
|
build_common_options(opts, options, [:options, :payload, :json, :dry_run, :remote])
|
803
|
-
opts.footer = "Create a network router
|
1715
|
+
opts.footer = "Create a network router NAT."
|
804
1716
|
end
|
805
1717
|
optparse.parse!(args)
|
806
1718
|
connect(options)
|
@@ -819,8 +1731,8 @@ class Morpheus::Cli::NetworkRoutersCommand
|
|
819
1731
|
return 1
|
820
1732
|
end
|
821
1733
|
|
822
|
-
if !router['type']['
|
823
|
-
print_red_alert "
|
1734
|
+
if !router['type']['hasNat']
|
1735
|
+
print_red_alert "NATs not supported for #{router['type']['name']}"
|
824
1736
|
return 1
|
825
1737
|
end
|
826
1738
|
|
@@ -828,51 +1740,108 @@ class Morpheus::Cli::NetworkRoutersCommand
|
|
828
1740
|
payload = options[:payload]
|
829
1741
|
else
|
830
1742
|
params['name'] ||= Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'name', 'type' => 'text', 'fieldLabel' => 'Name', 'required' => true}], options[:options], @api_client, params)['name']
|
831
|
-
params['description'] ||= Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'description', 'type' => 'text', 'fieldLabel' => 'Description', 'required' => false}], options[:options], @api_client, params)['description']
|
832
1743
|
|
833
|
-
|
834
|
-
params['enabled'] = options[:enabled].nil? ? Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'enabled', 'fieldLabel' => 'Enabled', 'type' => 'checkbox', 'description' => 'Enabling Route.', 'defaultValue' => true, 'required' => false}], options, @api_client, {})['enabled'] == 'on' : options[:enabled]
|
1744
|
+
option_types = router['type']['natOptionTypes'].reject {|it| ['name'].include?(it['fieldName'])}.sort {|it| it['displayOrder']}
|
835
1745
|
|
836
|
-
#
|
837
|
-
|
1746
|
+
# prompt options
|
1747
|
+
option_result = Morpheus::Cli::OptionTypes.prompt(option_types, options[:options].deep_merge({:context_map => {'nat' => ''}}), @api_client, {'networkServer' => {'id' => router['networkServer']['id']}}, nil, true)
|
1748
|
+
payload = {'networkRouterNAT' => params.deep_merge(option_result)}
|
1749
|
+
end
|
838
1750
|
|
839
|
-
|
840
|
-
|
841
|
-
|
842
|
-
|
1751
|
+
@network_routers_interface.setopts(options)
|
1752
|
+
if options[:dry_run]
|
1753
|
+
print_dry_run @network_routers_interface.dry.create_nat(router['id'], payload)
|
1754
|
+
return
|
1755
|
+
end
|
1756
|
+
|
1757
|
+
json_response = @network_routers_interface.create_nat(router['id'], payload)
|
1758
|
+
|
1759
|
+
if options[:json]
|
1760
|
+
print JSON.pretty_generate(json_response), "\n"
|
1761
|
+
return
|
1762
|
+
end
|
1763
|
+
print_green_success "\nAdded Network Router NAT #{payload['networkRouterNAT']['name']}\n"
|
1764
|
+
_nats(router['id'], options)
|
1765
|
+
rescue RestClient::Exception => e
|
1766
|
+
print_rest_exception(e, options)
|
1767
|
+
exit 1
|
1768
|
+
end
|
1769
|
+
end
|
1770
|
+
|
1771
|
+
def update_nat(args)
|
1772
|
+
options = {:options=>{}}
|
1773
|
+
params = {}
|
1774
|
+
optparse = Morpheus::Cli::OptionParser.new do|opts|
|
1775
|
+
opts.banner = subcommand_usage("[router] [NAT]")
|
1776
|
+
opts.on('-n', '--name VALUE', String, "Name for this NAT") do |val|
|
1777
|
+
params['name'] = val
|
1778
|
+
end
|
1779
|
+
build_common_options(opts, options, [:options, :payload, :json, :dry_run, :remote])
|
1780
|
+
opts.footer = "Update a network router NAT.\n" +
|
1781
|
+
"[router] is required. This is the name or id of an existing network router.\n" +
|
1782
|
+
"[NAT] is required. This is the name or id of an existing network router NAT."
|
1783
|
+
end
|
1784
|
+
optparse.parse!(args)
|
1785
|
+
if args.count != 2
|
1786
|
+
raise_command_error "wrong number of arguments, expected 2 and got (#{args.count}) #{args}\n#{optparse}"
|
1787
|
+
end
|
1788
|
+
connect(options)
|
1789
|
+
begin
|
1790
|
+
router = find_router(args[0])
|
1791
|
+
|
1792
|
+
if router.nil?
|
1793
|
+
return 1
|
1794
|
+
end
|
1795
|
+
|
1796
|
+
if !router['type']['hasNat']
|
1797
|
+
print_red_alert "NATs not supported for #{router['type']['name']}"
|
1798
|
+
return 1
|
1799
|
+
end
|
1800
|
+
|
1801
|
+
nat = router['firewall'] && router['nats'] ? router['nats'].find {|it| it['name'] == args[1] || it['id'] == args[1].to_i} : nil
|
1802
|
+
|
1803
|
+
if !nat
|
1804
|
+
print_red_alert "NAT #{args[1]} not found for router #{router['name']}"
|
1805
|
+
exit 1
|
1806
|
+
end
|
1807
|
+
|
1808
|
+
payload = parse_payload(options) || {'networkRouterNAT' => params}
|
1809
|
+
payload['networkRouterNAT'].deep_merge!(options[:options].reject {|k,v| k.is_a?(Symbol) }) if options[:options] && !payload['networkRouterNAT'].nil?
|
843
1810
|
|
844
|
-
|
1811
|
+
if payload['networkRouterNAT'].empty?
|
1812
|
+
print_green_success "Nothing to update"
|
1813
|
+
exit 1
|
845
1814
|
end
|
846
1815
|
|
847
1816
|
@network_routers_interface.setopts(options)
|
848
1817
|
if options[:dry_run]
|
849
|
-
print_dry_run @network_routers_interface.dry.
|
1818
|
+
print_dry_run @network_routers_interface.dry.update_nat(router['id'], nat['id'], payload)
|
850
1819
|
return
|
851
1820
|
end
|
852
1821
|
|
853
|
-
json_response = @network_routers_interface.
|
1822
|
+
json_response = @network_routers_interface.update_nat(router['id'], nat['id'], payload)
|
854
1823
|
|
855
1824
|
if options[:json]
|
856
1825
|
print JSON.pretty_generate(json_response), "\n"
|
857
1826
|
return
|
858
1827
|
end
|
859
|
-
print_green_success "\
|
860
|
-
|
1828
|
+
print_green_success "\nUpdated Network Router NAT #{nat['name']}\n"
|
1829
|
+
_nats(router['id'], options)
|
861
1830
|
rescue RestClient::Exception => e
|
862
1831
|
print_rest_exception(e, options)
|
863
1832
|
exit 1
|
864
1833
|
end
|
865
1834
|
end
|
866
1835
|
|
867
|
-
def
|
1836
|
+
def remove_nat(args)
|
868
1837
|
options = {}
|
869
1838
|
query_params = {}
|
870
1839
|
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
871
|
-
opts.banner = subcommand_usage("[router] [
|
1840
|
+
opts.banner = subcommand_usage("[router] [NAT]")
|
872
1841
|
build_common_options(opts, options, [:auto_confirm, :json, :dry_run, :quiet, :remote])
|
873
|
-
opts.footer = "Delete a network router
|
874
|
-
|
875
|
-
|
1842
|
+
opts.footer = "Delete a network router NAT.\n" +
|
1843
|
+
"[router] is required. This is the name or id of an existing network router."
|
1844
|
+
"[NAT] is required. This is the name or id of an existing network router NAT."
|
876
1845
|
end
|
877
1846
|
optparse.parse!(args)
|
878
1847
|
if args.count != 2
|
@@ -884,28 +1853,33 @@ class Morpheus::Cli::NetworkRoutersCommand
|
|
884
1853
|
router = find_router(args[0])
|
885
1854
|
return if !router
|
886
1855
|
|
887
|
-
|
1856
|
+
if !router['type']['hasNat']
|
1857
|
+
print_red_alert "NATs not supported for #{router['type']['name']}"
|
1858
|
+
return 1
|
1859
|
+
end
|
888
1860
|
|
889
|
-
|
890
|
-
|
1861
|
+
nat = router['nats'] ? router['nats'].find {|it| it['name'] == args[1] || it['id'] == args[1].to_i} : nil
|
1862
|
+
|
1863
|
+
if !nat
|
1864
|
+
print_red_alert "NAT #{args[1]} not found for router #{router['name']}"
|
891
1865
|
exit 1
|
892
1866
|
end
|
893
1867
|
|
894
|
-
unless options[:yes] || ::Morpheus::Cli::OptionTypes::confirm("Are you sure you would like to remove the
|
1868
|
+
unless options[:yes] || ::Morpheus::Cli::OptionTypes::confirm("Are you sure you would like to remove the NAT '#{nat['name']}' from router '#{router['name']}'?", options)
|
895
1869
|
return 9, "aborted command"
|
896
1870
|
end
|
897
1871
|
@network_routers_interface.setopts(options)
|
898
1872
|
if options[:dry_run]
|
899
|
-
print_dry_run @network_routers_interface.dry.
|
1873
|
+
print_dry_run @network_routers_interface.dry.destroy_nat(router['id'], nat['id'])
|
900
1874
|
return
|
901
1875
|
end
|
902
|
-
json_response = @network_routers_interface.
|
1876
|
+
json_response = @network_routers_interface.destroy_nat(router['id'], nat['id'])
|
903
1877
|
if options[:json]
|
904
1878
|
print JSON.pretty_generate(json_response)
|
905
1879
|
print "\n"
|
906
1880
|
elsif !options[:quiet]
|
907
|
-
print_green_success "\
|
908
|
-
|
1881
|
+
print_green_success "\nNAT #{nat['name']} for router #{router['name']} is being removed...\n"
|
1882
|
+
_nats(router['id'], options)
|
909
1883
|
end
|
910
1884
|
rescue RestClient::Exception => e
|
911
1885
|
print_rest_exception(e, options)
|
@@ -998,7 +1972,7 @@ class Morpheus::Cli::NetworkRoutersCommand
|
|
998
1972
|
return
|
999
1973
|
end
|
1000
1974
|
|
1001
|
-
print_h1 "Network Router Type Details
|
1975
|
+
print_h1 "Network Router Type Details For: #{router_type['name']}"
|
1002
1976
|
print cyan
|
1003
1977
|
|
1004
1978
|
description_cols = {
|
@@ -1015,12 +1989,14 @@ class Morpheus::Cli::NetworkRoutersCommand
|
|
1015
1989
|
}
|
1016
1990
|
print_description_list(description_cols, router_type)
|
1017
1991
|
|
1018
|
-
|
1019
|
-
|
1020
|
-
|
1021
|
-
|
1022
|
-
{
|
1023
|
-
|
1992
|
+
{'optionTypes' => 'Router', 'ruleOptionTypes' => 'Firewall Rule', 'ruleGroupOptionTypes' => 'Firewall Rule Group', 'natOptionTypes' => 'NAT'}.each_pair do |field, title|
|
1993
|
+
if !router_type[field].nil? && router_type[field].count > 0
|
1994
|
+
println cyan
|
1995
|
+
print Morpheus::Cli::OptionTypes.display_option_types_help(
|
1996
|
+
router_type[field].reject {|it| ['enabled'].include?(it['fieldName'])},
|
1997
|
+
{:include_context => true, :context_map => {'networkRouter' => ''}, :color => cyan, :title => "Available #{title} Options"}
|
1998
|
+
)
|
1999
|
+
end
|
1024
2000
|
end
|
1025
2001
|
print reset
|
1026
2002
|
return 0
|
@@ -1092,10 +2068,10 @@ class Morpheus::Cli::NetworkRoutersCommand
|
|
1092
2068
|
|
1093
2069
|
private
|
1094
2070
|
|
1095
|
-
def print_firewall(router, details=false, rules_only=false)
|
2071
|
+
def print_firewall(router, options = {}) #details=false, rules_only=false, rule_groups_only=false)
|
1096
2072
|
if router['type']['hasFirewall']
|
1097
2073
|
if router['firewall']
|
1098
|
-
if details
|
2074
|
+
if options[:details]
|
1099
2075
|
description_cols = {
|
1100
2076
|
"Network Router" => lambda {|it| it['name'] },
|
1101
2077
|
"Enabled" => lambda {|it| format_boolean(it['firewall']['enabled'])},
|
@@ -1106,28 +2082,10 @@ class Morpheus::Cli::NetworkRoutersCommand
|
|
1106
2082
|
description_cols[k.gsub(/[A-Z]/, ' \0').downcase] = lambda {|it| it['firewall']['global'][k]}
|
1107
2083
|
end
|
1108
2084
|
|
1109
|
-
|
1110
|
-
print_description_list(description_cols, router)
|
1111
|
-
print_h2 "Firewall Rules"
|
1112
|
-
end
|
2085
|
+
print_description_list(description_cols, router)
|
1113
2086
|
|
1114
|
-
if
|
1115
|
-
|
1116
|
-
{
|
1117
|
-
id: it['id'],
|
1118
|
-
name: it['name'],
|
1119
|
-
type: it['ruleType'],
|
1120
|
-
policy: it['policy'],
|
1121
|
-
direction: it['direction'] || 'any',
|
1122
|
-
source: it['source'] || 'any',
|
1123
|
-
destination: it['destination'] || 'any',
|
1124
|
-
application: it['applications'].count > 0 ? it['applications'][0]['name'] : "#{(it['protocol'] || 'any')} #{it['portRange'] || ''}"
|
1125
|
-
}
|
1126
|
-
end
|
1127
|
-
puts as_pretty_table(rows, [:id, :name, :type, :policy, :direction, :source, :destination, :application])
|
1128
|
-
else
|
1129
|
-
println "No firewall rules"
|
1130
|
-
end
|
2087
|
+
_firewall_rule_groups(router, options) if router['type']['hasFirewallGroups']
|
2088
|
+
_firewall_rules(router, options) if router['type']['hasFirewall']
|
1131
2089
|
else
|
1132
2090
|
print "Enabled: #{format_boolean(router['firewall']['enabled'])}".center(20)
|
1133
2091
|
print "Version: #{router['firewall']['version']}".center(20)
|
@@ -1209,6 +2167,26 @@ class Morpheus::Cli::NetworkRoutersCommand
|
|
1209
2167
|
end
|
1210
2168
|
end
|
1211
2169
|
|
2170
|
+
def print_nats(router)
|
2171
|
+
if router['type']['hasNat']
|
2172
|
+
if router['nats'].count > 0
|
2173
|
+
rows = router['nats'].collect do |it|
|
2174
|
+
{
|
2175
|
+
id: it['id'],
|
2176
|
+
name: it['name'],
|
2177
|
+
description: it['description'],
|
2178
|
+
source_network: it['sourceNetwork'],
|
2179
|
+
destination_network: it['destinationNetwork'],
|
2180
|
+
translated_network: it['translatedNetwork']
|
2181
|
+
}
|
2182
|
+
end
|
2183
|
+
puts as_pretty_table(rows, [:id, :name, :description, :source_network, :destination_network, :translated_network])
|
2184
|
+
else
|
2185
|
+
println "No NATs\n"
|
2186
|
+
end
|
2187
|
+
end
|
2188
|
+
end
|
2189
|
+
|
1212
2190
|
def format_router_status(router, return_color = cyan)
|
1213
2191
|
status = router['status']
|
1214
2192
|
color = white
|
@@ -1227,7 +2205,9 @@ class Morpheus::Cli::NetworkRoutersCommand
|
|
1227
2205
|
if val.to_s =~ /\A\d{1,}\Z/
|
1228
2206
|
return find_router_by_id(val)
|
1229
2207
|
else
|
1230
|
-
|
2208
|
+
if router = find_router_by_name(val)
|
2209
|
+
return find_router_by_id(router['id'])
|
2210
|
+
end
|
1231
2211
|
end
|
1232
2212
|
end
|
1233
2213
|
|
@@ -1291,4 +2271,22 @@ class Morpheus::Cli::NetworkRoutersCommand
|
|
1291
2271
|
services = @network_services_interface.list()['networkServices']
|
1292
2272
|
(val.to_s =~ /\A\d{1,}\Z/) ? services.find {|it| it['id'].to_i == val.to_i} : services.find {|it| it['name'] == val}
|
1293
2273
|
end
|
2274
|
+
|
2275
|
+
def find_firewall_rule(router, rule_id)
|
2276
|
+
rule = nil
|
2277
|
+
if router['type']['hasFirewallGroups']
|
2278
|
+
if router['firewall'] && router['firewall']['ruleGroups']
|
2279
|
+
router['firewall']['ruleGroups'].each do |group|
|
2280
|
+
if !rule && group['rules']
|
2281
|
+
if rule = group['rules'].find { |it| it['name'] == rule_id || it['id'] == rule_id.to_i }
|
2282
|
+
rule['groupId'] = group['id']
|
2283
|
+
end
|
2284
|
+
end
|
2285
|
+
end
|
2286
|
+
end
|
2287
|
+
else
|
2288
|
+
rule = router['firewall'] && router['firewall']['rules'] ? router['firewall']['rules'].find {|it| it['name'] == args[1] || it['id'] == args[1].to_i} : nil
|
2289
|
+
end
|
2290
|
+
rule
|
2291
|
+
end
|
1294
2292
|
end
|