config.go 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. package prom
  2. import (
  3. "crypto/x509"
  4. "fmt"
  5. "time"
  6. coreenv "github.com/opencost/opencost/core/pkg/env"
  7. "github.com/opencost/opencost/core/pkg/log"
  8. "github.com/opencost/opencost/modules/prometheus-source/pkg/env"
  9. restclient "k8s.io/client-go/rest"
  10. certutil "k8s.io/client-go/util/cert"
  11. )
  12. const (
  13. ServiceCA = `/var/run/secrets/kubernetes.io/serviceaccount/service-ca.crt`
  14. )
  15. type OpenCostPrometheusConfig struct {
  16. ServerEndpoint string
  17. Version string
  18. IsOffsetResolution bool
  19. ClientConfig *PrometheusClientConfig
  20. ScrapeInterval time.Duration
  21. JobName string
  22. Offset string
  23. QueryOffset time.Duration
  24. MaxQueryDuration time.Duration
  25. ClusterLabel string
  26. ClusterID string
  27. ClusterFilter string
  28. DataResolution time.Duration
  29. DataResolutionMinutes int
  30. }
  31. func (ocpc *OpenCostPrometheusConfig) IsRateLimitRetryEnabled() bool {
  32. return ocpc.ClientConfig.RateLimitRetryOpts != nil
  33. }
  34. // NewOpenCostPrometheusConfigFromEnv creates a new OpenCostPrometheusConfig from environment variables.
  35. func NewOpenCostPrometheusConfigFromEnv() (*OpenCostPrometheusConfig, error) {
  36. serverEndpoint := env.GetPrometheusServerEndpoint()
  37. if serverEndpoint == "" {
  38. return nil, fmt.Errorf("no address for prometheus set in $%s", env.PrometheusServerEndpointEnvVar)
  39. }
  40. queryConcurrency := env.GetMaxQueryConcurrency()
  41. log.Infof("Prometheus Client Max Concurrency set to %d", queryConcurrency)
  42. timeout := env.GetPrometheusQueryTimeout()
  43. keepAlive := env.GetPrometheusKeepAlive()
  44. tlsHandshakeTimeout := env.GetPrometheusTLSHandshakeTimeout()
  45. jobName := env.GetJobName()
  46. scrapeInterval := env.GetScrapeInterval()
  47. maxQueryDuration := env.GetPrometheusMaxQueryDuration()
  48. clusterId := coreenv.GetClusterID()
  49. clusterLabel := env.GetPromClusterLabel()
  50. clusterFilter := env.GetPromClusterFilter()
  51. var rateLimitRetryOpts *RateLimitRetryOpts = nil
  52. if env.IsPrometheusRetryOnRateLimitResponse() {
  53. rateLimitRetryOpts = &RateLimitRetryOpts{
  54. MaxRetries: env.GetPrometheusRetryOnRateLimitMaxRetries(),
  55. DefaultRetryWait: env.GetPrometheusRetryOnRateLimitDefaultWait(),
  56. }
  57. }
  58. auth := &ClientAuth{
  59. Username: env.GetDBBasicAuthUsername(),
  60. Password: env.GetDBBasicAuthUserPassword(),
  61. BearerToken: env.GetDBBearerToken(),
  62. }
  63. // We will use the service account token and service-ca.crt to authenticate with the Prometheus server via kube-rbac-proxy.
  64. // We need to ensure that the service account has the necessary permissions to access the Prometheus server by binding it to the appropriate role.
  65. var tlsCaCert *x509.CertPool
  66. if env.IsKubeRbacProxyEnabled() {
  67. restConfig, err := restclient.InClusterConfig()
  68. if err != nil {
  69. log.Errorf("%s was set to true but failed to get in-cluster config: %s", env.KubeRbacProxyEnabledEnvVar, err)
  70. }
  71. auth.BearerToken = restConfig.BearerToken
  72. tlsCaCert, err = certutil.NewPool(ServiceCA)
  73. if err != nil {
  74. log.Errorf("%s was set to true but failed to load service-ca.crt: %s", env.KubeRbacProxyEnabledEnvVar, err)
  75. }
  76. }
  77. dataResolution := env.GetPrometheusQueryResolution()
  78. // Ensuring if data resolution is less than 60s default it to 1m
  79. resolutionMinutes := int(dataResolution.Minutes())
  80. if resolutionMinutes == 0 {
  81. resolutionMinutes = 1
  82. }
  83. clientConfig := &PrometheusClientConfig{
  84. Timeout: timeout,
  85. KeepAlive: keepAlive,
  86. TLSHandshakeTimeout: tlsHandshakeTimeout,
  87. TLSInsecureSkipVerify: env.IsInsecureSkipVerify(),
  88. RootCAs: tlsCaCert,
  89. RateLimitRetryOpts: rateLimitRetryOpts,
  90. Auth: auth,
  91. QueryConcurrency: queryConcurrency,
  92. QueryLogFile: "",
  93. HeaderXScopeOrgId: env.GetPrometheusHeaderXScopeOrgId(),
  94. }
  95. return &OpenCostPrometheusConfig{
  96. ServerEndpoint: serverEndpoint,
  97. Version: "0.0.0",
  98. IsOffsetResolution: false,
  99. ClientConfig: clientConfig,
  100. ScrapeInterval: scrapeInterval,
  101. JobName: jobName,
  102. Offset: "",
  103. QueryOffset: time.Duration(0),
  104. MaxQueryDuration: maxQueryDuration,
  105. ClusterLabel: clusterLabel,
  106. ClusterID: clusterId,
  107. ClusterFilter: clusterFilter,
  108. DataResolution: dataResolution,
  109. DataResolutionMinutes: resolutionMinutes,
  110. }, nil
  111. }