Browse Source

add new endpoint for deployment revisions

Mohammed Nafees 3 years ago
parent
commit
cbf6a3372b

+ 20 - 0
api/server/handlers/environment/finalize_deployment.go

@@ -118,6 +118,26 @@ func (c *FinalizeDeploymentHandler) ServeHTTP(w http.ResponseWriter, r *http.Req
 		return
 	}
 
+	var resources []models.DeploymentRevisionResource
+
+	for _, res := range request.SuccessfulResources {
+		resources = append(resources, models.DeploymentRevisionResource{
+			Name:   res.ReleaseName,
+			Type:   res.ReleaseType,
+			Status: types.DeploymentStatusCreated,
+		})
+	}
+
+	_, err = c.Repo().Environment().AddNewDeploymentRevision(depl.ID, &models.DeploymentRevision{
+		Status:    types.DeploymentStatusCreated,
+		Resources: resources,
+	})
+
+	if err != nil {
+		c.HandleAPIError(w, r, apierrors.NewErrInternal(err))
+		return
+	}
+
 	client, err := getGithubClientFromEnvironment(c.Config(), env)
 
 	if err != nil {

+ 29 - 0
api/server/handlers/environment/finalize_deployment_with_errors.go

@@ -112,6 +112,35 @@ func (c *FinalizeDeploymentWithErrorsHandler) ServeHTTP(w http.ResponseWriter, r
 		return
 	}
 
+	var resources []models.DeploymentRevisionResource
+
+	for _, res := range request.SuccessfulResources {
+		resources = append(resources, models.DeploymentRevisionResource{
+			Name:   res.ReleaseName,
+			Type:   res.ReleaseType,
+			Status: types.DeploymentStatusCreated,
+		})
+	}
+
+	for name, errString := range request.Errors {
+		resources = append(resources, models.DeploymentRevisionResource{
+			Name: name,
+			// FIXME: get type for error-ed resource
+			Status: types.DeploymentStatusFailed,
+			Errors: errString,
+		})
+	}
+
+	_, err = c.Repo().Environment().AddNewDeploymentRevision(depl.ID, &models.DeploymentRevision{
+		Status:    types.DeploymentStatusFailed,
+		Resources: resources,
+	})
+
+	if err != nil {
+		c.HandleAPIError(w, r, apierrors.NewErrInternal(err))
+		return
+	}
+
 	client, err := getGithubClientFromEnvironment(c.Config(), env)
 
 	if err != nil {

+ 81 - 0
api/server/handlers/environment/list_deployment_revisions.go

@@ -0,0 +1,81 @@
+package environment
+
+import (
+	"errors"
+	"fmt"
+	"net/http"
+
+	"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/server/shared/requestutils"
+	"github.com/porter-dev/porter/api/types"
+	"github.com/porter-dev/porter/internal/models"
+	"gorm.io/gorm"
+)
+
+type ListDeploymentRevisionsHandler struct {
+	handlers.PorterHandlerReadWriter
+}
+
+func NewListDeploymentRevisionsHandler(
+	config *config.Config,
+	decoderValidator shared.RequestDecoderValidator,
+	writer shared.ResultWriter,
+) *ListDeploymentRevisionsHandler {
+	return &ListDeploymentRevisionsHandler{
+		PorterHandlerReadWriter: handlers.NewDefaultPorterHandler(config, decoderValidator, writer),
+	}
+}
+
+func (c *ListDeploymentRevisionsHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
+	project, _ := r.Context().Value(types.ProjectScope).(*models.Project)
+	cluster, _ := r.Context().Value(types.ClusterScope).(*models.Cluster)
+
+	envID, reqErr := requestutils.GetURLParamUint(r, "environment_id")
+
+	if reqErr != nil {
+		c.HandleAPIError(w, r, reqErr)
+		return
+	}
+
+	deplID, reqErr := requestutils.GetURLParamUint(r, "deployment_id")
+
+	if reqErr != nil {
+		c.HandleAPIError(w, r, reqErr)
+		return
+	}
+
+	depl, err := c.Repo().Environment().ReadDeploymentByID(project.ID, cluster.ID, deplID)
+
+	if err != nil {
+		if errors.Is(err, gorm.ErrRecordNotFound) {
+			c.HandleAPIError(w, r, apierrors.NewErrNotFound(errDeploymentNotFound))
+			return
+		}
+
+		c.HandleAPIError(w, r, apierrors.NewErrInternal(err))
+		return
+	}
+
+	if depl.EnvironmentID != envID {
+		c.HandleAPIError(w, r, apierrors.NewErrPassThroughToClient(fmt.Errorf("deployment does not exist in environment"), http.StatusBadRequest))
+		return
+	}
+
+	revisions, err := c.Repo().Environment().ListDeploymentRevisions(deplID)
+
+	if err != nil {
+		c.HandleAPIError(w, r, apierrors.NewErrInternal(err))
+		return
+	}
+
+	var res []*types.DeploymentRevision
+
+	for _, rev := range revisions {
+		res = append(res, rev.ToDeploymentRevisionType())
+	}
+
+	c.WriteResult(w, r, res)
+}

+ 30 - 0
api/server/router/cluster.go

@@ -468,6 +468,36 @@ func getClusterRoutes(
 			Router:   r,
 		})
 
+		// GET /api/projects/{project_id}/clusters/{cluster_id}/environments/{environment_id}/deployments/{deployment_id}/revisions -> environment.NewListDeploymentRevisionsHandler
+		listDeploymentRevisionsEndpoint := factory.NewAPIEndpoint(
+			&types.APIRequestMetadata{
+				Verb:   types.APIVerbGet,
+				Method: types.HTTPVerbGet,
+				Path: &types.Path{
+					Parent:       basePath,
+					RelativePath: relPath + "/environments/{environment_id}/deployments/{deployment_id}/revisions",
+				},
+				Scopes: []types.PermissionScope{
+					types.UserScope,
+					types.ProjectScope,
+					types.ClusterScope,
+					types.PreviewEnvironmentScope,
+				},
+			},
+		)
+
+		listDeploymentRevisionsHandler := environment.NewListDeploymentRevisionsHandler(
+			config,
+			factory.GetDecoderValidator(),
+			factory.GetResultWriter(),
+		)
+
+		routes = append(routes, &router.Route{
+			Endpoint: listDeploymentRevisionsEndpoint,
+			Handler:  listDeploymentRevisionsHandler,
+			Router:   r,
+		})
+
 		// PATCH /api/projects/{project_id}/clusters/{cluster_id}/deployments/{deployment_id}/reenable -> environment.NewReenableDeploymentHandler
 		reenableDeploymentEndpoint := factory.NewAPIEndpoint(
 			&types.APIRequestMetadata{

+ 3 - 1
api/types/environment.go

@@ -68,13 +68,15 @@ type Deployment struct {
 type DeploymentRevision struct {
 	RevisionNumber uint                         `json:"revision_number"`
 	DeploymentID   uint                         `json:"deployment_id"`
+	Status         DeploymentStatus             `json:"status"`
 	Resources      []DeploymentRevisionResource `json:"resources"`
 }
 
 type DeploymentRevisionResource struct {
 	Name   string           `json:"name"`
+	Type   string           `json:"type"`
 	Status DeploymentStatus `json:"status"`
-	Errors []string         `json:"errors"`
+	Errors string           `json:"errors"`
 }
 
 type CreateGHDeploymentRequest struct {

+ 6 - 6
internal/models/environment.go

@@ -106,6 +106,7 @@ type DeploymentRevision struct {
 	DeploymentID uint
 
 	RevisionNumber uint
+	Status         types.DeploymentStatus
 	Resources      []DeploymentRevisionResource
 }
 
@@ -119,6 +120,7 @@ func (d *DeploymentRevision) ToDeploymentRevisionType() *types.DeploymentRevisio
 	return &types.DeploymentRevision{
 		RevisionNumber: d.RevisionNumber,
 		DeploymentID:   d.DeploymentID,
+		Status:         d.Status,
 		Resources:      resources,
 	}
 }
@@ -129,19 +131,17 @@ type DeploymentRevisionResource struct {
 	DeploymentRevisionID uint
 
 	Name   string
+	Type   string
 	Status types.DeploymentStatus
-	Errors []byte
+	Errors string
 }
 
 func (d *DeploymentRevisionResource) ToDeploymentResourceType() types.DeploymentRevisionResource {
 	res := types.DeploymentRevisionResource{
 		Name:   d.Name,
+		Type:   d.Type,
 		Status: d.Status,
-		Errors: []string{},
-	}
-
-	if len(d.Errors) > 0 {
-		res.Errors = strings.Split(string(d.Errors), ",")
+		Errors: d.Errors,
 	}
 
 	return res

+ 2 - 0
internal/repository/gorm/migrate.go

@@ -21,6 +21,8 @@ func AutoMigrate(db *gorm.DB, debug bool) error {
 		&models.Release{},
 		&models.Environment{},
 		&models.Deployment{},
+		&models.DeploymentRevision{},
+		&models.DeploymentRevisionResource{},
 		&models.Session{},
 		&models.GitRepo{},
 		&models.Registry{},