Преглед изворни кода

add endpoints for reenable/enable deployments

Mohammed Nafees пре 4 година
родитељ
комит
3937597f2f

+ 0 - 2
api/server/handlers/environment/create.go

@@ -60,8 +60,6 @@ func (c *CreateEnvironmentHandler) ServeHTTP(w http.ResponseWriter, r *http.Requ
 		GitRepoOwner:      owner,
 		GitRepoName:       name,
 		Mode:              request.Mode,
-		PRCount:           0,
-		LastPRStatus:      "",
 	})
 
 	if err != nil {

+ 67 - 0
api/server/handlers/environment/enable_pull_request.go

@@ -0,0 +1,67 @@
+package environment
+
+import (
+	"fmt"
+	"net/http"
+
+	"github.com/google/go-github/v41/github"
+	"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/types"
+)
+
+type EnablePullRequestHandler struct {
+	handlers.PorterHandlerReadWriter
+}
+
+func NewEnablePullRequestHandler(
+	config *config.Config,
+	decoderValidator shared.RequestDecoderValidator,
+	writer shared.ResultWriter,
+) *EnablePullRequestHandler {
+	return &EnablePullRequestHandler{
+		PorterHandlerReadWriter: handlers.NewDefaultPorterHandler(config, decoderValidator, writer),
+	}
+}
+
+func (c *EnablePullRequestHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
+	request := &types.PullRequest{}
+
+	if ok := c.DecodeAndValidate(w, r, request); !ok {
+		return
+	}
+
+	env, err := c.Repo().Environment().ReadEnvironmentByOwnerRepoName(request.RepoOwner, request.RepoName)
+
+	if err != nil {
+		c.HandleAPIError(w, r, apierrors.NewErrInternal(err))
+		return
+	}
+
+	client, err := getGithubClientFromEnvironment(c.Config(), env)
+
+	if err != nil {
+		c.HandleAPIError(w, r, apierrors.NewErrInternal(err))
+		return
+	}
+
+	_, err = client.Actions.CreateWorkflowDispatchEventByFileName(
+		r.Context(), env.GitRepoOwner, env.GitRepoName, fmt.Sprintf("porter_%s_env.yml", env.Name),
+		github.CreateWorkflowDispatchEventRequest{
+			Ref: request.BranchFrom,
+			Inputs: map[string]interface{}{
+				"pr_number":      request.Number,
+				"pr_title":       request.Title,
+				"pr_branch_from": request.BranchFrom,
+				"pr_branch_into": request.BranchInto,
+			},
+		},
+	)
+
+	if err != nil {
+		c.HandleAPIError(w, r, apierrors.NewErrInternal(err))
+		return
+	}
+}

+ 16 - 1
api/server/handlers/environment/list.go

@@ -38,7 +38,22 @@ func (c *ListEnvironmentHandler) ServeHTTP(w http.ResponseWriter, r *http.Reques
 	res := make([]*types.Environment, 0)
 
 	for _, env := range envs {
-		res = append(res, env.ToEnvironmentType())
+		environment := env.ToEnvironmentType()
+
+		depls, err := c.Repo().Environment().ListDeployments(env.ID)
+
+		if err != nil {
+			c.HandleAPIError(w, r, apierrors.NewErrInternal(err))
+			return
+		}
+
+		environment.DeploymentCount = uint(len(depls))
+
+		if environment.DeploymentCount > 0 {
+			environment.LastDeploymentStatus = string(depls[0].Status)
+		}
+
+		res = append(res, environment)
 	}
 
 	c.WriteResult(w, r, res)

+ 84 - 0
api/server/handlers/environment/reenable_deployment.go

@@ -0,0 +1,84 @@
+package environment
+
+import (
+	"fmt"
+	"net/http"
+
+	"github.com/google/go-github/v41/github"
+	"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"
+)
+
+type ReenableDeploymentHandler struct {
+	handlers.PorterHandlerReadWriter
+}
+
+func NewReenableDeploymentHandler(
+	config *config.Config,
+	decoderValidator shared.RequestDecoderValidator,
+	writer shared.ResultWriter,
+) *ReenableDeploymentHandler {
+	return &ReenableDeploymentHandler{
+		PorterHandlerReadWriter: handlers.NewDefaultPorterHandler(config, decoderValidator, writer),
+	}
+}
+
+func (c *ReenableDeploymentHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
+	project, _ := r.Context().Value(types.ProjectScope).(*models.Project)
+	cluster, _ := r.Context().Value(types.ClusterScope).(*models.Cluster)
+
+	deplID, reqErr := requestutils.GetURLParamUint(r, "deployment_id")
+
+	if reqErr != nil {
+		c.HandleAPIError(w, r, reqErr)
+		return
+	}
+
+	depl, err := c.Repo().Environment().ReadDeploymentByID(deplID)
+
+	if err != nil {
+		c.HandleAPIError(w, r, apierrors.NewErrInternal(err))
+		return
+	}
+
+	if depl.Status != types.DeploymentStatusInactive {
+		return
+	}
+
+	env, err := c.Repo().Environment().ReadEnvironmentByID(project.ID, cluster.ID, depl.EnvironmentID)
+
+	if err != nil {
+		c.HandleAPIError(w, r, apierrors.NewErrInternal(err))
+		return
+	}
+
+	client, err := getGithubClientFromEnvironment(c.Config(), env)
+
+	if err != nil {
+		c.HandleAPIError(w, r, apierrors.NewErrInternal(err))
+		return
+	}
+
+	_, err = client.Actions.CreateWorkflowDispatchEventByFileName(
+		r.Context(), env.GitRepoOwner, env.GitRepoName, fmt.Sprintf("porter_%s_env.yml", env.Name),
+		github.CreateWorkflowDispatchEventRequest{
+			Ref: depl.PRBranchFrom,
+			Inputs: map[string]interface{}{
+				"pr_number":      depl.PullRequestID,
+				"pr_title":       depl.PRName,
+				"pr_branch_from": depl.PRBranchFrom,
+				"pr_branch_into": depl.PRBranchInto,
+			},
+		},
+	)
+
+	if err != nil {
+		c.HandleAPIError(w, r, apierrors.NewErrInternal(err))
+		return
+	}
+}

+ 2 - 1
api/server/handlers/webhook/github_incoming.go

@@ -12,6 +12,7 @@ import (
 	"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/types"
 	"github.com/porter-dev/porter/internal/models"
 )
 
@@ -98,7 +99,7 @@ func (c *GithubIncomingWebhookHandler) processPullRequestEvent(event *github.Pul
 			return err
 		}
 
-		if depl.Status != "disabled" {
+		if depl.Status != types.DeploymentStatusInactive {
 			_, err := client.Actions.CreateWorkflowDispatchEventByFileName(
 				r.Context(), owner, repo, fmt.Sprintf("porter_%s_env.yml", env.Name),
 				github.CreateWorkflowDispatchEventRequest{

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

@@ -376,6 +376,62 @@ func getClusterRoutes(
 			Router:   r,
 		})
 
+		// PATCH /api/projects/{project_id}/clusters/{cluster_id}/deployments/{deployment_id}/reenable -> environment.NewReenableDeploymentHandler
+		reenableDeploymentEndpoint := factory.NewAPIEndpoint(
+			&types.APIRequestMetadata{
+				Verb:   types.APIVerbUpdate,
+				Method: types.HTTPVerbPatch,
+				Path: &types.Path{
+					Parent:       basePath,
+					RelativePath: relPath + "/deployments/{deployment_id}/reenable",
+				},
+				Scopes: []types.PermissionScope{
+					types.ProjectScope,
+					types.ClusterScope,
+				},
+			},
+		)
+
+		reenableDeploymentHandler := environment.NewReenableDeploymentHandler(
+			config,
+			factory.GetDecoderValidator(),
+			factory.GetResultWriter(),
+		)
+
+		routes = append(routes, &Route{
+			Endpoint: reenableDeploymentEndpoint,
+			Handler:  reenableDeploymentHandler,
+			Router:   r,
+		})
+
+		// POST /api/projects/{project_id}/clusters/{cluster_id}/deployments/pull_request -> environment.NewEnablePullRequestHandler
+		enablePullRequestEndpoint := factory.NewAPIEndpoint(
+			&types.APIRequestMetadata{
+				Verb:   types.APIVerbCreate,
+				Method: types.HTTPVerbPost,
+				Path: &types.Path{
+					Parent:       basePath,
+					RelativePath: relPath + "/deployments/pull_request",
+				},
+				Scopes: []types.PermissionScope{
+					types.ProjectScope,
+					types.ClusterScope,
+				},
+			},
+		)
+
+		enablePullRequestHandler := environment.NewEnablePullRequestHandler(
+			config,
+			factory.GetDecoderValidator(),
+			factory.GetResultWriter(),
+		)
+
+		routes = append(routes, &Route{
+			Endpoint: enablePullRequestEndpoint,
+			Handler:  enablePullRequestHandler,
+			Router:   r,
+		})
+
 	}
 
 	// GET /api/projects/{project_id}/clusters/{cluster_id}/namespaces -> cluster.NewClusterListNamespacesHandler

+ 5 - 6
api/types/environment.go

@@ -10,15 +10,15 @@ type Environment struct {
 	GitRepoOwner      string `json:"git_repo_owner"`
 	GitRepoName       string `json:"git_repo_name"`
 
-	Name         string `json:"name"`
-	Mode         string `json:"mode"`
-	PRCount      uint   `json:"pr_count"`
-	LastPRStatus string `json:"last_pr_status"`
+	Name                 string `json:"name"`
+	Mode                 string `json:"mode"`
+	DeploymentCount      uint   `json:"deployment_count"`
+	LastDeploymentStatus string `json:"last_deployment_status"`
 }
 
 type CreateEnvironmentRequest struct {
 	Name string `json:"name" form:"required"`
-	Mode string `json:"mode" form:"required"`
+	Mode string `json:"mode" form:"oneof=auto manual" default:"manual"`
 }
 
 type GitHubMetadata struct {
@@ -38,7 +38,6 @@ const (
 	DeploymentStatusCreating DeploymentStatus = "creating"
 	DeploymentStatusInactive DeploymentStatus = "inactive"
 	DeploymentStatusFailed   DeploymentStatus = "failed"
-	DeploymentStatusDisabled DeploymentStatus = "disabled"
 )
 
 type Deployment struct {

+ 4 - 8
internal/models/environment.go

@@ -16,10 +16,8 @@ type Environment struct {
 	GitRepoOwner      string
 	GitRepoName       string
 
-	Name         string
-	Mode         string
-	PRCount      uint
-	LastPRStatus string
+	Name string
+	Mode string
 }
 
 func (e *Environment) ToEnvironmentType() *types.Environment {
@@ -31,10 +29,8 @@ func (e *Environment) ToEnvironmentType() *types.Environment {
 		GitRepoOwner:      e.GitRepoOwner,
 		GitRepoName:       e.GitRepoName,
 
-		Name:         e.Name,
-		Mode:         e.Mode,
-		PRCount:      e.PRCount,
-		LastPRStatus: e.LastPRStatus,
+		Name: e.Name,
+		Mode: e.Mode,
 	}
 }
 

+ 1 - 0
internal/repository/environment.go

@@ -11,6 +11,7 @@ type EnvironmentRepository interface {
 	DeleteEnvironment(env *models.Environment) (*models.Environment, error)
 	CreateDeployment(deployment *models.Deployment) (*models.Deployment, error)
 	ReadDeployment(environmentID uint, namespace string) (*models.Deployment, error)
+	ReadDeploymentByID(id uint) (*models.Deployment, error)
 	ReadDeploymentByCluster(projectID, clusterID uint, namespace string) (*models.Deployment, error)
 	ReadDeploymentByGitDetails(environmentID uint, owner, repo string, prNumber uint) (*models.Deployment, error)
 	ListDeploymentsByCluster(projectID, clusterID uint, states ...string) ([]*models.Deployment, error)

+ 8 - 0
internal/repository/gorm/environment.go

@@ -103,6 +103,14 @@ func (repo *EnvironmentRepository) ReadDeployment(environmentID uint, namespace
 	return depl, nil
 }
 
+func (repo *EnvironmentRepository) ReadDeploymentByID(id uint) (*models.Deployment, error) {
+	depl := &models.Deployment{}
+	if err := repo.db.Where("id = ?", id).First(&depl).Error; err != nil {
+		return nil, err
+	}
+	return depl, nil
+}
+
 func (repo *EnvironmentRepository) ReadDeploymentByCluster(projectID, clusterID uint, namespace string) (*models.Deployment, error) {
 	depl := &models.Deployment{}