mirror of
https://github.com/fleetdm/fleet
synced 2026-05-24 09:28:54 +00:00
Add bundle identifier to software when available (#2220)
* Add bundle identifier to software when available * Update docs * Delete unneeded test
This commit is contained in:
parent
a11282cdee
commit
435178e93c
10 changed files with 105 additions and 41 deletions
1
changes/issue-1837-bundle-identifier
Normal file
1
changes/issue-1837-bundle-identifier
Normal file
|
|
@ -0,0 +1 @@
|
|||
* Add bundle identifier to software if available.
|
||||
|
|
@ -419,7 +419,7 @@ func TestGetSoftawre(t *testing.T) {
|
|||
}
|
||||
foo002 := fleet.Software{Name: "foo", Version: "0.0.2", Source: "chrome_extensions"}
|
||||
foo003 := fleet.Software{Name: "foo", Version: "0.0.3", Source: "chrome_extensions", GenerateCPE: "someothercpewithoutvulns"}
|
||||
bar003 := fleet.Software{Name: "bar", Version: "0.0.3", Source: "deb_packages"}
|
||||
bar003 := fleet.Software{Name: "bar", Version: "0.0.3", Source: "deb_packages", BundleIdentifier: "bundle"}
|
||||
|
||||
var gotTeamID *uint
|
||||
|
||||
|
|
@ -467,14 +467,15 @@ spec:
|
|||
source: chrome_extensions
|
||||
version: 0.0.3
|
||||
vulnerabilities: null
|
||||
- generated_cpe: ""
|
||||
- bundle_identifier: bundle
|
||||
generated_cpe: ""
|
||||
id: 0
|
||||
name: bar
|
||||
source: deb_packages
|
||||
version: 0.0.3
|
||||
vulnerabilities: null
|
||||
`
|
||||
expectedJson := `{"kind":"software","apiVersion":"1","spec":[{"id":0,"name":"foo","version":"0.0.1","source":"chrome_extensions","generated_cpe":"somecpe","vulnerabilities":[{"cve":"cve-321-432-543","details_link":"https://nvd.nist.gov/vuln/detail/cve-321-432-543"},{"cve":"cve-333-444-555","details_link":"https://nvd.nist.gov/vuln/detail/cve-333-444-555"}]},{"id":0,"name":"foo","version":"0.0.2","source":"chrome_extensions","generated_cpe":"","vulnerabilities":null},{"id":0,"name":"foo","version":"0.0.3","source":"chrome_extensions","generated_cpe":"someothercpewithoutvulns","vulnerabilities":null},{"id":0,"name":"bar","version":"0.0.3","source":"deb_packages","generated_cpe":"","vulnerabilities":null}]}
|
||||
expectedJson := `{"kind":"software","apiVersion":"1","spec":[{"id":0,"name":"foo","version":"0.0.1","source":"chrome_extensions","generated_cpe":"somecpe","vulnerabilities":[{"cve":"cve-321-432-543","details_link":"https://nvd.nist.gov/vuln/detail/cve-321-432-543"},{"cve":"cve-333-444-555","details_link":"https://nvd.nist.gov/vuln/detail/cve-333-444-555"}]},{"id":0,"name":"foo","version":"0.0.2","source":"chrome_extensions","generated_cpe":"","vulnerabilities":null},{"id":0,"name":"foo","version":"0.0.3","source":"chrome_extensions","generated_cpe":"someothercpewithoutvulns","vulnerabilities":null},{"id":0,"name":"bar","version":"0.0.3","bundle_identifier":"bundle","source":"deb_packages","generated_cpe":"","vulnerabilities":null}]}
|
||||
`
|
||||
|
||||
assert.Equal(t, expected, runAppForTest(t, []string{"get", "software"}))
|
||||
|
|
|
|||
|
|
@ -617,6 +617,15 @@ The endpoint returns the host's installed `software` if the software inventory f
|
|||
"source": "rpm_packages",
|
||||
"generated_cpe": "",
|
||||
"vulnerabilities": null
|
||||
},
|
||||
{
|
||||
"id": 321,
|
||||
"name": "SomeApp.app",
|
||||
"version": "1.0",
|
||||
"source": "apps",
|
||||
"bundle_identifier": "com.some.app",
|
||||
"generated_cpe": "",
|
||||
"vulnerabilities": null
|
||||
}
|
||||
],
|
||||
"id": 1,
|
||||
|
|
|
|||
|
|
@ -0,0 +1,22 @@
|
|||
package tables
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
func init() {
|
||||
MigrationClient.AddMigration(Up_20210924114500, Down_20210924114500)
|
||||
}
|
||||
|
||||
func Up_20210924114500(tx *sql.Tx) error {
|
||||
if _, err := tx.Exec(`ALTER TABLE software ADD COLUMN bundle_identifier VARCHAR(255) DEFAULT ''`); err != nil {
|
||||
return errors.Wrap(err, "add column team_id")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func Down_20210924114500(tx *sql.Tx) error {
|
||||
return nil
|
||||
}
|
||||
|
|
@ -309,9 +309,9 @@ CREATE TABLE `migration_status_tables` (
|
|||
`tstamp` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `id` (`id`)
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=105 DEFAULT CHARSET=utf8mb4;
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=106 DEFAULT CHARSET=utf8mb4;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
INSERT INTO `migration_status_tables` VALUES (1,0,1,'2020-01-01 01:01:01'),(2,20161118193812,1,'2020-01-01 01:01:01'),(3,20161118211713,1,'2020-01-01 01:01:01'),(4,20161118212436,1,'2020-01-01 01:01:01'),(5,20161118212515,1,'2020-01-01 01:01:01'),(6,20161118212528,1,'2020-01-01 01:01:01'),(7,20161118212538,1,'2020-01-01 01:01:01'),(8,20161118212549,1,'2020-01-01 01:01:01'),(9,20161118212557,1,'2020-01-01 01:01:01'),(10,20161118212604,1,'2020-01-01 01:01:01'),(11,20161118212613,1,'2020-01-01 01:01:01'),(12,20161118212621,1,'2020-01-01 01:01:01'),(13,20161118212630,1,'2020-01-01 01:01:01'),(14,20161118212641,1,'2020-01-01 01:01:01'),(15,20161118212649,1,'2020-01-01 01:01:01'),(16,20161118212656,1,'2020-01-01 01:01:01'),(17,20161118212758,1,'2020-01-01 01:01:01'),(18,20161128234849,1,'2020-01-01 01:01:01'),(19,20161230162221,1,'2020-01-01 01:01:01'),(20,20170104113816,1,'2020-01-01 01:01:01'),(21,20170105151732,1,'2020-01-01 01:01:01'),(22,20170108191242,1,'2020-01-01 01:01:01'),(23,20170109094020,1,'2020-01-01 01:01:01'),(24,20170109130438,1,'2020-01-01 01:01:01'),(25,20170110202752,1,'2020-01-01 01:01:01'),(26,20170111133013,1,'2020-01-01 01:01:01'),(27,20170117025759,1,'2020-01-01 01:01:01'),(28,20170118191001,1,'2020-01-01 01:01:01'),(29,20170119234632,1,'2020-01-01 01:01:01'),(30,20170124230432,1,'2020-01-01 01:01:01'),(31,20170127014618,1,'2020-01-01 01:01:01'),(32,20170131232841,1,'2020-01-01 01:01:01'),(33,20170223094154,1,'2020-01-01 01:01:01'),(34,20170306075207,1,'2020-01-01 01:01:01'),(35,20170309100733,1,'2020-01-01 01:01:01'),(36,20170331111922,1,'2020-01-01 01:01:01'),(37,20170502143928,1,'2020-01-01 01:01:01'),(38,20170504130602,1,'2020-01-01 01:01:01'),(39,20170509132100,1,'2020-01-01 01:01:01'),(40,20170519105647,1,'2020-01-01 01:01:01'),(41,20170519105648,1,'2020-01-01 01:01:01'),(42,20170831234300,1,'2020-01-01 01:01:01'),(43,20170831234301,1,'2020-01-01 01:01:01'),(44,20170831234303,1,'2020-01-01 01:01:01'),(45,20171116163618,1,'2020-01-01 01:01:01'),(46,20171219164727,1,'2020-01-01 01:01:01'),(47,20180620164811,1,'2020-01-01 01:01:01'),(48,20180620175054,1,'2020-01-01 01:01:01'),(49,20180620175055,1,'2020-01-01 01:01:01'),(50,20191010101639,1,'2020-01-01 01:01:01'),(51,20191010155147,1,'2020-01-01 01:01:01'),(52,20191220130734,1,'2020-01-01 01:01:01'),(53,20200311140000,1,'2020-01-01 01:01:01'),(54,20200405120000,1,'2020-01-01 01:01:01'),(55,20200407120000,1,'2020-01-01 01:01:01'),(56,20200420120000,1,'2020-01-01 01:01:01'),(57,20200504120000,1,'2020-01-01 01:01:01'),(58,20200512120000,1,'2020-01-01 01:01:01'),(59,20200707120000,1,'2020-01-01 01:01:01'),(60,20201011162341,1,'2020-01-01 01:01:01'),(61,20201021104586,1,'2020-01-01 01:01:01'),(62,20201102112520,1,'2020-01-01 01:01:01'),(63,20201208121729,1,'2020-01-01 01:01:01'),(64,20201215091637,1,'2020-01-01 01:01:01'),(65,20210119174155,1,'2020-01-01 01:01:01'),(66,20210326182902,1,'2020-01-01 01:01:01'),(67,20210421112652,1,'2020-01-01 01:01:01'),(68,20210506095025,1,'2020-01-01 01:01:01'),(69,20210513115729,1,'2020-01-01 01:01:01'),(70,20210526113559,1,'2020-01-01 01:01:01'),(71,20210601000001,1,'2020-01-01 01:01:01'),(72,20210601000002,1,'2020-01-01 01:01:01'),(73,20210601000003,1,'2020-01-01 01:01:01'),(74,20210601000004,1,'2020-01-01 01:01:01'),(75,20210601000005,1,'2020-01-01 01:01:01'),(76,20210601000006,1,'2020-01-01 01:01:01'),(77,20210601000007,1,'2020-01-01 01:01:01'),(78,20210601000008,1,'2020-01-01 01:01:01'),(79,20210606151329,1,'2020-01-01 01:01:01'),(80,20210616163757,1,'2020-01-01 01:01:01'),(81,20210617174723,1,'2020-01-01 01:01:01'),(82,20210622160235,1,'2020-01-01 01:01:01'),(83,20210623100031,1,'2020-01-01 01:01:01'),(84,20210623133615,1,'2020-01-01 01:01:01'),(85,20210708143152,1,'2020-01-01 01:01:01'),(86,20210709124443,1,'2020-01-01 01:01:01'),(87,20210712155608,1,'2020-01-01 01:01:01'),(88,20210714102108,1,'2020-01-01 01:01:01'),(89,20210719153709,1,'2020-01-01 01:01:01'),(90,20210721171531,1,'2020-01-01 01:01:01'),(91,20210723135713,1,'2020-01-01 01:01:01'),(92,20210802135933,1,'2020-01-01 01:01:01'),(93,20210806112844,1,'2020-01-01 01:01:01'),(94,20210810095603,1,'2020-01-01 01:01:01'),(95,20210811150223,1,'2020-01-01 01:01:01'),(96,20210818151827,1,'2020-01-01 01:01:01'),(97,20210818151828,1,'2020-01-01 01:01:01'),(98,20210818182258,1,'2020-01-01 01:01:01'),(99,20210819131107,1,'2020-01-01 01:01:01'),(100,20210819143446,1,'2020-01-01 01:01:01'),(101,20210903132338,1,'2020-01-01 01:01:01'),(102,20210915144307,1,'2020-01-01 01:01:01'),(103,20210920155130,1,'2020-01-01 01:01:01'),(104,20210927143115,1,'2020-01-01 01:01:01');
|
||||
INSERT INTO `migration_status_tables` VALUES (1,0,1,'2020-01-01 01:01:01'),(2,20161118193812,1,'2020-01-01 01:01:01'),(3,20161118211713,1,'2020-01-01 01:01:01'),(4,20161118212436,1,'2020-01-01 01:01:01'),(5,20161118212515,1,'2020-01-01 01:01:01'),(6,20161118212528,1,'2020-01-01 01:01:01'),(7,20161118212538,1,'2020-01-01 01:01:01'),(8,20161118212549,1,'2020-01-01 01:01:01'),(9,20161118212557,1,'2020-01-01 01:01:01'),(10,20161118212604,1,'2020-01-01 01:01:01'),(11,20161118212613,1,'2020-01-01 01:01:01'),(12,20161118212621,1,'2020-01-01 01:01:01'),(13,20161118212630,1,'2020-01-01 01:01:01'),(14,20161118212641,1,'2020-01-01 01:01:01'),(15,20161118212649,1,'2020-01-01 01:01:01'),(16,20161118212656,1,'2020-01-01 01:01:01'),(17,20161118212758,1,'2020-01-01 01:01:01'),(18,20161128234849,1,'2020-01-01 01:01:01'),(19,20161230162221,1,'2020-01-01 01:01:01'),(20,20170104113816,1,'2020-01-01 01:01:01'),(21,20170105151732,1,'2020-01-01 01:01:01'),(22,20170108191242,1,'2020-01-01 01:01:01'),(23,20170109094020,1,'2020-01-01 01:01:01'),(24,20170109130438,1,'2020-01-01 01:01:01'),(25,20170110202752,1,'2020-01-01 01:01:01'),(26,20170111133013,1,'2020-01-01 01:01:01'),(27,20170117025759,1,'2020-01-01 01:01:01'),(28,20170118191001,1,'2020-01-01 01:01:01'),(29,20170119234632,1,'2020-01-01 01:01:01'),(30,20170124230432,1,'2020-01-01 01:01:01'),(31,20170127014618,1,'2020-01-01 01:01:01'),(32,20170131232841,1,'2020-01-01 01:01:01'),(33,20170223094154,1,'2020-01-01 01:01:01'),(34,20170306075207,1,'2020-01-01 01:01:01'),(35,20170309100733,1,'2020-01-01 01:01:01'),(36,20170331111922,1,'2020-01-01 01:01:01'),(37,20170502143928,1,'2020-01-01 01:01:01'),(38,20170504130602,1,'2020-01-01 01:01:01'),(39,20170509132100,1,'2020-01-01 01:01:01'),(40,20170519105647,1,'2020-01-01 01:01:01'),(41,20170519105648,1,'2020-01-01 01:01:01'),(42,20170831234300,1,'2020-01-01 01:01:01'),(43,20170831234301,1,'2020-01-01 01:01:01'),(44,20170831234303,1,'2020-01-01 01:01:01'),(45,20171116163618,1,'2020-01-01 01:01:01'),(46,20171219164727,1,'2020-01-01 01:01:01'),(47,20180620164811,1,'2020-01-01 01:01:01'),(48,20180620175054,1,'2020-01-01 01:01:01'),(49,20180620175055,1,'2020-01-01 01:01:01'),(50,20191010101639,1,'2020-01-01 01:01:01'),(51,20191010155147,1,'2020-01-01 01:01:01'),(52,20191220130734,1,'2020-01-01 01:01:01'),(53,20200311140000,1,'2020-01-01 01:01:01'),(54,20200405120000,1,'2020-01-01 01:01:01'),(55,20200407120000,1,'2020-01-01 01:01:01'),(56,20200420120000,1,'2020-01-01 01:01:01'),(57,20200504120000,1,'2020-01-01 01:01:01'),(58,20200512120000,1,'2020-01-01 01:01:01'),(59,20200707120000,1,'2020-01-01 01:01:01'),(60,20201011162341,1,'2020-01-01 01:01:01'),(61,20201021104586,1,'2020-01-01 01:01:01'),(62,20201102112520,1,'2020-01-01 01:01:01'),(63,20201208121729,1,'2020-01-01 01:01:01'),(64,20201215091637,1,'2020-01-01 01:01:01'),(65,20210119174155,1,'2020-01-01 01:01:01'),(66,20210326182902,1,'2020-01-01 01:01:01'),(67,20210421112652,1,'2020-01-01 01:01:01'),(68,20210506095025,1,'2020-01-01 01:01:01'),(69,20210513115729,1,'2020-01-01 01:01:01'),(70,20210526113559,1,'2020-01-01 01:01:01'),(71,20210601000001,1,'2020-01-01 01:01:01'),(72,20210601000002,1,'2020-01-01 01:01:01'),(73,20210601000003,1,'2020-01-01 01:01:01'),(74,20210601000004,1,'2020-01-01 01:01:01'),(75,20210601000005,1,'2020-01-01 01:01:01'),(76,20210601000006,1,'2020-01-01 01:01:01'),(77,20210601000007,1,'2020-01-01 01:01:01'),(78,20210601000008,1,'2020-01-01 01:01:01'),(79,20210606151329,1,'2020-01-01 01:01:01'),(80,20210616163757,1,'2020-01-01 01:01:01'),(81,20210617174723,1,'2020-01-01 01:01:01'),(82,20210622160235,1,'2020-01-01 01:01:01'),(83,20210623100031,1,'2020-01-01 01:01:01'),(84,20210623133615,1,'2020-01-01 01:01:01'),(85,20210708143152,1,'2020-01-01 01:01:01'),(86,20210709124443,1,'2020-01-01 01:01:01'),(87,20210712155608,1,'2020-01-01 01:01:01'),(88,20210714102108,1,'2020-01-01 01:01:01'),(89,20210719153709,1,'2020-01-01 01:01:01'),(90,20210721171531,1,'2020-01-01 01:01:01'),(91,20210723135713,1,'2020-01-01 01:01:01'),(92,20210802135933,1,'2020-01-01 01:01:01'),(93,20210806112844,1,'2020-01-01 01:01:01'),(94,20210810095603,1,'2020-01-01 01:01:01'),(95,20210811150223,1,'2020-01-01 01:01:01'),(96,20210818151827,1,'2020-01-01 01:01:01'),(97,20210818151828,1,'2020-01-01 01:01:01'),(98,20210818182258,1,'2020-01-01 01:01:01'),(99,20210819131107,1,'2020-01-01 01:01:01'),(100,20210819143446,1,'2020-01-01 01:01:01'),(101,20210903132338,1,'2020-01-01 01:01:01'),(102,20210915144307,1,'2020-01-01 01:01:01'),(103,20210920155130,1,'2020-01-01 01:01:01'),(104,20210924114500,1,'2020-01-01 01:01:01'),(105,20210927143115,1,'2020-01-01 01:01:01');
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8 */;
|
||||
CREATE TABLE `network_interfaces` (
|
||||
|
|
@ -516,6 +516,7 @@ CREATE TABLE `software` (
|
|||
`name` varchar(255) NOT NULL,
|
||||
`version` varchar(255) NOT NULL DEFAULT '',
|
||||
`source` varchar(64) NOT NULL,
|
||||
`bundle_identifier` varchar(255) DEFAULT '',
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `idx_name_version` (`name`,`version`,`source`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||
|
|
|
|||
|
|
@ -11,9 +11,10 @@ import (
|
|||
)
|
||||
|
||||
const (
|
||||
maxSoftwareNameLen = 255
|
||||
maxSoftwareVersionLen = 255
|
||||
maxSoftwareSourceLen = 64
|
||||
maxSoftwareNameLen = 255
|
||||
maxSoftwareVersionLen = 255
|
||||
maxSoftwareSourceLen = 64
|
||||
maxSoftwareBundleIdentifierLen = 255
|
||||
)
|
||||
|
||||
func truncateString(str string, length int) string {
|
||||
|
|
@ -24,15 +25,16 @@ func truncateString(str string, length int) string {
|
|||
}
|
||||
|
||||
func softwareToUniqueString(s fleet.Software) string {
|
||||
return strings.Join([]string{s.Name, s.Version, s.Source}, "\u0000")
|
||||
return strings.Join([]string{s.Name, s.Version, s.Source, s.BundleIdentifier}, "\u0000")
|
||||
}
|
||||
|
||||
func uniqueStringToSoftware(s string) fleet.Software {
|
||||
parts := strings.Split(s, "\u0000")
|
||||
return fleet.Software{
|
||||
Name: truncateString(parts[0], maxSoftwareNameLen),
|
||||
Version: truncateString(parts[1], maxSoftwareVersionLen),
|
||||
Source: truncateString(parts[2], maxSoftwareSourceLen),
|
||||
Name: truncateString(parts[0], maxSoftwareNameLen),
|
||||
Version: truncateString(parts[1], maxSoftwareVersionLen),
|
||||
Source: truncateString(parts[2], maxSoftwareSourceLen),
|
||||
BundleIdentifier: truncateString(parts[3], maxSoftwareBundleIdentifierLen),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -171,8 +173,8 @@ func getOrGenerateSoftwareIdDB(ctx context.Context, tx sqlx.ExtContext, s fleet.
|
|||
}
|
||||
|
||||
result, err := tx.ExecContext(ctx,
|
||||
`INSERT IGNORE INTO software (name, version, source) VALUES (?, ?, ?)`,
|
||||
s.Name, s.Version, s.Source,
|
||||
`INSERT IGNORE INTO software (name, version, source, bundle_identifier) VALUES (?, ?, ?, ?)`,
|
||||
s.Name, s.Version, s.Source, s.BundleIdentifier,
|
||||
)
|
||||
if err != nil {
|
||||
return 0, errors.Wrap(err, "insert software")
|
||||
|
|
@ -222,7 +224,7 @@ func listSoftwareDB(ctx context.Context, q sqlx.QueryerContext, hostID *uint, te
|
|||
teamWhere = "TRUE"
|
||||
}
|
||||
sql := fmt.Sprintf(`
|
||||
SELECT DISTINCT s.id, s.name, s.version, s.source, coalesce(scp.cpe, "") as generated_cpe
|
||||
SELECT DISTINCT s.*, coalesce(scp.cpe, "") as generated_cpe
|
||||
FROM host_software hs
|
||||
JOIN hosts h ON (hs.host_id=h.id)
|
||||
JOIN software s ON (hs.software_id=s.id)
|
||||
|
|
|
|||
|
|
@ -58,23 +58,19 @@ func testSoftwareSaveHost(t *testing.T, ds *Datastore) {
|
|||
Software: []fleet.Software{
|
||||
{Name: "foo", Version: "0.0.2", Source: "chrome_extensions"},
|
||||
{Name: "foo", Version: "0.0.3", Source: "chrome_extensions"},
|
||||
{Name: "bar", Version: "0.0.3", Source: "deb_packages"},
|
||||
{Name: "bar", Version: "0.0.3", Source: "deb_packages", BundleIdentifier: "com.some.identifier"},
|
||||
},
|
||||
}
|
||||
host2.HostSoftware = soft2
|
||||
|
||||
err := ds.SaveHostSoftware(context.Background(), host1)
|
||||
require.NoError(t, err)
|
||||
err = ds.SaveHostSoftware(context.Background(), host2)
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, ds.SaveHostSoftware(context.Background(), host1))
|
||||
require.NoError(t, ds.SaveHostSoftware(context.Background(), host2))
|
||||
|
||||
err = ds.LoadHostSoftware(context.Background(), host1)
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, ds.LoadHostSoftware(context.Background(), host1))
|
||||
assert.False(t, host1.HostSoftware.Modified)
|
||||
test.ElementsMatchSkipID(t, soft1.Software, host1.HostSoftware.Software)
|
||||
|
||||
err = ds.LoadHostSoftware(context.Background(), host2)
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, ds.LoadHostSoftware(context.Background(), host2))
|
||||
assert.False(t, host2.HostSoftware.Modified)
|
||||
test.ElementsMatchSkipID(t, soft2.Software, host2.HostSoftware.Software)
|
||||
|
||||
|
|
@ -93,18 +89,14 @@ func testSoftwareSaveHost(t *testing.T, ds *Datastore) {
|
|||
}
|
||||
host2.HostSoftware = soft2
|
||||
|
||||
err = ds.SaveHostSoftware(context.Background(), host1)
|
||||
require.NoError(t, err)
|
||||
err = ds.SaveHostSoftware(context.Background(), host2)
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, ds.SaveHostSoftware(context.Background(), host1))
|
||||
require.NoError(t, ds.SaveHostSoftware(context.Background(), host2))
|
||||
|
||||
err = ds.LoadHostSoftware(context.Background(), host1)
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, ds.LoadHostSoftware(context.Background(), host1))
|
||||
assert.False(t, host1.HostSoftware.Modified)
|
||||
test.ElementsMatchSkipID(t, soft1.Software, host1.HostSoftware.Software)
|
||||
|
||||
err = ds.LoadHostSoftware(context.Background(), host2)
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, ds.LoadHostSoftware(context.Background(), host2))
|
||||
assert.False(t, host2.HostSoftware.Modified)
|
||||
test.ElementsMatchSkipID(t, soft2.Software, host2.HostSoftware.Software)
|
||||
|
||||
|
|
@ -117,11 +109,9 @@ func testSoftwareSaveHost(t *testing.T, ds *Datastore) {
|
|||
}
|
||||
host1.HostSoftware = soft1
|
||||
|
||||
err = ds.SaveHostSoftware(context.Background(), host1)
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, ds.SaveHostSoftware(context.Background(), host1))
|
||||
|
||||
err = ds.LoadHostSoftware(context.Background(), host1)
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, ds.LoadHostSoftware(context.Background(), host1))
|
||||
assert.False(t, host1.HostSoftware.Modified)
|
||||
test.ElementsMatchSkipID(t, soft1.Software, host1.HostSoftware.Software)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,6 +12,8 @@ type Software struct {
|
|||
Name string `json:"name" db:"name"`
|
||||
// Version is reported version.
|
||||
Version string `json:"version" db:"version"`
|
||||
// BundleIdentifier is the CFBundleIdentifier label from the info properties
|
||||
BundleIdentifier string `json:"bundle_identifier,omitempty" db:"bundle_identifier"`
|
||||
// Source is the source of the data (osquery table name).
|
||||
Source string `json:"source" db:"source"`
|
||||
|
||||
|
|
|
|||
|
|
@ -360,6 +360,7 @@ SELECT
|
|||
name AS name,
|
||||
bundle_short_version AS version,
|
||||
'Application (macOS)' AS type,
|
||||
bundle_identifier AS bundle_identifier,
|
||||
'apps' AS source
|
||||
FROM apps
|
||||
UNION
|
||||
|
|
@ -367,6 +368,7 @@ SELECT
|
|||
name AS name,
|
||||
version AS version,
|
||||
'Package (Python)' AS type,
|
||||
'' AS bundle_identifier,
|
||||
'python_packages' AS source
|
||||
FROM python_packages
|
||||
UNION
|
||||
|
|
@ -374,6 +376,7 @@ SELECT
|
|||
name AS name,
|
||||
version AS version,
|
||||
'Browser plugin (Chrome)' AS type,
|
||||
'' AS bundle_identifier,
|
||||
'chrome_extensions' AS source
|
||||
FROM chrome_extensions
|
||||
UNION
|
||||
|
|
@ -381,6 +384,7 @@ SELECT
|
|||
name AS name,
|
||||
version AS version,
|
||||
'Browser plugin (Firefox)' AS type,
|
||||
'' AS bundle_identifier,
|
||||
'firefox_addons' AS source
|
||||
FROM firefox_addons
|
||||
UNION
|
||||
|
|
@ -388,6 +392,7 @@ SELECT
|
|||
name As name,
|
||||
version AS version,
|
||||
'Browser plugin (Safari)' AS type,
|
||||
'' AS bundle_identifier,
|
||||
'safari_extensions' AS source
|
||||
FROM safari_extensions
|
||||
UNION
|
||||
|
|
@ -395,6 +400,7 @@ SELECT
|
|||
name AS name,
|
||||
version AS version,
|
||||
'Package (Homebrew)' AS type,
|
||||
'' AS bundle_identifier,
|
||||
'homebrew_packages' AS source
|
||||
FROM homebrew_packages;
|
||||
`,
|
||||
|
|
@ -545,6 +551,7 @@ func ingestSoftware(logger log.Logger, host *fleet.Host, rows []map[string]strin
|
|||
name := row["name"]
|
||||
version := row["version"]
|
||||
source := row["source"]
|
||||
bundleIdentifier := row["bundle_identifier"]
|
||||
if name == "" {
|
||||
level.Debug(logger).Log(
|
||||
"msg", "host reported software with empty name",
|
||||
|
|
@ -563,7 +570,7 @@ func ingestSoftware(logger log.Logger, host *fleet.Host, rows []map[string]strin
|
|||
)
|
||||
continue
|
||||
}
|
||||
s := fleet.Software{Name: name, Version: version, Source: source}
|
||||
s := fleet.Software{Name: name, Version: version, Source: source, BundleIdentifier: bundleIdentifier}
|
||||
software.Software = append(software.Software, s)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -713,7 +713,7 @@ func TestDetailQueries(t *testing.T) {
|
|||
lq.On("QueriesForHost", host.ID).Return(map[string]string{}, nil)
|
||||
|
||||
ds.AppConfigFunc = func(ctx context.Context) (*fleet.AppConfig, error) {
|
||||
return &fleet.AppConfig{HostSettings: fleet.HostSettings{EnableHostUsers: true}}, nil
|
||||
return &fleet.AppConfig{HostSettings: fleet.HostSettings{EnableHostUsers: true, EnableSoftwareInventory: true}}, nil
|
||||
}
|
||||
ds.LabelQueriesForHostFunc = func(context.Context, *fleet.Host) (map[string]string, error) {
|
||||
return map[string]string{}, nil
|
||||
|
|
@ -725,8 +725,8 @@ func TestDetailQueries(t *testing.T) {
|
|||
// With a new host, we should get the detail queries (and accelerated
|
||||
// queries)
|
||||
queries, acc, err := svc.GetDistributedQueries(ctx)
|
||||
assert.Nil(t, err)
|
||||
assert.Len(t, queries, expectedDetailQueries)
|
||||
require.NoError(t, err)
|
||||
assert.Len(t, queries, expectedDetailQueries+1)
|
||||
assert.NotZero(t, acc)
|
||||
|
||||
resultJSON := `
|
||||
|
|
@ -826,6 +826,19 @@ func TestDetailQueries(t *testing.T) {
|
|||
"groupname": "somegroup"
|
||||
}
|
||||
],
|
||||
"fleet_detail_query_software_macos": [
|
||||
{
|
||||
"name": "app1",
|
||||
"version": "1.0.0",
|
||||
"source": "source1"
|
||||
},
|
||||
{
|
||||
"name": "app2",
|
||||
"version": "1.0.0",
|
||||
"source": "source2",
|
||||
"bundle_identifier": "somebundle"
|
||||
}
|
||||
],
|
||||
"fleet_detail_query_disk_space_unix": [
|
||||
{
|
||||
"percent_disk_space_available": "56",
|
||||
|
|
@ -882,6 +895,22 @@ func TestDetailQueries(t *testing.T) {
|
|||
GroupName: "somegroup",
|
||||
}, gotHost.Users[0])
|
||||
|
||||
// software
|
||||
require.Len(t, gotHost.HostSoftware.Software, 2)
|
||||
assert.Equal(t, []fleet.Software{
|
||||
{
|
||||
Name: "app1",
|
||||
Version: "1.0.0",
|
||||
Source: "source1",
|
||||
},
|
||||
{
|
||||
Name: "app2",
|
||||
Version: "1.0.0",
|
||||
BundleIdentifier: "somebundle",
|
||||
Source: "source2",
|
||||
},
|
||||
}, gotHost.HostSoftware.Software)
|
||||
|
||||
assert.Equal(t, 56.0, gotHost.PercentDiskSpaceAvailable)
|
||||
assert.Equal(t, 277.0, gotHost.GigsDiskSpaceAvailable)
|
||||
|
||||
|
|
@ -902,7 +931,7 @@ func TestDetailQueries(t *testing.T) {
|
|||
|
||||
queries, acc, err = svc.GetDistributedQueries(ctx)
|
||||
assert.Nil(t, err)
|
||||
assert.Len(t, queries, expectedDetailQueries)
|
||||
assert.Len(t, queries, expectedDetailQueries+1)
|
||||
assert.Zero(t, acc)
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue