From d0562a573c2517a33412b2bc03fecaefedc77ae9 Mon Sep 17 00:00:00 2001 From: Abhinav Singh Date: Tue, 23 Jul 2024 21:39:39 +0000 Subject: [PATCH] feat: [CODE-2146]: add new router paradigm * lint * address comment * fix * ssh ctx * add ctx for new places * generate wiregen * Merge remote-tracking branch 'harness0/main' into abhinav/new-router-paradigm * Merge branch 'main' into abhinav/new-router-paradigm * add new discussion changes * address comment * address comment * address comment * address comment * address comment * feat: abstract routers logic * feat: abstract routers logic * feat: abstract routers logic * feat: abstract routers logic * feat: abstract routers logic * feat: abstract routers logic * feat: abstract routers logic * style * remove nil context * add ctx to missing * style * remvoe ctx * remvoe ctx * feat: provider should have ctx --- app/api/controller/githook/post_receive.go | 4 +- app/api/controller/repo/create.go | 6 +- app/api/controller/repo/find.go | 4 +- app/api/controller/repo/import.go | 4 +- app/api/controller/repo/move.go | 4 +- app/api/controller/repo/purge.go | 2 +- app/api/controller/repo/update.go | 4 +- .../controller/repo/update_public_access.go | 4 +- app/api/controller/space/list_repositories.go | 4 +- app/api/controller/util.go | 2 +- app/api/handler/repo/find_redirect.go | 2 +- app/api/handler/repo/git_info_refs.go | 7 +- app/api/handler/repo/git_service_pack.go | 2 +- app/pipeline/manager/client.go | 4 +- app/pipeline/manager/manager.go | 4 +- app/pipeline/triggerer/env.go | 5 +- app/pipeline/triggerer/trigger.go | 2 +- app/router/api.go | 7 +- app/router/api_router.go | 58 +++++++++ app/router/git.go | 7 +- app/router/git_router.go | 76 ++++++++++++ app/router/interface.go | 25 ++++ app/router/logging.go | 28 +++++ app/router/router.go | 111 ++---------------- app/router/web.go | 7 +- app/router/web_router.go | 43 +++++++ app/router/wire.go | 56 ++++----- app/services/importer/repository.go | 2 +- app/services/notification/service.go | 2 +- app/services/pullreq/service.go | 2 +- app/services/repo/handlers_default_branch.go | 2 +- app/services/webhook/handler_branch.go | 6 +- app/services/webhook/handler_pullreq.go | 36 +++--- app/services/webhook/handler_tag.go | 6 +- app/services/webhook/types.go | 16 ++- app/url/provider.go | 45 +++---- cmd/gitness/wire_gen.go | 5 +- 37 files changed, 366 insertions(+), 238 deletions(-) create mode 100644 app/router/api_router.go create mode 100644 app/router/git_router.go create mode 100644 app/router/interface.go create mode 100644 app/router/logging.go create mode 100644 app/router/web_router.go diff --git a/app/api/controller/githook/post_receive.go b/app/api/controller/githook/post_receive.go index 428d29ebe..0ddda7790 100644 --- a/app/api/controller/githook/post_receive.go +++ b/app/api/controller/githook/post_receive.go @@ -245,7 +245,7 @@ func (c *Controller) suggestPullRequest( msgs[0] = fmt.Sprintf("Branch %q has open PRs:", branchName) for i, pr := range prs { msgs[2*i+1] = fmt.Sprintf(" (#%d) %s", pr.Number, pr.Title) - msgs[2*i+2] = " " + c.urlProvider.GenerateUIPRURL(repo.Path, pr.Number) + msgs[2*i+2] = " " + c.urlProvider.GenerateUIPRURL(ctx, repo.Path, pr.Number) } out.Messages = append(out.Messages, msgs...) return @@ -254,7 +254,7 @@ func (c *Controller) suggestPullRequest( // this is a new PR! out.Messages = append(out.Messages, fmt.Sprintf("Create a pull request for %q by visiting:", branchName), - " "+c.urlProvider.GenerateUICompareURL(repo.Path, repo.DefaultBranch, branchName), + " "+c.urlProvider.GenerateUICompareURL(ctx, repo.Path, repo.DefaultBranch, branchName), ) } diff --git a/app/api/controller/repo/create.go b/app/api/controller/repo/create.go index b8b235718..4f4f7cc4a 100644 --- a/app/api/controller/repo/create.go +++ b/app/api/controller/repo/create.go @@ -146,8 +146,8 @@ func (c *Controller) Create(ctx context.Context, session *auth.Session, in *Crea } // backfil GitURL - repo.GitURL = c.urlProvider.GenerateGITCloneURL(repo.Path) - repo.GitSSHURL = c.urlProvider.GenerateGITCloneSSHURL(repo.Path) + repo.GitURL = c.urlProvider.GenerateGITCloneURL(ctx, repo.Path) + repo.GitSSHURL = c.urlProvider.GenerateGITCloneSSHURL(ctx, repo.Path) repoOutput := GetRepoOutputWithAccess(ctx, in.IsPublic, repo) @@ -266,7 +266,7 @@ func (c *Controller) createGitRepository(ctx context.Context, session *auth.Sess // generate envars (add everything githook CLI needs for execution) envVars, err := githook.GenerateEnvironmentVariables( ctx, - c.urlProvider.GetInternalAPIURL(), + c.urlProvider.GetInternalAPIURL(ctx), 0, session.Principal.ID, true, diff --git a/app/api/controller/repo/find.go b/app/api/controller/repo/find.go index 036b089e7..48b79e423 100644 --- a/app/api/controller/repo/find.go +++ b/app/api/controller/repo/find.go @@ -35,8 +35,8 @@ func (c *Controller) Find(ctx context.Context, session *auth.Session, repoRef st } // backfill clone url - repo.GitURL = c.urlProvider.GenerateGITCloneURL(repo.Path) - repo.GitSSHURL = c.urlProvider.GenerateGITCloneSSHURL(repo.Path) + repo.GitURL = c.urlProvider.GenerateGITCloneURL(ctx, repo.Path) + repo.GitSSHURL = c.urlProvider.GenerateGITCloneSSHURL(ctx, repo.Path) return GetRepoOutput(ctx, c.publicAccess, repo) } diff --git a/app/api/controller/repo/import.go b/app/api/controller/repo/import.go index e9dd5a39f..353d292cc 100644 --- a/app/api/controller/repo/import.go +++ b/app/api/controller/repo/import.go @@ -97,8 +97,8 @@ func (c *Controller) Import(ctx context.Context, session *auth.Session, in *Impo return nil, err } - repo.GitURL = c.urlProvider.GenerateGITCloneURL(repo.Path) - repo.GitSSHURL = c.urlProvider.GenerateGITCloneSSHURL(repo.Path) + repo.GitURL = c.urlProvider.GenerateGITCloneURL(ctx, repo.Path) + repo.GitSSHURL = c.urlProvider.GenerateGITCloneSSHURL(ctx, repo.Path) err = c.auditService.Log(ctx, session.Principal, diff --git a/app/api/controller/repo/move.go b/app/api/controller/repo/move.go index c7f7fc4b9..984c9cd77 100644 --- a/app/api/controller/repo/move.go +++ b/app/api/controller/repo/move.go @@ -130,8 +130,8 @@ func (c *Controller) Move(ctx context.Context, return nil, fmt.Errorf("failed to set repo public access for new path (cleanup successful): %w", err) } - repo.GitURL = c.urlProvider.GenerateGITCloneURL(repo.Path) - repo.GitSSHURL = c.urlProvider.GenerateGITCloneSSHURL(repo.Path) + repo.GitURL = c.urlProvider.GenerateGITCloneURL(ctx, repo.Path) + repo.GitSSHURL = c.urlProvider.GenerateGITCloneSSHURL(ctx, repo.Path) return GetRepoOutput(ctx, c.publicAccess, repo) } diff --git a/app/api/controller/repo/purge.go b/app/api/controller/repo/purge.go index 37cd16aab..055aff589 100644 --- a/app/api/controller/repo/purge.go +++ b/app/api/controller/repo/purge.go @@ -97,7 +97,7 @@ func (c *Controller) DeleteGitRepository( // create custom write params for delete as repo might or might not exist in db (similar to create). envVars, err := githook.GenerateEnvironmentVariables( ctx, - c.urlProvider.GetInternalAPIURL(), + c.urlProvider.GetInternalAPIURL(ctx), 0, // no repoID session.Principal.ID, true, diff --git a/app/api/controller/repo/update.go b/app/api/controller/repo/update.go index e64980ee7..a6b1940ee 100644 --- a/app/api/controller/repo/update.go +++ b/app/api/controller/repo/update.go @@ -84,8 +84,8 @@ func (c *Controller) Update(ctx context.Context, } // backfill repo url - repo.GitURL = c.urlProvider.GenerateGITCloneURL(repo.Path) - repo.GitSSHURL = c.urlProvider.GenerateGITCloneSSHURL(repo.Path) + repo.GitURL = c.urlProvider.GenerateGITCloneURL(ctx, repo.Path) + repo.GitSSHURL = c.urlProvider.GenerateGITCloneSSHURL(ctx, repo.Path) return GetRepoOutput(ctx, c.publicAccess, repo) } diff --git a/app/api/controller/repo/update_public_access.go b/app/api/controller/repo/update_public_access.go index 90e418c29..85dc2dac3 100644 --- a/app/api/controller/repo/update_public_access.go +++ b/app/api/controller/repo/update_public_access.go @@ -71,8 +71,8 @@ func (c *Controller) UpdatePublicAccess(ctx context.Context, } // backfill GitURL - repo.GitURL = c.urlProvider.GenerateGITCloneURL(repo.Path) - repo.GitSSHURL = c.urlProvider.GenerateGITCloneSSHURL(repo.Path) + repo.GitURL = c.urlProvider.GenerateGITCloneURL(ctx, repo.Path) + repo.GitSSHURL = c.urlProvider.GenerateGITCloneSSHURL(ctx, repo.Path) err = c.auditService.Log(ctx, session.Principal, diff --git a/app/api/controller/space/list_repositories.go b/app/api/controller/space/list_repositories.go index 9d4092e00..4856e9123 100644 --- a/app/api/controller/space/list_repositories.go +++ b/app/api/controller/space/list_repositories.go @@ -81,8 +81,8 @@ func (c *Controller) ListRepositoriesNoAuth( var reposOut []*repoCtrl.RepositoryOutput for _, repo := range repos { // backfill URLs - repo.GitURL = c.urlProvider.GenerateGITCloneURL(repo.Path) - repo.GitSSHURL = c.urlProvider.GenerateGITCloneSSHURL(repo.Path) + repo.GitURL = c.urlProvider.GenerateGITCloneURL(ctx, repo.Path) + repo.GitSSHURL = c.urlProvider.GenerateGITCloneSSHURL(ctx, repo.Path) repoOut, err := repoCtrl.GetRepoOutput(ctx, c.publicAccess, repo) if err != nil { diff --git a/app/api/controller/util.go b/app/api/controller/util.go index bc3de209f..e492d3a2a 100644 --- a/app/api/controller/util.go +++ b/app/api/controller/util.go @@ -37,7 +37,7 @@ func createRPCWriteParams( // generate envars (add everything githook CLI needs for execution) envVars, err := githook.GenerateEnvironmentVariables( ctx, - urlProvider.GetInternalAPIURL(), + urlProvider.GetInternalAPIURL(ctx), repo.ID, session.Principal.ID, false, diff --git a/app/api/handler/repo/find_redirect.go b/app/api/handler/repo/find_redirect.go index 19745ce90..779f7dcf7 100644 --- a/app/api/handler/repo/find_redirect.go +++ b/app/api/handler/repo/find_redirect.go @@ -43,7 +43,7 @@ func HandleGitRedirect(urlProvider url.Provider) http.HandlerFunc { // NOTE: // Technically, we could find the repo first and use repo.Path. // However, the auth cookie isn't available in case of custom git domains, and thus the auth would fail. - repoURL := urlProvider.GenerateUIRepoURL(repoRef) + repoURL := urlProvider.GenerateUIRepoURL(ctx, repoRef) http.Redirect( w, diff --git a/app/api/handler/repo/git_info_refs.go b/app/api/handler/repo/git_info_refs.go index 0477278b7..ee88acbb6 100644 --- a/app/api/handler/repo/git_info_refs.go +++ b/app/api/handler/repo/git_info_refs.go @@ -15,6 +15,7 @@ package repo import ( + "context" "errors" "fmt" "net/http" @@ -53,7 +54,7 @@ func HandleGitInfoRefs(repoCtrl *repo.Controller, urlProvider url.Provider) http err = repoCtrl.GitInfoRefs(ctx, session, repoRef, service, gitProtocol, w) if errors.Is(err, apiauth.ErrNotAuthorized) && auth.IsAnonymousSession(session) { - renderBasicAuth(w, urlProvider) + renderBasicAuth(ctx, w, urlProvider) return } if err != nil { @@ -65,8 +66,8 @@ func HandleGitInfoRefs(repoCtrl *repo.Controller, urlProvider url.Provider) http // renderBasicAuth renders a response that indicates that the client (GIT) requires basic authentication. // This is required in order to tell git CLI to query user credentials. -func renderBasicAuth(w http.ResponseWriter, urlProvider url.Provider) { +func renderBasicAuth(ctx context.Context, w http.ResponseWriter, urlProvider url.Provider) { // Git doesn't seem to handle "realm" - so it doesn't seem to matter for basic user CLI interactions. - w.Header().Add("WWW-Authenticate", fmt.Sprintf(`Basic realm="%s"`, urlProvider.GetAPIHostname())) + w.Header().Add("WWW-Authenticate", fmt.Sprintf(`Basic realm="%s"`, urlProvider.GetAPIHostname(ctx))) w.WriteHeader(http.StatusUnauthorized) } diff --git a/app/api/handler/repo/git_service_pack.go b/app/api/handler/repo/git_service_pack.go index ee4c37da2..506b57e41 100644 --- a/app/api/handler/repo/git_service_pack.go +++ b/app/api/handler/repo/git_service_pack.go @@ -80,7 +80,7 @@ func HandleGitServicePack( Protocol: gitProtocol, }) if errors.Is(err, apiauth.ErrNotAuthorized) && auth.IsAnonymousSession(session) { - renderBasicAuth(w, urlProvider) + renderBasicAuth(ctx, w, urlProvider) return } if err != nil { diff --git a/app/pipeline/manager/client.go b/app/pipeline/manager/client.go index 68f01ce1e..e3d259321 100644 --- a/app/pipeline/manager/client.go +++ b/app/pipeline/manager/client.go @@ -109,8 +109,8 @@ func (e *embedded) Detail(ctx context.Context, stage *drone.Stage) (*client.Cont Config: ConvertToDroneFile(details.Config), Netrc: ConvertToDroneNetrc(details.Netrc), System: &drone.System{ - Proto: e.urlProvider.GetAPIProto(), - Host: e.urlProvider.GetAPIHostname(), + Proto: e.urlProvider.GetAPIProto(ctx), + Host: e.urlProvider.GetAPIHostname(ctx), }, }, nil } diff --git a/app/pipeline/manager/manager.go b/app/pipeline/manager/manager.go index 1f968eba3..8673ebcfb 100644 --- a/app/pipeline/manager/manager.go +++ b/app/pipeline/manager/manager.go @@ -280,7 +280,7 @@ func (m *Manager) UploadLogs(ctx context.Context, step int64, r io.Reader) error } // Details provides details about the stage. -func (m *Manager) Details(_ context.Context, stageID int64) (*ExecutionContext, error) { +func (m *Manager) Details(ctx context.Context, stageID int64) (*ExecutionContext, error) { log := log.With(). Int64("stage-id", stageID). Logger() @@ -308,7 +308,7 @@ func (m *Manager) Details(_ context.Context, stageID int64) (*ExecutionContext, } // Backfill clone URL - repo.GitURL = m.urlProvider.GenerateContainerGITCloneURL(repo.Path) + repo.GitURL = m.urlProvider.GenerateContainerGITCloneURL(ctx, repo.Path) stages, err := m.Stages.List(noContext, stage.ExecutionID) if err != nil { diff --git a/app/pipeline/triggerer/env.go b/app/pipeline/triggerer/env.go index ee625c789..20ed14542 100644 --- a/app/pipeline/triggerer/env.go +++ b/app/pipeline/triggerer/env.go @@ -15,6 +15,8 @@ package triggerer import ( + "context" + "github.com/harness/gitness/app/url" "github.com/harness/gitness/types" @@ -32,11 +34,12 @@ func combine(env ...map[string]string) map[string]string { } func Envs( + ctx context.Context, repo *types.Repository, pipeline *types.Pipeline, urlProvider url.Provider, ) map[string]string { return map[string]string{ - "DRONE_BUILD_LINK": urlProvider.GenerateUIBuildURL(repo.Path, pipeline.Identifier, pipeline.Seq), + "DRONE_BUILD_LINK": urlProvider.GenerateUIBuildURL(ctx, repo.Path, pipeline.Identifier, pipeline.Seq), } } diff --git a/app/pipeline/triggerer/trigger.go b/app/pipeline/triggerer/trigger.go index e44a80c52..5b5cfa7ec 100644 --- a/app/pipeline/triggerer/trigger.go +++ b/app/pipeline/triggerer/trigger.go @@ -356,7 +356,7 @@ func (t *triggerer) Trigger( // TODO: this can be made better. We are setting this later since otherwise any parsing failure // would lead to an incremented pipeline sequence number. execution.Number = pipeline.Seq - execution.Params = combine(execution.Params, Envs(repo, pipeline, t.urlProvider)) + execution.Params = combine(execution.Params, Envs(ctx, repo, pipeline, t.urlProvider)) err = t.createExecutionWithStages(ctx, execution, stages) if err != nil { diff --git a/app/router/api.go b/app/router/api.go index acf6040c9..b130fe653 100644 --- a/app/router/api.go +++ b/app/router/api.go @@ -89,11 +89,6 @@ import ( "github.com/rs/zerolog/hlog" ) -// APIHandler is an abstraction of a http handler that handles API calls. -type APIHandler interface { - http.Handler -} - var ( // terminatedPathPrefixesAPI is the list of prefixes that will require resolving terminated paths. terminatedPathPrefixesAPI = []string{"/v1/spaces/", "/v1/repos/", @@ -130,7 +125,7 @@ func NewAPIHandler( infraProviderCtrl *infraprovider.Controller, migrateCtrl *migrate.Controller, gitspaceCtrl *gitspace.Controller, -) APIHandler { +) http.Handler { // Use go-chi router for inner routing. r := chi.NewRouter() diff --git a/app/router/api_router.go b/app/router/api_router.go new file mode 100644 index 000000000..2aa86450a --- /dev/null +++ b/app/router/api_router.go @@ -0,0 +1,58 @@ +// Copyright 2023 Harness, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package router + +import ( + "net/http" + "strings" + + "github.com/harness/gitness/app/api/render" + "github.com/harness/gitness/logging" + + "github.com/rs/zerolog/log" +) + +const APIMount = "/api" + +type APIRouter struct { + handler http.Handler +} + +func NewAPIRouter(handler http.Handler) *APIRouter { + return &APIRouter{handler: handler} +} + +func (r *APIRouter) Handle(w http.ResponseWriter, req *http.Request) { + req = req.WithContext(logging.NewContext(req.Context(), WithLoggingRouter("api"))) + + // remove matched prefix to simplify API handlers + if err := StripPrefix(APIMount, req); err != nil { + log.Ctx(req.Context()).Err(err).Msgf("Failed striping of prefix for api request.") + render.InternalError(req.Context(), w) + return + } + + r.handler.ServeHTTP(w, req) +} + +func (r *APIRouter) IsEligibleTraffic(req *http.Request) bool { + // All Rest API calls start with "/api/", and thus can be uniquely identified. + p := req.URL.Path + return strings.HasPrefix(p, APIMount) +} + +func (r *APIRouter) Name() string { + return "api" +} diff --git a/app/router/git.go b/app/router/git.go index f1398bbbc..4615ed768 100644 --- a/app/router/git.go +++ b/app/router/git.go @@ -34,17 +34,12 @@ import ( "github.com/rs/zerolog/hlog" ) -// GitHandler is an abstraction of an http handler that handles git calls. -type GitHandler interface { - http.Handler -} - // NewGitHandler returns a new GitHandler. func NewGitHandler( urlProvider url.Provider, authenticator authn.Authenticator, repoCtrl *repo.Controller, -) GitHandler { +) http.Handler { // Use go-chi router for inner routing. r := chi.NewRouter() diff --git a/app/router/git_router.go b/app/router/git_router.go new file mode 100644 index 000000000..745357f01 --- /dev/null +++ b/app/router/git_router.go @@ -0,0 +1,76 @@ +// Copyright 2023 Harness, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package router + +import ( + "net/http" + "strings" + + "github.com/harness/gitness/app/api/render" + + "github.com/rs/zerolog/log" +) + +const GitMount = "/git" + +type GitRouter struct { + handler http.Handler + + // gitHost describes the optional host via which git traffic is identified. + // Note: always stored as lowercase. + gitHost string +} + +func NewGitRouter(handler http.Handler, gitHost string) *GitRouter { + return &GitRouter{handler: handler, gitHost: gitHost} +} + +func (r *GitRouter) Handle(w http.ResponseWriter, req *http.Request) { + // remove matched prefix to simplify API handlers (only if it's there) + if err := StripPrefix(GitMount, req); err != nil { + log.Ctx(req.Context()).Err(err).Msgf("Failed striping of prefix for git request.") + render.InternalError(req.Context(), w) + return + } + + r.handler.ServeHTTP(w, req) +} + +func (r *GitRouter) IsEligibleTraffic(req *http.Request) bool { + // All Git originating traffic starts with "/space1/space2/repo.git". + + // git traffic is always reachable via the git mounting path. + p := req.URL.Path + if strings.HasPrefix(p, GitMount) { + return true + } + + // otherwise check if the request came in via the configured git host (if enabled) + if len(r.gitHost) > 0 { + // cut (optional) port off the host + h, _, _ := strings.Cut(req.Host, ":") + + if strings.EqualFold(r.gitHost, h) { + return true + } + } + + // otherwise we don't treat it as git traffic + return false +} + +func (r *GitRouter) Name() string { + return "git" +} diff --git a/app/router/interface.go b/app/router/interface.go new file mode 100644 index 000000000..9eadd16e4 --- /dev/null +++ b/app/router/interface.go @@ -0,0 +1,25 @@ +// Copyright 2023 Harness, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package router + +import ( + "net/http" +) + +type Interface interface { + Handle(w http.ResponseWriter, req *http.Request) + IsEligibleTraffic(req *http.Request) bool + Name() string +} diff --git a/app/router/logging.go b/app/router/logging.go new file mode 100644 index 000000000..108caa0f7 --- /dev/null +++ b/app/router/logging.go @@ -0,0 +1,28 @@ +// Copyright 2023 Harness, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package router + +import ( + "github.com/harness/gitness/logging" + + "github.com/rs/zerolog" +) + +// WithLoggingRouter can be used to annotate logs with the handler info. +func WithLoggingRouter(handler string) logging.Option { + return func(c zerolog.Context) zerolog.Context { + return c.Str("http.router", handler) + } +} diff --git a/app/router/router.go b/app/router/router.go index 76fdc56fa..db7c46a2e 100644 --- a/app/router/router.go +++ b/app/router/router.go @@ -20,6 +20,7 @@ import ( "github.com/harness/gitness/app/api/render" "github.com/harness/gitness/app/request" + "github.com/harness/gitness/logging" "github.com/go-logr/logr" "github.com/go-logr/zerologr" @@ -27,40 +28,21 @@ import ( "github.com/rs/zerolog/log" ) -const ( - APIMount = "/api" - GitMount = "/git" -) - type Router struct { - api APIHandler - git GitHandler - web WebHandler - - // gitHost describes the optional host via which git traffic is identified. - // Note: always stored as lowercase. - gitHost string + routers []Interface } // NewRouter returns a new http.Handler that routes traffic // to the appropriate handlers. func NewRouter( - api APIHandler, - git GitHandler, - web WebHandler, - gitHost string, + routers []Interface, ) *Router { return &Router{ - api: api, - git: git, - web: web, - - gitHost: strings.ToLower(gitHost), + routers: routers, } } func (r *Router) ServeHTTP(w http.ResponseWriter, req *http.Request) { - var err error // setup logger for request log := log.Logger.With().Logger() ctx := log.WithContext(req.Context()) @@ -72,91 +54,20 @@ func (r *Router) ServeHTTP(w http.ResponseWriter, req *http.Request) { Str("http.original_url", req.URL.String()) }) - /* - * 1. GIT - * - * All Git originating traffic starts with "/space1/space2/repo.git". - */ - if r.isGitTraffic(req) { - log.UpdateContext(func(c zerolog.Context) zerolog.Context { - return c.Str("http.handler", "git") - }) - - // remove matched prefix to simplify API handlers (only if it's there) - if err = stripPrefix(GitMount, req); err != nil { - log.Err(err).Msgf("Failed striping of prefix for git request.") - render.InternalError(ctx, w) + for _, router := range r.routers { + if ok := router.IsEligibleTraffic(req); ok { + req = req.WithContext(logging.NewContext(req.Context(), WithLoggingRouter(router.Name()))) + router.Handle(w, req) return } - - r.git.ServeHTTP(w, req) - return } - - /* - * 2. REST API - * - * All Rest API calls start with "/api/", and thus can be uniquely identified. - */ - if r.isAPITraffic(req) { - log.UpdateContext(func(c zerolog.Context) zerolog.Context { - return c.Str("http.handler", "api") - }) - - // remove matched prefix to simplify API handlers - if err = stripPrefix(APIMount, req); err != nil { - log.Err(err).Msgf("Failed striping of prefix for api request.") - render.InternalError(ctx, w) - return - } - - r.api.ServeHTTP(w, req) - return - } - - /* - * 3. WEB - * - * Everything else will be routed to web (or return 404) - */ - log.UpdateContext(func(c zerolog.Context) zerolog.Context { - return c.Str("http.handler", "web") - }) - - r.web.ServeHTTP(w, req) + render.BadRequestf(ctx, w, "No eligible router found") } -// stripPrefix removes the prefix from the request path (or noop if it's not there). -func stripPrefix(prefix string, req *http.Request) error { +// StripPrefix removes the prefix from the request path (or noop if it's not there). +func StripPrefix(prefix string, req *http.Request) error { if !strings.HasPrefix(req.URL.Path, prefix) { return nil } return request.ReplacePrefix(req, prefix, "") } - -// isGitTraffic returns true iff the request is identified as part of the git http protocol. -func (r *Router) isGitTraffic(req *http.Request) bool { - // git traffic is always reachable via the git mounting path. - if strings.HasPrefix(req.URL.Path, GitMount+"/") { - return true - } - - // otherwise check if the request came in via the configured git host (if enabled) - if len(r.gitHost) > 0 { - // cut (optional) port off the host - h, _, _ := strings.Cut(req.Host, ":") - - // check if request host matches the configured git host (case insensitive) - if r.gitHost == strings.ToLower(h) { - return true - } - } - - // otherwise we don't treat it as git traffic - return false -} - -// isAPITraffic returns true iff the request is identified as part of our rest API. -func (r *Router) isAPITraffic(req *http.Request) bool { - return strings.HasPrefix(req.URL.Path, APIMount+"/") -} diff --git a/app/router/web.go b/app/router/web.go index ed76e6c38..eb358624b 100644 --- a/app/router/web.go +++ b/app/router/web.go @@ -29,15 +29,10 @@ import ( "github.com/unrolled/secure" ) -// WebHandler is an abstraction of an http handler that handles web calls. -type WebHandler interface { - http.Handler -} - // NewWebHandler returns a new WebHandler. func NewWebHandler(config *types.Config, openapi openapi.Service, -) WebHandler { +) http.Handler { // Use go-chi router for inner routing r := chi.NewRouter() // create middleware to enforce security best practices for diff --git a/app/router/web_router.go b/app/router/web_router.go new file mode 100644 index 000000000..d2a9f7326 --- /dev/null +++ b/app/router/web_router.go @@ -0,0 +1,43 @@ +// Copyright 2023 Harness, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package router + +import ( + "net/http" + + "github.com/harness/gitness/logging" +) + +type WebRouter struct { + handler http.Handler +} + +func NewWebRouter(handler http.Handler) *WebRouter { + return &WebRouter{handler: handler} +} + +func (r *WebRouter) Handle(w http.ResponseWriter, req *http.Request) { + req = req.WithContext(logging.NewContext(req.Context(), WithLoggingRouter("web"))) + r.handler.ServeHTTP(w, req) +} + +func (r *WebRouter) IsEligibleTraffic(*http.Request) bool { + // Everything else will be routed to web (or return 404) + return true +} + +func (r *WebRouter) Name() string { + return "web" +} diff --git a/app/router/wire.go b/app/router/wire.go index 3bf9ee4ef..f71c8e2d1 100644 --- a/app/router/wire.go +++ b/app/router/wire.go @@ -54,20 +54,12 @@ import ( // WireSet provides a wire set for this package. var WireSet = wire.NewSet( ProvideRouter, - ProvideGitHandler, - ProvideAPIHandler, - ProvideWebHandler, ) -func ProvideRouter( - api APIHandler, - git GitHandler, - web WebHandler, - urlProvider url.Provider, -) *Router { +func GetGitRoutingHost(ctx context.Context, urlProvider url.Provider) string { // use url provider as it has the latest data. - gitHostname := urlProvider.GetGITHostname() - apiHostname := urlProvider.GetAPIHostname() + gitHostname := urlProvider.GetGITHostname(ctx) + apiHostname := urlProvider.GetAPIHostname(ctx) // only use host name to identify git traffic if it differs from api hostname. // TODO: Can we make this even more flexible - aka use the full base urls to route traffic? @@ -75,23 +67,11 @@ func ProvideRouter( if !strings.EqualFold(gitHostname, apiHostname) { gitRoutingHost = gitHostname } - - return NewRouter(api, git, web, gitRoutingHost) + return gitRoutingHost } -func ProvideGitHandler( - urlProvider url.Provider, - authenticator authn.Authenticator, - repoCtrl *repo.Controller, -) GitHandler { - return NewGitHandler( - urlProvider, - authenticator, - repoCtrl, - ) -} - -func ProvideAPIHandler( +// ProvideRouter provides ordered list of routers. +func ProvideRouter( appCtx context.Context, config *types.Config, authenticator authn.Authenticator, @@ -120,14 +100,28 @@ func ProvideAPIHandler( infraProviderCtrl *infraprovider.Controller, gitspaceCtrl *gitspace.Controller, migrateCtrl *migrate.Controller, -) APIHandler { - return NewAPIHandler(appCtx, config, + urlProvider url.Provider, + openapi openapi.Service, +) *Router { + routers := make([]Interface, 3) + + gitRoutingHost := GetGitRoutingHost(appCtx, urlProvider) + gitHandler := NewGitHandler( + urlProvider, + authenticator, + repoCtrl, + ) + routers[0] = NewGitRouter(gitHandler, gitRoutingHost) + + apiHandler := NewAPIHandler(appCtx, config, authenticator, repoCtrl, repoSettingsCtrl, executionCtrl, logCtrl, spaceCtrl, pipelineCtrl, secretCtrl, triggerCtrl, connectorCtrl, templateCtrl, pluginCtrl, pullreqCtrl, webhookCtrl, githookCtrl, git, saCtrl, userCtrl, principalCtrl, checkCtrl, sysCtrl, blobCtrl, searchCtrl, infraProviderCtrl, migrateCtrl, gitspaceCtrl) -} + routers[1] = NewAPIRouter(apiHandler) -func ProvideWebHandler(config *types.Config, openapi openapi.Service) WebHandler { - return NewWebHandler(config, openapi) + webHandler := NewWebHandler(config, openapi) + routers[2] = NewWebRouter(webHandler) + + return NewRouter(routers) } diff --git a/app/services/importer/repository.go b/app/services/importer/repository.go index 98e173f5e..58b11340f 100644 --- a/app/services/importer/repository.go +++ b/app/services/importer/repository.go @@ -548,7 +548,7 @@ func (r *Repository) createEnvVars(ctx context.Context, ) (map[string]string, error) { envVars, err := githook.GenerateEnvironmentVariables( ctx, - r.urlProvider.GetInternalAPIURL(), + r.urlProvider.GetInternalAPIURL(ctx), repoID, principal.ID, false, diff --git a/app/services/notification/service.go b/app/services/notification/service.go index 8d0b754e0..1891835c8 100644 --- a/app/services/notification/service.go +++ b/app/services/notification/service.go @@ -180,6 +180,6 @@ func (s *Service) getBasePayload( Repo: repo, PullReq: pullReq, Author: author, - PullReqURL: s.urlProvider.GenerateUIPRURL(repo.Path, pullReq.Number), + PullReqURL: s.urlProvider.GenerateUIPRURL(ctx, repo.Path, pullReq.Number), }, nil } diff --git a/app/services/pullreq/service.go b/app/services/pullreq/service.go index d479aa86b..b87c08a3e 100644 --- a/app/services/pullreq/service.go +++ b/app/services/pullreq/service.go @@ -259,7 +259,7 @@ func createSystemRPCWriteParams( // generate envars (add everything githook CLI needs for execution) envVars, err := githook.GenerateEnvironmentVariables( ctx, - urlProvider.GetInternalAPIURL(), + urlProvider.GetInternalAPIURL(ctx), repoID, principal.ID, false, diff --git a/app/services/repo/handlers_default_branch.go b/app/services/repo/handlers_default_branch.go index 0de633f28..5ff582685 100644 --- a/app/services/repo/handlers_default_branch.go +++ b/app/services/repo/handlers_default_branch.go @@ -62,7 +62,7 @@ func (s *Service) handleUpdateDefaultBranch( systemPrincipal := bootstrap.NewSystemServiceSession().Principal envVars, err := githook.GenerateEnvironmentVariables( ctx, - s.urlProvider.GetInternalAPIURL(), + s.urlProvider.GetInternalAPIURL(ctx), repo.ID, systemPrincipal.ID, true, diff --git a/app/services/webhook/handler_branch.go b/app/services/webhook/handler_branch.go index 3f5977d47..9fbf80945 100644 --- a/app/services/webhook/handler_branch.go +++ b/app/services/webhook/handler_branch.go @@ -48,7 +48,7 @@ func (s *Service) handleEventBranchCreated(ctx context.Context, if err != nil { return nil, err } - repoInfo := repositoryInfoFrom(repo, s.urlProvider) + repoInfo := repositoryInfoFrom(ctx, repo, s.urlProvider) return &ReferencePayload{ BaseSegment: BaseSegment{ @@ -89,7 +89,7 @@ func (s *Service) handleEventBranchUpdated(ctx context.Context, } commitInfo := commitsInfo[0] - repoInfo := repositoryInfoFrom(repo, s.urlProvider) + repoInfo := repositoryInfoFrom(ctx, repo, s.urlProvider) return &ReferencePayload{ BaseSegment: BaseSegment{ @@ -125,7 +125,7 @@ func (s *Service) handleEventBranchDeleted(ctx context.Context, return s.triggerForEventWithRepo(ctx, enum.WebhookTriggerBranchDeleted, event.ID, event.Payload.PrincipalID, event.Payload.RepoID, func(principal *types.Principal, repo *types.Repository) (any, error) { - repoInfo := repositoryInfoFrom(repo, s.urlProvider) + repoInfo := repositoryInfoFrom(ctx, repo, s.urlProvider) return &ReferencePayload{ BaseSegment: BaseSegment{ diff --git a/app/services/webhook/handler_pullreq.go b/app/services/webhook/handler_pullreq.go index 1960f2bf6..d261b3dbb 100644 --- a/app/services/webhook/handler_pullreq.go +++ b/app/services/webhook/handler_pullreq.go @@ -50,8 +50,8 @@ func (s *Service) handleEventPullReqCreated(ctx context.Context, if err != nil { return nil, err } - targetRepoInfo := repositoryInfoFrom(targetRepo, s.urlProvider) - sourceRepoInfo := repositoryInfoFrom(sourceRepo, s.urlProvider) + targetRepoInfo := repositoryInfoFrom(ctx, targetRepo, s.urlProvider) + sourceRepoInfo := repositoryInfoFrom(ctx, sourceRepo, s.urlProvider) return &PullReqCreatedPayload{ BaseSegment: BaseSegment{ @@ -60,7 +60,7 @@ func (s *Service) handleEventPullReqCreated(ctx context.Context, Principal: principalInfoFrom(principal.ToPrincipalInfo()), }, PullReqSegment: PullReqSegment{ - PullReq: pullReqInfoFrom(pr, targetRepo, s.urlProvider), + PullReq: pullReqInfoFrom(ctx, pr, targetRepo, s.urlProvider), }, PullReqTargetReferenceSegment: PullReqTargetReferenceSegment{ TargetRef: ReferenceInfo{ @@ -98,8 +98,8 @@ func (s *Service) handleEventPullReqReopened(ctx context.Context, if err != nil { return nil, err } - targetRepoInfo := repositoryInfoFrom(targetRepo, s.urlProvider) - sourceRepoInfo := repositoryInfoFrom(sourceRepo, s.urlProvider) + targetRepoInfo := repositoryInfoFrom(ctx, targetRepo, s.urlProvider) + sourceRepoInfo := repositoryInfoFrom(ctx, sourceRepo, s.urlProvider) return &PullReqReopenedPayload{ BaseSegment: BaseSegment{ @@ -108,7 +108,7 @@ func (s *Service) handleEventPullReqReopened(ctx context.Context, Principal: principalInfoFrom(principal.ToPrincipalInfo()), }, PullReqSegment: PullReqSegment{ - PullReq: pullReqInfoFrom(pr, targetRepo, s.urlProvider), + PullReq: pullReqInfoFrom(ctx, pr, targetRepo, s.urlProvider), }, PullReqTargetReferenceSegment: PullReqTargetReferenceSegment{ TargetRef: ReferenceInfo{ @@ -156,8 +156,8 @@ func (s *Service) handleEventPullReqBranchUpdated(ctx context.Context, } commitInfo := commitsInfo[0] - targetRepoInfo := repositoryInfoFrom(targetRepo, s.urlProvider) - sourceRepoInfo := repositoryInfoFrom(sourceRepo, s.urlProvider) + targetRepoInfo := repositoryInfoFrom(ctx, targetRepo, s.urlProvider) + sourceRepoInfo := repositoryInfoFrom(ctx, sourceRepo, s.urlProvider) return &PullReqBranchUpdatedPayload{ BaseSegment: BaseSegment{ @@ -166,7 +166,7 @@ func (s *Service) handleEventPullReqBranchUpdated(ctx context.Context, Principal: principalInfoFrom(principal.ToPrincipalInfo()), }, PullReqSegment: PullReqSegment{ - PullReq: pullReqInfoFrom(pr, targetRepo, s.urlProvider), + PullReq: pullReqInfoFrom(ctx, pr, targetRepo, s.urlProvider), }, PullReqTargetReferenceSegment: PullReqTargetReferenceSegment{ TargetRef: ReferenceInfo{ @@ -213,8 +213,8 @@ func (s *Service) handleEventPullReqClosed(ctx context.Context, if err != nil { return nil, err } - targetRepoInfo := repositoryInfoFrom(targetRepo, s.urlProvider) - sourceRepoInfo := repositoryInfoFrom(sourceRepo, s.urlProvider) + targetRepoInfo := repositoryInfoFrom(ctx, targetRepo, s.urlProvider) + sourceRepoInfo := repositoryInfoFrom(ctx, sourceRepo, s.urlProvider) return &PullReqClosedPayload{ BaseSegment: BaseSegment{ @@ -223,7 +223,7 @@ func (s *Service) handleEventPullReqClosed(ctx context.Context, Principal: principalInfoFrom(principal.ToPrincipalInfo()), }, PullReqSegment: PullReqSegment{ - PullReq: pullReqInfoFrom(pr, targetRepo, s.urlProvider), + PullReq: pullReqInfoFrom(ctx, pr, targetRepo, s.urlProvider), }, PullReqTargetReferenceSegment: PullReqTargetReferenceSegment{ TargetRef: ReferenceInfo{ @@ -264,8 +264,8 @@ func (s *Service) handleEventPullReqMerged(ctx context.Context, if err != nil { return nil, err } - targetRepoInfo := repositoryInfoFrom(targetRepo, s.urlProvider) - sourceRepoInfo := repositoryInfoFrom(sourceRepo, s.urlProvider) + targetRepoInfo := repositoryInfoFrom(ctx, targetRepo, s.urlProvider) + sourceRepoInfo := repositoryInfoFrom(ctx, sourceRepo, s.urlProvider) return &PullReqClosedPayload{ BaseSegment: BaseSegment{ @@ -274,7 +274,7 @@ func (s *Service) handleEventPullReqMerged(ctx context.Context, Principal: principalInfoFrom(principal.ToPrincipalInfo()), }, PullReqSegment: PullReqSegment{ - PullReq: pullReqInfoFrom(pr, targetRepo, s.urlProvider), + PullReq: pullReqInfoFrom(ctx, pr, targetRepo, s.urlProvider), }, PullReqTargetReferenceSegment: PullReqTargetReferenceSegment{ TargetRef: ReferenceInfo{ @@ -314,8 +314,8 @@ func (s *Service) handleEventPullReqComment( return s.triggerForEventWithPullReq(ctx, enum.WebhookTriggerPullReqCommentCreated, event.ID, event.Payload.PrincipalID, event.Payload.PullReqID, func(principal *types.Principal, pr *types.PullReq, targetRepo, sourceRepo *types.Repository) (any, error) { - targetRepoInfo := repositoryInfoFrom(targetRepo, s.urlProvider) - sourceRepoInfo := repositoryInfoFrom(sourceRepo, s.urlProvider) + targetRepoInfo := repositoryInfoFrom(ctx, targetRepo, s.urlProvider) + sourceRepoInfo := repositoryInfoFrom(ctx, sourceRepo, s.urlProvider) activity, err := s.activityStore.Find(ctx, event.Payload.ActivityID) if err != nil { return nil, fmt.Errorf("failed to get activity by id for acitivity id %d: %w", event.Payload.ActivityID, err) @@ -331,7 +331,7 @@ func (s *Service) handleEventPullReqComment( Principal: principalInfoFrom(principal.ToPrincipalInfo()), }, PullReqSegment: PullReqSegment{ - PullReq: pullReqInfoFrom(pr, targetRepo, s.urlProvider), + PullReq: pullReqInfoFrom(ctx, pr, targetRepo, s.urlProvider), }, PullReqTargetReferenceSegment: PullReqTargetReferenceSegment{ TargetRef: ReferenceInfo{ diff --git a/app/services/webhook/handler_tag.go b/app/services/webhook/handler_tag.go index ef0828357..939c55c09 100644 --- a/app/services/webhook/handler_tag.go +++ b/app/services/webhook/handler_tag.go @@ -34,7 +34,7 @@ func (s *Service) handleEventTagCreated(ctx context.Context, if err != nil { return nil, err } - repoInfo := repositoryInfoFrom(repo, s.urlProvider) + repoInfo := repositoryInfoFrom(ctx, repo, s.urlProvider) return &ReferencePayload{ BaseSegment: BaseSegment{ @@ -78,7 +78,7 @@ func (s *Service) handleEventTagUpdated(ctx context.Context, if len(commitsInfo) > 0 { commitInfo = commitsInfo[0] } - repoInfo := repositoryInfoFrom(repo, s.urlProvider) + repoInfo := repositoryInfoFrom(ctx, repo, s.urlProvider) return &ReferencePayload{ BaseSegment: BaseSegment{ @@ -114,7 +114,7 @@ func (s *Service) handleEventTagDeleted(ctx context.Context, return s.triggerForEventWithRepo(ctx, enum.WebhookTriggerTagDeleted, event.ID, event.Payload.PrincipalID, event.Payload.RepoID, func(principal *types.Principal, repo *types.Repository) (any, error) { - repoInfo := repositoryInfoFrom(repo, s.urlProvider) + repoInfo := repositoryInfoFrom(ctx, repo, s.urlProvider) return &ReferencePayload{ BaseSegment: BaseSegment{ diff --git a/app/services/webhook/types.go b/app/services/webhook/types.go index 30198f6a9..6838fd0c6 100644 --- a/app/services/webhook/types.go +++ b/app/services/webhook/types.go @@ -15,6 +15,7 @@ package webhook import ( + "context" "encoding/json" "time" @@ -104,14 +105,14 @@ func (r RepositoryInfo) MarshalJSON() ([]byte, error) { } // repositoryInfoFrom gets the RespositoryInfo from a types.Repository. -func repositoryInfoFrom(repo *types.Repository, urlProvider url.Provider) RepositoryInfo { +func repositoryInfoFrom(ctx context.Context, repo *types.Repository, urlProvider url.Provider) RepositoryInfo { return RepositoryInfo{ ID: repo.ID, Path: repo.Path, Identifier: repo.Identifier, DefaultBranch: repo.DefaultBranch, - GitURL: urlProvider.GenerateGITCloneURL(repo.Path), - GitSSHURL: urlProvider.GenerateGITCloneSSHURL(repo.Path), + GitURL: urlProvider.GenerateGITCloneURL(ctx, repo.Path), + GitSSHURL: urlProvider.GenerateGITCloneSSHURL(ctx, repo.Path), } } @@ -133,7 +134,12 @@ type PullReqInfo struct { } // pullReqInfoFrom gets the PullReqInfo from a types.PullReq. -func pullReqInfoFrom(pr *types.PullReq, repo *types.Repository, urlProvider url.Provider) PullReqInfo { +func pullReqInfoFrom( + ctx context.Context, + pr *types.PullReq, + repo *types.Repository, + urlProvider url.Provider, +) PullReqInfo { return PullReqInfo{ Number: pr.Number, State: pr.State, @@ -146,7 +152,7 @@ func pullReqInfoFrom(pr *types.PullReq, repo *types.Repository, urlProvider url. TargetBranch: pr.TargetBranch, MergeStrategy: pr.MergeMethod, Author: principalInfoFrom(&pr.Author), - PrURL: urlProvider.GenerateUIPRURL(repo.Path, pr.Number), + PrURL: urlProvider.GenerateUIPRURL(ctx, repo.Path, pr.Number), } } diff --git a/app/url/provider.go b/app/url/provider.go index 33900a063..3a0b6c24d 100644 --- a/app/url/provider.go +++ b/app/url/provider.go @@ -15,6 +15,7 @@ package url import ( + "context" "fmt" "net/url" "path" @@ -38,40 +39,40 @@ const ( type Provider interface { // GetInternalAPIURL returns the internally reachable base url of the server. // NOTE: url is guaranteed to not have any trailing '/'. - GetInternalAPIURL() string + GetInternalAPIURL(ctx context.Context) string // GenerateContainerGITCloneURL generates a URL that can be used by CI container builds to // interact with gitness and clone a repo. - GenerateContainerGITCloneURL(repoPath string) string + GenerateContainerGITCloneURL(ctx context.Context, repoPath string) string // GenerateGITCloneURL generates the public git clone URL for the provided repo path. // NOTE: url is guaranteed to not have any trailing '/'. - GenerateGITCloneURL(repoPath string) string + GenerateGITCloneURL(ctx context.Context, repoPath string) string // GenerateGITCloneSSHURL generates the public git clone URL for the provided repo path. // NOTE: url is guaranteed to not have any trailing '/'. - GenerateGITCloneSSHURL(repoPath string) string + GenerateGITCloneSSHURL(ctx context.Context, repoPath string) string // GenerateUIRepoURL returns the url for the UI screen of a repository. - GenerateUIRepoURL(repoPath string) string + GenerateUIRepoURL(ctx context.Context, repoPath string) string // GenerateUIPRURL returns the url for the UI screen of an existing pr. - GenerateUIPRURL(repoPath string, prID int64) string + GenerateUIPRURL(ctx context.Context, repoPath string, prID int64) string // GenerateUICompareURL returns the url for the UI screen comparing two references. - GenerateUICompareURL(repoPath string, ref1 string, ref2 string) string + GenerateUICompareURL(ctx context.Context, repoPath string, ref1 string, ref2 string) string // GetAPIHostname returns the host for the api endpoint. - GetAPIHostname() string + GetAPIHostname(ctx context.Context) string // GenerateUIBuildURL returns the endpoint to use for viewing build executions. - GenerateUIBuildURL(repoPath, pipelineIdentifier string, seqNumber int64) string + GenerateUIBuildURL(ctx context.Context, repoPath, pipelineIdentifier string, seqNumber int64) string // GetGITHostname returns the host for the git endpoint. - GetGITHostname() string + GetGITHostname(ctx context.Context) string // GetAPIProto returns the proto for the API hostname - GetAPIProto() string + GetAPIProto(ctx context.Context) string } // Provider provides the URLs of the gitness system. @@ -159,11 +160,11 @@ func NewProvider( }, nil } -func (p *provider) GetInternalAPIURL() string { +func (p *provider) GetInternalAPIURL(context.Context) string { return p.internalURL.JoinPath(APIMount).String() } -func (p *provider) GenerateContainerGITCloneURL(repoPath string) string { +func (p *provider) GenerateContainerGITCloneURL(_ context.Context, repoPath string) string { repoPath = path.Clean(repoPath) if !strings.HasSuffix(repoPath, GITSuffix) { repoPath += GITSuffix @@ -172,7 +173,7 @@ func (p *provider) GenerateContainerGITCloneURL(repoPath string) string { return p.containerURL.JoinPath(GITMount, repoPath).String() } -func (p *provider) GenerateGITCloneURL(repoPath string) string { +func (p *provider) GenerateGITCloneURL(_ context.Context, repoPath string) string { repoPath = path.Clean(repoPath) if !strings.HasSuffix(repoPath, GITSuffix) { repoPath += GITSuffix @@ -181,7 +182,7 @@ func (p *provider) GenerateGITCloneURL(repoPath string) string { return p.gitURL.JoinPath(repoPath).String() } -func (p *provider) GenerateGITCloneSSHURL(repoPath string) string { +func (p *provider) GenerateGITCloneSSHURL(_ context.Context, repoPath string) string { if !p.SSHEnabled { return "" } @@ -193,31 +194,31 @@ func (p *provider) GenerateGITCloneSSHURL(repoPath string) string { return fmt.Sprintf("%s@%s:%s", p.SSHDefaultUser, p.gitSSHURL.String(), repoPath) } -func (p *provider) GenerateUIBuildURL(repoPath, pipelineIdentifier string, seqNumber int64) string { +func (p *provider) GenerateUIBuildURL(_ context.Context, repoPath, pipelineIdentifier string, seqNumber int64) string { return p.uiURL.JoinPath(repoPath, "pipelines", pipelineIdentifier, "execution", strconv.Itoa(int(seqNumber))).String() } -func (p *provider) GenerateUIRepoURL(repoPath string) string { +func (p *provider) GenerateUIRepoURL(_ context.Context, repoPath string) string { return p.uiURL.JoinPath(repoPath).String() } -func (p *provider) GenerateUIPRURL(repoPath string, prID int64) string { +func (p *provider) GenerateUIPRURL(_ context.Context, repoPath string, prID int64) string { return p.uiURL.JoinPath(repoPath, "pulls", fmt.Sprint(prID)).String() } -func (p *provider) GenerateUICompareURL(repoPath string, ref1 string, ref2 string) string { +func (p *provider) GenerateUICompareURL(_ context.Context, repoPath string, ref1 string, ref2 string) string { return p.uiURL.JoinPath(repoPath, "pulls/compare", ref1+"..."+ref2).String() } -func (p *provider) GetAPIHostname() string { +func (p *provider) GetAPIHostname(context.Context) string { return p.apiURL.Hostname() } -func (p *provider) GetGITHostname() string { +func (p *provider) GetGITHostname(context.Context) string { return p.gitURL.Hostname() } -func (p *provider) GetAPIProto() string { +func (p *provider) GetAPIProto(context.Context) string { return p.apiURL.Scheme } diff --git a/cmd/gitness/wire_gen.go b/cmd/gitness/wire_gen.go index 01a5ffb47..af355664d 100644 --- a/cmd/gitness/wire_gen.go +++ b/cmd/gitness/wire_gen.go @@ -349,11 +349,8 @@ func initSystem(ctx context.Context, config *types.Config) (*server.System, erro gitspaceEventStore := database.ProvideGitspaceEventStore(db) gitspaceController := gitspace2.ProvideController(transactor, authorizer, infraproviderService, gitspaceConfigStore, gitspaceInstanceStore, spaceStore, reporter3, orchestratorOrchestrator, gitspaceEventStore, statefulLogger, scmSCM) migrateController := migrate.ProvideController(authorizer, principalStore) - apiHandler := router.ProvideAPIHandler(ctx, config, authenticator, repoController, reposettingsController, executionController, logsController, spaceController, pipelineController, secretController, triggerController, connectorController, templateController, pluginController, pullreqController, webhookController, githookController, gitInterface, serviceaccountController, controller, principalController, checkController, systemController, uploadController, keywordsearchController, infraproviderController, gitspaceController, migrateController) - gitHandler := router.ProvideGitHandler(provider, authenticator, repoController) openapiService := openapi.ProvideOpenAPIService() - webHandler := router.ProvideWebHandler(config, openapiService) - routerRouter := router.ProvideRouter(apiHandler, gitHandler, webHandler, provider) + routerRouter := router.ProvideRouter(ctx, config, authenticator, repoController, reposettingsController, executionController, logsController, spaceController, pipelineController, secretController, triggerController, connectorController, templateController, pluginController, pullreqController, webhookController, githookController, gitInterface, serviceaccountController, controller, principalController, checkController, systemController, uploadController, keywordsearchController, infraproviderController, gitspaceController, migrateController, provider, openapiService) serverServer := server2.ProvideServer(config, routerRouter) publickeyService := publickey.ProvidePublicKey(publicKeyStore, principalInfoCache) sshServer := ssh.ProvideServer(config, publickeyService, repoController)