-
-
Save hiboyang/6df5af66ede002e77afd7d3505f13991 to your computer and use it in GitHub Desktop.
Connect to Google Kubernetes with GCP credentials and pure Golang
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"context" | |
"encoding/base64" | |
"flag" | |
"fmt" | |
"log" | |
"google.golang.org/api/container/v1" | |
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | |
"k8s.io/client-go/kubernetes" | |
_ "k8s.io/client-go/plugin/pkg/client/auth/gcp" // register GCP auth provider | |
"k8s.io/client-go/tools/clientcmd" | |
"k8s.io/client-go/tools/clientcmd/api" | |
) | |
var fProjectId = flag.String("projectId", "", "specify a project id to examine") | |
func main() { | |
flag.Parse() | |
if *fProjectId == "" { | |
log.Fatal("must specific -projectId") | |
} | |
if err := run(context.Background(), *fProjectId); err != nil { | |
log.Fatal(err) | |
} | |
} | |
func run(ctx context.Context, projectId string) error { | |
kubeConfig, err := getK8sClusterConfigs(ctx, projectId) | |
if err != nil { | |
return err | |
} | |
// Just list all the namespaces found in the project to test the API. | |
for clusterName := range kubeConfig.Clusters { | |
cfg, err := clientcmd.NewNonInteractiveClientConfig(*kubeConfig, clusterName, &clientcmd.ConfigOverrides{CurrentContext: clusterName}, nil).ClientConfig() | |
if err != nil { | |
return fmt.Errorf("failed to create Kubernetes configuration cluster=%s: %w", clusterName, err) | |
} | |
k8s, err := kubernetes.NewForConfig(cfg) | |
if err != nil { | |
return fmt.Errorf("failed to create Kubernetes client cluster=%s: %w", clusterName, err) | |
} | |
ns, err := k8s.CoreV1().Namespaces().List(metav1.ListOptions{}) | |
if err != nil { | |
return fmt.Errorf("failed to list namespaces cluster=%s: %w", clusterName, err) | |
} | |
log.Printf("Namespaces found in cluster=%s", clusterName) | |
for _, item := range ns.Items { | |
log.Println(item.Name) | |
} | |
} | |
return nil | |
} | |
func getK8sClusterConfigs(ctx context.Context, projectId string) (*api.Config, error) { | |
svc, err := container.NewService(ctx) | |
if err != nil { | |
return nil, fmt.Errorf("container.NewService: %w", err) | |
} | |
// Basic config structure | |
ret := api.Config{ | |
APIVersion: "v1", | |
Kind: "Config", | |
Clusters: map[string]*api.Cluster{}, // Clusters is a map of referencable names to cluster configs | |
AuthInfos: map[string]*api.AuthInfo{}, // AuthInfos is a map of referencable names to user configs | |
Contexts: map[string]*api.Context{}, // Contexts is a map of referencable names to context configs | |
} | |
// Ask Google for a list of all kube clusters in the given project. | |
resp, err := svc.Projects.Zones.Clusters.List(projectId, "-").Context(ctx).Do() | |
if err != nil { | |
return nil, fmt.Errorf("clusters list project=%s: %w", projectId, err) | |
} | |
for _, f := range resp.Clusters { | |
name := fmt.Sprintf("gke_%s_%s_%s", projectId, f.Zone, f.Name) | |
cert, err := base64.StdEncoding.DecodeString(f.MasterAuth.ClusterCaCertificate) | |
if err != nil { | |
return nil, fmt.Errorf("invalid certificate cluster=%s cert=%s: %w", name, f.MasterAuth.ClusterCaCertificate, err) | |
} | |
// example: gke_my-project_us-central1-b_cluster-1 => https://XX.XX.XX.XX | |
ret.Clusters[name] = &api.Cluster{ | |
CertificateAuthorityData: cert, | |
Server: "https://" + f.Endpoint, | |
} | |
// Just reuse the context name as an auth name. | |
ret.Contexts[name] = &api.Context{ | |
Cluster: name, | |
AuthInfo: name, | |
} | |
// GCP specific configation; use cloud platform scope. | |
ret.AuthInfos[name] = &api.AuthInfo{ | |
AuthProvider: &api.AuthProviderConfig{ | |
Name: "gcp", | |
Config: map[string]string{ | |
"scopes": "https://www.googleapis.com/auth/cloud-platform", | |
}, | |
}, | |
} | |
} | |
return &ret, nil | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment