...

Source file src/github.com/linkerd/linkerd2/pkg/k8s/k8s.go

Documentation: github.com/linkerd/linkerd2/pkg/k8s

     1  package k8s
     2  
     3  import (
     4  	"fmt"
     5  	"strings"
     6  
     7  	corev1 "k8s.io/api/core/v1"
     8  	"k8s.io/client-go/rest"
     9  	"k8s.io/client-go/tools/clientcmd"
    10  )
    11  
    12  // These constants are string representations of Kubernetes resource types.
    13  const (
    14  	All                   = "all"
    15  	Authority             = "authority"
    16  	ConfigMap             = "configmap"
    17  	CronJob               = "cronjob"
    18  	DaemonSet             = "daemonset"
    19  	Deployment            = "deployment"
    20  	Endpoints             = "endpoints"
    21  	EndpointSlices        = "endpointslices"
    22  	ExtWorkload           = "externalworkload"
    23  	Job                   = "job"
    24  	MeshTLSAuthentication = "meshtlsauthentication"
    25  	MutatingWebhookConfig = "mutatingwebhookconfig"
    26  	Namespace             = "namespace"
    27  	NetworkAuthentication = "networkauthentication"
    28  	Pod                   = "pod"
    29  	ReplicationController = "replicationcontroller"
    30  	ReplicaSet            = "replicaset"
    31  	Secret                = "secret"
    32  	Service               = "service"
    33  	ServiceProfile        = "serviceprofile"
    34  	StatefulSet           = "statefulset"
    35  	Node                  = "node"
    36  	Server                = "server"
    37  	ServerAuthorization   = "serverauthorization"
    38  	AuthorizationPolicy   = "authorizationpolicy"
    39  	HTTPRoute             = "httproute"
    40  
    41  	PolicyAPIGroup         = "policy.linkerd.io"
    42  	PolicyServerCRDVersion = "v1beta2"
    43  
    44  	ServiceProfileAPIVersion = "linkerd.io/v1alpha2"
    45  	ServiceProfileKind       = "ServiceProfile"
    46  
    47  	LinkAPIGroup        = "multicluster.linkerd.io"
    48  	LinkAPIVersion      = "v1alpha1"
    49  	LinkAPIGroupVersion = "multicluster.linkerd.io/v1alpha1"
    50  	LinkKind            = "Link"
    51  
    52  	K8sCoreAPIGroup = "core"
    53  
    54  	NamespaceKind   = "Namespace"
    55  	ServerKind      = "Server"
    56  	HTTPRouteKind   = "HTTPRoute"
    57  	ExtWorkloadKind = "ExternalWorkload"
    58  	PodKind         = "Pod"
    59  
    60  	WorkloadAPIGroup   = "workload.linkerd.io"
    61  	WorkloadAPIVersion = "v1alpha1"
    62  
    63  	// special case k8s job label, to not conflict with Prometheus' job label
    64  	l5dJob = "k8s_job"
    65  )
    66  
    67  type resourceName struct {
    68  	short  string
    69  	full   string
    70  	plural string
    71  }
    72  
    73  // AllResources is a sorted list of all resources defined as constants above.
    74  var AllResources = []string{
    75  	Authority,
    76  	AuthorizationPolicy,
    77  	CronJob,
    78  	DaemonSet,
    79  	Deployment,
    80  	HTTPRoute,
    81  	Job,
    82  	Namespace,
    83  	Pod,
    84  	ReplicaSet,
    85  	ReplicationController,
    86  	Server,
    87  	ServerAuthorization,
    88  	Service,
    89  	ServiceProfile,
    90  	StatefulSet,
    91  }
    92  
    93  // StatAllResourceTypes represents the resources to query in StatSummary when Resource.Type is "all"
    94  var StatAllResourceTypes = []string{
    95  	DaemonSet,
    96  	StatefulSet,
    97  	Job,
    98  	Deployment,
    99  	ReplicationController,
   100  	Pod,
   101  	Service,
   102  	Authority,
   103  	CronJob,
   104  	ReplicaSet,
   105  }
   106  
   107  // CompletionResourceTypes represents resources the CLI's uses for autocompleting resource type names
   108  var CompletionResourceTypes = []string{
   109  	Namespace,
   110  	DaemonSet,
   111  	StatefulSet,
   112  	Job,
   113  	Deployment,
   114  	ReplicationController,
   115  	Pod,
   116  	Service,
   117  	Authority,
   118  	CronJob,
   119  	ReplicaSet,
   120  }
   121  
   122  var resourceNames = []resourceName{
   123  	{"au", "authority", "authorities"},
   124  	{"cj", "cronjob", "cronjobs"},
   125  	{"ds", "daemonset", "daemonsets"},
   126  	{"deploy", "deployment", "deployments"},
   127  	{"job", "job", "jobs"},
   128  	{"meshtlsauthn", "meshtlsauthentication", "meshtlsauthentications"},
   129  	{"ns", "namespace", "namespaces"},
   130  	{"netauthn", "networkauthentication", "networkauthentications"},
   131  	{"networkauthn", "networkauthentication", "networkauthentications"},
   132  	{"po", "pod", "pods"},
   133  	{"rc", "replicationcontroller", "replicationcontrollers"},
   134  	{"rs", "replicaset", "replicasets"},
   135  	{"svc", "service", "services"},
   136  	{"sp", "serviceprofile", "serviceprofiles"},
   137  	{"saz", "serverauthorization", "serverauthorizations"},
   138  	{"serverauthz", "serverauthorization", "serverauthorizations"},
   139  	{"srvauthz", "serverauthorization", "serverauthorizations"},
   140  	{"srv", "server", "servers"},
   141  	{"ap", "authorizationpolicy", "authorizationpolicies"},
   142  	{"httproute", "httproute", "httproutes"},
   143  	{"authzpolicy", "authorizationpolicy", "authorizationpolicies"},
   144  	{"sts", "statefulset", "statefulsets"},
   145  	{"ln", "link", "links"},
   146  	{"all", "all", "all"},
   147  }
   148  
   149  // GetConfig returns kubernetes config based on the current environment.
   150  // If fpath is provided, loads configuration from that file. Otherwise,
   151  // GetConfig uses default strategy to load configuration from $KUBECONFIG,
   152  // .kube/config, or just returns in-cluster config.
   153  func GetConfig(fpath, kubeContext string) (*rest.Config, error) {
   154  	rules := clientcmd.NewDefaultClientConfigLoadingRules()
   155  	if fpath != "" {
   156  		rules.ExplicitPath = fpath
   157  	}
   158  	overrides := &clientcmd.ConfigOverrides{CurrentContext: kubeContext}
   159  	return clientcmd.
   160  		NewNonInteractiveDeferredLoadingClientConfig(rules, overrides).
   161  		ClientConfig()
   162  }
   163  
   164  // CanonicalResourceNameFromFriendlyName returns a canonical name from common shorthands used in command line tools.
   165  // This works based on https://github.com/kubernetes/kubernetes/blob/63ffb1995b292be0a1e9ebde6216b83fc79dd988/pkg/kubectl/kubectl.go#L39
   166  // This also works for non-k8s resources, e.g. authorities
   167  func CanonicalResourceNameFromFriendlyName(friendlyName string) (string, error) {
   168  	for _, name := range resourceNames {
   169  		if friendlyName == name.short || friendlyName == name.full || friendlyName == name.plural {
   170  			return name.full, nil
   171  		}
   172  	}
   173  	return "", fmt.Errorf("cannot find Kubernetes canonical name from friendly name [%s]", friendlyName)
   174  }
   175  
   176  // PluralResourceNameFromFriendlyName returns a pluralized canonical name from common shorthands used in command line tools.
   177  // This works based on https://github.com/kubernetes/kubernetes/blob/63ffb1995b292be0a1e9ebde6216b83fc79dd988/pkg/kubectl/kubectl.go#L39
   178  // This also works for non-k8s resources, e.g. authorities
   179  func PluralResourceNameFromFriendlyName(friendlyName string) (string, error) {
   180  	for _, name := range resourceNames {
   181  		if friendlyName == name.short || friendlyName == name.full || friendlyName == name.plural {
   182  			return name.plural, nil
   183  		}
   184  	}
   185  	return "", fmt.Errorf("cannot find Kubernetes canonical name from friendly name [%s]", friendlyName)
   186  }
   187  
   188  // ShortNameFromCanonicalResourceName returns the shortest name for a k8s canonical name.
   189  // Essentially the reverse of CanonicalResourceNameFromFriendlyName
   190  func ShortNameFromCanonicalResourceName(canonicalName string) string {
   191  	switch canonicalName {
   192  	case Authority:
   193  		return "au"
   194  	case CronJob:
   195  		return "cj"
   196  	case DaemonSet:
   197  		return "ds"
   198  	case Deployment:
   199  		return "deploy"
   200  	case Job:
   201  		return "job"
   202  	case Namespace:
   203  		return "ns"
   204  	case Pod:
   205  		return "po"
   206  	case ReplicationController:
   207  		return "rc"
   208  	case ReplicaSet:
   209  		return "rs"
   210  	case Service:
   211  		return "svc"
   212  	case ServiceProfile:
   213  		return "sp"
   214  	case StatefulSet:
   215  		return "sts"
   216  	default:
   217  		return ""
   218  	}
   219  }
   220  
   221  // KindToL5DLabel converts a Kubernetes `kind` to a Linkerd label.
   222  // For example:
   223  //
   224  //	`pod` -> `pod`
   225  //	`job` -> `k8s_job`
   226  func KindToL5DLabel(k8sKind string) string {
   227  	if k8sKind == Job {
   228  		return l5dJob
   229  	}
   230  	return k8sKind
   231  }
   232  
   233  // PodIdentity returns the mesh TLS identity name of this pod, as constructed
   234  // from the pod's service account name and other metadata.
   235  func PodIdentity(pod *corev1.Pod) (string, error) {
   236  	if pod.Status.Phase != corev1.PodRunning {
   237  		return "", fmt.Errorf("pod not running: %s", pod.GetName())
   238  	}
   239  
   240  	podsa := pod.Spec.ServiceAccountName
   241  	podns := pod.ObjectMeta.Namespace
   242  	containers := append(pod.Spec.InitContainers, pod.Spec.Containers...)
   243  	for _, c := range containers {
   244  		if c.Name == ProxyContainerName {
   245  			for _, env := range c.Env {
   246  				if env.Name == "LINKERD2_PROXY_IDENTITY_LOCAL_NAME" {
   247  					return strings.ReplaceAll(env.Value, "$(_pod_sa).$(_pod_ns)", fmt.Sprintf("%s.%s", podsa, podns)), nil
   248  				}
   249  			}
   250  		}
   251  	}
   252  	return "", nil
   253  }
   254  

View as plain text