@@ -163,109 +163,88 @@ func matchesKubeadmConfig(kubeadmConfigs map[string]*bootstrapv1.KubeadmConfig,
163
163
return "" , true , nil
164
164
}
165
165
166
- // Check if KCP and machine ClusterConfiguration matches, if not return
167
- match , diff , err := matchClusterConfiguration (currentKubeadmConfig , kcp )
166
+ // takes the KubeadmConfigSpec from KCP and applies the transformations required
167
+ // to allow a comparison with the KubeadmConfig referenced from the machine.
168
+ desiredKubeadmConfig := getAdjustedKcpConfig (kcp , currentKubeadmConfig )
169
+
170
+ desiredKubeadmConfigForDiff , currentKubeadmConfigForDiff , err := PrepareKubeadmConfigsForDiff (desiredKubeadmConfig , currentKubeadmConfig , kcp )
168
171
if err != nil {
169
172
return "" , false , errors .Wrapf (err , "failed to match KubeadmConfig" )
170
173
}
171
- if ! match {
172
- return fmt .Sprintf ("Machine KubeadmConfig ClusterConfiguration is outdated: diff: %s" , diff ), false , nil
173
- }
174
174
175
- // Check if KCP and machine InitConfiguration or JoinConfiguration matches
175
+ // Check if current and desired KubeadmConfigs match.
176
176
// NOTE: only one between init configuration and join configuration is set on a machine, depending
177
177
// on the fact that the machine was the initial control plane node or a joining control plane node.
178
- match , diff , err = matchInitOrJoinConfiguration ( currentKubeadmConfig , kcp )
178
+ match , diff , err := compare . Diff ( & currentKubeadmConfigForDiff . Spec , & desiredKubeadmConfigForDiff . Spec )
179
179
if err != nil {
180
180
return "" , false , errors .Wrapf (err , "failed to match KubeadmConfig" )
181
181
}
182
182
if ! match {
183
- return fmt .Sprintf ("Machine KubeadmConfig InitConfiguration or JoinConfiguration are outdated: diff: %s" , diff ), false , nil
183
+ return fmt .Sprintf ("Machine KubeadmConfig is outdated: diff: %s" , diff ), false , nil
184
184
}
185
185
186
186
return "" , true , nil
187
187
}
188
188
189
- // matchClusterConfiguration verifies if KCP and machine ClusterConfiguration matches.
190
- func matchClusterConfiguration (machineConfig * bootstrapv1.KubeadmConfig , kcp * controlplanev1.KubeadmControlPlane ) (bool , string , error ) {
191
- if machineConfig == nil {
192
- // Return true here because failing to get KubeadmConfig should not be considered as unmatching.
193
- // This is a safety precaution to avoid rolling out machines if the client or the api-server is misbehaving.
194
- return true , "" , nil
195
- }
196
- machineConfig = machineConfig .DeepCopy ()
197
-
198
- kcpLocalKubeadmConfig := kcp .Spec .KubeadmConfigSpec .DeepCopy ()
199
- if kcpLocalKubeadmConfig == nil {
200
- kcpLocalKubeadmConfig = & bootstrapv1.KubeadmConfigSpec {}
201
- }
189
+ // PrepareKubeadmConfigsForDiff cleans up all fields that are not relevant for the comparison.
190
+ func PrepareKubeadmConfigsForDiff (desiredKubeadmConfig , currentKubeadmConfig * bootstrapv1.KubeadmConfig , kcp * controlplanev1.KubeadmControlPlane ) (desired * bootstrapv1.KubeadmConfig , current * bootstrapv1.KubeadmConfig , _ error ) {
191
+ // DeepCopy to ensure the passed in KubeadmConfigs are not modified.
192
+ // This has to be done because we eventually want to be able to apply the desiredKubeadmConfig
193
+ // (without the modifications that we make here).
194
+ desiredKubeadmConfig = desiredKubeadmConfig .DeepCopy ()
195
+ currentKubeadmConfig = currentKubeadmConfig .DeepCopy ()
202
196
203
197
// Default feature gates like in initializeControlPlane / scaleUpControlPlane.
204
198
// Note: Changes in feature gates can still trigger rollouts.
205
199
// TODO(in-place) refactor this area so the desired KubeadmConfig is not computed in multiple places independently.
206
200
parsedVersion , err := semver .ParseTolerant (kcp .Spec .Version )
207
201
if err != nil {
208
- return false , "" , errors .Wrapf (err , "failed to parse Kubernetes version %q" , kcp .Spec .Version )
202
+ return nil , nil , errors .Wrapf (err , "failed to parse Kubernetes version %q" , kcp .Spec .Version )
209
203
}
210
- DefaultFeatureGates (kcpLocalKubeadmConfig , parsedVersion )
204
+ DefaultFeatureGates (& desiredKubeadmConfig . Spec , parsedVersion )
211
205
212
206
// Ignore ControlPlaneEndpoint which is added on the Machine KubeadmConfig by CABPK.
213
207
// Note: ControlPlaneEndpoint should also never change for a Cluster, so no reason to trigger a rollout because of that.
214
- machineConfig .Spec .ClusterConfiguration .ControlPlaneEndpoint = kcpLocalKubeadmConfig .ClusterConfiguration .ControlPlaneEndpoint
208
+ currentKubeadmConfig .Spec .ClusterConfiguration .ControlPlaneEndpoint = desiredKubeadmConfig . Spec .ClusterConfiguration .ControlPlaneEndpoint
215
209
216
210
// Skip checking DNS fields because we can update the configuration of the working cluster in place.
217
- machineConfig .Spec .ClusterConfiguration .DNS = kcpLocalKubeadmConfig .ClusterConfiguration .DNS
218
-
219
- // Drop differences that do not lead to changes to Machines, but that might exist due
220
- // to changes in how we serialize objects or how webhooks work.
221
- dropOmittableFields (kcpLocalKubeadmConfig )
222
- dropOmittableFields (& machineConfig .Spec )
223
-
224
- // Compare and return.
225
- match , diff , err := compare .Diff (machineConfig .Spec .ClusterConfiguration , kcpLocalKubeadmConfig .ClusterConfiguration )
226
- if err != nil {
227
- return false , "" , errors .Wrapf (err , "failed to match ClusterConfiguration" )
228
- }
229
- return match , diff , nil
230
- }
231
-
232
- // matchInitOrJoinConfiguration verifies if KCP and machine InitConfiguration or JoinConfiguration matches.
233
- // NOTE: By extension this method takes care of detecting changes in other fields of the KubeadmConfig configuration (e.g. Files, Mounts etc.)
234
- func matchInitOrJoinConfiguration (machineConfig * bootstrapv1.KubeadmConfig , kcp * controlplanev1.KubeadmControlPlane ) (bool , string , error ) {
235
- if machineConfig == nil {
236
- // Return true here because failing to get KubeadmConfig should not be considered as unmatching.
237
- // This is a safety precaution to avoid rolling out machines if the client or the api-server is misbehaving.
238
- return true , "" , nil
239
- }
240
- machineConfig = machineConfig .DeepCopy ()
241
-
242
- // takes the KubeadmConfigSpec from KCP and applies the transformations required
243
- // to allow a comparison with the KubeadmConfig referenced from the machine.
244
- kcpConfig := getAdjustedKcpConfig (kcp , machineConfig )
211
+ currentKubeadmConfig .Spec .ClusterConfiguration .DNS = desiredKubeadmConfig .Spec .ClusterConfiguration .DNS
245
212
246
213
// Default both KubeadmConfigSpecs before comparison.
247
214
// *Note* This assumes that newly added default values never
248
215
// introduce a semantic difference to the unset value.
249
216
// But that is something that is ensured by our API guarantees.
250
- defaulting .ApplyPreviousKubeadmConfigDefaults (kcpConfig )
251
- defaulting .ApplyPreviousKubeadmConfigDefaults (& machineConfig .Spec )
217
+ defaulting .ApplyPreviousKubeadmConfigDefaults (& desiredKubeadmConfig . Spec )
218
+ defaulting .ApplyPreviousKubeadmConfigDefaults (& currentKubeadmConfig .Spec )
252
219
253
- // Cleanup all fields that are not relevant for the comparison.
254
- cleanupConfigFields (kcpConfig , machineConfig )
220
+ // Cleanup JoinConfiguration.Discovery from desiredKubeadmConfig and currentKubeadmConfig, because those info are relevant only for
221
+ // the join process and not for comparing the configuration of the machine.
222
+ // Note: Changes to Discovery will apply for the next join, but they will not lead to a rollout.
223
+ // Note: We should also not send Discovery.BootstrapToken.Token to a RuntimeExtension for security reasons.
224
+ desiredKubeadmConfig .Spec .JoinConfiguration .Discovery = bootstrapv1.Discovery {}
225
+ currentKubeadmConfig .Spec .JoinConfiguration .Discovery = bootstrapv1.Discovery {}
255
226
256
- // Compare and return.
257
- match , diff , err := compare .Diff (& machineConfig .Spec , kcpConfig )
258
- if err != nil {
259
- return false , "" , errors .Wrapf (err , "failed to match InitConfiguration or JoinConfiguration" )
227
+ // If KCP JoinConfiguration.ControlPlane is nil and the Machine JoinConfiguration.ControlPlane is empty,
228
+ // set Machine JoinConfiguration.ControlPlane to nil.
229
+ // NOTE: This is required because CABPK applies an empty JoinConfiguration.ControlPlane in case it is nil.
230
+ if desiredKubeadmConfig .Spec .JoinConfiguration .ControlPlane == nil &&
231
+ reflect .DeepEqual (currentKubeadmConfig .Spec .JoinConfiguration .ControlPlane , & bootstrapv1.JoinControlPlane {}) {
232
+ currentKubeadmConfig .Spec .JoinConfiguration .ControlPlane = nil
260
233
}
261
- return match , diff , nil
234
+
235
+ // Drop differences that do not lead to changes to Machines, but that might exist due
236
+ // to changes in how we serialize objects or how webhooks work.
237
+ dropOmittableFields (& desiredKubeadmConfig .Spec )
238
+ dropOmittableFields (& currentKubeadmConfig .Spec )
239
+
240
+ return desiredKubeadmConfig , currentKubeadmConfig , nil
262
241
}
263
242
264
243
// getAdjustedKcpConfig takes the KubeadmConfigSpec from KCP and applies the transformations required
265
244
// to allow a comparison with the KubeadmConfig referenced from the machine.
266
245
// NOTE: The KCP controller applies a set of transformations when creating a KubeadmConfig referenced from the machine;
267
246
// those transformations are implemented in ControlPlane.InitialControlPlaneConfig() and ControlPlane.JoinControlPlaneConfig().
268
- func getAdjustedKcpConfig (kcp * controlplanev1.KubeadmControlPlane , machineConfig * bootstrapv1.KubeadmConfig ) * bootstrapv1.KubeadmConfigSpec {
247
+ func getAdjustedKcpConfig (kcp * controlplanev1.KubeadmControlPlane , machineConfig * bootstrapv1.KubeadmConfig ) * bootstrapv1.KubeadmConfig {
269
248
kcpConfig := kcp .Spec .KubeadmConfigSpec .DeepCopy ()
270
249
271
250
// if Machine's JoinConfiguration is set, this is a joining control plane machine, so empty out the InitConfiguration;
@@ -278,36 +257,7 @@ func getAdjustedKcpConfig(kcp *controlplanev1.KubeadmControlPlane, machineConfig
278
257
kcpConfig .JoinConfiguration = bootstrapv1.JoinConfiguration {}
279
258
}
280
259
281
- return kcpConfig
282
- }
283
-
284
- // cleanupConfigFields cleanups all the fields that are not relevant for the comparison.
285
- // Note: This function assumes that old defaults have been applied to kcpConfig and machineConfig
286
- // as a consequence we can assume JoinConfiguration and JoinConfiguration.NodeRegistration are always defined.
287
- func cleanupConfigFields (kcpConfig * bootstrapv1.KubeadmConfigSpec , machineConfig * bootstrapv1.KubeadmConfig ) {
288
- // KCP ClusterConfiguration will be compared in `matchClusterConfiguration` so we are cleaning it up here
289
- // so it doesn't lead to a duplicate diff in `matchInitOrJoinConfiguration`.
290
- kcpConfig .ClusterConfiguration = bootstrapv1.ClusterConfiguration {}
291
- machineConfig .Spec .ClusterConfiguration = bootstrapv1.ClusterConfiguration {}
292
-
293
- // Cleanup JoinConfiguration.Discovery from kcpConfig and machineConfig, because those info are relevant only for
294
- // the join process and not for comparing the configuration of the machine.
295
- // Note: Changes to Discovery will apply for the next join, but they will not lead to a rollout.
296
- kcpConfig .JoinConfiguration .Discovery = bootstrapv1.Discovery {}
297
- machineConfig .Spec .JoinConfiguration .Discovery = bootstrapv1.Discovery {}
298
-
299
- // If KCP JoinConfiguration.ControlPlane is nil and the Machine JoinConfiguration.ControlPlane is empty,
300
- // set Machine JoinConfiguration.ControlPlane to nil.
301
- // NOTE: This is required because CABPK applies an empty JoinConfiguration.ControlPlane in case it is nil.
302
- if kcpConfig .JoinConfiguration .ControlPlane == nil &&
303
- reflect .DeepEqual (machineConfig .Spec .JoinConfiguration .ControlPlane , & bootstrapv1.JoinControlPlane {}) {
304
- machineConfig .Spec .JoinConfiguration .ControlPlane = nil
305
- }
306
-
307
- // Drop differences that do not lead to changes to Machines, but that might exist due
308
- // to changes in how we serialize objects or how webhooks work.
309
- dropOmittableFields (kcpConfig )
310
- dropOmittableFields (& machineConfig .Spec )
260
+ return & bootstrapv1.KubeadmConfig {Spec : * kcpConfig }
311
261
}
312
262
313
263
// dropOmittableFields makes the comparison tolerant to omittable fields being set in the go struct. It applies to:
0 commit comments