| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102 |
- package datastore
- import (
- "net/http"
- "connectrpc.com/connect"
- porterv1 "github.com/porter-dev/api-contracts/generated/go/porter/v1"
- "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"
- )
- // StatusRequest describes an inbound datastore status request
- type StatusRequest struct {
- Type string `json:"type"`
- Name string `json:"name"`
- }
- // StatusResponse describes an outbound datastore status response
- type StatusResponse struct {
- Status string `json:"status"`
- }
- // StatusHandler is a struct for handling datastore status requests
- type StatusHandler struct {
- handlers.PorterHandlerReadWriter
- authz.KubernetesAgentGetter
- }
- // NewStatusHandler constructs a datastore StatusHandler
- func NewStatusHandler(
- config *config.Config,
- decoderValidator shared.RequestDecoderValidator,
- writer shared.ResultWriter,
- ) *StatusHandler {
- return &StatusHandler{
- PorterHandlerReadWriter: handlers.NewDefaultPorterHandler(config, decoderValidator, writer),
- KubernetesAgentGetter: authz.NewOutOfClusterAgentGetter(config),
- }
- }
- func (h *StatusHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
- ctx, span := telemetry.NewSpan(r.Context(), "serve-datastore-status")
- defer span.End()
- // read the project from context
- project, _ := ctx.Value(types.ProjectScope).(*models.Project)
- cluster, _ := ctx.Value(types.ClusterScope).(*models.Cluster)
- 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},
- )
- var datastoreType porterv1.EnumDatastore
- switch request.Type {
- case "rds-postgresql":
- datastoreType = porterv1.EnumDatastore_ENUM_DATASTORE_RDS_POSTGRESQL
- case "rds-postgresql-aurora":
- datastoreType = porterv1.EnumDatastore_ENUM_DATASTORE_RDS_AURORA_POSTGRESQL
- default:
- err := telemetry.Error(ctx, span, nil, "invalid datastore specified")
- h.HandleAPIError(w, r, apierrors.NewErrPassThroughToClient(err, http.StatusBadRequest))
- return
- }
- req := connect.NewRequest(&porterv1.DatastoreStatusRequest{
- ProjectId: int64(project.ID),
- ClusterId: int64(cluster.ID),
- Type: datastoreType,
- Name: request.Name,
- })
- resp, err := h.Config().ClusterControlPlaneClient.DatastoreStatus(ctx, req)
- if err != nil {
- err := telemetry.Error(ctx, span, err, "error fetching datastore status from ccp")
- h.HandleAPIError(w, r, apierrors.NewErrPassThroughToClient(err, http.StatusInternalServerError))
- return
- }
- if resp.Msg == nil {
- err := telemetry.Error(ctx, span, err, "missing response message from ccp")
- h.HandleAPIError(w, r, apierrors.NewErrPassThroughToClient(err, http.StatusInternalServerError))
- return
- }
- telemetry.WithAttributes(span, telemetry.AttributeKV{Key: "datastore-status", Value: resp.Msg.Status})
- h.WriteResult(w, r, StatusResponse{
- Status: resp.Msg.Status,
- })
- }
|