Parcourir la source

Drop Aggregation API, Drop InstantQuerier, Drop RangeQuerier, tag duplicate queries

Signed-off-by: Matt Bolt <mbolt35@gmail.com>
Matt Bolt il y a 1 an
Parent
commit
c7611abd56

+ 15 - 15
core/pkg/opencost/allocation_test.go

@@ -3469,7 +3469,7 @@ func Test_DetermineSharingName(t *testing.T) {
 	name, err = alloc.determineSharingName(nil)
 	if err != nil {
 		t.Fatalf("determineSharingName: expected no error; actual \"%s\"", err)
-	} else if err != nil || name != "unknown" {
+	} else if name != "unknown" {
 		t.Fatalf("determineSharingName: expected \"unknown\"; actual \"%s\"", name)
 	}
 
@@ -3478,7 +3478,7 @@ func Test_DetermineSharingName(t *testing.T) {
 	name, err = alloc.determineSharingName(options)
 	if err != nil {
 		t.Fatalf("determineSharingName: expected no error; actual \"%s\"", err)
-	} else if err != nil || name != "unknown" {
+	} else if name != "unknown" {
 		t.Fatalf("determineSharingName: expected \"unknown\"; actual \"%s\"", name)
 	}
 
@@ -3487,7 +3487,7 @@ func Test_DetermineSharingName(t *testing.T) {
 	name, err = alloc.determineSharingName(options)
 	if err != nil {
 		t.Fatalf("determineSharingName: expected no error; actual \"%s\"", err)
-	} else if err != nil || name != "namespace1" {
+	} else if name != "namespace1" {
 		t.Fatalf("determineSharingName: expected \"namespace1\"; actual \"%s\"", name)
 	}
 
@@ -3496,7 +3496,7 @@ func Test_DetermineSharingName(t *testing.T) {
 	name, err = alloc.determineSharingName(options)
 	if err != nil {
 		t.Fatalf("determineSharingName: expected no error; actual \"%s\"", err)
-	} else if err != nil || name != "unknown" {
+	} else if name != "unknown" {
 		t.Fatalf("determineSharingName: expected \"unknown\"; actual \"%s\"", name)
 	}
 
@@ -3508,7 +3508,7 @@ func Test_DetermineSharingName(t *testing.T) {
 	name, err = alloc.determineSharingName(options)
 	if err != nil {
 		t.Fatalf("determineSharingName: expected no error; actual \"%s\"", err)
-	} else if err != nil || name != "app1" {
+	} else if name != "app1" {
 		t.Fatalf("determineSharingName: expected \"app1\"; actual \"%s\"", name)
 	}
 
@@ -3519,7 +3519,7 @@ func Test_DetermineSharingName(t *testing.T) {
 	name, err = alloc.determineSharingName(options)
 	if err != nil {
 		t.Fatalf("determineSharingName: expected no error; actual \"%s\"", err)
-	} else if err != nil || name != "app1" {
+	} else if name != "app1" {
 		t.Fatalf("determineSharingName: expected \"app1\"; actual \"%s\"", name)
 	}
 
@@ -3530,7 +3530,7 @@ func Test_DetermineSharingName(t *testing.T) {
 	name, err = alloc.determineSharingName(options)
 	if err != nil {
 		t.Fatalf("determineSharingName: expected no error; actual \"%s\"", err)
-	} else if err != nil || name != "unknown" {
+	} else if name != "unknown" {
 		t.Fatalf("determineSharingName: expected \"unknown\"; actual \"%s\"", name)
 	}
 
@@ -3542,7 +3542,7 @@ func Test_DetermineSharingName(t *testing.T) {
 	name, err = alloc.determineSharingName(options)
 	if err != nil {
 		t.Fatalf("determineSharingName: expected no error; actual \"%s\"", err)
-	} else if err != nil || name != "app1" {
+	} else if name != "app1" {
 		t.Fatalf("determineSharingName: expected \"app1\"; actual \"%s\"", name)
 	}
 
@@ -3554,7 +3554,7 @@ func Test_DetermineSharingName(t *testing.T) {
 	name, err = alloc.determineSharingName(options)
 	if err != nil {
 		t.Fatalf("determineSharingName: expected no error; actual \"%s\"", err)
-	} else if err != nil || name != "app1" {
+	} else if name != "app1" {
 		t.Fatalf("determineSharingName: expected \"app1\"; actual \"%s\"", name)
 	}
 
@@ -3566,7 +3566,7 @@ func Test_DetermineSharingName(t *testing.T) {
 	name, err = alloc.determineSharingName(options)
 	if err != nil {
 		t.Fatalf("determineSharingName: expected no error; actual \"%s\"", err)
-	} else if err != nil || name != "unknown" {
+	} else if name != "unknown" {
 		t.Fatalf("determineSharingName: expected \"unknown\"; actual \"%s\"", name)
 	}
 
@@ -3583,7 +3583,7 @@ func Test_DetermineSharingName(t *testing.T) {
 	name, err = alloc.determineSharingName(options)
 	if err != nil {
 		t.Fatalf("determineSharingName: expected no error; actual \"%s\"", err)
-	} else if err != nil || name != "app1" {
+	} else if name != "app1" {
 		t.Fatalf("determineSharingName: expected \"app1\"; actual \"%s\"", name)
 	}
 
@@ -3600,7 +3600,7 @@ func Test_DetermineSharingName(t *testing.T) {
 	name, err = alloc.determineSharingName(options)
 	if err != nil {
 		t.Fatalf("determineSharingName: expected no error; actual \"%s\"", err)
-	} else if err != nil || name != "env1" {
+	} else if name != "env1" {
 		t.Fatalf("determineSharingName: expected \"env1\"; actual \"%s\"", name)
 	}
 
@@ -3611,7 +3611,7 @@ func Test_DetermineSharingName(t *testing.T) {
 	name, err = alloc.determineSharingName(options)
 	if err != nil {
 		t.Fatalf("determineSharingName: expected no error; actual \"%s\"", err)
-	} else if err != nil || name != "namespace1" {
+	} else if name != "namespace1" {
 		t.Fatalf("determineSharingName: expected \"namespace1\"; actual \"%s\"", name)
 	}
 
@@ -3622,7 +3622,7 @@ func Test_DetermineSharingName(t *testing.T) {
 	name, err = alloc.determineSharingName(options)
 	if err != nil {
 		t.Fatalf("determineSharingName: expected no error; actual \"%s\"", err)
-	} else if err != nil || name != "namespace2" {
+	} else if name != "namespace2" {
 		t.Fatalf("determineSharingName: expected \"namespace2\"; actual \"%s\"", name)
 	}
 
@@ -3632,7 +3632,7 @@ func Test_DetermineSharingName(t *testing.T) {
 	name, err = alloc.determineSharingName(options)
 	if err != nil {
 		t.Fatalf("determineSharingName: expected no error; actual \"%s\"", err)
-	} else if err != nil || name != "unknown" {
+	} else if name != "unknown" {
 		t.Fatalf("determineSharingName: expected \"unknown\"; actual \"%s\"", name)
 	}
 }

+ 0 - 36
core/pkg/opencost/window.go

@@ -15,12 +15,6 @@ import (
 	"github.com/opencost/opencost/core/pkg/util/timeutil"
 )
 
-const (
-	minutesPerDay  = 60 * 24
-	minutesPerHour = 60
-	hoursPerDay    = 24
-)
-
 var (
 	durationRegex       = regexp.MustCompile(`^(\d+)(m|h|d|w)$`)
 	durationOffsetRegex = regexp.MustCompile(`^(\d+)(m|h|d|w) offset (\d+)(m|h|d|w)$`)
@@ -29,40 +23,10 @@ var (
 	rfcRegex            = regexp.MustCompile(fmt.Sprintf(`(%s),(%s)`, rfc3339, rfc3339))
 	timestampPairRegex  = regexp.MustCompile(`^(\d+)[,|-](\d+)$`)
 
-	tOffsetLock sync.Mutex
-	tOffset     *time.Duration
-
 	utcOffsetLock sync.Mutex
 	utcOffsetDur  *time.Duration
 )
 
-// get and cache the thanos offset duration.
-// TODO: Due to dependencies here, we have to drag a non-core config option into
-// TOOD: core scope. Any solution here would be a one-off until we can generalize
-// TODO: global configuration options.
-func thanosOffset() time.Duration {
-	tOffsetLock.Lock()
-	defer tOffsetLock.Unlock()
-
-	if tOffset == nil {
-		d, err := time.ParseDuration(env.Get("THANOS_QUERY_OFFSET", "3h"))
-		if err != nil {
-			d = 0
-		}
-
-		tOffset = &d
-	}
-
-	return *tOffset
-}
-
-// returns true if thanos is enabled
-// TODO: Same note as thanosOffset above - temporary work-around until more
-// TODO: generalized global configuration.
-func isThanosEnabled() bool {
-	return env.GetBool("THANOS_ENABLED", false)
-}
-
 // returns the configured utc offset as a duration
 // TODO: Same as the above options -- we should provide a one-time initialization configuration
 // TODO: for these values, or deprecate their use.

+ 1 - 1
core/pkg/opencost/window_test.go

@@ -1166,7 +1166,7 @@ func TestMarshalUnmarshal(t *testing.T) {
 			}
 
 			if diff := cmp.Diff(c.w, unmarshaledW); len(diff) > 0 {
-				t.Errorf(diff)
+				t.Errorf("%s", diff)
 			}
 		})
 	}

+ 3 - 57
core/pkg/source/datasource.go

@@ -7,55 +7,6 @@ import (
 	"github.com/opencost/opencost/core/pkg/clusters"
 )
 
-type InstantMetricsQuerier interface {
-	QueryRAMUsage(window string, offset string) QueryResultsChan
-	QueryCPUUsage(window string, offset string) QueryResultsChan
-	QueryNetworkInZoneRequests(window string, offset string) QueryResultsChan
-	QueryNetworkInRegionRequests(window string, offset string) QueryResultsChan
-	QueryNetworkInternetRequests(window string, offset string) QueryResultsChan
-	QueryNormalization(window string, offset string) QueryResultsChan
-
-	QueryHistoricalCPUCost(window string, offset string) QueryResultsChan
-	QueryHistoricalRAMCost(window string, offset string) QueryResultsChan
-	QueryHistoricalGPUCost(window string, offset string) QueryResultsChan
-	QueryHistoricalPodLabels(window string, offset string) QueryResultsChan
-}
-
-type RangeMetricsQuerier interface {
-	QueryRAMRequestsOverTime(start, end time.Time, resolution time.Duration) QueryResultsChan
-	QueryRAMUsageOverTime(start, end time.Time, resolution time.Duration) QueryResultsChan
-	QueryRAMAllocationOverTime(start, end time.Time, resolution time.Duration) QueryResultsChan
-
-	QueryCPURequestsOverTime(start, end time.Time, resolution time.Duration) QueryResultsChan
-	QueryCPUUsageOverTime(start, end time.Time, resolution time.Duration) QueryResultsChan
-	QueryCPUAllocationOverTime(start, end time.Time, resolution time.Duration) QueryResultsChan
-
-	QueryGPURequestsOverTime(start, end time.Time, resolution time.Duration) QueryResultsChan
-
-	QueryPVRequestsOverTime(start, end time.Time, resolution time.Duration) QueryResultsChan
-	QueryPVCAllocationOverTime(start, end time.Time, resolution time.Duration) QueryResultsChan
-	QueryPVHourlyCostOverTime(start, end time.Time, resolution time.Duration) QueryResultsChan
-
-	QueryNetworkInZoneOverTime(start, end time.Time, resolution time.Duration) QueryResultsChan
-	QueryNetworkInRegionOverTime(start, end time.Time, resolution time.Duration) QueryResultsChan
-	QueryNetworkInternetOverTime(start, end time.Time, resolution time.Duration) QueryResultsChan
-
-	QueryNamespaceLabelsOverTime(start, end time.Time, resolution time.Duration) QueryResultsChan
-	QueryNamespaceAnnotationsOverTime(start, end time.Time, resolution time.Duration) QueryResultsChan
-
-	QueryPodLabelsOverTime(start, end time.Time, resolution time.Duration) QueryResultsChan
-	QueryPodAnnotationsOverTime(start, end time.Time, resolution time.Duration) QueryResultsChan
-
-	QueryServiceLabelsOverTime(start, end time.Time, resolution time.Duration) QueryResultsChan
-	QueryDeploymentLabelsOverTime(start, end time.Time, resolution time.Duration) QueryResultsChan
-	QueryStatefulsetLabelsOverTime(start, end time.Time, resolution time.Duration) QueryResultsChan
-
-	QueryPodJobsOverTime(start, end time.Time, resolution time.Duration) QueryResultsChan
-	QueryPodDaemonsetsOverTime(start, end time.Time, resolution time.Duration) QueryResultsChan
-
-	QueryNormalizationOverTime(start, end time.Time, resolution time.Duration) QueryResultsChan
-}
-
 type ClusterMetricsQuerier interface {
 	// Cluster Disks
 	QueryPVCost(start, end time.Time) QueryResultsChan
@@ -77,14 +28,14 @@ type ClusterMetricsQuerier interface {
 	QueryLocalStorageUsedByProvider(provider string, start, end time.Time) QueryResultsChan
 
 	// Nodes
-	QueryNodeCPUHourlyCost(start, end time.Time) QueryResultsChan
+	QueryNodeCPUHourlyCost(start, end time.Time) QueryResultsChan // Duplicate: QueryNodeCostPerCPUHr
 	QueryNodeCPUCoresCapacity(start, end time.Time) QueryResultsChan
 	QueryNodeCPUCoresAllocatable(start, end time.Time) QueryResultsChan
-	QueryNodeRAMHourlyCost(start, end time.Time) QueryResultsChan
+	QueryNodeRAMHourlyCost(start, end time.Time) QueryResultsChan // Duplicate: QueryNodeCostPerRAMHr
 	QueryNodeRAMBytesCapacity(start, end time.Time) QueryResultsChan
 	QueryNodeRAMBytesAllocatable(start, end time.Time) QueryResultsChan
 	QueryNodeGPUCount(start, end time.Time) QueryResultsChan
-	QueryNodeGPUHourlyCost(start, end time.Time) QueryResultsChan
+	QueryNodeGPUHourlyCost(start, end time.Time) QueryResultsChan // Duplicate: QueryNodeCostPerGPUHr
 	QueryNodeLabels(start, end time.Time) QueryResultsChan
 	QueryNodeActiveMinutes(start, end time.Time) QueryResultsChan
 	QueryNodeIsSpot(start, end time.Time) QueryResultsChan
@@ -94,9 +45,6 @@ type ClusterMetricsQuerier interface {
 	QueryNodeRAMSystemPercent(start, end time.Time) QueryResultsChan
 	QueryNodeRAMUserPercent(start, end time.Time) QueryResultsChan
 
-	//QueryNodeTotalLocalStorage(start, end time.Time) QueryResultsChan
-	//QueryNodeUsedLocalStorage(start, end time.Time) QueryResultsChan
-
 	// Load Balancers
 	QueryLBCost(start, end time.Time) QueryResultsChan
 	QueryLBActiveMinutes(start, end time.Time) QueryResultsChan
@@ -174,8 +122,6 @@ type AllocationMetricsQuerier interface {
 }
 
 type OpenCostDataSource interface {
-	InstantMetricsQuerier
-	RangeMetricsQuerier
 	ClusterMetricsQuerier
 	AllocationMetricsQuerier
 

+ 0 - 582
modules/prometheus-source/pkg/prom/datasource.go

@@ -576,588 +576,6 @@ func (pds *PrometheusDataSource) MetaData() map[string]string {
 //  InstantMetricsQuerier
 //--------------------------------------------------------------------------
 
-func (pds *PrometheusDataSource) QueryRAMUsage(window string, offset string) source.QueryResultsChan {
-	const ramUsageQuery = `avg(
-		label_replace(
-			label_replace(
-				label_replace(
-					sum_over_time(container_memory_working_set_bytes{container!="", container!="POD", instance!="", %s}[%s] %s), "node", "$1", "instance", "(.+)"
-				), "container_name", "$1", "container", "(.+)"
-			), "pod_name", "$1", "pod", "(.+)"
-		)
-	) by (namespace, container_name, pod_name, node, %s)`
-	// env.GetPromClusterFilter(), window, offset, env.GetPromClusterLabel())
-
-	if offset != "" && !strings.Contains(offset, "offset") {
-		offset = fmt.Sprintf("offset %s", offset)
-	}
-
-	cfg := pds.promConfig
-
-	queryRAMUsage := fmt.Sprintf(ramUsageQuery, cfg.ClusterFilter, window, offset, cfg.ClusterLabel)
-	ctx := pds.promContexts.NewNamedContext(ComputeCostDataContextName)
-	return ctx.Query(queryRAMUsage)
-}
-
-func (pds *PrometheusDataSource) QueryCPUUsage(window string, offset string) source.QueryResultsChan {
-	const cpuUsageQuery = `avg(
-		label_replace(
-			label_replace(
-				label_replace(
-					rate(
-						container_cpu_usage_seconds_total{container!="", container!="POD", instance!="", %s}[%s] %s
-					), "node", "$1", "instance", "(.+)"
-				), "container_name", "$1", "container", "(.+)"
-			), "pod_name", "$1", "pod", "(.+)"
-		)
-	) by (namespace, container_name, pod_name, node, %s)`
-	// env.GetPromClusterFilter(), window, offset, env.GetPromClusterLabel())
-
-	if offset != "" && !strings.Contains(offset, "offset") {
-		offset = fmt.Sprintf("offset %s", offset)
-	}
-
-	cfg := pds.promConfig
-
-	queryCPUUsage := fmt.Sprintf(cpuUsageQuery, cfg.ClusterFilter, window, offset, cfg.ClusterLabel)
-	ctx := pds.promContexts.NewNamedContext(ComputeCostDataContextName)
-	return ctx.Query(queryCPUUsage)
-}
-
-func (pds *PrometheusDataSource) QueryNetworkInZoneRequests(window string, offset string) source.QueryResultsChan {
-	const zoneNetworkUsageQuery = `sum(increase(kubecost_pod_network_egress_bytes_total{internet="false", sameZone="false", sameRegion="true", %s}[%s] %s)) by (namespace,pod_name,%s) / 1024 / 1024 / 1024`
-	// env.GetPromClusterFilter(), window, "", env.GetPromClusterLabel())
-
-	if offset != "" && !strings.Contains(offset, "offset") {
-		offset = fmt.Sprintf("offset %s", offset)
-	}
-
-	cfg := pds.promConfig
-
-	queryZoneNetworkUsage := fmt.Sprintf(zoneNetworkUsageQuery, cfg.ClusterFilter, window, offset, cfg.ClusterLabel)
-	ctx := pds.promContexts.NewNamedContext(ComputeCostDataContextName)
-	return ctx.Query(queryZoneNetworkUsage)
-}
-
-func (pds *PrometheusDataSource) QueryNetworkInRegionRequests(window string, offset string) source.QueryResultsChan {
-	const regionNetworkUsageQuery = `sum(increase(kubecost_pod_network_egress_bytes_total{internet="false", sameZone="false", sameRegion="false", %s}[%s] %s)) by (namespace,pod_name,%s) / 1024 / 1024 / 1024`
-	// env.GetPromClusterFilter(), window, "", env.GetPromClusterLabel())
-
-	if offset != "" && !strings.Contains(offset, "offset") {
-		offset = fmt.Sprintf("offset %s", offset)
-	}
-
-	cfg := pds.promConfig
-
-	queryRegionNetworkUsage := fmt.Sprintf(regionNetworkUsageQuery, cfg.ClusterFilter, window, offset, cfg.ClusterLabel)
-	ctx := pds.promContexts.NewNamedContext(ComputeCostDataContextName)
-	return ctx.Query(queryRegionNetworkUsage)
-}
-
-func (pds *PrometheusDataSource) QueryNetworkInternetRequests(window string, offset string) source.QueryResultsChan {
-	const internetNetworkUsageQuery = `sum(increase(kubecost_pod_network_egress_bytes_total{internet="true", %s}[%s] %s)) by (namespace,pod_name,%s) / 1024 / 1024 / 1024`
-	// env.GetPromClusterFilter(), window, "", env.GetPromClusterLabel())
-
-	cfg := pds.promConfig
-
-	queryInternetNetworkUsage := fmt.Sprintf(internetNetworkUsageQuery, cfg.ClusterFilter, window, offset, cfg.ClusterLabel)
-	ctx := pds.promContexts.NewNamedContext(ComputeCostDataContextName)
-	return ctx.Query(queryInternetNetworkUsage)
-}
-
-func (pds *PrometheusDataSource) QueryNormalization(window string, offset string) source.QueryResultsChan {
-	const normalizationQuery = `max(count_over_time(kube_pod_container_resource_requests{resource="memory", unit="byte", %s}[%s] %s))`
-	// env.GetPromClusterFilter(), window, offset)
-
-	if offset != "" && !strings.Contains(offset, "offset") {
-		offset = fmt.Sprintf("offset %s", offset)
-	}
-
-	cfg := pds.promConfig
-
-	queryNormalization := fmt.Sprintf(normalizationQuery, cfg.ClusterFilter, window, offset)
-	ctx := pds.promContexts.NewNamedContext(ComputeCostDataContextName)
-	return ctx.Query(queryNormalization)
-}
-
-func (pds *PrometheusDataSource) QueryHistoricalCPUCost(window string, offset string) source.QueryResultsChan {
-	const historicalCPUCostQuery = `avg(avg_over_time(node_cpu_hourly_cost{%s}[%s] %s)) by (node, instance, %s)`
-	// env.GetPromClusterFilter(), window, offsetStr, env.GetPromClusterLabel())
-
-	if offset != "" && !strings.Contains(offset, "offset") {
-		offset = fmt.Sprintf("offset %s", offset)
-	}
-
-	cfg := pds.promConfig
-
-	queryHistoricalCPUCost := fmt.Sprintf(historicalCPUCostQuery, cfg.ClusterFilter, window, offset, cfg.ClusterLabel)
-	ctx := pds.promContexts.NewNamedContext(ComputeCostDataContextName)
-	return ctx.Query(queryHistoricalCPUCost)
-}
-
-func (pds *PrometheusDataSource) QueryHistoricalRAMCost(window string, offset string) source.QueryResultsChan {
-	const historicalRAMCostQuery = `avg(avg_over_time(node_ram_hourly_cost{%s}[%s] %s)) by (node, instance, %s)`
-	// env.GetPromClusterFilter(), window, offsetStr, env.GetPromClusterLabel())
-
-	if offset != "" && !strings.Contains(offset, "offset") {
-		offset = fmt.Sprintf("offset %s", offset)
-	}
-
-	cfg := pds.promConfig
-
-	queryHistoricalRAMCost := fmt.Sprintf(historicalRAMCostQuery, cfg.ClusterFilter, window, offset, cfg.ClusterLabel)
-	ctx := pds.promContexts.NewNamedContext(ComputeCostDataContextName)
-	return ctx.Query(queryHistoricalRAMCost)
-}
-
-func (pds *PrometheusDataSource) QueryHistoricalGPUCost(window string, offset string) source.QueryResultsChan {
-	const historicalGPUCostQuery = `avg(avg_over_time(node_gpu_hourly_cost{%s}[%s] %s)) by (node, instance, %s)`
-	// env.GetPromClusterFilter(), window, offsetStr, env.GetPromClusterLabel())
-
-	if offset != "" && !strings.Contains(offset, "offset") {
-		offset = fmt.Sprintf("offset %s", offset)
-	}
-
-	cfg := pds.promConfig
-
-	queryHistoricalGPUCost := fmt.Sprintf(historicalGPUCostQuery, cfg.ClusterFilter, window, offset, cfg.ClusterLabel)
-	ctx := pds.promContexts.NewNamedContext(ComputeCostDataContextName)
-	return ctx.Query(queryHistoricalGPUCost)
-}
-
-func (pds *PrometheusDataSource) QueryHistoricalPodLabels(window string, offset string) source.QueryResultsChan {
-	const historicalPodLabelsQuery = `kube_pod_labels{%s}[%s] %s`
-	// env.GetPromClusterFilter(), window, offset
-
-	if offset != "" && !strings.Contains(offset, "offset") {
-		offset = fmt.Sprintf("offset %s", offset)
-	}
-
-	cfg := pds.promConfig
-
-	queryHistoricalPodLabels := fmt.Sprintf(historicalPodLabelsQuery, cfg.ClusterFilter, window, offset)
-	ctx := pds.promContexts.NewNamedContext(ComputeCostDataContextName)
-	return ctx.Query(queryHistoricalPodLabels)
-}
-
-//--------------------------------------------------------------------------
-//  RangeMetricsQuerier
-//--------------------------------------------------------------------------
-
-func (pds *PrometheusDataSource) QueryRAMRequestsOverTime(start, end time.Time, resolution time.Duration) source.QueryResultsChan {
-	const ramRequestsQuery = `avg(
-		label_replace(
-			label_replace(
-				sum_over_time(kube_pod_container_resource_requests{resource="memory", unit="byte", container!="",container!="POD", node!="", %s}[%s] %s)
-				, "container_name","$1","container","(.+)"
-			), "pod_name","$1","pod","(.+)"
-		)
-	) by (namespace,container_name,pod_name,node,%s)`
-	// env.GetPromClusterFilter(), resStr, "", env.GetPromClusterLabel())
-
-	cfg := pds.promConfig
-
-	resolution = snapResolutionMinute(resolution)
-	resMins := int64(resolution.Minutes())
-	resStr := formatResolutionMinutes(resMins)
-
-	queryRAMRequests := fmt.Sprintf(ramRequestsQuery, cfg.ClusterFilter, resStr, "", cfg.ClusterLabel)
-	ctx := pds.promContexts.NewNamedContext(ComputeCostDataRangeContextName)
-	return ctx.QueryRange(queryRAMRequests, start, end, resolution)
-}
-
-func (pds *PrometheusDataSource) QueryRAMUsageOverTime(start, end time.Time, resolution time.Duration) source.QueryResultsChan {
-	const ramUsageQuery = `avg(
-		label_replace(
-			label_replace(
-				label_replace(
-					sum_over_time(container_memory_working_set_bytes{container!="", container!="POD", instance!="", %s}[%s] %s), "node", "$1", "instance", "(.+)"
-				), "container_name", "$1", "container", "(.+)"
-			), "pod_name", "$1", "pod", "(.+)"
-		)
-	) by (namespace, container_name, pod_name, node, %s)`
-	// env.GetPromClusterFilter(), resStr, "", env.GetPromClusterLabel())
-
-	cfg := pds.promConfig
-
-	resolution = snapResolutionMinute(resolution)
-	resMins := int64(resolution.Minutes())
-	resStr := formatResolutionMinutes(resMins)
-
-	queryRAMUsage := fmt.Sprintf(ramUsageQuery, cfg.ClusterFilter, resStr, "", cfg.ClusterLabel)
-	ctx := pds.promContexts.NewNamedContext(ComputeCostDataRangeContextName)
-	return ctx.QueryRange(queryRAMUsage, start, end, resolution)
-}
-
-func (pds *PrometheusDataSource) QueryRAMAllocationOverTime(start, end time.Time, resolution time.Duration) source.QueryResultsChan {
-	// ramAllocationByteHoursQuery yields the total byte-hour RAM allocation over the given
-	// window, aggregated by container.
-	//  [line 3]  sum_over_time(each byte) = [byte*scrape] by metric
-	//  [line 4] (scalar(avg(prometheus_target_interval_length_seconds)) = [seconds/scrape] / 60 / 60 =  [hours/scrape] by container
-	//  [lines 2,4]  sum(") by unique container key and multiply [byte*scrape] * [hours/scrape] for byte*hours
-	//  [lines 1,5]  relabeling
-	const ramAllocationByteHoursQuery = `
-		label_replace(label_replace(
-			sum(
-				sum_over_time(container_memory_allocation_bytes{container!="",container!="POD", node!="", %s}[%s])
-			) by (namespace,container,pod,node,%s) * %f / 60 / 60
-		, "container_name","$1","container","(.+)"), "pod_name","$1","pod","(.+)")`
-	// env.GetPromClusterFilter(), resStr, env.GetPromClusterLabel(), scrapeIntervalSeconds)
-
-	cfg := pds.promConfig
-
-	resolution = snapResolutionMinute(resolution)
-	resMins := int64(resolution.Minutes())
-	resStr := formatResolutionMinutes(resMins)
-
-	scrapeIntervalSeconds := cfg.ScrapeInterval.Seconds()
-
-	queryRAMAllocationByteHours := fmt.Sprintf(ramAllocationByteHoursQuery, cfg.ClusterFilter, resStr, cfg.ClusterLabel, scrapeIntervalSeconds)
-	ctx := pds.promContexts.NewNamedContext(ComputeCostDataRangeContextName)
-	return ctx.QueryRange(queryRAMAllocationByteHours, start, end, resolution)
-}
-
-func (pds *PrometheusDataSource) QueryCPURequestsOverTime(start, end time.Time, resolution time.Duration) source.QueryResultsChan {
-	const cpuRequestsQuery = `avg(
-		label_replace(
-			label_replace(
-				sum_over_time(kube_pod_container_resource_requests{resource="cpu", unit="core", container!="",container!="POD", node!="", %s}[%s] %s)
-				, "container_name","$1","container","(.+)"
-			), "pod_name","$1","pod","(.+)"
-		)
-	) by (namespace,container_name,pod_name,node,%s)`
-	// env.GetPromClusterFilter(), resStr, "", env.GetPromClusterLabel())
-
-	cfg := pds.promConfig
-
-	resolution = snapResolutionMinute(resolution)
-	resMins := int64(resolution.Minutes())
-	resStr := formatResolutionMinutes(resMins)
-
-	queryCPURequests := fmt.Sprintf(cpuRequestsQuery, cfg.ClusterFilter, resStr, "", cfg.ClusterLabel)
-	ctx := pds.promContexts.NewNamedContext(ComputeCostDataRangeContextName)
-	return ctx.QueryRange(queryCPURequests, start, end, resolution)
-}
-
-func (pds *PrometheusDataSource) QueryCPUUsageOverTime(start, end time.Time, resolution time.Duration) source.QueryResultsChan {
-	const cpuUsageQuery = `avg(
-		label_replace(
-			label_replace(
-				label_replace(
-					rate(
-						container_cpu_usage_seconds_total{container!="", container!="POD", instance!="", %s}[%s] %s
-					), "node", "$1", "instance", "(.+)"
-				), "container_name", "$1", "container", "(.+)"
-			), "pod_name", "$1", "pod", "(.+)"
-		)
-	) by (namespace, container_name, pod_name, node, %s)`
-	// env.GetPromClusterFilter(), resStr, "", env.GetPromClusterLabel())
-
-	cfg := pds.promConfig
-
-	resolution = snapResolutionMinute(resolution)
-	resMins := int64(resolution.Minutes())
-	resStr := formatResolutionMinutes(resMins)
-
-	queryCPUUsage := fmt.Sprintf(cpuUsageQuery, cfg.ClusterFilter, resStr, "", cfg.ClusterLabel)
-	ctx := pds.promContexts.NewNamedContext(ComputeCostDataRangeContextName)
-	return ctx.QueryRange(queryCPUUsage, start, end, resolution)
-}
-
-func (pds *PrometheusDataSource) QueryCPUAllocationOverTime(start, end time.Time, resolution time.Duration) source.QueryResultsChan {
-	// cpuAllocationQuery yields the total VCPU-hour CPU allocation over the given
-	// window, aggregated by container.
-	//  [line 3] sum_over_time(each VCPU*mins in window) = [VCPU*scrape] by metric
-	//  [line 4] (scalar(avg(prometheus_target_interval_length_seconds)) = [seconds/scrape] / 60 / 60 =  [hours/scrape] by container
-	//  [lines 2,4]  sum(") by unique container key and multiply [VCPU*scrape] * [hours/scrape] for VCPU*hours
-	//  [lines 1,5]  relabeling
-	const cpuAllocationQuery = `
-		label_replace(label_replace(
-			sum(
-				sum_over_time(container_cpu_allocation{container!="",container!="POD", node!="", %s}[%s])
-			) by (namespace,container,pod,node,%s) * %f / 60 / 60
-		, "container_name","$1","container","(.+)"), "pod_name","$1","pod","(.+)")`
-	// env.GetPromClusterFilter(), resStr, env.GetPromClusterLabel(), scrapeIntervalSeconds)
-
-	cfg := pds.promConfig
-
-	resolution = snapResolutionMinute(resolution)
-	resMins := int64(resolution.Minutes())
-	resStr := formatResolutionMinutes(resMins)
-
-	scrapeIntervalSeconds := cfg.ScrapeInterval.Seconds()
-
-	queryCPUAllocation := fmt.Sprintf(cpuAllocationQuery, cfg.ClusterFilter, resStr, cfg.ClusterLabel, scrapeIntervalSeconds)
-	ctx := pds.promContexts.NewNamedContext(ComputeCostDataRangeContextName)
-	return ctx.QueryRange(queryCPUAllocation, start, end, resolution)
-}
-
-func (pds *PrometheusDataSource) QueryGPURequestsOverTime(start, end time.Time, resolution time.Duration) source.QueryResultsChan {
-	const gpuRequestsQuery = `avg(
-		label_replace(
-			label_replace(
-				sum_over_time(kube_pod_container_resource_requests{resource="nvidia_com_gpu", container!="",container!="POD", node!="", %s}[%s] %s),
-				"container_name","$1","container","(.+)"
-			), "pod_name","$1","pod","(.+)"
-		)
-	) by (namespace,container_name,pod_name,node,%s)`
-	// env.GetPromClusterFilter(), resStr, "", env.GetPromClusterLabel())
-
-	cfg := pds.promConfig
-
-	resolution = snapResolutionMinute(resolution)
-	resMins := int64(resolution.Minutes())
-	resStr := formatResolutionMinutes(resMins)
-
-	queryGPURequests := fmt.Sprintf(gpuRequestsQuery, cfg.ClusterFilter, resStr, "", cfg.ClusterLabel)
-	ctx := pds.promContexts.NewNamedContext(ComputeCostDataRangeContextName)
-	return ctx.QueryRange(queryGPURequests, start, end, resolution)
-}
-
-func (pds *PrometheusDataSource) QueryPVRequestsOverTime(start, end time.Time, resolution time.Duration) source.QueryResultsChan {
-	const pvRequestsQuery = `avg(avg(kube_persistentvolumeclaim_info{volumename != "", %s}) by (persistentvolumeclaim, storageclass, namespace, volumename, %s, kubernetes_node)
-	*
-	on (persistentvolumeclaim, namespace, %s, kubernetes_node) group_right(storageclass, volumename)
-	sum(kube_persistentvolumeclaim_resource_requests_storage_bytes{%s}) by (persistentvolumeclaim, namespace, %s, kubernetes_node, kubernetes_name)) by (persistentvolumeclaim, storageclass, namespace, %s, volumename, kubernetes_node)`
-	// env.GetPromClusterFilter(), env.GetPromClusterLabel(), env.GetPromClusterLabel(), env.GetPromClusterFilter(), env.GetPromClusterLabel(), env.GetPromClusterLabel())
-
-	cfg := pds.promConfig
-	resolution = snapResolutionMinute(resolution)
-
-	queryPVRequests := fmt.Sprintf(pvRequestsQuery, cfg.ClusterFilter, cfg.ClusterLabel, cfg.ClusterLabel, cfg.ClusterFilter, cfg.ClusterLabel, cfg.ClusterLabel)
-	ctx := pds.promContexts.NewNamedContext(ComputeCostDataRangeContextName)
-	return ctx.QueryRange(queryPVRequests, start, end, resolution)
-}
-
-func (pds *PrometheusDataSource) QueryPVCAllocationOverTime(start, end time.Time, resolution time.Duration) source.QueryResultsChan {
-	// pvcAllocationQuery yields the total byte-hour PVC allocation over the given window.
-	// sum_over_time(each byte) = [byte*scrape] by metric *(scalar(avg(prometheus_target_interval_length_seconds)) = [seconds/scrape] / 60 / 60 =  [hours/scrape] by pod
-	const pvcAllocationQuery = `sum(sum_over_time(pod_pvc_allocation{%s}[%s])) by (%s, namespace, pod, persistentvolume, persistentvolumeclaim) * %f/60/60`
-	// env.GetPromClusterFilter(), resStr, env.GetPromClusterLabel(), scrapeIntervalSeconds)
-
-	cfg := pds.promConfig
-
-	resolution = snapResolutionMinute(resolution)
-	resMins := int64(resolution.Minutes())
-	resStr := formatResolutionMinutes(resMins)
-
-	scrapeIntervalSeconds := cfg.ScrapeInterval.Seconds()
-
-	queryPVCAllocation := fmt.Sprintf(pvcAllocationQuery, cfg.ClusterFilter, resStr, cfg.ClusterLabel, scrapeIntervalSeconds)
-	ctx := pds.promContexts.NewNamedContext(ComputeCostDataRangeContextName)
-	return ctx.QueryRange(queryPVCAllocation, start, end, resolution)
-}
-
-func (pds *PrometheusDataSource) QueryPVHourlyCostOverTime(start, end time.Time, resolution time.Duration) source.QueryResultsChan {
-	const pvHourlyCostQuery = `avg_over_time(pv_hourly_cost{%s}[%s])`
-	// env.GetPromClusterFilter(), resStr)
-
-	cfg := pds.promConfig
-
-	resolution = snapResolutionMinute(resolution)
-	resMins := int64(resolution.Minutes())
-	resStr := formatResolutionMinutes(resMins)
-
-	queryPVHourlyCost := fmt.Sprintf(pvHourlyCostQuery, cfg.ClusterFilter, resStr)
-	ctx := pds.promContexts.NewNamedContext(ComputeCostDataRangeContextName)
-	return ctx.QueryRange(queryPVHourlyCost, start, end, resolution)
-}
-
-func (pds *PrometheusDataSource) QueryNetworkInZoneOverTime(start, end time.Time, resolution time.Duration) source.QueryResultsChan {
-	const netZoneRequestsQuery = `sum(increase(kubecost_pod_network_egress_bytes_total{internet="false", sameZone="false", sameRegion="true", %s}[%s] %s)) by (namespace,pod_name,%s) / 1024 / 1024 / 1024`
-	// env.GetPromClusterFilter(), resStr, "", env.GetPromClusterLabel())
-
-	cfg := pds.promConfig
-
-	resolution = snapResolutionMinute(resolution)
-	resMins := int64(resolution.Minutes())
-	resStr := formatResolutionMinutes(resMins)
-
-	queryNetZoneRequests := fmt.Sprintf(netZoneRequestsQuery, cfg.ClusterFilter, resStr, "", cfg.ClusterLabel)
-	ctx := pds.promContexts.NewNamedContext(ComputeCostDataRangeContextName)
-	return ctx.QueryRange(queryNetZoneRequests, start, end, resolution)
-}
-
-func (pds *PrometheusDataSource) QueryNetworkInRegionOverTime(start, end time.Time, resolution time.Duration) source.QueryResultsChan {
-	const netRegionRequestsQuery = `sum(increase(kubecost_pod_network_egress_bytes_total{internet="false", sameZone="false", sameRegion="false", %s}[%s] %s)) by (namespace,pod_name,%s) / 1024 / 1024 / 1024`
-	// env.GetPromClusterFilter(), resStr, "", env.GetPromClusterLabel())
-
-	cfg := pds.promConfig
-
-	resolution = snapResolutionMinute(resolution)
-	resMins := int64(resolution.Minutes())
-	resStr := formatResolutionMinutes(resMins)
-
-	queryNetRegionRequests := fmt.Sprintf(netRegionRequestsQuery, cfg.ClusterFilter, resStr, "", cfg.ClusterLabel)
-	ctx := pds.promContexts.NewNamedContext(ComputeCostDataRangeContextName)
-	return ctx.QueryRange(queryNetRegionRequests, start, end, resolution)
-}
-
-func (pds *PrometheusDataSource) QueryNetworkInternetOverTime(start, end time.Time, resolution time.Duration) source.QueryResultsChan {
-	const netInternetRequestsQuery = `sum(increase(kubecost_pod_network_egress_bytes_total{internet="true", %s}[%s] %s)) by (namespace,pod_name,%s) / 1024 / 1024 / 1024`
-	// env.GetPromClusterFilter(), resStr, "", env.GetPromClusterLabel())
-
-	cfg := pds.promConfig
-
-	resolution = snapResolutionMinute(resolution)
-	resMins := int64(resolution.Minutes())
-	resStr := formatResolutionMinutes(resMins)
-
-	queryNetInternetRequests := fmt.Sprintf(netInternetRequestsQuery, cfg.ClusterFilter, resStr, "", cfg.ClusterLabel)
-	ctx := pds.promContexts.NewNamedContext(ComputeCostDataRangeContextName)
-	return ctx.QueryRange(queryNetInternetRequests, start, end, resolution)
-}
-
-func (pds *PrometheusDataSource) QueryNamespaceLabelsOverTime(start, end time.Time, resolution time.Duration) source.QueryResultsChan {
-	const namespaceLabelsQuery = `avg_over_time(kube_namespace_labels{%s}[%s])`
-	// env.GetPromClusterFilter(), resStr
-
-	cfg := pds.promConfig
-
-	resolution = snapResolutionMinute(resolution)
-	resMins := int64(resolution.Minutes())
-	resStr := formatResolutionMinutes(resMins)
-
-	queryNamespaceLabels := fmt.Sprintf(namespaceLabelsQuery, cfg.ClusterFilter, resStr)
-	ctx := pds.promContexts.NewNamedContext(ComputeCostDataRangeContextName)
-	return ctx.QueryRange(queryNamespaceLabels, start, end, resolution)
-}
-
-func (pds *PrometheusDataSource) QueryNamespaceAnnotationsOverTime(start, end time.Time, resolution time.Duration) source.QueryResultsChan {
-	const namespaceAnnotationsQuery = `avg_over_time(kube_namespace_annotations{%s}[%s])`
-	// env.GetPromClusterFilter(), resStr
-
-	cfg := pds.promConfig
-
-	resolution = snapResolutionMinute(resolution)
-	resMins := int64(resolution.Minutes())
-	resStr := formatResolutionMinutes(resMins)
-
-	queryNamespaceAnnotations := fmt.Sprintf(namespaceAnnotationsQuery, cfg.ClusterFilter, resStr)
-	ctx := pds.promContexts.NewNamedContext(ComputeCostDataRangeContextName)
-	return ctx.QueryRange(queryNamespaceAnnotations, start, end, resolution)
-}
-
-func (pds *PrometheusDataSource) QueryPodLabelsOverTime(start, end time.Time, resolution time.Duration) source.QueryResultsChan {
-	const podLabelsQuery = `avg_over_time(kube_pod_labels{%s}[%s])`
-	// env.GetPromClusterFilter(), resStr
-
-	cfg := pds.promConfig
-
-	resolution = snapResolutionMinute(resolution)
-	resMins := int64(resolution.Minutes())
-	resStr := formatResolutionMinutes(resMins)
-
-	queryPodLabels := fmt.Sprintf(podLabelsQuery, cfg.ClusterFilter, resStr)
-	ctx := pds.promContexts.NewNamedContext(ComputeCostDataRangeContextName)
-	return ctx.QueryRange(queryPodLabels, start, end, resolution)
-}
-
-func (pds *PrometheusDataSource) QueryPodAnnotationsOverTime(start, end time.Time, resolution time.Duration) source.QueryResultsChan {
-	const podAnnotationsQuery = `avg_over_time(kube_pod_annotations{%s}[%s])`
-	// env.GetPromClusterFilter(), resStr
-
-	cfg := pds.promConfig
-
-	resolution = snapResolutionMinute(resolution)
-	resMins := int64(resolution.Minutes())
-	resStr := formatResolutionMinutes(resMins)
-
-	queryPodAnnotations := fmt.Sprintf(podAnnotationsQuery, cfg.ClusterFilter, resStr)
-	ctx := pds.promContexts.NewNamedContext(ComputeCostDataRangeContextName)
-	return ctx.QueryRange(queryPodAnnotations, start, end, resolution)
-}
-
-func (pds *PrometheusDataSource) QueryServiceLabelsOverTime(start, end time.Time, resolution time.Duration) source.QueryResultsChan {
-	const serviceLabelsQuery = `avg_over_time(service_selector_labels{%s}[%s])`
-	// env.GetPromClusterFilter(), resStr
-
-	cfg := pds.promConfig
-
-	resolution = snapResolutionMinute(resolution)
-	resMins := int64(resolution.Minutes())
-	resStr := formatResolutionMinutes(resMins)
-
-	queryServiceLabels := fmt.Sprintf(serviceLabelsQuery, cfg.ClusterFilter, resStr)
-	ctx := pds.promContexts.NewNamedContext(ComputeCostDataRangeContextName)
-	return ctx.QueryRange(queryServiceLabels, start, end, resolution)
-}
-
-func (pds *PrometheusDataSource) QueryDeploymentLabelsOverTime(start, end time.Time, resolution time.Duration) source.QueryResultsChan {
-	const deploymentLabelsQuery = `avg_over_time(deployment_match_labels{%s}[%s])`
-	// env.GetPromClusterFilter(), resStr
-
-	cfg := pds.promConfig
-
-	resolution = snapResolutionMinute(resolution)
-	resMins := int64(resolution.Minutes())
-	resStr := formatResolutionMinutes(resMins)
-
-	queryDeploymentLabels := fmt.Sprintf(deploymentLabelsQuery, cfg.ClusterFilter, resStr)
-	ctx := pds.promContexts.NewNamedContext(ComputeCostDataRangeContextName)
-	return ctx.QueryRange(queryDeploymentLabels, start, end, resolution)
-}
-
-func (pds *PrometheusDataSource) QueryStatefulsetLabelsOverTime(start, end time.Time, resolution time.Duration) source.QueryResultsChan {
-	const statefulsetLabelsQuery = `avg_over_time(statefulSet_match_labels{%s}[%s])`
-	// env.GetPromClusterFilter(), resStr
-
-	cfg := pds.promConfig
-
-	resolution = snapResolutionMinute(resolution)
-	resMins := int64(resolution.Minutes())
-	resStr := formatResolutionMinutes(resMins)
-
-	queryStatefulsetLabels := fmt.Sprintf(statefulsetLabelsQuery, cfg.ClusterFilter, resStr)
-	ctx := pds.promContexts.NewNamedContext(ComputeCostDataRangeContextName)
-	return ctx.QueryRange(queryStatefulsetLabels, start, end, resolution)
-}
-
-func (pds *PrometheusDataSource) QueryPodJobsOverTime(start, end time.Time, resolution time.Duration) source.QueryResultsChan {
-	const podJobsQuery = `sum(kube_pod_owner{owner_kind="Job", %s}) by (namespace,pod,owner_name,%s)`
-	// env.GetPromClusterFilter(), env.GetPromClusterLabel()
-
-	cfg := pds.promConfig
-
-	resolution = snapResolutionMinute(resolution)
-
-	queryPodJobs := fmt.Sprintf(podJobsQuery, cfg.ClusterFilter, cfg.ClusterLabel)
-	ctx := pds.promContexts.NewNamedContext(ComputeCostDataRangeContextName)
-	return ctx.QueryRange(queryPodJobs, start, end, resolution)
-}
-
-func (pds *PrometheusDataSource) QueryPodDaemonsetsOverTime(start, end time.Time, resolution time.Duration) source.QueryResultsChan {
-	const podDaemonsetsQuery = `sum(kube_pod_owner{owner_kind="DaemonSet", %s}) by (namespace,pod,owner_name,%s)`
-	// env.GetPromClusterFilter(), env.GetPromClusterLabel()
-
-	cfg := pds.promConfig
-
-	resolution = snapResolutionMinute(resolution)
-
-	queryPodDaemonsets := fmt.Sprintf(podDaemonsetsQuery, cfg.ClusterFilter, cfg.ClusterLabel)
-	ctx := pds.promContexts.NewNamedContext(ComputeCostDataRangeContextName)
-	return ctx.QueryRange(queryPodDaemonsets, start, end, resolution)
-}
-
-func (pds *PrometheusDataSource) QueryNormalizationOverTime(start, end time.Time, resolution time.Duration) source.QueryResultsChan {
-	const normalizationQuery = `max(count_over_time(kube_pod_container_resource_requests{resource="memory", unit="byte", %s}[%s] %s))`
-	// env.GetPromClusterFilter(), resStr, "")
-
-	cfg := pds.promConfig
-
-	resolution = snapResolutionMinute(resolution)
-	resMins := int64(resolution.Minutes())
-	resStr := formatResolutionMinutes(resMins)
-
-	queryNormalization := fmt.Sprintf(normalizationQuery, cfg.ClusterFilter, resStr, "")
-	ctx := pds.promContexts.NewNamedContext(ComputeCostDataRangeContextName)
-	return ctx.QueryRange(queryNormalization, start, end, resolution)
-}
-
-//--------------------------------------------------------------------------
-//  ClusterMetricsQuerier
-//--------------------------------------------------------------------------
-
 func (pds *PrometheusDataSource) QueryPVCost(start, end time.Time) source.QueryResultsChan {
 	const pvCostQuery = `avg(avg_over_time(pv_hourly_cost{%s}[%s])) by (%s, persistentvolume,provider_id)`
 

Fichier diff supprimé car celui-ci est trop grand
+ 8 - 970
pkg/costmodel/aggregation.go


+ 1 - 1
pkg/costmodel/aggregation_test.go

@@ -13,7 +13,7 @@ func TestScaleHourlyCostData(t *testing.T) {
 	start := 1570000000
 	oneHour := 60 * 60
 
-	generateVectorSeries := func(start, count, interval int, value float64) []*util.Vector {
+	generateVectorSeries := func(start, count, _ int, value float64) []*util.Vector {
 		vs := []*util.Vector{}
 		for i := 0; i < count; i++ {
 			v := &util.Vector{

+ 1 - 26
pkg/costmodel/cluster.go

@@ -18,30 +18,6 @@ import (
 	"github.com/opencost/opencost/pkg/env"
 )
 
-const (
-	queryClusterCores = `sum(
-		avg(avg_over_time(kube_node_status_capacity_cpu_cores{%s}[%s] %s)) by (node, %s) * avg(avg_over_time(node_cpu_hourly_cost{%s}[%s] %s)) by (node, %s) * 730 +
-		avg(avg_over_time(node_gpu_hourly_cost{%s}[%s] %s)) by (node, %s) * 730
-	  ) by (%s)`
-
-	queryClusterRAM = `sum(
-		avg(avg_over_time(kube_node_status_capacity_memory_bytes{%s}[%s] %s)) by (node, %s) / 1024 / 1024 / 1024 * avg(avg_over_time(node_ram_hourly_cost{%s}[%s] %s)) by (node, %s) * 730
-	  ) by (%s)`
-
-	queryStorage = `sum(
-		avg(avg_over_time(pv_hourly_cost{%s}[%s] %s)) by (persistentvolume, %s) * 730
-		* avg(avg_over_time(kube_persistentvolume_capacity_bytes{%s}[%s] %s)) by (persistentvolume, %s) / 1024 / 1024 / 1024
-	  ) by (%s) %s`
-
-	queryTotal = `sum(avg(node_total_hourly_cost{%s}) by (node, %s)) * 730 +
-	  sum(
-		avg(avg_over_time(pv_hourly_cost{%s}[1h])) by (persistentvolume, %s) * 730
-		* avg(avg_over_time(kube_persistentvolume_capacity_bytes{%s}[1h])) by (persistentvolume, %s) / 1024 / 1024 / 1024
-	  ) by (%s) %s`
-
-	queryNodes = `sum(avg(node_total_hourly_cost{%s}) by (node, %s)) * 730 %s`
-)
-
 const MAX_LOCAL_STORAGE_SIZE = 1024 * 1024 * 1024 * 1024
 
 // When ASSET_INCLUDE_LOCAL_DISK_COST is set to false, local storage
@@ -674,7 +650,6 @@ func ClusterNodes(dataSource source.OpenCostDataSource, cp models.Provider, star
 		preemptibleMap,
 		labelsMap,
 		clusterAndNameToType,
-		resolution,
 		overheadMap,
 	)
 
@@ -1107,7 +1082,7 @@ type Totals struct {
 
 func resultToTotals(qrs []*source.QueryResult) ([][]string, error) {
 	if len(qrs) == 0 {
-		return [][]string{}, fmt.Errorf("Not enough data available in the selected time range")
+		return [][]string{}, fmt.Errorf("not enough data available in the selected time range")
 	}
 
 	result := qrs[0]

+ 0 - 1
pkg/costmodel/cluster_helpers.go

@@ -746,7 +746,6 @@ func buildNodeMap(
 	preemptibleMap map[NodeIdentifier]bool,
 	labelsMap map[nodeIdentifierNoProviderID]map[string]string,
 	clusterAndNameToType map[nodeIdentifierNoProviderID]string,
-	res time.Duration,
 	overheadMap map[nodeIdentifierNoProviderID]*NodeOverhead,
 ) map[NodeIdentifier]*Node {
 

+ 0 - 1
pkg/costmodel/cluster_helpers_test.go

@@ -712,7 +712,6 @@ func TestBuildNodeMap(t *testing.T) {
 				testCase.preemptibleMap,
 				testCase.labelsMap,
 				testCase.clusterAndNameToType,
-				time.Minute,
 				testCase.overheadMap,
 			)
 

+ 12 - 12
pkg/costmodel/cluster_test.go

@@ -15,27 +15,27 @@ func Test_filterOutLocalPVs(t *testing.T) {
 		{
 			name: "Filter out local PVs",
 			input: map[DiskIdentifier]*Disk{
-				{Cluster: "cluster1", Name: "pv1"}:              &Disk{Name: "pv1"},
-				{Cluster: "cluster1", Name: "local-pv-123"}:     &Disk{Name: "local-pv-123"},
-				{Cluster: "cluster2", Name: "pv2"}:              &Disk{Name: "pv2"},
-				{Cluster: "cluster2", Name: "local-pv-456"}:     &Disk{Name: "local-pv-456"},
-				{Cluster: "cluster3", Name: "not-local-pv-789"}: &Disk{Name: "not-local-pv-789"},
+				{Cluster: "cluster1", Name: "pv1"}:              {Name: "pv1"},
+				{Cluster: "cluster1", Name: "local-pv-123"}:     {Name: "local-pv-123"},
+				{Cluster: "cluster2", Name: "pv2"}:              {Name: "pv2"},
+				{Cluster: "cluster2", Name: "local-pv-456"}:     {Name: "local-pv-456"},
+				{Cluster: "cluster3", Name: "not-local-pv-789"}: {Name: "not-local-pv-789"},
 			},
 			expected: map[DiskIdentifier]*Disk{
-				{Cluster: "cluster1", Name: "pv1"}:              &Disk{Name: "pv1"},
-				{Cluster: "cluster2", Name: "pv2"}:              &Disk{Name: "pv2"},
-				{Cluster: "cluster3", Name: "not-local-pv-789"}: &Disk{Name: "not-local-pv-789"},
+				{Cluster: "cluster1", Name: "pv1"}:              {Name: "pv1"},
+				{Cluster: "cluster2", Name: "pv2"}:              {Name: "pv2"},
+				{Cluster: "cluster3", Name: "not-local-pv-789"}: {Name: "not-local-pv-789"},
 			},
 		},
 		{
 			name: "No local PVs to filter",
 			input: map[DiskIdentifier]*Disk{
-				{Cluster: "cluster1", Name: "pv1"}: &Disk{Name: "pv1"},
-				{Cluster: "cluster2", Name: "pv2"}: &Disk{Name: "pv2"},
+				{Cluster: "cluster1", Name: "pv1"}: {Name: "pv1"},
+				{Cluster: "cluster2", Name: "pv2"}: {Name: "pv2"},
 			},
 			expected: map[DiskIdentifier]*Disk{
-				{Cluster: "cluster1", Name: "pv1"}: &Disk{Name: "pv1"},
-				{Cluster: "cluster2", Name: "pv2"}: &Disk{Name: "pv2"},
+				{Cluster: "cluster1", Name: "pv1"}: {Name: "pv1"},
+				{Cluster: "cluster2", Name: "pv2"}: {Name: "pv2"},
 			},
 		},
 		{

+ 17 - 17
pkg/costmodel/containerkeys.go

@@ -11,18 +11,18 @@ import (
 
 var (
 	// Static KeyTuple Errors
-	NewKeyTupleErr = errors.New("NewKeyTuple() Provided key not containing exactly 3 components.")
+	ErrNewKeyTuple = errors.New("new-key-tuple: key not containing exactly 3 components")
 
 	// Static Errors for ContainerMetric creation
-	InvalidKeyErr      error = errors.New("Not a valid key")
-	NoContainerErr     error = errors.New("Prometheus vector does not have container name")
-	NoContainerNameErr error = errors.New("Prometheus vector does not have string container name")
-	NoPodErr           error = errors.New("Prometheus vector does not have pod name")
-	NoPodNameErr       error = errors.New("Prometheus vector does not have string pod name")
-	NoNamespaceErr     error = errors.New("Prometheus vector does not have namespace")
-	NoNamespaceNameErr error = errors.New("Prometheus vector does not have string namespace")
-	NoNodeNameErr      error = errors.New("Prometheus vector does not have string node")
-	NoClusterIDErr     error = errors.New("Prometheus vector does not have string cluster id")
+	ErrInvalidKey      error = errors.New("not a valid key")
+	ErrNoContainer     error = errors.New("vector does not have container name")
+	ErrNoContainerName error = errors.New("vector does not have string container name")
+	ErrNoPod           error = errors.New("vector does not have pod name")
+	ErrNoPodName       error = errors.New("vector does not have string pod name")
+	ErrNoNamespace     error = errors.New("vector does not have namespace")
+	ErrNoNamespaceName error = errors.New("vector does not have string namespace")
+	ErrNoNodeName      error = errors.New("vector does not have string node")
+	ErrNoClusterID     error = errors.New("vector does not have string cluster id")
 )
 
 //--------------------------------------------------------------------------
@@ -57,18 +57,18 @@ func (kt *KeyTuple) ClusterID() string {
 func NewKeyTuple(key string) (*KeyTuple, error) {
 	kIndex := strings.IndexRune(key, ',')
 	if kIndex < 0 {
-		return nil, NewKeyTupleErr
+		return nil, ErrNewKeyTuple
 	}
 	kIndex += 1
 
 	subIndex := strings.IndexRune(key[kIndex:], ',')
 	if subIndex < 0 {
-		return nil, NewKeyTupleErr
+		return nil, ErrNewKeyTuple
 	}
 	cIndex := kIndex + subIndex + 1
 
 	if strings.ContainsRune(key[cIndex:], ',') {
-		return nil, NewKeyTupleErr
+		return nil, ErrNewKeyTuple
 	}
 
 	return &KeyTuple{
@@ -118,7 +118,7 @@ func NewContainerMetricFromKey(key string) (*ContainerMetric, error) {
 			key:           key,
 		}, nil
 	}
-	return nil, InvalidKeyErr
+	return nil, ErrInvalidKey
 }
 
 // NewContainerMetricFromValues creates a new ContainerMetric instance using the provided string parameters.
@@ -160,17 +160,17 @@ func NewContainerMetricsFromPod(pod *clustercache.Pod, clusterID string) ([]*Con
 func NewContainerMetricFromResult(result *source.QueryResult, defaultClusterID string) (*ContainerMetric, error) {
 	containerName, err := result.GetContainer()
 	if err != nil {
-		return nil, NoContainerErr
+		return nil, ErrNoContainer
 	}
 
 	podName, err := result.GetPod()
 	if err != nil {
-		return nil, NoPodNameErr
+		return nil, ErrNoPodName
 	}
 
 	namespace, err := result.GetNamespace()
 	if err != nil {
-		return nil, NoNamespaceNameErr
+		return nil, ErrNoNamespaceName
 	}
 
 	nodeName, err := result.GetNode()

Fichier diff supprimé car celui-ci est trop grand
+ 28 - 913
pkg/costmodel/costmodel.go


+ 1 - 1
pkg/costmodel/csv_export.go

@@ -305,7 +305,7 @@ func (e *csvExporter) writeCSVToWriter(ctx context.Context, w io.Writer, dates [
 		csvDef = append(csvDef, columnDef{
 			column: "Label_" + label,
 			value: func(data rowData) string {
-				value, _ := data.alloc.Properties.Labels[label]
+				value := data.alloc.Properties.Labels[label]
 				return value
 			},
 		})

+ 4 - 0
pkg/costmodel/handlers.go

@@ -62,6 +62,10 @@ func (a *Accesses) ComputeAssetsCarbonHandler(w http.ResponseWriter, r *http.Req
 	}
 
 	carbonEstimates, err := carbon.RelateCarbonAssets(assetSet)
+	if err != nil {
+		http.Error(w, fmt.Sprintf("Error relating carbon assets: %s", err), http.StatusInternalServerError)
+		return
+	}
 
 	w.Write(WrapData(carbonEstimates, nil))
 }

+ 7 - 5
pkg/costmodel/metrics.go

@@ -137,7 +137,7 @@ var (
 )
 
 // initCostModelMetrics uses a sync.Once to ensure that these metrics are only created once
-func initCostModelMetrics(clusterCache clustercache.ClusterCache, provider models.Provider, clusterInfo clusters.ClusterInfoProvider, metricsConfig *metrics.MetricsConfig) {
+func initCostModelMetrics(clusterInfo clusters.ClusterInfoProvider, metricsConfig *metrics.MetricsConfig) {
 
 	disabledMetrics := metricsConfig.GetDisabledMetricsMap()
 	var toRegisterGV []*prometheus.GaugeVec
@@ -337,7 +337,7 @@ func NewCostModelMetricsEmitter(clusterCache clustercache.ClusterCache, provider
 	}
 
 	// init will only actually execute once to register the custom gauges
-	initCostModelMetrics(clusterCache, provider, clusterInfo, metricsConfig)
+	initCostModelMetrics(clusterInfo, metricsConfig)
 
 	metrics.InitKubeMetrics(clusterCache, metricsConfig, &metrics.KubeMetricsOpts{
 		EmitKubecostControllerMetrics: true,
@@ -452,8 +452,10 @@ func (cmme *CostModelMetricsEmitter) Start() bool {
 				cmme.NetworkInternetEgressRecorder.Set(networkCosts.InternetNetworkEgressCost)
 			}
 
-			// TODO: Pass PrometheusClient and CloudProvider into CostModel on instantiation so this isn't so awkward
-			data, err := cmme.Model.ComputeCostData("2m", "", "")
+			end := time.Now()
+			start := end.Add(-time.Minute * 2)
+
+			data, err := cmme.Model.ComputeCostData(start, end)
 			if err != nil {
 				// For an error collection, we'll just log the length of the errors (ComputeCostData already logs the
 				// actual errors)
@@ -462,7 +464,7 @@ func (cmme *CostModelMetricsEmitter) Start() bool {
 						log.Errorf("Error in price recording: %d errors occurred", len(ec.Errors()))
 					}
 				} else {
-					log.Errorf("Error in price recording: " + err.Error())
+					log.Errorf("Error in price recording: %s", err)
 				}
 
 				// zero the for loop so the time.Sleep will still work

+ 2 - 29
pkg/costmodel/resultparsers.go

@@ -425,7 +425,7 @@ func GetServiceSelectorLabelsMetrics(qrs []*source.QueryResult, defaultClusterID
 	return toReturn, nil
 }
 
-func GetContainerMetricVector(qrs []*source.QueryResult, normalize bool, normalizationValue float64, defaultClusterID string) (map[string][]*util.Vector, error) {
+func GetContainerMetricVector(qrs []*source.QueryResult, defaultClusterID string) (map[string][]*util.Vector, error) {
 	containerData := make(map[string][]*util.Vector)
 	for _, val := range qrs {
 		containerMetric, err := NewContainerMetricFromResult(val, defaultClusterID)
@@ -433,11 +433,6 @@ func GetContainerMetricVector(qrs []*source.QueryResult, normalize bool, normali
 			return nil, err
 		}
 
-		if normalize && normalizationValue != 0 {
-			for _, v := range val.Values {
-				v.Value = v.Value / normalizationValue
-			}
-		}
 		containerData[containerMetric.Key()] = val.Values
 	}
 	return containerData, nil
@@ -482,33 +477,11 @@ func getCost(qrs []*source.QueryResult) (map[string][]*util.Vector, error) {
 	return toReturn, nil
 }
 
-// TODO niko/prom retain message:
-// normalization data is empty: time window may be invalid or kube-state-metrics or node-exporter may not be running
-func getNormalization(qrs []*source.QueryResult) (float64, error) {
-	if len(qrs) == 0 {
-		return 0.0, source.NewNoDataError("getNormalization")
-	}
-	if len(qrs[0].Values) == 0 {
-		return 0.0, source.NewNoDataError("getNormalization")
-	}
-	return qrs[0].Values[0].Value, nil
-}
-
-// TODO niko/prom retain message:
-// normalization data is empty: time window may be invalid or kube-state-metrics or node-exporter may not be running
-func getNormalizations(qrs []*source.QueryResult) ([]*util.Vector, error) {
-	if len(qrs) == 0 {
-		return nil, source.NewNoDataError("getNormalizations")
-	}
-
-	return qrs[0].Values, nil
-}
-
 func parsePodLabels(qrs []*source.QueryResult) (map[string]map[string]string, error) {
 	podLabels := map[string]map[string]string{}
 
 	for _, result := range qrs {
-		pod, err := result.GetString("pod")
+		pod, err := result.GetPod()
 		if err != nil {
 			return podLabels, errors.New("missing pod field")
 		}

+ 35 - 204
pkg/costmodel/router.go

@@ -13,10 +13,7 @@ import (
 	"sync"
 	"time"
 
-	"github.com/microcosm-cc/bluemonday"
-	"github.com/opencost/opencost/core/pkg/opencost"
 	"github.com/opencost/opencost/core/pkg/source"
-	"github.com/opencost/opencost/core/pkg/util/httputil"
 	"github.com/opencost/opencost/core/pkg/util/retry"
 	"github.com/opencost/opencost/core/pkg/util/timeutil"
 	"github.com/opencost/opencost/core/pkg/version"
@@ -43,7 +40,6 @@ import (
 	"github.com/opencost/opencost/modules/prometheus-source/pkg/prom"
 	"github.com/opencost/opencost/pkg/cloud/azure"
 	"github.com/opencost/opencost/pkg/cloud/models"
-	"github.com/opencost/opencost/pkg/cloud/utils"
 	"github.com/opencost/opencost/pkg/clustercache"
 	"github.com/opencost/opencost/pkg/env"
 	"github.com/opencost/opencost/pkg/errors"
@@ -54,8 +50,6 @@ import (
 	"k8s.io/client-go/kubernetes"
 )
 
-var sanitizePolicy = bluemonday.UGCPolicy()
-
 const (
 	RFC3339Milli         = "2006-01-02T15:04:05.000Z"
 	maxCacheMinutes1d    = 11
@@ -74,8 +68,6 @@ var (
 // Accesses defines a singleton application instance, providing access to
 // Prometheus, Kubernetes, the cloud provider, and caches.
 type Accesses struct {
-	//PrometheusClient    prometheus.Client
-	//ThanosClient        prometheus.Client
 	DataSource          source.OpenCostDataSource
 	KubeClientSet       kubernetes.Interface
 	ClusterCache        clustercache.ClusterCache
@@ -86,11 +78,9 @@ type Accesses struct {
 	Model               *CostModel
 	MetricsEmitter      *CostModelMetricsEmitter
 	OutOfClusterCache   *cache.Cache
-	AggregateCache      *cache.Cache
 	CostDataCache       *cache.Cache
 	ClusterCostsCache   *cache.Cache
 	CacheExpiration     map[time.Duration]time.Duration
-	AggAPI              Aggregator
 	// SettingsCache stores current state of app settings
 	SettingsCache *cache.Cache
 	// settingsSubscribers tracks channels through which changes to different
@@ -101,23 +91,6 @@ type Accesses struct {
 	httpServices services.HTTPServices
 }
 
-// GetPrometheusClient decides whether the default Prometheus client or the Thanos client
-// should be used.
-/*
-func (a *Accesses) GetPrometheusClient(remote bool) prometheus.Client {
-	// Use Thanos Client if it exists (enabled) and remote flag set
-	var pc prometheus.Client
-
-	if remote && a.ThanosClient != nil {
-		pc = a.ThanosClient
-	} else {
-		pc = a.PrometheusClient
-	}
-
-	return pc
-}
-*/
-
 // GetCacheExpiration looks up and returns custom cache expiration for the given duration.
 // If one does not exists, it returns the default cache expiration, which is defined by
 // the particular cache.
@@ -228,24 +201,6 @@ func filterFields(fields string, data map[string]*CostData) map[string]CostData
 	return filteredData
 }
 
-func normalizeTimeParam(param string) (string, error) {
-	if param == "" {
-		return "", fmt.Errorf("invalid time param")
-	}
-	// convert days to hours
-	if param[len(param)-1:] == "d" {
-		count := param[:len(param)-1]
-		val, err := strconv.ParseInt(count, 10, 64)
-		if err != nil {
-			return "", err
-		}
-		val = val * 24
-		param = fmt.Sprintf("%dh", val)
-	}
-
-	return param, nil
-}
-
 // ParsePercentString takes a string of expected format "N%" and returns a floating point 0.0N.
 // If the "%" symbol is missing, it just returns 0.0N. Empty string is interpreted as "0%" and
 // return 0.0.
@@ -362,14 +317,6 @@ func WrapDataWithMessageAndWarning(data interface{}, err error, message, warning
 	return resp
 }
 
-// wrapAsObjectItems wraps a slice of items into an object containing a single items list
-// allows our k8s proxy methods to emulate a List() request to k8s API
-func wrapAsObjectItems(items interface{}) map[string]interface{} {
-	return map[string]interface{}{
-		"items": items,
-	}
-}
-
 // RefreshPricingData needs to be called when a new node joins the fleet, since we cache the relevant subsets of pricing data to avoid storing the whole thing.
 func (a *Accesses) RefreshPricingData(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
 	w.Header().Set("Content-Type", "application/json")
@@ -392,11 +339,35 @@ func (a *Accesses) CostDataModel(w http.ResponseWriter, r *http.Request, ps http
 	fields := r.URL.Query().Get("filterFields")
 	namespace := r.URL.Query().Get("namespace")
 
+	duration, err := timeutil.ParseDuration(window)
+	if err != nil {
+		w.Write(WrapData(nil, fmt.Errorf("error parsing window (%s): %s", window, err)))
+		return
+	}
+
+	end := time.Now()
 	if offset != "" {
-		offset = "offset " + offset
+		offsetDur, err := timeutil.ParseDuration(offset)
+		if err != nil {
+			w.Write(WrapData(nil, fmt.Errorf("error parsing offset (%s): %s", offset, err)))
+			return
+		}
+
+		end = end.Add(-offsetDur)
 	}
 
-	data, err := a.Model.ComputeCostData(window, offset, namespace)
+	start := end.Add(-duration)
+
+	data, err := a.Model.ComputeCostData(start, end)
+
+	// apply filter by removing if != namespace
+	if namespace != "" {
+		for key, costData := range data {
+			if costData.Namespace != namespace {
+				delete(data, key)
+			}
+		}
+	}
 
 	if fields != "" {
 		filteredData := filterFields(fields, data)
@@ -404,7 +375,6 @@ func (a *Accesses) CostDataModel(w http.ResponseWriter, r *http.Request, ps http
 	} else {
 		w.Write(WrapData(data, err))
 	}
-
 }
 
 func (a *Accesses) ClusterCosts(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
@@ -505,84 +475,6 @@ func (a *Accesses) ClusterCostsOverTime(w http.ResponseWriter, r *http.Request,
 	w.Write(WrapData(data, err))
 }
 
-func (a *Accesses) CostDataModelRange(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
-	w.Header().Set("Content-Type", "application/json")
-	w.Header().Set("Access-Control-Allow-Origin", "*")
-
-	startStr := r.URL.Query().Get("start")
-	endStr := r.URL.Query().Get("end")
-	windowStr := r.URL.Query().Get("window")
-	fields := r.URL.Query().Get("filterFields")
-	namespace := r.URL.Query().Get("namespace")
-	cluster := r.URL.Query().Get("cluster")
-	//remote := r.URL.Query().Get("remote")
-	//remoteEnabled := env.IsRemoteEnabled() && remote != "false"
-
-	layout := "2006-01-02T15:04:05.000Z"
-	start, err := time.Parse(layout, startStr)
-	if err != nil {
-		w.Write(WrapDataWithMessage(nil, fmt.Errorf("invalid start date: %s", startStr), fmt.Sprintf("invalid start date: %s", startStr)))
-		return
-	}
-	end, err := time.Parse(layout, endStr)
-	if err != nil {
-		w.Write(WrapDataWithMessage(nil, fmt.Errorf("invalid end date: %s", endStr), fmt.Sprintf("invalid end date: %s", endStr)))
-		return
-	}
-
-	window := opencost.NewWindow(&start, &end)
-	if window.IsOpen() || !window.HasDuration() || window.IsNegative() {
-		w.Write(WrapDataWithMessage(nil, fmt.Errorf("invalid date range: %s", window), fmt.Sprintf("invalid date range: %s", window)))
-		return
-	}
-
-	resolution := time.Hour
-	if resDur, err := time.ParseDuration(windowStr); err == nil {
-		resolution = resDur
-	}
-
-	// Use Thanos Client if it exists (enabled) and remote flag set
-	/*
-		var pClient prometheus.Client
-		if remote != "false" && a.ThanosClient != nil {
-			pClient = a.ThanosClient
-		} else {
-			pClient = a.PrometheusClient
-		}
-	*/
-
-	data, err := a.Model.ComputeCostDataRange(window, resolution, namespace, cluster)
-	if err != nil {
-		w.Write(WrapData(nil, err))
-	}
-	if fields != "" {
-		filteredData := filterFields(fields, data)
-		w.Write(WrapData(filteredData, err))
-	} else {
-		w.Write(WrapData(data, err))
-	}
-}
-
-func parseAggregations(customAggregation, aggregator, filterType string) (string, []string, string) {
-	var key string
-	var filter string
-	var val []string
-	if customAggregation != "" {
-		key = customAggregation
-		filter = filterType
-		val = strings.Split(customAggregation, ",")
-	} else {
-		aggregations := strings.Split(aggregator, ",")
-		for i, agg := range aggregations {
-			aggregations[i] = "kubernetes_" + agg
-		}
-		key = strings.Join(aggregations, ",")
-		filter = "kubernetes_" + filterType
-		val = aggregations
-	}
-	return key, val, filter
-}
-
 func (a *Accesses) GetAllNodePricing(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
 	w.Header().Set("Content-Type", "application/json")
 	w.Header().Set("Access-Control-Allow-Origin", "*")
@@ -611,7 +503,6 @@ func (a *Accesses) UpdateSpotInfoConfigs(w http.ResponseWriter, r *http.Request,
 	if err != nil {
 		log.Errorf("Error redownloading data on config update: %s", err.Error())
 	}
-	return
 }
 
 func (a *Accesses) UpdateAthenaInfoConfigs(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
@@ -623,7 +514,6 @@ func (a *Accesses) UpdateAthenaInfoConfigs(w http.ResponseWriter, r *http.Reques
 		return
 	}
 	w.Write(WrapData(data, err))
-	return
 }
 
 func (a *Accesses) UpdateBigQueryInfoConfigs(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
@@ -635,7 +525,6 @@ func (a *Accesses) UpdateBigQueryInfoConfigs(w http.ResponseWriter, r *http.Requ
 		return
 	}
 	w.Write(WrapData(data, err))
-	return
 }
 
 func (a *Accesses) UpdateAzureStorageConfigs(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
@@ -647,7 +536,6 @@ func (a *Accesses) UpdateAzureStorageConfigs(w http.ResponseWriter, r *http.Requ
 		return
 	}
 	w.Write(WrapData(data, err))
-	return
 }
 
 func (a *Accesses) UpdateConfigByKey(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
@@ -659,7 +547,6 @@ func (a *Accesses) UpdateConfigByKey(w http.ResponseWriter, r *http.Request, ps
 		return
 	}
 	w.Write(WrapData(data, err))
-	return
 }
 
 func (a *Accesses) ManagementPlatform(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
@@ -672,7 +559,6 @@ func (a *Accesses) ManagementPlatform(w http.ResponseWriter, r *http.Request, ps
 		return
 	}
 	w.Write(WrapData(data, err))
-	return
 }
 
 func (a *Accesses) ClusterInfo(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
@@ -722,35 +608,6 @@ func (a *Accesses) GetPricingSourceSummary(w http.ResponseWriter, r *http.Reques
 	w.Write(WrapData(data, nil))
 }
 
-// helper for query range proxy requests
-func toStartEndStep(qp httputil.QueryParams) (start, end time.Time, step time.Duration, err error) {
-	var e error
-
-	ss := qp.Get("start", "")
-	es := qp.Get("end", "")
-	ds := qp.Get("duration", "")
-	layout := "2006-01-02T15:04:05.000Z"
-
-	start, e = time.Parse(layout, ss)
-	if e != nil {
-		err = fmt.Errorf("Error parsing time %s. Error: %s", ss, err)
-		return
-	}
-	end, e = time.Parse(layout, es)
-	if e != nil {
-		err = fmt.Errorf("Error parsing time %s. Error: %s", es, err)
-		return
-	}
-	step, e = time.ParseDuration(ds)
-	if e != nil {
-		err = fmt.Errorf("Error parsing duration %s. Error: %s", ds, err)
-		return
-	}
-	err = nil
-
-	return
-}
-
 func (a *Accesses) GetOrphanedPods(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
 	w.Header().Set("Content-Type", "application/json")
 	w.Header().Set("Access-Control-Allow-Origin", "*")
@@ -766,7 +623,7 @@ func (a *Accesses) GetOrphanedPods(w http.ResponseWriter, r *http.Request, ps ht
 
 	body, err := json.Marshal(lonePods)
 	if err != nil {
-		fmt.Fprintf(w, "Error decoding pod: "+err.Error())
+		fmt.Fprintf(w, "Error decoding pod: %s", err)
 	} else {
 		w.Write(body)
 	}
@@ -862,7 +719,7 @@ func (a *Accesses) AddServiceKey(w http.ResponseWriter, r *http.Request, ps http
 	k := []byte(key)
 	err := os.WriteFile(path.Join(env.GetConfigPathWithDefault(env.DefaultConfigMountPath), "key.json"), k, 0644)
 	if err != nil {
-		fmt.Fprintf(w, "Error writing service key: "+err.Error())
+		fmt.Fprintf(w, "Error writing service key: %s", err)
 	}
 
 	w.WriteHeader(http.StatusOK)
@@ -887,15 +744,10 @@ func (a *Accesses) GetHelmValues(w http.ResponseWriter, r *http.Request, ps http
 	w.Write(result)
 }
 
-// FIXME: Prometheus Status EP
-/*
-
- */
-
 // captures the panic event in sentry
 func capturePanicEvent(err string, stack string) {
 	msg := fmt.Sprintf("Panic: %s\nStackTrace: %s\n", err, stack)
-	log.Infof(msg)
+	log.Infof("%s", msg)
 	sentry.CurrentHub().CaptureEvent(&sentry.Event{
 		Level:   sentry.LevelError,
 		Message: msg,
@@ -997,19 +849,6 @@ func Initialize(router *httprouter.Router, additionalConfigWatchers ...*watcher.
 	configWatchers.AddWatcher(metrics.GetMetricsConfigWatcher())
 	configWatchers.Watch()
 
-	remoteEnabled := env.IsRemoteEnabled()
-	if remoteEnabled {
-		info, err := cloudProvider.ClusterInfo()
-		log.Infof("Saving cluster  with id:'%s', and name:'%s' to durable storage", info["id"], info["name"])
-		if err != nil {
-			log.Infof("Error saving cluster id %s", err.Error())
-		}
-		_, _, err = utils.GetOrCreateClusterMeta(info["id"], info["name"])
-		if err != nil {
-			log.Infof("Unable to set cluster id '%s' for cluster '%s', %s", info["id"], info["name"], err.Error())
-		}
-	}
-
 	// ClusterInfo Provider to provide the cluster map with local and remote cluster data
 	var clusterInfoProvider clusters.ClusterInfoProvider
 	if env.IsClusterInfoFileEnabled() {
@@ -1023,7 +862,6 @@ func Initialize(router *httprouter.Router, additionalConfigWatchers ...*watcher.
 
 	// cache responses from model and aggregation for a default of 10 minutes;
 	// clear expired responses every 20 minutes
-	aggregateCache := cache.New(time.Minute*10, time.Minute*20)
 	costDataCache := cache.New(time.Minute*10, time.Minute*20)
 	clusterCostsCache := cache.New(cache.NoExpiration, cache.NoExpiration)
 	outOfClusterCache := cache.New(time.Minute*5, time.Minute*10)
@@ -1054,7 +892,6 @@ func Initialize(router *httprouter.Router, additionalConfigWatchers ...*watcher.
 		ClusterInfoProvider: clusterInfoProvider,
 		Model:               costModel,
 		MetricsEmitter:      metricsEmitter,
-		AggregateCache:      aggregateCache,
 		CostDataCache:       costDataCache,
 		ClusterCostsCache:   clusterCostsCache,
 		OutOfClusterCache:   outOfClusterCache,
@@ -1062,27 +899,23 @@ func Initialize(router *httprouter.Router, additionalConfigWatchers ...*watcher.
 		CacheExpiration:     cacheExpiration,
 	}
 
-	// Use the Accesses instance, itself, as the CostModelAggregator. This is
-	// confusing and unconventional, but necessary so that we can swap it
-	// out for the ETL-adapted version elsewhere.
-	// TODO clean this up once ETL is open-sourced.
-	a.AggAPI = a
-
 	// Initialize mechanism for subscribing to settings changes
 	a.InitializeSettingsPubSub()
 	err = a.CloudProvider.DownloadPricingData()
 	if err != nil {
-		log.Infof("Failed to download pricing data: " + err.Error())
+		log.Infof("Failed to download pricing data: %s", err)
 	}
 
-	// Warm the aggregate cache unless explicitly set to false
+	// NOTE: (bolt) this only warms the cache for cluster costs.
 	if env.IsCacheWarmingEnabled() {
-		log.Infof("Init: AggregateCostModel cache warming enabled")
+		log.Infof("Init: ClusterCosts cache warming enabled")
 		a.warmAggregateCostModelCache()
 	} else {
-		log.Infof("Init: AggregateCostModel cache warming disabled")
+		log.Infof("Init: ClusterCosts cache warming disabled")
 	}
 
+	// router.GET("/aggregatedCostModel", a.AggregateCostModelHandler)
+
 	if !env.IsKubecostMetricsPodEnabled() {
 		a.MetricsEmitter.Start()
 	}
@@ -1091,8 +924,6 @@ func Initialize(router *httprouter.Router, additionalConfigWatchers ...*watcher.
 	a.DataSource.RegisterEndPoints(router)
 
 	router.GET("/costDataModel", a.CostDataModel)
-	router.GET("/costDataModelRange", a.CostDataModelRange)
-	router.GET("/aggregatedCostModel", a.AggregateCostModelHandler)
 	router.GET("/allocation/compute", a.ComputeAllocationHandler)
 	router.GET("/allocation/compute/summary", a.ComputeAllocationHandlerSummary)
 	router.GET("/allNodePricing", a.GetAllNodePricing)

+ 0 - 1
pkg/costmodel/settings.go

@@ -52,7 +52,6 @@ func (a *Accesses) InitializeSettingsPubSub() {
 		for {
 			msg := <-costDataCacheCh
 			log.Infof("Flushing cost data caches: %s", msg)
-			a.AggregateCache.Flush()
 			a.CostDataCache.Flush()
 		}
 	}(a)

Certains fichiers n'ont pas été affichés car il y a eu trop de fichiers modifiés dans ce diff