@@ -6,6 +6,9 @@ package controllers
6
6
7
7
import (
8
8
"context"
9
+ "reflect"
10
+
11
+ cabptv1 "github.com/siderolabs/cluster-api-bootstrap-provider-talos/api/v1alpha3"
9
12
10
13
"github.com/go-logr/logr"
11
14
"github.com/pkg/errors"
@@ -30,6 +33,7 @@ type ControlPlane struct {
30
33
Machines collections.Machines
31
34
32
35
infraObjects map [string ]* unstructured.Unstructured
36
+ talosConfigs map [string ]* cabptv1.TalosConfig
33
37
}
34
38
35
39
// newControlPlane returns an instantiated ControlPlane.
@@ -39,11 +43,17 @@ func newControlPlane(ctx context.Context, client client.Client, cluster *cluster
39
43
return nil , err
40
44
}
41
45
46
+ talosConfigs , err := getTalosConfigs (ctx , client , machines )
47
+ if err != nil {
48
+ return nil , err
49
+ }
50
+
42
51
return & ControlPlane {
43
52
TCP : tcp ,
44
53
Cluster : cluster ,
45
54
Machines : machines ,
46
55
infraObjects : infraObjects ,
56
+ talosConfigs : talosConfigs ,
47
57
}, nil
48
58
}
49
59
@@ -76,6 +86,7 @@ func (c *ControlPlane) MachinesNeedingRollout() collections.Machines {
76
86
collections .And (
77
87
collections .MatchesKubernetesVersion (c .TCP .Spec .Version ),
78
88
MatchesTemplateClonedFrom (c .infraObjects , c .TCP ),
89
+ MatchesControlPlaneConfig (c .talosConfigs , c .TCP ),
79
90
),
80
91
),
81
92
)
@@ -97,6 +108,35 @@ func getInfraResources(ctx context.Context, cl client.Client, machines collectio
97
108
return result , nil
98
109
}
99
110
111
+ // getTalosConfigs fetches the TalosConfigs for each machine in the collection and returns a map of machine.Name -> TalosConfig.
112
+ func getTalosConfigs (ctx context.Context , cl client.Client , machines collections.Machines ) (map [string ]* cabptv1.TalosConfig , error ) {
113
+ result := map [string ]* cabptv1.TalosConfig {}
114
+
115
+ for _ , m := range machines {
116
+ bootstrapRef := m .Spec .Bootstrap .ConfigRef
117
+ if bootstrapRef == nil {
118
+ continue
119
+ }
120
+
121
+ talosconfig := & cabptv1.TalosConfig {}
122
+
123
+ err := cl .Get (ctx , client.ObjectKey {
124
+ Namespace : m .Namespace ,
125
+ Name : bootstrapRef .Name ,
126
+ }, talosconfig )
127
+ if err != nil {
128
+ if apierrors .IsNotFound (errors .Cause (err )) {
129
+ continue
130
+ }
131
+ return nil , errors .Wrapf (err , "failed to retrieve talosconfig obj for machine %q" , m .Name )
132
+ }
133
+
134
+ result [m .Name ] = talosconfig
135
+ }
136
+
137
+ return result , nil
138
+ }
139
+
100
140
// MatchesTemplateClonedFrom returns a filter to find all machines that match a given TCP infra template.
101
141
func MatchesTemplateClonedFrom (infraConfigs map [string ]* unstructured.Unstructured , tcp * controlplanev1.TalosControlPlane ) collections.Func {
102
142
return func (machine * clusterv1.Machine ) bool {
@@ -127,3 +167,20 @@ func MatchesTemplateClonedFrom(infraConfigs map[string]*unstructured.Unstructure
127
167
return true
128
168
}
129
169
}
170
+
171
+ // MatchesControlPlaneConfig returns a filter to find all machines that match a given controlPaneConfig.
172
+ func MatchesControlPlaneConfig (talosConfigs map [string ]* cabptv1.TalosConfig , tcp * controlplanev1.TalosControlPlane ) collections.Func {
173
+ return func (machine * clusterv1.Machine ) bool {
174
+ if machine == nil {
175
+ return false
176
+ }
177
+
178
+ talosConfig , found := talosConfigs [machine .Name ]
179
+ if ! found {
180
+ // Return true here because failing to get talosconfig should not be considered as unmatching.
181
+ return true
182
+ }
183
+
184
+ return reflect .DeepEqual (tcp .Spec .ControlPlaneConfig .ControlPlaneConfig , talosConfig .Spec )
185
+ }
186
+ }
0 commit comments