@@ -249,13 +249,19 @@ func (actuator serverActuator) CreateResource(ctx context.Context, obj *orcv1alp
249249 // Sort tags before creation to simplify comparisons
250250 slices .Sort (tags )
251251
252+ metadata := make (map [string ]string )
253+ for _ , m := range resource .Metadata {
254+ metadata [m .Key ] = m .Value
255+ }
256+
252257 serverCreateOpts := servers.CreateOpts {
253258 Name : getResourceName (obj ),
254259 ImageRef : * image .Status .ID ,
255260 FlavorRef : * flavor .Status .ID ,
256261 Networks : portList ,
257262 UserData : userData ,
258263 Tags : tags ,
264+ Metadata : metadata ,
259265 AvailabilityZone : resource .AvailabilityZone ,
260266 }
261267
@@ -307,6 +313,7 @@ func (actuator serverActuator) GetResourceReconcilers(ctx context.Context, orcOb
307313 actuator .checkStatus ,
308314 actuator .updateResource ,
309315 actuator .reconcileTags ,
316+ actuator .reconcileMetadata ,
310317 actuator .reconcilePortAttachments ,
311318 actuator .reconcileVolumeAttachments ,
312319 }, nil
@@ -393,6 +400,39 @@ func (actuator serverActuator) reconcileTags(ctx context.Context, obj orcObjectP
393400 return tags .ReconcileTags [orcObjectPT , osResourceT ](obj .Spec .Resource .Tags , ptr .Deref (osResource .Tags , []string {}), tags .NewServerTagReplacer (actuator .osClient , osResource .ID ))(ctx , obj , osResource )
394401}
395402
403+ func (actuator serverActuator ) reconcileMetadata (ctx context.Context , obj orcObjectPT , osResource * osResourceT ) progress.ReconcileStatus {
404+ log := ctrl .LoggerFrom (ctx )
405+ resource := obj .Spec .Resource
406+ if resource == nil {
407+ return progress .WrapError (
408+ orcerrors .Terminal (orcv1alpha1 .ConditionReasonInvalidConfiguration , "Update requested, but spec.resource is not set" ))
409+ }
410+
411+ // Metadata cannot be set on a server that is still building
412+ if osResource .Status == "" || osResource .Status == ServerStatusBuild {
413+ return progress .NewReconcileStatus ().WaitingOnOpenStack (progress .WaitingOnReady , serverActivePollingPeriod )
414+ }
415+
416+ // Build the desired metadata map from spec
417+ desiredMetadata := make (map [string ]string )
418+ for _ , m := range resource .Metadata {
419+ desiredMetadata [m .Key ] = m .Value
420+ }
421+
422+ // Compare with current metadata
423+ if maps .Equal (desiredMetadata , osResource .Metadata ) {
424+ return nil
425+ }
426+
427+ log .V (logging .Verbose ).Info ("Updating server metadata" )
428+ _ , err := actuator .osClient .ReplaceServerMetadata (ctx , osResource .ID , desiredMetadata )
429+ if err != nil {
430+ return progress .WrapError (err )
431+ }
432+
433+ return progress .NeedsRefresh ()
434+ }
435+
396436func (actuator serverActuator ) reconcilePortAttachments (ctx context.Context , obj orcObjectPT , osResource * osResourceT ) progress.ReconcileStatus {
397437 log := ctrl .LoggerFrom (ctx )
398438 resource := obj .Spec .Resource
0 commit comments