@@ -19,28 +19,22 @@ package controller
19
19
import (
20
20
"context"
21
21
"fmt"
22
- "os"
23
- "strings"
24
- "time"
25
-
26
22
appsv1 "k8s.io/api/apps/v1"
27
23
corev1 "k8s.io/api/core/v1"
28
24
apierrors "k8s.io/apimachinery/pkg/api/errors"
29
25
"k8s.io/apimachinery/pkg/api/meta"
30
26
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
31
- "k8s.io/apimachinery/pkg/runtime"
32
27
"k8s.io/apimachinery/pkg/types"
33
- "k8s.io/client-go/tools/record"
28
+ "time"
29
+
30
+ "k8s.io/apimachinery/pkg/runtime"
34
31
ctrl "sigs.k8s.io/controller-runtime"
35
32
"sigs.k8s.io/controller-runtime/pkg/client"
36
- "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
37
33
"sigs.k8s.io/controller-runtime/pkg/log"
38
34
39
35
cachev1alpha1 "example.com/memcached/api/v1alpha1"
40
36
)
41
37
42
- const memcachedFinalizer = "cache.example.com/finalizer"
43
-
44
38
// Definitions to manage status conditions
45
39
const (
46
40
// typeAvailableMemcached represents the status of the Deployment reconciliation
@@ -52,14 +46,9 @@ const (
52
46
// MemcachedReconciler reconciles a Memcached object
53
47
type MemcachedReconciler struct {
54
48
client.Client
55
- Scheme * runtime.Scheme
56
- Recorder record.EventRecorder
49
+ Scheme * runtime.Scheme
57
50
}
58
51
59
- // The following markers are used to generate the rules permissions (RBAC) on config/rbac using controller-gen
60
- // when the command <make manifests> is executed.
61
- // To know more about markers see: https://book.kubebuilder.io/reference/markers.html
62
-
63
52
// +kubebuilder:rbac:groups=cache.example.com,resources=memcacheds,verbs=get;list;watch;create;update;patch;delete
64
53
// +kubebuilder:rbac:groups=cache.example.com,resources=memcacheds/status,verbs=get;update;patch
65
54
// +kubebuilder:rbac:groups=cache.example.com,resources=memcacheds/finalizers,verbs=update
@@ -77,6 +66,8 @@ type MemcachedReconciler struct {
77
66
// For further info:
78
67
// - About Operator Pattern: https://kubernetes.io/docs/concepts/extend-kubernetes/operator/
79
68
// - About Controllers: https://kubernetes.io/docs/concepts/architecture/controller/
69
+ //
70
+ // For more details, check Reconcile and its Result here:
80
71
// - https://pkg.go.dev/sigs.k8s.io/controller-runtime@v0.19.0/pkg/reconcile
81
72
func (r * MemcachedReconciler ) Reconcile (ctx context.Context , req ctrl.Request ) (ctrl.Result , error ) {
82
73
log := log .FromContext (ctx )
@@ -117,79 +108,6 @@ func (r *MemcachedReconciler) Reconcile(ctx context.Context, req ctrl.Request) (
117
108
}
118
109
}
119
110
120
- // Let's add a finalizer. Then, we can define some operations which should
121
- // occur before the custom resource is deleted.
122
- // More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/finalizers
123
- if ! controllerutil .ContainsFinalizer (memcached , memcachedFinalizer ) {
124
- log .Info ("Adding Finalizer for Memcached" )
125
- if ok := controllerutil .AddFinalizer (memcached , memcachedFinalizer ); ! ok {
126
- log .Error (err , "Failed to add finalizer into the custom resource" )
127
- return ctrl.Result {Requeue : true }, nil
128
- }
129
-
130
- if err = r .Update (ctx , memcached ); err != nil {
131
- log .Error (err , "Failed to update custom resource to add finalizer" )
132
- return ctrl.Result {}, err
133
- }
134
- }
135
-
136
- // Check if the Memcached instance is marked to be deleted, which is
137
- // indicated by the deletion timestamp being set.
138
- isMemcachedMarkedToBeDeleted := memcached .GetDeletionTimestamp () != nil
139
- if isMemcachedMarkedToBeDeleted {
140
- if controllerutil .ContainsFinalizer (memcached , memcachedFinalizer ) {
141
- log .Info ("Performing Finalizer Operations for Memcached before delete CR" )
142
-
143
- // Let's add here a status "Downgrade" to reflect that this resource began its process to be terminated.
144
- meta .SetStatusCondition (& memcached .Status .Conditions , metav1.Condition {Type : typeDegradedMemcached ,
145
- Status : metav1 .ConditionUnknown , Reason : "Finalizing" ,
146
- Message : fmt .Sprintf ("Performing finalizer operations for the custom resource: %s " , memcached .Name )})
147
-
148
- if err := r .Status ().Update (ctx , memcached ); err != nil {
149
- log .Error (err , "Failed to update Memcached status" )
150
- return ctrl.Result {}, err
151
- }
152
-
153
- // Perform all operations required before removing the finalizer and allow
154
- // the Kubernetes API to remove the custom resource.
155
- r .doFinalizerOperationsForMemcached (memcached )
156
-
157
- // TODO(user): If you add operations to the doFinalizerOperationsForMemcached method
158
- // then you need to ensure that all worked fine before deleting and updating the Downgrade status
159
- // otherwise, you should requeue here.
160
-
161
- // Re-fetch the memcached Custom Resource before updating the status
162
- // so that we have the latest state of the resource on the cluster and we will avoid
163
- // raising the error "the object has been modified, please apply
164
- // your changes to the latest version and try again" which would re-trigger the reconciliation
165
- if err := r .Get (ctx , req .NamespacedName , memcached ); err != nil {
166
- log .Error (err , "Failed to re-fetch memcached" )
167
- return ctrl.Result {}, err
168
- }
169
-
170
- meta .SetStatusCondition (& memcached .Status .Conditions , metav1.Condition {Type : typeDegradedMemcached ,
171
- Status : metav1 .ConditionTrue , Reason : "Finalizing" ,
172
- Message : fmt .Sprintf ("Finalizer operations for custom resource %s name were successfully accomplished" , memcached .Name )})
173
-
174
- if err := r .Status ().Update (ctx , memcached ); err != nil {
175
- log .Error (err , "Failed to update Memcached status" )
176
- return ctrl.Result {}, err
177
- }
178
-
179
- log .Info ("Removing Finalizer for Memcached after successfully perform the operations" )
180
- if ok := controllerutil .RemoveFinalizer (memcached , memcachedFinalizer ); ! ok {
181
- log .Error (err , "Failed to remove finalizer for Memcached" )
182
- return ctrl.Result {Requeue : true }, nil
183
- }
184
-
185
- if err := r .Update (ctx , memcached ); err != nil {
186
- log .Error (err , "Failed to remove finalizer for Memcached" )
187
- return ctrl.Result {}, err
188
- }
189
- }
190
- return ctrl.Result {}, nil
191
- }
192
-
193
111
// Check if the deployment already exists, if not create a new one
194
112
found := & appsv1.Deployment {}
195
113
err = r .Get (ctx , types.NamespacedName {Name : memcached .Name , Namespace : memcached .Namespace }, found )
@@ -282,37 +200,19 @@ func (r *MemcachedReconciler) Reconcile(ctx context.Context, req ctrl.Request) (
282
200
return ctrl.Result {}, nil
283
201
}
284
202
285
- // finalizeMemcached will perform the required operations before delete the CR.
286
- func (r * MemcachedReconciler ) doFinalizerOperationsForMemcached (cr * cachev1alpha1.Memcached ) {
287
- // TODO(user): Add the cleanup steps that the operator
288
- // needs to do before the CR can be deleted. Examples
289
- // of finalizers include performing backups and deleting
290
- // resources that are not owned by this CR, like a PVC.
291
-
292
- // Note: It is not recommended to use finalizers with the purpose of deleting resources which are
293
- // created and managed in the reconciliation. These ones, such as the Deployment created on this reconcile,
294
- // are defined as dependent of the custom resource. See that we use the method ctrl.SetControllerReference.
295
- // to set the ownerRef which means that the Deployment will be deleted by the Kubernetes API.
296
- // More info: https://kubernetes.io/docs/tasks/administer-cluster/use-cascading-deletion/
297
-
298
- // The following implementation will raise an event
299
- r .Recorder .Event (cr , "Warning" , "Deleting" ,
300
- fmt .Sprintf ("Custom Resource %s is being deleted from the namespace %s" ,
301
- cr .Name ,
302
- cr .Namespace ))
203
+ // SetupWithManager sets up the controller with the Manager.
204
+ func (r * MemcachedReconciler ) SetupWithManager (mgr ctrl.Manager ) error {
205
+ return ctrl .NewControllerManagedBy (mgr ).
206
+ For (& cachev1alpha1.Memcached {}).
207
+ Owns (& appsv1.Deployment {}).
208
+ Complete (r )
303
209
}
304
210
305
211
// deploymentForMemcached returns a Memcached Deployment object
306
212
func (r * MemcachedReconciler ) deploymentForMemcached (
307
213
memcached * cachev1alpha1.Memcached ) (* appsv1.Deployment , error ) {
308
- ls := labelsForMemcached ()
309
214
replicas := memcached .Spec .Size
310
-
311
- // Get the Operand image
312
- image , err := imageForMemcached ()
313
- if err != nil {
314
- return nil , err
315
- }
215
+ image := "memcached:1.6.26-alpine3.19"
316
216
317
217
dep := & appsv1.Deployment {
318
218
ObjectMeta : metav1.ObjectMeta {
@@ -322,46 +222,15 @@ func (r *MemcachedReconciler) deploymentForMemcached(
322
222
Spec : appsv1.DeploymentSpec {
323
223
Replicas : & replicas ,
324
224
Selector : & metav1.LabelSelector {
325
- MatchLabels : ls ,
225
+ MatchLabels : map [ string ] string { "app.kubernetes.io/name" : "project" } ,
326
226
},
327
227
Template : corev1.PodTemplateSpec {
328
228
ObjectMeta : metav1.ObjectMeta {
329
- Labels : ls ,
229
+ Labels : map [ string ] string { "app.kubernetes.io/name" : "project" } ,
330
230
},
331
231
Spec : corev1.PodSpec {
332
- // TODO(user): Uncomment the following code to configure the nodeAffinity expression
333
- // according to the platforms which are supported by your solution. It is considered
334
- // best practice to support multiple architectures. build your manager image using the
335
- // makefile target docker-buildx. Also, you can use docker manifest inspect <image>
336
- // to check what are the platforms supported.
337
- // More info: https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#node-affinity
338
- // Affinity: &corev1.Affinity{
339
- // NodeAffinity: &corev1.NodeAffinity{
340
- // RequiredDuringSchedulingIgnoredDuringExecution: &corev1.NodeSelector{
341
- // NodeSelectorTerms: []corev1.NodeSelectorTerm{
342
- // {
343
- // MatchExpressions: []corev1.NodeSelectorRequirement{
344
- // {
345
- // Key: "kubernetes.io/arch",
346
- // Operator: "In",
347
- // Values: []string{"amd64", "arm64", "ppc64le", "s390x"},
348
- // },
349
- // {
350
- // Key: "kubernetes.io/os",
351
- // Operator: "In",
352
- // Values: []string{"linux"},
353
- // },
354
- // },
355
- // },
356
- // },
357
- // },
358
- // },
359
- // },
360
232
SecurityContext : & corev1.PodSecurityContext {
361
233
RunAsNonRoot : & []bool {true }[0 ],
362
- // IMPORTANT: seccomProfile was introduced with Kubernetes 1.19
363
- // If you are looking for to produce solutions to be supported
364
- // on lower versions you must remove this option.
365
234
SeccompProfile : & corev1.SeccompProfile {
366
235
Type : corev1 .SeccompProfileTypeRuntimeDefault ,
367
236
},
@@ -383,7 +252,7 @@ func (r *MemcachedReconciler) deploymentForMemcached(
383
252
},
384
253
},
385
254
Ports : []corev1.ContainerPort {{
386
- ContainerPort : memcached . Spec . ContainerPort ,
255
+ ContainerPort : 11211 ,
387
256
Name : "memcached" ,
388
257
}},
389
258
Command : []string {"memcached" , "-m=64" , "-o" , "modern" , "-v" },
@@ -400,49 +269,3 @@ func (r *MemcachedReconciler) deploymentForMemcached(
400
269
}
401
270
return dep , nil
402
271
}
403
-
404
- // labelsForMemcached returns the labels for selecting the resources
405
- // More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/common-labels/
406
- func labelsForMemcached () map [string ]string {
407
- var imageTag string
408
- image , err := imageForMemcached ()
409
- if err == nil {
410
- imageTag = strings .Split (image , ":" )[1 ]
411
- }
412
- return map [string ]string {"app.kubernetes.io/name" : "project" ,
413
- "app.kubernetes.io/version" : imageTag ,
414
- "app.kubernetes.io/managed-by" : "MemcachedController" ,
415
- }
416
- }
417
-
418
- // imageForMemcached gets the Operand image which is managed by this controller
419
- // from the MEMCACHED_IMAGE environment variable defined in the config/manager/manager.yaml
420
- func imageForMemcached () (string , error ) {
421
- var imageEnvVar = "MEMCACHED_IMAGE"
422
- image , found := os .LookupEnv (imageEnvVar )
423
- if ! found {
424
- return "" , fmt .Errorf ("Unable to find %s environment variable with the image" , imageEnvVar )
425
- }
426
- return image , nil
427
- }
428
-
429
- // SetupWithManager sets up the controller with the Manager.
430
- // The whole idea is to be watching the resources that matter for the controller.
431
- // When a resource that the controller is interested in changes, the Watch triggers
432
- // the controller’s reconciliation loop, ensuring that the actual state of the resource
433
- // matches the desired state as defined in the controller’s logic.
434
- //
435
- // Notice how we configured the Manager to monitor events such as the creation, update,
436
- // or deletion of a Custom Resource (CR) of the Memcached kind, as well as any changes
437
- // to the Deployment that the controller manages and owns.
438
- func (r * MemcachedReconciler ) SetupWithManager (mgr ctrl.Manager ) error {
439
- return ctrl .NewControllerManagedBy (mgr ).
440
- // Watch the Memcached CR(s) and trigger reconciliation whenever it
441
- // is created, updated, or deleted
442
- For (& cachev1alpha1.Memcached {}).
443
- // Watch the Deployment managed by the MemcachedReconciler. If any changes occur to the Deployment
444
- // owned and managed by this controller, it will trigger reconciliation, ensuring that the cluster
445
- // state aligns with the desired state. See that the ownerRef was set when the Deployment was created.
446
- Owns (& appsv1.Deployment {}).
447
- Complete (r )
448
- }
0 commit comments