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"
instance.AppInfo.IpList = ips
}
- if instance.AppInfo.IpList == "" {
- return instance, &AppCRError{Code: 404, Message: "Application not found"}
- }
-
return instance, err
}
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
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)
}