Feature 6946: Fleet Desktop should use minimal api end-point for data (#7536)

Updated desktop client to use new EE desktop endpoint.
This commit is contained in:
Juan Fernandez 2022-09-15 13:12:50 -03:00 committed by GitHub
parent 7a5663bebf
commit 4ef883b311
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 30 additions and 44 deletions

View file

@ -0,0 +1,2 @@
Updated Fleet Desktop to use the new endpoint introduced in
https://github.com/fleetdm/fleet/issues/7084

View file

@ -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")
}

View file

@ -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
}

View file

@ -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)
})
}

View file

@ -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
}
/////////////////////////////////////////////////////////////////////////////////

View file

@ -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()