40 Commits
Author SHA1 Message Date
Jonathan Katz 45abf8c9ad Add software installer upload/download progress to GitOps runs (#50250)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or
remove if NA -->
**Related issue:** Resolves #45728
Changes:
- Adds a new redis key to keep track of downloaded packages. It starts
out with an empty list and gets filled with each download. Each update
writes the entire struct at once to the key.
- Adds logging in the fleetctl gitops client to show which packages were
downloaded
- Fixes the categories key potentially expiring 

# Checklist for submitter

If some of the following don't apply, delete the relevant line.

- [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.

- [ ] Input data is properly validated, `SELECT *` is avoided, SQL
injection is prevented (using placeholders for values in statements), JS
inline code is prevented especially for url redirects, and untrusted
data interpolated into shell scripts/commands is validated against shell
metacharacters.
-  Timeouts are implemented and retries are limited to avoid infinite
loops
- Right now the batch will write the whole slice of all packages to a
single redis key for every package in the loop. Looks like performance
is acceptable for now (500 packages), but maybe this will need to be
limited.
- [ ] If paths of existing endpoints are modified without backwards
compatibility, checked the frontend/CLI for any necessary changes

## Testing

- [x] Added/updated automated tests
- [ ] Where appropriate, [automated tests simulate multiple hosts and
test for host
isolation](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/reference/patterns-backend.md#unit-testing)
(updates to one hosts's records do not affect another)

- [x] QA'd all new/changed functionality manually



<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

## New Features
- Added per-package software download progress in fleetctl GitOps.
- Progress now reports downloading, completed, skipped, and failed
packages during real and dry runs.
- Installation output now distinguishes applying and applied stages.

## Bug Fixes
- Improved download error messages and cached-package handling.
- Prevented duplicate progress messages and ensured tracking issues do
not interrupt successful software batches.

## Tests
- Expanded coverage for progress reporting, failures, dry runs, package
types, and authorization scenarios.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-31 21:36:44 -04:00
Carlo a442d7af3a Python script-only packages: follow-on QA fixes (#50143)
**Related issues:** Resolves #50068, Resolves #50106, Resolves #50107,
Resolves #50108, Resolves #50110, Resolves #50114

Follow-on fixes from QA of #41470 (Python script-only packages):

- Software-installer validation errors are action-neutral, so the Add
and Edit flows each show the correct single verb, and the
unsupported-file error names a content/format mismatch instead of
blaming the extension (#50068, #50107).
- `.py` packages accept `setup_experience_platform` (`darwin`/`linux`),
matching `.sh` (#50106).
- A failed-to-run install script (exit code `-1`) now renders a
diagnostic instead of empty output, and orbit surfaces the underlying
execve error (#50108).
- The install-rejection message for `.sh`/`.py` packages says "macOS and
Linux hosts" instead of "linux" (#50110).
- Orbit writes each script's temp file with an extension matching its
shebang (`.py`/`.sh`/`.ps1`), so tracebacks reference the right file
type (#50114).

# Checklist for submitter

- [x] Changes file added for user-visible changes in `changes/`.

## Testing

- [x] Added/updated automated tests
- [x] QA'd all new/changed functionality manually

## fleetd/orbit/Fleet Desktop

- [x] If the change applies to only one platform, confirmed that
`runtime.GOOS` is used as needed to isolate changes.
- [x] Verified compatibility with the latest released version of Fleet
(orbit-only change; the server↔agent `SoftwareInstallDetails` contract
is unchanged).


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **Bug Fixes**
* Improved installer validation and rejection messaging for
unsupported/invalid package contents (including correcting “add” vs
“edit” wording and avoiding duplicated phrasing).
* Added clearer diagnostics when install scripts fail to start
(including empty output cases).
* Corrected handling of script-only packages so Python scripts use the
proper script type/extension, reducing misleading tracebacks.
* Updated platform availability messaging so `.sh`/`.py` packages
display macOS+Linux support.
* **New Features**
* Python script-only packages can now specify macOS and Linux setup
experience platforms.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-30 14:40:24 -04:00
Carlo 57bab9e5ec Allow Python script-only packages (#49070)
**Related issue:** Resolves #41470

Adds support for uploading Python (`.py`) script-only software packages
— accepted as script-only (the file contents become the install script;
advanced options and automatic install follow `.sh`/`.ps1`), assigned
the new `py_packages` source, and installable on macOS and Linux hosts
across the UI, REST API, and GitOps.

Feature branch combining the backend (#48942) and frontend (#48946)
sub-PRs.

# Checklist for submitter

- [x] Changes file added for user-visible changes in `changes/`,
`orbit/changes/` or `ee/fleetd-chrome/changes`.
- [x] Input data is properly validated, `SELECT *` is avoided, SQL
injection is prevented (using placeholders for values in statements), JS
inline code is prevented especially for url redirects, and untrusted
data interpolated into shell scripts/commands is validated against shell
metacharacters.

## Testing

- [x] Added/updated automated tests
- [x] QA'd all new/changed functionality manually


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Added support for Python (`.py`) script-only software packages across
UI uploads, API/self-service installs, and GitOps parsing.
* Python installers now derive metadata correctly and render the proper
Python icon, with install eligibility for macOS & Linux.
* **Bug Fixes**
* Improved installer-script validation and “supported file types” error
messages to include `.py` (and consistent handling of related script
fields/options).
* **Tests**
* Expanded unit, integration, and GitOps tests to cover Python package
parsing, metadata derivation, platform/host eligibility, and UI
rendering.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-16 14:20:03 -04:00
Steven Palmesano 20c0963331 Fix GitOps when using All fleets in VPP settings (#46855)
**Related issue:** Resolves #46824

# Checklist for submitter

- [x] Changes file added for user-visible changes in `changes/`,
`orbit/changes/` or `ee/fleetd-chrome/changes`.

## Testing

- [x] QA'd all new/changed functionality manually

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **Bug Fixes**
* Fixed an issue where volume purchasing program assignments failed when
"All fleets" was selected; validation and token assignment now treat the
"All fleets" label consistently, preventing errors during configuration
application.
* **Tests**
* Added an end-to-end GitOps test case verifying "All fleets" is
supported for volume purchasing program entries.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-06-08 13:27:57 -05:00
Jonathan Katz e34126ab3a Merge branch 'main' of github.com:fleetdm/fleet into feat/39018-self-service-categories
Bump migration, fix failing test and nilaway check
2026-06-08 12:12:33 -04:00
Scott Gress 07df7c5cfd Track software deletions in GitOps (#46764)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or
remove if NA -->
**Related issue:** Resolves #43729

# Details

Adds output to GitOps runs indicating which custom/FMA software packages
would be deleted. This involves adding a `deleted_packages` key to the
`/software/batch/:request_uuid` ("Get status of software batch-apply
request") API, which will be documented separately.

# Checklist for submitter

If some of the following don't apply, delete the relevant line.

- [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), JS
inline code is prevented especially for url redirects, and untrusted
data interpolated into shell scripts/commands is validated against shell
metacharacters.

## Testing

- [X] Added/updated automated tests
- [X] QA'd all new/changed functionality manually
- [X] verified that a GitOps dry run produces one "would've deleted"
line per custom package / fma that would be deleted
- [X] verified that a GitOps real run produces one "deleted" line per
custom package / fma that was deleted
  - [X] verified that adding software is unaffected



<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* GitOps batch software operations now report packages pending deletion:
dry-runs show "would've deleted" warnings and real runs show deletions;
apply flows surface per-package deletion messages.
* Empty payload dry-run now still reports pending deletions when
applicable.

* **Tests**
* Added integration and datastore tests validating deletion-warning
output, pending-deletion detection, and related result handling.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-06-04 13:11:49 -05:00
Jonathan Katz a3338d032e Self service categories - GitOps support (#46671)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or
remove if NA -->
**Related issue:** Resolves #46392 
A few things in this PR:
- updated the conversion from old default category to the new ones with
the emoji included that was introduced in the feature branch. It takes
into account what exists in the database now so if an admin wants to add
for example "Productivity" without the emoji as a category it won't get
overwritten.
- updated a few places to ignore missing categories rather than error
(what we do for adding a single FMA currently)
- updated permissions for "gitops" users 
- added everything needed for gitops, generate-gitops support using the
existing endpoints from the last PR.

Didn't add logs like "[+] applied X self service categories" since it
wasn't mentioned in the docs, but wouldn't be too hard to add.


# Checklist for submitter


## Testing

- [x] Added/updated automated tests
- [ ] Where appropriate, [automated tests simulate multiple hosts and
test for host
isolation](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/reference/patterns-backend.md#unit-testing)
(updates to one hosts's records do not affect another)

- [x] QA'd all new/changed functionality manually

## New Fleet configuration settings

- [x] Verified that the setting is exported via `fleetctl
generate-gitops`
- [x] Verified the setting is documented in a separate PR to [the GitOps
documentation](https://github.com/fleetdm/fleet/blob/main/docs/Configuration/yaml-files.md#L485)
- [x] Verified that the setting is cleared on the server if it is not
supplied in a YAML file (or that it is documented as being optional)
- [ ] Verified that any relevant UI is disabled when GitOps mode is
enabled
    - Currently missing, at least on this branch
2026-06-03 15:23:44 -04:00
Scott Gress 2bd7fec8a7 Handle edge case of adding new fleet + vpp at the same time (#46533)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or
remove if NA -->
**Related issue:** Resolves #44444 

# Details

This PR fixes the following edge case when running `fleetctl gitops`:

1. A new fleet is added
2. That fleet is declared as an ABM default fleet and/or a fleet in a
VPP token location
3. The _other_ fleets declared as ABM defaults or VPP fleets are _not_
all provided in the GitOps run

In that case, the GitOps run would fail with an error that one of the
previously-existing fleets could not be found. This PR fixes the bug by
making sure that GitOps looks at both the currently-persisted fleets
(via the API) and any fleets that are being created in the current run.

# Checklist for submitter

If some of the following don't apply, delete the relevant line.

- [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
- Reproduced the issue on `main` by attempting to create a new fleet
_and_ add it both as an ABM default fleet and to the set of VPP token
users in a single run, and getting an error about one of the existing
fleets not being found
- Verified that I was able to complete a gitops run successfully on this
branch with a new fleet as a VPP token user and a default ABM fleet



<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

## Release Notes

* **Bug Fixes**
* Improved validation for Apple Business Manager and Volume Purchasing
Program token team assignments with clearer error messages when
referenced teams aren't found in Fleet.
* Enhanced team name matching to properly handle Unicode characters,
ensuring consistent team identification across GitOps configurations.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-06-02 14:47:54 -05:00
Jonathan Katz abd38218fa Self service categories endpoints + activities (#46593)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or
remove if NA -->
**Related issue:** Resolves #46391 

# Checklist for submitter

If some of the following don't apply, delete the relevant line.

- [ ] 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), JS
inline code is prevented especially for url redirects, and untrusted
data interpolated into shell scripts/commands is validated against shell
metacharacters.
- [ ] Timeouts are implemented and retries are limited to avoid infinite
loops
- [ ] If paths of existing endpoints are modified without backwards
compatibility, checked the frontend/CLI for any necessary changes

## Testing

- [x] Added/updated automated tests
- [ ] Where appropriate, [automated tests simulate multiple hosts and
test for host
isolation](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/reference/patterns-backend.md#unit-testing)
(updates to one hosts's records do not affect another)

- [x] QA'd all new/changed functionality manually
2026-06-01 15:53:06 -04:00
Lucas Manuel Rodriguez e447a685f0 Rename fleetctl's testing_utils.go to testing_utils_test.go and create separate test package (#45585)
Resolves #45220 (one of several PRs, we are very close)

## Testing

- [X] QA'd all new/changed functionality manually

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **Tests**
* Improved test infrastructure for the CLI: consolidated and renamed
test helpers, added a dedicated in-process CLI test helper, and updated
many test cases to use the new helpers.
* Tightened several test assertions and standardized output/error
validation across unit and integration tests to improve reliability.

<!-- review_stack_entry_start -->

[![Review Change
Stack](https://storage.googleapis.com/coderabbit_public_assets/review-stack-in-coderabbit-ui.svg)](https://app.coderabbit.ai/change-stack/fleetdm/fleet/pull/45585)

<!-- review_stack_entry_end -->
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-05-15 11:59:18 -03:00
Jonathan Katz fd7bf3118b Fix TestGitOpsTeamVPPAppleConfiguration failing (#45305)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or
remove if NA -->
**Related issue:** Resolves #

# Checklist for submitter

If some of the following don't apply, delete the relevant line.


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Tests**
* Updated test fixtures for Apple VPP configuration in GitOps workflows
to better reflect real-world scenarios.

[![Review Change
Stack](https://storage.googleapis.com/coderabbit_public_assets/review-stack-in-coderabbit-ui.svg)](https://app.coderabbit.ai/change-stack/fleetdm/fleet/pull/45305)

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-05-12 18:11:57 -04:00
Carloandjkatz01 55636b3ef6 iOS/iPadOS managed config: GitOps (#43969) (#44933)
Part of #38790. Stacked on top of #44932.

Closes #43969.

`fleetctl gitops` reads `configuration.path` for iOS / iPadOS VPP apps
and in-house `.ipa` apps, validates the file via
`fleet.ValidateAppleAppConfiguration`, and stores the bytes through the
service layer.

`fleetctl generate-gitops` emits `configuration.path` for apps that have
a stored configuration, writing the XML to
`lib/<team>/software/<app-slug>-config.xml`. Apps without configuration
omit the block entirely.

Round-trip integration tests
(`cmd/fleetctl/integrationtest/gitops/software_test.go`) cover apply +
generate for both VPP and in-house, plus a negative case for invalid
configuration content.

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

## Release Notes

* **New Features**
* Added managed app configuration support for enterprise software
deployments through GitOps
* Configurations now support platform-specific formats: XML for
iOS/iPadOS, JSON for Android
* Configuration validation ensures compatibility and prevents invalid
variable references

* **Tests**
* Added integration tests for configuration handling in software
deployment workflows

[![Review Change
Stack](https://storage.googleapis.com/coderabbit_public_assets/review-stack-in-coderabbit-ui.svg)](https://app.coderabbit.ai/change-stack/fleetdm/fleet/pull/44933)

<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: jkatz01 <yehonatankatz@gmail.com>
2026-05-12 14:15:25 -04:00
fc907c4634 Rename Apple Business 'Location' to 'Organization Unit' in UI and docs (#44833)
## Summary

- Renames Apple Business "Location" / "Locations" to "Organization Unit"
/ "Organization Units" across user-facing UI strings, documentation, and
code comments
- Updates the VPP table column header, modal text, error messages, audit
log descriptions, YAML configuration docs, and article guides
- Underlying API field names (`location` in JSON) and YAML config keys
remain unchanged for backward compatibility

---

Built for [Mel
Pike](https://fleetdm.slack.com/archives/D0AKX7DJFCN/p1778077861693279?thread_ts=1777299502.461149&cid=D0AKX7DJFCN)
by [Kilo for Slack](https://kilo.ai/slack)

---------

Co-authored-by: kiloconnect[bot] <240665456+kiloconnect[bot]@users.noreply.github.com>
Co-authored-by: melpike <melpike.dev@gmail.com>
Co-authored-by: Copilot <copilot@github.com>
Co-authored-by: melpike <79950145+melpike@users.noreply.github.com>
2026-05-12 12:03:08 -06:00
Marko LisicaandCarlo e988dd4756 Support VPP apps from non-US App Store regions (#44368)
**Related issue:** Resolves #43846

---------

Co-authored-by: Carlo <1778532+cdcme@users.noreply.github.com>
2026-05-06 12:01:07 -04:00
Carlo 07e4e7afe6 Short-circuit for empty software config in Gitops dry run (#44405)
Fixes #42607
2026-04-29 14:54:49 -04:00
Scott Gress 91d9b25924 Allow conditional downloads across fleets (#43679)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or
remove if NA -->
**Related issue:** Resolves #43417

# Checklist for submitter

If some of the following don't apply, delete the relevant line.

- [X] Changes file added for user-visible changes in `changes/`,
`orbit/changes/` or `ee/fleetd-chrome/changes`.
done in https://github.com/fleetdm/fleet/pull/42216

## Testing

- [X] Added/updated automated tests
- [X] QA'd all new/changed functionality manually
- Using a local fileserver, added the same software to two fleets and
ran `fleetctl gitops`. Verified that the first fleet downloaded the
file, the second fleet used the cache, and both fleet showed the
software installer in the UI.

## Summary by CodeRabbit

* **Chores**
* Updated software installer lookup mechanism to support optional
team-scoped searches, enabling fallback to cross-team installer cache
when team-specific installers are unavailable.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-04-21 17:06:23 -05:00
aff440236e Add cache option for software packages to skip re-downloading unchanged content (#42216)
**Related issue:** 
Ref #34797
Ref #42675 

## Problem

When a software installer spec has no `hash_sha256`, Fleet re-downloads
the package, re-extracts metadata, and re-upserts the DB on every GitOps
run, even if the upstream file hasn't changed. For deployments with 50+
URL-only packages across multiple teams, this wastes bandwidth and
processing time on every run.

## Solution

By default, use etags to avoid unnecessary downloads:

1. First run: Fleet downloads the package normally and stores the
server's ETag header
2. Subsequent runs: Fleet sends a conditional GET with `If-None-Match`.
If the server returns 304 Not Modified, Fleet skips the download,
metadata extraction, S3 upload, and DB upsert entirely

Opt-out with `always_download:true`, meaning packages continue to be
downloaded and re-processed on every run, same as today. No UI changes
needed.

```yaml
url: https://nvidia.gpcloudservice.com/global-protect/getmsi.esp?version=64&platform=windows
always_download: true
install_script:
  path: install.ps1
```

### Why conditional GET instead of HEAD

Fleet team [analysis of 276 maintained
apps](https://github.com/fleetdm/fleet/pull/42216#issuecomment-4105430061)
showed 7 apps where HEAD requests fail (405, 403, timeout) but GET works
for all. Conditional GET eliminates that failure class: if the server
doesn't support conditional requests, it returns 200 with the full body,
same as today.

### Why opt-in

5 of 276 apps (1.8%) have stale ETags (content changes but ETag stays
the same), caused by CDN caching artifacts (CloudFront, Cloudflare,
nginx inode-based ETags). The `cache` key lets users opt in per package
for URLs where they've verified ETag behavior is correct.

Validation rejects `always_download: true` when hash_sha256` is set

## Changes

- New YAML field: `cache` (bool, package-level)
- New migration: `http_etag` VARCHAR(512) column (explicit
`utf8mb4_unicode_ci` collation) + composite index `(global_or_team_id,
url(255))` on `software_installers`
- New datastore method: `GetInstallerByTeamAndURL`
- `downloadURLFn` accepts optional `If-None-Match` header, returns 304
as `(resp, nil, nil)` with `http.NoBody`
- ETag validated per RFC 7232 (ASCII printable only, no control chars,
max 512 bytes) at both write and read time
- Cache skipped for `.ipa` packages (multi-platform extraInstallers)
- TempFileReader and HTTP response leak prevention on download retry
- Docs updated in `yaml-files.md`

## What doesn't change

- Packages with `hash_sha256`: existing hash-based skip, untouched
- FMA packages: FMA version cache, untouched
- Packages with `always_download: true`: identical to current behavior
- Fleet UI: no changes

## Test plan

Automated testing:
- [x] 16 unit tests for `validETag`
- [x] 8 unit tests for conditional GET behavior (304, 200, 403, 500,
weak ETag, S3 multipart, no ETag)
- [x] MySQL integration test for `GetInstallerByTeamAndURL`
- [x] All 23 existing `TestSoftwareInstallers` datastore tests pass
- [x] All existing service tests pass

Manual testing:
- [x] E2E: 86 packages across 6 CDN patterns, second apply shows 51
conditional hits (304)
- [x] @sgress454 used a local fileserver tool to test w/ a new instance
and dummy packages


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* ETag-based conditional downloads to skip unchanged remote installer
files.
  * New always_download flag to force full re-downloads.

* **Tests**
* Added integration and unit tests covering conditional GETs, ETag
validation, retries, edge cases, and payload behavior.

* **Chores**
* Persist HTTP ETag and related metadata; DB migration and index to
speed installer lookups.
* Added installer lookup by team+URL to support conditional download
flow.

* **Bug Fix**
* Rejects using always_download together with an explicit SHA256 in
uploads.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Scott Gress <scott@fleetdm.com>
Co-authored-by: Scott Gress <scott@pigandcow.com>
Co-authored-by: Ian Littman <iansltx@gmail.com>
2026-04-14 13:01:33 -05:00
Carlo aa0c0674a8 Defer all VPP apps when there are missing teams (#42862)
Fixes #40785

## Summary

When a GitOps run includes a `volume_purchasing_program` config that
references a team that doesn't exist yet, the code temporarily removes
the entire VPP config from the global AppConfig, clearing ALL VPP
token-to-team assignments on the server. However, the code only deferred
`app_store_apps` for the missing teams, not for existing teams that also
lost their VPP assignments. Those existing teams then failed with "No
available VPP Token" when their `app_store_apps` were applied.

The fix widens the deferral scope to match the clearing scope. When VPP
assignments are temporarily cleared, `app_store_apps` are now deferred
for all teams in the VPP config, not just the missing ones.
2026-04-02 15:38:58 -04:00
Scott Gress 6598b608b7 Enforce GitOps exceptions (#42191)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or
remove if NA -->
**Related issue:** Resolves #42180 

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Enhanced GitOps exception handling for labels, secrets, and software
with clearer enforcement and omission semantics.
* Server-side prefetch of team software so omitted team software can
preserve existing installers during validation.
* Presence flags track whether top-level keys (labels, secrets,
software) were provided versus omitted.

* **Behavior Changes**
* Omitted vs empty sections are now distinguished: omission can mean
“no-op” or “delete-all” depending on exception settings.
* GitOps YAML can define and manage labels directly; validations now
reject YAML that includes keys marked as excepted.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

# Checklist for submitter

If some of the following don't apply, delete the relevant line.

- [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
    * **Labels**
- [ ] Validated that with label exceptions off, omitting `labels:` key
from default.yml clears all global labels
- [ ] Validated that with label exceptions off, omitting `labels:` key
from a fleet .yml clears all labels for that fleet
- [ ] Validated that with label exceptions off, setting empty `labels:`
key from default.yml clears all global labels
- [ ] Validated that with label exceptions off, setting empty `labels:`
key from a fleet .yml clears all labels for that fleet
- [ ] Validated that with label exceptions on, omitting `labels:` key
from default .yml leaves existing global labels as-is
- [ ] Validated that with label exceptions on, omitting `labels:` key
from a fleet .yml leaves existing labels as-is
- [ ] Validated that with label exceptions on, setting `labels:` key on
default .yml generates an error
- [ ] Validated that with label exceptions on, setting `labels:` key on
a fleet .yml generates an error
- [ ] Validated that with label exceptions on, a policy using
`labels_include_any` referencing an existing label succeeds without
`labels:` key
- [ ] Validated that with label exceptions on, a query using
`labels_include_any` referencing an existing label succeeds without
`labels:` key
- [ ] Validated that with label exceptions on, an MDM profile using
`labels_include_any` referencing an existing label succeeds without
`labels:` key
- [ ] Validated that with label exceptions on, a software package using
`labels_include_any` referencing an existing label succeeds without
`labels:` key (requires software exceptions off)
- [ ] Validated that with label exceptions on, an app store app using
`labels_include_any` referencing an existing label succeeds without
`labels:` key (requires software exceptions off)
- [ ] Validated that with label exceptions on, a fleet maintained app
using `labels_include_any` referencing an existing label succeeds
without `labels:` key (requires software exceptions off)
    * **Secrets**
- [ ] Validated that with secrets exceptions off, omitting `secrets:`
key from default.yml clears all global secrets
- [ ] Validated that with secrets exceptions off, omitting `secrets:`
key from a fleet .yml clears all secrets for that fleet
- [ ] Validated that with secrets exceptions on, omitting `secrets:` key
from default .yml leaves existing global secrets as-is
- [ ] Validated that with secrets exceptions on, omitting `secrets:` key
from a fleet .yml leaves existing secrets as-is
- [ ] Validated that with secrets exceptions on, setting `secrets:` key
on default .yml generates an error
- [ ] Validated that with secrets exceptions on, setting `secrets:` key
on a fleet .yml generates an error
    * **Software**
- [ ] Validated that with software exceptions off, omitting `software:`
key from no-team.yml/unassigned.yml clears all software for "no team"
- [ ] Validated that with software exceptions off, omitting `software:`
key from a fleet .yml clears all software for that fleet
- [ ] Validated that with software exceptions off, setting empty
`software:` key on a fleet .yml clears all software for that fleet
- [ ] Validated that with software exceptions off, setting empty
`software:` key on no-team.yml/unassigned.yml clears all software for
"no team
- [ ] Validated that with software exceptions on, omitting `software:`
key from a fleet .yml leaves existing software as-is
- [ ] Validated that with software exceptions on, setting `software:`
key on a fleet .yml generates an error
- [ ] Validated that with software exceptions on, omitting `software:`
key from no-team.yml/unassigned.yml leaves existing software as-is for
"no team"
- [ ] Validated that with software exceptions on, setting `software:`
key on no-team.yml/unassigned.yml generates an error
- [ ] Validated that with software exceptions on, a policy using
`install_software.hash_sha256` referencing an existing package succeeds
without `software:` key
- [ ] Validated that with software exceptions on, a policy using
`install_software.app_store_id` referencing an existing VPP app succeeds
without `software:` key
- [ ] Validated that with software exceptions on, a patch policy using
`fleet_maintained_app_slug` referencing an existing FMA succeeds without
`software:` key
- [ ] Validated that with software exceptions on,
`setup_experience.software` referencing existing software succeeds
without `software:` key (server-side validation fallback)
- [ ] Validated that with software exceptions on, omitting `software:`
from no-team.yml/unassigned.yml preserves existing no-team software
- [ ] Validated that with software exceptions on, a policy in
no-team.yml/unassigned.yml using `install_software.hash_sha256`
referencing existing no-team software succeeds without `software:` key
For unreleased bug fixes in a release candidate, one of:

- [X] Confirmed that the fix is not expected to adversely impact load
test results
I don't think so. There is a bit of overhead when this feature is used
since we have to fetch software from the server, but it would be done in
a specific test, so even if there is an impact it should affect existing
load testing, only new, specific tests.
2026-03-27 15:38:08 -05:00
Martin AngersandJahziel Villasana-Espinoza ba04887100 Backend: Support labels_include_all for installers/apps (#41324)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or
remove if NA -->
**Related issue:** Resolves #40721 

# Checklist for submitter

If some of the following don't apply, delete the relevant line.

- [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), JS
inline code is prevented especially for url redirects

## Testing

- [x] Added/updated automated tests
- [x] Where appropriate, [automated tests simulate multiple hosts and
test for host
isolation](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/reference/patterns-backend.md#unit-testing)
(updates to one hosts's records do not affect another)

- [ ] QA'd all new/changed functionality manually

I (Martin) did test `labels_include_all` for FMA, custom installer, IPA
and VPP apps, and it seemed to all work great for gitops apply and
gitops generate, **except for VPP apps** which seem to have 2 important
pre-existing bugs, see
https://github.com/fleetdm/fleet/issues/40723#issuecomment-4041780707

## New Fleet configuration settings

- [ ] Verified that the setting is exported via `fleetctl
generate-gitops`
- [ ] Verified the setting is documented in a separate PR to [the GitOps
documentation](https://github.com/fleetdm/fleet/blob/main/docs/Configuration/yaml-files.md#L485)
- [ ] Verified that the setting is cleared on the server if it is not
supplied in a YAML file (or that it is documented as being optional)
- [ ] Verified that any relevant UI is disabled when GitOps mode is
enabled

---------

Co-authored-by: Jahziel Villasana-Espinoza <jahziel@fleetdm.com>
2026-03-18 13:27:53 -04:00
Scott Gress 4305ca1840 Fix output from gitops to use "fleets" instead of "teams", "queries" instead of "reports" (#40610)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or
remove if NA -->
**Related issue:** Resolves #40621 

# Details

This PR updates the output from `fleetctl gitops` and `fleetctl apply`
to use the correct terminology:
* "fleet" instead of "team"
* "report" instead of "query" (where appropriate)
* "for unassigned hosts" in place of "No Team" where possible, and "for
fleet Unassigned" otherwise.

All changes other than tests are in `client.go` and are text-only; no
functional code is changed (and no code relies on the strings besides
tests).

# Checklist for submitter

If some of the following don't apply, delete the relevant line.

- [ ] 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.
n/a

## Testing

- [X] Added/updated automated tests
- [ ] QA'd all new/changed functionality manually

I did a `fleetctl generate-gitops` and a `fleetctl gitops` run and saw
the updated logs:
```
[+] would've applied EULA
[+] would've applied certificate authorities
[+] would've applied fleet config
[+] would've applied MDM profiles
[+] would've applied enroll secrets
[+] would've applied 1 report
[+] would've applied 1 software package for fleet 'Unassigned'
[+] would've applied 0 app store apps for fleet 'Unassigned'
[+] would've applied webhook settings for unassigned hosts
[+] would've applied 1 policy
[!] gitops dry run succeeded
```

but I did not go through and try and replicate every log or error
message. I think the best we can do on this one is eyeball the code
changes for mistakes.
2026-02-26 14:38:07 -06:00
Jonathan Katz 544ba92114 Enforce GitOps setup experience when manual agent install is enabled (#39775)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or
remove if NA -->
**Related issue:** Resolves #38431
Attempts to get the ManualAgentInstall config from `ds.TeamLite` in the
case of software installers. In the VPP case, it attempts to get it from
either `ds.TeamByName` or from global `ds.AppConfig` if no team name is
provided.
I had to add some mock functions for TeamLite that were missing, or
missing for the team 0 case. Also added
FLEET_INTEGRATION_TESTS_DISABLE_LOG to disable logs in gitops
integration tests.
# Checklist for submitter

If some of the following don't apply, delete the relevant line.

- [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.

- [ ] Input data is properly validated, `SELECT *` is avoided, SQL
injection is prevented (using placeholders for values in statements)
- [ ] If paths of existing endpoints are modified without backwards
compatibility, checked the frontend/CLI for any necessary changes

## Testing

- [x] Added/updated automated tests
- [ ] Where appropriate, [automated tests simulate multiple hosts and
test for host
isolation](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/reference/patterns-backend.md#unit-testing)
(updates to one hosts's records do not affect another)

- [x] QA'd all new/changed functionality manually
2026-02-13 16:21:39 -05:00
Ian Littman a394596fbf Bump installer max size, make configurable (#38122)
Resolves #37464.

# Checklist for submitter

If some of the following don't apply, delete the relevant line.

- [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)

## Testing

- [x] Added/updated automated tests

- [x] QA'd all new/changed functionality manually

## New Fleet configuration settings

- [x] Setting(s) is/are explicitly excluded from GitOps
2026-01-19 13:36:01 -06:00
Ian Littman b1915800e2 Add custom VPP app support (#37969)
Resolves #32481 for Fleet server-side work.

# Checklist for submitter

If some of the following don't apply, delete the relevant line.

- [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)

## Testing

- [x] Added/updated automated tests

- [x] QA'd all new/changed functionality manually
2026-01-08 13:13:04 -06:00
Ian Littman 8e4e89f4e9 API + auth + UI changes for team labels (#37208)
Covers #36760, #36758.

# Checklist for submitter

If some of the following don't apply, delete the relevant line.

- [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)

## Testing

- [x] Added/updated automated tests
- [x] Where appropriate, [automated tests simulate multiple hosts and
test for host
isolation](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/reference/patterns-backend.md#unit-testing)
(updates to one hosts's records do not affect another)

- [ ] QA'd all new/changed functionality manually
2025-12-29 21:28:45 -06:00
Jonathan Katz 20230a688f Android Setup Experience Gitops (#37468)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or
remove if NA -->
**Related issue:** Resolves #35554

- Setup experience is generated to and can be set in the GitOps yaml
- No changes to policy creation, setup experience apps are still added
as `PREINSTALLED`
- API change: `GET /fleet/setup_experience/software` modified to be able
to take a comma separated list of platforms, like `GET
/fleet/setup_experience/software` does. Documentation update will be in
another PR.
- Modified `SetTeamVPPApps` to return if setup experience changed so the
function that calls it can create a "setup experience changed" activity.

# Checklist for submitter

## Testing

- [x] Added/updated automated tests
- [ ] Where appropriate, [automated tests simulate multiple hosts and
test for host
isolation](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/reference/patterns-backend.md#unit-testing)
(updates to one hosts's records do not affect another)

- [x] QA'd all new/changed functionality manually
- Used generate-gitops to create a yaml file, edited setup experience
apps with it to test that it applies and creates activities correctly.
- Re-enrolled an Android phone after editing setup experience with
GitOps, all setup experience apps were installed.
2025-12-19 10:45:27 -05:00
Lucas Manuel RodriguezandIan Littman 554f268768 Add team assignment checks to APIs that do label association (#37246)
Resolves #37104

## Testing

- [X] Added/updated automated tests
- [X] Where appropriate, [automated tests simulate multiple hosts and
test for host
isolation](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/reference/patterns-backend.md#unit-testing)
(updates to one hosts's records do not affect another)

- [ ] QA'd all new/changed functionality manually

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **New Features**
* Label validation now enforces team-context constraints for policies,
queries, and MDM profiles.
  * Global policies now verify label validity before creation.

* **Bug Fixes**
* Improved label association verification in team-specific
configurations.

* **Tests**
* Added comprehensive test coverage for team label associations,
including label scoping validation and team deletion scenarios.

<sub>✏️ Tip: You can customize this high-level summary in your review
settings.</sub>

<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Ian Littman <iansltx@gmail.com>
2025-12-15 14:11:36 -03:00
Allen Houchins a5b2e911d6 Add support for zip files as Windows FMAs (#36841)
### Summary
This PR adds support for `.zip` files as Windows Fleet Managed Apps
(FMAs). Zip files on Windows are treated similarly to `.exe` files and
require custom install/uninstall scripts, typically used for AppX/MSIX
packages that are distributed as zip archives.

### Changes

**Backend:**
- Added `.zip` as a supported Windows package type in
`SoftwareInstallerPlatformFromExtension`
- Updated validation to require install/uninstall scripts for zip files
(similar to `.exe` files)
- Added `addZipPackageMetadata` function to handle zip file metadata
extraction
- Updated error messages to include `.zip` in the list of supported file
types
- Enhanced `appExists` validation to detect provisioned AppX packages
(packages that are provisioned for all users but don't show up in the
programs table until a user logs in)
- Added version normalization logic to handle version string differences
(e.g., "11.2.1495.0" vs "11.2.1495")
- Updated winget ingester to recognize zip files and default to user
scope for MSIX/zip installers

**Frontend:**
- Added `.zip` to `windowsPackageTypes` in `package_type.ts`
- Updated `PackageAdvancedOptions` component to require
install/uninstall scripts for zip files
- Added validation rules for zip files in `PackageForm/helpers.tsx`
- Updated help text and tooltips to indicate script requirements for zip
packages
- Updated `software_install_scripts.ts` to include zip in default script
handling

**Maintained Apps:**
- Added Microsoft Company Portal as a maintained app example using zip
files
- Created install/uninstall PowerShell scripts that:
  - Extract zip files containing AppX packages
- Provision packages for all future users (works in headless
environments)
  - Install packages for the current user
  - Handle both provisioned and installed package detection

**Tests:**
- Updated integration tests to include `.zip` in supported file type
error messages
- Updated unit tests for `SoftwareInstallerPlatformFromExtension` and
`SofwareInstallerSourceFromExtensionAndName`

### Use Case
This enables distribution of Windows AppX/MSIX packages that are
packaged as zip files (common for Microsoft Store apps like Company
Portal). The implementation handles both provisioned packages (for all
users) and user-installed packages, ensuring detection works in both
headless and interactive environments.

### Testing
- Updated existing tests to include zip file support
- Added Microsoft Company Portal as a maintained app example with full
install/uninstall scripts

---

**Note:** This PR follows the same pattern as `.exe` file support,
requiring custom install/uninstall scripts since zip files can contain
various content types that need custom handling.
2025-12-15 11:03:43 -06:00
Jahziel Villasana-Espinoza 4ce4828ba0 fix app store apps display names in gitops (#36913)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or
remove if NA -->
**Related issue:** Resolves #36700 

# Checklist for submitter

If some of the following don't apply, delete the relevant line.

- [x] Input data is properly validated, `SELECT *` is avoided, SQL
injection is prevented (using placeholders for values in statements)

## Testing

- [x] Added/updated automated tests
- [x] Where appropriate, [automated tests simulate multiple hosts and
test for host
isolation](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/reference/patterns-backend.md#unit-testing)
(updates to one hosts's records do not affect another)
- [x] QA'd all new/changed functionality manually

For unreleased bug fixes in a release candidate, one of:

- [x] Confirmed that the fix is not expected to adversely impact load
test results

## New Fleet configuration settings

- [x] Verified that the setting is exported via `fleetctl
generate-gitops`
- [x] Verified that the setting is cleared on the server if it is not
supplied in a YAML file (or that it is documented as being optional)
2025-12-09 10:42:04 -05:00
Juan Fernandez 01814a1aa7 Refactored Android certificate CRUD to use ListOptions (#36503)
**Related issue:** Resolves #36288

Refactored Android certificate CRUD to use ListOptions
2025-12-02 12:50:11 -04:00
Scott Gress 4d9eccfabf Allow deleting all certificate templates from GitOps (#36264)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or
remove if NA -->
**Related issue:** For #35460 

# Checklist for submitter

If some of the following don't apply, delete the relevant line.

## Testing

- [X] Added/updated automated tests
- [X] QA'd all new/changed functionality manually
2025-11-26 11:44:55 -06:00
Carlo b5286a3047 Set GitOps custom display name for software (#35871)
Implements #33781. GitOps workflow support for custom software display names.
2025-11-19 14:05:21 -05:00
Martin Angers 1253b64528 Add gitops support for in house apps (#35423) 2025-11-11 16:38:54 -05:00
Carlo cc7062f8f0 Add filetype support and validation for .sh and .ps1 scripts (#33980)
Implements #33749. This PR is mostly just adding filetypes in key places and tests to catch any potential future regressions.
2025-10-14 09:56:53 -04:00
Ian Littman 17ff0968d4 Support providing multiple packages per software package file in GitOps (#32503)
For #30849.

# Checklist for submitter

If some of the following don't apply, delete the relevant line.

- [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)

## Testing

- [x] Added/updated automated tests

- [x] QA'd all new/changed functionality manually

## New Fleet configuration settings

- [n/a] Verified that the setting is exported via `fleetctl
generate-gitops`
- [x] Verified the setting is documented in a separate PR to [the GitOps
documentation](https://github.com/fleetdm/fleet/blob/main/docs/Configuration/yaml-files.md#L485)
- [x] Verified that the setting is cleared on the server if it is not
supplied in a YAML file (or that it is documented as being optional)
- [x] Verified that any relevant UI is disabled when GitOps mode is
enabled
2025-09-05 08:38:00 -05:00
Ian Littman e6ef600c5f Apply relevant cleanup suggested by CodeRabbit in #32245 for GitOps update work (#32482)
# Checklist for submitter

- [x] Added/updated automated tests
2025-09-03 13:52:25 -05:00
7450f0da7e Tweak GitOps software handling, allow setup experience bool on package details, update generate-gitops (#32492)
For #30095.

#32482 is additional cleanup. Merging this to unblock orchestration
Linux setup experience work. Code has already been reviewed prior to
merging into the feature branch.

---------

Co-authored-by: Konstantin Sykulev <konst@sykulev.com>
Co-authored-by: Anthony Maxwell <133805840+Illbjorn@users.noreply.github.com>
2025-09-03 13:32:11 -05:00
Konstantin Sykulev 68c3ade0b2 Removed fleet secret validation during gitops dry runs (#31402)
Fixes #30853

Install and uninstall scripts that contain fleet secrets do not need to
be validated in the `batchSetSoftwareInstallersEndpoint` during gitops
dry runs. These secrets are already validated on the gitops side.

# Checklist for submitter

If some of the following don't apply, delete the relevant line.

- [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
2025-07-30 13:12:39 -05:00
Dante Catalfamo cbc7c29dff Better gitops unmarshal type errors (#30647)
#21973
2025-07-24 13:49:17 -04:00
Victor Lyuboslavsky 33396a5d91 Moved some integration tests into their own package. (#28978)
For #27927 

Refactoring to speed up fleetctl tests, no functional changes. Mostly
changing test files.

fleetctl is no longer the long pole in CI, the long pole is mysql,
followed by vuln.

<img width="389" alt="image"
src="https://github.com/user-attachments/assets/9ada64e2-b5e8-42e3-b120-4eb36183ae38"
/>
2025-05-09 09:26:57 -05:00