How do I have to specify the comments like +kubebuilder:printcolumn
to add columns to the output of the command kubectl get my-crd.my-group.my-domain.com
?
I've a CRD (Custom Resource Definition) with the usual struct
s for the specs and the status (similar to what's explained in the Kubebuilder tutorial here https://book.kubebuilder.io/cronjob-tutorial/new-api.html#adding-a-new-api).
I've a Status struct
like this:
type ScheduleSetStatus struct {
// When was the last time the Schedule Set
// was successfully deployed.
LastDeployTime string `json:"lastDeployTime"` // metav1.Time
// The CronJobs that have been successfully deployed
DeployedCronJobs []string `json:"deployedCronJobs"`
// The CronJobs that had errors when the deployment
// has been attempted.
ErroredCronJobs map[string]string `json:"erroredCronJobs"` // TODO `error` JSON serialisable
}
Which has a few problems:
The time field
metav1.Time
(handy formatting as they state at https://book.kubebuilder.io/cronjob-tutorial/api-design.html?highlight=metav1.Time#designing-an-api), but then this comment // +kubebuilder:printcolumn:name="Last Deploy",type="date",JSONPath=
.status.lastDeployTime
shows as empty in the output of kubectl
.string
(then in the controller doing oess.Status.LastDeployTime = fmt.Sprintf("%s", metav1.Time{Time: time.Now().UTC()})
), then adding the comment +kubebuilder:printcolumn:name="Last Deploy",type=string,JSONPath=
.status.lastDeployTime
but still the field is shown as empty in the output of kubectl
.The slice field []string
and the map field map[string]string
kubectl
, does that mean the only option I have is to make them string
with some sort of fmt.Sprintf(...)
?The solution was to add the code to update the resource status in
the reconciler method of the controller - Reconcile(ctx context.Context, req ctrl.Request)
, like this:
// Update the status for "last deploy time" of a ScheduleSet
myStruct.Status.LastDeployTime = metav1.Time{Time: time.Now().UTC()} // https://book.kubebuilder.io/cronjob-tutorial/api-design.html?highlight=metav1.Time#designing-an-api
if err := r.Status().Update(ctx, &myStruct); err != nil {
log.Error(err, "unable to update status xyz")
return ctrl.Result{}, err
}
The special Kubebuilder annotation was all right:
//+kubebuilder:printcolumn:name="Last Deploy",type="date",JSONPath=`.status.lastDeployTime`
Also, Go slices and Go maps work out of the box with comments like:
...
DeployedCronJobs []string `json:"deployedCronJobs"`
...
ErroredCronJobs map[string]string `json:"erroredCronJobs"`
...
//+kubebuilder:printcolumn:name="Deployed CJs",type=string,JSONPath=`.status.deployedCronJobs`
//+kubebuilder:printcolumn:name="Errored CJs",type=string,JSONPath=`.status.erroredCronJobs`