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

add procfile endpoint for gitlab

Mohammed Nafees 4 лет назад
Родитель
Сommit
4bac12180f

+ 13 - 1
api/server/handlers/project_integration/get_gitlab_repo_buildpack.go

@@ -8,11 +8,13 @@ import (
 	"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/commonutils"
 	"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/integrations/buildpacks"
 	"github.com/porter-dev/porter/internal/models"
+	"github.com/porter-dev/porter/internal/oauth"
 	"github.com/xanzy/go-gitlab"
 	"gorm.io/gorm"
 )
@@ -95,7 +97,17 @@ func (p *GetGitlabRepoBuildpackHandler) ServeHTTP(w http.ResponseWriter, r *http
 		return
 	}
 
-	client, err := gitlab.NewOAuthClient(string(giAppOAuth.AccessToken), gitlab.WithBaseURL(gi.InstanceURL))
+	accessToken, _, err := oauth.GetAccessToken(giAppOAuth.SharedOAuthModel, commonutils.GetGitlabOAuthConf(
+		p.Config(), gi,
+	), oauth.MakeUpdateGitlabAppOAuthIntegrationFunction(giAppOAuth, p.Repo()))
+
+	if err != nil {
+		p.HandleAPIError(w, r, apierrors.NewErrPassThroughToClient(fmt.Errorf("invalid gitlab access token"),
+			http.StatusUnauthorized))
+		return
+	}
+
+	client, err := gitlab.NewOAuthClient(accessToken, gitlab.WithBaseURL(gi.InstanceURL))
 
 	if err != nil {
 		p.HandleAPIError(w, r, apierrors.NewErrInternal(err))

+ 13 - 1
api/server/handlers/project_integration/get_gitlab_repo_contents.go

@@ -8,10 +8,12 @@ import (
 	"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/commonutils"
 	"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"
+	"github.com/porter-dev/porter/internal/oauth"
 	"github.com/xanzy/go-gitlab"
 	"gorm.io/gorm"
 )
@@ -94,7 +96,17 @@ func (p *GetGitlabRepoContentsHandler) ServeHTTP(w http.ResponseWriter, r *http.
 		return
 	}
 
-	client, err := gitlab.NewOAuthClient(string(giAppOAuth.AccessToken), gitlab.WithBaseURL(gi.InstanceURL))
+	accessToken, _, err := oauth.GetAccessToken(giAppOAuth.SharedOAuthModel, commonutils.GetGitlabOAuthConf(
+		p.Config(), gi,
+	), oauth.MakeUpdateGitlabAppOAuthIntegrationFunction(giAppOAuth, p.Repo()))
+
+	if err != nil {
+		p.HandleAPIError(w, r, apierrors.NewErrPassThroughToClient(fmt.Errorf("invalid gitlab access token"),
+			http.StatusUnauthorized))
+		return
+	}
+
+	client, err := gitlab.NewOAuthClient(accessToken, gitlab.WithBaseURL(gi.InstanceURL))
 
 	if err != nil {
 		p.HandleAPIError(w, r, apierrors.NewErrInternal(err))

+ 150 - 0
api/server/handlers/project_integration/get_gitlab_repo_procfile.go

@@ -0,0 +1,150 @@
+package project_integration
+
+import (
+	"errors"
+	"fmt"
+	"net/http"
+	"regexp"
+	"strings"
+
+	"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/commonutils"
+	"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"
+	"github.com/porter-dev/porter/internal/oauth"
+	"github.com/xanzy/go-gitlab"
+	"gorm.io/gorm"
+)
+
+var procfileRegex = regexp.MustCompile("^([A-Za-z0-9_]+):\\s*(.+)$")
+
+type GetGitlabRepoProcfileHandler struct {
+	handlers.PorterHandlerReadWriter
+}
+
+func NewGetGitlabRepoProcfileHandler(
+	config *config.Config,
+	decoderValidator shared.RequestDecoderValidator,
+	writer shared.ResultWriter,
+) *GetGitlabRepoProcfileHandler {
+	return &GetGitlabRepoProcfileHandler{
+		PorterHandlerReadWriter: handlers.NewDefaultPorterHandler(config, decoderValidator, writer),
+	}
+}
+
+func (p *GetGitlabRepoProcfileHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
+	project, _ := r.Context().Value(types.ProjectScope).(*models.Project)
+	user, _ := r.Context().Value(types.UserScope).(*models.User)
+
+	request := &types.GetProcfileRequest{}
+
+	ok := p.DecodeAndValidate(w, r, request)
+
+	if !ok {
+		return
+	}
+
+	integrationID, reqErr := requestutils.GetURLParamUint(r, "integration_id")
+
+	if reqErr != nil {
+		p.HandleAPIError(w, r, apierrors.NewErrInternal(reqErr))
+		return
+	}
+
+	owner, reqErr := requestutils.GetURLParamString(r, types.URLParamGitRepoOwner)
+
+	if reqErr != nil {
+		p.HandleAPIError(w, r, apierrors.NewErrInternal(reqErr))
+		return
+	}
+
+	name, reqErr := requestutils.GetURLParamString(r, types.URLParamGitRepoName)
+
+	if reqErr != nil {
+		p.HandleAPIError(w, r, apierrors.NewErrInternal(reqErr))
+		return
+	}
+
+	branch, reqErr := requestutils.GetURLParamString(r, types.URLParamGitBranch)
+
+	if reqErr != nil {
+		p.HandleAPIError(w, r, apierrors.NewErrInternal(reqErr))
+		return
+	}
+
+	gi, err := p.Repo().GitlabIntegration().ReadGitlabIntegration(project.ID, integrationID)
+
+	if err != nil {
+		if errors.Is(err, gorm.ErrRecordNotFound) {
+			p.HandleAPIError(w, r, apierrors.NewErrPassThroughToClient(fmt.Errorf("no gitlab integration with ID: %d", integrationID), http.StatusNotFound))
+			return
+		}
+
+		p.HandleAPIError(w, r, apierrors.NewErrInternal(err))
+		return
+	}
+
+	giAppOAuth, err := p.Repo().GitlabAppOAuthIntegration().ReadGitlabAppOAuthIntegration(user.ID, project.ID, integrationID)
+
+	if err != nil {
+		if errors.Is(err, gorm.ErrRecordNotFound) {
+			p.HandleAPIError(w, r, apierrors.NewErrPassThroughToClient(fmt.Errorf("unauthorized gitlab user"), http.StatusUnauthorized))
+			return
+		}
+
+		p.HandleAPIError(w, r, apierrors.NewErrInternal(err))
+		return
+	}
+
+	accessToken, _, err := oauth.GetAccessToken(giAppOAuth.SharedOAuthModel, commonutils.GetGitlabOAuthConf(
+		p.Config(), gi,
+	), oauth.MakeUpdateGitlabAppOAuthIntegrationFunction(giAppOAuth, p.Repo()))
+
+	if err != nil {
+		p.HandleAPIError(w, r, apierrors.NewErrPassThroughToClient(fmt.Errorf("invalid gitlab access token"),
+			http.StatusUnauthorized))
+		return
+	}
+
+	client, err := gitlab.NewOAuthClient(accessToken, gitlab.WithBaseURL(gi.InstanceURL))
+
+	if err != nil {
+		p.HandleAPIError(w, r, apierrors.NewErrInternal(err))
+		return
+	}
+
+	file, resp, err := client.RepositoryFiles.GetRawFile(fmt.Sprintf("%s/%s", owner, name), request.Path,
+		&gitlab.GetRawFileOptions{
+			Ref: gitlab.String(branch),
+		},
+	)
+
+	if resp.StatusCode == http.StatusUnauthorized {
+		p.HandleAPIError(w, r, apierrors.NewErrPassThroughToClient(fmt.Errorf("unauthorized gitlab user"), http.StatusUnauthorized))
+		return
+	} else if resp.StatusCode == http.StatusNotFound {
+		w.WriteHeader(http.StatusNotFound)
+		p.HandleAPIError(w, r, apierrors.NewErrInternal(fmt.Errorf("no such procfile exists")))
+		return
+	}
+
+	if err != nil {
+		p.HandleAPIError(w, r, apierrors.NewErrInternal(err))
+		return
+	}
+
+	parsedContents := make(types.GetProcfileResponse)
+
+	// parse the procfile information
+	for _, line := range strings.Split(string(file), "\n") {
+		if matches := procfileRegex.FindStringSubmatch(line); matches != nil {
+			parsedContents[matches[1]] = matches[2]
+		}
+	}
+
+	p.WriteResult(w, r, parsedContents)
+}

+ 13 - 1
api/server/handlers/project_integration/list_gitlab_repo_branches.go

@@ -8,10 +8,12 @@ import (
 	"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/commonutils"
 	"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"
+	"github.com/porter-dev/porter/internal/oauth"
 	"github.com/xanzy/go-gitlab"
 	"gorm.io/gorm"
 )
@@ -79,7 +81,17 @@ func (p *ListGitlabRepoBranchesHandler) ServeHTTP(w http.ResponseWriter, r *http
 		return
 	}
 
-	client, err := gitlab.NewOAuthClient(string(giAppOAuth.AccessToken), gitlab.WithBaseURL(gi.InstanceURL))
+	accessToken, _, err := oauth.GetAccessToken(giAppOAuth.SharedOAuthModel, commonutils.GetGitlabOAuthConf(
+		p.Config(), gi,
+	), oauth.MakeUpdateGitlabAppOAuthIntegrationFunction(giAppOAuth, p.Repo()))
+
+	if err != nil {
+		p.HandleAPIError(w, r, apierrors.NewErrPassThroughToClient(fmt.Errorf("invalid gitlab access token"),
+			http.StatusUnauthorized))
+		return
+	}
+
+	client, err := gitlab.NewOAuthClient(accessToken, gitlab.WithBaseURL(gi.InstanceURL))
 
 	if err != nil {
 		p.HandleAPIError(w, r, apierrors.NewErrInternal(err))

+ 13 - 1
api/server/handlers/project_integration/list_gitlab_repos.go

@@ -8,10 +8,12 @@ import (
 	"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/commonutils"
 	"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"
+	"github.com/porter-dev/porter/internal/oauth"
 	"github.com/xanzy/go-gitlab"
 	"gorm.io/gorm"
 )
@@ -65,7 +67,17 @@ func (p *ListGitlabReposHandler) ServeHTTP(w http.ResponseWriter, r *http.Reques
 		return
 	}
 
-	client, err := gitlab.NewOAuthClient(string(giAppOAuth.AccessToken), gitlab.WithBaseURL(gi.InstanceURL))
+	accessToken, _, err := oauth.GetAccessToken(giAppOAuth.SharedOAuthModel, commonutils.GetGitlabOAuthConf(
+		p.Config(), gi,
+	), oauth.MakeUpdateGitlabAppOAuthIntegrationFunction(giAppOAuth, p.Repo()))
+
+	if err != nil {
+		p.HandleAPIError(w, r, apierrors.NewErrPassThroughToClient(fmt.Errorf("invalid gitlab access token"),
+			http.StatusUnauthorized))
+		return
+	}
+
+	client, err := gitlab.NewOAuthClient(accessToken, gitlab.WithBaseURL(gi.InstanceURL))
 
 	if err != nil {
 		p.HandleAPIError(w, r, apierrors.NewErrInternal(err))

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

@@ -530,5 +530,34 @@ func getProjectIntegrationRoutes(
 		Router:   r,
 	})
 
+	// GET /api/projects/{project_id}/integrations/gitlab/{integration_id}/repos/{owner}/{name}/{branch}/procfile
+	getGitlabRepoProcfileEndpoint := factory.NewAPIEndpoint(
+		&types.APIRequestMetadata{
+			Verb:   types.APIVerbGet,
+			Method: types.HTTPVerbGet,
+			Path: &types.Path{
+				Parent: basePath,
+				RelativePath: fmt.Sprintf("%s/gitlab/{integration_id}/repos/{%s}/{%s}/{%s}/procfile", relPath,
+					types.URLParamGitRepoOwner, types.URLParamGitRepoName, types.URLParamGitBranch),
+			},
+			Scopes: []types.PermissionScope{
+				types.UserScope,
+				types.ProjectScope,
+			},
+		},
+	)
+
+	getGitlabRepoProcfileHandler := project_integration.NewGetGitlabRepoProcfileHandler(
+		config,
+		factory.GetDecoderValidator(),
+		factory.GetResultWriter(),
+	)
+
+	routes = append(routes, &Route{
+		Endpoint: getGitlabRepoProcfileEndpoint,
+		Handler:  getGitlabRepoProcfileHandler,
+		Router:   r,
+	})
+
 	return routes, newPath
 }