morpheus-cli 5.3.2 → 5.3.2.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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, :routes, :types, :type, :add, :update, :remove
15
- register_subcommands :add_firewall_rule, :remove_firewall_rule
16
- register_subcommands :add_route, :remove_route
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 routing." ) do
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[:details])
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('-D', '--description VALUE', String, "Description") do |val|
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(router_id.to_i)
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:router_id})
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(router_id)
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
- if !options[:rules_only]
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, true, options[:rules_only])
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 add_firewall_rule(args)
534
- options = {:options=>{}}
535
- params = {}
536
- optparse = Morpheus::Cli::OptionParser.new do|opts|
537
- opts.banner = subcommand_usage("[router] [name]")
538
- opts.on('-n', '--name VALUE', String, "Name for this firewall rule") do |val|
539
- params['name'] = val
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 firewall rule."
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']['hasFirewall']
562
- print_red_alert "Firewall not supported for #{router['type']['name']}"
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' => 'Rule Name', 'required' => true}], options[:options], @api_client, params)['name']
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
- option_types = router['type']['ruleOptionTypes'].reject {|it| ['name'].include?(it['fieldName'])}.sort {|it| it['displayOrder']}
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
- # prompt options
574
- api_params = {}
575
- api_params['networkServerId'] = router['networkServer']['id'] if router['networkServer']
576
- api_params['zoneId'] = router['zone']['id'] if router['networkServer'].nil?
577
- option_result = Morpheus::Cli::OptionTypes.prompt(option_types, options[:options].deep_merge({:context_map => {'rule' => ''}}), @api_client, api_params, nil, true)
578
- payload = {'rule' => params.deep_merge(option_result)}
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.create_firewall_rule(router['id'], payload)
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.create_firewall_rule(router['id'], payload)
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 Firewall Rule #{payload['rule']['name']}\n"
594
- _firewall(router['id'], options.merge({:rules_only => true}))
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 remove_firewall_rule(args)
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 firewall rule.\n" +
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
- "[rule] is required. This is the name or id of an existing network router firewall rule."
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
- rule = router['firewall'] && router['firewall']['rules'] ? router['firewall']['rules'].find {|it| it['name'] == args[1] || it['id'] == args[1].to_i} : nil
1536
+ route = router['routes'] ? router['routes'].find {|it| it['name'] == args[1] || it['id'] == args[1].to_i} : nil
622
1537
 
623
- if !rule
624
- print_red_alert "Firewall rule #{args[1]} not found for router #{router['name']}"
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 firewall rule '#{rule['name']}' from router '#{router['name']}'?", options)
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.destroy_firewall_rule(router['id'], rule['id'])
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.destroy_firewall_rule(router['id'], rule['id'])
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 "\nFirewall rule #{rule['name']} for router #{router['name']} is being removed...\n"
642
- _firewall(router['id'], options.merge({:rules_only => true}))
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 dhcp(args)
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 = "Display network router DHCP details." + "\n" +
656
- "[router] is required. This is the name or id of a network router."
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(args[0].to_i)
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:args[0]})
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(args[0])
1595
+ router = find_router(router_id)
678
1596
  if router.nil?
679
1597
  return 1
680
1598
  end
681
1599
 
682
- json_response = {'networkRouter' => router}
1600
+ json_response = {'networkRouterNATs' => router['nats']}
683
1601
 
684
1602
  if options[:json]
685
- puts as_json(json_response, options, "networkRouter")
1603
+ puts as_json(json_response, options, "networkRouterNATs")
686
1604
  return 0
687
1605
  elsif options[:yaml]
688
- puts as_yaml(json_response, options, "networkRouter")
1606
+ puts as_yaml(json_response, options, "networkRouterNATs")
689
1607
  return 0
690
1608
  elsif options[:csv]
691
- puts records_as_csv([json_response['networkRouter']], options)
1609
+ puts records_as_csv(json_response['networkRouterNATs'], options)
692
1610
  return 0
693
1611
  end
694
1612
 
695
- print_h1 "Network Router DHCP Details for: #{router['name']}"
1613
+ print_h1 "Network Router NATs For: #{router['name']}"
696
1614
  print cyan
697
1615
 
698
- if router['type']['hasDhcp']
699
- print_dhcp(router, true)
1616
+ if router['type']['hasNat']
1617
+ print_nats(router)
700
1618
  else
701
- print_red_alert "DHCP not supported for #{router['type']['name']}"
1619
+ print_red_alert "NATs not supported for #{router['type']['name']}"
702
1620
  end
703
- println reset
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 routes(args)
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 = "List network router routes." + "\n" +
716
- "[router] is required. This is the name or id of a network router."
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 < 1
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(router_id.to_i)
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:router_id})
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(router_id)
1656
+ router = find_router(args[0])
741
1657
  if router.nil?
742
1658
  return 1
743
1659
  end
744
1660
 
745
- json_response = {'networkRouter' => router}
1661
+ if router['type']['hasNat']
1662
+ nat = (router['nats'] || []).find {|it| it['id'] == args[1].to_i || it['name'] == args[1]}
746
1663
 
747
- if options[:json]
748
- puts as_json(json_response, options, "networkRouter")
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
- print_h1 "Network Router Routes for: #{router['name']}"
759
- print cyan
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
- if router['type']['hasRouting']
762
- print_routes(router)
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 "Routes not supported for #{router['type']['name']}"
1697
+ print_red_alert "NATs not supported for #{router['type']['name']}"
765
1698
  end
766
- print reset
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 add_route(args)
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 route") do |val|
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 route."
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']['hasRouting']
823
- print_red_alert "Routes not supported for #{router['type']['name']}"
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
- # prompt for enabled if not set
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
- # default route
837
- 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]
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
- params['source'] ||= Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'source', 'type' => 'text', 'fieldLabel' => 'Network', 'required' => true}], options[:options], @api_client, params)['source']
840
- params['destination'] ||= Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'destination', 'type' => 'text', 'fieldLabel' => 'Next Hop', 'required' => true}], options[:options], @api_client, params)['destination']
841
- params['networkMtu'] ||= Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'networkMtu', 'type' => 'text', 'fieldLabel' => 'MTU', 'required' => false}], options[:options], @api_client, params)['networkMtu']
842
- params['priority'] ||= Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'priority', 'type' => 'number', 'fieldLabel' => 'Priority', 'required' => false}], options[:options], @api_client, params)['priority']
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
- payload = {'route' => params}
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.create_route(router['id'], payload)
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.create_route(router['id'], payload)
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 "\nAdded Network Router Route #{payload['route']['name']}"
860
- _routes(router['id'], options)
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 remove_route(args)
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] [rule]")
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 route.\n" +
874
- "[router] is required. This is the name or id of an existing network router."
875
- "[route] is required. This is the name or id of an existing network router route."
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
- route = router['routes'] ? router['routes'].find {|it| it['name'] == args[1] || it['id'] == args[1].to_i} : nil
1856
+ if !router['type']['hasNat']
1857
+ print_red_alert "NATs not supported for #{router['type']['name']}"
1858
+ return 1
1859
+ end
888
1860
 
889
- if !route
890
- print_red_alert "Route #{args[1]} not found for router #{router['name']}"
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 route '#{route['name']}' from router '#{router['name']}'?", options)
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.destroy_route(router['id'], route['id'])
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.destroy_route(router['id'], route['id'])
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 "\nRoute #{route['name']} for router #{router['name']} is being removed..."
908
- _routes(router['id'], options)
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 for: #{router_type['name']}"
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
- if router_type['optionTypes'].count > 0
1019
- println cyan
1020
- print Morpheus::Cli::OptionTypes.display_option_types_help(
1021
- router_type['optionTypes'].reject {|it| ['enabled'].include?(it['fieldName'])},
1022
- {:include_context => true, :context_map => {'networkRouter' => ''}, :color => cyan, :title => "Available Router Options"}
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
- if !rules_only
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 (router['firewall']['rules'] || []).count > 0
1115
- rows = router['firewall']['rules'].collect do |it|
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
- return find_router_by_name(val)
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