feat(edge): edgeStacks and edgeJobs operations small refactors [EE-2744] (#6648)

pull/6745/head
Marcelo Rydel 3 years ago committed by GitHub
parent 6419e7740a
commit f12c3968f1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -92,7 +92,7 @@ func (handler *Handler) updateEdgeSchedule(edgeJob *portainer.EdgeJob, payload *
continue
}
if meta, ok := edgeJob.Endpoints[endpointID]; ok {
if meta, exists := edgeJob.Endpoints[endpointID]; exists {
endpointsMap[endpointID] = meta
} else {
endpointsMap[endpointID] = portainer.EdgeJobEndpointMeta{}
@ -103,13 +103,18 @@ func (handler *Handler) updateEdgeSchedule(edgeJob *portainer.EdgeJob, payload *
}
updateVersion := false
if payload.CronExpression != nil {
if payload.CronExpression != nil && *payload.CronExpression != edgeJob.CronExpression {
edgeJob.CronExpression = *payload.CronExpression
updateVersion = true
}
if payload.FileContent != nil {
_, err := handler.FileService.StoreEdgeJobFileFromBytes(strconv.Itoa(int(edgeJob.ID)), []byte(*payload.FileContent))
fileContent, err := handler.FileService.GetFileContent(edgeJob.ScriptPath, "")
if err != nil {
return err
}
if payload.FileContent != nil && *payload.FileContent != string(fileContent) {
_, err := handler.FileService.StoreEdgeJobFileFromBytes(strconv.Itoa(int(edgeJob.ID)), fileContent)
if err != nil {
return err
}
@ -117,7 +122,7 @@ func (handler *Handler) updateEdgeSchedule(edgeJob *portainer.EdgeJob, payload *
updateVersion = true
}
if payload.Recurring != nil {
if payload.Recurring != nil && *payload.Recurring != edgeJob.Recurring {
edgeJob.Recurring = *payload.Recurring
updateVersion = true
}

@ -2,6 +2,7 @@ package edgestacks
import (
"errors"
"github.com/portainer/portainer/api/internal/endpointutils"
"net/http"
"strconv"
@ -80,8 +81,8 @@ func (handler *Handler) edgeStackUpdate(w http.ResponseWriter, r *http.Request)
return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve edge stack related environments from database", err}
}
oldRelatedSet := EndpointSet(relatedEndpointIds)
newRelatedSet := EndpointSet(newRelated)
oldRelatedSet := endpointutils.EndpointSet(relatedEndpointIds)
newRelatedSet := endpointutils.EndpointSet(newRelated)
endpointsToRemove := map[portainer.EndpointID]bool{}
for endpointID := range oldRelatedSet {
@ -189,13 +190,3 @@ func (handler *Handler) edgeStackUpdate(w http.ResponseWriter, r *http.Request)
return response.JSON(w, stack)
}
func EndpointSet(endpointIDs []portainer.EndpointID) map[portainer.EndpointID]bool {
set := map[portainer.EndpointID]bool{}
for _, endpointID := range endpointIDs {
set[endpointID] = true
}
return set
}

@ -8,6 +8,7 @@ import (
"github.com/portainer/libhttp/request"
"github.com/portainer/libhttp/response"
portainer "github.com/portainer/portainer/api"
"github.com/portainer/portainer/api/http/middlewares"
)
type logsPayload struct {
@ -31,16 +32,9 @@ func (payload *logsPayload) Validate(r *http.Request) error {
// @failure 400
// @router /endpoints/{id}/edge/jobs/{jobID}/logs [post]
func (handler *Handler) endpointEdgeJobsLogs(w http.ResponseWriter, r *http.Request) *httperror.HandlerError {
endpointID, err := request.RetrieveNumericRouteVariableValue(r, "id")
endpoint, err := middlewares.FetchEndpoint(r)
if err != nil {
return &httperror.HandlerError{http.StatusBadRequest, "Invalid environment identifier route variable", err}
}
endpoint, err := handler.DataStore.Endpoint().Endpoint(portainer.EndpointID(endpointID))
if handler.DataStore.IsErrObjectNotFound(err) {
return &httperror.HandlerError{http.StatusNotFound, "Unable to find an environment with the specified identifier inside the database", err}
} else if err != nil {
return &httperror.HandlerError{http.StatusInternalServerError, "Unable to find an environment with the specified identifier inside the database", err}
return httperror.BadRequest("Unable to find an environment on request context", err)
}
err = handler.requestBouncer.AuthorizedEdgeEndpointOperation(r, endpoint)
@ -66,7 +60,7 @@ func (handler *Handler) endpointEdgeJobsLogs(w http.ResponseWriter, r *http.Requ
return &httperror.HandlerError{http.StatusInternalServerError, "Unable to find an edge job with the specified identifier inside the database", err}
}
err = handler.FileService.StoreEdgeJobTaskLogFileFromBytes(strconv.Itoa(edgeJobID), strconv.Itoa(endpointID), []byte(payload.FileContent))
err = handler.FileService.StoreEdgeJobTaskLogFileFromBytes(strconv.Itoa(edgeJobID), strconv.Itoa(int(endpoint.ID)), []byte(payload.FileContent))
if err != nil {
return &httperror.HandlerError{http.StatusInternalServerError, "Unable to save task log to the filesystem", err}
}

@ -8,6 +8,7 @@ import (
"github.com/portainer/libhttp/request"
"github.com/portainer/libhttp/response"
portainer "github.com/portainer/portainer/api"
"github.com/portainer/portainer/api/http/middlewares"
"github.com/portainer/portainer/api/internal/endpointutils"
)
@ -29,16 +30,9 @@ type configResponse struct {
// @failure 404
// @router /endpoints/{id}/edge/stacks/{stackId} [get]
func (handler *Handler) endpointEdgeStackInspect(w http.ResponseWriter, r *http.Request) *httperror.HandlerError {
endpointID, err := request.RetrieveNumericRouteVariableValue(r, "id")
endpoint, err := middlewares.FetchEndpoint(r)
if err != nil {
return &httperror.HandlerError{http.StatusBadRequest, "Invalid environment identifier route variable", err}
}
endpoint, err := handler.DataStore.Endpoint().Endpoint(portainer.EndpointID(endpointID))
if handler.DataStore.IsErrObjectNotFound(err) {
return &httperror.HandlerError{http.StatusNotFound, "Unable to find an environment with the specified identifier inside the database", err}
} else if err != nil {
return &httperror.HandlerError{http.StatusInternalServerError, "Unable to find an environment with the specified identifier inside the database", err}
return httperror.BadRequest("Unable to find an environment on request context", err)
}
err = handler.requestBouncer.AuthorizedEdgeEndpointOperation(r, endpoint)

@ -9,9 +9,9 @@ import (
"time"
httperror "github.com/portainer/libhttp/error"
"github.com/portainer/libhttp/request"
"github.com/portainer/libhttp/response"
portainer "github.com/portainer/portainer/api"
"github.com/portainer/portainer/api/http/middlewares"
)
type stackStatusResponse struct {
@ -64,16 +64,9 @@ type endpointEdgeStatusInspectResponse struct {
// @failure 500 "Server error"
// @router /endpoints/{id}/edge/status [get]
func (handler *Handler) endpointEdgeStatusInspect(w http.ResponseWriter, r *http.Request) *httperror.HandlerError {
endpointID, err := request.RetrieveNumericRouteVariableValue(r, "id")
endpoint, err := middlewares.FetchEndpoint(r)
if err != nil {
return &httperror.HandlerError{http.StatusBadRequest, "Invalid environment identifier route variable", err}
}
endpoint, err := handler.DataStore.Endpoint().Endpoint(portainer.EndpointID(endpointID))
if handler.DataStore.IsErrObjectNotFound(err) {
return &httperror.HandlerError{http.StatusNotFound, "Unable to find an environment with the specified identifier inside the database", err}
} else if err != nil {
return &httperror.HandlerError{http.StatusInternalServerError, "Unable to find an environment with the specified identifier inside the database", err}
return httperror.BadRequest("Unable to find an environment on request context", err)
}
err = handler.requestBouncer.AuthorizedEdgeEndpointOperation(r, endpoint)

@ -3,6 +3,8 @@ package endpointedge
import (
"net/http"
"github.com/portainer/portainer/api/http/middlewares"
httperror "github.com/portainer/libhttp/error"
"github.com/gorilla/mux"
@ -21,17 +23,23 @@ type Handler struct {
}
// NewHandler creates a handler to manage environment(endpoint) operations.
func NewHandler(bouncer *security.RequestBouncer) *Handler {
func NewHandler(bouncer *security.RequestBouncer, dataStore dataservices.DataStore, fileService portainer.FileService, reverseTunnelService portainer.ReverseTunnelService) *Handler {
h := &Handler{
Router: mux.NewRouter(),
requestBouncer: bouncer,
Router: mux.NewRouter(),
requestBouncer: bouncer,
DataStore: dataStore,
FileService: fileService,
ReverseTunnelService: reverseTunnelService,
}
h.Handle("/{id}/edge/status",
endpointRouter := h.PathPrefix("/{id}").Subrouter()
endpointRouter.Use(middlewares.WithEndpoint(dataStore.Endpoint(), "id"))
endpointRouter.PathPrefix("/edge/status").Handler(
bouncer.PublicAccess(httperror.LoggerHandler(h.endpointEdgeStatusInspect))).Methods(http.MethodGet)
h.Handle("/{id}/edge/stacks/{stackId}",
endpointRouter.PathPrefix("/edge/stacks/{stackId}").Handler(
bouncer.PublicAccess(httperror.LoggerHandler(h.endpointEdgeStackInspect))).Methods(http.MethodGet)
h.Handle("/{id}/edge/jobs/{jobID}/logs",
endpointRouter.PathPrefix("/edge/jobs/{jobID}/logs").Handler(
bouncer.PublicAccess(httperror.LoggerHandler(h.endpointEdgeJobsLogs))).Methods(http.MethodPost)
return h
}

@ -302,14 +302,14 @@ func (handler *Handler) endpointUpdate(w http.ResponseWriter, r *http.Request) *
return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve edge stacks from the database", err}
}
edgeStackSet := map[portainer.EdgeStackID]bool{}
currentEdgeStackSet := map[portainer.EdgeStackID]bool{}
endpointEdgeStacks := edge.EndpointRelatedEdgeStacks(endpoint, endpointGroup, edgeGroups, edgeStacks)
for _, edgeStackID := range endpointEdgeStacks {
edgeStackSet[edgeStackID] = true
currentEdgeStackSet[edgeStackID] = true
}
relation.EdgeStacks = edgeStackSet
relation.EdgeStacks = currentEdgeStackSet
err = handler.DataStore.EndpointRelation().UpdateEndpointRelation(endpoint.ID, relation)
if err != nil {

@ -160,10 +160,7 @@ func (server *Server) Start() error {
endpointHandler.BindAddress = server.BindAddress
endpointHandler.BindAddressHTTPS = server.BindAddressHTTPS
var endpointEdgeHandler = endpointedge.NewHandler(requestBouncer)
endpointEdgeHandler.DataStore = server.DataStore
endpointEdgeHandler.FileService = server.FileService
endpointEdgeHandler.ReverseTunnelService = server.ReverseTunnelService
var endpointEdgeHandler = endpointedge.NewHandler(requestBouncer, server.DataStore, server.FileService, server.ReverseTunnelService)
var endpointGroupHandler = endpointgroups.NewHandler(requestBouncer)
endpointGroupHandler.AuthorizationService = server.AuthorizationService

@ -58,3 +58,14 @@ func FilterByExcludeIDs(endpoints []portainer.Endpoint, excludeIds []portainer.E
}
return filteredEndpoints
}
// EndpointSet receives an environment(endpoint) array and returns a set
func EndpointSet(endpointIDs []portainer.EndpointID) map[portainer.EndpointID]bool {
set := map[portainer.EndpointID]bool{}
for _, endpointID := range endpointIDs {
set[endpointID] = true
}
return set
}

Loading…
Cancel
Save