Przeglądaj źródła

support selecting deployment target for app commands (#4097)

d-g-town 2 lat temu
rodzic
commit
a1b6b613eb

+ 8 - 4
api/client/porter_app.go

@@ -634,8 +634,12 @@ func (c *Client) PorterYamlV2Pods(
 	ctx context.Context,
 	projectID, clusterID uint,
 	porterAppName string,
-	req *types.PorterYamlV2PodsRequest,
+	deploymentTargetName string,
 ) (*types.GetReleaseAllPodsResponse, error) {
+	req := &porter_app.PodStatusRequest{
+		DeploymentTargetName: deploymentTargetName,
+	}
+
 	resp := &types.GetReleaseAllPodsResponse{}
 
 	err := c.getRequest(
@@ -655,11 +659,11 @@ func (c *Client) PorterYamlV2Pods(
 func (c *Client) UpdateImage(
 	ctx context.Context,
 	projectID, clusterID uint,
-	appName, deploymentTargetId, tag string,
+	appName, deploymentTargetName, tag string,
 ) (*porter_app.UpdateImageResponse, error) {
 	req := &porter_app.UpdateImageRequest{
-		Tag:                tag,
-		DeploymentTargetId: deploymentTargetId,
+		Tag:                  tag,
+		DeploymentTargetName: deploymentTargetName,
 	}
 
 	resp := &porter_app.UpdateImageResponse{}

+ 20 - 17
api/server/handlers/porter_app/pod_status.go

@@ -37,8 +37,9 @@ func NewPodStatusHandler(
 
 // PodStatusRequest is the expected format for a request body on GET /apps/pods
 type PodStatusRequest struct {
-	DeploymentTargetID string `schema:"deployment_target_id"`
-	ServiceName        string `schema:"service"`
+	DeploymentTargetName string `schema:"deployment_target_name"`
+	DeploymentTargetID   string `schema:"deployment_target_id"`
+	ServiceName          string `schema:"service"`
 }
 
 func (c *PodStatusHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
@@ -62,20 +63,19 @@ func (c *PodStatusHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
 	cluster, _ := r.Context().Value(types.ClusterScope).(*models.Cluster)
 	project, _ := r.Context().Value(types.ProjectScope).(*models.Project)
 
-	telemetry.WithAttributes(span, telemetry.AttributeKV{Key: "service-name", Value: request.ServiceName}, telemetry.AttributeKV{Key: "app-name", Value: appName})
-
-	if request.DeploymentTargetID == "" {
-		err := telemetry.Error(ctx, span, nil, "must provide deployment target id")
-		c.HandleAPIError(w, r, apierrors.NewErrPassThroughToClient(err, http.StatusBadRequest))
-		return
-	}
-	telemetry.WithAttributes(span, telemetry.AttributeKV{Key: "deployment-target-id", Value: request.DeploymentTargetID})
+	telemetry.WithAttributes(span,
+		telemetry.AttributeKV{Key: "service-name", Value: request.ServiceName},
+		telemetry.AttributeKV{Key: "app-name", Value: appName},
+		telemetry.AttributeKV{Key: "input-deployment-target-id", Value: request.DeploymentTargetID},
+		telemetry.AttributeKV{Key: "input-deployment-target-name", Value: request.DeploymentTargetName},
+	)
 
 	deploymentTarget, err := deployment_target.DeploymentTargetDetails(ctx, deployment_target.DeploymentTargetDetailsInput{
-		ProjectID:          int64(project.ID),
-		ClusterID:          int64(cluster.ID),
-		DeploymentTargetID: request.DeploymentTargetID,
-		CCPClient:          c.Config().ClusterControlPlaneClient,
+		ProjectID:            int64(project.ID),
+		ClusterID:            int64(cluster.ID),
+		DeploymentTargetID:   request.DeploymentTargetID,
+		DeploymentTargetName: request.DeploymentTargetName,
+		CCPClient:            c.Config().ClusterControlPlaneClient,
 	})
 	if err != nil {
 		err := telemetry.Error(ctx, span, err, "error getting deployment target details")
@@ -84,7 +84,10 @@ func (c *PodStatusHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
 	}
 
 	namespace := deploymentTarget.Namespace
-	telemetry.WithAttributes(span, telemetry.AttributeKV{Key: "namespace", Value: namespace})
+	telemetry.WithAttributes(span,
+		telemetry.AttributeKV{Key: "namespace", Value: namespace},
+		telemetry.AttributeKV{Key: "deployment-target-id", Value: deploymentTarget.ID},
+	)
 
 	agent, err := c.GetAgent(r, cluster, "")
 	if err != nil {
@@ -97,9 +100,9 @@ func (c *PodStatusHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
 
 	var selectors string
 	if request.ServiceName == "" {
-		selectors = fmt.Sprintf("porter.run/deployment-target-id=%s,porter.run/app-name=%s", request.DeploymentTargetID, appName)
+		selectors = fmt.Sprintf("porter.run/deployment-target-id=%s,porter.run/app-name=%s", deploymentTarget.ID, appName)
 	} else {
-		selectors = fmt.Sprintf("porter.run/service-name=%s,porter.run/deployment-target-id=%s,porter.run/app-name=%s", request.ServiceName, request.DeploymentTargetID, appName)
+		selectors = fmt.Sprintf("porter.run/service-name=%s,porter.run/deployment-target-id=%s,porter.run/app-name=%s", deploymentTarget.ID, request.DeploymentTargetID, appName)
 	}
 	podsList, err := agent.GetPodsByLabel(selectors, namespace)
 	if err != nil {

+ 19 - 8
api/server/handlers/porter_app/update_image.go

@@ -36,9 +36,10 @@ func NewUpdateImageHandler(
 
 // UpdateImageRequest is the request object for the /apps/{porter_app_name}/update-image endpoint
 type UpdateImageRequest struct {
-	DeploymentTargetId string `json:"deployment_target_id"`
-	Repository         string `json:"repository"`
-	Tag                string `json:"tag"`
+	DeploymentTargetId   string `json:"deployment_target_id"`
+	DeploymentTargetName string `json:"deployment_target_name"`
+	Repository           string `json:"repository"`
+	Tag                  string `json:"tag"`
 }
 
 // UpdateImageResponse is the response object for the /apps/{porter_app_name}/update-image endpoint
@@ -74,12 +75,22 @@ func (c *UpdateImageHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
 		return
 	}
 
+	telemetry.WithAttributes(span,
+		telemetry.AttributeKV{Key: "deployment-target-id", Value: request.DeploymentTargetId},
+		telemetry.AttributeKV{Key: "deployment-target-name", Value: request.DeploymentTargetName},
+		telemetry.AttributeKV{Key: "repository", Value: request.Repository},
+		telemetry.AttributeKV{Key: "tag", Value: request.Tag},
+	)
+
 	updateImageReq := connect.NewRequest(&porterv1.UpdateAppImageRequest{
-		ProjectId:          int64(project.ID),
-		DeploymentTargetId: request.DeploymentTargetId,
-		RepositoryUrl:      request.Repository,
-		Tag:                request.Tag,
-		AppName:            appName,
+		ProjectId:     int64(project.ID),
+		RepositoryUrl: request.Repository,
+		Tag:           request.Tag,
+		AppName:       appName,
+		DeploymentTargetIdentifier: &porterv1.DeploymentTargetIdentifier{
+			Id:   request.DeploymentTargetId,
+			Name: request.DeploymentTargetName,
+		},
 	})
 	ccpResp, err := c.Config().ClusterControlPlaneClient.UpdateAppImage(ctx, updateImageReq)
 	if err != nil {

+ 15 - 17
cli/cmd/commands/app.go

@@ -40,6 +40,7 @@ var (
 	appInteractive   bool
 	appContainerName string
 	appTag           string
+	deploymentTarget string
 	appCpuMilli      int
 	appMemoryMi      int
 	jobName          string
@@ -58,6 +59,14 @@ func registerCommand_App(cliConf config.CLIConfig) *cobra.Command {
 		Short: "Runs a command for your application.",
 	}
 
+	appCmd.PersistentFlags().StringVarP(
+		&deploymentTarget,
+		"target",
+		"x",
+		"default",
+		"the deployment target for the app, default is \"default\"",
+	)
+
 	// appRunCmd represents the "porter app run" subcommand
 	appRunCmd := &cobra.Command{
 		Use:   "run [application] -- COMMAND [args...]",
@@ -238,7 +247,7 @@ func appRun(ctx context.Context, _ *types.GetAuthenticatedUserResponse, client a
 	// updated exec args includes launcher command prepended if needed, otherwise it is the same as execArgs
 	var updatedExecArgs []string
 	if project.ValidateApplyV2 {
-		podsSimple, updatedExecArgs, namespace, err = getPodsFromV2PorterYaml(ctx, execArgs, client, cliConfig, args[0])
+		podsSimple, updatedExecArgs, namespace, err = getPodsFromV2PorterYaml(ctx, execArgs, client, cliConfig, args[0], deploymentTarget)
 		if err != nil {
 			return err
 		}
@@ -553,23 +562,12 @@ func appGetPodsV1PorterYaml(ctx context.Context, cliConfig config.CLIConfig, cli
 	return res, containerHasLauncherStartCommand, nil
 }
 
-func appGetPodsV2PorterYaml(ctx context.Context, cliConfig config.CLIConfig, client api.Client, porterAppName string) ([]appPodSimple, string, bool, error) {
+func appGetPodsV2PorterYaml(ctx context.Context, cliConfig config.CLIConfig, client api.Client, porterAppName string, deploymentTargetName string) ([]appPodSimple, string, bool, error) {
 	pID := cliConfig.Project
 	cID := cliConfig.Cluster
 	var containerHasLauncherStartCommand bool
 
-	targetResp, err := client.DefaultDeploymentTarget(ctx, pID, cID)
-	if err != nil {
-		return nil, "", containerHasLauncherStartCommand, fmt.Errorf("error calling default deployment target endpoint: %w", err)
-	}
-
-	if targetResp.DeploymentTargetID == "" {
-		return nil, "", containerHasLauncherStartCommand, errors.New("deployment target id is empty")
-	}
-
-	resp, err := client.PorterYamlV2Pods(ctx, pID, cID, porterAppName, &types.PorterYamlV2PodsRequest{
-		DeploymentTargetID: targetResp.DeploymentTargetID,
-	})
+	resp, err := client.PorterYamlV2Pods(ctx, pID, cID, porterAppName, deploymentTargetName)
 	if err != nil {
 		return nil, "", containerHasLauncherStartCommand, err
 	}
@@ -1215,7 +1213,7 @@ func appUpdateTag(ctx context.Context, user *types.GetAuthenticatedUserResponse,
 	}
 
 	if project.ValidateApplyV2 {
-		tag, err := v2.UpdateImage(ctx, appTag, client, cliConf.Project, cliConf.Cluster, args[0])
+		tag, err := v2.UpdateImage(ctx, appTag, client, cliConf.Project, cliConf.Cluster, args[0], deploymentTarget)
 		if err != nil {
 			return fmt.Errorf("error updating tag: %w", err)
 		}
@@ -1276,8 +1274,8 @@ func getPodsFromV1PorterYaml(ctx context.Context, execArgs []string, client api.
 	return podsSimple, execArgs, nil
 }
 
-func getPodsFromV2PorterYaml(ctx context.Context, execArgs []string, client api.Client, cliConfig config.CLIConfig, porterAppName string) ([]appPodSimple, []string, string, error) {
-	podsSimple, namespace, containerHasLauncherStartCommand, err := appGetPodsV2PorterYaml(ctx, cliConfig, client, porterAppName)
+func getPodsFromV2PorterYaml(ctx context.Context, execArgs []string, client api.Client, cliConfig config.CLIConfig, porterAppName string, deploymentTargetName string) ([]appPodSimple, []string, string, error) {
+	podsSimple, namespace, containerHasLauncherStartCommand, err := appGetPodsV2PorterYaml(ctx, cliConfig, client, porterAppName, deploymentTargetName)
 	if err != nil {
 		return nil, nil, "", fmt.Errorf("could not retrieve list of pods: %w", err)
 	}

+ 4 - 9
cli/cmd/v2/update_image.go

@@ -9,21 +9,16 @@ import (
 )
 
 // UpdateImage updates the image of an application
-func UpdateImage(ctx context.Context, tag string, client api.Client, projectId, clusterId uint, appName string) (string, error) {
-	targetResp, err := client.DefaultDeploymentTarget(ctx, projectId, clusterId)
-	if err != nil {
-		return "", fmt.Errorf("error calling default deployment target endpoint: %w", err)
-	}
-
-	if targetResp.DeploymentTargetID == "" {
-		return "", errors.New("deployment target id is empty")
+func UpdateImage(ctx context.Context, tag string, client api.Client, projectId, clusterId uint, appName string, deploymentTargetName string) (string, error) {
+	if deploymentTargetName == "" {
+		return "", errors.New("please provide a deployment target")
 	}
 
 	if tag == "" {
 		tag = "latest"
 	}
 
-	resp, err := client.UpdateImage(ctx, projectId, clusterId, appName, targetResp.DeploymentTargetID, tag)
+	resp, err := client.UpdateImage(ctx, projectId, clusterId, appName, deploymentTargetName, tag)
 	if err != nil {
 		return "", fmt.Errorf("unable to update image: %w", err)
 	}

+ 1 - 1
go.mod

@@ -83,7 +83,7 @@ require (
 	github.com/matryer/is v1.4.0
 	github.com/nats-io/nats.go v1.24.0
 	github.com/open-policy-agent/opa v0.44.0
-	github.com/porter-dev/api-contracts v0.2.71
+	github.com/porter-dev/api-contracts v0.2.72
 	github.com/riandyrn/otelchi v0.5.1
 	github.com/santhosh-tekuri/jsonschema/v5 v5.0.1
 	github.com/stefanmcshane/helm v0.0.0-20221213002717-88a4a2c6e77d

+ 2 - 2
go.sum

@@ -1520,8 +1520,8 @@ github.com/pmezard/go-difflib v0.0.0-20151028094244-d8ed2627bdf0/go.mod h1:iKH77
 github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
 github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
 github.com/polyfloyd/go-errorlint v0.0.0-20210722154253-910bb7978349/go.mod h1:wi9BfjxjF/bwiZ701TzmfKu6UKC357IOAtNr0Td0Lvw=
-github.com/porter-dev/api-contracts v0.2.71 h1:A9JRjOzXLx9U2ECCvUORZEhLygExDyB0kafe+TnUsM4=
-github.com/porter-dev/api-contracts v0.2.71/go.mod h1:fX6JmP5QuzxDLvqP3evFOTXjI4dHxsG0+VKNTjImZU8=
+github.com/porter-dev/api-contracts v0.2.72 h1:+yYSMzRBmlum+u0MJBe6WBf+nvWHuf37MQUiNTH/nIY=
+github.com/porter-dev/api-contracts v0.2.72/go.mod h1:fX6JmP5QuzxDLvqP3evFOTXjI4dHxsG0+VKNTjImZU8=
 github.com/porter-dev/switchboard v0.0.3 h1:dBuYkiVLa5Ce7059d6qTe9a1C2XEORFEanhbtV92R+M=
 github.com/porter-dev/switchboard v0.0.3/go.mod h1:xSPzqSFMQ6OSbp42fhCi4AbGbQbsm6nRvOkrblFeXU4=
 github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=

+ 11 - 10
internal/deployment_target/get.go

@@ -11,10 +11,11 @@ import (
 
 // DeploymentTargetDetailsInput is the input to the DeploymentTargetDetails function
 type DeploymentTargetDetailsInput struct {
-	ProjectID          int64
-	ClusterID          int64
-	DeploymentTargetID string
-	CCPClient          porterv1connect.ClusterControlPlaneServiceClient
+	ProjectID            int64
+	ClusterID            int64
+	DeploymentTargetID   string
+	DeploymentTargetName string
+	CCPClient            porterv1connect.ClusterControlPlaneServiceClient
 }
 
 // DeploymentTarget is a struct representing the unique cluster, namespace pair for a deployment target
@@ -40,16 +41,16 @@ func DeploymentTargetDetails(ctx context.Context, inp DeploymentTargetDetailsInp
 	if inp.ProjectID == 0 {
 		return deploymentTarget, telemetry.Error(ctx, span, nil, "project id is empty")
 	}
-	if inp.DeploymentTargetID == "" {
-		return deploymentTarget, telemetry.Error(ctx, span, nil, "deployment target id is empty")
-	}
 	if inp.CCPClient == nil {
 		return deploymentTarget, telemetry.Error(ctx, span, nil, "cluster control plane client is nil")
 	}
 
 	deploymentTargetDetailsReq := connect.NewRequest(&porterv1.DeploymentTargetDetailsRequest{
-		ProjectId:          inp.ProjectID,
-		DeploymentTargetId: inp.DeploymentTargetID,
+		ProjectId: inp.ProjectID,
+		DeploymentTargetIdentifier: &porterv1.DeploymentTargetIdentifier{
+			Id:   inp.DeploymentTargetID,
+			Name: inp.DeploymentTargetName,
+		},
 	})
 
 	deploymentTargetDetailsResp, err := inp.CCPClient.DeploymentTargetDetails(ctx, deploymentTargetDetailsReq)
@@ -67,7 +68,7 @@ func DeploymentTargetDetails(ctx context.Context, inp DeploymentTargetDetailsInp
 	}
 
 	deploymentTarget = DeploymentTarget{
-		ID:        inp.DeploymentTargetID,
+		ID:        target.Id,
 		Name:      target.Name,
 		Namespace: target.Namespace,
 		ClusterID: target.ClusterId,