gateway: move run logic from api to actions

This commit is contained in:
Simone Gotti 2019-05-06 00:00:45 +02:00
parent 6b5bd40417
commit 05ae46a72d
4 changed files with 235 additions and 94 deletions

View File

@ -20,6 +20,7 @@ import (
"github.com/pkg/errors" "github.com/pkg/errors"
csapi "github.com/sorintlab/agola/internal/services/configstore/api" csapi "github.com/sorintlab/agola/internal/services/configstore/api"
"github.com/sorintlab/agola/internal/services/gateway/common" "github.com/sorintlab/agola/internal/services/gateway/common"
rsapi "github.com/sorintlab/agola/internal/services/runservice/scheduler/api"
"github.com/sorintlab/agola/internal/util" "github.com/sorintlab/agola/internal/util"
"go.uber.org/zap" "go.uber.org/zap"
@ -29,16 +30,18 @@ type ActionHandler struct {
log *zap.SugaredLogger log *zap.SugaredLogger
sd *common.TokenSigningData sd *common.TokenSigningData
configstoreClient *csapi.Client configstoreClient *csapi.Client
runserviceClient *rsapi.Client
agolaID string agolaID string
apiExposedURL string apiExposedURL string
webExposedURL 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{ return &ActionHandler{
log: logger.Sugar(), log: logger.Sugar(),
sd: sd, sd: sd,
configstoreClient: configstoreClient, configstoreClient: configstoreClient,
runserviceClient: runserviceClient,
agolaID: agolaID, agolaID: agolaID,
apiExposedURL: apiExposedURL, apiExposedURL: apiExposedURL,
webExposedURL: webExposedURL, webExposedURL: webExposedURL,

View File

@ -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
}

View File

@ -23,7 +23,7 @@ import (
"time" "time"
"github.com/pkg/errors" "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" rstypes "github.com/sorintlab/agola/internal/services/runservice/types"
"github.com/sorintlab/agola/internal/util" "github.com/sorintlab/agola/internal/util"
"go.uber.org/zap" "go.uber.org/zap"
@ -213,12 +213,12 @@ func createRunTaskResponse(rt *rstypes.RunTask, rct *rstypes.RunConfigTask) *Run
} }
type RunHandler struct { type RunHandler struct {
log *zap.SugaredLogger log *zap.SugaredLogger
runserviceClient *rsapi.Client ah *action.ActionHandler
} }
func NewRunHandler(logger *zap.Logger, runserviceClient *rsapi.Client) *RunHandler { func NewRunHandler(logger *zap.Logger, ah *action.ActionHandler) *RunHandler {
return &RunHandler{log: logger.Sugar(), runserviceClient: runserviceClient} return &RunHandler{log: logger.Sugar(), ah: ah}
} }
func (h *RunHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { 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) vars := mux.Vars(r)
runID := vars["runid"] runID := vars["runid"]
runResp, resp, err := h.runserviceClient.GetRun(ctx, runID) runResp, err := h.ah.GetRun(ctx, runID)
if httpErrorFromRemote(w, resp, err) { if httpError(w, err) {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
return return
} }
@ -239,12 +239,12 @@ func (h *RunHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
} }
type RuntaskHandler struct { type RuntaskHandler struct {
log *zap.SugaredLogger log *zap.SugaredLogger
runserviceClient *rsapi.Client ah *action.ActionHandler
} }
func NewRuntaskHandler(logger *zap.Logger, runserviceClient *rsapi.Client) *RuntaskHandler { func NewRuntaskHandler(logger *zap.Logger, ah *action.ActionHandler) *RuntaskHandler {
return &RuntaskHandler{log: logger.Sugar(), runserviceClient: runserviceClient} return &RuntaskHandler{log: logger.Sugar(), ah: ah}
} }
func (h *RuntaskHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { 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"] runID := vars["runid"]
taskID := vars["taskid"] taskID := vars["taskid"]
runResp, resp, err := h.runserviceClient.GetRun(ctx, runID) runResp, err := h.ah.GetRun(ctx, runID)
if httpErrorFromRemote(w, resp, err) { if httpError(w, err) {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
return return
} }
@ -300,12 +300,12 @@ func createRunsResponse(r *rstypes.Run) *RunsResponse {
} }
type RunsHandler struct { type RunsHandler struct {
log *zap.SugaredLogger log *zap.SugaredLogger
runserviceClient *rsapi.Client ah *action.ActionHandler
} }
func NewRunsHandler(logger *zap.Logger, runserviceClient *rsapi.Client) *RunsHandler { func NewRunsHandler(logger *zap.Logger, ah *action.ActionHandler) *RunsHandler {
return &RunsHandler{log: logger.Sugar(), runserviceClient: runserviceClient} return &RunsHandler{log: logger.Sugar(), ah: ah}
} }
func (h *RunsHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { 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") start := q.Get("start")
runsResp, resp, err := h.runserviceClient.GetRuns(ctx, phaseFilter, groups, lastRun, changeGroups, start, limit, asc) areq := &action.GetRunsRequest{
if httpErrorFromRemote(w, resp, err) { 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) h.log.Errorf("err: %+v", err)
return 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 { type RunActionsRequest struct {
ActionType RunActionType `json:"action_type"` ActionType action.RunActionType `json:"action_type"`
// Restart // Restart
FromStart bool `json:"from_start"` FromStart bool `json:"from_start"`
} }
type RunActionsHandler struct { type RunActionsHandler struct {
log *zap.SugaredLogger log *zap.SugaredLogger
runserviceClient *rsapi.Client ah *action.ActionHandler
} }
func NewRunActionsHandler(logger *zap.Logger, runserviceClient *rsapi.Client) *RunActionsHandler { func NewRunActionsHandler(logger *zap.Logger, ah *action.ActionHandler) *RunActionsHandler {
return &RunActionsHandler{log: logger.Sugar(), runserviceClient: runserviceClient} return &RunActionsHandler{log: logger.Sugar(), ah: ah}
} }
func (h *RunActionsHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { 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 return
} }
switch req.ActionType { areq := &action.RunActionsRequest{
case RunActionTypeRestart: RunID: runID,
rsreq := &rsapi.RunCreateRequest{ ActionType: req.ActionType,
RunID: runID, FromStart: req.FromStart,
FromStart: req.FromStart, }
}
resp, err := h.runserviceClient.CreateRun(ctx, rsreq) err := h.ah.RunAction(ctx, areq)
if httpErrorFromRemote(w, resp, err) { if httpError(w, err) {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
return 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
}
} }
} }
type RunTaskActionType string
const (
RunTaskActionTypeApprove RunTaskActionType = "approve"
)
type RunTaskActionsRequest struct { type RunTaskActionsRequest struct {
ActionType RunTaskActionType `json:"action_type"` ActionType action.RunTaskActionType `json:"action_type"`
ApprovalAnnotations map[string]string `json:"approval_annotations,omitempty"` ApprovalAnnotations map[string]string `json:"approval_annotations,omitempty"`
} }
type RunTaskActionsHandler struct { type RunTaskActionsHandler struct {
log *zap.SugaredLogger log *zap.SugaredLogger
runserviceClient *rsapi.Client ah *action.ActionHandler
} }
func NewRunTaskActionsHandler(logger *zap.Logger, runserviceClient *rsapi.Client) *RunTaskActionsHandler { func NewRunTaskActionsHandler(logger *zap.Logger, ah *action.ActionHandler) *RunTaskActionsHandler {
return &RunTaskActionsHandler{log: logger.Sugar(), runserviceClient: runserviceClient} return &RunTaskActionsHandler{log: logger.Sugar(), ah: ah}
} }
func (h *RunTaskActionsHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { 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 return
} }
switch req.ActionType { areq := &action.RunTaskActionsRequest{
case RunTaskActionTypeApprove: RunID: runID,
rsreq := &rsapi.RunTaskActionsRequest{ TaskID: taskID,
ActionType: rsapi.RunTaskActionTypeApprove, ActionType: req.ActionType,
ApprovalAnnotations: req.ApprovalAnnotations, ApprovalAnnotations: req.ApprovalAnnotations,
} }
resp, err := h.runserviceClient.RunTaskActions(ctx, runID, taskID, rsreq) err := h.ah.RunTaskAction(ctx, areq)
if httpErrorFromRemote(w, resp, err) { if httpError(w, err) {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
return
}
default:
httpError(w, util.NewErrBadRequest(errors.Errorf("wrong action type %q", req.ActionType)))
return return
} }
} }
type LogsHandler struct { type LogsHandler struct {
log *zap.SugaredLogger log *zap.SugaredLogger
runserviceClient *rsapi.Client ah *action.ActionHandler
} }
func NewLogsHandler(logger *zap.Logger, runserviceClient *rsapi.Client) *LogsHandler { func NewLogsHandler(logger *zap.Logger, ah *action.ActionHandler) *LogsHandler {
return &LogsHandler{log: logger.Sugar(), runserviceClient: runserviceClient} return &LogsHandler{log: logger.Sugar(), ah: ah}
} }
func (h *LogsHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { 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 stream = true
} }
resp, err := h.runserviceClient.GetLogs(ctx, runID, taskID, setup, step, follow, stream) areq := &action.GetLogsRequest{
if httpErrorFromRemote(w, resp, err) { 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) h.log.Errorf("err: %+v", err)
return return
} }

View File

@ -122,13 +122,14 @@ func NewGateway(gc *config.Config) (*Gateway, error) {
} }
configstoreClient := csapi.NewClient(c.ConfigStoreURL) 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{ return &Gateway{
c: c, c: c,
ost: ost, ost: ost,
runserviceClient: rsapi.NewClient(c.RunServiceURL), runserviceClient: runserviceClient,
configstoreClient: configstoreClient, configstoreClient: configstoreClient,
ah: ah, ah: ah,
sd: sd, sd: sd,
@ -186,13 +187,13 @@ func (g *Gateway) Run(ctx context.Context) error {
createOrgHandler := api.NewCreateOrgHandler(logger, g.ah) createOrgHandler := api.NewCreateOrgHandler(logger, g.ah)
deleteOrgHandler := api.NewDeleteOrgHandler(logger, g.ah) deleteOrgHandler := api.NewDeleteOrgHandler(logger, g.ah)
runHandler := api.NewRunHandler(logger, g.runserviceClient) runHandler := api.NewRunHandler(logger, g.ah)
runsHandler := api.NewRunsHandler(logger, g.runserviceClient) runsHandler := api.NewRunsHandler(logger, g.ah)
runtaskHandler := api.NewRuntaskHandler(logger, g.runserviceClient) runtaskHandler := api.NewRuntaskHandler(logger, g.ah)
runActionsHandler := api.NewRunActionsHandler(logger, g.runserviceClient) runActionsHandler := api.NewRunActionsHandler(logger, g.ah)
runTaskActionsHandler := api.NewRunTaskActionsHandler(logger, g.runserviceClient) 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) reposHandler := api.NewReposHandler(logger, g.c.GitServerURL)
userRemoteReposHandler := api.NewUserRemoteReposHandler(logger, g.ah, g.configstoreClient) userRemoteReposHandler := api.NewUserRemoteReposHandler(logger, g.ah, g.configstoreClient)