diff --git a/internal/services/gateway/webhook.go b/internal/services/gateway/api/webhook.go similarity index 71% rename from internal/services/gateway/webhook.go rename to internal/services/gateway/api/webhook.go index 79d9942..9ecc5b4 100644 --- a/internal/services/gateway/webhook.go +++ b/internal/services/gateway/api/webhook.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package gateway +package api import ( "net/http" @@ -36,47 +36,61 @@ type webhooksHandler struct { apiExposedURL string } -func (h *webhooksHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { - code, userErr, err := h.handleWebhook(r) - if err != nil { - h.log.Errorf("err: %+v", err) - http.Error(w, userErr, code) +func NewWebhooksHandler(logger *zap.Logger, ah *action.ActionHandler, configstoreClient *csapi.Client, runserviceClient *rsapi.Client, apiExposedURL string) *webhooksHandler { + return &webhooksHandler{ + log: logger.Sugar(), + ah: ah, + configstoreClient: configstoreClient, + runserviceClient: runserviceClient, + apiExposedURL: apiExposedURL, } } -func (h *webhooksHandler) handleWebhook(r *http.Request) (int, string, error) { +func (h *webhooksHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { + err := h.handleWebhook(r) + if httpError(w, err) { + h.log.Errorf("err: %+v", err) + return + } + + if err := httpResponse(w, http.StatusOK, nil); err != nil { + h.log.Errorf("err: %+v", err) + } +} + +func (h *webhooksHandler) handleWebhook(r *http.Request) error { ctx := r.Context() projectID := r.URL.Query().Get("projectid") if projectID == "" { - return http.StatusBadRequest, "", errors.Errorf("bad webhook url %q. Missing projectid", r.URL) + return util.NewErrBadRequest(errors.Errorf("bad webhook url %q. Missing projectid", r.URL)) } defer r.Body.Close() csProject, _, err := h.configstoreClient.GetProject(ctx, projectID) if err != nil { - return http.StatusBadRequest, "", errors.Errorf("failed to get project %s: %w", projectID, err) + return util.NewErrBadRequest(errors.Errorf("failed to get project %s: %w", projectID, err)) } project := csProject.Project user, _, err := h.configstoreClient.GetUserByLinkedAccount(ctx, project.LinkedAccountID) if err != nil { - return http.StatusInternalServerError, "", errors.Errorf("failed to get user by linked account %q: %w", project.LinkedAccountID, err) + return util.NewErrInternal(errors.Errorf("failed to get user by linked account %q: %w", project.LinkedAccountID, err)) } la := user.LinkedAccounts[project.LinkedAccountID] h.log.Infof("la: %s", util.Dump(la)) if la == nil { - return http.StatusInternalServerError, "", errors.Errorf("linked account %q in user %q doesn't exist", project.LinkedAccountID, user.Name) + return util.NewErrInternal(errors.Errorf("linked account %q in user %q doesn't exist", project.LinkedAccountID, user.Name)) } rs, _, err := h.configstoreClient.GetRemoteSource(ctx, la.RemoteSourceID) if err != nil { - return http.StatusInternalServerError, "", errors.Errorf("failed to get remote source %q: %w", la.RemoteSourceID, err) + return util.NewErrInternal(errors.Errorf("failed to get remote source %q: %w", la.RemoteSourceID, err)) } gitSource, err := h.ah.GetGitSource(ctx, rs, user.Name, la) if err != nil { - return http.StatusInternalServerError, "", errors.Errorf("failed to create gitea client: %w", err) + return util.NewErrInternal(errors.Errorf("failed to create gitea client: %w", err)) } sshPrivKey := project.SSHPrivateKey @@ -89,13 +103,13 @@ func (h *webhooksHandler) handleWebhook(r *http.Request) (int, string, error) { webhookData, err := gitSource.ParseWebhook(r, project.WebhookSecret) if err != nil { - return http.StatusBadRequest, "", errors.Errorf("failed to parse webhook: %w", err) + return util.NewErrBadRequest(errors.Errorf("failed to parse webhook: %w", err)) } // skip nil webhook data // TODO(sgotti) report the reason of the skip if webhookData == nil { h.log.Infof("skipping webhook") - return 0, "", nil + return nil } cloneURL := webhookData.SSHURL @@ -129,8 +143,8 @@ func (h *webhooksHandler) handleWebhook(r *http.Request) (int, string, error) { CompareLink: webhookData.CompareLink, } if err := h.ah.CreateRuns(ctx, req); err != nil { - return http.StatusInternalServerError, "", errors.Errorf("failed to create run: %w", err) + return util.NewErrInternal(errors.Errorf("failed to create run: %w", err)) } - return 0, "", nil + return nil } diff --git a/internal/services/gateway/gateway.go b/internal/services/gateway/gateway.go index c6d81d1..6183c94 100644 --- a/internal/services/gateway/gateway.go +++ b/internal/services/gateway/gateway.go @@ -147,7 +147,7 @@ func (g *Gateway) Run(ctx context.Context) error { corsAllowedOriginsOptions := ghandlers.AllowedOrigins([]string{"*"}) corsHandler = ghandlers.CORS(corsAllowedMethodsOptions, corsAllowedHeadersOptions, corsAllowedOriginsOptions) - webhooksHandler := &webhooksHandler{log: log, ah: g.ah, configstoreClient: g.configstoreClient, runserviceClient: g.runserviceClient, apiExposedURL: g.c.APIExposedURL} + webhooksHandler := api.NewWebhooksHandler(logger, g.ah, g.configstoreClient, g.runserviceClient, g.c.APIExposedURL) projectGroupHandler := api.NewProjectGroupHandler(logger, g.ah) projectGroupSubgroupsHandler := api.NewProjectGroupSubgroupsHandler(logger, g.ah)