Simple Schema
kro follows a different approach for defining your API schema and shapes. It leverages a human-friendly and readable syntax that is OpenAPI specification compatible. Here's a comprehensive example:
apiVersion: kro.run/v1alpha1
kind: ResourceGraphDefinition
metadata:
name: web-application
spec:
schema:
apiVersion: v1alpha1
kind: WebApplication
spec:
# Basic types
name: string | required=true description="My Name"
replicas: integer | default=1 minimum=1 maximum=100
image: string | required=true
# Structured type
ingress:
enabled: boolean | default=false
host: string | default="example.com"
path: string | default="/"
# Array type
ports: "[]integer"
# Map type
env: "map[string]mytype"
# Custom Types
types:
myType:
value1: string | required=true
value2: integer | default=42
status:
# Status fields with auto-inferred types
availableReplicas: ${deployment.status.availableReplicas}
serviceEndpoint: ${service.status.loadBalancer.ingress[0].hostname}
Type Definitions
Basic Types
kro supports these foundational types:
string
: Text valuesinteger
: Whole numbersboolean
: True/False valuesfloat
: Decimal numbers
For example:
name: string
age: integer
enabled: boolean
price: float
Structure Types
You can create complex objects by nesting fields. Each field can use any type, including other structures:
# Simple structure
address:
street: string
city: string
zipcode: string
# Nested structures
user:
name: string
address: # Nested object
street: string
city: string
contacts: "[]string" # Array of strings
Array Types
Arrays are denoted using []
syntax:
- Basic arrays:
[]string
,[]integer
,[]boolean
Examples:
tags: []string
ports: []integer
Map Types
Maps are key-value pairs denoted as map[keyType]valueType
:
map[string]string
: String to string mappingmap[string]integer
: String to integer mapping
Examples:
labels: "map[string]string"
metrics: "map[string]float"
Custom Types
Custom types are specified in the separate types
section.
They provide a map of names to type specifications that follow the simple schema.
Example:
schema:
types:
Person:
name: string
age: integer
spec:
people: '[]Person | required=true`
Validation and Documentation
Fields can have multiple markers for validation and documentation:
name: string | required=true default="app" description="Application name"
replicas: integer | default=3 minimum=1 maximum=10
mode: string | enum="debug,info,warn,error" default="info"
Supported Markers
required=true
: Field must be provideddefault=value
: Default value if not specifieddescription="..."
: Field documentationenum="value1,value2"
: Allowed valuesminimum=value
: Minimum value for numbersmaximum=value
: Maximum value for numbers
Multiple markers can be combined using the |
separator.
For example:
name: string | required=true default="app" description="Application name"
replicas: integer | default=3 minimum=1 maximum=10
price: float | minimum=0.01 maximum=999.99
mode: string | enum="debug,info,warn,error" default="info"
Status Fields
Status fields use CEL expressions to reference values from resources. kro automatically:
- Infers the correct types from the expressions
- Validates that referenced resources exist
- Updates values when the underlying resources change
status:
# Types are inferred from the referenced fields
availableReplicas: ${deployment.status.availableReplicas}
endpoint: ${service.status.loadBalancer.ingress[0].hostname}
Default Status Fields
kro automatically injects two fields to every instance's status:
1. Conditions
An array of condition objects tracking the instance's state:
status:
conditions:
- type: string # e.g., "Ready", "Progressing"
status: string # "True", "False", "Unknown"
lastTransitionTime: string
reason: string
message: string
Common condition types:
Ready
: Instance is fully reconciledProgressing
: Working towards desired stateDegraded
: Operational but not optimalError
: Reconciliation error occurred
2. State
A high-level summary of the instance's status:
status:
state: string # Ready, Progressing, Degraded, Unknown, Deleting
conditions
and state
are reserved words. If defined in your schema, kro will
override them with its own values.
Additional Printer Columns
You can define additionalPrinterColumns
for the created CRD through the ResourceGraphDefinition by setting them on spec.schema.additionalPrinterColumns
.
schema:
spec:
image: string | default="nginx"
status:
availableReplicas: ${deployment.status.availableReplicas}
additionalPrinterColumns:
- jsonPath: .status.availableReplicas
name: Available replicas
type: integer
- jsonPath: .spec.image
name: Image
type: string