Skip to content

Instantly share code, notes, and snippets.

@leosunmo
Last active August 19, 2020 23:01
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save leosunmo/9caed42b6a9a269f805caea9bf935840 to your computer and use it in GitHub Desktop.
Save leosunmo/9caed42b6a9a269f805caea9bf935840 to your computer and use it in GitHub Desktop.
Simple K8s client to query API resources
module simple-k8s-client
go 1.15
require (
github.com/golang/protobuf v1.4.2 // indirect
github.com/imdario/mergo v0.3.11 // indirect
golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de // indirect
golang.org/x/net v0.0.0-20200813134508-3edf25e44fcc // indirect
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d // indirect
golang.org/x/time v0.0.0-20200630173020-3af7569d3a1e // indirect
k8s.io/client-go v0.18.8
k8s.io/utils v0.0.0-20200815180417-3bc9d57fc792 // indirect
)
package main
import (
"flag"
"fmt"
"log"
"strings"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/tools/clientcmd"
)
func main() {
// flag.String() returns a _pointer_ to a string ('*string' vs 'string').
// This means we have to access it using '*' if we need a string value instead of a string pointer, for example '*kubeAPIAddress'.
var kubeAPIAddress, kubeConfPath *string
kubeAPIAddress = flag.String("kubeAPI", "", "Kuberenetes API address. Leave empty to auto-discover.")
kubeConfPath = flag.String("kubeConf", "", "Kube config path. Leave empty to auto-discover.")
// We have to parse the commandline flags before we can use them.
flag.Parse()
// Build a Rest config. Passing the values with '*' since BuildConfigFromFlags wants string values, not string pointers.
restConfig, err := clientcmd.BuildConfigFromFlags(*kubeAPIAddress, *kubeConfPath)
if err != nil {
log.Fatalf("failed to build k8s rest config, %s\n", err.Error())
}
// Using the rest config, get a K8s clientSet. The client set can be used to
// return all different clients we might need to query different apis.
// For example, ClientSet.AppsV1() to get a Apps/v1 client for querying
// Deployments.
ClientSet, err := kubernetes.NewForConfig(restConfig)
if err != nil {
log.Fatalf("failed to create k8s clientset from rest config, %s\n", err.Error())
}
// Get a Server Groups and Resources client to list all the available
// resources and API groups. It's quite a few of them so need to be a
// bit selective probably.
apiGroups, apiResources, err := ClientSet.ServerGroupsAndResources()
if err != nil {
log.Fatalf("failed to retreive api groups and resources, %s\n", err.Error())
}
// Let's print out the API groups and resources we find in a somewhat
// easy to read tab format.
fmt.Println("API Groups:")
// Print all the API groups we find
for _, apiGroup := range apiGroups {
fmt.Printf("\tName: %s\n", apiGroup.Name)
}
fmt.Printf("\nAPI Resources:\n")
// Print all the api resource lists we find.
for _, apiResourceList := range apiResources {
// Custom metrics is extremely noisy, skip it.
if apiResourceList.GroupVersion == "custom.metrics.k8s.io/v1beta1" {
continue
}
fmt.Printf("Group Version: %s\n", apiResourceList.GroupVersion)
// For each api resource list, print the api resources in that list.
for _, apiResource := range apiResourceList.APIResources {
fmt.Printf("\tName: %s\n", apiResource.Name)
fmt.Printf("\tKind: %s\n", apiResource.Kind)
fmt.Printf("\tNamespaced: %v\n", apiResource.Namespaced)
// Join the available verbs and print them newline separated
sepVerbs := strings.Join(apiResource.Verbs, "\n\t\t")
fmt.Printf("\tVerbs:\n\t\t%s\n\n", sepVerbs)
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment