@@ -42,11 +42,6 @@ import (
42
42
// updateV1Beta1Status is called after every reconciliation loop in a defer statement to always make sure we have the
43
43
// KubeadmControlPlane status up-to-date.
44
44
func (r * KubeadmControlPlaneReconciler ) updateV1Beta1Status (ctx context.Context , controlPlane * internal.ControlPlane ) error {
45
- selector := collections .ControlPlaneSelectorForCluster (controlPlane .Cluster .Name )
46
- // Copy label selector to its status counterpart in string format.
47
- // This is necessary for CRDs including scale subresources.
48
- controlPlane .KCP .Status .Selector = selector .String ()
49
-
50
45
upToDateMachines := controlPlane .UpToDateMachines ()
51
46
if controlPlane .KCP .Status .Deprecated == nil {
52
47
controlPlane .KCP .Status .Deprecated = & controlplanev1.KubeadmControlPlaneDeprecatedStatus {}
@@ -60,7 +55,6 @@ func (r *KubeadmControlPlaneReconciler) updateV1Beta1Status(ctx context.Context,
60
55
desiredReplicas := * controlPlane .KCP .Spec .Replicas
61
56
62
57
// set basic data that does not require interacting with the workload cluster
63
- controlPlane .KCP .Status .Replicas = replicas
64
58
controlPlane .KCP .Status .Deprecated .V1Beta1 .ReadyReplicas = 0
65
59
controlPlane .KCP .Status .Deprecated .V1Beta1 .UnavailableReplicas = replicas
66
60
@@ -70,11 +64,6 @@ func (r *KubeadmControlPlaneReconciler) updateV1Beta1Status(ctx context.Context,
70
64
return nil
71
65
}
72
66
73
- lowestVersion := controlPlane .Machines .LowestVersion ()
74
- if lowestVersion != nil {
75
- controlPlane .KCP .Status .Version = lowestVersion
76
- }
77
-
78
67
switch {
79
68
// We are scaling up
80
69
case replicas < desiredReplicas :
@@ -109,51 +98,17 @@ func (r *KubeadmControlPlaneReconciler) updateV1Beta1Status(ctx context.Context,
109
98
controlPlane .KCP .Status .Deprecated .V1Beta1 .ReadyReplicas = status .ReadyNodes
110
99
controlPlane .KCP .Status .Deprecated .V1Beta1 .UnavailableReplicas = replicas - status .ReadyNodes
111
100
112
- // This only gets initialized once and does not change if the kubeadm config map goes away.
113
101
if status .HasKubeadmConfig {
114
- if controlPlane .KCP .Status .Initialization == nil {
115
- controlPlane .KCP .Status .Initialization = & controlplanev1.KubeadmControlPlaneInitializationStatus {}
116
- }
117
- controlPlane .KCP .Status .Initialization .ControlPlaneInitialized = true
118
102
v1beta1conditions .MarkTrue (controlPlane .KCP , controlplanev1 .AvailableV1Beta1Condition )
119
103
}
120
-
121
- // Surface lastRemediation data in status.
122
- // LastRemediation is the remediation currently in progress, in any, or the
123
- // most recent of the remediation we are keeping track on machines.
124
- var lastRemediation * RemediationData
125
-
126
- if v , ok := controlPlane .KCP .Annotations [controlplanev1 .RemediationInProgressAnnotation ]; ok {
127
- remediationData , err := RemediationDataFromAnnotation (v )
128
- if err != nil {
129
- return err
130
- }
131
- lastRemediation = remediationData
132
- } else {
133
- for _ , m := range controlPlane .Machines .UnsortedList () {
134
- if v , ok := m .Annotations [controlplanev1 .RemediationForAnnotation ]; ok {
135
- remediationData , err := RemediationDataFromAnnotation (v )
136
- if err != nil {
137
- return err
138
- }
139
- if lastRemediation == nil || lastRemediation .Timestamp .Time .Before (remediationData .Timestamp .Time ) {
140
- lastRemediation = remediationData
141
- }
142
- }
143
- }
144
- }
145
-
146
- if lastRemediation != nil {
147
- controlPlane .KCP .Status .LastRemediation = lastRemediation .ToStatus ()
148
- }
149
104
return nil
150
105
}
151
106
152
107
// updateStatus reconciles KubeadmControlPlane's status during the entire lifecycle of the object.
153
- func (r * KubeadmControlPlaneReconciler ) updateStatus (ctx context.Context , controlPlane * internal.ControlPlane ) {
108
+ func (r * KubeadmControlPlaneReconciler ) updateStatus (ctx context.Context , controlPlane * internal.ControlPlane ) error {
154
109
// If the code failed initializing the control plane, do not update the status.
155
110
if controlPlane == nil {
156
- return
111
+ return nil
157
112
}
158
113
159
114
// Note: some of the status is set on reconcileControlPlaneAndMachinesConditions (EtcdClusterHealthy, ControlPlaneComponentsHealthy conditions),
@@ -163,6 +118,20 @@ func (r *KubeadmControlPlaneReconciler) updateStatus(ctx context.Context, contro
163
118
// Note: KCP also sets status on machines in reconcileUnhealthyMachines and reconcileControlPlaneAndMachinesConditions; if for
164
119
// any reason those functions are not called before, e.g. an error, this func relies on existing Machine's condition.
165
120
121
+ // Copy label selector to its status counterpart in string format.
122
+ // This is necessary for CRDs including scale subresources.
123
+ selector := collections .ControlPlaneSelectorForCluster (controlPlane .Cluster .Name )
124
+ controlPlane .KCP .Status .Selector = selector .String ()
125
+
126
+ // Set status.version with the lowest K8s version from CP machines.
127
+ lowestVersion := controlPlane .Machines .LowestVersion ()
128
+ if lowestVersion != nil {
129
+ controlPlane .KCP .Status .Version = lowestVersion
130
+ }
131
+
132
+ if err := setControlPlaneInitialized (ctx , controlPlane ); err != nil {
133
+ return err
134
+ }
166
135
setReplicas (ctx , controlPlane .KCP , controlPlane .Machines )
167
136
setInitializedCondition (ctx , controlPlane .KCP )
168
137
setRollingOutCondition (ctx , controlPlane .KCP , controlPlane .Machines )
@@ -173,6 +142,32 @@ func (r *KubeadmControlPlaneReconciler) updateStatus(ctx context.Context, contro
173
142
setRemediatingCondition (ctx , controlPlane .KCP , controlPlane .MachinesToBeRemediatedByKCP (), controlPlane .UnhealthyMachines ())
174
143
setDeletingCondition (ctx , controlPlane .KCP , controlPlane .DeletingReason , controlPlane .DeletingMessage )
175
144
setAvailableCondition (ctx , controlPlane .KCP , controlPlane .IsEtcdManaged (), controlPlane .EtcdMembers , controlPlane .EtcdMembersAndMachinesAreMatching , controlPlane .Machines )
145
+ return setLastRemediation (ctx , controlPlane )
146
+ }
147
+
148
+ // setControlPlaneInitialized surface control plane initialized when it is possible to check that the Kubeadm config exists in the workload cluster;
149
+ // this is considered a proxy information about the API Server being up and running and kubeadm init successfully completed.
150
+ // Note: This only gets initialized once and does not change if the kubeadm config map goes away.
151
+ func setControlPlaneInitialized (ctx context.Context , controlPlane * internal.ControlPlane ) error {
152
+ if controlPlane .KCP .Status .Initialization == nil || ! controlPlane .KCP .Status .Initialization .ControlPlaneInitialized {
153
+ workloadCluster , err := controlPlane .GetWorkloadCluster (ctx )
154
+ if err != nil {
155
+ return errors .Wrap (err , "failed to create remote cluster client" )
156
+ }
157
+ status , err := workloadCluster .ClusterStatus (ctx )
158
+ if err != nil {
159
+ return err
160
+ }
161
+
162
+ if status .HasKubeadmConfig {
163
+ if controlPlane .KCP .Status .Initialization == nil {
164
+ controlPlane .KCP .Status .Initialization = & controlplanev1.KubeadmControlPlaneInitializationStatus {}
165
+ }
166
+ controlPlane .KCP .Status .Initialization .ControlPlaneInitialized = true
167
+ v1beta1conditions .MarkTrue (controlPlane .KCP , controlplanev1 .AvailableV1Beta1Condition )
168
+ }
169
+ }
170
+ return nil
176
171
}
177
172
178
173
func setReplicas (_ context.Context , kcp * controlplanev1.KubeadmControlPlane , machines collections.Machines ) {
@@ -189,6 +184,7 @@ func setReplicas(_ context.Context, kcp *controlplanev1.KubeadmControlPlane, mac
189
184
}
190
185
}
191
186
187
+ kcp .Status .Replicas = int32 (len (machines ))
192
188
kcp .Status .ReadyReplicas = ptr .To (readyReplicas )
193
189
kcp .Status .AvailableReplicas = ptr .To (availableReplicas )
194
190
kcp .Status .UpToDateReplicas = ptr .To (upToDateReplicas )
@@ -768,6 +764,38 @@ func setAvailableCondition(_ context.Context, kcp *controlplanev1.KubeadmControl
768
764
})
769
765
}
770
766
767
+ // setLastRemediation surface lastRemediation data in status.
768
+ // LastRemediation is the remediation currently in progress, in any, or the
769
+ // most recent of the remediation we are keeping track on machines.
770
+ func setLastRemediation (_ context.Context , controlPlane * internal.ControlPlane ) error {
771
+ var lastRemediation * RemediationData
772
+
773
+ if v , ok := controlPlane .KCP .Annotations [controlplanev1 .RemediationInProgressAnnotation ]; ok {
774
+ remediationData , err := RemediationDataFromAnnotation (v )
775
+ if err != nil {
776
+ return err
777
+ }
778
+ lastRemediation = remediationData
779
+ } else {
780
+ for _ , m := range controlPlane .Machines .UnsortedList () {
781
+ if v , ok := m .Annotations [controlplanev1 .RemediationForAnnotation ]; ok {
782
+ remediationData , err := RemediationDataFromAnnotation (v )
783
+ if err != nil {
784
+ return err
785
+ }
786
+ if lastRemediation == nil || lastRemediation .Timestamp .Time .Before (remediationData .Timestamp .Time ) {
787
+ lastRemediation = remediationData
788
+ }
789
+ }
790
+ }
791
+ }
792
+
793
+ if lastRemediation != nil {
794
+ controlPlane .KCP .Status .LastRemediation = lastRemediation .ToStatus ()
795
+ }
796
+ return nil
797
+ }
798
+
771
799
// shouldSurfaceWhenAvailableTrue defines when a control plane components/etcd issue should surface when
772
800
// Available condition is true.
773
801
// The main goal of this check is to avoid to surface false negatives/flakes, and thus it requires that
0 commit comments