Skip to content

Commit 8539456

Browse files
committed
Refactor conditions, introduce terminating maintenance
Consolidate all condition to their respective API spec, this makes it easier and clearer for external componenets to identify condition and reason, also reuse conditions that are similar (Complated -> Successful). Also introducing a new maintenance enum value "terminating", that is set by the maintenance-operator in case the node is terminating - removing the need to monitor nodes status.
1 parent b4f14a7 commit 8539456

17 files changed

+124
-104
lines changed

api/v1/eviction_types.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@ type EvictionSpec struct {
3737
Reason string `json:"reason"`
3838
}
3939

40+
// Eviction Condition Types
41+
// type of condition in CamelCase or in foo.example.com/CamelCase.
4042
const (
4143
// ConditionTypeMigration is the type of condition for migration status of a server
4244
ConditionTypeMigration = "MigratingInstance"
@@ -52,7 +54,10 @@ const (
5254

5355
// ConditionTypeEvicting is the type of condition for eviction status
5456
ConditionTypeEvicting = "Evicting"
57+
)
5558

59+
// Condition Reasons
60+
const (
5661
// ConditionReasonRunning means the eviction is currently running
5762
ConditionReasonRunning string = "Running"
5863

api/v1/hypervisor_types.go

Lines changed: 40 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -26,23 +26,41 @@ import (
2626
// INSERT ADDITIONAL SPEC FIELDS - desired state of cluster
2727
// Important: Run "make" to regenerate code after modifying this file
2828

29+
// Hypervisor Condition Types
30+
// type of condition in CamelCase or in foo.example.com/CamelCase.
2931
const (
32+
// ConditionTypeOnboarding is the type of condition for onboarding status
33+
ConditionTypeOnboarding = "Onboarding"
34+
3035
// ConditionTypeReady is the type of condition for ready status of a hypervisor
31-
ConditionTypeReady = "Ready"
36+
ConditionTypeReady = "Ready"
37+
38+
// ConditionTypeTerminating is the type of condition for terminating status of a hypervisor
3239
ConditionTypeTerminating = "Terminating"
33-
ConditionTypeTainted = "Tainted"
3440

35-
// Reasons for the various being ready...
36-
ConditionReasonReadyReady = "ready"
37-
// or not
38-
ConditionReasonReadyMaintenance = "maintenance"
39-
ConditionReasonReadyEvicted = "evicted"
41+
// ConditionTypeTainted is the type of condition for tainted status of a hypervisor
42+
ConditionTypeTainted = "Tainted"
4043

41-
// HypervisorMaintenance "enum"
42-
MaintenanceUnset = ""
43-
MaintenanceManual = "manual"
44-
MaintenanceAuto = "auto"
45-
MaintenanceHA = "ha"
44+
// ConditionTypeTraitsUpdated is the type of condition for traits updated status of a hypervisor
45+
ConditionTypeTraitsUpdated = "TraitsUpdated"
46+
47+
// ConditionTypeAggregatesUpdated is the type of condition for aggregates updated status of a hypervisor
48+
ConditionTypeAggregatesUpdated = "AggregatesUpdated"
49+
)
50+
51+
// Condition Reasons
52+
// The value should be a CamelCase string.
53+
const (
54+
// ConditionTypeReady reasons
55+
ConditionReasonReadyReady = "Ready"
56+
ConditionReasonReadyMaintenance = "Maintenance"
57+
ConditionReasonReadyEvicted = "Evicted"
58+
59+
// ConditionTypeOnboarding reasons
60+
ConditionReasonInitial = "Initial"
61+
ConditionReasonOnboarding = "Onboarding"
62+
ConditionReasonTesting = "Testing"
63+
ConditionReasonAborted = "Aborted"
4664
)
4765

4866
// HypervisorSpec defines the desired state of Hypervisor
@@ -89,11 +107,20 @@ type HypervisorSpec struct {
89107
InstallCertificate bool `json:"installCertificate"`
90108

91109
// +kubebuilder:optional
92-
// +kubebuilder:validation:Enum:="";manual;auto;ha
110+
// +kubebuilder:validation:Enum:="";manual;auto;ha;termination
93111
// Maintenance indicates whether the hypervisor is in maintenance mode.
94112
Maintenance string `json:"maintenance,omitempty"`
95113
}
96114

115+
const (
116+
// HypervisorMaintenance "enum"
117+
MaintenanceUnset = ""
118+
MaintenanceManual = "manual" // manual maintenance mode by external user
119+
MaintenanceAuto = "auto" // automatic maintenance mode
120+
MaintenanceHA = "ha" // high availability maintenance mode
121+
MaintenanceTermination = "termination" // internal use only, when node is terminating state
122+
)
123+
97124
type Instance struct {
98125
// Represents the instance ID (uuidv4).
99126
ID string `json:"id"`

charts/openstack-hypervisor-operator/crds/hypervisor-crd.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,7 @@ spec:
149149
- manual
150150
- auto
151151
- ha
152+
- termination
152153
type: string
153154
reboot:
154155
default: false

config/crd/bases/kvm.cloud.sap_hypervisors.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,7 @@ spec:
150150
- manual
151151
- auto
152152
- ha
153+
- termination
153154
type: string
154155
reboot:
155156
default: false

internal/controller/aggregates_controller.go

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -40,10 +40,7 @@ import (
4040
)
4141

4242
const (
43-
ConditionTypeAggregatesUpdated = "AggregatesUpdated"
44-
ConditionAggregatesSuccess = "Success"
45-
ConditionAggregatesFailed = "Failed"
46-
AggregatesControllerName = "aggregates"
43+
AggregatesControllerName = "aggregates"
4744
)
4845

4946
type AggregatesController struct {
@@ -63,7 +60,7 @@ func (ac *AggregatesController) Reconcile(ctx context.Context, req ctrl.Request)
6360
}
6461

6562
/// On- and off-boarding need to mess with the aggregates, so let's get out of their way
66-
if !meta.IsStatusConditionFalse(hv.Status.Conditions, ConditionTypeOnboarding) ||
63+
if !meta.IsStatusConditionFalse(hv.Status.Conditions, kvmv1.ConditionTypeOnboarding) ||
6764
meta.IsStatusConditionTrue(hv.Status.Conditions, kvmv1.ConditionTypeTerminating) {
6865
return ctrl.Result{}, nil
6966
}
@@ -119,9 +116,9 @@ func (ac *AggregatesController) Reconcile(ctx context.Context, req ctrl.Request)
119116

120117
hv.Status.Aggregates = hv.Spec.Aggregates
121118
meta.SetStatusCondition(&hv.Status.Conditions, metav1.Condition{
122-
Type: ConditionTypeAggregatesUpdated,
119+
Type: kvmv1.ConditionTypeAggregatesUpdated,
123120
Status: metav1.ConditionTrue,
124-
Reason: ConditionAggregatesSuccess,
121+
Reason: kvmv1.ConditionReasonSucceeded,
125122
Message: "Aggregates updated successfully",
126123
})
127124
return ctrl.Result{}, ac.Status().Update(ctx, hv)
@@ -130,9 +127,9 @@ func (ac *AggregatesController) Reconcile(ctx context.Context, req ctrl.Request)
130127
// setErrorCondition sets the error condition on the Hypervisor status, returns error if update fails
131128
func (ac *AggregatesController) setErrorCondition(ctx context.Context, hv *kvmv1.Hypervisor, msg string) error {
132129
condition := metav1.Condition{
133-
Type: ConditionTypeAggregatesUpdated,
130+
Type: kvmv1.ConditionTypeAggregatesUpdated,
134131
Status: metav1.ConditionFalse,
135-
Reason: ConditionAggregatesFailed,
132+
Reason: kvmv1.ConditionReasonFailed,
136133
Message: msg,
137134
}
138135

internal/controller/aggregates_controller_test.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ var _ = Describe("AggregatesController", func() {
121121
Expect(k8sClient.Create(ctx, hypervisor)).To(Succeed())
122122
Expect(k8sClient.Get(ctx, hypervisorName, hypervisor)).To(Succeed())
123123
meta.SetStatusCondition(&hypervisor.Status.Conditions, v1.Condition{
124-
Type: ConditionTypeOnboarding,
124+
Type: kvmv1.ConditionTypeOnboarding,
125125
Status: v1.ConditionFalse,
126126
Reason: "dontcare",
127127
Message: "dontcare",
@@ -193,7 +193,7 @@ var _ = Describe("AggregatesController", func() {
193193
updated := &kvmv1.Hypervisor{}
194194
Expect(tc.Client.Get(ctx, hypervisorName, updated)).To(Succeed())
195195
Expect(updated.Status.Aggregates).To(ContainElements("test-aggregate1"))
196-
Expect(meta.IsStatusConditionTrue(updated.Status.Conditions, ConditionTypeAggregatesUpdated)).To(BeTrue())
196+
Expect(meta.IsStatusConditionTrue(updated.Status.Conditions, kvmv1.ConditionTypeAggregatesUpdated)).To(BeTrue())
197197
})
198198
})
199199

@@ -237,7 +237,7 @@ var _ = Describe("AggregatesController", func() {
237237
updated := &kvmv1.Hypervisor{}
238238
Expect(tc.Client.Get(ctx, hypervisorName, updated)).To(Succeed())
239239
Expect(updated.Status.Aggregates).To(BeEmpty())
240-
Expect(meta.IsStatusConditionTrue(updated.Status.Conditions, ConditionTypeAggregatesUpdated)).To(BeTrue())
240+
Expect(meta.IsStatusConditionTrue(updated.Status.Conditions, kvmv1.ConditionTypeAggregatesUpdated)).To(BeTrue())
241241
})
242242
})
243243

@@ -254,7 +254,7 @@ var _ = Describe("AggregatesController", func() {
254254
updated := &kvmv1.Hypervisor{}
255255
Expect(tc.Client.Get(ctx, hypervisorName, updated)).To(Succeed())
256256
Expect(updated.Status.Aggregates).To(BeEmpty())
257-
Expect(meta.IsStatusConditionTrue(updated.Status.Conditions, ConditionTypeAggregatesUpdated)).To(BeFalse())
257+
Expect(meta.IsStatusConditionTrue(updated.Status.Conditions, kvmv1.ConditionTypeAggregatesUpdated)).To(BeFalse())
258258
})
259259
})
260260

@@ -276,7 +276,7 @@ var _ = Describe("AggregatesController", func() {
276276
updated := &kvmv1.Hypervisor{}
277277
Expect(tc.Client.Get(ctx, hypervisorName, updated)).To(Succeed())
278278
Expect(updated.Status.Aggregates).To(BeEmpty())
279-
Expect(meta.IsStatusConditionTrue(updated.Status.Conditions, ConditionTypeAggregatesUpdated)).To(BeFalse())
279+
Expect(meta.IsStatusConditionTrue(updated.Status.Conditions, kvmv1.ConditionTypeAggregatesUpdated)).To(BeFalse())
280280
})
281281
})
282282
})

internal/controller/consts.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ package controller
1919

2020
// This should contain consts shared between controllers
2121
const (
22-
labelHypervisorID = "nova.openstack.cloud.sap/hypervisor-id"
2322
labelEvictionRequired = "cloud.sap/hypervisor-eviction-required"
2423
labelEvictionApproved = "cloud.sap/hypervisor-eviction-succeeded"
2524
labelHypervisor = "nova.openstack.cloud.sap/virt-driver"

internal/controller/eviction_controller.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,7 @@ func (r *EvictionReconciler) handlePreflight(ctx context.Context, eviction *kvmv
164164
}
165165

166166
if hv.Name != "" {
167-
expectHypervisor = HasStatusCondition(hv.Status.Conditions, ConditionTypeOnboarding)
167+
expectHypervisor = HasStatusCondition(hv.Status.Conditions, kvmv1.ConditionTypeOnboarding)
168168
}
169169

170170
if expectHypervisor {

internal/controller/gardener_node_lifecycle_controller.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ func (r *GardenerNodeLifecycleController) Reconcile(ctx context.Context, req ctr
101101
return ctrl.Result{}, err
102102
}
103103

104-
onboardingCompleted := meta.IsStatusConditionFalse(hv.Status.Conditions, ConditionTypeOnboarding)
104+
onboardingCompleted := meta.IsStatusConditionFalse(hv.Status.Conditions, kvmv1.ConditionTypeOnboarding)
105105

106106
if err := retry.RetryOnConflict(retry.DefaultRetry, func() error {
107107
return r.ensureSignallingDeployment(ctx, node, minAvailable, onboardingCompleted)

internal/controller/hypervisor_maintenance_controller.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ func (hec *HypervisorMaintenanceController) Reconcile(ctx context.Context, req c
6363
}
6464

6565
// is onboarding completed?
66-
if !meta.IsStatusConditionFalse(hv.Status.Conditions, ConditionTypeOnboarding) {
66+
if !meta.IsStatusConditionFalse(hv.Status.Conditions, kvmv1.ConditionTypeOnboarding) {
6767
return ctrl.Result{}, nil
6868
}
6969

@@ -120,7 +120,7 @@ func (hec *HypervisorMaintenanceController) reconcileComputeService(ctx context.
120120
if err != nil {
121121
return fmt.Errorf("failed to enable hypervisor due to %w", err)
122122
}
123-
case kvmv1.MaintenanceManual, kvmv1.MaintenanceAuto, kvmv1.MaintenanceHA:
123+
case kvmv1.MaintenanceManual, kvmv1.MaintenanceAuto, kvmv1.MaintenanceHA, kvmv1.MaintenanceTermination:
124124
// Disable the compute service:
125125
// Also in case of HA, as it doesn't hurt to disable it twice, and this
126126
// allows us to enable the service again, when the maintenance field is
@@ -173,7 +173,7 @@ func (hec *HypervisorMaintenanceController) reconcileEviction(ctx context.Contex
173173
return err
174174
}
175175
return nil
176-
case kvmv1.MaintenanceManual, kvmv1.MaintenanceAuto:
176+
case kvmv1.MaintenanceManual, kvmv1.MaintenanceAuto, kvmv1.MaintenanceTermination:
177177
// In case of "ha", the host gets emptied from the HA service
178178
if cond := meta.FindStatusCondition(hv.Status.Conditions, kvmv1.ConditionTypeEvicting); cond != nil {
179179
if cond.Reason == kvmv1.ConditionReasonSucceeded {

0 commit comments

Comments
 (0)