github.com/ali-iotechsys/cli@v20.10.0+incompatible/cli/context/kubernetes/load.go (about) 1 package kubernetes 2 3 import ( 4 "os" 5 "path/filepath" 6 7 "github.com/docker/cli/cli/command" 8 "github.com/docker/cli/cli/context" 9 "github.com/docker/cli/cli/context/store" 10 api "github.com/docker/compose-on-kubernetes/api" 11 "github.com/docker/docker/pkg/homedir" 12 "github.com/pkg/errors" 13 "k8s.io/client-go/tools/clientcmd" 14 clientcmdapi "k8s.io/client-go/tools/clientcmd/api" 15 ) 16 17 // EndpointMeta is a typed wrapper around a context-store generic endpoint describing 18 // a Kubernetes endpoint, without TLS data 19 type EndpointMeta struct { 20 context.EndpointMetaBase 21 DefaultNamespace string `json:",omitempty"` 22 AuthProvider *clientcmdapi.AuthProviderConfig `json:",omitempty"` 23 Exec *clientcmdapi.ExecConfig `json:",omitempty"` 24 UsernamePassword *UsernamePassword `json:"usernamePassword,omitempty"` 25 } 26 27 // UsernamePassword contains username/password auth info 28 type UsernamePassword struct { 29 Username string `json:"username,omitempty"` 30 Password string `json:"password,omitempty"` 31 } 32 33 var _ command.EndpointDefaultResolver = &EndpointMeta{} 34 35 // Endpoint is a typed wrapper around a context-store generic endpoint describing 36 // a Kubernetes endpoint, with TLS data 37 type Endpoint struct { 38 EndpointMeta 39 TLSData *context.TLSData 40 } 41 42 func init() { 43 command.RegisterDefaultStoreEndpoints( 44 store.EndpointTypeGetter(KubernetesEndpoint, func() interface{} { return &EndpointMeta{} }), 45 ) 46 } 47 48 // WithTLSData loads TLS materials for the endpoint 49 func (c *EndpointMeta) WithTLSData(s store.Reader, contextName string) (Endpoint, error) { 50 tlsData, err := context.LoadTLSData(s, contextName, KubernetesEndpoint) 51 if err != nil { 52 return Endpoint{}, err 53 } 54 return Endpoint{ 55 EndpointMeta: *c, 56 TLSData: tlsData, 57 }, nil 58 } 59 60 // KubernetesConfig creates the kubernetes client config from the endpoint 61 func (c *Endpoint) KubernetesConfig() clientcmd.ClientConfig { 62 cfg := clientcmdapi.NewConfig() 63 cluster := clientcmdapi.NewCluster() 64 cluster.Server = c.Host 65 cluster.InsecureSkipTLSVerify = c.SkipTLSVerify 66 authInfo := clientcmdapi.NewAuthInfo() 67 if c.TLSData != nil { 68 cluster.CertificateAuthorityData = c.TLSData.CA 69 authInfo.ClientCertificateData = c.TLSData.Cert 70 authInfo.ClientKeyData = c.TLSData.Key 71 } 72 if c.UsernamePassword != nil { 73 authInfo.Username = c.UsernamePassword.Username 74 authInfo.Password = c.UsernamePassword.Password 75 } 76 authInfo.AuthProvider = c.AuthProvider 77 authInfo.Exec = c.Exec 78 cfg.Clusters["cluster"] = cluster 79 cfg.AuthInfos["authInfo"] = authInfo 80 ctx := clientcmdapi.NewContext() 81 ctx.AuthInfo = "authInfo" 82 ctx.Cluster = "cluster" 83 ctx.Namespace = c.DefaultNamespace 84 cfg.Contexts["context"] = ctx 85 cfg.CurrentContext = "context" 86 return clientcmd.NewDefaultClientConfig(*cfg, &clientcmd.ConfigOverrides{}) 87 } 88 89 // ResolveDefault returns endpoint metadata for the default Kubernetes 90 // endpoint, which is derived from the env-based kubeconfig. 91 func (c *EndpointMeta) ResolveDefault(stackOrchestrator command.Orchestrator) (interface{}, *store.EndpointTLSData, error) { 92 kubeconfig := os.Getenv("KUBECONFIG") 93 if kubeconfig == "" { 94 kubeconfig = filepath.Join(homedir.Get(), ".kube/config") 95 } 96 kubeEP, err := FromKubeConfig(kubeconfig, "", "") 97 if err != nil { 98 if stackOrchestrator == command.OrchestratorKubernetes || stackOrchestrator == command.OrchestratorAll { 99 return nil, nil, errors.Wrapf(err, "default orchestrator is %s but unable to resolve kubernetes endpoint", stackOrchestrator) 100 } 101 102 // We deliberately quash the error here, returning nil 103 // for the first argument is sufficient to indicate we weren't able to 104 // provide a default 105 return nil, nil, nil 106 } 107 108 var tls *store.EndpointTLSData 109 if kubeEP.TLSData != nil { 110 tls = kubeEP.TLSData.ToStoreTLSData() 111 } 112 return kubeEP.EndpointMeta, tls, nil 113 } 114 115 // EndpointFromContext extracts kubernetes endpoint info from current context 116 func EndpointFromContext(metadata store.Metadata) *EndpointMeta { 117 ep, ok := metadata.Endpoints[KubernetesEndpoint] 118 if !ok { 119 return nil 120 } 121 typed, ok := ep.(EndpointMeta) 122 if !ok { 123 return nil 124 } 125 return &typed 126 } 127 128 // ConfigFromContext resolves a kubernetes client config for the specified context. 129 // If kubeconfigOverride is specified, use this config file instead of the context defaults.ConfigFromContext 130 // if command.ContextDockerHost is specified as the context name, fallsback to the default user's kubeconfig file 131 func ConfigFromContext(name string, s store.Reader) (clientcmd.ClientConfig, error) { 132 ctxMeta, err := s.GetMetadata(name) 133 if err != nil { 134 return nil, err 135 } 136 epMeta := EndpointFromContext(ctxMeta) 137 if epMeta != nil { 138 ep, err := epMeta.WithTLSData(s, name) 139 if err != nil { 140 return nil, err 141 } 142 return ep.KubernetesConfig(), nil 143 } 144 // context has no kubernetes endpoint 145 return api.NewKubernetesConfig(""), nil 146 }