Просмотр исходного кода

generalize router, and fix divide by zero

AjayTripathy 6 лет назад
Родитель
Сommit
f019d03849
1 измененных файлов с 26 добавлено и 22 удалено
  1. 26 22
      costmodel/router.go

+ 26 - 22
costmodel/router.go

@@ -383,6 +383,7 @@ func (a *Accesses) CustomPricingHasChanged() bool {
 // by time period using window and offset, aggregation field and subfield (e.g. grouping by label.app
 // by time period using window and offset, aggregation field and subfield (e.g. grouping by label.app
 // using aggregation=label, aggregationSubfield=app), and filtered by namespace and cluster.
 // using aggregation=label, aggregationSubfield=app), and filtered by namespace and cluster.
 func (a *Accesses) AggregateCostModel(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
 func (a *Accesses) AggregateCostModel(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
+
 	w.Header().Set("Content-Type", "application/json")
 	w.Header().Set("Content-Type", "application/json")
 	w.Header().Set("Access-Control-Allow-Origin", "*")
 	w.Header().Set("Access-Control-Allow-Origin", "*")
 
 
@@ -440,16 +441,11 @@ func (a *Accesses) AggregateCostModel(w http.ResponseWriter, r *http.Request, ps
 		return
 		return
 	}
 	}
 
 
-	// if custom pricing has changed, then clear the cache and recompute data
-	if a.CustomPricingHasChanged() {
-		clearCache = true
-	}
-
 	// clear cache prior to checking the cache so that a clearCache=true
 	// clear cache prior to checking the cache so that a clearCache=true
 	// request always returns a freshly computed value
 	// request always returns a freshly computed value
 	if clearCache {
 	if clearCache {
-		a.AggregateCache.Flush()
-		a.CostDataCache.Flush()
+		A.AggregateCache.Flush()
+		A.CostDataCache.Flush()
 	}
 	}
 
 
 	// parametrize cache key by all request parameters
 	// parametrize cache key by all request parameters
@@ -458,7 +454,7 @@ func (a *Accesses) AggregateCostModel(w http.ResponseWriter, r *http.Request, ps
 		allocateIdle, includeTimeSeries, includeEfficiency)
 		allocateIdle, includeTimeSeries, includeEfficiency)
 
 
 	// check the cache for aggregated response; if cache is hit and not disabled, return response
 	// check the cache for aggregated response; if cache is hit and not disabled, return response
-	if result, found := a.AggregateCache.Get(aggKey); found && !disableCache {
+	if result, found := A.AggregateCache.Get(aggKey); found && !disableCache {
 		w.Write(WrapDataWithMessage(result, nil, fmt.Sprintf("aggregate cache hit: %s", aggKey)))
 		w.Write(WrapDataWithMessage(result, nil, fmt.Sprintf("aggregate cache hit: %s", aggKey)))
 		return
 		return
 	}
 	}
@@ -469,10 +465,10 @@ func (a *Accesses) AggregateCostModel(w http.ResponseWriter, r *http.Request, ps
 
 
 	// Use Thanos Client if it exists (enabled) and remote flag set
 	// Use Thanos Client if it exists (enabled) and remote flag set
 	var pClient prometheusClient.Client
 	var pClient prometheusClient.Client
-	if remote && a.ThanosClient != nil {
-		pClient = a.ThanosClient
+	if remote && A.ThanosClient != nil {
+		pClient = A.ThanosClient
 	} else {
 	} else {
-		pClient = a.PrometheusClient
+		pClient = A.PrometheusClient
 	}
 	}
 
 
 	// convert duration and offset to start and end times
 	// convert duration and offset to start and end times
@@ -485,7 +481,7 @@ func (a *Accesses) AggregateCostModel(w http.ResponseWriter, r *http.Request, ps
 	durationHours := endTime.Sub(*startTime).Hours()
 	durationHours := endTime.Sub(*startTime).Hours()
 
 
 	threeHoursAgo := time.Now().Add(-3 * time.Hour)
 	threeHoursAgo := time.Now().Add(-3 * time.Hour)
-	if a.ThanosClient != nil && endTime.After(threeHoursAgo) {
+	if A.ThanosClient != nil && endTime.After(threeHoursAgo) {
 		klog.Infof("Setting end time backwards to first present data")
 		klog.Infof("Setting end time backwards to first present data")
 		*endTime = time.Now().Add(-3 * time.Hour)
 		*endTime = time.Now().Add(-3 * time.Hour)
 	}
 	}
@@ -509,6 +505,9 @@ func (a *Accesses) AggregateCostModel(w http.ResponseWriter, r *http.Request, ps
 	}
 	}
 	resolutionDuration, err := ParseDuration(resolution)
 	resolutionDuration, err := ParseDuration(resolution)
 	resolutionHours := resolutionDuration.Hours()
 	resolutionHours := resolutionDuration.Hours()
+	if resolutionHours < 1 {
+		resolutionHours = 1
+	}
 	if err != nil {
 	if err != nil {
 		w.WriteHeader(http.StatusBadRequest)
 		w.WriteHeader(http.StatusBadRequest)
 		w.Write(WrapData(nil, fmt.Errorf("Error parsing resolution (%s)", resolution)))
 		w.Write(WrapData(nil, fmt.Errorf("Error parsing resolution (%s)", resolution)))
@@ -523,7 +522,7 @@ func (a *Accesses) AggregateCostModel(w http.ResponseWriter, r *http.Request, ps
 	// attempt to retrieve cost data from cache
 	// attempt to retrieve cost data from cache
 	var costData map[string]*CostData
 	var costData map[string]*CostData
 	key := fmt.Sprintf(`%s:%s:%s:%t`, duration, offset, resolution, remoteEnabled)
 	key := fmt.Sprintf(`%s:%s:%s:%t`, duration, offset, resolution, remoteEnabled)
-	cacheData, found := a.CostDataCache.Get(key)
+	cacheData, found := A.CostDataCache.Get(key)
 	if found && !disableCache {
 	if found && !disableCache {
 		ok := false
 		ok := false
 		costData, ok = cacheData.(map[string]*CostData)
 		costData, ok = cacheData.(map[string]*CostData)
@@ -533,35 +532,40 @@ func (a *Accesses) AggregateCostModel(w http.ResponseWriter, r *http.Request, ps
 	} else {
 	} else {
 		start := startTime.Format(RFC3339Milli)
 		start := startTime.Format(RFC3339Milli)
 		end := endTime.Format(RFC3339Milli)
 		end := endTime.Format(RFC3339Milli)
-		costData, err = a.Model.ComputeCostDataRange(pClient, a.KubeClientSet, a.Cloud, start, end, resolution, "", "", remoteEnabled)
+		costData, err = A.Model.ComputeCostDataRange(pClient, A.KubeClientSet, A.Cloud, start, end, resolution, "", "", remoteEnabled)
 		if err != nil {
 		if err != nil {
 			w.Write(WrapData(nil, err))
 			w.Write(WrapData(nil, err))
 			return
 			return
 		}
 		}
 
 
-		a.CostDataCache.Set(key, costData, cache.DefaultExpiration)
+		A.CostDataCache.Set(key, costData, cache.DefaultExpiration)
 	}
 	}
 
 
-	c, err := a.Cloud.GetConfig()
+	c, err := A.Cloud.GetConfig()
 	if err != nil {
 	if err != nil {
 		w.Write(WrapData(nil, err))
 		w.Write(WrapData(nil, err))
 		return
 		return
 	}
 	}
-	discount, err := parsePercentString(c.Discount)
+	discount, err := strconv.ParseFloat(c.Discount[:len(c.Discount)-1], 64)
 	if err != nil {
 	if err != nil {
 		w.Write(WrapData(nil, err))
 		w.Write(WrapData(nil, err))
 		return
 		return
 	}
 	}
+	discount = discount * 0.01
 
 
 	idleCoefficients := make(map[string]float64)
 	idleCoefficients := make(map[string]float64)
 
 
 	if allocateIdle {
 	if allocateIdle {
-		windowStr := fmt.Sprintf("%dh", int(durationHours))
-		if a.ThanosClient != nil {
+		idleDurationCalcHours := durationHours
+		if durationHours < 1 {
+			idleDurationCalcHours = 1
+		}
+		windowStr := fmt.Sprintf("%dh", int(idleDurationCalcHours))
+		if A.ThanosClient != nil {
 			klog.Infof("Setting offset to 3h")
 			klog.Infof("Setting offset to 3h")
 			offset = "3h"
 			offset = "3h"
 		}
 		}
-		idleCoefficients, err = ComputeIdleCoefficient(costData, pClient, a.Cloud, discount, windowStr, offset, resolution)
+		idleCoefficients, err = ComputeIdleCoefficient(costData, pClient, A.Cloud, discount, windowStr, offset, resolution)
 		if err != nil {
 		if err != nil {
 			klog.Errorf("error computing idle coefficient: windowString=%s, offset=%s, err=%s", windowStr, offset, err)
 			klog.Errorf("error computing idle coefficient: windowString=%s, offset=%s, err=%s", windowStr, offset, err)
 			w.Write(WrapData(nil, err))
 			w.Write(WrapData(nil, err))
@@ -608,8 +612,8 @@ func (a *Accesses) AggregateCostModel(w http.ResponseWriter, r *http.Request, ps
 		ResolutionCoefficient: resolutionHours,
 		ResolutionCoefficient: resolutionHours,
 		SharedResourceInfo:    sr,
 		SharedResourceInfo:    sr,
 	}
 	}
-	result := AggregateCostData(costData, field, subfields, a.Cloud, opts)
-	a.AggregateCache.Set(aggKey, result, cache.DefaultExpiration)
+	result := AggregateCostData(costData, field, subfields, A.Cloud, opts)
+	A.AggregateCache.Set(aggKey, result, cache.DefaultExpiration)
 
 
 	w.Write(WrapDataWithMessage(result, nil, fmt.Sprintf("aggregate cache miss: %s", aggKey)))
 	w.Write(WrapDataWithMessage(result, nil, fmt.Sprintf("aggregate cache miss: %s", aggKey)))
 }
 }