From 18671eba946ecd66438ea1e28e3b5fdfb891d39d Mon Sep 17 00:00:00 2001 From: Lucas Manuel Rodriguez Date: Mon, 18 May 2026 14:06:38 -0300 Subject: [PATCH] Move `HostDetailResponse` type to `server/fleet/` (#45718) Resolves #45220 (one of several PRs). ## Testing - [x] QA'd all new/changed functionality manually ## Summary by CodeRabbit * **Refactor** * Consolidated and standardized host detail response handling across server and CLI, aligning host/device and MDM flows for more consistent behavior. * **Tests** * Updated integration tests to reflect the standardized host detail response format. [![Review Change Stack](https://storage.googleapis.com/coderabbit_public_assets/review-stack-in-coderabbit-ui.svg)](https://app.coderabbit.ai/change-stack/fleetdm/fleet/pull/45718?utm_source=github_walkthrough&utm_medium=github&utm_campaign=change_stack) --- cmd/fleetctl/fleetctl/get.go | 2 +- cmd/fleetctl/fleetctl/mdm.go | 2 +- server/fleet/hostresponse.go | 10 ++++++++++ server/service/client_hosts.go | 4 ++-- server/service/devices.go | 16 ++++++++-------- server/service/hosts.go | 18 ++++-------------- server/service/integration_core_test.go | 4 ++-- 7 files changed, 28 insertions(+), 28 deletions(-) diff --git a/cmd/fleetctl/fleetctl/get.go b/cmd/fleetctl/fleetctl/get.go index d4120a39bf..2fd57abe8f 100644 --- a/cmd/fleetctl/fleetctl/get.go +++ b/cmd/fleetctl/fleetctl/get.go @@ -160,7 +160,7 @@ func printHost(c *cli.Context, host *fleet.HostResponse) error { return printSpec(c, spec) } -func printHostDetail(c *cli.Context, host *service.HostDetailResponse) error { +func printHostDetail(c *cli.Context, host *fleet.HostDetailResponse) error { spec := specGeneric{ Kind: fleet.HostKind, Version: fleet.ApiVersion, diff --git a/cmd/fleetctl/fleetctl/mdm.go b/cmd/fleetctl/fleetctl/mdm.go index 8869db93b2..aaad917646 100644 --- a/cmd/fleetctl/fleetctl/mdm.go +++ b/cmd/fleetctl/fleetctl/mdm.go @@ -285,7 +285,7 @@ fleetctl get host %s`, hostIdent) // Does some common setup for the host mdm actions such as validating the host, // creating the client, getting the desired host, checking permissions, and // ensuring MDM is turned on for the host. -func hostMdmActionSetup(c *cli.Context, hostIdent string, actionType string) (client *service.Client, host *service.HostDetailResponse, err error) { +func hostMdmActionSetup(c *cli.Context, hostIdent string, actionType string) (client *service.Client, host *fleet.HostDetailResponse, err error) { if len(hostIdent) == 0 { return nil, nil, errors.New("No host targeted. Please provide --host.") } diff --git a/server/fleet/hostresponse.go b/server/fleet/hostresponse.go index ca5808149c..85e345d365 100644 --- a/server/fleet/hostresponse.go +++ b/server/fleet/hostresponse.go @@ -48,3 +48,13 @@ func HostResponsesForHostsCheap(hosts []Host) []HostResponse { } return hrs } + +// HostDetailResponse is the response struct that contains the full host information +// with the HostDetail details. +type HostDetailResponse struct { + HostDetail + Status HostStatus `json:"status"` + DisplayText string `json:"display_text"` + DisplayName string `json:"display_name"` + Geolocation *GeoLocation `json:"geolocation,omitempty"` +} diff --git a/server/service/client_hosts.go b/server/service/client_hosts.go index cc2e7ab506..b1841ebd38 100644 --- a/server/service/client_hosts.go +++ b/server/service/client_hosts.go @@ -17,7 +17,7 @@ func (c *Client) GetHosts(query string) ([]fleet.HostResponse, error) { return responseBody.Hosts, err } -func (c *Client) GetHost(id uint) (*HostDetailResponse, error) { +func (c *Client) GetHost(id uint) (*fleet.HostDetailResponse, error) { verb, path := "GET", fmt.Sprintf("/api/latest/fleet/hosts/%d", id) var responseBody getHostResponse err := c.authenticatedRequest(nil, verb, path, &responseBody) @@ -26,7 +26,7 @@ func (c *Client) GetHost(id uint) (*HostDetailResponse, error) { // HostByIdentifier retrieves a host by the uuid, osquery_host_id, hostname, or // node_key. -func (c *Client) HostByIdentifier(identifier string) (*HostDetailResponse, error) { +func (c *Client) HostByIdentifier(identifier string) (*fleet.HostDetailResponse, error) { verb, path := "GET", "/api/latest/fleet/hosts/identifier/"+identifier var responseBody getHostResponse err := c.authenticatedRequest(nil, verb, path, &responseBody) diff --git a/server/service/devices.go b/server/service/devices.go index c66c1c119a..d3370d6aea 100644 --- a/server/service/devices.go +++ b/server/service/devices.go @@ -108,14 +108,14 @@ func (r *getDeviceHostRequest) deviceAuthToken() string { } type getDeviceHostResponse struct { - Host *HostDetailResponse `json:"host"` - SelfService bool `json:"self_service"` - OrgLogoURL string `json:"org_logo_url"` - OrgLogoURLLightBackground string `json:"org_logo_url_light_background"` - OrgContactURL string `json:"org_contact_url"` - Err error `json:"error,omitempty"` - License fleet.LicenseInfo `json:"license"` - GlobalConfig fleet.DeviceGlobalConfig `json:"global_config"` + Host *fleet.HostDetailResponse `json:"host"` + SelfService bool `json:"self_service"` + OrgLogoURL string `json:"org_logo_url"` + OrgLogoURLLightBackground string `json:"org_logo_url_light_background"` + OrgContactURL string `json:"org_contact_url"` + Err error `json:"error,omitempty"` + License fleet.LicenseInfo `json:"license"` + GlobalConfig fleet.DeviceGlobalConfig `json:"global_config"` } func (r getDeviceHostResponse) Error() error { return r.Err } diff --git a/server/service/hosts.go b/server/service/hosts.go index 434a238744..fe210e7399 100644 --- a/server/service/hosts.go +++ b/server/service/hosts.go @@ -40,17 +40,7 @@ import ( "github.com/google/uuid" ) -// HostDetailResponse is the response struct that contains the full host information -// with the HostDetail details. -type HostDetailResponse struct { - fleet.HostDetail - Status fleet.HostStatus `json:"status"` - DisplayText string `json:"display_text"` - DisplayName string `json:"display_name"` - Geolocation *fleet.GeoLocation `json:"geolocation,omitempty"` -} - -func hostDetailResponseForHost(ctx context.Context, svc fleet.Service, host *fleet.HostDetail) (*HostDetailResponse, error) { +func hostDetailResponseForHost(ctx context.Context, svc fleet.Service, host *fleet.HostDetail) (*fleet.HostDetailResponse, error) { var isADEEnrolledIDevice bool if host.Platform == "ipados" || host.Platform == "ios" { ac, err := svc.AppConfigObfuscated(ctx) @@ -82,7 +72,7 @@ func hostDetailResponseForHost(ctx context.Context, svc fleet.Service, host *fle geoLoc = svc.LookupGeoIP(ctx, host.PublicIP) } - return &HostDetailResponse{ + return &fleet.HostDetailResponse{ HostDetail: *host, Status: host.Status(time.Now()), DisplayText: host.Hostname, @@ -833,8 +823,8 @@ type getHostRequest struct { } type getHostResponse struct { - Host *HostDetailResponse `json:"host"` - Err error `json:"error,omitempty"` + Host *fleet.HostDetailResponse `json:"host"` + Err error `json:"error,omitempty"` } func (r getHostResponse) Error() error { return r.Err } diff --git a/server/service/integration_core_test.go b/server/service/integration_core_test.go index 44f1aaf546..ee7809890a 100644 --- a/server/service/integration_core_test.go +++ b/server/service/integration_core_test.go @@ -3728,8 +3728,8 @@ func (s *integrationTestSuite) TestHostDetailsPolicies() { b, err := io.ReadAll(resp.Body) require.NoError(t, err) var r struct { - Host *HostDetailResponse `json:"host"` - Err error `json:"error,omitempty"` + Host *fleet.HostDetailResponse `json:"host"` + Err error `json:"error,omitempty"` } err = json.Unmarshal(b, &r) require.NoError(t, err)