cisco_node_utils 1.3.0 → 1.4.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.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/CHANGELOG.md +66 -0
- data/Gemfile +1 -0
- data/README.md +44 -43
- data/bin/.rubocop.yml +18 -0
- data/bin/show_running_yang.rb +233 -0
- data/cisco_node_utils.gemspec +1 -1
- data/docs/README-maintainers.md +1 -0
- data/docs/README-utilities.md +14 -0
- data/lib/.rubocop.yml +1 -1
- data/lib/cisco_node_utils/aaa_authentication_login_service.rb +8 -3
- data/lib/cisco_node_utils/aaa_authorization_service.rb +6 -0
- data/lib/cisco_node_utils/bfd_global.rb +300 -0
- data/lib/cisco_node_utils/bgp.rb +6 -4
- data/lib/cisco_node_utils/bgp_af.rb +2 -0
- data/lib/cisco_node_utils/bgp_neighbor.rb +14 -0
- data/lib/cisco_node_utils/bgp_neighbor_af.rb +4 -1
- data/lib/cisco_node_utils/cisco_cmn_utils.rb +126 -0
- data/lib/cisco_node_utils/client/client.rb +6 -2
- data/lib/cisco_node_utils/client/grpc/client.rb +120 -36
- data/lib/cisco_node_utils/client/nxapi/client.rb +6 -2
- data/lib/cisco_node_utils/cmd_ref/DEPRECATED.yaml +118 -0
- data/lib/cisco_node_utils/cmd_ref/aaa_authorization_service.yaml +14 -0
- data/lib/cisco_node_utils/cmd_ref/bfd_global.yaml +117 -0
- data/lib/cisco_node_utils/cmd_ref/bgp.yaml +7 -7
- data/lib/cisco_node_utils/cmd_ref/bgp_neighbor.yaml +7 -0
- data/lib/cisco_node_utils/cmd_ref/dhcp_relay_global.yaml +125 -0
- data/lib/cisco_node_utils/cmd_ref/feature.yaml +10 -0
- data/lib/cisco_node_utils/cmd_ref/interface.yaml +141 -49
- data/lib/cisco_node_utils/cmd_ref/interface_ospf.yaml +44 -0
- data/lib/cisco_node_utils/cmd_ref/interface_portchannel.yaml +6 -0
- data/lib/cisco_node_utils/cmd_ref/ospf.yaml +6 -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 +0 -3
- data/lib/cisco_node_utils/cmd_ref/show_version.yaml +3 -3
- data/lib/cisco_node_utils/cmd_ref/snmp_community.yaml +39 -15
- data/lib/cisco_node_utils/cmd_ref/snmp_notification_receiver.yaml +43 -21
- data/lib/cisco_node_utils/cmd_ref/snmp_server.yaml +48 -19
- data/lib/cisco_node_utils/cmd_ref/snmp_user.yaml +0 -0
- data/lib/cisco_node_utils/cmd_ref/tacacs_global.yaml +30 -0
- data/lib/cisco_node_utils/cmd_ref/tacacs_server.yaml +18 -6
- data/lib/cisco_node_utils/cmd_ref/vdc.yaml +4 -0
- data/lib/cisco_node_utils/cmd_ref/virtual_service.yaml +1 -0
- data/lib/cisco_node_utils/cmd_ref/vlan.yaml +23 -10
- data/lib/cisco_node_utils/cmd_ref/vxlan_vtep.yaml +8 -2
- data/lib/cisco_node_utils/cmd_ref/yang.yaml +7 -0
- data/lib/cisco_node_utils/cmd_ref/yum.yaml +10 -1
- data/lib/cisco_node_utils/constants.rb +8 -1
- data/lib/cisco_node_utils/dhcp_relay_global.rb +302 -0
- data/lib/cisco_node_utils/exceptions.rb +29 -0
- data/lib/cisco_node_utils/feature.rb +28 -0
- data/lib/cisco_node_utils/interface.rb +493 -402
- data/lib/cisco_node_utils/interface_DEPRECATED.rb +513 -0
- data/lib/cisco_node_utils/interface_ospf.rb +126 -0
- data/lib/cisco_node_utils/interface_portchannel.rb +16 -0
- data/lib/cisco_node_utils/logger.rb +3 -0
- data/lib/cisco_node_utils/node.rb +29 -1
- data/lib/cisco_node_utils/overlay_global.rb +1 -12
- data/lib/cisco_node_utils/pim.rb +1 -0
- data/lib/cisco_node_utils/pim_group_list.rb +1 -0
- data/lib/cisco_node_utils/pim_rp_address.rb +1 -0
- data/lib/cisco_node_utils/platform.rb +9 -2
- data/lib/cisco_node_utils/router_ospf.rb +1 -1
- 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 +17 -0
- data/lib/cisco_node_utils/snmp_notification_receiver.rb +27 -9
- data/lib/cisco_node_utils/snmpcommunity.rb +34 -8
- data/lib/cisco_node_utils/snmpserver.rb +4 -4
- data/lib/cisco_node_utils/snmpuser.rb +0 -0
- data/lib/cisco_node_utils/tacacs_global.rb +102 -0
- data/lib/cisco_node_utils/tacacs_server.rb +8 -7
- data/lib/cisco_node_utils/vdc.rb +25 -7
- data/lib/cisco_node_utils/version.rb +1 -1
- data/lib/cisco_node_utils/vlan.rb +30 -56
- data/lib/cisco_node_utils/vlan_DEPRECATED.rb +108 -0
- data/lib/cisco_node_utils/yang.rb +160 -0
- data/lib/cisco_node_utils/yum.rb +25 -32
- data/tests/.rubocop.yml +3 -0
- data/tests/ciscotest.rb +136 -19
- data/tests/cmd_config_invalid.yaml +1 -1
- data/tests/noop.rb +7 -0
- data/tests/tacacs_server.yaml.example +6 -0
- data/tests/test_aaa_authentication_login.rb +24 -1
- data/tests/test_aaa_authentication_login_service.rb +9 -16
- data/tests/test_aaa_authorization_service.rb +111 -84
- data/tests/test_bfd_global.rb +278 -0
- data/tests/test_bgp_neighbor.rb +20 -0
- data/tests/test_bridge_domain_vni.rb +2 -9
- data/tests/test_cmn_utils.rb +76 -0
- data/tests/test_dhcp_relay_global.rb +284 -0
- data/tests/test_dns_domain.rb +4 -4
- data/tests/test_domain_name.rb +2 -2
- data/tests/test_encapsulation.rb +2 -4
- data/tests/test_evpn_vni.rb +14 -7
- data/tests/test_fabricpath_global.rb +12 -13
- data/tests/test_feature.rb +35 -17
- data/tests/test_interface.rb +352 -127
- data/tests/test_interface_bdi.rb +2 -2
- data/tests/test_interface_channel_group.rb +1 -1
- data/tests/test_interface_ospf.rb +153 -23
- data/tests/test_interface_portchannel.rb +15 -6
- data/tests/test_interface_private_vlan.rb +200 -576
- data/tests/test_interface_svi.rb +5 -52
- data/tests/test_interface_switchport.rb +80 -240
- data/tests/test_itd_device_group.rb +2 -2
- data/tests/test_itd_device_group_node.rb +2 -2
- data/tests/test_itd_service.rb +1 -1
- data/tests/test_name_server.rb +3 -3
- data/tests/test_node_ext.rb +15 -17
- data/tests/test_ntp_config.rb +1 -1
- data/tests/test_ntp_server.rb +3 -3
- data/tests/test_nxapi.rb +1 -0
- data/tests/test_overlay_global.rb +15 -19
- data/tests/test_pim.rb +5 -5
- data/tests/test_pim_group_list.rb +1 -37
- data/tests/test_pim_rp_address.rb +1 -1
- data/tests/test_platform.rb +9 -11
- data/tests/test_portchannel_global.rb +43 -3
- data/tests/test_radius_server.rb +1 -1
- data/tests/test_radius_server_group.rb +1 -1
- data/tests/test_router_bgp.rb +17 -30
- 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 +17 -0
- data/tests/test_snmp_notification_receiver.rb +11 -11
- data/tests/test_snmpcommunity.rb +177 -69
- data/tests/test_snmpgroup.rb +7 -7
- data/tests/test_snmpserver.rb +164 -253
- data/tests/test_snmpuser.rb +73 -69
- data/tests/test_stp_global.rb +15 -15
- data/tests/test_syslog_settings.rb +1 -1
- data/tests/test_tacacs_global.rb +80 -0
- data/tests/test_tacacs_server.rb +129 -51
- data/tests/test_tacacs_server_group.rb +3 -29
- data/tests/test_tacacs_server_host.rb +24 -27
- data/tests/test_vlan.rb +57 -59
- data/tests/test_vlan_private.rb +271 -284
- data/tests/test_vpc.rb +10 -4
- data/tests/test_vrf.rb +2 -0
- data/tests/test_vrf_af.rb +2 -5
- data/tests/test_vtp.rb +5 -2
- data/tests/test_vxlan_vtep.rb +20 -44
- data/tests/test_vxlan_vtep_vni.rb +23 -16
- data/tests/test_yang.rb +369 -0
- data/tests/test_yum.rb +34 -42
- data/tests/yum_package.yaml +35 -0
- metadata +31 -4
- data/tests/test_vlan_mt_full.rb +0 -85
|
@@ -88,6 +88,35 @@ module Cisco
|
|
|
88
88
|
end
|
|
89
89
|
end
|
|
90
90
|
|
|
91
|
+
# Extension of RequestFailed class specifically for YANG errors
|
|
92
|
+
class YangError < RequestFailed
|
|
93
|
+
def initialize(message=nil,
|
|
94
|
+
error: nil,
|
|
95
|
+
rejected_input: nil,
|
|
96
|
+
successful_input: [],
|
|
97
|
+
**kwargs)
|
|
98
|
+
unless message
|
|
99
|
+
if rejected_input.is_a?(Array)
|
|
100
|
+
if rejected_input.length > 1
|
|
101
|
+
message = "The following configs were rejected:\n"
|
|
102
|
+
message += " #{rejected_input.join("\n ")}\n"
|
|
103
|
+
else
|
|
104
|
+
message = "The config '#{rejected_input.first}' was rejected "
|
|
105
|
+
end
|
|
106
|
+
else
|
|
107
|
+
message = "The config '#{rejected_input}' was rejected "
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
message += "with error:\n#{error}"
|
|
111
|
+
end
|
|
112
|
+
super(message,
|
|
113
|
+
:error => error,
|
|
114
|
+
:rejected_input => rejected_input,
|
|
115
|
+
:successful_input => successful_input,
|
|
116
|
+
**kwargs)
|
|
117
|
+
end
|
|
118
|
+
end
|
|
119
|
+
|
|
91
120
|
# RequestNotSupported means we made a request that was validly
|
|
92
121
|
# constructed but includes options that are unsupported.
|
|
93
122
|
#
|
|
@@ -22,6 +22,20 @@ module Cisco
|
|
|
22
22
|
# Note that in most cases the enable methods should only enable;
|
|
23
23
|
# however, for test purposes it is sometimes convenient to support
|
|
24
24
|
# feature disablement for cleanup purposes.
|
|
25
|
+
# ---------------------------
|
|
26
|
+
def self.bfd_enable
|
|
27
|
+
return if bfd_enabled?
|
|
28
|
+
config_set('feature', 'bfd')
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def self.bfd_enabled?
|
|
32
|
+
config_get('feature', 'bfd')
|
|
33
|
+
rescue Cisco::CliError => e
|
|
34
|
+
# cmd will syntax reject when feature is not enabled.
|
|
35
|
+
raise unless e.clierror =~ /Syntax error/
|
|
36
|
+
return false
|
|
37
|
+
end
|
|
38
|
+
|
|
25
39
|
# ---------------------------
|
|
26
40
|
def self.bgp_enable
|
|
27
41
|
return if bgp_enabled?
|
|
@@ -32,6 +46,20 @@ module Cisco
|
|
|
32
46
|
config_get('feature', 'bgp')
|
|
33
47
|
end
|
|
34
48
|
|
|
49
|
+
# ---------------------------
|
|
50
|
+
def self.dhcp_enable
|
|
51
|
+
return if dhcp_enabled?
|
|
52
|
+
config_set('feature', 'dhcp')
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def self.dhcp_enabled?
|
|
56
|
+
config_get('feature', 'dhcp')
|
|
57
|
+
rescue Cisco::CliError => e
|
|
58
|
+
# cmd will syntax reject when feature is not enabled.
|
|
59
|
+
raise unless e.clierror =~ /Syntax error/
|
|
60
|
+
return false
|
|
61
|
+
end
|
|
62
|
+
|
|
35
63
|
# ---------------------------
|
|
36
64
|
def self.fabric_enable
|
|
37
65
|
# install feature-set and enable it
|
|
@@ -18,31 +18,29 @@ require_relative 'cisco_cmn_utils'
|
|
|
18
18
|
require_relative 'node_util'
|
|
19
19
|
require_relative 'vrf'
|
|
20
20
|
require_relative 'overlay_global'
|
|
21
|
+
require_relative 'interface_DEPRECATED'
|
|
21
22
|
|
|
22
|
-
#
|
|
23
|
+
# Cisco provider module
|
|
23
24
|
module Cisco
|
|
24
25
|
IF_SWITCHPORT_MODE = {
|
|
25
|
-
disabled:
|
|
26
|
-
access:
|
|
27
|
-
trunk:
|
|
28
|
-
fex_fabric:
|
|
29
|
-
tunnel:
|
|
30
|
-
fabricpath:
|
|
26
|
+
disabled: '',
|
|
27
|
+
access: 'access',
|
|
28
|
+
trunk: 'trunk',
|
|
29
|
+
fex_fabric: 'fex-fabric',
|
|
30
|
+
tunnel: 'dot1q-tunnel',
|
|
31
|
+
fabricpath: 'fabricpath',
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
# REMOVE THIS HASH WITH RELEASE 2.0.0
|
|
35
|
+
IF_DEPRECATED = {
|
|
31
36
|
host: 'host',
|
|
32
37
|
promiscuous: 'promiscuous',
|
|
33
38
|
secondary: 'secondary',
|
|
34
39
|
}
|
|
35
|
-
|
|
36
|
-
PVLAN_PROPERTY = {
|
|
37
|
-
host_promisc: 'switchport_mode_private_vlan_host_promiscous',
|
|
38
|
-
allow_vlan: 'switchport_private_vlan_trunk_allowed_vlan',
|
|
39
|
-
trunk_assoc: 'switchport_private_vlan_association_trunk',
|
|
40
|
-
mapping_trunk: 'switchport_private_vlan_mapping_trunk',
|
|
41
|
-
vlan_mapping: 'private_vlan_mapping',
|
|
42
|
-
}
|
|
40
|
+
IF_SWITCHPORT_MODE.merge!(IF_DEPRECATED)
|
|
43
41
|
|
|
44
42
|
# Interface - node utility class for general interface config management
|
|
45
|
-
class Interface <
|
|
43
|
+
class Interface < Cisco::InterfaceDeprecated
|
|
46
44
|
# Regexp to match various Ethernet interface variants:
|
|
47
45
|
# Ethernet
|
|
48
46
|
# GigabitEthernet
|
|
@@ -83,14 +81,17 @@ module Cisco
|
|
|
83
81
|
end
|
|
84
82
|
|
|
85
83
|
# General-purpose filter for Interface.interfaces().
|
|
86
|
-
#
|
|
87
|
-
# allow a hash of filter conditions.
|
|
84
|
+
# filter: This may be overloaded in the future to allow a hash of filters.
|
|
88
85
|
# id: The interface name
|
|
89
86
|
# Return: true if the interface should be filtered out, false to keep it.
|
|
90
|
-
def self.filter(
|
|
91
|
-
case
|
|
92
|
-
when :
|
|
93
|
-
return false if config_get('interface', '
|
|
87
|
+
def self.filter(filter, id)
|
|
88
|
+
case filter
|
|
89
|
+
when :pvlan_any
|
|
90
|
+
return false if config_get('interface', 'pvlan_any', name: id)
|
|
91
|
+
|
|
92
|
+
else
|
|
93
|
+
# Just a basic pattern filter (:ethernet, :loopback, etc)
|
|
94
|
+
return false if id.match(filter.to_s)
|
|
94
95
|
end
|
|
95
96
|
true
|
|
96
97
|
end
|
|
@@ -121,6 +122,7 @@ module Cisco
|
|
|
121
122
|
next if k.nil? || v.nil?
|
|
122
123
|
k.gsub!(/ \(.*\)/, '') # Remove any parenthetical text from key
|
|
123
124
|
v.strip!
|
|
125
|
+
v.gsub!(%r{half/full}, 'half,full') if k == 'Duplex'
|
|
124
126
|
hash[k] = v
|
|
125
127
|
end
|
|
126
128
|
end
|
|
@@ -142,6 +144,11 @@ module Cisco
|
|
|
142
144
|
config_set('interface', 'destroy', name: @name)
|
|
143
145
|
end
|
|
144
146
|
|
|
147
|
+
def pvlan_enable
|
|
148
|
+
switchport_enable
|
|
149
|
+
Feature.private_vlan_enable
|
|
150
|
+
end
|
|
151
|
+
|
|
145
152
|
########################################################
|
|
146
153
|
# PROPERTIES #
|
|
147
154
|
########################################################
|
|
@@ -167,6 +174,28 @@ module Cisco
|
|
|
167
174
|
config_get_default('interface', 'access_vlan')
|
|
168
175
|
end
|
|
169
176
|
|
|
177
|
+
def bfd_echo
|
|
178
|
+
return nil unless Feature.bfd_enabled?
|
|
179
|
+
return nil if @name[/loop/i]
|
|
180
|
+
config_get('interface', 'bfd_echo', name: @name)
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
def bfd_echo=(val)
|
|
184
|
+
fail ArgumentError, 'Interface cannot be loopback' if
|
|
185
|
+
@name[/loop/i]
|
|
186
|
+
return if val == bfd_echo
|
|
187
|
+
state = (val ? '' : 'no')
|
|
188
|
+
Feature.bfd_enable
|
|
189
|
+
config_set('interface', 'bfd_echo',
|
|
190
|
+
name: @name, state: state)
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
def default_bfd_echo
|
|
194
|
+
return nil unless Feature.bfd_enabled?
|
|
195
|
+
return nil if @name[/loop/i]
|
|
196
|
+
config_get_default('interface', 'bfd_echo')
|
|
197
|
+
end
|
|
198
|
+
|
|
170
199
|
def description
|
|
171
200
|
config_get('interface', 'description', name: @name)
|
|
172
201
|
end
|
|
@@ -391,6 +420,105 @@ module Cisco
|
|
|
391
420
|
config_get_default('interface', ipv4_arp_timeout_lookup_string)
|
|
392
421
|
end
|
|
393
422
|
|
|
423
|
+
def ipv4_dhcp_relay_addr
|
|
424
|
+
config_get('interface', 'ipv4_dhcp_relay_addr', name: @name)
|
|
425
|
+
end
|
|
426
|
+
|
|
427
|
+
def ipv4_dhcp_relay_addr=(list)
|
|
428
|
+
cur_list = ipv4_dhcp_relay_addr
|
|
429
|
+
# remove the current addresses first
|
|
430
|
+
unless cur_list.empty?
|
|
431
|
+
cur_list.each do |addr|
|
|
432
|
+
config_set('interface', 'ipv4_dhcp_relay_addr',
|
|
433
|
+
name: @name, state: 'no', addr: addr)
|
|
434
|
+
end
|
|
435
|
+
end
|
|
436
|
+
Feature.dhcp_enable unless list.empty?
|
|
437
|
+
list.each do |addr|
|
|
438
|
+
config_set('interface', 'ipv4_dhcp_relay_addr',
|
|
439
|
+
name: @name, state: '', addr: addr)
|
|
440
|
+
end
|
|
441
|
+
end
|
|
442
|
+
|
|
443
|
+
def default_ipv4_dhcp_relay_addr
|
|
444
|
+
config_get_default('interface', 'ipv4_dhcp_relay_addr')
|
|
445
|
+
end
|
|
446
|
+
|
|
447
|
+
def ipv4_dhcp_relay_info_trust
|
|
448
|
+
config_get('interface', 'ipv4_dhcp_relay_info_trust', name: @name)
|
|
449
|
+
end
|
|
450
|
+
|
|
451
|
+
def ipv4_dhcp_relay_info_trust=(state)
|
|
452
|
+
Feature.dhcp_enable if state
|
|
453
|
+
config_set('interface', 'ipv4_dhcp_relay_info_trust',
|
|
454
|
+
name: @name, state: state ? '' : 'no')
|
|
455
|
+
end
|
|
456
|
+
|
|
457
|
+
def default_ipv4_dhcp_relay_info_trust
|
|
458
|
+
config_get_default('interface', 'ipv4_dhcp_relay_info_trust')
|
|
459
|
+
end
|
|
460
|
+
|
|
461
|
+
def ipv4_dhcp_relay_src_addr_hsrp
|
|
462
|
+
config_get('interface', 'ipv4_dhcp_relay_src_addr_hsrp', name: @name)
|
|
463
|
+
end
|
|
464
|
+
|
|
465
|
+
def ipv4_dhcp_relay_src_addr_hsrp=(state)
|
|
466
|
+
Feature.dhcp_enable if state
|
|
467
|
+
config_set('interface', 'ipv4_dhcp_relay_src_addr_hsrp',
|
|
468
|
+
name: @name, state: state ? '' : 'no')
|
|
469
|
+
end
|
|
470
|
+
|
|
471
|
+
def default_ipv4_dhcp_relay_src_addr_hsrp
|
|
472
|
+
config_get_default('interface', 'ipv4_dhcp_relay_src_addr_hsrp')
|
|
473
|
+
end
|
|
474
|
+
|
|
475
|
+
def ipv4_dhcp_relay_src_intf
|
|
476
|
+
intf = config_get('interface', 'ipv4_dhcp_relay_src_intf', name: @name)
|
|
477
|
+
# Normalize by downcasing and removing white space
|
|
478
|
+
intf = intf.downcase.delete(' ') if intf
|
|
479
|
+
intf
|
|
480
|
+
end
|
|
481
|
+
|
|
482
|
+
def ipv4_dhcp_relay_src_intf=(val)
|
|
483
|
+
state = val == default_ipv4_dhcp_relay_src_intf ? 'no' : ''
|
|
484
|
+
intf = val == default_ipv4_dhcp_relay_src_intf ? '' : val
|
|
485
|
+
Feature.dhcp_enable if state.empty?
|
|
486
|
+
config_set('interface', 'ipv4_dhcp_relay_src_intf',
|
|
487
|
+
name: @name, state: state, intf: intf)
|
|
488
|
+
end
|
|
489
|
+
|
|
490
|
+
def default_ipv4_dhcp_relay_src_intf
|
|
491
|
+
config_get_default('interface', 'ipv4_dhcp_relay_src_intf')
|
|
492
|
+
end
|
|
493
|
+
|
|
494
|
+
def ipv4_dhcp_relay_subnet_broadcast
|
|
495
|
+
config_get('interface', 'ipv4_dhcp_relay_subnet_broadcast', name: @name)
|
|
496
|
+
end
|
|
497
|
+
|
|
498
|
+
def ipv4_dhcp_relay_subnet_broadcast=(state)
|
|
499
|
+
Feature.dhcp_enable if state
|
|
500
|
+
config_set('interface', 'ipv4_dhcp_relay_subnet_broadcast',
|
|
501
|
+
name: @name, state: state ? '' : 'no')
|
|
502
|
+
end
|
|
503
|
+
|
|
504
|
+
def default_ipv4_dhcp_relay_subnet_broadcast
|
|
505
|
+
config_get_default('interface', 'ipv4_dhcp_relay_subnet_broadcast')
|
|
506
|
+
end
|
|
507
|
+
|
|
508
|
+
def ipv4_dhcp_smart_relay
|
|
509
|
+
config_get('interface', 'ipv4_dhcp_smart_relay', name: @name)
|
|
510
|
+
end
|
|
511
|
+
|
|
512
|
+
def ipv4_dhcp_smart_relay=(state)
|
|
513
|
+
Feature.dhcp_enable if state
|
|
514
|
+
config_set('interface', 'ipv4_dhcp_smart_relay',
|
|
515
|
+
name: @name, state: state ? '' : 'no')
|
|
516
|
+
end
|
|
517
|
+
|
|
518
|
+
def default_ipv4_dhcp_smart_relay
|
|
519
|
+
config_get_default('interface', 'ipv4_dhcp_smart_relay')
|
|
520
|
+
end
|
|
521
|
+
|
|
394
522
|
def ipv4_forwarding
|
|
395
523
|
config_get('interface', 'ipv4_forwarding', name: @name)
|
|
396
524
|
end
|
|
@@ -497,6 +625,49 @@ module Cisco
|
|
|
497
625
|
config_get_default('interface', 'ipv6_acl_out')
|
|
498
626
|
end
|
|
499
627
|
|
|
628
|
+
def ipv6_dhcp_relay_addr
|
|
629
|
+
config_get('interface', 'ipv6_dhcp_relay_addr', name: @name)
|
|
630
|
+
end
|
|
631
|
+
|
|
632
|
+
def ipv6_dhcp_relay_addr=(list)
|
|
633
|
+
cur_list = ipv6_dhcp_relay_addr
|
|
634
|
+
# remove the current addresses first
|
|
635
|
+
unless cur_list.empty?
|
|
636
|
+
cur_list.each do |addr|
|
|
637
|
+
config_set('interface', 'ipv6_dhcp_relay_addr',
|
|
638
|
+
name: @name, state: 'no', addr: addr)
|
|
639
|
+
end
|
|
640
|
+
end
|
|
641
|
+
Feature.dhcp_enable unless list.empty?
|
|
642
|
+
list.each do |addr|
|
|
643
|
+
config_set('interface', 'ipv6_dhcp_relay_addr',
|
|
644
|
+
name: @name, state: '', addr: addr)
|
|
645
|
+
end
|
|
646
|
+
end
|
|
647
|
+
|
|
648
|
+
def default_ipv6_dhcp_relay_addr
|
|
649
|
+
config_get_default('interface', 'ipv6_dhcp_relay_addr')
|
|
650
|
+
end
|
|
651
|
+
|
|
652
|
+
def ipv6_dhcp_relay_src_intf
|
|
653
|
+
intf = config_get('interface', 'ipv6_dhcp_relay_src_intf', name: @name)
|
|
654
|
+
# Normalize by downcasing and removing white space
|
|
655
|
+
intf = intf.downcase.delete(' ') if intf
|
|
656
|
+
intf
|
|
657
|
+
end
|
|
658
|
+
|
|
659
|
+
def ipv6_dhcp_relay_src_intf=(val)
|
|
660
|
+
state = val == default_ipv6_dhcp_relay_src_intf ? 'no' : ''
|
|
661
|
+
intf = val == default_ipv6_dhcp_relay_src_intf ? '' : val
|
|
662
|
+
Feature.dhcp_enable if state.empty?
|
|
663
|
+
config_set('interface', 'ipv6_dhcp_relay_src_intf',
|
|
664
|
+
name: @name, state: state, intf: intf)
|
|
665
|
+
end
|
|
666
|
+
|
|
667
|
+
def default_ipv6_dhcp_relay_src_intf
|
|
668
|
+
config_get_default('interface', 'ipv6_dhcp_relay_src_intf')
|
|
669
|
+
end
|
|
670
|
+
|
|
500
671
|
def feature_lacp?
|
|
501
672
|
config_get('interface', 'feature_lacp')
|
|
502
673
|
end
|
|
@@ -620,6 +791,51 @@ module Cisco
|
|
|
620
791
|
config_get_default('interface', lookup)
|
|
621
792
|
end
|
|
622
793
|
|
|
794
|
+
def storm_control_broadcast
|
|
795
|
+
config_get('interface', 'storm_control_broadcast', name: @name)
|
|
796
|
+
end
|
|
797
|
+
|
|
798
|
+
def storm_control_broadcast=(val)
|
|
799
|
+
state = val == default_storm_control_broadcast ? 'no' : ''
|
|
800
|
+
level = val == default_storm_control_broadcast ? '' : val
|
|
801
|
+
config_set('interface', 'storm_control_broadcast',
|
|
802
|
+
name: @name, state: state, level: level)
|
|
803
|
+
end
|
|
804
|
+
|
|
805
|
+
def default_storm_control_broadcast
|
|
806
|
+
config_get_default('interface', 'storm_control_broadcast')
|
|
807
|
+
end
|
|
808
|
+
|
|
809
|
+
def storm_control_multicast
|
|
810
|
+
config_get('interface', 'storm_control_multicast', name: @name)
|
|
811
|
+
end
|
|
812
|
+
|
|
813
|
+
def storm_control_multicast=(val)
|
|
814
|
+
state = val == default_storm_control_multicast ? 'no' : ''
|
|
815
|
+
level = val == default_storm_control_multicast ? '' : val
|
|
816
|
+
config_set('interface', 'storm_control_multicast',
|
|
817
|
+
name: @name, state: state, level: level)
|
|
818
|
+
end
|
|
819
|
+
|
|
820
|
+
def default_storm_control_multicast
|
|
821
|
+
config_get_default('interface', 'storm_control_multicast')
|
|
822
|
+
end
|
|
823
|
+
|
|
824
|
+
def storm_control_unicast
|
|
825
|
+
config_get('interface', 'storm_control_unicast', name: @name)
|
|
826
|
+
end
|
|
827
|
+
|
|
828
|
+
def storm_control_unicast=(val)
|
|
829
|
+
state = val == default_storm_control_unicast ? 'no' : ''
|
|
830
|
+
level = val == default_storm_control_unicast ? '' : val
|
|
831
|
+
config_set('interface', 'storm_control_unicast',
|
|
832
|
+
name: @name, state: state, level: level)
|
|
833
|
+
end
|
|
834
|
+
|
|
835
|
+
def default_storm_control_unicast
|
|
836
|
+
config_get_default('interface', 'storm_control_unicast')
|
|
837
|
+
end
|
|
838
|
+
|
|
623
839
|
def stp_bpdufilter
|
|
624
840
|
config_get('interface', 'stp_bpdufilter', name: @name)
|
|
625
841
|
end
|
|
@@ -882,7 +1098,7 @@ module Cisco
|
|
|
882
1098
|
end
|
|
883
1099
|
|
|
884
1100
|
def switchport_enable_and_mode(mode_set)
|
|
885
|
-
switchport_enable
|
|
1101
|
+
switchport_enable
|
|
886
1102
|
|
|
887
1103
|
if :fabricpath == mode_set
|
|
888
1104
|
fabricpath_feature_set(:enabled) unless :enabled == fabricpath_feature
|
|
@@ -927,7 +1143,11 @@ module Cisco
|
|
|
927
1143
|
end
|
|
928
1144
|
|
|
929
1145
|
def switchport_trunk_allowed_vlan
|
|
930
|
-
config_get('interface', 'switchport_trunk_allowed_vlan',
|
|
1146
|
+
vlans = config_get('interface', 'switchport_trunk_allowed_vlan',
|
|
1147
|
+
name: @name)
|
|
1148
|
+
vlans = vlans.join(',') if vlans.is_a?(Array)
|
|
1149
|
+
vlans = Utils.normalize_range_array(vlans, :string) unless vlans == 'none'
|
|
1150
|
+
vlans
|
|
931
1151
|
end
|
|
932
1152
|
|
|
933
1153
|
def switchport_trunk_allowed_vlan=(val)
|
|
@@ -958,19 +1178,14 @@ module Cisco
|
|
|
958
1178
|
end
|
|
959
1179
|
end
|
|
960
1180
|
|
|
961
|
-
#
|
|
962
|
-
# private vlan mode (host, promisc, trunk promisc , trunk sec)
|
|
963
|
-
# private vlan mapping
|
|
964
|
-
# private vlan native vlan
|
|
965
|
-
# private vlan allow vlan
|
|
966
|
-
|
|
1181
|
+
# --------------------------
|
|
967
1182
|
def cli_error_check(result)
|
|
968
|
-
#
|
|
1183
|
+
# Check for messages that can be safely ignored.
|
|
1184
|
+
# The NXOS interface private-vlan cli does not raise an exception
|
|
969
1185
|
# in some conditions and instead just displays a STDOUT error message
|
|
970
1186
|
# thus NXAPI does not detect the failure.
|
|
971
|
-
# We must catch it by inspecting the "body" hash entry
|
|
972
|
-
#
|
|
973
|
-
# Check for messages that can be safely ignored.
|
|
1187
|
+
# We must catch it by inspecting the "body" hash entry returned by NXAPI.
|
|
1188
|
+
# This vlan cli behavior is unlikely to change.
|
|
974
1189
|
|
|
975
1190
|
errors = /(ERROR:|VLAN:|Eth)/
|
|
976
1191
|
return unless
|
|
@@ -983,452 +1198,326 @@ module Cisco
|
|
|
983
1198
|
end
|
|
984
1199
|
end
|
|
985
1200
|
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
name: @name, state: '', mode: IF_SWITCHPORT_MODE[mode_set])
|
|
991
|
-
else
|
|
992
|
-
config_set('interface', 'switchport_mode_private_vlan_host',
|
|
993
|
-
name: @name, state: 'no', mode: IF_SWITCHPORT_MODE[mode_set])
|
|
994
|
-
end
|
|
1201
|
+
# --------------------------
|
|
1202
|
+
# <state> switchport mode private-vlan host
|
|
1203
|
+
def switchport_pvlan_host
|
|
1204
|
+
config_get('interface', 'switchport_pvlan_host', name: @name)
|
|
995
1205
|
end
|
|
996
1206
|
|
|
997
|
-
def
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
unless mode == default_switchport_mode_private_vlan_host
|
|
1002
|
-
mode = IF_SWITCHPORT_MODE.key(mode)
|
|
1003
|
-
end
|
|
1004
|
-
mode
|
|
1005
|
-
rescue IndexError
|
|
1006
|
-
# Assume this is an interface that doesn't support switchport.
|
|
1007
|
-
# Do not raise exception since the providers will prefetch this property
|
|
1008
|
-
# regardless of interface type.
|
|
1009
|
-
# TODO: this should probably be nil instead
|
|
1010
|
-
return default_switchport_mode_private_vlan_host
|
|
1207
|
+
def switchport_pvlan_host=(state)
|
|
1208
|
+
pvlan_enable
|
|
1209
|
+
config_set('interface', 'switchport_pvlan_host',
|
|
1210
|
+
name: @name, state: state ? '' : 'no')
|
|
1011
1211
|
end
|
|
1012
1212
|
|
|
1013
|
-
def
|
|
1014
|
-
|
|
1015
|
-
Feature.private_vlan_enable
|
|
1016
|
-
switchport_enable_and_mode_private_vlan_host(mode_set)
|
|
1213
|
+
def default_switchport_pvlan_host
|
|
1214
|
+
config_get_default('interface', 'switchport_pvlan_host')
|
|
1017
1215
|
end
|
|
1018
1216
|
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1217
|
+
# --------------------------
|
|
1218
|
+
# <state> switchport mode private-vlan promiscuous
|
|
1219
|
+
def switchport_pvlan_promiscuous
|
|
1220
|
+
config_get('interface', 'switchport_pvlan_promiscuous', name: @name)
|
|
1022
1221
|
end
|
|
1023
1222
|
|
|
1024
|
-
def
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
unless result == default_switchport_mode_private_vlan_host_association
|
|
1029
|
-
result = result[0].split(' ')
|
|
1030
|
-
end
|
|
1031
|
-
result
|
|
1223
|
+
def switchport_pvlan_promiscuous=(state)
|
|
1224
|
+
pvlan_enable
|
|
1225
|
+
config_set('interface', 'switchport_pvlan_promiscuous',
|
|
1226
|
+
name: @name, state: state ? '' : 'no')
|
|
1032
1227
|
end
|
|
1033
1228
|
|
|
1034
|
-
def
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
Feature.private_vlan_enable
|
|
1038
|
-
if vlans == default_switchport_mode_private_vlan_host_association
|
|
1039
|
-
result = config_set('interface',
|
|
1040
|
-
'switchport_mode_private_vlan_host_association',
|
|
1041
|
-
name: @name, state: 'no', vlan_pr: '', vlan_sec: '')
|
|
1042
|
-
|
|
1043
|
-
else
|
|
1044
|
-
result = config_set('interface',
|
|
1045
|
-
'switchport_mode_private_vlan_host_association',
|
|
1046
|
-
name: @name, state: '',
|
|
1047
|
-
vlan_pr: vlans[0], vlan_sec: vlans[1])
|
|
1229
|
+
def default_switchport_pvlan_promiscuous
|
|
1230
|
+
config_get_default('interface', 'switchport_pvlan_promiscuous')
|
|
1231
|
+
end
|
|
1048
1232
|
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
config_get_default('interface',
|
|
1055
|
-
'switchport_mode_private_vlan_host_association')
|
|
1056
|
-
end
|
|
1057
|
-
|
|
1058
|
-
# This api is used by private vlan to prepare the input to the setter
|
|
1059
|
-
# method. The input can be in the following formats for vlans:
|
|
1060
|
-
# 10-12,14. Prepare_array api is transforming this input into a flat array.
|
|
1061
|
-
# In the example above the returned array will be 10, 11, 12, 13. Prepare
|
|
1062
|
-
# array is first splitting the input on ',' and the than expanding the vlan
|
|
1063
|
-
# range element like 10-12 into a flat array. The final result will
|
|
1064
|
-
# be a flat array.
|
|
1065
|
-
# This way we can later used the lib utility to check the delta from
|
|
1066
|
-
# the input vlan value and the vlan configured to apply the right config.
|
|
1067
|
-
def prepare_array(is_list)
|
|
1068
|
-
new_list = []
|
|
1069
|
-
is_list.each do |item|
|
|
1070
|
-
if item.include?(',')
|
|
1071
|
-
new_list.push(item.split(','))
|
|
1072
|
-
else
|
|
1073
|
-
new_list.push(item)
|
|
1074
|
-
end
|
|
1075
|
-
end
|
|
1076
|
-
new_list.flatten!
|
|
1077
|
-
new_list.sort!
|
|
1078
|
-
new_list.each { |item| item.gsub!('-', '..') }
|
|
1079
|
-
is_list_new = []
|
|
1080
|
-
new_list.each do |elem|
|
|
1081
|
-
if elem.include?('..')
|
|
1082
|
-
elema = elem.split('..').map { |d| Integer(d) }
|
|
1083
|
-
elema.sort!
|
|
1084
|
-
tr = elema[0]..elema[1]
|
|
1085
|
-
tr.to_a.each do |item|
|
|
1086
|
-
is_list_new.push(item.to_s)
|
|
1087
|
-
end
|
|
1088
|
-
else
|
|
1089
|
-
is_list_new.push(elem)
|
|
1090
|
-
end
|
|
1091
|
-
end
|
|
1092
|
-
is_list_new
|
|
1233
|
+
# --------------------------
|
|
1234
|
+
# <state> switchport private-vlan host-association <pri> <sec>
|
|
1235
|
+
# Note this is NOT a multiple, unlike trunk association.
|
|
1236
|
+
def switchport_pvlan_host_association
|
|
1237
|
+
config_get('interface', 'switchport_pvlan_host_association', name: @name)
|
|
1093
1238
|
end
|
|
1094
1239
|
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
[:add, :remove].each do |action|
|
|
1099
|
-
delta_hash[action].each do |vlans|
|
|
1100
|
-
state = (action == :add) ? '' : 'no'
|
|
1101
|
-
oper = (action == :add) ? 'add' : 'remove'
|
|
1102
|
-
if property[/(host_promisc|mapping_trunk)/]
|
|
1240
|
+
# Input: An array of primary and secondary vlans: ['44', '244']
|
|
1241
|
+
def switchport_pvlan_host_association=(pri_and_sec)
|
|
1242
|
+
pvlan_enable
|
|
1103
1243
|
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
if property[/allow_vlan/]
|
|
1110
|
-
result = config_set('interface',
|
|
1111
|
-
PVLAN_PROPERTY[property],
|
|
1112
|
-
name: @name, state: '',
|
|
1113
|
-
oper: oper, vlans: vlans)
|
|
1114
|
-
end
|
|
1115
|
-
if property[/vlan_mapping/]
|
|
1116
|
-
result = config_set('interface',
|
|
1117
|
-
PVLAN_PROPERTY[property],
|
|
1118
|
-
name: @name, state: state,
|
|
1119
|
-
vlans: vlans)
|
|
1120
|
-
end
|
|
1121
|
-
cli_error_check(result)
|
|
1122
|
-
end
|
|
1123
|
-
end
|
|
1244
|
+
state = pri_and_sec.empty? ? 'no' : ''
|
|
1245
|
+
pri, sec = pri_and_sec
|
|
1246
|
+
cli_error_check(
|
|
1247
|
+
config_set('interface', 'switchport_pvlan_host_association',
|
|
1248
|
+
name: @name, state: state, pri: pri, sec: sec))
|
|
1124
1249
|
end
|
|
1125
1250
|
|
|
1126
|
-
def
|
|
1127
|
-
|
|
1128
|
-
case property
|
|
1129
|
-
when :trunk_assoc
|
|
1130
|
-
is_list.each do |vlans|
|
|
1131
|
-
vlans = vlans.split(' ')
|
|
1132
|
-
if vlans[0].eql? should_list_new[0]
|
|
1133
|
-
config_set('interface',
|
|
1134
|
-
'switchport_private_vlan_association_trunk',
|
|
1135
|
-
name: @name, state: 'no',
|
|
1136
|
-
vlan_pr: pr_vlan, vlan: vlans[1])
|
|
1137
|
-
break
|
|
1138
|
-
else
|
|
1139
|
-
next
|
|
1140
|
-
end
|
|
1141
|
-
end
|
|
1142
|
-
result = config_set('interface', PVLAN_PROPERTY[property], name: @name,
|
|
1143
|
-
state: '', vlan_pr: should_list_new[0],
|
|
1144
|
-
vlan: should_list_new[1])
|
|
1145
|
-
when :mapping_trunk
|
|
1146
|
-
@match_found = false
|
|
1147
|
-
is_list.each do |vlans|
|
|
1148
|
-
vlans = vlans.split(' ')
|
|
1149
|
-
interf_vlan_list_delta(:mapping_trunk, vlans,
|
|
1150
|
-
should_list_new)
|
|
1151
|
-
if @match_found
|
|
1152
|
-
break
|
|
1153
|
-
else
|
|
1154
|
-
next
|
|
1155
|
-
end
|
|
1156
|
-
end
|
|
1157
|
-
result = config_set('interface', PVLAN_PROPERTY[property], name: @name,
|
|
1158
|
-
state: '', vlan_pr: should_list_new[0],
|
|
1159
|
-
vlans: should_list_new[1])
|
|
1160
|
-
end
|
|
1161
|
-
cli_error_check(result)
|
|
1251
|
+
def default_switchport_pvlan_host_association
|
|
1252
|
+
config_get_default('interface', 'switchport_pvlan_host_association')
|
|
1162
1253
|
end
|
|
1163
1254
|
|
|
1164
1255
|
# --------------------------
|
|
1165
|
-
#
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
def interf_vlan_list_delta(property, is_list, should_list)
|
|
1170
|
-
pr_vlan = should_list[0]
|
|
1171
|
-
if is_list[0].eql? should_list[0]
|
|
1172
|
-
should_list = should_list[1].split(',')
|
|
1173
|
-
is_list = is_list[1].split(',')
|
|
1174
|
-
|
|
1175
|
-
should_list_new = prepare_array(should_list)
|
|
1176
|
-
is_list_new = prepare_array(is_list)
|
|
1177
|
-
configure_private_vlan_host_property(property, should_list_new,
|
|
1178
|
-
is_list_new, pr_vlan)
|
|
1179
|
-
else
|
|
1180
|
-
case property
|
|
1181
|
-
when :mapping_trunk
|
|
1182
|
-
return
|
|
1183
|
-
end
|
|
1184
|
-
# If primary vlan are different we can simply replacing the all
|
|
1185
|
-
# config
|
|
1186
|
-
if should_list == default_switchport_mode_private_vlan_host_promisc
|
|
1187
|
-
result = config_set('interface',
|
|
1188
|
-
'switchport_mode_private_vlan_host_promiscous',
|
|
1189
|
-
name: @name, state: 'no',
|
|
1190
|
-
vlan_pr: '', vlans: '')
|
|
1256
|
+
# <state> switchport private-vlan mapping <primary> <vlan>
|
|
1257
|
+
def switchport_pvlan_mapping
|
|
1258
|
+
config_get('interface', 'switchport_pvlan_mapping', name: @name)
|
|
1259
|
+
end
|
|
1191
1260
|
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1261
|
+
# Input: An array of primary vlan and range of vlans: ['44', '3-4,6']
|
|
1262
|
+
def switchport_pvlan_mapping=(primary_and_range)
|
|
1263
|
+
switchport_pvlan_mapping_delta(primary_and_range)
|
|
1264
|
+
end
|
|
1265
|
+
|
|
1266
|
+
def default_switchport_pvlan_mapping
|
|
1267
|
+
config_get_default('interface', 'switchport_pvlan_mapping')
|
|
1268
|
+
end
|
|
1197
1269
|
|
|
1270
|
+
# --------------------------
|
|
1271
|
+
# Find the is/should delta and add/remove commands as needed.
|
|
1272
|
+
#
|
|
1273
|
+
# Inputs:
|
|
1274
|
+
# primary_and_range: An array of primary vlan and range of vlans
|
|
1275
|
+
def switchport_pvlan_mapping_delta(primary_and_range)
|
|
1276
|
+
# Enable switchport mode and feature private-vlan
|
|
1277
|
+
pvlan_enable
|
|
1278
|
+
primary, should_range = primary_and_range
|
|
1279
|
+
|
|
1280
|
+
# primary changes require removing the entire command first
|
|
1281
|
+
is_range = switchport_pvlan_mapping_remove?(primary)
|
|
1282
|
+
|
|
1283
|
+
# convert ranges to individual elements
|
|
1284
|
+
is = Utils.dash_range_to_elements(is_range)
|
|
1285
|
+
should = Utils.dash_range_to_elements(should_range)
|
|
1286
|
+
|
|
1287
|
+
# create the delta hash and apply the changes
|
|
1288
|
+
delta_hash = Utils.delta_add_remove(should, is)
|
|
1289
|
+
Cisco::Logger.debug('switchport_pvlan_mapping_delta: '\
|
|
1290
|
+
"#{primary}: #{delta_hash}")
|
|
1291
|
+
[:add, :remove].each do |action|
|
|
1292
|
+
delta_hash[action].each do |vlan|
|
|
1293
|
+
state = (action == :add) ? '' : 'no'
|
|
1294
|
+
cli_error_check(
|
|
1295
|
+
config_set('interface', 'switchport_pvlan_mapping',
|
|
1296
|
+
name: @name, state: state, primary: primary, vlan: vlan))
|
|
1198
1297
|
end
|
|
1199
|
-
cli_error_check(result)
|
|
1200
1298
|
end
|
|
1201
1299
|
end
|
|
1202
1300
|
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1301
|
+
# --------------------------
|
|
1302
|
+
# switchport_pvlan_mapping_remove?
|
|
1303
|
+
# This is a helper to check if command needs to be removed entirely.
|
|
1304
|
+
#
|
|
1305
|
+
# should_primary: the new primary vlan value
|
|
1306
|
+
# Returns: the current vlan range
|
|
1307
|
+
def switchport_pvlan_mapping_remove?(should_primary)
|
|
1308
|
+
is_primary, is_range = switchport_pvlan_mapping
|
|
1309
|
+
|
|
1310
|
+
if (is_primary != should_primary) && !is_primary.nil?
|
|
1311
|
+
cli_error_check(
|
|
1312
|
+
config_set('interface', 'switchport_pvlan_mapping',
|
|
1313
|
+
name: @name, state: 'no', primary: '', vlan: ''))
|
|
1314
|
+
is_range = []
|
|
1209
1315
|
end
|
|
1210
|
-
|
|
1316
|
+
is_range
|
|
1211
1317
|
end
|
|
1212
1318
|
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
Feature.private_vlan_enable
|
|
1218
|
-
is_list = switchport_mode_private_vlan_host_promisc
|
|
1219
|
-
interf_vlan_list_delta(:host_promisc, is_list, vlans)
|
|
1319
|
+
# --------------------------
|
|
1320
|
+
# <state> switchport private-vlan mapping trunk <primary> <vlan>
|
|
1321
|
+
def switchport_pvlan_mapping_trunk
|
|
1322
|
+
config_get('interface', 'switchport_pvlan_mapping_trunk', name: @name)
|
|
1220
1323
|
end
|
|
1221
1324
|
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1325
|
+
# Input: A nested array of primary vlan and range of vlans:
|
|
1326
|
+
# [['44', '3-4,6'], ['99', '199']]
|
|
1327
|
+
def switchport_pvlan_mapping_trunk=(should)
|
|
1328
|
+
switchport_pvlan_mapping_trunk_delta(should)
|
|
1225
1329
|
end
|
|
1226
1330
|
|
|
1227
|
-
def
|
|
1228
|
-
|
|
1229
|
-
'switchport_mode_private_vlan_trunk_promiscuous',
|
|
1230
|
-
name: @name)
|
|
1231
|
-
rescue IndexError
|
|
1232
|
-
# Assume this is an interface that doesn't support switchport.
|
|
1233
|
-
# Do not raise exception since the providers will prefetch this property
|
|
1234
|
-
# regardless of interface type.
|
|
1235
|
-
# TODO: this should probably be nil instead
|
|
1236
|
-
return default_switchport_mode_private_vlan_trunk_promiscuous
|
|
1331
|
+
def default_switchport_pvlan_mapping_trunk
|
|
1332
|
+
config_get_default('interface', 'switchport_pvlan_mapping_trunk')
|
|
1237
1333
|
end
|
|
1238
1334
|
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1335
|
+
# --------------------------
|
|
1336
|
+
# switchport_pvlan_mapping_trunk_delta(should)
|
|
1337
|
+
#
|
|
1338
|
+
# Find the is/should delta and add/remove commands as needed.
|
|
1339
|
+
# The 'should' value is a nested array of primary vlan and secondary
|
|
1340
|
+
# ranges; e.g.:
|
|
1341
|
+
# [['44', '144-145'], ['99', '199-201']
|
|
1342
|
+
#
|
|
1343
|
+
def switchport_pvlan_mapping_trunk_delta(should)
|
|
1344
|
+
# Enable switchport mode and feature private-vlan
|
|
1345
|
+
pvlan_enable
|
|
1346
|
+
|
|
1347
|
+
# Handle single-level arrays if found: [pri, range] -> [[pri,range]]
|
|
1348
|
+
should = [should] if !should.empty? && (Utils.depth(should) == 1)
|
|
1349
|
+
|
|
1350
|
+
is = switchport_pvlan_mapping_trunk
|
|
1351
|
+
delta_hash = Utils.delta_add_remove(should, is, :updates_not_allowed)
|
|
1352
|
+
Cisco::Logger.debug("switchport_pvlan_mapping_trunk_delta: #{delta_hash}")
|
|
1353
|
+
[:remove, :add].each do |action|
|
|
1354
|
+
delta_hash[action].each do |pri_and_range|
|
|
1355
|
+
pri, range = pri_and_range
|
|
1356
|
+
if action == :add
|
|
1357
|
+
state = ''
|
|
1358
|
+
else
|
|
1359
|
+
state = 'no'
|
|
1360
|
+
range = ''
|
|
1361
|
+
end
|
|
1362
|
+
cli_error_check(
|
|
1363
|
+
config_set('interface', 'switchport_pvlan_mapping_trunk',
|
|
1364
|
+
name: @name, state: state, primary: pri, range: range))
|
|
1365
|
+
end
|
|
1250
1366
|
end
|
|
1251
1367
|
end
|
|
1252
1368
|
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1369
|
+
# --------------------------
|
|
1370
|
+
# <state> switchport private-vlan association trunk <pri> <sec>
|
|
1371
|
+
# Supports multiple.
|
|
1372
|
+
def switchport_pvlan_trunk_association
|
|
1373
|
+
config_get('interface', 'switchport_pvlan_trunk_association', name: @name)
|
|
1256
1374
|
end
|
|
1257
1375
|
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
rescue IndexError
|
|
1263
|
-
# Assume this is an interface that doesn't support switchport.
|
|
1264
|
-
# Do not raise exception since the providers will prefetch this property
|
|
1265
|
-
# regardless of interface type.
|
|
1266
|
-
# TODO: this should probably be nil instead
|
|
1267
|
-
return default_switchport_mode_private_vlan_trunk_secondary
|
|
1268
|
-
end
|
|
1376
|
+
# Input: A nested array of primary and secondary vlans:
|
|
1377
|
+
# [['44', '244'], ['99', '299']]
|
|
1378
|
+
def switchport_pvlan_trunk_association=(should)
|
|
1379
|
+
pvlan_enable
|
|
1269
1380
|
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
switchport_enable unless switchport
|
|
1273
|
-
if state == default_switchport_mode_private_vlan_trunk_secondary
|
|
1274
|
-
config_set('interface', 'switchport_mode_private_vlan_trunk_secondary',
|
|
1275
|
-
name: @name, state: 'no')
|
|
1276
|
-
else
|
|
1277
|
-
config_set('interface', 'switchport_mode_private_vlan_trunk_secondary',
|
|
1278
|
-
name: @name, state: '')
|
|
1279
|
-
end
|
|
1280
|
-
end
|
|
1381
|
+
# Handle single-level arrays if found: [pri, sec] -> [[pri,sec]]
|
|
1382
|
+
should = [should] if !should.empty? && (Utils.depth(should) == 1)
|
|
1281
1383
|
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
'switchport_mode_private_vlan_trunk_secondary')
|
|
1384
|
+
is = switchport_pvlan_trunk_association
|
|
1385
|
+
pvlan_trunk_association_delta(is, should)
|
|
1285
1386
|
end
|
|
1286
1387
|
|
|
1287
|
-
def
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1388
|
+
def pvlan_trunk_association_delta(is, should)
|
|
1389
|
+
delta_hash = Utils.delta_add_remove(should, is)
|
|
1390
|
+
Cisco::Logger.debug("pvlan_trunk_association_delta: #{delta_hash}")
|
|
1391
|
+
[:remove, :add].each do |action|
|
|
1392
|
+
delta_hash[action].each do |pri_and_sec|
|
|
1393
|
+
state = (action == :add) ? '' : 'no'
|
|
1394
|
+
pri, sec = pri_and_sec
|
|
1291
1395
|
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1396
|
+
# Cli does not like removals that specify the secondary
|
|
1397
|
+
sec = '' if action[/remove/]
|
|
1398
|
+
cli_error_check(
|
|
1399
|
+
config_set('interface', 'switchport_pvlan_trunk_association',
|
|
1400
|
+
name: @name, state: state, pri: pri, sec: sec))
|
|
1297
1401
|
end
|
|
1298
1402
|
end
|
|
1299
|
-
result
|
|
1300
1403
|
end
|
|
1301
1404
|
|
|
1302
|
-
def
|
|
1303
|
-
|
|
1304
|
-
Feature.private_vlan_enable
|
|
1305
|
-
switchport_enable unless switchport
|
|
1306
|
-
if vlans == default_switchport_private_vlan_trunk_allowed_vlan
|
|
1307
|
-
vlans = prepare_array(switchport_private_vlan_trunk_allowed_vlan)
|
|
1308
|
-
# If there are no vlan presently configured, we can simply return
|
|
1309
|
-
return if vlans == default_switchport_private_vlan_trunk_allowed_vlan
|
|
1310
|
-
configure_private_vlan_host_property(:allow_vlan, [],
|
|
1311
|
-
vlans, '')
|
|
1312
|
-
else
|
|
1313
|
-
vlans = prepare_array(vlans)
|
|
1314
|
-
is_list = prepare_array(switchport_private_vlan_trunk_allowed_vlan)
|
|
1315
|
-
configure_private_vlan_host_property(:allow_vlan, vlans,
|
|
1316
|
-
is_list, '')
|
|
1317
|
-
end
|
|
1405
|
+
def default_switchport_pvlan_trunk_association
|
|
1406
|
+
config_get_default('interface', 'switchport_pvlan_trunk_association')
|
|
1318
1407
|
end
|
|
1319
1408
|
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1409
|
+
# --------------------------
|
|
1410
|
+
# <state> switchport mode private-vlan trunk promiscuous
|
|
1411
|
+
def switchport_pvlan_trunk_promiscuous
|
|
1412
|
+
config_get('interface', 'switchport_pvlan_trunk_promiscuous', name: @name)
|
|
1323
1413
|
end
|
|
1324
1414
|
|
|
1325
|
-
def
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
name: @name)
|
|
1415
|
+
def switchport_pvlan_trunk_promiscuous=(state)
|
|
1416
|
+
pvlan_enable
|
|
1417
|
+
config_set('interface', 'switchport_pvlan_trunk_promiscuous',
|
|
1418
|
+
name: @name, state: state ? '' : 'no')
|
|
1329
1419
|
end
|
|
1330
1420
|
|
|
1331
|
-
def
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
if vlan == default_switchport_private_vlan_trunk_native_vlan
|
|
1335
|
-
config_set('interface',
|
|
1336
|
-
'switchport_private_vlan_trunk_native_vlan',
|
|
1337
|
-
name: @name, state: 'no', vlan: '')
|
|
1421
|
+
def default_switchport_pvlan_trunk_promiscuous
|
|
1422
|
+
config_get_default('interface', 'switchport_pvlan_trunk_promiscuous')
|
|
1423
|
+
end
|
|
1338
1424
|
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
end
|
|
1425
|
+
# --------------------------
|
|
1426
|
+
# <state> switchport mode private-vlan trunk secondary
|
|
1427
|
+
def switchport_pvlan_trunk_secondary
|
|
1428
|
+
config_get('interface', 'switchport_pvlan_trunk_secondary', name: @name)
|
|
1344
1429
|
end
|
|
1345
1430
|
|
|
1346
|
-
def
|
|
1347
|
-
|
|
1348
|
-
|
|
1431
|
+
def switchport_pvlan_trunk_secondary=(state)
|
|
1432
|
+
pvlan_enable
|
|
1433
|
+
config_set('interface', 'switchport_pvlan_trunk_secondary',
|
|
1434
|
+
name: @name, state: state ? '' : 'no')
|
|
1349
1435
|
end
|
|
1350
1436
|
|
|
1351
|
-
def
|
|
1352
|
-
|
|
1353
|
-
'switchport_private_vlan_association_trunk',
|
|
1354
|
-
name: @name)
|
|
1437
|
+
def default_switchport_pvlan_trunk_secondary
|
|
1438
|
+
config_get_default('interface', 'switchport_pvlan_trunk_secondary')
|
|
1355
1439
|
end
|
|
1356
1440
|
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
configure_private_vlan_trunk_property(:trunk_assoc, vlans,
|
|
1368
|
-
is_list, vlans[0])
|
|
1369
|
-
end
|
|
1441
|
+
# --------------------------
|
|
1442
|
+
# <state> switchport private-vlan trunk allowed vlan <range>
|
|
1443
|
+
# Note that range is handled as a string because the entire range is
|
|
1444
|
+
# replaced instead of individually adding or removing vlans from the range.
|
|
1445
|
+
def switchport_pvlan_trunk_allowed_vlan
|
|
1446
|
+
vlans = config_get('interface', 'switchport_pvlan_trunk_allowed_vlan',
|
|
1447
|
+
name: @name)
|
|
1448
|
+
vlans = vlans.join(',') if vlans.is_a?(Array)
|
|
1449
|
+
vlans = Utils.normalize_range_array(vlans, :string) unless vlans == 'none'
|
|
1450
|
+
vlans
|
|
1370
1451
|
end
|
|
1371
1452
|
|
|
1372
|
-
def
|
|
1373
|
-
|
|
1374
|
-
|
|
1453
|
+
def switchport_pvlan_trunk_allowed_vlan=(range)
|
|
1454
|
+
pvlan_enable
|
|
1455
|
+
|
|
1456
|
+
range = Utils.normalize_range_array(range, :string) unless
|
|
1457
|
+
range == default_switchport_pvlan_trunk_allowed_vlan
|
|
1458
|
+
|
|
1459
|
+
config_set('interface', 'switchport_pvlan_trunk_allowed_vlan',
|
|
1460
|
+
name: @name, range: range)
|
|
1375
1461
|
end
|
|
1376
1462
|
|
|
1377
|
-
def
|
|
1378
|
-
|
|
1379
|
-
'switchport_private_vlan_mapping_trunk',
|
|
1380
|
-
name: @name)
|
|
1463
|
+
def default_switchport_pvlan_trunk_allowed_vlan
|
|
1464
|
+
config_get_default('interface', 'switchport_pvlan_trunk_allowed_vlan')
|
|
1381
1465
|
end
|
|
1382
1466
|
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
if vlans == default_switchport_private_vlan_mapping_trunk
|
|
1388
|
-
config_set('interface', 'switchport_private_vlan_mapping_trunk',
|
|
1389
|
-
name: @name, state: 'no',
|
|
1390
|
-
vlan_pr: '', vlans: '')
|
|
1391
|
-
else
|
|
1392
|
-
is_list = switchport_private_vlan_mapping_trunk
|
|
1393
|
-
configure_private_vlan_trunk_property(:mapping_trunk, vlans,
|
|
1394
|
-
is_list, vlans[0])
|
|
1395
|
-
end
|
|
1467
|
+
# --------------------------
|
|
1468
|
+
# <state> switchport trunk native vlan <vlan>
|
|
1469
|
+
def switchport_pvlan_trunk_native_vlan
|
|
1470
|
+
config_get('interface', 'switchport_pvlan_trunk_native_vlan', name: @name)
|
|
1396
1471
|
end
|
|
1397
1472
|
|
|
1398
|
-
def
|
|
1399
|
-
|
|
1400
|
-
|
|
1473
|
+
def switchport_pvlan_trunk_native_vlan=(vlan)
|
|
1474
|
+
pvlan_enable
|
|
1475
|
+
config_set('interface', 'switchport_pvlan_trunk_native_vlan',
|
|
1476
|
+
name: @name, vlan: vlan)
|
|
1401
1477
|
end
|
|
1402
1478
|
|
|
1403
|
-
def
|
|
1404
|
-
|
|
1405
|
-
'private_vlan_mapping',
|
|
1406
|
-
name: @name)
|
|
1407
|
-
match[0].delete!(' ') unless match == default_private_vlan_mapping
|
|
1408
|
-
match
|
|
1479
|
+
def default_switchport_pvlan_trunk_native_vlan
|
|
1480
|
+
config_get_default('interface', 'switchport_pvlan_trunk_native_vlan')
|
|
1409
1481
|
end
|
|
1410
1482
|
|
|
1411
|
-
|
|
1412
|
-
|
|
1483
|
+
# --------------------------
|
|
1484
|
+
# This is an SVI property.
|
|
1485
|
+
# <state> private-vlan mapping <range> # ex. range = ['2-4,9']
|
|
1486
|
+
# Always returns an array.
|
|
1487
|
+
def pvlan_mapping
|
|
1488
|
+
range = config_get('interface', 'pvlan_mapping', name: @name)
|
|
1489
|
+
return default_pvlan_mapping if range.nil?
|
|
1490
|
+
range.empty? ? range : [range.delete(' ')]
|
|
1491
|
+
end
|
|
1492
|
+
|
|
1493
|
+
def pvlan_mapping=(range)
|
|
1494
|
+
feature_vlan_set
|
|
1413
1495
|
Feature.private_vlan_enable
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1496
|
+
|
|
1497
|
+
is = Utils.dash_range_to_elements(pvlan_mapping)
|
|
1498
|
+
should = Utils.dash_range_to_elements(range)
|
|
1499
|
+
|
|
1500
|
+
pvlan_mapping_delta(is, should)
|
|
1501
|
+
end
|
|
1502
|
+
|
|
1503
|
+
def pvlan_mapping_delta(is, should)
|
|
1504
|
+
delta_hash = Utils.delta_add_remove(should, is)
|
|
1505
|
+
Cisco::Logger.debug("pvlan_mapping_delta: #{delta_hash}")
|
|
1506
|
+
[:remove, :add].each do |action|
|
|
1507
|
+
delta_hash[action].each do |vlan|
|
|
1508
|
+
state = (action == :add) ? '' : 'no'
|
|
1509
|
+
cli_error_check(
|
|
1510
|
+
config_set('interface', 'pvlan_mapping',
|
|
1511
|
+
name: @name, state: state, vlan: vlan))
|
|
1512
|
+
end
|
|
1424
1513
|
end
|
|
1425
1514
|
end
|
|
1426
1515
|
|
|
1427
|
-
def
|
|
1428
|
-
config_get_default('interface',
|
|
1429
|
-
'private_vlan_mapping')
|
|
1516
|
+
def default_pvlan_mapping
|
|
1517
|
+
config_get_default('interface', 'pvlan_mapping')
|
|
1430
1518
|
end
|
|
1431
1519
|
|
|
1520
|
+
# --------------------------
|
|
1432
1521
|
# vlan_mapping & vlan_mapping_enable
|
|
1433
1522
|
# Hardware & Cli Dependencies:
|
|
1434
1523
|
# - F3 linecards only
|
|
@@ -1568,7 +1657,9 @@ module Cisco
|
|
|
1568
1657
|
config_get('interface', 'feature_vlan')
|
|
1569
1658
|
end
|
|
1570
1659
|
|
|
1571
|
-
def feature_vlan_set(val)
|
|
1660
|
+
def feature_vlan_set(val=true)
|
|
1661
|
+
# 'feature interface-vlan'
|
|
1662
|
+
# TBD: Replace this with Feature.interface_vlan_enable
|
|
1572
1663
|
return if feature_vlan? == val
|
|
1573
1664
|
config_set('interface', 'feature_vlan', state: val ? '' : 'no')
|
|
1574
1665
|
end
|