johnlinp
johnlinp

Reputation: 933

How to initialize the status of a CRD in Kubernetes?

I have created a CRD in my Kubernetes environment. The CRD has a corresponding operator. The operator will update the CRD's field .status.serviceState for the users to know the current state of the underlying service. The value of the field .status.serviceState could be one of "PENDING", "READY", "ERROR".

I wonder if there's a way to automatically initialize the field .status.serviceState to be "PENDING" when the CRD is created. Although I can do the initialization in the operator, I'm worried that user might still see the field uninitialized when there's a delay of the operator.

Any suggestion is appreciated.

Upvotes: 1

Views: 1075

Answers (1)

ahmet alp balkan
ahmet alp balkan

Reputation: 45302

As far as I know the only way to set status before the object is created is to do it through the OpenAPI spec itself, based on my experimentation webhooks don't help with this (since /status is a separate subresource that implicitly exists, and has no create verb on it you can intercept, and you cannot create a resource with status field pre-populated since status fields are only persisted through /status endpoint).

So, if you're using controller-gen to generate your CRD, you can achieve status field defaulting like this:

//+kubebuilder:object:root=true

type MyType struct {
    // +kubebuilder:default:={"phase":"PENDING"}
    Status MyTypeStatus `json:"status"`
}

type MyTypeStatus {
    // +kubebuilder:default:=PENDING
    Phase MyTypePhase `json:"phase"`
}

This does two interesting things:

  1. If request payload has status: null or completely unset in the payload, it initializes an empty struct with {"phase":"PENDING"}.
  2. If the request has a status: {} object set that doesn't have phase field specified, it defaults the field.

These two should essentially render it impossible to ever have status.phase unset.

Upvotes: 0

Related Questions