From 4ef883b3113da927b34d86accfd095c98a005ef0 Mon Sep 17 00:00:00 2001 From: Juan Fernandez Date: Thu, 15 Sep 2022 13:12:50 -0300 Subject: [PATCH] Feature 6946: Fleet Desktop should use minimal api end-point for data (#7536) Updated desktop client to use new EE desktop endpoint. --- changes/6946-fleet-desktop-uses-min-endpoint | 2 ++ orbit/cmd/desktop/desktop.go | 15 ++++--------- server/service/device_client.go | 21 +++++++++---------- server/service/device_client_test.go | 21 ++++++------------- server/service/devices.go | 13 ++++++------ server/service/integration_enterprise_test.go | 2 +- 6 files changed, 30 insertions(+), 44 deletions(-) create mode 100644 changes/6946-fleet-desktop-uses-min-endpoint diff --git a/changes/6946-fleet-desktop-uses-min-endpoint b/changes/6946-fleet-desktop-uses-min-endpoint new file mode 100644 index 0000000000..59ff4f2285 --- /dev/null +++ b/changes/6946-fleet-desktop-uses-min-endpoint @@ -0,0 +1,2 @@ +Updated Fleet Desktop to use the new endpoint introduced in +https://github.com/fleetdm/fleet/issues/7084 diff --git a/orbit/cmd/desktop/desktop.go b/orbit/cmd/desktop/desktop.go index e75908a02d..3cb9954d78 100644 --- a/orbit/cmd/desktop/desktop.go +++ b/orbit/cmd/desktop/desktop.go @@ -83,7 +83,7 @@ func main() { defer close(done) for { - _, err := client.ListDevicePolicies() + _, err := client.GetDesktopPayload() if err == nil || errors.Is(err, service.ErrMissingLicense) { myDeviceItem.SetTitle("My device") @@ -109,7 +109,7 @@ func main() { for { <-tic.C - policies, err := client.ListDevicePolicies() + res, err := client.GetDesktopPayload() switch { case err == nil: // OK @@ -121,15 +121,8 @@ func main() { continue } - failedPolicyCount := 0 - for _, policy := range policies { - if policy.Response != "pass" { - failedPolicyCount++ - } - } - - if failedPolicyCount > 0 { - myDeviceItem.SetTitle(fmt.Sprintf("🔴 My device (%d)", failedPolicyCount)) + if res.FailingPolicies != nil && *res.FailingPolicies > 0 { + myDeviceItem.SetTitle(fmt.Sprintf("🔴 My device (%d)", res.FailingPolicies)) } else { myDeviceItem.SetTitle("🟢 My device") } diff --git a/server/service/device_client.go b/server/service/device_client.go index 8dcac11e73..5865b3f47a 100644 --- a/server/service/device_client.go +++ b/server/service/device_client.go @@ -4,12 +4,9 @@ import ( "bytes" "fmt" "net/http" - - "github.com/fleetdm/fleet/v4/server/fleet" ) -// Device client is used to consume `/device/...` endpoints, -// and meant to be used by Fleet Desktop +// Device client is used consume the `device/...` endpoints and meant to be used by Fleet Desktop type DeviceClient struct { *baseClient token string @@ -35,7 +32,8 @@ func (dc *DeviceClient) request(verb string, path string, query string, response return dc.parseResponse(verb, path, response, responseDest) } -// NewDeviceClient instantiates a new client to perform requests against device endpoints +// NewDeviceClient instantiates a new client to perform requests against device +// endpoints func NewDeviceClient(addr, token string, insecureSkipVerify bool, rootCA string) (*DeviceClient, error) { baseClient, err := newBaseClient(addr, insecureSkipVerify, rootCA, "") if err != nil { @@ -48,13 +46,14 @@ func NewDeviceClient(addr, token string, insecureSkipVerify bool, rootCA string) }, nil } -// ListDevicePolicies fetches all policies for the device with the provided token -func (dc *DeviceClient) ListDevicePolicies() ([]*fleet.HostPolicy, error) { - verb, path := "GET", "/api/latest/fleet/device/"+dc.token+"/policies" - var responseBody listDevicePoliciesResponse - err := dc.request(verb, path, "", &responseBody) +// Get fetches payload used by Fleet Desktop. +func (dc *DeviceClient) GetDesktopPayload() (*FleetDesktopResponse, error) { + verb, path := "GET", "/api/latest/fleet/device/"+dc.token+"/desktop" + + var r FleetDesktopResponse + err := dc.request(verb, path, "", &r) if err != nil { return nil, err } - return responseBody.Policies, nil + return &r, nil } diff --git a/server/service/device_client_test.go b/server/service/device_client_test.go index 202edc89b2..c57c4d817b 100644 --- a/server/service/device_client_test.go +++ b/server/service/device_client_test.go @@ -28,7 +28,7 @@ func (m *mockHttpClient) Do(req *http.Request) (*http.Response, error) { return res, nil } -func TestDeviceClientListPolicies(t *testing.T) { +func TestDeviceClientGetDesktopPayload(t *testing.T) { client, err := NewDeviceClient("https://test.com", "test-token", true, "") require.NoError(t, err) @@ -37,24 +37,15 @@ func TestDeviceClientListPolicies(t *testing.T) { t.Run("with wrong license", func(t *testing.T) { mockRequestDoer.statusCode = http.StatusPaymentRequired - _, err = client.ListDevicePolicies() + _, err = client.GetDesktopPayload() require.ErrorIs(t, err, ErrMissingLicense) }) - t.Run("with empty policies", func(t *testing.T) { + t.Run("with failing policies", func(t *testing.T) { mockRequestDoer.statusCode = http.StatusOK - mockRequestDoer.resBody = `{"policies": []}` - policies, err := client.ListDevicePolicies() + mockRequestDoer.resBody = `{"failing_policies_count": 1}` + res, err := client.GetDesktopPayload() require.NoError(t, err) - require.Len(t, policies, 0) - }) - - t.Run("with policies", func(t *testing.T) { - mockRequestDoer.statusCode = http.StatusOK - mockRequestDoer.resBody = `{"policies": [{"id": 1}]}` - policies, err := client.ListDevicePolicies() - require.NoError(t, err) - require.Len(t, policies, 1) - require.Equal(t, uint(1), policies[0].ID) + require.Equal(t, uint(1), *res.FailingPolicies) }) } diff --git a/server/service/devices.go b/server/service/devices.go index 5bc3e88bfa..6afbdfe275 100644 --- a/server/service/devices.go +++ b/server/service/devices.go @@ -9,10 +9,11 @@ import ( "github.com/fleetdm/fleet/v4/server/fleet" ) -// /////////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////////// // Fleet Desktop endpoints -// /////////////////////////////////////////////////////////////////////////////// -type getFleetDesktopResponse struct { +///////////////////////////////////////////////////////////////////////////////// + +type FleetDesktopResponse struct { Err error `json:"error,omitempty"` FailingPolicies *uint `json:"failing_policies_count,omitempty"` } @@ -32,15 +33,15 @@ func getFleetDesktopEndpoint(ctx context.Context, request interface{}, svc fleet if !ok { err := ctxerr.Wrap(ctx, fleet.NewAuthRequiredError("internal error: missing host from request context")) - return getFleetDesktopResponse{Err: err}, nil + return FleetDesktopResponse{Err: err}, nil } r, err := svc.FailingPoliciesCount(ctx, host) if err != nil { - return getFleetDesktopResponse{Err: err}, nil + return FleetDesktopResponse{Err: err}, nil } - return getFleetDesktopResponse{FailingPolicies: &r}, nil + return FleetDesktopResponse{FailingPolicies: &r}, nil } ///////////////////////////////////////////////////////////////////////////////// diff --git a/server/service/integration_enterprise_test.go b/server/service/integration_enterprise_test.go index 4ec5652cfa..fbae4ded4b 100644 --- a/server/service/integration_enterprise_test.go +++ b/server/service/integration_enterprise_test.go @@ -1168,7 +1168,7 @@ func (s *integrationEnterpriseTestSuite) TestListDevicePolicies() { require.Len(t, *getDeviceHostResp.Host.Policies, 2) // GET `/api/_version_/fleet/device/{token}/desktop` - getDesktopResp := getFleetDesktopResponse{} + getDesktopResp := FleetDesktopResponse{} res = s.DoRawNoAuth("GET", "/api/latest/fleet/device/"+token+"/desktop", nil, http.StatusOK) json.NewDecoder(res.Body).Decode(&getDesktopResp) res.Body.Close()