Parcourir la source

add NewCreateGCPHandler

Anukul Sangwan il y a 4 ans
Parent
commit
2088374224

+ 3 - 13
api/client/integration.go

@@ -8,7 +8,6 @@ import (
 	"strings"
 
 	"github.com/porter-dev/porter/api/types"
-	ints "github.com/porter-dev/porter/internal/models/integrations"
 )
 
 // CreateAWSIntegration creates an AWS integration with the given request options
@@ -47,21 +46,12 @@ func (c *Client) CreateAWSIntegration(
 	return bodyResp, nil
 }
 
-// CreateGCPIntegrationRequest represents the accepted fields for creating
-// a gcp integration
-type CreateGCPIntegrationRequest struct {
-	GCPKeyData string `json:"gcp_key_data"`
-}
-
-// CreateGCPIntegrationResponse is the resulting integration after creation
-type CreateGCPIntegrationResponse ints.GCPIntegrationExternal
-
 // CreateGCPIntegration creates a GCP integration with the given request options
 func (c *Client) CreateGCPIntegration(
 	ctx context.Context,
 	projectID uint,
-	createGCP *CreateGCPIntegrationRequest,
-) (*CreateGCPIntegrationResponse, error) {
+	createGCP *types.CreateGCPRequest,
+) (*types.CreateGCPResponse, error) {
 	data, err := json.Marshal(createGCP)
 
 	if err != nil {
@@ -79,7 +69,7 @@ func (c *Client) CreateGCPIntegration(
 	}
 
 	req = req.WithContext(ctx)
-	bodyResp := &CreateGCPIntegrationResponse{}
+	bodyResp := &types.CreateGCPResponse{}
 
 	if httpErr, err := c.sendRequest(req, bodyResp, true); httpErr != nil || err != nil {
 		if httpErr != nil {

+ 63 - 0
api/server/handlers/project_integrations/create_gcp.go

@@ -0,0 +1,63 @@
+package project_integration
+
+import (
+	"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/types"
+	"github.com/porter-dev/porter/internal/models"
+	ints "github.com/porter-dev/porter/internal/models/integrations"
+)
+
+type CreateGCPHandler struct {
+	handlers.PorterHandlerReadWriter
+}
+
+func NewCreateGCPHandler(
+	config *config.Config,
+	decoderValidator shared.RequestDecoderValidator,
+	writer shared.ResultWriter,
+) *CreateGCPHandler {
+	return &CreateGCPHandler{
+		PorterHandlerReadWriter: handlers.NewDefaultPorterHandler(config, decoderValidator, writer),
+	}
+}
+
+func (p *CreateGCPHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
+	user, _ := r.Context().Value(types.UserScope).(*models.User)
+	project, _ := r.Context().Value(types.ProjectScope).(*models.Project)
+
+	request := &types.CreateGCPRequest{}
+
+	if ok := p.DecodeAndValidate(w, r, request); !ok {
+		return
+	}
+
+	gcp := CreateGCPIntegration(request, project.ID, user.ID)
+
+	gcp, err := p.Repo().GCPIntegration().CreateGCPIntegration(gcp)
+
+	if err != nil {
+		p.HandleAPIError(w, r, apierrors.NewErrInternal(err))
+		return
+	}
+
+	res := types.CreateGCPResponse{
+		GCPIntegration: gcp.ToGCPIntegrationType(),
+	}
+
+	p.WriteResult(w, r, res)
+}
+
+func CreateGCPIntegration(request *types.CreateGCPRequest, projectID, userID uint) *ints.GCPIntegration {
+	return &ints.GCPIntegration{
+		UserID:       userID,
+		ProjectID:    projectID,
+		GCPKeyData:   []byte(request.GCPKeyData),
+		GCPProjectID: request.GCPProjectID,
+		GCPRegion:    request.GCPRegion,
+	}
+}

+ 28 - 0
api/server/router/project_integration.go

@@ -163,5 +163,33 @@ func getProjectIntegrationRoutes(
 		Router:   r,
 	})
 
+	// POST /api/projects/{project_id}/integrations/gcp -> project_integrations.NewCreateGCPHandler
+	createGCPEndpoint := factory.NewAPIEndpoint(
+		&types.APIRequestMetadata{
+			Verb:   types.APIVerbCreate,
+			Method: types.HTTPVerbPost,
+			Path: &types.Path{
+				Parent:       basePath,
+				RelativePath: relPath + "/gcp",
+			},
+			Scopes: []types.PermissionScope{
+				types.UserScope,
+				types.ProjectScope,
+			},
+		},
+	)
+
+	createGCPHandler := project_integration.NewCreateGCPHandler(
+		config,
+		factory.GetDecoderValidator(),
+		factory.GetResultWriter(),
+	)
+
+	routes = append(routes, &Route{
+		Endpoint: createGCPEndpoint,
+		Handler:  createGCPHandler,
+		Router:   r,
+	})
+
 	return routes, newPath
 }

+ 26 - 0
api/types/project_integration.go

@@ -79,3 +79,29 @@ type OverwriteAWSRequest struct {
 type OverwriteAWSResponse struct {
 	*AWSIntegration
 }
+
+type GCPIntegration struct {
+	ID uint `json:"id"`
+
+	// The id of the user that linked this auth mechanism
+	UserID uint `json:"user_id"`
+
+	// The project that this integration belongs to
+	ProjectID uint `json:"project_id"`
+
+	// The GCP project id where the service account for this auth mechanism persists
+	GCPProjectID string `json:"gcp-project-id"`
+
+	// The GCP user email that linked this service account
+	GCPUserEmail string `json:"gcp-user-email"`
+}
+
+type CreateGCPRequest struct {
+	GCPKeyData   string `json:"gcp_key_data" form:"required"`
+	GCPProjectID string `json:"gcp_project_id"`
+	GCPRegion    string `json:"gcp_region"`
+}
+
+type CreateGCPResponse struct {
+	*GCPIntegration
+}

+ 3 - 1
cli/cmd/connect/gcr.go

@@ -7,7 +7,9 @@ import (
 	"os"
 
 	"github.com/fatih/color"
+
 	api "github.com/porter-dev/porter/api/client"
+	"github.com/porter-dev/porter/api/types"
 	"github.com/porter-dev/porter/cli/cmd/utils"
 )
 
@@ -41,7 +43,7 @@ Key file location: `))
 		integration, err := client.CreateGCPIntegration(
 			context.Background(),
 			projectID,
-			&api.CreateGCPIntegrationRequest{
+			&types.CreateGCPRequest{
 				GCPKeyData: string(bytes),
 			},
 		)

+ 1 - 1
docs/developing/backend-refactor-status.md

@@ -70,7 +70,7 @@
 | <li>- [x] `POST /api/projects/{project_id}/integrations/aws`                                                                | AS          |                 | yes         | yes              |
 | <li>- [x] `POST /api/projects/{project_id}/integrations/aws/{aws_integration_id}/overwrite`                                 | AS          | yes             |             | yes              |
 | <li>- [x] `POST /api/projects/{project_id}/integrations/basic`                                                              | AS          |                 | yes         |                  |
-| <li>- [ ] `POST /api/projects/{project_id}/integrations/gcp`                                                                |             |                 |             |                  |
+| <li>- [x] `POST /api/projects/{project_id}/integrations/gcp`                                                                | AS          |                 | yes         | yes              |
 | <li>- [x] `GET /api/projects/{project_id}/integrations/oauth`                                                               | AS          |                 | yes         | yes              |
 | <li>- [x] `GET /api/projects/{project_id}/invites`                                                                          | AS          |                 |             | yes              |
 | <li>- [x] `POST /api/projects/{project_id}/invites`                                                                         | AS          |                 |             | yes              |

+ 3 - 20
internal/models/integrations/gcp.go

@@ -3,6 +3,7 @@ package integrations
 import (
 	"context"
 	"encoding/json"
+	"github.com/porter-dev/porter/api/types"
 
 	"golang.org/x/oauth2"
 	"golang.org/x/oauth2/google"
@@ -37,26 +38,8 @@ type GCPIntegration struct {
 	GCPKeyData []byte `json:"gcp_key_data"`
 }
 
-// GCPIntegrationExternal is a GCPIntegration to be shared over REST
-type GCPIntegrationExternal struct {
-	ID uint `json:"id"`
-
-	// The id of the user that linked this auth mechanism
-	UserID uint `json:"user_id"`
-
-	// The project that this integration belongs to
-	ProjectID uint `json:"project_id"`
-
-	// The GCP project id where the service account for this auth mechanism persists
-	GCPProjectID string `json:"gcp-project-id"`
-
-	// The GCP user email that linked this service account
-	GCPUserEmail string `json:"gcp-user-email"`
-}
-
-// Externalize generates an external KubeIntegration to be shared over REST
-func (g *GCPIntegration) Externalize() *GCPIntegrationExternal {
-	return &GCPIntegrationExternal{
+func (g *GCPIntegration) ToGCPIntegrationType() *types.GCPIntegration {
+	return &types.GCPIntegration{
 		ID:           g.ID,
 		UserID:       g.UserID,
 		ProjectID:    g.ProjectID,