Validation Reference
Complete technical reference for all validation types supported by the Kubeasy CLI.
This page provides the complete reference for all validation types used in challenge.yaml objectives. Each objective is executed by the CLI directly against the Kubernetes cluster when users run kubeasy challenge submit.
Overview
| Type | Purpose | Target Resources |
|---|---|---|
condition | Check Kubernetes conditions (Ready, Available) | Any resource with .status.conditions |
status | Check status fields with comparison operators | Any resource with .status |
log | Find strings in container logs | Pod |
event | Detect forbidden Kubernetes events | Pod |
connectivity | Test HTTP connectivity between pods | Pod (source) |
Objective Structure
Every objective in challenge.yaml follows this structure:
objectives:
- key: unique-identifier # Required: unique key for this objective
title: "User-Friendly Title" # Required: shown in UI
description: "What this checks" # Required: description
order: 1 # Optional: display order
type: condition # Required: validation type
spec: # Required: type-specific config
target: # Required for most types
kind: Pod
labelSelector:
app: my-app
# ... type-specific fieldsTarget Specification
Most validation types use a target to specify which resources to check:
spec:
target:
kind: Pod # Required: resource kind (Pod, Deployment, Job, etc.)
name: my-pod # Optional: match a specific resource by name
labelSelector: # Optional: match resources by labels
app: my-appResolution:
- If
nameis set, validates that specific resource - If
labelSelectoris set, validates all matching resources - Provide at least one of
nameorlabelSelector
Condition Validation
Checks Kubernetes status conditions on a resource. Conditions are the standard mechanism Kubernetes uses to report resource health.
Spec
type: condition
spec:
target:
kind: Pod
labelSelector:
app: my-app
checks:
- type: Ready # Condition type to check
status: "True" # Expected status valueFields
| Field | Type | Required | Description |
|---|---|---|---|
target | TargetSpec | Yes | Resource to check |
checks | []ConditionCheck | Yes | List of condition checks |
ConditionCheck fields:
| Field | Type | Required | Description |
|---|---|---|---|
type | string | Yes | Condition type name |
status | string | Yes | Expected status ("True", "False", "Unknown") |
Common Conditions
Pod:
Ready-- All containers are readyContainersReady-- All containers have passed readiness checksPodScheduled-- Pod has been scheduled to a nodeInitialized-- All init containers have completed
Deployment:
Available-- Minimum replicas are availableProgressing-- Deployment is making progress
Job:
Complete-- Job has completed successfullyFailed-- Job has failed
Examples
Pod readiness:
type: condition
spec:
target:
kind: Pod
labelSelector:
app: web-app
checks:
- type: Ready
status: "True"Deployment availability:
type: condition
spec:
target:
kind: Deployment
name: my-deployment
checks:
- type: Available
status: "True"Multiple conditions:
type: condition
spec:
target:
kind: Pod
labelSelector:
app: web-app
checks:
- type: Ready
status: "True"
- type: ContainersReady
status: "True"Status Validation
Checks arbitrary status fields on a resource using comparison operators. Use this for numeric comparisons (restart count, replica count) or string field checks.
Spec
type: status
spec:
target:
kind: Pod
labelSelector:
app: my-app
checks:
- field: "containerStatuses[0].restartCount"
operator: "<"
value: 3Fields
| Field | Type | Required | Description |
|---|---|---|---|
target | TargetSpec | Yes | Resource to check |
checks | []StatusCheck | Yes | List of status field checks |
StatusCheck fields:
| Field | Type | Required | Description |
|---|---|---|---|
field | string | Yes | JSONPath-like field path relative to .status |
operator | string | Yes | Comparison operator |
value | any | Yes | Expected value to compare against |
Operators
| Operator | Description |
|---|---|
== | Equal to |
!= | Not equal to |
> | Greater than |
< | Less than |
>= | Greater than or equal to |
<= | Less than or equal to |
Field Path Syntax
Field paths are relative to the resource's .status:
| Syntax | Example | Description |
|---|---|---|
| Simple field | phase | .status.phase |
| Nested field | readyReplicas | .status.readyReplicas |
| Array index | containerStatuses[0].restartCount | First container's restart count |
| Array filter | conditions[type=Ready].status | Status of the Ready condition |
Examples
Low restart count:
type: status
spec:
target:
kind: Pod
labelSelector:
app: my-app
checks:
- field: "containerStatuses[0].restartCount"
operator: "<"
value: 3Minimum replicas:
type: status
spec:
target:
kind: Deployment
name: my-deployment
checks:
- field: "readyReplicas"
operator: ">="
value: 2Pod phase:
type: status
spec:
target:
kind: Pod
labelSelector:
app: my-app
checks:
- field: "phase"
operator: "=="
value: "Running"Log Validation
Searches for expected strings in container logs.
Spec
type: log
spec:
target:
kind: Pod
labelSelector:
app: my-app
expectedStrings:
- "Server started successfully"
sinceSeconds: 300Fields
| Field | Type | Required | Description |
|---|---|---|---|
target | TargetSpec | Yes | Pod to check logs from |
container | string | No | Container name (defaults to first container) |
expectedStrings | []string | Yes | Strings that must appear in logs |
sinceSeconds | int | No | Only check logs from last N seconds (default: 300) |
Examples
Basic log check:
type: log
spec:
target:
kind: Pod
labelSelector:
app: api-service
expectedStrings:
- "Connected to database successfully"Specific container:
type: log
spec:
target:
kind: Pod
labelSelector:
app: my-app
container: sidecar
expectedStrings:
- "Sidecar initialized"
sinceSeconds: 60Multiple expected strings:
type: log
spec:
target:
kind: Pod
labelSelector:
app: web-app
expectedStrings:
- "Server started"
- "Listening on port 8080"
sinceSeconds: 120Event Validation
Checks that no forbidden Kubernetes events have occurred for the target resource within a time window.
Spec
type: event
spec:
target:
kind: Pod
labelSelector:
app: my-app
forbiddenReasons:
- "OOMKilled"
- "Evicted"
sinceSeconds: 300Fields
| Field | Type | Required | Description |
|---|---|---|---|
target | TargetSpec | Yes | Resource to check events for |
forbiddenReasons | []string | Yes | Event reasons that must NOT appear |
sinceSeconds | int | No | Time window to check (default: 300) |
Common Forbidden Reasons
| Reason | Description |
|---|---|
OOMKilled | Container exceeded memory limit |
CrashLoopBackOff | Container keeps crashing and restarting |
Evicted | Pod was evicted from the node |
FailedScheduling | Pod could not be scheduled |
BackOff | Back-off restarting failed container |
FailedMount | Volume mount failed |
FailedAttachVolume | Volume attach failed |
Unhealthy | Container failed liveness/readiness probe |
Examples
No crash events:
type: event
spec:
target:
kind: Pod
labelSelector:
app: data-processor
forbiddenReasons:
- "OOMKilled"
- "Evicted"
sinceSeconds: 300No scheduling failures:
type: event
spec:
target:
kind: Pod
labelSelector:
app: web-app
forbiddenReasons:
- "FailedScheduling"
sinceSeconds: 600Connectivity Validation
Tests HTTP connectivity from a source pod to one or more target URLs. The CLI creates a temporary curl pod or uses an existing source pod to make HTTP requests.
Spec
type: connectivity
spec:
sourcePod:
labelSelector:
app: client
targets:
- url: "http://backend:8080/health"
expectedStatusCode: 200
timeoutSeconds: 5Fields
| Field | Type | Required | Description |
|---|---|---|---|
sourcePod | SourcePodSpec | Yes | Pod to make requests from |
targets | []ConnectivityTarget | Yes | URLs to test |
SourcePodSpec fields:
| Field | Type | Required | Description |
|---|---|---|---|
labelSelector | map | Yes | Labels to find the source pod |
ConnectivityTarget fields:
| Field | Type | Required | Description |
|---|---|---|---|
url | string | Yes | URL to request |
expectedStatusCode | int | Yes | Expected HTTP status code |
headers | map | No | Custom HTTP headers |
timeoutSeconds | int | No | Request timeout (default: 5) |
Examples
Basic service connectivity:
type: connectivity
spec:
sourcePod:
labelSelector:
app: client
targets:
- url: "http://backend-service:8080/health"
expectedStatusCode: 200Ingress routing with Host header:
type: connectivity
spec:
sourcePod:
labelSelector:
app: client
targets:
- url: "http://ingress-nginx-controller.ingress-nginx.svc.cluster.local"
headers:
Host: "api.local"
expectedStatusCode: 200
timeoutSeconds: 10Testing blocked connectivity (NetworkPolicy):
type: connectivity
spec:
sourcePod:
labelSelector:
app: untrusted-client
targets:
- url: "http://secure-service:8080"
expectedStatusCode: 0
timeoutSeconds: 3Use expectedStatusCode: 0 to verify that a connection is blocked.
Multiple targets:
type: connectivity
spec:
sourcePod:
labelSelector:
app: client
targets:
- url: "http://frontend:80"
expectedStatusCode: 200
- url: "http://api:8080/health"
expectedStatusCode: 200
- url: "http://database:5432"
expectedStatusCode: 0Complete Challenge Example
A complete challenge.yaml using multiple validation types:
title: Service Connectivity
description: |
A web application can't reach its backend API.
Users report that the frontend loads but shows no data.
theme: networking
difficulty: medium
type: fix
estimatedTime: 20
initialSituation: |
A frontend and backend are deployed in the same namespace.
The frontend pod is running but cannot connect to the backend service.
objective: |
Restore connectivity between the frontend and backend.
objectives:
- key: backend-ready
title: "Backend Running"
description: "The backend pod must be healthy"
order: 1
type: condition
spec:
target:
kind: Pod
labelSelector:
app: backend
checks:
- type: Ready
status: "True"
- key: backend-logs
title: "Backend Serving"
description: "The backend must be accepting requests"
order: 2
type: log
spec:
target:
kind: Pod
labelSelector:
app: backend
expectedStrings:
- "Listening on port 8080"
- key: no-crashes
title: "Stable Operation"
description: "No crash events"
order: 3
type: event
spec:
target:
kind: Pod
labelSelector:
app: backend
forbiddenReasons:
- "CrashLoopBackOff"
- "OOMKilled"
sinceSeconds: 300
- key: frontend-to-backend
title: "Service Connectivity"
description: "Frontend must reach the backend"
order: 4
type: connectivity
spec:
sourcePod:
labelSelector:
app: frontend
targets:
- url: "http://backend:8080/health"
expectedStatusCode: 200
timeoutSeconds: 5
- key: low-restarts
title: "Low Restart Count"
description: "Backend must be stable"
order: 5
type: status
spec:
target:
kind: Pod
labelSelector:
app: backend
checks:
- field: "containerStatuses[0].restartCount"
operator: "<"
value: 3Related Resources
- Validation Rules -- Practical examples and anti-patterns
- Challenge Structure -- Complete challenge format
- Testing Challenges -- Testing validation locally