Persist download URL when adding FMAs via non-GitOps API, fix software versions on GitOps YAML generation (#30331)
Fixes #29618, #30282. # Checklist for submitter If some of the following don't apply, delete the relevant line. <!-- Note that API documentation changes are now addressed by the product design team. --> - [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. - [x] Input data is properly validated, `SELECT *` is avoided, SQL injection is prevented (using placeholders for values in statements) - [x] Added/updated automated tests - [x] Manual QA for all new/changed functionality
This commit is contained in:
@@ -0,0 +1 @@
|
||||
* Fixed software package version output in generated GitOps YAML
|
||||
@@ -0,0 +1 @@
|
||||
* Recorded installer URL when a Fleet-maintained app is added via the web UI or REST API
|
||||
@@ -1122,10 +1122,6 @@ func (cmd *GenerateGitopsCommand) generateSoftware(filePath string, teamId uint,
|
||||
packages := make([]map[string]interface{}, 0)
|
||||
appStoreApps := make([]map[string]interface{}, 0)
|
||||
for _, sw := range software {
|
||||
versions := make([]string, len(sw.Versions))
|
||||
for j, version := range sw.Versions {
|
||||
versions[j] = version.Version
|
||||
}
|
||||
softwareSpec := make(map[string]interface{})
|
||||
switch {
|
||||
case sw.SoftwarePackage != nil:
|
||||
@@ -1133,7 +1129,7 @@ func (cmd *GenerateGitopsCommand) generateSoftware(filePath string, teamId uint,
|
||||
if sw.SoftwarePackage.Name != "" {
|
||||
pkgName = fmt.Sprintf(" (%s)", sw.SoftwarePackage.Name)
|
||||
}
|
||||
comment := cmd.AddComment(filePath, fmt.Sprintf("%s%s version %s", sw.Name, pkgName, strings.Join(versions, ", ")))
|
||||
comment := cmd.AddComment(filePath, fmt.Sprintf("%s%s version %s", sw.Name, pkgName, sw.SoftwarePackage.Version))
|
||||
if sw.HashSHA256 == nil {
|
||||
cmd.Messages.Notes = append(cmd.Messages.Notes, Note{
|
||||
Filename: filePath,
|
||||
|
||||
@@ -201,31 +201,18 @@ func (MockClient) ListSoftwareTitles(query string) ([]fleet.SoftwareTitleListRes
|
||||
case "available_for_install=1&team_id=1":
|
||||
return []fleet.SoftwareTitleListResult{
|
||||
{
|
||||
ID: 1,
|
||||
Name: "My Software Package",
|
||||
Versions: []fleet.SoftwareVersion{{
|
||||
ID: 1,
|
||||
Version: "1.0.0",
|
||||
}, {
|
||||
ID: 2,
|
||||
Version: "2.0.0",
|
||||
}},
|
||||
ID: 1,
|
||||
Name: "My Software Package",
|
||||
HashSHA256: ptr.String("software-package-hash"),
|
||||
SoftwarePackage: &fleet.SoftwarePackageOrApp{
|
||||
Name: "my-software.pkg",
|
||||
Platform: "darwin",
|
||||
Version: "13.37",
|
||||
},
|
||||
},
|
||||
{
|
||||
ID: 2,
|
||||
Name: "My App Store App",
|
||||
Versions: []fleet.SoftwareVersion{{
|
||||
ID: 3,
|
||||
Version: "5.6.7",
|
||||
}, {
|
||||
ID: 4,
|
||||
Version: "8.9.10",
|
||||
}},
|
||||
AppStoreApp: &fleet.SoftwarePackageOrApp{
|
||||
AppStoreID: "com.example.team-software",
|
||||
},
|
||||
|
||||
+1
-1
@@ -64,7 +64,7 @@ software:
|
||||
- Label C
|
||||
- Label D
|
||||
packages:
|
||||
- hash_sha256: software-package-hash # My Software Package (my-software.pkg) version 1.0.0, 2.0.0
|
||||
- hash_sha256: software-package-hash # My Software Package (my-software.pkg) version 13.37
|
||||
install_script:
|
||||
path: ../lib/team-a/scripts/my-software-package-darwin-install
|
||||
labels_include_any:
|
||||
|
||||
@@ -150,6 +150,7 @@ func (svc *Service) AddFleetMaintainedApp(
|
||||
AutomaticInstall: automaticInstall,
|
||||
AutomaticInstallQuery: app.AutomaticInstallQuery,
|
||||
Categories: app.Categories,
|
||||
URL: app.InstallerURL,
|
||||
}
|
||||
|
||||
payload.Categories = server.RemoveDuplicatesFromSlice(payload.Categories)
|
||||
|
||||
@@ -281,17 +281,6 @@ func TestAddFleetMaintainedApp(t *testing.T) {
|
||||
UniqueIdentifier: "Internet Exploder",
|
||||
}, nil
|
||||
}
|
||||
ds.MatchOrCreateSoftwareInstallerFunc = func(ctx context.Context, payload *fleet.UploadSoftwareInstallerPayload) (uint, uint, error) {
|
||||
require.Equal(t, spoofedSHA, payload.StorageID)
|
||||
require.Empty(t, payload.BundleIdentifier)
|
||||
require.Equal(t, "Internet Exploder", payload.Title)
|
||||
require.Equal(t, "programs", payload.Source)
|
||||
require.Equal(t, "Hello World!", payload.InstallScript)
|
||||
require.Equal(t, "Hello World!", payload.UninstallScript)
|
||||
|
||||
// Can't easily inject a proper fleet.service so we bail early before NewActivity gets called and panics
|
||||
return 0, 0, errors.New("forced error to short-circuit storage and activity creation")
|
||||
}
|
||||
ds.GetSoftwareCategoryIDsFunc = func(ctx context.Context, names []string) ([]uint, error) {
|
||||
return []uint{}, nil
|
||||
}
|
||||
@@ -301,6 +290,18 @@ func TestAddFleetMaintainedApp(t *testing.T) {
|
||||
_, _ = w.Write(installerBytes)
|
||||
}))
|
||||
defer installerServer.Close()
|
||||
ds.MatchOrCreateSoftwareInstallerFunc = func(ctx context.Context, payload *fleet.UploadSoftwareInstallerPayload) (uint, uint, error) {
|
||||
require.Equal(t, spoofedSHA, payload.StorageID)
|
||||
require.Empty(t, payload.BundleIdentifier)
|
||||
require.Equal(t, "Internet Exploder", payload.Title)
|
||||
require.Equal(t, "programs", payload.Source)
|
||||
require.Equal(t, "Hello World!", payload.InstallScript)
|
||||
require.Equal(t, "Hello World!", payload.UninstallScript)
|
||||
require.Equal(t, installerServer.URL+"/iexplode.exe", payload.URL)
|
||||
|
||||
// Can't easily inject a proper fleet.service so we bail early before NewActivity gets called and panics
|
||||
return 0, 0, errors.New("forced error to short-circuit storage and activity creation")
|
||||
}
|
||||
|
||||
// Mock server to serve the manifest
|
||||
manifestServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
@@ -326,6 +327,7 @@ func TestAddFleetMaintainedApp(t *testing.T) {
|
||||
err := json.NewEncoder(w).Encode(manifest)
|
||||
require.NoError(t, err)
|
||||
}))
|
||||
|
||||
t.Cleanup(manifestServer.Close)
|
||||
os.Setenv("FLEET_DEV_MAINTAINED_APPS_BASE_URL", manifestServer.URL)
|
||||
defer os.Unsetenv("FLEET_DEV_MAINTAINED_APPS_BASE_URL")
|
||||
|
||||
@@ -479,8 +479,12 @@ func testGetMaintainedAppBySlug(t *testing.T, ds *Datastore) {
|
||||
Platform: string(fleet.MacOSPlatform),
|
||||
BundleIdentifier: maintainedApp.UniqueIdentifier,
|
||||
ValidatedLabels: &fleet.LabelIdentsWithScope{},
|
||||
URL: "https://example.com/maintained-app-team1.pkg",
|
||||
})
|
||||
require.NoError(t, err)
|
||||
installer1, err := ds.GetSoftwareInstallerMetadataByTeamAndTitleID(ctx, &team1.ID, titleId1, false)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, "https://example.com/maintained-app-team1.pkg", installer1.URL)
|
||||
|
||||
// maintained app 2
|
||||
maintainedApp2, err := ds.UpsertMaintainedApp(ctx, &fleet.MaintainedApp{
|
||||
|
||||
@@ -211,8 +211,9 @@ INSERT INTO software_installers (
|
||||
user_id,
|
||||
user_name,
|
||||
user_email,
|
||||
fleet_maintained_app_id
|
||||
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, (SELECT name FROM users WHERE id = ?), (SELECT email FROM users WHERE id = ?), ?)`
|
||||
fleet_maintained_app_id,
|
||||
url
|
||||
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, (SELECT name FROM users WHERE id = ?), (SELECT email FROM users WHERE id = ?), ?, ?)`
|
||||
|
||||
args := []interface{}{
|
||||
tid,
|
||||
@@ -233,6 +234,7 @@ INSERT INTO software_installers (
|
||||
payload.UserID,
|
||||
payload.UserID,
|
||||
payload.FleetMaintainedAppID,
|
||||
payload.URL,
|
||||
}
|
||||
|
||||
res, err := tx.ExecContext(ctx, stmt, args...)
|
||||
|
||||
Reference in New Issue
Block a user