mirror of
https://github.com/fleetdm/fleet
synced 2026-05-23 08:58:41 +00:00
When fleet desktop is disabled, do not do API calls to desktop endpoints. (#15636)
When fleet desktop is disabled, do not do API calls to desktop endpoints. #15542 # Checklist for submitter - [x] Changes file added for user-visible changes in `changes/` or `orbit/changes/`. See [Changes files](https://fleetdm.com/docs/contributing/committing-changes#changes-files) for more information. - [x] Manual QA for all new/changed functionality - For Orbit and Fleet Desktop changes: - [x] Manual QA must be performed in the three main OSs, macOS, Windows and Linux. - [x] Auto-update manual QA, from released version of component to new version (see [tools/tuf/test](../tools/tuf/test/README.md)).
This commit is contained in:
parent
5817abb97b
commit
9ed7bc4744
2 changed files with 92 additions and 87 deletions
|
|
@ -0,0 +1 @@
|
|||
When fleet desktop is disabled, do not do API calls to desktop endpoints.
|
||||
|
|
@ -722,107 +722,111 @@ func main() {
|
|||
g.Add(extRunner.Execute, extRunner.Interrupt)
|
||||
}
|
||||
|
||||
trw := token.NewReadWriter(filepath.Join(c.String("root-dir"), "identifier"))
|
||||
|
||||
if err := trw.LoadOrGenerate(); err != nil {
|
||||
return fmt.Errorf("initializing token read writer: %w", err)
|
||||
}
|
||||
|
||||
// note: the initial flags fetch above already populated the capabilities
|
||||
// of the server based on the response header
|
||||
if orbitClient.GetServerCapabilities().Has(fleet.CapabilityOrbitEndpoints) &&
|
||||
orbitClient.GetServerCapabilities().Has(fleet.CapabilityTokenRotation) {
|
||||
log.Info().Msg("token rotation is enabled")
|
||||
|
||||
// we enable remote updates only if the server supports them by setting
|
||||
// this function.
|
||||
trw.SetRemoteUpdateFunc(func(token string) error {
|
||||
return orbitClient.SetOrUpdateDeviceToken(token)
|
||||
})
|
||||
|
||||
// Note that the deviceClient used by orbit must not define a retry on
|
||||
// invalid token, because its goal is to detect invalid tokens when
|
||||
// making requests with this client.
|
||||
deviceClient, err := service.NewDeviceClient(
|
||||
fleetURL,
|
||||
c.Bool("insecure"),
|
||||
c.String("fleet-certificate"),
|
||||
fleetClientCertificate,
|
||||
c.String("fleet-desktop-alternative-browser-host"),
|
||||
)
|
||||
if err != nil {
|
||||
return fmt.Errorf("initializing client: %w", err)
|
||||
var trw *token.ReadWriter
|
||||
if c.Bool("fleet-desktop") {
|
||||
trw = token.NewReadWriter(filepath.Join(c.String("root-dir"), "identifier"))
|
||||
if err := trw.LoadOrGenerate(); err != nil {
|
||||
return fmt.Errorf("initializing token read writer: %w", err)
|
||||
}
|
||||
|
||||
// Check if token is not expired and still good.
|
||||
// If not, rotate the token.
|
||||
expired, _ := trw.HasExpired()
|
||||
if expired || deviceClient.CheckToken(trw.GetCached()) != nil {
|
||||
if err := trw.Rotate(); err != nil {
|
||||
return fmt.Errorf("rotating token: %w", err)
|
||||
// note: the initial flags fetch above already populated the capabilities
|
||||
// of the server based on the response header
|
||||
if orbitClient.GetServerCapabilities().Has(fleet.CapabilityOrbitEndpoints) &&
|
||||
orbitClient.GetServerCapabilities().Has(fleet.CapabilityTokenRotation) {
|
||||
log.Info().Msg("token rotation is enabled")
|
||||
|
||||
// we enable remote updates only if the server supports them by setting
|
||||
// this function.
|
||||
trw.SetRemoteUpdateFunc(
|
||||
func(token string) error {
|
||||
return orbitClient.SetOrUpdateDeviceToken(token)
|
||||
},
|
||||
)
|
||||
|
||||
// Note that the deviceClient used by orbit must not define a retry on
|
||||
// invalid token, because its goal is to detect invalid tokens when
|
||||
// making requests with this client.
|
||||
deviceClient, err := service.NewDeviceClient(
|
||||
fleetURL,
|
||||
c.Bool("insecure"),
|
||||
c.String("fleet-certificate"),
|
||||
fleetClientCertificate,
|
||||
c.String("fleet-desktop-alternative-browser-host"),
|
||||
)
|
||||
if err != nil {
|
||||
return fmt.Errorf("initializing client: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
go func() {
|
||||
// This timer is used to check if the token should be rotated if at
|
||||
// least one hour has passed since the last modification of the token
|
||||
// file.
|
||||
//
|
||||
// This is better than using a ticker that ticks every hour because the
|
||||
// we can't ensure the tick actually runs every hour (eg: the computer is
|
||||
// asleep).
|
||||
rotationDuration := 30 * time.Second
|
||||
rotationTicker := time.NewTicker(rotationDuration)
|
||||
defer rotationTicker.Stop()
|
||||
// Check if token is not expired and still good.
|
||||
// If not, rotate the token.
|
||||
expired, _ := trw.HasExpired()
|
||||
if expired || deviceClient.CheckToken(trw.GetCached()) != nil {
|
||||
if err := trw.Rotate(); err != nil {
|
||||
return fmt.Errorf("rotating token: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
// This timer is used to periodically check if the token is valid. The
|
||||
// server might deem a toked as invalid for reasons out of our control,
|
||||
// for example if the database is restored to a back-up or if somebody
|
||||
// manually invalidates the token in the db.
|
||||
remoteCheckDuration := 5 * time.Minute
|
||||
remoteCheckTicker := time.NewTicker(remoteCheckDuration)
|
||||
defer remoteCheckTicker.Stop()
|
||||
go func() {
|
||||
// This timer is used to check if the token should be rotated if at
|
||||
// least one hour has passed since the last modification of the token
|
||||
// file.
|
||||
//
|
||||
// This is better than using a ticker that ticks every hour because the
|
||||
// we can't ensure the tick actually runs every hour (eg: the computer is
|
||||
// asleep).
|
||||
rotationDuration := 30 * time.Second
|
||||
rotationTicker := time.NewTicker(rotationDuration)
|
||||
defer rotationTicker.Stop()
|
||||
|
||||
for {
|
||||
select {
|
||||
case <-rotationTicker.C:
|
||||
rotationTicker.Reset(rotationDuration)
|
||||
// This timer is used to periodically check if the token is valid. The
|
||||
// server might deem a toked as invalid for reasons out of our control,
|
||||
// for example if the database is restored to a back-up or if somebody
|
||||
// manually invalidates the token in the db.
|
||||
remoteCheckDuration := 5 * time.Minute
|
||||
remoteCheckTicker := time.NewTicker(remoteCheckDuration)
|
||||
defer remoteCheckTicker.Stop()
|
||||
|
||||
log.Debug().Msgf("checking if token has changed or expired, cached mtime: %s", trw.GetMtime())
|
||||
hasChanged, err := trw.HasChanged()
|
||||
if err != nil {
|
||||
log.Error().Err(err).Msg("error checking if token has changed")
|
||||
}
|
||||
for {
|
||||
select {
|
||||
case <-rotationTicker.C:
|
||||
rotationTicker.Reset(rotationDuration)
|
||||
|
||||
exp, remain := trw.HasExpired()
|
||||
|
||||
// rotate if the token file has been modified, if the token is
|
||||
// expired or if it is very close to expire.
|
||||
if hasChanged || exp || remain <= time.Second {
|
||||
log.Info().Msg("token TTL expired, rotating token")
|
||||
|
||||
if err := trw.Rotate(); err != nil {
|
||||
log.Error().Err(err).Msg("error rotating token")
|
||||
log.Debug().Msgf("checking if token has changed or expired, cached mtime: %s", trw.GetMtime())
|
||||
hasChanged, err := trw.HasChanged()
|
||||
if err != nil {
|
||||
log.Error().Err(err).Msg("error checking if token has changed")
|
||||
}
|
||||
} else if remain > 0 && remain < rotationDuration {
|
||||
// check again when the token will expire, which will happen
|
||||
// before the next rotation check
|
||||
rotationTicker.Reset(remain)
|
||||
log.Debug().Msgf("token will expire soon, checking again in: %s", remain)
|
||||
}
|
||||
|
||||
case <-remoteCheckTicker.C:
|
||||
log.Debug().Msgf("initiating remote token check after %s", remoteCheckDuration)
|
||||
if err := deviceClient.CheckToken(trw.GetCached()); err != nil {
|
||||
log.Info().Err(err).Msg("periodic check of token failed, initiating rotation")
|
||||
exp, remain := trw.HasExpired()
|
||||
|
||||
if err := trw.Rotate(); err != nil {
|
||||
log.Error().Err(err).Msg("error rotating token")
|
||||
// rotate if the token file has been modified, if the token is
|
||||
// expired or if it is very close to expire.
|
||||
if hasChanged || exp || remain <= time.Second {
|
||||
log.Info().Msg("token TTL expired, rotating token")
|
||||
|
||||
if err := trw.Rotate(); err != nil {
|
||||
log.Error().Err(err).Msg("error rotating token")
|
||||
}
|
||||
} else if remain > 0 && remain < rotationDuration {
|
||||
// check again when the token will expire, which will happen
|
||||
// before the next rotation check
|
||||
rotationTicker.Reset(remain)
|
||||
log.Debug().Msgf("token will expire soon, checking again in: %s", remain)
|
||||
}
|
||||
|
||||
case <-remoteCheckTicker.C:
|
||||
log.Debug().Msgf("initiating remote token check after %s", remoteCheckDuration)
|
||||
if err := deviceClient.CheckToken(trw.GetCached()); err != nil {
|
||||
log.Info().Err(err).Msg("periodic check of token failed, initiating rotation")
|
||||
|
||||
if err := trw.Rotate(); err != nil {
|
||||
log.Error().Err(err).Msg("error rotating token")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}()
|
||||
}()
|
||||
}
|
||||
}
|
||||
|
||||
// On Windows, where augeas doesn't work, we have a stubbed CopyLenses that always returns
|
||||
|
|
|
|||
Loading…
Reference in a new issue