@@ -300,9 +300,15 @@ func (actuator trunkActuator) updateResource(ctx context.Context, obj orcObjectP
300300 return progress .WrapError (err )
301301 }
302302
303+ // Refresh is needed to get the updated resource state from OpenStack after modifications.
304+ // This ensures the status accurately reflects the current state before the next reconciliation cycle.
303305 return progress .NeedsRefresh ()
304306}
305307
308+ // reconcileSubports ensures the trunk's subports match the desired state from the spec.
309+ // It handles adding new subports, removing deleted ones, and updating existing subports.
310+ // Note: OpenStack trunk API does not support in-place updates of subport segmentation,
311+ // so changes require removing and re-adding the subport, which may cause brief network interruption.
306312func (actuator trunkActuator ) reconcileSubports (ctx context.Context , obj orcObjectPT , osResource * osResourceT ) progress.ReconcileStatus {
307313 log := ctrl .LoggerFrom (ctx )
308314 resource := obj .Spec .Resource
@@ -332,6 +338,7 @@ func (actuator trunkActuator) reconcileSubports(ctx context.Context, obj orcObje
332338 subportPort , ok := portMap [portName ]
333339 if ! ok {
334340 // Port not ready yet, will be retried
341+ log .V (logging .Debug ).Info ("Skipping subport: port not ready" , "portRef" , portName )
335342 continue
336343 }
337344 desiredSubports = append (desiredSubports , trunks.Subport {
@@ -341,23 +348,19 @@ func (actuator trunkActuator) reconcileSubports(ctx context.Context, obj orcObje
341348 })
342349 }
343350
344- // Build maps for comparison
345- currentMap := make (map [string ]trunks.Subport )
346- for _ , subport := range currentSubports {
347- currentMap [subport .PortID ] = subport
348- }
349-
350- desiredMap := make (map [string ]trunks.Subport )
351- for _ , subport := range desiredSubports {
352- desiredMap [subport .PortID ] = subport
353- }
351+ // Build maps for comparison (keyed by PortID for efficient lookup)
352+ currentMap := buildSubportMap (currentSubports )
353+ desiredMap := buildSubportMap (desiredSubports )
354354
355355 // Find subports to add
356+ // Note: OpenStack trunk API does not support in-place updates of subport segmentation.
357+ // When segmentation type or ID changes, we must remove the old subport and add it back
358+ // with the new segmentation. This may cause a brief network interruption for that subport.
356359 toAdd := []trunks.Subport {}
357360 for portID , desired := range desiredMap {
358361 if current , exists := currentMap [portID ]; ! exists {
359362 toAdd = append (toAdd , desired )
360- } else if current . SegmentationType != desired . SegmentationType || current . SegmentationID != desired . SegmentationID {
363+ } else if subportNeedsUpdate ( current , desired ) {
361364 // Subport exists but with different segmentation, need to remove and re-add
362365 // First remove the old one
363366 removeOpts := trunks.RemoveSubportsOpts {
@@ -396,12 +399,29 @@ func (actuator trunkActuator) reconcileSubports(ctx context.Context, obj orcObje
396399 }
397400
398401 if len (toAdd ) > 0 || len (toRemove ) > 0 {
402+ // Refresh is needed to get the updated subport list from OpenStack after modifications.
403+ // This ensures the status accurately reflects the current state before the next reconciliation.
399404 return progress .NeedsRefresh ()
400405 }
401406
402407 return nil
403408}
404409
410+ // buildSubportMap creates a map of subports keyed by PortID for efficient comparison.
411+ func buildSubportMap (subports []trunks.Subport ) map [string ]trunks.Subport {
412+ result := make (map [string ]trunks.Subport , len (subports ))
413+ for _ , subport := range subports {
414+ result [subport .PortID ] = subport
415+ }
416+ return result
417+ }
418+
419+ // subportNeedsUpdate checks if a subport needs to be updated by comparing segmentation parameters.
420+ // OpenStack trunk API does not support in-place updates, so any change requires remove+re-add.
421+ func subportNeedsUpdate (current , desired trunks.Subport ) bool {
422+ return current .SegmentationType != desired .SegmentationType || current .SegmentationID != desired .SegmentationID
423+ }
424+
405425type trunkHelperFactory struct {}
406426
407427var _ helperFactory = trunkHelperFactory {}
0 commit comments