delete.go 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. package project
  2. import (
  3. "fmt"
  4. "net/http"
  5. "github.com/bufbuild/connect-go"
  6. porterv1 "github.com/porter-dev/api-contracts/generated/go/porter/v1"
  7. "github.com/porter-dev/porter/api/server/handlers"
  8. "github.com/porter-dev/porter/api/server/shared"
  9. "github.com/porter-dev/porter/api/server/shared/apierrors"
  10. "github.com/porter-dev/porter/api/server/shared/config"
  11. "github.com/porter-dev/porter/api/types"
  12. "github.com/porter-dev/porter/internal/models"
  13. )
  14. type ProjectDeleteHandler struct {
  15. handlers.PorterHandlerWriter
  16. }
  17. func NewProjectDeleteHandler(
  18. config *config.Config,
  19. writer shared.ResultWriter,
  20. ) *ProjectDeleteHandler {
  21. return &ProjectDeleteHandler{
  22. PorterHandlerWriter: handlers.NewDefaultPorterHandler(config, nil, writer),
  23. }
  24. }
  25. func (p *ProjectDeleteHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
  26. ctx := r.Context()
  27. user, _ := ctx.Value(types.UserScope).(*models.User)
  28. proj, _ := ctx.Value(types.ProjectScope).(*models.Project)
  29. if proj.CapiProvisionerEnabled {
  30. clusters, err := p.Config().Repo.Cluster().ListClustersByProjectID(proj.ID)
  31. if err != nil {
  32. p.HandleAPIError(w, r, apierrors.NewErrInternal(fmt.Errorf("error finding clusters for project: %w", err)))
  33. return
  34. }
  35. for _, cluster := range clusters {
  36. if cluster.ProvisionedBy == "CAPI" {
  37. if !cluster.DeletedAt.Time.IsZero() {
  38. continue
  39. }
  40. contractRevision, err := p.Config().Repo.APIContractRevisioner().List(ctx, proj.ID, cluster.ID)
  41. if err != nil {
  42. p.HandleAPIError(w, r, apierrors.NewErrInternal(fmt.Errorf("error finding contract revisions for cluster: %w", err)))
  43. return
  44. }
  45. if len(contractRevision) == 0 {
  46. continue
  47. }
  48. req := connect.NewRequest(&porterv1.DeleteClusterRequest{
  49. ContractRevision: &porterv1.ContractRevision{
  50. ClusterId: int32(cluster.ID),
  51. ProjectId: int32(cluster.ProjectID),
  52. RevisionId: contractRevision[0].ID.String(),
  53. },
  54. })
  55. _, err = p.Config().ClusterControlPlaneClient.DeleteCluster(ctx, req)
  56. if err != nil {
  57. p.HandleAPIError(w, r, apierrors.NewErrInternal(fmt.Errorf("error deleting cluster: %w", err)))
  58. return
  59. }
  60. }
  61. }
  62. }
  63. deletedProject, err := p.Repo().Project().DeleteProject(proj)
  64. if err != nil {
  65. p.HandleAPIError(w, r, apierrors.NewErrInternal(err))
  66. return
  67. }
  68. p.WriteResult(w, r, deletedProject.ToProjectType())
  69. // delete the billing team
  70. if err := p.Config().BillingManager.DeleteTeam(user, proj); err != nil {
  71. // we do not write error response, since setting up billing error can be
  72. // resolved later and may not be fatal
  73. p.HandleAPIErrorNoWrite(w, r, apierrors.NewErrInternal(err))
  74. }
  75. }