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
"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.
-
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 -
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 -
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 -
Verify ApplicationSet
oc get applicationsets -n openshift-gitops | grep smoke-test # Expected: smoke-test-appset -
Verify Console Plugin
- Navigate to OpenShift Console → Integration Platform → Integration Flows
- Verify
smoke-testappears in the list - Click on
smoke-test→ Visual 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
-
Verify Telemetry
- In the flow detail page, check the "Node Telemetry" sidebar
- Green dot = connected, node metrics visible
-
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
IntegrationFlowCRs and ephemeral worker Deployments/Services/ConfigMaps - Create Tekton
PipelineRunresources in the operator namespace - Create Argo CD
ApplicationSetresources inopenshift-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
| Check | Command | Expected |
|---|---|---|
| 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— Pipelineintegration-flow-buildnot found. Re-deploy with Helm or apply manually.PodCreationFailed— MissingpipelineServiceAccount 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.xmlincludesquarkus-camel-bomindependencyManagement.
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):
| Strategy | Effect |
|---|---|
explicit + clusters: [local] | Deploy only to Argo CD cluster named local |
selector + clusterSelector | Clusters matching labels on Argo CD cluster secrets |
all | All 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