Now that we know how to manage resources status and conditions, it's time to see annotations.
All the annotations comes from Kubebuilder.
There are a lot of different annotations, and we already saw some of them because we defined RBAC rights for our operator with annotations.
// +kubebuilder:rbac:groups=apps,resources=deployments,verbs=get;list;watch;create;update;patch;delete
// +kubebuilder:rbac:groups=core,resources=services,verbs=get;list;watch;create;update;patch;delete
Today, we will see 4 annotations which will help us to be more efficient when using custom resources and/or to debug them.
1. Resource
This annotation must be above the resource struct definition. (in api/.../xxx_types.go)
Composed with 3 major parts, they are used to :
- Define the operator "scope" (if the operator is Namespace-scope or Cluster-scope)
-
Define the list of alternate names that can be used to access the resource (When you do
kubectl get ...
). Each name must be separated by;
-
Define the singular for the resource name (Also to use it when you do
kubectl get ...
)
//+kubebuilder:resource:scope=Cluster,shortName=myproxies;mp,singular=myproxy
type MyProxy struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`
Spec MyProxySpec `json:"spec,omitempty"`
Status MyProxyStatus `json:"status,omitempty"`
}
2. Printcolumn
Having custom resources is good, but being able to display important informations with kubectl get
is better!
Still above the resource struct definition (in api/.../xxx_types.go), you can define custom columns with the following pattern
// +kubebuilder:printcolumn:name="NAME",type=TYPE,JSONPath=JSONPATH
NAME : The name of the custom column.
TYPE : To define the type of data you want to display. (ex: String, number...)
Check the OpenAPI Specification to know which type can be used.
JSONPATH : To define the JSONPath to use to access the information in the custom resource. If the information isn't available in the resource, you won't be able to display it.
Check the Kubernetes documentation to know how to write a JSONPath value.
Example
// +kubebuilder:printcolumn:name="Name",type=string,JSONPath=`.spec.name`
Here are 3 more specific cases about this annotation!
2.1. Priority
When we want to get the information of a resource, we can use the option -o wide
to get more informations than default.
To do it with the operator, you just need to add ,priority=10
(or any value strictly greater than 0) in the printcolumn definition of the value you only want to display with the option -o wide
.
Example
// +kubebuilder:printcolumn:name="Name",type=string,JSONPath=`.spec.name`,priority=10
2.2. Age
By default when you do kubectl get ...
on your custom resource, their age is shown. But once you've added one printcolumn, the information isn't displayed anymore.
So if you want to keep the information, here is the annotation you must add.
// +kubebuilder:printcolumn:name="Age",type=date,JSONPath=.metadata.creationTimestamp
2.3. Ready
Previously in this serie, we talked about conditions and we said that it can be useful to know if everything goes well. With the following column, we will be able to easily see if everything goes well or not.
// +kubebuilder:printcolumn:name="Ready",type=string,JSONPath=`.status.conditions[?(@.type=="Ready")].status`
3. Validation
The following annotation simply add validations on your spec fields.
Here are a bunch of them :
-
Make mandatory a field :
//+kubebuilder:validation:Required
-
Make a field optional :
// +kubebuilder:validation:Optional
-
Define the minimum length of a string :
//+kubebuilder:validation:MinLength=8
-
Define the maximum length of a string :
//+kubebuilder:validation:MaxLength=20
-
Check if the value is contain in a Enum list :
// +kubebuilder:validation:Enum=earth;wind;fire
-
Define the minimum number of elements in an array :
//+kubebuilder:validation:MinItems=2
- For a number, check if the value is a multiple of a particular value :
//+kubebuilder:validation:MultipleOf=15
There are a lot more, and if you are interested, go check the KubeBuilder documentation. But with all these examples, you have a great idea about what can be done or not.
4. Default
The last annotation we will see today is the one which defines a default value for a spec field.
It can be really useful in case of an optional field..
Examples
// +kubebuilder:default:=test
// +kubebuilder:default:=0
Now that you know all of these annotations, you will be able to easily do a lot more with your operator.
In the next part of this serie, we will leave the tutorial part to talk about an operator which already exists : Crossplane!
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.
Top comments (0)