Official Go client library for Kubernetes API - typed clients, controllers, and cluster interaction tools
The discovery client allows you to discover what APIs, resources, and versions are available in a Kubernetes cluster at runtime.
k8s.io/client-go/discoveryk8s.io/client-go/discovery/cachedk8s.io/client-go/restmapperimport (
"k8s.io/client-go/discovery"
"k8s.io/apimachinery/pkg/runtime/schema"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)import (
"k8s.io/client-go/discovery"
"k8s.io/client-go/kubernetes"
)
// From config
discoveryClient, err := discovery.NewDiscoveryClientForConfig(config)
// From clientset
clientset, _ := kubernetes.NewForConfig(config)
discoveryClient := clientset.Discovery()type DiscoveryInterface interface {
RESTClient() rest.Interface
ServerGroupsInterface
ServerResourcesInterface
ServerVersionInterface
OpenAPISchemaInterface
OpenAPIV3SchemaInterface
}
type ServerGroupsInterface interface {
ServerGroups() (*metav1.APIGroupList, error)
}
type ServerResourcesInterface interface {
ServerResourcesForGroupVersion(groupVersion string) (*metav1.APIResourceList, error)
ServerGroupsAndResources() ([]*metav1.APIGroup, []*metav1.APIResourceList, error)
ServerPreferredResources() ([]*metav1.APIResourceList, error)
ServerPreferredNamespacedResources() ([]*metav1.APIResourceList, error)
}
type ServerVersionInterface interface {
ServerVersion() (*version.Info, error)
}// Get all API groups
groups, err := discoveryClient.ServerGroups()
if err != nil {
panic(err)
}
for _, group := range groups.Groups {
fmt.Printf("Group: %s\n", group.Name)
fmt.Printf(" Preferred Version: %s\n", group.PreferredVersion.Version)
for _, version := range group.Versions {
fmt.Printf(" Available Version: %s\n", version.Version)
}
}
// Example output:
// Group: apps
// Preferred Version: v1
// Available Version: v1
// Available Version: v1beta2
// Available Version: v1beta1// Get resources for specific API group version
resourceList, err := discoveryClient.ServerResourcesForGroupVersion("apps/v1")
if err != nil {
panic(err)
}
fmt.Printf("Group Version: %s\n", resourceList.GroupVersion)
for _, resource := range resourceList.APIResources {
fmt.Printf(" Resource: %s\n", resource.Name)
fmt.Printf(" Namespaced: %v\n", resource.Namespaced)
fmt.Printf(" Kind: %s\n", resource.Kind)
fmt.Printf(" Verbs: %v\n", resource.Verbs)
fmt.Printf(" ShortNames: %v\n", resource.ShortNames)
}
// Example output:
// Group Version: apps/v1
// Resource: deployments
// Namespaced: true
// Kind: Deployment
// Verbs: [create delete deletecollection get list patch update watch]
// ShortNames: [deploy]// Get all API groups and resources
groups, resources, err := discoveryClient.ServerGroupsAndResources()
if err != nil {
// Note: This may return partial results with error
// if some API groups are unavailable
}
for _, resourceList := range resources {
fmt.Printf("API Group Version: %s\n", resourceList.GroupVersion)
for _, resource := range resourceList.APIResources {
fmt.Printf(" %s (%s)\n", resource.Name, resource.Kind)
}
}// Get preferred version resources only
resources, err := discoveryClient.ServerPreferredResources()
if err != nil {
panic(err)
}
// Get preferred namespaced resources only
resources, err := discoveryClient.ServerPreferredNamespacedResources()// Get Kubernetes server version
versionInfo, err := discoveryClient.ServerVersion()
if err != nil {
panic(err)
}
fmt.Printf("Major: %s\n", versionInfo.Major)
fmt.Printf("Minor: %s\n", versionInfo.Minor)
fmt.Printf("GitVersion: %s\n", versionInfo.GitVersion)
fmt.Printf("Platform: %s\n", versionInfo.Platform)
// Example output:
// Major: 1
// Minor: 27
// GitVersion: v1.27.3
// Platform: linux/amd64For better performance, use cached discovery:
import (
"k8s.io/client-go/discovery/cached/memory"
"k8s.io/client-go/restmapper"
)
// Create memory-cached discovery client
cachedDiscovery := memory.NewMemCacheClient(discoveryClient)
// Use cached client for discovery operations
groups, err := cachedDiscovery.ServerGroups()
// Invalidate cache
cachedDiscovery.Invalidate()REST mapper converts between GroupVersionKind (GVK) and GroupVersionResource (GVR):
import "k8s.io/client-go/restmapper"
// Create REST mapper from discovery
groupResources, err := restmapper.GetAPIGroupResources(discoveryClient)
if err != nil {
panic(err)
}
mapper := restmapper.NewDiscoveryRESTMapper(groupResources)
// Convert GVK to GVR
gvk := schema.GroupVersionKind{
Group: "apps",
Version: "v1",
Kind: "Deployment",
}
mapping, err := mapper.RESTMapping(gvk.GroupKind(), gvk.Version)
if err != nil {
panic(err)
}
gvr := mapping.Resource
fmt.Printf("GVR: %s\n", gvr.String()) // apps/v1, Resource=deployments
// Check if resource is namespaced
fmt.Printf("Namespaced: %v\n", mapping.Scope.Name() == meta.RESTScopeNameNamespace)
// Convert partial GVK (find preferred version)
gvk = schema.GroupVersionKind{
Group: "apps",
Kind: "Deployment",
}
mapping, err = mapper.RESTMapping(gvk.GroupKind())
if err != nil {
panic(err)
}
fmt.Printf("Preferred GVR: %s\n", mapping.Resource.String())// Check if a resource exists
func ResourceExists(discoveryClient discovery.DiscoveryInterface, gvr schema.GroupVersionResource) (bool, error) {
groupVersion := gvr.GroupVersion().String()
resourceList, err := discoveryClient.ServerResourcesForGroupVersion(groupVersion)
if err != nil {
return false, err
}
for _, resource := range resourceList.APIResources {
if resource.Name == gvr.Resource {
return true, nil
}
}
return false, nil
}
// Find resource by kind
func FindResourceByKind(discoveryClient discovery.DiscoveryInterface, kind string) (*metav1.APIResource, schema.GroupVersion, error) {
_, resources, err := discoveryClient.ServerGroupsAndResources()
if err != nil {
return nil, schema.GroupVersion{}, err
}
for _, resourceList := range resources {
gv, err := schema.ParseGroupVersion(resourceList.GroupVersion)
if err != nil {
continue
}
for _, resource := range resourceList.APIResources {
if resource.Kind == kind {
return &resource, gv, nil
}
}
}
return nil, schema.GroupVersion{}, fmt.Errorf("resource not found for kind: %s", kind)
}package main
import (
"fmt"
"k8s.io/client-go/discovery"
"k8s.io/client-go/tools/clientcmd"
)
func main() {
// Load config
config, err := clientcmd.BuildConfigFromFlags("", clientcmd.RecommendedHomeFile)
if err != nil {
panic(err)
}
// Create discovery client
discoveryClient, err := discovery.NewDiscoveryClientForConfig(config)
if err != nil {
panic(err)
}
// Get server version
version, err := discoveryClient.ServerVersion()
if err != nil {
panic(err)
}
fmt.Printf("Kubernetes version: %s\n\n", version.GitVersion)
// Get all API groups
groups, err := discoveryClient.ServerGroups()
if err != nil {
panic(err)
}
fmt.Println("Available API Groups:")
for _, group := range groups.Groups {
fmt.Printf("- %s (preferred: %s)\n", group.Name, group.PreferredVersion.Version)
}
fmt.Println("\nCore v1 Resources:")
coreResources, err := discoveryClient.ServerResourcesForGroupVersion("v1")
if err != nil {
panic(err)
}
for _, resource := range coreResources.APIResources {
nsStatus := "cluster-scoped"
if resource.Namespaced {
nsStatus = "namespaced"
}
fmt.Printf("- %s (%s, %s)\n", resource.Name, resource.Kind, nsStatus)
}
}Install with Tessl CLI
npx tessl i tessl/golang-k8s-io--client-go