Skip to content

Commit 073ebee

Browse files
committed
change default naming for bgp cpe sessions
+ also keep old naming as a fallback when no tobago lines are attached + old naming still available using deprecated_naming:cpe tag + test suite updated with all cases for new/old naming scheme switch
1 parent 6afaefe commit 073ebee

File tree

5 files changed

+118
-25
lines changed

5 files changed

+118
-25
lines changed

cosmo/netbox_types.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
InterfaceSerializationError,
1515
head,
1616
)
17-
from typing import Self, Iterator, TypeVar, NoReturn, Never, Type, Any
17+
from typing import Self, Iterator, TypeVar, NoReturn, Never, Type, Any, Union
1818

1919
from .tobago_types import TobagoAbstractTerminationType
2020

@@ -565,9 +565,12 @@ def isLoopbackChild(self):
565565
def getConnectedEndpoints(self) -> list[DeviceType]:
566566
return self.get("connected_endpoints", [])
567567

568-
def hasAnAttachedTobagoLine(self):
568+
def hasAnAttachedTobagoLine(self) -> bool:
569569
return self.get("attached_tobago_line") is not None
570570

571+
def getAttachedTobagoLine(self) -> Union["CosmoTobagoLine", None]:
572+
return self.get("attached_tobago_line")
573+
571574

572575
class VLANType(AbstractNetboxType):
573576
def __repr__(self):

cosmo/routerbgpcpevisitor.py

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
from abc import ABCMeta, abstractmethod
2-
from typing import List, NoReturn
2+
from typing import List, NoReturn, TypeGuard
33

44
from multimethod import multimethod as singledispatchmethod
55
from ipaddress import IPv4Interface, IPv6Interface
@@ -119,6 +119,29 @@ def acceptVRFNameOrFailOn(
119119
) -> None | NoReturn:
120120
pass
121121

122+
@staticmethod
123+
def getGroupName(
124+
linked_interface: InterfaceType, parent_interface: InterfaceType
125+
) -> str:
126+
# technically a type guard, as we're narrowing on TagType. described
127+
# as such to satisfy the type checker.
128+
def tagFilter(t: TagType) -> TypeGuard[TagType]:
129+
return t.getTagName() == "deprecated_naming" and t.getTagValue() == "cpe"
130+
131+
attached_tobago_line = parent_interface.getAttachedTobagoLine()
132+
# if legacy naming tag is present, or no tobago line is attached, we keep the old name as a fallback
133+
if not attached_tobago_line or any(
134+
filter(
135+
tagFilter,
136+
linked_interface.getTags(),
137+
)
138+
):
139+
return "CPE_" + linked_interface.getName().replace(".", "-").replace(
140+
"/", "-"
141+
)
142+
else: # use new naming scheme with tobago line name
143+
return "CUST_" + attached_tobago_line.getLineNameLong()
144+
122145
def processBgpCpeTag(self, o: TagType):
123146
linked_interface = o.getParent(InterfaceType)
124147
if not linked_interface.hasParentInterface():
@@ -142,9 +165,7 @@ def processBgpCpeTag(self, o: TagType):
142165
)
143166
return
144167

145-
group_name = "CPE_" + linked_interface.getName().replace(".", "-").replace(
146-
"/", "-"
147-
)
168+
group_name = self.getGroupName(linked_interface, parent_interface)
148169
vrf_name = self._default_vrf_name
149170
# make the type checker happy, since it cannot reliably infer
150171
# type from default values of policy_v4 and policy_v6
@@ -178,7 +199,6 @@ def processBgpCpeTag(self, o: TagType):
178199
elif af and af is IPv6Interface:
179200
v6_import.add(prefix)
180201

181-
# import pdb; pdb.set_trace()
182202
policy_v4["import_list"], policy_v6["import_list"] = self.processImportLists(
183203
v4_import, v6_import
184204
)

cosmo/routervisitor.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -852,6 +852,8 @@ def _(self, o: TagType):
852852
return self.processAccessTag(o)
853853
case "unnumbered":
854854
return self.processBgpUnnumberedTag(o)
855+
case "deprecated_naming":
856+
pass # ignore, as it is treated in bgp cpe visitor
855857
case "bgp":
856858
if o.getTagValue() == "cpe":
857859
pass # ignore, treated with whole tag list

cosmo/tests/test_case_bgpcpe.yml

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,67 @@ device_list:
3030
untagged_vlan: null
3131
vrf: null
3232
parent: null
33+
attached_tobago_line:
34+
__typename: CosmoTobagoLine
35+
component_type: CABLE
36+
element:
37+
description: ''
38+
display: cable 000128934
39+
id: 39645
40+
label: cable 000128934
41+
url: https://netbox.example.com/api/dcim/cables/39645/
42+
element_id: 93827
43+
element_type: dcim.cable
44+
id: 5110
45+
index: 1
46+
termination_a:
47+
_occupied: true
48+
cable:
49+
description: ''
50+
display: cable 000128934
51+
id: 39645
52+
label: cable 000128934
53+
url: https://netbox.example.com/api/dcim/cables/39645/
54+
description: ''
55+
device:
56+
description: ''
57+
display: TEST0001
58+
id: 17799
59+
name: TEST0001
60+
url: https://netbox.example.com/api/dcim/devices/1747/
61+
display: ifp-0/1/2
62+
id: 191940
63+
name: ifp-0/1/2
64+
url: https://netbox.example.com/api/dcim/interfaces/191940/
65+
termination_a_id: 92387
66+
termination_a_type: dcim.interface
67+
termination_b:
68+
_occupied: true
69+
id: 198208
70+
url: https://netbox.example.com/api/dcim/interfaces/192878/
71+
display: DC10 duplex front 10b
72+
device:
73+
id: 39948
74+
url: https://netbox.example.com/api/dcim/device/39948/
75+
display: Panel C
76+
name: Panel C
77+
description: null
78+
name: DC10 duplex front 10b
79+
description: ""
80+
termination_b_id: 454
81+
termination_b_type: dcim.frontport
82+
version:
83+
created: '2025-09-03T11:34:19.643456+01:00'
84+
custom_fields: { }
85+
id: 2617
86+
last_updated: '2025-09-03T11:34:40.819703+01:00'
87+
line:
88+
display: cl390287
89+
id: 9834
90+
name: '390287'
91+
name_long: cl390287
92+
url: https://netbox.example.com/api/plugins/tobago/lines/9834/
93+
status: current
3394
connected_endpoints:
3495
- device:
3596
name: ''
@@ -114,6 +175,9 @@ device_list:
114175
- name: bgp:cpe
115176
slug: bgpcpe
116177
__typename: TagType
178+
- name: deprecated_naming:cpe
179+
slug: deprecatednamingcpe
180+
__typename: TagType
117181
type: VIRTUAL
118182
untagged_vlan: null
119183
vrf:
@@ -207,6 +271,9 @@ device_list:
207271
- name: max-prefixes:100
208272
slug: maxprefixes100
209273
__typename: TagType
274+
- name: deprecated_naming:cpe
275+
slug: deprecatednamingcpe
276+
__typename: TagType
210277
type: VIRTUAL
211278
untagged_vlan: null
212279
vrf:
@@ -251,6 +318,9 @@ device_list:
251318
- name: max-prefixes:100
252319
slug: maxprefixes100
253320
__typename: TagType
321+
- name: deprecated_naming:cpe
322+
slug: deprecatednamingcpe
323+
__typename: TagType
254324
type: VIRTUAL
255325
untagged_vlan: null
256326
vrf:

cosmo/tests/test_serializer.py

Lines changed: 16 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -475,26 +475,26 @@ def test_router_case_local_bgpcpe():
475475

476476
groups_default = d["routing_instances"]["default"]["protocols"]["bgp"]["groups"]
477477
assert len(groups_default) == 1
478-
assert "CPE_ifp-0-1-2-3" in groups_default
479478
assert (
480-
groups_default["CPE_ifp-0-1-2-3"]["neighbors"][0]["interface"] == "ifp-0/1/2.3"
481-
)
482-
assert groups_default["CPE_ifp-0-1-2-3"]["family"]["ipv4_unicast"]["policy"][
479+
"CUST_cl390287" in groups_default
480+
) # parent interface has tobago line attached
481+
assert groups_default["CUST_cl390287"]["neighbors"][0]["interface"] == "ifp-0/1/2.3"
482+
assert groups_default["CUST_cl390287"]["family"]["ipv4_unicast"]["policy"][
483483
"export"
484484
] == ["DEFAULT_V4"]
485-
assert groups_default["CPE_ifp-0-1-2-3"]["family"]["ipv6_unicast"]["policy"][
485+
assert groups_default["CUST_cl390287"]["family"]["ipv6_unicast"]["policy"][
486486
"export"
487487
] == ["DEFAULT_V6"]
488-
assert groups_default["CPE_ifp-0-1-2-3"]["family"]["ipv4_unicast"]["policy"][
488+
assert groups_default["CUST_cl390287"]["family"]["ipv4_unicast"]["policy"][
489489
"import_list"
490490
] == ["10.1.0.0/28"]
491-
assert groups_default["CPE_ifp-0-1-2-3"]["family"]["ipv6_unicast"]["policy"][
491+
assert groups_default["CUST_cl390287"]["family"]["ipv6_unicast"]["policy"][
492492
"import_list"
493493
] == ["2a0e:b941:2:42::/64", "2a0e:b941:2::/122"]
494494

495495
groups_L3VPN = d["routing_instances"]["L3VPN"]["protocols"]["bgp"]["groups"]
496496

497-
assert "CPE_ifp-0-1-2-4" in groups_L3VPN
497+
assert "CPE_ifp-0-1-2-4" in groups_L3VPN # sub interface using legacy naming tag
498498
assert groups_L3VPN["CPE_ifp-0-1-2-4"]["neighbors"][0]["interface"] == "ifp-0/1/2.4"
499499
assert (
500500
not "export"
@@ -511,25 +511,23 @@ def test_router_case_local_bgpcpe():
511511
"import_list"
512512
] == ["2a0e:b941:2:42::/64", "2a0e:b941:2::/122"]
513513

514-
assert "CPE_ifp-0-1-2-5_V4" in groups_L3VPN
515-
assert "CPE_ifp-0-1-2-5_V6" in groups_L3VPN
516-
assert groups_L3VPN["CPE_ifp-0-1-2-5_V4"]["neighbors"][0]["peer"] == "10.128.6.12"
517-
assert (
518-
groups_L3VPN["CPE_ifp-0-1-2-5_V6"]["neighbors"][0]["peer"] == "2a0e:b941:2::21"
519-
)
514+
assert "CUST_cl390287_V4" in groups_L3VPN
515+
assert "CUST_cl390287_V6" in groups_L3VPN
516+
assert groups_L3VPN["CUST_cl390287_V4"]["neighbors"][0]["peer"] == "10.128.6.12"
517+
assert groups_L3VPN["CUST_cl390287_V6"]["neighbors"][0]["peer"] == "2a0e:b941:2::21"
520518
assert (
521519
not "export"
522-
in groups_L3VPN["CPE_ifp-0-1-2-5_V4"]["family"]["ipv4_unicast"]["policy"]
520+
in groups_L3VPN["CUST_cl390287_V4"]["family"]["ipv4_unicast"]["policy"]
523521
)
524522
assert (
525523
not "export"
526-
in groups_L3VPN["CPE_ifp-0-1-2-5_V6"]["family"]["ipv6_unicast"]["policy"]
524+
in groups_L3VPN["CUST_cl390287_V6"]["family"]["ipv6_unicast"]["policy"]
527525
)
528-
assert groups_L3VPN["CPE_ifp-0-1-2-5_V4"]["family"]["ipv4_unicast"]["policy"][
526+
assert groups_L3VPN["CUST_cl390287_V4"]["family"]["ipv4_unicast"]["policy"][
529527
"import_list"
530528
] == ["10.1.0.0/28"]
531529
# should not be allowed to announce our transfer nets, so '2a0e:b941:2::/122' should not be there
532-
assert groups_L3VPN["CPE_ifp-0-1-2-5_V6"]["family"]["ipv6_unicast"]["policy"][
530+
assert groups_L3VPN["CUST_cl390287_V6"]["family"]["ipv6_unicast"]["policy"][
533531
"import_list"
534532
] == ["2a0e:b941:2:42::/64"]
535533

0 commit comments

Comments
 (0)