Skip to content

Commit 369a0b4

Browse files
authored
Merge pull request #43 from opsmill/ps-fix-create-dc-generator
Fix issue with cable generation in create_dc generator
2 parents c4f46d1 + da36e2f commit 369a0b4

File tree

5 files changed

+80
-19
lines changed

5 files changed

+80
-19
lines changed

generators/common.py

Lines changed: 31 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1125,26 +1125,51 @@ async def create_oob_connections(
11251125
kind=(InterfacePhysical if connection_type == "management" else DcimConsoleInterface),
11261126
name__value=connection["source_interface"],
11271127
device__name__value=connection["source"],
1128+
prefetch_relationships=True,
1129+
populate_store=True,
11281130
)
11291131
target_endpoint = await self.client.get(
11301132
kind=(InterfacePhysical if connection_type == "management" else DcimConsoleInterface),
11311133
name__value=connection["destination_interface"],
11321134
device__name__value=connection["target"],
1135+
prefetch_relationships=True,
1136+
populate_store=True,
11331137
)
11341138

11351139
source_endpoint.status.value = "active"
11361140
source_endpoint.description.value = f"Connection to {' -> '.join(target_endpoint.hfid or [])}"
11371141
target_endpoint.status.value = "active"
11381142
target_endpoint.description.value = f"Connection to {' -> '.join(source_endpoint.hfid or [])}"
11391143

1140-
# Create cable to connect the endpoints
1144+
# Check if either endpoint already has a cable attached
1145+
# Note: Accessing .peer can raise ValueError if the related node exists
1146+
# but doesn't have an ID/HFID (e.g., hasn't been saved yet). We catch
1147+
# this and treat it as "no existing cable".
1148+
existing_cable_id = None
1149+
try:
1150+
if source_endpoint.connector.peer:
1151+
existing_cable_id = source_endpoint.connector.peer.id
1152+
except ValueError:
1153+
pass # No existing cable or peer doesn't have an ID
1154+
if not existing_cable_id:
1155+
try:
1156+
if target_endpoint.connector.peer:
1157+
existing_cable_id = target_endpoint.connector.peer.id
1158+
except ValueError:
1159+
pass # No existing cable or peer doesn't have an ID
1160+
1161+
# Create or update cable to connect the endpoints
1162+
cable_data: dict[str, Any] = {
1163+
"status": "connected",
1164+
"cable_type": "cat6", # Use cat6 for management/console connections
1165+
"connected_endpoints": [source_endpoint.id, target_endpoint.id],
1166+
}
1167+
if existing_cable_id:
1168+
cable_data["id"] = existing_cable_id
1169+
11411170
cable = await self.client.create(
11421171
kind=DcimCable,
1143-
data={
1144-
"status": "connected",
1145-
"cable_type": "cat6", # Use cat6 for management/console connections
1146-
"connected_endpoints": [source_endpoint.id, target_endpoint.id],
1147-
},
1172+
data=cable_data,
11481173
)
11491174

11501175
# Save the cable first so it exists in the database

generators/generate_dc.py

Lines changed: 33 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
dual loopbacks (underlay + VTEP), and proper BGP peer group configuration.
1515
"""
1616

17+
from typing import Any
18+
1719
from infrahub_sdk.generator import InfrahubGenerator
1820
from infrahub_sdk.protocols import CoreNumberPool
1921

@@ -142,11 +144,15 @@ async def create_fabric_peering(self) -> None:
142144
kind=InterfacePhysical,
143145
name__value=connection["source_interface"],
144146
device__name__value=connection["source"],
147+
prefetch_relationships=True,
148+
populate_store=True,
145149
)
146150
target_endpoint = await self.client.get(
147151
kind=InterfacePhysical,
148152
name__value=connection["destination_interface"],
149153
device__name__value=connection["target"],
154+
prefetch_relationships=True,
155+
populate_store=True,
150156
)
151157

152158
# Configure source interface
@@ -159,15 +165,36 @@ async def create_fabric_peering(self) -> None:
159165
target_endpoint.description.value = f"Peering connection to {' -> '.join(source_endpoint.hfid or [])}"
160166
target_endpoint.role.value = interface_role
161167

162-
# Create cable object connecting both endpoints
168+
# Check if either endpoint already has a cable attached
169+
# Note: Accessing .peer can raise ValueError if the related node exists
170+
# but doesn't have an ID/HFID (e.g., hasn't been saved yet). We catch
171+
# this and treat it as "no existing cable".
172+
existing_cable_id = None
173+
try:
174+
if source_endpoint.connector.peer:
175+
existing_cable_id = source_endpoint.connector.peer.id
176+
except ValueError:
177+
pass # No existing cable or peer doesn't have an ID
178+
if not existing_cable_id:
179+
try:
180+
if target_endpoint.connector.peer:
181+
existing_cable_id = target_endpoint.connector.peer.id
182+
except ValueError:
183+
pass # No existing cable or peer doesn't have an ID
184+
185+
# Create or update cable object connecting both endpoints
163186
# Uses DAC (Direct Attach Copper) passive cables for fabric links
187+
cable_data: dict[str, Any] = {
188+
"status": "connected",
189+
"cable_type": "dac-passive",
190+
"connected_endpoints": [source_endpoint.id, target_endpoint.id],
191+
}
192+
if existing_cable_id:
193+
cable_data["id"] = existing_cable_id
194+
164195
cable = await self.client.create(
165196
kind=DcimCable,
166-
data={
167-
"status": "connected",
168-
"cable_type": "dac-passive",
169-
"connected_endpoints": [source_endpoint.id, target_endpoint.id],
170-
},
197+
data=cable_data,
171198
)
172199

173200
# Save the cable first so it exists in the database

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ authors = [
1313
]
1414
requires-python = ">=3.10,<3.13"
1515
dependencies = [
16-
"infrahub-sdk[all]>=1.17.0,<2.0.0",
16+
"infrahub-sdk[all,ctl]==1.18.1",
1717
"invoke>=2.2.1,<3.0.0",
1818
"rich>=13.9.4,<14.0.0",
1919
]

schemas/base/dcim.yml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,6 @@ generics:
137137
relationships:
138138
- name: connected_endpoints
139139
peer: DcimEndpoint
140-
optional: true
141140
cardinality: many
142141
order_weight: 1500
143142
kind: Generic

uv.lock

Lines changed: 15 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)