Explorar el Código

Opencost Support for CUR 2.0 (#3653)

Ishaan Mittal hace 1 mes
padre
commit
7a668f246d

+ 0 - 29
pkg/cloud/aws/athenaconfiguration.go

@@ -18,7 +18,6 @@ type AthenaConfiguration struct {
 	Workgroup  string     `json:"workgroup"`
 	Account    string     `json:"account"`
 	Authorizer Authorizer `json:"authorizer"`
-	CURVersion string     `json:"curVersion,omitempty"` // "1.0" or "2.0", defaults to "2.0" if not specified
 }
 
 func (ac *AthenaConfiguration) Validate() error {
@@ -54,11 +53,6 @@ func (ac *AthenaConfiguration) Validate() error {
 		return fmt.Errorf("AthenaConfiguration: missing account")
 	}
 
-	// Validate CURVersion if specified
-	if ac.CURVersion != "" && ac.CURVersion != "1.0" && ac.CURVersion != "2.0" {
-		return fmt.Errorf("AthenaConfiguration: invalid CURVersion '%s', must be '1.0' or '2.0'", ac.CURVersion)
-	}
-
 	return nil
 }
 
@@ -109,10 +103,6 @@ func (ac *AthenaConfiguration) Equals(config cloud.Config) bool {
 		return false
 	}
 
-	if ac.CURVersion != thatConfig.CURVersion {
-		return false
-	}
-
 	return true
 }
 
@@ -126,7 +116,6 @@ func (ac *AthenaConfiguration) Sanitize() cloud.Config {
 		Workgroup:  ac.Workgroup,
 		Account:    ac.Account,
 		Authorizer: ac.Authorizer.Sanitize().(Authorizer),
-		CURVersion: ac.CURVersion,
 	}
 }
 
@@ -201,18 +190,6 @@ func (ac *AthenaConfiguration) UnmarshalJSON(b []byte) error {
 	}
 	ac.Authorizer = authorizer
 
-	// Parse CURVersion if present (optional field)
-	if _, ok := fmap["curVersion"]; ok {
-		curVersion, err := cloud.GetInterfaceValue[string](fmap, "curVersion")
-		if err != nil {
-			return fmt.Errorf("AthenaConfiguration: UnmarshalJSON: %w", err)
-		}
-		ac.CURVersion = curVersion
-	} else {
-		// Default to 2.0 if not specified
-		ac.CURVersion = "2.0"
-	}
-
 	return nil
 }
 
@@ -243,11 +220,6 @@ func ConvertAwsAthenaInfoToConfig(aai AwsAthenaInfo) cloud.KeyedConfig {
 
 	var config cloud.KeyedConfig
 	if aai.AthenaTable != "" || aai.AthenaDatabase != "" {
-		// Use CURVersion from config if specified, otherwise default to 2.0
-		curVersion := aai.CURVersion
-		if curVersion == "" {
-			curVersion = "2.0"
-		}
 		config = &AthenaConfiguration{
 			Bucket:     aai.AthenaBucketName,
 			Region:     aai.AthenaRegion,
@@ -257,7 +229,6 @@ func ConvertAwsAthenaInfoToConfig(aai AwsAthenaInfo) cloud.KeyedConfig {
 			Workgroup:  aai.AthenaWorkgroup,
 			Account:    aai.AccountID,
 			Authorizer: authorizer,
-			CURVersion: curVersion,
 		}
 	} else {
 		config = &S3Configuration{

+ 1 - 159
pkg/cloud/aws/athenaconfiguration_test.go

@@ -161,62 +161,6 @@ func TestAthenaConfiguration_Validate(t *testing.T) {
 			},
 			expected: fmt.Errorf("AthenaConfiguration: missing account"),
 		},
-		"valid CUR version 1.0": {
-			config: AthenaConfiguration{
-				Bucket:     "bucket",
-				Region:     "region",
-				Database:   "database",
-				Catalog:    "catalog",
-				Table:      "table",
-				Workgroup:  "workgroup",
-				Account:    "account",
-				Authorizer: &ServiceAccount{},
-				CURVersion: "1.0",
-			},
-			expected: nil,
-		},
-		"valid CUR version 2.0": {
-			config: AthenaConfiguration{
-				Bucket:     "bucket",
-				Region:     "region",
-				Database:   "database",
-				Catalog:    "catalog",
-				Table:      "table",
-				Workgroup:  "workgroup",
-				Account:    "account",
-				Authorizer: &ServiceAccount{},
-				CURVersion: "2.0",
-			},
-			expected: nil,
-		},
-		"valid empty CUR version defaults to 2.0": {
-			config: AthenaConfiguration{
-				Bucket:     "bucket",
-				Region:     "region",
-				Database:   "database",
-				Catalog:    "catalog",
-				Table:      "table",
-				Workgroup:  "workgroup",
-				Account:    "account",
-				Authorizer: &ServiceAccount{},
-				CURVersion: "",
-			},
-			expected: nil,
-		},
-		"invalid CUR version": {
-			config: AthenaConfiguration{
-				Bucket:     "bucket",
-				Region:     "region",
-				Database:   "database",
-				Catalog:    "catalog",
-				Table:      "table",
-				Workgroup:  "workgroup",
-				Account:    "account",
-				Authorizer: &ServiceAccount{},
-				CURVersion: "3.0",
-			},
-			expected: fmt.Errorf("AthenaConfiguration: invalid CURVersion '3.0', must be '1.0' or '2.0'"),
-		},
 	}
 
 	for name, testCase := range testCases {
@@ -571,68 +515,6 @@ func TestAthenaConfiguration_Equals(t *testing.T) {
 			},
 			expected: false,
 		},
-		"different CUR version": {
-			left: AthenaConfiguration{
-				Bucket:    "bucket",
-				Region:    "region",
-				Database:  "database",
-				Catalog:   "catalog",
-				Table:     "table",
-				Workgroup: "workgroup",
-				Account:   "account",
-				Authorizer: &AccessKey{
-					ID:     "id",
-					Secret: "secret",
-				},
-				CURVersion: "1.0",
-			},
-			right: &AthenaConfiguration{
-				Bucket:    "bucket",
-				Region:    "region",
-				Database:  "database",
-				Catalog:   "catalog",
-				Table:     "table",
-				Workgroup: "workgroup",
-				Account:   "account",
-				Authorizer: &AccessKey{
-					ID:     "id",
-					Secret: "secret",
-				},
-				CURVersion: "2.0",
-			},
-			expected: false,
-		},
-		"matching CUR version": {
-			left: AthenaConfiguration{
-				Bucket:    "bucket",
-				Region:    "region",
-				Database:  "database",
-				Catalog:   "catalog",
-				Table:     "table",
-				Workgroup: "workgroup",
-				Account:   "account",
-				Authorizer: &AccessKey{
-					ID:     "id",
-					Secret: "secret",
-				},
-				CURVersion: "1.0",
-			},
-			right: &AthenaConfiguration{
-				Bucket:    "bucket",
-				Region:    "region",
-				Database:  "database",
-				Catalog:   "catalog",
-				Table:     "table",
-				Workgroup: "workgroup",
-				Account:   "account",
-				Authorizer: &AccessKey{
-					ID:     "id",
-					Secret: "secret",
-				},
-				CURVersion: "1.0",
-			},
-			expected: true,
-		},
 		"different config": {
 			left: AthenaConfiguration{
 				Bucket:    "bucket",
@@ -669,9 +551,7 @@ func TestAthenaConfiguration_JSON(t *testing.T) {
 		config AthenaConfiguration
 	}{
 		"Empty Config": {
-			config: AthenaConfiguration{
-				CURVersion: "2.0", // Default value after JSON unmarshal
-			},
+			config: AthenaConfiguration{},
 		},
 		"AccessKey": {
 			config: AthenaConfiguration{
@@ -686,7 +566,6 @@ func TestAthenaConfiguration_JSON(t *testing.T) {
 					ID:     "id",
 					Secret: "secret",
 				},
-				CURVersion: "2.0", // Default value after JSON unmarshal
 			},
 		},
 
@@ -700,7 +579,6 @@ func TestAthenaConfiguration_JSON(t *testing.T) {
 				Workgroup:  "workgroup",
 				Account:    "account",
 				Authorizer: &ServiceAccount{},
-				CURVersion: "2.0", // Default value after JSON unmarshal
 			},
 		},
 		"AssumeRole with AccessKey": {
@@ -719,7 +597,6 @@ func TestAthenaConfiguration_JSON(t *testing.T) {
 					},
 					RoleARN: "12345",
 				},
-				CURVersion: "2.0", // Default value after JSON unmarshal
 			},
 		},
 		"AssumeRole with ServiceAccount": {
@@ -735,7 +612,6 @@ func TestAthenaConfiguration_JSON(t *testing.T) {
 					Authorizer: &ServiceAccount{},
 					RoleARN:    "12345",
 				},
-				CURVersion: "2.0", // Default value after JSON unmarshal
 			},
 		},
 		"RoleArnNil": {
@@ -751,7 +627,6 @@ func TestAthenaConfiguration_JSON(t *testing.T) {
 					Authorizer: nil,
 					RoleARN:    "12345",
 				},
-				CURVersion: "2.0", // Default value after JSON unmarshal
 			},
 		},
 		"AssumeRole with AssumeRole with ServiceAccount": {
@@ -770,39 +645,6 @@ func TestAthenaConfiguration_JSON(t *testing.T) {
 					},
 					RoleARN: "12345",
 				},
-				CURVersion: "2.0", // Default value after JSON unmarshal
-			},
-		},
-		"CUR Version 1.0": {
-			config: AthenaConfiguration{
-				Bucket:    "bucket",
-				Region:    "region",
-				Database:  "database",
-				Catalog:   "catalog",
-				Table:     "table",
-				Workgroup: "workgroup",
-				Account:   "account",
-				Authorizer: &AccessKey{
-					ID:     "id",
-					Secret: "secret",
-				},
-				CURVersion: "1.0",
-			},
-		},
-		"CUR Version 2.0": {
-			config: AthenaConfiguration{
-				Bucket:    "bucket",
-				Region:    "region",
-				Database:  "database",
-				Catalog:   "catalog",
-				Table:     "table",
-				Workgroup: "workgroup",
-				Account:   "account",
-				Authorizer: &AccessKey{
-					ID:     "id",
-					Secret: "secret",
-				},
-				CURVersion: "2.0",
 			},
 		},
 	}

+ 72 - 28
pkg/cloud/aws/athenaintegration.go

@@ -10,6 +10,7 @@ import (
 	"github.com/aws/aws-sdk-go-v2/service/athena/types"
 	"github.com/opencost/opencost/core/pkg/log"
 	"github.com/opencost/opencost/core/pkg/opencost"
+	"github.com/opencost/opencost/core/pkg/util/json"
 	"github.com/opencost/opencost/core/pkg/util/timeutil"
 	"github.com/opencost/opencost/pkg/cloud"
 )
@@ -17,6 +18,12 @@ import (
 const LabelColumnPrefix = "resource_tags_user_"
 const AWSLabelColumnPrefix = "resource_tags_aws_"
 const AthenaResourceTagPrefix = "resource_tags_"
+const AthenaResourceTagsColumn = "resource_tags"
+
+const AthenaResourceTagsCastToJsonColumn = "CAST(resource_tags AS JSON) as resource_tags"
+
+const AthenaInvoiceEntityNameColumn = "bill_payer_account_name"
+const AthenaAccountNameColumn = "line_item_usage_account_name"
 
 // athenaDateLayout is the default AWS date format
 const AthenaDateLayout = "2006-01-02 15:04:05.000"
@@ -128,6 +135,18 @@ func (ai *AthenaIntegration) getCloudCost(start, end time.Time, limit int) (*ope
 			aqi.AWSTagColumns = append(aqi.AWSTagColumns, column)
 		}
 	}
+
+	// CUR 2.0 specific columns, CUR 2.0 has ability to disable any column, so we check for any of these columns before querying
+	if allColumns[AthenaResourceTagsColumn] {
+		groupByColumns = append(groupByColumns, AthenaResourceTagsCastToJsonColumn)
+	}
+	if allColumns[AthenaAccountNameColumn] {
+		groupByColumns = append(groupByColumns, AthenaAccountNameColumn)
+	}
+	if allColumns[AthenaInvoiceEntityNameColumn] {
+		groupByColumns = append(groupByColumns, AthenaInvoiceEntityNameColumn)
+	}
+
 	var selectColumns []string
 
 	// Duplicate GroupBy Columns into select columns
@@ -162,7 +181,7 @@ func (ai *AthenaIntegration) getCloudCost(start, end time.Time, limit int) (*ope
 		aqi.ColumnIndexes[column] = i
 	}
 	whereDate := fmt.Sprintf(AthenaWhereDateFmt, start.Format("2006-01-02"), end.Format("2006-01-02"))
-	wherePartitions := ai.GetPartitionWhere(start, end)
+	wherePartitions := ai.GetPartitionWhere(start, end, isCUR20(allColumns))
 
 	// Query for all line items with a resource_id or from AWS Marketplace, which did not end before
 	// the range or start after it. This captures all costs with any amount of
@@ -323,11 +342,9 @@ func (ai *AthenaIntegration) ConvertLabelToAWSTag(label string) string {
 
 // GetIsKubernetesColumn builds a column that determines if a row represents kubernetes spend
 func (ai *AthenaIntegration) GetIsKubernetesColumn(allColumns map[string]bool) string {
-	disjuncts := []string{
-		"line_item_product_code = 'AmazonEKS'", // EKS is always kubernetes
-	}
 	// tagColumns is a list of columns where the presence of a value indicates that a resource is part of a kubernetes cluster
-	tagColumns := []string{
+	// Known columns hardcoded for CUR 1.0 and CUR 2.0
+	tagColumnsIsK8sCUR10 := []string{
 		"resource_tags_aws_eks_cluster_name",
 		"resource_tags_user_eks_cluster_name",
 		"resource_tags_user_alpha_eksctl_io_cluster_name",
@@ -335,43 +352,49 @@ func (ai *AthenaIntegration) GetIsKubernetesColumn(allColumns map[string]bool) s
 		"resource_tags_user_kubernetes_io_created_for_pvc_name",
 		"resource_tags_user_kubernetes_io_created_for_pv_name",
 	}
+	tagColumnsIsK8sCUR20 := []string{
+		"resource_tags['aws_eks_cluster_name']",
+		"resource_tags['user_eks_cluster_name']",
+		"resource_tags['user_alpha_eksctl_io_cluster_name']",
+		"resource_tags['user_kubernetes_io_service_name']",
+		"resource_tags['user_kubernetes_io_created_for_pvc_name']",
+		"resource_tags['user_kubernetes_io_created_for_pv_name']",
+	}
 
-	for _, tagColumn := range tagColumns {
-		// if tag column is present in the CUR check for it
-		if _, ok := allColumns[tagColumn]; ok {
-			disjunctStr := fmt.Sprintf("%s <> ''", tagColumn)
+	disjuncts := []string{
+		"line_item_product_code = 'AmazonEKS'", // EKS is always kubernetes
+	}
+	if allColumns[AthenaResourceTagsColumn] {
+		// if resource tags column is present in the CUR check for IsKubernetes keys in the resource tags map
+		for _, tagColumn := range tagColumnsIsK8sCUR20 {
+			disjunctStr := fmt.Sprintf("COALESCE(%s, '') <> ''", tagColumn)
 			disjuncts = append(disjuncts, disjunctStr)
 		}
+	} else {
+		for _, tagColumn := range tagColumnsIsK8sCUR10 {
+			// if tag column is present in the CUR check for it
+			if _, ok := allColumns[tagColumn]; ok {
+				disjunctStr := fmt.Sprintf("%s <> ''", tagColumn)
+				disjuncts = append(disjuncts, disjunctStr)
+			}
+		}
 	}
 
 	return fmt.Sprintf("(%s) as is_kubernetes", strings.Join(disjuncts, " OR "))
 }
 
-func (ai *AthenaIntegration) GetPartitionWhere(start, end time.Time) string {
+func (ai *AthenaIntegration) GetPartitionWhere(start, end time.Time, isCUR20 bool) string {
 	month := time.Date(start.Year(), start.Month(), 1, 0, 0, 0, 0, time.UTC)
 	endMonth := time.Date(end.Year(), end.Month(), 1, 0, 0, 0, 0, time.UTC)
 	var disjuncts []string
 
-	// For CUR 2.0, check if billing_period partitions actually exist
-	useBillingPeriodPartitions := false
-	if ai.CURVersion != "1.0" {
-		// Check if billing_period partitions exist in the table
-		if hasBillingPeriod, err := ai.HasBillingPeriodPartitions(); err == nil && hasBillingPeriod {
-			useBillingPeriodPartitions = true
-		}
-	}
-
 	for !month.After(endMonth) {
-		if ai.CURVersion == "1.0" {
-			// CUR 1.0 uses year and month columns for partitioning
-			disjuncts = append(disjuncts, fmt.Sprintf("(year = '%d' AND month = '%d')", month.Year(), month.Month()))
-		} else if useBillingPeriodPartitions {
+		if isCUR20 {
 			// CUR 2.0 with billing_period partitions
 			disjuncts = append(disjuncts, fmt.Sprintf("(billing_period = '%d-%02d')", month.Year(), month.Month()))
 		} else {
-			// CUR 2.0 fallback - use date_format functions (less efficient but works without partitions)
-			disjuncts = append(disjuncts, fmt.Sprintf("(date_format(line_item_usage_start_date, '%%Y') = '%d' AND date_format(line_item_usage_start_date, '%%m') = '%02d')",
-				month.Year(), month.Month()))
+			// CUR 1.0 uses year and month columns for partitioning
+			disjuncts = append(disjuncts, fmt.Sprintf("(year = '%d' AND month = '%d')", month.Year(), month.Month()))
 		}
 		month = month.AddDate(0, 1, 0)
 	}
@@ -408,8 +431,24 @@ func athenaRowToCloudCost(row types.Row, aqi AthenaQueryIndexes) (*opencost.Clou
 		}
 	}
 
+	if _, ok := aqi.ColumnIndexes[AthenaResourceTagsCastToJsonColumn]; ok {
+		resourceTags := GetAthenaRowValue(row, aqi.ColumnIndexes, AthenaResourceTagsCastToJsonColumn)
+		err := json.Unmarshal([]byte(resourceTags), &labels)
+		if err != nil {
+			log.Errorf("athenaRowToCloudCost: error unmarshalling resource tags: %s", err.Error())
+		}
+	}
+
 	invoiceEntityID := GetAthenaRowValue(row, aqi.ColumnIndexes, "bill_payer_account_id")
 	accountID := GetAthenaRowValue(row, aqi.ColumnIndexes, "line_item_usage_account_id")
+	invoiceEntityName := invoiceEntityID
+	accountName := accountID
+	if _, ok := aqi.ColumnIndexes[AthenaInvoiceEntityNameColumn]; ok {
+		invoiceEntityName = GetAthenaRowValue(row, aqi.ColumnIndexes, AthenaInvoiceEntityNameColumn)
+	}
+	if _, ok := aqi.ColumnIndexes[AthenaAccountNameColumn]; ok {
+		accountName = GetAthenaRowValue(row, aqi.ColumnIndexes, AthenaAccountNameColumn)
+	}
 	startStr := GetAthenaRowValue(row, aqi.ColumnIndexes, AthenaDateTruncColumn)
 	providerID := GetAthenaRowValue(row, aqi.ColumnIndexes, "line_item_resource_id")
 	productCode := GetAthenaRowValue(row, aqi.ColumnIndexes, "line_item_product_code")
@@ -462,9 +501,9 @@ func athenaRowToCloudCost(row types.Row, aqi AthenaQueryIndexes) (*opencost.Clou
 		ProviderID:        providerID,
 		Provider:          opencost.AWSProvider,
 		AccountID:         accountID,
-		AccountName:       accountID,
+		AccountName:       accountName,
 		InvoiceEntityID:   invoiceEntityID,
-		InvoiceEntityName: invoiceEntityID,
+		InvoiceEntityName: invoiceEntityName,
 		RegionID:          regionCode,
 		AvailabilityZone:  availabilityZone,
 		Service:           productCode,
@@ -512,3 +551,8 @@ func (ai *AthenaIntegration) GetConnectionStatusFromResult(result cloud.EmptyChe
 	}
 	return cloud.SuccessfulConnection
 }
+
+// presence of any of resource_tags, line_item_usage_account_name, or bill_payer_account_name columns confirms CUR 2.0
+func isCUR20(allColumns map[string]bool) bool {
+	return allColumns[AthenaResourceTagsColumn] || allColumns[AthenaAccountNameColumn] || allColumns[AthenaInvoiceEntityNameColumn]
+}

+ 20 - 13
pkg/cloud/aws/athenaintegration_coverage_test.go

@@ -3,7 +3,6 @@ package aws
 import (
 	"strings"
 	"testing"
-	"time"
 
 	"github.com/opencost/opencost/pkg/cloud"
 )
@@ -185,15 +184,15 @@ func TestAthenaIntegration_ConvertLabelToAWSTag(t *testing.T) {
 func TestAthenaIntegration_GetIsKubernetesColumn(t *testing.T) {
 	ai := &AthenaIntegration{}
 
-	// Test with some tag columns present
-	allColumns := map[string]bool{
+	// Test with some tag columns present CUR 1.0
+	allColumnsCur10 := map[string]bool{
 		"resource_tags_user_eks_cluster_name":             true,
 		"resource_tags_user_alpha_eksctl_io_cluster_name": true,
 		"resource_tags_user_kubernetes_io_service_name":   true,
 		"some_other_column":                               true,
 	}
 
-	result := ai.GetIsKubernetesColumn(allColumns)
+	result := ai.GetIsKubernetesColumn(allColumnsCur10)
 	if !strings.Contains(result, "line_item_product_code = 'AmazonEKS'") {
 		t.Errorf("GetIsKubernetesColumn() should always include EKS check, got: %v", result)
 	}
@@ -203,6 +202,23 @@ func TestAthenaIntegration_GetIsKubernetesColumn(t *testing.T) {
 	if !strings.Contains(result, " as is_kubernetes") {
 		t.Errorf("GetIsKubernetesColumn() should alias result as is_kubernetes, got: %v", result)
 	}
+
+	// Test with some tag columns present CUR 2.0
+	allColumnsCur20 := map[string]bool{
+		"resource_tags":     true,
+		"some_other_column": true,
+	}
+
+	result = ai.GetIsKubernetesColumn(allColumnsCur20)
+	if !strings.Contains(result, "line_item_product_code = 'AmazonEKS'") {
+		t.Errorf("GetIsKubernetesColumn() should always include EKS check, got: %v", result)
+	}
+	if !strings.Contains(result, "COALESCE(resource_tags['user_eks_cluster_name'], '') <> ''") {
+		t.Errorf("GetIsKubernetesColumn() should include checks for tag columns, got: %v", result)
+	}
+	if !strings.Contains(result, " as is_kubernetes") {
+		t.Errorf("GetIsKubernetesColumn() should alias result as is_kubernetes, got: %v", result)
+	}
 }
 
 func TestAthenaQuerier_GetStatus(t *testing.T) {
@@ -284,12 +300,3 @@ func TestAthenaQuerier_Equals(t *testing.T) {
 		t.Errorf("Equals() should return false when comparing with different type")
 	}
 }
-
-// Helper function for parsing time in tests
-func mustParseTime(value string) time.Time {
-	t, err := time.Parse(time.RFC3339, value)
-	if err != nil {
-		panic(err)
-	}
-	return t
-}

+ 156 - 182
pkg/cloud/aws/athenaintegration_test.go

@@ -1,10 +1,8 @@
 package aws
 
 import (
-	"fmt"
 	"os"
 	"reflect"
-	"strings"
 	"testing"
 	"time"
 
@@ -70,7 +68,7 @@ func TestAthenaIntegration_GetCloudCost(t *testing.T) {
 }
 
 func Test_athenaRowToCloudCost(t *testing.T) {
-	aqi := AthenaQueryIndexes{
+	aqiCur10 := AthenaQueryIndexes{
 		ColumnIndexes: map[string]int{
 			"ListCostColumn":              0,
 			"NetCostColumn":               1,
@@ -97,6 +95,32 @@ func Test_athenaRowToCloudCost(t *testing.T) {
 		IsK8sColumn:            "IsK8sColumn",
 	}
 
+	aqiCur20 := AthenaQueryIndexes{
+		ColumnIndexes: map[string]int{
+			"ListCostColumn":                   0,
+			"NetCostColumn":                    1,
+			"AmortizedNetCostColumn":           2,
+			"AmortizedCostColumn":              3,
+			"IsK8sColumn":                      4,
+			AthenaDateTruncColumn:              5,
+			"line_item_resource_id":            6,
+			"bill_payer_account_id":            7,
+			"line_item_usage_account_id":       8,
+			"line_item_product_code":           9,
+			"line_item_usage_type":             10,
+			"product_region_code":              11,
+			"line_item_availability_zone":      12,
+			AthenaResourceTagsCastToJsonColumn: 13,
+		},
+		TagColumns:             []string{},
+		AWSTagColumns:          []string{},
+		ListCostColumn:         "ListCostColumn",
+		NetCostColumn:          "NetCostColumn",
+		AmortizedNetCostColumn: "AmortizedNetCostColumn",
+		AmortizedCostColumn:    "AmortizedCostColumn",
+		IsK8sColumn:            "IsK8sColumn",
+	}
+
 	tests := []struct {
 		name    string
 		row     []string
@@ -105,51 +129,51 @@ func Test_athenaRowToCloudCost(t *testing.T) {
 		wantErr bool
 	}{
 		{
-			name:    "incorrect row length",
+			name:    "incorrect row length CUR 1.0",
 			row:     []string{"not enough elements"},
-			aqi:     aqi,
+			aqi:     aqiCur10,
 			want:    nil,
 			wantErr: true,
 		},
 		{
-			name:    "invalid list cost",
+			name:    "invalid list cost CUR 1.0",
 			row:     []string{"invalid", "2", "3", "4", "true", "2024-09-01 00:00:00.000", "resourceID", "payerAccountID", "usageAccountID", "productCode", "usageType", "regionCode", "availabilityZone", "userTagTestValue", "awsTagTestValue"},
-			aqi:     aqi,
+			aqi:     aqiCur10,
 			want:    nil,
 			wantErr: true,
 		},
 		{
-			name:    "invalid net cost",
+			name:    "invalid net cost CUR 1.0",
 			row:     []string{"1", "invalid", "3", "4", "true", "2024-09-01 00:00:00.000", "resourceID", "payerAccountID", "usageAccountID", "productCode", "usageType", "regionCode", "availabilityZone", "userTagTestValue", "awsTagTestValue"},
-			aqi:     aqi,
+			aqi:     aqiCur10,
 			want:    nil,
 			wantErr: true,
 		},
 		{
-			name:    "invalid amortized net cost",
+			name:    "invalid amortized net cost CUR 1.0",
 			row:     []string{"1", "2", "invalid", "4", "true", "2024-09-01 00:00:00.000", "resourceID", "payerAccountID", "usageAccountID", "productCode", "usageType", "regionCode", "availabilityZone", "userTagTestValue", "awsTagTestValue"},
-			aqi:     aqi,
+			aqi:     aqiCur10,
 			want:    nil,
 			wantErr: true,
 		},
 		{
-			name:    "invalid amortized cost",
+			name:    "invalid amortized cost CUR 1.0",
 			row:     []string{"1", "2", "3", "invalid", "true", "2024-09-01 00:00:00.000", "resourceID", "payerAccountID", "usageAccountID", "productCode", "usageType", "regionCode", "availabilityZone", "userTagTestValue", "awsTagTestValue"},
-			aqi:     aqi,
+			aqi:     aqiCur10,
 			want:    nil,
 			wantErr: true,
 		},
 		{
-			name:    "invalid date",
+			name:    "invalid date CUR 1.0",
 			row:     []string{"1", "2", "3", "4", "true", "invalid", "resourceID", "payerAccountID", "usageAccountID", "productCode", "usageType", "regionCode", "availabilityZone", "userTagTestValue", "awsTagTestValue"},
-			aqi:     aqi,
+			aqi:     aqiCur10,
 			want:    nil,
 			wantErr: true,
 		},
 		{
-			name: "valid kubernetes with labels",
+			name: "valid kubernetes with labels CUR 1.0",
 			row:  []string{"1", "2", "3", "4", "true", "2024-09-01 00:00:00.000", "resourceID", "payerAccountID", "usageAccountID", "productCode", "usageType", "regionCode", "availabilityZone", "userTagTestValue", "awsTagTestValue"},
-			aqi:  aqi,
+			aqi:  aqiCur10,
 			want: &opencost.CloudCost{
 				Properties: &opencost.CloudCostProperties{
 					ProviderID:        "resourceID",
@@ -197,7 +221,7 @@ func Test_athenaRowToCloudCost(t *testing.T) {
 		{
 			name: "valid non-kubernetes, no labels",
 			row:  []string{"1", "2", "3", "4", "false", "2024-09-01 00:00:00.000", "resourceID", "payerAccountID", "usageAccountID", "productCode", "usageType", "regionCode", "availabilityZone", "", ""},
-			aqi:  aqi,
+			aqi:  aqiCur10,
 			want: &opencost.CloudCost{
 				Properties: &opencost.CloudCostProperties{
 					ProviderID:        "resourceID",
@@ -240,9 +264,9 @@ func Test_athenaRowToCloudCost(t *testing.T) {
 			wantErr: false,
 		},
 		{
-			name: "valid load balancer product code",
+			name: "valid load balancer product code CUR 1.0",
 			row:  []string{"1", "2", "3", "4", "false", "2024-09-01 00:00:00.000", "resourceID/lbID", "payerAccountID", "usageAccountID", "AWSELB", "usageType", "regionCode", "availabilityZone", "", ""},
-			aqi:  aqi,
+			aqi:  aqiCur10,
 			want: &opencost.CloudCost{
 				Properties: &opencost.CloudCostProperties{
 					ProviderID:        "lbID",
@@ -285,9 +309,9 @@ func Test_athenaRowToCloudCost(t *testing.T) {
 			wantErr: false,
 		},
 		{
-			name: "valid non-kubernetes, Fargate CPU",
+			name: "valid non-kubernetes, Fargate CPU CUR 1.0",
 			row:  []string{"1", "2", "3", "4", "false", "2024-09-01 00:00:00.000", "123:pod/resource", "payerAccountID", "usageAccountID", "AmazonEKS", "CPU", "regionCode", "availabilityZone", "", ""},
-			aqi:  aqi,
+			aqi:  aqiCur10,
 			want: &opencost.CloudCost{
 				Properties: &opencost.CloudCostProperties{
 					ProviderID:        "123:pod/resource/CPU",
@@ -330,9 +354,9 @@ func Test_athenaRowToCloudCost(t *testing.T) {
 			wantErr: false,
 		},
 		{
-			name: "valid non-kubernetes, Fargate RAM",
+			name: "valid non-kubernetes, Fargate RAM CUR 1.0",
 			row:  []string{"1", "2", "3", "4", "false", "2024-09-01 00:00:00.000", "123:pod/resource", "payerAccountID", "usageAccountID", "AmazonEKS", "GB", "regionCode", "availabilityZone", "", ""},
-			aqi:  aqi,
+			aqi:  aqiCur10,
 			want: &opencost.CloudCost{
 				Properties: &opencost.CloudCostProperties{
 					ProviderID:        "123:pod/resource/RAM",
@@ -374,6 +398,54 @@ func Test_athenaRowToCloudCost(t *testing.T) {
 			},
 			wantErr: false,
 		},
+		{
+			name: "valid kubernetes with labels CUR 2.0",
+			row:  []string{"1", "2", "3", "4", "true", "2024-09-01 00:00:00.000", "resourceID", "payerAccountID", "usageAccountID", "productCode", "usageType", "regionCode", "availabilityZone", `{"test": "userTagTestValue", "aws_test": "awsTagTestValue"}`},
+			aqi:  aqiCur20,
+			want: &opencost.CloudCost{
+				Properties: &opencost.CloudCostProperties{
+					ProviderID:        "resourceID",
+					Provider:          "AWS",
+					AccountID:         "usageAccountID",
+					AccountName:       "usageAccountID",
+					InvoiceEntityID:   "payerAccountID",
+					InvoiceEntityName: "payerAccountID",
+					RegionID:          "regionCode",
+					AvailabilityZone:  "availabilityZone",
+					Service:           "productCode",
+					Category:          opencost.OtherCategory,
+					Labels: opencost.CloudCostLabels{
+						"test":     "userTagTestValue",
+						"aws_test": "awsTagTestValue",
+					},
+				},
+				Window: opencost.NewClosedWindow(
+					time.Date(2024, 9, 1, 0, 0, 0, 0, time.UTC),
+					time.Date(2024, 9, 2, 0, 0, 0, 0, time.UTC),
+				),
+				ListCost: opencost.CostMetric{
+					Cost:              1,
+					KubernetesPercent: 1,
+				},
+				NetCost: opencost.CostMetric{
+					Cost:              2,
+					KubernetesPercent: 1,
+				},
+				AmortizedNetCost: opencost.CostMetric{
+					Cost:              3,
+					KubernetesPercent: 1,
+				},
+				InvoicedCost: opencost.CostMetric{
+					Cost:              2,
+					KubernetesPercent: 1,
+				},
+				AmortizedCost: opencost.CostMetric{
+					Cost:              4,
+					KubernetesPercent: 1,
+				},
+			},
+			wantErr: false,
+		},
 	}
 	for _, tt := range tests {
 		t.Run(tt.name, func(t *testing.T) {
@@ -399,58 +471,13 @@ func stringsToRow(strings []string) types.Row {
 	return types.Row{Data: data}
 }
 
-// mockAthenaQuerier is a mock that overrides HasBillingPeriodPartitions for testing
-type mockAthenaQuerier struct {
-	AthenaQuerier
-	hasBillingPeriodPartitions bool
-}
-
-func (m *mockAthenaQuerier) HasBillingPeriodPartitions() (bool, error) {
-	return m.hasBillingPeriodPartitions, nil
-}
-
-// mockAthenaIntegration is a mock that uses mockAthenaQuerier
-type mockAthenaIntegration struct {
-	*mockAthenaQuerier
-}
-
-func (m *mockAthenaIntegration) GetPartitionWhere(start, end time.Time) string {
-	// The partition logic using our mock's HasBillingPeriodPartitions result
-	month := time.Date(start.Year(), start.Month(), 1, 0, 0, 0, 0, time.UTC)
-	endMonth := time.Date(end.Year(), end.Month(), 1, 0, 0, 0, 0, time.UTC)
-	var disjuncts []string
-
-	// Using our mock's result for billing period partitions
-	useBillingPeriodPartitions := false
-	if m.mockAthenaQuerier.AthenaConfiguration.CURVersion != "1.0" {
-		useBillingPeriodPartitions = m.mockAthenaQuerier.hasBillingPeriodPartitions
-	}
-
-	for !month.After(endMonth) {
-		if m.mockAthenaQuerier.AthenaConfiguration.CURVersion == "1.0" {
-			// CUR 1.0 uses year and month columns for partitioning
-			disjuncts = append(disjuncts, fmt.Sprintf("(year = '%d' AND month = '%d')", month.Year(), month.Month()))
-		} else if useBillingPeriodPartitions {
-			// CUR 2.0 with billing_period partitions
-			disjuncts = append(disjuncts, fmt.Sprintf("(billing_period = '%d-%02d')", month.Year(), month.Month()))
-		} else {
-			// CUR 2.0 fallback - use date_format functions
-			disjuncts = append(disjuncts, fmt.Sprintf("(date_format(line_item_usage_start_date, '%%Y') = '%d' AND date_format(line_item_usage_start_date, '%%m') = '%02d')",
-				month.Year(), month.Month()))
-		}
-		month = month.AddDate(0, 1, 0)
-	}
-	return fmt.Sprintf("(%s)", strings.Join(disjuncts, " OR "))
-}
-
 func TestAthenaIntegration_GetPartitionWhere(t *testing.T) {
 	testCases := map[string]struct {
-		integration interface {
-			GetPartitionWhere(time.Time, time.Time) string
-		}
-		start    time.Time
-		end      time.Time
-		expected string
+		integration        *AthenaIntegration
+		start              time.Time
+		end                time.Time
+		resourceTagsColumn bool
+		expected           string
 	}{
 		"CUR 1.0 single month": {
 			integration: &AthenaIntegration{
@@ -463,35 +490,32 @@ func TestAthenaIntegration_GetPartitionWhere(t *testing.T) {
 						Workgroup:  "workgroup",
 						Account:    "account",
 						Authorizer: &ServiceAccount{},
-						CURVersion: "1.0",
 					},
 				},
 			},
-			start:    time.Date(2024, 1, 15, 0, 0, 0, 0, time.UTC),
-			end:      time.Date(2024, 1, 25, 0, 0, 0, 0, time.UTC),
-			expected: "((year = '2024' AND month = '1'))",
+			start:              time.Date(2024, 1, 15, 0, 0, 0, 0, time.UTC),
+			end:                time.Date(2024, 1, 25, 0, 0, 0, 0, time.UTC),
+			resourceTagsColumn: false,
+			expected:           "((year = '2024' AND month = '1'))",
 		},
 		"CUR 2.0 single month": {
-			integration: &mockAthenaIntegration{
-				mockAthenaQuerier: &mockAthenaQuerier{
-					AthenaQuerier: AthenaQuerier{
-						AthenaConfiguration: AthenaConfiguration{
-							Bucket:     "bucket",
-							Region:     "region",
-							Database:   "database",
-							Table:      "table",
-							Workgroup:  "workgroup",
-							Account:    "account",
-							Authorizer: &ServiceAccount{},
-							CURVersion: "2.0",
-						},
+			integration: &AthenaIntegration{
+				AthenaQuerier: AthenaQuerier{
+					AthenaConfiguration: AthenaConfiguration{
+						Bucket:     "bucket",
+						Region:     "region",
+						Database:   "database",
+						Table:      "table",
+						Workgroup:  "workgroup",
+						Account:    "account",
+						Authorizer: &ServiceAccount{},
 					},
-					hasBillingPeriodPartitions: true,
 				},
 			},
-			start:    time.Date(2024, 1, 15, 0, 0, 0, 0, time.UTC),
-			end:      time.Date(2024, 1, 25, 0, 0, 0, 0, time.UTC),
-			expected: "((billing_period = '2024-01'))",
+			start:              time.Date(2024, 1, 15, 0, 0, 0, 0, time.UTC),
+			end:                time.Date(2024, 1, 25, 0, 0, 0, 0, time.UTC),
+			resourceTagsColumn: true,
+			expected:           "((billing_period = '2024-01'))",
 		},
 		"CUR 1.0 multiple months": {
 			integration: &AthenaIntegration{
@@ -504,57 +528,51 @@ func TestAthenaIntegration_GetPartitionWhere(t *testing.T) {
 						Workgroup:  "workgroup",
 						Account:    "account",
 						Authorizer: &ServiceAccount{},
-						CURVersion: "1.0",
 					},
 				},
 			},
-			start:    time.Date(2024, 1, 15, 0, 0, 0, 0, time.UTC),
-			end:      time.Date(2024, 3, 10, 0, 0, 0, 0, time.UTC),
-			expected: "((year = '2024' AND month = '1') OR (year = '2024' AND month = '2') OR (year = '2024' AND month = '3'))",
+			start:              time.Date(2024, 1, 15, 0, 0, 0, 0, time.UTC),
+			end:                time.Date(2024, 3, 10, 0, 0, 0, 0, time.UTC),
+			resourceTagsColumn: false,
+			expected:           "((year = '2024' AND month = '1') OR (year = '2024' AND month = '2') OR (year = '2024' AND month = '3'))",
 		},
 		"CUR 2.0 multiple months": {
-			integration: &mockAthenaIntegration{
-				mockAthenaQuerier: &mockAthenaQuerier{
-					AthenaQuerier: AthenaQuerier{
-						AthenaConfiguration: AthenaConfiguration{
-							Bucket:     "bucket",
-							Region:     "region",
-							Database:   "database",
-							Table:      "table",
-							Workgroup:  "workgroup",
-							Account:    "account",
-							Authorizer: &ServiceAccount{},
-							CURVersion: "2.0",
-						},
+			integration: &AthenaIntegration{
+				AthenaQuerier: AthenaQuerier{
+					AthenaConfiguration: AthenaConfiguration{
+						Bucket:     "bucket",
+						Region:     "region",
+						Database:   "database",
+						Table:      "table",
+						Workgroup:  "workgroup",
+						Account:    "account",
+						Authorizer: &ServiceAccount{},
 					},
-					hasBillingPeriodPartitions: true,
 				},
 			},
-			start:    time.Date(2024, 1, 15, 0, 0, 0, 0, time.UTC),
-			end:      time.Date(2024, 3, 10, 0, 0, 0, 0, time.UTC),
-			expected: "((billing_period = '2024-01') OR (billing_period = '2024-02') OR (billing_period = '2024-03'))",
+			start:              time.Date(2024, 1, 15, 0, 0, 0, 0, time.UTC),
+			end:                time.Date(2024, 3, 10, 0, 0, 0, 0, time.UTC),
+			resourceTagsColumn: true,
+			expected:           "((billing_period = '2024-01') OR (billing_period = '2024-02') OR (billing_period = '2024-03'))",
 		},
 		"CUR 2.0 across year boundary": {
-			integration: &mockAthenaIntegration{
-				mockAthenaQuerier: &mockAthenaQuerier{
-					AthenaQuerier: AthenaQuerier{
-						AthenaConfiguration: AthenaConfiguration{
-							Bucket:     "bucket",
-							Region:     "region",
-							Database:   "database",
-							Table:      "table",
-							Workgroup:  "workgroup",
-							Account:    "account",
-							Authorizer: &ServiceAccount{},
-							CURVersion: "2.0",
-						},
+			integration: &AthenaIntegration{
+				AthenaQuerier: AthenaQuerier{
+					AthenaConfiguration: AthenaConfiguration{
+						Bucket:     "bucket",
+						Region:     "region",
+						Database:   "database",
+						Table:      "table",
+						Workgroup:  "workgroup",
+						Account:    "account",
+						Authorizer: &ServiceAccount{},
 					},
-					hasBillingPeriodPartitions: true,
 				},
 			},
-			start:    time.Date(2023, 12, 15, 0, 0, 0, 0, time.UTC),
-			end:      time.Date(2024, 2, 10, 0, 0, 0, 0, time.UTC),
-			expected: "((billing_period = '2023-12') OR (billing_period = '2024-01') OR (billing_period = '2024-02'))",
+			start:              time.Date(2023, 12, 15, 0, 0, 0, 0, time.UTC),
+			end:                time.Date(2024, 2, 10, 0, 0, 0, 0, time.UTC),
+			resourceTagsColumn: true,
+			expected:           "((billing_period = '2023-12') OR (billing_period = '2024-01') OR (billing_period = '2024-02'))",
 		},
 		"CUR 1.0 across year boundary": {
 			integration: &AthenaIntegration{
@@ -567,63 +585,19 @@ func TestAthenaIntegration_GetPartitionWhere(t *testing.T) {
 						Workgroup:  "workgroup",
 						Account:    "account",
 						Authorizer: &ServiceAccount{},
-						CURVersion: "1.0",
-					},
-				},
-			},
-			start:    time.Date(2023, 12, 15, 0, 0, 0, 0, time.UTC),
-			end:      time.Date(2024, 2, 10, 0, 0, 0, 0, time.UTC),
-			expected: "((year = '2023' AND month = '12') OR (year = '2024' AND month = '1') OR (year = '2024' AND month = '2'))",
-		},
-		"Default CUR version (empty string defaults to 2.0)": {
-			integration: &mockAthenaIntegration{
-				mockAthenaQuerier: &mockAthenaQuerier{
-					AthenaQuerier: AthenaQuerier{
-						AthenaConfiguration: AthenaConfiguration{
-							Bucket:     "bucket",
-							Region:     "region",
-							Database:   "database",
-							Table:      "table",
-							Workgroup:  "workgroup",
-							Account:    "account",
-							Authorizer: &ServiceAccount{},
-							CURVersion: "",
-						},
-					},
-					hasBillingPeriodPartitions: true,
-				},
-			},
-			start:    time.Date(2024, 1, 15, 0, 0, 0, 0, time.UTC),
-			end:      time.Date(2024, 1, 25, 0, 0, 0, 0, time.UTC),
-			expected: "((billing_period = '2024-01'))",
-		},
-		"CUR 2.0 fallback when no billing_period partitions": {
-			integration: &mockAthenaIntegration{
-				mockAthenaQuerier: &mockAthenaQuerier{
-					AthenaQuerier: AthenaQuerier{
-						AthenaConfiguration: AthenaConfiguration{
-							Bucket:     "bucket",
-							Region:     "region",
-							Database:   "database",
-							Table:      "table",
-							Workgroup:  "workgroup",
-							Account:    "account",
-							Authorizer: &ServiceAccount{},
-							CURVersion: "2.0",
-						},
 					},
-					hasBillingPeriodPartitions: false, // No billing_period partitions
 				},
 			},
-			start:    time.Date(2024, 1, 15, 0, 0, 0, 0, time.UTC),
-			end:      time.Date(2024, 1, 25, 0, 0, 0, 0, time.UTC),
-			expected: "((date_format(line_item_usage_start_date, '%Y') = '2024' AND date_format(line_item_usage_start_date, '%m') = '01'))",
+			start:              time.Date(2023, 12, 15, 0, 0, 0, 0, time.UTC),
+			end:                time.Date(2024, 2, 10, 0, 0, 0, 0, time.UTC),
+			resourceTagsColumn: false,
+			expected:           "((year = '2023' AND month = '12') OR (year = '2024' AND month = '1') OR (year = '2024' AND month = '2'))",
 		},
 	}
 
 	for name, testCase := range testCases {
 		t.Run(name, func(t *testing.T) {
-			actual := testCase.integration.GetPartitionWhere(testCase.start, testCase.end)
+			actual := testCase.integration.GetPartitionWhere(testCase.start, testCase.end, testCase.resourceTagsColumn)
 			if actual != testCase.expected {
 				t.Errorf("GetPartitionWhere() mismatch:\nActual:   %s\nExpected: %s", actual, testCase.expected)
 			}

+ 0 - 26
pkg/cloud/aws/athenaquerier.go

@@ -63,32 +63,6 @@ func (aq *AthenaQuerier) GetColumns() (map[string]bool, error) {
 	return columnSet, nil
 }
 
-// HasBillingPeriodPartitions checks if the table uses billing_period partitioning
-// by querying SHOW PARTITIONS and looking for billing_period partition keys
-func (aq *AthenaQuerier) HasBillingPeriodPartitions() (bool, error) {
-	// Use SHOW PARTITIONS to check if billing_period partitions exist
-	query := fmt.Sprintf("SHOW PARTITIONS \"%s\"", aq.Table)
-	hasBillingPeriodPartition := false
-
-	athenaErr := aq.Query(context.TODO(), query, GetAthenaQueryFunc(func(row types.Row) {
-		if len(row.Data) > 0 && row.Data[0].VarCharValue != nil {
-			partitionValue := *row.Data[0].VarCharValue
-			// Check if partition follows billing_period=YYYY-MM format
-			if strings.HasPrefix(partitionValue, "billing_period=") {
-				hasBillingPeriodPartition = true
-			}
-		}
-	}))
-
-	if athenaErr != nil {
-		// If SHOW PARTITIONS fails, assume no billing_period partitions
-		log.Debugf("AthenaQuerier[%s]: SHOW PARTITIONS failed: %s", aq.Key(), athenaErr.Error())
-		return false, athenaErr
-	}
-
-	return hasBillingPeriodPartition, nil
-}
-
 func (aq *AthenaQuerier) Query(ctx context.Context, query string, fn func(*athena.GetQueryResultsOutput) bool) error {
 	err := aq.Validate()
 	if err != nil {

+ 0 - 5
pkg/cloud/aws/provider.go

@@ -412,7 +412,6 @@ type AwsAthenaInfo struct {
 	ServiceKeySecret string `json:"serviceKeySecret"`
 	AccountID        string `json:"projectID"`
 	MasterPayerARN   string `json:"masterPayerARN"`
-	CURVersion       string `json:"curVersion"` // "1.0" or "2.0", defaults to "2.0" if not specified
 }
 
 // IsEmpty returns true if all fields in config are empty, false if not.
@@ -525,7 +524,6 @@ func (aws *AWS) GetAWSAthenaInfo() (*AwsAthenaInfo, error) {
 		ServiceKeySecret: aak.SecretAccessKey,
 		AccountID:        config.AthenaProjectID,
 		MasterPayerARN:   config.MasterPayerARN,
-		CURVersion:       config.AthenaCURVersion,
 	}, nil
 }
 
@@ -575,9 +573,6 @@ func configUpdaterWithReaderAndType(r io.Reader, updateType string) func(c *mode
 				c.MasterPayerARN = aai.MasterPayerARN
 			}
 			c.AthenaProjectID = aai.AccountID
-			if aai.CURVersion != "" {
-				c.AthenaCURVersion = aai.CURVersion
-			}
 		default:
 			a := make(map[string]any)
 			err := json.NewDecoder(r).Decode(&a)

+ 0 - 2
pkg/cloud/config/configurations_test.go

@@ -116,7 +116,6 @@ var (
 						ID:     "id",
 						Secret: "secret",
 					},
-					CURVersion: "2.0",
 				},
 			},
 		},
@@ -150,7 +149,6 @@ var (
 						Authorizer: &aws.ServiceAccount{},
 						RoleARN:    "roleArn",
 					},
-					CURVersion: "2.0",
 				},
 			},
 		},

+ 0 - 1
pkg/cloud/config/controller_handlers_test.go

@@ -62,7 +62,6 @@ func Test_ParseConfig_Athena(t *testing.T) {
 			ID:     "id",
 			Secret: "secret",
 		},
-		CURVersion: "curversion",
 	}
 
 	configBytes, err := json.Marshal(config)

+ 0 - 3
pkg/cloud/config/controller_test.go

@@ -22,7 +22,6 @@ var validAthenaConf = &aws.AthenaConfiguration{
 	Workgroup:  "workgroup",
 	Account:    "account",
 	Authorizer: &aws.ServiceAccount{},
-	CURVersion: "2.0",
 }
 
 // Config with the same key as the baseline but is not equal to it because of the change in the non-keyed property Workgroup
@@ -34,7 +33,6 @@ var validAthenaConfModifiedProperty = &aws.AthenaConfiguration{
 	Workgroup:  "workgroup1",
 	Account:    "account",
 	Authorizer: &aws.ServiceAccount{},
-	CURVersion: "2.0",
 }
 
 // Config with the same key as baseline but is invalid due to missing Authorizer
@@ -46,7 +44,6 @@ var invalidAthenaConf = &aws.AthenaConfiguration{
 	Workgroup:  "workgroup",
 	Account:    "account",
 	Authorizer: nil,
-	CURVersion: "2.0",
 }
 
 // A valid config with a different key from the baseline

+ 0 - 1
pkg/cloud/models/models.go

@@ -164,7 +164,6 @@ type CustomPricing struct {
 	AthenaTable                  string `json:"athenaTable"`
 	AthenaWorkgroup              string `json:"athenaWorkgroup"`
 	MasterPayerARN               string `json:"masterPayerARN"`
-	AthenaCURVersion             string `json:"athenaCURVersion,omitempty"` // "1.0" or "2.0", defaults to "2.0"
 	BillingDataDataset           string `json:"billingDataDataset,omitempty"`
 	CustomPricesEnabled          string `json:"customPricesEnabled"`
 	AzureSubscriptionID          string `json:"azureSubscriptionID"`

+ 0 - 32
pkg/cloud/models/models_test.go

@@ -120,35 +120,3 @@ func TestSetSetCustomPricingField(t *testing.T) {
 		})
 	}
 }
-
-func TestCustomPricing_AthenaCURVersion(t *testing.T) {
-	testCases := map[string]struct {
-		curVersion string
-		expected   string
-	}{
-		"CUR version 1.0": {
-			curVersion: "1.0",
-			expected:   "1.0",
-		},
-		"CUR version 2.0": {
-			curVersion: "2.0",
-			expected:   "2.0",
-		},
-		"empty CUR version": {
-			curVersion: "",
-			expected:   "",
-		},
-	}
-
-	for name, testCase := range testCases {
-		t.Run(name, func(t *testing.T) {
-			cp := &CustomPricing{
-				AthenaCURVersion: testCase.curVersion,
-			}
-
-			if cp.AthenaCURVersion != testCase.expected {
-				t.Errorf("expected AthenaCURVersion to be '%s', got '%s'", testCase.expected, cp.AthenaCURVersion)
-			}
-		})
-	}
-}