From 7f4c92d3be357615f98a0e342b2e9e3ce216d7b6 Mon Sep 17 00:00:00 2001 From: Skyler Clark Date: Wed, 9 Oct 2024 15:31:37 -0400 Subject: [PATCH 1/7] blocks out beginning of solutoin --- controllers/configmap_controller.go | 13 ++++ controllers/controllers.go | 99 +++++++++++++++++++++++++++++ 2 files changed, 112 insertions(+) diff --git a/controllers/configmap_controller.go b/controllers/configmap_controller.go index 1e5ab5ae43..4fe9718d52 100644 --- a/controllers/configmap_controller.go +++ b/controllers/configmap_controller.go @@ -25,6 +25,7 @@ import ( "strings" config "github.com/openshift/api/config/v1" + mcfgv1 "github.com/openshift/api/machineconfiguration/v1" core "k8s.io/api/core/v1" rbac "k8s.io/api/rbac/v1" k8sapierrors "k8s.io/apimachinery/pkg/api/errors" @@ -385,6 +386,12 @@ func (r *ConfigMapReconciler) mapToInstancesConfigMap(_ context.Context, _ clien }} } +func (r *ConfigMapReconciler) updateNodeArgs(_ context.Context, _ client.Object) []reconcile.Request { + return []reconcile.Request{{ + // update the windows-services configmap + }} +} + // mapToServicesConfigMap fulfills the MapFn type, while always returning a request to the windows-services ConfigMap func (r *ConfigMapReconciler) mapToServicesConfigMap(_ context.Context, _ client.Object) []reconcile.Request { return []reconcile.Request{{ @@ -414,6 +421,12 @@ func (r *ConfigMapReconciler) SetupWithManager(mgr ctrl.Manager) error { builder.WithPredicates(outdatedWindowsNodePredicate(true))). Watches(&core.Node{}, handler.EnqueueRequestsFromMapFunc(r.mapToServicesConfigMap), builder.WithPredicates(windowsNodeVersionChangePredicate())). + Watches(&core.Node{}, handler.EnqueueRequestsFromMapFunc(r.updateNodeArgs), + builder.WithPredicates(nodeLabelChangedPredicate())). + Watches(&core.Node{}, handler.EnqueueRequestsFromMapFunc(r.updateNodeArgs), + builder.WithPredicates(nodeconfigChangedPredicate())). + Watches(&mcfgv1.MachineConfig{}, handler.EnqueueRequestsFromMapFunc(r.updateNodeArgs), + builder.WithPredicates(machineConfigChangedPredicate())). Complete(r) } diff --git a/controllers/controllers.go b/controllers/controllers.go index c9386bc91e..a3099e359c 100644 --- a/controllers/controllers.go +++ b/controllers/controllers.go @@ -4,10 +4,12 @@ import ( "context" "fmt" "net" + "reflect" "sync" "github.com/go-logr/logr" config "github.com/openshift/api/config/v1" + mcfgv1 "github.com/openshift/api/machineconfiguration/v1" "golang.org/x/crypto/ssh" core "k8s.io/api/core/v1" kubeTypes "k8s.io/apimachinery/pkg/types" @@ -201,6 +203,103 @@ func windowsNodeVersionChangePredicate() predicate.Funcs { } } +func nodeLabelChangedPredicate() predicate.Funcs { + return predicate.Funcs{ + CreateFunc: func(e event.CreateEvent) bool { + return false + }, + UpdateFunc: func(e event.UpdateEvent) bool { + // check if node object metadata.labels = e.objectold vs e.objectnew + return !reflect.DeepEqual(e.ObjectOld.GetLabels(), e.ObjectNew.GetLabels()) + }, + GenericFunc: func(e event.GenericEvent) bool { + return false + + }, + DeleteFunc: func(e event.DeleteEvent) bool { + return false + }, + } +} + +func machineConfigChangedPredicate() predicate.Funcs { + return predicate.Funcs{ + CreateFunc: func(e event.CreateEvent) bool { + return false + }, + UpdateFunc: func(e event.UpdateEvent) bool { + oldMachineConfig, _ := e.ObjectOld.(*mcfgv1.MachineConfig) + newMachineConfig, _ := e.ObjectNew.(*mcfgv1.MachineConfig) + + // unmarshal the machine cong's json struct :( + // then check to see if anything has changed + // right now we can just check to see if the config changed at all + if !reflect.DeepEqual(oldMachineConfig.Spec.Config, newMachineConfig.Spec.Config) { + return true + } + + return false + + // check if any of the machineconfig attributes have changed + // + //Config + //Bootstrap-kubeconfig + //Kubeconfig + //Container-runtime + //Container-runtime-endpoint + //Runtime-cgroups + //Node-ip + //Volume-plugin-dir + //Cloud-provider + //Cloud-config + //Hostname-override + //Provider-id + //Pod-infra-container-image + //System-reserved + }, + GenericFunc: func(e event.GenericEvent) bool { + return false + + }, + DeleteFunc: func(e event.DeleteEvent) bool { + return false + }, + } +} + +func nodeconfigChangedPredicate() predicate.Funcs { + return predicate.Funcs{ + CreateFunc: func(e event.CreateEvent) bool { + return false + }, + UpdateFunc: func(e event.UpdateEvent) bool { + oldNode, _ := e.ObjectOld.(*core.Node) + newNode, _ := e.ObjectNew.(*core.Node) + + // Check if "Node-ip" label has changed + if oldNode.Labels["Node-ip"] != newNode.Labels["Node-ip"] { + return true + } + + // Check if "Hostname-override" label has changed + if oldNode.Labels["Hostname-override"] != newNode.Labels["Hostname-override"] { + return true + } + // check if nodeconfig has any attributes that have changed + // + // Node-ip + // Hostname-override + return false + }, + GenericFunc: func(e event.GenericEvent) bool { + return false + }, + DeleteFunc: func(e event.DeleteEvent) bool { + return false + }, + } +} + // outdatedWindowsNodePredicate returns a predicate which filters out all node objects that are not up-to-date Windows // nodes. Up-to-date refers to the version annotation and public key hash annotations. // If BYOH is true, only BYOH nodes will be allowed through, else no BYOH nodes will be allowed. From a5459bdf143f2af908046165b2fd02ba723b0bee Mon Sep 17 00:00:00 2001 From: Skyler Clark Date: Fri, 11 Oct 2024 10:52:17 -0400 Subject: [PATCH 2/7] adds things --- controllers/configmap_controller.go | 15 +++++++++++---- controllers/controllers.go | 3 --- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/controllers/configmap_controller.go b/controllers/configmap_controller.go index 4fe9718d52..b97840eec0 100644 --- a/controllers/configmap_controller.go +++ b/controllers/configmap_controller.go @@ -20,6 +20,7 @@ import ( "context" "encoding/json" "fmt" + "log" "net" "reflect" "strings" @@ -386,10 +387,16 @@ func (r *ConfigMapReconciler) mapToInstancesConfigMap(_ context.Context, _ clien }} } -func (r *ConfigMapReconciler) updateNodeArgs(_ context.Context, _ client.Object) []reconcile.Request { - return []reconcile.Request{{ - // update the windows-services configmap - }} +func (r *ConfigMapReconciler) updateNodeArgs (_ context.Context, obj client.Object) []reconcile.Request { + switch obj.(type) { + case *core.Node: + log.Printf("node changed") + case *mcfgv1.MachineConfig: + log.Printf("machineconfig changed") + } + return []reconcile.Request{{ + // update the windows-services configmap + }} } // mapToServicesConfigMap fulfills the MapFn type, while always returning a request to the windows-services ConfigMap diff --git a/controllers/controllers.go b/controllers/controllers.go index a3099e359c..e804abab17 100644 --- a/controllers/controllers.go +++ b/controllers/controllers.go @@ -231,9 +231,6 @@ func machineConfigChangedPredicate() predicate.Funcs { oldMachineConfig, _ := e.ObjectOld.(*mcfgv1.MachineConfig) newMachineConfig, _ := e.ObjectNew.(*mcfgv1.MachineConfig) - // unmarshal the machine cong's json struct :( - // then check to see if anything has changed - // right now we can just check to see if the config changed at all if !reflect.DeepEqual(oldMachineConfig.Spec.Config, newMachineConfig.Spec.Config) { return true } From cfd640f5b226f3bbfa2004864da2b55246f695fe Mon Sep 17 00:00:00 2001 From: Skyler Clark Date: Fri, 11 Oct 2024 15:40:20 -0400 Subject: [PATCH 3/7] fixes log --- controllers/configmap_controller.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/controllers/configmap_controller.go b/controllers/configmap_controller.go index b97840eec0..a7af609498 100644 --- a/controllers/configmap_controller.go +++ b/controllers/configmap_controller.go @@ -390,9 +390,9 @@ func (r *ConfigMapReconciler) mapToInstancesConfigMap(_ context.Context, _ clien func (r *ConfigMapReconciler) updateNodeArgs (_ context.Context, obj client.Object) []reconcile.Request { switch obj.(type) { case *core.Node: - log.Printf("node changed") + r.log.Info("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! node changed") case *mcfgv1.MachineConfig: - log.Printf("machineconfig changed") + r.log.Info("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! machineconfig changed") } return []reconcile.Request{{ // update the windows-services configmap From 3868d47dd033315526467100f4248de07e5906f5 Mon Sep 17 00:00:00 2001 From: Skyler Clark Date: Fri, 11 Oct 2024 15:47:53 -0400 Subject: [PATCH 4/7] fix --- controllers/configmap_controller.go | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/controllers/configmap_controller.go b/controllers/configmap_controller.go index a7af609498..e65657e165 100644 --- a/controllers/configmap_controller.go +++ b/controllers/configmap_controller.go @@ -20,7 +20,6 @@ import ( "context" "encoding/json" "fmt" - "log" "net" "reflect" "strings" @@ -387,16 +386,16 @@ func (r *ConfigMapReconciler) mapToInstancesConfigMap(_ context.Context, _ clien }} } -func (r *ConfigMapReconciler) updateNodeArgs (_ context.Context, obj client.Object) []reconcile.Request { - switch obj.(type) { - case *core.Node: - r.log.Info("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! node changed") - case *mcfgv1.MachineConfig: - r.log.Info("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! machineconfig changed") - } - return []reconcile.Request{{ - // update the windows-services configmap - }} +func (r *ConfigMapReconciler) updateNodeArgs(_ context.Context, obj client.Object) []reconcile.Request { + switch obj.(type) { + case *core.Node: + r.log.Info("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! node changed") + case *mcfgv1.MachineConfig: + r.log.Info("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! machineconfig changed") + } + return []reconcile.Request{{ + // update the windows-services configmap + }} } // mapToServicesConfigMap fulfills the MapFn type, while always returning a request to the windows-services ConfigMap From d8361170d61c44b0d11c66862b9399a9f92ecfa3 Mon Sep 17 00:00:00 2001 From: Skyler Clark Date: Tue, 15 Oct 2024 14:11:55 -0400 Subject: [PATCH 5/7] fix --- controllers/configmap_controller.go | 45 +++++++++++++++++------------ 1 file changed, 27 insertions(+), 18 deletions(-) diff --git a/controllers/configmap_controller.go b/controllers/configmap_controller.go index e65657e165..81888349e8 100644 --- a/controllers/configmap_controller.go +++ b/controllers/configmap_controller.go @@ -187,7 +187,21 @@ func (r *ConfigMapReconciler) Reconcile(ctx context.Context, // At this point configMap will be set properly switch req.NamespacedName.Name { case servicescm.Name: - return ctrl.Result{}, r.reconcileServices(ctx, configMap) + // get the machineConfig + machineConfig := &mcfgv1.MachineConfig{} + if err := r.client.Get(ctx, kubeTypes.NamespacedName{ + Namespace: req.Namespace}, machineConfig); err != nil { + return ctrl.Result{}, err + } + node := &core.Node{} + if err := r.client.Get(ctx, kubeTypes.NamespacedName{ + Namespace: "", + Name: req.Name}, + node); err != nil { + return ctrl.Result{}, err + } + + return ctrl.Result{}, r.reconcileServices(ctx, configMap, machineConfig, node) case wiparser.InstanceConfigMap: return ctrl.Result{}, r.reconcileNodes(ctx, configMap) case certificates.ProxyCertsConfigMap: @@ -201,7 +215,7 @@ func (r *ConfigMapReconciler) Reconcile(ctx context.Context, // reconcileServices uses the data within the services ConfigMap to ensure WMCO-managed Windows services on // Windows Nodes have the expected configuration and are in the expected state -func (r *ConfigMapReconciler) reconcileServices(ctx context.Context, windowsServices *core.ConfigMap) error { +func (r *ConfigMapReconciler) reconcileServices(ctx context.Context, windowsServices *core.ConfigMap, machineConfig *mcfgv1.MachineConfig, node *core.Node) error { if err := r.removeOutdatedServicesConfigMaps(ctx); err != nil { return err } @@ -217,6 +231,13 @@ func (r *ConfigMapReconciler) reconcileServices(ctx context.Context, windowsServ kubeTypes.NamespacedName{Namespace: r.watchNamespace, Name: windowsServices.Name}, "Error", err.Error()) return nil } + // machineconfig.Spec.Config + // unmarshal the json, and set the data to the machineconfig's value + + // for each in node.Annotations + // for each in node labels + + // TODO: actually react to changes to the services ConfigMap return nil } @@ -252,7 +273,7 @@ func (r *ConfigMapReconciler) removeOutdatedServicesConfigMaps(ctx context.Conte func isTiedToRelevantVersion(v string, versions map[string]struct{}) bool { if v == version.Get() { // The current WMCO version is always considered relevant - return true + return true } for version := range versions { if v == version { @@ -386,18 +407,6 @@ func (r *ConfigMapReconciler) mapToInstancesConfigMap(_ context.Context, _ clien }} } -func (r *ConfigMapReconciler) updateNodeArgs(_ context.Context, obj client.Object) []reconcile.Request { - switch obj.(type) { - case *core.Node: - r.log.Info("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! node changed") - case *mcfgv1.MachineConfig: - r.log.Info("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! machineconfig changed") - } - return []reconcile.Request{{ - // update the windows-services configmap - }} -} - // mapToServicesConfigMap fulfills the MapFn type, while always returning a request to the windows-services ConfigMap func (r *ConfigMapReconciler) mapToServicesConfigMap(_ context.Context, _ client.Object) []reconcile.Request { return []reconcile.Request{{ @@ -427,11 +436,11 @@ func (r *ConfigMapReconciler) SetupWithManager(mgr ctrl.Manager) error { builder.WithPredicates(outdatedWindowsNodePredicate(true))). Watches(&core.Node{}, handler.EnqueueRequestsFromMapFunc(r.mapToServicesConfigMap), builder.WithPredicates(windowsNodeVersionChangePredicate())). - Watches(&core.Node{}, handler.EnqueueRequestsFromMapFunc(r.updateNodeArgs), + Watches(&core.Node{}, handler.EnqueueRequestsFromMapFunc(r.mapToServicesConfigMap), builder.WithPredicates(nodeLabelChangedPredicate())). - Watches(&core.Node{}, handler.EnqueueRequestsFromMapFunc(r.updateNodeArgs), + Watches(&core.Node{}, handler.EnqueueRequestsFromMapFunc(r.mapToServicesConfigMap), builder.WithPredicates(nodeconfigChangedPredicate())). - Watches(&mcfgv1.MachineConfig{}, handler.EnqueueRequestsFromMapFunc(r.updateNodeArgs), + Watches(&mcfgv1.MachineConfig{}, handler.EnqueueRequestsFromMapFunc(r.mapToServicesConfigMap), builder.WithPredicates(machineConfigChangedPredicate())). Complete(r) } From c45288b1d98fad4ba2893a9ba050ca071846db39 Mon Sep 17 00:00:00 2001 From: Skyler Clark Date: Fri, 18 Oct 2024 15:17:58 -0400 Subject: [PATCH 6/7] awaaga --- controllers/configmap_controller.go | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/controllers/configmap_controller.go b/controllers/configmap_controller.go index 81888349e8..d882589321 100644 --- a/controllers/configmap_controller.go +++ b/controllers/configmap_controller.go @@ -190,13 +190,12 @@ func (r *ConfigMapReconciler) Reconcile(ctx context.Context, // get the machineConfig machineConfig := &mcfgv1.MachineConfig{} if err := r.client.Get(ctx, kubeTypes.NamespacedName{ - Namespace: req.Namespace}, machineConfig); err != nil { + Namespace: req.NamespacedName.Namespace}, machineConfig); err != nil { return ctrl.Result{}, err } node := &core.Node{} if err := r.client.Get(ctx, kubeTypes.NamespacedName{ - Namespace: "", - Name: req.Name}, + Name: req.NamespacedName.Name}, node); err != nil { return ctrl.Result{}, err } @@ -233,9 +232,13 @@ func (r *ConfigMapReconciler) reconcileServices(ctx context.Context, windowsServ } // machineconfig.Spec.Config // unmarshal the json, and set the data to the machineconfig's value + + for key, value := range data.Services { + r.log.Info("configmap data: Key", key, " Value: ", value) + } // for each in node.Annotations - // for each in node labels + // for each in node.Labels // TODO: actually react to changes to the services ConfigMap From a9bd074a09a1994a4adc04e9f786393e3a326410 Mon Sep 17 00:00:00 2001 From: Skyler Clark Date: Tue, 22 Oct 2024 10:27:46 -0400 Subject: [PATCH 7/7] fix --- controllers/configmap_controller.go | 61 +++++++++++++++++------------ 1 file changed, 36 insertions(+), 25 deletions(-) diff --git a/controllers/configmap_controller.go b/controllers/configmap_controller.go index d882589321..1e841d1c6a 100644 --- a/controllers/configmap_controller.go +++ b/controllers/configmap_controller.go @@ -187,20 +187,18 @@ func (r *ConfigMapReconciler) Reconcile(ctx context.Context, // At this point configMap will be set properly switch req.NamespacedName.Name { case servicescm.Name: - // get the machineConfig - machineConfig := &mcfgv1.MachineConfig{} - if err := r.client.Get(ctx, kubeTypes.NamespacedName{ - Namespace: req.NamespacedName.Namespace}, machineConfig); err != nil { - return ctrl.Result{}, err - } - node := &core.Node{} - if err := r.client.Get(ctx, kubeTypes.NamespacedName{ - Name: req.NamespacedName.Name}, - node); err != nil { - return ctrl.Result{}, err - } - - return ctrl.Result{}, r.reconcileServices(ctx, configMap, machineConfig, node) + // get the machineConfig + + if nodename, ok := ctx.Value("nodename").(string); ok { + node := &core.Node{} + if err := r.client.Get(ctx, kubeTypes.NamespacedName{ + Name: nodename}, + node); err != nil { + return ctrl.Result{}, err + } + return ctrl.Result{}, r.reconcileServices(ctx, configMap, node) + } + case wiparser.InstanceConfigMap: return ctrl.Result{}, r.reconcileNodes(ctx, configMap) case certificates.ProxyCertsConfigMap: @@ -214,7 +212,7 @@ func (r *ConfigMapReconciler) Reconcile(ctx context.Context, // reconcileServices uses the data within the services ConfigMap to ensure WMCO-managed Windows services on // Windows Nodes have the expected configuration and are in the expected state -func (r *ConfigMapReconciler) reconcileServices(ctx context.Context, windowsServices *core.ConfigMap, machineConfig *mcfgv1.MachineConfig, node *core.Node) error { +func (r *ConfigMapReconciler) reconcileServices(ctx context.Context, windowsServices *core.ConfigMap, node *core.Node) error { if err := r.removeOutdatedServicesConfigMaps(ctx); err != nil { return err } @@ -230,16 +228,15 @@ func (r *ConfigMapReconciler) reconcileServices(ctx context.Context, windowsServ kubeTypes.NamespacedName{Namespace: r.watchNamespace, Name: windowsServices.Name}, "Error", err.Error()) return nil } - // machineconfig.Spec.Config - // unmarshal the json, and set the data to the machineconfig's value - - for key, value := range data.Services { - r.log.Info("configmap data: Key", key, " Value: ", value) - } + // machineconfig.Spec.Config + // unmarshal the json, and set the data to the machineconfig's value - // for each in node.Annotations - // for each in node.Labels + for key, value := range data.Services { + r.log.Info("configmap data: Key", key, " Value: ", value) + } + // for each in node.Annotations + // for each in node.Labels // TODO: actually react to changes to the services ConfigMap return nil @@ -276,7 +273,7 @@ func (r *ConfigMapReconciler) removeOutdatedServicesConfigMaps(ctx context.Conte func isTiedToRelevantVersion(v string, versions map[string]struct{}) bool { if v == version.Get() { // The current WMCO version is always considered relevant - return true + return true } for version := range versions { if v == version { @@ -411,7 +408,21 @@ func (r *ConfigMapReconciler) mapToInstancesConfigMap(_ context.Context, _ clien } // mapToServicesConfigMap fulfills the MapFn type, while always returning a request to the windows-services ConfigMap -func (r *ConfigMapReconciler) mapToServicesConfigMap(_ context.Context, _ client.Object) []reconcile.Request { +func (r *ConfigMapReconciler) mapToServicesConfigMap(ctx context.Context, obj client.Object) []reconcile.Request { + switch resource := obj.(type) { + case *core.Node: + nodeName := resource.GetName() + ctx = context.WithValue(ctx, "nodename", nodeName) + r.log.Info("change triggered by node", "node", nodeName) + case *mcfgv1.MachineConfig: + machineconfigname := resource.GetName() + ctx = context.WithValue(ctx, "machineconfigname", machineconfigname) + r.log.Info("change triggered my machineconfig", "machineconfig", machineconfigname) + default: + r.log.Info("unknown object type") + return nil + } + return []reconcile.Request{{ NamespacedName: kubeTypes.NamespacedName{Namespace: r.watchNamespace, Name: servicescm.Name}, }}