Render Definitions
PaletteAI renders CUE templates using a modified version of the KubeVela rendering engine. For a comprehensive introduction to CUE syntax, refer to CUE Basic.
While writing definitions, you may reference additional context variables within your CUE code. CUE context for runtime information covers this in detail. We recommend leveraging context.clusterVersion to author definitions that are compatible with any spoke cluster, regardless of its Kubernetes API version. To review an example, check out Cron Task.
For a list of all supported context variables, check out Full available context in Component.
context.workflowName is unavailable, as PaletteAI does not support KubeVela workflows.
PaletteAI context Variables
The following table contains all the PaletteAI specific context variables available.
| Context Variable | Description | Type |
|---|---|---|
context.workloadYamls | An array of JSON-marshaled strings containing the active Workload custom resource and the Namespace it is destined for.Sample usage in CUE: manifests: [for x in context.workloadYamls {yaml.Unmarshal(x)}]. | []string |
Context Extensions
In addition to the context variables listed above, PaletteAI also supports context extensions. Context extensions are defined as an add-on to a component. They can then be referenced as part of the CUE template. Context extensions are one of the mechanisms by which data can be injected into a Workload resource during rendering. In contrast to outputs, context extensions apply to a definition template, not to the parameters for a definition in a workload profile.
Context extensions support the following types:
-
string -
integer -
boolean -
jsonRaw(for arbitrarily complex objects)
Check out the GSLB definition and its context extension for a working example.
Define a Context Extension
Context extensions are defined alongside a component definition. They can be created in the definition playground.
contextExtensionRefs:
- contextKey: primaryGeoTag
apiVersion: v1
kind: ConfigMap
name: k8gb-config
namespace: k8gb
path: .data.primaryGeoTag
The following table lists the parameters for contextExtensionRefs, ordered alphabetically.
| Parameter | Description | Required |
|---|---|---|
apiVersion | The apiVersion of the referenced object in the spoke cluster. | ✅ |
contextKey | A globally unique identifier for the context extension. | ✅ |
kind | The kind of the referenced object in the spoke cluster. | ✅ |
name | The metadata.name of the referenced object in the spoke cluster. | ✅ |
namespace | The metadata.namespace of the referenced object in the spoke cluster. Can be omitted if referencing a cluster-scoped resource. | ❌ |
path | A JSON path expression that resolves to the value of the context extension. {} is not required in the path expression. | ✅ |
If the referenced object or the path inside the referenced object is not found during the creation of a Workload resource containing a definition with the problematic context extension, the creation of the workload will fail.
Reference a Context Extension
Context extensions can be referenced in a CUE template as follows.
if context.primaryGeoTag != _|_ {
primaryGeoTag: context.primaryGeoTag
}
For context extensions that resolve to a type other than string, a conversion is required. This can be done in a CUE template as follows.
import (
"encoding/json"
)
myComplexVar: json.Unmarshal(context.someJsonValueFromContextExtension)
Status Attributes
Definition templates can include status attributes that control health checking and status reporting for deployed resources.
Health Policy
Health policies provide a boolean indicator of whether a component or trait is functioning correctly. These policies are defined in the attributes.status.healthPolicy field of a ComponentDefinition or TraitDefinition template.
You can define health policies using a multi-line CUE string. The health policy must define an isHealth field that evaluates to a boolean value. The PaletteAI runtime evaluates this field periodically during reconciliation. If you do not define a health policy, health checks always return true; this results in PaletteAI marking the component or trait as healthy immediately after resources are applied to Kubernetes, which may not reflect the actual operational state of the resources.
Use default values (for example, *expression | false) to ensure health checks always return a valid boolean, even when expected fields are missing or errors occur.
Syntax
mycomponent: {
type: "component"
attributes: {
status: {
healthPolicy: #"""
isHealth: context.output.status.readyReplicas == context.output.status.replicas
"""#
}
}
}
Custom Status
Custom status messages provide human-readable status information about deployed resources. They are defined in the attributes.status.customStatus field of a ComponentDefinition or TraitDefinition template.
The custom status must define a message field that evaluates to a string value. The PaletteAI runtime evaluates this field periodically during reconciliation. If you do not define a custom status, PaletteAI returns an empty string. If errors occur during evaluation, PaletteAI also returns an empty string.
Syntax
mycomponent: {
type: "component"
attributes: {
status: {
customStatus: #"""
message:"\(*context.output.status.readyReplicas | 0) / \(*context.output.status.replicas | 0) replicas ready"
"""#
}
}
}
Message Interpolation
CUE supports string interpolation using \(expression) syntax, allowing you to embed dynamic values in status messages.
customStatus: {
message: "\(context.output.status.readyReplicas) / \(context.output.status.replicas) replicas ready"
}
View Custom Status
PaletteAI stores custom status messages in the Workload resource's ComponentStatus or TraitStatus. You can view them using kubectl.
kubectl get workload <workload-name> --namespace <namespace> --output jsonpath='{.status.components[0].message}'
Use default values (for example, *expression | "default") to ensure status messages are always complete, even when expected fields are missing or errors occur.
Status Details
Status details provide structured, machine-readable status information evaluated at runtime from deployed resources. You define status details in the attributes.status.details field of a ComponentDefinition or TraitDefinition template.
Syntax
You can define status details either as a multi-line CUE string or directly as a struct.
mycomponent: {
type: "component"
attributes: {
status: {
details: #"""
fieldName: value
computedField: expression
"""#
}
}
}
mycomponent: {
type: "component"
attributes: {
status: {
details: {
fieldName: "value"
computedField: expression
}
}
}
}
Constraints and Rules
-
Field labels must be fewer than 32 characters (longer fields are skipped).
-
Fields prefixed with
$are considered local and excluded from the output. -
Fields with
@localor@excludeCUE attributes are excluded from the output. -
Fields that match names in the rendering context (such as
context,parameter, etc.) are automatically excluded.
The following CUE expression types are supported in detail fields:
-
Basic literals (strings, numbers, boolean values)
-
Identifiers (variable references)
-
Selector expressions (for example,
context.output.status.phase) -
Function calls (for example,
len(context.output.spec.containers)) -
Binary expressions (for example,
replicas == readyReplicas)
Complex types (nested structs, lists, etc.) are not supported directly but will be JSON-marshaled to strings.
Example
stsstatus: {
type: "component"
description: "StatefulSet with detailed status reporting"
attributes: {
status: {
customStatus: #"""
message: "\(context.output.status.readyReplicas) / \(context.output.status.replicas) replicas ready"
"""#
healthPolicy: #"""
isHealth: context.output.status.readyReplicas == context.output.status.replicas
"""#
details: {
replicas: *context.output.status.replicas | 0
readyReplicas: *context.output.status.readyReplicas | 0
currentRevision: *context.output.status.currentRevision | "unknown"
isReady: *(context.output.status.replicas == context.output.status.readyReplicas) | false
}
}
}
}
template: {
output: {
apiVersion: "apps/v1"
kind: "StatefulSet"
metadata: {
name: context.name
labels: app: context.name
}
spec: {
replicas: parameter.replicas
selector: matchLabels: app: context.name
template: {
metadata: labels: app: context.name
spec: containers: [{
name: "app"
image: "nginx:1.25"
ports: [{
containerPort: 80
name: "http"
}]
}]
}
}
}
parameter: replicas: *3 | int
}
View Status Details
Status details are stored in the Workload resource's ComponentStatus and TraitStatus. You can view them using kubectl.
kubectl get workload <workload-name> --namespace <namespace> --output jsonpath='{.status.components}' | jq
For WorkloadDeployment resources, status details are aggregated per cluster.
kubectl get workloaddeployment <deployment-name> --namespace <namespace> \
--output jsonpath='{.status.statuses.<cluster-name>.components}' | jq
[
[
{
"definitionNamespace": "mural-system",
"details": {
"currentRevision": "myjob-04e0a-c5cc4df5d",
"isReady": "true",
"readyReplicas": "5",
"replicas": "5"
},
"healthy": true,
"message": "5 / 5 replicas ready",
"name": "myjob-04e0a",
"type": "stsstatus"
}
]
]