cisco_node_utils 1.1.0 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (202) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -1
  3. data/CHANGELOG.md +126 -1
  4. data/README.md +19 -12
  5. data/Rakefile +1 -0
  6. data/bin/git/hooks/commit-msg/enforce_style +8 -0
  7. data/cisco_node_utils.gemspec +4 -3
  8. data/docs/README-develop-best-practices.md +127 -109
  9. data/docs/README-develop-node-utils-APIs.md +47 -39
  10. data/docs/template-router.rb +3 -7
  11. data/lib/.rubocop.yml +4 -4
  12. data/lib/cisco_node_utils.rb +1 -1
  13. data/lib/cisco_node_utils/aaa_authentication_login.rb +96 -0
  14. data/lib/cisco_node_utils/aaa_authentication_login_service.rb +133 -0
  15. data/lib/cisco_node_utils/aaa_authorization_service.rb +150 -0
  16. data/lib/cisco_node_utils/ace.rb +196 -0
  17. data/lib/cisco_node_utils/acl.rb +100 -0
  18. data/lib/cisco_node_utils/bgp.rb +301 -163
  19. data/lib/cisco_node_utils/bgp_af.rb +187 -19
  20. data/lib/cisco_node_utils/bgp_neighbor.rb +18 -33
  21. data/lib/cisco_node_utils/bgp_neighbor_af.rb +25 -48
  22. data/lib/cisco_node_utils/cisco_cmn_utils.rb +23 -4
  23. data/lib/cisco_node_utils/cmd_ref/README_YAML.md +593 -0
  24. data/lib/cisco_node_utils/cmd_ref/aaa_auth_login_service.yaml +22 -0
  25. data/lib/cisco_node_utils/cmd_ref/aaa_authentication_login.yaml +31 -0
  26. data/lib/cisco_node_utils/cmd_ref/aaa_authorization_service.yaml +22 -0
  27. data/lib/cisco_node_utils/cmd_ref/acl.yaml +43 -0
  28. data/lib/cisco_node_utils/cmd_ref/bgp.yaml +242 -0
  29. data/lib/cisco_node_utils/cmd_ref/bgp_af.yaml +164 -0
  30. data/lib/cisco_node_utils/cmd_ref/bgp_neighbor.yaml +131 -0
  31. data/lib/cisco_node_utils/cmd_ref/bgp_neighbor_af.yaml +179 -0
  32. data/lib/cisco_node_utils/cmd_ref/dnsclient.yaml +34 -0
  33. data/lib/cisco_node_utils/cmd_ref/evpn_vni.yaml +42 -0
  34. data/lib/cisco_node_utils/cmd_ref/fabricpath.yaml +172 -0
  35. data/lib/cisco_node_utils/cmd_ref/fabricpath_topology.yaml +35 -0
  36. data/lib/cisco_node_utils/cmd_ref/feature.yaml +42 -0
  37. data/lib/cisco_node_utils/cmd_ref/fex.yaml +9 -0
  38. data/lib/cisco_node_utils/cmd_ref/images.yaml +7 -0
  39. data/lib/cisco_node_utils/cmd_ref/interface.yaml +339 -0
  40. data/lib/cisco_node_utils/cmd_ref/interface_channel_group.yaml +28 -0
  41. data/lib/cisco_node_utils/cmd_ref/interface_ospf.yaml +61 -0
  42. data/lib/cisco_node_utils/cmd_ref/interface_portchannel.yaml +54 -0
  43. data/lib/cisco_node_utils/cmd_ref/interface_service_vni.yaml +32 -0
  44. data/lib/cisco_node_utils/cmd_ref/inventory.yaml +45 -0
  45. data/lib/cisco_node_utils/cmd_ref/memory.yaml +13 -0
  46. data/lib/cisco_node_utils/cmd_ref/ntp_config.yaml +7 -0
  47. data/lib/cisco_node_utils/cmd_ref/ntp_server.yaml +14 -0
  48. data/lib/cisco_node_utils/cmd_ref/ospf.yaml +74 -0
  49. data/lib/cisco_node_utils/cmd_ref/overlay_global.yaml +33 -0
  50. data/lib/cisco_node_utils/cmd_ref/pim.yaml +40 -0
  51. data/lib/cisco_node_utils/cmd_ref/portchannel_global.yaml +69 -0
  52. data/lib/cisco_node_utils/cmd_ref/radius_global.yaml +25 -0
  53. data/lib/cisco_node_utils/cmd_ref/radius_server.yaml +64 -0
  54. data/lib/cisco_node_utils/cmd_ref/radius_server_group.yaml +14 -0
  55. data/lib/cisco_node_utils/cmd_ref/show_system.yaml +5 -0
  56. data/lib/cisco_node_utils/cmd_ref/show_version.yaml +72 -0
  57. data/lib/cisco_node_utils/cmd_ref/snmp_community.yaml +23 -0
  58. data/lib/cisco_node_utils/cmd_ref/snmp_group.yaml +7 -0
  59. data/lib/cisco_node_utils/cmd_ref/snmp_notification_receiver.yaml +50 -0
  60. data/lib/cisco_node_utils/cmd_ref/snmp_server.yaml +51 -0
  61. data/lib/cisco_node_utils/cmd_ref/snmp_user.yaml +55 -0
  62. data/lib/cisco_node_utils/cmd_ref/snmpnotification.yaml +11 -0
  63. data/lib/cisco_node_utils/cmd_ref/syslog_server.yaml +18 -0
  64. data/lib/cisco_node_utils/cmd_ref/syslog_settings.yaml +7 -0
  65. data/lib/cisco_node_utils/cmd_ref/system.yaml +6 -0
  66. data/lib/cisco_node_utils/cmd_ref/tacacs_server.yaml +49 -0
  67. data/lib/cisco_node_utils/cmd_ref/tacacs_server_group.yaml +33 -0
  68. data/lib/cisco_node_utils/cmd_ref/tacacs_server_host.yaml +35 -0
  69. data/lib/cisco_node_utils/cmd_ref/vdc.yaml +38 -0
  70. data/lib/cisco_node_utils/cmd_ref/virtual_service.yaml +6 -0
  71. data/lib/cisco_node_utils/cmd_ref/vlan.yaml +56 -0
  72. data/lib/cisco_node_utils/cmd_ref/vni.yaml +76 -0
  73. data/lib/cisco_node_utils/cmd_ref/vpc.yaml +197 -0
  74. data/lib/cisco_node_utils/cmd_ref/vrf.yaml +88 -0
  75. data/lib/cisco_node_utils/cmd_ref/vtp.yaml +38 -0
  76. data/lib/cisco_node_utils/cmd_ref/vxlan_vtep.yaml +60 -0
  77. data/lib/cisco_node_utils/cmd_ref/vxlan_vtep_vni.yaml +39 -0
  78. data/lib/cisco_node_utils/cmd_ref/yum.yaml +13 -0
  79. data/lib/cisco_node_utils/command_reference.rb +359 -187
  80. data/lib/cisco_node_utils/configparser_lib.rb +1 -1
  81. data/lib/cisco_node_utils/dns_domain.rb +19 -5
  82. data/lib/cisco_node_utils/domain_name.rb +4 -8
  83. data/lib/cisco_node_utils/evpn_vni.rb +157 -0
  84. data/lib/cisco_node_utils/fabricpath_global.rb +388 -0
  85. data/lib/cisco_node_utils/fabricpath_topology.rb +150 -0
  86. data/lib/cisco_node_utils/feature.rb +111 -0
  87. data/lib/cisco_node_utils/interface.rb +390 -97
  88. data/lib/cisco_node_utils/interface_channel_group.rb +124 -0
  89. data/lib/cisco_node_utils/interface_ospf.rb +11 -34
  90. data/lib/cisco_node_utils/interface_portchannel.rb +157 -0
  91. data/lib/cisco_node_utils/interface_service_vni.rb +132 -0
  92. data/lib/cisco_node_utils/name_server.rb +1 -1
  93. data/lib/cisco_node_utils/node.rb +55 -249
  94. data/lib/cisco_node_utils/node_util.rb +5 -1
  95. data/lib/cisco_node_utils/ntp_config.rb +2 -2
  96. data/lib/cisco_node_utils/ntp_server.rb +14 -5
  97. data/lib/cisco_node_utils/overlay_global.rb +153 -0
  98. data/lib/cisco_node_utils/pim.rb +124 -0
  99. data/lib/cisco_node_utils/pim_group_list.rb +108 -0
  100. data/lib/cisco_node_utils/pim_rp_address.rb +102 -0
  101. data/lib/cisco_node_utils/platform.rb +8 -9
  102. data/lib/cisco_node_utils/portchannel_global.rb +277 -0
  103. data/lib/cisco_node_utils/radius_global.rb +9 -19
  104. data/lib/cisco_node_utils/radius_server.rb +31 -41
  105. data/lib/cisco_node_utils/radius_server_group.rb +117 -0
  106. data/lib/cisco_node_utils/router_ospf.rb +1 -1
  107. data/lib/cisco_node_utils/router_ospf_vrf.rb +14 -19
  108. data/lib/cisco_node_utils/snmp_notification_receiver.rb +158 -0
  109. data/lib/cisco_node_utils/snmpcommunity.rb +3 -5
  110. data/lib/cisco_node_utils/snmpgroup.rb +1 -1
  111. data/lib/cisco_node_utils/snmpnotification.rb +57 -0
  112. data/lib/cisco_node_utils/snmpserver.rb +8 -17
  113. data/lib/cisco_node_utils/snmpuser.rb +67 -28
  114. data/lib/cisco_node_utils/syslog_server.rb +3 -9
  115. data/lib/cisco_node_utils/syslog_settings.rb +2 -10
  116. data/lib/cisco_node_utils/tacacs_server.rb +9 -14
  117. data/lib/cisco_node_utils/tacacs_server_group.rb +145 -0
  118. data/lib/cisco_node_utils/tacacs_server_host.rb +5 -9
  119. data/lib/cisco_node_utils/vdc.rb +88 -0
  120. data/lib/cisco_node_utils/version.rb +5 -2
  121. data/lib/cisco_node_utils/vlan.rb +71 -8
  122. data/lib/cisco_node_utils/vni.rb +227 -0
  123. data/lib/cisco_node_utils/vpc.rb +377 -0
  124. data/lib/cisco_node_utils/vrf.rb +60 -9
  125. data/lib/cisco_node_utils/vrf_af.rb +191 -0
  126. data/lib/cisco_node_utils/vtp.rb +8 -6
  127. data/lib/cisco_node_utils/vxlan_vtep.rb +151 -0
  128. data/lib/cisco_node_utils/vxlan_vtep_vni.rb +234 -0
  129. data/lib/cisco_node_utils/yum.rb +1 -1
  130. data/tests/.rubocop.yml +1 -1
  131. data/tests/basetest.rb +16 -7
  132. data/tests/ciscotest.rb +55 -13
  133. data/tests/cmd_config.yaml +2 -2
  134. data/tests/platform_info.rb +3 -2
  135. data/tests/test_aaa_authentication_login.rb +219 -0
  136. data/tests/test_aaa_authentication_login_service.rb +759 -0
  137. data/tests/test_aaa_authorization_service.rb +1041 -0
  138. data/tests/test_ace.rb +160 -0
  139. data/tests/test_acl.rb +176 -0
  140. data/tests/test_bgp_af.rb +269 -13
  141. data/tests/test_bgp_neighbor.rb +38 -40
  142. data/tests/test_bgp_neighbor_af.rb +92 -32
  143. data/tests/test_command_config.rb +5 -5
  144. data/tests/test_command_reference.rb +284 -101
  145. data/tests/test_dns_domain.rb +1 -1
  146. data/tests/test_domain_name.rb +1 -1
  147. data/tests/test_evpn_vni.rb +106 -0
  148. data/tests/test_fabricpath_global.rb +243 -0
  149. data/tests/test_fabricpath_topology.rb +98 -0
  150. data/tests/test_interface.rb +292 -74
  151. data/tests/test_interface_channel_group.rb +74 -0
  152. data/tests/test_interface_ospf.rb +9 -4
  153. data/tests/test_interface_portchannel.rb +105 -0
  154. data/tests/test_interface_service_vni.rb +232 -0
  155. data/tests/test_interface_svi.rb +77 -62
  156. data/tests/test_interface_switchport.rb +17 -5
  157. data/tests/test_name_server.rb +1 -1
  158. data/tests/test_node.rb +1 -1
  159. data/tests/test_node_ext.rb +10 -20
  160. data/tests/test_ntp_config.rb +1 -1
  161. data/tests/test_ntp_server.rb +18 -6
  162. data/tests/test_overlay_global.rb +102 -0
  163. data/tests/test_pim.rb +177 -0
  164. data/tests/test_pim_group_list.rb +181 -0
  165. data/tests/test_pim_rp_address.rb +153 -0
  166. data/tests/test_platform.rb +3 -3
  167. data/tests/test_portchannel_global.rb +202 -0
  168. data/tests/test_radius_global.rb +1 -1
  169. data/tests/test_radius_server.rb +92 -57
  170. data/tests/test_radius_server_group.rb +149 -0
  171. data/tests/test_router_bgp.rb +283 -112
  172. data/tests/test_router_ospf.rb +2 -2
  173. data/tests/test_router_ospf_vrf.rb +4 -4
  174. data/tests/test_snmp_notification_receiver.rb +167 -0
  175. data/tests/test_snmpcommunity.rb +1 -1
  176. data/tests/test_snmpgroup.rb +1 -1
  177. data/tests/test_snmpnotification.rb +72 -0
  178. data/tests/test_snmpserver.rb +29 -105
  179. data/tests/test_snmpuser.rb +32 -30
  180. data/tests/test_syslog_server.rb +36 -10
  181. data/tests/test_syslog_settings.rb +1 -1
  182. data/tests/test_tacacs_server.rb +1 -1
  183. data/tests/test_tacacs_server_group.rb +405 -0
  184. data/tests/test_tacacs_server_host.rb +1 -1
  185. data/tests/test_vdc.rb +78 -0
  186. data/tests/test_vlan.rb +74 -19
  187. data/tests/test_vlan_mt_full.rb +95 -0
  188. data/tests/test_vni.rb +106 -0
  189. data/tests/test_vpc.rb +361 -0
  190. data/tests/test_vrf.rb +172 -29
  191. data/tests/test_vtp.rb +1 -1
  192. data/tests/test_vxlan_vtep.rb +214 -0
  193. data/tests/test_vxlan_vtep_vni.rb +201 -0
  194. data/tests/test_yum.rb +1 -1
  195. metadata +120 -11
  196. data/lib/cisco_node_utils/README_YAML.md +0 -325
  197. data/lib/cisco_node_utils/command_reference_common.yaml +0 -1051
  198. data/lib/cisco_node_utils/command_reference_common_bgp.yaml +0 -535
  199. data/lib/cisco_node_utils/command_reference_n3064.yaml +0 -13
  200. data/lib/cisco_node_utils/command_reference_n7k.yaml +0 -52
  201. data/lib/cisco_node_utils/command_reference_n9k.yaml +0 -26
  202. data/tests/platform_info.yaml +0 -10
@@ -0,0 +1,150 @@
1
+ # Fabricpath Topology provider class
2
+ #
3
+ # Deepak Cherian, November 2015
4
+ #
5
+ # Copyright (c) 2015-2016 Cisco and/or its affiliates.
6
+ #
7
+ # Licensed under the Apache License, Version 2.0 (the "License");
8
+ # you may not use this file except in compliance with the License.
9
+ # You may obtain a copy of the License at
10
+ #
11
+ # http://www.apache.org/licenses/LICENSE-2.0
12
+ #
13
+ # Unless required by applicable law or agreed to in writing, software
14
+ # distributed under the License is distributed on an "AS IS" BASIS,
15
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
+ # See the License for the specific language governing permissions and
17
+ # limitations under the License.
18
+
19
+ require_relative 'node_util'
20
+ require_relative 'fabricpath_global'
21
+
22
+ module Cisco
23
+ # node_utils class for fabricpath_topology
24
+ class FabricpathTopo < NodeUtil
25
+ attr_reader :topo_id
26
+
27
+ def initialize(topo_id, instantiate=true)
28
+ @topo_id = topo_id.to_s
29
+ @set_params = {}
30
+ fail ArgumentError, "Invalid value(non-numeric
31
+ Topo id #{@topo_id})" unless @topo_id[/^\d+$/]
32
+
33
+ create if instantiate
34
+ end
35
+
36
+ def self.topos
37
+ hash = {}
38
+ fabricpath = config_get('fabricpath', 'feature')
39
+ return hash if (:enabled != fabricpath.to_sym)
40
+ topo_list = config_get('fabricpath_topology', 'all_topos')
41
+ return hash if topo_list.nil?
42
+
43
+ topo_list.each do |id|
44
+ hash[id] = FabricpathTopo.new(id, false)
45
+ end
46
+ hash
47
+ end
48
+
49
+ def create
50
+ fabricpath_feature_set(:enabled) unless :enabled == fabricpath_feature
51
+ config_set('fabricpath_topology', 'create',
52
+ topo: @topo_id) unless @topo_id == '0'
53
+ end
54
+
55
+ def cli_error_check(result)
56
+ # The NXOS vlan cli does not raise an exception in some conditions and
57
+ # instead just displays a STDOUT error message; thus NXAPI does not detect
58
+ # the failure and we must catch it by inspecting the "body" hash entry
59
+ # returned by NXAPI. This vlan cli behavior is unlikely to change.
60
+ fail result[2]['body'] unless result[2]['body'].empty?
61
+ end
62
+
63
+ def destroy
64
+ config_set('fabricpath_topology', 'destroy', topo: @topo_id)
65
+ end
66
+
67
+ def fabricpath_feature
68
+ FabricpathGlobal.fabricpath_feature
69
+ end
70
+
71
+ def fabricpath_feature_set(fabricpath_set)
72
+ FabricpathGlobal.fabricpath_feature_set(fabricpath_set)
73
+ end
74
+
75
+ def state
76
+ result = config_get('fabricpath_topology', 'state', @topo_id)
77
+ return default_state if result.nil?
78
+ case result
79
+ when /Up/
80
+ return 'up'
81
+ when /Down/
82
+ return 'default'
83
+ end
84
+ end
85
+
86
+ def default_state
87
+ config_get_default('fabricpath_topology', 'state')
88
+ end
89
+
90
+ def member_vlans
91
+ str = config_get('fabricpath_topology', 'member_vlans', @topo_id)
92
+ return [] if str == '--'
93
+ str.gsub!('-', '..')
94
+ if /,/.match(str)
95
+ str.split(/\s*,\s*/)
96
+ else
97
+ str.lines.to_a
98
+ end
99
+ end
100
+
101
+ def member_vlans=(str)
102
+ debug "str is #{str} whose class is #{str.class}"
103
+ @set_params = {}
104
+ str = str.join(',') unless str.empty?
105
+ if str.empty?
106
+ @set_params[:topo] = @topo_id
107
+ @set_params[:state] = 'no'
108
+ @set_params[:vlan_range] = ''
109
+ else
110
+ str.gsub!('..', '-')
111
+ @set_params[:topo] = @topo_id
112
+ @set_params[:state] = ''
113
+ @set_params[:vlan_range] = str
114
+ end
115
+ result = config_set('fabricpath_topology', 'member_vlans', @set_params)
116
+ cli_error_check(result)
117
+ rescue CliError => e
118
+ raise "[topo #{@topo_id}] '#{e.command}' : #{e.clierror}"
119
+ end
120
+
121
+ def default_member_vlans
122
+ []
123
+ end
124
+
125
+ def topo_name
126
+ config_get('fabricpath_topology', 'description', @topo_id)
127
+ end
128
+
129
+ def topo_name=(desc)
130
+ fail TypeError unless desc.is_a?(String)
131
+ @set_params = {}
132
+ if desc.empty?
133
+ @set_params[:topo] = @topo_id
134
+ @set_params[:state] = 'no'
135
+ @set_params[:name] = ''
136
+ else
137
+ @set_params[:topo] = @topo_id
138
+ @set_params[:state] = ''
139
+ @set_params[:name] = desc
140
+ end
141
+ config_set('fabricpath_topology', 'description', @set_params)
142
+ rescue Cisco::CliError => e
143
+ raise "[#{@name}] '#{e.command}' : #{e.clierror}"
144
+ end
145
+
146
+ def default_topo_name
147
+ config_get_default('fabricpath_topology', 'description')
148
+ end
149
+ end # class
150
+ end # module
@@ -0,0 +1,111 @@
1
+ # January 2016, Robert W Gries
2
+ #
3
+ # Copyright (c) 2015-2016 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 'node_util'
18
+
19
+ module Cisco
20
+ # Feature - node util class for managing common features
21
+ class Feature < NodeUtil
22
+ # Note that in most cases the enable methods should only enable;
23
+ # however, for test purposes it is sometimes convenient to support
24
+ # feature disablement for cleanup purposes.
25
+ # ---------------------------
26
+ def self.bgp_enable
27
+ return if bgp_enabled?
28
+ config_set('feature', 'bgp')
29
+ end
30
+
31
+ def self.bgp_enabled?
32
+ config_get('feature', 'bgp')
33
+ end
34
+
35
+ # ---------------------------
36
+ def self.fabric_enable
37
+ # install feature-set and enable it
38
+ return if fabric_enabled?
39
+ config_set('feature', 'fabric', state: 'install') unless fabric_installed?
40
+ config_set('feature', 'fabric', state: '')
41
+ end
42
+
43
+ def self.fabric_enabled?
44
+ config_get('feature', 'fabric') =~ /^enabled/
45
+ end
46
+
47
+ def self.fabric_installed?
48
+ config_get('feature', 'fabric') !~ /^uninstalled/
49
+ end
50
+
51
+ def self.fabric_supported?
52
+ config_get('feature', 'fabric')
53
+ end
54
+
55
+ # ---------------------------
56
+ def self.fabric_forwarding_enable
57
+ return if fabric_forwarding_enabled?
58
+ Feature.fabric_enable if Feature.fabric_supported?
59
+ # The feature fabric-forwarding cli is required in some older nxos images
60
+ # but is not present in newer images because nv_overlay_evpn handles
61
+ # both features; therefore feature fabric-forwarding is best-effort
62
+ # and ignored on cli failure.
63
+ begin
64
+ config_set('feature', 'fabric_forwarding')
65
+ rescue Cisco::CliError
66
+ CiscoLogger.debug '"feature fabric forwarding" CLI was rejected'
67
+ end
68
+ end
69
+
70
+ def self.fabric_forwarding_enabled?
71
+ config_get('feature', 'fabric_forwarding')
72
+ end
73
+
74
+ # ---------------------------
75
+ def self.nv_overlay_enable
76
+ # Note: vdc platforms restrict this feature to F3 or newer linecards
77
+ return if nv_overlay_enabled?
78
+ config_set('feature', 'nv_overlay')
79
+ end
80
+
81
+ def self.nv_overlay_enabled?
82
+ config_get('feature', 'nv_overlay')
83
+ rescue Cisco::CliError => e
84
+ # cmd will syntax reject when feature is not enabled.
85
+ raise unless e.clierror =~ /Syntax error/
86
+ return false
87
+ end
88
+
89
+ # ---------------------------
90
+ def self.nv_overlay_evpn_enable
91
+ return if nv_overlay_evpn_enabled?
92
+ config_set('feature', 'nv_overlay_evpn')
93
+ end
94
+
95
+ def self.nv_overlay_evpn_enabled?
96
+ config_get('feature', 'nv_overlay_evpn')
97
+ end
98
+
99
+ # ---------------------------
100
+ def self.vn_segment_vlan_based_enable
101
+ return if vn_segment_vlan_based_enabled?
102
+ config_set('feature', 'vn_segment_vlan_based')
103
+ end
104
+
105
+ def self.vn_segment_vlan_based_enabled?
106
+ config_get('feature', 'vn_segment_vlan_based')
107
+ end
108
+
109
+ # ---------------------------
110
+ end
111
+ end
@@ -1,6 +1,6 @@
1
1
  # November 2015, Chris Van Heuveln
2
2
  #
3
- # Copyright (c) 2015 Cisco and/or its affiliates.
3
+ # Copyright (c) 2015-2016 Cisco and/or its affiliates.
4
4
  #
5
5
  # Licensed under the Apache License, Version 2.0 (the "License");
6
6
  # you may not use this file except in compliance with the License.
@@ -14,7 +14,12 @@
14
14
  # See the License for the specific language governing permissions and
15
15
  # limitations under the License.
16
16
 
17
+ require_relative 'cisco_cmn_utils'
17
18
  require_relative 'node_util'
19
+ require_relative 'pim'
20
+ require_relative 'vrf'
21
+ require_relative 'vni'
22
+ require_relative 'overlay_global'
18
23
 
19
24
  # Add some interface-specific constants to the Cisco namespace
20
25
  module Cisco
@@ -24,6 +29,7 @@ module Cisco
24
29
  trunk: 'trunk',
25
30
  fex_fabric: 'fex-fabric',
26
31
  tunnel: 'dot1q-tunnel',
32
+ fabricpath: 'fabricpath',
27
33
  }
28
34
 
29
35
  # Interface - node utility class for general interface config management
@@ -64,9 +70,7 @@ module Cisco
64
70
  ########################################################
65
71
 
66
72
  def access_vlan
67
- vlan = config_get('interface', 'access_vlan', @name)
68
- return default_access_vlan if vlan.nil?
69
- vlan.shift.to_i
73
+ config_get('interface', 'access_vlan', @name)
70
74
  end
71
75
 
72
76
  def access_vlan=(vlan)
@@ -75,14 +79,90 @@ module Cisco
75
79
  raise "[#{@name}] '#{e.command}' : #{e.clierror}"
76
80
  end
77
81
 
82
+ def ipv4_acl_in
83
+ config_get('interface', 'ipv4_acl_in', @name)
84
+ end
85
+
86
+ def ipv4_acl_in=(val)
87
+ if val != ''
88
+ state = ''
89
+ else
90
+ state = 'no'
91
+ val = ipv4_acl_in
92
+ end
93
+
94
+ return unless val && val != ''
95
+ config_set('interface', 'ipv4_acl_in', @name, state, val)
96
+ end
97
+
98
+ def default_ipv4_acl_in
99
+ config_get_default('interface', 'ipv4_acl_in')
100
+ end
101
+
102
+ def ipv4_acl_out
103
+ config_get('interface', 'ipv4_acl_out', @name)
104
+ end
105
+
106
+ def ipv4_acl_out=(val)
107
+ if val != ''
108
+ state = ''
109
+ else
110
+ state = 'no'
111
+ val = ipv4_acl_out
112
+ end
113
+
114
+ return unless val && val != ''
115
+ config_set('interface', 'ipv4_acl_out', @name, state, val)
116
+ end
117
+
118
+ def default_ipv4_acl_out
119
+ config_get_default('interface', 'ipv4_acl_out')
120
+ end
121
+
122
+ def ipv6_acl_in
123
+ config_get('interface', 'ipv6_acl_in', @name)
124
+ end
125
+
126
+ def ipv6_acl_in=(val)
127
+ if val != ''
128
+ state = ''
129
+ else
130
+ state = 'no'
131
+ val = ipv6_acl_in
132
+ end
133
+ return unless val && val != ''
134
+ config_set('interface', 'ipv6_acl_in', @name, state, val)
135
+ end
136
+
137
+ def default_ipv6_acl_in
138
+ config_get_default('interface', 'ipv6_acl_in')
139
+ end
140
+
141
+ def ipv6_acl_out
142
+ config_get('interface', 'ipv6_acl_out', @name)
143
+ end
144
+
145
+ def ipv6_acl_out=(val)
146
+ if val != ''
147
+ state = ''
148
+ else
149
+ state = 'no'
150
+ val = ipv6_acl_out
151
+ end
152
+ return unless val && val != ''
153
+ config_set('interface', 'ipv6_acl_out', @name, state, val)
154
+ end
155
+
156
+ def default_ipv6_acl_out
157
+ config_get_default('interface', 'ipv6_acl_out')
158
+ end
159
+
78
160
  def default_access_vlan
79
161
  config_get_default('interface', 'access_vlan')
80
162
  end
81
163
 
82
164
  def description
83
- desc = config_get('interface', 'description', @name)
84
- return '' if desc.nil?
85
- desc.shift.strip
165
+ config_get('interface', 'description', @name)
86
166
  end
87
167
 
88
168
  def description=(desc)
@@ -101,9 +181,7 @@ module Cisco
101
181
  end
102
182
 
103
183
  def encapsulation_dot1q
104
- val = config_get('interface', 'encapsulation_dot1q', @name)
105
- return default_encapsulation_dot1q if val.nil?
106
- val.shift.strip.to_i
184
+ config_get('interface', 'encapsulation_dot1q', @name)
107
185
  end
108
186
 
109
187
  def encapsulation_dot1q=(val)
@@ -120,10 +198,43 @@ module Cisco
120
198
  config_get_default('interface', 'encapsulation_dot1q')
121
199
  end
122
200
 
201
+ def fabricpath_feature
202
+ FabricpathGlobal.fabricpath_feature
203
+ end
204
+
205
+ def fabricpath_feature_set(fabricpath_set)
206
+ FabricpathGlobal.fabricpath_feature_set(fabricpath_set)
207
+ end
208
+
209
+ def fabric_forwarding_anycast_gateway
210
+ config_get('interface', 'fabric_forwarding_anycast_gateway', @name)
211
+ end
212
+
213
+ def fabric_forwarding_anycast_gateway=(state)
214
+ no_cmd = (state ? '' : 'no')
215
+ config_set('interface',
216
+ 'fabric_forwarding_anycast_gateway', @name, no_cmd)
217
+ fail if fabric_forwarding_anycast_gateway.to_s != state.to_s
218
+ rescue Cisco::CliError => e
219
+ info = "[#{@name}] '#{e.command}' : #{e.clierror}"
220
+ raise "#{info} 'fabric_forwarding_anycast_gateway' can only be " \
221
+ 'configured on a vlan interface' unless /vlan/.match(@name)
222
+ anycast_gateway_mac = OverlayGlobal.new.anycast_gateway_mac
223
+ if anycast_gateway_mac.nil? || anycast_gateway_mac.empty?
224
+ raise "#{info} Anycast gateway mac must be configured " \
225
+ 'before configuring forwarding mode under interface'
226
+ end
227
+ raise info
228
+ end
229
+
230
+ def default_fabric_forwarding_anycast_gateway
231
+ config_get_default('interface', 'fabric_forwarding_anycast_gateway')
232
+ end
233
+
123
234
  def fex_feature
124
235
  fex = config_get('fex', 'feature')
125
236
  fail 'fex_feature not found' if fex.nil?
126
- fex.shift.to_sym
237
+ fex.to_sym
127
238
  end
128
239
 
129
240
  def fex_feature_set(fex_set)
@@ -147,47 +258,127 @@ module Cisco
147
258
  raise "[#{@name}] '#{e.command}' : #{e.clierror}"
148
259
  end
149
260
 
150
- def ipv4_addr_mask
151
- config_get('interface', 'ipv4_addr_mask', @name)
152
- end
153
-
154
- def ipv4_addr_mask_set(addr, mask)
261
+ def ipv4_addr_mask_set(addr, mask, secondary=false)
155
262
  check_switchport_disabled
263
+ sec = secondary ? 'secondary' : ''
156
264
  if addr.nil? || addr == default_ipv4_address
157
- config_set('interface', 'ipv4_addr_mask', @name, 'no', '')
265
+ state = 'no'
266
+ if secondary
267
+ return if ipv4_address_secondary == default_ipv4_address_secondary
268
+ # We need address and mask to remove.
269
+ am = "#{ipv4_address_secondary}/#{ipv4_netmask_length_secondary}"
270
+ else
271
+ return if ipv4_address == default_ipv4_address
272
+ am = "#{ipv4_address}/#{ipv4_netmask_length}"
273
+ end
158
274
  else
159
- config_set('interface', 'ipv4_addr_mask', @name, '',
160
- "#{addr}/#{mask}")
275
+ state = ''
276
+ am = "#{addr}/#{mask}"
161
277
  end
278
+ config_set('interface', 'ipv4_addr_mask', @name, state, am, sec)
162
279
  rescue Cisco::CliError => e
163
280
  raise "[#{@name}] '#{e.command}' : #{e.clierror}"
164
281
  end
165
282
 
283
+ def ipv4_addr_mask
284
+ config_get('interface', 'ipv4_addr_mask', @name)
285
+ end
286
+
287
+ def select_ipv4_attribute(attribute)
288
+ d = ipv4_addr_mask.flatten unless ipv4_addr_mask.nil?
289
+ # (d)ata format after flatten: ['addr', 'mask', 'addr', 'mask secondary']
290
+ case attribute
291
+ when :v4_addr
292
+ v = d.nil? ? default_ipv4_address : d[0]
293
+ when :v4_mask
294
+ v = d.nil? ? default_ipv4_netmask_length : d[1].to_i
295
+ when :v4_addr_secondary
296
+ v = (d.nil? || d.size < 4) ? default_ipv4_address : d[2]
297
+ when :v4_mask_secondary
298
+ if d.nil? || d.size < 4
299
+ v = default_ipv4_netmask_length
300
+ else
301
+ v = d[3][0, 2].to_i
302
+ end
303
+ end
304
+ v
305
+ end
306
+
166
307
  def ipv4_address
167
- val = ipv4_addr_mask
168
- return default_ipv4_address if val.nil?
169
- # val is [[addr, mask]] - we just want the addr
170
- val.shift.first
308
+ select_ipv4_attribute(:v4_addr)
309
+ end
310
+
311
+ def ipv4_address_secondary
312
+ select_ipv4_attribute(:v4_addr_secondary)
313
+ end
314
+
315
+ def ipv4_netmask_length
316
+ select_ipv4_attribute(:v4_mask)
317
+ end
318
+
319
+ def ipv4_netmask_length_secondary
320
+ select_ipv4_attribute(:v4_mask_secondary)
171
321
  end
172
322
 
173
323
  def default_ipv4_address
174
324
  config_get_default('interface', 'ipv4_address')
175
325
  end
176
326
 
177
- def ipv4_netmask_length
178
- val = ipv4_addr_mask
179
- return default_ipv4_netmask_length if val.nil?
180
- # val is [[addr, mask]] - we just want the mask
181
- val.shift.last.to_i
327
+ def default_ipv4_address_secondary
328
+ default_ipv4_address
182
329
  end
183
330
 
184
331
  def default_ipv4_netmask_length
185
332
  config_get_default('interface', 'ipv4_netmask_length')
186
333
  end
187
334
 
335
+ def default_ipv4_netmask_length_secondary
336
+ default_ipv4_netmask_length
337
+ end
338
+
339
+ def ipv4_arp_timeout_lookup_string
340
+ case @name
341
+ when /vlan/i
342
+ return 'ipv4_arp_timeout'
343
+ else
344
+ return 'ipv4_arp_timeout_non_vlan_interfaces'
345
+ end
346
+ end
347
+
348
+ def ipv4_arp_timeout
349
+ config_get('interface', ipv4_arp_timeout_lookup_string, @name)
350
+ end
351
+
352
+ def ipv4_arp_timeout=(timeout)
353
+ fail "'ipv4 arp timeout' can ony be configured on a vlan interface" unless
354
+ /vlan/.match(@name)
355
+ state = (timeout == default_ipv4_arp_timeout) ? 'no' : ''
356
+ config_set('interface', 'ipv4_arp_timeout', @name, state, timeout)
357
+ end
358
+
359
+ def default_ipv4_arp_timeout
360
+ config_get_default('interface', ipv4_arp_timeout_lookup_string)
361
+ end
362
+
363
+ def ipv4_pim_sparse_mode
364
+ config_get('interface', 'ipv4_pim_sparse_mode', @name)
365
+ end
366
+
367
+ def ipv4_pim_sparse_mode=(state)
368
+ check_switchport_disabled
369
+ Pim.feature_enable unless Pim.feature_enabled
370
+ config_set('interface', 'ipv4_pim_sparse_mode', @name,
371
+ state ? '' : 'no')
372
+ rescue Cisco::CliError => e
373
+ raise "[#{@name}] '#{e.command}' : #{e.clierror}"
374
+ end
375
+
376
+ def default_ipv4_pim_sparse_mode
377
+ config_get_default('interface', 'ipv4_pim_sparse_mode')
378
+ end
379
+
188
380
  def ipv4_proxy_arp
189
- state = config_get('interface', 'ipv4_proxy_arp', @name)
190
- state.nil? ? false : true
381
+ config_get('interface', 'ipv4_proxy_arp', @name)
191
382
  end
192
383
 
193
384
  def ipv4_proxy_arp=(proxy_arp)
@@ -210,24 +401,13 @@ module Cisco
210
401
  end
211
402
 
212
403
  def ipv4_redirects
213
- begin
214
- state = config_get('interface',
215
- ipv4_redirects_lookup_string, @name)
216
- rescue IndexError
217
- state = nil
218
- end
219
- # We return default state for the platform if the platform doesn't support
220
- # the command
221
- return default_ipv4_redirects if state.nil? || state.empty?
222
- state.shift[/^ip redirects$/] ? true : false
404
+ config_get('interface', ipv4_redirects_lookup_string, @name)
223
405
  end
224
406
 
225
407
  def ipv4_redirects=(redirects)
226
408
  check_switchport_disabled
227
409
  no_cmd = (redirects ? '' : 'no')
228
410
  config_set('interface', ipv4_redirects_lookup_string, @name, no_cmd)
229
- rescue IndexError
230
- raise "ipv4 redirects not supported on #{@name}"
231
411
  end
232
412
 
233
413
  def default_ipv4_redirects
@@ -235,7 +415,7 @@ module Cisco
235
415
  end
236
416
 
237
417
  def feature_lacp?
238
- !config_get('interface', 'feature_lacp').nil?
418
+ config_get('interface', 'feature_lacp')
239
419
  end
240
420
 
241
421
  def feature_lacp_set(val)
@@ -244,9 +424,7 @@ module Cisco
244
424
  end
245
425
 
246
426
  def mtu
247
- mtu = config_get('interface', 'mtu', @name)
248
- return default_mtu if mtu.nil?
249
- mtu.shift.strip.to_i
427
+ config_get('interface', 'mtu', @name)
250
428
  end
251
429
 
252
430
  def mtu=(val)
@@ -260,6 +438,40 @@ module Cisco
260
438
  config_get_default('interface', 'mtu')
261
439
  end
262
440
 
441
+ def speed
442
+ config_get('interface', 'speed', @name)
443
+ end
444
+
445
+ def speed=(val)
446
+ if node.product_id =~ /C31\d\d/
447
+ fail 'Changing interface speed is not permitted on this platform'
448
+ end
449
+ config_set('interface', 'speed', @name, val)
450
+ rescue Cisco::CliError => e
451
+ raise "[#{@name}] '#{e.command}' : #{e.clierror}"
452
+ end
453
+
454
+ def default_speed
455
+ config_get_default('interface', 'speed')
456
+ end
457
+
458
+ def duplex
459
+ config_get('interface', 'duplex', @name)
460
+ end
461
+
462
+ def duplex=(val)
463
+ if node.product_id =~ /C31\d\d/
464
+ fail 'Changing interface duplex is not permitted on this platform'
465
+ end
466
+ config_set('interface', 'duplex', @name, val)
467
+ rescue Cisco::CliError => e
468
+ raise "[#{@name}] '#{e.command}' : #{e.clierror}"
469
+ end
470
+
471
+ def default_duplex
472
+ config_get_default('interface', 'duplex')
473
+ end
474
+
263
475
  def negotiate_auto_lookup_string
264
476
  case @name
265
477
  when /Ethernet/i
@@ -272,29 +484,13 @@ module Cisco
272
484
  end
273
485
 
274
486
  def negotiate_auto
275
- lookup = negotiate_auto_lookup_string
276
- begin
277
- state = config_get('interface', lookup, @name)
278
- rescue IndexError
279
- # We return default state even if the config_get is not supported
280
- # for this platform / interface type. This is done so that we can set
281
- # the manifest to 'default' so there is a 'workaround' for the
282
- # unsupported attribute
283
- return default_negotiate_auto
284
- end
285
- state.nil? ? false : true
487
+ config_get('interface', negotiate_auto_lookup_string, @name)
286
488
  end
287
489
 
288
490
  def negotiate_auto=(negotiate_auto)
289
491
  lookup = negotiate_auto_lookup_string
290
492
  no_cmd = (negotiate_auto ? '' : 'no')
291
- begin
292
- config_set('interface', lookup, @name, no_cmd)
293
- rescue Cisco::CliError => e
294
- raise "[#{@name}] '#{e.command}' : #{e.clierror}"
295
- rescue IndexError
296
- raise "[#{@name}] negotiate_auto is not supported on this interface"
297
- end
493
+ config_set('interface', lookup, @name, no_cmd)
298
494
  end
299
495
 
300
496
  def default_negotiate_auto
@@ -302,8 +498,7 @@ module Cisco
302
498
  end
303
499
 
304
500
  def shutdown
305
- state = config_get('interface', 'shutdown', @name)
306
- state ? true : false
501
+ config_get('interface', 'shutdown', @name)
307
502
  end
308
503
 
309
504
  def shutdown=(state)
@@ -348,8 +543,7 @@ module Cisco
348
543
 
349
544
  def switchport
350
545
  # This is "switchport", not "switchport mode"
351
- sw = config_get('interface', 'switchport', @name)
352
- sw.nil? ? false : true
546
+ config_get('interface', 'switchport', @name)
353
547
  end
354
548
 
355
549
  def switchport_enable(val=true)
@@ -358,8 +552,8 @@ module Cisco
358
552
 
359
553
  # switchport_autostate_exclude is exclusive to switchport interfaces
360
554
  def switchport_autostate_exclude
361
- !config_get('interface',
362
- 'switchport_autostate_exclude', @name).nil?
555
+ config_get('interface',
556
+ 'switchport_autostate_exclude', @name)
363
557
  end
364
558
 
365
559
  def switchport_autostate_exclude=(val)
@@ -389,7 +583,7 @@ module Cisco
389
583
  def switchport_mode
390
584
  mode = config_get('interface', switchport_mode_lookup_string, @name)
391
585
 
392
- return mode.nil? ? :disabled : IF_SWITCHPORT_MODE.key(mode.shift)
586
+ return mode.nil? ? :disabled : IF_SWITCHPORT_MODE.key(mode)
393
587
 
394
588
  rescue IndexError
395
589
  # Assume this is an interface that doesn't support switchport.
@@ -401,8 +595,10 @@ module Cisco
401
595
  def switchport_enable_and_mode(mode_set)
402
596
  switchport_enable unless switchport
403
597
 
404
- if (:fex_fabric == mode_set)
405
- fex_feature_set(:enabled) unless (:enabled == fex_feature)
598
+ if :fabricpath == mode_set
599
+ fabricpath_feature_set(:enabled) unless :enabled == fabricpath_feature
600
+ elsif :fex_fabric == mode_set
601
+ fex_feature_set(:enabled) unless :enabled == fex_feature
406
602
  end
407
603
  config_set('interface', switchport_mode_lookup_string, @name, '',
408
604
  IF_SWITCHPORT_MODE[mode_set])
@@ -447,10 +643,7 @@ module Cisco
447
643
  end
448
644
 
449
645
  def switchport_trunk_allowed_vlan
450
- val = config_get(
451
- 'interface', 'switchport_trunk_allowed_vlan', @name)
452
- return default_switchport_trunk_allowed_vlan if val.nil?
453
- val.shift.strip
646
+ config_get('interface', 'switchport_trunk_allowed_vlan', @name)
454
647
  end
455
648
 
456
649
  def switchport_trunk_allowed_vlan=(val)
@@ -470,10 +663,7 @@ module Cisco
470
663
  end
471
664
 
472
665
  def switchport_trunk_native_vlan
473
- val = config_get(
474
- 'interface', 'switchport_trunk_native_vlan', @name)
475
- return default_switchport_trunk_native_vlan if val.nil?
476
- val.shift.strip.to_i
666
+ config_get('interface', 'switchport_trunk_native_vlan', @name)
477
667
  end
478
668
 
479
669
  def switchport_trunk_native_vlan=(val)
@@ -488,28 +678,103 @@ module Cisco
488
678
  raise "[#{@name}] '#{e.command}' : #{e.clierror}"
489
679
  end
490
680
 
681
+ # vlan_mapping & vlan_mapping_enable
682
+ # Hardware & Cli Dependencies:
683
+ # - F3 linecards only
684
+ # - vdc
685
+ # - limit-resource
686
+ # - bridge-domain
687
+ # - feature vni
688
+ # - switchport mode
689
+
690
+ # Getter: Builds an array of vlan_mapping commands currently
691
+ # on the device.
692
+ # cli: switchport vlan mapping 2 200
693
+ # switchport vlan mapping 4 400
694
+ # array: [['2', '200'], ['4', '400']]
695
+ #
696
+ def default_vlan_mapping
697
+ config_get_default('interface', 'vlan_mapping')
698
+ end
699
+
700
+ def vlan_mapping
701
+ match = config_get('interface', 'vlan_mapping', @name)
702
+ match.each(&:compact!) unless match.nil?
703
+ match
704
+ end
705
+
706
+ def vlan_mapping=(should_list)
707
+ Vni.feature_vni_enable unless Vni.feature_vni_enabled
708
+
709
+ # Process a hash of vlan_mapping cmds from delta_add_remove().
710
+ # The vlan_mapping cli does not allow commands to be updated, they must
711
+ # first be removed if there is a change.
712
+ delta_hash = Utils.delta_add_remove(should_list, vlan_mapping,
713
+ :updates_not_allowed)
714
+ return if delta_hash.values.flatten.empty?
715
+ # Process :remove first to ensure "update" commands will not fail.
716
+ [:remove, :add].each do |action|
717
+ CiscoLogger.debug("vlan_mapping delta #{@get_args}\n"\
718
+ "#{action}: #{delta_hash[action]}")
719
+ delta_hash[action].each do |original, translated|
720
+ state = (action == :add) ? '' : 'no'
721
+ config_set('interface', 'vlan_mapping', @name,
722
+ state, original, translated)
723
+ end
724
+ end
725
+ rescue Cisco::CliError => e
726
+ raise "[#{@name}] '#{e.command}' : #{e.clierror}"
727
+ end
728
+
729
+ # cli: switchport vlan mapping enable
730
+ def default_vlan_mapping_enable
731
+ config_get_default('interface', 'vlan_mapping_enable')
732
+ end
733
+
734
+ def vlan_mapping_enable
735
+ config_get('interface', 'vlan_mapping_enable', @name)
736
+ end
737
+
738
+ def vlan_mapping_enable=(state)
739
+ config_set('interface', 'vlan_mapping_enable', @name,
740
+ state ? '' : 'no')
741
+ end
742
+
491
743
  def default_switchport_trunk_native_vlan
492
744
  config_get_default('interface', 'switchport_trunk_native_vlan')
493
745
  end
494
746
 
495
747
  def system_default_switchport
496
748
  # This command is a user-configurable system default.
497
- sys_def = config_get('interface', 'system_default_switchport')
498
- sys_def.nil? ? false : true
749
+ #
750
+ # Note: This is a simple boolean state but there is a bug on some
751
+ # platforms that causes the cli to nvgen twice; this causes config_get to
752
+ # raise an error when it encounters the multiple. Therefore we define it
753
+ # as a multiple to avoid the raise and handle the array if necessary.
754
+ #
755
+ val = config_get('interface', 'system_default_switchport')
756
+ return (val[0][/^no /] ? false : true) if val.is_a?(Array)
757
+ val
499
758
  end
500
759
 
501
760
  def system_default_switchport_shutdown
502
761
  # This command is a user-configurable system default.
503
- sys_def = config_get('interface',
504
- 'system_default_switchport_shutdown')
505
- sys_def.nil? ? false : true
762
+ config_get('interface', 'system_default_switchport_shutdown')
506
763
  end
507
764
 
508
765
  def system_default_svi_autostate
509
766
  # This command is a user-configurable system default.
510
- sys_def = config_get('interface',
511
- 'system_default_svi_autostate')
512
- sys_def.nil? ? false : true
767
+ #
768
+ # This property behaves differently on an n7k vs ni(3|9)k and therefore
769
+ # needs special handling.
770
+ # N7K: When enabled, does not nvgen.
771
+ # When disabled, does nvgen, but differently then n(3|9)k.
772
+ # Return true for the disabled case, false otherwise.
773
+ # N(3|9)K: When enabled, does nvgen.
774
+ # When disabled, does nvgen.
775
+ # Return true for the enabled case, false otherwise.
776
+ result = config_get('interface', 'system_default_svi_autostate')
777
+ /N7K/.match(node.product_id) ? !result : result
513
778
  end
514
779
 
515
780
  def switchport_vtp_mode_capable?
@@ -518,8 +783,7 @@ module Cisco
518
783
 
519
784
  def switchport_vtp
520
785
  return false unless switchport_vtp_mode_capable?
521
- vtp = config_get('interface', 'vtp', @name)
522
- vtp.nil? ? false : true
786
+ config_get('interface', 'vtp', @name)
523
787
  end
524
788
 
525
789
  def switchport_vtp=(vtp_set)
@@ -538,7 +802,7 @@ module Cisco
538
802
  # svi_autostate is exclusive to svi interfaces
539
803
  def svi_autostate
540
804
  return nil unless @name[/^vlan/i]
541
- !config_get('interface', 'svi_autostate', @name).nil?
805
+ config_get('interface', 'svi_autostate', @name)
542
806
  end
543
807
 
544
808
  def svi_autostate=(val)
@@ -552,7 +816,7 @@ module Cisco
552
816
  end
553
817
 
554
818
  def feature_vlan?
555
- !config_get('interface', 'feature_vlan').nil?
819
+ config_get('interface', 'feature_vlan')
556
820
  end
557
821
 
558
822
  def feature_vlan_set(val)
@@ -563,7 +827,7 @@ module Cisco
563
827
  # svi_management is exclusive to svi interfaces
564
828
  def svi_management
565
829
  return nil unless @name[/^vlan/i]
566
- !config_get('interface', 'svi_management', @name).nil?
830
+ config_get('interface', 'svi_management', @name)
567
831
  end
568
832
 
569
833
  def svi_management=(val)
@@ -589,10 +853,39 @@ module Cisco
589
853
  ' is disabled' unless switchport_mode == :disabled
590
854
  end
591
855
 
856
+ def vpc_id
857
+ config_get('interface', 'vpc_id', @name)
858
+ end
859
+
860
+ def vpc_id=(num)
861
+ if num
862
+ config_set('interface', 'vpc_id', @name, '', num)
863
+ else
864
+ # 'no vpc' doesn't work for phy ports, so do a get
865
+ num = vpc_id
866
+ config_set('interface', 'vpc_id', @name, 'no', num)
867
+ end
868
+ end
869
+
870
+ def default_vpc_id
871
+ config_get_default('interface', 'vpc_id')
872
+ end
873
+
874
+ def vpc_peer_link
875
+ config_get('interface', 'vpc_peer_link', @name)
876
+ end
877
+
878
+ def vpc_peer_link=(state)
879
+ no_cmd = (state ? '' : 'no')
880
+ config_set('interface', 'vpc_peer_link', @name, no_cmd)
881
+ end
882
+
883
+ def default_vpc_peer_link
884
+ config_get_default('interface', 'vpc_peer_link')
885
+ end
886
+
592
887
  def vrf
593
- vrf = config_get('interface', 'vrf', @name)
594
- return '' if vrf.nil?
595
- vrf.shift.strip
888
+ config_get('interface', 'vrf', @name)
596
889
  end
597
890
 
598
891
  def vrf=(vrf)