usage.go 2.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. package usage
  2. import (
  3. "time"
  4. "github.com/porter-dev/porter/api/server/shared/config/env"
  5. "github.com/porter-dev/porter/internal/adapter"
  6. "github.com/porter-dev/porter/internal/models"
  7. "github.com/porter-dev/porter/internal/repository"
  8. "github.com/porter-dev/porter/internal/usage"
  9. "golang.org/x/oauth2"
  10. "gorm.io/gorm"
  11. rgorm "github.com/porter-dev/porter/internal/repository/gorm"
  12. )
  13. type UsageTracker struct {
  14. db *gorm.DB
  15. repo repository.Repository
  16. doConf *oauth2.Config
  17. }
  18. type UsageTrackerOpts struct {
  19. DBConf *env.DBConf
  20. DOConf *oauth2.Config
  21. }
  22. const stepSize = 100
  23. func NewUsageTracker(opts *UsageTrackerOpts) (*UsageTracker, error) {
  24. db, err := adapter.New(opts.DBConf)
  25. if err != nil {
  26. return nil, err
  27. }
  28. var key [32]byte
  29. for i, b := range []byte(opts.DBConf.EncryptionKey) {
  30. key[i] = b
  31. }
  32. repo := rgorm.NewRepository(db, &key)
  33. return &UsageTracker{db, repo, opts.DOConf}, nil
  34. }
  35. type UsageTrackerResponse struct {
  36. ResourceCPU uint
  37. ResourceMemory uint
  38. Exceeded bool
  39. ExceededSince *time.Time
  40. }
  41. func (u *UsageTracker) GetProjectUsage() (map[uint]*UsageTrackerResponse, error) {
  42. res := make(map[uint]*UsageTrackerResponse)
  43. // get the count of the projects
  44. var count int64
  45. if err := u.db.Model(&models.Project{}).Count(&count).Error; err != nil {
  46. return nil, err
  47. }
  48. // iterate (count / stepSize) + 1 times using Limit and Offset
  49. for i := 0; i < (int(count)/stepSize)+1; i++ {
  50. projects := []*models.Project{}
  51. if err := u.db.Order("id asc").Offset(i * stepSize).Limit(stepSize).Find(&projects).Error; err != nil {
  52. return nil, err
  53. }
  54. // go through each project
  55. for _, project := range projects {
  56. _, _, cache, err := usage.GetUsage(&usage.GetUsageOpts{
  57. Repo: u.repo,
  58. DOConf: u.doConf,
  59. Project: project,
  60. })
  61. if err != nil {
  62. continue
  63. }
  64. if cache.Exceeded {
  65. res[project.ID] = &UsageTrackerResponse{
  66. ResourceCPU: cache.ResourceCPU,
  67. ResourceMemory: cache.ResourceMemory,
  68. Exceeded: cache.Exceeded,
  69. ExceededSince: cache.ExceededSince,
  70. }
  71. }
  72. }
  73. }
  74. return res, nil
  75. }