Переглянути джерело

POR-2050: create app instance with porter app; fix db structure (#3899)

Co-authored-by: David Townley <davidtownley@Davids-MacBook-Air.local>
d-g-town 2 роки тому
батько
коміт
41496a6b23

+ 17 - 15
api/client/porter_app.go

@@ -304,14 +304,15 @@ func (c *Client) CurrentAppRevision(
 
 // CreatePorterAppDBEntryInput is the input struct to CreatePorterAppDBEntry
 type CreatePorterAppDBEntryInput struct {
-	AppName         string
-	GitRepoName     string
-	GitRepoID       uint
-	GitBranch       string
-	ImageRepository string
-	PorterYamlPath  string
-	ImageTag        string
-	Local           bool
+	AppName            string
+	GitRepoName        string
+	GitRepoID          uint
+	GitBranch          string
+	ImageRepository    string
+	PorterYamlPath     string
+	ImageTag           string
+	Local              bool
+	DeploymentTargetID string
 }
 
 // CreatePorterAppDBEntry creates an entry in the porter app
@@ -337,13 +338,14 @@ func (c *Client) CreatePorterAppDBEntry(
 	}
 
 	req := &porter_app.CreateAppRequest{
-		Name:           inp.AppName,
-		SourceType:     sourceType,
-		GitBranch:      inp.GitBranch,
-		GitRepoName:    inp.GitRepoName,
-		GitRepoID:      inp.GitRepoID,
-		PorterYamlPath: inp.PorterYamlPath,
-		Image:          image,
+		Name:               inp.AppName,
+		SourceType:         sourceType,
+		GitBranch:          inp.GitBranch,
+		GitRepoName:        inp.GitRepoName,
+		GitRepoID:          inp.GitRepoID,
+		PorterYamlPath:     inp.PorterYamlPath,
+		Image:              image,
+		DeploymentTargetID: inp.DeploymentTargetID,
 	}
 
 	err := c.postRequest(

+ 43 - 7
api/server/handlers/porter_app/create_app.go

@@ -6,6 +6,10 @@ import (
 	"fmt"
 	"net/http"
 
+	"connectrpc.com/connect"
+
+	porterv1 "github.com/porter-dev/api-contracts/generated/go/porter/v1"
+
 	"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"
@@ -55,13 +59,15 @@ type Image struct {
 
 // CreateAppRequest is the request object for the /apps/create endpoint
 type CreateAppRequest struct {
-	Name           string     `json:"name"`
-	SourceType     SourceType `json:"type"`
-	GitBranch      string     `json:"git_branch"`
-	GitRepoName    string     `json:"git_repo_name"`
-	GitRepoID      uint       `json:"git_repo_id"`
-	PorterYamlPath string     `json:"porter_yaml_path"`
-	Image          *Image     `json:"image,omitempty"`
+	Name                 string     `json:"name"`
+	SourceType           SourceType `json:"type"`
+	GitBranch            string     `json:"git_branch"`
+	GitRepoName          string     `json:"git_repo_name"`
+	GitRepoID            uint       `json:"git_repo_id"`
+	PorterYamlPath       string     `json:"porter_yaml_path"`
+	Image                *Image     `json:"image,omitempty"`
+	DeploymentTargetName string     `json:"deployment_target_name,omitempty"`
+	DeploymentTargetID   string     `json:"deployment_target_id,omitempty"`
 }
 
 // CreateGithubAppInput is the input for creating an app with a github source
@@ -240,6 +246,36 @@ func (c *CreateAppHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
 
 	telemetry.WithAttributes(span, telemetry.AttributeKV{Key: "app-id", Value: porterApp.ID})
 
+	telemetry.WithAttributes(span,
+		telemetry.AttributeKV{Key: "deployment-target-name", Value: request.DeploymentTargetName},
+		telemetry.AttributeKV{Key: "deployment-target-id", Value: request.DeploymentTargetID},
+	)
+
+	if request.DeploymentTargetName != "" || request.DeploymentTargetID != "" {
+		createAppInstanceReq := connect.NewRequest(&porterv1.CreateAppInstanceRequest{
+			ProjectId: int64(project.ID),
+			AppName:   request.Name,
+			DeploymentTargetIdentifier: &porterv1.DeploymentTargetIdentifier{
+				Id:   request.DeploymentTargetID,
+				Name: request.DeploymentTargetName,
+			},
+			PorterAppId: int64(porterApp.ID),
+		})
+
+		createAppInstanceResp, err := c.Config().ClusterControlPlaneClient.CreateAppInstance(ctx, createAppInstanceReq)
+		if err != nil {
+			// ignore error until app instances are fully supported: POR-2056
+			telemetry.WithAttributes(span, telemetry.AttributeKV{Key: "create-app-instance-error", Value: err.Error()})
+		}
+
+		if createAppInstanceResp == nil || createAppInstanceResp.Msg == nil {
+			// ignore error until app instances are fully supported: POR-2056
+			telemetry.WithAttributes(span, telemetry.AttributeKV{Key: "create-app-instance-nil", Value: true})
+		} else {
+			telemetry.WithAttributes(span, telemetry.AttributeKV{Key: "app-instance-id", Value: createAppInstanceResp.Msg.AppInstanceId})
+		}
+	}
+
 	c.WriteResult(w, r, porterApp)
 }
 

+ 12 - 4
cli/cmd/v2/apply.go

@@ -118,6 +118,8 @@ func Apply(ctx context.Context, inp ApplyInput) error {
 			return fmt.Errorf("unable to form porter app creation input from yaml: %w", err)
 		}
 
+		createPorterAppDBEntryInp.DeploymentTargetID = deploymentTargetID
+
 		err = client.CreatePorterAppDBEntry(ctx, cliConf.Project, cliConf.Cluster, createPorterAppDBEntryInp)
 		if err != nil {
 			if err.Error() == porter_app.ErrMissingSourceType.Error() {
@@ -477,11 +479,17 @@ func buildSettingsFromBase64AppProto(base64AppProto string) (buildInput, error)
 func deploymentTargetFromConfig(ctx context.Context, client api.Client, projectID, clusterID uint, previewApply bool) (string, error) {
 	var deploymentTargetID string
 
-	targetResp, err := client.DefaultDeploymentTarget(ctx, projectID, clusterID)
-	if err != nil {
-		return deploymentTargetID, fmt.Errorf("error calling default deployment target endpoint: %w", err)
+	if os.Getenv("PORTER_DEPLOYMENT_TARGET_ID") != "" {
+		deploymentTargetID = os.Getenv("PORTER_DEPLOYMENT_TARGET_ID")
+	}
+
+	if deploymentTargetID == "" {
+		targetResp, err := client.DefaultDeploymentTarget(ctx, projectID, clusterID)
+		if err != nil {
+			return deploymentTargetID, fmt.Errorf("error calling default deployment target endpoint: %w", err)
+		}
+		deploymentTargetID = targetResp.DeploymentTargetID
 	}
-	deploymentTargetID = targetResp.DeploymentTargetID
 
 	if previewApply {
 		var branchName string

+ 1 - 0
dashboard/src/main/home/app-dashboard/create-app/CreateApp.tsx

@@ -278,6 +278,7 @@ const CreateApp: React.FC<CreateAppProps> = ({ history }) => {
           {
             ...source,
             name: app.name,
+            deployment_target_id: deploymentTarget.deployment_target_id
           },
           {
             project_id: currentProject.id,

+ 2 - 0
dashboard/src/shared/api.tsx

@@ -961,6 +961,7 @@ const validatePorterApp = baseApi<
 const createApp = baseApi<
   | {
       name: string;
+      deployment_target_id: string;
       type: "github";
       git_repo_id: number;
       git_branch: string;
@@ -969,6 +970,7 @@ const createApp = baseApi<
     }
   | {
       name: string;
+      deployment_target_id: string;
       type: "docker-registry";
       image: {
         repository: string;

+ 2 - 5
internal/models/app_instance.go

@@ -14,7 +14,7 @@ type AppInstance struct {
 	// ID is a unique identifier for a given app instance
 	ID uuid.UUID `gorm:"type:uuid;primaryKey" json:"id"`
 	// Name is the name of the app instance. This is unique across a given deployment target
-	Name string `json:"name"  gorm:"uniqueIndex:idx_name_deployment_target"`
+	Name string `json:"name"`
 	// ProjectID is the ID of the project that the app instance belongs to
 	ProjectID uint `json:"project_id"`
 	// CreatedAt is the time (UTC) that a given app instance was created. This should not change
@@ -24,8 +24,5 @@ type AppInstance struct {
 	// PorterAppID is the ID of the app (source information) that the given app instance relates to
 	PorterAppID uint `json:"porter_app_id"`
 	// DeploymentTargetID is the ID of the deployment target that the event relates to
-	DeploymentTargetID uuid.UUID `json:"deployment_target_id" gorm:"uniqueIndex:idx_name_deployment_target;type:uuid"`
-
-	// PorterYamlPath is the path to the porter.yaml file in the git repo
-	PorterYamlPath string
+	DeploymentTargetID uuid.UUID `json:"deployment_target_id" gorm:"type:uuid"`
 }