Ver Fonte

Merge pull request #957 from kubecost/mmd/fix-gcp-provider-k3s-panic

Avoid nil panic on non-GKE GCP clusters (K3s)
Michael Dresser há 4 anos atrás
pai
commit
8c7206a0c2
2 ficheiros alterados com 60 adições e 6 exclusões
  1. 24 6
      pkg/cloud/gcpprovider.go
  2. 36 0
      pkg/cloud/gcpprovider_test.go

+ 24 - 6
pkg/cloud/gcpprovider.go

@@ -1395,15 +1395,19 @@ func (gcp *gcpKey) GPUType() string {
 	return ""
 }
 
-// GetKey maps node labels to information needed to retrieve pricing data
-func (gcp *gcpKey) Features() string {
+func parseGCPInstanceTypeLabel(it string) string {
 	var instanceType string
-	it, _ := util.GetInstanceType(gcp.Labels)
-	if it == "" {
-		log.DedupedErrorf(1, "Missing or Unknown 'node.kubernetes.io/instance-type' node label")
+
+	splitByDash := strings.Split(it, "-")
+
+	// GKE nodes are labeled with the GCP instance type, but users can deploy on GCP
+	// with tools like K3s, whose instance type labels will be "k3s". This logic
+	// avoids a panic in the slice operation then there are no dashes (-) in the
+	// instance type label value.
+	if len(splitByDash) < 2 {
 		instanceType = "unknown"
 	} else {
-		instanceType = strings.ToLower(strings.Join(strings.Split(it, "-")[:2], ""))
+		instanceType = strings.ToLower(strings.Join(splitByDash[:2], ""))
 		if instanceType == "n1highmem" || instanceType == "n1highcpu" {
 			instanceType = "n1standard" // These are priced the same. TODO: support n1ultrahighmem
 		} else if instanceType == "n2highmem" || instanceType == "n2highcpu" {
@@ -1415,6 +1419,20 @@ func (gcp *gcpKey) Features() string {
 		}
 	}
 
+	return instanceType
+}
+
+// GetKey maps node labels to information needed to retrieve pricing data
+func (gcp *gcpKey) Features() string {
+	var instanceType string
+	it, _ := util.GetInstanceType(gcp.Labels)
+	if it == "" {
+		log.DedupedErrorf(1, "Missing or Unknown 'node.kubernetes.io/instance-type' node label")
+		instanceType = "unknown"
+	} else {
+		instanceType = parseGCPInstanceTypeLabel(it)
+	}
+
 	r, _ := util.GetRegion(gcp.Labels)
 	region := strings.ToLower(r)
 	var usageType string

+ 36 - 0
pkg/cloud/gcpprovider_test.go

@@ -0,0 +1,36 @@
+package cloud
+
+import (
+	"testing"
+)
+
+func TestParseGCPInstanceTypeLabel(t *testing.T) {
+	cases := []struct {
+		input    string
+		expected string
+	}{
+		{
+			input:    "n1-standard-2",
+			expected: "n1standard",
+		},
+		{
+			input:    "e2-medium",
+			expected: "e2medium",
+		},
+		{
+			input:    "k3s",
+			expected: "unknown",
+		},
+		{
+			input:    "custom-n1-standard-2",
+			expected: "custom",
+		},
+	}
+
+	for _, test := range cases {
+		result := parseGCPInstanceTypeLabel(test.input)
+		if result != test.expected {
+			t.Errorf("Input: %s, Expected: %s, Actual: %s", test.input, test.expected, result)
+		}
+	}
+}