Labels & Filter Queries
This guide provides a comprehensive reference for SPOG's label system and GlassQL filter query language. Labels are the foundation of cluster organization, and filters enable you to select, group, and display clusters based on their labels.
What You'll Learn
- How the label system works and how labels flow through SPOG
- Best practices for designing label taxonomies
- How to apply labels to clusters via Helm configuration
- The complete GlassQL filter query syntax with all operators
- Hands-on exercises using the quickstart deployment
Prerequisites
This guide assumes you have completed the Quickstart and have the three quickstart clusters running. All examples use these clusters to demonstrate filter behavior. For background on the overall system architecture, see the Architecture Overview.
The Label System
What Are Labels?
Labels are key-value pairs attached to clusters that describe their identity and organizational role. In SPOG, labels enable:
- Multi-dimensional organization: Categorize clusters by region, environment, team, tier, or any custom dimension
- Flexible filtering: Select clusters based on any combination of label values
- Authorization boundaries: Grant access based on label matching (covered in the authorization guide)
- Dynamic permissions: Combine with route parameters to create team-based dashboards that automatically filter by label values (see Dynamic Permission Arguments)
- Custom taxonomies: Define labels that match your specific organizational structure
Label Syntax
Labels are specified in YAML as key-value pairs. Values can be a single string or an array of strings:
| YAML | |
|---|---|
Reserved Label Keys
The following keywords are reserved and should not be used as label keys:
| Keyword | Reason |
|---|---|
and, or, not |
Boolean operators in GlassQL filter queries |
in, like, contains |
Comparison operators in GlassQL |
group, by |
Grouping keywords in GlassQL |
cluster_id |
Special field representing the cluster identifier |
Using these as label keys will generate runtime warnings and may cause unexpected behavior when filtering. For example, if you had a label and: "value", the query and = "value" would be ambiguous to the parser.
Reserved Keyword Detection
SPOG services will log warnings at startup if reserved keywords are detected in label configurations. While clusters will still function, filter queries involving these labels may not work as expected.
Multi-Valued Labels
Some organizational scenarios require a cluster to belong to multiple values for a single dimension. For example:
- A cluster managed by multiple teams
- A cluster serving multiple customers
- A cluster spanning multiple availability zones
When filtering, multi-valued labels match if any of the values match the filter condition. For example, team = "security" will match a cluster with team: ["platform", "security"].
Labels Are Completely Arbitrary
SPOG doesn't enforce any specific label schema. The label keys and values shown in these examples (region, environment, team, etc.) are illustrative. You can define any labels that match your organizational structure.
How Labels Flow Through SPOG
Labels propagate through the system in the following way:
- Cluster Definition: Labels are defined in the Glass Instrumentation Helm values
- NATS Discovery: Clusters announce themselves with their labels to the control plane
- Backend Registry: The middleware service maintains a registry of all clusters and their labels
- Frontend Store: The UI fetches cluster data including labels for display and filtering
- Filter Evaluation: GlassQL queries match clusters based on their label values
Label Design Principles
Follow these principles when designing your label taxonomy:
1. Keep Labels Simple and Consistent
Use the same label keys across all clusters. This enables reliable filtering and grouping.
| YAML | |
|---|---|
2. Use Meaningful, Human-Readable Values
Label values appear in the UI and filter autocomplete. Make them descriptive.
| YAML | |
|---|---|
3. Limit to 5-7 Dimensions
Too many labels create confusion. Focus on the dimensions that matter for filtering and access control.
4. Plan for Growth
Consider how your organization might evolve. Will you add new regions? New teams? Design labels that can accommodate growth.
5. Document Your Taxonomy
Maintain a reference document that defines each label key, its allowed values, and when to use each value.
Design Patterns
Single-Dimension Organization
Organize clusters by a single primary dimension, typically region or team:
| YAML | |
|---|---|
Use when: You have a simple infrastructure with one clear organizational axis.
Multi-Dimensional Hierarchy
Combine multiple dimensions for richer organization:
Use when: You need to filter by multiple criteria (e.g., "all production clusters in US regions owned by the platform team").
Team-Based Isolation
Organize clusters by team ownership with environment sub-classification:
| YAML | |
|---|---|
Use when: Teams have distinct ownership boundaries and need separate views of their infrastructure.
Multi-Valued Labels for Shared Ownership
When a cluster is managed by multiple teams or serves multiple purposes, use array values:
| YAML | |
|---|---|
This cluster will appear when filtering for either team:
team = "platform"→ matchesteam = "security"→ matchesteam in ("platform", "devops")→ matches (platform is in the set)
Use when: Clusters have shared ownership, serve multiple customers, or span multiple availability zones. Multi-valued labels enable flexible filtering without duplicating cluster definitions.
Applying Labels
Via Helm Configuration
Labels are applied through the Glass Instrumentation Helm chart. Each cluster where you install glass-instrumentation gets its own values file specifying the cluster ID and labels:
| YAML | |
|---|---|
To assign multiple values to a label, use YAML array syntax:
| YAML | |
|---|---|
Both single-value strings and arrays are supported for any label. The Helm chart automatically formats them correctly for the discovery service.
Quickstart Cluster Labels
The quickstart deployment includes three clusters with the following labels:
quickstart-1 (US East Production, multi-team):
| YAML | |
|---|---|
Multi-Valued Team Label
Notice that quickstart-1 demonstrates multi-valued labels with team assigned to both "platform" and "security". This cluster will match filters for either team: team = "platform" or team = "security".
quickstart-2 (US West Production):
| YAML | |
|---|---|
quickstart-3 (EU West Development):
| YAML | |
|---|---|
This gives you a realistic multi-cluster environment for practicing filter queries:
| Cluster | region | environment | team | tier |
|---|---|---|---|---|
| quickstart-1 | us-east | production | platform, security | critical |
| quickstart-2 | us-west | production | platform | standard |
| quickstart-3 | eu-west | development | infrastructure | standard |
GlassQL Filter Query Language
GlassQL is SPOG's filter query language for selecting and grouping clusters based on their labels. It uses a SQL-like syntax that's intuitive for anyone familiar with database queries.
When to Use Filters
- Interactive filtering: Type queries in the Glass UI filter input to narrow the cluster list
- Dashboard widgets: Configure widgets to show specific cluster subsets
- Programmatic selection: Use filters in API calls to target specific clusters
Query Anatomy
A GlassQL query consists of:
- Conditions: Label comparisons (e.g.,
region = "us-east") - Logical operators: Combine conditions (
and,or,not) - Grouping clause (optional): Organize results (
group by)
| Text Only | |
|---|---|
Technical Specifications
Case Sensitivity: All label keys and values are case-sensitive. region = "US-East" will not match region: "us-east".
Quoting Requirements: String values containing spaces or special characters must be enclosed in double quotes:
| Text Only | |
|---|---|
Reserved Keywords: The following are reserved and cannot be used as label keys without special handling:
- and, or, not
- in, like, contains
- group, by
- cluster_id (special field, not a label)
Comparison Operators
Equality: = and !=
Match exact label values:
| Text Only | |
|---|---|
| Text Only | |
|---|---|
The equality operators perform exact string matching. Values are case-sensitive. For multi-valued labels, a cluster matches if any of its values equals the filter value.
Set Membership: in and not in
Match any value from a set:
| Text Only | |
|---|---|
Exclude values from a set:
| Text Only | |
|---|---|
The in operator is useful when you want to match multiple possible values for a label. For multi-valued labels, a cluster matches if any of its values is in the filter set.
Pattern Matching: like and not like
Match using glob patterns with * (any characters) and ? (single character):
| Text Only | |
|---|---|
| Text Only | |
|---|---|
Pattern matching is useful for:
- Matching regions by prefix:
region like "us-*"(all US regions) - Matching clusters by naming convention:
cluster_id like "prod-*" - Excluding test clusters:
cluster_id not like "*-test"
Escaping Special Characters: If your label values contain literal * or ? characters, you cannot escape them in the current implementation. Consider using the contains operator or exact equality matching instead.
Substring Matching: contains and not contains
Check if a value contains a substring:
| Text Only | |
|---|---|
| Text Only | |
|---|---|
Numeric Comparison: <, >, <=, >=
Compare numeric label values:
| Text Only | |
|---|---|
| Text Only | |
|---|---|
Numeric operators parse label values as numbers. They're useful when you have labels like priority, replicas, or version that contain numeric values.
Non-Numeric Values
If a label value cannot be parsed as a number, the comparison will fail and the cluster will not match. For example, if priority = "high", then priority < 3 will not match that cluster. Ensure label values are numeric when using numeric comparison operators.
Logical Operators
AND: Both Conditions Must Match
| Text Only | |
|---|---|
Both conditions must be true for a cluster to match.
OR: Either Condition Matches
| Text Only | |
|---|---|
Either condition can be true for a cluster to match.
NOT: Negate a Condition
| Text Only | |
|---|---|
Inverts the match result. Note the parentheses around the condition being negated.
Combining Conditions & Operator Precedence
When combining multiple operators, SPOG evaluates them in this order (highest precedence first):
- Parentheses
() not- Comparison operators (
=,!=,in,like, etc.) andor
Example: Without parentheses
| Text Only | |
|---|---|
Due to operator precedence, this evaluates as: region = "us-east" or (region = "us-west" and environment = "production")
Step-by-step evaluation for each cluster:
- quickstart-1 (
region: "us-east",environment: "production"): - First condition:
region = "us-east"→ TRUE -
OR operator: Since first condition is true, entire query is TRUE ✓
-
quickstart-2 (
region: "us-west",environment: "production"): - First condition:
region = "us-east"→ FALSE - Second condition:
region = "us-west"→ TRUE - Third condition:
environment = "production"→ TRUE - Second AND third: TRUE and TRUE → TRUE
-
OR operator: FALSE or TRUE → TRUE ✓
-
quickstart-3 (
region: "eu-west",environment: "development"): - First condition:
region = "us-east"→ FALSE - Second condition:
region = "us-west"→ FALSE - OR operator: FALSE or (FALSE and anything) → FALSE ✗
→ Result: quickstart-1, quickstart-2
Example: With parentheses for clarity
| Text Only | |
|---|---|
This ensures the OR is evaluated first, then the AND.
→ quickstart-1, quickstart-2 (both are in US regions AND are production)
Complex query example:
| Text Only | |
|---|---|
Use Parentheses for Clarity
Even when not strictly required, parentheses make your intent clear to future readers and prevent subtle bugs from precedence confusion.
Group By Clause
The group by clause organizes results into a hierarchical structure based on label values.
Basic Grouping
| Text Only | |
|---|---|
Result structure:
Multi-Level Grouping
| Text Only | |
|---|---|
Result structure:
| JSON | |
|---|---|
Filter Then Group
Apply conditions first, then organize the results:
| Text Only | |
|---|---|
Groups clusters first by tier, then by team within each tier.
Widget-Specific Grouping Behavior
Different UI widgets interpret the group by clause in different ways:
- Tree widgets (like
cc-state-tree-table): Display a hierarchical tree with each group level as a parent node - Flat list widgets: May ignore grouping or display groups as section headers
- Chart widgets: Use groups as data series or categories
Consult the widget documentation to understand how it uses grouping information.
Cluster ID Field
The special cluster_id field lets you query by cluster identity. This is not a label, but a built-in field available for all clusters:
| Text Only | |
|---|---|
| Text Only | |
|---|---|
| Text Only | |
|---|---|
The cluster_id field supports all string comparison operators (=, !=, in, not in, like, not like, contains, not contains).
Simple Filters: Implicit Substring Matching
When you enter a simple string without any operators, GlassQL automatically treats it as a substring search against cluster_id. This enables very concise filtering:
| Text Only | |
|---|---|
cluster_id contains "us"
This means typing just us will match clusters like us-east-prod-001, dns-us-west, or any cluster with "us" anywhere in its ID.
Leveraging Hierarchical Cluster IDs
This behavior becomes powerful when you adopt a hierarchical naming convention for cluster IDs:
| YAML | |
|---|---|
With this naming scheme, simple filters become very effective:
| Filter | Matches | Description |
|---|---|---|
us |
us-east-prod-dns-001, us-west-prod-dns-002 |
All US clusters |
prod |
us-east-prod-dns-001, us-west-prod-dns-002 |
All production clusters |
us-east |
us-east-prod-dns-001 |
US East region only |
staging |
eu-central-staging-dns-001 |
Staging environment |
001 |
us-east-prod-dns-001, eu-central-staging-dns-001, ap-north-dev-dns-001 |
First instance of each |
Combine with Labels
While hierarchical cluster IDs enable quick filtering, labels are still recommended for structured organization and access control. Use simple cluster ID filters for quick exploration, and explicit label queries for dashboards and authorization policies.
Quick Reference
| Operator | Description | Example |
|---|---|---|
= |
Exact match | region = "us-east" |
!= |
Not equal | environment != "production" |
in |
Value in set | region in ("us-east", "us-west") |
not in |
Value not in set | tier not in ("experimental") |
like |
Glob pattern match | region like "us-*" |
not like |
Pattern exclusion | cluster_id not like "*-test" |
contains |
Substring match | team contains "plat" |
not contains |
No substring | name not contains "backup" |
<, >, <=, >= |
Numeric comparison | priority < 3 |
and |
Logical AND | env = "prod" and team = "platform" |
or |
Logical OR | region = "us-east" or region = "eu-west" |
not |
Logical NOT | not (env = "development") |
group by |
Hierarchical grouping | ... group by region, environment |
Hands-On Exercises
These exercises use the quickstart deployment. If you haven't completed the quickstart, do so first.
Exercise 1: Explore Labels in the UI
Open the Glass UI and examine the quickstart clusters.
Tasks:
- Click the filter input field and start typing a few letters (e.g.,
reg) to see autocomplete suggestions - Note which label keys are available (region, environment, team, tier, role)
- Continue typing
region =and observe the value suggestions - Identify which cluster has the
criticaltier - Click on a label value in the tree table (e.g., click "us-east" under a cluster's region) to automatically populate a filter query
Click Labels to Filter
You can click on label values displayed in the tree table to quickly create filter queries. Clicking a single value creates an equality filter (region = "us-east"). Selections are persistent—clicking additional label values adds them to the filter, creating a set membership query (region in ("us-east", "us-west")). Click a selected value again to deselect it.
Expected Results
- Available labels:
region,environment,role,team,tier,cluster_id - Region values:
us-east,us-west,eu-west - The cluster with
tier: "critical"is quickstart-1
Exercise 2: Practice Filter Queries
Test these queries in the Glass UI filter input. After each query, verify which clusters are displayed.
Task 1: Show only production clusters
Query: environment = "production"
Expected Result
- quickstart-1 and quickstart-2 are shown
- quickstart-3 is hidden (it's development)
Task 2: Show US-based clusters
Query: region in ("us-east", "us-west")
Expected Result
- quickstart-1 and quickstart-2 are shown
- quickstart-3 is hidden (it's eu-west)
Task 3: Combine conditions - production AND platform team
Query: environment = "production" and team = "platform"
Expected Result
- quickstart-1 and quickstart-2 are shown
- Both are production environment AND owned by platform team
Task 4: Pattern match - regions starting with "us"
Query: region like "us-*"
Expected Result
- quickstart-1 and quickstart-2 are shown
- Matches any region starting with "us"
Task 5: Complex query - critical OR infrastructure team
Query: tier = "critical" or team = "infrastructure"
Expected Result
- quickstart-1 (critical tier) and quickstart-3 (infrastructure team) are shown
- quickstart-2 is hidden (standard tier, platform team)
Task 6: Query multi-valued labels - security team
Query: team = "security"
Expected Result
- quickstart-1 is shown (has team: ["platform", "security"])
- quickstart-2 and quickstart-3 are hidden (neither has "security" in their team label)
- This demonstrates how multi-valued labels match: a cluster matches if any of its values match the filter
Task 7: Quick filter using cluster_id shorthand
Query: quick
Expected Result
- quickstart-1, quickstart-2, and quickstart-3 are all shown
- This simple string is automatically interpreted as
cluster_id contains "quick" - Try
start-1to match only quickstart-1, or2to match quickstart-2
Exercise 3: Add a Fourth Cluster
Extend the quickstart by adding a fourth cluster with new label values.
Step 1: Create the values file
Create quickstart-4.yaml:
| YAML | |
|---|---|
Step 2: Deploy the cluster
Step 3: Verify in the UI
After deployment, verify the new cluster appears:
| Text Only | |
|---|---|
Expected Result
- quickstart-4 appears as the only cluster matching
ap-north
Step 4: Test new filter combinations
Now you have a staging cluster. Test these queries:
| Text Only | |
|---|---|
| Text Only | |
|---|---|
| Text Only | |
|---|---|
Step 5: Cleanup (Optional)
To remove the fourth cluster when you're done experimenting:
| Bash | |
|---|---|
Best Practices & Troubleshooting
Best Practices
Label Naming Conventions
| Guideline | Good Example | Avoid |
|---|---|---|
| Use lowercase | environment: "production" |
Environment: "Production" |
| Use hyphens for multi-word values | region: "us-east" |
region: "us east" |
| Be consistent across clusters | All use environment |
Mix of env, environment, stage |
| Use full words | environment |
env |
Taxonomy Planning Checklist
Before deploying SPOG to production, document your label taxonomy:
- List all label keys you'll use
- Define allowed values for each key
- Document which labels are required vs optional
- Specify who owns/maintains each label
- Plan how labels map to access control policies
Common Pitfalls to Avoid
- Inconsistent label keys: Using
envin some clusters andenvironmentin others - Too many labels: Creating labels that aren't used for filtering or access control
- Changing labels frequently: Labels should be stable; frequent changes break filters
- Forgetting quotes:
region = us-eastfails; useregion = "us-east"