cisco_node_utils 1.2.0 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.gitignore +2 -0
- data/.rspec +2 -0
- data/.rubocop.yml +13 -0
- data/.travis.yml +4 -1
- data/CHANGELOG.md +81 -2
- data/CONTRIBUTING.md +2 -17
- data/Gemfile +5 -0
- data/README.md +92 -47
- data/Rakefile +23 -1
- data/bin/git/hooks/hook_lib +7 -0
- data/bin/git/hooks/pre-commit/check_unstaged_changes +18 -0
- data/bin/git/hooks/pre-commit/rubocop +7 -2
- data/bin/git/hooks/pre-commit/validate-diffs +18 -4
- data/bin/git/hooks/pre-commit/validate-yaml +18 -0
- data/bin/git/update-hooks +64 -6
- data/cisco_node_utils.gemspec +9 -6
- data/docs/README-develop-best-practices.md +149 -50
- data/docs/README-develop-node-utils-APIs.md +92 -42
- data/docs/README-maintainers.md +7 -4
- data/docs/README-test-execution.md +57 -0
- data/docs/cisco_node_utils.yaml.example +30 -0
- data/docs/template-router.rb +4 -0
- data/ext/mkrf_conf.rb +63 -0
- data/lib/.rubocop.yml +2 -2
- data/lib/cisco_node_utils.rb +5 -0
- data/lib/cisco_node_utils/aaa_authentication_login.rb +5 -6
- data/lib/cisco_node_utils/aaa_authorization_service.rb +1 -1
- data/lib/cisco_node_utils/ace.rb +165 -12
- data/lib/cisco_node_utils/acl.rb +2 -1
- data/lib/cisco_node_utils/bgp.rb +184 -21
- data/lib/cisco_node_utils/bgp_af.rb +94 -249
- data/lib/cisco_node_utils/bgp_neighbor.rb +94 -14
- data/lib/cisco_node_utils/bgp_neighbor_af.rb +75 -8
- data/lib/cisco_node_utils/bridge_domain.rb +183 -0
- data/lib/cisco_node_utils/bridge_domain_vni.rb +206 -0
- data/lib/cisco_node_utils/cisco_cmn_utils.rb +85 -2
- data/lib/cisco_node_utils/client.rb +35 -0
- data/lib/cisco_node_utils/client/client.rb +234 -0
- data/lib/cisco_node_utils/client/grpc.rb +33 -0
- data/lib/cisco_node_utils/client/grpc/client.rb +311 -0
- data/lib/cisco_node_utils/client/grpc/ems.proto +148 -0
- data/lib/cisco_node_utils/client/grpc/ems.rb +111 -0
- data/lib/cisco_node_utils/client/grpc/ems_services.rb +49 -0
- data/lib/cisco_node_utils/client/nxapi.rb +31 -0
- data/lib/cisco_node_utils/client/nxapi/client.rb +305 -0
- data/lib/cisco_node_utils/client/utils.rb +164 -0
- data/lib/cisco_node_utils/cmd_ref/README_YAML.md +222 -254
- data/lib/cisco_node_utils/cmd_ref/aaa_auth_login_service.yaml +11 -8
- data/lib/cisco_node_utils/cmd_ref/aaa_authentication_login.yaml +22 -15
- data/lib/cisco_node_utils/cmd_ref/aaa_authorization_service.yaml +11 -8
- data/lib/cisco_node_utils/cmd_ref/acl.yaml +21 -16
- data/lib/cisco_node_utils/cmd_ref/bgp.yaml +239 -109
- data/lib/cisco_node_utils/cmd_ref/bgp_af.yaml +114 -55
- data/lib/cisco_node_utils/cmd_ref/bgp_neighbor.yaml +76 -52
- data/lib/cisco_node_utils/cmd_ref/bgp_neighbor_af.yaml +106 -62
- data/lib/cisco_node_utils/cmd_ref/bridge_domain.yaml +71 -0
- data/lib/cisco_node_utils/cmd_ref/bridge_domain_vni.yaml +33 -0
- data/lib/cisco_node_utils/cmd_ref/dnsclient.yaml +35 -14
- data/lib/cisco_node_utils/cmd_ref/encapsulation.yaml +25 -0
- data/lib/cisco_node_utils/cmd_ref/evpn_vni.yaml +23 -17
- data/lib/cisco_node_utils/cmd_ref/fabricpath.yaml +94 -83
- data/lib/cisco_node_utils/cmd_ref/fabricpath_topology.yaml +22 -17
- data/lib/cisco_node_utils/cmd_ref/feature.yaml +76 -26
- data/lib/cisco_node_utils/cmd_ref/images.yaml +3 -2
- data/lib/cisco_node_utils/cmd_ref/interface.yaml +381 -153
- data/lib/cisco_node_utils/cmd_ref/interface_channel_group.yaml +21 -11
- data/lib/cisco_node_utils/cmd_ref/interface_ospf.yaml +21 -21
- data/lib/cisco_node_utils/cmd_ref/interface_portchannel.yaml +30 -21
- data/lib/cisco_node_utils/cmd_ref/interface_service_vni.yaml +18 -13
- data/lib/cisco_node_utils/cmd_ref/inventory.yaml +26 -31
- data/lib/cisco_node_utils/cmd_ref/itd_device_group.yaml +83 -0
- data/lib/cisco_node_utils/cmd_ref/itd_service.yaml +119 -0
- data/lib/cisco_node_utils/cmd_ref/memory.yaml +17 -6
- data/lib/cisco_node_utils/cmd_ref/ntp_config.yaml +10 -3
- data/lib/cisco_node_utils/cmd_ref/ntp_server.yaml +17 -5
- data/lib/cisco_node_utils/cmd_ref/ospf.yaml +33 -29
- data/lib/cisco_node_utils/cmd_ref/overlay_global.yaml +12 -10
- data/lib/cisco_node_utils/cmd_ref/pim.yaml +16 -19
- data/lib/cisco_node_utils/cmd_ref/portchannel_global.yaml +40 -25
- data/lib/cisco_node_utils/cmd_ref/radius_global.yaml +17 -12
- data/lib/cisco_node_utils/cmd_ref/radius_server.yaml +71 -35
- data/lib/cisco_node_utils/cmd_ref/radius_server_group.yaml +10 -5
- data/lib/cisco_node_utils/cmd_ref/show_system.yaml +6 -2
- data/lib/cisco_node_utils/cmd_ref/show_version.yaml +47 -43
- data/lib/cisco_node_utils/cmd_ref/snmp_community.yaml +13 -11
- data/lib/cisco_node_utils/cmd_ref/snmp_group.yaml +4 -2
- data/lib/cisco_node_utils/cmd_ref/snmp_notification_receiver.yaml +23 -21
- data/lib/cisco_node_utils/cmd_ref/snmp_server.yaml +26 -22
- data/lib/cisco_node_utils/cmd_ref/snmp_user.yaml +19 -17
- data/lib/cisco_node_utils/cmd_ref/snmpnotification.yaml +18 -6
- data/lib/cisco_node_utils/cmd_ref/stp_global.yaml +234 -0
- data/lib/cisco_node_utils/cmd_ref/syslog_server.yaml +24 -9
- data/lib/cisco_node_utils/cmd_ref/syslog_settings.yaml +5 -3
- data/lib/cisco_node_utils/cmd_ref/system.yaml +4 -3
- data/lib/cisco_node_utils/cmd_ref/tacacs_server.yaml +22 -20
- data/lib/cisco_node_utils/cmd_ref/tacacs_server_group.yaml +27 -15
- data/lib/cisco_node_utils/cmd_ref/tacacs_server_host.yaml +45 -16
- data/lib/cisco_node_utils/cmd_ref/vdc.yaml +21 -11
- data/lib/cisco_node_utils/cmd_ref/virtual_service.yaml +3 -2
- data/lib/cisco_node_utils/cmd_ref/vlan.yaml +60 -32
- data/lib/cisco_node_utils/cmd_ref/vpc.yaml +118 -101
- data/lib/cisco_node_utils/cmd_ref/vrf.yaml +54 -58
- data/lib/cisco_node_utils/cmd_ref/vrf_af.yaml +118 -0
- data/lib/cisco_node_utils/cmd_ref/vtp.yaml +19 -25
- data/lib/cisco_node_utils/cmd_ref/vxlan_vtep.yaml +28 -18
- data/lib/cisco_node_utils/cmd_ref/vxlan_vtep_vni.yaml +34 -17
- data/lib/cisco_node_utils/cmd_ref/yum.yaml +6 -4
- data/lib/cisco_node_utils/command_reference.rb +261 -142
- data/lib/cisco_node_utils/constants.rb +33 -0
- data/lib/cisco_node_utils/encapsulation.rb +112 -0
- data/lib/cisco_node_utils/environment.rb +102 -0
- data/lib/cisco_node_utils/evpn_vni.rb +5 -3
- data/lib/cisco_node_utils/exceptions.rb +111 -0
- data/lib/cisco_node_utils/fabricpath_global.rb +52 -35
- data/lib/cisco_node_utils/fabricpath_topology.rb +44 -57
- data/lib/cisco_node_utils/feature.rb +165 -3
- data/lib/cisco_node_utils/interface.rb +1051 -260
- data/lib/cisco_node_utils/interface_channel_group.rb +11 -10
- data/lib/cisco_node_utils/interface_ospf.rb +1 -2
- data/lib/cisco_node_utils/interface_portchannel.rb +4 -12
- data/lib/cisco_node_utils/interface_service_vni.rb +7 -7
- data/lib/cisco_node_utils/itd_device_group.rb +248 -0
- data/lib/cisco_node_utils/itd_device_group_node.rb +144 -0
- data/lib/cisco_node_utils/itd_service.rb +523 -0
- data/lib/cisco_node_utils/logger.rb +75 -0
- data/lib/cisco_node_utils/node.rb +62 -192
- data/lib/cisco_node_utils/node_util.rb +56 -10
- data/lib/cisco_node_utils/overlay_global.rb +2 -2
- data/lib/cisco_node_utils/pim.rb +2 -13
- data/lib/cisco_node_utils/pim_group_list.rb +1 -1
- data/lib/cisco_node_utils/pim_rp_address.rb +1 -1
- data/lib/cisco_node_utils/platform.rb +52 -21
- data/lib/cisco_node_utils/portchannel_global.rb +89 -19
- data/lib/cisco_node_utils/radius_server.rb +168 -37
- data/lib/cisco_node_utils/router_ospf.rb +20 -35
- data/lib/cisco_node_utils/router_ospf_vrf.rb +4 -4
- data/lib/cisco_node_utils/snmpserver.rb +1 -6
- data/lib/cisco_node_utils/snmpuser.rb +6 -4
- data/lib/cisco_node_utils/stp_global.rb +676 -0
- data/lib/cisco_node_utils/syslog_server.rb +77 -18
- data/lib/cisco_node_utils/syslog_settings.rb +1 -1
- data/lib/cisco_node_utils/tacacs_server_group.rb +8 -4
- data/lib/cisco_node_utils/tacacs_server_host.rb +115 -25
- data/lib/cisco_node_utils/vdc.rb +12 -0
- data/lib/cisco_node_utils/version.rb +1 -1
- data/lib/cisco_node_utils/vlan.rb +147 -29
- data/lib/cisco_node_utils/vpc.rb +55 -3
- data/lib/cisco_node_utils/vrf.rb +72 -11
- data/lib/cisco_node_utils/vrf_af.rb +114 -29
- data/lib/cisco_node_utils/vtp.rb +34 -52
- data/lib/cisco_node_utils/vxlan_vtep.rb +34 -8
- data/lib/cisco_node_utils/vxlan_vtep_vni.rb +36 -4
- data/lib/minitest/environment_plugin.rb +31 -0
- data/lib/minitest/log_level_plugin.rb +41 -0
- data/spec/client_spec.rb +7 -0
- data/spec/environment_spec.rb +263 -0
- data/spec/grpc_client_spec.rb +23 -0
- data/spec/isolate/all_clients_spec.rb +9 -0
- data/spec/isolate/grpc_only_spec.rb +16 -0
- data/spec/isolate/no_clients_spec.rb +26 -0
- data/spec/isolate/nxapi_only_spec.rb +16 -0
- data/spec/nxapi_client_spec.rb +42 -0
- data/spec/schema.yaml +75 -0
- data/spec/shared_examples_for_clients.rb +14 -0
- data/spec/spec_helper.rb +91 -0
- data/spec/whitespace_spec.rb +10 -0
- data/spec/yaml_spec.rb +42 -0
- data/tests/.rubocop.yml +2 -2
- data/tests/CSCuxdublin-1.0.0-7.0.3.I3.1.lib32_n9000.rpm +0 -0
- data/tests/basetest.rb +96 -36
- data/tests/ciscotest.rb +220 -12
- data/tests/cmd_config.yaml +71 -49
- data/tests/cmd_config_invalid.yaml +1 -1
- data/tests/test_aaa_authentication_login.rb +1 -0
- data/tests/test_aaa_authentication_login_service.rb +9 -0
- data/tests/test_aaa_authorization_service.rb +173 -367
- data/tests/test_ace.rb +171 -100
- data/tests/test_acl.rb +10 -1
- data/tests/test_bgp_af.rb +395 -728
- data/tests/test_bgp_neighbor.rb +274 -115
- data/tests/test_bgp_neighbor_af.rb +178 -77
- data/tests/test_bridge_domain.rb +191 -0
- data/tests/test_bridge_domain_vni.rb +116 -0
- data/tests/test_client_utils.rb +111 -0
- data/tests/test_command_config.rb +9 -5
- data/tests/test_command_reference.rb +380 -102
- data/tests/test_dns_domain.rb +13 -3
- data/tests/test_domain_name.rb +13 -3
- data/tests/test_encapsulation.rb +77 -0
- data/tests/test_evpn_vni.rb +25 -7
- data/tests/test_fabricpath_global.rb +167 -163
- data/tests/test_fabricpath_topology.rb +12 -33
- data/tests/test_feature.rb +215 -0
- data/tests/test_grpc.rb +166 -0
- data/tests/test_interface.rb +585 -344
- data/tests/test_interface_bdi.rb +80 -0
- data/tests/test_interface_channel_group.rb +6 -3
- data/tests/test_interface_ospf.rb +26 -24
- data/tests/test_interface_portchannel.rb +1 -0
- data/tests/test_interface_private_vlan.rb +724 -0
- data/tests/test_interface_service_vni.rb +37 -66
- data/tests/test_interface_svi.rb +98 -101
- data/tests/test_interface_switchport.rb +419 -549
- data/tests/test_itd_device_group.rb +145 -0
- data/tests/test_itd_device_group_node.rb +199 -0
- data/tests/test_itd_service.rb +298 -0
- data/tests/test_logger.rb +43 -0
- data/tests/test_name_server.rb +11 -2
- data/tests/test_node.rb +16 -75
- data/tests/test_node_ext.rb +174 -163
- data/tests/test_node_util.rb +119 -0
- data/tests/test_ntp_config.rb +5 -1
- data/tests/test_ntp_server.rb +2 -2
- data/tests/test_nxapi.rb +221 -0
- data/tests/test_overlay_global.rb +47 -38
- data/tests/test_pim.rb +2 -0
- data/tests/test_pim_group_list.rb +2 -0
- data/tests/test_pim_rp_address.rb +2 -0
- data/tests/test_platform.rb +86 -39
- data/tests/test_portchannel_global.rb +211 -135
- data/tests/test_radius_global.rb +13 -5
- data/tests/test_radius_server.rb +256 -104
- data/tests/test_radius_server_group.rb +2 -0
- data/tests/test_router_bgp.rb +781 -485
- data/tests/test_router_ospf.rb +26 -103
- data/tests/test_router_ospf_vrf.rb +52 -57
- data/tests/test_snmp_notification_receiver.rb +2 -0
- data/tests/test_snmpcommunity.rb +2 -0
- data/tests/test_snmpgroup.rb +2 -0
- data/tests/test_snmpnotification.rb +40 -21
- data/tests/test_snmpserver.rb +2 -0
- data/tests/test_snmpuser.rb +2 -0
- data/tests/test_stp_global.rb +563 -0
- data/tests/test_syslog_server.rb +32 -8
- data/tests/test_syslog_settings.rb +22 -9
- data/tests/test_tacacs_server.rb +32 -27
- data/tests/test_tacacs_server_group.rb +100 -45
- data/tests/test_tacacs_server_host.rb +135 -43
- data/tests/test_vdc.rb +2 -16
- data/tests/test_vlan.rb +106 -54
- data/tests/test_vlan_mt_full.rb +11 -21
- data/tests/test_vlan_private.rb +669 -0
- data/tests/test_vpc.rb +312 -159
- data/tests/test_vrf.rb +122 -113
- data/tests/test_vrf_af.rb +238 -0
- data/tests/test_vtp.rb +58 -102
- data/tests/test_vxlan_vtep.rb +38 -17
- data/tests/test_vxlan_vtep_vni.rb +61 -9
- data/tests/test_yum.rb +49 -25
- metadata +122 -36
- data/lib/cisco_node_utils/cmd_ref/fex.yaml +0 -9
- data/lib/cisco_node_utils/cmd_ref/vni.yaml +0 -76
- data/lib/cisco_node_utils/vni.rb +0 -227
- data/tests/test_vni.rb +0 -106
data/tests/test_ace.rb
CHANGED
|
@@ -18,143 +18,214 @@ require_relative '../lib/cisco_node_utils/ace'
|
|
|
18
18
|
|
|
19
19
|
# TestAce - Minitest for Ace node utility class
|
|
20
20
|
class TestAce < CiscoTestCase
|
|
21
|
+
@skip_unless_supported = 'acl'
|
|
22
|
+
@@pre_clean_needed = true # rubocop:disable Style/ClassVars
|
|
23
|
+
|
|
21
24
|
def setup
|
|
22
|
-
# setup runs at the beginning of each test
|
|
23
25
|
super
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
@seqno = 10
|
|
27
|
-
no_access_list_foo
|
|
26
|
+
remove_all_acls if @@pre_clean_needed
|
|
27
|
+
@@pre_clean_needed = false # rubocop:disable Style/ClassVars
|
|
28
28
|
end
|
|
29
29
|
|
|
30
30
|
def teardown
|
|
31
|
-
# teardown runs at the end of each test
|
|
32
|
-
no_access_list_foo
|
|
33
31
|
super
|
|
32
|
+
remove_all_acls
|
|
34
33
|
end
|
|
35
34
|
|
|
36
|
-
def
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
acl_name = afi[/ipv6/] ? @acl_name_v6 : @acl_name_v4
|
|
40
|
-
config('no ' + Acl.afi_cli(afi) + ' access-list ' + acl_name)
|
|
35
|
+
def remove_all_acls
|
|
36
|
+
Acl.acls.each do |_afis, acls|
|
|
37
|
+
acls.values.each(&:destroy)
|
|
41
38
|
end
|
|
42
39
|
end
|
|
43
40
|
|
|
44
|
-
#
|
|
45
|
-
|
|
46
|
-
|
|
41
|
+
# Helper to create an ACE and return the obj. The test_hash contains
|
|
42
|
+
# only the minimum properties which can be added to or overwritten as
|
|
43
|
+
# required for each test.
|
|
44
|
+
def ace_helper(afi, props=nil)
|
|
45
|
+
test_hash = {
|
|
47
46
|
action: 'permit',
|
|
48
47
|
proto: 'tcp',
|
|
49
|
-
src_addr: '
|
|
50
|
-
|
|
51
|
-
dst_addr: '1.2.3.4/32',
|
|
52
|
-
dst_port: 'neq 20',
|
|
48
|
+
src_addr: 'any',
|
|
49
|
+
dst_addr: 'any',
|
|
53
50
|
}
|
|
51
|
+
test_hash.merge!(props) unless props.nil?
|
|
54
52
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
53
|
+
a = Ace.new(afi, afi, 10)
|
|
54
|
+
begin
|
|
55
|
+
a.ace_set(test_hash)
|
|
56
|
+
a
|
|
57
|
+
end
|
|
58
|
+
rescue CliError => e
|
|
59
|
+
skip('This property is not supported on this platform') if
|
|
60
|
+
e.message[/(Invalid parameter detected|Invalid command)/]
|
|
61
|
+
flunk(e.message)
|
|
62
|
+
end
|
|
63
63
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
64
|
+
# TESTS
|
|
65
|
+
def test_remark
|
|
66
|
+
%w(ipv4 ipv6).each do |afi|
|
|
67
|
+
a = ace_helper(afi, remark: afi)
|
|
68
|
+
assert_equal(afi, a.remark)
|
|
69
|
+
end
|
|
70
|
+
end
|
|
67
71
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
72
|
+
def test_action
|
|
73
|
+
%w(ipv4 ipv6).each do |afi|
|
|
74
|
+
%w(permit deny).each do |val|
|
|
75
|
+
a = ace_helper(afi, action: val)
|
|
76
|
+
assert_equal(val, a.action)
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
end
|
|
76
80
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
proto
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
81
|
+
def test_proto
|
|
82
|
+
%w(ipv4 ipv6).each do |afi|
|
|
83
|
+
# Sampling of proto's
|
|
84
|
+
%w(ip tcp udp).each do |val|
|
|
85
|
+
val = 'ipv6' if val[/ip/] && afi[/ipv6/]
|
|
86
|
+
a = ace_helper(afi, proto: val)
|
|
87
|
+
assert_equal(val, a.proto)
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
end
|
|
85
91
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
92
|
+
def test_addrs
|
|
93
|
+
val = '10.1.1.1/32'
|
|
94
|
+
a = ace_helper('ipv4', src_addr: val, dst_addr: val)
|
|
95
|
+
assert_equal(val, a.src_addr)
|
|
96
|
+
assert_equal(val, a.dst_addr)
|
|
97
|
+
|
|
98
|
+
val = '10.1.1.1 0.0.0.0'
|
|
99
|
+
exp = '10.1.1.1/32'
|
|
100
|
+
# This syntax will transform to 10.1.1.1/32
|
|
101
|
+
a = ace_helper('ipv4', src_addr: val, dst_addr: val)
|
|
102
|
+
assert_equal(exp, a.src_addr)
|
|
103
|
+
assert_equal(exp, a.dst_addr)
|
|
104
|
+
|
|
105
|
+
val = '10.1.1.1 2.3.4.5'
|
|
106
|
+
a = ace_helper('ipv4', src_addr: val, dst_addr: val)
|
|
107
|
+
assert_equal(val, a.src_addr)
|
|
108
|
+
assert_equal(val, a.dst_addr)
|
|
109
|
+
|
|
110
|
+
val = '10:1:1::1/128'
|
|
111
|
+
a = ace_helper('ipv6', src_addr: val, dst_addr: val)
|
|
112
|
+
assert_equal(val, a.src_addr)
|
|
113
|
+
assert_equal(val, a.dst_addr)
|
|
89
114
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
115
|
+
%w(ipv4 ipv6).each do |afi|
|
|
116
|
+
val = "addrgroup my_addrgroup_#{afi}"
|
|
117
|
+
a = ace_helper(afi, src_addr: val, dst_addr: val)
|
|
118
|
+
assert_equal(val, a.src_addr)
|
|
119
|
+
assert_equal(val, a.dst_addr)
|
|
120
|
+
end
|
|
121
|
+
end
|
|
94
122
|
|
|
123
|
+
def test_ports
|
|
95
124
|
%w(ipv4 ipv6).each do |afi|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
125
|
+
['eq 2', 'neq 2', 'gt 2', 'lt 2',
|
|
126
|
+
'portgroup my_pg'].each do |val|
|
|
127
|
+
a = ace_helper(afi, src_port: val, dst_port: val)
|
|
128
|
+
assert_equal(val, a.src_port)
|
|
129
|
+
assert_equal(val, a.dst_port)
|
|
99
130
|
end
|
|
100
131
|
end
|
|
101
132
|
end
|
|
102
133
|
|
|
103
|
-
def
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
134
|
+
def test_dscp
|
|
135
|
+
%w(ipv4 ipv6).each do |afi|
|
|
136
|
+
%w(5 60 af11 af12 af13 af21 af22 af23 af31 af32 af33 af41 af42 af43
|
|
137
|
+
cs1 cs2 cs3 cs4 cs5 cs6 cs7 default ef).each do |val|
|
|
138
|
+
a = ace_helper(afi, dscp: val)
|
|
139
|
+
assert_equal(val, a.dscp)
|
|
140
|
+
end
|
|
141
|
+
end
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
def test_tcp_flags
|
|
145
|
+
%w(ipv4 ipv6).each do |afi|
|
|
146
|
+
%w(ack fin urg syn psh rst) + [
|
|
147
|
+
'ack fin', 'ack psh rst'].each do |val|
|
|
148
|
+
a = ace_helper(afi, tcp_flags: val)
|
|
149
|
+
assert_equal(val, a.tcp_flags)
|
|
150
|
+
end
|
|
151
|
+
end
|
|
152
|
+
end
|
|
107
153
|
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
154
|
+
def test_established
|
|
155
|
+
%w(ipv4 ipv6).each do |afi|
|
|
156
|
+
refute(ace_helper(afi).established)
|
|
157
|
+
a = ace_helper(afi, established: true)
|
|
158
|
+
assert(a.established)
|
|
159
|
+
a = ace_helper(afi, established: false)
|
|
160
|
+
refute(a.established)
|
|
161
|
+
end
|
|
162
|
+
end
|
|
111
163
|
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
found = true
|
|
164
|
+
def test_http_method
|
|
165
|
+
afi = 'ipv4'
|
|
166
|
+
%w(connect delete get head post put trace).each do |val|
|
|
167
|
+
a = ace_helper(afi, http_method: val)
|
|
168
|
+
assert_equal(val, a.http_method)
|
|
118
169
|
end
|
|
170
|
+
end
|
|
119
171
|
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
172
|
+
def test_log
|
|
173
|
+
%w(ipv4 ipv6).each do |afi|
|
|
174
|
+
refute(ace_helper(afi).log)
|
|
175
|
+
a = ace_helper(afi, log: true)
|
|
176
|
+
assert(a.log)
|
|
177
|
+
a = ace_helper(afi, log: false)
|
|
178
|
+
refute(a.log)
|
|
179
|
+
end
|
|
180
|
+
end
|
|
124
181
|
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
182
|
+
def test_precedence
|
|
183
|
+
afi = 'ipv4'
|
|
184
|
+
%w(critical flash flash-override immediate internet network
|
|
185
|
+
priority routine).each do |val|
|
|
186
|
+
a = ace_helper(afi, precedence: val)
|
|
187
|
+
assert_equal(val, a.precedence)
|
|
129
188
|
end
|
|
130
|
-
assert_show_match(pattern: /\s+#{@seqno} #{action}$/,
|
|
131
|
-
msg: "failed to create ace seqno #{@seqno}")
|
|
132
|
-
ace.destroy
|
|
133
|
-
refute_show_match(pattern: /\s+#{@seqno} #{entry[:action]} .*$/,
|
|
134
|
-
msg: "failed to remove ace seqno #{@seqno}")
|
|
135
189
|
end
|
|
136
190
|
|
|
137
|
-
def
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
191
|
+
def test_redirect
|
|
192
|
+
afi = 'ipv4'
|
|
193
|
+
val = 'port-channel1,port-channel2'
|
|
194
|
+
a = ace_helper(afi, redirect: val)
|
|
195
|
+
assert_equal(val, a.redirect)
|
|
196
|
+
end
|
|
143
197
|
|
|
144
|
-
|
|
145
|
-
|
|
198
|
+
def test_tcp_option_length
|
|
199
|
+
afi = 'ipv4'
|
|
200
|
+
%w(0 16 28).each do |val|
|
|
201
|
+
a = ace_helper(afi, tcp_option_length: val)
|
|
202
|
+
assert_equal(val, a.tcp_option_length)
|
|
203
|
+
end
|
|
204
|
+
end
|
|
146
205
|
|
|
147
|
-
|
|
148
|
-
|
|
206
|
+
def test_time_range
|
|
207
|
+
val = 'my_range'
|
|
208
|
+
%w(ipv4 ipv6).each do |afi|
|
|
209
|
+
a = ace_helper(afi, time_range: val)
|
|
210
|
+
assert_equal(val, a.time_range)
|
|
211
|
+
end
|
|
212
|
+
end
|
|
149
213
|
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
214
|
+
def test_packet_length
|
|
215
|
+
val = 'range 80 1000'
|
|
216
|
+
%w(ipv4 ipv6).each do |afi|
|
|
217
|
+
a = ace_helper(afi, packet_length: val)
|
|
218
|
+
assert_equal(val, a.packet_length)
|
|
219
|
+
end
|
|
220
|
+
end
|
|
154
221
|
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
222
|
+
def test_ttl
|
|
223
|
+
val = '3'
|
|
224
|
+
%w(ipv4 ipv6).each do |afi|
|
|
225
|
+
a = ace_helper(afi, ttl: val)
|
|
226
|
+
skip("This property has a known defect on the platform itself -\n"\
|
|
227
|
+
'CSCuy47463: access-list ttl does not nvgen') if a.ttl.nil?
|
|
228
|
+
assert_equal(val, a.ttl)
|
|
229
|
+
end
|
|
159
230
|
end
|
|
160
231
|
end
|
data/tests/test_acl.rb
CHANGED
|
@@ -17,6 +17,7 @@ require_relative '../lib/cisco_node_utils/acl'
|
|
|
17
17
|
|
|
18
18
|
# test client for acl creation and deletion
|
|
19
19
|
class TestAcl < CiscoTestCase
|
|
20
|
+
@skip_unless_supported = 'acl'
|
|
20
21
|
def setup
|
|
21
22
|
# setup runs at the beginning of each test
|
|
22
23
|
super
|
|
@@ -84,7 +85,7 @@ class TestAcl < CiscoTestCase
|
|
|
84
85
|
# set to false
|
|
85
86
|
rtr.stats_per_entry = false
|
|
86
87
|
refute_show_match(pattern: /statistics per-entry/,
|
|
87
|
-
msg: 'failed to
|
|
88
|
+
msg: 'failed to disable stats')
|
|
88
89
|
refute(rtr.stats_per_entry)
|
|
89
90
|
|
|
90
91
|
# default getter function
|
|
@@ -168,6 +169,14 @@ class TestAcl < CiscoTestCase
|
|
|
168
169
|
end
|
|
169
170
|
|
|
170
171
|
def test_fragments
|
|
172
|
+
if node.product_id[/N(5|6)/]
|
|
173
|
+
a = Acl.new('ipv4', 'acl_fragments')
|
|
174
|
+
assert_nil(a.fragments)
|
|
175
|
+
assert_nil(a.default_fragments)
|
|
176
|
+
assert_raises(Cisco::UnsupportedError) { a.fragments = 'permit-all' }
|
|
177
|
+
return
|
|
178
|
+
end
|
|
179
|
+
|
|
171
180
|
%w(ipv4 ipv6).each do |afi|
|
|
172
181
|
acl_name = afi[/ipv6/] ? @acl_name_v6 : @acl_name_v4
|
|
173
182
|
fragments(afi, acl_name)
|
data/tests/test_bgp_af.rb
CHANGED
|
@@ -30,34 +30,234 @@ class TestBgpAF < CiscoTestCase
|
|
|
30
30
|
def setup
|
|
31
31
|
super
|
|
32
32
|
remove_all_bgps if @@pre_clean_needed
|
|
33
|
+
remove_all_vrfs if @@pre_clean_needed
|
|
34
|
+
if platform == :ios_xr && @@pre_clean_needed
|
|
35
|
+
config_no_warn('no route-policy drop_all')
|
|
36
|
+
end
|
|
33
37
|
@@pre_clean_needed = false # rubocop:disable Style/ClassVars
|
|
34
38
|
end
|
|
35
39
|
|
|
36
40
|
def teardown
|
|
37
|
-
super
|
|
38
41
|
remove_all_bgps
|
|
42
|
+
remove_all_vrfs
|
|
43
|
+
config_no_warn('no route-policy drop_all') if platform == :ios_xr
|
|
44
|
+
super
|
|
39
45
|
end
|
|
40
46
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
47
|
+
# Disabling line length to support wide-format test matrix definition
|
|
48
|
+
# rubocop:disable Metrics/LineLength
|
|
49
|
+
|
|
50
|
+
# Address Families to test:
|
|
51
|
+
T_AFS = [
|
|
52
|
+
# afi safi
|
|
53
|
+
%w(ipv4 unicast),
|
|
54
|
+
%w(ipv6 unicast),
|
|
55
|
+
%w(ipv4 multicast),
|
|
56
|
+
%w(ipv6 multicast),
|
|
57
|
+
%w(l2vpn evpn),
|
|
58
|
+
|
|
59
|
+
# TODO: These are additional address families/modifiers reported by XR, should they be tested also?
|
|
60
|
+
# Looks like most of them are not supported on Nexus...
|
|
61
|
+
#
|
|
62
|
+
|
|
63
|
+
# %w(ipv4 mvpn),
|
|
64
|
+
# %w(ipv6 mvpn),
|
|
65
|
+
|
|
66
|
+
# Not on Nexus:
|
|
67
|
+
# %w(link-state link-state),
|
|
68
|
+
#
|
|
69
|
+
# %w(l2vpn mspw),
|
|
70
|
+
# %w(l2vpn vpls-vpws),
|
|
71
|
+
#
|
|
72
|
+
# %w(ipv4 flowspec),
|
|
73
|
+
# %w(ipv4 mdt),
|
|
74
|
+
# %w(ipv4 rt-filter),
|
|
75
|
+
# %w(ipv4 tunnel),
|
|
76
|
+
#
|
|
77
|
+
# %w(ipv6 flowspec),
|
|
78
|
+
#
|
|
79
|
+
# %w(vpnv4 unicast),
|
|
80
|
+
# %w(vpnv4 multicast),
|
|
81
|
+
# %w(vpnv4 flowspec),
|
|
82
|
+
#
|
|
83
|
+
# %w(vpnv6 unicast),
|
|
84
|
+
# %w(vpnv6 multicast),
|
|
85
|
+
# %w(vpnv6 flowspec),
|
|
86
|
+
]
|
|
87
|
+
|
|
88
|
+
# ASs to test:
|
|
89
|
+
# TODO: Do we ever need to test more than one AS?
|
|
90
|
+
T_ASNS = ['55']
|
|
91
|
+
|
|
92
|
+
# VRFs to test:
|
|
93
|
+
T_VRFS = %w(default red)
|
|
94
|
+
|
|
95
|
+
# Value-based properties
|
|
96
|
+
T_VALUES = [
|
|
97
|
+
[:default_information_originate, [:toggle]],
|
|
98
|
+
[:client_to_client, [:toggle]],
|
|
99
|
+
[:additional_paths_send, [:toggle]],
|
|
100
|
+
[:additional_paths_receive, [:toggle]],
|
|
101
|
+
[:additional_paths_install, [:toggle]],
|
|
102
|
+
[:advertise_l2vpn_evpn, [:toggle]],
|
|
103
|
+
|
|
104
|
+
[:next_hop_route_map, ['drop_all']],
|
|
105
|
+
[:additional_paths_selection, ['drop_all']],
|
|
106
|
+
[:maximum_paths, [7, 9]],
|
|
107
|
+
[:maximum_paths_ibgp, [7, 9]],
|
|
108
|
+
[:dampen_igp_metric, [555, nil]],
|
|
109
|
+
[:default_metric, [50, false]],
|
|
110
|
+
[:inject_map, [[%w(lax sfo), %w(lax sjc), %w(nyc sfo copy-attributes), %w(sjc nyc copy-attributes)], [%w(nyc sfo copy-attributes), %w(sjc nyc copy-attributes)]]],
|
|
111
|
+
]
|
|
112
|
+
|
|
113
|
+
# Given the cartesian product of the above parameters, not all tests are supported.
|
|
114
|
+
# Here we record which tests are expected to fail, and what kind of failure is expected.
|
|
115
|
+
# This supports a very simple workflow for adding new tests:
|
|
116
|
+
# - Add new entry into test tables above.
|
|
117
|
+
# - Run tests.
|
|
118
|
+
# - When test fails, add a new 'exception' entry.
|
|
119
|
+
# - Repeat until all tests pass.
|
|
120
|
+
# - Condense entries using :any where possible.
|
|
121
|
+
#
|
|
122
|
+
TEST_EXCEPTIONS = [
|
|
123
|
+
# Test OS VRF AF Expected result
|
|
124
|
+
|
|
125
|
+
# Tests that are successful even though a rule below says otherwise
|
|
126
|
+
[:next_hop_route_map, :nexus, 'default', %w(l2vpn evpn), :success],
|
|
127
|
+
|
|
128
|
+
# XR CLI Errors
|
|
129
|
+
[:additional_paths_send, :ios_xr, :any, :multicast, :CliError],
|
|
130
|
+
[:additional_paths_receive, :ios_xr, :any, :multicast, :CliError],
|
|
131
|
+
[:additional_paths_selection, :ios_xr, :any, :multicast, :CliError],
|
|
132
|
+
[:client_to_client, :ios_xr, :VRF, :any, :CliError],
|
|
133
|
+
[:maximum_paths, :ios_xr, :any, %w(l2vpn evpn), :CliError],
|
|
134
|
+
[:maximum_paths_ibgp, :ios_xr, :any, %w(l2vpn evpn), :CliError],
|
|
135
|
+
[:next_hop_route_map, :ios_xr, :VRF, :any, :CliError],
|
|
136
|
+
|
|
137
|
+
# Nexus Unsupported
|
|
138
|
+
|
|
139
|
+
# Nexus CLI Errors
|
|
140
|
+
[:any, :nexus, 'default', %w(l2vpn evpn), :CliError],
|
|
141
|
+
[:advertise_l2vpn_evpn, :nexus, 'default', :any, :CliError],
|
|
142
|
+
[:advertise_l2vpn_evpn, :nexus, :VRF, :multicast, :CliError],
|
|
143
|
+
[:inject_map, :nexus, :any, :multicast, :CliError],
|
|
144
|
+
]
|
|
145
|
+
|
|
146
|
+
# rubocop:disable Style/SpaceAroundOperators
|
|
147
|
+
# rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
|
148
|
+
def check_test_exceptions(test_, os_, vrf_, af_)
|
|
149
|
+
ret = nil
|
|
150
|
+
amb = nil
|
|
151
|
+
TEST_EXCEPTIONS.each do |test, os, vrf, af, expect|
|
|
152
|
+
next unless (test_ == test || test == :any) &&
|
|
153
|
+
(os_ == os || os == :any) &&
|
|
154
|
+
(vrf_ == vrf || vrf == :any ||
|
|
155
|
+
(vrf == :VRF && vrf_ != 'default')) &&
|
|
156
|
+
(af_ == af || af == :any ||
|
|
157
|
+
(af == :unicast && (af_.include? 'unicast')) ||
|
|
158
|
+
(af == :multicast && (af_.include? 'multicast')) ||
|
|
159
|
+
(af == :ipv4 && (af_.include? 'ipv4')) ||
|
|
160
|
+
(af == :ipv6 && (af_.include? 'ipv6')))
|
|
161
|
+
return expect if expect == :success || expect == :skip
|
|
162
|
+
|
|
163
|
+
# Otherwise, make sure there's no ambiguity/overlap in the exceptions.
|
|
164
|
+
if !ret.nil? && ret != expect
|
|
165
|
+
assert('TEST ERROR: Exceptions matrix has ambiguous entries! ' \
|
|
166
|
+
"#{amb} and [#{test}, #{os}, #{vrf}, #{af}]")
|
|
167
|
+
end
|
|
168
|
+
ret = expect
|
|
169
|
+
amb = [test, os, vrf, af, expect]
|
|
170
|
+
end
|
|
171
|
+
# Return the expected test result
|
|
172
|
+
ret.nil? ? :success : ret
|
|
173
|
+
end
|
|
174
|
+
# rubocop:enable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
|
175
|
+
# rubocop:enable Style/SpaceAroundOperators
|
|
176
|
+
|
|
177
|
+
def properties_matrix(asns, vrfs, afs, values)
|
|
178
|
+
asns.each do |asn|
|
|
179
|
+
config_ios_xr_dependencies(asn)
|
|
180
|
+
|
|
181
|
+
vrfs.each do |vrf|
|
|
182
|
+
afs.each do |af|
|
|
183
|
+
# l2vpn evpn restrictions
|
|
184
|
+
if af == %w(l2vpn evpn)
|
|
185
|
+
next if vrf != 'default' ||
|
|
186
|
+
validate_property_excluded?('feature', 'nv_overlay_evpn')
|
|
187
|
+
end
|
|
188
|
+
|
|
189
|
+
bgp_af = RouterBgpAF.new(asn, vrf, af)
|
|
190
|
+
|
|
191
|
+
values.each do |test, test_values|
|
|
192
|
+
if validate_property_excluded?('bgp_af', test.to_s)
|
|
193
|
+
assert_raises(Cisco::UnsupportedError) { bgp_af.send("#{test}=", nil) }
|
|
194
|
+
next
|
|
195
|
+
end
|
|
196
|
+
|
|
197
|
+
# What result do we expect from this test?
|
|
198
|
+
expect = check_test_exceptions(test, platform, vrf, af)
|
|
199
|
+
|
|
200
|
+
# Gather initial value, default value, and the first test value..
|
|
201
|
+
initial = bgp_af.send(test)
|
|
202
|
+
|
|
203
|
+
# Properties which are unsupported or OFF by default return initial == nil
|
|
204
|
+
if initial.nil?
|
|
205
|
+
default = nil
|
|
206
|
+
first_value = nil
|
|
207
|
+
else
|
|
208
|
+
default = bgp_af.send("default_#{test}")
|
|
209
|
+
first_value = (test_values[0] == :toggle) ? !default : test_values[0]
|
|
210
|
+
end
|
|
211
|
+
|
|
212
|
+
if expect == :skip
|
|
213
|
+
# Do nothing..
|
|
214
|
+
|
|
215
|
+
elsif expect == :CliError
|
|
216
|
+
|
|
217
|
+
# This set of parameters should produce a CLI error
|
|
218
|
+
assert_raises(Cisco::CliError,
|
|
219
|
+
"Assert 'cli error' failed for: "\
|
|
220
|
+
"#{test}=(#{first_value}), #{asn}, #{vrf}, #{af}") do
|
|
221
|
+
bgp_af.send("#{test}=", first_value)
|
|
222
|
+
end
|
|
223
|
+
|
|
224
|
+
else
|
|
225
|
+
|
|
226
|
+
# Check initial value == default value
|
|
227
|
+
# Skip this assertion for properties that use auto_default: false
|
|
228
|
+
assert_equal(default, initial,
|
|
229
|
+
"Initial value failed for: #{test}, #{asn}, #{vrf}, #{af}"
|
|
230
|
+
) unless initial.nil?
|
|
231
|
+
|
|
232
|
+
# Try all the test values in order
|
|
233
|
+
test_values.each do |test_value|
|
|
234
|
+
test_value = (test_value == :toggle) ? !default : test_value
|
|
235
|
+
|
|
236
|
+
# Try the test value
|
|
237
|
+
bgp_af.send("#{test}=", test_value)
|
|
238
|
+
assert_equal(test_value, bgp_af.send(test),
|
|
239
|
+
"Test value failed for: #{test}, #{asn}, #{vrf}, #{af}")
|
|
240
|
+
end # test_values
|
|
241
|
+
|
|
242
|
+
# Set it back to the default
|
|
243
|
+
unless default.nil?
|
|
244
|
+
bgp_af.send("#{test}=", default)
|
|
245
|
+
assert_equal(default, bgp_af.send(test),
|
|
246
|
+
"Default assignment failed for: #{test}, #{asn}, #{vrf}, #{af}")
|
|
247
|
+
end
|
|
248
|
+
end
|
|
249
|
+
|
|
250
|
+
# Cleanup
|
|
251
|
+
bgp_af.destroy
|
|
252
|
+
end # tests
|
|
253
|
+
end # afs
|
|
254
|
+
end # vrfs
|
|
255
|
+
end # asns
|
|
256
|
+
end
|
|
257
|
+
# rubocop:enable Metrics/LineLength
|
|
258
|
+
|
|
259
|
+
def test_properties_matrix
|
|
260
|
+
properties_matrix(T_ASNS, T_VRFS, T_AFS, T_VALUES)
|
|
61
261
|
end
|
|
62
262
|
|
|
63
263
|
##
|
|
@@ -77,17 +277,27 @@ class TestBgpAF < CiscoTestCase
|
|
|
77
277
|
## Enable VXLAN and the EVPN
|
|
78
278
|
##
|
|
79
279
|
def test_collection_not_empty
|
|
80
|
-
config('feature bgp'
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
280
|
+
config('feature bgp') if platform == :nexus
|
|
281
|
+
|
|
282
|
+
bgp_afs = []
|
|
283
|
+
%w(default red blue orange black).each do |vrf|
|
|
284
|
+
[%w(ipv4 unicast), %w(ipv6 unicast),
|
|
285
|
+
%w(ipv4 multicast), %w(ipv6 multicast)].each do |af|
|
|
286
|
+
config_ios_xr_dependencies(55, vrf)
|
|
287
|
+
bgp_afs.push(RouterBgpAF.new(55, vrf, af))
|
|
288
|
+
end
|
|
289
|
+
end
|
|
290
|
+
|
|
291
|
+
# config('router bgp 55',
|
|
292
|
+
# 'address-family ipv4 unicast',
|
|
293
|
+
# 'vrf red',
|
|
294
|
+
# 'address-family ipv4 unicast',
|
|
295
|
+
# 'vrf blue',
|
|
296
|
+
# 'address-family ipv6 multicast',
|
|
297
|
+
# 'vrf orange',
|
|
298
|
+
# 'address-family ipv4 multicast',
|
|
299
|
+
# 'vrf black',
|
|
300
|
+
# 'address-family ipv6 unicast')
|
|
91
301
|
|
|
92
302
|
# Construct a hash of routers, vrfs, afs
|
|
93
303
|
routers = RouterBgpAF.afs
|
|
@@ -106,449 +316,73 @@ class TestBgpAF < CiscoTestCase
|
|
|
106
316
|
afi = af_key[0]
|
|
107
317
|
safi = af_key[1]
|
|
108
318
|
assert(afi.length > 0, 'Error: AFI length is zero')
|
|
109
|
-
assert_match(/^
|
|
319
|
+
assert_match(/^(ip|vpn)v[46]/, afi,
|
|
320
|
+
'Error: AFI must be vpnv4, ipv4, vpnv6 or ipv6')
|
|
110
321
|
assert(safi.length > 0, 'Error: SAFI length is zero')
|
|
322
|
+
assert_match(/^(un|mult)icast/, safi,
|
|
323
|
+
'Error: AFI must be unicast or multicast')
|
|
111
324
|
end
|
|
112
325
|
end
|
|
113
326
|
end
|
|
114
327
|
end
|
|
115
328
|
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
##
|
|
121
|
-
## default-information originate
|
|
122
|
-
##
|
|
123
|
-
def test_default_information_originate
|
|
124
|
-
asn = '55'
|
|
125
|
-
vrf = 'red'
|
|
126
|
-
af = %w(ipv4 unicast)
|
|
127
|
-
|
|
128
|
-
#
|
|
129
|
-
# Set and verify
|
|
130
|
-
#
|
|
131
|
-
bgp_af = RouterBgpAF.new(asn, vrf, af)
|
|
132
|
-
bgp_af.default_information_originate = true
|
|
133
|
-
assert(bgp_af.default_information_originate,
|
|
134
|
-
'Error: default-information originate not set')
|
|
135
|
-
|
|
136
|
-
pattern = /^ *default-information originate$/
|
|
137
|
-
af_string = get_bgp_af_cfg(asn, vrf, af)
|
|
138
|
-
|
|
139
|
-
assert_match(pattern, af_string,
|
|
140
|
-
"Error: 'default_information originate' is not" \
|
|
141
|
-
' configured and should be')
|
|
142
|
-
|
|
143
|
-
#
|
|
144
|
-
# Unset and verify
|
|
145
|
-
#
|
|
146
|
-
|
|
147
|
-
# Do a 'no default-information originate'
|
|
148
|
-
bgp_af.default_information_originate = false
|
|
149
|
-
|
|
150
|
-
pattern = /^ *default-information originate$/
|
|
151
|
-
af_string = get_bgp_af_cfg(asn, vrf, af)
|
|
152
|
-
|
|
153
|
-
refute_match(pattern, af_string,
|
|
154
|
-
"Error: 'default_information originate' " \
|
|
155
|
-
'is configured and should not be')
|
|
156
|
-
end
|
|
157
|
-
|
|
158
|
-
##
|
|
159
|
-
## client-to-client reflection
|
|
160
|
-
##
|
|
161
|
-
def test_client_to_client
|
|
162
|
-
asn = '55'
|
|
163
|
-
vrf = 'red'
|
|
164
|
-
af = %w(ipv4 unicast)
|
|
165
|
-
|
|
166
|
-
bgp_af = RouterBgpAF.new(asn, vrf, af)
|
|
167
|
-
#
|
|
168
|
-
# Default is 'client-to-client' is configured
|
|
169
|
-
#
|
|
170
|
-
assert(bgp_af.client_to_client,
|
|
171
|
-
"Error: 'client-to-client is not configured but should be")
|
|
172
|
-
#
|
|
173
|
-
# Unset and verify
|
|
174
|
-
#
|
|
175
|
-
|
|
176
|
-
# Do a 'no client-to-client reflection'
|
|
177
|
-
bgp_af.client_to_client = false
|
|
178
|
-
pattern = /^ *no client-to-client reflection$/
|
|
179
|
-
af_string = get_bgp_af_cfg(asn, vrf, af)
|
|
180
|
-
|
|
181
|
-
assert_match(pattern, af_string,
|
|
182
|
-
"Error: 'no client-to-client' is not configured and should be")
|
|
183
|
-
|
|
184
|
-
#
|
|
185
|
-
# Set and verify
|
|
186
|
-
#
|
|
187
|
-
|
|
188
|
-
# Do a 'client-to-client reflection'
|
|
189
|
-
bgp_af.client_to_client = true
|
|
190
|
-
af_string = get_bgp_af_cfg(asn, vrf, af)
|
|
191
|
-
|
|
192
|
-
refute_match(pattern, af_string,
|
|
193
|
-
"Error: 'no client-to-client' is configured and should not be")
|
|
194
|
-
end
|
|
195
|
-
|
|
196
|
-
##
|
|
197
|
-
## next_hop route-map
|
|
198
|
-
##
|
|
199
|
-
def test_next_hop_route_map
|
|
200
|
-
asn = '55'
|
|
201
|
-
vrf = 'red'
|
|
202
|
-
af = %w(ipv4 unicast)
|
|
203
|
-
|
|
204
|
-
#
|
|
205
|
-
# Set and verify
|
|
206
|
-
#
|
|
207
|
-
bgp_af = RouterBgpAF.new(asn, vrf, af)
|
|
208
|
-
bgp_af.next_hop_route_map = 'drop_all'
|
|
209
|
-
assert_match(bgp_af.next_hop_route_map, 'drop_all',
|
|
210
|
-
'Error: nexthop route-map not set')
|
|
211
|
-
pattern = /^ *nexthop route-map drop_all$/
|
|
212
|
-
af_string = get_bgp_af_cfg(asn, vrf, af)
|
|
213
|
-
|
|
214
|
-
assert_match(pattern, af_string,
|
|
215
|
-
"Error: 'nexthop route-map drop_all' is " \
|
|
216
|
-
'not configured and should be')
|
|
217
|
-
|
|
218
|
-
#
|
|
219
|
-
# Unset and verify
|
|
220
|
-
#
|
|
221
|
-
|
|
222
|
-
# Do a 'no nexthop route-map drop_all'
|
|
223
|
-
bgp_af.next_hop_route_map = bgp_af.default_next_hop_route_map
|
|
224
|
-
af_string = get_bgp_af_cfg(asn, vrf, af)
|
|
225
|
-
|
|
226
|
-
refute_match(pattern, af_string,
|
|
227
|
-
"Error: 'nexthop route-map drop_all' is " \
|
|
228
|
-
'configured and should not be')
|
|
229
|
-
end
|
|
230
|
-
|
|
231
|
-
##
|
|
232
|
-
## additional_paths
|
|
233
|
-
##
|
|
234
|
-
def test_additional_paths
|
|
235
|
-
asn = '55'
|
|
236
|
-
vrf = 'red'
|
|
237
|
-
af = %w(ipv4 unicast)
|
|
238
|
-
|
|
239
|
-
bgp_af = RouterBgpAF.new(asn, vrf, af)
|
|
240
|
-
|
|
241
|
-
pattern_send = 'additional-paths send'
|
|
242
|
-
pattern_receive = 'additional-paths receive'
|
|
243
|
-
pattern_install = 'additional-paths install backup'
|
|
244
|
-
|
|
245
|
-
#
|
|
246
|
-
# Default is not configured
|
|
247
|
-
#
|
|
248
|
-
af_string = get_bgp_af_cfg(asn, vrf, af)
|
|
249
|
-
|
|
250
|
-
[pattern_send, pattern_receive, pattern_install].each do |pat|
|
|
251
|
-
refute_match(pat, af_string,
|
|
252
|
-
"Error: '#{pat}' is configured but should not be")
|
|
253
|
-
end
|
|
254
|
-
|
|
255
|
-
#
|
|
256
|
-
# Test default and getter methods
|
|
257
|
-
#
|
|
258
|
-
assert_equal(bgp_af.default_additional_paths_send,
|
|
259
|
-
bgp_af.additional_paths_send)
|
|
260
|
-
assert_equal(bgp_af.default_additional_paths_receive,
|
|
261
|
-
bgp_af.additional_paths_receive)
|
|
262
|
-
assert_equal(bgp_af.default_additional_paths_install,
|
|
263
|
-
bgp_af.additional_paths_install)
|
|
264
|
-
|
|
265
|
-
#
|
|
266
|
-
# Set and verify
|
|
267
|
-
#
|
|
268
|
-
|
|
269
|
-
# Do a 'additional-paths send, receive, install'
|
|
270
|
-
bgp_af.additional_paths_send = true
|
|
271
|
-
bgp_af.additional_paths_receive = true
|
|
272
|
-
bgp_af.additional_paths_install = true
|
|
273
|
-
|
|
274
|
-
af_string = get_bgp_af_cfg(asn, vrf, af)
|
|
275
|
-
|
|
276
|
-
[pattern_send, pattern_receive, pattern_install].each do |pat|
|
|
277
|
-
assert_match(pat, af_string,
|
|
278
|
-
"Error: '#{pat}' is not configured and should be")
|
|
279
|
-
end
|
|
280
|
-
|
|
281
|
-
#
|
|
282
|
-
# Test getter
|
|
283
|
-
#
|
|
284
|
-
|
|
285
|
-
assert(bgp_af.additional_paths_send)
|
|
286
|
-
assert(bgp_af.additional_paths_receive)
|
|
287
|
-
assert(bgp_af.additional_paths_install)
|
|
288
|
-
|
|
289
|
-
#
|
|
290
|
-
# Unset and verify
|
|
291
|
-
#
|
|
292
|
-
|
|
293
|
-
# Do a 'no additional-paths send, receive, install'
|
|
294
|
-
bgp_af.additional_paths_send = false
|
|
295
|
-
bgp_af.additional_paths_receive = false
|
|
296
|
-
bgp_af.additional_paths_install = false
|
|
297
|
-
|
|
298
|
-
af_string = get_bgp_af_cfg(asn, vrf, af)
|
|
299
|
-
|
|
300
|
-
[pattern_send, pattern_receive, pattern_install].each do |pat|
|
|
301
|
-
refute_match(pat, af_string,
|
|
302
|
-
"Error: '#{pat}' is configured but should not be")
|
|
303
|
-
end
|
|
304
|
-
end
|
|
305
|
-
|
|
306
|
-
##
|
|
307
|
-
## additional_paths_selection route-map
|
|
308
|
-
##
|
|
309
|
-
def test_additional_paths_selection
|
|
310
|
-
asn = '55'
|
|
311
|
-
vrf = 'red'
|
|
312
|
-
af = %w(ipv4 unicast)
|
|
313
|
-
|
|
314
|
-
#
|
|
315
|
-
# Set and verify
|
|
316
|
-
#
|
|
317
|
-
bgp_af = RouterBgpAF.new(asn, vrf, af)
|
|
318
|
-
bgp_af.additional_paths_selection = 'drop_all'
|
|
319
|
-
|
|
320
|
-
assert_equal(bgp_af.additional_paths_selection, 'drop_all',
|
|
321
|
-
'Error: additional-paths selection route-map not set')
|
|
322
|
-
|
|
323
|
-
af_string = get_bgp_af_cfg(asn, vrf, af)
|
|
324
|
-
pattern = /^ *additional-paths selection route-map drop_all$/
|
|
325
|
-
|
|
326
|
-
assert_match(pattern, af_string,
|
|
327
|
-
"Error: 'additional-paths selection route-map drop_all' is " \
|
|
328
|
-
'not configured and should be')
|
|
329
|
-
|
|
330
|
-
#
|
|
331
|
-
# Test getter
|
|
332
|
-
#
|
|
333
|
-
pattern = /^ *drop_all$/
|
|
334
|
-
assert_match(pattern, bgp_af.additional_paths_selection,
|
|
335
|
-
"Error: 'route-map drop_all' is not configured and should be")
|
|
336
|
-
|
|
337
|
-
#
|
|
338
|
-
# Unset and verify
|
|
339
|
-
#
|
|
329
|
+
def config_ios_xr_dependencies(asn, vrf='red')
|
|
330
|
+
return unless platform == :ios_xr
|
|
331
|
+
# These dependencies are required on ios xr
|
|
340
332
|
|
|
341
|
-
#
|
|
342
|
-
|
|
343
|
-
|
|
333
|
+
# "rd auto" required, otherwise XR reports:
|
|
334
|
+
# 'The RD for the VRF must be present before an
|
|
335
|
+
# address family is activated'
|
|
344
336
|
|
|
345
|
-
|
|
337
|
+
# "bgp router-id" requred, otherwise XR reports:
|
|
338
|
+
# 'BGP router ID must be configured.'
|
|
346
339
|
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
'configured and should not be')
|
|
350
|
-
end
|
|
340
|
+
# "address-family vpnv4 unicast" required, otherwise XR reports:
|
|
341
|
+
# 'The parent address family has not been initialized'
|
|
351
342
|
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
#
|
|
360
|
-
|
|
361
|
-
val = false
|
|
362
|
-
bgp_af.advertise_l2vpn_evpn = val
|
|
363
|
-
assert_equal(val, bgp_af.advertise_l2vpn_evpn,
|
|
364
|
-
'Error: advertise l2vpn evpn value does not match set value')
|
|
343
|
+
cfg = ["router bgp #{asn}",
|
|
344
|
+
'bgp router-id 10.1.1.1',
|
|
345
|
+
'address-family vpnv4 unicast',
|
|
346
|
+
'address-family vpnv6 unicast',
|
|
347
|
+
'address-family vpnv4 multicast',
|
|
348
|
+
'address-family vpnv6 multicast',
|
|
349
|
+
]
|
|
350
|
+
cfg << "vrf #{vrf}" << 'rd auto' unless vrf == 'default'
|
|
351
|
+
config(cfg)
|
|
365
352
|
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
assert_equal(val, bgp_af.advertise_l2vpn_evpn,
|
|
369
|
-
'Error: advertise l2vpn evpn value does not match set value')
|
|
370
|
-
|
|
371
|
-
val = bgp_af.default_advertise_l2vpn_evpn
|
|
372
|
-
bgp_af.advertise_l2vpn_evpn = val
|
|
373
|
-
assert_equal(val, bgp_af.advertise_l2vpn_evpn,
|
|
374
|
-
'Error: advertise l2vpn evpn value does not match default' \
|
|
375
|
-
'value')
|
|
376
|
-
end
|
|
353
|
+
# Needed for testing route-policy commands
|
|
354
|
+
config_no_warn('route-policy drop_all', 'end-policy')
|
|
377
355
|
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
advertise_l2vpn_evpn(55, 'red', af)
|
|
382
|
-
end
|
|
356
|
+
# TBD: Reduce the number of different route-policies used by this test
|
|
357
|
+
# and move the remaining ones into this method. Then create an
|
|
358
|
+
# unconfig_ios_xr_dependencies to handle the cleanups.
|
|
383
359
|
end
|
|
384
360
|
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
def test_dampen_igp_metric
|
|
389
|
-
asn = '44'
|
|
390
|
-
vrf = 'green'
|
|
391
|
-
af = %w(ipv4 multicast)
|
|
392
|
-
|
|
393
|
-
bgp_af = RouterBgpAF.new(asn, vrf, af)
|
|
394
|
-
|
|
395
|
-
#
|
|
396
|
-
# Verify default value
|
|
397
|
-
#
|
|
398
|
-
assert_equal(bgp_af.dampen_igp_metric, bgp_af.default_dampen_igp_metric,
|
|
399
|
-
"Error: Default 'dampen-igp-metric' value should be " \
|
|
400
|
-
"#{bgp_af.default_dampen_igp_metric}")
|
|
401
|
-
|
|
402
|
-
#
|
|
403
|
-
# Set and verify 'dampen-igp-metric <value>'
|
|
404
|
-
#
|
|
405
|
-
|
|
406
|
-
# Do a 'dampen-igp-metric 555'
|
|
407
|
-
pattern = /^ *dampen-igp-metric 555$/
|
|
408
|
-
bgp_af.dampen_igp_metric = 555
|
|
409
|
-
|
|
410
|
-
af_string = get_bgp_af_cfg(asn, vrf, af)
|
|
411
|
-
|
|
412
|
-
assert_match(pattern, af_string,
|
|
413
|
-
"Error: 'dampen-igp-metric 555' is not configured " \
|
|
414
|
-
'and should be')
|
|
415
|
-
#
|
|
416
|
-
# Test getter
|
|
417
|
-
#
|
|
418
|
-
assert_equal(bgp_af.dampen_igp_metric, 555,
|
|
419
|
-
'Error: dampen_igp_metric should be 555')
|
|
420
|
-
|
|
421
|
-
#
|
|
422
|
-
# Set and verify 'no dampen-igp-metric'
|
|
423
|
-
#
|
|
424
|
-
|
|
425
|
-
# Do a 'no dampen-igp-metric'
|
|
426
|
-
pattern = /no dampen-igp-metric$/
|
|
427
|
-
bgp_af.dampen_igp_metric = nil
|
|
428
|
-
|
|
429
|
-
af_string = get_bgp_af_cfg(asn, vrf, af)
|
|
430
|
-
|
|
431
|
-
assert_match(pattern, af_string,
|
|
432
|
-
"Error: 'no dampen-igp-metric' is not configured " \
|
|
433
|
-
'and should be')
|
|
434
|
-
#
|
|
435
|
-
# Test getter
|
|
436
|
-
#
|
|
437
|
-
assert_equal(bgp_af.dampen_igp_metric, nil,
|
|
438
|
-
'Error: dampen_igp_metric should be nil')
|
|
439
|
-
|
|
440
|
-
#
|
|
441
|
-
# Set default value explicitly
|
|
442
|
-
#
|
|
443
|
-
bgp_af.dampen_igp_metric = bgp_af.default_dampen_igp_metric
|
|
444
|
-
assert_equal(bgp_af.dampen_igp_metric, bgp_af.default_dampen_igp_metric,
|
|
445
|
-
"Error: Default 'dampen-igp-metric' value should be " \
|
|
446
|
-
"#{bgp_af.default_dampen_igp_metric}")
|
|
447
|
-
end
|
|
361
|
+
########################################################
|
|
362
|
+
# PROPERTIES #
|
|
363
|
+
########################################################
|
|
448
364
|
|
|
449
|
-
##
|
|
450
|
-
## dampening
|
|
451
|
-
##
|
|
452
|
-
# rubocop:disable Metrics/MethodLength
|
|
453
365
|
def test_dampening
|
|
454
366
|
asn = '101'
|
|
455
|
-
|
|
456
|
-
############################################
|
|
457
|
-
# Set and verify 'dampening' with defaults #
|
|
458
|
-
############################################
|
|
459
|
-
vrf = 'orange'
|
|
460
367
|
af = %w(ipv4 unicast)
|
|
368
|
+
if platform == :nexus
|
|
369
|
+
vrf = 'orange'
|
|
370
|
+
elsif platform == :ios_xr
|
|
371
|
+
vrf = 'default'
|
|
372
|
+
config_ios_xr_dependencies(asn, vrf)
|
|
373
|
+
config_no_warn('route-policy DropAllTraffic', 'end-policy')
|
|
374
|
+
end
|
|
461
375
|
bgp_af = RouterBgpAF.new(asn, vrf, af)
|
|
462
376
|
|
|
463
377
|
# Test no dampening configured
|
|
464
378
|
assert_nil(bgp_af.dampening)
|
|
465
379
|
|
|
466
|
-
pattern = /^ *dampening$/
|
|
467
|
-
|
|
468
|
-
bgp_af.dampening = []
|
|
469
|
-
|
|
470
|
-
# Check property got set
|
|
471
|
-
af_string = get_bgp_af_cfg(asn, vrf, af)
|
|
472
|
-
|
|
473
|
-
assert_match(pattern, af_string,
|
|
474
|
-
"Error: 'dampening' is not configured and should be")
|
|
475
|
-
|
|
476
|
-
# Check properties got set
|
|
477
|
-
af_string = get_bgp_af_dampening_params(asn, vrf, af)
|
|
478
|
-
|
|
479
|
-
pattern_params1 = 'Half-life time : 15 mins'
|
|
480
|
-
pattern_params2 = 'Suppress penalty : 2000'
|
|
481
|
-
pattern_params3 = 'Reuse penalty : 750'
|
|
482
|
-
pattern_params4 = 'Max suppress time : 45 mins'
|
|
483
|
-
pattern_params5 = 'Max suppress penalty : 6000'
|
|
484
|
-
|
|
485
|
-
error = ("Error: 'dampening' properties are incorrect")
|
|
486
|
-
|
|
487
|
-
assert_match(pattern_params1, af_string, error)
|
|
488
|
-
assert_match(pattern_params2, af_string, error)
|
|
489
|
-
assert_match(pattern_params3, af_string, error)
|
|
490
|
-
assert_match(pattern_params4, af_string, error)
|
|
491
|
-
assert_match(pattern_params5, af_string, error)
|
|
492
|
-
|
|
493
|
-
# Check getter
|
|
494
|
-
assert_empty(bgp_af.dampening, 'Error: dampening is configured and ' \
|
|
495
|
-
'should not be')
|
|
496
|
-
|
|
497
|
-
#
|
|
498
|
-
# Unset and verify
|
|
499
|
-
#
|
|
500
|
-
bgp_af.dampening = nil
|
|
501
|
-
|
|
502
|
-
af_string = get_bgp_af_cfg(asn, vrf, af)
|
|
503
|
-
pattern = /^ *dampening$/
|
|
504
|
-
|
|
505
|
-
refute_match(pattern, af_string, "Error: 'dampening' is still configured")
|
|
506
|
-
|
|
507
|
-
#
|
|
508
|
-
# Test Getters
|
|
509
|
-
#
|
|
510
|
-
assert_nil(bgp_af.dampening)
|
|
511
|
-
assert_nil(bgp_af.dampening_half_time)
|
|
512
|
-
assert_nil(bgp_af.dampening_reuse_time)
|
|
513
|
-
assert_nil(bgp_af.dampening_suppress_time)
|
|
514
|
-
assert_nil(bgp_af.dampening_max_suppress_time)
|
|
515
|
-
assert_nil(bgp_af.dampening_routemap)
|
|
516
|
-
|
|
517
|
-
bgp_af.destroy
|
|
518
|
-
|
|
519
380
|
#############################################
|
|
520
381
|
# Set and verify 'dampening' with overrides #
|
|
521
382
|
#############################################
|
|
522
|
-
vrf = 'green'
|
|
523
|
-
af = %w(ipv4 multicast)
|
|
524
|
-
bgp_af = RouterBgpAF.new(asn, vrf, af)
|
|
525
383
|
|
|
526
384
|
bgp_af.dampening = %w(1 2 3 4)
|
|
527
385
|
|
|
528
|
-
# Check property got set
|
|
529
|
-
af_string = get_bgp_af_cfg(asn, vrf, af)
|
|
530
|
-
pattern = /^ *dampening 1 2 3 4$/
|
|
531
|
-
|
|
532
|
-
assert_match(pattern, af_string,
|
|
533
|
-
"Error: 'dampening' is not configured and should be")
|
|
534
|
-
|
|
535
|
-
# Check properties got set
|
|
536
|
-
af_string = get_bgp_af_dampening_params(asn, vrf, af)
|
|
537
|
-
|
|
538
|
-
pattern_params1 = 'Half-life time : 1 mins'
|
|
539
|
-
pattern_params2 = 'Suppress penalty : 3'
|
|
540
|
-
pattern_params3 = 'Reuse penalty : 2'
|
|
541
|
-
pattern_params4 = 'Max suppress time : 4 mins'
|
|
542
|
-
pattern_params5 = 'Max suppress penalty : 32'
|
|
543
|
-
|
|
544
|
-
error = ("Error: 'dampening' properties are incorrect")
|
|
545
|
-
|
|
546
|
-
assert_match(pattern_params1, af_string, error)
|
|
547
|
-
assert_match(pattern_params2, af_string, error)
|
|
548
|
-
assert_match(pattern_params3, af_string, error)
|
|
549
|
-
assert_match(pattern_params4, af_string, error)
|
|
550
|
-
assert_match(pattern_params5, af_string, error)
|
|
551
|
-
|
|
552
386
|
# Check getters
|
|
553
387
|
assert_equal(bgp_af.dampening, %w(1 2 3 4),
|
|
554
388
|
'Error: dampening getter did not match')
|
|
@@ -563,92 +397,28 @@ class TestBgpAF < CiscoTestCase
|
|
|
563
397
|
assert_empty(bgp_af.dampening_routemap,
|
|
564
398
|
'A routemap should not be configured')
|
|
565
399
|
|
|
566
|
-
#
|
|
567
|
-
# Unset and verify
|
|
568
|
-
#
|
|
569
|
-
bgp_af.dampening = nil
|
|
570
|
-
|
|
571
|
-
af_string = get_bgp_af_cfg(asn, vrf, af)
|
|
572
|
-
pattern = /^ *dampening$/
|
|
573
|
-
|
|
574
|
-
refute_match(pattern, af_string, "Error: 'dampening' is still configured")
|
|
575
|
-
|
|
576
400
|
#############################################
|
|
577
401
|
# Set and verify 'dampening' with route-map #
|
|
578
402
|
#############################################
|
|
579
|
-
vrf = 'brown'
|
|
580
|
-
af = %w(ipv6 unicast)
|
|
581
|
-
bgp_af = RouterBgpAF.new(asn, vrf, af)
|
|
582
403
|
|
|
583
404
|
bgp_af.dampening = 'DropAllTraffic'
|
|
584
405
|
|
|
585
|
-
pattern = /^ *dampening route-map DropAllTraffic$/
|
|
586
|
-
|
|
587
|
-
# Check property got set
|
|
588
|
-
af_string = get_bgp_af_cfg(asn, vrf, af)
|
|
589
|
-
|
|
590
|
-
assert_match(pattern, af_string,
|
|
591
|
-
"Error: 'dampening' is not configured and should be")
|
|
592
|
-
|
|
593
|
-
# Check properties got set
|
|
594
|
-
af_string = get_bgp_af_dampening_params(asn, vrf, af)
|
|
595
|
-
pattern_params = 'Dampening policy configured: DropAllTraffic'
|
|
596
|
-
|
|
597
|
-
assert_match(pattern_params, af_string,
|
|
598
|
-
'Error: dampening properties DropAllTraffic is not ' \
|
|
599
|
-
'configured and should be')
|
|
600
|
-
|
|
601
406
|
# Check getters
|
|
602
|
-
assert_equal(
|
|
603
|
-
|
|
604
|
-
assert_equal(bgp_af.dampening_routemap, 'DropAllTraffic',
|
|
605
|
-
'Error: dampening getter did not match')
|
|
606
|
-
|
|
607
|
-
#
|
|
608
|
-
# Unset and verify
|
|
609
|
-
#
|
|
610
|
-
bgp_af.dampening = nil
|
|
611
|
-
af_string = get_bgp_af_cfg(asn, vrf, af)
|
|
612
|
-
pattern = /^ *dampening$/
|
|
613
|
-
|
|
614
|
-
refute_match(pattern, af_string, "Error: 'dampening' is still configured")
|
|
407
|
+
assert_equal('DropAllTraffic', bgp_af.dampening)
|
|
408
|
+
assert_equal('DropAllTraffic', bgp_af.dampening_routemap)
|
|
615
409
|
|
|
616
410
|
#############################################
|
|
617
|
-
# Set and verify 'dampening'
|
|
411
|
+
# Set and verify 'dampening' to defaults #
|
|
618
412
|
#############################################
|
|
619
|
-
vrf = 'sangria'
|
|
620
|
-
af = %w(ipv4 multicast)
|
|
621
|
-
bgp_af = RouterBgpAF.new(asn, vrf, af)
|
|
622
413
|
|
|
623
414
|
bgp_af.dampening = bgp_af.default_dampening
|
|
624
415
|
|
|
625
|
-
# Check
|
|
626
|
-
af_string = get_bgp_af_cfg(asn, vrf, af)
|
|
627
|
-
|
|
628
|
-
assert_match(pattern, af_string,
|
|
629
|
-
"Error: 'dampening' is not configured and should be")
|
|
630
|
-
|
|
631
|
-
# Check properties got set
|
|
632
|
-
af_string = get_bgp_af_dampening_params(asn, vrf, af)
|
|
633
|
-
|
|
634
|
-
pattern_params1 = 'Half-life time : 15 mins'
|
|
635
|
-
pattern_params2 = 'Suppress penalty : 2000'
|
|
636
|
-
pattern_params3 = 'Reuse penalty : 750'
|
|
637
|
-
pattern_params4 = 'Max suppress time : 45 mins'
|
|
638
|
-
pattern_params5 = 'Max suppress penalty : 6000'
|
|
639
|
-
|
|
640
|
-
error = ("Error: 'dampening' properties are incorrect")
|
|
416
|
+
# Check getters
|
|
641
417
|
|
|
642
|
-
|
|
643
|
-
assert_match(pattern_params2, af_string, error)
|
|
644
|
-
assert_match(pattern_params3, af_string, error)
|
|
645
|
-
assert_match(pattern_params4, af_string, error)
|
|
646
|
-
assert_match(pattern_params5, af_string, error)
|
|
418
|
+
assert_equal(bgp_af.default_dampening, bgp_af.dampening)
|
|
647
419
|
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
'and should be')
|
|
651
|
-
assert_equal(bgp_af.default_dampening_half_time, bgp_af.dampening_half_time,
|
|
420
|
+
assert_equal(bgp_af.default_dampening_half_time,
|
|
421
|
+
bgp_af.dampening_half_time,
|
|
652
422
|
'Wrong default dampening half_time value configured')
|
|
653
423
|
assert_equal(bgp_af.default_dampening_reuse_time,
|
|
654
424
|
bgp_af.dampening_reuse_time,
|
|
@@ -663,15 +433,20 @@ class TestBgpAF < CiscoTestCase
|
|
|
663
433
|
bgp_af.dampening_routemap,
|
|
664
434
|
'The default dampening routemap should configured')
|
|
665
435
|
|
|
666
|
-
|
|
667
|
-
#
|
|
668
|
-
|
|
436
|
+
############################################
|
|
437
|
+
# Turn off 'dampening' #
|
|
438
|
+
############################################
|
|
439
|
+
|
|
669
440
|
bgp_af.dampening = nil
|
|
670
|
-
|
|
441
|
+
assert_nil(bgp_af.dampening)
|
|
442
|
+
assert_nil(bgp_af.dampening_half_time)
|
|
443
|
+
assert_nil(bgp_af.dampening_reuse_time)
|
|
444
|
+
assert_nil(bgp_af.dampening_suppress_time)
|
|
445
|
+
assert_nil(bgp_af.dampening_max_suppress_time)
|
|
446
|
+
assert_nil(bgp_af.dampening_routemap)
|
|
671
447
|
|
|
672
|
-
|
|
448
|
+
bgp_af.destroy
|
|
673
449
|
end
|
|
674
|
-
# rubocop:enable Metrics/AbcSize,Metrics/MethodLength
|
|
675
450
|
|
|
676
451
|
##
|
|
677
452
|
## distance
|
|
@@ -681,6 +456,7 @@ class TestBgpAF < CiscoTestCase
|
|
|
681
456
|
vrf = 'red'
|
|
682
457
|
af = %w(ipv4 unicast)
|
|
683
458
|
|
|
459
|
+
config_ios_xr_dependencies(asn)
|
|
684
460
|
bgp_af = RouterBgpAF.new(asn, vrf, af)
|
|
685
461
|
distance = [{ ebgp: 20, ibgp: 40, local: 60 },
|
|
686
462
|
{ ebgp: bgp_af.default_distance_ebgp,
|
|
@@ -705,163 +481,6 @@ class TestBgpAF < CiscoTestCase
|
|
|
705
481
|
bgp_af.destroy
|
|
706
482
|
end
|
|
707
483
|
|
|
708
|
-
##
|
|
709
|
-
## default_metric
|
|
710
|
-
##
|
|
711
|
-
def default_metric(asn, vrf, af)
|
|
712
|
-
bgp_af = RouterBgpAF.new(asn, vrf, af)
|
|
713
|
-
|
|
714
|
-
refute(bgp_af.default_default_metric,
|
|
715
|
-
'default value for default default metric should be false')
|
|
716
|
-
#
|
|
717
|
-
# Set and verify
|
|
718
|
-
#
|
|
719
|
-
val = 50
|
|
720
|
-
bgp_af.default_metric = val
|
|
721
|
-
assert_equal(val, bgp_af.default_metric,
|
|
722
|
-
'Error: default metric value does not match set value')
|
|
723
|
-
|
|
724
|
-
val = bgp_af.default_default_metric
|
|
725
|
-
bgp_af.default_metric = val
|
|
726
|
-
assert_equal(val, bgp_af.default_metric,
|
|
727
|
-
'Error: default metric value does not match default' \
|
|
728
|
-
'value')
|
|
729
|
-
end
|
|
730
|
-
|
|
731
|
-
def test_default_metric
|
|
732
|
-
afs = [%w(ipv4 unicast), %w(ipv6 unicast)]
|
|
733
|
-
afs.each do |af|
|
|
734
|
-
default_metric(55, 'red', af)
|
|
735
|
-
end
|
|
736
|
-
end
|
|
737
|
-
|
|
738
|
-
##
|
|
739
|
-
## inject_map
|
|
740
|
-
##
|
|
741
|
-
def inject_map(asn, vrf, af)
|
|
742
|
-
# rubocop:disable Style/WordArray
|
|
743
|
-
master = [['lax', 'sfo'],
|
|
744
|
-
['lax', 'sjc'],
|
|
745
|
-
['nyc', 'sfo', 'copy-attributes'],
|
|
746
|
-
['sjc', 'nyc', 'copy-attributes']]
|
|
747
|
-
bgp_af = RouterBgpAF.new(asn, vrf, af)
|
|
748
|
-
|
|
749
|
-
# Test1: both/import/export when no commands are present. Each target
|
|
750
|
-
# option will be tested with and without evpn (6 separate types)
|
|
751
|
-
should = master.clone
|
|
752
|
-
inject_map_tester(bgp_af, should, 'Test 1')
|
|
753
|
-
|
|
754
|
-
# Test 2: remove half of the entries
|
|
755
|
-
should = [['lax', 'sfo'], ['nyc', 'sfo', 'copy-attributes']]
|
|
756
|
-
# rubocop:enable Style/WordArray
|
|
757
|
-
inject_map_tester(bgp_af, should, 'Test 2')
|
|
758
|
-
|
|
759
|
-
# Test 3: restore the removed entries
|
|
760
|
-
should = master.clone
|
|
761
|
-
inject_map_tester(bgp_af, should, 'Test 3')
|
|
762
|
-
|
|
763
|
-
# Test 4: 'default'
|
|
764
|
-
should = bgp_af.default_inject_map
|
|
765
|
-
inject_map_tester(bgp_af, should, 'Test 4')
|
|
766
|
-
end
|
|
767
|
-
|
|
768
|
-
def inject_map_tester(bgp_af, should, test_id)
|
|
769
|
-
bgp_af.send('inject_map=', should)
|
|
770
|
-
result = bgp_af.send('inject_map')
|
|
771
|
-
assert_equal(should, result,
|
|
772
|
-
"#{test_id} : inject_map")
|
|
773
|
-
end
|
|
774
|
-
|
|
775
|
-
def test_inject_map
|
|
776
|
-
afs = [%w(ipv4 unicast), %w(ipv6 unicast)]
|
|
777
|
-
afs.each do |af|
|
|
778
|
-
inject_map(55, 'red', af)
|
|
779
|
-
end
|
|
780
|
-
end
|
|
781
|
-
|
|
782
|
-
##
|
|
783
|
-
## maximum_paths
|
|
784
|
-
##
|
|
785
|
-
def maximum_paths(asn, vrf, af)
|
|
786
|
-
bgp_af = RouterBgpAF.new(asn, vrf, af)
|
|
787
|
-
|
|
788
|
-
#
|
|
789
|
-
# Set and verify
|
|
790
|
-
#
|
|
791
|
-
val = 7
|
|
792
|
-
bgp_af.maximum_paths = val
|
|
793
|
-
assert_equal(bgp_af.maximum_paths, val,
|
|
794
|
-
'Error: maximum paths value not match to set value')
|
|
795
|
-
|
|
796
|
-
val = 9
|
|
797
|
-
bgp_af.maximum_paths = val
|
|
798
|
-
assert_equal(bgp_af.maximum_paths, val,
|
|
799
|
-
'Error: maximum paths value not match to set value')
|
|
800
|
-
|
|
801
|
-
val = bgp_af.default_maximum_paths
|
|
802
|
-
bgp_af.maximum_paths = val
|
|
803
|
-
assert_equal(bgp_af.maximum_paths, val,
|
|
804
|
-
'Error: maximum paths value not match to default value')
|
|
805
|
-
end
|
|
806
|
-
|
|
807
|
-
def test_maximum_paths
|
|
808
|
-
vrfs = %w(default red)
|
|
809
|
-
afs = [%w(ipv4 unicast), %w(ipv6 unicast)]
|
|
810
|
-
vrfs.each do |vrf|
|
|
811
|
-
afs.each do |af|
|
|
812
|
-
maximum_paths(55, vrf, af)
|
|
813
|
-
end
|
|
814
|
-
end
|
|
815
|
-
end
|
|
816
|
-
|
|
817
|
-
##
|
|
818
|
-
## maximum_paths_ibgp
|
|
819
|
-
##
|
|
820
|
-
def maximum_paths_ibgp(asn, vrf, af)
|
|
821
|
-
/ipv4/.match(af) ? af = %w(ipv4 unicast) : af = %w(ipv6 unicast)
|
|
822
|
-
bgp_af = RouterBgpAF.new(asn, vrf, af)
|
|
823
|
-
|
|
824
|
-
#
|
|
825
|
-
# Set and verify
|
|
826
|
-
#
|
|
827
|
-
val = 7
|
|
828
|
-
bgp_af.maximum_paths_ibgp = val
|
|
829
|
-
assert_equal(bgp_af.maximum_paths_ibgp, val,
|
|
830
|
-
'Error: maximum paths ibgp value not match to set value')
|
|
831
|
-
|
|
832
|
-
val = 9
|
|
833
|
-
bgp_af.maximum_paths_ibgp = val
|
|
834
|
-
assert_equal(bgp_af.maximum_paths_ibgp, val,
|
|
835
|
-
'Error: maximum paths ibgp value not match to set value')
|
|
836
|
-
|
|
837
|
-
val = bgp_af.default_maximum_paths_ibgp
|
|
838
|
-
bgp_af.maximum_paths = val
|
|
839
|
-
assert_equal(bgp_af.default_maximum_paths_ibgp, val,
|
|
840
|
-
'Error: maximum paths ibgp value not match to default value')
|
|
841
|
-
end
|
|
842
|
-
|
|
843
|
-
def test_maximum_paths_ibgp
|
|
844
|
-
asn = '55'
|
|
845
|
-
vrf = 'default'
|
|
846
|
-
af = 'ipv4 unicast'
|
|
847
|
-
maximum_paths_ibgp(asn, vrf, af)
|
|
848
|
-
|
|
849
|
-
asn = '55'
|
|
850
|
-
vrf = 'red'
|
|
851
|
-
af = 'ipv4 unicast'
|
|
852
|
-
maximum_paths_ibgp(asn, vrf, af)
|
|
853
|
-
|
|
854
|
-
asn = '55'
|
|
855
|
-
vrf = 'default'
|
|
856
|
-
af = 'ipv6 unicast'
|
|
857
|
-
maximum_paths_ibgp(asn, vrf, af)
|
|
858
|
-
|
|
859
|
-
asn = '55'
|
|
860
|
-
vrf = 'red'
|
|
861
|
-
af = 'ipv6 unicast'
|
|
862
|
-
maximum_paths_ibgp(asn, vrf, af)
|
|
863
|
-
end
|
|
864
|
-
|
|
865
484
|
##
|
|
866
485
|
## network
|
|
867
486
|
##
|
|
@@ -872,13 +491,22 @@ class TestBgpAF < CiscoTestCase
|
|
|
872
491
|
vrfs.each do |vrf|
|
|
873
492
|
afs.each do |af|
|
|
874
493
|
dbg = sprintf('[VRF %s AF %s]', vrf, af.join('/'))
|
|
494
|
+
config_ios_xr_dependencies(1)
|
|
875
495
|
af_obj = RouterBgpAF.new(1, vrf, af)
|
|
876
496
|
network_cmd(af_obj, dbg)
|
|
497
|
+
|
|
498
|
+
af_obj.destroy
|
|
877
499
|
end
|
|
878
500
|
end
|
|
879
501
|
end
|
|
880
502
|
|
|
881
503
|
def network_cmd(af, dbg)
|
|
504
|
+
if platform == :ios_xr
|
|
505
|
+
%w(rtmap1 rtmap2 rtmap3 rtmap5 rtmap6 rtmap7).each do |policy|
|
|
506
|
+
config_no_warn("route-policy #{policy}", 'end-policy')
|
|
507
|
+
end
|
|
508
|
+
end
|
|
509
|
+
|
|
882
510
|
# Initial 'should' state
|
|
883
511
|
if /ipv6/.match(dbg)
|
|
884
512
|
master = [
|
|
@@ -926,7 +554,13 @@ class TestBgpAF < CiscoTestCase
|
|
|
926
554
|
"#{dbg} Test 3. Restore the removed networks")
|
|
927
555
|
|
|
928
556
|
# Test: Change route-maps on existing networks
|
|
929
|
-
|
|
557
|
+
if platform == :ios_xr
|
|
558
|
+
%w(rtmap1_55 rtmap2_55 rtmap3_55 rtmap5_55
|
|
559
|
+
rtmap6_55 rtmap7_55).each do |policy|
|
|
560
|
+
config_no_warn("route-policy #{policy}", 'end-policy')
|
|
561
|
+
end
|
|
562
|
+
end
|
|
563
|
+
should = master.map { |network, rm| [network, rm.nil? ? nil : "#{rm}_55"] }
|
|
930
564
|
af.networks = should
|
|
931
565
|
result = af.networks
|
|
932
566
|
assert_equal(should.sort, result.sort,
|
|
@@ -938,6 +572,12 @@ class TestBgpAF < CiscoTestCase
|
|
|
938
572
|
result = af.networks
|
|
939
573
|
assert_equal(should.sort, result.sort,
|
|
940
574
|
"#{dbg} Test 5. 'Default'")
|
|
575
|
+
return unless platform == :ios_xr
|
|
576
|
+
%w(rtmap1 rtmap2 rtmap3 rtmap5 rtmap6 rtmap7
|
|
577
|
+
rtmap1_55 rtmap2_55 rtmap3_55
|
|
578
|
+
rtmap5_55 rtmap6_55 rtmap7_55).each do |policy|
|
|
579
|
+
config("no route-policy #{policy}")
|
|
580
|
+
end
|
|
941
581
|
end
|
|
942
582
|
|
|
943
583
|
##
|
|
@@ -950,8 +590,10 @@ class TestBgpAF < CiscoTestCase
|
|
|
950
590
|
vrfs.each do |vrf|
|
|
951
591
|
afs.each do |af|
|
|
952
592
|
dbg = sprintf('[VRF %s AF %s]', vrf, af.join('/'))
|
|
593
|
+
config_ios_xr_dependencies(1)
|
|
953
594
|
af = RouterBgpAF.new(1, vrf, af)
|
|
954
595
|
redistribute_cmd(af, dbg)
|
|
596
|
+
af.destroy
|
|
955
597
|
end
|
|
956
598
|
end
|
|
957
599
|
end
|
|
@@ -960,13 +602,22 @@ class TestBgpAF < CiscoTestCase
|
|
|
960
602
|
# rubocop:disable Style/WordArray
|
|
961
603
|
# Initial 'should' state
|
|
962
604
|
ospf = (dbg.include? 'ipv6') ? 'ospfv3 3' : 'ospf 3'
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
605
|
+
if platform == :nexus
|
|
606
|
+
master = [['direct', 'rm_direct'],
|
|
607
|
+
['lisp', 'rm_lisp'],
|
|
608
|
+
['static', 'rm_static'],
|
|
609
|
+
['eigrp 1', 'rm_eigrp'],
|
|
610
|
+
['isis 2', 'rm_isis'],
|
|
611
|
+
[ospf, 'rm_ospf'],
|
|
612
|
+
['rip 4', 'rm_rip']]
|
|
613
|
+
elsif platform == :ios_xr
|
|
614
|
+
config_no_warn('route-policy my_policy', 'end-policy')
|
|
615
|
+
master = [['connected', 'my_policy'],
|
|
616
|
+
['eigrp 1', 'my_policy'],
|
|
617
|
+
[ospf, 'my_policy'],
|
|
618
|
+
['static', 'my_policy']]
|
|
619
|
+
master.push(['isis abc', 'my_policy']) if dbg.include? 'default'
|
|
620
|
+
end
|
|
970
621
|
# rubocop:enable Style/WordArray
|
|
971
622
|
|
|
972
623
|
# Test: Add all protocols w/route-maps when no cmds are present
|
|
@@ -991,6 +642,9 @@ class TestBgpAF < CiscoTestCase
|
|
|
991
642
|
"#{dbg} Test 3. Restore the removed protocols")
|
|
992
643
|
|
|
993
644
|
# Test: Change route-maps on existing commands
|
|
645
|
+
if platform == :ios_xr
|
|
646
|
+
config_no_warn('route-policy my_policy_2', 'end-policy')
|
|
647
|
+
end
|
|
994
648
|
should = master.map { |prot_only, rm| [prot_only, "#{rm}_2"] }
|
|
995
649
|
af.redistribute = should
|
|
996
650
|
result = af.redistribute
|
|
@@ -1003,6 +657,10 @@ class TestBgpAF < CiscoTestCase
|
|
|
1003
657
|
result = af.redistribute
|
|
1004
658
|
assert_equal(should.sort, result.sort,
|
|
1005
659
|
"#{dbg} Test 5. 'Default'")
|
|
660
|
+
return unless platform == :ios_xr
|
|
661
|
+
%w(my_policy my_policy_2).each do |policy|
|
|
662
|
+
config("no route-policy #{policy}")
|
|
663
|
+
end
|
|
1006
664
|
end
|
|
1007
665
|
|
|
1008
666
|
##
|
|
@@ -1099,36 +757,36 @@ class TestBgpAF < CiscoTestCase
|
|
|
1099
757
|
assert_equal(expected, result, 'Test 5. delta mismatch')
|
|
1100
758
|
end
|
|
1101
759
|
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
def suppress_inactive(asn, vrf, af)
|
|
1106
|
-
bgp_af = RouterBgpAF.new(asn, vrf, af)
|
|
760
|
+
def test_respond_to?
|
|
761
|
+
config_ios_xr_dependencies('22')
|
|
762
|
+
bgp_af = RouterBgpAF.new('22', 'red', %w(ipv4 unicast))
|
|
1107
763
|
|
|
1108
|
-
#
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
bgp_af.suppress_inactive = val
|
|
1113
|
-
refute(bgp_af.suppress_inactive,
|
|
1114
|
-
'Error: suppress inactive value does not match set value')
|
|
764
|
+
# Functions that are actually defined in bgp_af.rb
|
|
765
|
+
assert_respond_to(bgp_af, :dampening_max_suppress_time)
|
|
766
|
+
assert_respond_to(bgp_af, :next_hop_route_map=)
|
|
767
|
+
assert_respond_to(bgp_af, :default_additional_paths_selection)
|
|
1115
768
|
|
|
1116
|
-
|
|
1117
|
-
bgp_af
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
end
|
|
1126
|
-
|
|
1127
|
-
def test_suppress_inactive
|
|
1128
|
-
afs = [%w(ipv4 unicast), %w(ipv6 unicast)]
|
|
1129
|
-
afs.each do |af|
|
|
1130
|
-
suppress_inactive(55, 'red', af)
|
|
769
|
+
# Functions that are covered by the method_missing magic
|
|
770
|
+
assert_respond_to(bgp_af, :next_hop_route_map)
|
|
771
|
+
assert_respond_to(bgp_af, :additional_paths_selection)
|
|
772
|
+
assert_respond_to(bgp_af, :default_default_information_originate)
|
|
773
|
+
if platform == :ios_xr
|
|
774
|
+
# not supported
|
|
775
|
+
refute_respond_to(bgp_af, :default_information_originate=)
|
|
776
|
+
else
|
|
777
|
+
assert_respond_to(bgp_af, :default_information_originate=)
|
|
1131
778
|
end
|
|
779
|
+
assert_respond_to(bgp_af, :table_map)
|
|
780
|
+
assert_respond_to(bgp_af, :default_table_map)
|
|
781
|
+
|
|
782
|
+
# Functions that are explicitly excluded from method_missing
|
|
783
|
+
refute_respond_to(bgp_af, :table_map=)
|
|
784
|
+
refute_respond_to(bgp_af, :table_map_filter=)
|
|
785
|
+
|
|
786
|
+
# Functions that shouldn't be covered by method_missing
|
|
787
|
+
refute_respond_to(bgp_af, :default_next_hop_route_map=)
|
|
788
|
+
|
|
789
|
+
bgp_af.destroy
|
|
1132
790
|
end
|
|
1133
791
|
|
|
1134
792
|
##
|
|
@@ -1142,35 +800,44 @@ class TestBgpAF < CiscoTestCase
|
|
|
1142
800
|
#
|
|
1143
801
|
val = 'sjc'
|
|
1144
802
|
bgp_af.table_map_set(val)
|
|
1145
|
-
assert_equal(val, bgp_af.table_map
|
|
1146
|
-
'Error: default metric value does not match set value')
|
|
803
|
+
assert_equal(val, bgp_af.table_map)
|
|
1147
804
|
|
|
1148
805
|
val = bgp_af.default_table_map
|
|
1149
806
|
bgp_af.table_map_set(val)
|
|
1150
|
-
assert_equal(val, bgp_af.table_map
|
|
1151
|
-
|
|
1152
|
-
|
|
807
|
+
assert_equal(val, bgp_af.table_map)
|
|
808
|
+
|
|
809
|
+
if validate_property_excluded?('bgp_af', 'table_map_filter')
|
|
810
|
+
assert_raises(Cisco::UnsupportedError) do
|
|
811
|
+
bgp_af.table_map_set('sjc', true)
|
|
812
|
+
end
|
|
813
|
+
assert_nil(bgp_af.default_table_map_filter)
|
|
814
|
+
return
|
|
815
|
+
end
|
|
1153
816
|
|
|
1154
817
|
val = false
|
|
1155
818
|
bgp_af.table_map_set('sjc', val)
|
|
1156
|
-
refute(bgp_af.table_map_filter
|
|
1157
|
-
'Error: suppress inactive value does not match set value')
|
|
819
|
+
refute(bgp_af.table_map_filter)
|
|
1158
820
|
|
|
1159
821
|
val = true
|
|
1160
822
|
bgp_af.table_map_set('sjc', val)
|
|
1161
|
-
assert(bgp_af.table_map_filter
|
|
1162
|
-
'Error: suppress inactive value does not match set value')
|
|
823
|
+
assert(bgp_af.table_map_filter)
|
|
1163
824
|
|
|
1164
|
-
|
|
1165
|
-
bgp_af.table_map_set('sjc',
|
|
1166
|
-
|
|
1167
|
-
'Error: suppress inactive value does not match default value')
|
|
825
|
+
default = bgp_af.default_table_map_filter
|
|
826
|
+
bgp_af.table_map_set('sjc', default)
|
|
827
|
+
assert_equal(default, bgp_af.table_map_filter)
|
|
1168
828
|
end
|
|
1169
829
|
|
|
1170
830
|
def test_table_map
|
|
831
|
+
if platform == :ios_xr
|
|
832
|
+
config_no_warn('route-policy sjc', 'end-policy')
|
|
833
|
+
config_ios_xr_dependencies('55')
|
|
834
|
+
end
|
|
835
|
+
|
|
1171
836
|
afs = [%w(ipv4 unicast), %w(ipv6 unicast)]
|
|
1172
837
|
afs.each do |af|
|
|
1173
838
|
table_map(55, 'red', af)
|
|
1174
839
|
end
|
|
840
|
+
|
|
841
|
+
config('no route-policy sjc') if platform == :ios_xr
|
|
1175
842
|
end
|
|
1176
843
|
end
|