cisco_node_utils_mgx 2.1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +10 -0
- data/.rspec +2 -0
- data/.rubocop.yml +96 -0
- data/.travis.yml +17 -0
- data/CHANGELOG.md +676 -0
- data/CONTRIBUTING.md +43 -0
- data/Gemfile +10 -0
- data/LICENSE +201 -0
- data/README.md +246 -0
- data/Rakefile +44 -0
- data/SUPPORT.md +3 -0
- data/bin/.rubocop.yml +18 -0
- data/bin/check_metric_limits.rb +109 -0
- data/bin/git/hooks/commit-msg/enforce_style +89 -0
- data/bin/git/hooks/hook_lib +115 -0
- data/bin/git/hooks/hooks-wrapper +38 -0
- data/bin/git/hooks/post-flow-hotfix-start/update-version +24 -0
- data/bin/git/hooks/post-flow-release-finish/update-version +29 -0
- data/bin/git/hooks/post-flow-release-start/update-version +19 -0
- data/bin/git/hooks/post-merge/update-hooks +6 -0
- data/bin/git/hooks/post-rewrite/update-hooks +6 -0
- data/bin/git/hooks/pre-commit/check_unstaged_changes +18 -0
- data/bin/git/hooks/pre-commit/rubocop +25 -0
- data/bin/git/hooks/pre-commit/validate-diffs +45 -0
- data/bin/git/hooks/pre-commit/validate-yaml +18 -0
- data/bin/git/hooks/pre-push/check-changelog +24 -0
- data/bin/git/hooks/pre-push/rubocop +7 -0
- data/bin/git/update-hooks +123 -0
- data/bin/show_running_yang.rb +233 -0
- data/cisco_node_utils.gemspec +41 -0
- data/docs/README-develop-best-practices.md +521 -0
- data/docs/README-develop-node-utils-APIs.md +570 -0
- data/docs/README-maintainers.md +77 -0
- data/docs/README-test-execution.md +57 -0
- data/docs/README-utilities.md +14 -0
- data/docs/agent_files.png +0 -0
- data/docs/cisco_node_utils.yaml.example +36 -0
- data/docs/template-router.rb +123 -0
- data/docs/template-test_router.rb +104 -0
- data/ext/mkrf_conf.rb +63 -0
- data/lib/.rubocop.yml +18 -0
- data/lib/cisco_node_utils/aaa_authentication_login.rb +95 -0
- data/lib/cisco_node_utils/aaa_authentication_login_service.rb +138 -0
- data/lib/cisco_node_utils/aaa_authorization_service.rb +156 -0
- data/lib/cisco_node_utils/ace.rb +467 -0
- data/lib/cisco_node_utils/acl.rb +101 -0
- data/lib/cisco_node_utils/banner.rb +63 -0
- data/lib/cisco_node_utils/bfd_global.rb +305 -0
- data/lib/cisco_node_utils/bgp.rb +988 -0
- data/lib/cisco_node_utils/bgp_af.rb +545 -0
- data/lib/cisco_node_utils/bgp_af_aggr_addr.rb +207 -0
- data/lib/cisco_node_utils/bgp_neighbor.rb +527 -0
- data/lib/cisco_node_utils/bgp_neighbor_af.rb +780 -0
- data/lib/cisco_node_utils/bridge_domain.rb +178 -0
- data/lib/cisco_node_utils/bridge_domain_vni.rb +206 -0
- data/lib/cisco_node_utils/cisco_cmn_utils.rb +444 -0
- data/lib/cisco_node_utils/client/client.rb +238 -0
- data/lib/cisco_node_utils/client/grpc/client.rb +395 -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/grpc.rb +33 -0
- data/lib/cisco_node_utils/client/nxapi/client.rb +368 -0
- data/lib/cisco_node_utils/client/nxapi.rb +31 -0
- data/lib/cisco_node_utils/client/utils.rb +180 -0
- data/lib/cisco_node_utils/client.rb +35 -0
- data/lib/cisco_node_utils/cmd_ref/README_YAML.md +590 -0
- data/lib/cisco_node_utils/cmd_ref/aaa_auth_login_service.yaml +25 -0
- data/lib/cisco_node_utils/cmd_ref/aaa_authentication_login.yaml +38 -0
- data/lib/cisco_node_utils/cmd_ref/aaa_authorization_service.yaml +40 -0
- data/lib/cisco_node_utils/cmd_ref/acl.yaml +48 -0
- data/lib/cisco_node_utils/cmd_ref/banner.yaml +11 -0
- data/lib/cisco_node_utils/cmd_ref/bfd_global.yaml +117 -0
- data/lib/cisco_node_utils/cmd_ref/bgp.yaml +383 -0
- data/lib/cisco_node_utils/cmd_ref/bgp_af.yaml +223 -0
- data/lib/cisco_node_utils/cmd_ref/bgp_af_aa.yaml +38 -0
- data/lib/cisco_node_utils/cmd_ref/bgp_neighbor.yaml +174 -0
- data/lib/cisco_node_utils/cmd_ref/bgp_neighbor_af.yaml +236 -0
- data/lib/cisco_node_utils/cmd_ref/bridge_domain.yaml +49 -0
- data/lib/cisco_node_utils/cmd_ref/bridge_domain_vni.yaml +33 -0
- data/lib/cisco_node_utils/cmd_ref/dhcp_relay_global.yaml +128 -0
- data/lib/cisco_node_utils/cmd_ref/dnsclient.yaml +55 -0
- data/lib/cisco_node_utils/cmd_ref/encapsulation.yaml +25 -0
- data/lib/cisco_node_utils/cmd_ref/evpn_multicast.yaml +12 -0
- data/lib/cisco_node_utils/cmd_ref/evpn_multisite.yaml +18 -0
- data/lib/cisco_node_utils/cmd_ref/evpn_stormcontrol.yaml +18 -0
- data/lib/cisco_node_utils/cmd_ref/evpn_vni.yaml +48 -0
- data/lib/cisco_node_utils/cmd_ref/fabricpath.yaml +183 -0
- data/lib/cisco_node_utils/cmd_ref/fabricpath_topology.yaml +40 -0
- data/lib/cisco_node_utils/cmd_ref/feature.yaml +126 -0
- data/lib/cisco_node_utils/cmd_ref/hostname.yaml +8 -0
- data/lib/cisco_node_utils/cmd_ref/hsrp_global.yaml +25 -0
- data/lib/cisco_node_utils/cmd_ref/images.yaml +8 -0
- data/lib/cisco_node_utils/cmd_ref/interface.yaml +781 -0
- data/lib/cisco_node_utils/cmd_ref/interface_channel_group.yaml +45 -0
- data/lib/cisco_node_utils/cmd_ref/interface_evpn_multisite.yaml +17 -0
- data/lib/cisco_node_utils/cmd_ref/interface_hsrp_group.yaml +120 -0
- data/lib/cisco_node_utils/cmd_ref/interface_ospf.yaml +112 -0
- data/lib/cisco_node_utils/cmd_ref/interface_portchannel.yaml +87 -0
- data/lib/cisco_node_utils/cmd_ref/interface_service_vni.yaml +42 -0
- data/lib/cisco_node_utils/cmd_ref/inventory.yaml +45 -0
- data/lib/cisco_node_utils/cmd_ref/ip_multicast.yaml +22 -0
- 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 +24 -0
- data/lib/cisco_node_utils/cmd_ref/ntp_auth_key.yaml +10 -0
- data/lib/cisco_node_utils/cmd_ref/ntp_config.yaml +27 -0
- data/lib/cisco_node_utils/cmd_ref/ntp_server.yaml +34 -0
- data/lib/cisco_node_utils/cmd_ref/object_group.yaml +32 -0
- data/lib/cisco_node_utils/cmd_ref/ospf.yaml +91 -0
- data/lib/cisco_node_utils/cmd_ref/ospf_area.yaml +91 -0
- data/lib/cisco_node_utils/cmd_ref/ospf_area_vlink.yaml +88 -0
- data/lib/cisco_node_utils/cmd_ref/overlay_global.yaml +37 -0
- data/lib/cisco_node_utils/cmd_ref/pim.yaml +43 -0
- data/lib/cisco_node_utils/cmd_ref/portchannel_global.yaml +86 -0
- data/lib/cisco_node_utils/cmd_ref/radius_global.yaml +37 -0
- data/lib/cisco_node_utils/cmd_ref/radius_server.yaml +100 -0
- data/lib/cisco_node_utils/cmd_ref/radius_server_group.yaml +19 -0
- data/lib/cisco_node_utils/cmd_ref/route_map.yaml +601 -0
- data/lib/cisco_node_utils/cmd_ref/show_system.yaml +9 -0
- data/lib/cisco_node_utils/cmd_ref/show_version.yaml +84 -0
- data/lib/cisco_node_utils/cmd_ref/snmp_community.yaml +81 -0
- data/lib/cisco_node_utils/cmd_ref/snmp_group.yaml +9 -0
- data/lib/cisco_node_utils/cmd_ref/snmp_notification_receiver.yaml +74 -0
- data/lib/cisco_node_utils/cmd_ref/snmp_server.yaml +91 -0
- data/lib/cisco_node_utils/cmd_ref/snmp_user.yaml +57 -0
- data/lib/cisco_node_utils/cmd_ref/snmpnotification.yaml +23 -0
- data/lib/cisco_node_utils/cmd_ref/span_session.yaml +65 -0
- data/lib/cisco_node_utils/cmd_ref/stp_global.yaml +235 -0
- data/lib/cisco_node_utils/cmd_ref/syslog_facility.yaml +10 -0
- data/lib/cisco_node_utils/cmd_ref/syslog_server.yaml +34 -0
- data/lib/cisco_node_utils/cmd_ref/syslog_settings.yaml +45 -0
- data/lib/cisco_node_utils/cmd_ref/system.yaml +7 -0
- data/lib/cisco_node_utils/cmd_ref/tacacs_global.yaml +37 -0
- data/lib/cisco_node_utils/cmd_ref/tacacs_server.yaml +63 -0
- data/lib/cisco_node_utils/cmd_ref/tacacs_server_group.yaml +45 -0
- data/lib/cisco_node_utils/cmd_ref/tacacs_server_host.yaml +64 -0
- data/lib/cisco_node_utils/cmd_ref/upgrade.yaml +38 -0
- data/lib/cisco_node_utils/cmd_ref/vdc.yaml +52 -0
- data/lib/cisco_node_utils/cmd_ref/virtual_service.yaml +8 -0
- data/lib/cisco_node_utils/cmd_ref/vlan.yaml +106 -0
- data/lib/cisco_node_utils/cmd_ref/vpc.yaml +233 -0
- data/lib/cisco_node_utils/cmd_ref/vrf.yaml +86 -0
- data/lib/cisco_node_utils/cmd_ref/vrf_af.yaml +139 -0
- data/lib/cisco_node_utils/cmd_ref/vtp.yaml +32 -0
- data/lib/cisco_node_utils/cmd_ref/vxlan_vtep.yaml +114 -0
- data/lib/cisco_node_utils/cmd_ref/vxlan_vtep_vni.yaml +71 -0
- data/lib/cisco_node_utils/cmd_ref/yang.yaml +7 -0
- data/lib/cisco_node_utils/cmd_ref/yum.yaml +68 -0
- data/lib/cisco_node_utils/command_reference.rb +724 -0
- data/lib/cisco_node_utils/configparser_lib.rb +195 -0
- data/lib/cisco_node_utils/constants.rb +40 -0
- data/lib/cisco_node_utils/dhcp_relay_global.rb +302 -0
- data/lib/cisco_node_utils/dns_domain.rb +93 -0
- data/lib/cisco_node_utils/domain_name.rb +82 -0
- data/lib/cisco_node_utils/encapsulation.rb +112 -0
- data/lib/cisco_node_utils/environment.rb +110 -0
- data/lib/cisco_node_utils/evpn_multicast.rb +66 -0
- data/lib/cisco_node_utils/evpn_multisite.rb +96 -0
- data/lib/cisco_node_utils/evpn_stormcontrol.rb +84 -0
- data/lib/cisco_node_utils/evpn_vni.rb +159 -0
- data/lib/cisco_node_utils/exceptions.rb +140 -0
- data/lib/cisco_node_utils/fabricpath_global.rb +405 -0
- data/lib/cisco_node_utils/fabricpath_topology.rb +137 -0
- data/lib/cisco_node_utils/feature.rb +377 -0
- data/lib/cisco_node_utils/hostname.rb +62 -0
- data/lib/cisco_node_utils/hsrp_global.rb +97 -0
- data/lib/cisco_node_utils/interface.rb +2128 -0
- data/lib/cisco_node_utils/interface_channel_group.rb +142 -0
- data/lib/cisco_node_utils/interface_evpn_multisite.rb +72 -0
- data/lib/cisco_node_utils/interface_hsrp_group.rb +557 -0
- data/lib/cisco_node_utils/interface_ospf.rb +378 -0
- data/lib/cisco_node_utils/interface_portchannel.rb +180 -0
- data/lib/cisco_node_utils/interface_service_vni.rb +132 -0
- data/lib/cisco_node_utils/ip_multicast.rb +90 -0
- data/lib/cisco_node_utils/itd_device_group.rb +228 -0
- data/lib/cisco_node_utils/itd_device_group_node.rb +144 -0
- data/lib/cisco_node_utils/itd_service.rb +511 -0
- data/lib/cisco_node_utils/logger.rb +78 -0
- data/lib/cisco_node_utils/name_server.rb +64 -0
- data/lib/cisco_node_utils/node.rb +443 -0
- data/lib/cisco_node_utils/node_util.rb +111 -0
- data/lib/cisco_node_utils/ntp_auth_key.rb +67 -0
- data/lib/cisco_node_utils/ntp_config.rb +83 -0
- data/lib/cisco_node_utils/ntp_server.rb +86 -0
- data/lib/cisco_node_utils/object_group.rb +75 -0
- data/lib/cisco_node_utils/object_group_entry.rb +143 -0
- data/lib/cisco_node_utils/overlay_global.rb +142 -0
- data/lib/cisco_node_utils/pim.rb +131 -0
- data/lib/cisco_node_utils/pim_group_list.rb +109 -0
- data/lib/cisco_node_utils/pim_rp_address.rb +103 -0
- data/lib/cisco_node_utils/platform.rb +217 -0
- data/lib/cisco_node_utils/portchannel_global.rb +347 -0
- data/lib/cisco_node_utils/radius_global.rb +165 -0
- data/lib/cisco_node_utils/radius_server.rb +421 -0
- data/lib/cisco_node_utils/radius_server_group.rb +117 -0
- data/lib/cisco_node_utils/route_map.rb +2540 -0
- data/lib/cisco_node_utils/router_ospf.rb +77 -0
- data/lib/cisco_node_utils/router_ospf_area.rb +416 -0
- data/lib/cisco_node_utils/router_ospf_area_vlink.rb +313 -0
- data/lib/cisco_node_utils/router_ospf_vrf.rb +342 -0
- data/lib/cisco_node_utils/snmp_notification_receiver.rb +176 -0
- data/lib/cisco_node_utils/snmpcommunity.rb +109 -0
- data/lib/cisco_node_utils/snmpgroup.rb +54 -0
- data/lib/cisco_node_utils/snmpnotification.rb +57 -0
- data/lib/cisco_node_utils/snmpserver.rb +132 -0
- data/lib/cisco_node_utils/snmpuser.rb +403 -0
- data/lib/cisco_node_utils/span_session.rb +149 -0
- data/lib/cisco_node_utils/stp_global.rb +676 -0
- data/lib/cisco_node_utils/syslog_facility.rb +64 -0
- data/lib/cisco_node_utils/syslog_server.rb +146 -0
- data/lib/cisco_node_utils/syslog_settings.rb +174 -0
- data/lib/cisco_node_utils/tacacs_global.rb +137 -0
- data/lib/cisco_node_utils/tacacs_server.rb +173 -0
- data/lib/cisco_node_utils/tacacs_server_group.rb +149 -0
- data/lib/cisco_node_utils/tacacs_server_host.rb +216 -0
- data/lib/cisco_node_utils/upgrade.rb +122 -0
- data/lib/cisco_node_utils/vdc.rb +118 -0
- data/lib/cisco_node_utils/version.rb +21 -0
- data/lib/cisco_node_utils/vlan.rb +301 -0
- data/lib/cisco_node_utils/vpc.rb +466 -0
- data/lib/cisco_node_utils/vrf.rb +192 -0
- data/lib/cisco_node_utils/vrf_af.rb +327 -0
- data/lib/cisco_node_utils/vtp.rb +125 -0
- data/lib/cisco_node_utils/vxlan_vtep.rb +286 -0
- data/lib/cisco_node_utils/vxlan_vtep_vni.rb +331 -0
- data/lib/cisco_node_utils/yang.rb +160 -0
- data/lib/cisco_node_utils/yum.rb +213 -0
- data/lib/cisco_node_utils.rb +21 -0
- 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 +384 -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 +82 -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 +18 -0
- data/tests/CSCuxdublin-1.0.0-7.0.3.I3.1.lib32_n9000.rpm +0 -0
- data/tests/basetest.rb +243 -0
- data/tests/ciscotest.rb +577 -0
- data/tests/cmd_config.yaml +75 -0
- data/tests/cmd_config_invalid.yaml +16 -0
- data/tests/n9000_sample-1.0.0-7.0.3.x86_64.rpm +0 -0
- data/tests/noop.rb +7 -0
- data/tests/platform_info.rb +63 -0
- data/tests/tacacs_server.yaml.example +6 -0
- data/tests/test_aaa_authentication_login.rb +243 -0
- data/tests/test_aaa_authentication_login_service.rb +761 -0
- data/tests/test_aaa_authorization_service.rb +874 -0
- data/tests/test_ace.rb +304 -0
- data/tests/test_acl.rb +185 -0
- data/tests/test_banner.rb +85 -0
- data/tests/test_bfd_global.rb +272 -0
- data/tests/test_bgp_af.rb +875 -0
- data/tests/test_bgp_af_aa.rb +108 -0
- data/tests/test_bgp_neighbor.rb +596 -0
- data/tests/test_bgp_neighbor_af.rb +781 -0
- data/tests/test_bridge_domain.rb +198 -0
- data/tests/test_bridge_domain_vni.rb +109 -0
- data/tests/test_client_utils.rb +111 -0
- data/tests/test_cmn_utils.rb +76 -0
- data/tests/test_command_config.rb +206 -0
- data/tests/test_command_reference.rb +669 -0
- data/tests/test_dhcp_relay_global.rb +286 -0
- data/tests/test_dns_domain.rb +123 -0
- data/tests/test_domain_name.rb +96 -0
- data/tests/test_encapsulation.rb +75 -0
- data/tests/test_evpn_multicast.rb +65 -0
- data/tests/test_evpn_multisite.rb +70 -0
- data/tests/test_evpn_stormcontrol.rb +56 -0
- data/tests/test_evpn_vni.rb +131 -0
- data/tests/test_fabricpath_global.rb +246 -0
- data/tests/test_fabricpath_topology.rb +77 -0
- data/tests/test_feature.rb +272 -0
- data/tests/test_grpc.rb +166 -0
- data/tests/test_hostname.rb +64 -0
- data/tests/test_hsrp_global.rb +79 -0
- data/tests/test_interface.rb +1958 -0
- data/tests/test_interface_bdi.rb +80 -0
- data/tests/test_interface_channel_group.rb +131 -0
- data/tests/test_interface_evpn_multisite.rb +94 -0
- data/tests/test_interface_hsrp.rb +134 -0
- data/tests/test_interface_hsrp_group.rb +570 -0
- data/tests/test_interface_ospf.rb +820 -0
- data/tests/test_interface_portchannel.rb +135 -0
- data/tests/test_interface_private_vlan.rb +365 -0
- data/tests/test_interface_service_vni.rb +203 -0
- data/tests/test_interface_svi.rb +210 -0
- data/tests/test_interface_switchport.rb +468 -0
- data/tests/test_ip_multicast.rb +80 -0
- 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 +314 -0
- data/tests/test_logger.rb +43 -0
- data/tests/test_name_server.rb +94 -0
- data/tests/test_node.rb +50 -0
- data/tests/test_node_ext.rb +406 -0
- data/tests/test_node_util.rb +119 -0
- data/tests/test_ntp_auth_key.rb +77 -0
- data/tests/test_ntp_config.rb +100 -0
- data/tests/test_ntp_server.rb +146 -0
- data/tests/test_nxapi.rb +236 -0
- data/tests/test_object_group.rb +122 -0
- data/tests/test_overlay_global.rb +108 -0
- data/tests/test_pim.rb +203 -0
- data/tests/test_pim_group_list.rb +147 -0
- data/tests/test_pim_rp_address.rb +155 -0
- data/tests/test_platform.rb +254 -0
- data/tests/test_portchannel_global.rb +322 -0
- data/tests/test_radius_global.rb +108 -0
- data/tests/test_radius_server.rb +377 -0
- data/tests/test_radius_server_group.rb +151 -0
- data/tests/test_route_map.rb +1479 -0
- data/tests/test_router_bgp.rb +1325 -0
- data/tests/test_router_ospf.rb +56 -0
- data/tests/test_router_ospf_area.rb +433 -0
- data/tests/test_router_ospf_area_vlink.rb +298 -0
- data/tests/test_router_ospf_vrf.rb +690 -0
- data/tests/test_snmp_notification_receiver.rb +169 -0
- data/tests/test_snmpcommunity.rb +422 -0
- data/tests/test_snmpgroup.rb +71 -0
- data/tests/test_snmpnotification.rb +91 -0
- data/tests/test_snmpserver.rb +251 -0
- data/tests/test_snmpuser.rb +666 -0
- data/tests/test_span_session.rb +155 -0
- data/tests/test_stp_global.rb +575 -0
- data/tests/test_syslog_facility.rb +80 -0
- data/tests/test_syslog_server.rb +119 -0
- data/tests/test_syslog_settings.rb +123 -0
- data/tests/test_tacacs_global.rb +109 -0
- data/tests/test_tacacs_server.rb +436 -0
- data/tests/test_tacacs_server_group.rb +434 -0
- data/tests/test_tacacs_server_host.rb +427 -0
- data/tests/test_upgrade.rb +105 -0
- data/tests/test_vdc.rb +64 -0
- data/tests/test_vlan.rb +386 -0
- data/tests/test_vlan_private.rb +656 -0
- data/tests/test_vpc.rb +548 -0
- data/tests/test_vrf.rb +248 -0
- data/tests/test_vrf_af.rb +288 -0
- data/tests/test_vtp.rb +278 -0
- data/tests/test_vxlan_vtep.rb +327 -0
- data/tests/test_vxlan_vtep_vni.rb +326 -0
- data/tests/test_yang.rb +369 -0
- data/tests/test_yum.rb +109 -0
- data/tests/upgrade_info.yaml.example +3 -0
- data/tests/yum_package.yaml +94 -0
- metadata +534 -0
|
@@ -0,0 +1,875 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
# RouterBgpAF Unit Tests
|
|
4
|
+
#
|
|
5
|
+
# Richard Wellum, August, 2015
|
|
6
|
+
#
|
|
7
|
+
# Copyright (c) 2015-2017 Cisco and/or its affiliates.
|
|
8
|
+
#
|
|
9
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
10
|
+
# you may not use this file except in compliance with the License.
|
|
11
|
+
# You may obtain a copy of the License at
|
|
12
|
+
#
|
|
13
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
14
|
+
#
|
|
15
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
16
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
17
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
18
|
+
# See the License for the specific language governing permissions and
|
|
19
|
+
# limitations under the License.
|
|
20
|
+
|
|
21
|
+
require_relative 'ciscotest'
|
|
22
|
+
require_relative '../lib/cisco_node_utils/bgp'
|
|
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
|
|
29
|
+
|
|
30
|
+
def setup
|
|
31
|
+
super
|
|
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
|
|
37
|
+
@@pre_clean_needed = false # rubocop:disable Style/ClassVars
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def teardown
|
|
41
|
+
remove_all_bgps
|
|
42
|
+
remove_all_vrfs
|
|
43
|
+
config_no_warn('no route-policy drop_all') if platform == :ios_xr
|
|
44
|
+
super
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
# Disabling line length to support wide-format test matrix definition
|
|
48
|
+
# rubocop:disable Metrics/LineLength
|
|
49
|
+
# Address Families to test:
|
|
50
|
+
T_AFS = [
|
|
51
|
+
# afi safi
|
|
52
|
+
%w(ipv4 unicast),
|
|
53
|
+
%w(ipv6 unicast),
|
|
54
|
+
%w(ipv4 multicast),
|
|
55
|
+
%w(ipv6 multicast),
|
|
56
|
+
%w(l2vpn evpn),
|
|
57
|
+
|
|
58
|
+
# TODO: These are additional address families/modifiers reported by XR, should they be tested also?
|
|
59
|
+
# Looks like most of them are not supported on Nexus...
|
|
60
|
+
#
|
|
61
|
+
|
|
62
|
+
# %w(ipv4 mvpn),
|
|
63
|
+
# %w(ipv6 mvpn),
|
|
64
|
+
|
|
65
|
+
# Not on Nexus:
|
|
66
|
+
# %w(link-state link-state),
|
|
67
|
+
#
|
|
68
|
+
# %w(l2vpn mspw),
|
|
69
|
+
# %w(l2vpn vpls-vpws),
|
|
70
|
+
#
|
|
71
|
+
# %w(ipv4 flowspec),
|
|
72
|
+
# %w(ipv4 mdt),
|
|
73
|
+
# %w(ipv4 rt-filter),
|
|
74
|
+
# %w(ipv4 tunnel),
|
|
75
|
+
#
|
|
76
|
+
# %w(ipv6 flowspec),
|
|
77
|
+
#
|
|
78
|
+
# %w(vpnv4 unicast),
|
|
79
|
+
# %w(vpnv4 multicast),
|
|
80
|
+
# %w(vpnv4 flowspec),
|
|
81
|
+
#
|
|
82
|
+
# %w(vpnv6 unicast),
|
|
83
|
+
# %w(vpnv6 multicast),
|
|
84
|
+
# %w(vpnv6 flowspec),
|
|
85
|
+
]
|
|
86
|
+
|
|
87
|
+
# ASs to test:
|
|
88
|
+
# TODO: Do we ever need to test more than one AS?
|
|
89
|
+
T_ASNS = ['55']
|
|
90
|
+
|
|
91
|
+
# VRFs to test:
|
|
92
|
+
T_VRFS = %w(default red)
|
|
93
|
+
|
|
94
|
+
# Value-based properties
|
|
95
|
+
T_VALUES = [
|
|
96
|
+
[:default_information_originate, [:toggle]],
|
|
97
|
+
[:client_to_client, [:toggle]],
|
|
98
|
+
[:additional_paths_send, [:toggle]],
|
|
99
|
+
[:additional_paths_receive, [:toggle]],
|
|
100
|
+
[:additional_paths_install, [:toggle]],
|
|
101
|
+
[:advertise_l2vpn_evpn, [:toggle]],
|
|
102
|
+
|
|
103
|
+
[:next_hop_route_map, ['drop_all']],
|
|
104
|
+
[:additional_paths_selection, ['drop_all']],
|
|
105
|
+
[:maximum_paths, [7, 9]],
|
|
106
|
+
[:maximum_paths_ibgp, [7, 9]],
|
|
107
|
+
[:dampen_igp_metric, [555, nil]],
|
|
108
|
+
[:default_metric, [50, false]],
|
|
109
|
+
[: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)]]],
|
|
110
|
+
]
|
|
111
|
+
|
|
112
|
+
# Given the cartesian product of the above parameters, not all tests are supported.
|
|
113
|
+
# Here we record which tests are expected to fail, and what kind of failure is expected.
|
|
114
|
+
# This supports a very simple workflow for adding new tests:
|
|
115
|
+
# - Add new entry into test tables above.
|
|
116
|
+
# - Run tests.
|
|
117
|
+
# - When test fails, add a new 'exception' entry.
|
|
118
|
+
# - Repeat until all tests pass.
|
|
119
|
+
# - Condense entries using :any where possible.
|
|
120
|
+
#
|
|
121
|
+
TEST_EXCEPTIONS = [
|
|
122
|
+
# Test OS VRF AF Expected result
|
|
123
|
+
|
|
124
|
+
# Tests that are successful even though a rule below says otherwise
|
|
125
|
+
[:next_hop_route_map, :nexus, 'default', %w(l2vpn evpn), :success],
|
|
126
|
+
[:additional_paths_send, :nexus, 'default', %w(l2vpn evpn), :runtime],
|
|
127
|
+
[:additional_paths_receive, :nexus, 'default', %w(l2vpn evpn), :runtime],
|
|
128
|
+
[:additional_paths_selection, :nexus, 'default', %w(l2vpn evpn), :runtime],
|
|
129
|
+
[:maximum_paths, :nexus, 'default', %w(l2vpn evpn), :runtime],
|
|
130
|
+
[:maximum_paths_ibgp, :nexus, 'default', %w(l2vpn evpn), :runtime],
|
|
131
|
+
|
|
132
|
+
# XR CLI Errors
|
|
133
|
+
[:additional_paths_send, :ios_xr, :any, :multicast, :CliError],
|
|
134
|
+
[:additional_paths_receive, :ios_xr, :any, :multicast, :CliError],
|
|
135
|
+
[:additional_paths_selection, :ios_xr, :any, :multicast, :CliError],
|
|
136
|
+
[:client_to_client, :ios_xr, :VRF, :any, :CliError],
|
|
137
|
+
[:maximum_paths, :ios_xr, :any, %w(l2vpn evpn), :CliError],
|
|
138
|
+
[:maximum_paths_ibgp, :ios_xr, :any, %w(l2vpn evpn), :CliError],
|
|
139
|
+
[:next_hop_route_map, :ios_xr, :VRF, :any, :CliError],
|
|
140
|
+
|
|
141
|
+
# Nexus Unsupported
|
|
142
|
+
|
|
143
|
+
# Nexus CLI Errors
|
|
144
|
+
[:any, :nexus, 'default', %w(l2vpn evpn), :CliError],
|
|
145
|
+
[:advertise_l2vpn_evpn, :nexus, 'default', :any, :CliError],
|
|
146
|
+
[:advertise_l2vpn_evpn, :nexus, :VRF, :multicast, :CliError],
|
|
147
|
+
[:inject_map, :nexus, :any, :multicast, :CliError],
|
|
148
|
+
]
|
|
149
|
+
|
|
150
|
+
# rubocop:disable Style/SpaceAroundOperators
|
|
151
|
+
# rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
|
152
|
+
def check_test_exceptions(test_, os_, vrf_, af_)
|
|
153
|
+
ret = nil
|
|
154
|
+
amb = nil
|
|
155
|
+
TEST_EXCEPTIONS.each do |test, os, vrf, af, expect|
|
|
156
|
+
next unless (test_ == test || test == :any) &&
|
|
157
|
+
(os_ == os || os == :any) &&
|
|
158
|
+
(vrf_ == vrf || vrf == :any ||
|
|
159
|
+
(vrf == :VRF && vrf_ != 'default')) &&
|
|
160
|
+
(af_ == af || af == :any ||
|
|
161
|
+
(af == :unicast && (af_.include? 'unicast')) ||
|
|
162
|
+
(af == :multicast && (af_.include? 'multicast')) ||
|
|
163
|
+
(af == :ipv4 && (af_.include? 'ipv4')) ||
|
|
164
|
+
(af == :ipv6 && (af_.include? 'ipv6')))
|
|
165
|
+
|
|
166
|
+
# We need a connection to the device under test so that we can
|
|
167
|
+
# query the image version to determine if some properties are
|
|
168
|
+
# supported. When TEST_EXCEPTIONS is defined, no connection
|
|
169
|
+
# to the device is available. If the entry is :runtime this
|
|
170
|
+
# triggers a version check below.
|
|
171
|
+
if expect == :runtime
|
|
172
|
+
case Platform.image_version
|
|
173
|
+
when /7\.3/
|
|
174
|
+
expect = :success if test == :additional_paths_send ||
|
|
175
|
+
test == :additional_paths_receive ||
|
|
176
|
+
test == :additional_paths_selection ||
|
|
177
|
+
test == :maximum_paths ||
|
|
178
|
+
test == :maximum_paths_ibgp
|
|
179
|
+
when /8.0|8.1|8.2|8.3|F3.2/
|
|
180
|
+
expect = :success
|
|
181
|
+
expect = :runtime if test == :additional_paths_receive && Platform.image_version[/8.0|8.1/]
|
|
182
|
+
when /I5.2|I5.3|I6/
|
|
183
|
+
expect = :success if test == :maximum_paths || test == :maximum_paths_ibgp
|
|
184
|
+
when /I7|9\.2/
|
|
185
|
+
expect = :success if test == :maximum_paths ||
|
|
186
|
+
test == :maximum_paths_ibgp ||
|
|
187
|
+
test == :additional_paths_send ||
|
|
188
|
+
test == :additional_paths_receive ||
|
|
189
|
+
test == :additional_paths_selection
|
|
190
|
+
else
|
|
191
|
+
expect = :CliError
|
|
192
|
+
end
|
|
193
|
+
end
|
|
194
|
+
return expect if expect == :success || expect == :skip
|
|
195
|
+
|
|
196
|
+
# Otherwise, make sure there's no ambiguity/overlap in the exceptions.
|
|
197
|
+
if !ret.nil? && ret != expect
|
|
198
|
+
assert('TEST ERROR: Exceptions matrix has ambiguous entries! ' \
|
|
199
|
+
"#{amb} and [#{test}, #{os}, #{vrf}, #{af}]")
|
|
200
|
+
end
|
|
201
|
+
ret = expect
|
|
202
|
+
amb = [test, os, vrf, af, expect]
|
|
203
|
+
end
|
|
204
|
+
# Return the expected test result
|
|
205
|
+
ret.nil? ? :success : ret
|
|
206
|
+
end
|
|
207
|
+
# rubocop:enable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
|
208
|
+
# rubocop:enable Style/SpaceAroundOperators
|
|
209
|
+
|
|
210
|
+
def properties_matrix(asns, vrfs, afs, values)
|
|
211
|
+
asns.each do |asn|
|
|
212
|
+
config_ios_xr_dependencies(asn)
|
|
213
|
+
|
|
214
|
+
vrfs.each do |vrf|
|
|
215
|
+
afs.each do |af|
|
|
216
|
+
# l2vpn evpn restrictions
|
|
217
|
+
if af == %w(l2vpn evpn)
|
|
218
|
+
next if vrf != 'default' ||
|
|
219
|
+
validate_property_excluded?('feature', 'nv_overlay_evpn')
|
|
220
|
+
end
|
|
221
|
+
|
|
222
|
+
bgp_af = RouterBgpAF.new(asn, vrf, af)
|
|
223
|
+
|
|
224
|
+
values.each do |test, test_values|
|
|
225
|
+
if validate_property_excluded?('bgp_af', test.to_s)
|
|
226
|
+
assert_raises(Cisco::UnsupportedError) { bgp_af.send("#{test}=", nil) }
|
|
227
|
+
next
|
|
228
|
+
end
|
|
229
|
+
|
|
230
|
+
# What result do we expect from this test?
|
|
231
|
+
expect = check_test_exceptions(test, platform, vrf, af)
|
|
232
|
+
# Gather initial value, default value, and the first test value..
|
|
233
|
+
initial = bgp_af.send(test)
|
|
234
|
+
|
|
235
|
+
# Properties which are unsupported or OFF by default return initial == nil
|
|
236
|
+
if initial.nil?
|
|
237
|
+
default = nil
|
|
238
|
+
first_value = nil
|
|
239
|
+
else
|
|
240
|
+
default = bgp_af.send("default_#{test}")
|
|
241
|
+
first_value = (test_values[0] == :toggle) ? !default : test_values[0]
|
|
242
|
+
end
|
|
243
|
+
|
|
244
|
+
if expect == :skip
|
|
245
|
+
# Do nothing..
|
|
246
|
+
|
|
247
|
+
elsif expect == :CliError
|
|
248
|
+
|
|
249
|
+
# This set of parameters should produce a CLI error
|
|
250
|
+
assert_raises(Cisco::CliError,
|
|
251
|
+
"Assert 'cli error' failed for: "\
|
|
252
|
+
"#{test}=(#{first_value}), #{asn}, #{vrf}, #{af}") do
|
|
253
|
+
bgp_af.send("#{test}=", first_value)
|
|
254
|
+
end
|
|
255
|
+
|
|
256
|
+
else
|
|
257
|
+
|
|
258
|
+
# Check initial value == default value
|
|
259
|
+
# Skip this assertion for properties that use auto_default: false
|
|
260
|
+
assert_equal(default, initial,
|
|
261
|
+
"Initial value failed for: #{test}, #{asn}, #{vrf}, #{af}"
|
|
262
|
+
) unless initial.nil?
|
|
263
|
+
|
|
264
|
+
# Try all the test values in order
|
|
265
|
+
test_values.each do |test_value|
|
|
266
|
+
test_value = (test_value == :toggle) ? !default : test_value
|
|
267
|
+
|
|
268
|
+
# Try the test value
|
|
269
|
+
bgp_af.send("#{test}=", test_value)
|
|
270
|
+
assert_equal(test_value, bgp_af.send(test),
|
|
271
|
+
"Test value failed for: #{test}, #{asn}, #{vrf}, #{af}")
|
|
272
|
+
end # test_values
|
|
273
|
+
|
|
274
|
+
# Set it back to the default
|
|
275
|
+
unless default.nil?
|
|
276
|
+
bgp_af.send("#{test}=", default)
|
|
277
|
+
assert_equal(default, bgp_af.send(test),
|
|
278
|
+
"Default assignment failed for: #{test}, #{asn}, #{vrf}, #{af}")
|
|
279
|
+
end
|
|
280
|
+
end
|
|
281
|
+
|
|
282
|
+
# Cleanup
|
|
283
|
+
bgp_af.destroy
|
|
284
|
+
end # tests
|
|
285
|
+
end # afs
|
|
286
|
+
end # vrfs
|
|
287
|
+
end # asns
|
|
288
|
+
end
|
|
289
|
+
# rubocop:enable Metrics/LineLength
|
|
290
|
+
|
|
291
|
+
def test_properties_matrix
|
|
292
|
+
properties_matrix(T_ASNS, T_VRFS, T_AFS, T_VALUES)
|
|
293
|
+
end
|
|
294
|
+
|
|
295
|
+
##
|
|
296
|
+
## BGP Address Family
|
|
297
|
+
## Validate that RouterBgp.afs is empty when bgp is not enabled
|
|
298
|
+
##
|
|
299
|
+
def test_collection_empty
|
|
300
|
+
node.cache_flush
|
|
301
|
+
afs = RouterBgpAF.afs
|
|
302
|
+
assert_empty(afs, 'BGP address-family collection is not empty')
|
|
303
|
+
end
|
|
304
|
+
|
|
305
|
+
##
|
|
306
|
+
## BGP Address Family
|
|
307
|
+
## Configure router bgp, some VRF's and address-family statements
|
|
308
|
+
## - verify that the final instance objects are correctly populated
|
|
309
|
+
## Enable VXLAN and the EVPN
|
|
310
|
+
##
|
|
311
|
+
def test_collection_not_empty
|
|
312
|
+
config('feature bgp') if platform == :nexus
|
|
313
|
+
|
|
314
|
+
bgp_afs = []
|
|
315
|
+
%w(default red blue orange black).each do |vrf|
|
|
316
|
+
[%w(ipv4 unicast), %w(ipv6 unicast),
|
|
317
|
+
%w(ipv4 multicast), %w(ipv6 multicast)].each do |af|
|
|
318
|
+
config_ios_xr_dependencies(55, vrf)
|
|
319
|
+
bgp_afs.push(RouterBgpAF.new(55, vrf, af))
|
|
320
|
+
end
|
|
321
|
+
end
|
|
322
|
+
|
|
323
|
+
# config('router bgp 55',
|
|
324
|
+
# 'address-family ipv4 unicast',
|
|
325
|
+
# 'vrf red',
|
|
326
|
+
# 'address-family ipv4 unicast',
|
|
327
|
+
# 'vrf blue',
|
|
328
|
+
# 'address-family ipv6 multicast',
|
|
329
|
+
# 'vrf orange',
|
|
330
|
+
# 'address-family ipv4 multicast',
|
|
331
|
+
# 'vrf black',
|
|
332
|
+
# 'address-family ipv6 unicast')
|
|
333
|
+
|
|
334
|
+
# Construct a hash of routers, vrfs, afs
|
|
335
|
+
routers = RouterBgpAF.afs
|
|
336
|
+
refute_empty(routers, 'Error: BGP address_family collection is empty')
|
|
337
|
+
|
|
338
|
+
# Validate the collection
|
|
339
|
+
routers.each do |asn, vrfs|
|
|
340
|
+
assert((asn.kind_of? Fixnum),
|
|
341
|
+
'Error: Autonomous number must be a fixed number')
|
|
342
|
+
refute_empty(vrfs, 'Error: Collection is empty')
|
|
343
|
+
|
|
344
|
+
vrfs.each do |vrf, afs|
|
|
345
|
+
refute_empty(afs, 'Error: No Address Family found')
|
|
346
|
+
assert(vrf.length > 0, 'Error: No VRF found')
|
|
347
|
+
afs.each_key do |af_key|
|
|
348
|
+
afi = af_key[0]
|
|
349
|
+
safi = af_key[1]
|
|
350
|
+
assert(afi.length > 0, 'Error: AFI length is zero')
|
|
351
|
+
assert_match(/^(ip|vpn)v[46]/, afi,
|
|
352
|
+
'Error: AFI must be vpnv4, ipv4, vpnv6 or ipv6')
|
|
353
|
+
assert(safi.length > 0, 'Error: SAFI length is zero')
|
|
354
|
+
assert_match(/^(un|mult)icast/, safi,
|
|
355
|
+
'Error: AFI must be unicast or multicast')
|
|
356
|
+
end
|
|
357
|
+
end
|
|
358
|
+
end
|
|
359
|
+
end
|
|
360
|
+
|
|
361
|
+
def config_ios_xr_dependencies(asn, vrf='red')
|
|
362
|
+
return unless platform == :ios_xr
|
|
363
|
+
# These dependencies are required on ios xr
|
|
364
|
+
|
|
365
|
+
# "rd auto" required, otherwise XR reports:
|
|
366
|
+
# 'The RD for the VRF must be present before an
|
|
367
|
+
# address family is activated'
|
|
368
|
+
|
|
369
|
+
# "bgp router-id" requred, otherwise XR reports:
|
|
370
|
+
# 'BGP router ID must be configured.'
|
|
371
|
+
|
|
372
|
+
# "address-family vpnv4 unicast" required, otherwise XR reports:
|
|
373
|
+
# 'The parent address family has not been initialized'
|
|
374
|
+
|
|
375
|
+
cfg = ["router bgp #{asn}",
|
|
376
|
+
'bgp router-id 10.1.1.1',
|
|
377
|
+
'address-family vpnv4 unicast',
|
|
378
|
+
'address-family vpnv6 unicast',
|
|
379
|
+
'address-family vpnv4 multicast',
|
|
380
|
+
'address-family vpnv6 multicast',
|
|
381
|
+
]
|
|
382
|
+
cfg << "vrf #{vrf}" << 'rd auto' unless vrf == 'default'
|
|
383
|
+
config(cfg)
|
|
384
|
+
|
|
385
|
+
# Needed for testing route-policy commands
|
|
386
|
+
config_no_warn('route-policy drop_all', 'end-policy')
|
|
387
|
+
|
|
388
|
+
# TBD: Reduce the number of different route-policies used by this test
|
|
389
|
+
# and move the remaining ones into this method. Then create an
|
|
390
|
+
# unconfig_ios_xr_dependencies to handle the cleanups.
|
|
391
|
+
end
|
|
392
|
+
|
|
393
|
+
########################################################
|
|
394
|
+
# PROPERTIES #
|
|
395
|
+
########################################################
|
|
396
|
+
|
|
397
|
+
def test_dampening
|
|
398
|
+
asn = '101'
|
|
399
|
+
af = %w(ipv4 unicast)
|
|
400
|
+
if platform == :nexus
|
|
401
|
+
vrf = 'orange'
|
|
402
|
+
elsif platform == :ios_xr
|
|
403
|
+
vrf = 'default'
|
|
404
|
+
config_ios_xr_dependencies(asn, vrf)
|
|
405
|
+
config_no_warn('route-policy DropAllTraffic', 'end-policy')
|
|
406
|
+
end
|
|
407
|
+
bgp_af = RouterBgpAF.new(asn, vrf, af)
|
|
408
|
+
|
|
409
|
+
# Test no dampening configured
|
|
410
|
+
assert_nil(bgp_af.dampening)
|
|
411
|
+
|
|
412
|
+
#############################################
|
|
413
|
+
# Set and verify 'dampening' with overrides #
|
|
414
|
+
#############################################
|
|
415
|
+
|
|
416
|
+
bgp_af.dampening = %w(1 2 3 4)
|
|
417
|
+
|
|
418
|
+
# Check getters
|
|
419
|
+
assert_equal(bgp_af.dampening, %w(1 2 3 4),
|
|
420
|
+
'Error: dampening getter did not match')
|
|
421
|
+
assert_equal(1, bgp_af.dampening_half_time,
|
|
422
|
+
'The wrong dampening half_time value is configured')
|
|
423
|
+
assert_equal(2, bgp_af.dampening_reuse_time,
|
|
424
|
+
'The wrong dampening reuse_time value is configured')
|
|
425
|
+
assert_equal(3, bgp_af.dampening_suppress_time,
|
|
426
|
+
'The wrong dampening suppress_time value is configured')
|
|
427
|
+
assert_equal(4, bgp_af.dampening_max_suppress_time,
|
|
428
|
+
'The wrong dampening max_suppress_time value is configured')
|
|
429
|
+
assert_empty(bgp_af.dampening_routemap,
|
|
430
|
+
'A routemap should not be configured')
|
|
431
|
+
|
|
432
|
+
#############################################
|
|
433
|
+
# Set and verify 'dampening' with route-map #
|
|
434
|
+
#############################################
|
|
435
|
+
|
|
436
|
+
bgp_af.dampening = 'DropAllTraffic'
|
|
437
|
+
|
|
438
|
+
# Check getters
|
|
439
|
+
assert_equal('DropAllTraffic', bgp_af.dampening)
|
|
440
|
+
assert_equal('DropAllTraffic', bgp_af.dampening_routemap)
|
|
441
|
+
|
|
442
|
+
#############################################
|
|
443
|
+
# Set and verify 'dampening' to defaults #
|
|
444
|
+
#############################################
|
|
445
|
+
|
|
446
|
+
bgp_af.dampening = bgp_af.default_dampening
|
|
447
|
+
|
|
448
|
+
# Check getters
|
|
449
|
+
|
|
450
|
+
assert_equal(bgp_af.default_dampening, bgp_af.dampening)
|
|
451
|
+
|
|
452
|
+
assert_equal(bgp_af.default_dampening_half_time,
|
|
453
|
+
bgp_af.dampening_half_time,
|
|
454
|
+
'Wrong default dampening half_time value configured')
|
|
455
|
+
assert_equal(bgp_af.default_dampening_reuse_time,
|
|
456
|
+
bgp_af.dampening_reuse_time,
|
|
457
|
+
'Wrong default dampening reuse_time value configured')
|
|
458
|
+
assert_equal(bgp_af.default_dampening_suppress_time,
|
|
459
|
+
bgp_af.dampening_suppress_time,
|
|
460
|
+
'Wrong default dampening suppress_time value configured')
|
|
461
|
+
assert_equal(bgp_af.default_dampening_max_suppress_time,
|
|
462
|
+
bgp_af.dampening_max_suppress_time,
|
|
463
|
+
'Wrong default dampening suppress_max_time value configured')
|
|
464
|
+
assert_equal(bgp_af.default_dampening_routemap,
|
|
465
|
+
bgp_af.dampening_routemap,
|
|
466
|
+
'The default dampening routemap should configured')
|
|
467
|
+
|
|
468
|
+
############################################
|
|
469
|
+
# Turn off 'dampening' #
|
|
470
|
+
############################################
|
|
471
|
+
|
|
472
|
+
bgp_af.dampening = nil
|
|
473
|
+
assert_nil(bgp_af.dampening)
|
|
474
|
+
assert_nil(bgp_af.dampening_half_time)
|
|
475
|
+
assert_nil(bgp_af.dampening_reuse_time)
|
|
476
|
+
assert_nil(bgp_af.dampening_suppress_time)
|
|
477
|
+
assert_nil(bgp_af.dampening_max_suppress_time)
|
|
478
|
+
assert_nil(bgp_af.dampening_routemap)
|
|
479
|
+
|
|
480
|
+
bgp_af.destroy
|
|
481
|
+
end
|
|
482
|
+
|
|
483
|
+
##
|
|
484
|
+
## distance
|
|
485
|
+
##
|
|
486
|
+
def test_distance
|
|
487
|
+
asn = '55'
|
|
488
|
+
vrf = 'red'
|
|
489
|
+
af = %w(ipv4 unicast)
|
|
490
|
+
|
|
491
|
+
config_ios_xr_dependencies(asn)
|
|
492
|
+
bgp_af = RouterBgpAF.new(asn, vrf, af)
|
|
493
|
+
distance = [{ ebgp: 20, ibgp: 40, local: 60 },
|
|
494
|
+
{ ebgp: bgp_af.default_distance_ebgp,
|
|
495
|
+
ibgp: bgp_af.default_distance_ibgp,
|
|
496
|
+
local: bgp_af.default_distance_local },
|
|
497
|
+
{ ebgp: bgp_af.default_distance_ebgp,
|
|
498
|
+
ibgp: 40,
|
|
499
|
+
local: 60 },
|
|
500
|
+
{ ebgp: 20,
|
|
501
|
+
ibgp: bgp_af.default_distance_ibgp,
|
|
502
|
+
local: bgp_af.default_distance_local },
|
|
503
|
+
{ ebgp: bgp_af.default_distance_ebgp,
|
|
504
|
+
ibgp: bgp_af.default_distance_ibgp,
|
|
505
|
+
local: 60 },
|
|
506
|
+
]
|
|
507
|
+
distance.each do |distancer|
|
|
508
|
+
bgp_af.distance_set(distancer[:ebgp], distancer[:ibgp], distancer[:local])
|
|
509
|
+
assert_equal(distancer[:ebgp], bgp_af.distance_ebgp)
|
|
510
|
+
assert_equal(distancer[:ibgp], bgp_af.distance_ibgp)
|
|
511
|
+
assert_equal(distancer[:local], bgp_af.distance_local)
|
|
512
|
+
end
|
|
513
|
+
bgp_af.destroy
|
|
514
|
+
end
|
|
515
|
+
|
|
516
|
+
##
|
|
517
|
+
## network
|
|
518
|
+
##
|
|
519
|
+
|
|
520
|
+
def test_network
|
|
521
|
+
vrfs = %w(default red)
|
|
522
|
+
afs = [%w(ipv4 unicast), %w(ipv6 unicast)]
|
|
523
|
+
vrfs.each do |vrf|
|
|
524
|
+
afs.each do |af|
|
|
525
|
+
dbg = sprintf('[VRF %s AF %s]', vrf, af.join('/'))
|
|
526
|
+
config_ios_xr_dependencies(1)
|
|
527
|
+
af_obj = RouterBgpAF.new(1, vrf, af)
|
|
528
|
+
network_cmd(af_obj, dbg)
|
|
529
|
+
|
|
530
|
+
af_obj.destroy
|
|
531
|
+
end
|
|
532
|
+
end
|
|
533
|
+
end
|
|
534
|
+
|
|
535
|
+
def network_cmd(af, dbg)
|
|
536
|
+
if platform == :ios_xr
|
|
537
|
+
%w(rtmap1 rtmap2 rtmap3 rtmap5 rtmap6 rtmap7).each do |policy|
|
|
538
|
+
config_no_warn("route-policy #{policy}", 'end-policy')
|
|
539
|
+
end
|
|
540
|
+
end
|
|
541
|
+
|
|
542
|
+
# Initial 'should' state
|
|
543
|
+
if /ipv6/.match(dbg)
|
|
544
|
+
master = [
|
|
545
|
+
['2000:123:38::/64', 'rtmap1'],
|
|
546
|
+
['2000:123:39::/64', 'rtmap2'],
|
|
547
|
+
['2000:123:40::/64', 'rtmap3'],
|
|
548
|
+
['2000:123:41::/64'],
|
|
549
|
+
['2000:123:42::/64', 'rtmap5'],
|
|
550
|
+
['2000:123:43::/64', 'rtmap6'],
|
|
551
|
+
['2000:123:44::/64'],
|
|
552
|
+
['2000:123:45::/64', 'rtmap7'],
|
|
553
|
+
]
|
|
554
|
+
else
|
|
555
|
+
master = [
|
|
556
|
+
['192.168.5.0/24', 'rtmap1'],
|
|
557
|
+
['192.168.6.0/24', 'rtmap2'],
|
|
558
|
+
['192.168.7.0/24', 'rtmap3'],
|
|
559
|
+
['192.168.8.0/24'],
|
|
560
|
+
['192.168.9.0/24', 'rtmap5'],
|
|
561
|
+
['192.168.10.0/24', 'rtmap6'],
|
|
562
|
+
['192.168.11.0/24'],
|
|
563
|
+
['192.168.12.0/24', 'rtmap7'],
|
|
564
|
+
]
|
|
565
|
+
end
|
|
566
|
+
|
|
567
|
+
# Test: all networks are set when current is empty.
|
|
568
|
+
should = master.clone
|
|
569
|
+
af.networks = should
|
|
570
|
+
result = af.networks
|
|
571
|
+
assert_equal(should.sort, result.sort,
|
|
572
|
+
"#{dbg} Test 1. From empty, to all networks")
|
|
573
|
+
|
|
574
|
+
# Test: remove half of the networks
|
|
575
|
+
should.shift(4)
|
|
576
|
+
af.networks = should
|
|
577
|
+
result = af.networks
|
|
578
|
+
assert_equal(should.sort, result.sort,
|
|
579
|
+
"#{dbg} Test 2. Remove half of the networks")
|
|
580
|
+
|
|
581
|
+
# Test: restore the removed networks
|
|
582
|
+
should = master.clone
|
|
583
|
+
af.networks = should
|
|
584
|
+
result = af.networks
|
|
585
|
+
assert_equal(should.sort, result.sort,
|
|
586
|
+
"#{dbg} Test 3. Restore the removed networks")
|
|
587
|
+
|
|
588
|
+
# Test: Change route-maps on existing networks
|
|
589
|
+
if platform == :ios_xr
|
|
590
|
+
%w(rtmap1_55 rtmap2_55 rtmap3_55 rtmap5_55
|
|
591
|
+
rtmap6_55 rtmap7_55).each do |policy|
|
|
592
|
+
config_no_warn("route-policy #{policy}", 'end-policy')
|
|
593
|
+
end
|
|
594
|
+
end
|
|
595
|
+
should = master.map { |network, rm| [network, rm.nil? ? nil : "#{rm}_55"] }
|
|
596
|
+
af.networks = should
|
|
597
|
+
result = af.networks
|
|
598
|
+
assert_equal(should.sort, result.sort,
|
|
599
|
+
"#{dbg} Test 4. Change route-map on existing networks")
|
|
600
|
+
|
|
601
|
+
# Test: 'default'
|
|
602
|
+
should = af.default_networks
|
|
603
|
+
af.networks = should
|
|
604
|
+
result = af.networks
|
|
605
|
+
assert_equal(should.sort, result.sort,
|
|
606
|
+
"#{dbg} Test 5. 'Default'")
|
|
607
|
+
return unless platform == :ios_xr
|
|
608
|
+
%w(rtmap1 rtmap2 rtmap3 rtmap5 rtmap6 rtmap7
|
|
609
|
+
rtmap1_55 rtmap2_55 rtmap3_55
|
|
610
|
+
rtmap5_55 rtmap6_55 rtmap7_55).each do |policy|
|
|
611
|
+
config("no route-policy #{policy}")
|
|
612
|
+
end
|
|
613
|
+
end
|
|
614
|
+
|
|
615
|
+
##
|
|
616
|
+
## redistribute
|
|
617
|
+
##
|
|
618
|
+
|
|
619
|
+
def test_redistribute
|
|
620
|
+
vrfs = %w(default red)
|
|
621
|
+
afs = [%w(ipv4 unicast), %w(ipv6 unicast)]
|
|
622
|
+
vrfs.each do |vrf|
|
|
623
|
+
afs.each do |af|
|
|
624
|
+
dbg = sprintf('[VRF %s AF %s]', vrf, af.join('/'))
|
|
625
|
+
config_ios_xr_dependencies(1)
|
|
626
|
+
af = RouterBgpAF.new(1, vrf, af)
|
|
627
|
+
redistribute_cmd(af, dbg)
|
|
628
|
+
af.destroy
|
|
629
|
+
end
|
|
630
|
+
end
|
|
631
|
+
end
|
|
632
|
+
|
|
633
|
+
def redistribute_cmd(af, dbg)
|
|
634
|
+
# rubocop:disable Style/WordArray
|
|
635
|
+
# Initial 'should' state
|
|
636
|
+
ospf = (dbg.include? 'ipv6') ? 'ospfv3 3' : 'ospf 3'
|
|
637
|
+
if platform == :nexus
|
|
638
|
+
master = [['direct', 'rm_direct'],
|
|
639
|
+
['lisp', 'rm_lisp'],
|
|
640
|
+
['static', 'rm_static'],
|
|
641
|
+
['eigrp 1', 'rm_eigrp'],
|
|
642
|
+
['isis 2', 'rm_isis'],
|
|
643
|
+
[ospf, 'rm_ospf'],
|
|
644
|
+
['rip 4', 'rm_rip']]
|
|
645
|
+
elsif platform == :ios_xr
|
|
646
|
+
config_no_warn('route-policy my_policy', 'end-policy')
|
|
647
|
+
master = [['connected', 'my_policy'],
|
|
648
|
+
['eigrp 1', 'my_policy'],
|
|
649
|
+
[ospf, 'my_policy'],
|
|
650
|
+
['static', 'my_policy']]
|
|
651
|
+
master.push(['isis abc', 'my_policy']) if dbg.include? 'default'
|
|
652
|
+
end
|
|
653
|
+
# rubocop:enable Style/WordArray
|
|
654
|
+
|
|
655
|
+
# Test: Add all protocols w/route-maps when no cmds are present
|
|
656
|
+
should = master.clone
|
|
657
|
+
af.redistribute = should
|
|
658
|
+
result = af.redistribute
|
|
659
|
+
assert_equal(should.sort, result.sort,
|
|
660
|
+
"#{dbg} Test 1. From empty, to all protocols")
|
|
661
|
+
|
|
662
|
+
# Test: remove half of the protocols
|
|
663
|
+
should.shift(4)
|
|
664
|
+
af.redistribute = should
|
|
665
|
+
result = af.redistribute
|
|
666
|
+
assert_equal(should.sort, result.sort,
|
|
667
|
+
"#{dbg} Test 2. Remove half of the protocols")
|
|
668
|
+
|
|
669
|
+
# Test: restore the removed protocols
|
|
670
|
+
should = master.clone
|
|
671
|
+
af.redistribute = should
|
|
672
|
+
result = af.redistribute
|
|
673
|
+
assert_equal(should.sort, result.sort,
|
|
674
|
+
"#{dbg} Test 3. Restore the removed protocols")
|
|
675
|
+
|
|
676
|
+
# Test: Change route-maps on existing commands
|
|
677
|
+
if platform == :ios_xr
|
|
678
|
+
config_no_warn('route-policy my_policy_2', 'end-policy')
|
|
679
|
+
end
|
|
680
|
+
should = master.map { |prot_only, rm| [prot_only, "#{rm}_2"] }
|
|
681
|
+
af.redistribute = should
|
|
682
|
+
result = af.redistribute
|
|
683
|
+
assert_equal(should.sort, result.sort,
|
|
684
|
+
"#{dbg} Test 4. Change route-maps on existing commands")
|
|
685
|
+
|
|
686
|
+
# Test: 'default'
|
|
687
|
+
should = af.default_redistribute
|
|
688
|
+
af.redistribute = should
|
|
689
|
+
result = af.redistribute
|
|
690
|
+
assert_equal(should.sort, result.sort,
|
|
691
|
+
"#{dbg} Test 5. 'Default'")
|
|
692
|
+
return unless platform == :ios_xr
|
|
693
|
+
%w(my_policy my_policy_2).each do |policy|
|
|
694
|
+
config("no route-policy #{policy}")
|
|
695
|
+
end
|
|
696
|
+
end
|
|
697
|
+
|
|
698
|
+
##
|
|
699
|
+
## common utilities
|
|
700
|
+
##
|
|
701
|
+
def test_utils_delta_add_remove_depth_1
|
|
702
|
+
# Note: AF context is not needed. This test is only validating the
|
|
703
|
+
# delta_add_remove class method and does not test directly on the device.
|
|
704
|
+
|
|
705
|
+
# Initial 'should' state
|
|
706
|
+
should = ['1:1', '2:2', '3:3', '4:4', '5:5', '6:6']
|
|
707
|
+
# rubocop:enable Style/WordArray
|
|
708
|
+
|
|
709
|
+
# Test: Check delta when every protocol is specified and has a route-map.
|
|
710
|
+
current = []
|
|
711
|
+
expected = { add: should, remove: [] }
|
|
712
|
+
result = Utils.delta_add_remove(should, current)
|
|
713
|
+
assert_equal(expected, result, 'Test 1. delta mismatch')
|
|
714
|
+
|
|
715
|
+
# Test: Check delta when should is the same as current.
|
|
716
|
+
current = should.clone
|
|
717
|
+
expected = { add: [], remove: [] }
|
|
718
|
+
result = Utils.delta_add_remove(should, current)
|
|
719
|
+
assert_equal(expected, result, 'Test 2. delta mismatch')
|
|
720
|
+
|
|
721
|
+
# Test: Move half the 'current' entries to 'should'. Check delta.
|
|
722
|
+
should = current.shift(4)
|
|
723
|
+
expected = { add: should, remove: current }
|
|
724
|
+
result = Utils.delta_add_remove(should, current)
|
|
725
|
+
assert_equal(expected, result, 'Test 3. delta mismatch')
|
|
726
|
+
|
|
727
|
+
# Test: Remove the route-maps from the current list. Check delta.
|
|
728
|
+
# Note: The :remove list should be empty since this is just
|
|
729
|
+
# an update of the route-map.
|
|
730
|
+
should = current.map { |prot_only, _route_map| [prot_only] }
|
|
731
|
+
expected = { add: should, remove: [] }
|
|
732
|
+
result = Utils.delta_add_remove(should, current)
|
|
733
|
+
assert_equal(expected, result, 'Test 4. delta mismatch')
|
|
734
|
+
|
|
735
|
+
# Test: Check empty inputs
|
|
736
|
+
should = []
|
|
737
|
+
current = []
|
|
738
|
+
expected = { add: [], remove: [] }
|
|
739
|
+
result = Utils.delta_add_remove(should, current)
|
|
740
|
+
assert_equal(expected, result, 'Test 5. delta mismatch')
|
|
741
|
+
end
|
|
742
|
+
|
|
743
|
+
def test_utils_delta_add_remove
|
|
744
|
+
# Note: AF context is not needed. This test is only validating the
|
|
745
|
+
# delta_add_remove class method and does not test directly on the device.
|
|
746
|
+
|
|
747
|
+
# rubocop:disable Style/WordArray
|
|
748
|
+
# Initial 'should' state
|
|
749
|
+
should = [['direct', 'rm_direct'],
|
|
750
|
+
['lisp', 'rm_lisp'],
|
|
751
|
+
['static', 'rm_static'],
|
|
752
|
+
['eigrp 1', 'rm_eigrp'],
|
|
753
|
+
['isis 2', 'rm_isis'],
|
|
754
|
+
['ospf 3', 'rm_ospf'],
|
|
755
|
+
['rip 4', 'rm_rip']]
|
|
756
|
+
# rubocop:enable Style/WordArray
|
|
757
|
+
|
|
758
|
+
# Test: Check delta when every protocol is specified and has a route-map.
|
|
759
|
+
current = []
|
|
760
|
+
expected = { add: should, remove: [] }
|
|
761
|
+
result = Utils.delta_add_remove(should, current)
|
|
762
|
+
assert_equal(expected, result, 'Test 1. delta mismatch')
|
|
763
|
+
|
|
764
|
+
# Test: Check delta when should is the same as current.
|
|
765
|
+
current = should.clone
|
|
766
|
+
expected = { add: [], remove: [] }
|
|
767
|
+
result = Utils.delta_add_remove(should, current)
|
|
768
|
+
assert_equal(expected, result, 'Test 2. delta mismatch')
|
|
769
|
+
|
|
770
|
+
# Test: Move half the 'current' entries to 'should'. Check delta.
|
|
771
|
+
should = current.shift(4)
|
|
772
|
+
expected = { add: should, remove: current }
|
|
773
|
+
result = Utils.delta_add_remove(should, current)
|
|
774
|
+
assert_equal(expected, result, 'Test 3. delta mismatch')
|
|
775
|
+
|
|
776
|
+
# Test: Remove the route-maps from the current list. Check delta.
|
|
777
|
+
# Note: The :remove list should be empty since this is just
|
|
778
|
+
# an update of the route-map.
|
|
779
|
+
should = current.map { |prot_only, _route_map| [prot_only] }
|
|
780
|
+
expected = { add: should, remove: [] }
|
|
781
|
+
result = Utils.delta_add_remove(should, current)
|
|
782
|
+
assert_equal(expected, result, 'Test 4. delta mismatch')
|
|
783
|
+
|
|
784
|
+
# Test: Check empty inputs
|
|
785
|
+
should = []
|
|
786
|
+
current = []
|
|
787
|
+
expected = { add: [], remove: [] }
|
|
788
|
+
result = Utils.delta_add_remove(should, current)
|
|
789
|
+
assert_equal(expected, result, 'Test 5. delta mismatch')
|
|
790
|
+
end
|
|
791
|
+
|
|
792
|
+
def test_respond_to?
|
|
793
|
+
config_ios_xr_dependencies('22')
|
|
794
|
+
bgp_af = RouterBgpAF.new('22', 'red', %w(ipv4 unicast))
|
|
795
|
+
|
|
796
|
+
# Functions that are actually defined in bgp_af.rb
|
|
797
|
+
assert_respond_to(bgp_af, :dampening_max_suppress_time)
|
|
798
|
+
assert_respond_to(bgp_af, :next_hop_route_map=)
|
|
799
|
+
assert_respond_to(bgp_af, :default_additional_paths_selection)
|
|
800
|
+
|
|
801
|
+
# Functions that are covered by the method_missing magic
|
|
802
|
+
assert_respond_to(bgp_af, :next_hop_route_map)
|
|
803
|
+
assert_respond_to(bgp_af, :additional_paths_selection)
|
|
804
|
+
assert_respond_to(bgp_af, :default_default_information_originate)
|
|
805
|
+
if platform == :ios_xr
|
|
806
|
+
# not supported
|
|
807
|
+
refute_respond_to(bgp_af, :default_information_originate=)
|
|
808
|
+
else
|
|
809
|
+
assert_respond_to(bgp_af, :default_information_originate=)
|
|
810
|
+
end
|
|
811
|
+
assert_respond_to(bgp_af, :table_map)
|
|
812
|
+
assert_respond_to(bgp_af, :default_table_map)
|
|
813
|
+
|
|
814
|
+
# Functions that are explicitly excluded from method_missing
|
|
815
|
+
refute_respond_to(bgp_af, :table_map=)
|
|
816
|
+
refute_respond_to(bgp_af, :table_map_filter=)
|
|
817
|
+
|
|
818
|
+
# Functions that shouldn't be covered by method_missing
|
|
819
|
+
refute_respond_to(bgp_af, :default_next_hop_route_map=)
|
|
820
|
+
|
|
821
|
+
bgp_af.destroy
|
|
822
|
+
end
|
|
823
|
+
|
|
824
|
+
##
|
|
825
|
+
## table_map
|
|
826
|
+
##
|
|
827
|
+
def table_map(asn, vrf, af)
|
|
828
|
+
bgp_af = RouterBgpAF.new(asn, vrf, af)
|
|
829
|
+
|
|
830
|
+
#
|
|
831
|
+
# Set and verify
|
|
832
|
+
#
|
|
833
|
+
val = 'sjc'
|
|
834
|
+
bgp_af.table_map_set(val)
|
|
835
|
+
assert_equal(val, bgp_af.table_map)
|
|
836
|
+
|
|
837
|
+
val = bgp_af.default_table_map
|
|
838
|
+
bgp_af.table_map_set(val)
|
|
839
|
+
assert_equal(val, bgp_af.table_map)
|
|
840
|
+
|
|
841
|
+
if validate_property_excluded?('bgp_af', 'table_map_filter')
|
|
842
|
+
assert_raises(Cisco::UnsupportedError) do
|
|
843
|
+
bgp_af.table_map_set('sjc', true)
|
|
844
|
+
end
|
|
845
|
+
assert_nil(bgp_af.default_table_map_filter)
|
|
846
|
+
return
|
|
847
|
+
end
|
|
848
|
+
|
|
849
|
+
val = false
|
|
850
|
+
bgp_af.table_map_set('sjc', val)
|
|
851
|
+
refute(bgp_af.table_map_filter)
|
|
852
|
+
|
|
853
|
+
val = true
|
|
854
|
+
bgp_af.table_map_set('sjc', val)
|
|
855
|
+
assert(bgp_af.table_map_filter)
|
|
856
|
+
|
|
857
|
+
default = bgp_af.default_table_map_filter
|
|
858
|
+
bgp_af.table_map_set('sjc', default)
|
|
859
|
+
assert_equal(default, bgp_af.table_map_filter)
|
|
860
|
+
end
|
|
861
|
+
|
|
862
|
+
def test_table_map
|
|
863
|
+
if platform == :ios_xr
|
|
864
|
+
config_no_warn('route-policy sjc', 'end-policy')
|
|
865
|
+
config_ios_xr_dependencies('55')
|
|
866
|
+
end
|
|
867
|
+
|
|
868
|
+
afs = [%w(ipv4 unicast), %w(ipv6 unicast)]
|
|
869
|
+
afs.each do |af|
|
|
870
|
+
table_map(55, 'red', af)
|
|
871
|
+
end
|
|
872
|
+
|
|
873
|
+
config('no route-policy sjc') if platform == :ios_xr
|
|
874
|
+
end
|
|
875
|
+
end
|