@@ -29,7 +29,6 @@ import (
2929 "github.com/gophercloud/gophercloud/v2/openstack/compute/v2/hypervisors"
3030 "github.com/gophercloud/gophercloud/v2/openstack/compute/v2/servers"
3131 "github.com/gophercloud/gophercloud/v2/openstack/compute/v2/services"
32- corev1 "k8s.io/api/core/v1"
3332 "k8s.io/apimachinery/pkg/api/meta"
3433 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
3534 "k8s.io/apimachinery/pkg/runtime"
@@ -40,7 +39,6 @@ import (
4039 logger "sigs.k8s.io/controller-runtime/pkg/log"
4140
4241 kvmv1 "github.com/cobaltcore-dev/openstack-hypervisor-operator/api/v1"
43- "github.com/cobaltcore-dev/openstack-hypervisor-operator/internal/global"
4442 "github.com/cobaltcore-dev/openstack-hypervisor-operator/internal/openstack"
4543)
4644
@@ -61,7 +59,7 @@ const (
6159// +kubebuilder:rbac:groups=kvm.cloud.sap,resources=evictions,verbs=get;list;watch;create;update;patch;delete
6260// +kubebuilder:rbac:groups=kvm.cloud.sap,resources=evictions/status,verbs=get;update;patch
6361// +kubebuilder:rbac:groups=kvm.cloud.sap,resources=evictions/finalizers,verbs=update
64- // +kubebuilder:rbac:groups="" ,resources=nodes ,verbs=get;list;watch
62+ // +kubebuilder:rbac:groups=kvm.cloud.sap ,resources=hypervisors ,verbs=get;list;watch
6563
6664// Reconcile is part of the main kubernetes reconciliation loop which aims to
6765// move the current state of the cluster closer to the desired state.
@@ -72,12 +70,11 @@ func (r *EvictionReconciler) Reconcile(ctx context.Context, req ctrl.Request) (c
7270 return ctrl.Result {}, client .IgnoreNotFound (err )
7371 }
7472
75- if global .LabelSelector != "" {
76- // This test-fetch the Node assigned to the eviction, it won't be cached if it's not part of our partition so
77- // we won't reconcile evictions for nodes outside our partition
78- if err := r .Get (ctx , types.NamespacedName {Name : eviction .Spec .Hypervisor }, & corev1.Node {}); err != nil {
79- return ctrl.Result {}, client .IgnoreNotFound (err )
80- }
73+ hv := & kvmv1.Hypervisor {}
74+ // Let's fetch the Hypervisor assigned to the eviction, it won't be cached if it's not part of our partition so
75+ // we won't reconcile evictions for nodes outside our partition
76+ if err := r .Get (ctx , types.NamespacedName {Name : eviction .Spec .Hypervisor }, hv ); err != nil {
77+ return ctrl.Result {}, client .IgnoreNotFound (err )
8178 }
8279
8380 log := logger .FromContext (ctx ).
@@ -87,7 +84,7 @@ func (r *EvictionReconciler) Reconcile(ctx context.Context, req ctrl.Request) (c
8784
8885 // Being deleted
8986 if ! eviction .DeletionTimestamp .IsZero () {
90- err := r .handleFinalizer (ctx , eviction )
87+ err := r .handleFinalizer (ctx , eviction , hv )
9188 if err != nil {
9289 if errors .Is (err , ErrRetry ) {
9390 return ctrl.Result {RequeueAfter : defaultWaitTime }, nil
@@ -114,7 +111,7 @@ func (r *EvictionReconciler) Reconcile(ctx context.Context, req ctrl.Request) (c
114111 switch statusCondition .Status {
115112 case metav1 .ConditionTrue :
116113 // We are running, so we need to evict the next instance
117- return r .handleRunning (ctx , eviction )
114+ return r .handleRunning (ctx , eviction , hv )
118115 case metav1 .ConditionFalse :
119116 // We are done, so we can just return
120117 log .Info ("finished" )
@@ -129,10 +126,10 @@ func (r *EvictionReconciler) Reconcile(ctx context.Context, req ctrl.Request) (c
129126 return ctrl.Result {}, nil
130127}
131128
132- func (r * EvictionReconciler ) handleRunning (ctx context.Context , eviction * kvmv1.Eviction ) (ctrl.Result , error ) {
129+ func (r * EvictionReconciler ) handleRunning (ctx context.Context , eviction * kvmv1.Eviction , hypervisor * kvmv1. Hypervisor ) (ctrl.Result , error ) {
133130 if ! meta .IsStatusConditionTrue (eviction .Status .Conditions , kvmv1 .ConditionTypePreflight ) {
134131 // Ensure the hypervisor is disabled and we have the preflight condition
135- return r .handlePreflight (ctx , eviction )
132+ return r .handlePreflight (ctx , eviction , hypervisor )
136133 }
137134
138135 // That should leave us with "Running" and the hypervisor should be deactivated
@@ -158,30 +155,22 @@ func (r *EvictionReconciler) updateStatus(ctx context.Context, eviction, base *k
158155 client.MergeFromWithOptimisticLock {}), client .FieldOwner (EvictionControllerName ))
159156}
160157
161- func (r * EvictionReconciler ) handlePreflight (ctx context.Context , eviction * kvmv1.Eviction ) (ctrl.Result , error ) {
158+ func (r * EvictionReconciler ) handlePreflight (ctx context.Context , eviction * kvmv1.Eviction , hv * kvmv1. Hypervisor ) (ctrl.Result , error ) {
162159 base := eviction .DeepCopy ()
163- hypervisorName := eviction .Spec .Hypervisor
164-
160+ expectHypervisor := HasStatusCondition (hv .Status .Conditions , kvmv1 .ConditionTypeOnboarding )
165161 // Does the hypervisor even exist? Is it enabled/disabled?
166- hypervisor , err := openstack . GetHypervisorByName (ctx , r .computeClient , hypervisorName , false )
162+ hypervisor , err := hypervisors . Get (ctx , r .computeClient , hv . Status . HypervisorID ). Extract ( )
167163 if err != nil {
168- expectHypervisor := true
169- hv := & kvmv1.Hypervisor {}
170- if err := r .Get (ctx , client.ObjectKey {Name : eviction .Spec .Hypervisor }, hv ); client .IgnoreNotFound (err ) != nil {
164+ if ! gophercloud .ResponseCodeIs (err , http .StatusNotFound ) {
171165 return ctrl.Result {}, err
172166 }
173167
174- if hv .Name != "" {
175- expectHypervisor = HasStatusCondition (hv .Status .Conditions , kvmv1 .ConditionTypeOnboarding )
176- }
177-
178168 if expectHypervisor {
179169 // Abort eviction
180- err = fmt .Errorf ("failed to get hypervisor %w" , err )
181170 meta .SetStatusCondition (& eviction .Status .Conditions , metav1.Condition {
182171 Type : kvmv1 .ConditionTypeEvicting ,
183172 Status : metav1 .ConditionFalse ,
184- Message : err . Error ( ),
173+ Message : fmt . Sprintf ( "failed to get hypervisor %v" , err ),
185174 Reason : kvmv1 .ConditionReasonFailed ,
186175 })
187176 return ctrl.Result {}, r .updateStatus (ctx , eviction , base )
@@ -201,27 +190,14 @@ func (r *EvictionReconciler) handlePreflight(ctx context.Context, eviction *kvmv
201190 }
202191 }
203192
204- log := logger .FromContext (ctx )
205- currentHypervisor , _ , _ := strings .Cut (hypervisor .HypervisorHostname , "." )
206- if currentHypervisor != hypervisorName {
207- err = fmt .Errorf ("hypervisor name %q does not match spec %q" , currentHypervisor , hypervisorName )
208- log .Error (err , "Hypervisor name mismatch" )
209- meta .SetStatusCondition (& eviction .Status .Conditions , metav1.Condition {
210- Type : kvmv1 .ConditionTypeEvicting ,
211- Status : metav1 .ConditionFalse ,
212- Message : err .Error (),
213- Reason : kvmv1 .ConditionReasonFailed ,
214- })
215- return ctrl.Result {}, r .updateStatus (ctx , eviction , base )
216- }
217-
218193 if ! meta .IsStatusConditionTrue (eviction .Status .Conditions , kvmv1 .ConditionTypeHypervisorDisabled ) {
219194 // Hypervisor is not disabled/ensured, so we need to disable it
220195 return ctrl.Result {}, r .disableHypervisor (ctx , hypervisor , eviction )
221196 }
222197
223198 // Fetch all virtual machines on the hypervisor
224- hypervisor , err = openstack .GetHypervisorByName (ctx , r .computeClient , hypervisorName , true )
199+ trueVal := true
200+ hypervisor , err = hypervisors .GetExt (ctx , r .computeClient , hv .Status .HypervisorID , hypervisors.GetOpts {WithServers : & trueVal }).Extract ()
225201 if err != nil {
226202 return ctrl.Result {}, err
227203 }
@@ -386,7 +362,7 @@ func (r *EvictionReconciler) evictionReason(eviction *kvmv1.Eviction) string {
386362 return fmt .Sprintf ("Eviction %v/%v: %v" , eviction .Namespace , eviction .Name , eviction .Spec .Reason )
387363}
388364
389- func (r * EvictionReconciler ) handleFinalizer (ctx context.Context , eviction * kvmv1.Eviction ) error {
365+ func (r * EvictionReconciler ) handleFinalizer (ctx context.Context , eviction * kvmv1.Eviction , hypervisor * kvmv1. Hypervisor ) error {
390366 if ! controllerutil .ContainsFinalizer (eviction , evictionFinalizerName ) {
391367 return nil
392368 }
@@ -395,7 +371,7 @@ func (r *EvictionReconciler) handleFinalizer(ctx context.Context, eviction *kvmv
395371 // - the hypervisor being gone, because it has been torn down
396372 // - the hypervisor having been enabled by someone else
397373 if ! meta .IsStatusConditionTrue (eviction .Status .Conditions , kvmv1 .ConditionTypeHypervisorReEnabled ) {
398- err := r .enableHypervisorService (ctx , eviction )
374+ err := r .enableHypervisorService (ctx , eviction , hypervisor )
399375 if err != nil {
400376 return err
401377 }
@@ -406,10 +382,10 @@ func (r *EvictionReconciler) handleFinalizer(ctx context.Context, eviction *kvmv
406382 return r .Patch (ctx , eviction , client .MergeFromWithOptions (base , client.MergeFromWithOptimisticLock {}))
407383}
408384
409- func (r * EvictionReconciler ) enableHypervisorService (ctx context.Context , eviction * kvmv1.Eviction ) error {
385+ func (r * EvictionReconciler ) enableHypervisorService (ctx context.Context , eviction * kvmv1.Eviction , hv * kvmv1. Hypervisor ) error {
410386 log := logger .FromContext (ctx )
411387
412- hypervisor , err := openstack . GetHypervisorByName (ctx , r .computeClient , eviction . Spec . Hypervisor , false )
388+ hypervisor , err := hypervisors . Get (ctx , r .computeClient , hv . Status . HypervisorID ). Extract ( )
413389 if err != nil {
414390 if errors .Is (err , openstack .ErrNoHypervisor ) {
415391 base := eviction .DeepCopy ()
0 commit comments