Browse Source

Merge branch 'feature/kubemodel-2' into feature/pricing-module

Sean Holcomb 5 ngày trước cách đây
mục cha
commit
95d5ea3d77
43 tập tin đã thay đổi với 199 bổ sung3639 xóa
  1. 0 3
      core/pkg/clustercache/clustercache.go
  2. 1 1
      core/pkg/compute/kubemodel/cluster.go
  3. 1 1
      core/pkg/compute/kubemodel/container.go
  4. 1 1
      core/pkg/compute/kubemodel/cronjob.go
  5. 1 1
      core/pkg/compute/kubemodel/daemonset.go
  6. 1 1
      core/pkg/compute/kubemodel/dcgmdevice.go
  7. 1 1
      core/pkg/compute/kubemodel/deployment.go
  8. 1 1
      core/pkg/compute/kubemodel/job.go
  9. 1 1
      core/pkg/compute/kubemodel/kubemodel.go
  10. 1 1
      core/pkg/compute/kubemodel/persistentvolume.go
  11. 1 1
      core/pkg/compute/kubemodel/persistentvolumeclaim.go
  12. 1 1
      core/pkg/compute/kubemodel/pod.go
  13. 1 1
      core/pkg/compute/kubemodel/replicaset.go
  14. 1 1
      core/pkg/compute/kubemodel/resourcequota.go
  15. 1 1
      core/pkg/compute/kubemodel/service.go
  16. 1 1
      core/pkg/compute/kubemodel/statefulset.go
  17. 11 0
      core/pkg/env/core.go
  18. 8 6
      core/pkg/exporter/exporter_test.go
  19. 9 2
      core/pkg/exporter/pathing/bingenpath.go
  20. 58 44
      core/pkg/exporter/pathing/path_test.go
  21. 0 53
      core/pkg/exporter/pathing/staticpath.go
  22. 0 143
      core/pkg/exporter/pathing/staticpath_test.go
  23. 0 35
      core/pkg/model/helper.go
  24. 0 88
      core/pkg/model/helper_test.go
  25. 0 29
      core/pkg/model/kubemodel/kubemodel.go
  26. 15 0
      core/pkg/model/kubemodel/kubemodel_codecs_test.go
  27. 0 4
      core/pkg/model/kubemodel/kubemodel_test.go
  28. 0 3
      core/pkg/model/kubemodel/namespace.go
  29. 0 246
      core/pkg/model/pb/kubemodel/cluster.pb.go
  30. 0 258
      core/pkg/model/pb/kubemodel/container.pb.go
  31. 0 298
      core/pkg/model/pb/kubemodel/controller.pb.go
  32. 0 266
      core/pkg/model/pb/kubemodel/diagnostic.pb.go
  33. 0 366
      core/pkg/model/pb/kubemodel/gpu.pb.go
  34. 0 213
      core/pkg/model/pb/kubemodel/namespace.pb.go
  35. 0 340
      core/pkg/model/pb/kubemodel/network.pb.go
  36. 0 222
      core/pkg/model/pb/kubemodel/node.pb.go
  37. 0 343
      core/pkg/model/pb/kubemodel/pod.pb.go
  38. 0 418
      core/pkg/model/pb/kubemodel/storage.pb.go
  39. 0 9
      core/pkg/model/shared/usagetype.go
  40. 39 42
      core/pkg/opencost/exporter/controllers.go
  41. 20 20
      core/pkg/opencost/exporter/exporter_test.go
  42. 20 165
      core/pkg/opencost/exporter/exporters.go
  43. 4 8
      pkg/kubemodel/pipeline.go

+ 0 - 3
core/pkg/clustercache/clustercache.go

@@ -182,9 +182,6 @@ type CronJob struct {
 	Annotations map[string]string
 }
 
-type Volume struct {
-}
-
 // GetPublicIPAddresses returns all external IP addresses associated with the node
 func (n *Node) GetPublicIPAddresses() []string {
 	var publicIPs []string

+ 1 - 1
core/pkg/compute/kubemodel/cluster.go

@@ -50,4 +50,4 @@ func (km *KubeModel) computeCluster(kms *kubemodel.KubeModelSet, start, end time
 	kms.RegisterCluster(cluster)
 
 	return nil
-}
+}

+ 1 - 1
core/pkg/compute/kubemodel/container.go

@@ -169,4 +169,4 @@ func (km *KubeModel) computeContainers(kms *kubemodel.KubeModelSet, start, end t
 	}
 
 	return nil
-}
+}

+ 1 - 1
core/pkg/compute/kubemodel/cronjob.go

@@ -68,4 +68,4 @@ func (km *KubeModel) computeCronJobs(kms *kubemodel.KubeModelSet, start, end tim
 	}
 
 	return nil
-}
+}

+ 1 - 1
core/pkg/compute/kubemodel/daemonset.go

@@ -68,4 +68,4 @@ func (km *KubeModel) computeDaemonSets(kms *kubemodel.KubeModelSet, start, end t
 	}
 
 	return nil
-}
+}

+ 1 - 1
core/pkg/compute/kubemodel/dcgmdevice.go

@@ -86,4 +86,4 @@ func (km *KubeModel) computeDCGMDevices(kms *kubemodel.KubeModelSet, start, end
 	}
 
 	return nil
-}
+}

+ 1 - 1
core/pkg/compute/kubemodel/deployment.go

@@ -79,4 +79,4 @@ func (km *KubeModel) computeDeployments(kms *kubemodel.KubeModelSet, start, end
 	}
 
 	return nil
-}
+}

+ 1 - 1
core/pkg/compute/kubemodel/job.go

@@ -68,4 +68,4 @@ func (km *KubeModel) computeJobs(kms *kubemodel.KubeModelSet, start, end time.Ti
 	}
 
 	return nil
-}
+}

+ 1 - 1
core/pkg/compute/kubemodel/kubemodel.go

@@ -145,4 +145,4 @@ func (km *KubeModel) ComputeKubeModelSet(start, end time.Time) (*kubemodel.KubeM
 	kms.Metadata.CompletedAt = time.Now().UTC()
 
 	return kms, nil
-}
+}

+ 1 - 1
core/pkg/compute/kubemodel/persistentvolume.go

@@ -60,4 +60,4 @@ func (km *KubeModel) computePersistentVolumes(kms *kubemodel.KubeModelSet, start
 	}
 
 	return nil
-}
+}

+ 1 - 1
core/pkg/compute/kubemodel/persistentvolumeclaim.go

@@ -83,4 +83,4 @@ func (km *KubeModel) computePersistentVolumeClaims(kms *kubemodel.KubeModelSet,
 	}
 
 	return nil
-}
+}

+ 1 - 1
core/pkg/compute/kubemodel/pod.go

@@ -147,4 +147,4 @@ func (km *KubeModel) computePods(kms *kubemodel.KubeModelSet, start, end time.Ti
 	}
 
 	return nil
-}
+}

+ 1 - 1
core/pkg/compute/kubemodel/replicaset.go

@@ -83,4 +83,4 @@ func (km *KubeModel) computeReplicaSets(kms *kubemodel.KubeModelSet, start, end
 	}
 
 	return nil
-}
+}

+ 1 - 1
core/pkg/compute/kubemodel/resourcequota.go

@@ -259,4 +259,4 @@ func (km *KubeModel) computeResourceQuotas(kms *kubemodel.KubeModelSet, start, e
 	}
 
 	return nil
-}
+}

+ 1 - 1
core/pkg/compute/kubemodel/service.go

@@ -60,4 +60,4 @@ func (km *KubeModel) computeServices(kms *kubemodel.KubeModelSet, start, end tim
 	}
 
 	return nil
-}
+}

+ 1 - 1
core/pkg/compute/kubemodel/statefulset.go

@@ -79,4 +79,4 @@ func (km *KubeModel) computeStatefulSets(kms *kubemodel.KubeModelSet, start, end
 	}
 
 	return nil
-}
+}

+ 11 - 0
core/pkg/env/core.go

@@ -20,6 +20,9 @@ const (
 	Resolution1dRetentionEnvVar  = "RESOLUTION_1D_RETENTION"  // int: number of days
 	Resolution1hRetentionEnvVar  = "RESOLUTION_1H_RETENTION"  // int: number of hours
 	Resolution10mRetentionEnvVar = "RESOLUTION_10M_RETENTION" // int: number of 10m segments
+
+	ExportLegacyDataModelEnvVar = "EXPORT_LEGACY_DATA_MODEL"
+	ExportKubeModelEnvVar       = "EXPORT_KUBEMODEL"
 )
 
 // GetAPIPort returns the environment variable value for APIPortEnvVar which
@@ -61,3 +64,11 @@ func IsPProfEnabled() bool {
 func GetInstallNamespace(def string) string {
 	return Get(InstallNamespaceEnvVar, def)
 }
+
+func GetExportLegacyDataModel() bool {
+	return GetBool(ExportLegacyDataModelEnvVar, true)
+}
+
+func GetExportKubeModel() bool {
+	return GetBool(ExportKubeModelEnvVar, true)
+}

+ 8 - 6
core/pkg/exporter/exporter_test.go

@@ -15,8 +15,10 @@ import (
 )
 
 const (
-	TestClusterId = "test-cluster"
-	TestEventName = "test-event-path"
+	TestAppName     = "test-app"
+	TestClusterID   = "test-cluster-id"
+	TestClusterName = "test-cluster"
+	TestEventName   = "test-event-path"
 )
 
 type TestData struct {
@@ -26,7 +28,7 @@ type TestData struct {
 func TestStorageExporters(t *testing.T) {
 	t.Run("test event storage exporter", func(t *testing.T) {
 		store := storage.NewMemoryStorage()
-		p, err := pathing.NewEventStoragePathFormatter("root", TestClusterId, TestEventName)
+		p, err := pathing.NewEventStoragePathFormatter("root", TestClusterName, TestEventName)
 		if err != nil {
 			t.Fatalf("failed to create path formatter: %v", err)
 		}
@@ -67,7 +69,7 @@ func TestStorageExporters(t *testing.T) {
 	t.Run("test compute storage exporter", func(t *testing.T) {
 		res := 24 * time.Hour
 		store := storage.NewMemoryStorage()
-		p, err := pathing.NewDefaultStoragePathFormatter(TestClusterId, pipelines.AllocationPipelineName, &res)
+		p, err := pathing.NewDefaultStoragePathFormatter(TestAppName, TestClusterID, TestClusterName, pipelines.AllocationPipelineName, &res)
 		if err != nil {
 			t.Fatalf("failed to create path formatter: %v", err)
 		}
@@ -115,7 +117,7 @@ func TestStorageExporters(t *testing.T) {
 	t.Run("test streaming compute storage exporter", func(t *testing.T) {
 		res := 24 * time.Hour
 		store := storage.NewMemoryStorage()
-		p, err := pathing.NewDefaultStoragePathFormatter(TestClusterId, pipelines.AllocationPipelineName, &res)
+		p, err := pathing.NewDefaultStoragePathFormatter(TestAppName, TestClusterID, TestClusterName, pipelines.AllocationPipelineName, &res)
 		if err != nil {
 			t.Fatalf("failed to create path formatter: %v", err)
 		}
@@ -163,7 +165,7 @@ func TestStorageExporters(t *testing.T) {
 	t.Run("test compressed streaming compute storage exporter", func(t *testing.T) {
 		res := 24 * time.Hour
 		store := storage.NewMemoryStorage()
-		p, err := pathing.NewDefaultStoragePathFormatter(TestClusterId, pipelines.AllocationPipelineName, &res)
+		p, err := pathing.NewDefaultStoragePathFormatter(TestAppName, TestClusterID, TestClusterName, pipelines.AllocationPipelineName, &res)
 		if err != nil {
 			t.Fatalf("failed to create path formatter: %v", err)
 		}

+ 9 - 2
core/pkg/exporter/pathing/bingenpath.go

@@ -7,6 +7,7 @@ import (
 
 	"github.com/opencost/opencost/core/pkg/exporter/pathing/pathutils"
 	"github.com/opencost/opencost/core/pkg/opencost"
+	"github.com/opencost/opencost/core/pkg/pipelines"
 	"github.com/opencost/opencost/core/pkg/util/timeutil"
 )
 
@@ -26,13 +27,19 @@ type BingenStoragePathFormatter struct {
 	resolution string
 }
 
-func NewDefaultStoragePathFormatter(clusterId, pipeline string, resolution *time.Duration) (StoragePathFormatter[opencost.Window], error) {
+func NewDefaultStoragePathFormatter(appName, clusterID, clusterName, pipeline string, resolution *time.Duration) (StoragePathFormatter[opencost.Window], error) {
 	res := "."
 	if resolution != nil {
 		res = timeutil.FormatStoreResolution(*resolution)
 	}
 
-	return NewBingenStoragePathFormatter(DefaultRootDir, clusterId, pipeline, res)
+	// KubeModel uses a distinct pathing pattern which breaks with the original
+	// Allocations and Assets bingen pathing.
+	if pipeline == pipelines.KubeModelPipelineName {
+		return NewKubeModelStoragePathFormatter(appName, clusterID, res)
+	}
+
+	return NewBingenStoragePathFormatter(DefaultRootDir, clusterName, pipeline, res)
 }
 
 // NewBingenStoragePathFormatter creates a StoragePathFormatter for a cluster separated storage path

+ 58 - 44
core/pkg/exporter/pathing/path_test.go

@@ -9,70 +9,84 @@ import (
 	"github.com/stretchr/testify/require"
 )
 
-func TestBingenPathFormatter(t *testing.T) {
+func TestDefaultPathFormatter(t *testing.T) {
 	type testCase struct {
-		name       string
-		clusterID  string
-		pipeline   string
-		resolution *time.Duration
-		prefix     string
-		expected   string
+		name        string
+		appName     string
+		clusterID   string
+		clusterName string
+		pipeline    string
+		resolution  *time.Duration
+		prefix      string
+		expected    string
 	}
 
 	testCases := []testCase{
 		{
-			name:       "no resolution",
-			clusterID:  "cluster-a",
-			pipeline:   "allocation",
-			resolution: nil,
-			prefix:     "",
-			expected:   fmt.Sprintf("%s/cluster-a/%s/allocation/1704110400-1704114000", DefaultRootDir, BaseStorageDir),
+			name:        "no resolution",
+			appName:     "test-app",
+			clusterID:   "clusterID-a",
+			clusterName: "cluster-a",
+			pipeline:    "allocation",
+			resolution:  nil,
+			prefix:      "",
+			expected:    fmt.Sprintf("%s/cluster-a/%s/allocation/1704110400-1704114000", DefaultRootDir, BaseStorageDir),
 		},
 		{
-			name:       "with resolution",
-			clusterID:  "cluster-a",
-			pipeline:   "allocation",
-			resolution: &[]time.Duration{1 * time.Hour}[0],
-			prefix:     "",
-			expected:   fmt.Sprintf("%s/cluster-a/%s/allocation/1h/1704110400-1704114000", DefaultRootDir, BaseStorageDir),
+			name:        "with resolution",
+			appName:     "test-app",
+			clusterID:   "clusterID-a",
+			clusterName: "cluster-a",
+			pipeline:    "allocation",
+			resolution:  &[]time.Duration{1 * time.Hour}[0],
+			prefix:      "",
+			expected:    fmt.Sprintf("%s/cluster-a/%s/allocation/1h/1704110400-1704114000", DefaultRootDir, BaseStorageDir),
 		},
 		{
-			name:       "no resolution with prefix",
-			clusterID:  "cluster-a",
-			pipeline:   "allocation",
-			resolution: nil,
-			prefix:     "test",
-			expected:   fmt.Sprintf("%s/cluster-a/%s/allocation/test.1704110400-1704114000", DefaultRootDir, BaseStorageDir),
+			name:        "no resolution with prefix",
+			appName:     "test-app",
+			clusterID:   "clusterID-a",
+			clusterName: "cluster-a",
+			pipeline:    "allocation",
+			resolution:  nil,
+			prefix:      "test",
+			expected:    fmt.Sprintf("%s/cluster-a/%s/allocation/test.1704110400-1704114000", DefaultRootDir, BaseStorageDir),
 		},
 		{
-			name:       "with resolution with prefix",
-			clusterID:  "cluster-a",
-			pipeline:   "allocation",
-			resolution: &[]time.Duration{1 * time.Hour}[0],
-			prefix:     "test",
-			expected:   fmt.Sprintf("%s/cluster-a/%s/allocation/1h/test.1704110400-1704114000", DefaultRootDir, BaseStorageDir),
+			name:        "with resolution with prefix",
+			appName:     "test-app",
+			clusterID:   "clusterID-a",
+			clusterName: "cluster-a",
+			pipeline:    "allocation",
+			resolution:  &[]time.Duration{1 * time.Hour}[0],
+			prefix:      "test",
+			expected:    fmt.Sprintf("%s/cluster-a/%s/allocation/1h/test.1704110400-1704114000", DefaultRootDir, BaseStorageDir),
 		},
 		{
-			name:       "daily resolution",
-			clusterID:  "cluster-a",
-			pipeline:   "allocation",
-			resolution: &[]time.Duration{24 * time.Hour}[0],
-			prefix:     "",
-			expected:   fmt.Sprintf("%s/cluster-a/%s/allocation/1d/1704110400-1704196800", DefaultRootDir, BaseStorageDir),
+			name:        "daily resolution",
+			appName:     "test-app",
+			clusterID:   "clusterID-a",
+			clusterName: "cluster-a",
+			pipeline:    "allocation",
+			resolution:  &[]time.Duration{24 * time.Hour}[0],
+			prefix:      "",
+			expected:    fmt.Sprintf("%s/cluster-a/%s/allocation/1d/1704110400-1704196800", DefaultRootDir, BaseStorageDir),
 		},
 		{
-			name:       "weekly resolution",
-			clusterID:  "cluster-a",
-			pipeline:   "allocation",
-			resolution: &[]time.Duration{7 * 24 * time.Hour}[0],
-			prefix:     "",
-			expected:   fmt.Sprintf("%s/cluster-a/%s/allocation/1w/1704110400-1704715200", DefaultRootDir, BaseStorageDir),
+			name:        "weekly resolution",
+			appName:     "test-app",
+			clusterID:   "clusterID-a",
+			clusterName: "cluster-a",
+			pipeline:    "allocation",
+			resolution:  &[]time.Duration{7 * 24 * time.Hour}[0],
+			prefix:      "",
+			expected:    fmt.Sprintf("%s/cluster-a/%s/allocation/1w/1704110400-1704715200", DefaultRootDir, BaseStorageDir),
 		},
 	}
 
 	for _, tc := range testCases {
 		t.Run(tc.name, func(t *testing.T) {
-			pathing, err := NewDefaultStoragePathFormatter(tc.clusterID, tc.pipeline, tc.resolution)
+			pathing, err := NewDefaultStoragePathFormatter(tc.appName, tc.clusterID, tc.clusterName, tc.pipeline, tc.resolution)
 			if err != nil {
 				t.Fatalf("Unexpected error: %v", err)
 			}

+ 0 - 53
core/pkg/exporter/pathing/staticpath.go

@@ -1,53 +0,0 @@
-package pathing
-
-import (
-	"fmt"
-	"path"
-)
-
-// StaticFileStoragePathFormatter is an implementation of the StoragePathFormatter interface
-// for static files whose path does not vary with time. The format is:
-//
-//	<rootDir>/<pipeline>/<prefix>.<in>.<fileExt>
-//
-// If prefix is empty the leading dot is omitted. If fileExt is empty the trailing dot is omitted.
-type StaticFileStoragePathFormatter struct {
-	rootDir  string
-	pipeline string
-}
-
-// NewStaticFileStoragePathFormatter creates a StaticFileStoragePathFormatter with the given
-// root directory and pipeline name.
-func NewStaticFileStoragePathFormatter(rootDir, pipeline string) (*StaticFileStoragePathFormatter, error) {
-	if rootDir == "" {
-		return nil, fmt.Errorf("rootDir cannot be empty")
-	}
-	if pipeline == "" {
-		return nil, fmt.Errorf("pipeline cannot be empty")
-	}
-	return &StaticFileStoragePathFormatter{
-		rootDir:  rootDir,
-		pipeline: pipeline,
-	}, nil
-}
-
-// Dir returns the directory where static files are placed.
-func (s *StaticFileStoragePathFormatter) Dir() string {
-	return path.Join(s.rootDir, s.pipeline)
-}
-
-// ToFullPath returns the full path for a static file. The in parameter is used as the
-// file name and may include subdirectory segments. prefix and fileExt are optional and
-// apply only to the base file name component of in.
-func (s *StaticFileStoragePathFormatter) ToFullPath(prefix string, in string, fileExt string) string {
-	dir, base := path.Split(in)
-
-	name := base
-	if prefix != "" {
-		name = fmt.Sprintf("%s.%s", prefix, base)
-	}
-	if fileExt != "" {
-		name = fmt.Sprintf("%s.%s", name, fileExt)
-	}
-	return path.Join(s.rootDir, s.pipeline, dir, name)
-}

+ 0 - 143
core/pkg/exporter/pathing/staticpath_test.go

@@ -1,143 +0,0 @@
-package pathing
-
-import (
-	"testing"
-
-	"github.com/stretchr/testify/require"
-)
-
-func TestNewStaticFileStoragePathFormatter(t *testing.T) {
-	tests := []struct {
-		name     string
-		rootDir  string
-		pipeline string
-		wantErr  bool
-	}{
-		{"empty rootDir returns error", "", "pricingmodel", true},
-		{"empty pipeline returns error", "cloud-agent", "", true},
-		{"valid args returns formatter", "cloud-agent", "pricingmodel", false},
-	}
-
-	for _, tt := range tests {
-		t.Run(tt.name, func(t *testing.T) {
-			f, err := NewStaticFileStoragePathFormatter(tt.rootDir, tt.pipeline)
-			if tt.wantErr {
-				require.Error(t, err)
-				require.Nil(t, f)
-			} else {
-				require.NoError(t, err)
-				require.NotNil(t, f)
-			}
-		})
-	}
-}
-
-func TestStaticFileStoragePathFormatter_Dir(t *testing.T) {
-	tests := []struct {
-		rootDir  string
-		pipeline string
-		expected string
-	}{
-		{"cloud-agent", "pricingmodel", "cloud-agent/pricingmodel"},
-		{"/var/data", "kubemodel", "/var/data/kubemodel"},
-		{"root", "a/b/c", "root/a/b/c"},
-	}
-
-	for _, tt := range tests {
-		t.Run(tt.expected, func(t *testing.T) {
-			f, err := NewStaticFileStoragePathFormatter(tt.rootDir, tt.pipeline)
-			require.NoError(t, err)
-			require.Equal(t, tt.expected, f.Dir())
-		})
-	}
-}
-
-func TestStaticFilePathFormatter(t *testing.T) {
-	type testCase struct {
-		name     string
-		rootDir  string
-		pipeline string
-		prefix   string
-		in       string
-		fileExt  string
-		expected string
-	}
-
-	testCases := []testCase{
-		{
-			name:     "no prefix no ext",
-			rootDir:  "cloud-agent",
-			pipeline: "pricingmodel",
-			prefix:   "",
-			in:       "aws_list_pricing_api",
-			fileExt:  "",
-			expected: "cloud-agent/pricingmodel/aws_list_pricing_api",
-		},
-		{
-			name:     "no prefix with ext",
-			rootDir:  "cloud-agent",
-			pipeline: "pricingmodel",
-			prefix:   "",
-			in:       "aws_list_pricing_api",
-			fileExt:  "bin",
-			expected: "cloud-agent/pricingmodel/aws_list_pricing_api.bin",
-		},
-		{
-			name:     "with prefix with ext",
-			rootDir:  "cloud-agent",
-			pipeline: "pricingmodel",
-			prefix:   "v1",
-			in:       "aws_list_pricing_api",
-			fileExt:  "bin",
-			expected: "cloud-agent/pricingmodel/v1.aws_list_pricing_api.bin",
-		},
-		{
-			name:     "with prefix no ext",
-			rootDir:  "cloud-agent",
-			pipeline: "pricingmodel",
-			prefix:   "v1",
-			in:       "aws_list_pricing_api",
-			fileExt:  "",
-			expected: "cloud-agent/pricingmodel/v1.aws_list_pricing_api",
-		},
-		{
-			name:     "in with subdir no prefix no ext",
-			rootDir:  "cloud-agent",
-			pipeline: "pricingmodel",
-			prefix:   "",
-			in:       "us-east-1/aws_list_pricing_api",
-			fileExt:  "",
-			expected: "cloud-agent/pricingmodel/us-east-1/aws_list_pricing_api",
-		},
-		{
-			name:     "in with subdir with prefix and ext",
-			rootDir:  "cloud-agent",
-			pipeline: "pricingmodel",
-			prefix:   "v1",
-			in:       "us-east-1/aws_list_pricing_api",
-			fileExt:  "bin",
-			expected: "cloud-agent/pricingmodel/us-east-1/v1.aws_list_pricing_api.bin",
-		},
-		{
-			name:     "in with nested subdir with ext",
-			rootDir:  "/var/data",
-			pipeline: "kubemodel",
-			prefix:   "",
-			in:       "2024/01/nodes",
-			fileExt:  "bin",
-			expected: "/var/data/kubemodel/2024/01/nodes.bin",
-		},
-	}
-
-	for _, tc := range testCases {
-		t.Run(tc.name, func(t *testing.T) {
-			pathing, err := NewStaticFileStoragePathFormatter(tc.rootDir, tc.pipeline)
-			if err != nil {
-				t.Fatalf("Unexpected error: %v", err)
-			}
-
-			result := pathing.ToFullPath(tc.prefix, tc.in, tc.fileExt)
-			require.Equal(t, tc.expected, result)
-		})
-	}
-}

+ 0 - 35
core/pkg/model/helper.go

@@ -1,35 +0,0 @@
-package model
-
-import (
-	"fmt"
-	"time"
-
-	"github.com/opencost/opencost/core/pkg/model/pb"
-	"github.com/opencost/opencost/core/pkg/opencost"
-	"github.com/opencost/opencost/core/pkg/util/timeutil"
-)
-
-// ConvertWindow validates and converts a protobuf window to a closed opencost.Window or returns an error
-func ConvertWindow(window *pb.Window) (opencost.Window, error) {
-	if window == nil {
-		return opencost.Window{}, fmt.Errorf("cannot convert nil window")
-	}
-	var res time.Duration
-	switch window.Resolution {
-	case pb.Resolution_RESOLUTION_1D:
-		res = timeutil.Day
-	case pb.Resolution_RESOLUTION_1H:
-		res = time.Hour
-	case pb.Resolution_RESOLUTION_10M:
-		res = time.Minute * 10
-	default:
-		return opencost.Window{}, fmt.Errorf("invalid window resolution %v", window.Resolution)
-	}
-
-	start := window.Start.AsTime().UTC()
-	if !start.Equal(start.Truncate(res)) {
-		return opencost.Window{}, fmt.Errorf("invalid start time for resolution '%s': %s", window.Resolution, start.Format(time.RFC3339))
-	}
-	win := opencost.NewClosedWindow(start, start.Add(res))
-	return win, nil
-}

+ 0 - 88
core/pkg/model/helper_test.go

@@ -1,88 +0,0 @@
-package model
-
-import (
-	"github.com/opencost/opencost/core/pkg/model/pb"
-	"github.com/opencost/opencost/core/pkg/opencost"
-	"github.com/opencost/opencost/core/pkg/util/timeutil"
-	"google.golang.org/protobuf/types/known/timestamppb"
-	"reflect"
-	"testing"
-	"time"
-)
-
-func TestConvertWindow(t *testing.T) {
-	timeDay := time.Date(2025, 9, 1, 0, 0, 0, 0, time.UTC)
-	timeHour := timeDay.Add(time.Hour)
-	timeTenMinute := timeHour.Add(time.Minute * 10)
-	invalidTime := timeTenMinute.Add(time.Second)
-	tests := []struct {
-		name    string
-		window  *pb.Window
-		want    opencost.Window
-		wantErr bool
-	}{
-		{
-			name:    "nil window",
-			window:  nil,
-			want:    opencost.Window{},
-			wantErr: true,
-		},
-		{
-			name: "invalid resolution",
-			window: &pb.Window{
-				Resolution: 999,
-				Start:      timestamppb.New(timeDay),
-			},
-			want:    opencost.Window{},
-			wantErr: true,
-		},
-		{
-			name: "invalid time",
-			window: &pb.Window{
-				Resolution: pb.Resolution_RESOLUTION_1D,
-				Start:      timestamppb.New(invalidTime),
-			},
-			want:    opencost.Window{},
-			wantErr: true,
-		},
-		{
-			name: "valid 1d",
-			window: &pb.Window{
-				Resolution: pb.Resolution_RESOLUTION_1D,
-				Start:      timestamppb.New(timeDay),
-			},
-			want:    opencost.NewClosedWindow(timeDay, timeDay.Add(timeutil.Day)),
-			wantErr: false,
-		},
-		{
-			name: "valid 1h",
-			window: &pb.Window{
-				Resolution: pb.Resolution_RESOLUTION_1H,
-				Start:      timestamppb.New(timeHour),
-			},
-			want:    opencost.NewClosedWindow(timeHour, timeHour.Add(time.Hour)),
-			wantErr: false,
-		},
-		{
-			name: "valid 10m",
-			window: &pb.Window{
-				Resolution: pb.Resolution_RESOLUTION_10M,
-				Start:      timestamppb.New(timeTenMinute),
-			},
-			want:    opencost.NewClosedWindow(timeTenMinute, timeTenMinute.Add(10*time.Minute)),
-			wantErr: false,
-		},
-	}
-	for _, tt := range tests {
-		t.Run(tt.name, func(t *testing.T) {
-			got, err := ConvertWindow(tt.window)
-			if (err != nil) != tt.wantErr {
-				t.Errorf("ConvertWindow() error = %v, wantErr %v", err, tt.wantErr)
-				return
-			}
-			if !reflect.DeepEqual(got, tt.want) {
-				t.Errorf("ConvertWindow() got = %v, want %v", got, tt.want)
-			}
-		})
-	}
-}

+ 0 - 29
core/pkg/model/kubemodel/kubemodel.go

@@ -25,7 +25,6 @@ type KubeModelSet struct {
 	Pods                   map[string]*Pod                   `json:"pods"`              // @bingen:field[version=2]
 	Containers             map[string]*Container             `json:"containers"`        // @bingen:field[version=2]
 	DCGMDevices            map[string]*DCGMDevice            `json:"dcgmDevices"`       // @bingen:field[version=2]
-	idx                    *kubeModelSetIndexes              // @bingen:field[ignore]
 }
 
 func NewKubeModelSet(start time.Time, end time.Time) *KubeModelSet {
@@ -55,26 +54,10 @@ func NewKubeModelSet(start time.Time, end time.Time) *KubeModelSet {
 		ResourceQuotas:         map[string]*ResourceQuota{},
 		Services:               map[string]*Service{},
 		PersistentVolumes:      map[string]*PersistentVolume{},
-		idx:                    newKubeModelSetIndexes(),
 	}
 	return kms
 }
 
-// GetNamespaceByName retrieves a namespace by its name using the index
-func (kms *KubeModelSet) GetNamespaceByName(name string) (*Namespace, bool) {
-	if kms.idx == nil {
-		return nil, false
-	}
-
-	uid, ok := kms.idx.namespaceNameToID[name]
-	if !ok {
-		return nil, false
-	}
-
-	ns, ok := kms.Namespaces[uid]
-	return ns, ok
-}
-
 // IsEmpty returns true if the KubeModelSet is nil, has no cluster, or contains no resources
 func (kms *KubeModelSet) IsEmpty() bool {
 	if kms == nil || kms.Cluster == nil {
@@ -116,15 +99,3 @@ func checkWindow(window Window, start, end time.Time) error {
 	}
 	return nil
 }
-
-type kubeModelSetIndexes struct {
-	namespaceNameToID map[string]string
-	namespaceByName   map[string]*Namespace
-}
-
-func newKubeModelSetIndexes() *kubeModelSetIndexes {
-	return &kubeModelSetIndexes{
-		namespaceNameToID: make(map[string]string),
-		namespaceByName:   make(map[string]*Namespace),
-	}
-}

+ 15 - 0
core/pkg/model/kubemodel/kubemodel_codecs_test.go

@@ -1,6 +1,7 @@
 package kubemodel
 
 import (
+	"bytes"
 	"testing"
 	"time"
 
@@ -36,4 +37,18 @@ func TestKubeModelSetCodecRoundTrip(t *testing.T) {
 
 		KubeModelSetEquals(t, kms, act)
 	})
+
+	t.Run("full KubeModelSet streaming (MarshalBinaryTo/UnmarshalBinaryFromReader)", func(t *testing.T) {
+		kms := NewMockKubeModelSet(start, end)
+
+		var buf bytes.Buffer
+		err := kms.MarshalBinaryTo(&buf)
+		require.NoError(t, err)
+
+		act := new(KubeModelSet)
+		err = act.UnmarshalBinaryFromReader(&buf)
+		require.NoError(t, err)
+
+		KubeModelSetEquals(t, kms, act)
+	})
 }

+ 0 - 4
core/pkg/model/kubemodel/kubemodel_test.go

@@ -183,8 +183,6 @@ func TestKubeModel(t *testing.T) {
 
 			require.NotNil(t, kms.Namespaces[testUID])
 			require.Equal(t, testNamespace, kms.Namespaces[testUID])
-			require.NotNil(t, kms.idx.namespaceByName[testName])
-			require.Equal(t, testNamespace, kms.idx.namespaceByName[testName])
 			require.Equal(t, 1, kms.Metadata.ObjectCount)
 		})
 
@@ -209,7 +207,6 @@ func TestKubeModel(t *testing.T) {
 			testNamespace := &Namespace{UID: testUID, Name: testName, Start: start, End: end}
 
 			require.Equal(t, testNamespace, kms.Namespaces[testUID])
-			require.Equal(t, testNamespace, kms.idx.namespaceByName[testName])
 			require.Equal(t, 1, kms.Metadata.ObjectCount)
 
 			// Register same namespace again, expect no-op on second try
@@ -219,7 +216,6 @@ func TestKubeModel(t *testing.T) {
 			require.Len(t, kms.GetErrors(), 0)
 			require.NotNil(t, kms.Namespaces[testUID])
 			require.Equal(t, testNamespace, kms.Namespaces[testUID])
-			require.Equal(t, testNamespace, kms.idx.namespaceByName[testName])
 			require.Equal(t, 1, kms.Metadata.ObjectCount) // remains 1
 		})
 	})

+ 0 - 3
core/pkg/model/kubemodel/namespace.go

@@ -47,9 +47,6 @@ func (kms *KubeModelSet) RegisterNamespace(namespace *Namespace) error {
 		}
 
 		kms.Namespaces[namespace.UID] = namespace
-
-		kms.idx.namespaceByName[namespace.Name] = namespace
-
 		kms.Metadata.ObjectCount++
 	}
 

+ 0 - 246
core/pkg/model/pb/kubemodel/cluster.pb.go

@@ -1,246 +0,0 @@
-// Code generated by protoc-gen-go. DO NOT EDIT.
-// versions:
-// 	protoc-gen-go v1.36.9
-// 	protoc        v6.32.1
-// source: kubemodel/cluster.proto
-
-package kubemodel
-
-import (
-	pb "github.com/opencost/opencost/core/pkg/model/pb"
-	protoreflect "google.golang.org/protobuf/reflect/protoreflect"
-	protoimpl "google.golang.org/protobuf/runtime/protoimpl"
-	reflect "reflect"
-	sync "sync"
-	unsafe "unsafe"
-)
-
-const (
-	// Verify that this generated code is sufficiently up-to-date.
-	_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
-	// Verify that runtime/protoimpl is sufficiently up-to-date.
-	_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
-)
-
-// Provider represents the cloud provider or infrastructure type
-type Provider int32
-
-const (
-	Provider_PROVIDER_UNSPECIFIED  Provider = 0
-	Provider_PROVIDER_AWS          Provider = 1
-	Provider_PROVIDER_GCP          Provider = 2
-	Provider_PROVIDER_AZURE        Provider = 3
-	Provider_PROVIDER_ON_PREMISES  Provider = 4
-	Provider_PROVIDER_ALIBABA      Provider = 5
-	Provider_PROVIDER_DIGITALOCEAN Provider = 6
-	Provider_PROVIDER_ORACLE       Provider = 7
-)
-
-// Enum value maps for Provider.
-var (
-	Provider_name = map[int32]string{
-		0: "PROVIDER_UNSPECIFIED",
-		1: "PROVIDER_AWS",
-		2: "PROVIDER_GCP",
-		3: "PROVIDER_AZURE",
-		4: "PROVIDER_ON_PREMISES",
-		5: "PROVIDER_ALIBABA",
-		6: "PROVIDER_DIGITALOCEAN",
-		7: "PROVIDER_ORACLE",
-	}
-	Provider_value = map[string]int32{
-		"PROVIDER_UNSPECIFIED":  0,
-		"PROVIDER_AWS":          1,
-		"PROVIDER_GCP":          2,
-		"PROVIDER_AZURE":        3,
-		"PROVIDER_ON_PREMISES":  4,
-		"PROVIDER_ALIBABA":      5,
-		"PROVIDER_DIGITALOCEAN": 6,
-		"PROVIDER_ORACLE":       7,
-	}
-)
-
-func (x Provider) Enum() *Provider {
-	p := new(Provider)
-	*p = x
-	return p
-}
-
-func (x Provider) String() string {
-	return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
-}
-
-func (Provider) Descriptor() protoreflect.EnumDescriptor {
-	return file_kubemodel_cluster_proto_enumTypes[0].Descriptor()
-}
-
-func (Provider) Type() protoreflect.EnumType {
-	return &file_kubemodel_cluster_proto_enumTypes[0]
-}
-
-func (x Provider) Number() protoreflect.EnumNumber {
-	return protoreflect.EnumNumber(x)
-}
-
-// Deprecated: Use Provider.Descriptor instead.
-func (Provider) EnumDescriptor() ([]byte, []int) {
-	return file_kubemodel_cluster_proto_rawDescGZIP(), []int{0}
-}
-
-// Cluster represents the top-level Kubernetes cluster
-type Cluster struct {
-	state protoimpl.MessageState `protogen:"open.v1"`
-	// Identification
-	// User-configured cluster identifier, defaults to kube-system namespace UID
-	// The kube-system namespace UID is unique per cluster and stable across its lifetime
-	ID string `protobuf:"bytes,1,opt,name=ID,proto3" json:"ID,omitempty"`
-	// Properties
-	Provider Provider `protobuf:"varint,2,opt,name=provider,proto3,enum=kubemodel.Provider" json:"provider,omitempty"`
-	Account  string   `protobuf:"bytes,3,opt,name=account,proto3" json:"account,omitempty"`
-	Name     string   `protobuf:"bytes,4,opt,name=name,proto3" json:"name,omitempty"`
-	// Centralized window definition for entire cluster
-	// All resources inherit this window unless they specify their own duration
-	Window        *pb.Window `protobuf:"bytes,5,opt,name=window,proto3" json:"window,omitempty"`
-	unknownFields protoimpl.UnknownFields
-	sizeCache     protoimpl.SizeCache
-}
-
-func (x *Cluster) Reset() {
-	*x = Cluster{}
-	mi := &file_kubemodel_cluster_proto_msgTypes[0]
-	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
-	ms.StoreMessageInfo(mi)
-}
-
-func (x *Cluster) String() string {
-	return protoimpl.X.MessageStringOf(x)
-}
-
-func (*Cluster) ProtoMessage() {}
-
-func (x *Cluster) ProtoReflect() protoreflect.Message {
-	mi := &file_kubemodel_cluster_proto_msgTypes[0]
-	if x != nil {
-		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
-		if ms.LoadMessageInfo() == nil {
-			ms.StoreMessageInfo(mi)
-		}
-		return ms
-	}
-	return mi.MessageOf(x)
-}
-
-// Deprecated: Use Cluster.ProtoReflect.Descriptor instead.
-func (*Cluster) Descriptor() ([]byte, []int) {
-	return file_kubemodel_cluster_proto_rawDescGZIP(), []int{0}
-}
-
-func (x *Cluster) GetID() string {
-	if x != nil {
-		return x.ID
-	}
-	return ""
-}
-
-func (x *Cluster) GetProvider() Provider {
-	if x != nil {
-		return x.Provider
-	}
-	return Provider_PROVIDER_UNSPECIFIED
-}
-
-func (x *Cluster) GetAccount() string {
-	if x != nil {
-		return x.Account
-	}
-	return ""
-}
-
-func (x *Cluster) GetName() string {
-	if x != nil {
-		return x.Name
-	}
-	return ""
-}
-
-func (x *Cluster) GetWindow() *pb.Window {
-	if x != nil {
-		return x.Window
-	}
-	return nil
-}
-
-var File_kubemodel_cluster_proto protoreflect.FileDescriptor
-
-const file_kubemodel_cluster_proto_rawDesc = "" +
-	"\n" +
-	"\x17kubemodel/cluster.proto\x12\tkubemodel\x1a\x12model/window.proto\"\x9f\x01\n" +
-	"\aCluster\x12\x0e\n" +
-	"\x02ID\x18\x01 \x01(\tR\x02ID\x12/\n" +
-	"\bprovider\x18\x02 \x01(\x0e2\x13.kubemodel.ProviderR\bprovider\x12\x18\n" +
-	"\aaccount\x18\x03 \x01(\tR\aaccount\x12\x12\n" +
-	"\x04name\x18\x04 \x01(\tR\x04name\x12%\n" +
-	"\x06window\x18\x05 \x01(\v2\r.model.WindowR\x06window*\xbc\x01\n" +
-	"\bProvider\x12\x18\n" +
-	"\x14PROVIDER_UNSPECIFIED\x10\x00\x12\x10\n" +
-	"\fPROVIDER_AWS\x10\x01\x12\x10\n" +
-	"\fPROVIDER_GCP\x10\x02\x12\x12\n" +
-	"\x0ePROVIDER_AZURE\x10\x03\x12\x18\n" +
-	"\x14PROVIDER_ON_PREMISES\x10\x04\x12\x14\n" +
-	"\x10PROVIDER_ALIBABA\x10\x05\x12\x19\n" +
-	"\x15PROVIDER_DIGITALOCEAN\x10\x06\x12\x13\n" +
-	"\x0fPROVIDER_ORACLE\x10\aB:Z8github.com/opencost/opencost/core/pkg/model/pb/kubemodelb\x06proto3"
-
-var (
-	file_kubemodel_cluster_proto_rawDescOnce sync.Once
-	file_kubemodel_cluster_proto_rawDescData []byte
-)
-
-func file_kubemodel_cluster_proto_rawDescGZIP() []byte {
-	file_kubemodel_cluster_proto_rawDescOnce.Do(func() {
-		file_kubemodel_cluster_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_kubemodel_cluster_proto_rawDesc), len(file_kubemodel_cluster_proto_rawDesc)))
-	})
-	return file_kubemodel_cluster_proto_rawDescData
-}
-
-var file_kubemodel_cluster_proto_enumTypes = make([]protoimpl.EnumInfo, 1)
-var file_kubemodel_cluster_proto_msgTypes = make([]protoimpl.MessageInfo, 1)
-var file_kubemodel_cluster_proto_goTypes = []any{
-	(Provider)(0),     // 0: kubemodel.Provider
-	(*Cluster)(nil),   // 1: kubemodel.Cluster
-	(*pb.Window)(nil), // 2: model.Window
-}
-var file_kubemodel_cluster_proto_depIdxs = []int32{
-	0, // 0: kubemodel.Cluster.provider:type_name -> kubemodel.Provider
-	2, // 1: kubemodel.Cluster.window:type_name -> model.Window
-	2, // [2:2] is the sub-list for method output_type
-	2, // [2:2] is the sub-list for method input_type
-	2, // [2:2] is the sub-list for extension type_name
-	2, // [2:2] is the sub-list for extension extendee
-	0, // [0:2] is the sub-list for field type_name
-}
-
-func init() { file_kubemodel_cluster_proto_init() }
-func file_kubemodel_cluster_proto_init() {
-	if File_kubemodel_cluster_proto != nil {
-		return
-	}
-	type x struct{}
-	out := protoimpl.TypeBuilder{
-		File: protoimpl.DescBuilder{
-			GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
-			RawDescriptor: unsafe.Slice(unsafe.StringData(file_kubemodel_cluster_proto_rawDesc), len(file_kubemodel_cluster_proto_rawDesc)),
-			NumEnums:      1,
-			NumMessages:   1,
-			NumExtensions: 0,
-			NumServices:   0,
-		},
-		GoTypes:           file_kubemodel_cluster_proto_goTypes,
-		DependencyIndexes: file_kubemodel_cluster_proto_depIdxs,
-		EnumInfos:         file_kubemodel_cluster_proto_enumTypes,
-		MessageInfos:      file_kubemodel_cluster_proto_msgTypes,
-	}.Build()
-	File_kubemodel_cluster_proto = out.File
-	file_kubemodel_cluster_proto_goTypes = nil
-	file_kubemodel_cluster_proto_depIdxs = nil
-}

+ 0 - 258
core/pkg/model/pb/kubemodel/container.pb.go

@@ -1,258 +0,0 @@
-// Code generated by protoc-gen-go. DO NOT EDIT.
-// versions:
-// 	protoc-gen-go v1.36.9
-// 	protoc        v6.32.1
-// source: kubemodel/container.proto
-
-package kubemodel
-
-import (
-	protoreflect "google.golang.org/protobuf/reflect/protoreflect"
-	protoimpl "google.golang.org/protobuf/runtime/protoimpl"
-	timestamppb "google.golang.org/protobuf/types/known/timestamppb"
-	reflect "reflect"
-	sync "sync"
-	unsafe "unsafe"
-)
-
-const (
-	// Verify that this generated code is sufficiently up-to-date.
-	_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
-	// Verify that runtime/protoimpl is sufficiently up-to-date.
-	_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
-)
-
-// Container represents a container within a pod (allocated resource)
-type Container struct {
-	state protoimpl.MessageState `protogen:"open.v1"`
-	// Identification
-	PodID string `protobuf:"bytes,1,opt,name=podID,proto3" json:"podID,omitempty"`
-	// Properties
-	Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"`
-	// Resource lifecycle (only when different from cluster window)
-	CreationTime *timestamppb.Timestamp `protobuf:"bytes,3,opt,name=creationTime,proto3,oneof" json:"creationTime,omitempty"`
-	DeletionTime *timestamppb.Timestamp `protobuf:"bytes,4,opt,name=deletionTime,proto3,oneof" json:"deletionTime,omitempty"`
-	// Usage metrics
-	// CPU usage in core-hours
-	CpuCoreHours float32 `protobuf:"fixed32,5,opt,name=cpuCoreHours,proto3" json:"cpuCoreHours,omitempty"`
-	// CPU request average in cores
-	CpuCoreRequestAverage float32 `protobuf:"fixed32,6,opt,name=cpuCoreRequestAverage,proto3" json:"cpuCoreRequestAverage,omitempty"`
-	// CPU usage average in cores
-	CpuCoreUsageAverage float32 `protobuf:"fixed32,7,opt,name=cpuCoreUsageAverage,proto3" json:"cpuCoreUsageAverage,omitempty"`
-	// CPU usage max in cores
-	CpuCoreUsageMax float32 `protobuf:"fixed32,8,opt,name=cpuCoreUsageMax,proto3" json:"cpuCoreUsageMax,omitempty"`
-	// RAM usage in byte-hours
-	RamByteHours int64 `protobuf:"varint,9,opt,name=ramByteHours,proto3" json:"ramByteHours,omitempty"`
-	// RAM request average in bytes
-	RamBytesRequestAverage int64 `protobuf:"varint,10,opt,name=ramBytesRequestAverage,proto3" json:"ramBytesRequestAverage,omitempty"`
-	// RAM usage average in bytes
-	RamBytesUsageAverage int64 `protobuf:"varint,11,opt,name=ramBytesUsageAverage,proto3" json:"ramBytesUsageAverage,omitempty"`
-	// RAM usage max in bytes
-	RamBytesUsageMax int64 `protobuf:"varint,12,opt,name=ramBytesUsageMax,proto3" json:"ramBytesUsageMax,omitempty"`
-	// Diagnostic information about this resource
-	Diagnostic    *DiagnosticResult `protobuf:"bytes,99,opt,name=diagnostic,proto3,oneof" json:"diagnostic,omitempty"`
-	unknownFields protoimpl.UnknownFields
-	sizeCache     protoimpl.SizeCache
-}
-
-func (x *Container) Reset() {
-	*x = Container{}
-	mi := &file_kubemodel_container_proto_msgTypes[0]
-	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
-	ms.StoreMessageInfo(mi)
-}
-
-func (x *Container) String() string {
-	return protoimpl.X.MessageStringOf(x)
-}
-
-func (*Container) ProtoMessage() {}
-
-func (x *Container) ProtoReflect() protoreflect.Message {
-	mi := &file_kubemodel_container_proto_msgTypes[0]
-	if x != nil {
-		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
-		if ms.LoadMessageInfo() == nil {
-			ms.StoreMessageInfo(mi)
-		}
-		return ms
-	}
-	return mi.MessageOf(x)
-}
-
-// Deprecated: Use Container.ProtoReflect.Descriptor instead.
-func (*Container) Descriptor() ([]byte, []int) {
-	return file_kubemodel_container_proto_rawDescGZIP(), []int{0}
-}
-
-func (x *Container) GetPodID() string {
-	if x != nil {
-		return x.PodID
-	}
-	return ""
-}
-
-func (x *Container) GetName() string {
-	if x != nil {
-		return x.Name
-	}
-	return ""
-}
-
-func (x *Container) GetCreationTime() *timestamppb.Timestamp {
-	if x != nil {
-		return x.CreationTime
-	}
-	return nil
-}
-
-func (x *Container) GetDeletionTime() *timestamppb.Timestamp {
-	if x != nil {
-		return x.DeletionTime
-	}
-	return nil
-}
-
-func (x *Container) GetCpuCoreHours() float32 {
-	if x != nil {
-		return x.CpuCoreHours
-	}
-	return 0
-}
-
-func (x *Container) GetCpuCoreRequestAverage() float32 {
-	if x != nil {
-		return x.CpuCoreRequestAverage
-	}
-	return 0
-}
-
-func (x *Container) GetCpuCoreUsageAverage() float32 {
-	if x != nil {
-		return x.CpuCoreUsageAverage
-	}
-	return 0
-}
-
-func (x *Container) GetCpuCoreUsageMax() float32 {
-	if x != nil {
-		return x.CpuCoreUsageMax
-	}
-	return 0
-}
-
-func (x *Container) GetRamByteHours() int64 {
-	if x != nil {
-		return x.RamByteHours
-	}
-	return 0
-}
-
-func (x *Container) GetRamBytesRequestAverage() int64 {
-	if x != nil {
-		return x.RamBytesRequestAverage
-	}
-	return 0
-}
-
-func (x *Container) GetRamBytesUsageAverage() int64 {
-	if x != nil {
-		return x.RamBytesUsageAverage
-	}
-	return 0
-}
-
-func (x *Container) GetRamBytesUsageMax() int64 {
-	if x != nil {
-		return x.RamBytesUsageMax
-	}
-	return 0
-}
-
-func (x *Container) GetDiagnostic() *DiagnosticResult {
-	if x != nil {
-		return x.Diagnostic
-	}
-	return nil
-}
-
-var File_kubemodel_container_proto protoreflect.FileDescriptor
-
-const file_kubemodel_container_proto_rawDesc = "" +
-	"\n" +
-	"\x19kubemodel/container.proto\x12\tkubemodel\x1a\x1akubemodel/diagnostic.proto\x1a\x1fgoogle/protobuf/timestamp.proto\"\xa4\x05\n" +
-	"\tContainer\x12\x14\n" +
-	"\x05podID\x18\x01 \x01(\tR\x05podID\x12\x12\n" +
-	"\x04name\x18\x02 \x01(\tR\x04name\x12C\n" +
-	"\fcreationTime\x18\x03 \x01(\v2\x1a.google.protobuf.TimestampH\x00R\fcreationTime\x88\x01\x01\x12C\n" +
-	"\fdeletionTime\x18\x04 \x01(\v2\x1a.google.protobuf.TimestampH\x01R\fdeletionTime\x88\x01\x01\x12\"\n" +
-	"\fcpuCoreHours\x18\x05 \x01(\x02R\fcpuCoreHours\x124\n" +
-	"\x15cpuCoreRequestAverage\x18\x06 \x01(\x02R\x15cpuCoreRequestAverage\x120\n" +
-	"\x13cpuCoreUsageAverage\x18\a \x01(\x02R\x13cpuCoreUsageAverage\x12(\n" +
-	"\x0fcpuCoreUsageMax\x18\b \x01(\x02R\x0fcpuCoreUsageMax\x12\"\n" +
-	"\framByteHours\x18\t \x01(\x03R\framByteHours\x126\n" +
-	"\x16ramBytesRequestAverage\x18\n" +
-	" \x01(\x03R\x16ramBytesRequestAverage\x122\n" +
-	"\x14ramBytesUsageAverage\x18\v \x01(\x03R\x14ramBytesUsageAverage\x12*\n" +
-	"\x10ramBytesUsageMax\x18\f \x01(\x03R\x10ramBytesUsageMax\x12@\n" +
-	"\n" +
-	"diagnostic\x18c \x01(\v2\x1b.kubemodel.DiagnosticResultH\x02R\n" +
-	"diagnostic\x88\x01\x01B\x0f\n" +
-	"\r_creationTimeB\x0f\n" +
-	"\r_deletionTimeB\r\n" +
-	"\v_diagnosticB:Z8github.com/opencost/opencost/core/pkg/model/pb/kubemodelb\x06proto3"
-
-var (
-	file_kubemodel_container_proto_rawDescOnce sync.Once
-	file_kubemodel_container_proto_rawDescData []byte
-)
-
-func file_kubemodel_container_proto_rawDescGZIP() []byte {
-	file_kubemodel_container_proto_rawDescOnce.Do(func() {
-		file_kubemodel_container_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_kubemodel_container_proto_rawDesc), len(file_kubemodel_container_proto_rawDesc)))
-	})
-	return file_kubemodel_container_proto_rawDescData
-}
-
-var file_kubemodel_container_proto_msgTypes = make([]protoimpl.MessageInfo, 1)
-var file_kubemodel_container_proto_goTypes = []any{
-	(*Container)(nil),             // 0: kubemodel.Container
-	(*timestamppb.Timestamp)(nil), // 1: google.protobuf.Timestamp
-	(*DiagnosticResult)(nil),      // 2: kubemodel.DiagnosticResult
-}
-var file_kubemodel_container_proto_depIdxs = []int32{
-	1, // 0: kubemodel.Container.creationTime:type_name -> google.protobuf.Timestamp
-	1, // 1: kubemodel.Container.deletionTime:type_name -> google.protobuf.Timestamp
-	2, // 2: kubemodel.Container.diagnostic:type_name -> kubemodel.DiagnosticResult
-	3, // [3:3] is the sub-list for method output_type
-	3, // [3:3] is the sub-list for method input_type
-	3, // [3:3] is the sub-list for extension type_name
-	3, // [3:3] is the sub-list for extension extendee
-	0, // [0:3] is the sub-list for field type_name
-}
-
-func init() { file_kubemodel_container_proto_init() }
-func file_kubemodel_container_proto_init() {
-	if File_kubemodel_container_proto != nil {
-		return
-	}
-	file_kubemodel_diagnostic_proto_init()
-	file_kubemodel_container_proto_msgTypes[0].OneofWrappers = []any{}
-	type x struct{}
-	out := protoimpl.TypeBuilder{
-		File: protoimpl.DescBuilder{
-			GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
-			RawDescriptor: unsafe.Slice(unsafe.StringData(file_kubemodel_container_proto_rawDesc), len(file_kubemodel_container_proto_rawDesc)),
-			NumEnums:      0,
-			NumMessages:   1,
-			NumExtensions: 0,
-			NumServices:   0,
-		},
-		GoTypes:           file_kubemodel_container_proto_goTypes,
-		DependencyIndexes: file_kubemodel_container_proto_depIdxs,
-		MessageInfos:      file_kubemodel_container_proto_msgTypes,
-	}.Build()
-	File_kubemodel_container_proto = out.File
-	file_kubemodel_container_proto_goTypes = nil
-	file_kubemodel_container_proto_depIdxs = nil
-}

+ 0 - 298
core/pkg/model/pb/kubemodel/controller.pb.go

@@ -1,298 +0,0 @@
-// Code generated by protoc-gen-go. DO NOT EDIT.
-// versions:
-// 	protoc-gen-go v1.36.9
-// 	protoc        v6.32.1
-// source: kubemodel/controller.proto
-
-package kubemodel
-
-import (
-	protoreflect "google.golang.org/protobuf/reflect/protoreflect"
-	protoimpl "google.golang.org/protobuf/runtime/protoimpl"
-	timestamppb "google.golang.org/protobuf/types/known/timestamppb"
-	reflect "reflect"
-	sync "sync"
-	unsafe "unsafe"
-)
-
-const (
-	// Verify that this generated code is sufficiently up-to-date.
-	_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
-	// Verify that runtime/protoimpl is sufficiently up-to-date.
-	_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
-)
-
-type ControllerKind int32
-
-const (
-	ControllerKind_KIND_UNSPECIFIED ControllerKind = 0
-	ControllerKind_DEPLOYMENT       ControllerKind = 1
-	ControllerKind_STATEFULSET      ControllerKind = 2
-	ControllerKind_DAEMONSET        ControllerKind = 3
-	ControllerKind_JOB              ControllerKind = 4
-	ControllerKind_CRONJOB          ControllerKind = 5
-	ControllerKind_REPLICASET       ControllerKind = 6
-)
-
-// Enum value maps for ControllerKind.
-var (
-	ControllerKind_name = map[int32]string{
-		0: "KIND_UNSPECIFIED",
-		1: "DEPLOYMENT",
-		2: "STATEFULSET",
-		3: "DAEMONSET",
-		4: "JOB",
-		5: "CRONJOB",
-		6: "REPLICASET",
-	}
-	ControllerKind_value = map[string]int32{
-		"KIND_UNSPECIFIED": 0,
-		"DEPLOYMENT":       1,
-		"STATEFULSET":      2,
-		"DAEMONSET":        3,
-		"JOB":              4,
-		"CRONJOB":          5,
-		"REPLICASET":       6,
-	}
-)
-
-func (x ControllerKind) Enum() *ControllerKind {
-	p := new(ControllerKind)
-	*p = x
-	return p
-}
-
-func (x ControllerKind) String() string {
-	return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
-}
-
-func (ControllerKind) Descriptor() protoreflect.EnumDescriptor {
-	return file_kubemodel_controller_proto_enumTypes[0].Descriptor()
-}
-
-func (ControllerKind) Type() protoreflect.EnumType {
-	return &file_kubemodel_controller_proto_enumTypes[0]
-}
-
-func (x ControllerKind) Number() protoreflect.EnumNumber {
-	return protoreflect.EnumNumber(x)
-}
-
-// Deprecated: Use ControllerKind.Descriptor instead.
-func (ControllerKind) EnumDescriptor() ([]byte, []int) {
-	return file_kubemodel_controller_proto_rawDescGZIP(), []int{0}
-}
-
-// Controller represents a Kubernetes workload controller
-type Controller struct {
-	state protoimpl.MessageState `protogen:"open.v1"`
-	// Identification
-	ID          string `protobuf:"bytes,1,opt,name=ID,proto3" json:"ID,omitempty"`
-	NamespaceID string `protobuf:"bytes,2,opt,name=namespaceID,proto3" json:"namespaceID,omitempty"`
-	// Properties
-	Name        string            `protobuf:"bytes,3,opt,name=name,proto3" json:"name,omitempty"`
-	Kind        ControllerKind    `protobuf:"varint,4,opt,name=kind,proto3,enum=kubemodel.ControllerKind" json:"kind,omitempty"`
-	Labels      map[string]string `protobuf:"bytes,5,rep,name=labels,proto3" json:"labels,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"`
-	Annotations map[string]string `protobuf:"bytes,6,rep,name=annotations,proto3" json:"annotations,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"`
-	// Resource lifecycle (only when different from cluster window)
-	CreationTime *timestamppb.Timestamp `protobuf:"bytes,7,opt,name=creationTime,proto3,oneof" json:"creationTime,omitempty"`
-	DeletionTime *timestamppb.Timestamp `protobuf:"bytes,8,opt,name=deletionTime,proto3,oneof" json:"deletionTime,omitempty"`
-	// Diagnostic information about this resource
-	Diagnostic    *DiagnosticResult `protobuf:"bytes,99,opt,name=diagnostic,proto3,oneof" json:"diagnostic,omitempty"`
-	unknownFields protoimpl.UnknownFields
-	sizeCache     protoimpl.SizeCache
-}
-
-func (x *Controller) Reset() {
-	*x = Controller{}
-	mi := &file_kubemodel_controller_proto_msgTypes[0]
-	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
-	ms.StoreMessageInfo(mi)
-}
-
-func (x *Controller) String() string {
-	return protoimpl.X.MessageStringOf(x)
-}
-
-func (*Controller) ProtoMessage() {}
-
-func (x *Controller) ProtoReflect() protoreflect.Message {
-	mi := &file_kubemodel_controller_proto_msgTypes[0]
-	if x != nil {
-		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
-		if ms.LoadMessageInfo() == nil {
-			ms.StoreMessageInfo(mi)
-		}
-		return ms
-	}
-	return mi.MessageOf(x)
-}
-
-// Deprecated: Use Controller.ProtoReflect.Descriptor instead.
-func (*Controller) Descriptor() ([]byte, []int) {
-	return file_kubemodel_controller_proto_rawDescGZIP(), []int{0}
-}
-
-func (x *Controller) GetID() string {
-	if x != nil {
-		return x.ID
-	}
-	return ""
-}
-
-func (x *Controller) GetNamespaceID() string {
-	if x != nil {
-		return x.NamespaceID
-	}
-	return ""
-}
-
-func (x *Controller) GetName() string {
-	if x != nil {
-		return x.Name
-	}
-	return ""
-}
-
-func (x *Controller) GetKind() ControllerKind {
-	if x != nil {
-		return x.Kind
-	}
-	return ControllerKind_KIND_UNSPECIFIED
-}
-
-func (x *Controller) GetLabels() map[string]string {
-	if x != nil {
-		return x.Labels
-	}
-	return nil
-}
-
-func (x *Controller) GetAnnotations() map[string]string {
-	if x != nil {
-		return x.Annotations
-	}
-	return nil
-}
-
-func (x *Controller) GetCreationTime() *timestamppb.Timestamp {
-	if x != nil {
-		return x.CreationTime
-	}
-	return nil
-}
-
-func (x *Controller) GetDeletionTime() *timestamppb.Timestamp {
-	if x != nil {
-		return x.DeletionTime
-	}
-	return nil
-}
-
-func (x *Controller) GetDiagnostic() *DiagnosticResult {
-	if x != nil {
-		return x.Diagnostic
-	}
-	return nil
-}
-
-var File_kubemodel_controller_proto protoreflect.FileDescriptor
-
-const file_kubemodel_controller_proto_rawDesc = "" +
-	"\n" +
-	"\x1akubemodel/controller.proto\x12\tkubemodel\x1a\x1akubemodel/diagnostic.proto\x1a\x1fgoogle/protobuf/timestamp.proto\"\xfe\x04\n" +
-	"\n" +
-	"Controller\x12\x0e\n" +
-	"\x02ID\x18\x01 \x01(\tR\x02ID\x12 \n" +
-	"\vnamespaceID\x18\x02 \x01(\tR\vnamespaceID\x12\x12\n" +
-	"\x04name\x18\x03 \x01(\tR\x04name\x12-\n" +
-	"\x04kind\x18\x04 \x01(\x0e2\x19.kubemodel.ControllerKindR\x04kind\x129\n" +
-	"\x06labels\x18\x05 \x03(\v2!.kubemodel.Controller.LabelsEntryR\x06labels\x12H\n" +
-	"\vannotations\x18\x06 \x03(\v2&.kubemodel.Controller.AnnotationsEntryR\vannotations\x12C\n" +
-	"\fcreationTime\x18\a \x01(\v2\x1a.google.protobuf.TimestampH\x00R\fcreationTime\x88\x01\x01\x12C\n" +
-	"\fdeletionTime\x18\b \x01(\v2\x1a.google.protobuf.TimestampH\x01R\fdeletionTime\x88\x01\x01\x12@\n" +
-	"\n" +
-	"diagnostic\x18c \x01(\v2\x1b.kubemodel.DiagnosticResultH\x02R\n" +
-	"diagnostic\x88\x01\x01\x1a9\n" +
-	"\vLabelsEntry\x12\x10\n" +
-	"\x03key\x18\x01 \x01(\tR\x03key\x12\x14\n" +
-	"\x05value\x18\x02 \x01(\tR\x05value:\x028\x01\x1a>\n" +
-	"\x10AnnotationsEntry\x12\x10\n" +
-	"\x03key\x18\x01 \x01(\tR\x03key\x12\x14\n" +
-	"\x05value\x18\x02 \x01(\tR\x05value:\x028\x01B\x0f\n" +
-	"\r_creationTimeB\x0f\n" +
-	"\r_deletionTimeB\r\n" +
-	"\v_diagnostic*|\n" +
-	"\x0eControllerKind\x12\x14\n" +
-	"\x10KIND_UNSPECIFIED\x10\x00\x12\x0e\n" +
-	"\n" +
-	"DEPLOYMENT\x10\x01\x12\x0f\n" +
-	"\vSTATEFULSET\x10\x02\x12\r\n" +
-	"\tDAEMONSET\x10\x03\x12\a\n" +
-	"\x03JOB\x10\x04\x12\v\n" +
-	"\aCRONJOB\x10\x05\x12\x0e\n" +
-	"\n" +
-	"REPLICASET\x10\x06B:Z8github.com/opencost/opencost/core/pkg/model/pb/kubemodelb\x06proto3"
-
-var (
-	file_kubemodel_controller_proto_rawDescOnce sync.Once
-	file_kubemodel_controller_proto_rawDescData []byte
-)
-
-func file_kubemodel_controller_proto_rawDescGZIP() []byte {
-	file_kubemodel_controller_proto_rawDescOnce.Do(func() {
-		file_kubemodel_controller_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_kubemodel_controller_proto_rawDesc), len(file_kubemodel_controller_proto_rawDesc)))
-	})
-	return file_kubemodel_controller_proto_rawDescData
-}
-
-var file_kubemodel_controller_proto_enumTypes = make([]protoimpl.EnumInfo, 1)
-var file_kubemodel_controller_proto_msgTypes = make([]protoimpl.MessageInfo, 3)
-var file_kubemodel_controller_proto_goTypes = []any{
-	(ControllerKind)(0),           // 0: kubemodel.ControllerKind
-	(*Controller)(nil),            // 1: kubemodel.Controller
-	nil,                           // 2: kubemodel.Controller.LabelsEntry
-	nil,                           // 3: kubemodel.Controller.AnnotationsEntry
-	(*timestamppb.Timestamp)(nil), // 4: google.protobuf.Timestamp
-	(*DiagnosticResult)(nil),      // 5: kubemodel.DiagnosticResult
-}
-var file_kubemodel_controller_proto_depIdxs = []int32{
-	0, // 0: kubemodel.Controller.kind:type_name -> kubemodel.ControllerKind
-	2, // 1: kubemodel.Controller.labels:type_name -> kubemodel.Controller.LabelsEntry
-	3, // 2: kubemodel.Controller.annotations:type_name -> kubemodel.Controller.AnnotationsEntry
-	4, // 3: kubemodel.Controller.creationTime:type_name -> google.protobuf.Timestamp
-	4, // 4: kubemodel.Controller.deletionTime:type_name -> google.protobuf.Timestamp
-	5, // 5: kubemodel.Controller.diagnostic:type_name -> kubemodel.DiagnosticResult
-	6, // [6:6] is the sub-list for method output_type
-	6, // [6:6] is the sub-list for method input_type
-	6, // [6:6] is the sub-list for extension type_name
-	6, // [6:6] is the sub-list for extension extendee
-	0, // [0:6] is the sub-list for field type_name
-}
-
-func init() { file_kubemodel_controller_proto_init() }
-func file_kubemodel_controller_proto_init() {
-	if File_kubemodel_controller_proto != nil {
-		return
-	}
-	file_kubemodel_diagnostic_proto_init()
-	file_kubemodel_controller_proto_msgTypes[0].OneofWrappers = []any{}
-	type x struct{}
-	out := protoimpl.TypeBuilder{
-		File: protoimpl.DescBuilder{
-			GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
-			RawDescriptor: unsafe.Slice(unsafe.StringData(file_kubemodel_controller_proto_rawDesc), len(file_kubemodel_controller_proto_rawDesc)),
-			NumEnums:      1,
-			NumMessages:   3,
-			NumExtensions: 0,
-			NumServices:   0,
-		},
-		GoTypes:           file_kubemodel_controller_proto_goTypes,
-		DependencyIndexes: file_kubemodel_controller_proto_depIdxs,
-		EnumInfos:         file_kubemodel_controller_proto_enumTypes,
-		MessageInfos:      file_kubemodel_controller_proto_msgTypes,
-	}.Build()
-	File_kubemodel_controller_proto = out.File
-	file_kubemodel_controller_proto_goTypes = nil
-	file_kubemodel_controller_proto_depIdxs = nil
-}

+ 0 - 266
core/pkg/model/pb/kubemodel/diagnostic.pb.go

@@ -1,266 +0,0 @@
-// Code generated by protoc-gen-go. DO NOT EDIT.
-// versions:
-// 	protoc-gen-go v1.36.9
-// 	protoc        v6.32.1
-// source: kubemodel/diagnostic.proto
-
-package kubemodel
-
-import (
-	protoreflect "google.golang.org/protobuf/reflect/protoreflect"
-	protoimpl "google.golang.org/protobuf/runtime/protoimpl"
-	timestamppb "google.golang.org/protobuf/types/known/timestamppb"
-	reflect "reflect"
-	sync "sync"
-	unsafe "unsafe"
-)
-
-const (
-	// Verify that this generated code is sufficiently up-to-date.
-	_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
-	// Verify that runtime/protoimpl is sufficiently up-to-date.
-	_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
-)
-
-// DiagnosticResult represents the result of a diagnostic run
-// This matches the JSON structure from core/pkg/diagnostics/diagnostics.go
-type DiagnosticResult struct {
-	state protoimpl.MessageState `protogen:"open.v1"`
-	// Unique Identifier for the diagnostic run result
-	Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
-	// Name of the diagnostic that ran
-	Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"`
-	// Description of the diagnostic run, human readable description
-	Description string `protobuf:"bytes,3,opt,name=description,proto3" json:"description,omitempty"`
-	// Category of the diagnostic run, used to group similar diagnostics
-	Category string `protobuf:"bytes,4,opt,name=category,proto3" json:"category,omitempty"`
-	// Timestamp when the diagnostic run was executed
-	Timestamp *timestamppb.Timestamp `protobuf:"bytes,5,opt,name=timestamp,proto3" json:"timestamp,omitempty"`
-	// Error message if the diagnostic run failed (optional)
-	Error string `protobuf:"bytes,6,opt,name=error,proto3" json:"error,omitempty"`
-	// Additional custom information about the diagnostic run
-	// Using string values to match map[string]any from JSON
-	Details       map[string]string `protobuf:"bytes,7,rep,name=details,proto3" json:"details,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"`
-	unknownFields protoimpl.UnknownFields
-	sizeCache     protoimpl.SizeCache
-}
-
-func (x *DiagnosticResult) Reset() {
-	*x = DiagnosticResult{}
-	mi := &file_kubemodel_diagnostic_proto_msgTypes[0]
-	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
-	ms.StoreMessageInfo(mi)
-}
-
-func (x *DiagnosticResult) String() string {
-	return protoimpl.X.MessageStringOf(x)
-}
-
-func (*DiagnosticResult) ProtoMessage() {}
-
-func (x *DiagnosticResult) ProtoReflect() protoreflect.Message {
-	mi := &file_kubemodel_diagnostic_proto_msgTypes[0]
-	if x != nil {
-		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
-		if ms.LoadMessageInfo() == nil {
-			ms.StoreMessageInfo(mi)
-		}
-		return ms
-	}
-	return mi.MessageOf(x)
-}
-
-// Deprecated: Use DiagnosticResult.ProtoReflect.Descriptor instead.
-func (*DiagnosticResult) Descriptor() ([]byte, []int) {
-	return file_kubemodel_diagnostic_proto_rawDescGZIP(), []int{0}
-}
-
-func (x *DiagnosticResult) GetId() string {
-	if x != nil {
-		return x.Id
-	}
-	return ""
-}
-
-func (x *DiagnosticResult) GetName() string {
-	if x != nil {
-		return x.Name
-	}
-	return ""
-}
-
-func (x *DiagnosticResult) GetDescription() string {
-	if x != nil {
-		return x.Description
-	}
-	return ""
-}
-
-func (x *DiagnosticResult) GetCategory() string {
-	if x != nil {
-		return x.Category
-	}
-	return ""
-}
-
-func (x *DiagnosticResult) GetTimestamp() *timestamppb.Timestamp {
-	if x != nil {
-		return x.Timestamp
-	}
-	return nil
-}
-
-func (x *DiagnosticResult) GetError() string {
-	if x != nil {
-		return x.Error
-	}
-	return ""
-}
-
-func (x *DiagnosticResult) GetDetails() map[string]string {
-	if x != nil {
-		return x.Details
-	}
-	return nil
-}
-
-// DiagnosticsRunReport contains the start time and all diagnostic results
-// This matches the JSON structure from core/pkg/diagnostics/diagnostics.go
-type DiagnosticsRunReport struct {
-	state protoimpl.MessageState `protogen:"open.v1"`
-	// Application name that the diagnostics run belongs to
-	Application string `protobuf:"bytes,1,opt,name=application,proto3" json:"application,omitempty"`
-	// Time when the full diagnostics run started
-	StartTime *timestamppb.Timestamp `protobuf:"bytes,2,opt,name=startTime,proto3" json:"startTime,omitempty"`
-	// All results of the diagnostics run
-	Results       []*DiagnosticResult `protobuf:"bytes,3,rep,name=results,proto3" json:"results,omitempty"`
-	unknownFields protoimpl.UnknownFields
-	sizeCache     protoimpl.SizeCache
-}
-
-func (x *DiagnosticsRunReport) Reset() {
-	*x = DiagnosticsRunReport{}
-	mi := &file_kubemodel_diagnostic_proto_msgTypes[1]
-	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
-	ms.StoreMessageInfo(mi)
-}
-
-func (x *DiagnosticsRunReport) String() string {
-	return protoimpl.X.MessageStringOf(x)
-}
-
-func (*DiagnosticsRunReport) ProtoMessage() {}
-
-func (x *DiagnosticsRunReport) ProtoReflect() protoreflect.Message {
-	mi := &file_kubemodel_diagnostic_proto_msgTypes[1]
-	if x != nil {
-		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
-		if ms.LoadMessageInfo() == nil {
-			ms.StoreMessageInfo(mi)
-		}
-		return ms
-	}
-	return mi.MessageOf(x)
-}
-
-// Deprecated: Use DiagnosticsRunReport.ProtoReflect.Descriptor instead.
-func (*DiagnosticsRunReport) Descriptor() ([]byte, []int) {
-	return file_kubemodel_diagnostic_proto_rawDescGZIP(), []int{1}
-}
-
-func (x *DiagnosticsRunReport) GetApplication() string {
-	if x != nil {
-		return x.Application
-	}
-	return ""
-}
-
-func (x *DiagnosticsRunReport) GetStartTime() *timestamppb.Timestamp {
-	if x != nil {
-		return x.StartTime
-	}
-	return nil
-}
-
-func (x *DiagnosticsRunReport) GetResults() []*DiagnosticResult {
-	if x != nil {
-		return x.Results
-	}
-	return nil
-}
-
-var File_kubemodel_diagnostic_proto protoreflect.FileDescriptor
-
-const file_kubemodel_diagnostic_proto_rawDesc = "" +
-	"\n" +
-	"\x1akubemodel/diagnostic.proto\x12\tkubemodel\x1a\x1fgoogle/protobuf/timestamp.proto\"\xc4\x02\n" +
-	"\x10DiagnosticResult\x12\x0e\n" +
-	"\x02id\x18\x01 \x01(\tR\x02id\x12\x12\n" +
-	"\x04name\x18\x02 \x01(\tR\x04name\x12 \n" +
-	"\vdescription\x18\x03 \x01(\tR\vdescription\x12\x1a\n" +
-	"\bcategory\x18\x04 \x01(\tR\bcategory\x128\n" +
-	"\ttimestamp\x18\x05 \x01(\v2\x1a.google.protobuf.TimestampR\ttimestamp\x12\x14\n" +
-	"\x05error\x18\x06 \x01(\tR\x05error\x12B\n" +
-	"\adetails\x18\a \x03(\v2(.kubemodel.DiagnosticResult.DetailsEntryR\adetails\x1a:\n" +
-	"\fDetailsEntry\x12\x10\n" +
-	"\x03key\x18\x01 \x01(\tR\x03key\x12\x14\n" +
-	"\x05value\x18\x02 \x01(\tR\x05value:\x028\x01\"\xa9\x01\n" +
-	"\x14DiagnosticsRunReport\x12 \n" +
-	"\vapplication\x18\x01 \x01(\tR\vapplication\x128\n" +
-	"\tstartTime\x18\x02 \x01(\v2\x1a.google.protobuf.TimestampR\tstartTime\x125\n" +
-	"\aresults\x18\x03 \x03(\v2\x1b.kubemodel.DiagnosticResultR\aresultsB:Z8github.com/opencost/opencost/core/pkg/model/pb/kubemodelb\x06proto3"
-
-var (
-	file_kubemodel_diagnostic_proto_rawDescOnce sync.Once
-	file_kubemodel_diagnostic_proto_rawDescData []byte
-)
-
-func file_kubemodel_diagnostic_proto_rawDescGZIP() []byte {
-	file_kubemodel_diagnostic_proto_rawDescOnce.Do(func() {
-		file_kubemodel_diagnostic_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_kubemodel_diagnostic_proto_rawDesc), len(file_kubemodel_diagnostic_proto_rawDesc)))
-	})
-	return file_kubemodel_diagnostic_proto_rawDescData
-}
-
-var file_kubemodel_diagnostic_proto_msgTypes = make([]protoimpl.MessageInfo, 3)
-var file_kubemodel_diagnostic_proto_goTypes = []any{
-	(*DiagnosticResult)(nil),      // 0: kubemodel.DiagnosticResult
-	(*DiagnosticsRunReport)(nil),  // 1: kubemodel.DiagnosticsRunReport
-	nil,                           // 2: kubemodel.DiagnosticResult.DetailsEntry
-	(*timestamppb.Timestamp)(nil), // 3: google.protobuf.Timestamp
-}
-var file_kubemodel_diagnostic_proto_depIdxs = []int32{
-	3, // 0: kubemodel.DiagnosticResult.timestamp:type_name -> google.protobuf.Timestamp
-	2, // 1: kubemodel.DiagnosticResult.details:type_name -> kubemodel.DiagnosticResult.DetailsEntry
-	3, // 2: kubemodel.DiagnosticsRunReport.startTime:type_name -> google.protobuf.Timestamp
-	0, // 3: kubemodel.DiagnosticsRunReport.results:type_name -> kubemodel.DiagnosticResult
-	4, // [4:4] is the sub-list for method output_type
-	4, // [4:4] is the sub-list for method input_type
-	4, // [4:4] is the sub-list for extension type_name
-	4, // [4:4] is the sub-list for extension extendee
-	0, // [0:4] is the sub-list for field type_name
-}
-
-func init() { file_kubemodel_diagnostic_proto_init() }
-func file_kubemodel_diagnostic_proto_init() {
-	if File_kubemodel_diagnostic_proto != nil {
-		return
-	}
-	type x struct{}
-	out := protoimpl.TypeBuilder{
-		File: protoimpl.DescBuilder{
-			GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
-			RawDescriptor: unsafe.Slice(unsafe.StringData(file_kubemodel_diagnostic_proto_rawDesc), len(file_kubemodel_diagnostic_proto_rawDesc)),
-			NumEnums:      0,
-			NumMessages:   3,
-			NumExtensions: 0,
-			NumServices:   0,
-		},
-		GoTypes:           file_kubemodel_diagnostic_proto_goTypes,
-		DependencyIndexes: file_kubemodel_diagnostic_proto_depIdxs,
-		MessageInfos:      file_kubemodel_diagnostic_proto_msgTypes,
-	}.Build()
-	File_kubemodel_diagnostic_proto = out.File
-	file_kubemodel_diagnostic_proto_goTypes = nil
-	file_kubemodel_diagnostic_proto_depIdxs = nil
-}

+ 0 - 366
core/pkg/model/pb/kubemodel/gpu.pb.go

@@ -1,366 +0,0 @@
-// Code generated by protoc-gen-go. DO NOT EDIT.
-// versions:
-// 	protoc-gen-go v1.36.9
-// 	protoc        v6.32.1
-// source: kubemodel/gpu.proto
-
-package kubemodel
-
-import (
-	protoreflect "google.golang.org/protobuf/reflect/protoreflect"
-	protoimpl "google.golang.org/protobuf/runtime/protoimpl"
-	reflect "reflect"
-	sync "sync"
-	unsafe "unsafe"
-)
-
-const (
-	// Verify that this generated code is sufficiently up-to-date.
-	_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
-	// Verify that runtime/protoimpl is sufficiently up-to-date.
-	_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
-)
-
-// GPUDevice represents a GPU device with DCGM integration (provisioned resource)
-// This tracks available GPU capacity on a node
-type GPUDevice struct {
-	state protoimpl.MessageState `protogen:"open.v1"`
-	// Identification
-	ID     string `protobuf:"bytes,1,opt,name=ID,proto3" json:"ID,omitempty"`         // GPU UUID (hardware identifier)
-	NodeID string `protobuf:"bytes,2,opt,name=nodeID,proto3" json:"nodeID,omitempty"` // Node hosting this GPU device
-	// Properties
-	DeviceNumber int32  `protobuf:"varint,3,opt,name=deviceNumber,proto3" json:"deviceNumber,omitempty"`
-	ModelName    string `protobuf:"bytes,4,opt,name=modelName,proto3" json:"modelName,omitempty"`
-	// GPU sharing information
-	IsShared        bool    `protobuf:"varint,6,opt,name=isShared,proto3" json:"isShared,omitempty"`
-	SharePercentage float32 `protobuf:"fixed32,9,opt,name=sharePercentage,proto3" json:"sharePercentage,omitempty"`
-	// Capacity metrics
-	// GPU hours available
-	GpuHours float32 `protobuf:"fixed32,10,opt,name=gpuHours,proto3" json:"gpuHours,omitempty"`
-	// GPU request average percentage (0-100)
-	GpuRequestAverage float32 `protobuf:"fixed32,11,opt,name=gpuRequestAverage,proto3" json:"gpuRequestAverage,omitempty"`
-	// GPU usage average percentage (0-100)
-	GpuUsageAverage float32 `protobuf:"fixed32,12,opt,name=gpuUsageAverage,proto3" json:"gpuUsageAverage,omitempty"`
-	// GPU usage max percentage (0-100)
-	GpuUsageMax float32 `protobuf:"fixed32,13,opt,name=gpuUsageMax,proto3" json:"gpuUsageMax,omitempty"`
-	// GPU memory capacity in bytes
-	MemoryBytes int64 `protobuf:"varint,14,opt,name=memoryBytes,proto3" json:"memoryBytes,omitempty"`
-	// Diagnostic information about this resource
-	Diagnostic    *DiagnosticResult `protobuf:"bytes,99,opt,name=diagnostic,proto3,oneof" json:"diagnostic,omitempty"`
-	unknownFields protoimpl.UnknownFields
-	sizeCache     protoimpl.SizeCache
-}
-
-func (x *GPUDevice) Reset() {
-	*x = GPUDevice{}
-	mi := &file_kubemodel_gpu_proto_msgTypes[0]
-	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
-	ms.StoreMessageInfo(mi)
-}
-
-func (x *GPUDevice) String() string {
-	return protoimpl.X.MessageStringOf(x)
-}
-
-func (*GPUDevice) ProtoMessage() {}
-
-func (x *GPUDevice) ProtoReflect() protoreflect.Message {
-	mi := &file_kubemodel_gpu_proto_msgTypes[0]
-	if x != nil {
-		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
-		if ms.LoadMessageInfo() == nil {
-			ms.StoreMessageInfo(mi)
-		}
-		return ms
-	}
-	return mi.MessageOf(x)
-}
-
-// Deprecated: Use GPUDevice.ProtoReflect.Descriptor instead.
-func (*GPUDevice) Descriptor() ([]byte, []int) {
-	return file_kubemodel_gpu_proto_rawDescGZIP(), []int{0}
-}
-
-func (x *GPUDevice) GetID() string {
-	if x != nil {
-		return x.ID
-	}
-	return ""
-}
-
-func (x *GPUDevice) GetNodeID() string {
-	if x != nil {
-		return x.NodeID
-	}
-	return ""
-}
-
-func (x *GPUDevice) GetDeviceNumber() int32 {
-	if x != nil {
-		return x.DeviceNumber
-	}
-	return 0
-}
-
-func (x *GPUDevice) GetModelName() string {
-	if x != nil {
-		return x.ModelName
-	}
-	return ""
-}
-
-func (x *GPUDevice) GetIsShared() bool {
-	if x != nil {
-		return x.IsShared
-	}
-	return false
-}
-
-func (x *GPUDevice) GetSharePercentage() float32 {
-	if x != nil {
-		return x.SharePercentage
-	}
-	return 0
-}
-
-func (x *GPUDevice) GetGpuHours() float32 {
-	if x != nil {
-		return x.GpuHours
-	}
-	return 0
-}
-
-func (x *GPUDevice) GetGpuRequestAverage() float32 {
-	if x != nil {
-		return x.GpuRequestAverage
-	}
-	return 0
-}
-
-func (x *GPUDevice) GetGpuUsageAverage() float32 {
-	if x != nil {
-		return x.GpuUsageAverage
-	}
-	return 0
-}
-
-func (x *GPUDevice) GetGpuUsageMax() float32 {
-	if x != nil {
-		return x.GpuUsageMax
-	}
-	return 0
-}
-
-func (x *GPUDevice) GetMemoryBytes() int64 {
-	if x != nil {
-		return x.MemoryBytes
-	}
-	return 0
-}
-
-func (x *GPUDevice) GetDiagnostic() *DiagnosticResult {
-	if x != nil {
-		return x.Diagnostic
-	}
-	return nil
-}
-
-// GPUUsage represents GPU resources consumed by a container (allocated resource)
-// This tracks actual GPU usage by containers for cost analysis
-type GPUUsage struct {
-	state protoimpl.MessageState `protogen:"open.v1"`
-	// Identification
-	ContainerID string `protobuf:"bytes,1,opt,name=containerID,proto3" json:"containerID,omitempty"` // Container consuming GPU resources
-	GpuDeviceID string `protobuf:"bytes,2,opt,name=gpuDeviceID,proto3" json:"gpuDeviceID,omitempty"` // Reference to the GPU device being used
-	// Usage metrics
-	// GPU usage in device-hours consumed
-	GpuHours float32 `protobuf:"fixed32,3,opt,name=gpuHours,proto3" json:"gpuHours,omitempty"`
-	// GPU request in percentage (0-100)
-	GpuRequestPercentage float32 `protobuf:"fixed32,4,opt,name=gpuRequestPercentage,proto3" json:"gpuRequestPercentage,omitempty"`
-	// GPU usage average percentage (0-100)
-	GpuUsageAverage float32 `protobuf:"fixed32,5,opt,name=gpuUsageAverage,proto3" json:"gpuUsageAverage,omitempty"`
-	// GPU usage max percentage (0-100)
-	GpuUsageMax float32 `protobuf:"fixed32,6,opt,name=gpuUsageMax,proto3" json:"gpuUsageMax,omitempty"`
-	// GPU memory usage in bytes
-	MemoryBytesUsed int64 `protobuf:"varint,7,opt,name=memoryBytesUsed,proto3" json:"memoryBytesUsed,omitempty"`
-	// Diagnostic information about this resource
-	Diagnostic    *DiagnosticResult `protobuf:"bytes,99,opt,name=diagnostic,proto3,oneof" json:"diagnostic,omitempty"`
-	unknownFields protoimpl.UnknownFields
-	sizeCache     protoimpl.SizeCache
-}
-
-func (x *GPUUsage) Reset() {
-	*x = GPUUsage{}
-	mi := &file_kubemodel_gpu_proto_msgTypes[1]
-	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
-	ms.StoreMessageInfo(mi)
-}
-
-func (x *GPUUsage) String() string {
-	return protoimpl.X.MessageStringOf(x)
-}
-
-func (*GPUUsage) ProtoMessage() {}
-
-func (x *GPUUsage) ProtoReflect() protoreflect.Message {
-	mi := &file_kubemodel_gpu_proto_msgTypes[1]
-	if x != nil {
-		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
-		if ms.LoadMessageInfo() == nil {
-			ms.StoreMessageInfo(mi)
-		}
-		return ms
-	}
-	return mi.MessageOf(x)
-}
-
-// Deprecated: Use GPUUsage.ProtoReflect.Descriptor instead.
-func (*GPUUsage) Descriptor() ([]byte, []int) {
-	return file_kubemodel_gpu_proto_rawDescGZIP(), []int{1}
-}
-
-func (x *GPUUsage) GetContainerID() string {
-	if x != nil {
-		return x.ContainerID
-	}
-	return ""
-}
-
-func (x *GPUUsage) GetGpuDeviceID() string {
-	if x != nil {
-		return x.GpuDeviceID
-	}
-	return ""
-}
-
-func (x *GPUUsage) GetGpuHours() float32 {
-	if x != nil {
-		return x.GpuHours
-	}
-	return 0
-}
-
-func (x *GPUUsage) GetGpuRequestPercentage() float32 {
-	if x != nil {
-		return x.GpuRequestPercentage
-	}
-	return 0
-}
-
-func (x *GPUUsage) GetGpuUsageAverage() float32 {
-	if x != nil {
-		return x.GpuUsageAverage
-	}
-	return 0
-}
-
-func (x *GPUUsage) GetGpuUsageMax() float32 {
-	if x != nil {
-		return x.GpuUsageMax
-	}
-	return 0
-}
-
-func (x *GPUUsage) GetMemoryBytesUsed() int64 {
-	if x != nil {
-		return x.MemoryBytesUsed
-	}
-	return 0
-}
-
-func (x *GPUUsage) GetDiagnostic() *DiagnosticResult {
-	if x != nil {
-		return x.Diagnostic
-	}
-	return nil
-}
-
-var File_kubemodel_gpu_proto protoreflect.FileDescriptor
-
-const file_kubemodel_gpu_proto_rawDesc = "" +
-	"\n" +
-	"\x13kubemodel/gpu.proto\x12\tkubemodel\x1a\x1akubemodel/diagnostic.proto\"\xc4\x03\n" +
-	"\tGPUDevice\x12\x0e\n" +
-	"\x02ID\x18\x01 \x01(\tR\x02ID\x12\x16\n" +
-	"\x06nodeID\x18\x02 \x01(\tR\x06nodeID\x12\"\n" +
-	"\fdeviceNumber\x18\x03 \x01(\x05R\fdeviceNumber\x12\x1c\n" +
-	"\tmodelName\x18\x04 \x01(\tR\tmodelName\x12\x1a\n" +
-	"\bisShared\x18\x06 \x01(\bR\bisShared\x12(\n" +
-	"\x0fsharePercentage\x18\t \x01(\x02R\x0fsharePercentage\x12\x1a\n" +
-	"\bgpuHours\x18\n" +
-	" \x01(\x02R\bgpuHours\x12,\n" +
-	"\x11gpuRequestAverage\x18\v \x01(\x02R\x11gpuRequestAverage\x12(\n" +
-	"\x0fgpuUsageAverage\x18\f \x01(\x02R\x0fgpuUsageAverage\x12 \n" +
-	"\vgpuUsageMax\x18\r \x01(\x02R\vgpuUsageMax\x12 \n" +
-	"\vmemoryBytes\x18\x0e \x01(\x03R\vmemoryBytes\x12@\n" +
-	"\n" +
-	"diagnostic\x18c \x01(\v2\x1b.kubemodel.DiagnosticResultH\x00R\n" +
-	"diagnostic\x88\x01\x01B\r\n" +
-	"\v_diagnostic\"\xe5\x02\n" +
-	"\bGPUUsage\x12 \n" +
-	"\vcontainerID\x18\x01 \x01(\tR\vcontainerID\x12 \n" +
-	"\vgpuDeviceID\x18\x02 \x01(\tR\vgpuDeviceID\x12\x1a\n" +
-	"\bgpuHours\x18\x03 \x01(\x02R\bgpuHours\x122\n" +
-	"\x14gpuRequestPercentage\x18\x04 \x01(\x02R\x14gpuRequestPercentage\x12(\n" +
-	"\x0fgpuUsageAverage\x18\x05 \x01(\x02R\x0fgpuUsageAverage\x12 \n" +
-	"\vgpuUsageMax\x18\x06 \x01(\x02R\vgpuUsageMax\x12(\n" +
-	"\x0fmemoryBytesUsed\x18\a \x01(\x03R\x0fmemoryBytesUsed\x12@\n" +
-	"\n" +
-	"diagnostic\x18c \x01(\v2\x1b.kubemodel.DiagnosticResultH\x00R\n" +
-	"diagnostic\x88\x01\x01B\r\n" +
-	"\v_diagnosticB:Z8github.com/opencost/opencost/core/pkg/model/pb/kubemodelb\x06proto3"
-
-var (
-	file_kubemodel_gpu_proto_rawDescOnce sync.Once
-	file_kubemodel_gpu_proto_rawDescData []byte
-)
-
-func file_kubemodel_gpu_proto_rawDescGZIP() []byte {
-	file_kubemodel_gpu_proto_rawDescOnce.Do(func() {
-		file_kubemodel_gpu_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_kubemodel_gpu_proto_rawDesc), len(file_kubemodel_gpu_proto_rawDesc)))
-	})
-	return file_kubemodel_gpu_proto_rawDescData
-}
-
-var file_kubemodel_gpu_proto_msgTypes = make([]protoimpl.MessageInfo, 2)
-var file_kubemodel_gpu_proto_goTypes = []any{
-	(*GPUDevice)(nil),        // 0: kubemodel.GPUDevice
-	(*GPUUsage)(nil),         // 1: kubemodel.GPUUsage
-	(*DiagnosticResult)(nil), // 2: kubemodel.DiagnosticResult
-}
-var file_kubemodel_gpu_proto_depIdxs = []int32{
-	2, // 0: kubemodel.GPUDevice.diagnostic:type_name -> kubemodel.DiagnosticResult
-	2, // 1: kubemodel.GPUUsage.diagnostic:type_name -> kubemodel.DiagnosticResult
-	2, // [2:2] is the sub-list for method output_type
-	2, // [2:2] is the sub-list for method input_type
-	2, // [2:2] is the sub-list for extension type_name
-	2, // [2:2] is the sub-list for extension extendee
-	0, // [0:2] is the sub-list for field type_name
-}
-
-func init() { file_kubemodel_gpu_proto_init() }
-func file_kubemodel_gpu_proto_init() {
-	if File_kubemodel_gpu_proto != nil {
-		return
-	}
-	file_kubemodel_diagnostic_proto_init()
-	file_kubemodel_gpu_proto_msgTypes[0].OneofWrappers = []any{}
-	file_kubemodel_gpu_proto_msgTypes[1].OneofWrappers = []any{}
-	type x struct{}
-	out := protoimpl.TypeBuilder{
-		File: protoimpl.DescBuilder{
-			GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
-			RawDescriptor: unsafe.Slice(unsafe.StringData(file_kubemodel_gpu_proto_rawDesc), len(file_kubemodel_gpu_proto_rawDesc)),
-			NumEnums:      0,
-			NumMessages:   2,
-			NumExtensions: 0,
-			NumServices:   0,
-		},
-		GoTypes:           file_kubemodel_gpu_proto_goTypes,
-		DependencyIndexes: file_kubemodel_gpu_proto_depIdxs,
-		MessageInfos:      file_kubemodel_gpu_proto_msgTypes,
-	}.Build()
-	File_kubemodel_gpu_proto = out.File
-	file_kubemodel_gpu_proto_goTypes = nil
-	file_kubemodel_gpu_proto_depIdxs = nil
-}

+ 0 - 213
core/pkg/model/pb/kubemodel/namespace.pb.go

@@ -1,213 +0,0 @@
-// Code generated by protoc-gen-go. DO NOT EDIT.
-// versions:
-// 	protoc-gen-go v1.36.9
-// 	protoc        v6.32.1
-// source: kubemodel/namespace.proto
-
-package kubemodel
-
-import (
-	protoreflect "google.golang.org/protobuf/reflect/protoreflect"
-	protoimpl "google.golang.org/protobuf/runtime/protoimpl"
-	timestamppb "google.golang.org/protobuf/types/known/timestamppb"
-	reflect "reflect"
-	sync "sync"
-	unsafe "unsafe"
-)
-
-const (
-	// Verify that this generated code is sufficiently up-to-date.
-	_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
-	// Verify that runtime/protoimpl is sufficiently up-to-date.
-	_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
-)
-
-// Namespace represents a Kubernetes namespace (allocated resource grouping)
-type Namespace struct {
-	state protoimpl.MessageState `protogen:"open.v1"`
-	// Identification
-	ID        string `protobuf:"bytes,1,opt,name=ID,proto3" json:"ID,omitempty"`
-	ClusterID string `protobuf:"bytes,2,opt,name=clusterID,proto3" json:"clusterID,omitempty"`
-	// Properties
-	Name        string            `protobuf:"bytes,3,opt,name=name,proto3" json:"name,omitempty"`
-	Labels      map[string]string `protobuf:"bytes,4,rep,name=labels,proto3" json:"labels,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"`
-	Annotations map[string]string `protobuf:"bytes,5,rep,name=annotations,proto3" json:"annotations,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"`
-	// Resource lifecycle (only when different from cluster window)
-	CreationTime *timestamppb.Timestamp `protobuf:"bytes,7,opt,name=creationTime,proto3,oneof" json:"creationTime,omitempty"`
-	DeletionTime *timestamppb.Timestamp `protobuf:"bytes,8,opt,name=deletionTime,proto3,oneof" json:"deletionTime,omitempty"`
-	// Diagnostic information about this resource
-	Diagnostic    *DiagnosticResult `protobuf:"bytes,99,opt,name=diagnostic,proto3,oneof" json:"diagnostic,omitempty"`
-	unknownFields protoimpl.UnknownFields
-	sizeCache     protoimpl.SizeCache
-}
-
-func (x *Namespace) Reset() {
-	*x = Namespace{}
-	mi := &file_kubemodel_namespace_proto_msgTypes[0]
-	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
-	ms.StoreMessageInfo(mi)
-}
-
-func (x *Namespace) String() string {
-	return protoimpl.X.MessageStringOf(x)
-}
-
-func (*Namespace) ProtoMessage() {}
-
-func (x *Namespace) ProtoReflect() protoreflect.Message {
-	mi := &file_kubemodel_namespace_proto_msgTypes[0]
-	if x != nil {
-		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
-		if ms.LoadMessageInfo() == nil {
-			ms.StoreMessageInfo(mi)
-		}
-		return ms
-	}
-	return mi.MessageOf(x)
-}
-
-// Deprecated: Use Namespace.ProtoReflect.Descriptor instead.
-func (*Namespace) Descriptor() ([]byte, []int) {
-	return file_kubemodel_namespace_proto_rawDescGZIP(), []int{0}
-}
-
-func (x *Namespace) GetID() string {
-	if x != nil {
-		return x.ID
-	}
-	return ""
-}
-
-func (x *Namespace) GetClusterID() string {
-	if x != nil {
-		return x.ClusterID
-	}
-	return ""
-}
-
-func (x *Namespace) GetName() string {
-	if x != nil {
-		return x.Name
-	}
-	return ""
-}
-
-func (x *Namespace) GetLabels() map[string]string {
-	if x != nil {
-		return x.Labels
-	}
-	return nil
-}
-
-func (x *Namespace) GetAnnotations() map[string]string {
-	if x != nil {
-		return x.Annotations
-	}
-	return nil
-}
-
-func (x *Namespace) GetCreationTime() *timestamppb.Timestamp {
-	if x != nil {
-		return x.CreationTime
-	}
-	return nil
-}
-
-func (x *Namespace) GetDeletionTime() *timestamppb.Timestamp {
-	if x != nil {
-		return x.DeletionTime
-	}
-	return nil
-}
-
-func (x *Namespace) GetDiagnostic() *DiagnosticResult {
-	if x != nil {
-		return x.Diagnostic
-	}
-	return nil
-}
-
-var File_kubemodel_namespace_proto protoreflect.FileDescriptor
-
-const file_kubemodel_namespace_proto_rawDesc = "" +
-	"\n" +
-	"\x19kubemodel/namespace.proto\x12\tkubemodel\x1a\x1akubemodel/diagnostic.proto\x1a\x1fgoogle/protobuf/timestamp.proto\"\xc8\x04\n" +
-	"\tNamespace\x12\x0e\n" +
-	"\x02ID\x18\x01 \x01(\tR\x02ID\x12\x1c\n" +
-	"\tclusterID\x18\x02 \x01(\tR\tclusterID\x12\x12\n" +
-	"\x04name\x18\x03 \x01(\tR\x04name\x128\n" +
-	"\x06labels\x18\x04 \x03(\v2 .kubemodel.Namespace.LabelsEntryR\x06labels\x12G\n" +
-	"\vannotations\x18\x05 \x03(\v2%.kubemodel.Namespace.AnnotationsEntryR\vannotations\x12C\n" +
-	"\fcreationTime\x18\a \x01(\v2\x1a.google.protobuf.TimestampH\x00R\fcreationTime\x88\x01\x01\x12C\n" +
-	"\fdeletionTime\x18\b \x01(\v2\x1a.google.protobuf.TimestampH\x01R\fdeletionTime\x88\x01\x01\x12@\n" +
-	"\n" +
-	"diagnostic\x18c \x01(\v2\x1b.kubemodel.DiagnosticResultH\x02R\n" +
-	"diagnostic\x88\x01\x01\x1a9\n" +
-	"\vLabelsEntry\x12\x10\n" +
-	"\x03key\x18\x01 \x01(\tR\x03key\x12\x14\n" +
-	"\x05value\x18\x02 \x01(\tR\x05value:\x028\x01\x1a>\n" +
-	"\x10AnnotationsEntry\x12\x10\n" +
-	"\x03key\x18\x01 \x01(\tR\x03key\x12\x14\n" +
-	"\x05value\x18\x02 \x01(\tR\x05value:\x028\x01B\x0f\n" +
-	"\r_creationTimeB\x0f\n" +
-	"\r_deletionTimeB\r\n" +
-	"\v_diagnosticB:Z8github.com/opencost/opencost/core/pkg/model/pb/kubemodelb\x06proto3"
-
-var (
-	file_kubemodel_namespace_proto_rawDescOnce sync.Once
-	file_kubemodel_namespace_proto_rawDescData []byte
-)
-
-func file_kubemodel_namespace_proto_rawDescGZIP() []byte {
-	file_kubemodel_namespace_proto_rawDescOnce.Do(func() {
-		file_kubemodel_namespace_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_kubemodel_namespace_proto_rawDesc), len(file_kubemodel_namespace_proto_rawDesc)))
-	})
-	return file_kubemodel_namespace_proto_rawDescData
-}
-
-var file_kubemodel_namespace_proto_msgTypes = make([]protoimpl.MessageInfo, 3)
-var file_kubemodel_namespace_proto_goTypes = []any{
-	(*Namespace)(nil),             // 0: kubemodel.Namespace
-	nil,                           // 1: kubemodel.Namespace.LabelsEntry
-	nil,                           // 2: kubemodel.Namespace.AnnotationsEntry
-	(*timestamppb.Timestamp)(nil), // 3: google.protobuf.Timestamp
-	(*DiagnosticResult)(nil),      // 4: kubemodel.DiagnosticResult
-}
-var file_kubemodel_namespace_proto_depIdxs = []int32{
-	1, // 0: kubemodel.Namespace.labels:type_name -> kubemodel.Namespace.LabelsEntry
-	2, // 1: kubemodel.Namespace.annotations:type_name -> kubemodel.Namespace.AnnotationsEntry
-	3, // 2: kubemodel.Namespace.creationTime:type_name -> google.protobuf.Timestamp
-	3, // 3: kubemodel.Namespace.deletionTime:type_name -> google.protobuf.Timestamp
-	4, // 4: kubemodel.Namespace.diagnostic:type_name -> kubemodel.DiagnosticResult
-	5, // [5:5] is the sub-list for method output_type
-	5, // [5:5] is the sub-list for method input_type
-	5, // [5:5] is the sub-list for extension type_name
-	5, // [5:5] is the sub-list for extension extendee
-	0, // [0:5] is the sub-list for field type_name
-}
-
-func init() { file_kubemodel_namespace_proto_init() }
-func file_kubemodel_namespace_proto_init() {
-	if File_kubemodel_namespace_proto != nil {
-		return
-	}
-	file_kubemodel_diagnostic_proto_init()
-	file_kubemodel_namespace_proto_msgTypes[0].OneofWrappers = []any{}
-	type x struct{}
-	out := protoimpl.TypeBuilder{
-		File: protoimpl.DescBuilder{
-			GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
-			RawDescriptor: unsafe.Slice(unsafe.StringData(file_kubemodel_namespace_proto_rawDesc), len(file_kubemodel_namespace_proto_rawDesc)),
-			NumEnums:      0,
-			NumMessages:   3,
-			NumExtensions: 0,
-			NumServices:   0,
-		},
-		GoTypes:           file_kubemodel_namespace_proto_goTypes,
-		DependencyIndexes: file_kubemodel_namespace_proto_depIdxs,
-		MessageInfos:      file_kubemodel_namespace_proto_msgTypes,
-	}.Build()
-	File_kubemodel_namespace_proto = out.File
-	file_kubemodel_namespace_proto_goTypes = nil
-	file_kubemodel_namespace_proto_depIdxs = nil
-}

+ 0 - 340
core/pkg/model/pb/kubemodel/network.pb.go

@@ -1,340 +0,0 @@
-// Code generated by protoc-gen-go. DO NOT EDIT.
-// versions:
-// 	protoc-gen-go v1.36.9
-// 	protoc        v6.32.1
-// source: kubemodel/network.proto
-
-package kubemodel
-
-import (
-	protoreflect "google.golang.org/protobuf/reflect/protoreflect"
-	protoimpl "google.golang.org/protobuf/runtime/protoimpl"
-	timestamppb "google.golang.org/protobuf/types/known/timestamppb"
-	reflect "reflect"
-	sync "sync"
-	unsafe "unsafe"
-)
-
-const (
-	// Verify that this generated code is sufficiently up-to-date.
-	_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
-	// Verify that runtime/protoimpl is sufficiently up-to-date.
-	_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
-)
-
-// ServicePort represents a port exposed by a service
-type ServicePort struct {
-	state         protoimpl.MessageState `protogen:"open.v1"`
-	Name          string                 `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
-	Protocol      string                 `protobuf:"bytes,2,opt,name=protocol,proto3" json:"protocol,omitempty"`
-	Port          int32                  `protobuf:"varint,3,opt,name=port,proto3" json:"port,omitempty"`
-	TargetPort    int32                  `protobuf:"varint,4,opt,name=targetPort,proto3" json:"targetPort,omitempty"`
-	NodePort      int32                  `protobuf:"varint,5,opt,name=nodePort,proto3" json:"nodePort,omitempty"`
-	unknownFields protoimpl.UnknownFields
-	sizeCache     protoimpl.SizeCache
-}
-
-func (x *ServicePort) Reset() {
-	*x = ServicePort{}
-	mi := &file_kubemodel_network_proto_msgTypes[0]
-	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
-	ms.StoreMessageInfo(mi)
-}
-
-func (x *ServicePort) String() string {
-	return protoimpl.X.MessageStringOf(x)
-}
-
-func (*ServicePort) ProtoMessage() {}
-
-func (x *ServicePort) ProtoReflect() protoreflect.Message {
-	mi := &file_kubemodel_network_proto_msgTypes[0]
-	if x != nil {
-		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
-		if ms.LoadMessageInfo() == nil {
-			ms.StoreMessageInfo(mi)
-		}
-		return ms
-	}
-	return mi.MessageOf(x)
-}
-
-// Deprecated: Use ServicePort.ProtoReflect.Descriptor instead.
-func (*ServicePort) Descriptor() ([]byte, []int) {
-	return file_kubemodel_network_proto_rawDescGZIP(), []int{0}
-}
-
-func (x *ServicePort) GetName() string {
-	if x != nil {
-		return x.Name
-	}
-	return ""
-}
-
-func (x *ServicePort) GetProtocol() string {
-	if x != nil {
-		return x.Protocol
-	}
-	return ""
-}
-
-func (x *ServicePort) GetPort() int32 {
-	if x != nil {
-		return x.Port
-	}
-	return 0
-}
-
-func (x *ServicePort) GetTargetPort() int32 {
-	if x != nil {
-		return x.TargetPort
-	}
-	return 0
-}
-
-func (x *ServicePort) GetNodePort() int32 {
-	if x != nil {
-		return x.NodePort
-	}
-	return 0
-}
-
-// Service represents a K8s Service (allocated resource)
-type Service struct {
-	state protoimpl.MessageState `protogen:"open.v1"`
-	// Identification
-	ID        string `protobuf:"bytes,1,opt,name=ID,proto3" json:"ID,omitempty"`
-	ClusterID string `protobuf:"bytes,2,opt,name=clusterID,proto3" json:"clusterID,omitempty"`
-	// Properties
-	Name        string            `protobuf:"bytes,3,opt,name=name,proto3" json:"name,omitempty"`
-	ServiceType string            `protobuf:"bytes,4,opt,name=serviceType,proto3" json:"serviceType,omitempty"`
-	Ports       []*ServicePort    `protobuf:"bytes,5,rep,name=ports,proto3" json:"ports,omitempty"`
-	Labels      map[string]string `protobuf:"bytes,6,rep,name=labels,proto3" json:"labels,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"`
-	Annotations map[string]string `protobuf:"bytes,7,rep,name=annotations,proto3" json:"annotations,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"`
-	// Resource lifecycle (only when different from cluster window)
-	CreationTime *timestamppb.Timestamp `protobuf:"bytes,8,opt,name=creationTime,proto3,oneof" json:"creationTime,omitempty"`
-	DeletionTime *timestamppb.Timestamp `protobuf:"bytes,9,opt,name=deletionTime,proto3,oneof" json:"deletionTime,omitempty"`
-	// Usage metrics
-	// Network transfer bytes sent through this service
-	NetworkTransferBytes int64 `protobuf:"varint,10,opt,name=networkTransferBytes,proto3" json:"networkTransferBytes,omitempty"`
-	// Network bytes received through this service
-	NetworkReceiveBytes int64 `protobuf:"varint,11,opt,name=networkReceiveBytes,proto3" json:"networkReceiveBytes,omitempty"`
-	// Diagnostic information about this resource
-	Diagnostic    *DiagnosticResult `protobuf:"bytes,99,opt,name=diagnostic,proto3,oneof" json:"diagnostic,omitempty"`
-	unknownFields protoimpl.UnknownFields
-	sizeCache     protoimpl.SizeCache
-}
-
-func (x *Service) Reset() {
-	*x = Service{}
-	mi := &file_kubemodel_network_proto_msgTypes[1]
-	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
-	ms.StoreMessageInfo(mi)
-}
-
-func (x *Service) String() string {
-	return protoimpl.X.MessageStringOf(x)
-}
-
-func (*Service) ProtoMessage() {}
-
-func (x *Service) ProtoReflect() protoreflect.Message {
-	mi := &file_kubemodel_network_proto_msgTypes[1]
-	if x != nil {
-		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
-		if ms.LoadMessageInfo() == nil {
-			ms.StoreMessageInfo(mi)
-		}
-		return ms
-	}
-	return mi.MessageOf(x)
-}
-
-// Deprecated: Use Service.ProtoReflect.Descriptor instead.
-func (*Service) Descriptor() ([]byte, []int) {
-	return file_kubemodel_network_proto_rawDescGZIP(), []int{1}
-}
-
-func (x *Service) GetID() string {
-	if x != nil {
-		return x.ID
-	}
-	return ""
-}
-
-func (x *Service) GetClusterID() string {
-	if x != nil {
-		return x.ClusterID
-	}
-	return ""
-}
-
-func (x *Service) GetName() string {
-	if x != nil {
-		return x.Name
-	}
-	return ""
-}
-
-func (x *Service) GetServiceType() string {
-	if x != nil {
-		return x.ServiceType
-	}
-	return ""
-}
-
-func (x *Service) GetPorts() []*ServicePort {
-	if x != nil {
-		return x.Ports
-	}
-	return nil
-}
-
-func (x *Service) GetLabels() map[string]string {
-	if x != nil {
-		return x.Labels
-	}
-	return nil
-}
-
-func (x *Service) GetAnnotations() map[string]string {
-	if x != nil {
-		return x.Annotations
-	}
-	return nil
-}
-
-func (x *Service) GetCreationTime() *timestamppb.Timestamp {
-	if x != nil {
-		return x.CreationTime
-	}
-	return nil
-}
-
-func (x *Service) GetDeletionTime() *timestamppb.Timestamp {
-	if x != nil {
-		return x.DeletionTime
-	}
-	return nil
-}
-
-func (x *Service) GetNetworkTransferBytes() int64 {
-	if x != nil {
-		return x.NetworkTransferBytes
-	}
-	return 0
-}
-
-func (x *Service) GetNetworkReceiveBytes() int64 {
-	if x != nil {
-		return x.NetworkReceiveBytes
-	}
-	return 0
-}
-
-func (x *Service) GetDiagnostic() *DiagnosticResult {
-	if x != nil {
-		return x.Diagnostic
-	}
-	return nil
-}
-
-var File_kubemodel_network_proto protoreflect.FileDescriptor
-
-const file_kubemodel_network_proto_rawDesc = "" +
-	"\n" +
-	"\x17kubemodel/network.proto\x12\tkubemodel\x1a\x1akubemodel/diagnostic.proto\x1a\x1fgoogle/protobuf/timestamp.proto\"\x8d\x01\n" +
-	"\vServicePort\x12\x12\n" +
-	"\x04name\x18\x01 \x01(\tR\x04name\x12\x1a\n" +
-	"\bprotocol\x18\x02 \x01(\tR\bprotocol\x12\x12\n" +
-	"\x04port\x18\x03 \x01(\x05R\x04port\x12\x1e\n" +
-	"\n" +
-	"targetPort\x18\x04 \x01(\x05R\n" +
-	"targetPort\x12\x1a\n" +
-	"\bnodePort\x18\x05 \x01(\x05R\bnodePort\"\xf8\x05\n" +
-	"\aService\x12\x0e\n" +
-	"\x02ID\x18\x01 \x01(\tR\x02ID\x12\x1c\n" +
-	"\tclusterID\x18\x02 \x01(\tR\tclusterID\x12\x12\n" +
-	"\x04name\x18\x03 \x01(\tR\x04name\x12 \n" +
-	"\vserviceType\x18\x04 \x01(\tR\vserviceType\x12,\n" +
-	"\x05ports\x18\x05 \x03(\v2\x16.kubemodel.ServicePortR\x05ports\x126\n" +
-	"\x06labels\x18\x06 \x03(\v2\x1e.kubemodel.Service.LabelsEntryR\x06labels\x12E\n" +
-	"\vannotations\x18\a \x03(\v2#.kubemodel.Service.AnnotationsEntryR\vannotations\x12C\n" +
-	"\fcreationTime\x18\b \x01(\v2\x1a.google.protobuf.TimestampH\x00R\fcreationTime\x88\x01\x01\x12C\n" +
-	"\fdeletionTime\x18\t \x01(\v2\x1a.google.protobuf.TimestampH\x01R\fdeletionTime\x88\x01\x01\x122\n" +
-	"\x14networkTransferBytes\x18\n" +
-	" \x01(\x03R\x14networkTransferBytes\x120\n" +
-	"\x13networkReceiveBytes\x18\v \x01(\x03R\x13networkReceiveBytes\x12@\n" +
-	"\n" +
-	"diagnostic\x18c \x01(\v2\x1b.kubemodel.DiagnosticResultH\x02R\n" +
-	"diagnostic\x88\x01\x01\x1a9\n" +
-	"\vLabelsEntry\x12\x10\n" +
-	"\x03key\x18\x01 \x01(\tR\x03key\x12\x14\n" +
-	"\x05value\x18\x02 \x01(\tR\x05value:\x028\x01\x1a>\n" +
-	"\x10AnnotationsEntry\x12\x10\n" +
-	"\x03key\x18\x01 \x01(\tR\x03key\x12\x14\n" +
-	"\x05value\x18\x02 \x01(\tR\x05value:\x028\x01B\x0f\n" +
-	"\r_creationTimeB\x0f\n" +
-	"\r_deletionTimeB\r\n" +
-	"\v_diagnosticB:Z8github.com/opencost/opencost/core/pkg/model/pb/kubemodelb\x06proto3"
-
-var (
-	file_kubemodel_network_proto_rawDescOnce sync.Once
-	file_kubemodel_network_proto_rawDescData []byte
-)
-
-func file_kubemodel_network_proto_rawDescGZIP() []byte {
-	file_kubemodel_network_proto_rawDescOnce.Do(func() {
-		file_kubemodel_network_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_kubemodel_network_proto_rawDesc), len(file_kubemodel_network_proto_rawDesc)))
-	})
-	return file_kubemodel_network_proto_rawDescData
-}
-
-var file_kubemodel_network_proto_msgTypes = make([]protoimpl.MessageInfo, 4)
-var file_kubemodel_network_proto_goTypes = []any{
-	(*ServicePort)(nil),           // 0: kubemodel.ServicePort
-	(*Service)(nil),               // 1: kubemodel.Service
-	nil,                           // 2: kubemodel.Service.LabelsEntry
-	nil,                           // 3: kubemodel.Service.AnnotationsEntry
-	(*timestamppb.Timestamp)(nil), // 4: google.protobuf.Timestamp
-	(*DiagnosticResult)(nil),      // 5: kubemodel.DiagnosticResult
-}
-var file_kubemodel_network_proto_depIdxs = []int32{
-	0, // 0: kubemodel.Service.ports:type_name -> kubemodel.ServicePort
-	2, // 1: kubemodel.Service.labels:type_name -> kubemodel.Service.LabelsEntry
-	3, // 2: kubemodel.Service.annotations:type_name -> kubemodel.Service.AnnotationsEntry
-	4, // 3: kubemodel.Service.creationTime:type_name -> google.protobuf.Timestamp
-	4, // 4: kubemodel.Service.deletionTime:type_name -> google.protobuf.Timestamp
-	5, // 5: kubemodel.Service.diagnostic:type_name -> kubemodel.DiagnosticResult
-	6, // [6:6] is the sub-list for method output_type
-	6, // [6:6] is the sub-list for method input_type
-	6, // [6:6] is the sub-list for extension type_name
-	6, // [6:6] is the sub-list for extension extendee
-	0, // [0:6] is the sub-list for field type_name
-}
-
-func init() { file_kubemodel_network_proto_init() }
-func file_kubemodel_network_proto_init() {
-	if File_kubemodel_network_proto != nil {
-		return
-	}
-	file_kubemodel_diagnostic_proto_init()
-	file_kubemodel_network_proto_msgTypes[1].OneofWrappers = []any{}
-	type x struct{}
-	out := protoimpl.TypeBuilder{
-		File: protoimpl.DescBuilder{
-			GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
-			RawDescriptor: unsafe.Slice(unsafe.StringData(file_kubemodel_network_proto_rawDesc), len(file_kubemodel_network_proto_rawDesc)),
-			NumEnums:      0,
-			NumMessages:   4,
-			NumExtensions: 0,
-			NumServices:   0,
-		},
-		GoTypes:           file_kubemodel_network_proto_goTypes,
-		DependencyIndexes: file_kubemodel_network_proto_depIdxs,
-		MessageInfos:      file_kubemodel_network_proto_msgTypes,
-	}.Build()
-	File_kubemodel_network_proto = out.File
-	file_kubemodel_network_proto_goTypes = nil
-	file_kubemodel_network_proto_depIdxs = nil
-}

+ 0 - 222
core/pkg/model/pb/kubemodel/node.pb.go

@@ -1,222 +0,0 @@
-// Code generated by protoc-gen-go. DO NOT EDIT.
-// versions:
-// 	protoc-gen-go v1.36.9
-// 	protoc        v6.32.1
-// source: kubemodel/node.proto
-
-package kubemodel
-
-import (
-	protoreflect "google.golang.org/protobuf/reflect/protoreflect"
-	protoimpl "google.golang.org/protobuf/runtime/protoimpl"
-	timestamppb "google.golang.org/protobuf/types/known/timestamppb"
-	reflect "reflect"
-	sync "sync"
-	unsafe "unsafe"
-)
-
-const (
-	// Verify that this generated code is sufficiently up-to-date.
-	_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
-	// Verify that runtime/protoimpl is sufficiently up-to-date.
-	_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
-)
-
-// Node represents a Kubernetes worker node (provisioned resource)
-type Node struct {
-	state protoimpl.MessageState `protogen:"open.v1"`
-	// Identification
-	ID        string `protobuf:"bytes,1,opt,name=ID,proto3" json:"ID,omitempty"`
-	ClusterID string `protobuf:"bytes,2,opt,name=clusterID,proto3" json:"clusterID,omitempty"`
-	// Properties
-	ProviderResourceID string            `protobuf:"bytes,3,opt,name=providerResourceID,proto3" json:"providerResourceID,omitempty"`
-	Name               string            `protobuf:"bytes,4,opt,name=name,proto3" json:"name,omitempty"`
-	Labels             map[string]string `protobuf:"bytes,5,rep,name=labels,proto3" json:"labels,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"`
-	Annotations        map[string]string `protobuf:"bytes,6,rep,name=annotations,proto3" json:"annotations,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"`
-	// Resource lifecycle (only when different from cluster window)
-	CreationTime *timestamppb.Timestamp `protobuf:"bytes,7,opt,name=creationTime,proto3,oneof" json:"creationTime,omitempty"`
-	DeletionTime *timestamppb.Timestamp `protobuf:"bytes,8,opt,name=deletionTime,proto3,oneof" json:"deletionTime,omitempty"`
-	// Diagnostic information about this resource
-	Diagnostic    *DiagnosticResult `protobuf:"bytes,99,opt,name=diagnostic,proto3,oneof" json:"diagnostic,omitempty"`
-	unknownFields protoimpl.UnknownFields
-	sizeCache     protoimpl.SizeCache
-}
-
-func (x *Node) Reset() {
-	*x = Node{}
-	mi := &file_kubemodel_node_proto_msgTypes[0]
-	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
-	ms.StoreMessageInfo(mi)
-}
-
-func (x *Node) String() string {
-	return protoimpl.X.MessageStringOf(x)
-}
-
-func (*Node) ProtoMessage() {}
-
-func (x *Node) ProtoReflect() protoreflect.Message {
-	mi := &file_kubemodel_node_proto_msgTypes[0]
-	if x != nil {
-		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
-		if ms.LoadMessageInfo() == nil {
-			ms.StoreMessageInfo(mi)
-		}
-		return ms
-	}
-	return mi.MessageOf(x)
-}
-
-// Deprecated: Use Node.ProtoReflect.Descriptor instead.
-func (*Node) Descriptor() ([]byte, []int) {
-	return file_kubemodel_node_proto_rawDescGZIP(), []int{0}
-}
-
-func (x *Node) GetID() string {
-	if x != nil {
-		return x.ID
-	}
-	return ""
-}
-
-func (x *Node) GetClusterID() string {
-	if x != nil {
-		return x.ClusterID
-	}
-	return ""
-}
-
-func (x *Node) GetProviderResourceID() string {
-	if x != nil {
-		return x.ProviderResourceID
-	}
-	return ""
-}
-
-func (x *Node) GetName() string {
-	if x != nil {
-		return x.Name
-	}
-	return ""
-}
-
-func (x *Node) GetLabels() map[string]string {
-	if x != nil {
-		return x.Labels
-	}
-	return nil
-}
-
-func (x *Node) GetAnnotations() map[string]string {
-	if x != nil {
-		return x.Annotations
-	}
-	return nil
-}
-
-func (x *Node) GetCreationTime() *timestamppb.Timestamp {
-	if x != nil {
-		return x.CreationTime
-	}
-	return nil
-}
-
-func (x *Node) GetDeletionTime() *timestamppb.Timestamp {
-	if x != nil {
-		return x.DeletionTime
-	}
-	return nil
-}
-
-func (x *Node) GetDiagnostic() *DiagnosticResult {
-	if x != nil {
-		return x.Diagnostic
-	}
-	return nil
-}
-
-var File_kubemodel_node_proto protoreflect.FileDescriptor
-
-const file_kubemodel_node_proto_rawDesc = "" +
-	"\n" +
-	"\x14kubemodel/node.proto\x12\tkubemodel\x1a\x1akubemodel/diagnostic.proto\x1a\x1fgoogle/protobuf/timestamp.proto\"\xe9\x04\n" +
-	"\x04Node\x12\x0e\n" +
-	"\x02ID\x18\x01 \x01(\tR\x02ID\x12\x1c\n" +
-	"\tclusterID\x18\x02 \x01(\tR\tclusterID\x12.\n" +
-	"\x12providerResourceID\x18\x03 \x01(\tR\x12providerResourceID\x12\x12\n" +
-	"\x04name\x18\x04 \x01(\tR\x04name\x123\n" +
-	"\x06labels\x18\x05 \x03(\v2\x1b.kubemodel.Node.LabelsEntryR\x06labels\x12B\n" +
-	"\vannotations\x18\x06 \x03(\v2 .kubemodel.Node.AnnotationsEntryR\vannotations\x12C\n" +
-	"\fcreationTime\x18\a \x01(\v2\x1a.google.protobuf.TimestampH\x00R\fcreationTime\x88\x01\x01\x12C\n" +
-	"\fdeletionTime\x18\b \x01(\v2\x1a.google.protobuf.TimestampH\x01R\fdeletionTime\x88\x01\x01\x12@\n" +
-	"\n" +
-	"diagnostic\x18c \x01(\v2\x1b.kubemodel.DiagnosticResultH\x02R\n" +
-	"diagnostic\x88\x01\x01\x1a9\n" +
-	"\vLabelsEntry\x12\x10\n" +
-	"\x03key\x18\x01 \x01(\tR\x03key\x12\x14\n" +
-	"\x05value\x18\x02 \x01(\tR\x05value:\x028\x01\x1a>\n" +
-	"\x10AnnotationsEntry\x12\x10\n" +
-	"\x03key\x18\x01 \x01(\tR\x03key\x12\x14\n" +
-	"\x05value\x18\x02 \x01(\tR\x05value:\x028\x01B\x0f\n" +
-	"\r_creationTimeB\x0f\n" +
-	"\r_deletionTimeB\r\n" +
-	"\v_diagnosticB:Z8github.com/opencost/opencost/core/pkg/model/pb/kubemodelb\x06proto3"
-
-var (
-	file_kubemodel_node_proto_rawDescOnce sync.Once
-	file_kubemodel_node_proto_rawDescData []byte
-)
-
-func file_kubemodel_node_proto_rawDescGZIP() []byte {
-	file_kubemodel_node_proto_rawDescOnce.Do(func() {
-		file_kubemodel_node_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_kubemodel_node_proto_rawDesc), len(file_kubemodel_node_proto_rawDesc)))
-	})
-	return file_kubemodel_node_proto_rawDescData
-}
-
-var file_kubemodel_node_proto_msgTypes = make([]protoimpl.MessageInfo, 3)
-var file_kubemodel_node_proto_goTypes = []any{
-	(*Node)(nil),                  // 0: kubemodel.Node
-	nil,                           // 1: kubemodel.Node.LabelsEntry
-	nil,                           // 2: kubemodel.Node.AnnotationsEntry
-	(*timestamppb.Timestamp)(nil), // 3: google.protobuf.Timestamp
-	(*DiagnosticResult)(nil),      // 4: kubemodel.DiagnosticResult
-}
-var file_kubemodel_node_proto_depIdxs = []int32{
-	1, // 0: kubemodel.Node.labels:type_name -> kubemodel.Node.LabelsEntry
-	2, // 1: kubemodel.Node.annotations:type_name -> kubemodel.Node.AnnotationsEntry
-	3, // 2: kubemodel.Node.creationTime:type_name -> google.protobuf.Timestamp
-	3, // 3: kubemodel.Node.deletionTime:type_name -> google.protobuf.Timestamp
-	4, // 4: kubemodel.Node.diagnostic:type_name -> kubemodel.DiagnosticResult
-	5, // [5:5] is the sub-list for method output_type
-	5, // [5:5] is the sub-list for method input_type
-	5, // [5:5] is the sub-list for extension type_name
-	5, // [5:5] is the sub-list for extension extendee
-	0, // [0:5] is the sub-list for field type_name
-}
-
-func init() { file_kubemodel_node_proto_init() }
-func file_kubemodel_node_proto_init() {
-	if File_kubemodel_node_proto != nil {
-		return
-	}
-	file_kubemodel_diagnostic_proto_init()
-	file_kubemodel_node_proto_msgTypes[0].OneofWrappers = []any{}
-	type x struct{}
-	out := protoimpl.TypeBuilder{
-		File: protoimpl.DescBuilder{
-			GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
-			RawDescriptor: unsafe.Slice(unsafe.StringData(file_kubemodel_node_proto_rawDesc), len(file_kubemodel_node_proto_rawDesc)),
-			NumEnums:      0,
-			NumMessages:   3,
-			NumExtensions: 0,
-			NumServices:   0,
-		},
-		GoTypes:           file_kubemodel_node_proto_goTypes,
-		DependencyIndexes: file_kubemodel_node_proto_depIdxs,
-		MessageInfos:      file_kubemodel_node_proto_msgTypes,
-	}.Build()
-	File_kubemodel_node_proto = out.File
-	file_kubemodel_node_proto_goTypes = nil
-	file_kubemodel_node_proto_depIdxs = nil
-}

+ 0 - 343
core/pkg/model/pb/kubemodel/pod.pb.go

@@ -1,343 +0,0 @@
-// Code generated by protoc-gen-go. DO NOT EDIT.
-// versions:
-// 	protoc-gen-go v1.36.9
-// 	protoc        v6.32.1
-// source: kubemodel/pod.proto
-
-package kubemodel
-
-import (
-	protoreflect "google.golang.org/protobuf/reflect/protoreflect"
-	protoimpl "google.golang.org/protobuf/runtime/protoimpl"
-	timestamppb "google.golang.org/protobuf/types/known/timestamppb"
-	reflect "reflect"
-	sync "sync"
-	unsafe "unsafe"
-)
-
-const (
-	// Verify that this generated code is sufficiently up-to-date.
-	_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
-	// Verify that runtime/protoimpl is sufficiently up-to-date.
-	_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
-)
-
-// Pod represents a Kubernetes pod (allocated resource grouping)
-type Pod struct {
-	state protoimpl.MessageState `protogen:"open.v1"`
-	// Identification
-	ID           string `protobuf:"bytes,1,opt,name=ID,proto3" json:"ID,omitempty"`
-	NamespaceID  string `protobuf:"bytes,2,opt,name=namespaceID,proto3" json:"namespaceID,omitempty"`
-	ControllerID string `protobuf:"bytes,3,opt,name=controllerID,proto3" json:"controllerID,omitempty"`
-	NodeID       string `protobuf:"bytes,4,opt,name=nodeID,proto3" json:"nodeID,omitempty"`
-	// Properties
-	Name        string            `protobuf:"bytes,5,opt,name=name,proto3" json:"name,omitempty"`
-	Labels      map[string]string `protobuf:"bytes,6,rep,name=labels,proto3" json:"labels,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"`
-	Annotations map[string]string `protobuf:"bytes,7,rep,name=annotations,proto3" json:"annotations,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"`
-	// Resource lifecycle (only when different from cluster window)
-	CreationTime *timestamppb.Timestamp `protobuf:"bytes,8,opt,name=creationTime,proto3,oneof" json:"creationTime,omitempty"`
-	DeletionTime *timestamppb.Timestamp `protobuf:"bytes,9,opt,name=deletionTime,proto3,oneof" json:"deletionTime,omitempty"`
-	// Usage metrics
-	// CPU usage in core-hours
-	CpuCoreHours float32 `protobuf:"fixed32,10,opt,name=cpuCoreHours,proto3" json:"cpuCoreHours,omitempty"`
-	// CPU request average in cores
-	CpuCoreRequestAverage float32 `protobuf:"fixed32,11,opt,name=cpuCoreRequestAverage,proto3" json:"cpuCoreRequestAverage,omitempty"`
-	// CPU usage average in cores
-	CpuCoreUsageAverage float32 `protobuf:"fixed32,12,opt,name=cpuCoreUsageAverage,proto3" json:"cpuCoreUsageAverage,omitempty"`
-	// CPU usage max in cores
-	CpuCoreUsageMax float32 `protobuf:"fixed32,13,opt,name=cpuCoreUsageMax,proto3" json:"cpuCoreUsageMax,omitempty"`
-	// RAM usage in byte-hours
-	RamByteHours int64 `protobuf:"varint,14,opt,name=ramByteHours,proto3" json:"ramByteHours,omitempty"`
-	// RAM request average in bytes
-	RamBytesRequestAverage int64 `protobuf:"varint,15,opt,name=ramBytesRequestAverage,proto3" json:"ramBytesRequestAverage,omitempty"`
-	// RAM usage average in bytes
-	RamBytesUsageAverage int64 `protobuf:"varint,16,opt,name=ramBytesUsageAverage,proto3" json:"ramBytesUsageAverage,omitempty"`
-	// RAM usage max in bytes
-	RamBytesUsageMax int64 `protobuf:"varint,17,opt,name=ramBytesUsageMax,proto3" json:"ramBytesUsageMax,omitempty"`
-	// Storage usage in byte-hours
-	StorageByteHours int64 `protobuf:"varint,18,opt,name=storageByteHours,proto3" json:"storageByteHours,omitempty"`
-	// Network transfer bytes sent
-	NetworkTransferBytes int64 `protobuf:"varint,19,opt,name=networkTransferBytes,proto3" json:"networkTransferBytes,omitempty"`
-	// Network bytes received
-	NetworkReceiveBytes int64 `protobuf:"varint,20,opt,name=networkReceiveBytes,proto3" json:"networkReceiveBytes,omitempty"`
-	// Diagnostic information about this resource
-	Diagnostic    *DiagnosticResult `protobuf:"bytes,99,opt,name=diagnostic,proto3,oneof" json:"diagnostic,omitempty"`
-	unknownFields protoimpl.UnknownFields
-	sizeCache     protoimpl.SizeCache
-}
-
-func (x *Pod) Reset() {
-	*x = Pod{}
-	mi := &file_kubemodel_pod_proto_msgTypes[0]
-	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
-	ms.StoreMessageInfo(mi)
-}
-
-func (x *Pod) String() string {
-	return protoimpl.X.MessageStringOf(x)
-}
-
-func (*Pod) ProtoMessage() {}
-
-func (x *Pod) ProtoReflect() protoreflect.Message {
-	mi := &file_kubemodel_pod_proto_msgTypes[0]
-	if x != nil {
-		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
-		if ms.LoadMessageInfo() == nil {
-			ms.StoreMessageInfo(mi)
-		}
-		return ms
-	}
-	return mi.MessageOf(x)
-}
-
-// Deprecated: Use Pod.ProtoReflect.Descriptor instead.
-func (*Pod) Descriptor() ([]byte, []int) {
-	return file_kubemodel_pod_proto_rawDescGZIP(), []int{0}
-}
-
-func (x *Pod) GetID() string {
-	if x != nil {
-		return x.ID
-	}
-	return ""
-}
-
-func (x *Pod) GetNamespaceID() string {
-	if x != nil {
-		return x.NamespaceID
-	}
-	return ""
-}
-
-func (x *Pod) GetControllerID() string {
-	if x != nil {
-		return x.ControllerID
-	}
-	return ""
-}
-
-func (x *Pod) GetNodeID() string {
-	if x != nil {
-		return x.NodeID
-	}
-	return ""
-}
-
-func (x *Pod) GetName() string {
-	if x != nil {
-		return x.Name
-	}
-	return ""
-}
-
-func (x *Pod) GetLabels() map[string]string {
-	if x != nil {
-		return x.Labels
-	}
-	return nil
-}
-
-func (x *Pod) GetAnnotations() map[string]string {
-	if x != nil {
-		return x.Annotations
-	}
-	return nil
-}
-
-func (x *Pod) GetCreationTime() *timestamppb.Timestamp {
-	if x != nil {
-		return x.CreationTime
-	}
-	return nil
-}
-
-func (x *Pod) GetDeletionTime() *timestamppb.Timestamp {
-	if x != nil {
-		return x.DeletionTime
-	}
-	return nil
-}
-
-func (x *Pod) GetCpuCoreHours() float32 {
-	if x != nil {
-		return x.CpuCoreHours
-	}
-	return 0
-}
-
-func (x *Pod) GetCpuCoreRequestAverage() float32 {
-	if x != nil {
-		return x.CpuCoreRequestAverage
-	}
-	return 0
-}
-
-func (x *Pod) GetCpuCoreUsageAverage() float32 {
-	if x != nil {
-		return x.CpuCoreUsageAverage
-	}
-	return 0
-}
-
-func (x *Pod) GetCpuCoreUsageMax() float32 {
-	if x != nil {
-		return x.CpuCoreUsageMax
-	}
-	return 0
-}
-
-func (x *Pod) GetRamByteHours() int64 {
-	if x != nil {
-		return x.RamByteHours
-	}
-	return 0
-}
-
-func (x *Pod) GetRamBytesRequestAverage() int64 {
-	if x != nil {
-		return x.RamBytesRequestAverage
-	}
-	return 0
-}
-
-func (x *Pod) GetRamBytesUsageAverage() int64 {
-	if x != nil {
-		return x.RamBytesUsageAverage
-	}
-	return 0
-}
-
-func (x *Pod) GetRamBytesUsageMax() int64 {
-	if x != nil {
-		return x.RamBytesUsageMax
-	}
-	return 0
-}
-
-func (x *Pod) GetStorageByteHours() int64 {
-	if x != nil {
-		return x.StorageByteHours
-	}
-	return 0
-}
-
-func (x *Pod) GetNetworkTransferBytes() int64 {
-	if x != nil {
-		return x.NetworkTransferBytes
-	}
-	return 0
-}
-
-func (x *Pod) GetNetworkReceiveBytes() int64 {
-	if x != nil {
-		return x.NetworkReceiveBytes
-	}
-	return 0
-}
-
-func (x *Pod) GetDiagnostic() *DiagnosticResult {
-	if x != nil {
-		return x.Diagnostic
-	}
-	return nil
-}
-
-var File_kubemodel_pod_proto protoreflect.FileDescriptor
-
-const file_kubemodel_pod_proto_rawDesc = "" +
-	"\n" +
-	"\x13kubemodel/pod.proto\x12\tkubemodel\x1a\x1akubemodel/diagnostic.proto\x1a\x1fgoogle/protobuf/timestamp.proto\"\xfa\b\n" +
-	"\x03Pod\x12\x0e\n" +
-	"\x02ID\x18\x01 \x01(\tR\x02ID\x12 \n" +
-	"\vnamespaceID\x18\x02 \x01(\tR\vnamespaceID\x12\"\n" +
-	"\fcontrollerID\x18\x03 \x01(\tR\fcontrollerID\x12\x16\n" +
-	"\x06nodeID\x18\x04 \x01(\tR\x06nodeID\x12\x12\n" +
-	"\x04name\x18\x05 \x01(\tR\x04name\x122\n" +
-	"\x06labels\x18\x06 \x03(\v2\x1a.kubemodel.Pod.LabelsEntryR\x06labels\x12A\n" +
-	"\vannotations\x18\a \x03(\v2\x1f.kubemodel.Pod.AnnotationsEntryR\vannotations\x12C\n" +
-	"\fcreationTime\x18\b \x01(\v2\x1a.google.protobuf.TimestampH\x00R\fcreationTime\x88\x01\x01\x12C\n" +
-	"\fdeletionTime\x18\t \x01(\v2\x1a.google.protobuf.TimestampH\x01R\fdeletionTime\x88\x01\x01\x12\"\n" +
-	"\fcpuCoreHours\x18\n" +
-	" \x01(\x02R\fcpuCoreHours\x124\n" +
-	"\x15cpuCoreRequestAverage\x18\v \x01(\x02R\x15cpuCoreRequestAverage\x120\n" +
-	"\x13cpuCoreUsageAverage\x18\f \x01(\x02R\x13cpuCoreUsageAverage\x12(\n" +
-	"\x0fcpuCoreUsageMax\x18\r \x01(\x02R\x0fcpuCoreUsageMax\x12\"\n" +
-	"\framByteHours\x18\x0e \x01(\x03R\framByteHours\x126\n" +
-	"\x16ramBytesRequestAverage\x18\x0f \x01(\x03R\x16ramBytesRequestAverage\x122\n" +
-	"\x14ramBytesUsageAverage\x18\x10 \x01(\x03R\x14ramBytesUsageAverage\x12*\n" +
-	"\x10ramBytesUsageMax\x18\x11 \x01(\x03R\x10ramBytesUsageMax\x12*\n" +
-	"\x10storageByteHours\x18\x12 \x01(\x03R\x10storageByteHours\x122\n" +
-	"\x14networkTransferBytes\x18\x13 \x01(\x03R\x14networkTransferBytes\x120\n" +
-	"\x13networkReceiveBytes\x18\x14 \x01(\x03R\x13networkReceiveBytes\x12@\n" +
-	"\n" +
-	"diagnostic\x18c \x01(\v2\x1b.kubemodel.DiagnosticResultH\x02R\n" +
-	"diagnostic\x88\x01\x01\x1a9\n" +
-	"\vLabelsEntry\x12\x10\n" +
-	"\x03key\x18\x01 \x01(\tR\x03key\x12\x14\n" +
-	"\x05value\x18\x02 \x01(\tR\x05value:\x028\x01\x1a>\n" +
-	"\x10AnnotationsEntry\x12\x10\n" +
-	"\x03key\x18\x01 \x01(\tR\x03key\x12\x14\n" +
-	"\x05value\x18\x02 \x01(\tR\x05value:\x028\x01B\x0f\n" +
-	"\r_creationTimeB\x0f\n" +
-	"\r_deletionTimeB\r\n" +
-	"\v_diagnosticB:Z8github.com/opencost/opencost/core/pkg/model/pb/kubemodelb\x06proto3"
-
-var (
-	file_kubemodel_pod_proto_rawDescOnce sync.Once
-	file_kubemodel_pod_proto_rawDescData []byte
-)
-
-func file_kubemodel_pod_proto_rawDescGZIP() []byte {
-	file_kubemodel_pod_proto_rawDescOnce.Do(func() {
-		file_kubemodel_pod_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_kubemodel_pod_proto_rawDesc), len(file_kubemodel_pod_proto_rawDesc)))
-	})
-	return file_kubemodel_pod_proto_rawDescData
-}
-
-var file_kubemodel_pod_proto_msgTypes = make([]protoimpl.MessageInfo, 3)
-var file_kubemodel_pod_proto_goTypes = []any{
-	(*Pod)(nil),                   // 0: kubemodel.Pod
-	nil,                           // 1: kubemodel.Pod.LabelsEntry
-	nil,                           // 2: kubemodel.Pod.AnnotationsEntry
-	(*timestamppb.Timestamp)(nil), // 3: google.protobuf.Timestamp
-	(*DiagnosticResult)(nil),      // 4: kubemodel.DiagnosticResult
-}
-var file_kubemodel_pod_proto_depIdxs = []int32{
-	1, // 0: kubemodel.Pod.labels:type_name -> kubemodel.Pod.LabelsEntry
-	2, // 1: kubemodel.Pod.annotations:type_name -> kubemodel.Pod.AnnotationsEntry
-	3, // 2: kubemodel.Pod.creationTime:type_name -> google.protobuf.Timestamp
-	3, // 3: kubemodel.Pod.deletionTime:type_name -> google.protobuf.Timestamp
-	4, // 4: kubemodel.Pod.diagnostic:type_name -> kubemodel.DiagnosticResult
-	5, // [5:5] is the sub-list for method output_type
-	5, // [5:5] is the sub-list for method input_type
-	5, // [5:5] is the sub-list for extension type_name
-	5, // [5:5] is the sub-list for extension extendee
-	0, // [0:5] is the sub-list for field type_name
-}
-
-func init() { file_kubemodel_pod_proto_init() }
-func file_kubemodel_pod_proto_init() {
-	if File_kubemodel_pod_proto != nil {
-		return
-	}
-	file_kubemodel_diagnostic_proto_init()
-	file_kubemodel_pod_proto_msgTypes[0].OneofWrappers = []any{}
-	type x struct{}
-	out := protoimpl.TypeBuilder{
-		File: protoimpl.DescBuilder{
-			GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
-			RawDescriptor: unsafe.Slice(unsafe.StringData(file_kubemodel_pod_proto_rawDesc), len(file_kubemodel_pod_proto_rawDesc)),
-			NumEnums:      0,
-			NumMessages:   3,
-			NumExtensions: 0,
-			NumServices:   0,
-		},
-		GoTypes:           file_kubemodel_pod_proto_goTypes,
-		DependencyIndexes: file_kubemodel_pod_proto_depIdxs,
-		MessageInfos:      file_kubemodel_pod_proto_msgTypes,
-	}.Build()
-	File_kubemodel_pod_proto = out.File
-	file_kubemodel_pod_proto_goTypes = nil
-	file_kubemodel_pod_proto_depIdxs = nil
-}

+ 0 - 418
core/pkg/model/pb/kubemodel/storage.pb.go

@@ -1,418 +0,0 @@
-// Code generated by protoc-gen-go. DO NOT EDIT.
-// versions:
-// 	protoc-gen-go v1.36.9
-// 	protoc        v6.32.1
-// source: kubemodel/storage.proto
-
-package kubemodel
-
-import (
-	protoreflect "google.golang.org/protobuf/reflect/protoreflect"
-	protoimpl "google.golang.org/protobuf/runtime/protoimpl"
-	timestamppb "google.golang.org/protobuf/types/known/timestamppb"
-	reflect "reflect"
-	sync "sync"
-	unsafe "unsafe"
-)
-
-const (
-	// Verify that this generated code is sufficiently up-to-date.
-	_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
-	// Verify that runtime/protoimpl is sufficiently up-to-date.
-	_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
-)
-
-// Volume represents a persistent volume (provisioned resource)
-type Volume struct {
-	state protoimpl.MessageState `protogen:"open.v1"`
-	// Identification
-	ID        string `protobuf:"bytes,1,opt,name=ID,proto3" json:"ID,omitempty"`
-	ClusterID string `protobuf:"bytes,2,opt,name=clusterID,proto3" json:"clusterID,omitempty"`
-	// Properties
-	Name         string            `protobuf:"bytes,3,opt,name=name,proto3" json:"name,omitempty"`
-	StorageClass string            `protobuf:"bytes,4,opt,name=storageClass,proto3" json:"storageClass,omitempty"`
-	Labels       map[string]string `protobuf:"bytes,5,rep,name=labels,proto3" json:"labels,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"`
-	Annotations  map[string]string `protobuf:"bytes,6,rep,name=annotations,proto3" json:"annotations,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"`
-	// Resource lifecycle (only when different from cluster window)
-	CreationTime *timestamppb.Timestamp `protobuf:"bytes,7,opt,name=creationTime,proto3,oneof" json:"creationTime,omitempty"`
-	DeletionTime *timestamppb.Timestamp `protobuf:"bytes,8,opt,name=deletionTime,proto3,oneof" json:"deletionTime,omitempty"`
-	// Usage metrics
-	// Storage capacity in bytes
-	CapacityBytes int64 `protobuf:"varint,9,opt,name=capacityBytes,proto3" json:"capacityBytes,omitempty"`
-	// Diagnostic information about this resource
-	Diagnostic    *DiagnosticResult `protobuf:"bytes,99,opt,name=diagnostic,proto3,oneof" json:"diagnostic,omitempty"`
-	unknownFields protoimpl.UnknownFields
-	sizeCache     protoimpl.SizeCache
-}
-
-func (x *Volume) Reset() {
-	*x = Volume{}
-	mi := &file_kubemodel_storage_proto_msgTypes[0]
-	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
-	ms.StoreMessageInfo(mi)
-}
-
-func (x *Volume) String() string {
-	return protoimpl.X.MessageStringOf(x)
-}
-
-func (*Volume) ProtoMessage() {}
-
-func (x *Volume) ProtoReflect() protoreflect.Message {
-	mi := &file_kubemodel_storage_proto_msgTypes[0]
-	if x != nil {
-		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
-		if ms.LoadMessageInfo() == nil {
-			ms.StoreMessageInfo(mi)
-		}
-		return ms
-	}
-	return mi.MessageOf(x)
-}
-
-// Deprecated: Use Volume.ProtoReflect.Descriptor instead.
-func (*Volume) Descriptor() ([]byte, []int) {
-	return file_kubemodel_storage_proto_rawDescGZIP(), []int{0}
-}
-
-func (x *Volume) GetID() string {
-	if x != nil {
-		return x.ID
-	}
-	return ""
-}
-
-func (x *Volume) GetClusterID() string {
-	if x != nil {
-		return x.ClusterID
-	}
-	return ""
-}
-
-func (x *Volume) GetName() string {
-	if x != nil {
-		return x.Name
-	}
-	return ""
-}
-
-func (x *Volume) GetStorageClass() string {
-	if x != nil {
-		return x.StorageClass
-	}
-	return ""
-}
-
-func (x *Volume) GetLabels() map[string]string {
-	if x != nil {
-		return x.Labels
-	}
-	return nil
-}
-
-func (x *Volume) GetAnnotations() map[string]string {
-	if x != nil {
-		return x.Annotations
-	}
-	return nil
-}
-
-func (x *Volume) GetCreationTime() *timestamppb.Timestamp {
-	if x != nil {
-		return x.CreationTime
-	}
-	return nil
-}
-
-func (x *Volume) GetDeletionTime() *timestamppb.Timestamp {
-	if x != nil {
-		return x.DeletionTime
-	}
-	return nil
-}
-
-func (x *Volume) GetCapacityBytes() int64 {
-	if x != nil {
-		return x.CapacityBytes
-	}
-	return 0
-}
-
-func (x *Volume) GetDiagnostic() *DiagnosticResult {
-	if x != nil {
-		return x.Diagnostic
-	}
-	return nil
-}
-
-// PersistentVolumeClaim represents a PVC (allocated resource) that refers to a Volume
-type PersistentVolumeClaim struct {
-	state protoimpl.MessageState `protogen:"open.v1"`
-	// Identification
-	ID          string  `protobuf:"bytes,1,opt,name=ID,proto3" json:"ID,omitempty"`
-	NamespaceID string  `protobuf:"bytes,2,opt,name=namespaceID,proto3" json:"namespaceID,omitempty"`
-	VolumeID    *string `protobuf:"bytes,3,opt,name=volumeID,proto3,oneof" json:"volumeID,omitempty"`
-	PodID       *string `protobuf:"bytes,4,opt,name=podID,proto3,oneof" json:"podID,omitempty"`
-	// Properties
-	Name         string            `protobuf:"bytes,5,opt,name=name,proto3" json:"name,omitempty"`
-	StorageClass string            `protobuf:"bytes,6,opt,name=storageClass,proto3" json:"storageClass,omitempty"`
-	Labels       map[string]string `protobuf:"bytes,7,rep,name=labels,proto3" json:"labels,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"`
-	Annotations  map[string]string `protobuf:"bytes,8,rep,name=annotations,proto3" json:"annotations,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"`
-	// Resource lifecycle (only when different from cluster window)
-	CreationTime *timestamppb.Timestamp `protobuf:"bytes,9,opt,name=creationTime,proto3,oneof" json:"creationTime,omitempty"`
-	DeletionTime *timestamppb.Timestamp `protobuf:"bytes,10,opt,name=deletionTime,proto3,oneof" json:"deletionTime,omitempty"`
-	// Usage metrics
-	// Storage usage in byte-hours
-	StorageByteHours int64 `protobuf:"varint,11,opt,name=storageByteHours,proto3" json:"storageByteHours,omitempty"`
-	// Requested storage capacity in bytes
-	RequestedBytes int64 `protobuf:"varint,12,opt,name=requestedBytes,proto3" json:"requestedBytes,omitempty"`
-	// Diagnostic information about this resource
-	Diagnostic    *DiagnosticResult `protobuf:"bytes,99,opt,name=diagnostic,proto3,oneof" json:"diagnostic,omitempty"`
-	unknownFields protoimpl.UnknownFields
-	sizeCache     protoimpl.SizeCache
-}
-
-func (x *PersistentVolumeClaim) Reset() {
-	*x = PersistentVolumeClaim{}
-	mi := &file_kubemodel_storage_proto_msgTypes[1]
-	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
-	ms.StoreMessageInfo(mi)
-}
-
-func (x *PersistentVolumeClaim) String() string {
-	return protoimpl.X.MessageStringOf(x)
-}
-
-func (*PersistentVolumeClaim) ProtoMessage() {}
-
-func (x *PersistentVolumeClaim) ProtoReflect() protoreflect.Message {
-	mi := &file_kubemodel_storage_proto_msgTypes[1]
-	if x != nil {
-		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
-		if ms.LoadMessageInfo() == nil {
-			ms.StoreMessageInfo(mi)
-		}
-		return ms
-	}
-	return mi.MessageOf(x)
-}
-
-// Deprecated: Use PersistentVolumeClaim.ProtoReflect.Descriptor instead.
-func (*PersistentVolumeClaim) Descriptor() ([]byte, []int) {
-	return file_kubemodel_storage_proto_rawDescGZIP(), []int{1}
-}
-
-func (x *PersistentVolumeClaim) GetID() string {
-	if x != nil {
-		return x.ID
-	}
-	return ""
-}
-
-func (x *PersistentVolumeClaim) GetNamespaceID() string {
-	if x != nil {
-		return x.NamespaceID
-	}
-	return ""
-}
-
-func (x *PersistentVolumeClaim) GetVolumeID() string {
-	if x != nil && x.VolumeID != nil {
-		return *x.VolumeID
-	}
-	return ""
-}
-
-func (x *PersistentVolumeClaim) GetPodID() string {
-	if x != nil && x.PodID != nil {
-		return *x.PodID
-	}
-	return ""
-}
-
-func (x *PersistentVolumeClaim) GetName() string {
-	if x != nil {
-		return x.Name
-	}
-	return ""
-}
-
-func (x *PersistentVolumeClaim) GetStorageClass() string {
-	if x != nil {
-		return x.StorageClass
-	}
-	return ""
-}
-
-func (x *PersistentVolumeClaim) GetLabels() map[string]string {
-	if x != nil {
-		return x.Labels
-	}
-	return nil
-}
-
-func (x *PersistentVolumeClaim) GetAnnotations() map[string]string {
-	if x != nil {
-		return x.Annotations
-	}
-	return nil
-}
-
-func (x *PersistentVolumeClaim) GetCreationTime() *timestamppb.Timestamp {
-	if x != nil {
-		return x.CreationTime
-	}
-	return nil
-}
-
-func (x *PersistentVolumeClaim) GetDeletionTime() *timestamppb.Timestamp {
-	if x != nil {
-		return x.DeletionTime
-	}
-	return nil
-}
-
-func (x *PersistentVolumeClaim) GetStorageByteHours() int64 {
-	if x != nil {
-		return x.StorageByteHours
-	}
-	return 0
-}
-
-func (x *PersistentVolumeClaim) GetRequestedBytes() int64 {
-	if x != nil {
-		return x.RequestedBytes
-	}
-	return 0
-}
-
-func (x *PersistentVolumeClaim) GetDiagnostic() *DiagnosticResult {
-	if x != nil {
-		return x.Diagnostic
-	}
-	return nil
-}
-
-var File_kubemodel_storage_proto protoreflect.FileDescriptor
-
-const file_kubemodel_storage_proto_rawDesc = "" +
-	"\n" +
-	"\x17kubemodel/storage.proto\x12\tkubemodel\x1a\x1akubemodel/diagnostic.proto\x1a\x1fgoogle/protobuf/timestamp.proto\"\x89\x05\n" +
-	"\x06Volume\x12\x0e\n" +
-	"\x02ID\x18\x01 \x01(\tR\x02ID\x12\x1c\n" +
-	"\tclusterID\x18\x02 \x01(\tR\tclusterID\x12\x12\n" +
-	"\x04name\x18\x03 \x01(\tR\x04name\x12\"\n" +
-	"\fstorageClass\x18\x04 \x01(\tR\fstorageClass\x125\n" +
-	"\x06labels\x18\x05 \x03(\v2\x1d.kubemodel.Volume.LabelsEntryR\x06labels\x12D\n" +
-	"\vannotations\x18\x06 \x03(\v2\".kubemodel.Volume.AnnotationsEntryR\vannotations\x12C\n" +
-	"\fcreationTime\x18\a \x01(\v2\x1a.google.protobuf.TimestampH\x00R\fcreationTime\x88\x01\x01\x12C\n" +
-	"\fdeletionTime\x18\b \x01(\v2\x1a.google.protobuf.TimestampH\x01R\fdeletionTime\x88\x01\x01\x12$\n" +
-	"\rcapacityBytes\x18\t \x01(\x03R\rcapacityBytes\x12@\n" +
-	"\n" +
-	"diagnostic\x18c \x01(\v2\x1b.kubemodel.DiagnosticResultH\x02R\n" +
-	"diagnostic\x88\x01\x01\x1a9\n" +
-	"\vLabelsEntry\x12\x10\n" +
-	"\x03key\x18\x01 \x01(\tR\x03key\x12\x14\n" +
-	"\x05value\x18\x02 \x01(\tR\x05value:\x028\x01\x1a>\n" +
-	"\x10AnnotationsEntry\x12\x10\n" +
-	"\x03key\x18\x01 \x01(\tR\x03key\x12\x14\n" +
-	"\x05value\x18\x02 \x01(\tR\x05value:\x028\x01B\x0f\n" +
-	"\r_creationTimeB\x0f\n" +
-	"\r_deletionTimeB\r\n" +
-	"\v_diagnostic\"\xbb\x06\n" +
-	"\x15PersistentVolumeClaim\x12\x0e\n" +
-	"\x02ID\x18\x01 \x01(\tR\x02ID\x12 \n" +
-	"\vnamespaceID\x18\x02 \x01(\tR\vnamespaceID\x12\x1f\n" +
-	"\bvolumeID\x18\x03 \x01(\tH\x00R\bvolumeID\x88\x01\x01\x12\x19\n" +
-	"\x05podID\x18\x04 \x01(\tH\x01R\x05podID\x88\x01\x01\x12\x12\n" +
-	"\x04name\x18\x05 \x01(\tR\x04name\x12\"\n" +
-	"\fstorageClass\x18\x06 \x01(\tR\fstorageClass\x12D\n" +
-	"\x06labels\x18\a \x03(\v2,.kubemodel.PersistentVolumeClaim.LabelsEntryR\x06labels\x12S\n" +
-	"\vannotations\x18\b \x03(\v21.kubemodel.PersistentVolumeClaim.AnnotationsEntryR\vannotations\x12C\n" +
-	"\fcreationTime\x18\t \x01(\v2\x1a.google.protobuf.TimestampH\x02R\fcreationTime\x88\x01\x01\x12C\n" +
-	"\fdeletionTime\x18\n" +
-	" \x01(\v2\x1a.google.protobuf.TimestampH\x03R\fdeletionTime\x88\x01\x01\x12*\n" +
-	"\x10storageByteHours\x18\v \x01(\x03R\x10storageByteHours\x12&\n" +
-	"\x0erequestedBytes\x18\f \x01(\x03R\x0erequestedBytes\x12@\n" +
-	"\n" +
-	"diagnostic\x18c \x01(\v2\x1b.kubemodel.DiagnosticResultH\x04R\n" +
-	"diagnostic\x88\x01\x01\x1a9\n" +
-	"\vLabelsEntry\x12\x10\n" +
-	"\x03key\x18\x01 \x01(\tR\x03key\x12\x14\n" +
-	"\x05value\x18\x02 \x01(\tR\x05value:\x028\x01\x1a>\n" +
-	"\x10AnnotationsEntry\x12\x10\n" +
-	"\x03key\x18\x01 \x01(\tR\x03key\x12\x14\n" +
-	"\x05value\x18\x02 \x01(\tR\x05value:\x028\x01B\v\n" +
-	"\t_volumeIDB\b\n" +
-	"\x06_podIDB\x0f\n" +
-	"\r_creationTimeB\x0f\n" +
-	"\r_deletionTimeB\r\n" +
-	"\v_diagnosticB:Z8github.com/opencost/opencost/core/pkg/model/pb/kubemodelb\x06proto3"
-
-var (
-	file_kubemodel_storage_proto_rawDescOnce sync.Once
-	file_kubemodel_storage_proto_rawDescData []byte
-)
-
-func file_kubemodel_storage_proto_rawDescGZIP() []byte {
-	file_kubemodel_storage_proto_rawDescOnce.Do(func() {
-		file_kubemodel_storage_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_kubemodel_storage_proto_rawDesc), len(file_kubemodel_storage_proto_rawDesc)))
-	})
-	return file_kubemodel_storage_proto_rawDescData
-}
-
-var file_kubemodel_storage_proto_msgTypes = make([]protoimpl.MessageInfo, 6)
-var file_kubemodel_storage_proto_goTypes = []any{
-	(*Volume)(nil),                // 0: kubemodel.Volume
-	(*PersistentVolumeClaim)(nil), // 1: kubemodel.PersistentVolumeClaim
-	nil,                           // 2: kubemodel.Volume.LabelsEntry
-	nil,                           // 3: kubemodel.Volume.AnnotationsEntry
-	nil,                           // 4: kubemodel.PersistentVolumeClaim.LabelsEntry
-	nil,                           // 5: kubemodel.PersistentVolumeClaim.AnnotationsEntry
-	(*timestamppb.Timestamp)(nil), // 6: google.protobuf.Timestamp
-	(*DiagnosticResult)(nil),      // 7: kubemodel.DiagnosticResult
-}
-var file_kubemodel_storage_proto_depIdxs = []int32{
-	2,  // 0: kubemodel.Volume.labels:type_name -> kubemodel.Volume.LabelsEntry
-	3,  // 1: kubemodel.Volume.annotations:type_name -> kubemodel.Volume.AnnotationsEntry
-	6,  // 2: kubemodel.Volume.creationTime:type_name -> google.protobuf.Timestamp
-	6,  // 3: kubemodel.Volume.deletionTime:type_name -> google.protobuf.Timestamp
-	7,  // 4: kubemodel.Volume.diagnostic:type_name -> kubemodel.DiagnosticResult
-	4,  // 5: kubemodel.PersistentVolumeClaim.labels:type_name -> kubemodel.PersistentVolumeClaim.LabelsEntry
-	5,  // 6: kubemodel.PersistentVolumeClaim.annotations:type_name -> kubemodel.PersistentVolumeClaim.AnnotationsEntry
-	6,  // 7: kubemodel.PersistentVolumeClaim.creationTime:type_name -> google.protobuf.Timestamp
-	6,  // 8: kubemodel.PersistentVolumeClaim.deletionTime:type_name -> google.protobuf.Timestamp
-	7,  // 9: kubemodel.PersistentVolumeClaim.diagnostic:type_name -> kubemodel.DiagnosticResult
-	10, // [10:10] is the sub-list for method output_type
-	10, // [10:10] is the sub-list for method input_type
-	10, // [10:10] is the sub-list for extension type_name
-	10, // [10:10] is the sub-list for extension extendee
-	0,  // [0:10] is the sub-list for field type_name
-}
-
-func init() { file_kubemodel_storage_proto_init() }
-func file_kubemodel_storage_proto_init() {
-	if File_kubemodel_storage_proto != nil {
-		return
-	}
-	file_kubemodel_diagnostic_proto_init()
-	file_kubemodel_storage_proto_msgTypes[0].OneofWrappers = []any{}
-	file_kubemodel_storage_proto_msgTypes[1].OneofWrappers = []any{}
-	type x struct{}
-	out := protoimpl.TypeBuilder{
-		File: protoimpl.DescBuilder{
-			GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
-			RawDescriptor: unsafe.Slice(unsafe.StringData(file_kubemodel_storage_proto_rawDesc), len(file_kubemodel_storage_proto_rawDesc)),
-			NumEnums:      0,
-			NumMessages:   6,
-			NumExtensions: 0,
-			NumServices:   0,
-		},
-		GoTypes:           file_kubemodel_storage_proto_goTypes,
-		DependencyIndexes: file_kubemodel_storage_proto_depIdxs,
-		MessageInfos:      file_kubemodel_storage_proto_msgTypes,
-	}.Build()
-	File_kubemodel_storage_proto = out.File
-	file_kubemodel_storage_proto_goTypes = nil
-	file_kubemodel_storage_proto_depIdxs = nil
-}

+ 0 - 9
core/pkg/model/shared/usagetype.go

@@ -1,9 +0,0 @@
-package shared
-
-type UsageType string
-
-const (
-	UsageTypeEmpty    UsageType = ""
-	UsageTypeOnDemand UsageType = "OnDemand"
-	UsageTypeSpot     UsageType = "Spot"
-)

+ 39 - 42
core/pkg/opencost/exporter/controllers.go

@@ -42,6 +42,17 @@ type PipelinesExportConfig struct {
 	Compression                       ExportCompressionLevel
 }
 
+func (c PipelinesExportConfig) toControllerConfig(res time.Duration) ComputeExporterConfig {
+	return ComputeExporterConfig{
+		AppName:     c.AppName,
+		ClusterUID:  c.ClusterUID,
+		ClusterName: c.ClusterName,
+		Resolution:  res,
+		Streaming:   c.Streaming,
+		Compression: c.Compression,
+	}
+}
+
 // defaultPipelineExportResolutions returns the default export configuration for the pipeline
 // which is set to export hourly and daily.
 func defaultPipelineExportResolutions() []time.Duration {
@@ -53,18 +64,24 @@ func defaultPipelineExportResolutions() []time.Duration {
 
 // NewPipelinesExportConfig returns the default export configuration for all pipelines
 // which is set to export hourly and daily for allocations, assets, and network insights.
-func NewPipelinesExportConfig(appName, clusterUID, clusterName string) PipelinesExportConfig {
-	return PipelinesExportConfig{
-		AppName:                           appName,
-		ClusterUID:                        clusterUID,
-		ClusterName:                       clusterName,
-		AllocationPiplineResolutions:      defaultPipelineExportResolutions(),
-		AssetPipelineResolutons:           defaultPipelineExportResolutions(),
-		NetworkInsightPipelineResolutions: defaultPipelineExportResolutions(),
-		KubeModelPipelineResolutions:      defaultPipelineExportResolutions(),
-		Streaming:                         false,
-		Compression:                       ExportCompressionLevelNone,
+func NewPipelinesExportConfig(appName, clusterUID, clusterName string, exportLegacy, exportKubeModel bool) PipelinesExportConfig {
+	config := PipelinesExportConfig{
+		AppName:     appName,
+		ClusterUID:  clusterUID,
+		ClusterName: clusterName,
+		Compression: ExportCompressionLevelNone,
 	}
+	if exportLegacy {
+		config.AllocationPiplineResolutions = defaultPipelineExportResolutions()
+		config.AssetPipelineResolutons = defaultPipelineExportResolutions()
+		config.NetworkInsightPipelineResolutions = defaultPipelineExportResolutions()
+
+	}
+	if exportKubeModel {
+		config.KubeModelPipelineResolutions = defaultPipelineExportResolutions()
+	}
+
+	return config
 }
 
 // PipelineExportControllers is a facade that contains the export controllers for allocations, assets, and network insights.
@@ -96,14 +113,9 @@ func NewPipelineExportControllers(store storage.Storage, cm ComputePipelineSourc
 			continue
 		}
 
-		// Use ClusterName for "clusterId" here to maintain legacy pattern
-		var allocController *export.ComputeExportController[opencost.AllocationSet]
-		var err error
-		if config.Streaming {
-			allocController, err = NewStreamingComputePipelineExportController(config.ClusterName, store, allocSource, res, config.Compression)
-		} else {
-			allocController, err = NewComputePipelineExportController(config.ClusterName, store, allocSource, res)
-		}
+		controllerConfig := config.toControllerConfig(res)
+		allocController, err := NewComputePipelineExportController(controllerConfig, store, allocSource)
+
 		if err != nil {
 			log.Errorf("Failed to create allocation export controller for resolution: %s - %v", timeutil.DurationString(res), err)
 			continue
@@ -122,14 +134,9 @@ func NewPipelineExportControllers(store storage.Storage, cm ComputePipelineSourc
 			continue
 		}
 
-		// Use ClusterName for "clusterId" here to maintain legacy pattern
-		var assetController *export.ComputeExportController[opencost.AssetSet]
-		var err error
-		if config.Streaming {
-			assetController, err = NewStreamingComputePipelineExportController(config.ClusterName, store, assetSource, res, config.Compression)
-		} else {
-			assetController, err = NewComputePipelineExportController(config.ClusterName, store, assetSource, res)
-		}
+		controllerConfig := config.toControllerConfig(res)
+		assetController, err := NewComputePipelineExportController(controllerConfig, store, assetSource)
+
 		if err != nil {
 			log.Errorf("Failed to create asset export controller for resolution: %s - %v", timeutil.DurationString(res), err)
 			continue
@@ -148,14 +155,9 @@ func NewPipelineExportControllers(store storage.Storage, cm ComputePipelineSourc
 			continue
 		}
 
-		// Use ClusterName for "clusterId" here to maintain legacy pattern
-		var networkInsightController *export.ComputeExportController[opencost.NetworkInsightSet]
-		var err error
-		if config.Streaming {
-			networkInsightController, err = NewStreamingComputePipelineExportController(config.ClusterName, store, networkInsightSource, res, config.Compression)
-		} else {
-			networkInsightController, err = NewComputePipelineExportController(config.ClusterName, store, networkInsightSource, res)
-		}
+		controllerConfig := config.toControllerConfig(res)
+		networkInsightController, err := NewComputePipelineExportController(controllerConfig, store, networkInsightSource)
+
 		if err != nil {
 			log.Errorf("Failed to create network insight export controller for resolution: %s - %v", timeutil.DurationString(res), err)
 			continue
@@ -174,13 +176,8 @@ func NewPipelineExportControllers(store storage.Storage, cm ComputePipelineSourc
 			continue
 		}
 
-		var kubeModelController *export.ComputeExportController[kubemodel.KubeModelSet]
-		var err error
-		if config.Streaming {
-			kubeModelController, err = NewStreamingKubeModelComputePipelineExportController(config.AppName, config.ClusterUID, store, kubeModelSource, res, config.Compression)
-		} else {
-			kubeModelController, err = NewKubeModelComputePipelineExportController(config.AppName, config.ClusterUID, store, kubeModelSource, res)
-		}
+		controllerConfig := config.toControllerConfig(res)
+		kubeModelController, err := NewComputePipelineExportController(controllerConfig, store, kubeModelSource)
 
 		if err != nil {
 			log.Errorf("Failed to create KubeModel export controller for resolution: %s - %v", timeutil.DurationString(res), err)

+ 20 - 20
core/pkg/opencost/exporter/exporter_test.go

@@ -167,12 +167,12 @@ func TestExporters(t *testing.T) {
 	t.Run("allocation exporter", func(t *testing.T) {
 		allocSource := NewMockAllocationSource()
 		memStore := storage.NewMemoryStorage()
-		p, err := pathing.NewDefaultStoragePathFormatter(TestClusterName, pipelines.AllocationPipelineName, ptr(TestResolution))
+		p, err := pathing.NewDefaultStoragePathFormatter(TestAppName, TestClusterID, TestClusterName, pipelines.AllocationPipelineName, ptr(TestResolution))
 		if err != nil {
 			t.Fatalf("failed to create path formatter: %v", err)
 		}
 
-		allocExporter, err := NewComputePipelineExporter[opencost.AllocationSet](TestClusterName, TestResolution, memStore)
+		allocExporter, err := NewComputePipelineExporter[opencost.AllocationSet](ComputeExporterConfig{AppName: TestAppName, ClusterUID: TestClusterID, ClusterName: TestClusterName, Resolution: TestResolution}, memStore)
 		if err != nil {
 			t.Fatalf("failed to create allocation exporter: %v", err)
 		}
@@ -196,12 +196,12 @@ func TestExporters(t *testing.T) {
 	t.Run("asset exporter", func(t *testing.T) {
 		assetSource := NewMockAssetSource()
 		memStore := storage.NewMemoryStorage()
-		p, err := pathing.NewDefaultStoragePathFormatter(TestClusterName, pipelines.AssetsPipelineName, ptr(TestResolution))
+		p, err := pathing.NewDefaultStoragePathFormatter(TestAppName, TestClusterID, TestClusterName, pipelines.AssetsPipelineName, ptr(TestResolution))
 		if err != nil {
 			t.Fatalf("failed to create path formatter: %v", err)
 		}
 
-		assetExporter, err := NewComputePipelineExporter[opencost.AssetSet](TestClusterName, TestResolution, memStore)
+		assetExporter, err := NewComputePipelineExporter[opencost.AssetSet](ComputeExporterConfig{AppName: TestAppName, ClusterUID: TestClusterID, ClusterName: TestClusterName, Resolution: TestResolution}, memStore)
 		if err != nil {
 			t.Fatalf("failed to create allocation exporter: %v", err)
 		}
@@ -225,12 +225,12 @@ func TestExporters(t *testing.T) {
 	t.Run("network insight exporter", func(t *testing.T) {
 		netInsightSource := NewMockNetworkInsightSource()
 		memStore := storage.NewMemoryStorage()
-		p, err := pathing.NewDefaultStoragePathFormatter(TestClusterName, pipelines.NetworkInsightPipelineName, ptr(TestResolution))
+		p, err := pathing.NewDefaultStoragePathFormatter(TestAppName, TestClusterID, TestClusterName, pipelines.NetworkInsightPipelineName, ptr(TestResolution))
 		if err != nil {
 			t.Fatalf("failed to create path formatter: %v", err)
 		}
 
-		netInsightExporter, err := NewComputePipelineExporter[opencost.NetworkInsightSet](TestClusterName, TestResolution, memStore)
+		netInsightExporter, err := NewComputePipelineExporter[opencost.NetworkInsightSet](ComputeExporterConfig{AppName: TestAppName, ClusterUID: TestClusterID, ClusterName: TestClusterName, Resolution: TestResolution}, memStore)
 		if err != nil {
 			t.Fatalf("failed to create net insights exporter: %v", err)
 		}
@@ -260,7 +260,7 @@ func TestExporters(t *testing.T) {
 			t.Fatalf("failed to create path formatter: %v", err)
 		}
 
-		kubeModelExporter, err := NewKubeModelComputePipelineExporter[kubemodel.KubeModelSet](TestAppName, TestClusterID, TestResolution, memStore)
+		kubeModelExporter, err := NewComputePipelineExporter[kubemodel.KubeModelSet](ComputeExporterConfig{AppName: TestAppName, ClusterUID: TestClusterID, Resolution: TestResolution}, memStore)
 		if err != nil {
 			t.Fatalf("failed to create KubeModel exporter: %v", err)
 		}
@@ -278,20 +278,20 @@ func TestExporters(t *testing.T) {
 			t.Fatalf("failed to export KubeModel data: %v", err)
 		}
 
-		validateFileCreation[kubemodel.KubeModelSet](t, memStore, p, exporter.BingenExt, start, end)
+		validateFileCreation[kubemodel.KubeModelSet](t, memStore, p, "", start, end)
 	})
 
 	t.Run("unknown exporter", func(t *testing.T) {
 		memStore := storage.NewMemoryStorage()
 
 		// Invalid pipeline
-		_, err := NewComputePipelineExporter[UnknownSet](TestClusterName, TestResolution, memStore)
+		_, err := NewComputePipelineExporter[UnknownSet](ComputeExporterConfig{ClusterName: TestClusterName, Resolution: TestResolution}, memStore)
 		if err == nil {
 			t.Fatalf("expected error creating unknown pipeline exporter, got nil")
 		}
 
-		// Invalid cluster id
-		_, err = NewComputePipelineExporter[opencost.AllocationSet]("", TestResolution, memStore)
+		// Invalid cluster name
+		_, err = NewComputePipelineExporter[opencost.AllocationSet](ComputeExporterConfig{ClusterName: "", Resolution: TestResolution}, memStore)
 		if err == nil {
 			t.Fatalf("expected error creating allocation pipeline exporter with empty cluster id, got nil")
 		}
@@ -320,15 +320,15 @@ func TestPipelineExportControllers(t *testing.T) {
 		time.Sleep(time.Second + (750 * time.Millisecond))
 		exportControllers.Stop()
 
-		allocPath, err := pathing.NewDefaultStoragePathFormatter(TestClusterName, pipelines.AllocationPipelineName, ptr(TestResolution))
+		allocPath, err := pathing.NewDefaultStoragePathFormatter(TestAppName, TestClusterID, TestClusterName, pipelines.AllocationPipelineName, ptr(TestResolution))
 		if err != nil {
 			t.Fatalf("failed to create allocations path formatter: %v", err)
 		}
-		assetPath, err := pathing.NewDefaultStoragePathFormatter(TestClusterName, pipelines.AssetsPipelineName, ptr(TestResolution))
+		assetPath, err := pathing.NewDefaultStoragePathFormatter(TestAppName, TestClusterID, TestClusterName, pipelines.AssetsPipelineName, ptr(TestResolution))
 		if err != nil {
 			t.Fatalf("failed to create assets path formatter: %v", err)
 		}
-		netPath, err := pathing.NewDefaultStoragePathFormatter(TestClusterName, pipelines.NetworkInsightPipelineName, ptr(TestResolution))
+		netPath, err := pathing.NewDefaultStoragePathFormatter(TestAppName, TestClusterID, TestClusterName, pipelines.NetworkInsightPipelineName, ptr(TestResolution))
 		if err != nil {
 			t.Fatalf("failed to create net insights path formatter: %v", err)
 		}
@@ -359,15 +359,15 @@ func TestPipelineExportControllers(t *testing.T) {
 		time.Sleep(time.Second + (750 * time.Millisecond))
 		exportControllers.Stop()
 
-		allocPath, err := pathing.NewDefaultStoragePathFormatter(TestClusterName, pipelines.AllocationPipelineName, ptr(TestResolution))
+		allocPath, err := pathing.NewDefaultStoragePathFormatter(TestAppName, TestClusterID, TestClusterName, pipelines.AllocationPipelineName, ptr(TestResolution))
 		if err != nil {
 			t.Fatalf("failed to create allocations path formatter: %v", err)
 		}
-		assetPath, err := pathing.NewDefaultStoragePathFormatter(TestClusterName, pipelines.AssetsPipelineName, ptr(TestResolution))
+		assetPath, err := pathing.NewDefaultStoragePathFormatter(TestAppName, TestClusterID, TestClusterName, pipelines.AssetsPipelineName, ptr(TestResolution))
 		if err != nil {
 			t.Fatalf("failed to create assets path formatter: %v", err)
 		}
-		netPath, err := pathing.NewDefaultStoragePathFormatter(TestClusterName, pipelines.NetworkInsightPipelineName, ptr(TestResolution))
+		netPath, err := pathing.NewDefaultStoragePathFormatter(TestAppName, TestClusterID, TestClusterName, pipelines.NetworkInsightPipelineName, ptr(TestResolution))
 		if err != nil {
 			t.Fatalf("failed to create net insights path formatter: %v", err)
 		}
@@ -381,7 +381,7 @@ func TestPipelineExportControllers(t *testing.T) {
 		pipelineComputeSource := NewMockPipelineComputeSource()
 		memStore := storage.NewMemoryStorage()
 
-		exportControllers := NewPipelineExportControllers(memStore, pipelineComputeSource, NewPipelinesExportConfig(TestAppName, TestClusterID, TestClusterName))
+		exportControllers := NewPipelineExportControllers(memStore, pipelineComputeSource, NewPipelinesExportConfig(TestAppName, TestClusterID, TestClusterName, true, false))
 
 		if len(exportControllers.AllocationExportController.Resolutions()) != 2 {
 			t.Fatalf("expected 2 allocation resolutions, got %d", len(exportControllers.AllocationExportController.Resolutions()))
@@ -399,7 +399,7 @@ func TestPipelineExportControllers(t *testing.T) {
 		pipelineComputeSource := NewMockPipelineComputeSourceWith(48 * time.Hour)
 		memStore := storage.NewMemoryStorage()
 
-		exportControllers := NewPipelineExportControllers(memStore, pipelineComputeSource, NewPipelinesExportConfig(TestAppName, TestClusterID, TestClusterName))
+		exportControllers := NewPipelineExportControllers(memStore, pipelineComputeSource, NewPipelinesExportConfig(TestAppName, TestClusterID, TestClusterName, true, true))
 
 		if len(exportControllers.AllocationExportController.Resolutions()) != 0 {
 			t.Fatalf("expected 0 allocation resolutions, got %d", len(exportControllers.AllocationExportController.Resolutions()))
@@ -416,7 +416,7 @@ func TestPipelineExportControllers(t *testing.T) {
 		pipelineComputeSource := NewMockPipelineComputeSource()
 		memStore := storage.NewMemoryStorage()
 
-		exportControllers := NewPipelineExportControllers(memStore, pipelineComputeSource, NewPipelinesExportConfig("", "", ""))
+		exportControllers := NewPipelineExportControllers(memStore, pipelineComputeSource, NewPipelinesExportConfig("", "", "", false, false))
 
 		if len(exportControllers.AllocationExportController.Resolutions()) != 0 {
 			t.Fatalf("expected 0 allocation resolutions, got %d", len(exportControllers.AllocationExportController.Resolutions()))

+ 20 - 165
core/pkg/opencost/exporter/exporters.go

@@ -10,7 +10,6 @@ import (
 	"github.com/opencost/opencost/core/pkg/exporter/validator"
 	"github.com/opencost/opencost/core/pkg/pipelines"
 	"github.com/opencost/opencost/core/pkg/storage"
-	"github.com/opencost/opencost/core/pkg/util/timeutil"
 	"github.com/opencost/opencost/core/pkg/util/typeutil"
 )
 
@@ -36,60 +35,38 @@ const (
 	ExportCompressionLevelDefault         ExportCompressionLevel = gzip.DefaultCompression
 )
 
-// NewComputePipelineExporter creates a new `ComputeExporter[T]` instance which is used to export computed data
-// by window for a specific pipeline.
-func NewComputePipelineExporter[T any, U export.BinaryMarshalerPtr[T], S validator.SetConstraint[T]](
-	clusterName string,
-	resolution time.Duration,
-	store storage.Storage,
-) (export.ComputeExporter[T], error) {
-	pipelineName := pipelines.NameFor[T]()
-	if pipelineName == "" {
-		return nil, fmt.Errorf("failed to extract pipeline name for type: %s", typeutil.TypeOf[T]())
-	}
-
-	pathing, err := pathing.NewDefaultStoragePathFormatter(clusterName, pipelineName, &resolution)
-	if err != nil {
-		return nil, fmt.Errorf("failed to create path formatter: %w", err)
-	}
-
-	var encoder export.Encoder[T]
-	encoder = export.NewBingenEncoder[T, U]()
-
-	return export.NewComputeStorageExporter(
-		pathing,
-		encoder,
-		store,
-		validator.NewSetValidator[T, S](resolution),
-		false,
-	), nil
+type ComputeExporterConfig struct {
+	AppName     string
+	ClusterUID  string
+	ClusterName string
+	Resolution  time.Duration
+	Streaming   bool
+	Compression ExportCompressionLevel
 }
 
-// NewStreamingComputePipelineExporter creates a new `ComputeExporter[T]` instance which is used to export computed data
+// NewComputePipelineExporter creates a new `ComputeExporter[T]` instance which is used to export computed data
 // by window for a specific pipeline.
-func NewStreamingComputePipelineExporter[T any, U export.BinaryMarshalerPtr[T], S validator.SetConstraint[T]](
-	clusterId string,
-	resolution time.Duration,
+func NewComputePipelineExporter[T any, U export.BinaryMarshalerPtr[T], S validator.SetConstraint[T]](
+	config ComputeExporterConfig,
 	store storage.Storage,
-	compressionLevel ExportCompressionLevel,
 ) (export.ComputeExporter[T], error) {
 	pipelineName := pipelines.NameFor[T]()
 	if pipelineName == "" {
 		return nil, fmt.Errorf("failed to extract pipeline name for type: %s", typeutil.TypeOf[T]())
 	}
 
-	pathing, err := pathing.NewDefaultStoragePathFormatter(clusterId, pipelineName, &resolution)
+	pathing, err := pathing.NewDefaultStoragePathFormatter(config.AppName, config.ClusterUID, config.ClusterName, pipelineName, &config.Resolution)
 	if err != nil {
 		return nil, fmt.Errorf("failed to create path formatter: %w", err)
 	}
 
-	if !compressionLevel.IsValid() {
-		return nil, fmt.Errorf("invalid compression level passed: %d is not a valid compression level", int(compressionLevel))
+	if !config.Compression.IsValid() {
+		return nil, fmt.Errorf("invalid compression level passed: %d is not a valid compression level", int(config.Compression))
 	}
 
 	var encoder export.Encoder[T]
-	if compressionLevel != ExportCompressionLevelNone {
-		encoder = export.NewGZipEncoderWithLevel(export.NewBingenEncoder[T, U](), int(compressionLevel))
+	if config.Streaming && config.Compression != ExportCompressionLevelNone {
+		encoder = export.NewGZipEncoderWithLevel(export.NewBingenEncoder[T, U](), int(config.Compression))
 	} else {
 		encoder = export.NewBingenEncoder[T, U]()
 	}
@@ -98,144 +75,22 @@ func NewStreamingComputePipelineExporter[T any, U export.BinaryMarshalerPtr[T],
 		pathing,
 		encoder,
 		store,
-		validator.NewSetValidator[T, S](resolution),
-		true,
+		validator.NewSetValidator[T, S](config.Resolution),
+		config.Streaming,
 	), nil
 }
 
 // NewComputePipelineExportController creates a new `ComputeExportController[T]` instance which is used to export computed data
 // using the provided source, storage, resolution, and source resolution.
 func NewComputePipelineExportController[T any, U export.BinaryMarshalerPtr[T], S validator.SetConstraint[T]](
-	clusterName string,
-	store storage.Storage,
-	source export.ComputeSource[T],
-	resolution time.Duration,
-) (*export.ComputeExportController[T], error) {
-	exporter, err := NewComputePipelineExporter[T, U, S](clusterName, resolution, store)
-	if err != nil {
-		return nil, fmt.Errorf("failed to create compute exporter: %w", err)
-	}
-
-	return export.NewComputeExportController(source, exporter, resolution), nil
-}
-
-// NewStreamingComputePipelineExportController creates a new `ComputeExportController[T]` instance which is used to stream/export the
-// computed data using the provided source, storage, resolution, and source resolution.
-func NewStreamingComputePipelineExportController[T any, U export.BinaryMarshalerPtr[T], S validator.SetConstraint[T]](
-	clusterId string,
-	store storage.Storage,
-	source export.ComputeSource[T],
-	resolution time.Duration,
-	compressionLevel ExportCompressionLevel,
-) (*export.ComputeExportController[T], error) {
-	exporter, err := NewStreamingComputePipelineExporter[T, U, S](clusterId, resolution, store, compressionLevel)
-	if err != nil {
-		return nil, fmt.Errorf("failed to create compute exporter: %w", err)
-	}
-
-	return export.NewComputeExportController(source, exporter, resolution), nil
-}
-
-// NewKubeModelComputePipelineExporter creates a new `ComputeExporter[T]` instance which is used to export computed data
-// by window for a specific pipeline.
-func NewKubeModelComputePipelineExporter[T any, U export.BinaryMarshalerPtr[T], S validator.SetConstraint[T]](
-	appName string,
-	clusterId string,
-	resolution time.Duration,
-	store storage.Storage,
-) (export.ComputeExporter[T], error) {
-	pipelineName := pipelines.NameFor[T]()
-	if pipelineName == "" {
-		return nil, fmt.Errorf("failed to extract pipeline name for type: %s", typeutil.TypeOf[T]())
-	}
-	res := timeutil.FormatStoreResolution(resolution)
-	pathing, err := pathing.NewKubeModelStoragePathFormatter(appName, clusterId, res)
-	if err != nil {
-		return nil, fmt.Errorf("failed to create path formatter: %w", err)
-	}
-
-	encoder := export.NewBingenFileEncoder[T, U]()
-
-	return export.NewComputeStorageExporter(
-		pathing,
-		encoder,
-		store,
-		validator.NewSetValidator[T, S](resolution),
-		false,
-	), nil
-}
-
-// NewStreamingComputePipelineExporter creates a new `ComputeExporter[T]` instance which is used to export computed data
-// by window for a specific pipeline.
-func NewStreamingKubeModelComputePipelineExporter[T any, U export.BinaryMarshalerPtr[T], S validator.SetConstraint[T]](
-	appName string,
-	clusterId string,
-	resolution time.Duration,
-	store storage.Storage,
-	compressionLevel ExportCompressionLevel,
-) (export.ComputeExporter[T], error) {
-	pipelineName := pipelines.NameFor[T]()
-	if pipelineName == "" {
-		return nil, fmt.Errorf("failed to extract pipeline name for type: %s", typeutil.TypeOf[T]())
-	}
-
-	res := timeutil.FormatStoreResolution(resolution)
-	pathing, err := pathing.NewKubeModelStoragePathFormatter(appName, clusterId, res)
-	if err != nil {
-		return nil, fmt.Errorf("failed to create path formatter: %w", err)
-	}
-
-	if !compressionLevel.IsValid() {
-		return nil, fmt.Errorf("invalid compression level passed: %d is not a valid compression level", int(compressionLevel))
-	}
-
-	var encoder export.Encoder[T]
-	if compressionLevel != ExportCompressionLevelNone {
-		encoder = export.NewGZipEncoderWithLevel(export.NewBingenEncoder[T, U](), int(compressionLevel))
-	} else {
-		encoder = export.NewBingenEncoder[T, U]()
-	}
-
-	return export.NewComputeStorageExporter(
-		pathing,
-		encoder,
-		store,
-		validator.NewSetValidator[T, S](resolution),
-		true,
-	), nil
-}
-
-// NewKubeModelComputePipelineExportController creates a new `ComputeExportController[T]` instance which is used to export computed data
-// using the provided source, storage, resolution, and source resolution.
-func NewKubeModelComputePipelineExportController[T any, U export.BinaryMarshalerPtr[T], S validator.SetConstraint[T]](
-	appName string,
-	clusterId string,
-	store storage.Storage,
-	source export.ComputeSource[T],
-	resolution time.Duration,
-) (*export.ComputeExportController[T], error) {
-	exporter, err := NewKubeModelComputePipelineExporter[T, U, S](appName, clusterId, resolution, store)
-	if err != nil {
-		return nil, fmt.Errorf("failed to create compute exporter: %w", err)
-	}
-
-	return export.NewComputeExportController(source, exporter, resolution), nil
-}
-
-// NewStreamingComputePipelineExportController creates a new `ComputeExportController[T]` instance which is used to stream/export the
-// computed data using the provided source, storage, resolution, and source resolution.
-func NewStreamingKubeModelComputePipelineExportController[T any, U export.BinaryMarshalerPtr[T], S validator.SetConstraint[T]](
-	appName string,
-	clusterId string,
+	config ComputeExporterConfig,
 	store storage.Storage,
 	source export.ComputeSource[T],
-	resolution time.Duration,
-	compressionLevel ExportCompressionLevel,
 ) (*export.ComputeExportController[T], error) {
-	exporter, err := NewStreamingKubeModelComputePipelineExporter[T, U, S](appName, clusterId, resolution, store, compressionLevel)
+	exporter, err := NewComputePipelineExporter[T, U, S](config, store)
 	if err != nil {
 		return nil, fmt.Errorf("failed to create compute exporter: %w", err)
 	}
 
-	return export.NewComputeExportController(source, exporter, resolution), nil
+	return export.NewComputeExportController(source, exporter, config.Resolution), nil
 }

+ 4 - 8
pkg/kubemodel/pipeline.go

@@ -4,15 +4,15 @@ import (
 	"fmt"
 	"time"
 
+	"github.com/opencost/opencost/core/pkg/env"
 	ocexporter "github.com/opencost/opencost/core/pkg/opencost/exporter"
 	"github.com/opencost/opencost/core/pkg/storage"
 	"github.com/opencost/opencost/core/pkg/util/timeutil"
 )
 
 var (
-	exportInterval     = 5 * time.Minute
-	janitorInterval    = timeutil.Day
-	defaultResolutions = []time.Duration{time.Hour, timeutil.Day}
+	exportInterval  = 5 * time.Minute
+	janitorInterval = timeutil.Day
 )
 
 // Pipeline manages the KubeModel export controller group and the retention janitor.
@@ -30,11 +30,7 @@ func NewPipeline(appName, clusterUID string, store storage.Storage, cm ocexporte
 		return nil, fmt.Errorf("NewPipeline: clusterUID cannot be empty")
 	}
 
-	config := ocexporter.PipelinesExportConfig{
-		AppName:                      appName,
-		ClusterUID:                   clusterUID,
-		KubeModelPipelineResolutions: defaultResolutions,
-	}
+	config := ocexporter.NewPipelinesExportConfig(appName, clusterUID, "", false, env.GetExportKubeModel())
 
 	controllers := ocexporter.NewPipelineExportControllers(store, cm, config)