Automatic install policies in ListHostSoftware (#31469)
Fixes #30197 # Checklist for submitter - [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/guides/committing-changes.md#changes-files) for more information. ## Testing - [x] Added/updated automated tests - [x] QA'd all new/changed functionality manually
This commit is contained in:
@@ -0,0 +1 @@
|
||||
* Added automatic install policies into host software responses
|
||||
@@ -3792,8 +3792,10 @@ func (ds *Datastore) ListHostSoftware(ctx context.Context, host *fleet.Host, opt
|
||||
}
|
||||
|
||||
var vppAdamIDs []string
|
||||
for key := range byVPPAdamID {
|
||||
var vppTitleIds []uint
|
||||
for key, v := range byVPPAdamID {
|
||||
vppAdamIDs = append(vppAdamIDs, key)
|
||||
vppTitleIds = append(vppTitleIds, v.ID)
|
||||
}
|
||||
|
||||
var titleCount uint
|
||||
@@ -4126,6 +4128,17 @@ func (ds *Datastore) ListHostSoftware(ctx context.Context, host *fleet.Host, opt
|
||||
vulnerabilitiesBySoftwareID[cve.SoftwareID] = append(vulnerabilitiesBySoftwareID[cve.SoftwareID], cve.CVE)
|
||||
}
|
||||
|
||||
// Grab the automatic install policies, if any exist
|
||||
policies, err := ds.getPoliciesBySoftwareTitleIDs(ctx, append(vppTitleIds, softwareTitleIds...), host.TeamID)
|
||||
if err != nil {
|
||||
return nil, nil, ctxerr.Wrap(ctx, err, "batch getting policies by software title IDs")
|
||||
}
|
||||
|
||||
policiesBySoftwareTitleId := make(map[uint][]fleet.AutomaticInstallPolicy, len(policies))
|
||||
for _, p := range policies {
|
||||
policiesBySoftwareTitleId[p.TitleID] = append(policiesBySoftwareTitleId[p.TitleID], p)
|
||||
}
|
||||
|
||||
indexOfSoftwareTitle := make(map[uint]uint)
|
||||
deduplicatedList := make([]*hostSoftware, 0, len(hostSoftwareList))
|
||||
for _, softwareTitleRecord := range hostSoftwareList {
|
||||
@@ -4268,6 +4281,14 @@ func (ds *Datastore) ListHostSoftware(ctx context.Context, host *fleet.Host, opt
|
||||
}
|
||||
}
|
||||
|
||||
if policies, ok := policiesBySoftwareTitleId[softwareTitleRecord.ID]; ok {
|
||||
if softwareTitleRecord.AppStoreApp != nil {
|
||||
softwareTitleRecord.AppStoreApp.AutomaticInstallPolicies = policies
|
||||
} else {
|
||||
softwareTitleRecord.SoftwarePackage.AutomaticInstallPolicies = policies
|
||||
}
|
||||
}
|
||||
|
||||
if _, ok := indexOfSoftwareTitle[softwareTitleRecord.ID]; !ok {
|
||||
indexOfSoftwareTitle[softwareTitleRecord.ID] = uint(len(deduplicatedList))
|
||||
deduplicatedList = append(deduplicatedList, softwareTitleRecord)
|
||||
|
||||
@@ -3702,6 +3702,13 @@ func testListHostSoftware(t *testing.T, ds *Datastore) {
|
||||
assert.Equal(t, e.SoftwarePackage.LastUninstall.ExecutionID, g.SoftwarePackage.LastUninstall.ExecutionID)
|
||||
assert.NotNil(t, g.SoftwarePackage.LastUninstall.UninstalledAt)
|
||||
}
|
||||
if e.SoftwarePackage.AutomaticInstallPolicies != nil {
|
||||
require.Len(t, e.SoftwarePackage.AutomaticInstallPolicies, len(g.SoftwarePackage.AutomaticInstallPolicies))
|
||||
for i, p := range e.SoftwarePackage.AutomaticInstallPolicies {
|
||||
require.Equal(t, p.ID, g.SoftwarePackage.AutomaticInstallPolicies[i].ID)
|
||||
require.Equal(t, p.Name, g.SoftwarePackage.AutomaticInstallPolicies[i].Name)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if e.AppStoreApp != nil {
|
||||
@@ -3716,6 +3723,13 @@ func testListHostSoftware(t *testing.T, ds *Datastore) {
|
||||
require.Equal(t, e.AppStoreApp.LastInstall.CommandUUID, g.AppStoreApp.LastInstall.CommandUUID)
|
||||
require.NotNil(t, g.AppStoreApp.LastInstall.InstalledAt)
|
||||
}
|
||||
if e.AppStoreApp.AutomaticInstallPolicies != nil {
|
||||
require.Len(t, e.AppStoreApp.AutomaticInstallPolicies, len(g.AppStoreApp.AutomaticInstallPolicies))
|
||||
for i, p := range e.AppStoreApp.AutomaticInstallPolicies {
|
||||
require.Equal(t, p.ID, g.AppStoreApp.AutomaticInstallPolicies[i].ID)
|
||||
require.Equal(t, p.Name, g.AppStoreApp.AutomaticInstallPolicies[i].Name)
|
||||
}
|
||||
}
|
||||
}
|
||||
// require.Equal(t, e.SoftwarePackage, g.SoftwarePackage)
|
||||
// require.Equal(t, e.AppStoreApp, g.AppStoreApp)
|
||||
@@ -4220,6 +4234,33 @@ func testListHostSoftware(t *testing.T, ds *Datastore) {
|
||||
i3.Name + i3.Source: expected[i3.Name+i3.Source],
|
||||
}, sw, true)
|
||||
|
||||
// add policies to software
|
||||
policy1 := newTestPolicy(t, ds, user, "policy 1", "darwin", &tm.ID)
|
||||
policy1.SoftwareInstallerID = ptr.Uint(swi5Tm)
|
||||
err = ds.SavePolicy(context.Background(), policy1, false, false)
|
||||
require.NoError(t, err)
|
||||
policy2 := newTestPolicy(t, ds, user, "policy 2", "darwin", &tm.ID)
|
||||
policy2.SoftwareInstallerID = ptr.Uint(swi5Tm)
|
||||
err = ds.SavePolicy(context.Background(), policy2, false, false)
|
||||
require.NoError(t, err)
|
||||
sw, meta, err = ds.ListHostSoftware(ctx, tmHost, opts)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, &fleet.PaginationMetadata{TotalResults: 1}, meta)
|
||||
expectedWithPolicies := map[string]fleet.HostSoftwareWithInstaller{
|
||||
i3.Name + i3.Source: expected[i3.Name+i3.Source],
|
||||
}
|
||||
expectedWithPolicies[i3.Name+i3.Source].SoftwarePackage.AutomaticInstallPolicies = []fleet.AutomaticInstallPolicy{
|
||||
{
|
||||
ID: policy1.ID,
|
||||
Name: policy1.Name,
|
||||
},
|
||||
{
|
||||
ID: policy2.ID,
|
||||
Name: policy2.Name,
|
||||
},
|
||||
}
|
||||
compareResults(expectedWithPolicies, sw, true)
|
||||
|
||||
// test with a search query (searches on name), with and without available software
|
||||
opts.ListOptions.MatchQuery = "a"
|
||||
opts.IncludeAvailableForInstall = false
|
||||
@@ -4260,7 +4301,7 @@ func testListHostSoftware(t *testing.T, ds *Datastore) {
|
||||
BundleIdentifier: "com.app.vpp1",
|
||||
}, nil)
|
||||
require.NoError(t, err)
|
||||
_, err = ds.InsertVPPAppWithTeam(ctx,
|
||||
vatm1, err := ds.InsertVPPAppWithTeam(ctx,
|
||||
&fleet.VPPApp{
|
||||
VPPAppTeam: fleet.VPPAppTeam{VPPAppID: fleet.VPPAppID{AdamID: "adam_vpp_1", Platform: fleet.MacOSPlatform}}, Name: "vpp1",
|
||||
BundleIdentifier: "com.app.vpp1",
|
||||
@@ -4303,6 +4344,20 @@ func testListHostSoftware(t *testing.T, ds *Datastore) {
|
||||
vpp1TmCmdUUID := createVPPAppInstallRequest(t, ds, tmHost, vpp1, user)
|
||||
require.NotEmpty(t, vpp1TmCmdUUID)
|
||||
|
||||
// add policies to vpp app 1
|
||||
va1FromDB, err := ds.GetVPPAppMetadataByAdamIDPlatformTeamID(ctx, vatm1.AdamID, vatm1.Platform, &tm.ID)
|
||||
require.NoError(t, err)
|
||||
|
||||
policy3 := newTestPolicy(t, ds, user, "policy 3", "darwin", &tm.ID)
|
||||
policy3.VPPAppsTeamsID = &va1FromDB.AppTeamID
|
||||
err = ds.SavePolicy(context.Background(), policy3, false, false)
|
||||
require.NoError(t, err)
|
||||
|
||||
policy4 := newTestPolicy(t, ds, user, "policy 4", "darwin", &tm.ID)
|
||||
policy4.VPPAppsTeamsID = &va1FromDB.AppTeamID
|
||||
err = ds.SavePolicy(context.Background(), policy4, false, false)
|
||||
require.NoError(t, err)
|
||||
|
||||
opts.IncludeAvailableForInstall = false
|
||||
opts.ListOptions.MatchQuery = ""
|
||||
sw, meta, err = ds.ListHostSoftware(ctx, host, opts)
|
||||
@@ -4374,10 +4429,25 @@ func testListHostSoftware(t *testing.T, ds *Datastore) {
|
||||
compareResults(map[string]fleet.HostSoftwareWithInstaller{
|
||||
i3.Name + i3.Source: expected[i3.Name+i3.Source],
|
||||
"vpp1apps": {
|
||||
Name: "vpp1",
|
||||
Source: "apps",
|
||||
Status: expectStatus(fleet.SoftwareInstallPending),
|
||||
AppStoreApp: &fleet.SoftwarePackageOrApp{AppStoreID: vpp1, Platform: "darwin", SelfService: ptr.Bool(false), LastInstall: &fleet.HostSoftwareInstall{CommandUUID: vpp1TmCmdUUID}},
|
||||
Name: "vpp1",
|
||||
Source: "apps",
|
||||
Status: expectStatus(fleet.SoftwareInstallPending),
|
||||
AppStoreApp: &fleet.SoftwarePackageOrApp{
|
||||
AppStoreID: vpp1,
|
||||
Platform: "darwin",
|
||||
SelfService: ptr.Bool(false),
|
||||
LastInstall: &fleet.HostSoftwareInstall{CommandUUID: vpp1TmCmdUUID},
|
||||
AutomaticInstallPolicies: []fleet.AutomaticInstallPolicy{
|
||||
{
|
||||
ID: policy3.ID,
|
||||
Name: policy3.Name,
|
||||
},
|
||||
{
|
||||
ID: policy4.ID,
|
||||
Name: policy4.Name,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}, sw, true)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user