DockerCLI/cli/context/kubernetes/load.go

136 lines
4.3 KiB
Go
Raw Normal View History

package kubernetes
import (
"os"
"path/filepath"
"github.com/docker/cli/cli/command"
"github.com/docker/cli/cli/context"
"github.com/docker/cli/cli/context/store"
Use underlying `NewKubernetesConfig` directly from compose-on-kubernetes. The comment on `github.com/docker/cli/kubernetes.NewKubernetesConfig` said: // Deprecated: Use github.com/docker/compose-on-kubernetes/api.NewKubernetesConfig instead By making this switch in `github.com/docker/cli/context/kubernetes/load.go` we break a vendoring chain: `github.com/docker/cli/cli/command` → `vendor/github.com/docker/cli/cli/context/kubernetes/load.go` → `vendor/github.com/docker/cli/kubernetes` → `github.com/docker/compose-on-kubernetes/api/compose/...` This means that projects which just want `github.com/docker/cli/cli/command` (which is itself pulled in transitively by `github.com/docker/cli/cli-plugins/plugin`) which do not themselves need the compose-on-kubernetes API avoid a huge pile of transitive dependencies. On one of my private projects the diff on the vendor dir is: 280 files changed, 21 insertions(+), 211346 deletions(-) and includes dropping: * `github.com/docker/compose-on-kubernetes/api/compose/{clone,impersonation}` * `github.com/docker/compose-on-kubernetes/api/compose/{v1alpha3,v1beta1,v1beta2,v1beta3}` * `github.com/google/btree` * `github.com/googleapis/gnostic` * `github.com/gregjones/httpcache` * `github.com/peterbourgon/diskv` * `k8s.io/api/*` (_lots_ of subpackages) * `k8s.io/client-go/{discovery,kubernetes/scheme}` and I've gone from: $ du -sh vendor/k8s.io/ 8.1M vendor/k8s.io/ to: $ du -sh vendor/k8s.io/ 2.1M vendor/k8s.io/ (overall I went from 36M → 29M of vendor dir for this particular project) The change to `cli/command/system/version.go` is just for consistency and allows us to drop the now unused alias. Signed-off-by: Ian Campbell <ijc@docker.com> (cherry picked from commit 8635abd662c8bb794eaee6f99d7fbf03e610e7e5) Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2019-05-14 10:12:06 -04:00
api "github.com/docker/compose-on-kubernetes/api"
"github.com/docker/docker/pkg/homedir"
"github.com/pkg/errors"
"k8s.io/client-go/tools/clientcmd"
clientcmdapi "k8s.io/client-go/tools/clientcmd/api"
)
// EndpointMeta is a typed wrapper around a context-store generic endpoint describing
// a Kubernetes endpoint, without TLS data
type EndpointMeta struct {
context.EndpointMetaBase
DefaultNamespace string `json:",omitempty"`
AuthProvider *clientcmdapi.AuthProviderConfig `json:",omitempty"`
Exec *clientcmdapi.ExecConfig `json:",omitempty"`
}
var _ command.EndpointDefaultResolver = &EndpointMeta{}
// Endpoint is a typed wrapper around a context-store generic endpoint describing
// a Kubernetes endpoint, with TLS data
type Endpoint struct {
EndpointMeta
TLSData *context.TLSData
}
func init() {
command.RegisterDefaultStoreEndpoints(
store.EndpointTypeGetter(KubernetesEndpoint, func() interface{} { return &EndpointMeta{} }),
)
}
// WithTLSData loads TLS materials for the endpoint
func (c *EndpointMeta) WithTLSData(s store.Reader, contextName string) (Endpoint, error) {
tlsData, err := context.LoadTLSData(s, contextName, KubernetesEndpoint)
if err != nil {
return Endpoint{}, err
}
return Endpoint{
EndpointMeta: *c,
TLSData: tlsData,
}, nil
}
// KubernetesConfig creates the kubernetes client config from the endpoint
func (c *Endpoint) KubernetesConfig() clientcmd.ClientConfig {
cfg := clientcmdapi.NewConfig()
cluster := clientcmdapi.NewCluster()
cluster.Server = c.Host
cluster.InsecureSkipTLSVerify = c.SkipTLSVerify
authInfo := clientcmdapi.NewAuthInfo()
if c.TLSData != nil {
cluster.CertificateAuthorityData = c.TLSData.CA
authInfo.ClientCertificateData = c.TLSData.Cert
authInfo.ClientKeyData = c.TLSData.Key
}
authInfo.AuthProvider = c.AuthProvider
authInfo.Exec = c.Exec
cfg.Clusters["cluster"] = cluster
cfg.AuthInfos["authInfo"] = authInfo
ctx := clientcmdapi.NewContext()
ctx.AuthInfo = "authInfo"
ctx.Cluster = "cluster"
ctx.Namespace = c.DefaultNamespace
cfg.Contexts["context"] = ctx
cfg.CurrentContext = "context"
return clientcmd.NewDefaultClientConfig(*cfg, &clientcmd.ConfigOverrides{})
}
// ResolveDefault returns endpoint metadata for the default Kubernetes
// endpoint, which is derived from the env-based kubeconfig.
func (c *EndpointMeta) ResolveDefault(stackOrchestrator command.Orchestrator) (interface{}, *store.EndpointTLSData, error) {
kubeconfig := os.Getenv("KUBECONFIG")
if kubeconfig == "" {
kubeconfig = filepath.Join(homedir.Get(), ".kube/config")
}
kubeEP, err := FromKubeConfig(kubeconfig, "", "")
if err != nil {
if stackOrchestrator == command.OrchestratorKubernetes || stackOrchestrator == command.OrchestratorAll {
return nil, nil, errors.Wrapf(err, "default orchestrator is %s but unable to resolve kubernetes endpoint", stackOrchestrator)
}
// We deliberately quash the error here, returning nil
// for the first argument is sufficient to indicate we weren't able to
// provide a default
return nil, nil, nil
}
var tls *store.EndpointTLSData
if kubeEP.TLSData != nil {
tls = kubeEP.TLSData.ToStoreTLSData()
}
return kubeEP.EndpointMeta, tls, nil
}
// EndpointFromContext extracts kubernetes endpoint info from current context
func EndpointFromContext(metadata store.Metadata) *EndpointMeta {
ep, ok := metadata.Endpoints[KubernetesEndpoint]
if !ok {
return nil
}
typed, ok := ep.(EndpointMeta)
if !ok {
return nil
}
return &typed
}
// ConfigFromContext resolves a kubernetes client config for the specified context.
// If kubeconfigOverride is specified, use this config file instead of the context defaults.ConfigFromContext
// if command.ContextDockerHost is specified as the context name, fallsback to the default user's kubeconfig file
func ConfigFromContext(name string, s store.Reader) (clientcmd.ClientConfig, error) {
ctxMeta, err := s.GetMetadata(name)
if err != nil {
return nil, err
}
epMeta := EndpointFromContext(ctxMeta)
if epMeta != nil {
ep, err := epMeta.WithTLSData(s, name)
if err != nil {
return nil, err
}
return ep.KubernetesConfig(), nil
}
// context has no kubernetes endpoint
Use underlying `NewKubernetesConfig` directly from compose-on-kubernetes. The comment on `github.com/docker/cli/kubernetes.NewKubernetesConfig` said: // Deprecated: Use github.com/docker/compose-on-kubernetes/api.NewKubernetesConfig instead By making this switch in `github.com/docker/cli/context/kubernetes/load.go` we break a vendoring chain: `github.com/docker/cli/cli/command` → `vendor/github.com/docker/cli/cli/context/kubernetes/load.go` → `vendor/github.com/docker/cli/kubernetes` → `github.com/docker/compose-on-kubernetes/api/compose/...` This means that projects which just want `github.com/docker/cli/cli/command` (which is itself pulled in transitively by `github.com/docker/cli/cli-plugins/plugin`) which do not themselves need the compose-on-kubernetes API avoid a huge pile of transitive dependencies. On one of my private projects the diff on the vendor dir is: 280 files changed, 21 insertions(+), 211346 deletions(-) and includes dropping: * `github.com/docker/compose-on-kubernetes/api/compose/{clone,impersonation}` * `github.com/docker/compose-on-kubernetes/api/compose/{v1alpha3,v1beta1,v1beta2,v1beta3}` * `github.com/google/btree` * `github.com/googleapis/gnostic` * `github.com/gregjones/httpcache` * `github.com/peterbourgon/diskv` * `k8s.io/api/*` (_lots_ of subpackages) * `k8s.io/client-go/{discovery,kubernetes/scheme}` and I've gone from: $ du -sh vendor/k8s.io/ 8.1M vendor/k8s.io/ to: $ du -sh vendor/k8s.io/ 2.1M vendor/k8s.io/ (overall I went from 36M → 29M of vendor dir for this particular project) The change to `cli/command/system/version.go` is just for consistency and allows us to drop the now unused alias. Signed-off-by: Ian Campbell <ijc@docker.com> (cherry picked from commit 8635abd662c8bb794eaee6f99d7fbf03e610e7e5) Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2019-05-14 10:12:06 -04:00
return api.NewKubernetesConfig(""), nil
}