validate.go 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. package prom
  2. import (
  3. "fmt"
  4. prometheus "github.com/prometheus/client_golang/api"
  5. )
  6. const UpQuery = "up"
  7. // PrometheusMetadata represents a validation result for prometheus running
  8. // opencost.
  9. type PrometheusMetadata struct {
  10. Running bool `json:"running"`
  11. KubecostDataExists bool `json:"kubecostDataExists"`
  12. }
  13. // Validate tells the model what data prometheus has on it.
  14. func Validate(cli prometheus.Client, config *OpenCostPrometheusConfig) (*PrometheusMetadata, error) {
  15. return validate(cli, validationQueryFor(config), config)
  16. }
  17. func validationQueryFor(config *OpenCostPrometheusConfig) string {
  18. if config.Offset != "" {
  19. return fmt.Sprintf("%s offset %s", UpQuery, config.Offset)
  20. }
  21. return UpQuery
  22. }
  23. // validate executes the prometheus query against the provided client.
  24. func validate(cli prometheus.Client, q string, config *OpenCostPrometheusConfig) (*PrometheusMetadata, error) {
  25. ctx := NewContext(cli, config)
  26. resUp, _, err := ctx.QuerySync(q)
  27. if err != nil {
  28. return &PrometheusMetadata{
  29. Running: false,
  30. KubecostDataExists: false,
  31. }, err
  32. }
  33. if len(resUp) == 0 {
  34. return &PrometheusMetadata{
  35. Running: false,
  36. KubecostDataExists: false,
  37. }, fmt.Errorf("no running jobs on Prometheus at %s", ctx.QueryURL().Path)
  38. }
  39. running := false
  40. for _, result := range resUp {
  41. job, err := result.GetString("job")
  42. if err != nil {
  43. // Stop evaluating result if it does not have a job label (continue to next result)
  44. // We don't error here because not every result from `up` will necessarily have a job label.
  45. continue
  46. }
  47. // At least one job is running, so we can set running to true
  48. running = true
  49. if job == config.JobName {
  50. return &PrometheusMetadata{
  51. Running: true,
  52. KubecostDataExists: true,
  53. }, err
  54. }
  55. }
  56. if !running {
  57. return &PrometheusMetadata{
  58. Running: false,
  59. KubecostDataExists: false,
  60. }, fmt.Errorf("up query does not have job names")
  61. }
  62. return &PrometheusMetadata{
  63. Running: true,
  64. KubecostDataExists: false,
  65. }, nil
  66. }