mirror of
https://github.com/portainer/portainer.git
synced 2025-07-24 07:49:41 +02:00
fix(tunnels): make the tunnels more robust EE-7042 (#11877)
This commit is contained in:
parent
aaab2fa9d8
commit
c5a1d7e051
20 changed files with 389 additions and 355 deletions
|
@ -15,6 +15,7 @@ import (
|
|||
|
||||
portainer "github.com/portainer/portainer/api"
|
||||
"github.com/portainer/portainer/api/dataservices"
|
||||
"github.com/portainer/portainer/api/internal/edge"
|
||||
"github.com/portainer/portainer/api/internal/edge/cache"
|
||||
httperror "github.com/portainer/portainer/pkg/libhttp/error"
|
||||
"github.com/portainer/portainer/pkg/libhttp/request"
|
||||
|
@ -134,7 +135,7 @@ func (handler *Handler) inspectStatus(tx dataservices.DataStoreTx, r *http.Reque
|
|||
|
||||
// Take an initial snapshot
|
||||
if endpoint.LastCheckInDate == 0 {
|
||||
handler.ReverseTunnelService.SetTunnelStatusToRequired(endpoint.ID)
|
||||
handler.ReverseTunnelService.Open(endpoint)
|
||||
}
|
||||
|
||||
agentPlatform, agentPlatformErr := parseAgentPlatform(r)
|
||||
|
@ -153,34 +154,21 @@ func (handler *Handler) inspectStatus(tx dataservices.DataStoreTx, r *http.Reque
|
|||
return nil, httperror.InternalServerError("Unable to persist environment changes inside the database", err)
|
||||
}
|
||||
|
||||
checkinInterval := endpoint.EdgeCheckinInterval
|
||||
if endpoint.EdgeCheckinInterval == 0 {
|
||||
settings, err := tx.Settings().Settings()
|
||||
if err != nil {
|
||||
return nil, httperror.InternalServerError("Unable to retrieve settings from the database", err)
|
||||
}
|
||||
checkinInterval = settings.EdgeAgentCheckinInterval
|
||||
}
|
||||
|
||||
tunnel := handler.ReverseTunnelService.GetTunnelDetails(endpoint.ID)
|
||||
tunnel := handler.ReverseTunnelService.Config(endpoint.ID)
|
||||
|
||||
statusResponse := endpointEdgeStatusInspectResponse{
|
||||
Status: tunnel.Status,
|
||||
Port: tunnel.Port,
|
||||
CheckinInterval: checkinInterval,
|
||||
CheckinInterval: edge.EffectiveCheckinInterval(tx, endpoint),
|
||||
Credentials: tunnel.Credentials,
|
||||
}
|
||||
|
||||
schedules, handlerErr := handler.buildSchedules(endpoint.ID, tunnel)
|
||||
schedules, handlerErr := handler.buildSchedules(endpoint.ID)
|
||||
if handlerErr != nil {
|
||||
return nil, handlerErr
|
||||
}
|
||||
statusResponse.Schedules = schedules
|
||||
|
||||
if tunnel.Status == portainer.EdgeAgentManagementRequired {
|
||||
handler.ReverseTunnelService.SetTunnelStatusToActive(endpoint.ID)
|
||||
}
|
||||
|
||||
edgeStacksStatus, handlerErr := handler.buildEdgeStacks(tx, endpoint.ID)
|
||||
if handlerErr != nil {
|
||||
return nil, handlerErr
|
||||
|
@ -213,9 +201,9 @@ func parseAgentPlatform(r *http.Request) (portainer.EndpointType, error) {
|
|||
}
|
||||
}
|
||||
|
||||
func (handler *Handler) buildSchedules(endpointID portainer.EndpointID, tunnel portainer.TunnelDetails) ([]edgeJobResponse, *httperror.HandlerError) {
|
||||
func (handler *Handler) buildSchedules(endpointID portainer.EndpointID) ([]edgeJobResponse, *httperror.HandlerError) {
|
||||
schedules := []edgeJobResponse{}
|
||||
for _, job := range tunnel.Jobs {
|
||||
for _, job := range handler.ReverseTunnelService.EdgeJobs(endpointID) {
|
||||
var collectLogs bool
|
||||
if _, ok := job.GroupLogsCollection[endpointID]; ok {
|
||||
collectLogs = job.GroupLogsCollection[endpointID].CollectLogs
|
||||
|
|
|
@ -34,7 +34,7 @@ func (handler *Handler) proxyRequestsToDockerAPI(w http.ResponseWriter, r *http.
|
|||
return httperror.InternalServerError("No Edge agent registered with the environment", errors.New("No agent available"))
|
||||
}
|
||||
|
||||
_, err := handler.ReverseTunnelService.GetActiveTunnel(endpoint)
|
||||
_, err := handler.ReverseTunnelService.TunnelAddr(endpoint)
|
||||
if err != nil {
|
||||
return httperror.InternalServerError("Unable to get the active tunnel", err)
|
||||
}
|
||||
|
|
|
@ -34,7 +34,7 @@ func (handler *Handler) proxyRequestsToKubernetesAPI(w http.ResponseWriter, r *h
|
|||
return httperror.InternalServerError("No Edge agent registered with the environment", errors.New("No agent available"))
|
||||
}
|
||||
|
||||
_, err := handler.ReverseTunnelService.GetActiveTunnel(endpoint)
|
||||
_, err := handler.ReverseTunnelService.TunnelAddr(endpoint)
|
||||
if err != nil {
|
||||
return httperror.InternalServerError("Unable to get the active tunnel", err)
|
||||
}
|
||||
|
|
|
@ -59,8 +59,6 @@ func (handler *Handler) endpointAssociationDelete(w http.ResponseWriter, r *http
|
|||
return httperror.InternalServerError("Failed persisting environment in database", err)
|
||||
}
|
||||
|
||||
handler.ReverseTunnelService.SetTunnelStatusToIdle(endpoint.ID)
|
||||
|
||||
return response.Empty(w)
|
||||
}
|
||||
|
||||
|
|
|
@ -18,12 +18,12 @@ import (
|
|||
)
|
||||
|
||||
func (handler *Handler) proxyEdgeAgentWebsocketRequest(w http.ResponseWriter, r *http.Request, params *webSocketRequestParams) error {
|
||||
tunnel, err := handler.ReverseTunnelService.GetActiveTunnel(params.endpoint)
|
||||
tunnelAddr, err := handler.ReverseTunnelService.TunnelAddr(params.endpoint)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
agentURL, err := url.Parse(fmt.Sprintf("http://127.0.0.1:%d", tunnel.Port))
|
||||
agentURL, err := url.Parse("http://" + tunnelAddr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -93,7 +93,7 @@ func (handler *Handler) doProxyWebsocketRequest(
|
|||
}
|
||||
|
||||
if isEdge {
|
||||
handler.ReverseTunnelService.SetTunnelStatusToActive(params.endpoint.ID)
|
||||
handler.ReverseTunnelService.UpdateLastActivity(params.endpoint.ID)
|
||||
handler.ReverseTunnelService.KeepTunnelAlive(params.endpoint.ID, r.Context(), portainer.WebSocketKeepAlive)
|
||||
}
|
||||
|
||||
|
|
|
@ -26,12 +26,12 @@ func (factory *ProxyFactory) NewAgentProxy(endpoint *portainer.Endpoint) (*Proxy
|
|||
urlString := endpoint.URL
|
||||
|
||||
if endpointutils.IsEdgeEndpoint(endpoint) {
|
||||
tunnel, err := factory.reverseTunnelService.GetActiveTunnel(endpoint)
|
||||
tunnelAddr, err := factory.reverseTunnelService.TunnelAddr(endpoint)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed starting tunnel")
|
||||
}
|
||||
|
||||
urlString = fmt.Sprintf("http://127.0.0.1:%d", tunnel.Port)
|
||||
urlString = "http://" + tunnelAddr
|
||||
}
|
||||
|
||||
endpointURL, err := url.ParseURL(urlString)
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package factory
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
@ -35,8 +34,11 @@ func (factory *ProxyFactory) newDockerLocalProxy(endpoint *portainer.Endpoint) (
|
|||
func (factory *ProxyFactory) newDockerHTTPProxy(endpoint *portainer.Endpoint) (http.Handler, error) {
|
||||
rawURL := endpoint.URL
|
||||
if endpoint.Type == portainer.EdgeAgentOnDockerEnvironment {
|
||||
tunnel := factory.reverseTunnelService.GetTunnelDetails(endpoint.ID)
|
||||
rawURL = fmt.Sprintf("http://127.0.0.1:%d", tunnel.Port)
|
||||
tunnelAddr, err := factory.reverseTunnelService.TunnelAddr(endpoint)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
rawURL = "http://" + tunnelAddr
|
||||
}
|
||||
|
||||
endpointURL, err := url.ParseURL(rawURL)
|
||||
|
|
|
@ -138,9 +138,7 @@ func (transport *Transport) executeDockerRequest(request *http.Request) (*http.R
|
|||
}
|
||||
|
||||
if err == nil {
|
||||
transport.reverseTunnelService.SetTunnelStatusToActive(transport.endpoint.ID)
|
||||
} else {
|
||||
transport.reverseTunnelService.SetTunnelStatusToIdle(transport.endpoint.ID)
|
||||
transport.reverseTunnelService.UpdateLastActivity(transport.endpoint.ID)
|
||||
}
|
||||
|
||||
return response, err
|
||||
|
|
|
@ -51,8 +51,11 @@ func (factory *ProxyFactory) newKubernetesLocalProxy(endpoint *portainer.Endpoin
|
|||
}
|
||||
|
||||
func (factory *ProxyFactory) newKubernetesEdgeHTTPProxy(endpoint *portainer.Endpoint) (http.Handler, error) {
|
||||
tunnel := factory.reverseTunnelService.GetTunnelDetails(endpoint.ID)
|
||||
rawURL := fmt.Sprintf("http://127.0.0.1:%d", tunnel.Port)
|
||||
tunnelAddr, err := factory.reverseTunnelService.TunnelAddr(endpoint)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
rawURL := "http://" + tunnelAddr
|
||||
|
||||
endpointURL, err := url.Parse(rawURL)
|
||||
if err != nil {
|
||||
|
|
|
@ -59,9 +59,7 @@ func (transport *edgeTransport) RoundTrip(request *http.Request) (*http.Response
|
|||
response, err := transport.baseTransport.RoundTrip(request)
|
||||
|
||||
if err == nil {
|
||||
transport.reverseTunnelService.SetTunnelStatusToActive(transport.endpoint.ID)
|
||||
} else {
|
||||
transport.reverseTunnelService.SetTunnelStatusToIdle(transport.endpoint.ID)
|
||||
transport.reverseTunnelService.UpdateLastActivity(transport.endpoint.ID)
|
||||
}
|
||||
|
||||
return response, err
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue