mirror of
https://github.com/fleetdm/fleet
synced 2026-05-13 12:09:19 +00:00
#22069 API changes: https://github.com/fleetdm/fleet/pull/22259 QAd by applying 10 pieces of software on a team, which took 3+ minutes in total (which, before these changes was timing out at 100s.) With this approach, a GitOps CI run timing out might leave the background process running (which will eventually be applied to the database). The team discussed and agreed that we can fix this edge case later. - [X] Changes file added for user-visible changes in `changes/`, `orbit/changes/` or `ee/fleetd-chrome/changes`. See [Changes files](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/Committing-Changes.md#changes-files) for more information. - [X] Input data is properly validated, `SELECT *` is avoided, SQL injection is prevented (using placeholders for values in statements) - [X] Added/updated tests - [X] Manual QA for all new/changed functionality
69 lines
2.4 KiB
Go
69 lines
2.4 KiB
Go
package service
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"net/url"
|
|
"time"
|
|
|
|
"github.com/fleetdm/fleet/v4/server/fleet"
|
|
)
|
|
|
|
// ListSoftwareVersions retrieves the software versions installed on hosts.
|
|
func (c *Client) ListSoftwareVersions(query string) ([]fleet.Software, error) {
|
|
verb, path := "GET", "/api/latest/fleet/software/versions"
|
|
var responseBody listSoftwareVersionsResponse
|
|
err := c.authenticatedRequestWithQuery(nil, verb, path, &responseBody, query)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return responseBody.Software, nil
|
|
}
|
|
|
|
// ListSoftwareTitles retrieves the software titles installed on hosts.
|
|
func (c *Client) ListSoftwareTitles(query string) ([]fleet.SoftwareTitleListResult, error) {
|
|
verb, path := "GET", "/api/latest/fleet/software/titles"
|
|
var responseBody listSoftwareTitlesResponse
|
|
err := c.authenticatedRequestWithQuery(nil, verb, path, &responseBody, query)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return responseBody.SoftwareTitles, nil
|
|
}
|
|
|
|
func (c *Client) ApplyNoTeamSoftwareInstallers(softwareInstallers []fleet.SoftwareInstallerPayload, opts fleet.ApplySpecOptions) ([]fleet.SoftwarePackageResponse, error) {
|
|
query, err := url.ParseQuery(opts.RawQuery())
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return c.applySoftwareInstallers(softwareInstallers, query, opts.DryRun)
|
|
}
|
|
|
|
func (c *Client) applySoftwareInstallers(softwareInstallers []fleet.SoftwareInstallerPayload, query url.Values, dryRun bool) ([]fleet.SoftwarePackageResponse, error) {
|
|
path := "/api/latest/fleet/software/batch"
|
|
var resp batchSetSoftwareInstallersResponse
|
|
if err := c.authenticatedRequestWithQuery(map[string]interface{}{"software": softwareInstallers}, "POST", path, &resp, query.Encode()); err != nil {
|
|
return nil, err
|
|
}
|
|
if dryRun && resp.RequestUUID == "" {
|
|
return nil, nil
|
|
}
|
|
|
|
requestUUID := resp.RequestUUID
|
|
for {
|
|
var resp batchSetSoftwareInstallersResultResponse
|
|
if err := c.authenticatedRequestWithQuery(nil, "GET", path+"/"+requestUUID, &resp, query.Encode()); err != nil {
|
|
return nil, err
|
|
}
|
|
switch {
|
|
case resp.Status == fleet.BatchSetSoftwareInstallersStatusProcessing:
|
|
time.Sleep(5 * time.Second)
|
|
case resp.Status == fleet.BatchSetSoftwareInstallersStatusFailed:
|
|
return nil, errors.New(resp.Message)
|
|
case resp.Status == fleet.BatchSetSoftwareInstallersStatusCompleted:
|
|
return resp.Packages, nil
|
|
default:
|
|
return nil, fmt.Errorf("unknown status: %q", resp.Status)
|
|
}
|
|
}
|
|
}
|