Просмотр исходного кода

add porter endpoint that toggles whether the CLI runs the new or old apply flow

David Townley 2 лет назад
Родитель
Сommit
56fa3ecec1

+ 21 - 0
api/client/porter_app.go

@@ -615,3 +615,24 @@ func (c *Client) RollbackRevision(
 
 	return resp, err
 }
+
+// UseNewApplyLogic checks whether the CLI should use the new apply logic
+func (c *Client) UseNewApplyLogic(
+	ctx context.Context,
+	projectID, clusterID uint,
+) (*porter_app.UseNewApplyLogicResponse, error) {
+	resp := &porter_app.UseNewApplyLogicResponse{}
+
+	req := &porter_app.UseNewApplyLogicRequest{}
+
+	err := c.getRequest(
+		fmt.Sprintf(
+			"/projects/%d/clusters/%d/apps/use-new-apply-logic",
+			projectID, clusterID,
+		),
+		req,
+		resp,
+	)
+
+	return resp, err
+}

+ 57 - 0
api/server/handlers/porter_app/use_new_apply_logic.go

@@ -0,0 +1,57 @@
+package porter_app
+
+import (
+	"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/config"
+	"github.com/porter-dev/porter/api/types"
+	"github.com/porter-dev/porter/internal/models"
+	"github.com/porter-dev/porter/internal/telemetry"
+)
+
+// UseNewApplyLogicHandler returns whether the CLI should use the new apply logic or not
+type UseNewApplyLogicHandler struct {
+	handlers.PorterHandlerReadWriter
+	authz.KubernetesAgentGetter
+}
+
+// NewUseNewApplyLogicHandler returns a new UseNewApplyLogicHandler
+func NewUseNewApplyLogicHandler(
+	config *config.Config,
+	decoderValidator shared.RequestDecoderValidator,
+	writer shared.ResultWriter,
+) *UseNewApplyLogicHandler {
+	return &UseNewApplyLogicHandler{
+		PorterHandlerReadWriter: handlers.NewDefaultPorterHandler(config, decoderValidator, writer),
+		KubernetesAgentGetter:   authz.NewOutOfClusterAgentGetter(config),
+	}
+}
+
+// UseNewApplyLogicRequest is the request body for the /apps/use-new-apply-logic endpoint
+type UseNewApplyLogicRequest struct{}
+
+// UseNewApplyLogicResponse is the response body for the /apps/use-new-apply-logic endpoint
+type UseNewApplyLogicResponse struct {
+	UseNewApplyLogic bool `json:"use_new_apply_logic"`
+}
+
+// ServeHTTP handles the request on the /apps/use-new-apply-logic endpoint, allowing the server to tell the CLI whether to use the new apply logic or not
+func (c *UseNewApplyLogicHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
+	ctx, span := telemetry.NewSpan(r.Context(), "serve-use-new-apply-logic")
+	defer span.End()
+
+	project, _ := ctx.Value(types.ProjectScope).(*models.Project)
+	cluster, _ := ctx.Value(types.ClusterScope).(*models.Cluster)
+
+	telemetry.WithAttributes(span,
+		telemetry.AttributeKV{Key: "project_id", Value: project.ID},
+		telemetry.AttributeKV{Key: "cluster_id", Value: cluster.ID},
+	)
+
+	c.WriteResult(w, r, &UseNewApplyLogicResponse{
+		UseNewApplyLogic: false,
+	})
+}

+ 29 - 0
api/server/router/porter_app.go

@@ -1415,5 +1415,34 @@ func getPorterAppRoutes(
 		Router:   r,
 	})
 
+	// GET /api/projects/{project_id}/clusters/{cluster_id}/apps/use-new-apply-logic -> porter_app.NewUseNewApplyLogicHandler
+	useNewApplyLogicEndpoint := factory.NewAPIEndpoint(
+		&types.APIRequestMetadata{
+			Verb:   types.APIVerbGet,
+			Method: types.HTTPVerbGet,
+			Path: &types.Path{
+				Parent:       basePath,
+				RelativePath: fmt.Sprintf("%s/use-new-apply-logic", relPathV2),
+			},
+			Scopes: []types.PermissionScope{
+				types.UserScope,
+				types.ProjectScope,
+				types.ClusterScope,
+			},
+		},
+	)
+
+	useNewApplyLogicHandler := porter_app.NewUseNewApplyLogicHandler(
+		config,
+		factory.GetDecoderValidator(),
+		factory.GetResultWriter(),
+	)
+
+	routes = append(routes, &router.Route{
+		Endpoint: useNewApplyLogicEndpoint,
+		Handler:  useNewApplyLogicHandler,
+		Router:   r,
+	})
+
 	return routes, newPath
 }

+ 10 - 0
cli/cmd/v2/apply.go

@@ -46,6 +46,16 @@ func Apply(ctx context.Context, inp ApplyInput) error {
 	cliConf := inp.CLIConfig
 	client := inp.Client
 
+	useNewApplyResp, err := client.UseNewApplyLogic(ctx, cliConf.Project, cliConf.Cluster)
+	if err != nil {
+		return fmt.Errorf("error checking if project uses new apply logic: %w", err)
+	}
+	if useNewApplyResp.UseNewApplyLogic {
+		return fmt.Errorf("new apply logic not implemented yet: contact support@porter.run for assistance")
+	} else {
+		fmt.Println("Using old apply logic")
+	}
+
 	deploymentTargetID, err := deploymentTargetFromConfig(ctx, client, cliConf.Project, cliConf.Cluster, inp.PreviewApply)
 	if err != nil {
 		return fmt.Errorf("error getting deployment target from config: %w", err)