Skip to content

Add public_ip host vitals label support + LIKE operator#46931

Open
robbiet480 wants to merge 4 commits into
fleetdm:mainfrom
CampusTech:feat/public-ip-host-vital
Open

Add public_ip host vitals label support + LIKE operator#46931
robbiet480 wants to merge 4 commits into
fleetdm:mainfrom
CampusTech:feat/public-ip-host-vital

Conversation

@robbiet480
Copy link
Copy Markdown

@robbiet480 robbiet480 commented Jun 5, 2026

Summary

Host vitals labels currently only support foreign vitals sourced from IdP/SCIM data (end_user_idp_group, end_user_idp_department), which are joined from the scim_* tables. The HostVitalTypeDomestic type — for vitals stored directly on the hosts table — was already defined in the codebase but had no registered vitals.

This PR registers public_ip as a domestic host vital so labels can target it directly (no JOIN), and adds a LIKE operator for criteria matching (in addition to the default =) for wildcard patterns.

Motivation

The driving use case: labeling hosts by which network they connect from, keyed on their public egress IP — for example, scoping profiles or software to hosts physically in an office by its egress IP.

A host's public IP is server-side metadata: Fleet derives hosts.public_ip from the source address of the host's own connection (see server/service/osquery_utils/queries.gopublicip.FromContext), not from anything on the device. osquery has no table that reports the host's public/egress IP, so a dynamic (osquery) label can't express it. A host vitals label is the only label type that can filter on a Fleet-side hosts column, which is what makes this possible.

Scope note: an earlier revision of this PR also added hardware_model and hardware_vendor vitals. Those are osquery-observable (system_info), so they can already be targeted with a dynamic label and added no new capability — they've been dropped. This PR is now public_ip only.

Example GitOps usage:

- name: NYC office
  description: Hosts connecting from the New York City office egress IP
  label_membership_type: host_vitals
  criteria:
    vital: public_ip
    value: 203.0.113.10

Changes

  • server/fleet/hosts.go — register public_ip as a HostVitalTypeDomestic vital.
  • server/fleet/labels.go — allow the LIKE operator in parseHostVitalCriteria (emitting the matching SQL operator); other operators (!=, >, <) remain rejected. Also fixes a doubled space in the generated query when a vital has no foreign-table joins.
  • Docs — REST API criteria table (vital list + new operator field) and the GitOps yaml-files.md labels section.
  • Tests — unit tests for the public_ip vital and the LIKE operator in server/fleet, a domestic-vital create test in server/service (TestNewHostVitalsLabel), and the gitops enterprise integration test's host_vitals edit phase now switches to a public_ip + LIKE criteria to exercise the no-JOIN path end-to-end.

Testing

  • go test ./server/fleet/
  • go test ./server/service/ -run Label
  • golangci-lint run server/fleet/... → 0 issues
  • The gitops integration test (cmd/fleetctl/integrationtest/gitops) requires MySQL; it compiles and the modified phase is covered there.

Notes for reviewers

  • The = / LIKE allowlist is intentionally conservative; And/Or and other operators remain unimplemented as before (existing TODOs).
  • hosts.public_ip reflects the last-seen egress IP updated on host check-in — membership is as fresh as the host's last check-in, consistent with how the host vitals cron (5 min) materializes membership.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Hosts can be labeled using host attributes, including public IP, hardware model, and hardware vendor.
    • Host vitals criteria now support LIKE pattern matching for wildcard filtering.
  • Tests

    • Added tests for domestic (no-join) vitals labeling and LIKE vs equals behavior.
    • Added tests ensuring unsupported operators are rejected.
  • Documentation

    • Clarified host-attribute labeling and LIKE usage.

Copilot AI review requested due to automatic review settings June 5, 2026 18:18
@robbiet480 robbiet480 requested review from a team, eashaw and rachaelshaw as code owners June 5, 2026 18:18
Copy link
Copy Markdown

@claude claude Bot left a comment

Choose a reason for hiding this comment

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

Claude Code Review

This pull request is from a fork — automated review is disabled. A repository maintainer can comment @claude review to run a one-time review.

@robbiet480 robbiet480 force-pushed the feat/public-ip-host-vital branch from 76a926a to 46f9f38 Compare June 5, 2026 18:19
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Note

Copilot was unable to run its full agentic suite in this review.

Adds support for “domestic” host vitals (stored directly on hosts) in host vitals labels and introduces a LIKE operator for vitals matching.

Changes:

  • Add host vitals for public_ip, hardware_model, and hardware_vendor and adjust query generation to omit JOINs for domestic vitals.
  • Allow LIKE (in addition to =) in host vitals criteria and add tests for domestic vitals + operator validation.
  • Document new vitals and operator support; extend gitops integration coverage.

Reviewed changes

Copilot reviewed 5 out of 8 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
server/service/labels_test.go Adds service-level test for creating a domestic host vitals label (public_ip).
server/fleet/labels_test.go Adds unit tests for domestic vitals query generation and operator rejection.
server/fleet/labels.go Avoids extra whitespace when no JOINs; adds LIKE support in vitals parsing.
server/fleet/hosts.go Registers domestic vitals mapped to hosts columns.
docs/REST API/rest-api.md Documents new vitals and optional operator field for criteria.
docs/Configuration/yaml-files.md Documents new vitals/operator in YAML and adds example config.
cmd/fleetctl/integrationtest/gitops/gitops_enterprise_integration_test.go Updates gitops integration to exercise domestic vital + LIKE operator.
changes/add-domestic-host-vitals-labels Adds changelog entry describing domestic vitals + LIKE operator.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread server/fleet/labels_test.go Outdated
Comment thread server/fleet/labels_test.go Outdated
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Jun 5, 2026

Ready to act? Review this PR in Change Stack to turn feedback into patch suggestions you can inspect and refine.

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

Adds a domestic host vital entry for public_ip (mapped to hosts.public_ip), updates CalculateHostVitalsQuery to include JOINs only when foreign vitals are required, and extends parseHostVitalCriteria to accept both '=' and 'LIKE' operators. Unit and service tests assert generated SQL and parameter values for public_ip equality and LIKE cases and verify rejection of unsupported operators. The gitops integration test YAML and inline comments were updated to use public_ip with operator LIKE and a wildcard value; docs/changelog note public_ip and LIKE support.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% 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 is comprehensive and mostly complete, documenting the motivation, changes, and testing. However, the PR description does not include a properly filled-out checklist from the template.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title check ✅ Passed The title accurately describes the main changes: adding public_ip host vitals label support and introducing the LIKE operator for host vitals criteria.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

@robbiet480
Copy link
Copy Markdown
Author

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Jun 5, 2026

✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@robbiet480 robbiet480 force-pushed the feat/public-ip-host-vital branch from 46f9f38 to 2b5822e Compare June 5, 2026 18:22
…vendor) + LIKE operator

Host vitals labels could previously only target IdP-sourced vitals
(end_user_idp_group, end_user_idp_department), which are foreign vitals
joined from the scim_* tables. The HostVitalTypeDomestic type — for
vitals stored directly on the hosts table — was defined but unused.

This registers three domestic vitals (public_ip, hardware_model,
hardware_vendor) so labels can target host-table columns with no join.
The motivating use case is labeling hosts by the office they connect
from via their public egress IP, which osquery cannot observe.

Also adds a LIKE operator for criteria matching (in addition to the
default =), enabling SQL wildcard patterns, and fixes a doubled space
in the generated query when a vital has no foreign-table joins.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@robbiet480 robbiet480 force-pushed the feat/public-ip-host-vital branch from 2b5822e to c416970 Compare June 5, 2026 18:35
@robbiet480
Copy link
Copy Markdown
Author

@coderabbitai full review

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Jun 5, 2026

✅ Action performed

Full review finished.

@codecov
Copy link
Copy Markdown

codecov Bot commented Jun 5, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 67.04%. Comparing base (1e9f380) to head (5600a05).
⚠️ Report is 9 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main   #46931      +/-   ##
==========================================
+ Coverage   67.02%   67.04%   +0.01%     
==========================================
  Files        2862     2861       -1     
  Lines      224832   225014     +182     
  Branches    11739    11702      -37     
==========================================
+ Hits       150699   150855     +156     
- Misses      60480    60487       +7     
- Partials    13653    13672      +19     
Flag Coverage Δ
backend 68.74% <100.00%> (+<0.01%) ⬆️

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

☔ View full report in Codecov by Harness.
📢 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.

@robbiet480
Copy link
Copy Markdown
Author

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Jun 5, 2026

✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@ThomasSalomon4
Copy link
Copy Markdown
Contributor

@claude review

Comment thread server/fleet/labels_test.go
Comment thread docs/Configuration/yaml-files.md Outdated
…n docs example

- Replace deprecated ptr.String/ptr.RawMessage with new(expr) in the new
  host vitals tests (per .claude/rules/fleet-go-backend.md, Go 1.26+).
- Dedent the Engineering department and NYC office labels in the
  yaml-files.md 'Separate file' example to column 0 so the block is valid
  YAML (they were nested under the C-Suite mapping and failed to parse).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@allenhouchins
Copy link
Copy Markdown
Member

I'm not sure I understand the use case behind this PR. You can already do all of this using labels without this code change.

@robbiet480
Copy link
Copy Markdown
Author

Via osquery?

@allenhouchins
Copy link
Copy Markdown
Member

Via osquery?

Yes. Here's an example of your New York office label:

  - name: New York office
    description: Hosts egressing through the NYC office public IP
    label_membership_type: dynamic
    query: "SELECT 1 FROM curl WHERE url = 'https://api.ipify.org' AND result = '203.0.113.10'"

@robbiet480
Copy link
Copy Markdown
Author

Totally fair, and I did know of that route and consider it beforehand but thought since we already have the live data in Fleet, why do a whole osquery + hit an external API for it? As for the make/model info, again, we already have it local in Fleet, why do a roundtrip for it to every host?

@allenhouchins
Copy link
Copy Markdown
Member

Other than the public IP address example, the hardware vendor and hardware model info is also being populated by osquery. The roundtrip is negligible since your devices are likely already reaching out to run refetch, reports, and policies.

@robbiet480
Copy link
Copy Markdown
Author

Fair enough, will trim this down to just public IP

Drop the hardware_model and hardware_vendor domestic vitals. Both are
osquery-observable (system_info), so they can already be targeted with a
dynamic label — they added no capability. public_ip is the vital that
isn't reachable any other way: Fleet derives it server-side from the
host's connection, so no osquery/dynamic label can express it.

Keeps the public_ip domestic vital + LIKE operator support.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@robbiet480 robbiet480 changed the title Add domestic host vitals labels (public_ip, hardware_model, hardware_vendor) + LIKE operator Add public_ip host vitals label support + LIKE operator Jun 5, 2026
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.

4 participants