@@ -19,28 +19,22 @@ package controller
1919import (
2020 "context"
2121 "fmt"
22- "os"
23- "strings"
24- "time"
25-
2622 appsv1 "k8s.io/api/apps/v1"
2723 corev1 "k8s.io/api/core/v1"
2824 apierrors "k8s.io/apimachinery/pkg/api/errors"
2925 "k8s.io/apimachinery/pkg/api/meta"
3026 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
31- "k8s.io/apimachinery/pkg/runtime"
3227 "k8s.io/apimachinery/pkg/types"
33- "k8s.io/client-go/tools/record"
28+ "time"
29+
30+ "k8s.io/apimachinery/pkg/runtime"
3431 ctrl "sigs.k8s.io/controller-runtime"
3532 "sigs.k8s.io/controller-runtime/pkg/client"
36- "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
3733 "sigs.k8s.io/controller-runtime/pkg/log"
3834
3935 cachev1alpha1 "example.com/memcached/api/v1alpha1"
4036)
4137
42- const memcachedFinalizer = "cache.example.com/finalizer"
43-
4438// Definitions to manage status conditions
4539const (
4640 // typeAvailableMemcached represents the status of the Deployment reconciliation
@@ -52,14 +46,9 @@ const (
5246// MemcachedReconciler reconciles a Memcached object
5347type MemcachedReconciler struct {
5448 client.Client
55- Scheme * runtime.Scheme
56- Recorder record.EventRecorder
49+ Scheme * runtime.Scheme
5750}
5851
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-
6352// +kubebuilder:rbac:groups=cache.example.com,resources=memcacheds,verbs=get;list;watch;create;update;patch;delete
6453// +kubebuilder:rbac:groups=cache.example.com,resources=memcacheds/status,verbs=get;update;patch
6554// +kubebuilder:rbac:groups=cache.example.com,resources=memcacheds/finalizers,verbs=update
@@ -77,6 +66,8 @@ type MemcachedReconciler struct {
7766// For further info:
7867// - About Operator Pattern: https://kubernetes.io/docs/concepts/extend-kubernetes/operator/
7968// - About Controllers: https://kubernetes.io/docs/concepts/architecture/controller/
69+ //
70+ // For more details, check Reconcile and its Result here:
8071// - https://pkg.go.dev/sigs.k8s.io/[email protected] /pkg/reconcile 8172func (r * MemcachedReconciler ) Reconcile (ctx context.Context , req ctrl.Request ) (ctrl.Result , error ) {
8273 log := log .FromContext (ctx )
@@ -117,79 +108,6 @@ func (r *MemcachedReconciler) Reconcile(ctx context.Context, req ctrl.Request) (
117108 }
118109 }
119110
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-
193111 // Check if the deployment already exists, if not create a new one
194112 found := & appsv1.Deployment {}
195113 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) (
282200 return ctrl.Result {}, nil
283201}
284202
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 )
303209}
304210
305211// deploymentForMemcached returns a Memcached Deployment object
306212func (r * MemcachedReconciler ) deploymentForMemcached (
307213 memcached * cachev1alpha1.Memcached ) (* appsv1.Deployment , error ) {
308- ls := labelsForMemcached ()
309214 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"
316216
317217 dep := & appsv1.Deployment {
318218 ObjectMeta : metav1.ObjectMeta {
@@ -322,46 +222,15 @@ func (r *MemcachedReconciler) deploymentForMemcached(
322222 Spec : appsv1.DeploymentSpec {
323223 Replicas : & replicas ,
324224 Selector : & metav1.LabelSelector {
325- MatchLabels : ls ,
225+ MatchLabels : map [ string ] string { "app.kubernetes.io/name" : "project" } ,
326226 },
327227 Template : corev1.PodTemplateSpec {
328228 ObjectMeta : metav1.ObjectMeta {
329- Labels : ls ,
229+ Labels : map [ string ] string { "app.kubernetes.io/name" : "project" } ,
330230 },
331231 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- // },
360232 SecurityContext : & corev1.PodSecurityContext {
361233 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.
365234 SeccompProfile : & corev1.SeccompProfile {
366235 Type : corev1 .SeccompProfileTypeRuntimeDefault ,
367236 },
@@ -383,7 +252,7 @@ func (r *MemcachedReconciler) deploymentForMemcached(
383252 },
384253 },
385254 Ports : []corev1.ContainerPort {{
386- ContainerPort : memcached . Spec . ContainerPort ,
255+ ContainerPort : 11211 ,
387256 Name : "memcached" ,
388257 }},
389258 Command : []string {"memcached" , "-m=64" , "-o" , "modern" , "-v" },
@@ -400,49 +269,3 @@ func (r *MemcachedReconciler) deploymentForMemcached(
400269 }
401270 return dep , nil
402271}
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