1+ package client
2+
3+ import (
4+ "fmt"
5+ "net/url"
6+
7+ "k8s.io/client-go/rest"
8+ "k8s.io/client-go/tools/clientcmd"
9+ kcapi "k8s.io/client-go/tools/clientcmd/api"
10+ )
11+
12+ const (
13+ envtestName = "envtest"
14+ )
15+
16+ // KubeConfigFromREST reverse-engineers a kubeconfig file from a rest.Config.
17+ // The options are tailored towards the rest.Configs we generate, so they're
18+ // not broadly applicable.
19+ //
20+ // This is not intended to be exposed outside envtest for the above reasons.
21+ func KubeConfigFromREST (cfg * rest.Config ) ([]byte , error ) {
22+ kubeConfig := kcapi .NewConfig ()
23+ protocol := "https"
24+ if ! rest .IsConfigTransportTLS (* cfg ) {
25+ protocol = "http"
26+ }
27+
28+ // cfg.Host is a URL, so we need to parse it so we can properly append the API path
29+ baseURL , err := url .Parse (cfg .Host )
30+ if err != nil {
31+ return nil , fmt .Errorf ("unable to interpret config's host value as a URL: %w" , err )
32+ }
33+
34+ kubeConfig .Clusters [envtestName ] = & kcapi.Cluster {
35+ // TODO(directxman12): if client-go ever decides to expose defaultServerUrlFor(config),
36+ // we can just use that. Note that this is not the same as the public DefaultServerURL,
37+ // which requires us to pass a bunch of stuff in manually.
38+ Server : (& url.URL {Scheme : protocol , Host : baseURL .Host , Path : cfg .APIPath }).String (),
39+ CertificateAuthorityData : cfg .CAData ,
40+ }
41+ kubeConfig .AuthInfos [envtestName ] = & kcapi.AuthInfo {
42+ // try to cover all auth strategies that aren't plugins
43+ ClientCertificateData : cfg .CertData ,
44+ ClientKeyData : cfg .KeyData ,
45+ Token : cfg .BearerToken ,
46+ Username : cfg .Username ,
47+ Password : cfg .Password ,
48+ }
49+ kcCtx := kcapi .NewContext ()
50+ kcCtx .Cluster = envtestName
51+ kcCtx .AuthInfo = envtestName
52+ kubeConfig .Contexts [envtestName ] = kcCtx
53+ kubeConfig .CurrentContext = envtestName
54+
55+ contents , err := clientcmd .Write (* kubeConfig )
56+ if err != nil {
57+ return nil , fmt .Errorf ("unable to serialize kubeconfig file: %w" , err )
58+ }
59+ return contents , nil
60+ }
0 commit comments