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"
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,

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

View File

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