Skip to content

Commit f1f8d92

Browse files
authored
Add osism-ipa-metalbox kernel parameter for yrzn001 IPA type (#2083)
Resolve the metalbox primary IPv4 address by matching the device's OOB IP subnet against metalbox interfaces in NetBox, and append it as the osism-ipa-metalbox kernel parameter. AI-assisted: Claude Code Signed-off-by: Christian Berendt <berendt@osism.tech>
1 parent 7a37830 commit f1f8d92

1 file changed

Lines changed: 45 additions & 0 deletions

File tree

osism/tasks/conductor/ironic.py

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
# SPDX-License-Identifier: Apache-2.0
22

3+
import ipaddress
34
import json
45
import re
56
import textwrap
@@ -27,6 +28,7 @@
2728
"osism-ipa-as": "frr_local_as",
2829
"osism-ipa-ipv4": "frr_loopback_v4",
2930
"osism-ipa-ipv6": "frr_loopback_v6",
31+
"osism-ipa-metalbox": None, # resolved via metalbox lookup
3032
},
3133
}
3234

@@ -59,6 +61,45 @@ def _derive_as_from_hostname_yrzn(hostname):
5961
return f"42001{t}{rack}{server}"
6062

6163

64+
def _get_metalbox_primary_ip4(device):
65+
"""Get the primary IPv4 address of the metalbox managing this device.
66+
67+
Finds the metalbox whose interface shares the same subnet as the
68+
device's OOB IP address, then returns that metalbox's primary_ip4.
69+
70+
Args:
71+
device: NetBox device object
72+
73+
Returns:
74+
str: The metalbox's primary IPv4 address (without prefix), or None
75+
"""
76+
from osism import utils
77+
78+
oob_ip_result = get_device_oob_ip(device)
79+
if not oob_ip_result:
80+
return None
81+
82+
oob_ip, _ = oob_ip_result
83+
oob_addr = ipaddress.ip_address(oob_ip)
84+
85+
metalboxes = utils.nb.dcim.devices.filter(role="metalbox")
86+
for metalbox in metalboxes:
87+
interfaces = utils.nb.dcim.interfaces.filter(device_id=metalbox.id)
88+
for interface in interfaces:
89+
ip_addresses = utils.nb.ipam.ip_addresses.filter(
90+
assigned_object_id=interface.id,
91+
)
92+
for ip_addr in ip_addresses:
93+
if ip_addr.address:
94+
network = ipaddress.ip_network(ip_addr.address, strict=False)
95+
if oob_addr in network:
96+
if metalbox.primary_ip4:
97+
return str(metalbox.primary_ip4).split("/")[0]
98+
return None
99+
100+
return None
101+
102+
62103
driver_params = {
63104
"ipmi": {
64105
"address": "ipmi_address",
@@ -184,6 +225,10 @@ def _prepare_node_attributes(device, get_ironic_parameters):
184225
for kap_name, frr_key in SUPPORTED_IPA_TYPES[ipa_type].items():
185226
if kap_name == "osism-ipa-as" and derived_as:
186227
kap += f" {kap_name}={derived_as}"
228+
elif kap_name == "osism-ipa-metalbox":
229+
metalbox_ip = _get_metalbox_primary_ip4(device)
230+
if metalbox_ip:
231+
kap += f" {kap_name}={metalbox_ip}"
187232
elif frr_key in frr:
188233
kap += f" {kap_name}={frr[frr_key]}"
189234
node_attributes["instance_info"]["kernel_append_params"] = kap

0 commit comments

Comments
 (0)