Skip to content

Commit

Permalink
🐛 Regularly check in with upstream
Browse files Browse the repository at this point in the history
Fixes #894

Signed-off-by: Christian Zunker <[email protected]>
  • Loading branch information
czunker committed Oct 31, 2023
1 parent 7b62a99 commit 914f534
Show file tree
Hide file tree
Showing 5 changed files with 165 additions and 2 deletions.
154 changes: 154 additions & 0 deletions apps/cnspec/cmd/backgroundjob/checkin.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
// Copyright (c) Mondoo, Inc.
// SPDX-License-Identifier: BUSL-1.1

package backgroundjob

import (
"context"
"math/rand"
"net/http"
"sync"
"time"

"github.com/pkg/errors"
"github.com/rs/zerolog/log"
"github.com/spf13/viper"
"go.mondoo.com/cnquery/v9"
"go.mondoo.com/cnquery/v9/cli/sysinfo"
"go.mondoo.com/cnquery/v9/providers-sdk/v1/upstream"
"go.mondoo.com/ranger-rpc"
"go.mondoo.com/ranger-rpc/plugins/scope"
)

type checkinPinger struct {
ctx context.Context
interval time.Duration
quit chan struct{}
wg sync.WaitGroup
endpoint string
httpClient *http.Client
mrn string
creds *upstream.ServiceAccountCredentials
}

func NewCheckinPinger(ctx context.Context, httpClient *http.Client, endpoint string, config *upstream.UpstreamConfig, interval time.Duration) *checkinPinger {
return &checkinPinger{
ctx: ctx,
interval: interval,
quit: make(chan struct{}),
endpoint: endpoint,
httpClient: httpClient,
mrn: config.Creds.Mrn,
creds: config.Creds,
}
}

func (c *checkinPinger) Start() {
// determine information about the client
sysInfo, err := sysinfo.GatherSystemInfo()
if err != nil {
log.Error().Err(err).Msg("could not gather client information")
return
}
c.wg.Add(1)
runCheckIn := func() {
err := c.checkIn(sysInfo)
if err != nil {
log.Info().Err(err).Msg("could not perform check-in")
}
}

// run check-in once on startup
runCheckIn()

jitter := time.Duration(rand.Int63n(int64(c.interval)))
ticker := time.NewTicker(c.interval + jitter)
go func() {
defer c.wg.Done()
for {
select {
case <-ticker.C:
runCheckIn()
case <-c.quit:
ticker.Stop()
return
}
}
}()
}

func (c *checkinPinger) Stop() {
close(c.quit)
c.wg.Wait()
}

func (c *checkinPinger) checkIn(sysInfo *sysinfo.SystemInfo) error {
// gather service account
plugins := []ranger.ClientPlugin{}
plugins = append(plugins, sysInfoHeader(sysInfo, cnquery.DefaultFeatures))

credentials := c.creds
if credentials != nil && len(credentials.Mrn) > 0 {
certAuth, err := upstream.NewServiceAccountRangerPlugin(credentials)
if err != nil {
return errors.Wrap(err, "invalid credentials")
}
plugins = append(plugins, certAuth)
} else {
return errors.New("no credentials configured")
}

client, err := upstream.NewAgentManagerClient(c.endpoint, c.httpClient, plugins...)
if err != nil {
return errors.Wrap(err, "could not connect to mondoo platform")
}

name := viper.GetString("name")
if name == "" {
name = sysInfo.Hostname
}

_, err = client.HealthCheck(context.Background(), &upstream.AgentInfo{
Mrn: c.mrn,
Version: sysInfo.Version,
Build: sysInfo.Build,
PlatformName: sysInfo.Platform.Name,
PlatformRelease: sysInfo.Platform.Version,
PlatformArch: sysInfo.Platform.Arch,
PlatformIp: sysInfo.IP,
PlatformHostname: sysInfo.Hostname,
Labels: nil,
PlatformId: sysInfo.PlatformId,
})

if err != nil {
return errors.Wrap(err, "failed to check in upstream")
}

return nil
}

func sysInfoHeader(sysInfo *sysinfo.SystemInfo, features cnquery.Features) ranger.ClientPlugin {
const (
HttpHeaderUserAgent = "User-Agent"
HttpHeaderClientFeatures = "Mondoo-Features"
HttpHeaderPlatformID = "Mondoo-PlatformID"
)

h := http.Header{}
info := map[string]string{
"cnquery": cnquery.Version,
"build": cnquery.Build,
}
if sysInfo != nil {
info["PN"] = sysInfo.Platform.Name
info["PR"] = sysInfo.Platform.Version
info["PA"] = sysInfo.Platform.Arch
info["IP"] = sysInfo.IP
info["HN"] = sysInfo.Hostname
h.Set(HttpHeaderPlatformID, sysInfo.PlatformId)
}
h.Set(HttpHeaderUserAgent, scope.XInfoHeader(info))
h.Set(HttpHeaderClientFeatures, features.Encode())
return scope.NewCustomHeaderRangerPlugin(h)
}
5 changes: 3 additions & 2 deletions apps/cnspec/cmd/backgroundjob/healthping.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ package backgroundjob

import (
"context"
"math/rand"
"net/http"
"sync"
"time"
Expand Down Expand Up @@ -44,8 +45,8 @@ func (h *healthPinger) Start() {
// run health check once on startup
runHealthCheck()

// TODO we may want to add jitter and backoff
healthTicker := time.NewTicker(h.interval)
jitter := time.Duration(rand.Int63n(int64(h.interval)))
healthTicker := time.NewTicker(h.interval + jitter)
go func() {
defer h.wg.Done()
for {
Expand Down
4 changes: 4 additions & 0 deletions apps/cnspec/cmd/serve.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,10 @@ var serveCmd = &cobra.Command{
hc := backgroundjob.NewHealthPinger(ctx, client.HttpClient, client.ApiEndpoint, 5*time.Minute)
hc.Start()
defer hc.Stop()

checkin := backgroundjob.NewCheckinPinger(ctx, client.HttpClient, client.ApiEndpoint, conf.runtime.UpstreamConfig, 2*time.Hour)
checkin.Start()
defer checkin.Stop()
}

bj, err := backgroundjob.New()
Expand Down
2 changes: 2 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ require (
sigs.k8s.io/yaml v1.3.0
)

require go.mondoo.com/cnquery/v9 v9.4.1-0.20231030152550-5d25283b8f03

require (
4d63.com/gocheckcompilerdirectives v1.2.1 // indirect
cloud.google.com/go/storage v1.33.0 // indirect
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -951,6 +951,8 @@ go-simpler.org/assert v0.6.0 h1:QxSrXa4oRuo/1eHMXSBFHKvJIpWABayzKldqZyugG7E=
go-simpler.org/assert v0.6.0/go.mod h1:74Eqh5eI6vCK6Y5l3PI8ZYFXG4Sa+tkr70OIPJAUr28=
go-simpler.org/sloglint v0.2.0 h1:XpOhA+7BCQJnl7KlDLmnFUFTSrl989ZmaVPSWWCWEtc=
go-simpler.org/sloglint v0.2.0/go.mod h1:/RQr0TeTf89IyRjLJ9ogUbIp1Zs5zJJAj02pwQoDQdg=
go.mondoo.com/cnquery/v9 v9.4.0 h1:VgI8bhSA/HAIBJwL5ABpbYDst8+uZy6WC/t7tt3+Xv8=
go.mondoo.com/cnquery/v9 v9.4.0/go.mod h1:ciOp7VYpkgOdUVKukPFBSwbAZJN/a+V2GrSmy620UkQ=
go.mondoo.com/cnquery/v9 v9.4.1-0.20231030152550-5d25283b8f03 h1:f6bc01UViozGSTiNumDAcJE36WoFkvB4qFuS0flSe6c=
go.mondoo.com/cnquery/v9 v9.4.1-0.20231030152550-5d25283b8f03/go.mod h1:ciOp7VYpkgOdUVKukPFBSwbAZJN/a+V2GrSmy620UkQ=
go.mondoo.com/ranger-rpc v0.5.2 h1:UrcVtMIinzfWsuSzZKibbMqcGZSARInKJi0Xs2AxXeU=
Expand Down

0 comments on commit 914f534

Please sign in to comment.