Idp Nested Spec

2 min read

Nested Spec Paths

idp.fields.path

By default, idp.fields maps field names directly to top-level spec paths. Use path to map a field to a nested location in the CRD spec.

idp:
  fields:
    # Flat field — maps to spec.repository
    repository:
      label: "Repository"

    # Nested field — maps to spec.app.repository
    repository:
      path: app.repository
      label: "Repository"

    # Deeply nested — maps to spec.app.resources.cpu
    cpu:
      path: app.resources.cpu
      label: "CPU Request"

Callers submit flat field names — they don’t need to know about nesting. The gateway maps the field to the correct location in the CRD.

curl -X POST /api/v1/apply \
  -d '{
    "target": "smartapp",
    "repository": "myorg/payments-api",  # → spec.app.repository
    "cpu": "500m"                         # → spec.app.resources.cpu
  }'

Why Use path

Without pathWith path
Fields must match CRD structureFields are flat and caller-friendly
Callers must know nested pathsCallers submit simple field names
CRD evolution breaks callersGateway maps to new paths
UI fields show dot-pathsUI fields show clean names

Validation

ork validate enforces:

  • Unique paths — no two fields can map to the same spec location
  • Valid format — path segments must be valid Kubernetes names (alphanumeric, _, -, .)
  • No empty segmentsapp..repository is rejected
  • No leading/trailing dots.app.repository is rejected

Schema Validation (Not Yet Implemented)

Path existence in the CRD schema is not yet validated by ork validate. The platform team must verify that nested paths exist in the CRD spec. This will be added in a future release when OpenAPI schemas are loaded into the Katalog.

Example

CRD:

spec:
  app:
    repository: string
    image: string
    resources:
      cpu: string
      memory: string
  scaling:
    replicas: integer
    minReplicas: integer
    maxReplicas: integer

IDP Config:

idp:
  fields:
    repository:
      path: app.repository
      label: "Repository"
    image:
      path: app.image
      label: "Container Image"
    cpu:
      path: app.resources.cpu
      label: "CPU Request"
    memory:
      path: app.resources.memory
      label: "Memory Request"
    replicas:
      path: scaling.replicas
      label: "Replicas"

Caller Request:

{
  "target": "smartapp",
  "repository": "myorg/payments-api",
  "image": "ghcr.io/myorg/app:v1",
  "cpu": "500m",
  "memory": "512Mi",
  "replicas": 3
}

Generated CR:

spec:
  app:
    repository: myorg/payments-api
    image: ghcr.io/myorg/app:v1
    resources:
      cpu: 500m
      memory: 512Mi
  scaling:
    replicas: 3

idp.fields — field configuration reference

idp.additionalFields — labels and annotations as fields

Target Mode API — submitting fields instead of CRs