I'm writing a controller that watches kubernetes service objects, and creates trafficsplits if they contain a certain label.
Since the native kubernetes go client does not support the trafficsplit object, I had to find a way and extend the client so it would recognize the custom resource. I found this guide which was helpful and allowed me to tackle the issue like so -
import (
"splitClientV1alpha1 "github.com/servicemeshinterface/smi-sdk-go/pkg/gen/client/split/clientset/versioned/typed/split/v1alpha1"
"k8s.io/client-go/kubernetes"
...
)
// getting ./kube/config from file
kubehome := filepath.Join(homedir.HomeDir(), ".kube", "config")
// Building the config from file
kubeConfig, err = clientcmd.BuildConfigFromFlags("", kubehome)
if err != nil {
return fmt.Errorf("error loading kubernetes configuration: %w", err)
}
// Creating the native client object
kubeClient, err := kubernetes.NewForConfig(kubeConfig)
if err != nil {
return fmt.Errorf("error creating kubernetes client: %w", err)
}
// Creating another clientset exclusively for the custom resource
splitClient, err := splitClientV1alpha1.NewForConfig(kubeConfig)
if err != nil {
return fmt.Errorf("error creating split client: %s", err)
}
I feel like there must be a way to extend the kubeClient object with the trafficsplit schema, instead of creating a separate client like I did. Is there any way to achieve this?
This is definitely possible! You want to use go's struct extension features :)
Bsasically, we create a struct that extends both
kubernetes.Clientset
andsplitClientV1alpha1.SplitV1alpha1Client
and initialize it using code very similar to yours above. We can then use methods from either client on that struct.If you need to pass your custom client to a function that expects only the original
kubernetes.ClientSet
, you can do that with: