K8s Operator - Conditions
Tags: kubernetes, devops, sre, tutorial
Published: 2023-06-26 13:00:00

After seeing how to manage resources status, we will go one step further today and define **Conditions**.

## What are those conditions?
If you already worked with Kubernetes and describe resources, you've already seen some conditions without realizing they are here. But this element is really important:

> Conditions are a list of checks done on a resource to be sure that the resource is in a **Ready** state.

---

## Why implement them?
If it's really important to implement them it's because they will gives us a **lot of informations** for debugging.

In our serie example, MyProxy can have a condition **"Pods are correctly started"**. So with it we can directly see in the resource status if everything goes well.

Another way it can be really useful is by using them as **requirements to create another resource or to do a particular action**.

---

## How to implement it?
Like the status, we must update the resource status definition in `api/../xxx_types.go` and modify the status update in the **Reconcile** method of the controller.

### Update status definition
In the status, we will add a new variable `Conditions`

```go
type MyProxyStatus struct {  
   Conditions []metav1.Condition `json:"conditions"`  
   PodNames   []string           `json:"pod_names"`  
}
```

### Update Reconcile function
Like any other resource variable, we can update the value of the `Conditions` parameter.
```go
myProxy.Status.Conditions = conditions  
err = r.Status().Update(ctx, myProxy)  
if err != nil {  
   log.Error(err, "Failed to update MyProxy status")  
   return ctrl.Result{}, err  
}
```
But how do we create them?

### Create conditions
Conditions objects are quite simple, with only 4 fields:

- **Status** : Which will contain the status of the condition. It only accepts 3 values
	- `metav1.ConditionTrue` : If the condition is resolved
	- `metav1.ConditionFalse` : If the condition isn't resolved
	- `metav1.ConditionUnknown` : If there are not enough informations to resolve the status of the condition
- **Type** : Name of the condition *(ex: Check pods health)*
- **Reason** : A status summary *(ex: Healthy pods)*
- **Message** : A longer message which adds details on the condition status *(Generally used to detail an error)*

From here, we can now create methods which will create `Conditions` to fill the conditions variable defined earlier.

*Example*
```go
func checkPodExistance(podNames []string) metav1.Condition {  
   if len(podNames) == 2 {  
      return metav1.Condition{  
         Status:  metav1.ConditionTrue,  
         Reason:  "Pods found",  
         Message: "Both pods were found",  
         Type:    "Check existance of pods",  
      }  
   } else {  
      return metav1.Condition{  
         Status:  metav1.ConditionFalse,  
         Reason:  "Pods not found",  
         Message: "The list of pod names doesn't contains the correct number of pods",  
         Type:    "Check existance of pods",  
      }  
   }  
}
```

---

Conditions are a powerful tool and you won't be able to do without once you tested it!

In the next episode of this serie, we will focus on annotations that we can add in our operator!

I hope it will help you and if you have any questions *(there are not dumb questions)* or some points are not clear for you, don't hesitate to add your question in the comments or to contact me directly on  [LinkedIn](https://www.linkedin.com/in/maxime-guilbert-14b6a5128/).

---

<center><h3>You want to support me?</h3></center>
<a href="https://www.buymeacoffee.com/mxguilbert7" target="_blank"><img src="https://cdn.buymeacoffee.com/buttons/default-orange.png" alt="Buy Me A Coffee" height="41" width="174"></a>