fix(snapshots): increase the chance of taking a snapshot for edge environments EE-4795 (#9211)

pull/9212/head
andres-portainer 2023-07-14 12:34:50 -03:00 committed by GitHub
parent 615af4fdee
commit 146681e1c7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 55 additions and 4 deletions

View File

@ -126,8 +126,11 @@ func (service *Service) SetTunnelStatusToIdle(endpointID portainer.EndpointID) {
credentials := tunnel.Credentials
if credentials != "" {
tunnel.Credentials = ""
if service.chiselServer != nil {
service.chiselServer.DeleteUser(strings.Split(credentials, ":")[0])
}
}
service.ProxyManager.DeleteEndpointProxy(endpointID)
@ -161,10 +164,13 @@ func (service *Service) SetTunnelStatusToRequired(endpointID portainer.EndpointI
username, password := generateRandomCredentials()
authorizedRemote := fmt.Sprintf("^R:0.0.0.0:%d$", tunnel.Port)
if service.chiselServer != nil {
err = service.chiselServer.AddUser(username, password, authorizedRemote)
if err != nil {
return err
}
}
credentials, err := encryptCredentials(username, password, endpoint.EdgeID)
if err != nil {

View File

@ -138,6 +138,11 @@ func (handler *Handler) inspectStatus(tx dataservices.DataStoreTx, r *http.Reque
endpoint.EdgeID = edgeIdentifier
}
// Take an initial snapshot
if endpoint.LastCheckInDate == 0 {
handler.ReverseTunnelService.SetTunnelStatusToRequired(endpoint.ID)
}
agentPlatform, agentPlatformErr := parseAgentPlatform(r)
if agentPlatformErr != nil {
return nil, httperror.BadRequest("agent platform header is not valid", err)

View File

@ -59,6 +59,7 @@ import (
"github.com/portainer/portainer/api/http/security"
"github.com/portainer/portainer/api/internal/authorization"
edgestackservice "github.com/portainer/portainer/api/internal/edge/edgestacks"
"github.com/portainer/portainer/api/internal/snapshot"
"github.com/portainer/portainer/api/internal/ssl"
"github.com/portainer/portainer/api/internal/upgrade"
k8s "github.com/portainer/portainer/api/kubernetes"
@ -367,6 +368,8 @@ func (server *Server) Start() error {
go shutdown(server.ShutdownCtx, httpsServer)
go snapshot.NewBackgroundSnapshotter(server.DataStore, server.ReverseTunnelService)
return httpsServer.ListenAndServeTLS("", "")
}

View File

@ -10,6 +10,7 @@ import (
"github.com/portainer/portainer/api/agent"
"github.com/portainer/portainer/api/crypto"
"github.com/portainer/portainer/api/dataservices"
"github.com/portainer/portainer/api/internal/endpointutils"
"github.com/portainer/portainer/pkg/featureflags"
"github.com/rs/zerolog/log"
@ -44,6 +45,42 @@ func NewService(snapshotIntervalFromFlag string, dataStore dataservices.DataStor
}, nil
}
// NewBackgroundSnapshotter queues snapshots of existing edge environments that
// do not have one already
func NewBackgroundSnapshotter(dataStore dataservices.DataStore, tunnelService portainer.ReverseTunnelService) {
var endpointIDs []portainer.EndpointID
err := dataStore.ViewTx(func(tx dataservices.DataStoreTx) error {
endpoints, err := tx.Endpoint().Endpoints()
if err != nil {
return err
}
for _, e := range endpoints {
if !endpointutils.IsEdgeEndpoint(&e) {
continue
}
s, err := tx.Snapshot().Read(e.ID)
if dataservices.IsErrObjectNotFound(err) ||
(err == nil && s.Docker == nil && s.Kubernetes == nil) {
endpointIDs = append(endpointIDs, e.ID)
}
}
return nil
})
if err != nil {
log.Error().Err(err).Msg("background snapshotter failure")
return
}
for _, endpointID := range endpointIDs {
tunnelService.SetTunnelStatusToActive(endpointID)
time.Sleep(10 * time.Second)
}
}
func parseSnapshotFrequency(snapshotInterval string, dataStore dataservices.DataStore) (float64, error) {
if snapshotInterval == "" {
settings, err := dataStore.Settings().Settings()