@@ -27,16 +27,20 @@ import (
2727 corev1 "k8s.io/api/core/v1"
2828 apierrors "k8s.io/apimachinery/pkg/api/errors"
2929 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
30+ "k8s.io/apimachinery/pkg/labels"
3031 "k8s.io/utils/ptr"
3132 clusterv1 "sigs.k8s.io/cluster-api/api/v1beta1"
3233 capierrors "sigs.k8s.io/cluster-api/errors" //nolint:staticcheck
3334 "sigs.k8s.io/cluster-api/util"
3435 "sigs.k8s.io/cluster-api/util/annotations"
3536 "sigs.k8s.io/cluster-api/util/conditions"
3637 "sigs.k8s.io/cluster-api/util/patch"
38+ "sigs.k8s.io/cluster-api/util/predicates"
3739 ctrl "sigs.k8s.io/controller-runtime"
40+ "sigs.k8s.io/controller-runtime/pkg/builder"
3841 "sigs.k8s.io/controller-runtime/pkg/client"
3942 "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
43+ "sigs.k8s.io/controller-runtime/pkg/handler"
4044 ctrllog "sigs.k8s.io/controller-runtime/pkg/log"
4145
4246 "github.com/go-logr/logr"
@@ -178,9 +182,145 @@ func (r *MetalStackMachineReconciler) SetupWithManager(mgr ctrl.Manager) error {
178182 return ctrl .NewControllerManagedBy (mgr ).
179183 For (& v1alpha1.MetalStackMachine {}).
180184 Named ("metalstackmachine" ).
185+ WithEventFilter (predicates .ResourceIsNotExternallyManaged (mgr .GetScheme (), mgr .GetLogger ())).
186+ WithEventFilter (predicates .ResourceNotPaused (mgr .GetScheme (), mgr .GetLogger ())).
187+ Watches (
188+ & clusterv1.Cluster {},
189+ handler .EnqueueRequestsFromMapFunc (r .clusterToMetalStackMachine (mgr .GetLogger ())),
190+ builder .WithPredicates (predicates .ClusterUnpaused (mgr .GetScheme (), mgr .GetLogger ())),
191+ ).
192+ Watches (
193+ & v1alpha1.MetalStackCluster {},
194+ handler .EnqueueRequestsFromMapFunc (r .metalStackClusterToMetalStackMachine (mgr .GetLogger ())),
195+ builder .WithPredicates (predicates .ResourceNotPaused (mgr .GetScheme (), mgr .GetLogger ())),
196+ ).
197+ Watches (
198+ & clusterv1.Machine {},
199+ handler .EnqueueRequestsFromMapFunc (r .machineToMetalStackMachine (mgr .GetLogger ())),
200+ builder .WithPredicates (predicates .ResourceNotPaused (mgr .GetScheme (), mgr .GetLogger ())),
201+ ).
181202 Complete (r )
182203}
183204
205+ func (r * MetalStackMachineReconciler ) clusterToMetalStackMachine (log logr.Logger ) handler.MapFunc {
206+ return func (ctx context.Context , o client.Object ) []ctrl.Request {
207+ cluster , ok := o .(* clusterv1.Cluster )
208+ if ! ok {
209+ log .Error (fmt .Errorf ("expected a cluster, got %T" , o ), "failed to get cluster" , "object" , o )
210+ return nil
211+ }
212+
213+ log := log .WithValues ("cluster" , cluster .Name , "namespace" , cluster .Namespace )
214+
215+ infraMachineList := & v1alpha1.MetalStackMachineList {}
216+ err := r .Client .List (ctx , infraMachineList , & client.ListOptions {
217+ Namespace : cluster .Namespace ,
218+ LabelSelector : labels .SelectorFromSet (labels.Set {
219+ clusterv1 .ClusterNameLabel : cluster .Name ,
220+ }),
221+ })
222+ if err != nil {
223+ log .Error (err , "failed to get infra machines" )
224+ return nil
225+ }
226+
227+ var reqs []ctrl.Request
228+ for _ , infraMachine := range infraMachineList .Items {
229+ log .Info ("cluster changed, reconcile" , "infraMachine" , infraMachine .Name )
230+ reqs = append (reqs , ctrl.Request {
231+ NamespacedName : client .ObjectKeyFromObject (& infraMachine ),
232+ })
233+ }
234+ return reqs
235+ }
236+ }
237+
238+ func (r * MetalStackMachineReconciler ) metalStackClusterToMetalStackMachine (log logr.Logger ) handler.MapFunc {
239+ return func (ctx context.Context , o client.Object ) []ctrl.Request {
240+ infraCluster , ok := o .(* v1alpha1.MetalStackCluster )
241+ if ! ok {
242+ log .Error (fmt .Errorf ("expected an infra cluster, got %T" , o ), "failed to get cluster" , "object" , o )
243+ return nil
244+ }
245+
246+ log := log .WithValues ("infraCluster" , infraCluster .Name , "namespace" , infraCluster .Namespace )
247+
248+ clusterName , ok := infraCluster .Labels [clusterv1 .ClusterNameLabel ]
249+ if ! ok {
250+ return nil
251+ }
252+
253+ infraMachineList := & v1alpha1.MetalStackMachineList {}
254+ err := r .Client .List (ctx , infraMachineList , & client.ListOptions {
255+ Namespace : infraCluster .Namespace ,
256+ LabelSelector : labels .SelectorFromSet (labels.Set {
257+ clusterv1 .ClusterNameLabel : clusterName ,
258+ }),
259+ })
260+ if err != nil {
261+ log .Error (err , "failed to get infra machines" )
262+ return nil
263+ }
264+
265+ var reqs []ctrl.Request
266+ for _ , infraMachine := range infraMachineList .Items {
267+ log .Info ("metalstackcluster changed, reconcile" , "infraMachine" , infraMachine .Name )
268+ reqs = append (reqs , ctrl.Request {
269+ NamespacedName : client .ObjectKeyFromObject (& infraMachine ),
270+ })
271+ }
272+ return reqs
273+ }
274+ }
275+
276+ func (r * MetalStackMachineReconciler ) machineToMetalStackMachine (log logr.Logger ) handler.MapFunc {
277+ return func (ctx context.Context , o client.Object ) []ctrl.Request {
278+ machine , ok := o .(* clusterv1.Machine )
279+ if ! ok {
280+ log .Error (fmt .Errorf ("expected a machine, got %T" , o ), "failed to get machine" , "object" , o )
281+ return nil
282+ }
283+
284+ log := log .WithValues ("machine" , machine .Name , "namespace" , machine .Namespace )
285+
286+ clusterName , ok := machine .Labels [clusterv1 .ClusterNameLabel ]
287+ if ! ok {
288+ return nil
289+ }
290+ deploymentName , ok := machine .Labels [clusterv1 .MachineDeploymentNameLabel ]
291+ if ! ok {
292+ return nil
293+ }
294+ machineSetName , ok := machine .Labels [clusterv1 .MachineSetNameLabel ]
295+ if ! ok {
296+ return nil
297+ }
298+
299+ infraMachineList := & v1alpha1.MetalStackMachineList {}
300+ err := r .Client .List (ctx , infraMachineList , & client.ListOptions {
301+ Namespace : machine .Namespace ,
302+ LabelSelector : labels .SelectorFromSet (labels.Set {
303+ clusterv1 .ClusterNameLabel : clusterName ,
304+ clusterv1 .MachineDeploymentNameLabel : deploymentName ,
305+ clusterv1 .MachineSetNameLabel : machineSetName ,
306+ }),
307+ })
308+ if err != nil {
309+ log .Error (err , "failed to get infra machines" )
310+ return nil
311+ }
312+
313+ var reqs []ctrl.Request
314+ for _ , infraMachine := range infraMachineList .Items {
315+ log .Info ("machine changed, reconcile" , "infraMachine" , infraMachine .Name )
316+ reqs = append (reqs , ctrl.Request {
317+ NamespacedName : client .ObjectKeyFromObject (& infraMachine ),
318+ })
319+ }
320+ return reqs
321+ }
322+ }
323+
184324func (r * machineReconciler ) reconcile () (ctrl.Result , error ) {
185325 if r .infraCluster .Spec .ControlPlaneEndpoint .Host == "" {
186326 return ctrl.Result {}, errors .New ("waiting until control plane ip was set to infrastructure cluster spec" )
0 commit comments