Skip to content

Commit 242294a

Browse files
committed
[hypervisor-controller] transfer aggregates/traits after inital creation
due to delayed labeling/annotation of node properties, transfer aggregates/traits also after initial creation of hypervisor CRO.
1 parent 24c5d88 commit 242294a

2 files changed

Lines changed: 68 additions & 31 deletions

File tree

internal/controller/hypervisor_controller.go

Lines changed: 46 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ package controller
2020
import (
2121
"context"
2222
"fmt"
23+
"reflect"
2324
"slices"
2425
"strings"
2526

@@ -111,14 +112,15 @@ func (hv *HypervisorController) Reconcile(ctx context.Context, req ctrl.Request)
111112
return ctrl.Result{}, hv.Status().Update(ctx, hypervisor)
112113
}
113114
}
114-
return ctrl.Result{}, nil
115-
}
116115

117-
// transfer labels
118-
for _, label := range transferLabels {
119-
if nodeLabels.Has(label) {
120-
hypervisor.Labels[label] = nodeLabels.Get(label)
116+
// transport label/anotations changes
117+
before := hypervisor.DeepCopy()
118+
updateLabelsAndAnnotations(&node.ObjectMeta, hypervisor)
119+
if !reflect.DeepEqual(before, hypervisor) {
120+
return ctrl.Result{}, hv.Patch(ctx, hypervisor, k8sclient.MergeFrom(before))
121121
}
122+
123+
return ctrl.Result{}, nil
122124
}
123125

124126
// transport lifecycle label to hypervisor spec
@@ -127,31 +129,8 @@ func (hv *HypervisorController) Reconcile(ctx context.Context, req ctrl.Request)
127129
hypervisor.Spec.SkipTests = nodeLabels.Get(labelLifecycleMode) == "skip-tests"
128130
}
129131

130-
// transport aggregates annotation to hypervisor spec
131-
if aggregates, found := node.Annotations[annotationAggregates]; found {
132-
// split aggregates string
133-
hypervisor.Spec.Aggregates = slices.Collect(func(yield func(string) bool) {
134-
for _, agg := range strings.Split(aggregates, ",") {
135-
trimmed := strings.TrimSpace(agg)
136-
if trimmed != "" && yield(trimmed) {
137-
return
138-
}
139-
}
140-
})
141-
}
142-
143-
// transport custom traits annotation to hypervisor spec
144-
if customTraits, found := node.Annotations[annotationCustomTraits]; found {
145-
// split custom traits string
146-
hypervisor.Spec.CustomTraits = slices.Collect(func(yield func(string) bool) {
147-
for _, trait := range strings.Split(customTraits, ",") {
148-
trimmed := strings.TrimSpace(trait)
149-
if trimmed != "" && yield(trimmed) {
150-
return
151-
}
152-
}
153-
})
154-
}
132+
// transport relevant annotations
133+
updateLabelsAndAnnotations(&node.ObjectMeta, hypervisor)
155134

156135
if err := controllerutil.SetOwnerReference(node, hypervisor, hv.Scheme, controllerutil.WithBlockOwnerDeletion(true)); err != nil {
157136
return ctrl.Result{}, fmt.Errorf("failed setting controller reference: %w", err)
@@ -183,3 +162,39 @@ func (hv *HypervisorController) SetupWithManager(mgr ctrl.Manager) error {
183162
WithEventFilter(novaVirtLabeledPredicate).
184163
Complete(hv)
185164
}
165+
166+
// updateLabelsAndAnnotations transports relevant annotations from the Node to the Hypervisor spec
167+
func updateLabelsAndAnnotations(node *metav1.ObjectMeta, hypervisor *kvmv1.Hypervisor) {
168+
// transport aggregates annotation to hypervisor spec
169+
if aggregates, found := node.Annotations[annotationAggregates]; found {
170+
// split aggregates string
171+
hypervisor.Spec.Aggregates = slices.Collect(func(yield func(string) bool) {
172+
for _, agg := range strings.Split(aggregates, ",") {
173+
trimmed := strings.TrimSpace(agg)
174+
if trimmed != "" && yield(trimmed) {
175+
return
176+
}
177+
}
178+
})
179+
}
180+
181+
// transport custom traits annotation to hypervisor spec
182+
if customTraits, found := node.Annotations[annotationCustomTraits]; found {
183+
// split custom traits string
184+
hypervisor.Spec.CustomTraits = slices.Collect(func(yield func(string) bool) {
185+
for _, trait := range strings.Split(customTraits, ",") {
186+
trimmed := strings.TrimSpace(trait)
187+
if trimmed != "" && yield(trimmed) {
188+
return
189+
}
190+
}
191+
})
192+
}
193+
194+
// transfer labels
195+
for _, transferLabel := range transferLabels {
196+
if label, ok := node.Labels[transferLabel]; ok {
197+
hypervisor.Labels[transferLabel] = label
198+
}
199+
}
200+
}

internal/controller/hypervisor_controller_test.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,28 @@ var _ = Describe("Hypervisor Controller", func() {
8282
Expect(hypervisor.Name).To(Equal(resource.Name))
8383
Expect(hypervisor.Labels).ToNot(BeNil())
8484
Expect(hypervisor.Labels[corev1.LabelTopologyZone]).To(Equal("test-zone"))
85+
86+
By("Adding a aggregate annotation to the node and reconciling again")
87+
// Add an aggregate annotation to the node
88+
annotedResource := resource.DeepCopy()
89+
if annotedResource.Annotations == nil {
90+
annotedResource.Annotations = map[string]string{}
91+
}
92+
annotedResource.Annotations[annotationCustomTraits] = "test-trait"
93+
Expect(k8sClient.Patch(ctx, annotedResource, client.Merge)).To(Succeed())
94+
95+
_, err = hypervisorController.Reconcile(ctx, ctrl.Request{
96+
NamespacedName: types.NamespacedName{Name: resource.Name},
97+
})
98+
Expect(err).NotTo(HaveOccurred())
99+
100+
By("should have updated the Hypervisor resource with the aggregate")
101+
// Get the Hypervisor resource again
102+
updatedHypervisor := &kvmv1.Hypervisor{}
103+
Expect(hypervisorController.Get(ctx, hypervisorName, updatedHypervisor)).To(Succeed())
104+
Expect(updatedHypervisor.Name).To(Equal(resource.Name))
105+
Expect(updatedHypervisor.Spec.CustomTraits).ToNot(BeNil())
106+
Expect(updatedHypervisor.Spec.CustomTraits).To(ContainElement("test-trait"))
85107
})
86108
})
87109

0 commit comments

Comments
 (0)