From 82892d2ece3d42388b9545d2b47c26b26c28dee2 Mon Sep 17 00:00:00 2001 From: Fedor Zhukov Date: Wed, 4 Feb 2026 19:59:42 +0100 Subject: [PATCH 1/5] add tests/annet/test_patch/cisco_switchport_trunk_allowed.yaml --- .../cisco_switchport_trunk_allowed.yaml | 199 ++++++++++++++++++ 1 file changed, 199 insertions(+) create mode 100644 tests/annet/test_patch/cisco_switchport_trunk_allowed.yaml diff --git a/tests/annet/test_patch/cisco_switchport_trunk_allowed.yaml b/tests/annet/test_patch/cisco_switchport_trunk_allowed.yaml new file mode 100644 index 00000000..41f70747 --- /dev/null +++ b/tests/annet/test_patch/cisco_switchport_trunk_allowed.yaml @@ -0,0 +1,199 @@ +- vendor: cisco + diff: | + interface FastEthernet0/30 + + switchport access vlan 2612 + + switchport mode access + + patch: | + conf t + interface FastEthernet0/30 + switchport access vlan 2612 + switchport mode access + exit + exit + copy running-config startup-config + +- vendor: cisco + diff: | + interface FastEthernet0/30 + - switchport access vlan 2612 + - switchport mode access + + patch: | + conf t + interface FastEthernet0/30 + no switchport access vlan + no switchport mode + exit + exit + copy running-config startup-config + +- vendor: cisco + diff: | + interface FastEthernet0/30 + + switchport trunk native vlan 2612 + + switchport trunk allowed vlan 2600-2602,2612,2670 + + switchport mode trunk + + patch: | + conf t + interface FastEthernet0/30 + switchport mode trunk + switchport trunk allowed vlan add 2600-2602,2612,2670 + switchport trunk native vlan 2612 + exit + exit + copy running-config startup-config + +- vendor: cisco + diff: | + interface FastEthernet0/30 + - switchport trunk native vlan 2612 + - switchport trunk allowed vlan 2600-2602,2612,2670 + - switchport mode trunk + + patch: | + conf t + interface FastEthernet0/30 + no switchport mode + no switchport trunk allowed vlan remove 2600-2602,2612,2670 + no switchport trunk native vlan + exit + exit + copy running-config startup-config + +- vendor: cisco + diff: | + interface GigabitEthernet1/0/38 + - switchport access vlan 462 + - switchport mode access + + switchport trunk native vlan 410 + + switchport mode trunk + + switchport trunk allowed vlan 410,2423,2433,2443 + + patch: | + conf t + interface GigabitEthernet1/0/38 + no switchport access vlan + switchport mode trunk + switchport trunk allowed vlan add 410,2423,2433,2443 + switchport trunk native vlan 410 + exit + exit + copy running-config startup-config + +- vendor: cisco + diff: | + interface GigabitEthernet1/0/38 + - switchport trunk native vlan 410 + - switchport trunk allowed vlan 410,2423,2433,2443 + - switchport mode trunk + + switchport access vlan 462 + + switchport mode access + + patch: | + conf t + interface GigabitEthernet1/0/38 + switchport access vlan 462 + switchport mode access + no switchport trunk allowed vlan remove 410,2423,2433,2443 + no switchport trunk native vlan + exit + exit + copy running-config startup-config + +- vendor: cisco + diff: | + interface GigabitEthernet1/0/38 + - switchport trunk native vlan 410 + - switchport trunk allowed vlan 410,2423,2433,2443 + + switchport trunk native vlan 400 + + switchport trunk allowed vlan 400,2423,2433,2443 + + patch: | + conf t + interface GigabitEthernet1/0/38 + no switchport trunk allowed vlan remove 410 + switchport trunk allowed vlan add 400 + switchport trunk native vlan 400 + exit + exit + copy running-config startup-config + +- vendor: cisco + diff: | + interface GigabitEthernet1/0/38 + + switchport mode trunk + + switchport trunk allowed vlan 10,20,30,40,50,60,70,80,90,100,110,120,130,140 + + switchport trunk allowed vlan add 150,160,170 + + patch: | + conf t + interface GigabitEthernet1/0/38 + switchport mode trunk + switchport trunk allowed vlan add 10,20,30,40,50 + switchport trunk allowed vlan add 60,70,80,90,100 + switchport trunk allowed vlan add 110,120,130,140,150 + switchport trunk allowed vlan add 160,170 + exit + exit + copy running-config startup-config + +- vendor: cisco + diff: | + interface GigabitEthernet1/0/38 + - switchport mode trunk + - switchport trunk allowed vlan 10,20,30,40,50,60,70,80,90,100,110,120,130,140 + - switchport trunk allowed vlan add 150,160,170 + + patch: | + conf t + interface GigabitEthernet1/0/38 + no switchport mode + no switchport trunk allowed vlan remove 10,20,30,40,50 + no switchport trunk allowed vlan remove 60,70,80,90,100 + no switchport trunk allowed vlan remove 110,120,130,140,150 + no switchport trunk allowed vlan remove 160,170 + exit + exit + copy running-config startup-config + +- vendor: cisco + diff: | + interface GigabitEthernet1/0/38 + switchport mode trunk + switchport trunk allowed vlan 10,20,30,40,50,60,70,80,90,100,110,120,130,140 + - switchport trunk allowed vlan add 150,160,170 + + patch: | + conf t + interface GigabitEthernet1/0/38 + no switchport trunk allowed vlan remove 150,160,170 + exit + exit + copy running-config startup-config + +- vendor: cisco + diff: | + interface GigabitEthernet1/0/38 + + switchport trunk allowed vlan none + + patch: | + conf t + interface GigabitEthernet1/0/38 + switchport trunk allowed vlan none + exit + exit + copy running-config startup-config + +- vendor: cisco + diff: | + interface GigabitEthernet1/0/38 + - switchport trunk allowed vlan none + + patch: | + conf t + interface GigabitEthernet1/0/38 + exit + exit + copy running-config startup-config From 914d45c03d0df34e98d9d494c0dafd03f9dfd27d Mon Sep 17 00:00:00 2001 From: Fedor Zhukov Date: Thu, 5 Feb 2026 10:04:38 +0100 Subject: [PATCH 2/5] add tests/annet/test_patch/cisco_vlandb.yaml --- tests/annet/test_patch/cisco_vlandb.yaml | 257 +++++++++++++++++++++++ 1 file changed, 257 insertions(+) create mode 100644 tests/annet/test_patch/cisco_vlandb.yaml diff --git a/tests/annet/test_patch/cisco_vlandb.yaml b/tests/annet/test_patch/cisco_vlandb.yaml new file mode 100644 index 00000000..aeff456c --- /dev/null +++ b/tests/annet/test_patch/cisco_vlandb.yaml @@ -0,0 +1,257 @@ +- vendor: cisco + diff: | + + vlan 10 + patch: | + conf t + vlan 10 + exit + exit + copy running-config startup-config + +- vendor: cisco + diff: | + vlan 10 + + name USERS + patch: | + conf t + vlan 10 + name USERS + exit + exit + copy running-config startup-config + +- vendor: cisco + diff: | + - vlan 20 + patch: | + conf t + no vlan 20 + exit + copy running-config startup-config + +- vendor: cisco + diff: | + vlan 30 + - name OLD_NAME + + name NEW_NAME + patch: | + conf t + vlan 30 + name NEW_NAME + exit + exit + copy running-config startup-config + +- vendor: cisco + diff: | + vlan 40 + - shutdown + + no shutdown + patch: | + conf t + vlan 40 + no shutdown + exit + exit + copy running-config startup-config + +- vendor: cisco + diff: | + + vlan 100-103 + patch: | + conf t + vlan 100-103 + exit + exit + copy running-config startup-config + +- vendor: cisco + diff: | + + vlan 200,205,210 + patch: | + conf t + vlan 200,205,210 + exit + exit + copy running-config startup-config + +- vendor: cisco + diff: | + - vlan 300-302 + patch: | + conf t + no vlan 300-302 + exit + copy running-config startup-config + +- vendor: cisco + diff: | + - vlan 12,15-16,18 + patch: | + conf t + no vlan 12,15,16,18 + exit + copy running-config startup-config + +- vendor: cisco + diff: | + + vlan 110 + vlan 110 + + name VOICE + patch: | + conf t + vlan 110 + name VOICE + exit + exit + copy running-config startup-config + +- vendor: cisco + diff: | + + vlan 120 + + vlan 121 + + vlan 122 + patch: | + conf t + vlan 120-122 + exit + exit + copy running-config startup-config + +- vendor: cisco + diff: | + + vlan 130-132 + vlan 131 + + name PRINTERS + patch: | + conf t + vlan 131 + name PRINTERS + exit + vlan 130-132 + exit + exit + copy running-config startup-config + +- vendor: cisco + diff: | + - vlan 140 + vlan 141 + - name LEGACY + + name CORE + patch: | + conf t + no vlan 140 + vlan 141 + name CORE + exit + exit + copy running-config startup-config + +- vendor: cisco + diff: | + - vlan 150-152 + + vlan 160-161 + patch: | + conf t + no vlan 150-152 + vlan 160-161 + exit + exit + copy running-config startup-config + +- vendor: cisco + diff: | + + vlan 170,175-176 + - vlan 180,185-186 + patch: | + conf t + no vlan 180,185-186 + vlan 170,175-176 + exit + exit + copy running-config startup-config + +- vendor: cisco + diff: | + vlan 190 + - name DEV_OLD + + name DEV + vlan 191 + - shutdown + + no shutdown + patch: | + conf t + vlan 191 + no shutdown + exit + vlan 190 + name DEV + exit + exit + copy running-config startup-config + +- vendor: cisco + diff: | + - vlan 210-212 + vlan 213 + - name TEMP + + name PROD + + vlan 220 + patch: | + conf t + no vlan 210-212 + vlan 213 + name PROD + exit + vlan 220 + exit + exit + copy running-config startup-config + +- vendor: cisco + diff: | + + vlan 250-255 + - vlan 240,245-247 + vlan 252 + + name AP_MGMT + vlan 253 + - name WIFI_OLD + + name WIFI + patch: | + conf t + no vlan 240,245-247 + vlan 252 + name AP_MGMT + exit + vlan 253 + name WIFI + exit + vlan 250-255 + exit + exit + copy running-config startup-config + +- vendor: cisco + diff: | + - vlan 300-305 + - vlan 310 + + vlan 320-321 + vlan 321 + + name TRANSIT + vlan 299 + - shutdown + + no shutdown + patch: | + conf t + no vlan 300-305,310 + vlan 299 + no shutdown + exit + vlan 321 + name TRANSIT + exit + vlan 320-321 + exit + exit + copy running-config startup-config From 326a8036161136216f5113c9fd64d369f199c085 Mon Sep 17 00:00:00 2001 From: Fedor Zhukov Date: Mon, 2 Feb 2026 13:10:27 +0100 Subject: [PATCH 3/5] fix: cisco vlan mask patching logic Stuff in swtrunk() does not seem to be reqired at all. By default vlan mask is "allowed all". When you run "allowed vlan 10,20,30" it replaces current mask. This is exactly a behaviour that default patching assumes. --- annet/rulebook/texts/cisco.rul | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/annet/rulebook/texts/cisco.rul b/annet/rulebook/texts/cisco.rul index b994ce70..12dbe288 100644 --- a/annet/rulebook/texts/cisco.rul +++ b/annet/rulebook/texts/cisco.rul @@ -59,7 +59,7 @@ interface */\w*Ethernet[0-9\/]+$/ %logic=common.permanent %diff_logic=cis switchport mode switchport trunk native vlan switchport access vlan - switchport trunk allowed vlan %logic=cisco.vlandb.swtrunk + switchport trunk allowed vlan ip vrf forwarding %diff_logic=cisco.iface.diff vrf forwarding %diff_logic=cisco.iface.diff ip address ~ %diff_logic=cisco.iface.diff From 2f311d3ba6b40d2a6cf287e6d160ea61afb1f6a9 Mon Sep 17 00:00:00 2001 From: Fedor Zhukov Date: Thu, 5 Feb 2026 11:04:38 +0100 Subject: [PATCH 4/5] Return swtrunk back and fix explicit_changing instead After playing around with config I finally realised the reason for custom logic. There are cases when allowed vlans are splitted in a following manner: switchport trunk allowed vlan 10,20,30,40,50,60,70,80,90,100,110,120,130,140 switchport trunk allowed vlan add 150,160,170 This in turn requires a custom logic. So I reverted swtrunk() back. Still the old beheviour is obviously broken so I spent a day checking behaviour with minimal changes. Summary of changes in cisco/vlandb.py: - refactored tenary if ... else - the code is complicated enought as is - fix "no" from "switchport trunk allowed vlan remove" - its a direct cmd - issue "switchport trunk allowed vlan none" if no old mask existed - by default all vlans are allowed - issue "no switchport trunk allowed vlan" if no new mask added - this returns state to a default --- annet/rulebook/cisco/vlandb.py | 29 +++++++++++++++++++++++------ annet/rulebook/texts/cisco.rul | 2 +- 2 files changed, 24 insertions(+), 7 deletions(-) diff --git a/annet/rulebook/cisco/vlandb.py b/annet/rulebook/cisco/vlandb.py index 289af6da..89def565 100644 --- a/annet/rulebook/cisco/vlandb.py +++ b/annet/rulebook/cisco/vlandb.py @@ -30,10 +30,16 @@ def _process_vlandb(rule, key, diff, hw, explicit_changing, multi_chunk): if not prefix: prefix = prefix2 - if len(diff[Op.ADDED]) == 1 and len(new) == 0: - # switchport trunk allowed vlan none - yield (True, "%s none" % prefix, None) - return + if explicit_changing and not new: + if diff[Op.ADDED] and not diff[Op.UNCHANGED]: + # switchport trunk allowed vlan none + yield (True, "%s none" % prefix, None) + return + if diff[Op.REMOVED] and not diff[Op.UNCHANGED]: + # no switchport trunk allowed vlan + yield (False, "no %s" % prefix, None) + return + for vlan_id in (set(old_blocks.keys()) - set(new_blocks)) & new: # Удалено содержимое блока vlan, но сам влан остался yield (True, "%s %s" % (prefix, vlan_id), old_blocks[vlan_id]) @@ -47,12 +53,23 @@ def _process_vlandb(rule, key, diff, hw, explicit_changing, multi_chunk): if removed: collapsed = collapse_vlandb(removed, hw.Catalyst) for chunk in _chunked(collapsed, multi_chunk): - yield (False, "no %s%s%s" % (prefix, " remove " if explicit_changing else " ", ",".join(chunk)), None) + if explicit_changing: + yield (True, "%s%s%s" % (prefix, " remove ", ",".join(chunk)), None) + else: + yield (False, "no %s%s%s" % (prefix, " ", ",".join(chunk)), None) if added: collapsed = collapse_vlandb(added, hw.Catalyst) + if explicit_changing and not old: + # by default all vlans are allowed + # switchport trunk allowed vlan none + yield (True, "%s none" % prefix, None) for chunk in _chunked(collapsed, multi_chunk): - yield (True, "%s%s%s" % (prefix, " add " if explicit_changing else " ", ",".join(chunk)), None) + if explicit_changing: + yield (True, "%s%s%s" % (prefix, " add ", ",".join(chunk)), None) + else: + yield (True, "%s%s%s" % (prefix, " ", ",".join(chunk)), None) + if new_blocks: for vlan_id, block in new_blocks.items(): yield (True, "%s %s" % (prefix, vlan_id), block) diff --git a/annet/rulebook/texts/cisco.rul b/annet/rulebook/texts/cisco.rul index 12dbe288..b994ce70 100644 --- a/annet/rulebook/texts/cisco.rul +++ b/annet/rulebook/texts/cisco.rul @@ -59,7 +59,7 @@ interface */\w*Ethernet[0-9\/]+$/ %logic=common.permanent %diff_logic=cis switchport mode switchport trunk native vlan switchport access vlan - switchport trunk allowed vlan + switchport trunk allowed vlan %logic=cisco.vlandb.swtrunk ip vrf forwarding %diff_logic=cisco.iface.diff vrf forwarding %diff_logic=cisco.iface.diff ip address ~ %diff_logic=cisco.iface.diff From 8ed67325768492146fa3a13833f05be3c166c577 Mon Sep 17 00:00:00 2001 From: Fedor Zhukov Date: Thu, 5 Feb 2026 11:07:35 +0100 Subject: [PATCH 5/5] fix tests --- .../cisco_port_channel_members_config.yaml | 1 + .../cisco_switchport_trunk_allowed.yaml | 17 +++++++++-------- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/tests/annet/test_patch/cisco_port_channel_members_config.yaml b/tests/annet/test_patch/cisco_port_channel_members_config.yaml index 0aea4850..567948e8 100644 --- a/tests/annet/test_patch/cisco_port_channel_members_config.yaml +++ b/tests/annet/test_patch/cisco_port_channel_members_config.yaml @@ -43,6 +43,7 @@ patch: | interface Ethernet1/2 no channel-group switchport mode trunk + switchport trunk allowed vlan none switchport trunk allowed vlan add 2 switchport mtu 1500 diff --git a/tests/annet/test_patch/cisco_switchport_trunk_allowed.yaml b/tests/annet/test_patch/cisco_switchport_trunk_allowed.yaml index 41f70747..d84044f1 100644 --- a/tests/annet/test_patch/cisco_switchport_trunk_allowed.yaml +++ b/tests/annet/test_patch/cisco_switchport_trunk_allowed.yaml @@ -39,6 +39,7 @@ conf t interface FastEthernet0/30 switchport mode trunk + switchport trunk allowed vlan none switchport trunk allowed vlan add 2600-2602,2612,2670 switchport trunk native vlan 2612 exit @@ -56,7 +57,7 @@ conf t interface FastEthernet0/30 no switchport mode - no switchport trunk allowed vlan remove 2600-2602,2612,2670 + no switchport trunk allowed vlan no switchport trunk native vlan exit exit @@ -76,6 +77,7 @@ interface GigabitEthernet1/0/38 no switchport access vlan switchport mode trunk + switchport trunk allowed vlan none switchport trunk allowed vlan add 410,2423,2433,2443 switchport trunk native vlan 410 exit @@ -96,7 +98,7 @@ interface GigabitEthernet1/0/38 switchport access vlan 462 switchport mode access - no switchport trunk allowed vlan remove 410,2423,2433,2443 + no switchport trunk allowed vlan no switchport trunk native vlan exit exit @@ -113,7 +115,7 @@ patch: | conf t interface GigabitEthernet1/0/38 - no switchport trunk allowed vlan remove 410 + switchport trunk allowed vlan remove 410 switchport trunk allowed vlan add 400 switchport trunk native vlan 400 exit @@ -131,6 +133,7 @@ conf t interface GigabitEthernet1/0/38 switchport mode trunk + switchport trunk allowed vlan none switchport trunk allowed vlan add 10,20,30,40,50 switchport trunk allowed vlan add 60,70,80,90,100 switchport trunk allowed vlan add 110,120,130,140,150 @@ -150,10 +153,7 @@ conf t interface GigabitEthernet1/0/38 no switchport mode - no switchport trunk allowed vlan remove 10,20,30,40,50 - no switchport trunk allowed vlan remove 60,70,80,90,100 - no switchport trunk allowed vlan remove 110,120,130,140,150 - no switchport trunk allowed vlan remove 160,170 + no switchport trunk allowed vlan exit exit copy running-config startup-config @@ -168,7 +168,7 @@ patch: | conf t interface GigabitEthernet1/0/38 - no switchport trunk allowed vlan remove 150,160,170 + switchport trunk allowed vlan remove 150,160,170 exit exit copy running-config startup-config @@ -194,6 +194,7 @@ patch: | conf t interface GigabitEthernet1/0/38 + no switchport trunk allowed vlan exit exit copy running-config startup-config