@@ -343,6 +343,21 @@ def parse_bmc_address(bmc_addr):
343343 "redfish_system_id" : system_id ,
344344 }
345345
346+ def resolve_ironic_network_data ():
347+ """Resolve Ironic node.network_data for IPA ramdisk: preprov secret first, then Spec.NetworkData."""
348+ nd_raw = read_host_secret ("preprovisioningNetworkData" )
349+ if not nd_raw :
350+ nd_raw = read_host_secret ("networkData" )
351+ if not nd_raw :
352+ return None
353+ nd = yaml_decode (nd_raw )
354+
355+ # Ironic schema requires network_id on each network entry; CAPM3 omits it.
356+ for net in nd .get ("networks" , []):
357+ if "network_id" not in net :
358+ net ["network_id" ] = net .get ("id" , "" )
359+ return nd
360+
346361def create_node (bmc_addr , bmc_user , bmc_password , boot_mac , data ):
347362 """Creates a new node in Ironic via POST /v1/nodes."""
348363 bmc = parse_bmc_address (bmc_addr )
@@ -373,9 +388,9 @@ def create_node(bmc_addr, bmc_user, bmc_password, boot_mac, data):
373388 "cpu_arch" : cpu_arch ,
374389 },
375390 }
376- nd_raw = data . get ( "PreprovisioningNetworkData" , "" )
377- if nd_raw :
378- body ["network_data" ] = yaml_decode ( nd_raw )
391+ nd = resolve_ironic_network_data ( )
392+ if nd :
393+ body ["network_data" ] = nd
379394 node , status = http_post ("/v1/nodes" , body )
380395 if status == 409 :
381396 return None , status
@@ -432,11 +447,9 @@ def build_register_patch(node, data, _creds_changed):
432447 ops .append (patch_op ("add" , "/driver_info/deploy_ramdisk" , DEPLOY_RAMDISK_URL ))
433448
434449 # Network data for IPA (so it can reach Ironic callback endpoint)
435- nd_raw = data .get ("PreprovisioningNetworkData" , "" )
436- if nd_raw :
437- nd = yaml_decode (nd_raw )
438- if nd != node .get ("network_data" ):
439- ops .append (patch_op ("add" , "/network_data" , nd ))
450+ nd = resolve_ironic_network_data ()
451+ if nd and nd != node .get ("network_data" ):
452+ ops .append (patch_op ("add" , "/network_data" , nd ))
440453
441454 return ops
442455
@@ -759,9 +772,18 @@ def adopt(host, data, restart_on_failure):
759772 return {}
760773
761774def prepare (host , data , _unprepared , _restart_on_failure ):
762- """Reject RAID; prepare itself is not implemented ."""
775+ """Reject RAID; sync network_data on the Ironic node for cleaning boots ."""
763776 require_redfish_virtualmedia (host )
764777 require_no_raid (data )
778+
779+ prov_id = host [HOST_PROVISIONER_ID ]
780+ if prov_id :
781+ nd = resolve_ironic_network_data ()
782+ if nd :
783+ node , status = http_get ("/v1/nodes/" + prov_id , ignore_statuses = [404 ])
784+ if status == 200 and node and nd != node .get ("network_data" ):
785+ http_patch ("/v1/nodes/" + prov_id , [patch_op ("add" , "/network_data" , nd )])
786+
765787 return {"started" : False }
766788
767789def service (host , _data , _unprepared , _restart_on_failure ):
@@ -778,6 +800,11 @@ def provision(host, data, force_reboot):
778800 if status != 200 or not node :
779801 return {"dirty" : True , "error" : "provision: cannot get node" }
780802
803+ # Sync network_data so the deploy ramdisk boots with network config.
804+ nd = resolve_ironic_network_data ()
805+ if nd and nd != node .get ("network_data" ):
806+ http_patch ("/v1/nodes/" + prov_id , [patch_op ("add" , "/network_data" , nd )])
807+
781808 state = node .get ("provision_state" , "" )
782809
783810 if state == MANAGEABLE :
@@ -926,6 +953,11 @@ def deprovision(host, restart_on_failure, automated_cleaning_mode):
926953 if status != 200 or not node :
927954 return {"dirty" : True , "error" : "deprovision: cannot get node" }
928955
956+ # Sync network_data so the cleaning ramdisk boots with network config.
957+ nd = resolve_ironic_network_data ()
958+ if nd and nd != node .get ("network_data" ):
959+ http_patch ("/v1/nodes/" + prov_id , [patch_op ("add" , "/network_data" , nd )])
960+
929961 state = node .get ("provision_state" , "" )
930962
931963 # Sync automated_clean setting
@@ -980,6 +1012,11 @@ def delete(host):
9801012 if status != 200 or not node :
9811013 return {"dirty" : True , "error" : "delete: cannot get node" }
9821014
1015+ # Sync network_data so any cleaning triggered by delete has network config.
1016+ nd = resolve_ironic_network_data ()
1017+ if nd and nd != node .get ("network_data" ):
1018+ http_patch ("/v1/nodes/" + prov_id , [patch_op ("add" , "/network_data" , nd )])
1019+
9831020 state = node .get ("provision_state" , "" )
9841021
9851022 if state == VERIFYING :
0 commit comments