From: Le Yao Date: Tue, 15 Dec 2020 08:46:57 +0000 (+0000) Subject: Add watch mechanism for pod to auto sync X-Git-Tag: 21-12-01~20^2 X-Git-Url: https://gerrit.akraino.org/r/gitweb?a=commitdiff_plain;h=b594a8f8875a46ef48de9891cfe69b967e37ab6d;p=icn%2Fsdwan.git Add watch mechanism for pod to auto sync Sync status and reconcile when pod status change Signed-off-by: Le Yao Change-Id: Icad1caf52e43d25106753c02525e1eaceb449ba2 --- diff --git a/platform/crd-ctrlr/src/controllers/sdewanapplication_controller.go b/platform/crd-ctrlr/src/controllers/sdewanapplication_controller.go index dfd8eea..8be6749 100644 --- a/platform/crd-ctrlr/src/controllers/sdewanapplication_controller.go +++ b/platform/crd-ctrlr/src/controllers/sdewanapplication_controller.go @@ -24,9 +24,14 @@ import ( appsv1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/types" ctrl "sigs.k8s.io/controller-runtime" + "sigs.k8s.io/controller-runtime/pkg/builder" "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/event" "sigs.k8s.io/controller-runtime/pkg/handler" + "sigs.k8s.io/controller-runtime/pkg/predicate" + "sigs.k8s.io/controller-runtime/pkg/reconcile" "sigs.k8s.io/controller-runtime/pkg/source" batchv1alpha1 "sdewan.akraino.org/sdewan/api/v1alpha1" @@ -79,10 +84,6 @@ func (m *SdewanApplicationHandler) GetInstance(r client.Client, ctx context.Cont instance.AppInfo.IpList = ips } - if instance.AppInfo.IpList == "" { - return instance, &AppCRError{Code: 404, Message: "Application not found"} - } - return instance, err } @@ -132,6 +133,77 @@ func (m *SdewanApplicationHandler) Restart(clientInfo *openwrt.OpenwrtClientInfo return true, nil } +var appFilter = builder.WithPredicates(predicate.Funcs{ + CreateFunc: func(e event.CreateEvent) bool { + podPhase := reflect.ValueOf(e.Object).Interface().(*corev1.Pod).Status.Phase + + if podPhase == "Running" { + return true + } + return false + }, + UpdateFunc: func(e event.UpdateEvent) bool { + podOldPhase := reflect.ValueOf(e.ObjectOld).Interface().(*corev1.Pod).Status.Phase + podNewPhase := reflect.ValueOf(e.ObjectNew).Interface().(*corev1.Pod).Status.Phase + + if podOldPhase != podNewPhase && podNewPhase == "Running" { + return true + } + + return false + }, + DeleteFunc: func(e event.DeleteEvent) bool { + return true + }, +}) + +func GetAppToRequestsFunc(r client.Client) func(h handler.MapObject) []reconcile.Request { + + return func(h handler.MapObject) []reconcile.Request { + podLabels := h.Meta.GetLabels() + podNamespace := h.Meta.GetNamespace() + appCRList := &batchv1alpha1.SdewanApplicationList{} + cr := &batchv1alpha1.SdewanApplication{} + ctx := context.Background() + r.List(ctx, appCRList) + crIsFound := false + for _, appCR := range appCRList.Items { + ps := appCR.Spec.PodSelector.MatchLabels + ns := appCR.Spec.AppNamespace + judge := true + if ns != podNamespace { + judge = false + } else { + for key, value := range ps { + if _, ok := podLabels[key]; ok && podLabels[key] == value { + continue + } else { + judge = false + break + } + } + } + if judge { + // Assume one application only have one Application CR + cr = &appCR + crIsFound = true + break + } + } + + if crIsFound { + return []reconcile.Request{ + {NamespacedName: types.NamespacedName{ + Name: cr.ObjectMeta.GetName(), + Namespace: cr.ObjectMeta.GetNamespace(), + }}, + } + } else { + return []reconcile.Request{} + } + } +} + // SdewanApplicationReconciler reconciles a SdewanApplication object type SdewanApplicationReconciler struct { client.Client @@ -150,10 +222,16 @@ func (r *SdewanApplicationReconciler) SetupWithManager(mgr ctrl.Manager) error { return ctrl.NewControllerManagedBy(mgr). For(&batchv1alpha1.SdewanApplication{}). Watches( - &source.Kind{Type: &corev1.Service{}}, + &source.Kind{Type: &appsv1.Deployment{}}, + &handler.EnqueueRequestsFromMapFunc{ + ToRequests: handler.ToRequestsFunc(GetToRequestsFunc(r, &batchv1alpha1.SdewanApplicationList{})), + }, + Filter). + Watches( + &source.Kind{Type: &corev1.Pod{}}, &handler.EnqueueRequestsFromMapFunc{ - ToRequests: handler.ToRequestsFunc(GetServiceToRequestsFunc(r)), + ToRequests: handler.ToRequestsFunc(GetAppToRequestsFunc(r)), }, - IPFilter). + appFilter). Complete(r) }