Search code examples
kuberneteskubectlkubernetes-go-clientkubernetes-custom-resourceskubebuilder

How to print Status fields defined in Kubebuilder to show up when using Kubectl


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 structs 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

  • I've tried that to be of type 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.
  • So I changed the type to be 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

  • How do I configure these? Here there's no mention (when clicking on "Show Detailed Argument Help"): https://book.kubebuilder.io/reference/markers/crd.html
  • In case these are not "simple types" with formatting issues when using kubectl, does that mean the only option I have is to make them string with some sort of fmt.Sprintf(...)?
  • Any other option?

Solution

  • 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`