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

View File

@ -138,6 +138,11 @@ func (handler *Handler) inspectStatus(tx dataservices.DataStoreTx, r *http.Reque
endpoint.EdgeID = edgeIdentifier endpoint.EdgeID = edgeIdentifier
} }
// Take an initial snapshot
if endpoint.LastCheckInDate == 0 {
handler.ReverseTunnelService.SetTunnelStatusToRequired(endpoint.ID)
}
agentPlatform, agentPlatformErr := parseAgentPlatform(r) agentPlatform, agentPlatformErr := parseAgentPlatform(r)
if agentPlatformErr != nil { if agentPlatformErr != nil {
return nil, httperror.BadRequest("agent platform header is not valid", err) 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/http/security"
"github.com/portainer/portainer/api/internal/authorization" "github.com/portainer/portainer/api/internal/authorization"
edgestackservice "github.com/portainer/portainer/api/internal/edge/edgestacks" 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/ssl"
"github.com/portainer/portainer/api/internal/upgrade" "github.com/portainer/portainer/api/internal/upgrade"
k8s "github.com/portainer/portainer/api/kubernetes" k8s "github.com/portainer/portainer/api/kubernetes"
@ -367,6 +368,8 @@ func (server *Server) Start() error {
go shutdown(server.ShutdownCtx, httpsServer) go shutdown(server.ShutdownCtx, httpsServer)
go snapshot.NewBackgroundSnapshotter(server.DataStore, server.ReverseTunnelService)
return httpsServer.ListenAndServeTLS("", "") return httpsServer.ListenAndServeTLS("", "")
} }

View File

@ -10,6 +10,7 @@ import (
"github.com/portainer/portainer/api/agent" "github.com/portainer/portainer/api/agent"
"github.com/portainer/portainer/api/crypto" "github.com/portainer/portainer/api/crypto"
"github.com/portainer/portainer/api/dataservices" "github.com/portainer/portainer/api/dataservices"
"github.com/portainer/portainer/api/internal/endpointutils"
"github.com/portainer/portainer/pkg/featureflags" "github.com/portainer/portainer/pkg/featureflags"
"github.com/rs/zerolog/log" "github.com/rs/zerolog/log"
@ -44,6 +45,42 @@ func NewService(snapshotIntervalFromFlag string, dataStore dataservices.DataStor
}, nil }, 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) { func parseSnapshotFrequency(snapshotInterval string, dataStore dataservices.DataStore) (float64, error) {
if snapshotInterval == "" { if snapshotInterval == "" {
settings, err := dataStore.Settings().Settings() settings, err := dataStore.Settings().Settings()