github.com/grahambrereton-form3/tilt@v0.10.18/internal/k8s/env.go (about)

     1  package k8s
     2  
     3  import (
     4  	"context"
     5  	"path/filepath"
     6  	"strings"
     7  
     8  	"github.com/mitchellh/go-homedir"
     9  	"github.com/pkg/errors"
    10  	"k8s.io/client-go/tools/clientcmd"
    11  	"k8s.io/client-go/tools/clientcmd/api"
    12  
    13  	"github.com/windmilleng/tilt/internal/ospath"
    14  	"github.com/windmilleng/tilt/pkg/logger"
    15  )
    16  
    17  type ClusterName string
    18  type Env string
    19  
    20  const (
    21  	EnvUnknown       Env = "unknown"
    22  	EnvGKE           Env = "gke"
    23  	EnvMinikube      Env = "minikube"
    24  	EnvDockerDesktop Env = "docker-for-desktop"
    25  	EnvMicroK8s      Env = "microk8s"
    26  	EnvKIND          Env = "kind"
    27  	EnvK3D           Env = "k3d"
    28  	EnvNone          Env = "none" // k8s not running (not neces. a problem, e.g. if using Tilt x Docker Compose)
    29  )
    30  
    31  func (e Env) UsesLocalDockerRegistry() bool {
    32  	return e == EnvMinikube || e == EnvDockerDesktop || e == EnvMicroK8s
    33  }
    34  
    35  func (e Env) IsLocalCluster() bool {
    36  	return e == EnvMinikube || e == EnvDockerDesktop || e == EnvMicroK8s || e == EnvKIND || e == EnvK3D
    37  }
    38  
    39  func ProvideKubeContext(config *api.Config) (KubeContext, error) {
    40  	return KubeContext(config.CurrentContext), nil
    41  }
    42  
    43  func ProvideKubeConfig(clientLoader clientcmd.ClientConfig) (*api.Config, error) {
    44  	access := clientLoader.ConfigAccess()
    45  	config, err := access.GetStartingConfig()
    46  	if err != nil {
    47  		return nil, errors.Wrap(err, "Loading Kubernetes current-context")
    48  	}
    49  
    50  	return config, nil
    51  }
    52  
    53  func ProvideClusterName(ctx context.Context, config *api.Config) ClusterName {
    54  	n := config.CurrentContext
    55  	c, ok := config.Contexts[n]
    56  	if !ok {
    57  		return ""
    58  	}
    59  	return ClusterName(c.Cluster)
    60  }
    61  
    62  func ProvideEnv(ctx context.Context, config *api.Config) Env {
    63  	n := config.CurrentContext
    64  
    65  	c, ok := config.Contexts[n]
    66  	if !ok {
    67  		if n == "" {
    68  			return EnvNone
    69  		}
    70  		return EnvUnknown
    71  	}
    72  
    73  	cn := c.Cluster
    74  	if Env(cn) == EnvMinikube {
    75  		return EnvMinikube
    76  	} else if cn == "docker-for-desktop-cluster" || cn == "docker-desktop" {
    77  		return EnvDockerDesktop
    78  	} else if strings.HasPrefix(cn, string(EnvGKE)) {
    79  		// GKE cluster strings look like:
    80  		// gke_blorg-dev_us-central1-b_blorg
    81  		return EnvGKE
    82  	} else if Env(cn) == EnvKIND {
    83  		return EnvKIND
    84  	} else if cn == "microk8s-cluster" {
    85  		return EnvMicroK8s
    86  	}
    87  
    88  	loc := c.LocationOfOrigin
    89  	homedir, err := homedir.Dir()
    90  	if err != nil {
    91  		logger.Get(ctx).Infof("Error loading homedir: %v", err)
    92  		return EnvUnknown
    93  	}
    94  
    95  	k3dDir := filepath.Join(homedir, ".config", "k3d")
    96  	if ospath.IsChild(k3dDir, loc) {
    97  		return EnvK3D
    98  	}
    99  
   100  	// NOTE(nick): Users can set the KIND cluster name with `kind create cluster
   101  	// --name`.  This makes the KIND cluster really hard to detect.
   102  	//
   103  	// We currently do it by assuming that KIND configs are always stored in a
   104  	// file named kind-config-*.
   105  	//
   106  	// KIND internally looks for its clusters with `docker ps` + filters,
   107  	// which might be a route to explore if this isn't robust enough.
   108  	if strings.HasPrefix(filepath.Base(loc), "kind-config-") {
   109  		return EnvKIND
   110  	}
   111  
   112  	return EnvUnknown
   113  }