VPP: unify List host's software and List my device's software response payload (#20519)
This commit is contained in:
@@ -3,7 +3,6 @@ package mysql
|
||||
import (
|
||||
"context"
|
||||
"crypto/md5" //nolint:gosec // This hash is used as a DB optimization for software row lookup, not security
|
||||
"database/sql"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"sort"
|
||||
@@ -2050,12 +2049,12 @@ AND EXISTS (SELECT 1 FROM software s JOIN software_cve scve ON scve.software_id
|
||||
st.source,
|
||||
-- will be NULL for VPP apps for now, self-service not supported yet
|
||||
si.self_service as self_service,
|
||||
-- we want that field to be empty string for VPP apps, the filename for installers,
|
||||
-- and NULL otherwise.
|
||||
CASE WHEN vap.adam_id IS NOT NULL THEN '' ELSE si.filename END as package_available_for_install,
|
||||
-- we don't store VPP app information in the package sub-object at the moment,
|
||||
-- only software installer information
|
||||
-- this count will be 1 if an installer or VPP app is available, 0 otherwise
|
||||
IF(COALESCE(si.id, vap.adam_id) IS NOT NULL, 1, 0) as available_for_install,
|
||||
si.filename as package_name,
|
||||
si.version as package_version,
|
||||
vap.adam_id as vpp_app_adam_id,
|
||||
vap.latest_version as vpp_app_version,
|
||||
COALESCE(hsi.created_at, hvsi.created_at) as last_install_installed_at,
|
||||
COALESCE(hsi.execution_id, hvsi.command_uuid) as last_install_install_uuid,
|
||||
-- get either the softare installer status or the vpp app status
|
||||
@@ -2070,7 +2069,7 @@ AND EXISTS (SELECT 1 FROM software s JOIN software_cve scve ON scve.software_id
|
||||
vpp_apps vap ON st.id = vap.title_id
|
||||
LEFT OUTER JOIN
|
||||
host_vpp_software_installs hvsi ON vap.adam_id = hvsi.adam_id AND hvsi.host_id = :host_id
|
||||
LEFT OUTER JOIN
|
||||
LEFT OUTER JOIN
|
||||
nano_command_results ncr ON ncr.command_uuid = hvsi.command_uuid
|
||||
WHERE
|
||||
-- use the latest install only
|
||||
@@ -2113,12 +2112,11 @@ AND EXISTS (SELECT 1 FROM software s JOIN software_cve scve ON scve.software_id
|
||||
st.source,
|
||||
-- will be NULL for VPP apps for now, self-service not supported yet
|
||||
si.self_service as self_service,
|
||||
-- we want that field to be empty string for VPP apps, the filename for installers,
|
||||
-- and NULL otherwise.
|
||||
CASE WHEN vap.adam_id IS NOT NULL THEN '' ELSE si.filename END as package_available_for_install,
|
||||
-- we don't store VPP app information in the package sub-object at the moment,
|
||||
-- only software installer information
|
||||
1 as available_for_install,
|
||||
si.filename as package_name,
|
||||
si.version as package_version,
|
||||
vap.adam_id as vpp_app_adam_id,
|
||||
vap.latest_version as vpp_app_version,
|
||||
NULL as last_install_installed_at,
|
||||
NULL as last_install_install_uuid,
|
||||
NULL as status
|
||||
@@ -2174,8 +2172,11 @@ AND EXISTS (SELECT 1 FROM software s JOIN software_cve scve ON scve.software_id
|
||||
name,
|
||||
source,
|
||||
self_service,
|
||||
package_available_for_install,
|
||||
available_for_install,
|
||||
package_name,
|
||||
package_version,
|
||||
vpp_app_adam_id,
|
||||
vpp_app_version,
|
||||
last_install_installed_at,
|
||||
last_install_install_uuid,
|
||||
status
|
||||
@@ -2238,10 +2239,12 @@ AND EXISTS (SELECT 1 FROM software s JOIN software_cve scve ON scve.software_id
|
||||
|
||||
type hostSoftware struct {
|
||||
fleet.HostSoftwareWithInstaller
|
||||
LastInstallInstalledAt *time.Time `db:"last_install_installed_at"`
|
||||
LastInstallInstallUUID *string `db:"last_install_install_uuid"`
|
||||
StatusSort sql.NullInt32 `db:"status_sort"`
|
||||
PackageVersion *string `db:"package_version"`
|
||||
LastInstallInstalledAt *time.Time `db:"last_install_installed_at"`
|
||||
LastInstallInstallUUID *string `db:"last_install_install_uuid"`
|
||||
PackageName *string `db:"package_name"`
|
||||
PackageVersion *string `db:"package_version"`
|
||||
VPPAppAdamID *string `db:"vpp_app_adam_id"`
|
||||
VPPAppVersion *string `db:"vpp_app_version"`
|
||||
}
|
||||
var hostSoftwareList []*hostSoftware
|
||||
if err := sqlx.SelectContext(ctx, ds.reader(ctx), &hostSoftwareList, stmt, args...); err != nil {
|
||||
@@ -2264,20 +2267,29 @@ AND EXISTS (SELECT 1 FROM software s JOIN software_cve scve ON scve.software_id
|
||||
}
|
||||
|
||||
// promote the package name and version to the proper destination fields
|
||||
// (the service layer will arbitrate whether package_available_for_install
|
||||
// or package fields are returned). For now this "Package" object is only
|
||||
// for software installers.
|
||||
if hs.PackageAvailableForInstall != nil && *hs.PackageAvailableForInstall != "" {
|
||||
if hs.PackageName != nil {
|
||||
var version string
|
||||
if hs.PackageVersion != nil {
|
||||
version = *hs.PackageVersion
|
||||
}
|
||||
hs.Package = &fleet.DeviceSoftwarePackage{
|
||||
Name: *hs.PackageAvailableForInstall,
|
||||
hs.SoftwarePackage = &fleet.HostSoftwarePackageOrApp{
|
||||
Name: *hs.PackageName,
|
||||
Version: version,
|
||||
}
|
||||
}
|
||||
|
||||
// promote the VPP app id and version to the proper destination fields
|
||||
if hs.VPPAppAdamID != nil {
|
||||
var version string
|
||||
if hs.VPPAppVersion != nil {
|
||||
version = *hs.VPPAppVersion
|
||||
}
|
||||
hs.AppStoreApp = &fleet.HostSoftwarePackageOrApp{
|
||||
AppStoreID: *hs.VPPAppAdamID,
|
||||
Version: version,
|
||||
}
|
||||
}
|
||||
|
||||
titleIDs = append(titleIDs, hs.ID)
|
||||
byTitleID[hs.ID] = hs
|
||||
}
|
||||
|
||||
@@ -3288,15 +3288,9 @@ func testListHostSoftware(t *testing.T, ds *Datastore) {
|
||||
require.True(t, ok)
|
||||
require.Equal(t, e.Name, g.Name)
|
||||
require.Equal(t, e.Source, g.Source)
|
||||
if e.SelfService != nil {
|
||||
// there is a software installer, so package information should be present
|
||||
require.Equal(t, e.SelfService, g.SelfService)
|
||||
require.NotNil(t, g.Package)
|
||||
require.NotNil(t, g.PackageAvailableForInstall)
|
||||
require.Equal(t, e.PackageAvailableForInstall, g.PackageAvailableForInstall)
|
||||
require.Equal(t, *e.PackageAvailableForInstall, g.Package.Name)
|
||||
require.NotEmpty(t, g.Package.Version)
|
||||
}
|
||||
require.Equal(t, e.AvailableForInstall, g.AvailableForInstall, g.Name+g.Source)
|
||||
require.Equal(t, e.SoftwarePackage, g.SoftwarePackage)
|
||||
require.Equal(t, e.AppStoreApp, g.AppStoreApp)
|
||||
require.Len(t, g.InstalledVersions, len(e.InstalledVersions))
|
||||
if len(e.InstalledVersions) > 0 {
|
||||
byVers := make(map[string]fleet.HostSoftwareInstalledVersion, len(e.InstalledVersions))
|
||||
@@ -3471,33 +3465,36 @@ func testListHostSoftware(t *testing.T, ds *Datastore) {
|
||||
|
||||
// swi1Pending uses software title id of "b"
|
||||
expected[byNSV[b].Name+byNSV[b].Source] = fleet.HostSoftwareWithInstaller{
|
||||
Name: "b",
|
||||
Source: "apps",
|
||||
Status: expectStatus(fleet.SoftwareInstallerPending),
|
||||
LastInstall: &fleet.HostSoftwareInstall{InstallUUID: "uuid1"},
|
||||
PackageAvailableForInstall: ptr.String("installer-0.pkg"),
|
||||
SelfService: ptr.Bool(true),
|
||||
Name: "b",
|
||||
Source: "apps",
|
||||
Status: expectStatus(fleet.SoftwareInstallerPending),
|
||||
LastInstall: &fleet.HostSoftwareInstall{InstallUUID: "uuid1"},
|
||||
AvailableForInstall: true,
|
||||
SoftwarePackage: &fleet.HostSoftwarePackageOrApp{Name: "installer-0.pkg", Version: "v0.0.0"},
|
||||
SelfService: ptr.Bool(true),
|
||||
InstalledVersions: []*fleet.HostSoftwareInstalledVersion{
|
||||
{Version: byNSV[b].Version, Vulnerabilities: []string{vulns[3].CVE}, InstalledPaths: []string{installPaths[2]}},
|
||||
},
|
||||
}
|
||||
i0 := fleet.HostSoftwareWithInstaller{
|
||||
Name: "i0",
|
||||
Source: "apps",
|
||||
Status: expectStatus(fleet.SoftwareInstallerInstalled),
|
||||
LastInstall: &fleet.HostSoftwareInstall{InstallUUID: "uuid2"},
|
||||
SelfService: ptr.Bool(true),
|
||||
PackageAvailableForInstall: ptr.String("installer-1.pkg"),
|
||||
Name: "i0",
|
||||
Source: "apps",
|
||||
Status: expectStatus(fleet.SoftwareInstallerInstalled),
|
||||
LastInstall: &fleet.HostSoftwareInstall{InstallUUID: "uuid2"},
|
||||
SelfService: ptr.Bool(true),
|
||||
AvailableForInstall: true,
|
||||
SoftwarePackage: &fleet.HostSoftwarePackageOrApp{Name: "installer-1.pkg", Version: "v1.0.0"},
|
||||
}
|
||||
expected[i0.Name+i0.Source] = i0
|
||||
|
||||
i1 := fleet.HostSoftwareWithInstaller{
|
||||
Name: "i1",
|
||||
Source: "apps",
|
||||
Status: expectStatus(fleet.SoftwareInstallerFailed),
|
||||
LastInstall: &fleet.HostSoftwareInstall{InstallUUID: "uuid3"},
|
||||
SelfService: ptr.Bool(false),
|
||||
PackageAvailableForInstall: ptr.String("installer-2.pkg"),
|
||||
Name: "i1",
|
||||
Source: "apps",
|
||||
Status: expectStatus(fleet.SoftwareInstallerFailed),
|
||||
LastInstall: &fleet.HostSoftwareInstall{InstallUUID: "uuid3"},
|
||||
SelfService: ptr.Bool(false),
|
||||
AvailableForInstall: true,
|
||||
SoftwarePackage: &fleet.HostSoftwarePackageOrApp{Name: "installer-2.pkg", Version: "v2.0.0"},
|
||||
}
|
||||
expected[i1.Name+i1.Source] = i1
|
||||
|
||||
@@ -3510,22 +3507,24 @@ func testListHostSoftware(t *testing.T, ds *Datastore) {
|
||||
|
||||
// request with available software
|
||||
i2 := fleet.HostSoftwareWithInstaller{
|
||||
Name: "i2",
|
||||
Source: "apps",
|
||||
Status: nil,
|
||||
LastInstall: nil,
|
||||
PackageAvailableForInstall: ptr.String("installer-3.pkg"),
|
||||
SelfService: ptr.Bool(false),
|
||||
Name: "i2",
|
||||
Source: "apps",
|
||||
Status: nil,
|
||||
LastInstall: nil,
|
||||
AvailableForInstall: true,
|
||||
SoftwarePackage: &fleet.HostSoftwarePackageOrApp{Name: "installer-3.pkg", Version: "v3.0.0"},
|
||||
SelfService: ptr.Bool(false),
|
||||
}
|
||||
expected[i2.Name+i2.Source] = i2
|
||||
|
||||
i3 := fleet.HostSoftwareWithInstaller{
|
||||
Name: "i3",
|
||||
Source: "apps",
|
||||
Status: nil,
|
||||
LastInstall: nil,
|
||||
PackageAvailableForInstall: ptr.String("installer-4.pkg"),
|
||||
SelfService: ptr.Bool(false),
|
||||
Name: "i3",
|
||||
Source: "apps",
|
||||
Status: nil,
|
||||
LastInstall: nil,
|
||||
AvailableForInstall: true,
|
||||
SoftwarePackage: &fleet.HostSoftwarePackageOrApp{Name: "installer-4.pkg", Version: "v4.0.0"},
|
||||
SelfService: ptr.Bool(false),
|
||||
}
|
||||
expected[i3.Name+i3.Source] = i3
|
||||
|
||||
@@ -3569,23 +3568,25 @@ func testListHostSoftware(t *testing.T, ds *Datastore) {
|
||||
})
|
||||
|
||||
expected[byNSV[b].Name+byNSV[b].Source] = fleet.HostSoftwareWithInstaller{
|
||||
Name: "b",
|
||||
Source: "apps",
|
||||
Status: expectStatus(fleet.SoftwareInstallerFailed),
|
||||
LastInstall: &fleet.HostSoftwareInstall{InstallUUID: "uuid1"},
|
||||
PackageAvailableForInstall: ptr.String("installer-0.pkg"),
|
||||
SelfService: ptr.Bool(true),
|
||||
Name: "b",
|
||||
Source: "apps",
|
||||
Status: expectStatus(fleet.SoftwareInstallerFailed),
|
||||
LastInstall: &fleet.HostSoftwareInstall{InstallUUID: "uuid1"},
|
||||
AvailableForInstall: true,
|
||||
SoftwarePackage: &fleet.HostSoftwarePackageOrApp{Name: "installer-0.pkg", Version: "v0.0.0"},
|
||||
SelfService: ptr.Bool(true),
|
||||
InstalledVersions: []*fleet.HostSoftwareInstalledVersion{
|
||||
{Version: byNSV[b].Version, Vulnerabilities: []string{vulns[3].CVE}, InstalledPaths: []string{installPaths[2]}},
|
||||
},
|
||||
}
|
||||
expected[i1.Name+i1.Source] = fleet.HostSoftwareWithInstaller{
|
||||
Name: "i1",
|
||||
Source: "apps",
|
||||
Status: expectStatus(fleet.SoftwareInstallerPending),
|
||||
LastInstall: &fleet.HostSoftwareInstall{InstallUUID: "uuid4"},
|
||||
SelfService: ptr.Bool(false),
|
||||
PackageAvailableForInstall: ptr.String("installer-2.pkg"),
|
||||
Name: "i1",
|
||||
Source: "apps",
|
||||
Status: expectStatus(fleet.SoftwareInstallerPending),
|
||||
LastInstall: &fleet.HostSoftwareInstall{InstallUUID: "uuid4"},
|
||||
SelfService: ptr.Bool(false),
|
||||
AvailableForInstall: true,
|
||||
SoftwarePackage: &fleet.HostSoftwarePackageOrApp{Name: "installer-2.pkg", Version: "v2.0.0"},
|
||||
}
|
||||
|
||||
// request without available software
|
||||
@@ -3676,20 +3677,22 @@ func testListHostSoftware(t *testing.T, ds *Datastore) {
|
||||
require.NotEmpty(t, vpp1TmCmdUUID)
|
||||
|
||||
expected["vpp1apps"] = fleet.HostSoftwareWithInstaller{
|
||||
Name: "vpp1",
|
||||
Source: "apps",
|
||||
Status: expectStatus(fleet.SoftwareInstallerInstalled),
|
||||
LastInstall: &fleet.HostSoftwareInstall{InstallUUID: vpp1CmdUUID},
|
||||
SelfService: nil,
|
||||
PackageAvailableForInstall: ptr.String(""),
|
||||
Name: "vpp1",
|
||||
Source: "apps",
|
||||
Status: expectStatus(fleet.SoftwareInstallerInstalled),
|
||||
LastInstall: &fleet.HostSoftwareInstall{InstallUUID: vpp1CmdUUID},
|
||||
SelfService: nil,
|
||||
AvailableForInstall: true,
|
||||
AppStoreApp: &fleet.HostSoftwarePackageOrApp{AppStoreID: vpp1},
|
||||
}
|
||||
expected["vpp2apps"] = fleet.HostSoftwareWithInstaller{
|
||||
Name: "vpp2",
|
||||
Source: "apps",
|
||||
Status: expectStatus(fleet.SoftwareInstallerPending),
|
||||
LastInstall: &fleet.HostSoftwareInstall{InstallUUID: vpp2bCmdUUID},
|
||||
SelfService: nil,
|
||||
PackageAvailableForInstall: ptr.String(""),
|
||||
Name: "vpp2",
|
||||
Source: "apps",
|
||||
Status: expectStatus(fleet.SoftwareInstallerPending),
|
||||
LastInstall: &fleet.HostSoftwareInstall{InstallUUID: vpp2bCmdUUID},
|
||||
SelfService: nil,
|
||||
AvailableForInstall: true,
|
||||
AppStoreApp: &fleet.HostSoftwarePackageOrApp{AppStoreID: vpp2},
|
||||
}
|
||||
|
||||
opts.IncludeAvailableForInstall = false
|
||||
@@ -3700,12 +3703,13 @@ func testListHostSoftware(t *testing.T, ds *Datastore) {
|
||||
compareResults(expected, sw, true, i3.Name+i3.Source, i2.Name+i2.Source) // i3 is for team, i2 is available (excluded)
|
||||
|
||||
expected["vpp3apps"] = fleet.HostSoftwareWithInstaller{
|
||||
Name: "vpp3",
|
||||
Source: "apps",
|
||||
Status: nil,
|
||||
LastInstall: nil,
|
||||
SelfService: nil,
|
||||
PackageAvailableForInstall: ptr.String(""),
|
||||
Name: "vpp3",
|
||||
Source: "apps",
|
||||
Status: nil,
|
||||
LastInstall: nil,
|
||||
SelfService: nil,
|
||||
AvailableForInstall: true,
|
||||
AppStoreApp: &fleet.HostSoftwarePackageOrApp{AppStoreID: vpp3},
|
||||
}
|
||||
opts.IncludeAvailableForInstall = true
|
||||
opts.ListOptions.PerPage = 20
|
||||
@@ -3722,12 +3726,13 @@ 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.SoftwareInstallerPending),
|
||||
LastInstall: &fleet.HostSoftwareInstall{InstallUUID: vpp1TmCmdUUID},
|
||||
SelfService: nil,
|
||||
PackageAvailableForInstall: ptr.String(""),
|
||||
Name: "vpp1",
|
||||
Source: "apps",
|
||||
Status: expectStatus(fleet.SoftwareInstallerPending),
|
||||
LastInstall: &fleet.HostSoftwareInstall{InstallUUID: vpp1TmCmdUUID},
|
||||
SelfService: nil,
|
||||
AvailableForInstall: true,
|
||||
AppStoreApp: &fleet.HostSoftwarePackageOrApp{AppStoreID: vpp1},
|
||||
},
|
||||
}, sw, true)
|
||||
|
||||
@@ -3745,20 +3750,22 @@ func testListHostSoftware(t *testing.T, ds *Datastore) {
|
||||
{Version: otherSoftware[1].Version},
|
||||
}},
|
||||
"i1apps": {
|
||||
Name: "i1",
|
||||
Source: "apps",
|
||||
Status: expectStatus(fleet.SoftwareInstallerPending),
|
||||
LastInstall: &fleet.HostSoftwareInstall{InstallUUID: otherHostI1UUID},
|
||||
SelfService: ptr.Bool(false),
|
||||
PackageAvailableForInstall: ptr.String("installer-2.pkg"),
|
||||
Name: "i1",
|
||||
Source: "apps",
|
||||
Status: expectStatus(fleet.SoftwareInstallerPending),
|
||||
LastInstall: &fleet.HostSoftwareInstall{InstallUUID: otherHostI1UUID},
|
||||
SelfService: ptr.Bool(false),
|
||||
AvailableForInstall: true,
|
||||
SoftwarePackage: &fleet.HostSoftwarePackageOrApp{Name: "installer-2.pkg", Version: "v2.0.0"},
|
||||
},
|
||||
"i2apps": {
|
||||
Name: "i2",
|
||||
Source: "apps",
|
||||
Status: expectStatus(fleet.SoftwareInstallerPending),
|
||||
LastInstall: &fleet.HostSoftwareInstall{InstallUUID: otherHostI2UUID},
|
||||
SelfService: ptr.Bool(false),
|
||||
PackageAvailableForInstall: ptr.String("installer-3.pkg"),
|
||||
Name: "i2",
|
||||
Source: "apps",
|
||||
Status: expectStatus(fleet.SoftwareInstallerPending),
|
||||
LastInstall: &fleet.HostSoftwareInstall{InstallUUID: otherHostI2UUID},
|
||||
SelfService: ptr.Bool(false),
|
||||
AvailableForInstall: true,
|
||||
SoftwarePackage: &fleet.HostSoftwarePackageOrApp{Name: "installer-3.pkg", Version: "v3.0.0"},
|
||||
},
|
||||
}
|
||||
compareResults(expectedOther, sw, true)
|
||||
|
||||
@@ -315,23 +315,26 @@ type HostSoftwareWithInstaller struct {
|
||||
LastInstall *HostSoftwareInstall `json:"last_install"`
|
||||
InstalledVersions []*HostSoftwareInstalledVersion `json:"installed_versions"`
|
||||
|
||||
// PackageAvailableForInstall is only present for the user-authenticated
|
||||
// endpoint, not the device-authenticated one. If non-nil and non-empty, it
|
||||
// indicates that a software installer is present for that software (and the
|
||||
// name is the installer's filename). If non-nil and empty, it indicates that
|
||||
// a VPP app is present for that software. If nil, none of those are present.
|
||||
PackageAvailableForInstall *string `json:"package_available_for_install,omitempty" db:"package_available_for_install"`
|
||||
// AvailableForInstall is true if a software installer or a VPP app is
|
||||
// available to install this software.
|
||||
AvailableForInstall bool `json:"available_for_install" db:"available_for_install"`
|
||||
|
||||
// Package provides software installer package information, it is only
|
||||
// present for the device-authenticated endpoint, not for the
|
||||
// user-authenticated one.
|
||||
Package *DeviceSoftwarePackage `json:"package,omitempty"`
|
||||
// SoftwarePackage provides software installer package information, it is
|
||||
// only present if a software installer is available for the software title.
|
||||
SoftwarePackage *HostSoftwarePackageOrApp `json:"software_package"`
|
||||
|
||||
// AppStoreApp provides VPP app information, it is only present if a VPP app
|
||||
// is available for the software title.
|
||||
AppStoreApp *HostSoftwarePackageOrApp `json:"app_store_app"`
|
||||
}
|
||||
|
||||
// DeviceSoftwarePackage provides information about a software installer
|
||||
// package for self-service on a device.
|
||||
type DeviceSoftwarePackage struct {
|
||||
Name string `json:"name"`
|
||||
// HostSoftwarePackageOrApp provides information about a software installer
|
||||
// package or a VPP app.
|
||||
type HostSoftwarePackageOrApp struct {
|
||||
// AppStoreID is only present for VPP apps.
|
||||
AppStoreID string `json:"app_store_id,omitempty"`
|
||||
// Name is only present for software installer packages.
|
||||
Name string `json:"name,omitempty"`
|
||||
Version string `json:"version"`
|
||||
}
|
||||
|
||||
|
||||
@@ -2563,18 +2563,5 @@ func (svc *Service) ListHostSoftware(ctx context.Context, hostID uint, opts flee
|
||||
opts.IncludeAvailableForInstall = includeAvailableForInstall || opts.SelfServiceOnly
|
||||
|
||||
software, meta, err := svc.ds.ListHostSoftware(ctx, host, opts)
|
||||
if includeAvailableForInstall {
|
||||
// for the host software page, we don't want to return the package object,
|
||||
// only the package name
|
||||
for _, s := range software {
|
||||
s.Package = nil
|
||||
}
|
||||
} else {
|
||||
// for the device page, we don't want to return the package name, only the
|
||||
// package object
|
||||
for _, s := range software {
|
||||
s.PackageAvailableForInstall = nil
|
||||
}
|
||||
}
|
||||
return software, meta, ctxerr.Wrap(ctx, err, "list host software")
|
||||
}
|
||||
|
||||
@@ -9148,11 +9148,13 @@ func (s *integrationEnterpriseTestSuite) TestListHostSoftware() {
|
||||
require.Len(t, getHostSw.Software[1].InstalledVersions, 2)
|
||||
// no package information as there is no installer
|
||||
require.Nil(t, getHostSw.Software[0].SelfService)
|
||||
require.Nil(t, getHostSw.Software[0].Package)
|
||||
require.Nil(t, getHostSw.Software[0].PackageAvailableForInstall)
|
||||
require.False(t, getHostSw.Software[0].AvailableForInstall)
|
||||
require.Nil(t, getHostSw.Software[0].SoftwarePackage)
|
||||
require.Nil(t, getHostSw.Software[0].AppStoreApp)
|
||||
require.Nil(t, getHostSw.Software[1].SelfService)
|
||||
require.Nil(t, getHostSw.Software[1].Package)
|
||||
require.Nil(t, getHostSw.Software[1].PackageAvailableForInstall)
|
||||
require.False(t, getHostSw.Software[1].AvailableForInstall)
|
||||
require.Nil(t, getHostSw.Software[1].SoftwarePackage)
|
||||
require.Nil(t, getHostSw.Software[1].AppStoreApp)
|
||||
|
||||
// Add vulnerabilities to software to check query param filtering
|
||||
_, err = s.ds.InsertSoftwareVulnerability(ctx, fleet.SoftwareVulnerability{SoftwareID: barSoftwareID, CVE: "CVE-bar-1234"}, fleet.NVDSource)
|
||||
@@ -9166,8 +9168,9 @@ func (s *integrationEnterpriseTestSuite) TestListHostSoftware() {
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, "bar", getHostSw.Software[0].Name)
|
||||
require.Nil(t, getHostSw.Software[0].SelfService)
|
||||
require.Nil(t, getHostSw.Software[0].Package)
|
||||
require.Nil(t, getHostSw.Software[0].PackageAvailableForInstall)
|
||||
require.False(t, getHostSw.Software[0].AvailableForInstall)
|
||||
require.Nil(t, getHostSw.Software[0].SoftwarePackage)
|
||||
require.Nil(t, getHostSw.Software[0].AppStoreApp)
|
||||
require.Len(t, getHostSw.Software[0].InstalledVersions, 1)
|
||||
require.Len(t, getHostSw.Software[0].InstalledVersions[0].Vulnerabilities, 2)
|
||||
require.Equal(t, getHostSw.Software[0].InstalledVersions[0].Vulnerabilities, []string{"CVE-bar-1234", "CVE-bar-5678"})
|
||||
@@ -9182,11 +9185,13 @@ func (s *integrationEnterpriseTestSuite) TestListHostSoftware() {
|
||||
require.Len(t, getDeviceSw.Software[1].InstalledVersions, 2)
|
||||
// no package information as there is no installer
|
||||
require.Nil(t, getDeviceSw.Software[0].SelfService)
|
||||
require.Nil(t, getDeviceSw.Software[0].Package)
|
||||
require.Nil(t, getDeviceSw.Software[0].PackageAvailableForInstall)
|
||||
require.False(t, getDeviceSw.Software[0].AvailableForInstall)
|
||||
require.Nil(t, getDeviceSw.Software[0].SoftwarePackage)
|
||||
require.Nil(t, getDeviceSw.Software[0].AppStoreApp)
|
||||
require.Nil(t, getDeviceSw.Software[1].SelfService)
|
||||
require.Nil(t, getDeviceSw.Software[1].Package)
|
||||
require.Nil(t, getDeviceSw.Software[1].PackageAvailableForInstall)
|
||||
require.False(t, getDeviceSw.Software[1].AvailableForInstall)
|
||||
require.Nil(t, getDeviceSw.Software[1].SoftwarePackage)
|
||||
require.Nil(t, getDeviceSw.Software[1].AppStoreApp)
|
||||
|
||||
// create a software installer, not installed on the host
|
||||
payload := &fleet.UploadSoftwareInstallerPayload{
|
||||
@@ -9208,18 +9213,19 @@ func (s *integrationEnterpriseTestSuite) TestListHostSoftware() {
|
||||
s.DoJSON("GET", fmt.Sprintf("/api/latest/fleet/hosts/%d/software", host.ID), nil, http.StatusOK, &getHostSw)
|
||||
require.Len(t, getHostSw.Software, 3) // foo, bar and ruby.deb
|
||||
require.Equal(t, getHostSw.Software[0].Name, "bar")
|
||||
require.Nil(t, getHostSw.Software[0].PackageAvailableForInstall)
|
||||
require.False(t, getHostSw.Software[0].AvailableForInstall)
|
||||
require.Equal(t, getHostSw.Software[1].Name, "foo")
|
||||
require.Nil(t, getHostSw.Software[1].PackageAvailableForInstall)
|
||||
require.False(t, getHostSw.Software[1].AvailableForInstall)
|
||||
require.Equal(t, getHostSw.Software[2].Name, "ruby")
|
||||
require.Len(t, getHostSw.Software[1].InstalledVersions, 2)
|
||||
require.NotNil(t, getHostSw.Software[2].PackageAvailableForInstall)
|
||||
require.Equal(t, "ruby.deb", *getHostSw.Software[2].PackageAvailableForInstall)
|
||||
require.True(t, getHostSw.Software[2].AvailableForInstall)
|
||||
require.Nil(t, getHostSw.Software[2].AppStoreApp)
|
||||
require.NotNil(t, getHostSw.Software[2].SoftwarePackage)
|
||||
require.Equal(t, "ruby.deb", getHostSw.Software[2].SoftwarePackage.Name)
|
||||
require.Equal(t, payload.Version, getHostSw.Software[2].SoftwarePackage.Version)
|
||||
require.NotNil(t, getHostSw.Software[2].SelfService)
|
||||
require.True(t, *getHostSw.Software[2].SelfService)
|
||||
require.Nil(t, getHostSw.Software[2].Status)
|
||||
// package object is not returned for user-authenticated endpoint
|
||||
require.Nil(t, getHostSw.Software[2].Package)
|
||||
|
||||
// only the installer is returned for self-service only
|
||||
getHostSw = getHostSoftwareResponse{}
|
||||
@@ -9236,8 +9242,8 @@ func (s *integrationEnterpriseTestSuite) TestListHostSoftware() {
|
||||
require.Equal(t, getDeviceSw.Software[0].Name, "bar")
|
||||
require.Equal(t, getDeviceSw.Software[1].Name, "foo")
|
||||
require.Len(t, getDeviceSw.Software[1].InstalledVersions, 2)
|
||||
require.Nil(t, getDeviceSw.Software[0].PackageAvailableForInstall)
|
||||
require.Nil(t, getDeviceSw.Software[1].PackageAvailableForInstall)
|
||||
require.False(t, getDeviceSw.Software[0].AvailableForInstall)
|
||||
require.False(t, getDeviceSw.Software[1].AvailableForInstall)
|
||||
|
||||
// but it gets returned for self-service only
|
||||
res = s.DoRawNoAuth("GET", "/api/latest/fleet/device/"+token+"/software?self_service=1", nil, http.StatusOK)
|
||||
@@ -9246,14 +9252,13 @@ func (s *integrationEnterpriseTestSuite) TestListHostSoftware() {
|
||||
require.NoError(t, err)
|
||||
require.Len(t, getDeviceSw.Software, 1)
|
||||
require.Equal(t, getDeviceSw.Software[0].Name, "ruby")
|
||||
// package available for install is not returned for device-authenticated
|
||||
require.Nil(t, getDeviceSw.Software[0].PackageAvailableForInstall)
|
||||
// but package object is
|
||||
require.NotNil(t, getDeviceSw.Software[0].Package)
|
||||
require.True(t, getDeviceSw.Software[0].AvailableForInstall)
|
||||
require.Nil(t, getDeviceSw.Software[0].AppStoreApp)
|
||||
require.NotNil(t, getDeviceSw.Software[0].SoftwarePackage)
|
||||
require.NotNil(t, getDeviceSw.Software[0].SelfService)
|
||||
require.True(t, *getDeviceSw.Software[0].SelfService)
|
||||
require.Equal(t, payload.Filename, getDeviceSw.Software[0].Package.Name)
|
||||
require.Equal(t, payload.Version, getDeviceSw.Software[0].Package.Version)
|
||||
require.Equal(t, payload.Filename, getDeviceSw.Software[0].SoftwarePackage.Name)
|
||||
require.Equal(t, payload.Version, getDeviceSw.Software[0].SoftwarePackage.Version)
|
||||
|
||||
// request installation on the host
|
||||
var installResp installSoftwareResponse
|
||||
@@ -9268,13 +9273,13 @@ func (s *integrationEnterpriseTestSuite) TestListHostSoftware() {
|
||||
require.Equal(t, getHostSw.Software[1].Name, "foo")
|
||||
require.Equal(t, getHostSw.Software[2].Name, "ruby")
|
||||
require.Len(t, getHostSw.Software[1].InstalledVersions, 2)
|
||||
require.NotNil(t, getHostSw.Software[2].PackageAvailableForInstall)
|
||||
require.Equal(t, "ruby.deb", *getHostSw.Software[2].PackageAvailableForInstall)
|
||||
require.True(t, getHostSw.Software[2].AvailableForInstall)
|
||||
require.NotNil(t, getHostSw.Software[2].SoftwarePackage)
|
||||
require.Equal(t, "ruby.deb", getHostSw.Software[2].SoftwarePackage.Name)
|
||||
require.NotNil(t, getHostSw.Software[2].Status)
|
||||
require.Equal(t, fleet.SoftwareInstallerPending, *getHostSw.Software[2].Status)
|
||||
require.NotNil(t, getHostSw.Software[2].SelfService)
|
||||
require.True(t, *getHostSw.Software[2].SelfService)
|
||||
require.Nil(t, getHostSw.Software[2].Package)
|
||||
|
||||
// still returned with self-service filter
|
||||
getHostSw = getHostSoftwareResponse{}
|
||||
@@ -9292,12 +9297,13 @@ func (s *integrationEnterpriseTestSuite) TestListHostSoftware() {
|
||||
require.Equal(t, getDeviceSw.Software[1].Name, "foo")
|
||||
require.Equal(t, getDeviceSw.Software[2].Name, "ruby")
|
||||
require.Len(t, getDeviceSw.Software[1].InstalledVersions, 2)
|
||||
require.Nil(t, getDeviceSw.Software[2].PackageAvailableForInstall)
|
||||
require.True(t, getDeviceSw.Software[2].AvailableForInstall)
|
||||
require.NotNil(t, getDeviceSw.Software[2].Status)
|
||||
require.Equal(t, fleet.SoftwareInstallerPending, *getDeviceSw.Software[2].Status)
|
||||
require.NotNil(t, getDeviceSw.Software[2].SelfService)
|
||||
require.True(t, *getDeviceSw.Software[2].SelfService)
|
||||
require.NotNil(t, getDeviceSw.Software[2].Package)
|
||||
require.NotNil(t, getDeviceSw.Software[2].SoftwarePackage)
|
||||
require.Nil(t, getDeviceSw.Software[2].AppStoreApp)
|
||||
|
||||
// still returned for self-service only too
|
||||
res = s.DoRawNoAuth("GET", "/api/latest/fleet/device/"+token+"/software?self_service=1", nil, http.StatusOK)
|
||||
@@ -9308,8 +9314,9 @@ func (s *integrationEnterpriseTestSuite) TestListHostSoftware() {
|
||||
require.Equal(t, getDeviceSw.Software[0].Name, "ruby")
|
||||
require.NotNil(t, getDeviceSw.Software[0].SelfService)
|
||||
require.True(t, *getDeviceSw.Software[0].SelfService)
|
||||
require.NotNil(t, getDeviceSw.Software[0].Package)
|
||||
require.Nil(t, getDeviceSw.Software[0].PackageAvailableForInstall)
|
||||
require.NotNil(t, getDeviceSw.Software[0].SoftwarePackage)
|
||||
require.Nil(t, getDeviceSw.Software[0].AppStoreApp)
|
||||
require.True(t, getDeviceSw.Software[0].AvailableForInstall)
|
||||
|
||||
// test with a query
|
||||
getHostSw = getHostSoftwareResponse{}
|
||||
|
||||
Reference in New Issue
Block a user