Pre-flight Checklist

Run these commands before deploying workloads to confirm the platform is ready.

  • Operator pod running
    oc get pods -n openshift-integration -l app.kubernetes.io/name=openshift-integration-operator
  • CRD registered
    oc get crd integrationflows.platform.io
  • Console plugin active
    oc get consoleplugin integration-console-plugin -o jsonpath='{.metadata.name}'
  • Kaoto accessible
    oc get route kaoto -n openshift-integration -o jsonpath='{.spec.host}'
  • ArgoCD namespace accessible
    oc get namespace openshift-gitops
  • Tekton Pipeline ready
    oc get pipeline integration-flow-build -n openshift-integration
  • Pipeline ServiceAccount configured
    oc get serviceaccount pipeline -n openshift-integration
    oc adm policy who-can use scc pipelines-scc | grep pipeline
  • OpenTelemetry Collector running
    oc get pods -n openshift-integration -l app=integration-otel-collector

Health Checks

Probe the operator's Quarkus health endpoints from inside the cluster.

Liveness & Readiness

# Liveness probe
oc exec deploy/openshift-integration-operator -n openshift-integration \
  -- curl -s http://localhost:8080/q/health/live

# Readiness probe
oc exec deploy/openshift-integration-operator -n openshift-integration \
  -- curl -s http://localhost:8080/q/health/ready

OpenAPI Spec

# Verify the API spec is served
oc exec deploy/openshift-integration-operator -n openshift-integration \
  -- curl -s http://localhost:8080/q/openapi | head -5
Both endpoints return JSON with "status": "UP" when healthy. If either returns "status": "DOWN", check the operator logs for details.

End-to-End Smoke Test

Walk through the full lifecycle — create, reconcile, verify, and clean up — to confirm all components work together.

  1. Create a test flow
    oc apply -f - <<'EOF'
    apiVersion: platform.io/v1alpha1
    kind: IntegrationFlow
    metadata:
      name: smoke-test
      namespace: openshift-integration
    spec:
      engine: CAMEL
      gitRepository: https://gitea-gitea.apps.example.com/user1/smoke-test
      branch: main
      kaotoDesign: |
        - route:
            id: smoke-test
            from:
              uri: "timer:tick?period=10000"
              steps:
                - log:
                    message: "Smoke test OK"
    EOF
  2. Verify reconciliation
    # Wait for scaffolding
    oc get iflow smoke-test -n openshift-integration -o jsonpath='{.status.phase}'
    # Expected: Building or Deploying
    
    # Check conditions
    oc get iflow smoke-test -n openshift-integration -o jsonpath='{.status.conditions[*].type}'
    # Expected: Scaffolded GitPushed ApplicationSetReady
  3. Verify Git repository
    # Check files were pushed (replace with your git provider URL)
    curl -s -u "user1:password" \
      "https://gitea.example.com/api/v1/repos/user1/smoke-test/contents/" \
      | jq '.[].path'
    # Expected: README.md, pom.xml, src, kaoto-config.json, base
  4. Verify ApplicationSet
    oc get applicationsets -n openshift-gitops | grep smoke-test
    # Expected: smoke-test-appset
  5. Verify Console Plugin
    • Navigate to OpenShift Console → Integration Platform → Integration Flows
    • Verify smoke-test appears in the list
    • Click on smoke-testVisual Flow tab shows the route
    • Switch to Logs tab → worker pod logs stream via proxy (integration-console-plugin/backend)
    • Switch to Kaoto Designer tab → Kaoto loads
  6. Verify Telemetry
    • In the flow detail page, check the "Node Telemetry" sidebar
    • Green dot = connected, node metrics visible
  7. Clean up
    oc delete iflow smoke-test -n openshift-integration

Component Validation Matrix

Use this matrix to systematically verify every platform component.

Component Command / Action Expected Result Status
Operator oc logs deploy/openshift-integration-operator -n openshift-integration --tail=5 "controller started", no errors
CRD oc explain integrationflow.spec Shows engine, gitRepository, branch fields
Console Plugin Browser: /integration-flows List page with table renders
Kaoto Browser: flow detail → Kaoto Designer tab Kaoto editor loads with route/kamelet options
GitOps Push Check git repo after creating flow pom.xml, kaoto-config.json, workflow YAML present
Telemetry SSE Sidebar shows "Node Telemetry" with green dot Latency, throughput, status per node
ArgoCD oc get applicationsets -n openshift-gitops AppSet created per flow
Tekton Pipeline oc get pipeline integration-flow-build -n openshift-integration Pipeline exists with git-clone, maven, buildah tasks
PipelineRun oc get pipelineruns -n openshift-integration -l platform.io/component=build PipelineRuns created per flow, status Succeeded
OTel Collector oc get pods -n openshift-integration -l app=integration-otel-collector Pod running, receiving traces on :4317
RBAC oc auth can-i create integrationflows --as=system:serviceaccount:openshift-integration:integration-operator-sa yes

Multi-namespace flows and RBAC

IntegrationFlow is namespaced. Install the operator once (cluster-admin); users create flows in their OpenShift project. The console plugin lists flows in the active project, or cluster-wide when the user has cluster list permission.

Default (no extra RoleBindings)

On install, the operator creates ClusterRole openshift-integration-integrationflow-user bound to system:authenticated, so any logged-in user can manage IntegrationFlow resources in their active OpenShift project via the console. Standard project roles (edit/admin) also inherit CRUD via CRD aggregation labels.

# Verify self-service RBAC (installed with the operator)
oc get clusterrole,clusterrolebinding openshift-integration-integrationflow-user

# Developer in project team-a creates a flow in team-a
oc project team-a
oc apply -f my-flow.yaml

# Cluster admin sees all flows in the console Integration Flows tab
oc get integrationflows -A

Optional tighten (post-install)

Platform engineers can remove the default binding and require explicit RoleBindings per namespace:

oc delete clusterrolebinding openshift-integration-integrationflow-user

Then grant only selected users/groups via namespace RoleBinding to edit or a custom role.

Optional quota (ResourceQuota)

Limit flows per namespace with a native ResourceQuota (opt-in):

apiVersion: v1
kind: ResourceQuota
metadata:
  name: integration-flows
  namespace: team-a
spec:
  hard:
    count/integrationflows.platform.io: "10"

Lifecycle API (namespaced)

# Extend TTL — namespace in path, Bearer token required
curl -X POST "https://<operator>/api/namespaces/team-a/flows/my-flow/ephemeral/extend?seconds=3600" \
  -H "Authorization: Bearer <token>"

# Promote to GitOps
curl -X POST "https://<operator>/api/namespaces/team-a/flows/my-flow/promote-to-gitops" \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{"gitRepository":"https://gitea.example.com/org/repo","branch":"main"}'

Operator ServiceAccount permissions

The operator runs as integration-operator-sa in openshift-integration (Helm default). It needs cluster-scoped permissions to:

  • Reconcile IntegrationFlow CRs and ephemeral worker Deployments/Services/ConfigMaps
  • Create Tekton PipelineRun resources in the operator namespace
  • Create Argo CD ApplicationSet resources in openshift-gitops
  • Register and serve the OpenShift Console plugin
# Verify operator SA can create IntegrationFlows
oc auth can-i create integrationflows.platform.io \
  --as=system:serviceaccount:openshift-integration:integration-operator-sa

# Verify ApplicationSet permissions in openshift-gitops
oc auth can-i create applicationsets.argoproj.io \
  --as=system:serviceaccount:openshift-integration:integration-operator-sa \
  -n openshift-gitops

Tekton build ServiceAccount

PipelineRuns use the pipeline ServiceAccount. It must have the pipelines-scc SCC and read access to integration-git-basic-auth for git-clone tasks:

oc get sa pipeline -n openshift-integration
oc adm policy who-can use scc pipelines-scc | grep pipeline
oc get rolebinding -n openshift-integration | grep pipeline

Ephemeral flow secrets (per namespace)

Developers create Secrets in their project and reference them from spec.secrets. The operator SA needs permission to read Secrets in namespaces where ephemeral flows run (included in the bundled ClusterRole when using default install). Platform teams can scope with operator.watchedNamespaces in Helm.

Vault & External Secrets Operator

Production GitOps installs should sync Git credentials from a central vault instead of inline Helm values. The Helm chart supports secrets.provider: external-secrets to render an ExternalSecret that materializes integration-git-basic-auth.

Step 1 — Install External Secrets Operator

# OpenShift 4.19+ — OperatorHub or oc apply from Red Hat docs
oc get crd externalsecrets.external-secrets.io
oc get pods -n external-secrets-operator

Step 2 — Configure ClusterSecretStore (Vault example)

apiVersion: external-secrets.io/v1beta1
kind: ClusterSecretStore
metadata:
  name: cluster-secret-store
spec:
  provider:
    vault:
      server: "https://vault.example.com"
      path: "secret"
      version: "v2"
      auth:
        kubernetes:
          mountPath: "kubernetes"
          role: "integration-platform"
          serviceAccountRef:
            name: external-secrets
            namespace: external-secrets-operator

Step 3 — Store Git credentials in Vault

# KV v2 paths expected by the chart ExternalSecret
vault kv put secret/integration-platform/git username=user1 password='REPLACE_ME'
vault kv put secret/integration-platform/github token='ghp_REPLACE_ME'
vault kv put secret/integration-platform/gitlab token='glpat_REPLACE_ME'

Step 4 — Enable ESO in Helm

helm upgrade --install openshift-integration-operator \
  helm/openshift-integration-operator \
  --namespace openshift-integration \
  --set secrets.provider=external-secrets \
  --set secrets.externalSecrets.enabled=true \
  --set secrets.externalSecrets.secretStoreRef=cluster-secret-store \
  --set operator.image.tag=v0.8.1 \
  --set consolePlugin.image.tag=v0.8.1 \
  --set git.url=https://gitea.example.com

Step 5 — Verify

oc get externalsecret integration-git-basic-auth -n openshift-integration
oc describe externalsecret integration-git-basic-auth -n openshift-integration
oc get secret integration-git-basic-auth -n openshift-integration -o jsonpath='{.data.username}' | base64 -d; echo

# Trigger a GitOps flow and confirm git-clone succeeds
oc get pipelineruns -n openshift-integration -l platform.io/component=build

For ephemeral worker credentials (API keys, OAuth tokens), create per-flow Secrets and reference via spec.secrets, or use ExternalSecrets that target the flow namespace. See Security — Secrets Management and AI Models — Credential types.

Ephemeral Quick Try Mode

Flows with spec.deploymentMode: EPHEMERAL run directly in the cluster without Git, Tekton, or ArgoCD. Use this for rapid prototyping; promote to GitOps when ready for production.

Validation Checklist

CheckCommandExpected
CRD supports deploymentMode oc get crd integrationflows.platform.io -o yaml | grep deploymentMode Field present in OpenAPI schema
Ephemeral enabled oc get deploy openshift-integration-operator -n openshift-integration -o jsonpath='{.spec.template.spec.containers[0].env[?(@.name=="EPHEMERAL_ENABLED")].value}' true
Ephemeral flow running oc get integrationflow ephemeral-camel-demo -o jsonpath='{.status.phase} {.status.ephemeralWorkerRef}' Running with worker ref
Worker deployed oc get deploy -n openshift-integration -l platform.io/ephemeral=true Deployment with platform.io/ephemeral=true label

Lifecycle API

# Extend TTL by 1 hour
curl -X POST "https://<operator>/api/namespaces/openshift-integration/flows/ephemeral-camel-demo/ephemeral/extend?seconds=3600" \
  -H "Authorization: Bearer <token>"

# Promote to GitOps
curl -X POST "https://<operator>/api/namespaces/openshift-integration/flows/ephemeral-camel-demo/promote-to-gitops" \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{"gitRepository":"https://gitea.example.com/org/repo","branch":"main"}'

Apply the bundled example:

oc apply -f k8s/examples/09-ephemeral-demo.yaml

AI models, multi-provider properties, and MCP bridge calls from flows: AI Models & MCP.

Offline Flow Catalog (Air-Gapped)

By default, the console plugin loads templates from GitHub Pages (flow-catalog.json). In disconnected clusters, import the catalog as a ConfigMap and point the operator to serve it via the backend proxy.

Option A — Helm install

helm upgrade --install openshift-integration-operator \
  helm/openshift-integration-operator \
  --namespace openshift-integration \
  --create-namespace \
  --set flowCatalog.source=configmap \
  --set flowCatalog.embedOnInstall=true

This creates ConfigMap flow-catalog from the bundled JSON and sets FLOW_CATALOG_SOURCE=configmap on the operator.

Option B — Manual import (OLM / existing install)

./scripts/import-flow-catalog-configmap.sh

Or step by step:

oc create configmap flow-catalog \
  --from-file=flow-catalog.json=docs/flow-catalog.json \
  -n openshift-integration --dry-run=client -o yaml | oc apply -f -

oc set env deployment/openshift-integration-operator -n openshift-integration \
  FLOW_CATALOG_SOURCE=configmap \
  FLOW_CATALOG_CONFIG_MAP_NAME=flow-catalog \
  FLOW_CATALOG_CONFIG_MAP_KEY=flow-catalog.json

Verify

oc get configmap flow-catalog -n openshift-integration
oc get deploy openshift-integration-operator -n openshift-integration \
  -o jsonpath='{.spec.template.spec.containers[0].env[?(@.name=="FLOW_CATALOG_SOURCE")].value}{"\n"}'

In the console: Integration Platform → Overview shows Catalog: configmap. Create Flow → Browse Templates loads from the ConfigMap (no egress to GitHub).

API check (requires authenticated console session or token):

curl -sk "https://<console-host>/api/proxy/plugin/integration-console-plugin/backend/api/flow-catalog" \
  -H "Authorization: Bearer <token>" | head -c 200

Troubleshooting

Common issues and their resolutions.

1. Console plugin not loading / React error

Check: Verify the ConsolePlugin resource and Deployment are running (plugin is served from a container, not a ConfigMap).

oc get consoleplugin integration-console-plugin -o yaml
oc get deploy integration-console-plugin -n openshift-integration
oc get pods -n openshift-integration -l app=integration-console-plugin

Check: Plugin manifest is served over HTTPS on port 9443:

oc exec deploy/integration-console-plugin -n openshift-integration -- \
  curl -sk https://localhost:9443/plugin-manifest.json

Fix: Rebuild the plugin image and rollout the Deployment:

docker build -f console-plugin/Dockerfile -t <registry>/integration-console-plugin:latest console-plugin
oc rollout restart deploy/integration-console-plugin -n openshift-integration

Proxy: API calls use /api/proxy/plugin/integration-console-plugin/backend. Ensure the ConsolePlugin spec.proxy alias is backend and plugin name is integration-console-plugin.

2. 403 Forbidden on Create/Delete

Cause: Missing CSRF token.

The plugin uses X-CSRFToken from cookies automatically. Open browser DevTools → Network tab → verify the header is present on mutation requests.

3. Git push fails

Check operator logs:

oc logs deploy/openshift-integration-operator -n openshift-integration \
  | grep -i "git\|push\|fail"

Verify credentials:

oc get deploy openshift-integration-operator -n openshift-integration \
  -o jsonpath='{.spec.template.spec.containers[0].env}'

Placeholder URLs: Example CRs use gitea.example.com — the operator rewrites these to configured provider URLs via GitUrlResolver. Set git.url (or legacy gitea.url) in Helm values to match your cluster Git server.

Common cause: TLS certificate issues — the operator uses trust-all for dev environments.

4. ApplicationSet not created

Check RBAC:

oc get role -n openshift-gitops | grep integration

Check: Operator service account has permissions in the openshift-gitops namespace.

Logs:

oc logs deploy/openshift-integration-operator \
  | grep -i "appset\|argo"

5. Tekton PipelineRun fails

Check PipelineRun status:

oc get pipelineruns -n openshift-integration
oc describe pipelinerun <name> -n openshift-integration

Clean up failed builds:

./scripts/cleanup-failed-builds.sh openshift-integration

Common causes:

  • CouldntGetPipeline — Pipeline integration-flow-build not found. Re-deploy with Helm or apply manually.
  • PodCreationFailed — Missing pipeline ServiceAccount or SCC. Run:
    oc create sa pipeline -n openshift-integration
    oc adm policy add-scc-to-user pipelines-scc -z pipeline -n openshift-integration
  • Maven build errors — Check pom.xml includes quarkus-camel-bom in dependencyManagement.

7. Ephemeral resources not deleted with IntegrationFlow

Cause: Missing ownerReferences on ephemeral resources (built-in cleanup in current releases).

Fix: Upgrade to the latest release from Quay via OLM bundle:

operator-sdk run bundle quay.io/maximilianopizarro/openshift-integration-operator-bundle:v0.8.1 \
  --namespace openshift-integration --install-mode AllNamespaces --timeout 10m

Verify: After delete, oc get deploy -l platform.io/ephemeral=true returns no resources.

8. Multi-cluster targeting

GitOps flows use Argo CD ApplicationSets. Use spec.targeting (not deprecated targetClusters):

StrategyEffect
explicit + clusters: [local]Deploy only to Argo CD cluster named local
selector + clusterSelectorClusters matching labels on Argo CD cluster secrets
allAll clusters registered in Argo CD

Ephemeral mode is always single-cluster. Register clusters with argocd cluster add before multicluster GitOps.

6. Telemetry not connecting

The SSE stream goes through the console proxy. Verify the ConsolePlugin has proxy configuration:

oc get consoleplugin integration-console-plugin \
  -o jsonpath='{.spec.proxy}'

Check operator health:

oc exec deploy/openshift-integration-operator -n openshift-integration \
  -- curl -s http://localhost:8080/q/health/ready

Ecosystem (future)

Post-0.5.0 checklist items — not started:

  • CNCF Landscape — submit under Integration category when catalog and OperatorHub path are ready
  • Red Hat Certified Operator — partner certification path; requires supported image lifecycle and support matrix