2
0

delete_resource.go 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. package state
  2. import (
  3. "context"
  4. "encoding/json"
  5. "net/http"
  6. "github.com/porter-dev/porter/api/server/shared"
  7. "github.com/porter-dev/porter/api/server/shared/apierrors"
  8. "github.com/porter-dev/porter/api/types"
  9. "github.com/porter-dev/porter/internal/models"
  10. "github.com/porter-dev/porter/internal/telemetry"
  11. "github.com/porter-dev/porter/provisioner/integrations/redis_stream"
  12. "github.com/porter-dev/porter/provisioner/server/config"
  13. )
  14. type DeleteResourceHandler struct {
  15. Config *config.Config
  16. decoderValidator shared.RequestDecoderValidator
  17. }
  18. func NewDeleteResourceHandler(
  19. config *config.Config,
  20. ) *DeleteResourceHandler {
  21. return &DeleteResourceHandler{
  22. Config: config,
  23. decoderValidator: shared.NewDefaultRequestDecoderValidator(config.Logger, config.Alerter),
  24. }
  25. }
  26. func (c *DeleteResourceHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
  27. ctx, span := telemetry.NewSpan(r.Context(), "serve-delete-resource")
  28. defer span.End()
  29. // read the infra from the attached scope
  30. infra, _ := ctx.Value(types.InfraScope).(*models.Infra)
  31. operation, _ := ctx.Value(types.OperationScope).(*models.Operation)
  32. // update the operation to indicate completion
  33. operation.Status = "completed"
  34. operation, err := c.Config.Repo.Infra().UpdateOperation(operation)
  35. if err != nil {
  36. apierrors.HandleAPIError(c.Config.Logger, c.Config.Alerter, w, r, apierrors.NewErrInternal(err), true)
  37. return
  38. }
  39. // push to the operation stream
  40. err = redis_stream.SendOperationCompleted(c.Config.RedisClient, infra, operation)
  41. if err != nil {
  42. apierrors.HandleAPIError(c.Config.Logger, c.Config.Alerter, w, r, apierrors.NewErrInternal(err), true)
  43. return
  44. }
  45. // push to the global stream
  46. err = redis_stream.PushToGlobalStream(c.Config.RedisClient, infra, operation, "destroyed")
  47. if err != nil {
  48. apierrors.HandleAPIError(c.Config.Logger, c.Config.Alerter, w, r, apierrors.NewErrInternal(err), true)
  49. return
  50. }
  51. // update the infra to indicate deletion
  52. infra.Status = "deleted"
  53. infra, err = c.Config.Repo.Infra().UpdateInfra(infra)
  54. if err != nil {
  55. apierrors.HandleAPIError(c.Config.Logger, c.Config.Alerter, w, r, apierrors.NewErrInternal(err), true)
  56. return
  57. }
  58. // switch on the kind of resource and write the corresponding objects to the database
  59. switch infra.Kind {
  60. case types.InfraECR, types.InfraGCR, types.InfraGAR, types.InfraDOCR, types.InfraACR:
  61. _, err = deleteRegistry(c.Config, infra, operation)
  62. case types.InfraEKS, types.InfraDOKS, types.InfraGKE, types.InfraAKS:
  63. _, err = deleteCluster(c.Config, infra, operation)
  64. case types.InfraRDS:
  65. _, err = deleteDatabase(c.Config, infra, operation)
  66. case types.InfraS3:
  67. err = deleteS3Bucket(ctx, c.Config, infra, operation)
  68. }
  69. if err != nil {
  70. apierrors.HandleAPIError(c.Config.Logger, c.Config.Alerter, w, r, apierrors.NewErrInternal(err), true)
  71. return
  72. }
  73. }
  74. func deleteRegistry(config *config.Config, infra *models.Infra, operation *models.Operation) (*models.Registry, error) {
  75. reg, err := config.Repo.Registry().ReadRegistryByInfraID(infra.ProjectID, infra.ID)
  76. if err != nil {
  77. return nil, err
  78. }
  79. err = config.Repo.Registry().DeleteRegistry(reg)
  80. if err != nil {
  81. return nil, err
  82. }
  83. return reg, nil
  84. }
  85. func deleteCluster(config *config.Config, infra *models.Infra, operation *models.Operation) (*models.Cluster, error) {
  86. cluster, err := config.Repo.Cluster().ReadClusterByInfraID(infra.ProjectID, infra.ID)
  87. if err != nil {
  88. return nil, err
  89. }
  90. err = config.Repo.Cluster().DeleteCluster(cluster)
  91. if err != nil {
  92. return nil, err
  93. }
  94. return cluster, nil
  95. }
  96. func deleteDatabase(config *config.Config, infra *models.Infra, operation *models.Operation) (*models.Database, error) {
  97. database, err := config.Repo.Database().ReadDatabaseByInfraID(infra.ProjectID, infra.ID)
  98. if err != nil {
  99. return nil, err
  100. }
  101. err = config.Repo.Database().DeleteDatabase(database.ProjectID, database.ClusterID, database.ID)
  102. if err != nil {
  103. return nil, err
  104. }
  105. // TODO: add delete env group here
  106. return database, nil
  107. }
  108. func deleteS3Bucket(ctx context.Context, config *config.Config, infra *models.Infra, operation *models.Operation) error {
  109. lastApplied := make(map[string]interface{})
  110. err := json.Unmarshal(operation.LastApplied, &lastApplied)
  111. if err != nil {
  112. return err
  113. }
  114. return deleteS3EnvGroup(ctx, config, infra, lastApplied)
  115. }