cisco_node_utils 1.1.0 → 1.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +2 -1
- data/CHANGELOG.md +126 -1
- data/README.md +19 -12
- data/Rakefile +1 -0
- data/bin/git/hooks/commit-msg/enforce_style +8 -0
- data/cisco_node_utils.gemspec +4 -3
- data/docs/README-develop-best-practices.md +127 -109
- data/docs/README-develop-node-utils-APIs.md +47 -39
- data/docs/template-router.rb +3 -7
- data/lib/.rubocop.yml +4 -4
- data/lib/cisco_node_utils.rb +1 -1
- data/lib/cisco_node_utils/aaa_authentication_login.rb +96 -0
- data/lib/cisco_node_utils/aaa_authentication_login_service.rb +133 -0
- data/lib/cisco_node_utils/aaa_authorization_service.rb +150 -0
- data/lib/cisco_node_utils/ace.rb +196 -0
- data/lib/cisco_node_utils/acl.rb +100 -0
- data/lib/cisco_node_utils/bgp.rb +301 -163
- data/lib/cisco_node_utils/bgp_af.rb +187 -19
- data/lib/cisco_node_utils/bgp_neighbor.rb +18 -33
- data/lib/cisco_node_utils/bgp_neighbor_af.rb +25 -48
- data/lib/cisco_node_utils/cisco_cmn_utils.rb +23 -4
- data/lib/cisco_node_utils/cmd_ref/README_YAML.md +593 -0
- data/lib/cisco_node_utils/cmd_ref/aaa_auth_login_service.yaml +22 -0
- data/lib/cisco_node_utils/cmd_ref/aaa_authentication_login.yaml +31 -0
- data/lib/cisco_node_utils/cmd_ref/aaa_authorization_service.yaml +22 -0
- data/lib/cisco_node_utils/cmd_ref/acl.yaml +43 -0
- data/lib/cisco_node_utils/cmd_ref/bgp.yaml +242 -0
- data/lib/cisco_node_utils/cmd_ref/bgp_af.yaml +164 -0
- data/lib/cisco_node_utils/cmd_ref/bgp_neighbor.yaml +131 -0
- data/lib/cisco_node_utils/cmd_ref/bgp_neighbor_af.yaml +179 -0
- data/lib/cisco_node_utils/cmd_ref/dnsclient.yaml +34 -0
- data/lib/cisco_node_utils/cmd_ref/evpn_vni.yaml +42 -0
- data/lib/cisco_node_utils/cmd_ref/fabricpath.yaml +172 -0
- data/lib/cisco_node_utils/cmd_ref/fabricpath_topology.yaml +35 -0
- data/lib/cisco_node_utils/cmd_ref/feature.yaml +42 -0
- data/lib/cisco_node_utils/cmd_ref/fex.yaml +9 -0
- data/lib/cisco_node_utils/cmd_ref/images.yaml +7 -0
- data/lib/cisco_node_utils/cmd_ref/interface.yaml +339 -0
- data/lib/cisco_node_utils/cmd_ref/interface_channel_group.yaml +28 -0
- data/lib/cisco_node_utils/cmd_ref/interface_ospf.yaml +61 -0
- data/lib/cisco_node_utils/cmd_ref/interface_portchannel.yaml +54 -0
- data/lib/cisco_node_utils/cmd_ref/interface_service_vni.yaml +32 -0
- data/lib/cisco_node_utils/cmd_ref/inventory.yaml +45 -0
- data/lib/cisco_node_utils/cmd_ref/memory.yaml +13 -0
- data/lib/cisco_node_utils/cmd_ref/ntp_config.yaml +7 -0
- data/lib/cisco_node_utils/cmd_ref/ntp_server.yaml +14 -0
- data/lib/cisco_node_utils/cmd_ref/ospf.yaml +74 -0
- data/lib/cisco_node_utils/cmd_ref/overlay_global.yaml +33 -0
- data/lib/cisco_node_utils/cmd_ref/pim.yaml +40 -0
- data/lib/cisco_node_utils/cmd_ref/portchannel_global.yaml +69 -0
- data/lib/cisco_node_utils/cmd_ref/radius_global.yaml +25 -0
- data/lib/cisco_node_utils/cmd_ref/radius_server.yaml +64 -0
- data/lib/cisco_node_utils/cmd_ref/radius_server_group.yaml +14 -0
- data/lib/cisco_node_utils/cmd_ref/show_system.yaml +5 -0
- data/lib/cisco_node_utils/cmd_ref/show_version.yaml +72 -0
- data/lib/cisco_node_utils/cmd_ref/snmp_community.yaml +23 -0
- data/lib/cisco_node_utils/cmd_ref/snmp_group.yaml +7 -0
- data/lib/cisco_node_utils/cmd_ref/snmp_notification_receiver.yaml +50 -0
- data/lib/cisco_node_utils/cmd_ref/snmp_server.yaml +51 -0
- data/lib/cisco_node_utils/cmd_ref/snmp_user.yaml +55 -0
- data/lib/cisco_node_utils/cmd_ref/snmpnotification.yaml +11 -0
- data/lib/cisco_node_utils/cmd_ref/syslog_server.yaml +18 -0
- data/lib/cisco_node_utils/cmd_ref/syslog_settings.yaml +7 -0
- data/lib/cisco_node_utils/cmd_ref/system.yaml +6 -0
- data/lib/cisco_node_utils/cmd_ref/tacacs_server.yaml +49 -0
- data/lib/cisco_node_utils/cmd_ref/tacacs_server_group.yaml +33 -0
- data/lib/cisco_node_utils/cmd_ref/tacacs_server_host.yaml +35 -0
- data/lib/cisco_node_utils/cmd_ref/vdc.yaml +38 -0
- data/lib/cisco_node_utils/cmd_ref/virtual_service.yaml +6 -0
- data/lib/cisco_node_utils/cmd_ref/vlan.yaml +56 -0
- data/lib/cisco_node_utils/cmd_ref/vni.yaml +76 -0
- data/lib/cisco_node_utils/cmd_ref/vpc.yaml +197 -0
- data/lib/cisco_node_utils/cmd_ref/vrf.yaml +88 -0
- data/lib/cisco_node_utils/cmd_ref/vtp.yaml +38 -0
- data/lib/cisco_node_utils/cmd_ref/vxlan_vtep.yaml +60 -0
- data/lib/cisco_node_utils/cmd_ref/vxlan_vtep_vni.yaml +39 -0
- data/lib/cisco_node_utils/cmd_ref/yum.yaml +13 -0
- data/lib/cisco_node_utils/command_reference.rb +359 -187
- data/lib/cisco_node_utils/configparser_lib.rb +1 -1
- data/lib/cisco_node_utils/dns_domain.rb +19 -5
- data/lib/cisco_node_utils/domain_name.rb +4 -8
- data/lib/cisco_node_utils/evpn_vni.rb +157 -0
- data/lib/cisco_node_utils/fabricpath_global.rb +388 -0
- data/lib/cisco_node_utils/fabricpath_topology.rb +150 -0
- data/lib/cisco_node_utils/feature.rb +111 -0
- data/lib/cisco_node_utils/interface.rb +390 -97
- data/lib/cisco_node_utils/interface_channel_group.rb +124 -0
- data/lib/cisco_node_utils/interface_ospf.rb +11 -34
- data/lib/cisco_node_utils/interface_portchannel.rb +157 -0
- data/lib/cisco_node_utils/interface_service_vni.rb +132 -0
- data/lib/cisco_node_utils/name_server.rb +1 -1
- data/lib/cisco_node_utils/node.rb +55 -249
- data/lib/cisco_node_utils/node_util.rb +5 -1
- data/lib/cisco_node_utils/ntp_config.rb +2 -2
- data/lib/cisco_node_utils/ntp_server.rb +14 -5
- data/lib/cisco_node_utils/overlay_global.rb +153 -0
- data/lib/cisco_node_utils/pim.rb +124 -0
- data/lib/cisco_node_utils/pim_group_list.rb +108 -0
- data/lib/cisco_node_utils/pim_rp_address.rb +102 -0
- data/lib/cisco_node_utils/platform.rb +8 -9
- data/lib/cisco_node_utils/portchannel_global.rb +277 -0
- data/lib/cisco_node_utils/radius_global.rb +9 -19
- data/lib/cisco_node_utils/radius_server.rb +31 -41
- data/lib/cisco_node_utils/radius_server_group.rb +117 -0
- data/lib/cisco_node_utils/router_ospf.rb +1 -1
- data/lib/cisco_node_utils/router_ospf_vrf.rb +14 -19
- data/lib/cisco_node_utils/snmp_notification_receiver.rb +158 -0
- data/lib/cisco_node_utils/snmpcommunity.rb +3 -5
- data/lib/cisco_node_utils/snmpgroup.rb +1 -1
- data/lib/cisco_node_utils/snmpnotification.rb +57 -0
- data/lib/cisco_node_utils/snmpserver.rb +8 -17
- data/lib/cisco_node_utils/snmpuser.rb +67 -28
- data/lib/cisco_node_utils/syslog_server.rb +3 -9
- data/lib/cisco_node_utils/syslog_settings.rb +2 -10
- data/lib/cisco_node_utils/tacacs_server.rb +9 -14
- data/lib/cisco_node_utils/tacacs_server_group.rb +145 -0
- data/lib/cisco_node_utils/tacacs_server_host.rb +5 -9
- data/lib/cisco_node_utils/vdc.rb +88 -0
- data/lib/cisco_node_utils/version.rb +5 -2
- data/lib/cisco_node_utils/vlan.rb +71 -8
- data/lib/cisco_node_utils/vni.rb +227 -0
- data/lib/cisco_node_utils/vpc.rb +377 -0
- data/lib/cisco_node_utils/vrf.rb +60 -9
- data/lib/cisco_node_utils/vrf_af.rb +191 -0
- data/lib/cisco_node_utils/vtp.rb +8 -6
- data/lib/cisco_node_utils/vxlan_vtep.rb +151 -0
- data/lib/cisco_node_utils/vxlan_vtep_vni.rb +234 -0
- data/lib/cisco_node_utils/yum.rb +1 -1
- data/tests/.rubocop.yml +1 -1
- data/tests/basetest.rb +16 -7
- data/tests/ciscotest.rb +55 -13
- data/tests/cmd_config.yaml +2 -2
- data/tests/platform_info.rb +3 -2
- data/tests/test_aaa_authentication_login.rb +219 -0
- data/tests/test_aaa_authentication_login_service.rb +759 -0
- data/tests/test_aaa_authorization_service.rb +1041 -0
- data/tests/test_ace.rb +160 -0
- data/tests/test_acl.rb +176 -0
- data/tests/test_bgp_af.rb +269 -13
- data/tests/test_bgp_neighbor.rb +38 -40
- data/tests/test_bgp_neighbor_af.rb +92 -32
- data/tests/test_command_config.rb +5 -5
- data/tests/test_command_reference.rb +284 -101
- data/tests/test_dns_domain.rb +1 -1
- data/tests/test_domain_name.rb +1 -1
- data/tests/test_evpn_vni.rb +106 -0
- data/tests/test_fabricpath_global.rb +243 -0
- data/tests/test_fabricpath_topology.rb +98 -0
- data/tests/test_interface.rb +292 -74
- data/tests/test_interface_channel_group.rb +74 -0
- data/tests/test_interface_ospf.rb +9 -4
- data/tests/test_interface_portchannel.rb +105 -0
- data/tests/test_interface_service_vni.rb +232 -0
- data/tests/test_interface_svi.rb +77 -62
- data/tests/test_interface_switchport.rb +17 -5
- data/tests/test_name_server.rb +1 -1
- data/tests/test_node.rb +1 -1
- data/tests/test_node_ext.rb +10 -20
- data/tests/test_ntp_config.rb +1 -1
- data/tests/test_ntp_server.rb +18 -6
- data/tests/test_overlay_global.rb +102 -0
- data/tests/test_pim.rb +177 -0
- data/tests/test_pim_group_list.rb +181 -0
- data/tests/test_pim_rp_address.rb +153 -0
- data/tests/test_platform.rb +3 -3
- data/tests/test_portchannel_global.rb +202 -0
- data/tests/test_radius_global.rb +1 -1
- data/tests/test_radius_server.rb +92 -57
- data/tests/test_radius_server_group.rb +149 -0
- data/tests/test_router_bgp.rb +283 -112
- data/tests/test_router_ospf.rb +2 -2
- data/tests/test_router_ospf_vrf.rb +4 -4
- data/tests/test_snmp_notification_receiver.rb +167 -0
- data/tests/test_snmpcommunity.rb +1 -1
- data/tests/test_snmpgroup.rb +1 -1
- data/tests/test_snmpnotification.rb +72 -0
- data/tests/test_snmpserver.rb +29 -105
- data/tests/test_snmpuser.rb +32 -30
- data/tests/test_syslog_server.rb +36 -10
- data/tests/test_syslog_settings.rb +1 -1
- data/tests/test_tacacs_server.rb +1 -1
- data/tests/test_tacacs_server_group.rb +405 -0
- data/tests/test_tacacs_server_host.rb +1 -1
- data/tests/test_vdc.rb +78 -0
- data/tests/test_vlan.rb +74 -19
- data/tests/test_vlan_mt_full.rb +95 -0
- data/tests/test_vni.rb +106 -0
- data/tests/test_vpc.rb +361 -0
- data/tests/test_vrf.rb +172 -29
- data/tests/test_vtp.rb +1 -1
- data/tests/test_vxlan_vtep.rb +214 -0
- data/tests/test_vxlan_vtep_vni.rb +201 -0
- data/tests/test_yum.rb +1 -1
- metadata +120 -11
- data/lib/cisco_node_utils/README_YAML.md +0 -325
- data/lib/cisco_node_utils/command_reference_common.yaml +0 -1051
- data/lib/cisco_node_utils/command_reference_common_bgp.yaml +0 -535
- data/lib/cisco_node_utils/command_reference_n3064.yaml +0 -13
- data/lib/cisco_node_utils/command_reference_n7k.yaml +0 -52
- data/lib/cisco_node_utils/command_reference_n9k.yaml +0 -26
- data/tests/platform_info.yaml +0 -10
data/tests/test_ace.rb
ADDED
@@ -0,0 +1,160 @@
|
|
1
|
+
# Copyright (c) 2015-2016 Cisco and/or its affiliates.
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
#
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
|
15
|
+
require_relative 'ciscotest'
|
16
|
+
require_relative '../lib/cisco_node_utils/acl'
|
17
|
+
require_relative '../lib/cisco_node_utils/ace'
|
18
|
+
|
19
|
+
# TestAce - Minitest for Ace node utility class
|
20
|
+
class TestAce < CiscoTestCase
|
21
|
+
def setup
|
22
|
+
# setup runs at the beginning of each test
|
23
|
+
super
|
24
|
+
@acl_name_v4 = 'test-foo-v4-1'
|
25
|
+
@acl_name_v6 = 'test-foo-v6-1'
|
26
|
+
@seqno = 10
|
27
|
+
no_access_list_foo
|
28
|
+
end
|
29
|
+
|
30
|
+
def teardown
|
31
|
+
# teardown runs at the end of each test
|
32
|
+
no_access_list_foo
|
33
|
+
super
|
34
|
+
end
|
35
|
+
|
36
|
+
def no_access_list_foo
|
37
|
+
# Remove the test ACLs
|
38
|
+
%w(ipv4 ipv6).each do |afi|
|
39
|
+
acl_name = afi[/ipv6/] ? @acl_name_v6 : @acl_name_v4
|
40
|
+
config('no ' + Acl.afi_cli(afi) + ' access-list ' + acl_name)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
# TESTS
|
45
|
+
def test_create_destroy_ace_one
|
46
|
+
attr_v4_1 = {
|
47
|
+
action: 'permit',
|
48
|
+
proto: 'tcp',
|
49
|
+
src_addr: '7.8.9.6 2.3.4.5',
|
50
|
+
src_port: 'eq 40',
|
51
|
+
dst_addr: '1.2.3.4/32',
|
52
|
+
dst_port: 'neq 20',
|
53
|
+
}
|
54
|
+
|
55
|
+
attr_v4_2 = {
|
56
|
+
action: 'deny',
|
57
|
+
proto: 'udp',
|
58
|
+
src_addr: '7.8.9.6/32',
|
59
|
+
src_port: 'eq 41',
|
60
|
+
dst_addr: 'host 1.2.3.4',
|
61
|
+
dst_port: 'neq 20',
|
62
|
+
}
|
63
|
+
|
64
|
+
attr_v4_3 = {
|
65
|
+
remark: 'ipv4 remark'
|
66
|
+
}
|
67
|
+
|
68
|
+
attr_v6_1 = {
|
69
|
+
action: 'permit',
|
70
|
+
proto: '6',
|
71
|
+
src_addr: 'addrgroup fi',
|
72
|
+
src_port: '',
|
73
|
+
dst_addr: '1::7/32',
|
74
|
+
dst_port: '',
|
75
|
+
}
|
76
|
+
|
77
|
+
attr_v6_2 = {
|
78
|
+
action: 'permit',
|
79
|
+
proto: 'udp',
|
80
|
+
src_addr: '1::8/56',
|
81
|
+
src_port: 'eq 41',
|
82
|
+
dst_addr: 'any',
|
83
|
+
dst_port: '',
|
84
|
+
}
|
85
|
+
|
86
|
+
attr_v6_3 = {
|
87
|
+
remark: 'ipv6 remark'
|
88
|
+
}
|
89
|
+
|
90
|
+
props = {
|
91
|
+
'ipv4' => [attr_v4_1, attr_v4_2, attr_v4_3],
|
92
|
+
'ipv6' => [attr_v6_1, attr_v6_2, attr_v6_3],
|
93
|
+
}
|
94
|
+
|
95
|
+
%w(ipv4 ipv6).each do |afi|
|
96
|
+
@seqno = 0
|
97
|
+
props[afi].each do |item|
|
98
|
+
create_destroy_ace(afi, item)
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
def create_destroy_ace(afi, entry)
|
104
|
+
acl_name = @acl_name_v4 if afi[/(ip|ipv4)$/]
|
105
|
+
acl_name = @acl_name_v6 if afi[/ipv6/]
|
106
|
+
@seqno += 10
|
107
|
+
|
108
|
+
Acl.new(afi, acl_name)
|
109
|
+
ace = Ace.new(afi, acl_name, @seqno)
|
110
|
+
ace.ace_set(entry)
|
111
|
+
|
112
|
+
afi_cli = Acl.afi_cli(afi)
|
113
|
+
all_aces = Ace.aces
|
114
|
+
found = false
|
115
|
+
all_aces[afi][acl_name].each do |seqno, _inst|
|
116
|
+
next unless seqno.to_i == @seqno.to_i
|
117
|
+
found = true
|
118
|
+
end
|
119
|
+
|
120
|
+
@default_show_command =
|
121
|
+
"show runn aclmgr | sec '#{afi_cli} access-list #{acl_name}'"
|
122
|
+
assert(found,
|
123
|
+
"#{afi_cli} acl #{acl_name} seqno #{@seqno} is not configured")
|
124
|
+
|
125
|
+
if entry.include?(:action)
|
126
|
+
action = "#{entry[:action]} .*"
|
127
|
+
else
|
128
|
+
action = "remark #{entry[:remark]}"
|
129
|
+
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
|
+
end
|
136
|
+
|
137
|
+
def test_ace_update
|
138
|
+
action = 'permit'
|
139
|
+
proto = 'tcp'
|
140
|
+
src = '1.0.0.0/8'
|
141
|
+
dst = '3.0.0.0 0.0.0.8'
|
142
|
+
entry = { action: action, proto: proto, src_addr: src, dst_addr: dst }
|
143
|
+
|
144
|
+
a = Ace.new('ipv4', 'ace_update', 10)
|
145
|
+
a.ace_set(entry)
|
146
|
+
|
147
|
+
assert_equal(src, a.src_addr)
|
148
|
+
assert_equal(dst, a.dst_addr)
|
149
|
+
|
150
|
+
src = '2.0.0.0/16'
|
151
|
+
entry = { action: action, proto: proto, src_addr: src, dst_addr: dst }
|
152
|
+
a.ace_set(entry)
|
153
|
+
assert_equal(src, a.src_addr)
|
154
|
+
|
155
|
+
dst = '3.0.0.0 0.0.0.4'
|
156
|
+
entry = { action: action, proto: proto, src_addr: src, dst_addr: dst }
|
157
|
+
a.ace_set(entry)
|
158
|
+
assert_equal(dst, a.dst_addr)
|
159
|
+
end
|
160
|
+
end
|
data/tests/test_acl.rb
ADDED
@@ -0,0 +1,176 @@
|
|
1
|
+
# Copyright (c) 2014-2016 Cisco and/or its affiliates.
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
#
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
|
15
|
+
require_relative 'ciscotest'
|
16
|
+
require_relative '../lib/cisco_node_utils/acl'
|
17
|
+
|
18
|
+
# test client for acl creation and deletion
|
19
|
+
class TestAcl < CiscoTestCase
|
20
|
+
def setup
|
21
|
+
# setup runs at the beginning of each test
|
22
|
+
super
|
23
|
+
@acl_name_v4 = 'test-foo-v4-1'
|
24
|
+
@acl_name_v6 = 'test-foo-v6-1'
|
25
|
+
@permit = 'permit-all'
|
26
|
+
@deny = 'deny-all'
|
27
|
+
no_access_list_foo
|
28
|
+
end
|
29
|
+
|
30
|
+
def teardown
|
31
|
+
# teardown runs at the end of each test
|
32
|
+
no_access_list_foo
|
33
|
+
super
|
34
|
+
end
|
35
|
+
|
36
|
+
def no_access_list_foo
|
37
|
+
# Remove the test ACLs
|
38
|
+
%w(ipv4 ipv6).each do |afi|
|
39
|
+
acl_name = afi[/ipv6/] ? @acl_name_v6 : @acl_name_v4
|
40
|
+
config('no ' + Acl.afi_cli(afi) + ' access-list ' + acl_name)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
# TESTS
|
45
|
+
def create_acl(afi, acl_name)
|
46
|
+
rtr = Acl.new(afi, acl_name)
|
47
|
+
afi_cli = Acl.afi_cli(afi)
|
48
|
+
|
49
|
+
assert(Acl.acls[afi].key?(acl_name),
|
50
|
+
"ACL #{afi_cli} #{acl_name} is not configured")
|
51
|
+
|
52
|
+
@default_show_command =
|
53
|
+
"show runn aclmgr | i '#{afi_cli} access-list #{acl_name}'"
|
54
|
+
assert_show_match(pattern: /^#{afi_cli} access-list #{acl_name}$/,
|
55
|
+
msg: "failed to create acl '#{afi_cli} #{acl_name}'")
|
56
|
+
rtr.destroy
|
57
|
+
refute_show_match(pattern: /^#{afi} access-list #{acl_name}$/,
|
58
|
+
msg: "failed to destroy acl '#{afi_cli} #{acl_name}")
|
59
|
+
end
|
60
|
+
|
61
|
+
def test_create_acl
|
62
|
+
%w(ipv4 ipv6).each do |afi|
|
63
|
+
acl_name = afi[/ipv6/] ? @acl_name_v6 : @acl_name_v4
|
64
|
+
create_acl(afi, acl_name)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def stats_enable(afi, acl_name)
|
69
|
+
rtr = Acl.new(afi, acl_name)
|
70
|
+
afi_cli = Acl.afi_cli(afi)
|
71
|
+
|
72
|
+
@default_show_command =
|
73
|
+
"show runn aclmgr | sec '#{afi_cli} access-list #{acl_name}'"
|
74
|
+
assert_show_match(pattern: /^#{afi_cli} access-list #{acl_name}$/,
|
75
|
+
msg: "failed to create acl #{acl_name}")
|
76
|
+
|
77
|
+
# set to true
|
78
|
+
rtr.stats_per_entry = true
|
79
|
+
assert_show_match(pattern: /statistics per-entry/,
|
80
|
+
msg: 'failed to enable stats')
|
81
|
+
|
82
|
+
assert(rtr.stats_per_entry)
|
83
|
+
|
84
|
+
# set to false
|
85
|
+
rtr.stats_per_entry = false
|
86
|
+
refute_show_match(pattern: /statistics per-entry/,
|
87
|
+
msg: 'failed to disnable stats')
|
88
|
+
refute(rtr.stats_per_entry)
|
89
|
+
|
90
|
+
# default getter function
|
91
|
+
refute(rtr.default_stats_per_entry)
|
92
|
+
|
93
|
+
rtr.destroy
|
94
|
+
refute_show_match(pattern: /^#{afi_cli} access-list #{acl_name}$/,
|
95
|
+
msg: "failed to destroy acl #{acl_name}")
|
96
|
+
end
|
97
|
+
|
98
|
+
def test_stats_enable
|
99
|
+
%w(ipv4 ipv6).each do |afi|
|
100
|
+
acl_name = afi[/ipv6/] ? @acl_name_v6 : @acl_name_v4
|
101
|
+
stats_enable(afi, acl_name)
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
def set_fragments(rtr, afi, acl_name, option)
|
106
|
+
afi_cli = Acl.afi_cli(afi)
|
107
|
+
@default_show_command =
|
108
|
+
"show runn aclmgr | sec '#{afi_cli} access-list #{acl_name}'"
|
109
|
+
|
110
|
+
# setter function
|
111
|
+
rtr.fragments = option
|
112
|
+
assert_show_match(pattern: /fragments #{option}/,
|
113
|
+
msg: 'failed to set fragments #{option} ' + option)
|
114
|
+
|
115
|
+
# getter function
|
116
|
+
assert_equal(option, rtr.fragments)
|
117
|
+
end
|
118
|
+
|
119
|
+
def unset_fragments(rtr, afi, acl_name)
|
120
|
+
afi_cli = Acl.afi_cli(afi)
|
121
|
+
@default_show_command =
|
122
|
+
"show runn aclmgr | sec '#{afi_cli} access-list #{acl_name}'"
|
123
|
+
|
124
|
+
# setter function
|
125
|
+
rtr.fragments = nil
|
126
|
+
refute_show_match(pattern: /fragments #{@permit}|fragments #{@deny}/,
|
127
|
+
msg: 'failed to unset set fragments')
|
128
|
+
|
129
|
+
# getter function
|
130
|
+
val = rtr.fragments
|
131
|
+
assert_nil(val)
|
132
|
+
end
|
133
|
+
|
134
|
+
def fragments(afi, acl_name)
|
135
|
+
rtr = Acl.new(afi, acl_name)
|
136
|
+
afi_cli = Acl.afi_cli(afi)
|
137
|
+
|
138
|
+
@default_show_command =
|
139
|
+
"show runn aclmgr | sec '#{afi_cli} access-list #{acl_name}'"
|
140
|
+
assert_show_match(pattern: /^#{afi_cli} access-list #{acl_name}$/,
|
141
|
+
msg: "failed to create acl #{acl_name}")
|
142
|
+
|
143
|
+
# set 'no fragments ...'
|
144
|
+
unset_fragments(rtr, afi, acl_name)
|
145
|
+
|
146
|
+
# set 'fragments permit-all' from nothing set
|
147
|
+
set_fragments(rtr, afi, acl_name, @permit)
|
148
|
+
|
149
|
+
# set 'no fragments ...'
|
150
|
+
unset_fragments(rtr, afi, acl_name)
|
151
|
+
|
152
|
+
# set 'fragments deny-all' from nothing set
|
153
|
+
set_fragments(rtr, afi, acl_name, @deny)
|
154
|
+
|
155
|
+
# set 'fragments permit-all' from 'fragments deny-all'
|
156
|
+
set_fragments(rtr, afi, acl_name, @permit)
|
157
|
+
|
158
|
+
# set 'fragments deny-all' from 'fragments permit-all'
|
159
|
+
set_fragments(rtr, afi, acl_name, @deny)
|
160
|
+
|
161
|
+
# default getter function
|
162
|
+
val = rtr.default_stats_per_entry
|
163
|
+
refute_equal(val, nil, 'value is not nil')
|
164
|
+
|
165
|
+
rtr.destroy
|
166
|
+
refute_show_match(pattern: /^#{afi_cli} access-list #{acl_name}$/,
|
167
|
+
msg: "failed to destroy acl #{acl_name}")
|
168
|
+
end
|
169
|
+
|
170
|
+
def test_fragments
|
171
|
+
%w(ipv4 ipv6).each do |afi|
|
172
|
+
acl_name = afi[/ipv6/] ? @acl_name_v6 : @acl_name_v4
|
173
|
+
fragments(afi, acl_name)
|
174
|
+
end
|
175
|
+
end
|
176
|
+
end
|
data/tests/test_bgp_af.rb
CHANGED
@@ -4,7 +4,7 @@
|
|
4
4
|
#
|
5
5
|
# Richard Wellum, August, 2015
|
6
6
|
#
|
7
|
-
# Copyright (c) 2015 Cisco and/or its affiliates.
|
7
|
+
# Copyright (c) 2015-2016 Cisco and/or its affiliates.
|
8
8
|
#
|
9
9
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
10
10
|
# you may not use this file except in compliance with the License.
|
@@ -21,14 +21,21 @@
|
|
21
21
|
require_relative 'ciscotest'
|
22
22
|
require_relative '../lib/cisco_node_utils/bgp'
|
23
23
|
require_relative '../lib/cisco_node_utils/bgp_af'
|
24
|
+
require_relative '../lib/cisco_node_utils/feature'
|
25
|
+
|
26
|
+
# TestBgpAF - Minitest for RouterBgpAF class
|
27
|
+
class TestBgpAF < CiscoTestCase
|
28
|
+
@@pre_clean_needed = true # rubocop:disable Style/ClassVars
|
24
29
|
|
25
|
-
# TestRouterBgpAF - Minitest for RouterBgpAF class
|
26
|
-
class TestRouterBgpAF < CiscoTestCase
|
27
30
|
def setup
|
28
31
|
super
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
+
remove_all_bgps if @@pre_clean_needed
|
33
|
+
@@pre_clean_needed = false # rubocop:disable Style/ClassVars
|
34
|
+
end
|
35
|
+
|
36
|
+
def teardown
|
37
|
+
super
|
38
|
+
remove_all_bgps
|
32
39
|
end
|
33
40
|
|
34
41
|
def get_bgp_af_cfg(asn, vrf, af)
|
@@ -67,6 +74,7 @@ class TestRouterBgpAF < CiscoTestCase
|
|
67
74
|
## BGP Address Family
|
68
75
|
## Configure router bgp, some VRF's and address-family statements
|
69
76
|
## - verify that the final instance objects are correctly populated
|
77
|
+
## Enable VXLAN and the EVPN
|
70
78
|
##
|
71
79
|
def test_collection_not_empty
|
72
80
|
config('feature bgp',
|
@@ -156,16 +164,9 @@ class TestRouterBgpAF < CiscoTestCase
|
|
156
164
|
af = %w(ipv4 unicast)
|
157
165
|
|
158
166
|
bgp_af = RouterBgpAF.new(asn, vrf, af)
|
159
|
-
pattern = /^ *client-to-client reflection$/
|
160
167
|
#
|
161
168
|
# Default is 'client-to-client' is configured
|
162
169
|
#
|
163
|
-
af_string = get_bgp_af_cfg(asn, vrf, af)
|
164
|
-
|
165
|
-
assert_match(pattern, af_string,
|
166
|
-
"Error: 'client-to-client reflection' is not configured " \
|
167
|
-
'and should be')
|
168
|
-
|
169
170
|
assert(bgp_af.client_to_client,
|
170
171
|
"Error: 'client-to-client is not configured but should be")
|
171
172
|
#
|
@@ -348,6 +349,39 @@ class TestRouterBgpAF < CiscoTestCase
|
|
348
349
|
'configured and should not be')
|
349
350
|
end
|
350
351
|
|
352
|
+
##
|
353
|
+
## advertise_l2vpn_evpn
|
354
|
+
##
|
355
|
+
def advertise_l2vpn_evpn(asn, vrf, af)
|
356
|
+
bgp_af = RouterBgpAF.new(asn, vrf, af)
|
357
|
+
|
358
|
+
#
|
359
|
+
# Set and verify
|
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')
|
365
|
+
|
366
|
+
val = true
|
367
|
+
bgp_af.advertise_l2vpn_evpn = val
|
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
|
377
|
+
|
378
|
+
def test_advertise_l2vpn_evpn
|
379
|
+
afs = [%w(ipv4 unicast), %w(ipv6 unicast)]
|
380
|
+
afs.each do |af|
|
381
|
+
advertise_l2vpn_evpn(55, 'red', af)
|
382
|
+
end
|
383
|
+
end
|
384
|
+
|
351
385
|
##
|
352
386
|
## get_dampen_igp_metric
|
353
387
|
##
|
@@ -639,6 +673,112 @@ class TestRouterBgpAF < CiscoTestCase
|
|
639
673
|
end
|
640
674
|
# rubocop:enable Metrics/AbcSize,Metrics/MethodLength
|
641
675
|
|
676
|
+
##
|
677
|
+
## distance
|
678
|
+
##
|
679
|
+
def test_distance
|
680
|
+
asn = '55'
|
681
|
+
vrf = 'red'
|
682
|
+
af = %w(ipv4 unicast)
|
683
|
+
|
684
|
+
bgp_af = RouterBgpAF.new(asn, vrf, af)
|
685
|
+
distance = [{ ebgp: 20, ibgp: 40, local: 60 },
|
686
|
+
{ ebgp: bgp_af.default_distance_ebgp,
|
687
|
+
ibgp: bgp_af.default_distance_ibgp,
|
688
|
+
local: bgp_af.default_distance_local },
|
689
|
+
{ ebgp: bgp_af.default_distance_ebgp,
|
690
|
+
ibgp: 40,
|
691
|
+
local: 60 },
|
692
|
+
{ ebgp: 20,
|
693
|
+
ibgp: bgp_af.default_distance_ibgp,
|
694
|
+
local: bgp_af.default_distance_local },
|
695
|
+
{ ebgp: bgp_af.default_distance_ebgp,
|
696
|
+
ibgp: bgp_af.default_distance_ibgp,
|
697
|
+
local: 60 },
|
698
|
+
]
|
699
|
+
distance.each do |distancer|
|
700
|
+
bgp_af.distance_set(distancer[:ebgp], distancer[:ibgp], distancer[:local])
|
701
|
+
assert_equal(distancer[:ebgp], bgp_af.distance_ebgp)
|
702
|
+
assert_equal(distancer[:ibgp], bgp_af.distance_ibgp)
|
703
|
+
assert_equal(distancer[:local], bgp_af.distance_local)
|
704
|
+
end
|
705
|
+
bgp_af.destroy
|
706
|
+
end
|
707
|
+
|
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
|
+
|
642
782
|
##
|
643
783
|
## maximum_paths
|
644
784
|
##
|
@@ -868,6 +1008,47 @@ class TestRouterBgpAF < CiscoTestCase
|
|
868
1008
|
##
|
869
1009
|
## common utilities
|
870
1010
|
##
|
1011
|
+
def test_utils_delta_add_remove_depth_1
|
1012
|
+
# Note: AF context is not needed. This test is only validating the
|
1013
|
+
# delta_add_remove class method and does not test directly on the device.
|
1014
|
+
|
1015
|
+
# Initial 'should' state
|
1016
|
+
should = ['1:1', '2:2', '3:3', '4:4', '5:5', '6:6']
|
1017
|
+
# rubocop:enable Style/WordArray
|
1018
|
+
|
1019
|
+
# Test: Check delta when every protocol is specified and has a route-map.
|
1020
|
+
current = []
|
1021
|
+
expected = { add: should, remove: [] }
|
1022
|
+
result = Utils.delta_add_remove(should, current)
|
1023
|
+
assert_equal(expected, result, 'Test 1. delta mismatch')
|
1024
|
+
|
1025
|
+
# Test: Check delta when should is the same as current.
|
1026
|
+
current = should.clone
|
1027
|
+
expected = { add: [], remove: [] }
|
1028
|
+
result = Utils.delta_add_remove(should, current)
|
1029
|
+
assert_equal(expected, result, 'Test 2. delta mismatch')
|
1030
|
+
|
1031
|
+
# Test: Move half the 'current' entries to 'should'. Check delta.
|
1032
|
+
should = current.shift(4)
|
1033
|
+
expected = { add: should, remove: current }
|
1034
|
+
result = Utils.delta_add_remove(should, current)
|
1035
|
+
assert_equal(expected, result, 'Test 3. delta mismatch')
|
1036
|
+
|
1037
|
+
# Test: Remove the route-maps from the current list. Check delta.
|
1038
|
+
# Note: The :remove list should be empty since this is just
|
1039
|
+
# an update of the route-map.
|
1040
|
+
should = current.map { |prot_only, _route_map| [prot_only] }
|
1041
|
+
expected = { add: should, remove: [] }
|
1042
|
+
result = Utils.delta_add_remove(should, current)
|
1043
|
+
assert_equal(expected, result, 'Test 4. delta mismatch')
|
1044
|
+
|
1045
|
+
# Test: Check empty inputs
|
1046
|
+
should = []
|
1047
|
+
current = []
|
1048
|
+
expected = { add: [], remove: [] }
|
1049
|
+
result = Utils.delta_add_remove(should, current)
|
1050
|
+
assert_equal(expected, result, 'Test 5. delta mismatch')
|
1051
|
+
end
|
871
1052
|
|
872
1053
|
def test_utils_delta_add_remove
|
873
1054
|
# Note: AF context is not needed. This test is only validating the
|
@@ -917,4 +1098,79 @@ class TestRouterBgpAF < CiscoTestCase
|
|
917
1098
|
result = Utils.delta_add_remove(should, current)
|
918
1099
|
assert_equal(expected, result, 'Test 5. delta mismatch')
|
919
1100
|
end
|
1101
|
+
|
1102
|
+
##
|
1103
|
+
## suppress_inactive
|
1104
|
+
##
|
1105
|
+
def suppress_inactive(asn, vrf, af)
|
1106
|
+
bgp_af = RouterBgpAF.new(asn, vrf, af)
|
1107
|
+
|
1108
|
+
#
|
1109
|
+
# Set and verify
|
1110
|
+
#
|
1111
|
+
val = false
|
1112
|
+
bgp_af.suppress_inactive = val
|
1113
|
+
refute(bgp_af.suppress_inactive,
|
1114
|
+
'Error: suppress inactive value does not match set value')
|
1115
|
+
|
1116
|
+
val = true
|
1117
|
+
bgp_af.suppress_inactive = val
|
1118
|
+
assert(bgp_af.suppress_inactive,
|
1119
|
+
'Error: suppress inactive value does not match set value')
|
1120
|
+
|
1121
|
+
val = bgp_af.default_suppress_inactive
|
1122
|
+
bgp_af.suppress_inactive = val
|
1123
|
+
refute(bgp_af.suppress_inactive,
|
1124
|
+
'Error: suppress inactive value does not match default value')
|
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)
|
1131
|
+
end
|
1132
|
+
end
|
1133
|
+
|
1134
|
+
##
|
1135
|
+
## table_map
|
1136
|
+
##
|
1137
|
+
def table_map(asn, vrf, af)
|
1138
|
+
bgp_af = RouterBgpAF.new(asn, vrf, af)
|
1139
|
+
|
1140
|
+
#
|
1141
|
+
# Set and verify
|
1142
|
+
#
|
1143
|
+
val = 'sjc'
|
1144
|
+
bgp_af.table_map_set(val)
|
1145
|
+
assert_equal(val, bgp_af.table_map,
|
1146
|
+
'Error: default metric value does not match set value')
|
1147
|
+
|
1148
|
+
val = bgp_af.default_table_map
|
1149
|
+
bgp_af.table_map_set(val)
|
1150
|
+
assert_equal(val, bgp_af.table_map,
|
1151
|
+
'Error: default metric value does not match default' \
|
1152
|
+
'value')
|
1153
|
+
|
1154
|
+
val = false
|
1155
|
+
bgp_af.table_map_set('sjc', val)
|
1156
|
+
refute(bgp_af.table_map_filter,
|
1157
|
+
'Error: suppress inactive value does not match set value')
|
1158
|
+
|
1159
|
+
val = true
|
1160
|
+
bgp_af.table_map_set('sjc', val)
|
1161
|
+
assert(bgp_af.table_map_filter,
|
1162
|
+
'Error: suppress inactive value does not match set value')
|
1163
|
+
|
1164
|
+
val = bgp_af.default_table_map_filter
|
1165
|
+
bgp_af.table_map_set('sjc', val)
|
1166
|
+
refute(bgp_af.table_map_filter,
|
1167
|
+
'Error: suppress inactive value does not match default value')
|
1168
|
+
end
|
1169
|
+
|
1170
|
+
def test_table_map
|
1171
|
+
afs = [%w(ipv4 unicast), %w(ipv6 unicast)]
|
1172
|
+
afs.each do |af|
|
1173
|
+
table_map(55, 'red', af)
|
1174
|
+
end
|
1175
|
+
end
|
920
1176
|
end
|