diff --git a/internal/services/gateway/action/action.go b/internal/services/gateway/action/action.go index 57d5f74..744af48 100644 --- a/internal/services/gateway/action/action.go +++ b/internal/services/gateway/action/action.go @@ -20,6 +20,7 @@ import ( "github.com/pkg/errors" csapi "github.com/sorintlab/agola/internal/services/configstore/api" "github.com/sorintlab/agola/internal/services/gateway/common" + rsapi "github.com/sorintlab/agola/internal/services/runservice/scheduler/api" "github.com/sorintlab/agola/internal/util" "go.uber.org/zap" @@ -29,16 +30,18 @@ type ActionHandler struct { log *zap.SugaredLogger sd *common.TokenSigningData configstoreClient *csapi.Client + runserviceClient *rsapi.Client agolaID string apiExposedURL string webExposedURL string } -func NewActionHandler(logger *zap.Logger, sd *common.TokenSigningData, configstoreClient *csapi.Client, agolaID, apiExposedURL, webExposedURL string) *ActionHandler { +func NewActionHandler(logger *zap.Logger, sd *common.TokenSigningData, configstoreClient *csapi.Client, runserviceClient *rsapi.Client, agolaID, apiExposedURL, webExposedURL string) *ActionHandler { return &ActionHandler{ log: logger.Sugar(), sd: sd, configstoreClient: configstoreClient, + runserviceClient: runserviceClient, agolaID: agolaID, apiExposedURL: apiExposedURL, webExposedURL: webExposedURL, diff --git a/internal/services/gateway/action/run.go b/internal/services/gateway/action/run.go new file mode 100644 index 0000000..69fc37d --- /dev/null +++ b/internal/services/gateway/action/run.go @@ -0,0 +1,150 @@ +// Copyright 2019 Sorint.lab +// +// 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 action + +import ( + "context" + "net/http" + + rsapi "github.com/sorintlab/agola/internal/services/runservice/scheduler/api" + "github.com/sorintlab/agola/internal/util" + + "github.com/pkg/errors" +) + +func (h *ActionHandler) GetRun(ctx context.Context, runID string) (*rsapi.RunResponse, error) { + runResp, resp, err := h.runserviceClient.GetRun(ctx, runID) + if err != nil { + return nil, ErrFromRemote(resp, err) + } + + return runResp, nil +} + +type GetRunsRequest struct { + PhaseFilter []string + Groups []string + LastRun bool + ChangeGroups []string + StartRunID string + Limit int + Asc bool +} + +func (h *ActionHandler) GetRuns(ctx context.Context, req *GetRunsRequest) (*rsapi.GetRunsResponse, error) { + runsResp, resp, err := h.runserviceClient.GetRuns(ctx, req.PhaseFilter, req.Groups, req.LastRun, req.ChangeGroups, req.StartRunID, req.Limit, req.Asc) + if err != nil { + return nil, ErrFromRemote(resp, err) + } + + return runsResp, nil +} + +type GetLogsRequest struct { + RunID string + TaskID string + Setup bool + Step int + Follow bool + Stream bool +} + +func (h *ActionHandler) GetLogs(ctx context.Context, req *GetLogsRequest) (*http.Response, error) { + resp, err := h.runserviceClient.GetLogs(ctx, req.RunID, req.TaskID, req.Setup, req.Step, req.Follow, req.Stream) + if err != nil { + return nil, ErrFromRemote(resp, err) + } + + return resp, nil +} + +type RunActionType string + +const ( + RunActionTypeRestart RunActionType = "restart" + RunActionTypeStop RunActionType = "stop" +) + +type RunActionsRequest struct { + RunID string + ActionType RunActionType + + // Restart + FromStart bool +} + +func (h *ActionHandler) RunAction(ctx context.Context, req *RunActionsRequest) error { + switch req.ActionType { + case RunActionTypeRestart: + rsreq := &rsapi.RunCreateRequest{ + RunID: req.RunID, + FromStart: req.FromStart, + } + + resp, err := h.runserviceClient.CreateRun(ctx, rsreq) + if err != nil { + return ErrFromRemote(resp, err) + } + + case RunActionTypeStop: + rsreq := &rsapi.RunActionsRequest{ + ActionType: rsapi.RunActionTypeStop, + } + + resp, err := h.runserviceClient.RunActions(ctx, req.RunID, rsreq) + if err != nil { + return ErrFromRemote(resp, err) + } + + default: + return util.NewErrBadRequest(errors.Errorf("wrong run action type %q", req.ActionType)) + } + + return nil +} + +type RunTaskActionType string + +const ( + RunTaskActionTypeApprove RunTaskActionType = "approve" +) + +type RunTaskActionsRequest struct { + RunID string + TaskID string + + ActionType RunTaskActionType + ApprovalAnnotations map[string]string +} + +func (h *ActionHandler) RunTaskAction(ctx context.Context, req *RunTaskActionsRequest) error { + switch req.ActionType { + case RunTaskActionTypeApprove: + rsreq := &rsapi.RunTaskActionsRequest{ + ActionType: rsapi.RunTaskActionTypeApprove, + ApprovalAnnotations: req.ApprovalAnnotations, + } + + resp, err := h.runserviceClient.RunTaskActions(ctx, req.RunID, req.TaskID, rsreq) + if err != nil { + return ErrFromRemote(resp, err) + } + + default: + return util.NewErrBadRequest(errors.Errorf("wrong run task action type %q", req.ActionType)) + } + + return nil +} diff --git a/internal/services/gateway/api/run.go b/internal/services/gateway/api/run.go index 24f0bb7..3c46cfb 100644 --- a/internal/services/gateway/api/run.go +++ b/internal/services/gateway/api/run.go @@ -23,7 +23,7 @@ import ( "time" "github.com/pkg/errors" - rsapi "github.com/sorintlab/agola/internal/services/runservice/scheduler/api" + "github.com/sorintlab/agola/internal/services/gateway/action" rstypes "github.com/sorintlab/agola/internal/services/runservice/types" "github.com/sorintlab/agola/internal/util" "go.uber.org/zap" @@ -213,12 +213,12 @@ func createRunTaskResponse(rt *rstypes.RunTask, rct *rstypes.RunConfigTask) *Run } type RunHandler struct { - log *zap.SugaredLogger - runserviceClient *rsapi.Client + log *zap.SugaredLogger + ah *action.ActionHandler } -func NewRunHandler(logger *zap.Logger, runserviceClient *rsapi.Client) *RunHandler { - return &RunHandler{log: logger.Sugar(), runserviceClient: runserviceClient} +func NewRunHandler(logger *zap.Logger, ah *action.ActionHandler) *RunHandler { + return &RunHandler{log: logger.Sugar(), ah: ah} } func (h *RunHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { @@ -226,8 +226,8 @@ func (h *RunHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) runID := vars["runid"] - runResp, resp, err := h.runserviceClient.GetRun(ctx, runID) - if httpErrorFromRemote(w, resp, err) { + runResp, err := h.ah.GetRun(ctx, runID) + if httpError(w, err) { h.log.Errorf("err: %+v", err) return } @@ -239,12 +239,12 @@ func (h *RunHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { } type RuntaskHandler struct { - log *zap.SugaredLogger - runserviceClient *rsapi.Client + log *zap.SugaredLogger + ah *action.ActionHandler } -func NewRuntaskHandler(logger *zap.Logger, runserviceClient *rsapi.Client) *RuntaskHandler { - return &RuntaskHandler{log: logger.Sugar(), runserviceClient: runserviceClient} +func NewRuntaskHandler(logger *zap.Logger, ah *action.ActionHandler) *RuntaskHandler { + return &RuntaskHandler{log: logger.Sugar(), ah: ah} } func (h *RuntaskHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { @@ -253,8 +253,8 @@ func (h *RuntaskHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { runID := vars["runid"] taskID := vars["taskid"] - runResp, resp, err := h.runserviceClient.GetRun(ctx, runID) - if httpErrorFromRemote(w, resp, err) { + runResp, err := h.ah.GetRun(ctx, runID) + if httpError(w, err) { h.log.Errorf("err: %+v", err) return } @@ -300,12 +300,12 @@ func createRunsResponse(r *rstypes.Run) *RunsResponse { } type RunsHandler struct { - log *zap.SugaredLogger - runserviceClient *rsapi.Client + log *zap.SugaredLogger + ah *action.ActionHandler } -func NewRunsHandler(logger *zap.Logger, runserviceClient *rsapi.Client) *RunsHandler { - return &RunsHandler{log: logger.Sugar(), runserviceClient: runserviceClient} +func NewRunsHandler(logger *zap.Logger, ah *action.ActionHandler) *RunsHandler { + return &RunsHandler{log: logger.Sugar(), ah: ah} } func (h *RunsHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { @@ -348,8 +348,17 @@ func (h *RunsHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { start := q.Get("start") - runsResp, resp, err := h.runserviceClient.GetRuns(ctx, phaseFilter, groups, lastRun, changeGroups, start, limit, asc) - if httpErrorFromRemote(w, resp, err) { + areq := &action.GetRunsRequest{ + PhaseFilter: phaseFilter, + Groups: groups, + LastRun: lastRun, + ChangeGroups: changeGroups, + StartRunID: start, + Limit: limit, + Asc: asc, + } + runsResp, err := h.ah.GetRuns(ctx, areq) + if httpError(w, err) { h.log.Errorf("err: %+v", err) return } @@ -363,27 +372,20 @@ func (h *RunsHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { } } -type RunActionType string - -const ( - RunActionTypeRestart RunActionType = "restart" - RunActionTypeStop RunActionType = "stop" -) - type RunActionsRequest struct { - ActionType RunActionType `json:"action_type"` + ActionType action.RunActionType `json:"action_type"` // Restart FromStart bool `json:"from_start"` } type RunActionsHandler struct { - log *zap.SugaredLogger - runserviceClient *rsapi.Client + log *zap.SugaredLogger + ah *action.ActionHandler } -func NewRunActionsHandler(logger *zap.Logger, runserviceClient *rsapi.Client) *RunActionsHandler { - return &RunActionsHandler{log: logger.Sugar(), runserviceClient: runserviceClient} +func NewRunActionsHandler(logger *zap.Logger, ah *action.ActionHandler) *RunActionsHandler { + return &RunActionsHandler{log: logger.Sugar(), ah: ah} } func (h *RunActionsHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { @@ -398,50 +400,31 @@ func (h *RunActionsHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { return } - switch req.ActionType { - case RunActionTypeRestart: - rsreq := &rsapi.RunCreateRequest{ - RunID: runID, - FromStart: req.FromStart, - } + areq := &action.RunActionsRequest{ + RunID: runID, + ActionType: req.ActionType, + FromStart: req.FromStart, + } - resp, err := h.runserviceClient.CreateRun(ctx, rsreq) - if httpErrorFromRemote(w, resp, err) { - h.log.Errorf("err: %+v", err) - return - } - - case RunActionTypeStop: - rsreq := &rsapi.RunActionsRequest{ - ActionType: rsapi.RunActionTypeStop, - } - - resp, err := h.runserviceClient.RunActions(ctx, runID, rsreq) - if httpErrorFromRemote(w, resp, err) { - h.log.Errorf("err: %+v", err) - return - } + err := h.ah.RunAction(ctx, areq) + if httpError(w, err) { + h.log.Errorf("err: %+v", err) + return } } -type RunTaskActionType string - -const ( - RunTaskActionTypeApprove RunTaskActionType = "approve" -) - type RunTaskActionsRequest struct { - ActionType RunTaskActionType `json:"action_type"` - ApprovalAnnotations map[string]string `json:"approval_annotations,omitempty"` + ActionType action.RunTaskActionType `json:"action_type"` + ApprovalAnnotations map[string]string `json:"approval_annotations,omitempty"` } type RunTaskActionsHandler struct { - log *zap.SugaredLogger - runserviceClient *rsapi.Client + log *zap.SugaredLogger + ah *action.ActionHandler } -func NewRunTaskActionsHandler(logger *zap.Logger, runserviceClient *rsapi.Client) *RunTaskActionsHandler { - return &RunTaskActionsHandler{log: logger.Sugar(), runserviceClient: runserviceClient} +func NewRunTaskActionsHandler(logger *zap.Logger, ah *action.ActionHandler) *RunTaskActionsHandler { + return &RunTaskActionsHandler{log: logger.Sugar(), ah: ah} } func (h *RunTaskActionsHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { @@ -457,32 +440,27 @@ func (h *RunTaskActionsHandler) ServeHTTP(w http.ResponseWriter, r *http.Request return } - switch req.ActionType { - case RunTaskActionTypeApprove: - rsreq := &rsapi.RunTaskActionsRequest{ - ActionType: rsapi.RunTaskActionTypeApprove, - ApprovalAnnotations: req.ApprovalAnnotations, - } + areq := &action.RunTaskActionsRequest{ + RunID: runID, + TaskID: taskID, + ActionType: req.ActionType, + ApprovalAnnotations: req.ApprovalAnnotations, + } - resp, err := h.runserviceClient.RunTaskActions(ctx, runID, taskID, rsreq) - if httpErrorFromRemote(w, resp, err) { - h.log.Errorf("err: %+v", err) - return - } - - default: - httpError(w, util.NewErrBadRequest(errors.Errorf("wrong action type %q", req.ActionType))) + err := h.ah.RunTaskAction(ctx, areq) + if httpError(w, err) { + h.log.Errorf("err: %+v", err) return } } type LogsHandler struct { - log *zap.SugaredLogger - runserviceClient *rsapi.Client + log *zap.SugaredLogger + ah *action.ActionHandler } -func NewLogsHandler(logger *zap.Logger, runserviceClient *rsapi.Client) *LogsHandler { - return &LogsHandler{log: logger.Sugar(), runserviceClient: runserviceClient} +func NewLogsHandler(logger *zap.Logger, ah *action.ActionHandler) *LogsHandler { + return &LogsHandler{log: logger.Sugar(), ah: ah} } func (h *LogsHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { @@ -534,8 +512,17 @@ func (h *LogsHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { stream = true } - resp, err := h.runserviceClient.GetLogs(ctx, runID, taskID, setup, step, follow, stream) - if httpErrorFromRemote(w, resp, err) { + areq := &action.GetLogsRequest{ + RunID: runID, + TaskID: taskID, + Setup: setup, + Step: step, + Follow: follow, + Stream: stream, + } + + resp, err := h.ah.GetLogs(ctx, areq) + if httpError(w, err) { h.log.Errorf("err: %+v", err) return } diff --git a/internal/services/gateway/gateway.go b/internal/services/gateway/gateway.go index 1502f2b..d1d9bf9 100644 --- a/internal/services/gateway/gateway.go +++ b/internal/services/gateway/gateway.go @@ -122,13 +122,14 @@ func NewGateway(gc *config.Config) (*Gateway, error) { } configstoreClient := csapi.NewClient(c.ConfigStoreURL) + runserviceClient := rsapi.NewClient(c.RunServiceURL) - ah := action.NewActionHandler(logger, sd, configstoreClient, gc.ID, c.APIExposedURL, c.WebExposedURL) + ah := action.NewActionHandler(logger, sd, configstoreClient, runserviceClient, gc.ID, c.APIExposedURL, c.WebExposedURL) return &Gateway{ c: c, ost: ost, - runserviceClient: rsapi.NewClient(c.RunServiceURL), + runserviceClient: runserviceClient, configstoreClient: configstoreClient, ah: ah, sd: sd, @@ -186,13 +187,13 @@ func (g *Gateway) Run(ctx context.Context) error { createOrgHandler := api.NewCreateOrgHandler(logger, g.ah) deleteOrgHandler := api.NewDeleteOrgHandler(logger, g.ah) - runHandler := api.NewRunHandler(logger, g.runserviceClient) - runsHandler := api.NewRunsHandler(logger, g.runserviceClient) - runtaskHandler := api.NewRuntaskHandler(logger, g.runserviceClient) - runActionsHandler := api.NewRunActionsHandler(logger, g.runserviceClient) - runTaskActionsHandler := api.NewRunTaskActionsHandler(logger, g.runserviceClient) + runHandler := api.NewRunHandler(logger, g.ah) + runsHandler := api.NewRunsHandler(logger, g.ah) + runtaskHandler := api.NewRuntaskHandler(logger, g.ah) + runActionsHandler := api.NewRunActionsHandler(logger, g.ah) + runTaskActionsHandler := api.NewRunTaskActionsHandler(logger, g.ah) - logsHandler := api.NewLogsHandler(logger, g.runserviceClient) + logsHandler := api.NewLogsHandler(logger, g.ah) reposHandler := api.NewReposHandler(logger, g.c.GitServerURL) userRemoteReposHandler := api.NewUserRemoteReposHandler(logger, g.ah, g.configstoreClient)