Skip to content

Instantly share code, notes, and snippets.

@quentinalbertone
Last active May 3, 2022 13:46
Show Gist options
  • Save quentinalbertone/ec00085b57992d836c08d4586295ace7 to your computer and use it in GitHub Desktop.
Save quentinalbertone/ec00085b57992d836c08d4586295ace7 to your computer and use it in GitHub Desktop.
Use url.URL type with controller-gen (kubernetes-operator)
// api/v1/example_types.go
// link to the post : https://stackoverflow.com/questions/72097153/use-url-url-with-controller-gen
// A part of an example CRD
package v1
import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"{path_of_your_module}/internal/url"
)
// ExampleSpec defines the desired state of Example
type ExampleSpec struct {
// In order to validate the url as a string use the marker Type=string
// +kubebuilder:validation:Type=string
// +kubebuilder:validation:MinLength=42
Url *url.URL `json:"url,omitempty"`
}
//+kubebuilder:object:root=true
//+kubebuilder:subresource:status
// Example is the Schema for the Examples API
type Example struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`
Spec ExampleSpec `json:"spec,omitempty"`
Status ExampleStatus `json:"status,omitempty"`
}
// ExampleStatus defines the observed state of Example
type ExampleStatus struct {
[...]
}
// internal/url/url.go
// link to the post : https://stackoverflow.com/questions/72097153/use-url-url-with-controller-gen
package url
import (
"encoding/json"
"fmt"
"net/url"
)
// URL wraps url.URL.
// It has custom json marshal methods that enable it to be used in K8s CRDs
// such that the CRD resource will have the URL but operator code can can work with url.URL struct
type URL struct {
url.URL
}
func (u *URL) MarshalJSON() ([]byte, error) {
return []byte(fmt.Sprintf("%q", u.String())), nil
}
func (u *URL) UnmarshalJSON(b []byte) error {
var ref string
if err := json.Unmarshal(b, &ref); err != nil {
return err
}
if ref == "" {
*u = URL{}
return nil
}
r, err := url.Parse(ref)
if err != nil {
return err
} else if r != nil {
*u = URL{*r}
} else {
*u = URL{}
}
return nil
}
func (u *URL) String() string {
if u == nil {
return ""
}
return u.URL.String()
}
// DeepCopyInto copy the receiver, write into out. in must be non-nil.
func (in *URL) DeepCopyInto(out *URL) {
*out = *in
}
// DeepCopy copy the receiver, create a new URL.
func (in *URL) DeepCopy() *URL {
if in == nil {
return nil
}
out := new(URL)
in.DeepCopyInto(out)
return out
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment