From 4547ac02d16cf1c989be6576306357ce665401ed Mon Sep 17 00:00:00 2001 From: James Slagle Date: Fri, 15 Sep 2023 12:42:03 -0400 Subject: [PATCH] Add Watch to NodeSet for Deployments Instead of the OpenStackDataPlaneDeployment controller updating the status of OpenStackDataPlaneNodeSet after a deployment, use a watch instead. The watch is added for the OpenStackDataPlaneNodeSet reconciler and it when a reconcile is triggerd, the deployment condition will be set to True if there any associated deployed OpenStackDataPlaneDeployments. Signed-off-by: James Slagle --- ...openstackdataplanedeployment_controller.go | 11 --- .../openstackdataplanenodeset_controller.go | 77 +++++++++++++++++++ 2 files changed, 77 insertions(+), 11 deletions(-) diff --git a/controllers/openstackdataplanedeployment_controller.go b/controllers/openstackdataplanedeployment_controller.go index 1f3e988cd..fd54f89f7 100644 --- a/controllers/openstackdataplanedeployment_controller.go +++ b/controllers/openstackdataplanedeployment_controller.go @@ -28,7 +28,6 @@ import ( "k8s.io/client-go/kubernetes" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" "sigs.k8s.io/controller-runtime/pkg/log" "github.com/go-logr/logr" @@ -235,16 +234,6 @@ func (r *OpenStackDataPlaneDeploymentReconciler) Reconcile(ctx context.Context, condition.TrueCondition( condition.Type(fmt.Sprintf(dataplanev1.NodeSetDeploymentReadyCondition, nodeSet.Name)), condition.DeploymentReadyMessage)) - - logger.Info("Set NodeSet DeploymentReadyCondition true", "nodeSet", nodeSet.Name) - _, err = controllerutil.CreateOrPatch(ctx, helper.GetClient(), &nodeSet, func() error { - nodeSet.Status.Conditions.MarkTrue(condition.DeploymentReadyCondition, condition.DeploymentReadyMessage) - return nil - }) - if err != nil { - util.LogErrorForObject(helper, err, "Unable to set Status on NodeSet", &nodeSet) - return ctrl.Result{}, err - } } } diff --git a/controllers/openstackdataplanenodeset_controller.go b/controllers/openstackdataplanenodeset_controller.go index dabf81850..274470b6e 100644 --- a/controllers/openstackdataplanenodeset_controller.go +++ b/controllers/openstackdataplanenodeset_controller.go @@ -259,9 +259,65 @@ func (r *OpenStackDataPlaneNodeSetReconciler) Reconcile(ctx context.Context, req instance.Status.Conditions.Set(condition.FalseCondition(condition.DeploymentReadyCondition, condition.NotRequestedReason, condition.SeverityInfo, condition.DeploymentReadyInitMessage)) } + deployedDeploymentsForNodeSet, err := r.GetDeployedDeploymentsForNodeSet(instance.Name) + if err != nil { + logger.Error(err, "Unable to get deployed OpenStackDataPlaneDeployments.") + return ctrl.Result{}, err + } + if len(deployedDeploymentsForNodeSet.Items) > 0 { + logger.Info("Set NodeSet DeploymentReadyCondition true") + instance.Status.Conditions.MarkTrue(condition.DeploymentReadyCondition, condition.DeploymentReadyMessage) + } + return ctrl.Result{}, nil } +// GetDeployedDeploymentsForNodeSet - Get the OpenStackDataPlaneDeployment +// resources that have been deployed and are for the given +// OpenStackDataPlaneNodeSet. +func (r *OpenStackDataPlaneNodeSetReconciler) GetDeployedDeploymentsForNodeSet(nodeSetName string) (*dataplanev1.OpenStackDataPlaneDeploymentList, error) { + // Get all deployments + deployments := &dataplanev1.OpenStackDataPlaneDeploymentList{} + err := r.Client.List(context.Background(), deployments) + if err != nil { + r.Log.Error(err, "Unable to retrieve OpenStackDataPlaneDeployment CRs %v") + return deployments, nil + } + deployedDeploymentsForNodeSet := &dataplanev1.OpenStackDataPlaneDeploymentList{} + for _, deployment := range deployments.Items { + for _, nodeSet := range deployment.Spec.NodeSets { + if nodeSet == nodeSetName { + if deployment.Status.Conditions.IsTrue(condition.Type(fmt.Sprintf(dataplanev1.NodeSetDeploymentReadyCondition, nodeSetName))) { + deployedDeploymentsForNodeSet.Items = append(deployedDeploymentsForNodeSet.Items, deployment) + } + } + } + } + + return deployedDeploymentsForNodeSet, err +} + +// GetNodeSetsForDeployment - Get the OpenStackDataPlaneNodeSet +// resources for the given OpenStackDataPlaneDeployment +func (r *OpenStackDataPlaneNodeSetReconciler) GetNodeSetsForDeployment(namespace string, deployment *dataplanev1.OpenStackDataPlaneDeployment) (dataplanev1.OpenStackDataPlaneNodeSetList, error) { + nodeSets := dataplanev1.OpenStackDataPlaneNodeSetList{} + var err error + for _, nodeSetName := range deployment.Spec.NodeSets { + nodeSet := &dataplanev1.OpenStackDataPlaneNodeSet{} + namespacedName := client.ObjectKey{ + Namespace: namespace, + Name: nodeSetName} + err = r.Client.Get(context.Background(), namespacedName, nodeSet) + if err != nil { + r.Log.Error(err, "Unable to retrieve OpenStackDataPlaneNodeSet CR %v") + return nodeSets, nil + } + nodeSets.Items = append(nodeSets.Items, *nodeSet) + } + + return nodeSets, err +} + // SetupWithManager sets up the controller with the Manager. func (r *OpenStackDataPlaneNodeSetReconciler) SetupWithManager(mgr ctrl.Manager) error { reconcileFunction := handler.EnqueueRequestsFromMapFunc(func(o client.Object) []reconcile.Request { @@ -296,6 +352,25 @@ func (r *OpenStackDataPlaneNodeSetReconciler) SetupWithManager(mgr ctrl.Manager) return nil }) + deploymentWatcher := handler.EnqueueRequestsFromMapFunc(func(obj client.Object) []reconcile.Request { + var namespace string = obj.GetNamespace() + result := []reconcile.Request{} + + deployment := obj.(*dataplanev1.OpenStackDataPlaneDeployment) + nodeSets, err := r.GetNodeSetsForDeployment(namespace, deployment) + if err != nil { + r.Log.Error(err, "Unable to retrieve OpenStackDataPlaneNodeSets %w") + return nil + } + for _, nodeSet := range nodeSets.Items { + name := client.ObjectKey{ + Namespace: namespace, + Name: nodeSet.Name} + result = append(result, reconcile.Request{NamespacedName: name}) + } + return result + }) + return ctrl.NewControllerManagedBy(mgr). For(&dataplanev1.OpenStackDataPlaneNodeSet{}). Owns(&v1alpha1.OpenStackAnsibleEE{}). @@ -305,5 +380,7 @@ func (r *OpenStackDataPlaneNodeSetReconciler) SetupWithManager(mgr ctrl.Manager) Owns(&corev1.Secret{}). Watches(&source.Kind{Type: &infranetworkv1.DNSMasq{}}, reconcileFunction). + Watches(&source.Kind{Type: &dataplanev1.OpenStackDataPlaneDeployment{}}, + deploymentWatcher). Complete(r) }