-
Notifications
You must be signed in to change notification settings - Fork 21
feat: register ext.Lists() in CEL environment #186
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -69,6 +69,7 @@ func buildCELOptions(ctx *EvaluationContext) []cel.EnvOption { | |
| // Enable optional types for optional chaining syntax (e.g., a.?b.?c) | ||
| options = append(options, cel.OptionalTypes()) | ||
| options = append(options, ext.Strings()) | ||
| options = append(options, ext.Lists()) | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Cross-component CEL drift risks policy mismatch (CWE-436/CWE-693). Line 72 enables As per coding guidelines, “Validate changes against HyperFleet architecture standards from the linked architecture repository” and “Prioritize Critical and Major severity issues.” 🤖 Prompt for AI AgentsSources: Coding guidelines, Linked repositories |
||
| options = append(options, customCELFunctions()...) | ||
|
|
||
| // Get a snapshot of the data for thread safety | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -20,6 +20,11 @@ | |
| # 13. toJson() — JSON serialization (new helper) | ||
| # 14. adapter.? — adapter execution metadata access | ||
| # 15. Go templates — template rendering with {{ }} | ||
| # 16. distinct() — deduplicate list elements (ext.Lists) | ||
| # 17. sort() — sort list elements (ext.Lists) | ||
| # 18. slice() — extract a sub-list by index range (ext.Lists) | ||
| # 19. flatten() — collapse nested lists into one (ext.Lists) | ||
| # 20. sortBy() — sort objects by a derived key (ext.Lists) | ||
|
Comment on lines
+23
to
+27
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. CEL list extension version skew with hyperfleet-sentinel. Sentinel's decision.go and payload/builder.go register ext.Strings() but not ext.Lists(). ADR 0006 defines CEL as a shared expression engine. Configs using 🤖 Prompt for AI AgentsSource: Linked repositories |
||
|
|
||
| params: | ||
| - name: "clusterId" | ||
|
|
@@ -141,6 +146,46 @@ preconditions: | |
| - name: "timestamp" | ||
| expression: "\"2006-01-02T15:04:05Z07:00\"" | ||
|
|
||
| # --------------------------------------------------------------- | ||
| # Pattern 16: distinct() — deduplicate list elements | ||
| # Removes duplicate entries from the tags list. | ||
| # --------------------------------------------------------------- | ||
| - name: "uniqueTags" | ||
| expression: | | ||
| spec.tags.distinct() | ||
|
|
||
| # --------------------------------------------------------------- | ||
| # Pattern 17: sort() — sort list elements alphabetically | ||
| # Sorts the deduplicated tags list in ascending order. | ||
| # --------------------------------------------------------------- | ||
| - name: "sortedTags" | ||
| expression: | | ||
| spec.tags.distinct().sort() | ||
|
|
||
| # --------------------------------------------------------------- | ||
| # Pattern 18: slice() — extract a sub-list by index range | ||
| # Returns the first node pool name only (indices 0..1 exclusive). | ||
| # --------------------------------------------------------------- | ||
| - name: "firstNodePoolName" | ||
| expression: | | ||
| spec.node_pools.map(p, p.name).slice(0, 1) | ||
|
|
||
| # --------------------------------------------------------------- | ||
| # Pattern 19: flatten() — collapse nested lists into one | ||
| # Extracts type and status from each condition into a flat list. | ||
| # --------------------------------------------------------------- | ||
| - name: "conditionSummary" | ||
| expression: | | ||
| status.conditions.map(c, [c.type, c.status]).flatten() | ||
|
|
||
| # --------------------------------------------------------------- | ||
| # Pattern 20: sortBy() — sort objects by a derived key | ||
| # Sorts node pools by replica count ascending, then extracts names. | ||
| # --------------------------------------------------------------- | ||
| - name: "nodePoolsByReplicas" | ||
| expression: | | ||
| spec.node_pools.sortBy(p, p.replicas).map(p, p.name) | ||
|
|
||
| conditions: | ||
| - field: "clusterStatus" | ||
| operator: "notEquals" | ||
|
|
@@ -350,6 +395,33 @@ post: | |
| expression: | | ||
| dig(resources, "configmap1.data.endpoint") | ||
|
|
||
| # --------------------------------------------------------- | ||
| # Pattern 16-20 (payload): ext.Lists functions via captured variables | ||
| # Note: raw API fields (spec.*, status.*) are not in scope here — | ||
| # reference the variables captured in the precondition phase instead. | ||
| # --------------------------------------------------------- | ||
| lists: | ||
| unique_tags: | ||
| # Pattern 16: distinct() — captured uniqueTags list as JSON | ||
| expression: | | ||
| toJson(uniqueTags) | ||
| sorted_tags: | ||
| # Pattern 17: sort() — captured sortedTags list as JSON | ||
| expression: | | ||
| toJson(sortedTags) | ||
| first_pool: | ||
| # Pattern 18: slice() — first element from captured firstNodePoolName | ||
| expression: | | ||
| firstNodePoolName[0] | ||
| condition_summary: | ||
| # Pattern 19: flatten() — captured conditionSummary flat list as JSON | ||
| expression: | | ||
| toJson(conditionSummary) | ||
| pools_by_replicas: | ||
| # Pattern 20: sortBy() — captured nodePoolsByReplicas list as JSON | ||
| expression: | | ||
| toJson(nodePoolsByReplicas) | ||
|
|
||
| # --------------------------------------------------------- | ||
| # Pattern 9 (payload): nested ternary chains — multi-level branching | ||
| # --------------------------------------------------------- | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.