Skip to content

Commit

Permalink
controlplane-cli: dump kolide cache
Browse files Browse the repository at this point in the history
Co-authored-by: Thomas Krampl <[email protected]>
  • Loading branch information
sechmann and thokra-nav committed Jun 10, 2024
1 parent e5b39ed commit fbc1372
Show file tree
Hide file tree
Showing 11 changed files with 636 additions and 244 deletions.
12 changes: 12 additions & 0 deletions cmd/controlplane-cli/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,18 @@ func main() {
},
Action: controlplanecli.HashPassword,
},
{
Name: "kolide",
Aliases: []string{"k"},
Usage: "kolide cache",
Subcommands: []*cli.Command{
{
Name: "dump",
Usage: "dump kolide cache",
Action: controlplanecli.GetKolideCache,
},
},
},
{
Name: "session",
Aliases: []string{"s"},
Expand Down
22 changes: 22 additions & 0 deletions internal/apiserver/api/admin.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,3 +81,25 @@ func (s *grpcServer) GetSessions(ctx context.Context, r *pb.GetSessionsRequest)
Sessions: s.sessionStore.All(),
}, nil
}

func (s *grpcServer) GetKolideCache(ctx context.Context, r *pb.GetKolideCacheRequest) (*pb.GetKolideCacheResponse, error) {
err := s.adminAuth.Authenticate(r.GetUsername(), r.GetPassword())
if err != nil {
return nil, status.Errorf(codes.Unauthenticated, err.Error())
}

devices, err := s.kolideClient.DumpDevices()
if err != nil {
return nil, err
}

checks, err := s.kolideClient.DumpChecks()
if err != nil {
return nil, err
}

return &pb.GetKolideCacheResponse{
RawDevices: devices,
RawChecks: checks,
}, nil
}
14 changes: 13 additions & 1 deletion internal/apiserver/kolide/cache.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package kolide

import "sync"
import (
"encoding/json"
"sync"
)

type Cache[K comparable, V any] struct {
mutex sync.RWMutex
Expand All @@ -17,6 +20,9 @@ func (c *Cache[K, V]) Get(key K) (V, bool) {
func (c *Cache[K, V]) Set(key K, value V) {
c.mutex.Lock()
defer c.mutex.Unlock()
if c.cache == nil {
c.cache = make(map[K]V)
}
c.cache[key] = value
}

Expand All @@ -25,3 +31,9 @@ func (c *Cache[K, V]) Replace(cache map[K]V) {
defer c.mutex.Unlock()
c.cache = cache
}

func (c *Cache[K, V]) MarshalJSON() ([]byte, error) {
c.mutex.RLock()
defer c.mutex.RUnlock()
return json.Marshal(c.cache)
}
22 changes: 22 additions & 0 deletions internal/apiserver/kolide/cache_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package kolide_test

import (
"encoding/json"
"testing"

"github.com/nais/device/internal/apiserver/kolide"
"github.com/stretchr/testify/assert"
)

func TestJSONMarshal(t *testing.T) {
c := &kolide.Cache[string, string]{}

val, ok := c.Get("key")
assert.False(t, ok)
assert.Equal(t, "", val)

c.Set("key", "value")
actual, err := json.Marshal(c)
assert.NoError(t, err)
assert.Equal(t, `{"key":"value"}`, string(actual))
}
10 changes: 10 additions & 0 deletions internal/apiserver/kolide/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ import (
type Client interface {
RefreshCache(ctx context.Context) error
GetDevice(ctx context.Context, email, platform, serial string) (Device, error)
DumpDevices() ([]byte, error)
DumpChecks() ([]byte, error)
}

type client struct {
Expand Down Expand Up @@ -235,3 +237,11 @@ func (kc *client) get(ctx context.Context, url string) (*http.Response, error) {

return kc.client.Do(req)
}

func (kc client) DumpDevices() ([]byte, error) {
return json.Marshal(kc.devices)
}

func (kc client) DumpChecks() ([]byte, error) {
return json.Marshal(kc.checks)
}
10 changes: 10 additions & 0 deletions internal/apiserver/kolide/fakeclient.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,3 +45,13 @@ func (f *FakeClient) RefreshCache(ctx context.Context) error {
// no-op
return nil
}

// DumpChecks implements Client.
func (f *FakeClient) DumpChecks() ([]byte, error) {
panic("unimplemented")
}

// DumpDevices implements Client.
func (f *FakeClient) DumpDevices() ([]byte, error) {
panic("unimplemented")
}
41 changes: 41 additions & 0 deletions internal/controlplane-cli/kolide.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package controlplanecli

import (
"encoding/json"
"os"

"github.com/nais/device/internal/pb"
"github.com/urfave/cli/v2"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials/insecure"
)

func GetKolideCache(c *cli.Context) error {
conn, err := grpc.DialContext(
c.Context,
c.String(FlagAPIServer),
grpc.WithTransportCredentials(insecure.NewCredentials()),
)
if err != nil {
return err
}

client := pb.NewAPIServerClient(conn)
resp, err := client.GetKolideCache(c.Context, &pb.GetKolideCacheRequest{
Username: AdminUsername,
Password: c.String(FlagAdminPassword),
})
if err != nil {
return err
}

out := struct {
Devices json.RawMessage
Checks json.RawMessage
}{
Devices: resp.RawDevices,
Checks: resp.RawChecks,
}

return json.NewEncoder(os.Stdout).Encode(out)
}
74 changes: 74 additions & 0 deletions internal/pb/mock_api_server_client.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit fbc1372

Please sign in to comment.