Ctrl K
ComunidadGuías…

pkg/k8score/cluster_detection.go

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
package k8score

import (
	"context"
	"strings"

	corev1 "k8s.io/api/core/v1"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/client-go/kubernetes"
)

// NKPNamespace is where Nutanix Kubernetes Platform runs its own Flux, on
// every cluster it manages. NKP also runs on AWS, Azure and other
// infrastructure, so this is checked before the nodes' provider.
const NKPNamespace = "kommander-flux"

// IsNKP reports whether the cluster has the NKP namespace. A denied or failed
// read counts as no.
func IsNKP(ctx context.Context, client kubernetes.Interface) bool {
	_, err := client.CoreV1().Namespaces().Get(ctx, NKPNamespace, metav1.GetOptions{})
	return err == nil
}

// DetectClusterPlatform detects the Kubernetes platform/provider by inspecting nodes.
// Returns one of: nkp, rke2, gke, gke-autopilot, eks, aks, nutanix, minikube, kind, docker-desktop, openshift, rancher, generic, unknown.
func DetectClusterPlatform(ctx context.Context, client kubernetes.Interface) (string, error) {
	if client == nil {
		return "unknown", nil
	}

	if IsNKP(ctx, client) {
		return "nkp", nil
	}

	nodeList, err := client.CoreV1().Nodes().List(ctx, metav1.ListOptions{Limit: 1})
	if err != nil || len(nodeList.Items) == 0 {
		return "unknown", err
	}

	node := nodeList.Items[0]

	platform := DetectNodePlatform(node)
	if platform != "unknown" {
		if platform == "gke" {
			if isAutopilot, _ := detectAutopilot(ctx, client); isAutopilot {
				return "gke-autopilot", nil
			}
		}
		return platform, nil
	}

	return "generic", nil
}

// DetectNodePlatform classifies a sampled node. Distribution markers take
// precedence over infrastructure labels because a Rancher-managed RKE2 node is
// still operationally an RKE2 cluster.
func DetectNodePlatform(node corev1.Node) string {
	if platform := DetectPlatformFromVersion(node.Status.NodeInfo.KubeletVersion); platform != "unknown" {
		return platform
	}
	if platform := DetectByProviderID(node); platform != "unknown" {
		return platform
	}
	if platform := DetectByLabels(node); platform != "unknown" {
		return platform
	}
	return DetectByNodeName(node)
}

// DetectPlatformFromVersion classifies distribution markers embedded in Kubernetes versions.
func DetectPlatformFromVersion(gitVersion string) string {
	if strings.Contains(gitVersion, "+rke2r") {
		return "rke2"
	}
	return "unknown"
}

// DetectByProviderID detects the platform from a node's ProviderID field.
func DetectByProviderID(node corev1.Node) string {
	providerID := node.Spec.ProviderID
	switch {
	case strings.HasPrefix(providerID, "gce://") || strings.HasPrefix(providerID, "gke://"):
		return "gke"
	case strings.HasPrefix(providerID, "aws://"):
		return "eks"
	case strings.HasPrefix(providerID, "azure://"):
		return "aks"
	case strings.HasPrefix(providerID, "kind://"):
		return "kind"
	case strings.HasPrefix(providerID, "nutanix://"):
		return "nutanix"
	default:
		return "unknown"
	}
}

// DetectByLabels detects the platform from a node's labels.
func DetectByLabels(node corev1.Node) string {
	if IsNodeGKE(node) {
		return "gke"
	}
	if _, exists := node.Labels["eks.amazonaws.com/nodegroup"]; exists {
		return "eks"
	}
	if _, exists := node.Labels["eks.amazonaws.com/capacityType"]; exists {
		return "eks"
	}
	for label := range node.Labels {
		if strings.HasPrefix(label, "kubernetes.azure.com/") {
			return "aks"
		}
	}
	if _, exists := node.Labels["node.openshift.io/os_id"]; exists {
		return "openshift"
	}
	if _, exists := node.Labels["rke.cattle.io/machine"]; exists {
		return "rancher"
	}
	return "unknown"
}

// DetectByNodeName detects the platform from a node's name (local dev clusters).
func DetectByNodeName(node corev1.Node) string {
	name := node.Name
	switch {
	case strings.Contains(name, "kind-"):
		return "kind"
	case name == "minikube" || strings.HasPrefix(name, "minikube-"):
		return "minikube"
	case name == "docker-desktop":
		return "docker-desktop"
	default:
		return "unknown"
	}
}

// IsNodeGKE returns true if the node belongs to a GKE cluster.
func IsNodeGKE(node corev1.Node) bool {
	if _, exists := node.Labels["cloud.google.com/gke-nodepool"]; exists {
		return true
	}
	if _, exists := node.Labels["cloud.google.com/gke-os-distribution"]; exists {
		return true
	}
	return strings.HasPrefix(node.Spec.ProviderID, "gce://")
}

// detectAutopilot checks whether a GKE cluster is running in Autopilot mode.
func detectAutopilot(ctx context.Context, client kubernetes.Interface) (bool, error) {
	nodeList, err := client.CoreV1().Nodes().List(ctx, metav1.ListOptions{Limit: 1})
	if err == nil && len(nodeList.Items) > 0 {
		node := nodeList.Items[0]
		if val, exists := node.Labels["cloud.google.com/gke-autopilot"]; exists && val == "true" {
			return true, nil
		}
		if !IsNodeGKE(node) {
			return false, nil
		}
	}

	// Check kube-system pod annotations for Autopilot marker
	podList, err := client.CoreV1().Pods("kube-system").List(ctx, metav1.ListOptions{Limit: 10})
	if err != nil {
		return false, err
	}
	for _, pod := range podList.Items {
		for key := range pod.Annotations {
			if strings.HasPrefix(key, "autopilot.gke.io/") {
				return true, nil
			}
		}
	}

	return false, nil
}