Kubeasy LogoKubeasy

Validation Reference

Complete technical reference for all validation types supported by the Kubeasy CLI.

Last updated: February 15, 2026GitHubView on GitHub

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

TypePurposeTarget Resources
conditionCheck Kubernetes conditions (Ready, Available)Any resource with .status.conditions
statusCheck status fields with comparison operatorsAny resource with .status
logFind strings in container logsPod
eventDetect forbidden Kubernetes eventsPod
connectivityTest HTTP connectivity between podsPod (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 fields

Target 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-app

Resolution:

  • If name is set, validates that specific resource
  • If labelSelector is set, validates all matching resources
  • Provide at least one of name or labelSelector

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 value

Fields

FieldTypeRequiredDescription
targetTargetSpecYesResource to check
checks[]ConditionCheckYesList of condition checks

ConditionCheck fields:

FieldTypeRequiredDescription
typestringYesCondition type name
statusstringYesExpected status ("True", "False", "Unknown")

Common Conditions

Pod:

  • Ready -- All containers are ready
  • ContainersReady -- All containers have passed readiness checks
  • PodScheduled -- Pod has been scheduled to a node
  • Initialized -- All init containers have completed

Deployment:

  • Available -- Minimum replicas are available
  • Progressing -- Deployment is making progress

Job:

  • Complete -- Job has completed successfully
  • Failed -- 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: 3

Fields

FieldTypeRequiredDescription
targetTargetSpecYesResource to check
checks[]StatusCheckYesList of status field checks

StatusCheck fields:

FieldTypeRequiredDescription
fieldstringYesJSONPath-like field path relative to .status
operatorstringYesComparison operator
valueanyYesExpected value to compare against

Operators

OperatorDescription
==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:

SyntaxExampleDescription
Simple fieldphase.status.phase
Nested fieldreadyReplicas.status.readyReplicas
Array indexcontainerStatuses[0].restartCountFirst container's restart count
Array filterconditions[type=Ready].statusStatus 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: 3

Minimum replicas:

type: status
spec:
  target:
    kind: Deployment
    name: my-deployment
  checks:
    - field: "readyReplicas"
      operator: ">="
      value: 2

Pod 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: 300

Fields

FieldTypeRequiredDescription
targetTargetSpecYesPod to check logs from
containerstringNoContainer name (defaults to first container)
expectedStrings[]stringYesStrings that must appear in logs
sinceSecondsintNoOnly 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: 60

Multiple expected strings:

type: log
spec:
  target:
    kind: Pod
    labelSelector:
      app: web-app
  expectedStrings:
    - "Server started"
    - "Listening on port 8080"
  sinceSeconds: 120

Event 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: 300

Fields

FieldTypeRequiredDescription
targetTargetSpecYesResource to check events for
forbiddenReasons[]stringYesEvent reasons that must NOT appear
sinceSecondsintNoTime window to check (default: 300)

Common Forbidden Reasons

ReasonDescription
OOMKilledContainer exceeded memory limit
CrashLoopBackOffContainer keeps crashing and restarting
EvictedPod was evicted from the node
FailedSchedulingPod could not be scheduled
BackOffBack-off restarting failed container
FailedMountVolume mount failed
FailedAttachVolumeVolume attach failed
UnhealthyContainer failed liveness/readiness probe

Examples

No crash events:

type: event
spec:
  target:
    kind: Pod
    labelSelector:
      app: data-processor
  forbiddenReasons:
    - "OOMKilled"
    - "Evicted"
  sinceSeconds: 300

No scheduling failures:

type: event
spec:
  target:
    kind: Pod
    labelSelector:
      app: web-app
  forbiddenReasons:
    - "FailedScheduling"
  sinceSeconds: 600

Connectivity 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: 5

Fields

FieldTypeRequiredDescription
sourcePodSourcePodSpecYesPod to make requests from
targets[]ConnectivityTargetYesURLs to test

SourcePodSpec fields:

FieldTypeRequiredDescription
labelSelectormapYesLabels to find the source pod

ConnectivityTarget fields:

FieldTypeRequiredDescription
urlstringYesURL to request
expectedStatusCodeintYesExpected HTTP status code
headersmapNoCustom HTTP headers
timeoutSecondsintNoRequest timeout (default: 5)

Examples

Basic service connectivity:

type: connectivity
spec:
  sourcePod:
    labelSelector:
      app: client
  targets:
    - url: "http://backend-service:8080/health"
      expectedStatusCode: 200

Ingress 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: 10

Testing blocked connectivity (NetworkPolicy):

type: connectivity
spec:
  sourcePod:
    labelSelector:
      app: untrusted-client
  targets:
    - url: "http://secure-service:8080"
      expectedStatusCode: 0
      timeoutSeconds: 3

Use 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: 0

Complete 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: 3

On this page