cisco_node_utils_mgx 2.1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +10 -0
- data/.rspec +2 -0
- data/.rubocop.yml +96 -0
- data/.travis.yml +17 -0
- data/CHANGELOG.md +676 -0
- data/CONTRIBUTING.md +43 -0
- data/Gemfile +10 -0
- data/LICENSE +201 -0
- data/README.md +246 -0
- data/Rakefile +44 -0
- data/SUPPORT.md +3 -0
- data/bin/.rubocop.yml +18 -0
- data/bin/check_metric_limits.rb +109 -0
- data/bin/git/hooks/commit-msg/enforce_style +89 -0
- data/bin/git/hooks/hook_lib +115 -0
- data/bin/git/hooks/hooks-wrapper +38 -0
- data/bin/git/hooks/post-flow-hotfix-start/update-version +24 -0
- data/bin/git/hooks/post-flow-release-finish/update-version +29 -0
- data/bin/git/hooks/post-flow-release-start/update-version +19 -0
- data/bin/git/hooks/post-merge/update-hooks +6 -0
- data/bin/git/hooks/post-rewrite/update-hooks +6 -0
- data/bin/git/hooks/pre-commit/check_unstaged_changes +18 -0
- data/bin/git/hooks/pre-commit/rubocop +25 -0
- data/bin/git/hooks/pre-commit/validate-diffs +45 -0
- data/bin/git/hooks/pre-commit/validate-yaml +18 -0
- data/bin/git/hooks/pre-push/check-changelog +24 -0
- data/bin/git/hooks/pre-push/rubocop +7 -0
- data/bin/git/update-hooks +123 -0
- data/bin/show_running_yang.rb +233 -0
- data/cisco_node_utils.gemspec +41 -0
- data/docs/README-develop-best-practices.md +521 -0
- data/docs/README-develop-node-utils-APIs.md +570 -0
- data/docs/README-maintainers.md +77 -0
- data/docs/README-test-execution.md +57 -0
- data/docs/README-utilities.md +14 -0
- data/docs/agent_files.png +0 -0
- data/docs/cisco_node_utils.yaml.example +36 -0
- data/docs/template-router.rb +123 -0
- data/docs/template-test_router.rb +104 -0
- data/ext/mkrf_conf.rb +63 -0
- data/lib/.rubocop.yml +18 -0
- data/lib/cisco_node_utils/aaa_authentication_login.rb +95 -0
- data/lib/cisco_node_utils/aaa_authentication_login_service.rb +138 -0
- data/lib/cisco_node_utils/aaa_authorization_service.rb +156 -0
- data/lib/cisco_node_utils/ace.rb +467 -0
- data/lib/cisco_node_utils/acl.rb +101 -0
- data/lib/cisco_node_utils/banner.rb +63 -0
- data/lib/cisco_node_utils/bfd_global.rb +305 -0
- data/lib/cisco_node_utils/bgp.rb +988 -0
- data/lib/cisco_node_utils/bgp_af.rb +545 -0
- data/lib/cisco_node_utils/bgp_af_aggr_addr.rb +207 -0
- data/lib/cisco_node_utils/bgp_neighbor.rb +527 -0
- data/lib/cisco_node_utils/bgp_neighbor_af.rb +780 -0
- data/lib/cisco_node_utils/bridge_domain.rb +178 -0
- data/lib/cisco_node_utils/bridge_domain_vni.rb +206 -0
- data/lib/cisco_node_utils/cisco_cmn_utils.rb +444 -0
- data/lib/cisco_node_utils/client/client.rb +238 -0
- data/lib/cisco_node_utils/client/grpc/client.rb +395 -0
- data/lib/cisco_node_utils/client/grpc/ems.proto +148 -0
- data/lib/cisco_node_utils/client/grpc/ems.rb +111 -0
- data/lib/cisco_node_utils/client/grpc/ems_services.rb +49 -0
- data/lib/cisco_node_utils/client/grpc.rb +33 -0
- data/lib/cisco_node_utils/client/nxapi/client.rb +368 -0
- data/lib/cisco_node_utils/client/nxapi.rb +31 -0
- data/lib/cisco_node_utils/client/utils.rb +180 -0
- data/lib/cisco_node_utils/client.rb +35 -0
- data/lib/cisco_node_utils/cmd_ref/README_YAML.md +590 -0
- data/lib/cisco_node_utils/cmd_ref/aaa_auth_login_service.yaml +25 -0
- data/lib/cisco_node_utils/cmd_ref/aaa_authentication_login.yaml +38 -0
- data/lib/cisco_node_utils/cmd_ref/aaa_authorization_service.yaml +40 -0
- data/lib/cisco_node_utils/cmd_ref/acl.yaml +48 -0
- data/lib/cisco_node_utils/cmd_ref/banner.yaml +11 -0
- data/lib/cisco_node_utils/cmd_ref/bfd_global.yaml +117 -0
- data/lib/cisco_node_utils/cmd_ref/bgp.yaml +383 -0
- data/lib/cisco_node_utils/cmd_ref/bgp_af.yaml +223 -0
- data/lib/cisco_node_utils/cmd_ref/bgp_af_aa.yaml +38 -0
- data/lib/cisco_node_utils/cmd_ref/bgp_neighbor.yaml +174 -0
- data/lib/cisco_node_utils/cmd_ref/bgp_neighbor_af.yaml +236 -0
- data/lib/cisco_node_utils/cmd_ref/bridge_domain.yaml +49 -0
- data/lib/cisco_node_utils/cmd_ref/bridge_domain_vni.yaml +33 -0
- data/lib/cisco_node_utils/cmd_ref/dhcp_relay_global.yaml +128 -0
- data/lib/cisco_node_utils/cmd_ref/dnsclient.yaml +55 -0
- data/lib/cisco_node_utils/cmd_ref/encapsulation.yaml +25 -0
- data/lib/cisco_node_utils/cmd_ref/evpn_multicast.yaml +12 -0
- data/lib/cisco_node_utils/cmd_ref/evpn_multisite.yaml +18 -0
- data/lib/cisco_node_utils/cmd_ref/evpn_stormcontrol.yaml +18 -0
- data/lib/cisco_node_utils/cmd_ref/evpn_vni.yaml +48 -0
- data/lib/cisco_node_utils/cmd_ref/fabricpath.yaml +183 -0
- data/lib/cisco_node_utils/cmd_ref/fabricpath_topology.yaml +40 -0
- data/lib/cisco_node_utils/cmd_ref/feature.yaml +126 -0
- data/lib/cisco_node_utils/cmd_ref/hostname.yaml +8 -0
- data/lib/cisco_node_utils/cmd_ref/hsrp_global.yaml +25 -0
- data/lib/cisco_node_utils/cmd_ref/images.yaml +8 -0
- data/lib/cisco_node_utils/cmd_ref/interface.yaml +781 -0
- data/lib/cisco_node_utils/cmd_ref/interface_channel_group.yaml +45 -0
- data/lib/cisco_node_utils/cmd_ref/interface_evpn_multisite.yaml +17 -0
- data/lib/cisco_node_utils/cmd_ref/interface_hsrp_group.yaml +120 -0
- data/lib/cisco_node_utils/cmd_ref/interface_ospf.yaml +112 -0
- data/lib/cisco_node_utils/cmd_ref/interface_portchannel.yaml +87 -0
- data/lib/cisco_node_utils/cmd_ref/interface_service_vni.yaml +42 -0
- data/lib/cisco_node_utils/cmd_ref/inventory.yaml +45 -0
- data/lib/cisco_node_utils/cmd_ref/ip_multicast.yaml +22 -0
- data/lib/cisco_node_utils/cmd_ref/itd_device_group.yaml +83 -0
- data/lib/cisco_node_utils/cmd_ref/itd_service.yaml +119 -0
- data/lib/cisco_node_utils/cmd_ref/memory.yaml +24 -0
- data/lib/cisco_node_utils/cmd_ref/ntp_auth_key.yaml +10 -0
- data/lib/cisco_node_utils/cmd_ref/ntp_config.yaml +27 -0
- data/lib/cisco_node_utils/cmd_ref/ntp_server.yaml +34 -0
- data/lib/cisco_node_utils/cmd_ref/object_group.yaml +32 -0
- data/lib/cisco_node_utils/cmd_ref/ospf.yaml +91 -0
- data/lib/cisco_node_utils/cmd_ref/ospf_area.yaml +91 -0
- data/lib/cisco_node_utils/cmd_ref/ospf_area_vlink.yaml +88 -0
- data/lib/cisco_node_utils/cmd_ref/overlay_global.yaml +37 -0
- data/lib/cisco_node_utils/cmd_ref/pim.yaml +43 -0
- data/lib/cisco_node_utils/cmd_ref/portchannel_global.yaml +86 -0
- data/lib/cisco_node_utils/cmd_ref/radius_global.yaml +37 -0
- data/lib/cisco_node_utils/cmd_ref/radius_server.yaml +100 -0
- data/lib/cisco_node_utils/cmd_ref/radius_server_group.yaml +19 -0
- data/lib/cisco_node_utils/cmd_ref/route_map.yaml +601 -0
- data/lib/cisco_node_utils/cmd_ref/show_system.yaml +9 -0
- data/lib/cisco_node_utils/cmd_ref/show_version.yaml +84 -0
- data/lib/cisco_node_utils/cmd_ref/snmp_community.yaml +81 -0
- data/lib/cisco_node_utils/cmd_ref/snmp_group.yaml +9 -0
- data/lib/cisco_node_utils/cmd_ref/snmp_notification_receiver.yaml +74 -0
- data/lib/cisco_node_utils/cmd_ref/snmp_server.yaml +91 -0
- data/lib/cisco_node_utils/cmd_ref/snmp_user.yaml +57 -0
- data/lib/cisco_node_utils/cmd_ref/snmpnotification.yaml +23 -0
- data/lib/cisco_node_utils/cmd_ref/span_session.yaml +65 -0
- data/lib/cisco_node_utils/cmd_ref/stp_global.yaml +235 -0
- data/lib/cisco_node_utils/cmd_ref/syslog_facility.yaml +10 -0
- data/lib/cisco_node_utils/cmd_ref/syslog_server.yaml +34 -0
- data/lib/cisco_node_utils/cmd_ref/syslog_settings.yaml +45 -0
- data/lib/cisco_node_utils/cmd_ref/system.yaml +7 -0
- data/lib/cisco_node_utils/cmd_ref/tacacs_global.yaml +37 -0
- data/lib/cisco_node_utils/cmd_ref/tacacs_server.yaml +63 -0
- data/lib/cisco_node_utils/cmd_ref/tacacs_server_group.yaml +45 -0
- data/lib/cisco_node_utils/cmd_ref/tacacs_server_host.yaml +64 -0
- data/lib/cisco_node_utils/cmd_ref/upgrade.yaml +38 -0
- data/lib/cisco_node_utils/cmd_ref/vdc.yaml +52 -0
- data/lib/cisco_node_utils/cmd_ref/virtual_service.yaml +8 -0
- data/lib/cisco_node_utils/cmd_ref/vlan.yaml +106 -0
- data/lib/cisco_node_utils/cmd_ref/vpc.yaml +233 -0
- data/lib/cisco_node_utils/cmd_ref/vrf.yaml +86 -0
- data/lib/cisco_node_utils/cmd_ref/vrf_af.yaml +139 -0
- data/lib/cisco_node_utils/cmd_ref/vtp.yaml +32 -0
- data/lib/cisco_node_utils/cmd_ref/vxlan_vtep.yaml +114 -0
- data/lib/cisco_node_utils/cmd_ref/vxlan_vtep_vni.yaml +71 -0
- data/lib/cisco_node_utils/cmd_ref/yang.yaml +7 -0
- data/lib/cisco_node_utils/cmd_ref/yum.yaml +68 -0
- data/lib/cisco_node_utils/command_reference.rb +724 -0
- data/lib/cisco_node_utils/configparser_lib.rb +195 -0
- data/lib/cisco_node_utils/constants.rb +40 -0
- data/lib/cisco_node_utils/dhcp_relay_global.rb +302 -0
- data/lib/cisco_node_utils/dns_domain.rb +93 -0
- data/lib/cisco_node_utils/domain_name.rb +82 -0
- data/lib/cisco_node_utils/encapsulation.rb +112 -0
- data/lib/cisco_node_utils/environment.rb +110 -0
- data/lib/cisco_node_utils/evpn_multicast.rb +66 -0
- data/lib/cisco_node_utils/evpn_multisite.rb +96 -0
- data/lib/cisco_node_utils/evpn_stormcontrol.rb +84 -0
- data/lib/cisco_node_utils/evpn_vni.rb +159 -0
- data/lib/cisco_node_utils/exceptions.rb +140 -0
- data/lib/cisco_node_utils/fabricpath_global.rb +405 -0
- data/lib/cisco_node_utils/fabricpath_topology.rb +137 -0
- data/lib/cisco_node_utils/feature.rb +377 -0
- data/lib/cisco_node_utils/hostname.rb +62 -0
- data/lib/cisco_node_utils/hsrp_global.rb +97 -0
- data/lib/cisco_node_utils/interface.rb +2128 -0
- data/lib/cisco_node_utils/interface_channel_group.rb +142 -0
- data/lib/cisco_node_utils/interface_evpn_multisite.rb +72 -0
- data/lib/cisco_node_utils/interface_hsrp_group.rb +557 -0
- data/lib/cisco_node_utils/interface_ospf.rb +378 -0
- data/lib/cisco_node_utils/interface_portchannel.rb +180 -0
- data/lib/cisco_node_utils/interface_service_vni.rb +132 -0
- data/lib/cisco_node_utils/ip_multicast.rb +90 -0
- data/lib/cisco_node_utils/itd_device_group.rb +228 -0
- data/lib/cisco_node_utils/itd_device_group_node.rb +144 -0
- data/lib/cisco_node_utils/itd_service.rb +511 -0
- data/lib/cisco_node_utils/logger.rb +78 -0
- data/lib/cisco_node_utils/name_server.rb +64 -0
- data/lib/cisco_node_utils/node.rb +443 -0
- data/lib/cisco_node_utils/node_util.rb +111 -0
- data/lib/cisco_node_utils/ntp_auth_key.rb +67 -0
- data/lib/cisco_node_utils/ntp_config.rb +83 -0
- data/lib/cisco_node_utils/ntp_server.rb +86 -0
- data/lib/cisco_node_utils/object_group.rb +75 -0
- data/lib/cisco_node_utils/object_group_entry.rb +143 -0
- data/lib/cisco_node_utils/overlay_global.rb +142 -0
- data/lib/cisco_node_utils/pim.rb +131 -0
- data/lib/cisco_node_utils/pim_group_list.rb +109 -0
- data/lib/cisco_node_utils/pim_rp_address.rb +103 -0
- data/lib/cisco_node_utils/platform.rb +217 -0
- data/lib/cisco_node_utils/portchannel_global.rb +347 -0
- data/lib/cisco_node_utils/radius_global.rb +165 -0
- data/lib/cisco_node_utils/radius_server.rb +421 -0
- data/lib/cisco_node_utils/radius_server_group.rb +117 -0
- data/lib/cisco_node_utils/route_map.rb +2540 -0
- data/lib/cisco_node_utils/router_ospf.rb +77 -0
- data/lib/cisco_node_utils/router_ospf_area.rb +416 -0
- data/lib/cisco_node_utils/router_ospf_area_vlink.rb +313 -0
- data/lib/cisco_node_utils/router_ospf_vrf.rb +342 -0
- data/lib/cisco_node_utils/snmp_notification_receiver.rb +176 -0
- data/lib/cisco_node_utils/snmpcommunity.rb +109 -0
- data/lib/cisco_node_utils/snmpgroup.rb +54 -0
- data/lib/cisco_node_utils/snmpnotification.rb +57 -0
- data/lib/cisco_node_utils/snmpserver.rb +132 -0
- data/lib/cisco_node_utils/snmpuser.rb +403 -0
- data/lib/cisco_node_utils/span_session.rb +149 -0
- data/lib/cisco_node_utils/stp_global.rb +676 -0
- data/lib/cisco_node_utils/syslog_facility.rb +64 -0
- data/lib/cisco_node_utils/syslog_server.rb +146 -0
- data/lib/cisco_node_utils/syslog_settings.rb +174 -0
- data/lib/cisco_node_utils/tacacs_global.rb +137 -0
- data/lib/cisco_node_utils/tacacs_server.rb +173 -0
- data/lib/cisco_node_utils/tacacs_server_group.rb +149 -0
- data/lib/cisco_node_utils/tacacs_server_host.rb +216 -0
- data/lib/cisco_node_utils/upgrade.rb +122 -0
- data/lib/cisco_node_utils/vdc.rb +118 -0
- data/lib/cisco_node_utils/version.rb +21 -0
- data/lib/cisco_node_utils/vlan.rb +301 -0
- data/lib/cisco_node_utils/vpc.rb +466 -0
- data/lib/cisco_node_utils/vrf.rb +192 -0
- data/lib/cisco_node_utils/vrf_af.rb +327 -0
- data/lib/cisco_node_utils/vtp.rb +125 -0
- data/lib/cisco_node_utils/vxlan_vtep.rb +286 -0
- data/lib/cisco_node_utils/vxlan_vtep_vni.rb +331 -0
- data/lib/cisco_node_utils/yang.rb +160 -0
- data/lib/cisco_node_utils/yum.rb +213 -0
- data/lib/cisco_node_utils.rb +21 -0
- data/lib/minitest/environment_plugin.rb +31 -0
- data/lib/minitest/log_level_plugin.rb +41 -0
- data/spec/client_spec.rb +7 -0
- data/spec/environment_spec.rb +384 -0
- data/spec/grpc_client_spec.rb +23 -0
- data/spec/isolate/all_clients_spec.rb +9 -0
- data/spec/isolate/grpc_only_spec.rb +16 -0
- data/spec/isolate/no_clients_spec.rb +26 -0
- data/spec/isolate/nxapi_only_spec.rb +16 -0
- data/spec/nxapi_client_spec.rb +42 -0
- data/spec/schema.yaml +82 -0
- data/spec/shared_examples_for_clients.rb +14 -0
- data/spec/spec_helper.rb +91 -0
- data/spec/whitespace_spec.rb +10 -0
- data/spec/yaml_spec.rb +42 -0
- data/tests/.rubocop.yml +18 -0
- data/tests/CSCuxdublin-1.0.0-7.0.3.I3.1.lib32_n9000.rpm +0 -0
- data/tests/basetest.rb +243 -0
- data/tests/ciscotest.rb +577 -0
- data/tests/cmd_config.yaml +75 -0
- data/tests/cmd_config_invalid.yaml +16 -0
- data/tests/n9000_sample-1.0.0-7.0.3.x86_64.rpm +0 -0
- data/tests/noop.rb +7 -0
- data/tests/platform_info.rb +63 -0
- data/tests/tacacs_server.yaml.example +6 -0
- data/tests/test_aaa_authentication_login.rb +243 -0
- data/tests/test_aaa_authentication_login_service.rb +761 -0
- data/tests/test_aaa_authorization_service.rb +874 -0
- data/tests/test_ace.rb +304 -0
- data/tests/test_acl.rb +185 -0
- data/tests/test_banner.rb +85 -0
- data/tests/test_bfd_global.rb +272 -0
- data/tests/test_bgp_af.rb +875 -0
- data/tests/test_bgp_af_aa.rb +108 -0
- data/tests/test_bgp_neighbor.rb +596 -0
- data/tests/test_bgp_neighbor_af.rb +781 -0
- data/tests/test_bridge_domain.rb +198 -0
- data/tests/test_bridge_domain_vni.rb +109 -0
- data/tests/test_client_utils.rb +111 -0
- data/tests/test_cmn_utils.rb +76 -0
- data/tests/test_command_config.rb +206 -0
- data/tests/test_command_reference.rb +669 -0
- data/tests/test_dhcp_relay_global.rb +286 -0
- data/tests/test_dns_domain.rb +123 -0
- data/tests/test_domain_name.rb +96 -0
- data/tests/test_encapsulation.rb +75 -0
- data/tests/test_evpn_multicast.rb +65 -0
- data/tests/test_evpn_multisite.rb +70 -0
- data/tests/test_evpn_stormcontrol.rb +56 -0
- data/tests/test_evpn_vni.rb +131 -0
- data/tests/test_fabricpath_global.rb +246 -0
- data/tests/test_fabricpath_topology.rb +77 -0
- data/tests/test_feature.rb +272 -0
- data/tests/test_grpc.rb +166 -0
- data/tests/test_hostname.rb +64 -0
- data/tests/test_hsrp_global.rb +79 -0
- data/tests/test_interface.rb +1958 -0
- data/tests/test_interface_bdi.rb +80 -0
- data/tests/test_interface_channel_group.rb +131 -0
- data/tests/test_interface_evpn_multisite.rb +94 -0
- data/tests/test_interface_hsrp.rb +134 -0
- data/tests/test_interface_hsrp_group.rb +570 -0
- data/tests/test_interface_ospf.rb +820 -0
- data/tests/test_interface_portchannel.rb +135 -0
- data/tests/test_interface_private_vlan.rb +365 -0
- data/tests/test_interface_service_vni.rb +203 -0
- data/tests/test_interface_svi.rb +210 -0
- data/tests/test_interface_switchport.rb +468 -0
- data/tests/test_ip_multicast.rb +80 -0
- data/tests/test_itd_device_group.rb +145 -0
- data/tests/test_itd_device_group_node.rb +199 -0
- data/tests/test_itd_service.rb +314 -0
- data/tests/test_logger.rb +43 -0
- data/tests/test_name_server.rb +94 -0
- data/tests/test_node.rb +50 -0
- data/tests/test_node_ext.rb +406 -0
- data/tests/test_node_util.rb +119 -0
- data/tests/test_ntp_auth_key.rb +77 -0
- data/tests/test_ntp_config.rb +100 -0
- data/tests/test_ntp_server.rb +146 -0
- data/tests/test_nxapi.rb +236 -0
- data/tests/test_object_group.rb +122 -0
- data/tests/test_overlay_global.rb +108 -0
- data/tests/test_pim.rb +203 -0
- data/tests/test_pim_group_list.rb +147 -0
- data/tests/test_pim_rp_address.rb +155 -0
- data/tests/test_platform.rb +254 -0
- data/tests/test_portchannel_global.rb +322 -0
- data/tests/test_radius_global.rb +108 -0
- data/tests/test_radius_server.rb +377 -0
- data/tests/test_radius_server_group.rb +151 -0
- data/tests/test_route_map.rb +1479 -0
- data/tests/test_router_bgp.rb +1325 -0
- data/tests/test_router_ospf.rb +56 -0
- data/tests/test_router_ospf_area.rb +433 -0
- data/tests/test_router_ospf_area_vlink.rb +298 -0
- data/tests/test_router_ospf_vrf.rb +690 -0
- data/tests/test_snmp_notification_receiver.rb +169 -0
- data/tests/test_snmpcommunity.rb +422 -0
- data/tests/test_snmpgroup.rb +71 -0
- data/tests/test_snmpnotification.rb +91 -0
- data/tests/test_snmpserver.rb +251 -0
- data/tests/test_snmpuser.rb +666 -0
- data/tests/test_span_session.rb +155 -0
- data/tests/test_stp_global.rb +575 -0
- data/tests/test_syslog_facility.rb +80 -0
- data/tests/test_syslog_server.rb +119 -0
- data/tests/test_syslog_settings.rb +123 -0
- data/tests/test_tacacs_global.rb +109 -0
- data/tests/test_tacacs_server.rb +436 -0
- data/tests/test_tacacs_server_group.rb +434 -0
- data/tests/test_tacacs_server_host.rb +427 -0
- data/tests/test_upgrade.rb +105 -0
- data/tests/test_vdc.rb +64 -0
- data/tests/test_vlan.rb +386 -0
- data/tests/test_vlan_private.rb +656 -0
- data/tests/test_vpc.rb +548 -0
- data/tests/test_vrf.rb +248 -0
- data/tests/test_vrf_af.rb +288 -0
- data/tests/test_vtp.rb +278 -0
- data/tests/test_vxlan_vtep.rb +327 -0
- data/tests/test_vxlan_vtep_vni.rb +326 -0
- data/tests/test_yang.rb +369 -0
- data/tests/test_yum.rb +109 -0
- data/tests/upgrade_info.yaml.example +3 -0
- data/tests/yum_package.yaml +94 -0
- metadata +534 -0
|
@@ -0,0 +1,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
|