From c9e7087acb94210ba546b5b3efe6bd5b36b696e3 Mon Sep 17 00:00:00 2001 From: pokom Date: Thu, 13 Mar 2025 14:48:43 -0400 Subject: [PATCH] Remove all references to OpenCost Now that the v0.0.5 has been tested out in production, we can remove all references to OpenCost. This removes the flags, configuration, and branches in the codebase. There is still one query that references OpenCost, but that can be removed in a future patch once cloudcost-exporter emits Azure persistent volume costs. --- cmd/bot/config.go | 9 +++-- cmd/bot/main.go | 18 +++++----- cmd/estimator/main.go | 15 ++++---- pkg/costmodel/client.go | 78 +++++++---------------------------------- 4 files changed, 30 insertions(+), 90 deletions(-) diff --git a/cmd/bot/config.go b/cmd/bot/config.go index 94ae1d0..b9abb28 100644 --- a/cmd/bot/config.go +++ b/cmd/bot/config.go @@ -31,11 +31,10 @@ type config struct { GitHub github.Config - IsCI bool `envconfig:"CI"` - PR int `envconfig:"GITHUB_PULL_REQUEST" required:"true"` - Event string `envconfig:"GITHUB_EVENT_NAME"` - LogLevel string `envconfig:"LOG_LEVEL" default:"info"` - UseCloudCostExporterMetrics bool `envconfig:"USE_CLOUD_COST_EXPORTER" default:"false"` + IsCI bool `envconfig:"CI"` + PR int `envconfig:"GITHUB_PULL_REQUEST" required:"true"` + Event string `envconfig:"GITHUB_EVENT_NAME"` + LogLevel string `envconfig:"LOG_LEVEL" default:"info"` } const pullRequestEvent = "pull_request" diff --git a/cmd/bot/main.go b/cmd/bot/main.go index d5454c6..9a1f2df 100644 --- a/cmd/bot/main.go +++ b/cmd/bot/main.go @@ -56,18 +56,16 @@ func realMain(ctx context.Context) error { prometheusClients, err := costmodel.NewClients( &costmodel.ClientConfig{ - Address: cfg.Prometheus.Prod.Address, - HTTPConfigFile: cfg.Prometheus.Prod.HTTPConfigFile, - Username: cfg.Prometheus.Prod.Username, - Password: cfg.Prometheus.Prod.Password, - UseCloudCostExporterMetrics: cfg.UseCloudCostExporterMetrics, + Address: cfg.Prometheus.Prod.Address, + HTTPConfigFile: cfg.Prometheus.Prod.HTTPConfigFile, + Username: cfg.Prometheus.Prod.Username, + Password: cfg.Prometheus.Prod.Password, }, &costmodel.ClientConfig{ - Address: cfg.Prometheus.Dev.Address, - HTTPConfigFile: cfg.Prometheus.Dev.HTTPConfigFile, - Username: cfg.Prometheus.Dev.Username, - Password: cfg.Prometheus.Dev.Password, - UseCloudCostExporterMetrics: cfg.UseCloudCostExporterMetrics, + Address: cfg.Prometheus.Dev.Address, + HTTPConfigFile: cfg.Prometheus.Dev.HTTPConfigFile, + Username: cfg.Prometheus.Dev.Username, + Password: cfg.Prometheus.Dev.Password, }) if err != nil { return fmt.Errorf("creating cost model client: %w", err) diff --git a/cmd/estimator/main.go b/cmd/estimator/main.go index dd6ef10..eafd436 100644 --- a/cmd/estimator/main.go +++ b/cmd/estimator/main.go @@ -11,7 +11,6 @@ import ( func main() { var fromFile, toFile, prometheusAddress, httpConfigFile, reportType, username, password string - var useCloudCostExporterMetrics bool flag.StringVar(&fromFile, "from", "", "The file to compare from") flag.StringVar(&toFile, "to", "", "The file to compare to") flag.StringVar(&prometheusAddress, "prometheus.address", "http://localhost:9093/prometheus", "The Address of the prometheus server") @@ -19,19 +18,18 @@ func main() { flag.StringVar(&username, "username", "", "Mimir username") flag.StringVar(&password, "password", "", "Mimir password") flag.StringVar(&reportType, "report.type", "table", "The type of report to generate. Options are: table, summary") - flag.BoolVar(&useCloudCostExporterMetrics, "use.cloud.cost.exporter.metrics", false, "Whether to use the cloud cost exporter metrics") flag.Parse() clusters := flag.Args() ctx := context.Background() - if err := run(ctx, fromFile, toFile, prometheusAddress, httpConfigFile, reportType, username, password, clusters, useCloudCostExporterMetrics); err != nil { + if err := run(ctx, fromFile, toFile, prometheusAddress, httpConfigFile, reportType, username, password, clusters); err != nil { fmt.Printf("Could not run: %s\n", err) os.Exit(1) } } -func run(ctx context.Context, fromFile, toFile, address, httpConfigFile, reportType, username, password string, clusters []string, useCloudCostExporterMetrics bool) error { +func run(ctx context.Context, fromFile, toFile, address, httpConfigFile, reportType, username, password string, clusters []string) error { from, err := os.ReadFile(fromFile) if err != nil { return fmt.Errorf("could not read file: %s", err) @@ -44,11 +42,10 @@ func run(ctx context.Context, fromFile, toFile, address, httpConfigFile, reportT } client, err := costmodel.NewClient(&costmodel.ClientConfig{ - Address: address, - HTTPConfigFile: httpConfigFile, - Username: username, - Password: password, - UseCloudCostExporterMetrics: useCloudCostExporterMetrics, + Address: address, + HTTPConfigFile: httpConfigFile, + Username: username, + Password: password, }) if err != nil { diff --git a/pkg/costmodel/client.go b/pkg/costmodel/client.go index 66f99cb..0aeb8e5 100644 --- a/pkg/costmodel/client.go +++ b/pkg/costmodel/client.go @@ -16,23 +16,7 @@ import ( ) const ( - queryCostPerCPU = ` -avg by (spot) (node_cpu_hourly_cost{cluster="%s"} -* on (cluster, node) group_left(spot) - group by (cluster, node, spot) ( - label_replace( - label_join(kubecost_node_is_spot == 1, "node", "", "exported_instance") - ,"spot", "true", "", "" - ) - or on (cluster, node) - label_replace( - label_join(kubecost_node_is_spot == 0, "node", "", "exported_instance") - ,"spot", "false", "", "" - ) - ) -) -` - cloudcostExporterQueryCostPerCpu = ` + queryCostPerCpu = ` avg by (price_tier) ( cloudcost_aws_ec2_instance_cpu_usd_per_core_hour{cluster_name="%s"} or @@ -41,24 +25,7 @@ avg by (spot) (node_cpu_hourly_cost{cluster="%s"} cloudcost_gcp_gke_instance_cpu_usd_per_core_hour{cluster_name="%s"} ) ` - queryMemoryCost = ` -avg by (spot) (node_ram_hourly_cost{cluster="%s"} -* on (cluster, node) group_left(spot) - group by (cluster, node, spot) ( - label_replace( - label_join(kubecost_node_is_spot == 1, "node", "", "exported_instance") - ,"spot", "true", "", "" - ) - or on (cluster, node) - label_replace( - label_join(kubecost_node_is_spot == 0, "node", "", "exported_instance") - ,"spot", "false", "", "" - ) - ) -) -` - cloudcostExporterQueryMemoryCost = ` avg by (price_tier) ( cloudcost_aws_ec2_instance_memory_usd_per_gib_hour{cluster_name="%s"} or @@ -67,13 +34,9 @@ avg by (spot) (node_ram_hourly_cost{cluster="%s"} cloudcost_gcp_gke_instance_memory_usd_per_gib_hour{cluster_name="%s"} ) ` + + // TODO(@Pokom): update this query with azure's PVC's cost once https://github.com/grafana/cloudcost-exporter/issues/236 is merged in queryPersistentVolumeCost = ` -avg_over_time( - avg( - pv_hourly_cost{cluster="%s"} - )[24h:1m] -)` - cloudcostQueryPersistentVolumeCost = ` avg( cloudcost_aws_ec2_persistent_volume_usd_per_hour{persistentvolume!="", state="in-use"} / on (persistentvolume) group_left() ( @@ -112,8 +75,7 @@ var ( // Client is a client for the cost model. type Client struct { - client api.Client - useCloudCostExporterMetrics bool + client api.Client } // Clients bundles the dev and prod client in one struct. @@ -124,11 +86,10 @@ type Clients struct { // ClientConfig is the configuration for the cost model client. type ClientConfig struct { - Address string - HTTPConfigFile string - Username string - Password string - UseCloudCostExporterMetrics bool + Address string + HTTPConfigFile string + Username string + Password string } // NewClient creates a new cost model client with the given configuration. @@ -168,8 +129,7 @@ func NewClient(config *ClientConfig) (*Client, error) { return nil, err } return &Client{ - client: client, - useCloudCostExporterMetrics: config.UseCloudCostExporterMetrics, + client: client, }, nil } @@ -189,12 +149,7 @@ func NewClients(prodConfig, devConfig *ClientConfig) (*Clients, error) { // GetCostPerCPU returns the average cost per CPU for a given cluster. func (c *Client) GetCostPerCPU(ctx context.Context, cluster string) (Cost, error) { - query := fmt.Sprintf(queryCostPerCPU, cluster) - // TODO: Remove this once we've removed support for OpenCost - if c.useCloudCostExporterMetrics { - slog.Info("GetMemoryCost", "cluster", cluster, "message", "using cloudcost exporter metrics") - query = fmt.Sprintf(cloudcostExporterQueryCostPerCpu, cluster, cluster, cluster) - } + query := fmt.Sprintf(queryCostPerCpu, cluster, cluster, cluster) results, err := c.query(ctx, query) if err != nil { return Cost{}, err @@ -204,12 +159,7 @@ func (c *Client) GetCostPerCPU(ctx context.Context, cluster string) (Cost, error // GetMemoryCost returns the cost per memory for a given cluster func (c *Client) GetMemoryCost(ctx context.Context, cluster string) (Cost, error) { - query := fmt.Sprintf(queryMemoryCost, cluster) - // TODO: Remove this once we've removed support for OpenCost - if c.useCloudCostExporterMetrics { - slog.Info("GetMemoryCost", "cluster", cluster, "message", "using cloudcost exporter metrics") - query = fmt.Sprintf(cloudcostExporterQueryMemoryCost, cluster, cluster, cluster) - } + query := fmt.Sprintf(queryMemoryCost, cluster, cluster, cluster) results, err := c.query(ctx, query) if err != nil { return Cost{}, err @@ -235,11 +185,7 @@ func (c *Client) GetNodeCount(ctx context.Context, cluster string) (int, error) // GetCostForPersistentVolume returns the average cost per persistent volume for a given cluster func (c *Client) GetCostForPersistentVolume(ctx context.Context, cluster string) (Cost, error) { - query := fmt.Sprintf(queryPersistentVolumeCost, cluster) - if c.useCloudCostExporterMetrics { - slog.Info("GetCostForPersistentVolume", "cluster", cluster, "message", "using cloudcost exporter metrics") - query = fmt.Sprintf(cloudcostQueryPersistentVolumeCost, cluster, cluster, cluster, cluster) - } + query := fmt.Sprintf(queryPersistentVolumeCost, cluster, cluster, cluster, cluster) results, err := c.query(ctx, query) if err != nil { return Cost{}, err