Documentation
¶
Index ¶
- Variables
- func BaseCELExtensions() []cel.EnvOption
- func CustomFunctions() []cel.EnvOption
- func RemoveOmittedFields(data any) any
- type CELMatch
- type Engine
- type EngineCache
- func (c *EngineCache) GetEnv(key string) (*cel.Env, bool)
- func (c *EngineCache) GetProgram(envKey, expression string) (cel.Program, bool)
- func (c *EngineCache) ProgramCacheSize() int
- func (c *EngineCache) SetEnv(key string, env *cel.Env)
- func (c *EngineCache) SetProgram(envKey, expression string, program cel.Program)
- type EngineOption
Constants ¶
This section is empty.
Variables ¶
var ErrNestedExpression = errors.New("nested CEL expressions must be quoted")
ErrNestedExpression is returned when nested CEL expressions are found.
Functions ¶
func BaseCELExtensions ¶ added in v0.9.0
BaseCELExtensions returns the CEL extensions used across OpenChoreo. This includes optional types, common utility extensions for strings, encoding, math, lists, sets, two-variable comprehensions, and OpenChoreo custom functions.
func CustomFunctions ¶
CustomFunctions returns the CEL environment options for custom template functions.
These functions provide additional capabilities beyond the standard CEL-go extensions, designed for use in CEL-based templates throughout OpenChoreo. All custom functions use the "oc_" prefix to avoid potential conflicts with upstream CEL-go.
Available Functions ¶
oc_omit() - Remove fields, map keys, or array items from rendered output
oc_merge(map1, map2, ...mapN) - Shallow merge of multiple maps
oc_generate_name(...strings) - Generate valid Kubernetes resource names (≤253 chars)
oc_dns_label(...strings) - Generate valid Kubernetes DNS label names (≤63 chars)
oc_hash(string) - Generate 8-character hash from input string
oc_omit() - Conditional Omission ¶
Returns a sentinel value that is removed during post-processing. Supports two use cases:
Use Case 1: Remove entire fields from YAML/JSON structure
metadata:
annotations: ${has(spec.annotations) ? spec.annotations : oc_omit()}
labels:
version: ${has(spec.version) ? spec.version : oc_omit()}
Result when spec.annotations and spec.version are undefined:
metadata:
labels: {}
Use Case 2: Remove map keys or array items within CEL expressions
# Conditional map keys
labels: ${{"app": metadata.name, "env": has(spec.env) ? spec.env : oc_omit()}}
# Conditional array items
args: ${["--port=8080", spec.debug ? "--debug" : oc_omit(), "--log=info"]}
oc_merge() - Shallow Map Merge ¶
Merges multiple maps left-to-right, with later maps overriding earlier ones. IMPORTANT: This is a shallow merge - nested maps are replaced, not merged recursively.
# Basic merge
env: ${oc_merge(defaults, spec.env, environmentConfigs)}
# Inline map literals
resources: ${oc_merge({cpu: "100m", memory: "128Mi"}, spec.resources)}
# Variadic merge (3+ maps)
config: ${oc_merge(base, layer1, layer2, layer3)}
Shallow merge behavior:
base = {resources: {cpu: "100m", memory: "128Mi"}, replicas: 1}
override = {resources: {cpu: "200m"}}
result = {resources: {cpu: "200m"}, replicas: 1}
# Note: memory is LOST because resources map was replaced entirely
oc_generate_name() - Kubernetes Name Generation ¶
Generates valid Kubernetes DNS subdomain names from arbitrary strings. Names are sanitized, truncated to 253 characters, and include an 8-character hash suffix for uniqueness.
# Variadic arguments
name: ${oc_generate_name(component.name, environment, "cache")}
# "payment-service", "prod", "cache" -> "payment-service-prod-cache-a1b2c3d4"
# Array input
name: ${oc_generate_name([metadata.namespace, metadata.name, "worker"])}
# Single string (sanitized)
name: ${oc_generate_name("My App!")}
# "My App!" -> "my-app-e5f6g7h8"
Hash suffix ensures uniqueness even when inputs sanitize to the same string:
oc_generate_name("my-app") -> "my-app-abc12345"
oc_generate_name("My App!") -> "my-app-def67890" # Different hash
oc_dns_label() - Kubernetes DNS Label Name Generation ¶
Same as oc_generate_name() but enforces a ≤63 character limit, suitable for Kubernetes DNS label names (e.g., hostname subdomain labels).
# Webapp hostname subdomain (≤63 chars)
hostnames:
- ${oc_dns_label(endpointName, metadata.componentName, metadata.environmentName, metadata.componentNamespace)}.example.com
oc_hash() - String Hashing ¶
Generates an 8-character hexadecimal hash from an input string using the FNV-32a algorithm. Useful for creating stable, deterministic identifiers or suffixes.
The hash is deterministic - the same input always produces the same output:
oc_hash("test") -> "4fdcca5d" # Always produces this hash
oc_hash("test") -> "4fdcca5d" # Same input, same output
All custom functions use the "oc_" prefix to avoid potential conflicts with upstream CEL-go.
func RemoveOmittedFields ¶
RemoveOmittedFields walks the rendered tree after CEL evaluation and strips the omit() sentinel. Templates using the reusable `omit()` helper stay compatible with the rendering pipeline's pruning semantics.
Types ¶
type CELMatch ¶ added in v0.9.0
type CELMatch struct {
FullExpr string // The complete ${...} expression including delimiters
InnerExpr string // The CEL expression content without ${ and }
}
CELMatch represents a CEL expression found in a template string.
func FindCELExpressions ¶ added in v0.9.0
FindCELExpressions locates all ${...} expression markers within a string.
This function performs brace-balanced parsing to handle nested curly braces correctly. For example, in "${merge({a: 1}, {b: 2})}", the parser counts opening and closing braces to identify the complete expression boundary.
The algorithm uses a brace counter that increments on '{' and decrements on '}'. When the counter returns to zero, we've found the matching closing brace.
Returns:
- FullExpr: the complete ${...} expression including delimiters
- InnerExpr: the CEL expression content without ${ and }
Example:
- Input: "image:${spec.image}:${spec.tag}"
- Output: [{FullExpr: "${spec.image}", InnerExpr: "spec.image"}, {FullExpr: "${spec.tag}", InnerExpr: "spec.tag"}]
type Engine ¶
type Engine struct {
// contains filtered or unexported fields
}
Engine evaluates CEL backed templates that can contain inline expressions, map keys, and nested structures.
func NewEngine ¶
func NewEngine() *Engine
NewEngine creates a new CEL template engine with default cache settings.
func NewEngineWithOptions ¶
func NewEngineWithOptions(opts ...EngineOption) *Engine
NewEngineWithOptions creates a new CEL template engine with custom options. Use this for testing and benchmarking different caching strategies, or to add custom CEL extensions.
Example:
// Disable all caching for baseline benchmark engine := template.NewEngineWithOptions(template.DisableCache()) // Add custom CEL extensions engine := template.NewEngineWithOptions(template.WithCELExtensions(context.CELExtensions()...))
type EngineCache ¶
type EngineCache struct {
// contains filtered or unexported fields
}
EngineCache provides caching for CEL environments and compiled programs. It maintains two levels of caching: - Environment cache: LRU cache of CEL environments by variable names - Program cache: LRU cache of compiled programs by (env, expression)
Cache Architecture:
Level 1: ENV Cache (LRU, max 100 entries) └─ envKey: ["trait", "metadata", ..."] → CEL Environment Level 2: PROGRAM Cache (LRU, max 2000 entries) └─ (envKey + expression) → Compiled CEL Program
For a deployment with 5 CTs and 50 traits, expect ~875 cached programs. The 2000 entry limit provides 2x headroom and protects against edge cases like dynamic template updates or multi-tenancy scenarios.
func (*EngineCache) GetEnv ¶
func (c *EngineCache) GetEnv(key string) (*cel.Env, bool)
GetEnv retrieves a cached CEL environment by its cache key. Returns (nil, false) if caching is disabled.
func (*EngineCache) GetProgram ¶
func (c *EngineCache) GetProgram(envKey, expression string) (cel.Program, bool)
GetProgram retrieves a cached compiled CEL program. Returns (nil, false) if caching is disabled.
func (*EngineCache) ProgramCacheSize ¶
func (c *EngineCache) ProgramCacheSize() int
ProgramCacheSize returns the number of entries in the program cache. Returns 0 if caching is disabled. Useful for testing and monitoring cache effectiveness.
func (*EngineCache) SetEnv ¶
func (c *EngineCache) SetEnv(key string, env *cel.Env)
SetEnv stores a CEL environment in the cache. No-op if caching is disabled.
func (*EngineCache) SetProgram ¶
func (c *EngineCache) SetProgram(envKey, expression string, program cel.Program)
SetProgram stores a compiled CEL program in the cache. No-op if caching is disabled.
type EngineOption ¶
type EngineOption func(*Engine)
EngineOption configures the template engine. Used for cache configuration, custom CEL extensions, and testing.
func DisableCache ¶
func DisableCache() EngineOption
DisableCache disables all caching (both environment and program caches). Use this for benchmarking to measure the cost of caching vs compilation.
Example:
engine := template.NewEngineWithOptions(template.DisableCache())
func DisableProgramCacheOnly ¶
func DisableProgramCacheOnly() EngineOption
DisableProgramCacheOnly disables only the program cache, keeping environment cache enabled. Use this to measure the impact of program compilation caching separately from environment caching.
Example:
engine := template.NewEngineWithOptions(template.DisableProgramCacheOnly())
func WithCELExtensions ¶ added in v0.9.0
func WithCELExtensions(extensions ...cel.EnvOption) EngineOption
WithCELExtensions adds custom CEL environment options to the engine. Use this to register custom functions, macros, and types.