Kaynağa Gözat

initial pass of key stuff

Ajay Tripathy 5 yıl önce
ebeveyn
işleme
94cccd69b1

+ 11 - 0
pkg/cloud/awsprovider.go

@@ -101,6 +101,7 @@ type AWS struct {
 	ProjectID               string
 	DownloadPricingDataLock sync.RWMutex
 	Config                  *ProviderConfig
+	ServiceAccountChecks    []*ServiceAccountCheck
 	*CustomProvider
 }
 
@@ -512,6 +513,9 @@ func (aws *AWS) isPreemptible(key string) bool {
 func (aws *AWS) DownloadPricingData() error {
 	aws.DownloadPricingDataLock.Lock()
 	defer aws.DownloadPricingDataLock.Unlock()
+	if aws.ServiceAccountChecks == nil {
+		aws.ServiceAccountChecks = []*ServiceAccountCheck{}
+	}
 	c, err := aws.Config.GetCustomPricingData()
 	if err != nil {
 		klog.V(1).Infof("Error downloading default pricing data: %s", err.Error())
@@ -1876,6 +1880,7 @@ func parseSpotData(bucket string, prefix string, projectID string, region string
 	}
 	lso, err := s3Svc.ListObjects(ls)
 	if err != nil {
+
 		return nil, err
 	}
 	lsoLen := len(lso.Contents)
@@ -2221,3 +2226,9 @@ func (a *AWS) getReservedInstances() ([]*AWSReservedInstance, error) {
 
 	return reservedInstances, nil
 }
+
+func (a *AWS) ServiceAccountStatus() *ServiceAccountStatus {
+	return &ServiceAccountStatus{
+		Checks: []*ServiceAccountCheck{},
+	}
+}

+ 6 - 0
pkg/cloud/azureprovider.go

@@ -774,3 +774,9 @@ func (az *Azure) PVPricing(pvk PVKey) (*PV, error) {
 func (az *Azure) GetLocalStorageQuery(window, offset string, rate bool, used bool) string {
 	return ""
 }
+
+func (az *Azure) ServiceAccountStatus() *ServiceAccountStatus {
+	return &ServiceAccountStatus{
+		Checks: []*ServiceAccountCheck{},
+	}
+}

+ 9 - 3
pkg/cloud/csvprovider.go

@@ -120,9 +120,9 @@ func (c *CSVProvider) DownloadPricingData() error {
 			continue
 		}
 		klog.V(4).Infof("Found price info %+v", p)
-		key := p.InstanceID
+		key := strings.ToLower(p.InstanceID)
 		if p.Region != "" { // strip the casing from region and add to key.
-			key = fmt.Sprintf("%s,%s", strings.ToLower(p.Region), p.InstanceID)
+			key = fmt.Sprintf("%s,%s", strings.ToLower(p.Region), strings.ToLower(p.InstanceID))
 			c.UsesRegion = true
 		}
 		if p.AssetClass == "pv" {
@@ -195,7 +195,7 @@ func NodeValueFromMapField(m string, n *v1.Node, useRegion bool) string {
 			}
 		}
 		if strings.HasPrefix(n.Spec.ProviderID, "azure://") {
-			vmOrScaleSet := strings.TrimPrefix(n.Spec.ProviderID, "azure://")
+			vmOrScaleSet := strings.ToLower(strings.TrimPrefix(n.Spec.ProviderID, "azure://"))
 			return toReturn + vmOrScaleSet
 		}
 		return toReturn + n.Spec.ProviderID
@@ -288,3 +288,9 @@ func (c *CSVProvider) PVPricing(pvk PVKey) (*PV, error) {
 		Cost: pricing.MarketPriceHourly,
 	}, nil
 }
+
+func (c *CSVProvider) ServiceAccountStatus() *ServiceAccountStatus {
+	return &ServiceAccountStatus{
+		Checks: []*ServiceAccountCheck{},
+	}
+}

+ 6 - 0
pkg/cloud/customprovider.go

@@ -262,3 +262,9 @@ func (cpk *customProviderKey) Features() string {
 	}
 	return "default" // TODO: multiple custom pricing support.
 }
+
+func (cp *CustomProvider) ServiceAccountStatus() *ServiceAccountStatus {
+	return &ServiceAccountStatus{
+		Checks: []*ServiceAccountCheck{},
+	}
+}

+ 6 - 0
pkg/cloud/gcpprovider.go

@@ -1379,3 +1379,9 @@ func (gcp *GCP) NodePricing(key Key) (*Node, error) {
 	}
 	return nil, fmt.Errorf("Warning: no pricing data found for %s", key)
 }
+
+func (gcp *GCP) ServiceAccountStatus() *ServiceAccountStatus {
+	return &ServiceAccountStatus{
+		Checks: []*ServiceAccountCheck{},
+	}
+}

+ 10 - 0
pkg/cloud/provider.go

@@ -157,6 +157,15 @@ type CustomPricing struct {
 	ReadOnly              string            `json:"readOnly"`
 }
 
+type ServiceAccountStatus struct {
+	Checks []*ServiceAccountCheck `json:"checks"`
+}
+
+type ServiceAccountCheck struct {
+	Message string `json:"message"`
+	Status  bool   `json:"status"`
+}
+
 // Provider represents a k8s provider.
 type Provider interface {
 	ClusterInfo() (map[string]string, error)
@@ -176,6 +185,7 @@ type Provider interface {
 	GetLocalStorageQuery(string, string, bool, bool) string
 	ExternalAllocations(string, string, []string, string, string, bool) ([]*OutOfClusterAllocation, error)
 	ApplyReservedInstancePricing(map[string]*Node)
+	ServiceAccountStatus() *ServiceAccountStatus
 }
 
 // ClusterName returns the name defined in cluster info, defaulting to the

+ 1 - 1
pkg/costmodel/costmodel.go

@@ -1136,7 +1136,7 @@ func (cm *CostModel) GetNodeCost(cp costAnalyzerCloud.Provider) (map[string]*cos
 
 		cnode, err := cp.NodePricing(cp.GetKey(nodeLabels, n))
 		if err != nil {
-			log.DedupedWarningf(10, "Error getting node pricing. Error: %s", err.Error())
+			klog.Infof("Error getting node pricing. Error: %s", err.Error())
 			if cnode != nil {
 				nodes[name] = cnode
 				continue

+ 46 - 20
test/cloud_test.go

@@ -1,20 +1,22 @@
 package test
 
 import (
+	"strings"
 	"testing"
+
 	"github.com/kubecost/cost-model/pkg/cloud"
 	v1 "k8s.io/api/core/v1"
 )
 
-const(
+const (
 	providerIDMap = "spec.providerID"
-	nameMap = "metadata.name"
-	labelMapFoo = "metadata.labels.foo"
+	nameMap       = "metadata.name"
+	labelMapFoo   = "metadata.labels.foo"
 )
 
-func TestRegionValueFromMapField(t * testing.T) {
+func TestRegionValueFromMapField(t *testing.T) {
 	wantRegion := "useast"
-	wantpid := "/subscriptions/0bd50fdf-c923-4e1e-850c-196dd3dcc5d3/resourceGroups/MC_test_test_eastus/providers/Microsoft.Compute/virtualMachines/aks-agentpool-20139558-0"
+	wantpid := strings.ToLower("/subscriptions/0bd50fdf-c923-4e1e-850c-196dd3dcc5d3/resourceGroups/MC_test_test_eastus/providers/Microsoft.Compute/virtualMachines/aks-agentpool-20139558-0")
 	providerIDWant := wantRegion + "," + wantpid
 
 	n := &v1.Node{}
@@ -26,7 +28,6 @@ func TestRegionValueFromMapField(t * testing.T) {
 		t.Errorf("Assert on '%s' want '%s' got '%s'", providerIDMap, providerIDWant, got)
 	}
 
-
 }
 func TestTransformedValueFromMapField(t *testing.T) {
 	providerIDWant := "i-05445591e0d182d42"
@@ -37,7 +38,7 @@ func TestTransformedValueFromMapField(t *testing.T) {
 		t.Errorf("Assert on '%s' want '%s' got '%s'", providerIDMap, providerIDWant, got)
 	}
 
-	providerIDWant2 := "/subscriptions/0bd50fdf-c923-4e1e-850c-196dd3dcc5d3/resourceGroups/MC_test_test_eastus/providers/Microsoft.Compute/virtualMachines/aks-agentpool-20139558-0"
+	providerIDWant2 := strings.ToLower("/subscriptions/0bd50fdf-c923-4e1e-850c-196dd3dcc5d3/resourceGroups/MC_test_test_eastus/providers/Microsoft.Compute/virtualMachines/aks-agentpool-20139558-0")
 	n2 := &v1.Node{}
 	n2.Spec.ProviderID = "azure:///subscriptions/0bd50fdf-c923-4e1e-850c-196dd3dcc5d3/resourceGroups/MC_test_test_eastus/providers/Microsoft.Compute/virtualMachines/aks-agentpool-20139558-0"
 	got2 := cloud.NodeValueFromMapField(providerIDMap, n2, false)
@@ -45,7 +46,7 @@ func TestTransformedValueFromMapField(t *testing.T) {
 		t.Errorf("Assert on '%s' want '%s' got '%s'", providerIDMap, providerIDWant2, got2)
 	}
 
-	providerIDWant3 := "/subscriptions/0bd50fdf-c923-4e1e-850c-196dd3dcc5d3/resourceGroups/mc_testspot_testspot_eastus/providers/Microsoft.Compute/virtualMachineScaleSets/aks-nodepool1-19213364-vmss/virtualMachines/0"
+	providerIDWant3 := strings.ToLower("/subscriptions/0bd50fdf-c923-4e1e-850c-196dd3dcc5d3/resourceGroups/mc_testspot_testspot_eastus/providers/Microsoft.Compute/virtualMachineScaleSets/aks-nodepool1-19213364-vmss/virtualMachines/0")
 	n3 := &v1.Node{}
 	n3.Spec.ProviderID = "azure:///subscriptions/0bd50fdf-c923-4e1e-850c-196dd3dcc5d3/resourceGroups/mc_testspot_testspot_eastus/providers/Microsoft.Compute/virtualMachineScaleSets/aks-nodepool1-19213364-vmss/virtualMachines/0"
 	got3 := cloud.NodeValueFromMapField(providerIDMap, n3, false)
@@ -54,13 +55,11 @@ func TestTransformedValueFromMapField(t *testing.T) {
 	}
 }
 
-
 func TestNodeValueFromMapField(t *testing.T) {
 	providerIDWant := "providerid"
 	nameWant := "gke-standard-cluster-1-pool-1-91dc432d-cg69"
 	labelFooWant := "labelfoo"
 
-	
 	n := &v1.Node{}
 	n.Spec.ProviderID = providerIDWant
 	n.Name = nameWant
@@ -71,7 +70,7 @@ func TestNodeValueFromMapField(t *testing.T) {
 	if got != providerIDWant {
 		t.Errorf("Assert on '%s' want '%s' got '%s'", providerIDMap, providerIDWant, got)
 	}
-	
+
 	got = cloud.NodeValueFromMapField(nameMap, n, false)
 	if got != nameWant {
 		t.Errorf("Assert on '%s' want '%s' got '%s'", nameMap, nameWant, got)
@@ -84,7 +83,7 @@ func TestNodeValueFromMapField(t *testing.T) {
 
 }
 
-func TestNodePriceFromCSV(t * testing.T) {
+func TestNodePriceFromCSV(t *testing.T) {
 	providerIDWant := "providerid"
 	nameWant := "gke-standard-cluster-1-pool-1-91dc432d-cg69"
 	labelFooWant := "labelfoo"
@@ -100,7 +99,7 @@ func TestNodePriceFromCSV(t * testing.T) {
 	c := &cloud.CSVProvider{
 		CSVLocation: "../configs/pricing_schema.csv",
 		CustomProvider: &cloud.CustomProvider{
-			Config:    cloud.NewProviderConfig("../configs/default.json"),
+			Config: cloud.NewProviderConfig("../configs/default.json"),
 		},
 	}
 	c.DownloadPricingData()
@@ -125,11 +124,11 @@ func TestNodePriceFromCSV(t * testing.T) {
 	if resN2 != nil {
 		t.Errorf("CSV provider should return nil on missing node")
 	}
-	
+
 	c2 := &cloud.CSVProvider{
 		CSVLocation: "../configs/fake.csv",
 		CustomProvider: &cloud.CustomProvider{
-			Config:    cloud.NewProviderConfig("../configs/default.json"),
+			Config: cloud.NewProviderConfig("../configs/default.json"),
 		},
 	}
 	k3 := c.GetKey(n.Labels, n)
@@ -139,7 +138,7 @@ func TestNodePriceFromCSV(t * testing.T) {
 	}
 }
 
-func TestNodePriceFromCSVWithRegion(t * testing.T) {
+func TestNodePriceFromCSVWithRegion(t *testing.T) {
 	providerIDWant := "gke-standard-cluster-1-pool-1-91dc432d-cg69"
 	nameWant := "foo"
 	labelFooWant := "labelfoo"
@@ -171,7 +170,7 @@ func TestNodePriceFromCSVWithRegion(t * testing.T) {
 	c := &cloud.CSVProvider{
 		CSVLocation: "../configs/pricing_schema_region.csv",
 		CustomProvider: &cloud.CustomProvider{
-			Config:    cloud.NewProviderConfig("../configs/default.json"),
+			Config: cloud.NewProviderConfig("../configs/default.json"),
 		},
 	}
 	c.DownloadPricingData()
@@ -206,7 +205,6 @@ func TestNodePriceFromCSVWithRegion(t * testing.T) {
 		}
 	}
 
-
 	unknownN := &v1.Node{}
 	unknownN.Spec.ProviderID = "fake providerID"
 	unknownN.Name = "unknownname"
@@ -217,11 +215,11 @@ func TestNodePriceFromCSVWithRegion(t * testing.T) {
 	if resN4 != nil {
 		t.Errorf("CSV provider should return nil on missing node, instead returned %+v", resN4)
 	}
-	
+
 	c2 := &cloud.CSVProvider{
 		CSVLocation: "../configs/fake.csv",
 		CustomProvider: &cloud.CustomProvider{
-			Config:    cloud.NewProviderConfig("../configs/default.json"),
+			Config: cloud.NewProviderConfig("../configs/default.json"),
 		},
 	}
 	k5 := c.GetKey(n.Labels, n)
@@ -230,3 +228,31 @@ func TestNodePriceFromCSVWithRegion(t * testing.T) {
 		t.Errorf("CSV provider should return nil on missing csv")
 	}
 }
+
+func TestNodePriceFromCSVWithCase(t *testing.T) {
+	n := &v1.Node{}
+	n.Spec.ProviderID = "azure:///subscriptions/75d6a706-70ad-4689-9ca4-4659a44f0ba8/resourceGroups/ethos_11_stage_va7/providers/Microsoft.Compute/virtualMachineScaleSets/vmss-agent-worker0-11stageva7-ezpwh/virtualMachines/7"
+	n.Labels = make(map[string]string)
+	n.Labels[v1.LabelZoneRegion] = "eastus2"
+	wantPrice := "0.443952693121295"
+
+	c := &cloud.CSVProvider{
+		CSVLocation: "../configs/pricing_schema_case.csv",
+		CustomProvider: &cloud.CustomProvider{
+			Config: cloud.NewProviderConfig("../configs/default.json"),
+		},
+	}
+
+	c.DownloadPricingData()
+	k := c.GetKey(n.Labels, n)
+	resN, err := c.NodePricing(k)
+	if err != nil {
+		t.Errorf("Error in NodePricing: %s", err.Error())
+	} else {
+		gotPrice := resN.Cost
+		if gotPrice != wantPrice {
+			t.Errorf("Wanted price '%s' got price '%s'", wantPrice, gotPrice)
+		}
+	}
+
+}