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

setup default environment for production

Ian Edwards 2 лет назад
Родитель
Сommit
b1a30bc824

+ 1 - 1
api/server/handlers/environment_config/get_stack.go

@@ -64,7 +64,7 @@ func (c *GetEnvConfigStackHandler) ServeHTTP(w http.ResponseWriter, r *http.Requ
 		telemetry.AttributeKV{Key: "stack-name", Value: stackName},
 	)
 
-	app, err := c.Repo().PorterApp().ReadPorterAppByNameInEnvironment(cluster.ID, stackName, uint(envConfigId))
+	app, err := c.Repo().PorterApp().ReadPorterAppByName(cluster.ID, stackName, uint(envConfigId))
 	if err != nil {
 		if errors.Is(err, gorm.ErrRecordNotFound) {
 			err = telemetry.Error(ctx, span, err, "App not found for environment config")

+ 1 - 1
api/server/handlers/namespace/create_stacks_env_group.go

@@ -281,7 +281,7 @@ func rolloutStacksApplications(
 			}
 		}()
 
-		app, err := c.Repo().PorterApp().ReadPorterAppByName(cluster.ID, releases[index].Name)
+		app, err := c.Repo().PorterApp().ReadPorterAppByName(cluster.ID, releases[index].Name, 0)
 		ctx, span := telemetry.NewSpan(ctx, "serve-update-porter-app")
 		updatedPorterApp, err := c.Repo().PorterApp().UpdatePorterApp(app)
 		if err != nil {

+ 48 - 42
api/server/handlers/porter_app/create.go

@@ -134,7 +134,7 @@ func (c *CreatePorterAppHandler) ServeHTTP(w http.ResponseWriter, r *http.Reques
 
 	if request.Builder == "" {
 		// attempt to get builder from db
-		app, err := c.Repo().PorterApp().ReadPorterAppByName(cluster.ID, stackName)
+		app, err := c.Repo().PorterApp().ReadPorterAppByName(cluster.ID, stackName, request.EnvironmentConfigID)
 		if err == nil {
 			request.Builder = app.Builder
 		}
@@ -258,33 +258,24 @@ func (c *CreatePorterAppHandler) ServeHTTP(w http.ResponseWriter, r *http.Reques
 			PorterYamlPath: request.PorterYamlPath,
 		}
 
-		if request.EnvironmentConfigID != 0 {
-			existing, err := c.Repo().PorterApp().ReadPorterAppByNameInEnvironment(cluster.ID, stackName, request.EnvironmentConfigID)
-			if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) {
-				err = telemetry.Error(ctx, span, err, "error reading app from DB")
-				c.HandleAPIError(w, r, apierrors.NewErrPassThroughToClient(err, http.StatusInternalServerError))
-				return
-			}
-
-			if existing != nil {
-				err = telemetry.Error(ctx, span, err, "app with name already exists in environment")
-				c.HandleAPIError(w, r, apierrors.NewErrPassThroughToClient(err, http.StatusForbidden))
-				return
-			}
-
-			app.EnvironmentConfigID = request.EnvironmentConfigID
+		existing, err := c.Repo().PorterApp().ReadPorterAppByName(cluster.ID, stackName, request.EnvironmentConfigID)
+		if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) {
+			err = telemetry.Error(ctx, span, err, "error reading app from DB")
+			c.HandleAPIError(w, r, apierrors.NewErrPassThroughToClient(err, http.StatusInternalServerError))
+			return
+		}
+		
+		if existing != nil && request.EnvironmentConfigID == 0 {
+			err = telemetry.Error(ctx, span, err, "app with name already exists in environment")
+			c.HandleAPIError(w, r, apierrors.NewErrPassThroughToClient(err, http.StatusForbidden))
+			return
+		}
 
-		} else {
-			existing, err := c.Repo().PorterApp().ReadPorterAppByName(cluster.ID, stackName)
-			if err != nil {
-				err = telemetry.Error(ctx, span, err, "error reading app from DB")
-				c.HandleAPIError(w, r, apierrors.NewErrPassThroughToClient(err, http.StatusInternalServerError))
-				return
-			} else if existing.Name != "" {
-				err = telemetry.Error(ctx, span, err, "app with name already exists in project")
-				c.HandleAPIError(w, r, apierrors.NewErrPassThroughToClient(err, http.StatusForbidden))
-				return
-			}
+		err = assignEnvironmentToApp(c, app, project.ID, cluster.ID, request.EnvironmentConfigID)
+		if err != nil {
+			err = telemetry.Error(ctx, span, err, "error assigning environment to app")
+			c.HandleAPIError(w, r, apierrors.NewErrPassThroughToClient(err, http.StatusInternalServerError))
+			return
 		}
 
 		// create the db entry
@@ -399,21 +390,11 @@ func (c *CreatePorterAppHandler) ServeHTTP(w http.ResponseWriter, r *http.Reques
 		}
 
 		// update the DB entry
-		var app *models.PorterApp
-		if request.EnvironmentConfigID != 0 {
-			app, err = c.Repo().PorterApp().ReadPorterAppByNameInEnvironment(cluster.ID, stackName, request.EnvironmentConfigID)
-			if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) {
-				err = telemetry.Error(ctx, span, err, "error reading app from DB")
-				c.HandleAPIError(w, r, apierrors.NewErrPassThroughToClient(err, http.StatusInternalServerError))
-				return
-			}
-		} else {
-			app, err = c.Repo().PorterApp().ReadPorterAppByName(cluster.ID, stackName)
-			if err != nil {
-				err = telemetry.Error(ctx, span, err, "error reading app from DB")
-				c.HandleAPIError(w, r, apierrors.NewErrPassThroughToClient(err, http.StatusInternalServerError))
-				return
-			}
+		app, err := c.Repo().PorterApp().ReadPorterAppByName(cluster.ID, stackName, request.EnvironmentConfigID)
+		if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) {
+			err = telemetry.Error(ctx, span, err, "error reading app from DB")
+			c.HandleAPIError(w, r, apierrors.NewErrPassThroughToClient(err, http.StatusInternalServerError))
+			return
 		}
 
 		if app == nil {
@@ -603,3 +584,28 @@ func cloneEnvGroup(c *CreatePorterAppHandler, w http.ResponseWriter, r *http.Req
 		}
 	}
 }
+
+func assignEnvironmentToApp(c *CreatePorterAppHandler, app *models.PorterApp, projectID, clusterID, envConfID uint) error {
+	ctx, span := telemetry.NewSpan(context.Background(), "assign-env-to-app")
+	if app == nil {
+		return fmt.Errorf("Application does not exist")
+	}
+
+	if envConfID != 0 {
+		envConf, err := c.Repo().EnvironmentConfig().ReadEnvironmentConfig(projectID, clusterID, envConfID)
+		if err != nil {
+			return telemetry.Error(ctx, span, err, "error reading environment config from DB")
+		}
+
+		app.EnvironmentConfigID = envConf.ID
+		return nil
+	}
+
+	envConf, err := c.Repo().EnvironmentConfig().ReadDefaultEnvironmentConfig(projectID, clusterID)
+	if err != nil {
+		return telemetry.Error(ctx, span, err, "error reading environment config from DB")
+	}
+
+	app.EnvironmentConfigID = envConf.ID
+	return nil
+}

+ 2 - 2
api/server/handlers/porter_app/create_and_update_events.go

@@ -87,7 +87,7 @@ func (p *CreateUpdatePorterAppEventHandler) createNewAppEvent(ctx context.Contex
 	ctx, span := telemetry.NewSpan(ctx, "create-porter-app-event")
 	defer span.End()
 
-	app, err := p.Repo().PorterApp().ReadPorterAppByName(cluster.ID, porterAppName)
+	app, err := p.Repo().PorterApp().ReadPorterAppByName(cluster.ID, porterAppName, 0)
 	if err != nil {
 		return types.PorterAppEvent{}, telemetry.Error(ctx, span, err, "error retrieving porter app by name for cluster")
 	}
@@ -153,7 +153,7 @@ func (p *CreateUpdatePorterAppEventHandler) updateExistingAppEvent(ctx context.C
 	ctx, span := telemetry.NewSpan(ctx, "update-porter-app-event")
 	defer span.End()
 
-	app, err := p.Repo().PorterApp().ReadPorterAppByName(cluster.ID, porterAppName)
+	app, err := p.Repo().PorterApp().ReadPorterAppByName(cluster.ID, porterAppName, 0)
 	if err != nil {
 		return types.PorterAppEvent{}, telemetry.Error(ctx, span, err, "error retrieving porter app by name for cluster")
 	}

+ 33 - 11
api/server/handlers/porter_app/create_secret_and_open_pr.go

@@ -17,6 +17,7 @@ import (
 	"github.com/porter-dev/porter/internal/auth/token"
 	"github.com/porter-dev/porter/internal/integrations/ci/actions"
 	"github.com/porter-dev/porter/internal/models"
+	"github.com/porter-dev/porter/internal/telemetry"
 )
 
 type OpenStackPRHandler struct {
@@ -34,20 +35,34 @@ func NewOpenStackPRHandler(
 }
 
 func (c *OpenStackPRHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
-	user, _ := r.Context().Value(types.UserScope).(*models.User)
-	project, _ := r.Context().Value(types.ProjectScope).(*models.Project)
-	cluster, _ := r.Context().Value(types.ClusterScope).(*models.Cluster)
+	ctx, span := telemetry.NewSpan(r.Context(), "serve-create-secret-and-open-pr")
+	defer span.End()
+
+	user, _ := ctx.Value(types.UserScope).(*models.User)
+	project, _ := ctx.Value(types.ProjectScope).(*models.Project)
+	cluster, _ := ctx.Value(types.ClusterScope).(*models.Cluster)
+
 	stackName, reqErr := requestutils.GetURLParamString(r, types.URLParamStackName)
 	if reqErr != nil {
 		c.HandleAPIError(w, r, apierrors.NewErrPassThroughToClient(reqErr, http.StatusBadRequest))
 		return
 	}
+	telemetry.WithAttributes(span,
+		telemetry.AttributeKV{Key: "stack-name", Value: stackName},
+	)
 
 	request := &types.CreateSecretAndOpenGHPRRequest{}
 	if ok := c.DecodeAndValidate(w, r, request); !ok {
 		return
 	}
 
+	telemetry.WithAttributes(span,
+		telemetry.AttributeKV{Key: "repo-owner", Value: request.GithubRepoOwner},
+		telemetry.AttributeKV{Key: "repo-name", Value: request.GithubRepoName},
+		telemetry.AttributeKV{Key: "branch", Value: request.Branch},
+		telemetry.AttributeKV{Key: "open-pr", Value: request.OpenPr},
+	)
+
 	client, err := getGithubClient(c.Config(), request.GithubAppInstallationID)
 	if err != nil {
 		c.HandleAPIError(w, r, apierrors.NewErrInternal(err))
@@ -57,12 +72,14 @@ func (c *OpenStackPRHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
 	// generate porter jwt token
 	jwt, err := token.GetTokenForAPI(user.ID, project.ID)
 	if err != nil {
-		c.HandleAPIError(w, r, apierrors.NewErrInternal(fmt.Errorf("error getting token for API: %w", err)))
+		err = telemetry.Error(ctx, span, err, "Error getting token for API")
+		c.HandleAPIError(w, r, apierrors.NewErrPassThroughToClient(err, http.StatusInternalServerError))
 		return
 	}
 	encoded, err := jwt.EncodeToken(c.Config().TokenConf)
 	if err != nil {
-		c.HandleAPIError(w, r, apierrors.NewErrInternal(fmt.Errorf("error encoding API token: %w", err)))
+		err = telemetry.Error(ctx, span, err, "Error encoding token")
+		c.HandleAPIError(w, r, apierrors.NewErrPassThroughToClient(err, http.StatusInternalServerError))
 		return
 	}
 
@@ -76,7 +93,8 @@ func (c *OpenStackPRHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
 		request.GithubRepoName,
 	)
 	if err != nil {
-		c.HandleAPIError(w, r, apierrors.NewErrInternal(fmt.Errorf("error generating secret: %w", err)))
+		err = telemetry.Error(ctx, span, err, "Error creating github secret")
+		c.HandleAPIError(w, r, apierrors.NewErrPassThroughToClient(err, http.StatusInternalServerError))
 		return
 	}
 
@@ -102,13 +120,15 @@ func (c *OpenStackPRHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
 
 		if unwrappedErr != nil {
 			if errors.Is(unwrappedErr, actions.ErrProtectedBranch) {
+				err = telemetry.Error(ctx, span, err, "Branch is protected")
 				c.HandleAPIError(w, r, apierrors.NewErrPassThroughToClient(err, http.StatusConflict))
 			} else if errors.Is(unwrappedErr, actions.ErrCreatePRForProtectedBranch) {
+				err = telemetry.Error(ctx, span, err, "Error creating PR for protected branch")
 				c.HandleAPIError(w, r, apierrors.NewErrPassThroughToClient(err, http.StatusPreconditionFailed))
 			}
 		} else {
-			c.HandleAPIError(w, r, apierrors.NewErrInternal(fmt.Errorf("error setting up application in the github "+
-				"repo: %w", err)))
+			err = telemetry.Error(ctx, span, err, "Error opening PR")
+			c.HandleAPIError(w, r, apierrors.NewErrPassThroughToClient(err, http.StatusInternalServerError))
 			return
 		}
 	}
@@ -120,9 +140,10 @@ func (c *OpenStackPRHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
 		}
 
 		// update DB with the PR url
-		porterApp, err := c.Repo().PorterApp().ReadPorterAppByName(cluster.ID, stackName)
+		porterApp, err := c.Repo().PorterApp().ReadPorterAppByName(cluster.ID, stackName, 0)
 		if err != nil {
-			c.HandleAPIError(w, r, apierrors.NewErrInternal(fmt.Errorf("unable to get porter app db: %w", err)))
+			err = telemetry.Error(ctx, span, err, "Error reading porter app from db")
+			c.HandleAPIError(w, r, apierrors.NewErrPassThroughToClient(err, http.StatusInternalServerError))
 			return
 		}
 
@@ -130,7 +151,8 @@ func (c *OpenStackPRHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
 
 		_, err = c.Repo().PorterApp().UpdatePorterApp(porterApp)
 		if err != nil {
-			c.HandleAPIError(w, r, apierrors.NewErrInternal(fmt.Errorf("unable to write pr url to porter app db: %w", err)))
+			err = telemetry.Error(ctx, span, err, "Unable to write pr url to porter app to db")
+			c.HandleAPIError(w, r, apierrors.NewErrPassThroughToClient(err, http.StatusInternalServerError))
 			return
 		}
 	}

+ 1 - 1
api/server/handlers/porter_app/delete.go

@@ -39,7 +39,7 @@ func (c *DeletePorterAppByNameHandler) ServeHTTP(w http.ResponseWriter, r *http.
 		return
 	}
 
-	porterApp, appErr := c.Repo().PorterApp().ReadPorterAppByName(cluster.ID, stackName)
+	porterApp, appErr := c.Repo().PorterApp().ReadPorterAppByName(cluster.ID, stackName, 0)
 	if appErr != nil {
 		c.HandleAPIError(w, r, apierrors.NewErrInternal(appErr))
 		return

+ 8 - 3
api/server/handlers/porter_app/get.go

@@ -11,6 +11,7 @@ import (
 	"github.com/porter-dev/porter/api/server/shared/requestutils"
 	"github.com/porter-dev/porter/api/types"
 	"github.com/porter-dev/porter/internal/models"
+	"github.com/porter-dev/porter/internal/telemetry"
 )
 
 type GetPorterAppHandler struct {
@@ -28,17 +29,21 @@ func NewGetPorterAppHandler(
 }
 
 func (c *GetPorterAppHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
-	ctx := r.Context()
+	ctx, span := telemetry.NewSpan(r.Context(), "serve-get-porter-app")
+	defer span.End()
+
 	cluster, _ := ctx.Value(types.ClusterScope).(*models.Cluster)
+
 	stackName, reqErr := requestutils.GetURLParamString(r, types.URLParamStackName)
 	if reqErr != nil {
 		c.HandleAPIError(w, r, apierrors.NewErrPassThroughToClient(reqErr, http.StatusBadRequest))
 		return
 	}
 
-	app, err := c.Repo().PorterApp().ReadPorterAppByName(cluster.ID, stackName)
+	app, err := c.Repo().PorterApp().ReadPorterAppByName(cluster.ID, stackName, 0)
 	if err != nil {
-		c.HandleAPIError(w, r, apierrors.NewErrInternal(err))
+		err = telemetry.Error(ctx, span, err, "Failed to read porter app")
+		c.HandleAPIError(w, r, apierrors.NewErrPassThroughToClient(err, http.StatusInternalServerError))
 		return
 	}
 

+ 7 - 3
api/server/handlers/porter_app/list.go

@@ -9,6 +9,7 @@ import (
 	"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"
 )
 
 type PorterAppListHandler struct {
@@ -25,12 +26,15 @@ func NewPorterAppListHandler(
 }
 
 func (p *PorterAppListHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
-	ctx := r.Context()
+	ctx, span := telemetry.NewSpan(r.Context(), "serve-list-porter-apps")
+	defer span.End()
+
 	cluster, _ := ctx.Value(types.ClusterScope).(*models.Cluster)
 
-	porterApps, err := p.Repo().PorterApp().ListPorterAppByClusterID(cluster.ID)
+	porterApps, err := p.Repo().PorterApp().ListPorterAppByClusterID(cluster.ID, 0)
 	if err != nil {
-		p.HandleAPIError(w, r, apierrors.NewErrInternal(err))
+		err = telemetry.Error(ctx, span, err, "Failed to list porter apps")
+		p.HandleAPIError(w, r, apierrors.NewErrPassThroughToClient(err, http.StatusInternalServerError))
 		return
 	}
 

+ 1 - 1
api/server/handlers/porter_app/list_events.go

@@ -63,7 +63,7 @@ func (p *PorterAppEventListHandler) ServeHTTP(w http.ResponseWriter, r *http.Req
 		return
 	}
 
-	app, err := p.Repo().PorterApp().ReadPorterAppByName(cluster.ID, stackName)
+	app, err := p.Repo().PorterApp().ReadPorterAppByName(cluster.ID, stackName, 0)
 	if err != nil {
 		p.HandleAPIError(w, r, apierrors.NewErrInternal(err))
 		return

+ 1 - 1
api/server/handlers/porter_app/rollback.go

@@ -71,7 +71,7 @@ func (c *RollbackPorterAppHandler) ServeHTTP(w http.ResponseWriter, r *http.Requ
 		imageInfo.Tag = "latest"
 	}
 
-	porterApp, err := c.Repo().PorterApp().ReadPorterAppByName(cluster.ID, stackName)
+	porterApp, err := c.Repo().PorterApp().ReadPorterAppByName(cluster.ID, stackName, 0)
 	if err != nil {
 		err = telemetry.Error(ctx, span, err, "error getting porter app")
 		c.HandleAPIError(w, r, apierrors.NewErrPassThroughToClient(err, http.StatusInternalServerError))

+ 4 - 3
internal/models/environment_config.go

@@ -11,14 +11,15 @@ type EnvironmentConfig struct {
 	gorm.Model
 
 	ProjectID         uint
-	ClusterID         uint
+	ClusterID         uint `gorm:"uniqueIndex:idx_cluster_id_name"`
 	GitInstallationID uint
 
 	WebhookID       string `gorm:"unique"`
 	GithubWebhookID int64
 
-	Name string
-	Auto bool
+	Name      string `gorm:"uniqueIndex:idx_cluster_id_name"`
+	Auto      bool   `gorm:"default:false"`
+	IsDefault bool   `gorm:"default:false"`
 
 	PreviewEnvironments []PreviewEnvironment
 	PorterApps          []PorterApp

+ 2 - 2
internal/models/porter_app.go

@@ -13,7 +13,7 @@ type PorterApp struct {
 	ProjectID uint
 	ClusterID uint
 
-	Name string
+	Name string `gorm:"uniqueIndex:idx_name_env_config_id"`
 
 	ImageRepoURI string
 
@@ -31,7 +31,7 @@ type PorterApp struct {
 	// Porter YAML
 	PorterYamlPath string
 
-	EnvironmentConfigID uint
+	EnvironmentConfigID uint `gorm:"uniqueIndex:idx_name_env_config_id"`
 }
 
 // ToPorterAppType generates an external types.PorterApp to be shared over REST

+ 1 - 0
internal/repository/environment_config.go

@@ -7,4 +7,5 @@ import (
 // EnvironmentConfigRepository represents the set of queries on the EnvironmentConfig model
 type EnvironmentConfigRepository interface {
 	ReadEnvironmentConfig(projectID, clusterID, id uint) (*models.EnvironmentConfig, error)
+	ReadDefaultEnvironmentConfig(projectID, clusterID uint) (*models.EnvironmentConfig, error)
 }

+ 13 - 0
internal/repository/gorm/environment_config.go

@@ -30,3 +30,16 @@ func (repo *EnvironmentConfigRepository) ReadEnvironmentConfig(projectID, cluste
 
 	return env_config, nil
 }
+
+func (repo *EnvironmentConfigRepository) ReadDefaultEnvironmentConfig(projectID, clusterID uint) (*models.EnvironmentConfig, error) {
+	env_config := &models.EnvironmentConfig{}
+
+	if err := repo.db.Order("id desc").Where(
+		"project_id = ? AND cluster_id = ? AND is_default = true",
+		projectID, clusterID,
+	).First(&env_config).Error; err != nil {
+		return nil, err
+	}
+
+	return env_config, nil
+}

+ 19 - 11
internal/repository/gorm/porter_app.go

@@ -24,28 +24,36 @@ func (repo *PorterAppRepository) CreatePorterApp(a *models.PorterApp) (*models.P
 	return a, nil
 }
 
-func (repo *PorterAppRepository) ListPorterAppByClusterID(clusterID uint) ([]*models.PorterApp, error) {
+func (repo *PorterAppRepository) ListPorterAppByClusterID(clusterID, envConfigID uint) ([]*models.PorterApp, error) {
 	apps := []*models.PorterApp{}
 
-	if err := repo.db.Where("cluster_id = ? AND environment_config_id IS NULL", clusterID).Find(&apps).Error; err != nil {
+	if envConfigID == 0 {
+		// get porter_apps where environment_config is default by joining on environment_config_id
+		if err := repo.db.Joins("JOIN environment_configs ON porter_apps.environment_config_id = environment_configs.id").Where("porter_apps.cluster_id = ? AND environment_configs.is_default = true", clusterID).Find(&apps).Error; err != nil {
+			return nil, err
+		}
+
+		return apps, nil
+	}
+
+	if err := repo.db.Where("cluster_id = ? AND environment_config_id = ?", clusterID, envConfigID).Find(&apps).Error; err != nil {
 		return nil, err
 	}
 
 	return apps, nil
 }
 
-func (repo *PorterAppRepository) ReadPorterAppByName(clusterID uint, name string) (*models.PorterApp, error) {
+func (repo *PorterAppRepository) ReadPorterAppByName(clusterID uint, name string, envConfigID uint) (*models.PorterApp, error) {
 	app := &models.PorterApp{}
 
-	if err := repo.db.Where("cluster_id = ? AND name = ? AND environment_config_id IS NULL", clusterID, name).Limit(1).Find(&app).Error; err != nil {
-		return nil, err
-	}
-
-	return app, nil
-}
+	if envConfigID == 0 {
+		// get porter_app where environment_config is default by joining on environment_config_id
+		if err := repo.db.Joins("JOIN environment_configs ON porter_apps.environment_config_id = environment_configs.id").Where("porter_apps.cluster_id = ? AND porter_apps.name = ? AND environment_configs.is_default = true", clusterID, name).First(&app).Error; err != nil {
+			return nil, err
+		}
 
-func (repo *PorterAppRepository) ReadPorterAppByNameInEnvironment(clusterID uint, name string, envConfigID uint) (*models.PorterApp, error) {
-	app := &models.PorterApp{}
+		return app, nil
+	}
 
 	if err := repo.db.Where("cluster_id = ? AND name = ? AND environment_config_id = ?", clusterID, name, envConfigID).First(&app).Error; err != nil {
 		return nil, err

+ 2 - 3
internal/repository/porter_app.go

@@ -6,10 +6,9 @@ import (
 
 // PorterAppRepository represents the set of queries on the PorterApp model
 type PorterAppRepository interface {
-	ReadPorterAppByName(clusterID uint, name string) (*models.PorterApp, error)
-	ReadPorterAppByNameInEnvironment(clusterID uint, name string, envConfigID uint) (*models.PorterApp, error)
+	ReadPorterAppByName(clusterID uint, name string, envConfigID uint) (*models.PorterApp, error)
 	CreatePorterApp(app *models.PorterApp) (*models.PorterApp, error)
-	ListPorterAppByClusterID(clusterID uint) ([]*models.PorterApp, error)
+	ListPorterAppByClusterID(clusterID uint, envConfigID uint) ([]*models.PorterApp, error)
 	UpdatePorterApp(app *models.PorterApp) (*models.PorterApp, error)
 	DeletePorterApp(app *models.PorterApp) (*models.PorterApp, error)
 }

+ 4 - 0
internal/repository/test/environment_config.go

@@ -20,3 +20,7 @@ func NewEnvironmentConfigRepository(canQuery bool, failingMethods ...string) rep
 func (repo *EnvironmentConfigRepository) ReadEnvironmentConfig(projectID, clusterID, id uint) (*models.EnvironmentConfig, error) {
 	return nil, errors.New("cannot write database")
 }
+
+func (repo *EnvironmentConfigRepository) ReadDefaultEnvironmentConfig(projectID, clusterID uint) (*models.EnvironmentConfig, error) {
+	return nil, errors.New("cannot write database")
+}

+ 2 - 6
internal/repository/test/porter_app.go

@@ -17,7 +17,7 @@ func NewPorterAppRepository(canQuery bool, failingMethods ...string) repository.
 	return &PorterAppRepository{canQuery, strings.Join(failingMethods, ",")}
 }
 
-func (repo *PorterAppRepository) ReadPorterAppByName(clusterID uint, name string) (*models.PorterApp, error) {
+func (repo *PorterAppRepository) ReadPorterAppByName(clusterID uint, name string, envConfigID uint) (*models.PorterApp, error) {
 	return nil, errors.New("cannot write database")
 }
 
@@ -29,14 +29,10 @@ func (repo *PorterAppRepository) UpdatePorterApp(app *models.PorterApp) (*models
 	return nil, errors.New("cannot write database")
 }
 
-func (repo *PorterAppRepository) ListPorterAppByClusterID(clusterID uint) ([]*models.PorterApp, error) {
+func (repo *PorterAppRepository) ListPorterAppByClusterID(clusterID, envConfigID uint) ([]*models.PorterApp, error) {
 	return nil, errors.New("cannot write database")
 }
 
 func (repo *PorterAppRepository) DeletePorterApp(app *models.PorterApp) (*models.PorterApp, error) {
 	return nil, errors.New("cannot write database")
 }
-
-func (repo *PorterAppRepository) ReadPorterAppByNameInEnvironment(clusterID uint, name string, envConfigID uint) (*models.PorterApp, error) {
-	return nil, errors.New("cannot write database")
-}