From af2de5bc42732a73b1bda5b94e77d14fe710a3a8 Mon Sep 17 00:00:00 2001 From: Scott Gress Date: Mon, 30 Jun 2025 09:58:58 -0500 Subject: [PATCH] Add support for host vitals labels (#30278) # Details This PR adds support for a new label membership type, `host_vitals`. Membership for these labels is based on a database query created from user-supplied criteria. In this first iteration, the allowed criteria are very simple: a label can specify either an IdP group or IdP department, and hosts with linked users with a matching group or department. Groundwork is laid here for more complex host vitals queries, including `and` and `or` logic, different data types and different kinds of vitals (rather than just the "foreign" vitals of which IdP is an example). Note that this PR does _not_ include the cron job that will trigger membership updating, and it doesn't include ; for sake of simplicity in review that will be done in a follow-on PR. ## Basic flow ### Creating a host vitals label 1. A new label is created via the API / GitOps with membership type `host_vitals` and a `criteria` property that's a JSON blob. Currently the JSON can only contain `vital` and `value` keys (and must contain those keys) 2. The server validates that the specified `vital` exists in our [set of known host vitals](https://github.com/fleetdm/fleet/pull/30278/files#diff-b6d4c48f2624b82c2567b2b88db1de51c6b152eeb261d40acfd5b63a890839b7R418-R436). 3. The server validates that the [criteria can be parsed into a query](https://github.com/fleetdm/fleet/pull/30278/files?diff=unified&w=1#diff-4ac4cfba8bed490e8ef125a0556f5417156f805017bfe93c6e2c61aa94ba8a8cR81-R86). This also happens during GitOps dry run. 4. The label is saved (criteria is saved as JSON in the db) ### Updating membership for a host vitals label 1. The label's criteria is used to generate a query to run on the _Fleet_ db. 1. For each vital criteria, check the vital type. Currently only foreign vitals are supported. 2. For foreign vitals, add its group to a set we keep track of. 3. Add a `WHERE` clause section for the vital and value, e.g. `end_user_idp_groups = ?` 4. Once we have all the `WHERE` clauses, create the query as `SELECT %s FROM %s` + any joins contributed by foreign vitals groups + `WHERE ` + all the `WHERE` clauses we just calculated. The `%s` provide some flexibility if we want to use these queries in other contexts. 2. Delete all existing label members 3. Do an `INSERT...SELECT` using the query we calculated from the label criteria. The query will be `SELECT