Skip to content

Add include_all label scope to GitOps and fleetctl (#41566)#44534

Draft
juan-fdz-hawa wants to merge 3 commits intomainfrom
41566-policyreport-labels-gitops
Draft

Add include_all label scope to GitOps and fleetctl (#41566)#44534
juan-fdz-hawa wants to merge 3 commits intomainfrom
41566-policyreport-labels-gitops

Conversation

@juan-fdz-hawa
Copy link
Copy Markdown
Contributor

@juan-fdz-hawa juan-fdz-hawa commented Apr 30, 2026

Related issue: Resolves #41566

Wires labels_include_all to GitOps and fleetctl for policies and reports.

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 for more information.

Testing

  • Added/updated automated tests
  • QA'd all new/changed functionality manually

Summary by CodeRabbit

Release Notes

  • New Features
    • Added support for "include all labels" mode in queries and policies, enabling more granular label-based targeting alongside the existing "include any labels" option
    • Extended fleetctl get commands to display include-all label settings in table, YAML, and JSON formats
    • Enhanced GitOps validation to enforce mutual exclusivity between label-scope modes and detect conflicts during specification application (premium feature)

Wires labels_include_all to GitOps and fleetctl for policies and reports.
@juan-fdz-hawa
Copy link
Copy Markdown
Contributor Author

@coderabbitai full review

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 30, 2026

✅ Actions performed

Full review triggered.

@juan-fdz-hawa juan-fdz-hawa changed the title Add include_all label scope to GitOps and fleetctl Add include_all label scope to GitOps and fleetctl (#41566) Apr 30, 2026
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 30, 2026

Walkthrough

This PR adds support for labels_include_all across policies and queries in Fleet's GitOps, CLI, and API layers. Changes include adding the LabelsIncludeAll field to policy and query spec structs, enforcing mutual exclusivity validation between label-scoping modes in service and GitOps layers, propagating the field through the datastore, updating fleetctl output to display the field in table/YAML/JSON formats, and implementing license gating to restrict the feature to premium users. Comprehensive test coverage includes endpoint validation, batch semantics, and label resolution scenarios.

Possibly related PRs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 12.50% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description check ✅ Passed The description includes the related issue, explicitly mentions the main change, confirms a changes file was added, and indicates tests were updated.
Linked Issues check ✅ Passed The PR implementation fulfills all three objectives from #41566: adds LabelsIncludeAll to policy/query specs [server/fleet/policies.go, server/fleet/queries.go], enforces mutual exclusion validation [cmd/fleetctl/fleetctl/gitops.go, server/service/queries.go], and includes labels_include_all in YAML output [cmd/fleetctl/fleetctl/get.go].
Out of Scope Changes check ✅ Passed All code changes directly support the core objective of adding include_all label scope to GitOps and fleetctl, with no extraneous modifications detected.
Title check ✅ Passed The title clearly and concisely summarizes the main change: adding include_all label scope functionality to GitOps and fleetctl for policies and reports, matching the extensive modifications across the codebase.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch 41566-policyreport-labels-gitops

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (5)
changes/41566-policy-report-labels-gitops (1)

1-1: ⚡ Quick win

Use user-facing language in the changelog entry.

The word "Wires" is developer jargon that doesn't clearly communicate the user-visible change. Changelog entries should describe what users can now do, not implementation details.

📝 Suggested rewording for clarity
-- Wires labels_include_all to GitOps/fleetctl for policies and reports.
+- Added support for `labels_include_all` label scope in GitOps and fleetctl for policies and reports.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@changes/41566-policy-report-labels-gitops` at line 1, Change the changelog
entry that currently reads "Wires labels_include_all to GitOps/fleetctl for
policies and reports" to user-facing language that describes the new capability;
for example, replace "Wires" with a clear phrase such as "Add support for" or
"Allow users to include" so the entry reads like "Add support for
labels_include_all in GitOps/fleetctl for policies and reports" (referencing the
labels_include_all flag, GitOps/fleetctl integration, and the policies and
reports feature to locate the entry).
cmd/fleetctl/fleetctl/get_test.go (1)

1891-1945: ⚡ Quick win

Add one default table-output assertion for labels_include_all.

These tests cover --yaml/--json, but the table behavior added at Line 352 in cmd/fleetctl/fleetctl/get.go isn’t exercised yet. A plain fleetctl get reports assertion for labels_include_all would close that gap.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@cmd/fleetctl/fleetctl/get_test.go` around lines 1891 - 1945,
TestGetReportsLabelsIncludeAll currently asserts only YAML/JSON outputs but not
the default table output; add a table-output assertion by calling
RunAppForTest(t, []string{"get", "reports"}) and asserting the returned string
contains the labels (e.g. assert.Contains(t, out, "labelA") and
assert.Contains(t, out, "labelB") or a combined "labelA,labelB" as appropriate)
so the new table formatting in the get reports command is exercised; update
TestGetReportsLabelsIncludeAll to include these assert calls referencing
RunAppForTest and the "get reports" invocation.
server/service/queries.go (1)

824-827: ⚡ Quick win

Return the missing label names here.

label not found is too generic now that both labels_include_any and labels_include_all funnel through this branch. Including the missing names would make GitOps/API failures much easier to fix.

Suggested change
-		for _, name := range allLabelNames {
-			if _, ok := labelsMap[name]; !ok {
-				return nil, ctxerr.New(ctx, "label not found")
-			}
-		}
+		missing := make([]string, 0)
+		for _, name := range allLabelNames {
+			if _, ok := labelsMap[name]; !ok {
+				missing = append(missing, name)
+			}
+		}
+		if len(missing) > 0 {
+			return nil, ctxerr.New(ctx, fmt.Sprintf("labels not found: %s", strings.Join(missing, ", ")))
+		}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@server/service/queries.go` around lines 824 - 827, The loop over
allLabelNames that currently returns a generic ctxerr.New(ctx, "label not
found") should collect the actual missing label names (e.g., build a slice
missing := []string{} when iterating for _, name := range allLabelNames and
checking labelsMap[name]) and return an error that includes them (e.g., fmt.Join
or formatted message) instead of the generic string; update the return to use
ctxerr.Newf or ctxerr.New with a formatted message like "labels not found:
<names>" so callers of the function that contains this loop (the block using
labelsMap and allLabelNames) get the specific missing label names.
cmd/fleetctl/fleetctl/gitops_test.go (1)

295-334: ⚡ Quick win

Add a free-tier labels_include_all GitOps test.

These new cases only exercise labels_include_all with a premium license. The existing free-tier coverage still only protects labels_include_any, so the new license-gated branch can regress without a failing test.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@cmd/fleetctl/fleetctl/gitops_test.go` around lines 295 - 334, Add a new test
function (e.g., TestGitOpsQueryLabelsIncludeAllFreeTier) that mirrors
TestGitOpsQueryLabelsIncludeAllUnknownLabel but sets the license to
fleet.TierFree (use RunServerWithMockedDS/TestServerOpts like the existing
test), creates the same GitOps YAML that uses labels_include_all, calls
RunAppNoChecks with that file, and assert that it errors and the error message
mentions the license/gating of labels_include_all (check Error and ErrorContains
against text including "labels_include_all" and "license" or "premium"). This
ensures the labels_include_all license-gated branch is covered; reference the
existing TestGitOpsQueryLabelsIncludeAllUnknownLabel, labels_include_all,
RunServerWithMockedDS, and RunAppNoChecks to locate where to add the duplicate
test.
server/service/integration_enterprise_test.go (1)

29473-29493: ⚡ Quick win

Add explicit non-persistence assertions for rejected single-spec GitOps requests

These negative tests currently validate only the error response. Please also assert the rejected policy/query names were not created, so partial-write regressions are caught (same guarantee you already enforce in the batch test).

Also applies to: 29589-29599

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@server/service/integration_enterprise_test.go` around lines 29473 - 29493,
Add explicit assertions that the rejected spec names were not persisted: after
each POST that returns BadRequest (the requests captured in rejSpecResp and
rejSpecResp2 sent with fleet.ApplyPolicySpecsRequest containing fleet.PolicySpec
named "spec-rej-any-"+t.Name() and "spec-rej-excl-"+t.Name()), call the API to
fetch specs (e.g., via s.Do GET /api/latest/fleet/spec/policies or the
single-spec read endpoint) and assert the returned list does not contain those
policy names; use the same helper extractServerErrorText and compare against the
PolicySpec.Name values and fleet.ErrPolicyConflictingLabels to ensure no partial
write occurred.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@changes/41566-policy-report-labels-gitops`:
- Line 1: Change the changelog entry that currently reads "Wires
labels_include_all to GitOps/fleetctl for policies and reports" to user-facing
language that describes the new capability; for example, replace "Wires" with a
clear phrase such as "Add support for" or "Allow users to include" so the entry
reads like "Add support for labels_include_all in GitOps/fleetctl for policies
and reports" (referencing the labels_include_all flag, GitOps/fleetctl
integration, and the policies and reports feature to locate the entry).

In `@cmd/fleetctl/fleetctl/get_test.go`:
- Around line 1891-1945: TestGetReportsLabelsIncludeAll currently asserts only
YAML/JSON outputs but not the default table output; add a table-output assertion
by calling RunAppForTest(t, []string{"get", "reports"}) and asserting the
returned string contains the labels (e.g. assert.Contains(t, out, "labelA") and
assert.Contains(t, out, "labelB") or a combined "labelA,labelB" as appropriate)
so the new table formatting in the get reports command is exercised; update
TestGetReportsLabelsIncludeAll to include these assert calls referencing
RunAppForTest and the "get reports" invocation.

In `@cmd/fleetctl/fleetctl/gitops_test.go`:
- Around line 295-334: Add a new test function (e.g.,
TestGitOpsQueryLabelsIncludeAllFreeTier) that mirrors
TestGitOpsQueryLabelsIncludeAllUnknownLabel but sets the license to
fleet.TierFree (use RunServerWithMockedDS/TestServerOpts like the existing
test), creates the same GitOps YAML that uses labels_include_all, calls
RunAppNoChecks with that file, and assert that it errors and the error message
mentions the license/gating of labels_include_all (check Error and ErrorContains
against text including "labels_include_all" and "license" or "premium"). This
ensures the labels_include_all license-gated branch is covered; reference the
existing TestGitOpsQueryLabelsIncludeAllUnknownLabel, labels_include_all,
RunServerWithMockedDS, and RunAppNoChecks to locate where to add the duplicate
test.

In `@server/service/integration_enterprise_test.go`:
- Around line 29473-29493: Add explicit assertions that the rejected spec names
were not persisted: after each POST that returns BadRequest (the requests
captured in rejSpecResp and rejSpecResp2 sent with fleet.ApplyPolicySpecsRequest
containing fleet.PolicySpec named "spec-rej-any-"+t.Name() and
"spec-rej-excl-"+t.Name()), call the API to fetch specs (e.g., via s.Do GET
/api/latest/fleet/spec/policies or the single-spec read endpoint) and assert the
returned list does not contain those policy names; use the same helper
extractServerErrorText and compare against the PolicySpec.Name values and
fleet.ErrPolicyConflictingLabels to ensure no partial write occurred.

In `@server/service/queries.go`:
- Around line 824-827: The loop over allLabelNames that currently returns a
generic ctxerr.New(ctx, "label not found") should collect the actual missing
label names (e.g., build a slice missing := []string{} when iterating for _,
name := range allLabelNames and checking labelsMap[name]) and return an error
that includes them (e.g., fmt.Join or formatted message) instead of the generic
string; update the return to use ctxerr.Newf or ctxerr.New with a formatted
message like "labels not found: <names>" so callers of the function that
contains this loop (the block using labelsMap and allLabelNames) get the
specific missing label names.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 86db80c1-58bc-4b6d-91b0-7cc95e932b01

📥 Commits

Reviewing files that changed from the base of the PR and between f70a02a and 6a694b3.

📒 Files selected for processing (13)
  • changes/41566-policy-report-labels-gitops
  • cmd/fleetctl/fleetctl/get.go
  • cmd/fleetctl/fleetctl/get_test.go
  • cmd/fleetctl/fleetctl/gitops.go
  • cmd/fleetctl/fleetctl/gitops_test.go
  • server/datastore/mysql/policies.go
  • server/datastore/mysql/policies_test.go
  • server/fleet/policies.go
  • server/fleet/queries.go
  • server/service/global_policies.go
  • server/service/integration_core_test.go
  • server/service/integration_enterprise_test.go
  • server/service/queries.go

@codecov
Copy link
Copy Markdown

codecov Bot commented Apr 30, 2026

Codecov Report

❌ Patch coverage is 88.23529% with 8 lines in your changes missing coverage. Please review.
✅ Project coverage is 66.79%. Comparing base (f70a02a) to head (6a694b3).
⚠️ Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
cmd/fleetctl/fleetctl/get.go 71.42% 3 Missing and 1 partial ⚠️
cmd/fleetctl/fleetctl/gitops.go 73.33% 3 Missing and 1 partial ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main   #44534      +/-   ##
==========================================
- Coverage   66.79%   66.79%   -0.01%     
==========================================
  Files        2637     2637              
  Lines      212132   212178      +46     
  Branches     9437     9437              
==========================================
+ Hits       141688   141718      +30     
- Misses      57578    57590      +12     
- Partials    12866    12870       +4     
Flag Coverage Δ
backend 68.56% <88.23%> (-0.01%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Policy/report labels: GitOps

1 participant