@@ -18,6 +18,7 @@ package controllers
1818
1919import (
2020 "context"
21+ "encoding/json"
2122 "strings"
2223
2324 "github.com/pkg/errors"
@@ -33,6 +34,7 @@ import (
3334 controlplanev1 "sigs.k8s.io/cluster-api/controlplane/kubeadm/api/v1alpha3"
3435 "sigs.k8s.io/cluster-api/controlplane/kubeadm/internal"
3536 "sigs.k8s.io/cluster-api/controlplane/kubeadm/internal/hash"
37+ "sigs.k8s.io/cluster-api/controlplane/kubeadm/internal/machinefilters"
3638 capierrors "sigs.k8s.io/cluster-api/errors"
3739 "sigs.k8s.io/cluster-api/util"
3840 "sigs.k8s.io/cluster-api/util/certs"
@@ -241,8 +243,36 @@ func (r *KubeadmControlPlaneReconciler) generateMachine(ctx context.Context, kcp
241243 },
242244 }
243245
246+ // Machine's bootstrap config may be missing ClusterConfiguration if it is not the first machine in the control plane.
247+ // We store ClusterConfiguration as annotation here to detect any changes in KCP ClusterConfiguration and rollout the machine if any.
248+ clusterConfig , err := json .Marshal (kcp .Spec .KubeadmConfigSpec .ClusterConfiguration )
249+ if err != nil {
250+ return errors .Wrap (err , "failed to marshal cluster configuration" )
251+ }
252+ machine .SetAnnotations (map [string ]string {controlplanev1 .KubeadmClusterConfigurationAnnotation : string (clusterConfig )})
253+
244254 if err := r .Client .Create (ctx , machine ); err != nil {
245- return errors .Wrap (err , "Failed to create machine" )
255+ return errors .Wrap (err , "failed to create machine" )
246256 }
247257 return nil
248258}
259+
260+ // machinesNeedingRollout return a list of machines that need to be rolled out.
261+ func (r * KubeadmControlPlaneReconciler ) machinesNeedingRollout (ctx context.Context , c * internal.ControlPlane ) internal.FilterableMachineCollection {
262+ now := metav1 .Now ()
263+
264+ // Ignore machines to be deleted.
265+ machines := c .Machines .Filter (machinefilters .Not (machinefilters .HasDeletionTimestamp ))
266+
267+ // Return machines if their creation timestamp is older than the KCP.Spec.UpgradeAfter, or any machine with an outdated configuration.
268+ if c .KCP .Spec .UpgradeAfter != nil && c .KCP .Spec .UpgradeAfter .Before (& now ) {
269+ return machines .Filter (machinefilters .Or (
270+ // Machines that are old.
271+ machinefilters .OlderThan (c .KCP .Spec .UpgradeAfter ),
272+ // Machines that do not match with KCP config.
273+ machinefilters .Not (machinefilters .MatchesKCPConfiguration (ctx , r .Client , * c .KCP , * c .Cluster )),
274+ ))
275+ }
276+
277+ return machines .Filter (machinefilters .Not (machinefilters .MatchesKCPConfiguration (ctx , r .Client , * c .KCP , * c .Cluster )))
278+ }
0 commit comments