@@ -36,28 +36,29 @@ limitations under the License.
36
36
package controllers
37
37
38
38
import (
39
- appsv1 "k8s.io/api/apps/v1"
40
- corev1 "k8s.io/api/core/v1"
41
- "k8s.io/apimachinery/pkg/api/errors"
42
- metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
43
- "k8s.io/apimachinery/pkg/types"
44
- "reflect"
45
-
46
- "context"
47
-
48
- "github.com/go-logr/logr"
49
- "k8s.io/apimachinery/pkg/runtime"
50
- ctrl "sigs.k8s.io/controller-runtime"
51
- "sigs.k8s.io/controller-runtime/pkg/client"
52
-
53
- cachev1alpha1 "github.com/example/memcached-operator/api/v1alpha1"
39
+ appsv1 "k8s.io/api/apps/v1"
40
+ corev1 "k8s.io/api/core/v1"
41
+ "k8s.io/apimachinery/pkg/api/errors"
42
+ metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
43
+ "k8s.io/apimachinery/pkg/types"
44
+ "reflect"
45
+
46
+ "context"
47
+
48
+ "github.com/go-logr/logr"
49
+ "k8s.io/apimachinery/pkg/runtime"
50
+ ctrl "sigs.k8s.io/controller-runtime"
51
+ "sigs.k8s.io/controller-runtime/pkg/client"
52
+ ctrllog "sigs.k8s.io/controller-runtime/pkg/log"
53
+
54
+ cachev1 "github.com/example-inc/memcached-operator/api/v1"
54
55
)
55
56
56
57
// MemcachedReconciler reconciles a Memcached object
57
58
type MemcachedReconciler struct {
58
- client.Client
59
- Log logr.Logger
60
- Scheme *runtime.Scheme
59
+ client.Client
60
+ Log logr.Logger
61
+ Scheme *runtime.Scheme
61
62
}
62
63
63
64
// +kubebuilder:rbac:groups=cache.example.com,resources=memcacheds,verbs=get;list;watch;create;update;patch;delete
@@ -76,142 +77,144 @@ type MemcachedReconciler struct {
76
77
// For more details, check Reconcile and its Result here:
77
78
// - https://pkg.go.dev/sigs.k8s.io/
[email protected] /pkg/reconcile
78
79
func (r *MemcachedReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
79
- log := r.Log.WithValues("memcached", req.NamespacedName)
80
-
81
- // Fetch the Memcached instance
82
- memcached := &cachev1alpha1 .Memcached{}
83
- err := r.Get(ctx, req.NamespacedName, memcached)
84
- if err != nil {
85
- if errors.IsNotFound(err) {
86
- // Request object not found, could have been deleted after reconcile request.
87
- // Owned objects are automatically garbage collected. For additional cleanup logic use finalizers.
88
- // Return and don't requeue
89
- log.Info("Memcached resource not found. Ignoring since object must be deleted")
90
- return ctrl.Result{}, nil
91
- }
92
- // Error reading the object - requeue the request.
93
- log.Error(err, "Failed to get Memcached")
94
- return ctrl.Result{}, err
95
- }
96
-
97
- // Check if the deployment already exists, if not create a new one
98
- found := &appsv1.Deployment{}
99
- err = r.Get(ctx, types.NamespacedName{Name: memcached.Name, Namespace: memcached.Namespace}, found)
100
- if err != nil && errors.IsNotFound(err) {
101
- // Define a new deployment
102
- dep := r.deploymentForMemcached(memcached)
103
- log.Info("Creating a new Deployment", "Deployment.Namespace", dep.Namespace, "Deployment.Name", dep.Name)
104
- err = r.Create(ctx, dep)
105
- if err != nil {
106
- log.Error(err, "Failed to create new Deployment", "Deployment.Namespace", dep.Namespace, "Deployment.Name", dep.Name)
107
- return ctrl.Result{}, err
108
- }
109
- // Deployment created successfully - return and requeue
110
- return ctrl.Result{Requeue: true}, nil
111
- } else if err != nil {
112
- log.Error(err, "Failed to get Deployment")
113
- return ctrl.Result{}, err
114
- }
115
-
116
- // Ensure the deployment size is the same as the spec
117
- size := memcached.Spec.Size
118
- if *found.Spec.Replicas != size {
119
- found.Spec.Replicas = &size
120
- err = r.Update(ctx, found)
121
- if err != nil {
122
- log.Error(err, "Failed to update Deployment", "Deployment.Namespace", found.Namespace, "Deployment.Name", found.Name)
123
- return ctrl.Result{}, err
124
- }
125
- // Spec updated - return and requeue
126
- return ctrl.Result{Requeue: true}, nil
127
- }
128
-
129
- // Update the Memcached status with the pod names
130
- // List the pods for this memcached's deployment
131
- podList := &corev1.PodList{}
132
- listOpts := []client.ListOption{
133
- client.InNamespace(memcached.Namespace),
134
- client.MatchingLabels(labelsForMemcached(memcached.Name)),
135
- }
136
- if err = r.List(ctx, podList, listOpts...); err != nil {
137
- log.Error(err, "Failed to list pods", "Memcached.Namespace", memcached.Namespace, "Memcached.Name", memcached.Name)
138
- return ctrl.Result{}, err
139
- }
140
- podNames := getPodNames(podList.Items)
141
-
142
- // Update status.Nodes if needed
143
- if !reflect.DeepEqual(podNames, memcached.Status.Nodes) {
144
- memcached.Status.Nodes = podNames
145
- err := r.Status().Update(ctx, memcached)
146
- if err != nil {
147
- log.Error(err, "Failed to update Memcached status")
148
- return ctrl.Result{}, err
149
- }
150
- }
151
-
152
- return ctrl.Result{}, nil
80
+ // log := r.Log.WithValues("memcached", req.NamespacedName)
81
+ log := ctrllog.FromContext(ctx)
82
+ // Fetch the Memcached instance
83
+ memcached := &cachev1 .Memcached{}
84
+ err := r.Get(ctx, req.NamespacedName, memcached)
85
+ if err != nil {
86
+ if errors.IsNotFound(err) {
87
+ // Request object not found, could have been deleted after reconcile request.
88
+ // Owned objects are automatically garbage collected. For additional cleanup logic use finalizers.
89
+ // Return and don't requeue
90
+ log.Info("Memcached resource not found. Ignoring since object must be deleted")
91
+ return ctrl.Result{}, nil
92
+ }
93
+ // Error reading the object - requeue the request.
94
+ log.Error(err, "Failed to get Memcached")
95
+ return ctrl.Result{}, err
96
+ }
97
+
98
+ // Check if the deployment already exists, if not create a new one
99
+ found := &appsv1.Deployment{}
100
+ err = r.Get(ctx, types.NamespacedName{Name: memcached.Name, Namespace: memcached.Namespace}, found)
101
+ if err != nil && errors.IsNotFound(err) {
102
+ // Define a new deployment
103
+ dep := r.deploymentForMemcached(memcached)
104
+ log.Info("Creating a new Deployment", "Deployment.Namespace", dep.Namespace, "Deployment.Name", dep.Name)
105
+ err = r.Create(ctx, dep)
106
+ if err != nil {
107
+ log.Error(err, "Failed to create new Deployment", "Deployment.Namespace", dep.Namespace, "Deployment.Name", dep.Name)
108
+ return ctrl.Result{}, err
109
+ }
110
+ // Deployment created successfully - return and requeue
111
+ return ctrl.Result{Requeue: true}, nil
112
+ } else if err != nil {
113
+ log.Error(err, "Failed to get Deployment")
114
+ return ctrl.Result{}, err
115
+ }
116
+
117
+ // Ensure the deployment size is the same as the spec
118
+ size := memcached.Spec.Size
119
+ if *found.Spec.Replicas != size {
120
+ found.Spec.Replicas = &size
121
+ err = r.Update(ctx, found)
122
+ if err != nil {
123
+ log.Error(err, "Failed to update Deployment", "Deployment.Namespace", found.Namespace, "Deployment.Name", found.Name)
124
+ return ctrl.Result{}, err
125
+ }
126
+ // Spec updated - return and requeue
127
+ return ctrl.Result{Requeue: true}, nil
128
+ }
129
+
130
+ // Update the Memcached status with the pod names
131
+ // List the pods for this memcached's deployment
132
+ podList := &corev1.PodList{}
133
+ listOpts := []client.ListOption{
134
+ client.InNamespace(memcached.Namespace),
135
+ client.MatchingLabels(labelsForMemcached(memcached.Name)),
136
+ }
137
+ if err = r.List(ctx, podList, listOpts...); err != nil {
138
+ log.Error(err, "Failed to list pods", "Memcached.Namespace", memcached.Namespace, "Memcached.Name", memcached.Name)
139
+ return ctrl.Result{}, err
140
+ }
141
+ podNames := getPodNames(podList.Items)
142
+
143
+ // Update status.Nodes if needed
144
+ if !reflect.DeepEqual(podNames, memcached.Status.Nodes) {
145
+ memcached.Status.Nodes = podNames
146
+ err := r.Status().Update(ctx, memcached)
147
+ if err != nil {
148
+ log.Error(err, "Failed to update Memcached status")
149
+ return ctrl.Result{}, err
150
+ }
151
+ }
152
+
153
+ return ctrl.Result{}, nil
153
154
}
154
155
155
156
// deploymentForMemcached returns a memcached Deployment object
156
- func (r *MemcachedReconciler) deploymentForMemcached(m *cachev1alpha1 .Memcached) *appsv1.Deployment {
157
- ls := labelsForMemcached(m.Name)
158
- replicas := m.Spec.Size
159
-
160
- dep := &appsv1.Deployment{
161
- ObjectMeta: metav1.ObjectMeta{
162
- Name: m.Name,
163
- Namespace: m.Namespace,
164
- },
165
- Spec: appsv1.DeploymentSpec{
166
- Replicas: &replicas,
167
- Selector: &metav1.LabelSelector{
168
- MatchLabels: ls,
169
- },
170
- Template: corev1.PodTemplateSpec{
171
- ObjectMeta: metav1.ObjectMeta{
172
- Labels: ls,
173
- },
174
- Spec: corev1.PodSpec{
175
- Containers: []corev1.Container{{
176
- Image: "memcached:1.4.36-alpine",
177
- Name: "memcached",
178
- Command: []string{"memcached", "-m=64", "-o", "modern", "-v"},
179
- Ports: []corev1.ContainerPort{{
180
- ContainerPort: 11211,
181
- Name: "memcached",
182
- }},
183
- }},
184
- },
185
- },
186
- },
187
- }
188
- // Set Memcached instance as the owner and controller
189
- ctrl.SetControllerReference(m, dep, r.Scheme)
190
- return dep
157
+ func (r *MemcachedReconciler) deploymentForMemcached(m *cachev1 .Memcached) *appsv1.Deployment {
158
+ ls := labelsForMemcached(m.Name)
159
+ replicas := m.Spec.Size
160
+
161
+ dep := &appsv1.Deployment{
162
+ ObjectMeta: metav1.ObjectMeta{
163
+ Name: m.Name,
164
+ Namespace: m.Namespace,
165
+ },
166
+ Spec: appsv1.DeploymentSpec{
167
+ Replicas: &replicas,
168
+ Selector: &metav1.LabelSelector{
169
+ MatchLabels: ls,
170
+ },
171
+ Template: corev1.PodTemplateSpec{
172
+ ObjectMeta: metav1.ObjectMeta{
173
+ Labels: ls,
174
+ },
175
+ Spec: corev1.PodSpec{
176
+ Containers: []corev1.Container{{
177
+ Image: "memcached:1.4.36-alpine",
178
+ Name: "memcached",
179
+ Command: []string{"memcached", "-m=64", "-o", "modern", "-v"},
180
+ Ports: []corev1.ContainerPort{{
181
+ ContainerPort: 11211,
182
+ Name: "memcached",
183
+ }},
184
+ }},
185
+ },
186
+ },
187
+ },
188
+ }
189
+ // Set Memcached instance as the owner and controller
190
+ ctrl.SetControllerReference(m, dep, r.Scheme)
191
+ return dep
191
192
}
192
193
193
194
// labelsForMemcached returns the labels for selecting the resources
194
195
// belonging to the given memcached CR name.
195
196
func labelsForMemcached(name string) map[string]string {
196
- return map[string]string{"app": "memcached", "memcached_cr": name}
197
+ return map[string]string{"app": "memcached", "memcached_cr": name}
197
198
}
198
199
199
200
// getPodNames returns the pod names of the array of pods passed in
200
201
func getPodNames(pods []corev1.Pod) []string {
201
- var podNames []string
202
- for _, pod := range pods {
203
- podNames = append(podNames, pod.Name)
204
- }
205
- return podNames
202
+ var podNames []string
203
+ for _, pod := range pods {
204
+ podNames = append(podNames, pod.Name)
205
+ }
206
+ return podNames
206
207
}
207
208
208
209
// SetupWithManager sets up the controller with the Manager.
209
210
func (r *MemcachedReconciler) SetupWithManager(mgr ctrl.Manager) error {
210
- return ctrl.NewControllerManagedBy(mgr).
211
- For(&cachev1alpha1 .Memcached{}).
212
- Owns(&appsv1.Deployment{}).
213
- Complete(r)
211
+ return ctrl.NewControllerManagedBy(mgr).
212
+ For(&cachev1 .Memcached{}).
213
+ Owns(&appsv1.Deployment{}).
214
+ Complete(r)
214
215
}
216
+
217
+
215
218
----
216
219
====
217
220
+
0 commit comments