1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
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
}
|