| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119 |
- package datastore
- import (
- "context"
- "net/http"
- "github.com/porter-dev/porter/api/server/authz"
- "github.com/porter-dev/porter/api/server/handlers"
- "github.com/porter-dev/porter/api/server/shared"
- "github.com/porter-dev/porter/api/server/shared/apierrors"
- "github.com/porter-dev/porter/api/server/shared/config"
- "github.com/porter-dev/porter/api/types"
- "github.com/porter-dev/porter/internal/models"
- "github.com/porter-dev/porter/internal/telemetry"
- )
- // DeleteRequest describes an inbound datastore deletion request
- type DeleteRequest struct {
- Type string `json:"type" form:"required"`
- Name string `json:"name" form:"required"`
- }
- // DeleteDatastoreHandler is a struct for handling datastore deletion requests
- type DeleteDatastoreHandler struct {
- handlers.PorterHandlerReadWriter
- authz.KubernetesAgentGetter
- }
- // NewDeleteDatastoreHandler constructs a datastore DeleteDatastoreHandler
- func NewDeleteDatastoreHandler(
- config *config.Config,
- decoderValidator shared.RequestDecoderValidator,
- writer shared.ResultWriter,
- ) *DeleteDatastoreHandler {
- return &DeleteDatastoreHandler{
- PorterHandlerReadWriter: handlers.NewDefaultPorterHandler(config, decoderValidator, writer),
- KubernetesAgentGetter: authz.NewOutOfClusterAgentGetter(config),
- }
- }
- func (h *DeleteDatastoreHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
- ctx, span := telemetry.NewSpan(r.Context(), "serve-datastore-delete")
- defer span.End()
- project, _ := ctx.Value(types.ProjectScope).(*models.Project)
- request := &StatusRequest{}
- if ok := h.DecodeAndValidate(w, r, request); !ok {
- err := telemetry.Error(ctx, span, nil, "error decoding request")
- h.HandleAPIError(w, r, apierrors.NewErrPassThroughToClient(err, http.StatusBadRequest))
- return
- }
- telemetry.WithAttributes(span,
- telemetry.AttributeKV{Key: "datastore-name", Value: request.Name},
- telemetry.AttributeKV{Key: "datastore-type", Value: request.Type},
- )
- cluster, err := h.getClusterForDatastore(ctx, r, project.ID, request.Name)
- if err != nil {
- err = telemetry.Error(ctx, span, err, "unable to find datastore on any associated cluster")
- h.HandleAPIError(w, r, apierrors.NewErrPassThroughToClient(err, http.StatusInternalServerError))
- return
- }
- telemetry.WithAttributes(span, telemetry.AttributeKV{Key: "cluster-id", Value: cluster.ID})
- helmAgent, err := h.GetHelmAgent(ctx, r, cluster, "ack-system")
- if err != nil {
- err := telemetry.Error(ctx, span, err, "unable to get helm client for cluster")
- h.HandleAPIError(w, r, apierrors.NewErrPassThroughToClient(err, http.StatusInternalServerError))
- return
- }
- _, err = helmAgent.GetRelease(ctx, request.Name, 0, false)
- if err != nil {
- err := telemetry.Error(ctx, span, err, "unable to get helm release")
- h.HandleAPIError(w, r, apierrors.NewErrPassThroughToClient(err, http.StatusInternalServerError))
- return
- }
- _, err = helmAgent.UninstallChart(ctx, request.Name)
- if err != nil {
- telemetry.WithAttributes(span, telemetry.AttributeKV{Key: "cluster-id", Value: cluster.ID})
- err := telemetry.Error(ctx, span, err, "unable to uninstall chart")
- h.HandleAPIError(w, r, apierrors.NewErrPassThroughToClient(err, http.StatusInternalServerError))
- return
- }
- // if the release was deleted by helm without error, mark it as accepted
- w.WriteHeader(http.StatusAccepted)
- }
- func (h *DeleteDatastoreHandler) getClusterForDatastore(ctx context.Context, r *http.Request, projectID uint, datastoreName string) (*models.Cluster, error) {
- ctx, span := telemetry.NewSpan(ctx, "get-cluster-for-datastore")
- if r == nil {
- return nil, telemetry.Error(ctx, span, nil, "missing http request object")
- }
- clusters, err := h.Repo().Cluster().ListClustersByProjectID(projectID)
- if err != nil {
- return nil, telemetry.Error(ctx, span, err, "unable to get project clusters")
- }
- for _, cluster := range clusters {
- helmAgent, err := h.GetHelmAgent(ctx, r, cluster, "ack-system")
- if err != nil {
- telemetry.WithAttributes(span, telemetry.AttributeKV{Key: "cluster-id", Value: cluster.ID})
- return nil, telemetry.Error(ctx, span, err, "unable to get helm client for cluster")
- }
- _, err = helmAgent.GetRelease(ctx, datastoreName, 0, false)
- if err == nil {
- return cluster, nil
- }
- }
- return nil, telemetry.Error(ctx, span, nil, "unable to find datastore on any associated cluster")
- }
|