Skip to content

Import Consumes

The import pattern lets you split large capability specs by extracting the consumes definitions into separate files. The engine loads them at startup — the operator mounts them as individual files into the pod.


When to Use Import

Instead of declaring all consumed APIs inline:

# everything in one file — gets large
capability:
  consumes:
    - namespace: registry
      type: http
      baseUri: "https://..."
      resources: [ ... 50 lines ... ]
    - namespace: legacy
      type: http
      baseUri: "https://..."
      resources: [ ... 40 lines ... ]

Split into separate files:

# main spec — clean and focused
capability:
  consumes:
    - import: registry
      location: "./shared/registry-consumes.yml"
    - import: legacy
      location: "./shared/legacy-consumes.yaml"

Import File Format

Each imported file contains a standard ikanos consumes definition:

# registry-consumes.yml
ikanos: "1.0.0-alpha3"
consumes:
  - namespace: registry
    type: http
    baseUri: "https://api.example.com"
    authentication:
      type: bearer
      token: "{{REGISTRY_TOKEN}}"
    inputParameters:
      - name: Api-Version
        in: header
        value: "{{REGISTRY_VERSION}}"
    resources:
      - name: ships
        path: "/ships"
        operations:
          - name: list-ships
            method: GET
            inputParameters:
              - name: status
                in: query
      - name: ship
        path: "/ships/{{imo_number}}"
        operations:
          - name: get-ship
            method: GET
            inputParameters:
              - name: imo_number
                in: path

ConfigMap Convention

For each import entry, the operator expects a ConfigMap named:

{capability-name}-import-{import-namespace}

The ConfigMap key must match the filename from the location path:

location ConfigMap name ConfigMap key
./shared/registry-consumes.yml {name}-import-registry registry-consumes.yml
./shared/legacy-consumes.yaml {name}-import-legacy legacy-consumes.yaml
./shared/step7-registry-consumes.yml {name}-import-registry step7-registry-consumes.yml

Creating Import ConfigMaps

kubectl create configmap my-capability-import-registry \
  --from-file=registry-consumes.yml=path/to/registry-consumes.yml \
  -n default

kubectl create configmap my-capability-import-legacy \
  --from-file=legacy-consumes.yaml=path/to/legacy-consumes.yaml \
  -n default

The --from-file=<key>=<file> syntax sets the ConfigMap key explicitly. The key must match the filename in the location path.


What the Operator Creates

For each import entry, the operator:

  1. Looks up {capability-name}-import-{namespace} in the cluster
  2. Mounts the file individually via subPath at /data/{location}
location: "./shared/registry-consumes.yml"
  → mounted at: /data/shared/registry-consumes.yml

Using subPath means multiple imports sharing the same parent directory (/data/shared/) do not conflict — each file has its own VolumeMount.

# Verify the mounts on the generated Deployment
kubectl get deployment my-capability -n default \
  -o jsonpath='{.spec.template.spec.containers[0].volumeMounts}' \
  | python3 -m json.tool

Expected output includes entries like:

{
  "mountPath": "/data/shared/registry-consumes.yml",
  "name": "import-registry",
  "readOnly": true,
  "subPath": "registry-consumes.yml"
}

Error: ConfigMap Not Found

If the import ConfigMap does not exist, the operator throws a ReconcileError:

Import ConfigMap 'my-capability-import-registry' not found in namespace 'default'.
Create it with:
kubectl create configmap my-capability-import-registry \
  --from-file=registry-consumes.yml=<path-to-file> -n default

Create all import ConfigMaps before applying the Capability CR.


Complete Example

Directory structure:

my-capability/
├── spec.yaml                       ← main ikanos spec
└── shared/
    ├── registry-consumes.yml
    └── legacy-consumes.yaml

Create ConfigMaps:

kubectl create configmap shipyard-spec \
  --from-file=capability.yaml=my-capability/spec.yaml \
  -n default

kubectl create configmap shipyard-import-registry \
  --from-file=registry-consumes.yml=my-capability/shared/registry-consumes.yml \
  -n default

kubectl create configmap shipyard-import-legacy \
  --from-file=legacy-consumes.yaml=my-capability/shared/legacy-consumes.yaml \
  -n default

Apply the Capability CR:

kubectl apply -f - <<EOF
apiVersion: naftiko.io/v1alpha3
kind: Capability
metadata:
  name: shipyard
  namespace: default
  labels:
    naftiko.io/tier: standard
spec:
  specRef:
    configMap: shipyard-spec
EOF

Verify imports are mounted:

kubectl wait pod -l naftiko.io/capability=shipyard \
  --for=condition=Ready --timeout=60s -n default

kubectl logs -l naftiko.io/capability=shipyard -n default | head -5
# → Reading configuration from: /data/capability.yaml
# → Capability started successfully.