delete.go 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. package cluster
  2. import (
  3. "net/http"
  4. "connectrpc.com/connect"
  5. porterv1 "github.com/porter-dev/api-contracts/generated/go/porter/v1"
  6. "github.com/porter-dev/porter/api/server/authz"
  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. "github.com/porter-dev/porter/internal/repository"
  14. "github.com/porter-dev/porter/internal/telemetry"
  15. )
  16. type ClusterDeleteHandler struct {
  17. handlers.PorterHandlerWriter
  18. authz.KubernetesAgentGetter
  19. }
  20. func NewClusterDeleteHandler(
  21. config *config.Config,
  22. writer shared.ResultWriter,
  23. ) *ClusterDeleteHandler {
  24. return &ClusterDeleteHandler{
  25. PorterHandlerWriter: handlers.NewDefaultPorterHandler(config, nil, writer),
  26. KubernetesAgentGetter: authz.NewOutOfClusterAgentGetter(config),
  27. }
  28. }
  29. func (c *ClusterDeleteHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
  30. ctx, span := telemetry.NewSpan(r.Context(), "serve-delete-cluster")
  31. defer span.End()
  32. cluster, _ := ctx.Value(types.ClusterScope).(*models.Cluster)
  33. if cluster.ProvisionedBy == "CAPI" {
  34. if c.Config().EnableCAPIProvisioner {
  35. revisions, err := c.Config().Repo.APIContractRevisioner().List(ctx, cluster.ProjectID, repository.WithClusterID(cluster.ID))
  36. if err != nil {
  37. err = telemetry.Error(ctx, span, err, "error listing revisions for cluster")
  38. c.HandleAPIError(w, r, apierrors.NewErrPassThroughToClient(err, http.StatusInternalServerError))
  39. return
  40. }
  41. if cluster.Status == types.UpdatingUnavailable || cluster.Status == types.Updating {
  42. err = telemetry.Error(ctx, span, nil, "unable to delete cluster that is updating")
  43. c.HandleAPIError(w, r, apierrors.NewErrPassThroughToClient(err, http.StatusInternalServerError))
  44. return
  45. }
  46. var revisionID string
  47. for _, rev := range revisions {
  48. if rev.Condition != "" {
  49. revisionID = rev.ID.String()
  50. break
  51. }
  52. }
  53. cl := connect.NewRequest(&porterv1.DeleteClusterRequest{
  54. ContractRevision: &porterv1.ContractRevision{
  55. ClusterId: int32(cluster.ID),
  56. ProjectId: int32(cluster.ProjectID),
  57. RevisionId: revisionID,
  58. },
  59. })
  60. _, err = c.Config().ClusterControlPlaneClient.DeleteCluster(ctx, cl)
  61. if err != nil {
  62. err = telemetry.Error(ctx, span, err, "error deleting cluster")
  63. c.HandleAPIError(w, r, apierrors.NewErrPassThroughToClient(err, http.StatusInternalServerError))
  64. return
  65. }
  66. }
  67. }
  68. err := c.Repo().Cluster().DeleteCluster(cluster)
  69. if err != nil {
  70. err = telemetry.Error(ctx, span, err, "error deleting cluster")
  71. c.HandleAPIError(w, r, apierrors.NewErrPassThroughToClient(err, http.StatusInternalServerError))
  72. return
  73. }
  74. c.WriteResult(w, r, cluster.ToClusterType())
  75. }