Skip to content

Commit 04cd561

Browse files
authored
Merge pull request #630 from eshulman2/mdata
Add metadata to server controller
2 parents 270e5de + e3b4d21 commit 04cd561

22 files changed

Lines changed: 514 additions & 2 deletions

File tree

api/v1alpha1/server_types.go

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,27 @@ type ServerResourceSpec struct {
181181
// +listType=set
182182
// +optional
183183
Tags []ServerTag `json:"tags,omitempty"`
184+
185+
// metadata is a list of metadata key-value pairs which will be set on the server.
186+
// +kubebuilder:validation:MaxItems:=128
187+
// +listType=atomic
188+
// +optional
189+
Metadata []ServerMetadata `json:"metadata,omitempty"`
190+
}
191+
192+
// ServerMetadata represents a key-value pair for server metadata.
193+
type ServerMetadata struct {
194+
// key is the metadata key.
195+
// +kubebuilder:validation:MinLength:=1
196+
// +kubebuilder:validation:MaxLength:=255
197+
// +required
198+
Key string `json:"key,omitempty"`
199+
200+
// value is the metadata value.
201+
// +kubebuilder:validation:MaxLength:=255
202+
// +kubebuilder:validation:MinLength:=1
203+
// +required
204+
Value string `json:"value,omitempty"`
184205
}
185206

186207
// +kubebuilder:validation:MinProperties:=1
@@ -261,4 +282,23 @@ type ServerResourceStatus struct {
261282
// +listType=atomic
262283
// +optional
263284
Tags []string `json:"tags,omitempty"`
285+
286+
// metadata is the list of metadata key-value pairs on the resource.
287+
// +kubebuilder:validation:MaxItems:=128
288+
// +listType=atomic
289+
// +optional
290+
Metadata []ServerMetadataStatus `json:"metadata,omitempty"`
291+
}
292+
293+
// ServerMetadataStatus represents a key-value pair for server metadata in status.
294+
type ServerMetadataStatus struct {
295+
// key is the metadata key.
296+
// +kubebuilder:validation:MaxLength:=255
297+
// +optional
298+
Key string `json:"key,omitempty"`
299+
300+
// value is the metadata value.
301+
// +kubebuilder:validation:MaxLength:=255
302+
// +optional
303+
Value string `json:"value,omitempty"`
264304
}

api/v1alpha1/zz_generated.deepcopy.go

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

cmd/models-schema/zz_generated.openapi.go

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

config/crd/bases/openstack.k-orc.cloud_servers.yaml

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,30 @@ spec:
231231
x-kubernetes-validations:
232232
- message: keypairRef is immutable
233233
rule: self == oldSelf
234+
metadata:
235+
description: metadata is a list of metadata key-value pairs which
236+
will be set on the server.
237+
items:
238+
description: ServerMetadata represents a key-value pair for
239+
server metadata.
240+
properties:
241+
key:
242+
description: key is the metadata key.
243+
maxLength: 255
244+
minLength: 1
245+
type: string
246+
value:
247+
description: value is the metadata value.
248+
maxLength: 255
249+
minLength: 1
250+
type: string
251+
required:
252+
- key
253+
- value
254+
type: object
255+
maxItems: 128
256+
type: array
257+
x-kubernetes-list-type: atomic
234258
name:
235259
description: |-
236260
name will be the name of the created resource. If not specified, the
@@ -488,6 +512,25 @@ spec:
488512
maxItems: 64
489513
type: array
490514
x-kubernetes-list-type: atomic
515+
metadata:
516+
description: metadata is the list of metadata key-value pairs
517+
on the resource.
518+
items:
519+
description: ServerMetadataStatus represents a key-value pair
520+
for server metadata in status.
521+
properties:
522+
key:
523+
description: key is the metadata key.
524+
maxLength: 255
525+
type: string
526+
value:
527+
description: value is the metadata value.
528+
maxLength: 255
529+
type: string
530+
type: object
531+
maxItems: 128
532+
type: array
533+
x-kubernetes-list-type: atomic
491534
name:
492535
description: name is the human-readable name of the resource.
493536
Might not be unique.

config/samples/openstack_v1alpha1_server.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,3 +20,8 @@ spec:
2020
tags:
2121
- tag1
2222
- tag2
23+
metadata:
24+
- key: environment
25+
value: development
26+
- key: owner
27+
value: sample

internal/controllers/server/actuator.go

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
396436
func (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

Comments
 (0)