diff options
Diffstat (limited to 'src/monitor/pkg/controller/resourcebundlestate/controller.go')
-rw-r--r-- | src/monitor/pkg/controller/resourcebundlestate/controller.go | 126 |
1 files changed, 126 insertions, 0 deletions
diff --git a/src/monitor/pkg/controller/resourcebundlestate/controller.go b/src/monitor/pkg/controller/resourcebundlestate/controller.go new file mode 100644 index 00000000..debd5f65 --- /dev/null +++ b/src/monitor/pkg/controller/resourcebundlestate/controller.go @@ -0,0 +1,126 @@ +package resourcebundlestate + +import ( + "context" + "log" + + "monitor/pkg/apis/k8splugin/v1alpha1" + + corev1 "k8s.io/api/core/v1" + k8serrors "k8s.io/apimachinery/pkg/api/errors" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/controller" + "sigs.k8s.io/controller-runtime/pkg/manager" + "sigs.k8s.io/controller-runtime/pkg/reconcile" + "sigs.k8s.io/controller-runtime/pkg/source" +) + +// Add the new controller to the controller manager +func Add(mgr manager.Manager) error { + return add(mgr, newReconciler(mgr)) +} + +func add(mgr manager.Manager, r *reconciler) error { + // Create a new controller + c, err := controller.New("ResourceBundleState-controller", mgr, controller.Options{Reconciler: r}) + if err != nil { + return err + } + + // Watch for changes to primary resource ResourceBundleState + err = c.Watch(&source.Kind{Type: &v1alpha1.ResourceBundleState{}}, &EventHandler{}) + if err != nil { + return err + } + + return nil +} + +func newReconciler(m manager.Manager) *reconciler { + return &reconciler{client: m.GetClient()} +} + +type reconciler struct { + // Stores an array of all the ResourceBundleState + crList []v1alpha1.ResourceBundleState + client client.Client +} + +// Reconcile implements the loop that will manage the ResourceBundleState CR +// We only accept CREATE events here and any subsequent changes are ignored. +func (r *reconciler) Reconcile(req reconcile.Request) (reconcile.Result, error) { + log.Printf("Reconciling ResourceBundleState %+v\n", req) + + rbstate := &v1alpha1.ResourceBundleState{} + err := r.client.Get(context.TODO(), req.NamespacedName, rbstate) + if err != nil { + if k8serrors.IsNotFound(err) { + log.Printf("Object not found: %+v. Ignore as it must have been deleted.\n", req.NamespacedName) + return reconcile.Result{}, nil + } + log.Printf("Failed to get object: %+v\n", req.NamespacedName) + return reconcile.Result{}, err + } + + err = r.updatePods(rbstate, rbstate.Spec.Selector.MatchLabels) + if err != nil { + log.Printf("Error adding podstatuses: %v\n", err) + return reconcile.Result{}, err + } + + err = r.updateServices(rbstate, rbstate.Spec.Selector.MatchLabels) + if err != nil { + log.Printf("Error adding services: %v\n", err) + return reconcile.Result{}, err + } + + // TODO: Update this based on the statuses of the lower resources + rbstate.Status.Ready = false + err = r.client.Status().Update(context.TODO(), rbstate) + if err != nil { + log.Printf("failed to update rbstate: %v\n", err) + return reconcile.Result{}, err + } + + return reconcile.Result{}, nil +} + +func (r *reconciler) updateServices(rbstate *v1alpha1.ResourceBundleState, + selectors map[string]string) error { + + // Update the CR with the Services created as well + serviceList := &corev1.ServiceList{} + err := listResources(r.client, rbstate.Namespace, selectors, serviceList) + if err != nil { + log.Printf("Failed to list services: %v", err) + return err + } + + rbstate.Status.ServiceStatuses = serviceList.Items + return nil +} + +func (r *reconciler) updatePods(rbstate *v1alpha1.ResourceBundleState, + selectors map[string]string) error { + + // Update the CR with the pods tracked + podList := &corev1.PodList{} + err := listResources(r.client, rbstate.Namespace, selectors, podList) + if err != nil { + log.Printf("Failed to list pods: %v", err) + return err + } + + rbstate.Status.PodStatuses = []v1alpha1.PodStatus{} + + for _, pod := range podList.Items { + resStatus := v1alpha1.PodStatus{ + ObjectMeta: pod.ObjectMeta, + Ready: false, + Status: pod.Status, + } + rbstate.Status.PodStatuses = append(rbstate.Status.PodStatuses, resStatus) + } + + return nil +} |