helm_repo.go 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. package gorm
  2. import (
  3. "github.com/porter-dev/porter/internal/encryption"
  4. "github.com/porter-dev/porter/internal/models"
  5. ints "github.com/porter-dev/porter/internal/models/integrations"
  6. "github.com/porter-dev/porter/internal/repository"
  7. "gorm.io/gorm"
  8. )
  9. // HelmRepoRepository uses gorm.DB for querying the database
  10. type HelmRepoRepository struct {
  11. db *gorm.DB
  12. key *[32]byte
  13. }
  14. // NewHelmRepoRepository returns a HelmRepoRepository which uses
  15. // gorm.DB for querying the database
  16. func NewHelmRepoRepository(db *gorm.DB, key *[32]byte) repository.HelmRepoRepository {
  17. return &HelmRepoRepository{db, key}
  18. }
  19. // CreateHelmRepo creates a new helm repo
  20. func (repo *HelmRepoRepository) CreateHelmRepo(hr *models.HelmRepo) (*models.HelmRepo, error) {
  21. err := repo.EncryptHelmRepoData(hr, repo.key)
  22. if err != nil {
  23. return nil, err
  24. }
  25. project := &models.Project{}
  26. if err := repo.db.Where("id = ?", hr.ProjectID).First(&project).Error; err != nil {
  27. return nil, err
  28. }
  29. assoc := repo.db.Model(&project).Association("HelmRepos")
  30. if assoc.Error != nil {
  31. return nil, assoc.Error
  32. }
  33. if err := assoc.Append(hr); err != nil {
  34. return nil, err
  35. }
  36. // create a token cache by default
  37. assoc = repo.db.Model(hr).Association("TokenCache")
  38. if assoc.Error != nil {
  39. return nil, assoc.Error
  40. }
  41. if err := assoc.Append(&hr.TokenCache); err != nil {
  42. return nil, err
  43. }
  44. err = repo.DecryptHelmRepoData(hr, repo.key)
  45. if err != nil {
  46. return nil, err
  47. }
  48. return hr, nil
  49. }
  50. // ReadHelmRepo gets a helm repo specified by a unique id
  51. func (repo *HelmRepoRepository) ReadHelmRepo(projectID, hrID uint) (*models.HelmRepo, error) {
  52. hr := &models.HelmRepo{}
  53. if err := repo.db.Preload("TokenCache").Where("project_id = ? AND id = ?", projectID, hrID).First(&hr).Error; err != nil {
  54. return nil, err
  55. }
  56. repo.DecryptHelmRepoData(hr, repo.key)
  57. return hr, nil
  58. }
  59. // ListHelmReposByProjectID finds all helm repos
  60. // for a given project id
  61. func (repo *HelmRepoRepository) ListHelmReposByProjectID(
  62. projectID uint,
  63. ) ([]*models.HelmRepo, error) {
  64. hrs := []*models.HelmRepo{}
  65. if err := repo.db.Preload("TokenCache").Where("project_id = ?", projectID).Find(&hrs).Error; err != nil {
  66. return nil, err
  67. }
  68. for _, hr := range hrs {
  69. repo.DecryptHelmRepoData(hr, repo.key)
  70. }
  71. return hrs, nil
  72. }
  73. // UpdateHelmRepo modifies an existing HelmRepo in the database
  74. func (repo *HelmRepoRepository) UpdateHelmRepo(
  75. hr *models.HelmRepo,
  76. ) (*models.HelmRepo, error) {
  77. if err := repo.db.Save(hr).Error; err != nil {
  78. return nil, err
  79. }
  80. return hr, nil
  81. }
  82. // UpdateHelmRepoTokenCache updates the helm repo for a registry
  83. func (repo *HelmRepoRepository) UpdateHelmRepoTokenCache(
  84. tokenCache *ints.HelmRepoTokenCache,
  85. ) (*models.HelmRepo, error) {
  86. if tok := tokenCache.Token; len(tok) > 0 {
  87. cipherData, err := encryption.Encrypt(tok, repo.key)
  88. if err != nil {
  89. return nil, err
  90. }
  91. tokenCache.Token = cipherData
  92. }
  93. hr := &models.HelmRepo{}
  94. if err := repo.db.Where("id = ?", tokenCache.HelmRepoID).First(&hr).Error; err != nil {
  95. return nil, err
  96. }
  97. hr.TokenCache.Token = tokenCache.Token
  98. hr.TokenCache.Expiry = tokenCache.Expiry
  99. if err := repo.db.Save(hr).Error; err != nil {
  100. return nil, err
  101. }
  102. return hr, nil
  103. }
  104. // DeleteHelmRepo removes a registry from the db
  105. func (repo *HelmRepoRepository) DeleteHelmRepo(
  106. hr *models.HelmRepo,
  107. ) error {
  108. // clear TokenCache association
  109. assoc := repo.db.Model(hr).Association("TokenCache")
  110. if assoc.Error != nil {
  111. return assoc.Error
  112. }
  113. if err := assoc.Clear(); err != nil {
  114. return err
  115. }
  116. if err := repo.db.Where("id = ?", hr.ID).Delete(&models.HelmRepo{}).Error; err != nil {
  117. return err
  118. }
  119. return nil
  120. }
  121. // EncryptHelmRepoData will encrypt the user's helm repo data before writing
  122. // to the DB
  123. func (repo *HelmRepoRepository) EncryptHelmRepoData(
  124. hr *models.HelmRepo,
  125. key *[32]byte,
  126. ) error {
  127. if tok := hr.TokenCache.Token; len(tok) > 0 {
  128. cipherData, err := encryption.Encrypt(tok, key)
  129. if err != nil {
  130. return err
  131. }
  132. hr.TokenCache.Token = cipherData
  133. }
  134. return nil
  135. }
  136. // DecryptHelmRepoData will decrypt the user's helm repo data before returning it
  137. // from the DB
  138. func (repo *HelmRepoRepository) DecryptHelmRepoData(
  139. hr *models.HelmRepo,
  140. key *[32]byte,
  141. ) error {
  142. if tok := hr.TokenCache.Token; len(tok) > 0 {
  143. plaintext, err := encryption.Decrypt(tok, key)
  144. if err != nil {
  145. return err
  146. }
  147. hr.TokenCache.Token = plaintext
  148. }
  149. return nil
  150. }