cisco_node_utils_mgx 2.1.0.1
Sign up to get free protection for your applications and to get access to all the features.
- 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,2128 @@
|
|
1
|
+
# November 2015, Chris Van Heuveln
|
2
|
+
#
|
3
|
+
# Copyright (c) 2015-2018 Cisco and/or its affiliates.
|
4
|
+
#
|
5
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
6
|
+
# you may not use this file except in compliance with the License.
|
7
|
+
# You may obtain a copy of the License at
|
8
|
+
#
|
9
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
10
|
+
#
|
11
|
+
# Unless required by applicable law or agreed to in writing, software
|
12
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
13
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
14
|
+
# See the License for the specific language governing permissions and
|
15
|
+
# limitations under the License.
|
16
|
+
|
17
|
+
require_relative 'cisco_cmn_utils'
|
18
|
+
require_relative 'node_util'
|
19
|
+
require_relative 'vrf'
|
20
|
+
require_relative 'overlay_global'
|
21
|
+
|
22
|
+
# Cisco provider module
|
23
|
+
module Cisco
|
24
|
+
IF_SWITCHPORT_MODE = {
|
25
|
+
disabled: '',
|
26
|
+
access: 'access',
|
27
|
+
trunk: 'trunk',
|
28
|
+
fex_fabric: 'fex-fabric',
|
29
|
+
tunnel: 'dot1q-tunnel',
|
30
|
+
fabricpath: 'fabricpath',
|
31
|
+
}
|
32
|
+
|
33
|
+
# Interface - node utility class for general interface config management
|
34
|
+
class Interface < NodeUtil
|
35
|
+
# Regexp to match various Ethernet interface variants:
|
36
|
+
# Ethernet
|
37
|
+
# GigabitEthernet
|
38
|
+
# TenGigE
|
39
|
+
# HundredGigE
|
40
|
+
# MgmtEth
|
41
|
+
ETHERNET = Regexp.new('(Ethernet|GigE|MgmtEth)', Regexp::IGNORECASE)
|
42
|
+
# Regexp to match various link bundle interface variants
|
43
|
+
PORTCHANNEL = Regexp.new('(port-channel|Bundle-Ether)', Regexp::IGNORECASE)
|
44
|
+
|
45
|
+
attr_reader :name, :state_default, :show_name
|
46
|
+
|
47
|
+
def initialize(name, instantiate=true, default_state=false, show_name=nil)
|
48
|
+
fail TypeError unless name.is_a?(String)
|
49
|
+
fail ArgumentError unless name.length > 0
|
50
|
+
|
51
|
+
# @name is used for context: keys only
|
52
|
+
# @show_name is used for get_command: keys; allows callers to limit
|
53
|
+
# show command to a single interface
|
54
|
+
@name = name.downcase
|
55
|
+
@show_name = show_name.nil? ? '' : Utils.normalize_intf_pattern(show_name)
|
56
|
+
@get_args = { name: @name, show_name: @show_name }
|
57
|
+
@smr = config_get('interface', 'stp_mst_range')
|
58
|
+
@svr = config_get('interface', 'stp_vlan_range')
|
59
|
+
@match_found = false
|
60
|
+
# Keep track of default vs non-default state for
|
61
|
+
# interfaces that cannot be created/destroyed.
|
62
|
+
@state_default = nil
|
63
|
+
# Track ethernet but not sub-interfaces
|
64
|
+
if @name[/ethernet/] && !@name[/ethernet.*\.\d+/]
|
65
|
+
@state_default = default_state
|
66
|
+
end
|
67
|
+
create if instantiate
|
68
|
+
end
|
69
|
+
|
70
|
+
def to_s
|
71
|
+
"interface #{name}"
|
72
|
+
end
|
73
|
+
|
74
|
+
def self.interface_count
|
75
|
+
config_get('interface', 'all_count').to_i
|
76
|
+
end
|
77
|
+
|
78
|
+
def self.interfaces(opt=nil, show_name=nil)
|
79
|
+
hash = {}
|
80
|
+
show_name = Utils.normalize_intf_pattern(show_name)
|
81
|
+
begin
|
82
|
+
intf_list = config_get('interface', 'all_interfaces',
|
83
|
+
show_name: show_name)
|
84
|
+
rescue CliError => e
|
85
|
+
raise unless show_name
|
86
|
+
# ignore logical interfaces that do not exist
|
87
|
+
debug 'Interface.interfaces ignoring CliError => ' + e.to_s
|
88
|
+
end
|
89
|
+
return hash if intf_list.nil?
|
90
|
+
|
91
|
+
# Massage intf_list data into an array that is easy to work with.
|
92
|
+
# Use a MARKER to hide pesky 'interface' substrings
|
93
|
+
intf_list.collect! { |x| x.strip || x }
|
94
|
+
intf_list.delete('')
|
95
|
+
intf_list.collect! { |x| (x.sub('interface', '~!MARKER!~') unless x[/^interface /]) || x } # rubocop:disable Metrics/LineLength
|
96
|
+
intf_list = intf_list.join(' ').split('interface')
|
97
|
+
intf_list.delete('')
|
98
|
+
# Restore 'interface' substrings
|
99
|
+
intf_list.collect! { |x| x.sub('~!MARKER!~', 'interface') }
|
100
|
+
|
101
|
+
intf_list.each do |id|
|
102
|
+
int_data = id.strip.split(' ')
|
103
|
+
next if int_data[0].nil?
|
104
|
+
id = int_data[0].downcase
|
105
|
+
next if opt && filter(opt, id, show_name)
|
106
|
+
# If there are any additional options associated
|
107
|
+
# with this interface then it's in a non-default
|
108
|
+
# state.
|
109
|
+
default_state = int_data.size > 1 ? false : true
|
110
|
+
hash[id] = Interface.new(id, false, default_state, show_name)
|
111
|
+
end
|
112
|
+
hash
|
113
|
+
end
|
114
|
+
|
115
|
+
# General-purpose filter for Interface.interfaces().
|
116
|
+
# filter: This may be overloaded in the future to allow a hash of filters.
|
117
|
+
# id: The interface name
|
118
|
+
# show_name: needed for get_command: <show_name>
|
119
|
+
# Return: true if the interface should be filtered out, false to keep it.
|
120
|
+
def self.filter(filter, id, show_name)
|
121
|
+
case filter
|
122
|
+
when :pvlan_any
|
123
|
+
return false if config_get('interface', 'pvlan_any',
|
124
|
+
name: id, show_name: show_name)
|
125
|
+
|
126
|
+
else
|
127
|
+
# Just a basic pattern filter (:ethernet, :loopback, etc)
|
128
|
+
return false if id.match(filter.to_s)
|
129
|
+
end
|
130
|
+
true
|
131
|
+
end
|
132
|
+
|
133
|
+
# 'capabilities' is a getter-only helper for minitest and beaker.
|
134
|
+
# mode values:
|
135
|
+
# :hash = Transform the output into a hash
|
136
|
+
# :raw = The raw output from 'show int capabilities'. Some multi-line
|
137
|
+
# values do not translate easily so this option allows the
|
138
|
+
# caller to extract the data it needs.
|
139
|
+
#
|
140
|
+
# Sample cli output:
|
141
|
+
# Model: N7K-M132XP-12L
|
142
|
+
# Type (SFP capable): 10Gbase-SR
|
143
|
+
# Speed: 10,100,1000
|
144
|
+
#
|
145
|
+
# Sample hash output:
|
146
|
+
# {"Model"=>"N7K-M132XP-12L", "Type"=>"10Gbase-SR", "Speed"=>"10,100,1000"}
|
147
|
+
#
|
148
|
+
def self.capabilities(intf, mode=:hash)
|
149
|
+
array = []
|
150
|
+
begin
|
151
|
+
array = config_get('interface', 'capabilities', name: intf)
|
152
|
+
rescue CliError => e
|
153
|
+
raise unless e.clierror[/(Invalid command|Cmd exec error)/]
|
154
|
+
end
|
155
|
+
return array if mode == :raw
|
156
|
+
hash = {}
|
157
|
+
if array
|
158
|
+
array.delete('')
|
159
|
+
array.each do |line|
|
160
|
+
k, v = line.split(':')
|
161
|
+
next if k.nil? || v.nil?
|
162
|
+
k.gsub!(/ \(.*\)/, '') # Remove any parenthetical text from key
|
163
|
+
v.strip!
|
164
|
+
v.gsub!(%r{half/full}, 'half,full') if k == 'Duplex'
|
165
|
+
hash[k] = v
|
166
|
+
end
|
167
|
+
end
|
168
|
+
hash
|
169
|
+
end
|
170
|
+
|
171
|
+
def create
|
172
|
+
feature_vlan_set(true) if @name[/(vlan|bdi)/i]
|
173
|
+
config_set('interface', 'create', name: @name)
|
174
|
+
rescue Cisco::CliError
|
175
|
+
# Some XR platforms do not support channel-group configuration
|
176
|
+
# on some OS versions. Since this is an OS version difference and not
|
177
|
+
# a platform difference, we can't handle this in the YAML.
|
178
|
+
raise unless PORTCHANNEL =~ @name && platform == :ios_xr
|
179
|
+
raise Cisco::UnsupportedError.new('interface', @name, 'create')
|
180
|
+
end
|
181
|
+
|
182
|
+
def destroy
|
183
|
+
if @name[/ethernet/] && !@name[/ethernet.*\.\d+/]
|
184
|
+
config_set('interface', 'default', name: @name)
|
185
|
+
else
|
186
|
+
config_set('interface', 'destroy', name: @name)
|
187
|
+
end
|
188
|
+
end
|
189
|
+
|
190
|
+
def default?
|
191
|
+
state = config_get('interface', 'default', @get_args)
|
192
|
+
state.nil? ? true : false
|
193
|
+
end
|
194
|
+
|
195
|
+
def pvlan_enable
|
196
|
+
switchport_enable
|
197
|
+
Feature.private_vlan_enable
|
198
|
+
end
|
199
|
+
|
200
|
+
########################################################
|
201
|
+
# PROPERTIES #
|
202
|
+
########################################################
|
203
|
+
|
204
|
+
# For range based attributes, a new attribute purge will
|
205
|
+
# be added in future. When purge is set to true, all the
|
206
|
+
# ranges which are specified in the manifest will be set
|
207
|
+
# to the desired values and those which are not specified
|
208
|
+
# in the manifest will be set to default. When purge is
|
209
|
+
# false, only the ranges specified in the manifest will
|
210
|
+
# be set to the values given in the manifest and others
|
211
|
+
# are left untouched.
|
212
|
+
|
213
|
+
def lacp_rate_shut_needed?
|
214
|
+
config_get('interface', 'lacp_rate_shut_needed')
|
215
|
+
end
|
216
|
+
|
217
|
+
def lacp_rate
|
218
|
+
config_get('interface', 'lacp_rate', @get_args)
|
219
|
+
end
|
220
|
+
|
221
|
+
def lacp_rate=(val)
|
222
|
+
if val
|
223
|
+
state = ''
|
224
|
+
else
|
225
|
+
return unless lacp_rate
|
226
|
+
state = 'no'
|
227
|
+
val = lacp_rate
|
228
|
+
end
|
229
|
+
int = Interface.new(@name, false)
|
230
|
+
current_state = int.shutdown
|
231
|
+
int.shutdown = true if lacp_rate_shut_needed? && !current_state
|
232
|
+
config_set('interface', 'lacp_rate', name: @name,
|
233
|
+
state: state, type: val)
|
234
|
+
int.shutdown = current_state unless current_state == int.shutdown
|
235
|
+
end
|
236
|
+
|
237
|
+
def default_lacp_rate
|
238
|
+
config_get_default('interface', 'lacp_rate')
|
239
|
+
end
|
240
|
+
|
241
|
+
def access_vlan
|
242
|
+
return nil if switchport_mode == :disabled
|
243
|
+
config_get('interface', 'access_vlan', @get_args)
|
244
|
+
end
|
245
|
+
|
246
|
+
def access_vlan=(vlan)
|
247
|
+
config_set('interface', 'access_vlan', name: @name, vlan: vlan)
|
248
|
+
end
|
249
|
+
|
250
|
+
def default_access_vlan
|
251
|
+
config_get_default('interface', 'access_vlan')
|
252
|
+
end
|
253
|
+
|
254
|
+
def bfd_echo
|
255
|
+
return nil unless Feature.bfd_enabled?
|
256
|
+
return nil if @name[/loop/i]
|
257
|
+
config_get('interface', 'bfd_echo', @get_args)
|
258
|
+
end
|
259
|
+
|
260
|
+
def bfd_echo=(val)
|
261
|
+
fail ArgumentError, 'Interface cannot be loopback' if
|
262
|
+
@name[/loop/i]
|
263
|
+
return if val == bfd_echo
|
264
|
+
state = (val ? '' : 'no')
|
265
|
+
Feature.bfd_enable
|
266
|
+
config_set('interface', 'bfd_echo',
|
267
|
+
name: @name, state: state)
|
268
|
+
end
|
269
|
+
|
270
|
+
def default_bfd_echo
|
271
|
+
return nil unless Feature.bfd_enabled?
|
272
|
+
return nil if @name[/loop/i]
|
273
|
+
config_get_default('interface', 'bfd_echo')
|
274
|
+
end
|
275
|
+
|
276
|
+
def description
|
277
|
+
config_get('interface', 'description', @get_args)
|
278
|
+
end
|
279
|
+
|
280
|
+
def description=(desc)
|
281
|
+
fail TypeError unless desc.is_a?(String)
|
282
|
+
if desc.strip.empty?
|
283
|
+
config_set('interface', 'description',
|
284
|
+
name: @name, state: 'no', desc: '')
|
285
|
+
else
|
286
|
+
config_set('interface', 'description',
|
287
|
+
name: @name, state: '', desc: desc)
|
288
|
+
end
|
289
|
+
end
|
290
|
+
|
291
|
+
def default_description
|
292
|
+
config_get_default('interface', 'description')
|
293
|
+
end
|
294
|
+
|
295
|
+
def encapsulation_dot1q
|
296
|
+
config_get('interface', 'encapsulation_dot1q', @get_args)
|
297
|
+
end
|
298
|
+
|
299
|
+
def encapsulation_dot1q=(val)
|
300
|
+
if val.to_s.empty?
|
301
|
+
config_set('interface', 'encapsulation_dot1q',
|
302
|
+
name: @name, state: 'no', vlan: '')
|
303
|
+
else
|
304
|
+
config_set('interface', 'encapsulation_dot1q',
|
305
|
+
name: @name, state: '', vlan: val)
|
306
|
+
end
|
307
|
+
end
|
308
|
+
|
309
|
+
def default_encapsulation_dot1q
|
310
|
+
config_get_default('interface', 'encapsulation_dot1q')
|
311
|
+
end
|
312
|
+
|
313
|
+
def fabricpath_feature
|
314
|
+
FabricpathGlobal.fabricpath_feature
|
315
|
+
end
|
316
|
+
|
317
|
+
def fabricpath_feature_set(fabricpath_set)
|
318
|
+
FabricpathGlobal.fabricpath_feature_set(fabricpath_set)
|
319
|
+
end
|
320
|
+
|
321
|
+
def fabric_forwarding_anycast_gateway
|
322
|
+
config_get('interface', 'fabric_forwarding_anycast_gateway', @get_args)
|
323
|
+
end
|
324
|
+
|
325
|
+
def fabric_forwarding_anycast_gateway=(state)
|
326
|
+
return if fabric_forwarding_anycast_gateway == state
|
327
|
+
no_cmd = (state ? '' : 'no')
|
328
|
+
config_set('interface',
|
329
|
+
'fabric_forwarding_anycast_gateway',
|
330
|
+
name: @name, state: no_cmd)
|
331
|
+
fail if fabric_forwarding_anycast_gateway.to_s != state.to_s
|
332
|
+
rescue Cisco::CliError => e
|
333
|
+
raise "#{e} 'fabric_forwarding_anycast_gateway' can only be " \
|
334
|
+
'configured on a vlan interface' unless /vlan/.match(@name)
|
335
|
+
anycast_gateway_mac = OverlayGlobal.new.anycast_gateway_mac
|
336
|
+
if anycast_gateway_mac.nil? || anycast_gateway_mac.empty?
|
337
|
+
raise "#{e} Anycast gateway mac must be configured " \
|
338
|
+
'before configuring forwarding mode under interface'
|
339
|
+
end
|
340
|
+
raise
|
341
|
+
end
|
342
|
+
|
343
|
+
def default_fabric_forwarding_anycast_gateway
|
344
|
+
config_get_default('interface', 'fabric_forwarding_anycast_gateway')
|
345
|
+
end
|
346
|
+
|
347
|
+
def hsrp_bfd
|
348
|
+
config_get('interface', 'hsrp_bfd', @get_args)
|
349
|
+
end
|
350
|
+
|
351
|
+
def hsrp_bfd=(val)
|
352
|
+
return if val == hsrp_bfd
|
353
|
+
state = val ? '' : 'no'
|
354
|
+
if val
|
355
|
+
Feature.hsrp_enable
|
356
|
+
Feature.bfd_enable
|
357
|
+
end
|
358
|
+
config_set('interface', 'hsrp_bfd', name: @name, state: state)
|
359
|
+
end
|
360
|
+
|
361
|
+
def default_hsrp_bfd
|
362
|
+
config_get_default('interface', 'hsrp_bfd')
|
363
|
+
end
|
364
|
+
|
365
|
+
# hsrp delay minimum and reload are in the same CLI
|
366
|
+
# hsrp delay minimum 0 reload 0
|
367
|
+
def hsrp_delay
|
368
|
+
match = config_get('interface', 'hsrp_delay', @get_args)
|
369
|
+
match.nil? ? default_hsrp_delay : match.collect(&:to_i)
|
370
|
+
end
|
371
|
+
|
372
|
+
def default_hsrp_delay
|
373
|
+
[default_hsrp_delay_minimum, default_hsrp_delay_reload]
|
374
|
+
end
|
375
|
+
|
376
|
+
def hsrp_delay_minimum
|
377
|
+
return nil if switchport_mode != :disabled || @name[/loop/i]
|
378
|
+
minimum, _reload = hsrp_delay
|
379
|
+
minimum.nil? ? default_hsrp_delay_minimum : minimum
|
380
|
+
end
|
381
|
+
|
382
|
+
# hsrp delay minimum and reload are in the same CLI
|
383
|
+
# but both can be set independent of each other
|
384
|
+
def hsrp_delay_minimum=(val)
|
385
|
+
Feature.hsrp_enable if val
|
386
|
+
config_set('interface', 'hsrp_delay', name: @name,
|
387
|
+
minimum: 'minimum', min: val, reload: '', rel: '')
|
388
|
+
end
|
389
|
+
|
390
|
+
def default_hsrp_delay_minimum
|
391
|
+
config_get_default('interface', 'hsrp_delay_minimum')
|
392
|
+
end
|
393
|
+
|
394
|
+
def hsrp_delay_reload
|
395
|
+
return nil if switchport_mode != :disabled || @name[/loop/i]
|
396
|
+
_minimum, reload = hsrp_delay
|
397
|
+
reload.nil? ? default_hsrp_delay_reload : reload
|
398
|
+
end
|
399
|
+
|
400
|
+
# hsrp delay minimum and reload are in the same CLI
|
401
|
+
# but both can be set independent of each other
|
402
|
+
def hsrp_delay_reload=(val)
|
403
|
+
Feature.hsrp_enable if val
|
404
|
+
config_set('interface', 'hsrp_delay', name: @name,
|
405
|
+
minimum: '', min: '', reload: 'reload', rel: val)
|
406
|
+
end
|
407
|
+
|
408
|
+
def default_hsrp_delay_reload
|
409
|
+
config_get_default('interface', 'hsrp_delay_reload')
|
410
|
+
end
|
411
|
+
|
412
|
+
def hsrp_mac_refresh
|
413
|
+
config_get('interface', 'hsrp_mac_refresh', @get_args)
|
414
|
+
end
|
415
|
+
|
416
|
+
def hsrp_mac_refresh=(val)
|
417
|
+
state = val ? '' : 'no'
|
418
|
+
time = val ? val : ''
|
419
|
+
Feature.hsrp_enable if val
|
420
|
+
config_set('interface', 'hsrp_mac_refresh', name: @name,
|
421
|
+
state: state, timeout: time)
|
422
|
+
end
|
423
|
+
|
424
|
+
def default_hsrp_mac_refresh
|
425
|
+
config_get_default('interface', 'hsrp_mac_refresh')
|
426
|
+
end
|
427
|
+
|
428
|
+
def hsrp_use_bia
|
429
|
+
match = config_get('interface', 'hsrp_use_bia', @get_args)
|
430
|
+
return default_hsrp_use_bia unless match
|
431
|
+
match.include?('scope') ? :use_bia_intf : :use_bia
|
432
|
+
end
|
433
|
+
|
434
|
+
def hsrp_use_bia=(val)
|
435
|
+
# Return early if device already set to the correct value
|
436
|
+
return if val == hsrp_use_bia
|
437
|
+
# need to reset before set
|
438
|
+
if val
|
439
|
+
Feature.hsrp_enable
|
440
|
+
if val == :use_bia
|
441
|
+
config_set('interface', 'hsrp_use_bia', name: name,
|
442
|
+
state: 'no', scope: ' scope interface')
|
443
|
+
config_set('interface', 'hsrp_use_bia', name: name,
|
444
|
+
state: '', scope: '')
|
445
|
+
else
|
446
|
+
config_set('interface', 'hsrp_use_bia', name: name,
|
447
|
+
state: 'no', scope: '')
|
448
|
+
config_set('interface', 'hsrp_use_bia', name: name,
|
449
|
+
state: '', scope: ' scope interface')
|
450
|
+
end
|
451
|
+
else
|
452
|
+
if hsrp_use_bia == :use_bia
|
453
|
+
config_set('interface', 'hsrp_use_bia', name: name,
|
454
|
+
state: 'no', scope: '')
|
455
|
+
else
|
456
|
+
config_set('interface', 'hsrp_use_bia', name: name,
|
457
|
+
state: 'no', scope: ' scope interface')
|
458
|
+
end
|
459
|
+
end
|
460
|
+
end
|
461
|
+
|
462
|
+
def default_hsrp_use_bia
|
463
|
+
config_get_default('interface', 'hsrp_use_bia')
|
464
|
+
end
|
465
|
+
|
466
|
+
def hsrp_version
|
467
|
+
return nil if switchport_mode != :disabled || @name[/loop/i]
|
468
|
+
config_get('interface', 'hsrp_version', @get_args)
|
469
|
+
end
|
470
|
+
|
471
|
+
def hsrp_version=(val)
|
472
|
+
Feature.hsrp_enable if val
|
473
|
+
config_set('interface', 'hsrp_version', name: name, ver: val)
|
474
|
+
end
|
475
|
+
|
476
|
+
def default_hsrp_version
|
477
|
+
config_get_default('interface', 'hsrp_version')
|
478
|
+
end
|
479
|
+
|
480
|
+
def ipv4_acl_in
|
481
|
+
config_get('interface', 'ipv4_acl_in', @get_args)
|
482
|
+
end
|
483
|
+
|
484
|
+
def ipv4_acl_in=(val)
|
485
|
+
if val != ''
|
486
|
+
state = ''
|
487
|
+
else
|
488
|
+
state = 'no'
|
489
|
+
val = ipv4_acl_in
|
490
|
+
end
|
491
|
+
|
492
|
+
return unless val && val != ''
|
493
|
+
config_set('interface', 'ipv4_acl_in',
|
494
|
+
name: @name, state: state, acl: val)
|
495
|
+
end
|
496
|
+
|
497
|
+
def default_ipv4_acl_in
|
498
|
+
config_get_default('interface', 'ipv4_acl_in')
|
499
|
+
end
|
500
|
+
|
501
|
+
def ipv4_acl_out
|
502
|
+
config_get('interface', 'ipv4_acl_out', @get_args)
|
503
|
+
end
|
504
|
+
|
505
|
+
def ipv4_acl_out=(val)
|
506
|
+
if val != ''
|
507
|
+
state = ''
|
508
|
+
else
|
509
|
+
state = 'no'
|
510
|
+
val = ipv4_acl_out
|
511
|
+
end
|
512
|
+
|
513
|
+
return unless val && val != ''
|
514
|
+
config_set('interface', 'ipv4_acl_out',
|
515
|
+
name: @name, state: state, acl: val)
|
516
|
+
end
|
517
|
+
|
518
|
+
def default_ipv4_acl_out
|
519
|
+
config_get_default('interface', 'ipv4_acl_out')
|
520
|
+
end
|
521
|
+
|
522
|
+
def ipv4_addr_mask_set(addr, mask, secondary=false)
|
523
|
+
check_switchport(:disabled)
|
524
|
+
sec = secondary ? 'secondary' : ''
|
525
|
+
if addr.nil? || addr == default_ipv4_address
|
526
|
+
state = 'no'
|
527
|
+
if secondary
|
528
|
+
return if ipv4_address_secondary == default_ipv4_address_secondary
|
529
|
+
# We need address and mask to remove.
|
530
|
+
am = "#{ipv4_address_secondary}/#{ipv4_netmask_length_secondary}"
|
531
|
+
else
|
532
|
+
return if ipv4_address == default_ipv4_address
|
533
|
+
am = "#{ipv4_address}/#{ipv4_netmask_length}"
|
534
|
+
end
|
535
|
+
else
|
536
|
+
state = ''
|
537
|
+
am = "#{addr}/#{mask}"
|
538
|
+
end
|
539
|
+
config_set('interface', 'ipv4_addr_mask',
|
540
|
+
name: @name, state: state, addr: am, secondary: sec)
|
541
|
+
end
|
542
|
+
|
543
|
+
def ipv4_addr_mask
|
544
|
+
val = config_get('interface', 'ipv4_addr_mask', @get_args)
|
545
|
+
if val && platform == :ios_xr
|
546
|
+
# IOS XR reports address as <address> <bitmask> [secondary] but we
|
547
|
+
# want <address>/<length> [secondary]
|
548
|
+
val.each_with_index do |entry, i|
|
549
|
+
mask = entry[1].split(' ')
|
550
|
+
mask[0] = Utils.bitmask_to_length(mask[0])
|
551
|
+
val[i][1] = mask.join(' ')
|
552
|
+
end
|
553
|
+
end
|
554
|
+
val
|
555
|
+
end
|
556
|
+
|
557
|
+
def select_ipv4_attribute(attribute)
|
558
|
+
d = ipv4_addr_mask.flatten unless ipv4_addr_mask.nil?
|
559
|
+
# (d)ata format after flatten: ['addr', 'mask', 'addr', 'mask secondary']
|
560
|
+
case attribute
|
561
|
+
when :v4_addr
|
562
|
+
v = d.nil? ? default_ipv4_address : d[0]
|
563
|
+
when :v4_mask
|
564
|
+
v = d.nil? ? default_ipv4_netmask_length : d[1].to_i
|
565
|
+
when :v4_addr_secondary
|
566
|
+
v = (d.nil? || d.size < 4) ? default_ipv4_address : d[2]
|
567
|
+
when :v4_mask_secondary
|
568
|
+
if d.nil? || d.size < 4
|
569
|
+
v = default_ipv4_netmask_length
|
570
|
+
else
|
571
|
+
v = d[3][0, 2].to_i
|
572
|
+
end
|
573
|
+
end
|
574
|
+
v
|
575
|
+
end
|
576
|
+
|
577
|
+
def ipv4_address
|
578
|
+
select_ipv4_attribute(:v4_addr)
|
579
|
+
end
|
580
|
+
|
581
|
+
def ipv4_address_secondary
|
582
|
+
select_ipv4_attribute(:v4_addr_secondary)
|
583
|
+
end
|
584
|
+
|
585
|
+
def ipv4_netmask_length
|
586
|
+
select_ipv4_attribute(:v4_mask)
|
587
|
+
end
|
588
|
+
|
589
|
+
def ipv4_netmask_length_secondary
|
590
|
+
select_ipv4_attribute(:v4_mask_secondary)
|
591
|
+
end
|
592
|
+
|
593
|
+
def default_ipv4_address
|
594
|
+
config_get_default('interface', 'ipv4_address')
|
595
|
+
end
|
596
|
+
|
597
|
+
def default_ipv4_address_secondary
|
598
|
+
default_ipv4_address
|
599
|
+
end
|
600
|
+
|
601
|
+
def default_ipv4_netmask_length
|
602
|
+
config_get_default('interface', 'ipv4_netmask_length')
|
603
|
+
end
|
604
|
+
|
605
|
+
def default_ipv4_netmask_length_secondary
|
606
|
+
default_ipv4_netmask_length
|
607
|
+
end
|
608
|
+
|
609
|
+
def ipv4_arp_timeout_lookup_string
|
610
|
+
case @name
|
611
|
+
when /vlan/i
|
612
|
+
return 'ipv4_arp_timeout'
|
613
|
+
else
|
614
|
+
return 'ipv4_arp_timeout_non_vlan_interfaces'
|
615
|
+
end
|
616
|
+
end
|
617
|
+
|
618
|
+
def ipv4_arp_timeout
|
619
|
+
config_get('interface', ipv4_arp_timeout_lookup_string, @get_args)
|
620
|
+
end
|
621
|
+
|
622
|
+
def ipv4_arp_timeout=(timeout)
|
623
|
+
fail "'ipv4 arp timeout' can ony be configured on a vlan interface" unless
|
624
|
+
/vlan/.match(@name)
|
625
|
+
state = (timeout == default_ipv4_arp_timeout) ? 'no' : ''
|
626
|
+
config_set('interface', 'ipv4_arp_timeout',
|
627
|
+
name: @name, state: state, timeout: timeout)
|
628
|
+
end
|
629
|
+
|
630
|
+
def default_ipv4_arp_timeout
|
631
|
+
config_get_default('interface', ipv4_arp_timeout_lookup_string)
|
632
|
+
end
|
633
|
+
|
634
|
+
def ipv4_dhcp_relay_addr
|
635
|
+
config_get('interface', 'ipv4_dhcp_relay_addr', @get_args)
|
636
|
+
end
|
637
|
+
|
638
|
+
def ipv4_dhcp_relay_addr=(list)
|
639
|
+
cur_list = ipv4_dhcp_relay_addr
|
640
|
+
# remove the current addresses first
|
641
|
+
unless cur_list.empty?
|
642
|
+
cur_list.each do |addr|
|
643
|
+
config_set('interface', 'ipv4_dhcp_relay_addr',
|
644
|
+
name: @name, state: 'no', addr: addr)
|
645
|
+
end
|
646
|
+
end
|
647
|
+
Feature.dhcp_enable unless list.empty?
|
648
|
+
list.each do |addr|
|
649
|
+
config_set('interface', 'ipv4_dhcp_relay_addr',
|
650
|
+
name: @name, state: '', addr: addr)
|
651
|
+
end
|
652
|
+
end
|
653
|
+
|
654
|
+
def default_ipv4_dhcp_relay_addr
|
655
|
+
config_get_default('interface', 'ipv4_dhcp_relay_addr')
|
656
|
+
end
|
657
|
+
|
658
|
+
def ipv4_dhcp_relay_info_trust
|
659
|
+
return nil if @name[/loop/i] || switchport_mode != :disabled
|
660
|
+
config_get('interface', 'ipv4_dhcp_relay_info_trust', @get_args)
|
661
|
+
end
|
662
|
+
|
663
|
+
def ipv4_dhcp_relay_info_trust=(state)
|
664
|
+
return false if !state && !Feature.dhcp_enabled?
|
665
|
+
Feature.dhcp_enable if state
|
666
|
+
config_set('interface', 'ipv4_dhcp_relay_info_trust',
|
667
|
+
name: @name, state: state ? '' : 'no')
|
668
|
+
end
|
669
|
+
|
670
|
+
def default_ipv4_dhcp_relay_info_trust
|
671
|
+
config_get_default('interface', 'ipv4_dhcp_relay_info_trust')
|
672
|
+
end
|
673
|
+
|
674
|
+
def ipv4_dhcp_relay_src_addr_hsrp
|
675
|
+
config_get('interface', 'ipv4_dhcp_relay_src_addr_hsrp', @get_args)
|
676
|
+
end
|
677
|
+
|
678
|
+
def ipv4_dhcp_relay_src_addr_hsrp=(state)
|
679
|
+
return false if !state && !Feature.dhcp_enabled?
|
680
|
+
Feature.dhcp_enable if state
|
681
|
+
config_set('interface', 'ipv4_dhcp_relay_src_addr_hsrp',
|
682
|
+
name: @name, state: state ? '' : 'no')
|
683
|
+
end
|
684
|
+
|
685
|
+
def default_ipv4_dhcp_relay_src_addr_hsrp
|
686
|
+
config_get_default('interface', 'ipv4_dhcp_relay_src_addr_hsrp')
|
687
|
+
end
|
688
|
+
|
689
|
+
def ipv4_dhcp_relay_src_intf
|
690
|
+
intf = config_get('interface', 'ipv4_dhcp_relay_src_intf', @get_args)
|
691
|
+
# Normalize by downcasing and removing white space
|
692
|
+
intf = intf.downcase.delete(' ') if intf
|
693
|
+
intf
|
694
|
+
end
|
695
|
+
|
696
|
+
def ipv4_dhcp_relay_src_intf=(val)
|
697
|
+
state = val == default_ipv4_dhcp_relay_src_intf ? 'no' : ''
|
698
|
+
return false if state == 'no' && !Feature.dhcp_enabled?
|
699
|
+
Feature.dhcp_enable if state.empty?
|
700
|
+
intf = val == default_ipv4_dhcp_relay_src_intf ? '' : val
|
701
|
+
config_set('interface', 'ipv4_dhcp_relay_src_intf',
|
702
|
+
name: @name, state: state, intf: intf)
|
703
|
+
end
|
704
|
+
|
705
|
+
def default_ipv4_dhcp_relay_src_intf
|
706
|
+
config_get_default('interface', 'ipv4_dhcp_relay_src_intf')
|
707
|
+
end
|
708
|
+
|
709
|
+
def ipv4_dhcp_relay_subnet_broadcast
|
710
|
+
return nil if @name[/loop/i] || switchport_mode != :disabled
|
711
|
+
config_get('interface', 'ipv4_dhcp_relay_subnet_broadcast', @get_args)
|
712
|
+
end
|
713
|
+
|
714
|
+
def ipv4_dhcp_relay_subnet_broadcast=(state)
|
715
|
+
return false if !state && !Feature.dhcp_enabled?
|
716
|
+
Feature.dhcp_enable if state
|
717
|
+
config_set('interface', 'ipv4_dhcp_relay_subnet_broadcast',
|
718
|
+
name: @name, state: state ? '' : 'no')
|
719
|
+
end
|
720
|
+
|
721
|
+
def default_ipv4_dhcp_relay_subnet_broadcast
|
722
|
+
config_get_default('interface', 'ipv4_dhcp_relay_subnet_broadcast')
|
723
|
+
end
|
724
|
+
|
725
|
+
def ipv4_dhcp_smart_relay
|
726
|
+
return nil if @name[/loop/i] || switchport_mode != :disabled
|
727
|
+
config_get('interface', 'ipv4_dhcp_smart_relay', @get_args)
|
728
|
+
end
|
729
|
+
|
730
|
+
def ipv4_dhcp_smart_relay=(state)
|
731
|
+
return false if !state && !Feature.dhcp_enabled?
|
732
|
+
Feature.dhcp_enable if state
|
733
|
+
config_set('interface', 'ipv4_dhcp_smart_relay',
|
734
|
+
name: @name, state: state ? '' : 'no')
|
735
|
+
end
|
736
|
+
|
737
|
+
def default_ipv4_dhcp_smart_relay
|
738
|
+
config_get_default('interface', 'ipv4_dhcp_smart_relay')
|
739
|
+
end
|
740
|
+
|
741
|
+
def ipv4_forwarding
|
742
|
+
config_get('interface', 'ipv4_forwarding', @get_args)
|
743
|
+
end
|
744
|
+
|
745
|
+
def ipv4_forwarding=(state)
|
746
|
+
return if state == ipv4_forwarding
|
747
|
+
config_set('interface', 'ipv4_forwarding',
|
748
|
+
name: @name, state: state ? '' : 'no')
|
749
|
+
end
|
750
|
+
|
751
|
+
def default_ipv4_forwarding
|
752
|
+
config_get_default('interface', 'ipv4_forwarding')
|
753
|
+
end
|
754
|
+
|
755
|
+
def ipv4_pim_sparse_mode
|
756
|
+
return nil unless switchport_mode == :disabled
|
757
|
+
config_get('interface', 'ipv4_pim_sparse_mode', @get_args)
|
758
|
+
end
|
759
|
+
|
760
|
+
def ipv4_pim_sparse_mode=(state)
|
761
|
+
check_switchport(:disabled)
|
762
|
+
Feature.pim_enable unless platform == :ios_xr
|
763
|
+
config_set('interface', 'ipv4_pim_sparse_mode',
|
764
|
+
name: @name, state: state ? '' : 'no')
|
765
|
+
end
|
766
|
+
|
767
|
+
def default_ipv4_pim_sparse_mode
|
768
|
+
config_get_default('interface', 'ipv4_pim_sparse_mode')
|
769
|
+
end
|
770
|
+
|
771
|
+
def ipv4_proxy_arp
|
772
|
+
return nil if @name[/loop/i] || switchport_mode != :disabled
|
773
|
+
config_get('interface', 'ipv4_proxy_arp', @get_args)
|
774
|
+
end
|
775
|
+
|
776
|
+
def ipv4_proxy_arp=(proxy_arp)
|
777
|
+
check_switchport(:disabled)
|
778
|
+
no_cmd = (proxy_arp ? '' : 'no')
|
779
|
+
config_set('interface', 'ipv4_proxy_arp', name: @name, state: no_cmd)
|
780
|
+
end
|
781
|
+
|
782
|
+
def default_ipv4_proxy_arp
|
783
|
+
config_get_default('interface', 'ipv4_proxy_arp')
|
784
|
+
end
|
785
|
+
|
786
|
+
def ipv4_redirects_lookup_string
|
787
|
+
case @name
|
788
|
+
when /loopback/i
|
789
|
+
return 'ipv4_redirects_loopback'
|
790
|
+
else
|
791
|
+
return 'ipv4_redirects_other_interfaces'
|
792
|
+
end
|
793
|
+
end
|
794
|
+
|
795
|
+
def ipv4_redirects
|
796
|
+
return nil unless switchport_mode == :disabled
|
797
|
+
config_get('interface', ipv4_redirects_lookup_string, @get_args)
|
798
|
+
end
|
799
|
+
|
800
|
+
def ipv4_redirects=(redirects)
|
801
|
+
check_switchport(:disabled)
|
802
|
+
no_cmd = (redirects ? '' : 'no')
|
803
|
+
config_set('interface', ipv4_redirects_lookup_string,
|
804
|
+
name: @name, state: no_cmd)
|
805
|
+
end
|
806
|
+
|
807
|
+
def default_ipv4_redirects
|
808
|
+
config_get_default('interface', ipv4_redirects_lookup_string)
|
809
|
+
end
|
810
|
+
|
811
|
+
def ipv6_acl_in
|
812
|
+
config_get('interface', 'ipv6_acl_in', @get_args)
|
813
|
+
end
|
814
|
+
|
815
|
+
def ipv6_acl_in=(val)
|
816
|
+
if val != ''
|
817
|
+
state = ''
|
818
|
+
else
|
819
|
+
state = 'no'
|
820
|
+
val = ipv6_acl_in
|
821
|
+
end
|
822
|
+
return unless val && val != ''
|
823
|
+
config_set('interface', 'ipv6_acl_in',
|
824
|
+
name: @name, state: state, acl: val)
|
825
|
+
end
|
826
|
+
|
827
|
+
def default_ipv6_acl_in
|
828
|
+
config_get_default('interface', 'ipv6_acl_in')
|
829
|
+
end
|
830
|
+
|
831
|
+
def ipv6_acl_out
|
832
|
+
config_get('interface', 'ipv6_acl_out', @get_args)
|
833
|
+
end
|
834
|
+
|
835
|
+
def ipv6_acl_out=(val)
|
836
|
+
if val != ''
|
837
|
+
state = ''
|
838
|
+
else
|
839
|
+
state = 'no'
|
840
|
+
val = ipv6_acl_out
|
841
|
+
end
|
842
|
+
return unless val && val != ''
|
843
|
+
config_set('interface', 'ipv6_acl_out',
|
844
|
+
name: @name, state: state, acl: val)
|
845
|
+
end
|
846
|
+
|
847
|
+
def default_ipv6_acl_out
|
848
|
+
config_get_default('interface', 'ipv6_acl_out')
|
849
|
+
end
|
850
|
+
|
851
|
+
def ipv6_dhcp_relay_addr
|
852
|
+
config_get('interface', 'ipv6_dhcp_relay_addr', @get_args)
|
853
|
+
end
|
854
|
+
|
855
|
+
def ipv6_dhcp_relay_addr=(list)
|
856
|
+
cur_list = ipv6_dhcp_relay_addr
|
857
|
+
# remove the current addresses first
|
858
|
+
unless cur_list.empty?
|
859
|
+
cur_list.each do |addr|
|
860
|
+
config_set('interface', 'ipv6_dhcp_relay_addr',
|
861
|
+
name: @name, state: 'no', addr: addr)
|
862
|
+
end
|
863
|
+
end
|
864
|
+
Feature.dhcp_enable unless list.empty?
|
865
|
+
list.each do |addr|
|
866
|
+
config_set('interface', 'ipv6_dhcp_relay_addr',
|
867
|
+
name: @name, state: '', addr: addr)
|
868
|
+
end
|
869
|
+
end
|
870
|
+
|
871
|
+
def default_ipv6_dhcp_relay_addr
|
872
|
+
config_get_default('interface', 'ipv6_dhcp_relay_addr')
|
873
|
+
end
|
874
|
+
|
875
|
+
def ipv6_dhcp_relay_src_intf
|
876
|
+
intf = config_get('interface', 'ipv6_dhcp_relay_src_intf', @get_args)
|
877
|
+
# Normalize by downcasing and removing white space
|
878
|
+
intf = intf.downcase.delete(' ') if intf
|
879
|
+
intf
|
880
|
+
end
|
881
|
+
|
882
|
+
def ipv6_dhcp_relay_src_intf=(val)
|
883
|
+
state = val == default_ipv6_dhcp_relay_src_intf ? 'no' : ''
|
884
|
+
return false if state == 'no' && !Feature.dhcp_enabled?
|
885
|
+
Feature.dhcp_enable if state.empty?
|
886
|
+
intf = val == default_ipv6_dhcp_relay_src_intf ? '' : val
|
887
|
+
config_set('interface', 'ipv6_dhcp_relay_src_intf',
|
888
|
+
name: @name, state: state, intf: intf)
|
889
|
+
end
|
890
|
+
|
891
|
+
def default_ipv6_dhcp_relay_src_intf
|
892
|
+
config_get_default('interface', 'ipv6_dhcp_relay_src_intf')
|
893
|
+
end
|
894
|
+
|
895
|
+
def ipv6_redirects
|
896
|
+
return nil if @name[/loop/i] || switchport_mode != :disabled
|
897
|
+
config_get('interface', 'ipv6_redirects', @get_args)
|
898
|
+
end
|
899
|
+
|
900
|
+
def ipv6_redirects=(redirects)
|
901
|
+
check_switchport(:disabled)
|
902
|
+
no_cmd = (redirects ? '' : 'no')
|
903
|
+
config_set('interface', 'ipv6_redirects',
|
904
|
+
name: @name, state: no_cmd)
|
905
|
+
end
|
906
|
+
|
907
|
+
def default_ipv6_redirects
|
908
|
+
config_get_default('interface', 'ipv6_redirects')
|
909
|
+
end
|
910
|
+
|
911
|
+
def feature_lacp?
|
912
|
+
config_get('interface', 'feature_lacp')
|
913
|
+
end
|
914
|
+
|
915
|
+
def feature_lacp_set(val)
|
916
|
+
return if feature_lacp? == val
|
917
|
+
config_set('interface', 'feature_lacp', state: val ? '' : 'no')
|
918
|
+
end
|
919
|
+
|
920
|
+
def load_interval_counter_1_delay
|
921
|
+
return nil if @name[/loop/] || @name[/ethernet.*\S+\.\d+$/]
|
922
|
+
config_get('interface', 'load_interval_counter_1_delay', @get_args)
|
923
|
+
end
|
924
|
+
|
925
|
+
def load_interval_counter_1_delay=(val)
|
926
|
+
fail ArgumentError, 'Interface cannot be sub-intf or loopback' if
|
927
|
+
@name[/loop/] || @name[/ethernet.*\S+\.\d+$/]
|
928
|
+
config_set('interface', 'load_interval_counter_1_delay',
|
929
|
+
name: @name, delay: val)
|
930
|
+
end
|
931
|
+
|
932
|
+
def default_load_interval_counter_1_delay
|
933
|
+
# for vlan and bdi the default is 60
|
934
|
+
if @name[/(vlan|bdi)/i]
|
935
|
+
config_get_default('interface',
|
936
|
+
'load_interval_counter_1_delay_vlan_bdi')
|
937
|
+
else
|
938
|
+
config_get_default('interface', 'load_interval_counter_1_delay')
|
939
|
+
end
|
940
|
+
end
|
941
|
+
|
942
|
+
def load_interval_counter_2_delay
|
943
|
+
return nil if @name[/loop/] || @name[/ethernet.*\S+\.\d+$/]
|
944
|
+
config_get('interface', 'load_interval_counter_2_delay', @get_args)
|
945
|
+
end
|
946
|
+
|
947
|
+
def load_interval_counter_2_delay=(val)
|
948
|
+
fail ArgumentError, 'Interface cannot be sub-intf or loopback' if
|
949
|
+
@name[/loop/] || @name[/ethernet.*\S+\.\d+$/]
|
950
|
+
config_set('interface', 'load_interval_counter_2_delay',
|
951
|
+
name: @name, delay: val)
|
952
|
+
end
|
953
|
+
|
954
|
+
def default_load_interval_counter_2_delay
|
955
|
+
config_get_default('interface', 'load_interval_counter_2_delay')
|
956
|
+
end
|
957
|
+
|
958
|
+
def load_interval_counter_3_delay
|
959
|
+
return nil if @name[/loop/] || @name[/ethernet.*\S+\.\d+$/]
|
960
|
+
config_get('interface', 'load_interval_counter_3_delay', @get_args)
|
961
|
+
end
|
962
|
+
|
963
|
+
def load_interval_counter_3_delay=(val)
|
964
|
+
fail ArgumentError, 'Interface cannot be sub-intf or loopback' if
|
965
|
+
@name[/loop/] || @name[/ethernet.*\S+\.\d+$/]
|
966
|
+
state = val ? '' : 'no'
|
967
|
+
delay = val ? val : ''
|
968
|
+
config_set('interface', 'load_interval_counter_3_delay',
|
969
|
+
name: @name, state: state, delay: delay)
|
970
|
+
end
|
971
|
+
|
972
|
+
def default_load_interval_counter_3_delay
|
973
|
+
config_get_default('interface', 'load_interval_counter_3_delay')
|
974
|
+
end
|
975
|
+
|
976
|
+
def mtu_lookup_string
|
977
|
+
case @name
|
978
|
+
when /loopback/i
|
979
|
+
return 'mtu_loopback'
|
980
|
+
else
|
981
|
+
return 'mtu_other_interfaces'
|
982
|
+
end
|
983
|
+
end
|
984
|
+
|
985
|
+
def mtu
|
986
|
+
config_get('interface', mtu_lookup_string, @get_args)
|
987
|
+
end
|
988
|
+
|
989
|
+
def mtu=(val)
|
990
|
+
return if mtu == val
|
991
|
+
check_switchport(:disabled)
|
992
|
+
config_set('interface', mtu_lookup_string,
|
993
|
+
name: @name, state: '', mtu: val)
|
994
|
+
end
|
995
|
+
|
996
|
+
def default_mtu
|
997
|
+
config_get_default('interface', mtu_lookup_string)
|
998
|
+
end
|
999
|
+
|
1000
|
+
def speed
|
1001
|
+
return nil if @name[/loop|vlan/i]
|
1002
|
+
config_get('interface', 'speed', @get_args)
|
1003
|
+
end
|
1004
|
+
|
1005
|
+
def speed=(val)
|
1006
|
+
config_set('interface', 'speed', name: @name, speed: val)
|
1007
|
+
end
|
1008
|
+
|
1009
|
+
def default_speed
|
1010
|
+
config_get_default('interface', 'speed')
|
1011
|
+
end
|
1012
|
+
|
1013
|
+
def duplex
|
1014
|
+
return nil if @name[/loop|vlan/i]
|
1015
|
+
config_get('interface', 'duplex', @get_args)
|
1016
|
+
end
|
1017
|
+
|
1018
|
+
def duplex=(val)
|
1019
|
+
config_set('interface', 'duplex', name: @name, duplex: val)
|
1020
|
+
end
|
1021
|
+
|
1022
|
+
def default_duplex
|
1023
|
+
config_get_default('interface', 'duplex')
|
1024
|
+
end
|
1025
|
+
|
1026
|
+
def negotiate_auto_lookup_string
|
1027
|
+
case @name
|
1028
|
+
when ETHERNET
|
1029
|
+
return 'negotiate_auto_ethernet'
|
1030
|
+
when PORTCHANNEL
|
1031
|
+
return 'negotiate_auto_portchannel'
|
1032
|
+
else
|
1033
|
+
return 'negotiate_auto_other_interfaces'
|
1034
|
+
end
|
1035
|
+
end
|
1036
|
+
|
1037
|
+
def negotiate_auto
|
1038
|
+
return nil if @name[/loop|vlan/]
|
1039
|
+
config_get('interface', negotiate_auto_lookup_string, @get_args)
|
1040
|
+
end
|
1041
|
+
|
1042
|
+
def negotiate_auto=(negotiate_auto)
|
1043
|
+
lookup = negotiate_auto_lookup_string
|
1044
|
+
no_cmd = (negotiate_auto ? '' : 'no')
|
1045
|
+
config_set('interface', lookup, name: @name, state: no_cmd)
|
1046
|
+
end
|
1047
|
+
|
1048
|
+
def default_negotiate_auto
|
1049
|
+
config_get_default('interface', negotiate_auto_lookup_string)
|
1050
|
+
end
|
1051
|
+
|
1052
|
+
def shutdown
|
1053
|
+
config_get('interface', 'shutdown', @get_args)
|
1054
|
+
end
|
1055
|
+
|
1056
|
+
def shutdown=(state)
|
1057
|
+
no_cmd = (state ? '' : 'no')
|
1058
|
+
config_set('interface', 'shutdown', name: @name, state: no_cmd)
|
1059
|
+
end
|
1060
|
+
|
1061
|
+
def default_shutdown
|
1062
|
+
case @name
|
1063
|
+
when ETHERNET
|
1064
|
+
def_sw = system_default_switchport
|
1065
|
+
def_shut = system_default_switchport_shutdown
|
1066
|
+
|
1067
|
+
if def_sw && def_shut
|
1068
|
+
lookup = 'shutdown_ethernet_switchport_shutdown'
|
1069
|
+
elsif def_sw && !def_shut
|
1070
|
+
lookup = 'shutdown_ethernet_switchport_noshutdown'
|
1071
|
+
elsif !def_sw && def_shut
|
1072
|
+
lookup = 'shutdown_ethernet_noswitchport_shutdown'
|
1073
|
+
elsif !def_sw && !def_shut
|
1074
|
+
lookup = 'shutdown_ethernet_noswitchport_noshutdown'
|
1075
|
+
else
|
1076
|
+
fail "Error: def_sw #{def_sw}, def_shut #{def_shut}"
|
1077
|
+
end
|
1078
|
+
|
1079
|
+
when /loopback/i
|
1080
|
+
lookup = 'shutdown_loopback'
|
1081
|
+
|
1082
|
+
when PORTCHANNEL
|
1083
|
+
lookup = 'shutdown_ether_channel'
|
1084
|
+
|
1085
|
+
when /Vlan/i
|
1086
|
+
lookup = 'shutdown_vlan'
|
1087
|
+
|
1088
|
+
else
|
1089
|
+
lookup = 'shutdown_unknown'
|
1090
|
+
end
|
1091
|
+
config_get_default('interface', lookup)
|
1092
|
+
end
|
1093
|
+
|
1094
|
+
def pim_bfd
|
1095
|
+
config_get('interface', 'pim_bfd', @get_args)
|
1096
|
+
end
|
1097
|
+
|
1098
|
+
def pim_bfd=(val)
|
1099
|
+
return if val == pim_bfd
|
1100
|
+
state = val ? '' : 'no'
|
1101
|
+
if val
|
1102
|
+
Feature.pim_enable
|
1103
|
+
Feature.bfd_enable
|
1104
|
+
end
|
1105
|
+
config_set('interface', 'pim_bfd', name: @name, state: state)
|
1106
|
+
end
|
1107
|
+
|
1108
|
+
def default_pim_bfd
|
1109
|
+
config_get_default('interface', 'pim_bfd')
|
1110
|
+
end
|
1111
|
+
|
1112
|
+
def storm_control_broadcast
|
1113
|
+
return nil if @name[/loop|vlan/i]
|
1114
|
+
config_get('interface', 'storm_control_broadcast', @get_args)
|
1115
|
+
end
|
1116
|
+
|
1117
|
+
def storm_control_broadcast=(val)
|
1118
|
+
return if val == storm_control_broadcast
|
1119
|
+
state = val == default_storm_control_broadcast ? 'no' : ''
|
1120
|
+
level = val == default_storm_control_broadcast ? '' : val
|
1121
|
+
config_set('interface', 'storm_control_broadcast',
|
1122
|
+
name: @name, state: state, level: level)
|
1123
|
+
end
|
1124
|
+
|
1125
|
+
def default_storm_control_broadcast
|
1126
|
+
config_get_default('interface', 'storm_control_broadcast')
|
1127
|
+
end
|
1128
|
+
|
1129
|
+
def storm_control_multicast
|
1130
|
+
return nil if @name[/loop|vlan/i]
|
1131
|
+
config_get('interface', 'storm_control_multicast', @get_args)
|
1132
|
+
end
|
1133
|
+
|
1134
|
+
def storm_control_multicast=(val)
|
1135
|
+
return if val == storm_control_multicast
|
1136
|
+
state = val == default_storm_control_multicast ? 'no' : ''
|
1137
|
+
level = val == default_storm_control_multicast ? '' : val
|
1138
|
+
config_set('interface', 'storm_control_multicast',
|
1139
|
+
name: @name, state: state, level: level)
|
1140
|
+
end
|
1141
|
+
|
1142
|
+
def default_storm_control_multicast
|
1143
|
+
config_get_default('interface', 'storm_control_multicast')
|
1144
|
+
end
|
1145
|
+
|
1146
|
+
def storm_control_unicast
|
1147
|
+
return nil if @name[/loop|vlan/i]
|
1148
|
+
config_get('interface', 'storm_control_unicast', @get_args)
|
1149
|
+
end
|
1150
|
+
|
1151
|
+
def storm_control_unicast=(val)
|
1152
|
+
return if val == storm_control_unicast
|
1153
|
+
state = val == default_storm_control_unicast ? 'no' : ''
|
1154
|
+
level = val == default_storm_control_unicast ? '' : val
|
1155
|
+
config_set('interface', 'storm_control_unicast',
|
1156
|
+
name: @name, state: state, level: level)
|
1157
|
+
end
|
1158
|
+
|
1159
|
+
def default_storm_control_unicast
|
1160
|
+
config_get_default('interface', 'storm_control_unicast')
|
1161
|
+
end
|
1162
|
+
|
1163
|
+
def stp_bpdufilter
|
1164
|
+
config_get('interface', 'stp_bpdufilter', @get_args)
|
1165
|
+
end
|
1166
|
+
|
1167
|
+
def stp_bpdufilter=(val)
|
1168
|
+
check_switchport([:access, :trunk])
|
1169
|
+
if val
|
1170
|
+
state = ''
|
1171
|
+
else
|
1172
|
+
state = 'no'
|
1173
|
+
val = ''
|
1174
|
+
end
|
1175
|
+
config_set('interface',
|
1176
|
+
'stp_bpdufilter', name: @name, state: state, filter: val)
|
1177
|
+
end
|
1178
|
+
|
1179
|
+
def default_stp_bpdufilter
|
1180
|
+
config_get_default('interface', 'stp_bpdufilter')
|
1181
|
+
end
|
1182
|
+
|
1183
|
+
def stp_bpduguard
|
1184
|
+
config_get('interface', 'stp_bpduguard', @get_args)
|
1185
|
+
end
|
1186
|
+
|
1187
|
+
def stp_bpduguard=(val)
|
1188
|
+
if val
|
1189
|
+
state = ''
|
1190
|
+
else
|
1191
|
+
state = 'no'
|
1192
|
+
val = ''
|
1193
|
+
end
|
1194
|
+
config_set('interface',
|
1195
|
+
'stp_bpduguard', name: @name, state: state, guard: val)
|
1196
|
+
end
|
1197
|
+
|
1198
|
+
def default_stp_bpduguard
|
1199
|
+
config_get_default('interface', 'stp_bpduguard')
|
1200
|
+
end
|
1201
|
+
|
1202
|
+
def stp_cost
|
1203
|
+
return nil if switchport_mode == :disabled
|
1204
|
+
cost = config_get('interface', 'stp_cost', @get_args)
|
1205
|
+
cost == 'auto' ? cost : cost.to_i
|
1206
|
+
end
|
1207
|
+
|
1208
|
+
def stp_cost=(val)
|
1209
|
+
check_switchport([:access, :trunk])
|
1210
|
+
config_set('interface', 'stp_cost', name: @name, cost: val)
|
1211
|
+
end
|
1212
|
+
|
1213
|
+
def default_stp_cost
|
1214
|
+
config_get_default('interface', 'stp_cost')
|
1215
|
+
end
|
1216
|
+
|
1217
|
+
def stp_guard
|
1218
|
+
config_get('interface', 'stp_guard', @get_args)
|
1219
|
+
end
|
1220
|
+
|
1221
|
+
def stp_guard=(val)
|
1222
|
+
check_switchport([:access, :trunk])
|
1223
|
+
if val
|
1224
|
+
state = ''
|
1225
|
+
else
|
1226
|
+
state = 'no'
|
1227
|
+
val = ''
|
1228
|
+
end
|
1229
|
+
config_set('interface', 'stp_guard', name: @name, state: state,
|
1230
|
+
guard: val)
|
1231
|
+
end
|
1232
|
+
|
1233
|
+
def default_stp_guard
|
1234
|
+
config_get_default('interface', 'stp_guard')
|
1235
|
+
end
|
1236
|
+
|
1237
|
+
def stp_link_type
|
1238
|
+
return nil if switchport_mode == :disabled
|
1239
|
+
config_get('interface', 'stp_link_type', @get_args)
|
1240
|
+
end
|
1241
|
+
|
1242
|
+
def stp_link_type=(val)
|
1243
|
+
check_switchport([:access, :trunk])
|
1244
|
+
config_set('interface', 'stp_link_type', name: @name, type: val)
|
1245
|
+
end
|
1246
|
+
|
1247
|
+
def default_stp_link_type
|
1248
|
+
config_get_default('interface', 'stp_link_type')
|
1249
|
+
end
|
1250
|
+
|
1251
|
+
def stp_port_priority
|
1252
|
+
return nil if switchport_mode == :disabled
|
1253
|
+
config_get('interface', 'stp_port_priority', @get_args)
|
1254
|
+
end
|
1255
|
+
|
1256
|
+
def stp_port_priority=(val)
|
1257
|
+
check_switchport([:access, :trunk])
|
1258
|
+
config_set('interface', 'stp_port_priority', name: @name, pp: val)
|
1259
|
+
end
|
1260
|
+
|
1261
|
+
def default_stp_port_priority
|
1262
|
+
config_get_default('interface', 'stp_port_priority')
|
1263
|
+
end
|
1264
|
+
|
1265
|
+
# Getter: Builds an array of mst cost commands currently
|
1266
|
+
# on the device.
|
1267
|
+
# cli: spanning-tree mst 0,2-4,6,8-12 cost 1000
|
1268
|
+
# spanning-tree mst 4000-4020 cost 2568
|
1269
|
+
# array: [['0,2-4,6,8-12', '1000'], ['4000-4020', '2568']]
|
1270
|
+
#
|
1271
|
+
def stp_mst_cost
|
1272
|
+
config_get('interface', 'stp_mst_cost', @get_args)
|
1273
|
+
end
|
1274
|
+
|
1275
|
+
def stp_mst_cost=(list)
|
1276
|
+
check_switchport([:access, :trunk])
|
1277
|
+
config_set('interface', 'stp_mst_cost',
|
1278
|
+
name: @name, state: 'no', range: @smr,
|
1279
|
+
val: '') if list.empty?
|
1280
|
+
set_range_based_params(list, 'stp_mst_cost')
|
1281
|
+
end
|
1282
|
+
|
1283
|
+
def default_stp_mst_cost
|
1284
|
+
config_get_default('interface', 'stp_mst_cost')
|
1285
|
+
end
|
1286
|
+
|
1287
|
+
# Getter: Builds an array of mst port-priority commands
|
1288
|
+
# currently on the device.
|
1289
|
+
# cli: spanning-tree mst 0,2-4,6,8-12 port-priority 64
|
1290
|
+
# spanning-tree mst 4000-4020 port-priority 160
|
1291
|
+
# array: [['0,2-4,6,8-12', '64'], ['4000-4020', '160']]
|
1292
|
+
#
|
1293
|
+
def stp_mst_port_priority
|
1294
|
+
config_get('interface', 'stp_mst_port_priority', @get_args)
|
1295
|
+
end
|
1296
|
+
|
1297
|
+
def stp_mst_port_priority=(list)
|
1298
|
+
check_switchport([:access, :trunk])
|
1299
|
+
config_set('interface', 'stp_mst_port_priority',
|
1300
|
+
name: @name, state: 'no', range: @smr,
|
1301
|
+
val: '') if list.empty?
|
1302
|
+
set_range_based_params(list, 'stp_mst_port_priority')
|
1303
|
+
end
|
1304
|
+
|
1305
|
+
def default_stp_mst_port_priority
|
1306
|
+
config_get_default('interface', 'stp_mst_port_priority')
|
1307
|
+
end
|
1308
|
+
|
1309
|
+
def stp_port_type
|
1310
|
+
config_get('interface', 'stp_port_type', @get_args)
|
1311
|
+
end
|
1312
|
+
|
1313
|
+
def stp_port_type=(val)
|
1314
|
+
if val
|
1315
|
+
state = ''
|
1316
|
+
else
|
1317
|
+
return unless stp_port_type
|
1318
|
+
state = 'no'
|
1319
|
+
val = stp_port_type
|
1320
|
+
end
|
1321
|
+
config_set('interface', 'stp_port_type', name: @name,
|
1322
|
+
state: state, type: val)
|
1323
|
+
end
|
1324
|
+
|
1325
|
+
def default_stp_port_type
|
1326
|
+
config_get_default('interface', 'stp_port_type')
|
1327
|
+
end
|
1328
|
+
|
1329
|
+
# Getter: Builds an array of vlan cost commands currently
|
1330
|
+
# on the device.
|
1331
|
+
# cli: spanning-tree vlan 1-4,6,8-12 cost 1000
|
1332
|
+
# spanning-tree vlan 3000-3960 cost 2568
|
1333
|
+
# array: [['1-4,6,8-12', '1000'], ['3000-3960', '2568']]
|
1334
|
+
#
|
1335
|
+
def stp_vlan_cost
|
1336
|
+
config_get('interface', 'stp_vlan_cost', @get_args)
|
1337
|
+
end
|
1338
|
+
|
1339
|
+
def stp_vlan_cost=(list)
|
1340
|
+
check_switchport([:access, :trunk])
|
1341
|
+
config_set('interface', 'stp_vlan_cost',
|
1342
|
+
name: @name, state: 'no',
|
1343
|
+
range: @svr, val: '') if list.empty?
|
1344
|
+
set_range_based_params(list, 'stp_vlan_cost')
|
1345
|
+
end
|
1346
|
+
|
1347
|
+
def default_stp_vlan_cost
|
1348
|
+
config_get_default('interface', 'stp_vlan_cost')
|
1349
|
+
end
|
1350
|
+
|
1351
|
+
# Getter: Builds an array of vlan port-priority commands
|
1352
|
+
# currently on the device.
|
1353
|
+
# cli: spanning-tree vlan 1-4,6,8-12 port-priority 64
|
1354
|
+
# spanning-tree vlan 3000-3960 port-priority 160
|
1355
|
+
# array: [['1-4,6,8-12', '64'], ['3000-3960', '160']]
|
1356
|
+
#
|
1357
|
+
def stp_vlan_port_priority
|
1358
|
+
config_get('interface', 'stp_vlan_port_priority', @get_args)
|
1359
|
+
end
|
1360
|
+
|
1361
|
+
def stp_vlan_port_priority=(list)
|
1362
|
+
check_switchport([:access, :trunk])
|
1363
|
+
config_set('interface', 'stp_vlan_port_priority',
|
1364
|
+
name: @name, state: 'no',
|
1365
|
+
range: @svr, val: '') if list.empty?
|
1366
|
+
set_range_based_params(list, 'stp_vlan_port_priority')
|
1367
|
+
end
|
1368
|
+
|
1369
|
+
def default_stp_vlan_port_priority
|
1370
|
+
config_get_default('interface', 'stp_vlan_port_priority')
|
1371
|
+
end
|
1372
|
+
|
1373
|
+
def switchport
|
1374
|
+
# This is "switchport", not "switchport mode"
|
1375
|
+
config_get('interface', 'switchport', @get_args)
|
1376
|
+
end
|
1377
|
+
|
1378
|
+
def switchport_enable(val=true)
|
1379
|
+
config_set('interface', 'switchport', name: @name, state: val ? '' : 'no')
|
1380
|
+
end
|
1381
|
+
|
1382
|
+
# switchport_autostate_exclude is exclusive to switchport interfaces
|
1383
|
+
def switchport_autostate_exclude
|
1384
|
+
return nil if switchport_mode == :disabled
|
1385
|
+
config_get('interface', 'switchport_autostate_exclude', @get_args)
|
1386
|
+
end
|
1387
|
+
|
1388
|
+
def switchport_autostate_exclude=(val)
|
1389
|
+
if platform == :nexus
|
1390
|
+
# cannot configure autostate unless feature vlan is enabled
|
1391
|
+
fail('switchport mode must be configured before ' \
|
1392
|
+
'switchport autostate') unless switchport
|
1393
|
+
feature_vlan_set(true)
|
1394
|
+
end
|
1395
|
+
config_set('interface', 'switchport_autostate_exclude',
|
1396
|
+
name: @name, state: val ? '' : 'no')
|
1397
|
+
end
|
1398
|
+
|
1399
|
+
def default_switchport_autostate_exclude
|
1400
|
+
config_get_default('interface', 'switchport_autostate_exclude')
|
1401
|
+
end
|
1402
|
+
|
1403
|
+
def switchport_mode_lookup_string
|
1404
|
+
case @name
|
1405
|
+
when ETHERNET
|
1406
|
+
return 'switchport_mode_ethernet'
|
1407
|
+
when PORTCHANNEL
|
1408
|
+
return 'switchport_mode_port_channel'
|
1409
|
+
else
|
1410
|
+
return 'switchport_mode_other_interfaces'
|
1411
|
+
end
|
1412
|
+
end
|
1413
|
+
|
1414
|
+
def switchport_mode
|
1415
|
+
return nil if platform == :ios_xr
|
1416
|
+
mode = config_get('interface', switchport_mode_lookup_string, @get_args)
|
1417
|
+
|
1418
|
+
return mode.nil? ? :disabled : IF_SWITCHPORT_MODE.key(mode)
|
1419
|
+
|
1420
|
+
rescue IndexError
|
1421
|
+
# Assume this is an interface that doesn't support switchport.
|
1422
|
+
# Do not raise exception since the providers will prefetch this property
|
1423
|
+
# regardless of interface type.
|
1424
|
+
# TODO: this should probably be nil instead
|
1425
|
+
return :disabled
|
1426
|
+
end
|
1427
|
+
|
1428
|
+
def switchport_enable_and_mode(mode_set)
|
1429
|
+
switchport_enable
|
1430
|
+
|
1431
|
+
if :fabricpath == mode_set
|
1432
|
+
fabricpath_feature_set(:enabled) unless :enabled == fabricpath_feature
|
1433
|
+
elsif :fex_fabric == mode_set
|
1434
|
+
Feature.fex_enable
|
1435
|
+
end
|
1436
|
+
config_set('interface', switchport_mode_lookup_string,
|
1437
|
+
name: @name, state: '', mode: IF_SWITCHPORT_MODE[mode_set])
|
1438
|
+
end
|
1439
|
+
|
1440
|
+
def switchport_mode=(mode_set)
|
1441
|
+
# no system default switchport
|
1442
|
+
# int e1/1
|
1443
|
+
# switchport
|
1444
|
+
# switchport mode [access|trunk|fex|...]
|
1445
|
+
fail ArgumentError unless IF_SWITCHPORT_MODE.keys.include? mode_set
|
1446
|
+
case mode_set
|
1447
|
+
when :disabled
|
1448
|
+
if switchport
|
1449
|
+
# Note: turn off switchport command, not switchport mode
|
1450
|
+
config_set('interface', 'switchport', name: @name, state: 'no')
|
1451
|
+
end
|
1452
|
+
|
1453
|
+
when :default
|
1454
|
+
if :disabled == default_switchport_mode
|
1455
|
+
config_set('interface', switchport_mode_lookup_string,
|
1456
|
+
name: @name, state: 'no', mode: '')
|
1457
|
+
else
|
1458
|
+
switchport_enable_and_mode(mode_set)
|
1459
|
+
end
|
1460
|
+
|
1461
|
+
else
|
1462
|
+
switchport_enable_and_mode(mode_set)
|
1463
|
+
end # case
|
1464
|
+
end
|
1465
|
+
|
1466
|
+
def default_switchport_mode
|
1467
|
+
return nil if platform == :ios_xr
|
1468
|
+
return :disabled unless system_default_switchport
|
1469
|
+
IF_SWITCHPORT_MODE.key(
|
1470
|
+
config_get_default('interface', switchport_mode_lookup_string))
|
1471
|
+
end
|
1472
|
+
|
1473
|
+
def switchport_trunk_allowed_vlan
|
1474
|
+
return nil if switchport_mode == :disabled
|
1475
|
+
vlans = config_get('interface', 'switchport_trunk_allowed_vlan',
|
1476
|
+
@get_args)
|
1477
|
+
vlans = vlans.join(',') if vlans.is_a?(Array)
|
1478
|
+
vlans = Utils.normalize_range_array(vlans, :string) unless vlans == 'none'
|
1479
|
+
vlans
|
1480
|
+
end
|
1481
|
+
|
1482
|
+
def switchport_trunk_allowed_vlan=(val)
|
1483
|
+
if val.nil?
|
1484
|
+
config_set('interface', 'switchport_trunk_allowed_vlan',
|
1485
|
+
name: @name, state: 'no', vlan: '')
|
1486
|
+
else
|
1487
|
+
config_set('interface', 'switchport_trunk_allowed_vlan',
|
1488
|
+
name: @name, state: '', vlan: val)
|
1489
|
+
end
|
1490
|
+
end
|
1491
|
+
|
1492
|
+
def default_switchport_trunk_allowed_vlan
|
1493
|
+
config_get_default('interface', 'switchport_trunk_allowed_vlan')
|
1494
|
+
end
|
1495
|
+
|
1496
|
+
def switchport_trunk_native_vlan
|
1497
|
+
return nil if switchport_mode == :disabled
|
1498
|
+
config_get('interface', 'switchport_trunk_native_vlan', @get_args)
|
1499
|
+
end
|
1500
|
+
|
1501
|
+
def switchport_trunk_native_vlan=(val)
|
1502
|
+
if val.nil?
|
1503
|
+
config_set('interface', 'switchport_trunk_native_vlan',
|
1504
|
+
name: @name, state: 'no', vlan: '')
|
1505
|
+
else
|
1506
|
+
config_set('interface', 'switchport_trunk_native_vlan',
|
1507
|
+
name: @name, state: '', vlan: val)
|
1508
|
+
end
|
1509
|
+
end
|
1510
|
+
|
1511
|
+
# --------------------------
|
1512
|
+
def cli_error_check(result)
|
1513
|
+
# Check for messages that can be safely ignored.
|
1514
|
+
# The NXOS interface private-vlan cli does not raise an exception
|
1515
|
+
# in some conditions and instead just displays a STDOUT error message
|
1516
|
+
# thus NXAPI does not detect the failure.
|
1517
|
+
# We must catch it by inspecting the "body" hash entry returned by NXAPI.
|
1518
|
+
# This vlan cli behavior is unlikely to change.
|
1519
|
+
|
1520
|
+
errors = /(ERROR:|VLAN:|Eth)/
|
1521
|
+
return unless
|
1522
|
+
result[1].is_a?(Hash) && errors.match(result[1]['body'].to_s)
|
1523
|
+
# Split errors into a list, but keep the delimiter as part of the message.
|
1524
|
+
error_list =
|
1525
|
+
(result[1]['body'].split(errors) - ['']).each_slice(2).map(&:join)
|
1526
|
+
error_list.each do |_msg|
|
1527
|
+
fail result[1]['body']
|
1528
|
+
end
|
1529
|
+
end
|
1530
|
+
|
1531
|
+
# --------------------------
|
1532
|
+
# <state> switchport mode private-vlan host
|
1533
|
+
def switchport_pvlan_host
|
1534
|
+
return nil if switchport_mode == :disabled
|
1535
|
+
config_get('interface', 'switchport_pvlan_host', @get_args)
|
1536
|
+
end
|
1537
|
+
|
1538
|
+
def switchport_pvlan_host=(state)
|
1539
|
+
pvlan_enable
|
1540
|
+
config_set('interface', 'switchport_pvlan_host',
|
1541
|
+
name: @name, state: state ? '' : 'no')
|
1542
|
+
end
|
1543
|
+
|
1544
|
+
def default_switchport_pvlan_host
|
1545
|
+
config_get_default('interface', 'switchport_pvlan_host')
|
1546
|
+
end
|
1547
|
+
|
1548
|
+
# --------------------------
|
1549
|
+
# <state> switchport mode private-vlan promiscuous
|
1550
|
+
def switchport_pvlan_promiscuous
|
1551
|
+
return nil if switchport_mode == :disabled
|
1552
|
+
config_get('interface', 'switchport_pvlan_promiscuous', @get_args)
|
1553
|
+
end
|
1554
|
+
|
1555
|
+
def switchport_pvlan_promiscuous=(state)
|
1556
|
+
pvlan_enable
|
1557
|
+
config_set('interface', 'switchport_pvlan_promiscuous',
|
1558
|
+
name: @name, state: state ? '' : 'no')
|
1559
|
+
end
|
1560
|
+
|
1561
|
+
def default_switchport_pvlan_promiscuous
|
1562
|
+
config_get_default('interface', 'switchport_pvlan_promiscuous')
|
1563
|
+
end
|
1564
|
+
|
1565
|
+
# --------------------------
|
1566
|
+
# <state> switchport private-vlan host-association <pri> <sec>
|
1567
|
+
# Note this is NOT a multiple, unlike trunk association.
|
1568
|
+
def switchport_pvlan_host_association
|
1569
|
+
config_get('interface', 'switchport_pvlan_host_association', @get_args)
|
1570
|
+
end
|
1571
|
+
|
1572
|
+
# Input: An array of primary and secondary vlans: ['44', '244']
|
1573
|
+
def switchport_pvlan_host_association=(pri_and_sec)
|
1574
|
+
pvlan_enable
|
1575
|
+
|
1576
|
+
state = pri_and_sec.empty? ? 'no' : ''
|
1577
|
+
pri, sec = pri_and_sec
|
1578
|
+
cli_error_check(
|
1579
|
+
config_set('interface', 'switchport_pvlan_host_association',
|
1580
|
+
name: @name, state: state, pri: pri, sec: sec))
|
1581
|
+
end
|
1582
|
+
|
1583
|
+
def default_switchport_pvlan_host_association
|
1584
|
+
config_get_default('interface', 'switchport_pvlan_host_association')
|
1585
|
+
end
|
1586
|
+
|
1587
|
+
# --------------------------
|
1588
|
+
# <state> switchport private-vlan mapping <primary> <vlan>
|
1589
|
+
def switchport_pvlan_mapping
|
1590
|
+
config_get('interface', 'switchport_pvlan_mapping', @get_args)
|
1591
|
+
end
|
1592
|
+
|
1593
|
+
# Input: An array of primary vlan and range of vlans: ['44', '3-4,6']
|
1594
|
+
def switchport_pvlan_mapping=(primary_and_range)
|
1595
|
+
switchport_pvlan_mapping_delta(primary_and_range)
|
1596
|
+
end
|
1597
|
+
|
1598
|
+
def default_switchport_pvlan_mapping
|
1599
|
+
config_get_default('interface', 'switchport_pvlan_mapping')
|
1600
|
+
end
|
1601
|
+
|
1602
|
+
# --------------------------
|
1603
|
+
# Find the is/should delta and add/remove commands as needed.
|
1604
|
+
#
|
1605
|
+
# Inputs:
|
1606
|
+
# primary_and_range: An array of primary vlan and range of vlans
|
1607
|
+
def switchport_pvlan_mapping_delta(primary_and_range)
|
1608
|
+
# Enable switchport mode and feature private-vlan
|
1609
|
+
pvlan_enable
|
1610
|
+
primary, should_range = primary_and_range
|
1611
|
+
|
1612
|
+
# primary changes require removing the entire command first
|
1613
|
+
is_range = switchport_pvlan_mapping_remove?(primary)
|
1614
|
+
|
1615
|
+
# convert ranges to individual elements
|
1616
|
+
is = Utils.dash_range_to_elements(is_range)
|
1617
|
+
should = Utils.dash_range_to_elements(should_range)
|
1618
|
+
|
1619
|
+
# create the delta hash and apply the changes
|
1620
|
+
delta_hash = Utils.delta_add_remove(should, is)
|
1621
|
+
Cisco::Logger.debug('switchport_pvlan_mapping_delta: '\
|
1622
|
+
"#{primary}: #{delta_hash}")
|
1623
|
+
[:add, :remove].each do |action|
|
1624
|
+
delta_hash[action].each do |vlan|
|
1625
|
+
state = (action == :add) ? '' : 'no'
|
1626
|
+
cli_error_check(
|
1627
|
+
config_set('interface', 'switchport_pvlan_mapping',
|
1628
|
+
name: @name, state: state, primary: primary, vlan: vlan))
|
1629
|
+
end
|
1630
|
+
end
|
1631
|
+
end
|
1632
|
+
|
1633
|
+
# --------------------------
|
1634
|
+
# switchport_pvlan_mapping_remove?
|
1635
|
+
# This is a helper to check if command needs to be removed entirely.
|
1636
|
+
#
|
1637
|
+
# should_primary: the new primary vlan value
|
1638
|
+
# Returns: the current vlan range
|
1639
|
+
def switchport_pvlan_mapping_remove?(should_primary)
|
1640
|
+
is_primary, is_range = switchport_pvlan_mapping
|
1641
|
+
|
1642
|
+
if (is_primary != should_primary) && !is_primary.nil?
|
1643
|
+
cli_error_check(
|
1644
|
+
config_set('interface', 'switchport_pvlan_mapping',
|
1645
|
+
name: @name, state: 'no', primary: '', vlan: ''))
|
1646
|
+
is_range = []
|
1647
|
+
end
|
1648
|
+
is_range
|
1649
|
+
end
|
1650
|
+
|
1651
|
+
# --------------------------
|
1652
|
+
# <state> switchport private-vlan mapping trunk <primary> <vlan>
|
1653
|
+
def switchport_pvlan_mapping_trunk
|
1654
|
+
config_get('interface', 'switchport_pvlan_mapping_trunk', @get_args)
|
1655
|
+
end
|
1656
|
+
|
1657
|
+
# Input: A nested array of primary vlan and range of vlans:
|
1658
|
+
# [['44', '3-4,6'], ['99', '199']]
|
1659
|
+
def switchport_pvlan_mapping_trunk=(should)
|
1660
|
+
switchport_pvlan_mapping_trunk_delta(should)
|
1661
|
+
end
|
1662
|
+
|
1663
|
+
def default_switchport_pvlan_mapping_trunk
|
1664
|
+
config_get_default('interface', 'switchport_pvlan_mapping_trunk')
|
1665
|
+
end
|
1666
|
+
|
1667
|
+
# --------------------------
|
1668
|
+
# switchport_pvlan_mapping_trunk_delta(should)
|
1669
|
+
#
|
1670
|
+
# Find the is/should delta and add/remove commands as needed.
|
1671
|
+
# The 'should' value is a nested array of primary vlan and secondary
|
1672
|
+
# ranges; e.g.:
|
1673
|
+
# [['44', '144-145'], ['99', '199-201']
|
1674
|
+
#
|
1675
|
+
def switchport_pvlan_mapping_trunk_delta(should)
|
1676
|
+
# Enable switchport mode and feature private-vlan
|
1677
|
+
pvlan_enable
|
1678
|
+
|
1679
|
+
# Handle single-level arrays if found: [pri, range] -> [[pri,range]]
|
1680
|
+
should = [should] if !should.empty? && (Utils.depth(should) == 1)
|
1681
|
+
|
1682
|
+
is = switchport_pvlan_mapping_trunk
|
1683
|
+
delta_hash = Utils.delta_add_remove(should, is, :updates_not_allowed)
|
1684
|
+
Cisco::Logger.debug("switchport_pvlan_mapping_trunk_delta: #{delta_hash}")
|
1685
|
+
[:remove, :add].each do |action|
|
1686
|
+
delta_hash[action].each do |pri_and_range|
|
1687
|
+
pri, range = pri_and_range
|
1688
|
+
if action == :add
|
1689
|
+
state = ''
|
1690
|
+
else
|
1691
|
+
state = 'no'
|
1692
|
+
range = ''
|
1693
|
+
end
|
1694
|
+
cli_error_check(
|
1695
|
+
config_set('interface', 'switchport_pvlan_mapping_trunk',
|
1696
|
+
name: @name, state: state, primary: pri, range: range))
|
1697
|
+
end
|
1698
|
+
end
|
1699
|
+
end
|
1700
|
+
|
1701
|
+
# --------------------------
|
1702
|
+
# <state> switchport private-vlan association trunk <pri> <sec>
|
1703
|
+
# Supports multiple.
|
1704
|
+
def switchport_pvlan_trunk_association
|
1705
|
+
config_get('interface', 'switchport_pvlan_trunk_association', @get_args)
|
1706
|
+
end
|
1707
|
+
|
1708
|
+
# Input: A nested array of primary and secondary vlans:
|
1709
|
+
# [['44', '244'], ['99', '299']]
|
1710
|
+
def switchport_pvlan_trunk_association=(should)
|
1711
|
+
pvlan_enable
|
1712
|
+
|
1713
|
+
# Handle single-level arrays if found: [pri, sec] -> [[pri,sec]]
|
1714
|
+
should = [should] if !should.empty? && (Utils.depth(should) == 1)
|
1715
|
+
|
1716
|
+
is = switchport_pvlan_trunk_association
|
1717
|
+
pvlan_trunk_association_delta(is, should)
|
1718
|
+
end
|
1719
|
+
|
1720
|
+
def pvlan_trunk_association_delta(is, should)
|
1721
|
+
delta_hash = Utils.delta_add_remove(should, is)
|
1722
|
+
Cisco::Logger.debug("pvlan_trunk_association_delta: #{delta_hash}")
|
1723
|
+
[:remove, :add].each do |action|
|
1724
|
+
delta_hash[action].each do |pri_and_sec|
|
1725
|
+
state = (action == :add) ? '' : 'no'
|
1726
|
+
pri, sec = pri_and_sec
|
1727
|
+
|
1728
|
+
# Cli does not like removals that specify the secondary
|
1729
|
+
sec = '' if action[/remove/]
|
1730
|
+
cli_error_check(
|
1731
|
+
config_set('interface', 'switchport_pvlan_trunk_association',
|
1732
|
+
name: @name, state: state, pri: pri, sec: sec))
|
1733
|
+
end
|
1734
|
+
end
|
1735
|
+
end
|
1736
|
+
|
1737
|
+
def default_switchport_pvlan_trunk_association
|
1738
|
+
config_get_default('interface', 'switchport_pvlan_trunk_association')
|
1739
|
+
end
|
1740
|
+
|
1741
|
+
# --------------------------
|
1742
|
+
# <state> switchport mode private-vlan trunk promiscuous
|
1743
|
+
def switchport_pvlan_trunk_promiscuous
|
1744
|
+
return nil if switchport_mode == :disabled
|
1745
|
+
config_get('interface', 'switchport_pvlan_trunk_promiscuous', @get_args)
|
1746
|
+
end
|
1747
|
+
|
1748
|
+
def switchport_pvlan_trunk_promiscuous=(state)
|
1749
|
+
pvlan_enable
|
1750
|
+
config_set('interface', 'switchport_pvlan_trunk_promiscuous',
|
1751
|
+
name: @name, state: state ? '' : 'no')
|
1752
|
+
end
|
1753
|
+
|
1754
|
+
def default_switchport_pvlan_trunk_promiscuous
|
1755
|
+
config_get_default('interface', 'switchport_pvlan_trunk_promiscuous')
|
1756
|
+
end
|
1757
|
+
|
1758
|
+
# --------------------------
|
1759
|
+
# <state> switchport mode private-vlan trunk secondary
|
1760
|
+
def switchport_pvlan_trunk_secondary
|
1761
|
+
return nil if switchport_mode == :disabled
|
1762
|
+
config_get('interface', 'switchport_pvlan_trunk_secondary', @get_args)
|
1763
|
+
end
|
1764
|
+
|
1765
|
+
def switchport_pvlan_trunk_secondary=(state)
|
1766
|
+
pvlan_enable
|
1767
|
+
config_set('interface', 'switchport_pvlan_trunk_secondary',
|
1768
|
+
name: @name, state: state ? '' : 'no')
|
1769
|
+
end
|
1770
|
+
|
1771
|
+
def default_switchport_pvlan_trunk_secondary
|
1772
|
+
config_get_default('interface', 'switchport_pvlan_trunk_secondary')
|
1773
|
+
end
|
1774
|
+
|
1775
|
+
# --------------------------
|
1776
|
+
# <state> switchport private-vlan trunk allowed vlan <range>
|
1777
|
+
# Note that range is handled as a string because the entire range is
|
1778
|
+
# replaced instead of individually adding or removing vlans from the range.
|
1779
|
+
def switchport_pvlan_trunk_allowed_vlan
|
1780
|
+
return nil if switchport_mode == :disabled
|
1781
|
+
vlans = config_get('interface', 'switchport_pvlan_trunk_allowed_vlan',
|
1782
|
+
@get_args)
|
1783
|
+
vlans = vlans.join(',') if vlans.is_a?(Array)
|
1784
|
+
vlans = Utils.normalize_range_array(vlans, :string) unless vlans == 'none'
|
1785
|
+
vlans
|
1786
|
+
end
|
1787
|
+
|
1788
|
+
def switchport_pvlan_trunk_allowed_vlan=(range)
|
1789
|
+
pvlan_enable
|
1790
|
+
|
1791
|
+
range = Utils.normalize_range_array(range, :string) unless
|
1792
|
+
range == default_switchport_pvlan_trunk_allowed_vlan
|
1793
|
+
|
1794
|
+
config_set('interface', 'switchport_pvlan_trunk_allowed_vlan',
|
1795
|
+
name: @name, range: range)
|
1796
|
+
end
|
1797
|
+
|
1798
|
+
def default_switchport_pvlan_trunk_allowed_vlan
|
1799
|
+
config_get_default('interface', 'switchport_pvlan_trunk_allowed_vlan')
|
1800
|
+
end
|
1801
|
+
|
1802
|
+
# --------------------------
|
1803
|
+
# <state> switchport trunk native vlan <vlan>
|
1804
|
+
def switchport_pvlan_trunk_native_vlan
|
1805
|
+
return nil if switchport_mode == :disabled
|
1806
|
+
config_get('interface', 'switchport_pvlan_trunk_native_vlan', @get_args)
|
1807
|
+
end
|
1808
|
+
|
1809
|
+
def switchport_pvlan_trunk_native_vlan=(vlan)
|
1810
|
+
pvlan_enable
|
1811
|
+
config_set('interface', 'switchport_pvlan_trunk_native_vlan',
|
1812
|
+
name: @name, vlan: vlan)
|
1813
|
+
end
|
1814
|
+
|
1815
|
+
def default_switchport_pvlan_trunk_native_vlan
|
1816
|
+
config_get_default('interface', 'switchport_pvlan_trunk_native_vlan')
|
1817
|
+
end
|
1818
|
+
|
1819
|
+
# --------------------------
|
1820
|
+
# This is an SVI property.
|
1821
|
+
# <state> private-vlan mapping <range> # ex. range = ['2-4,9']
|
1822
|
+
# Always returns an array.
|
1823
|
+
def pvlan_mapping
|
1824
|
+
range = config_get('interface', 'pvlan_mapping', @get_args)
|
1825
|
+
return default_pvlan_mapping if range.nil?
|
1826
|
+
range.empty? ? range : [range.delete(' ')]
|
1827
|
+
end
|
1828
|
+
|
1829
|
+
def pvlan_mapping=(range)
|
1830
|
+
feature_vlan_set
|
1831
|
+
Feature.private_vlan_enable
|
1832
|
+
|
1833
|
+
is = Utils.dash_range_to_elements(pvlan_mapping)
|
1834
|
+
should = Utils.dash_range_to_elements(range)
|
1835
|
+
|
1836
|
+
pvlan_mapping_delta(is, should)
|
1837
|
+
end
|
1838
|
+
|
1839
|
+
def pvlan_mapping_delta(is, should)
|
1840
|
+
delta_hash = Utils.delta_add_remove(should, is)
|
1841
|
+
Cisco::Logger.debug("pvlan_mapping_delta: #{delta_hash}")
|
1842
|
+
[:remove, :add].each do |action|
|
1843
|
+
delta_hash[action].each do |vlan|
|
1844
|
+
state = (action == :add) ? '' : 'no'
|
1845
|
+
cli_error_check(
|
1846
|
+
config_set('interface', 'pvlan_mapping',
|
1847
|
+
name: @name, state: state, vlan: vlan))
|
1848
|
+
end
|
1849
|
+
end
|
1850
|
+
end
|
1851
|
+
|
1852
|
+
def default_pvlan_mapping
|
1853
|
+
config_get_default('interface', 'pvlan_mapping')
|
1854
|
+
end
|
1855
|
+
|
1856
|
+
# --------------------------
|
1857
|
+
# vlan_mapping & vlan_mapping_enable
|
1858
|
+
# Hardware & Cli Dependencies:
|
1859
|
+
# - F3 linecards only
|
1860
|
+
# - vdc
|
1861
|
+
# - limit-resource
|
1862
|
+
# - bridge-domain
|
1863
|
+
# - feature vni
|
1864
|
+
# - switchport mode
|
1865
|
+
|
1866
|
+
# Getter: Builds an array of vlan_mapping commands currently
|
1867
|
+
# on the device.
|
1868
|
+
# cli: switchport vlan mapping 2 200
|
1869
|
+
# switchport vlan mapping 4 400
|
1870
|
+
# array: [['2', '200'], ['4', '400']]
|
1871
|
+
#
|
1872
|
+
def default_vlan_mapping
|
1873
|
+
config_get_default('interface', 'vlan_mapping')
|
1874
|
+
end
|
1875
|
+
|
1876
|
+
def vlan_mapping
|
1877
|
+
match = config_get('interface', 'vlan_mapping', @get_args)
|
1878
|
+
match.each(&:compact!) unless match.nil?
|
1879
|
+
match
|
1880
|
+
end
|
1881
|
+
|
1882
|
+
def vlan_mapping=(should_list)
|
1883
|
+
Feature.vni_enable
|
1884
|
+
|
1885
|
+
# Process a hash of vlan_mapping cmds from delta_add_remove().
|
1886
|
+
# The vlan_mapping cli does not allow commands to be updated, they must
|
1887
|
+
# first be removed if there is a change.
|
1888
|
+
delta_hash = Utils.delta_add_remove(should_list, vlan_mapping,
|
1889
|
+
:updates_not_allowed)
|
1890
|
+
return if delta_hash.values.flatten.empty?
|
1891
|
+
# Process :remove first to ensure "update" commands will not fail.
|
1892
|
+
[:remove, :add].each do |action|
|
1893
|
+
Cisco::Logger.debug("vlan_mapping delta #{@get_args}\n"\
|
1894
|
+
"#{action}: #{delta_hash[action]}")
|
1895
|
+
delta_hash[action].each do |original, translated|
|
1896
|
+
state = (action == :add) ? '' : 'no'
|
1897
|
+
config_set('interface', 'vlan_mapping', name: @name,
|
1898
|
+
state: state, original: original, translated: translated)
|
1899
|
+
end
|
1900
|
+
end
|
1901
|
+
end
|
1902
|
+
|
1903
|
+
# cli: switchport vlan mapping enable
|
1904
|
+
def default_vlan_mapping_enable
|
1905
|
+
config_get_default('interface', 'vlan_mapping_enable')
|
1906
|
+
end
|
1907
|
+
|
1908
|
+
def vlan_mapping_enable
|
1909
|
+
config_get('interface', 'vlan_mapping_enable', @get_args)
|
1910
|
+
end
|
1911
|
+
|
1912
|
+
def vlan_mapping_enable=(state)
|
1913
|
+
config_set('interface', 'vlan_mapping_enable',
|
1914
|
+
name: @name, state: state ? '' : 'no')
|
1915
|
+
end
|
1916
|
+
|
1917
|
+
def default_switchport_trunk_native_vlan
|
1918
|
+
config_get_default('interface', 'switchport_trunk_native_vlan')
|
1919
|
+
end
|
1920
|
+
|
1921
|
+
def system_default_switchport
|
1922
|
+
# This command is a user-configurable system default.
|
1923
|
+
#
|
1924
|
+
# Note: This is a simple boolean state but there is a bug on some
|
1925
|
+
# platforms that causes the cli to nvgen twice; this causes config_get to
|
1926
|
+
# raise an error when it encounters the multiple. Therefore we define it
|
1927
|
+
# as a multiple to avoid the raise and handle the array if necessary.
|
1928
|
+
#
|
1929
|
+
val = config_get('interface', 'system_default_switchport')
|
1930
|
+
return (val[0][/^no /] ? false : true) if val.is_a?(Array)
|
1931
|
+
val
|
1932
|
+
end
|
1933
|
+
|
1934
|
+
def system_default_switchport_shutdown
|
1935
|
+
# This command is a user-configurable system default.
|
1936
|
+
config_get('interface', 'system_default_switchport_shutdown')
|
1937
|
+
end
|
1938
|
+
|
1939
|
+
def system_default_svi_autostate
|
1940
|
+
# This command is a user-configurable system default.
|
1941
|
+
#
|
1942
|
+
# This property behaves differently on an n7k vs ni(3|9)k and therefore
|
1943
|
+
# needs special handling.
|
1944
|
+
# N7K: When enabled, does not nvgen.
|
1945
|
+
# When disabled, does nvgen, but differently then n(3|9)k.
|
1946
|
+
# Return true for the disabled case, false otherwise.
|
1947
|
+
# N(3|9)K: When enabled, does nvgen.
|
1948
|
+
# When disabled, does nvgen.
|
1949
|
+
# Return true for the enabled case, false otherwise.
|
1950
|
+
result = config_get('interface', 'system_default_svi_autostate')
|
1951
|
+
/N7K/.match(node.product_id) ? !result : result
|
1952
|
+
end
|
1953
|
+
|
1954
|
+
def switchport_vtp_mode_capable?
|
1955
|
+
!switchport_mode.to_s.match(/(access|trunk)/).nil?
|
1956
|
+
end
|
1957
|
+
|
1958
|
+
def switchport_vtp
|
1959
|
+
return nil unless switchport_vtp_mode_capable?
|
1960
|
+
config_get('interface', 'vtp', @get_args)
|
1961
|
+
end
|
1962
|
+
|
1963
|
+
def switchport_vtp=(vtp_set)
|
1964
|
+
# TODO: throw UnsupportedError instead of returning false?
|
1965
|
+
return false unless switchport_vtp_mode_capable?
|
1966
|
+
return false if !vtp_set && !Feature.vtp_enabled?
|
1967
|
+
Feature.vtp_enable if vtp_set
|
1968
|
+
no_cmd = (vtp_set) ? '' : 'no'
|
1969
|
+
config_set('interface', 'vtp', name: @name, state: no_cmd)
|
1970
|
+
end
|
1971
|
+
|
1972
|
+
def svi_cmd_allowed?(cmd)
|
1973
|
+
fail "[#{@name}] Invalid interface type for command [#{cmd}]" unless
|
1974
|
+
@name[/vlan/i]
|
1975
|
+
end
|
1976
|
+
|
1977
|
+
# svi_autostate is exclusive to svi interfaces
|
1978
|
+
def svi_autostate
|
1979
|
+
return nil unless @name[/^vlan/i]
|
1980
|
+
config_get('interface', 'svi_autostate', @get_args)
|
1981
|
+
end
|
1982
|
+
|
1983
|
+
def svi_autostate=(val)
|
1984
|
+
check_switchport(:disabled)
|
1985
|
+
svi_cmd_allowed?('autostate')
|
1986
|
+
config_set('interface', 'svi_autostate',
|
1987
|
+
name: @name, state: val ? '' : 'no')
|
1988
|
+
end
|
1989
|
+
|
1990
|
+
def default_svi_autostate
|
1991
|
+
system_default_svi_autostate
|
1992
|
+
end
|
1993
|
+
|
1994
|
+
def feature_vlan?
|
1995
|
+
config_get('interface', 'feature_vlan')
|
1996
|
+
end
|
1997
|
+
|
1998
|
+
def feature_vlan_set(val=true)
|
1999
|
+
# 'feature interface-vlan'
|
2000
|
+
# TBD: Replace this with Feature.interface_vlan_enable
|
2001
|
+
return if feature_vlan? == val
|
2002
|
+
config_set('interface', 'feature_vlan', state: val ? '' : 'no')
|
2003
|
+
end
|
2004
|
+
|
2005
|
+
# svi_management is exclusive to svi interfaces
|
2006
|
+
def svi_management
|
2007
|
+
return nil unless @name[/^vlan/i]
|
2008
|
+
config_get('interface', 'svi_management', @get_args)
|
2009
|
+
end
|
2010
|
+
|
2011
|
+
def svi_management=(val)
|
2012
|
+
check_switchport(:disabled)
|
2013
|
+
svi_cmd_allowed?('management')
|
2014
|
+
config_set('interface', 'svi_management',
|
2015
|
+
name: @name, state: val ? '' : 'no')
|
2016
|
+
end
|
2017
|
+
|
2018
|
+
def default_svi_management
|
2019
|
+
config_get_default('interface', 'svi_management')
|
2020
|
+
end
|
2021
|
+
|
2022
|
+
def default_switchport_vtp
|
2023
|
+
return nil unless switchport_vtp_mode_capable?
|
2024
|
+
config_get_default('interface', 'vtp')
|
2025
|
+
end
|
2026
|
+
|
2027
|
+
def switchport_vtp_feature?
|
2028
|
+
config_get('vtp', 'feature')
|
2029
|
+
end
|
2030
|
+
|
2031
|
+
def switchport_status?(status)
|
2032
|
+
case status
|
2033
|
+
when :disabled
|
2034
|
+
return true if switchport_mode == status || switchport_mode.nil?
|
2035
|
+
when :access, :trunk
|
2036
|
+
return switchport_mode == status
|
2037
|
+
when Array
|
2038
|
+
return status.include?(switchport_mode)
|
2039
|
+
else
|
2040
|
+
return false
|
2041
|
+
end
|
2042
|
+
end
|
2043
|
+
|
2044
|
+
def check_switchport(status)
|
2045
|
+
return if switchport_status?(status)
|
2046
|
+
fail("#{caller[0][/`.*'/][1..-2]} cannot be set unless " \
|
2047
|
+
"switchport mode is #{status}")
|
2048
|
+
end
|
2049
|
+
|
2050
|
+
def vpc_id
|
2051
|
+
config_get('interface', 'vpc_id', @get_args)
|
2052
|
+
end
|
2053
|
+
|
2054
|
+
def vpc_id=(num)
|
2055
|
+
if num
|
2056
|
+
config_set('interface', 'vpc_id', name: @name, state: '', id: num)
|
2057
|
+
else
|
2058
|
+
# 'no vpc' doesn't work for phy ports, so do a get
|
2059
|
+
num = vpc_id
|
2060
|
+
config_set('interface', 'vpc_id', name: @name, state: 'no', id: num)
|
2061
|
+
end
|
2062
|
+
end
|
2063
|
+
|
2064
|
+
def default_vpc_id
|
2065
|
+
config_get_default('interface', 'vpc_id')
|
2066
|
+
end
|
2067
|
+
|
2068
|
+
def vpc_peer_link
|
2069
|
+
return nil unless @name[/port-channel/i] && switchport_mode != :disabled
|
2070
|
+
config_get('interface', 'vpc_peer_link', @get_args)
|
2071
|
+
end
|
2072
|
+
|
2073
|
+
def vpc_peer_link=(state)
|
2074
|
+
return if vpc_peer_link == state
|
2075
|
+
no_cmd = (state ? '' : 'no')
|
2076
|
+
config_set('interface', 'vpc_peer_link', name: @name, state: no_cmd)
|
2077
|
+
end
|
2078
|
+
|
2079
|
+
def default_vpc_peer_link
|
2080
|
+
config_get_default('interface', 'vpc_peer_link')
|
2081
|
+
end
|
2082
|
+
|
2083
|
+
def vrf
|
2084
|
+
config_get('interface', 'vrf', @get_args)
|
2085
|
+
end
|
2086
|
+
|
2087
|
+
def vrf=(v)
|
2088
|
+
fail TypeError unless v.is_a?(String)
|
2089
|
+
return if v == vrf
|
2090
|
+
# Changing the VRF can result in loss of IP address, so cache it
|
2091
|
+
addr_1 = ipv4_address
|
2092
|
+
mask_1 = ipv4_netmask_length
|
2093
|
+
addr_2 = ipv4_address_secondary
|
2094
|
+
mask_2 = ipv4_netmask_length_secondary
|
2095
|
+
# XR actually blocks you from changing the VRF if IP addr is present
|
2096
|
+
unless platform == :nexus
|
2097
|
+
ipv4_addr_mask_set(nil, nil, false) unless addr_1.nil?
|
2098
|
+
ipv4_addr_mask_set(nil, nil, true) unless addr_2.nil?
|
2099
|
+
end
|
2100
|
+
if v.empty?
|
2101
|
+
config_set('interface', 'vrf', name: @name, state: 'no', vrf: '')
|
2102
|
+
else
|
2103
|
+
config_set('interface', 'vrf', name: @name, state: '', vrf: v)
|
2104
|
+
end
|
2105
|
+
ipv4_addr_mask_set(addr_1, mask_1, false) unless addr_1.nil?
|
2106
|
+
ipv4_addr_mask_set(addr_2, mask_2, true) unless addr_2.nil?
|
2107
|
+
end
|
2108
|
+
|
2109
|
+
def default_vrf
|
2110
|
+
config_get_default('interface', 'vrf')
|
2111
|
+
end
|
2112
|
+
|
2113
|
+
def set_range_based_params(list, param_name)
|
2114
|
+
list.each do |range, property_value|
|
2115
|
+
# if a particular range is set to default, use 'no' cmd
|
2116
|
+
if property_value == 'default'
|
2117
|
+
config_set('interface', param_name,
|
2118
|
+
name: @name, state: 'no',
|
2119
|
+
range: range, val: '')
|
2120
|
+
else
|
2121
|
+
config_set('interface', param_name,
|
2122
|
+
name: @name, state: '',
|
2123
|
+
range: range, val: property_value)
|
2124
|
+
end
|
2125
|
+
end
|
2126
|
+
end
|
2127
|
+
end # Class
|
2128
|
+
end # Module
|