Analyze a Kubernetes GitOps repository (raw YAML or Kustomize) and produce a migration inventory. Detects workloads, services, configs, secrets, inter-service connections, and namespace patterns.
Analyze a Kubernetes GitOps repository and produce a structured migration inventory for OpenChoreo.
/k8s-oc-explore [k8s-repo-path]
$ARGUMENTS = path to K8s repo (defaults to current directory if omitted)
Use $ARGUMENTS as the target directory. If empty, use ..
Search for kustomization.yaml files:
Use Glob: <path>/**/kustomization.yaml
Use Glob to find all YAML files: <path>/**/*.yaml and <path>/**/*.yml
For each file, Read it and parse the kind field. Skip files where:
kind is empty or unrecognizedapp.kubernetes.io/managed-by: Helm) — flag these with a warningCollect resources by kind into these categories:
Deployment → standard deploymentsStatefulSet → stateful workloadsCronJob → scheduled tasksJob → one-time tasksDaemonSet → UNSUPPORTED — add to warnings listService → collect name, type (ClusterIP/LoadBalancer/NodePort), ports, selector labelsIngress → collect rules (host, path, backend service name)ConfigMap → collect name, namespace, keys; note if referenced as envFrom/env or volume mountSecret → collect name, namespace, keys; note if referenced as envFrom/env or volume mountPersistentVolumeClaim → collect name, namespace, storageClassName, accessModes, sizeHorizontalPodAutoscaler → collect target workload name, min/max replicas, metricsServiceAccount, ClusterRole, ClusterRoleBinding, Role, RoleBinding → SKIP (OC platform responsibility)NetworkPolicy → SKIP (OC platform responsibility)Create a map of all Services:
serviceRegistry = {
"<service-name>": {
namespace: "...",
type: "ClusterIP|LoadBalancer|NodePort",
ports: [{port: 80, targetPort: 8080, protocol: "TCP"}],
selector: {app: "..."}
}
}
Also add short-name patterns for K8s DNS: <name>, <name>.<namespace>, <name>.<namespace>.svc.cluster.local
Collect all namespaces found across resources.
Analyze namespace names for environment suffixes:
-dev, -development, -staging, -stage, -prod, -production, -test, -qa, -uatpayment-dev, payment-staging, payment-prod → group into project payment with environments development, staging, productionIf no environment-suffix namespaces found, treat each namespace as an independent project.
For Kustomize repos: examine overlay directory names for environment hints (dev, staging, prod, etc.)
For each Deployment/StatefulSet, inspect the container env array:
<service>.<ns>.svc.cluster.local or <service>.<ns>.svc → extract service name<SERVICE_NAME>_SERVICE_HOST or <SERVICE_NAME>_SERVICE_PORT → extract service name by converting _SERVICE_HOST suffix and underscore-to-hyphen to find matching serviceFor each detected connection, record:
{
"fromComponent": "<deployment-name>",
"toService": "<service-name>",
"envVarName": "<ENV_VAR_NAME>",
"envVarValue": "<original-value>",
"detectionMethod": "dns|shortname|k8s-injected"
}
For Kustomize repos:
base/kustomization.yaml — collect base resourcesoverlays/<env>/kustomization.yaml — collect patchescomponentTypeEnvOverrides.replicascomponentTypeEnvOverrides.resourcesMap overlay directory names to OC environments:
dev, development → developmentstaging, stage → stagingprod, production → productiontest, qa, uat → testing (with note)Based on namespace analysis, propose a mapping:
Proposed Project Mapping:
------------------------
K8s Namespace(s) → OC Project OC Environments
payment-dev, payment-staging, payment development, staging, production
payment-prod
orders orders (from Kustomize overlays or single env)
auth auth (from Kustomize overlays or single env)
Ask the user:
"I've analyzed the K8s repository and proposed the above Project/namespace mapping. Does this look correct? You can adjust project names, merge/split projects, or change environment names. Reply 'yes' to accept, or describe any changes."
Wait for user confirmation before proceeding.
After user confirms the mapping, write oc-migration-inventory.json to the current working directory.
Schema defined in inventory-schema.md. Key structure:
{
"sourceRepo": "<path>",
"repoType": "raw|kustomize|mixed",
"ocNamespace": "default",
"projects": [
{
"name": "<project-name>",
"sourceNamespaces": ["<ns1>", "<ns2>"],
"environments": ["development", "staging", "production"],
"components": [
{
"name": "<component-name>",
"sourceKind": "Deployment|StatefulSet|CronJob|Job",
"ocComponentType": "deployment/service|cronjob/scheduled-task|statefulset/service",
"image": "<image>",
"containers": [...],
"services": [...],
"configMaps": [...],
"secrets": [...],
"pvcs": [...],
"hpa": null,
"connections": [...],
"traits": [...],
"kustomizeOverlays": {...},
"warnings": [...]
}
]
}
],
"warnings": [...],
"skippedResources": [...]
}
Print a structured markdown report:
## K8s Migration Inventory Report
**Source**: <path>
**Repo Type**: raw YAML | Kustomize
**Scanned Files**: N
### Projects Detected
- <project-name>: N components, environments: [dev, staging, prod]
### Components Summary
| Component | Kind | Image | Connections | Traits | Warnings |
|-----------|------|-------|-------------|--------|----------|
| ... | ... | ... | ... | ... | ... |
### Warnings
- [UNSUPPORTED] DaemonSet <name> in namespace <ns> — no OC equivalent, will be skipped
- [HELM] Resource <name> appears Helm-managed — metadata stripped in output
- [MULTI-CONTAINER] Deployment <name> has sidecars: [<names>] — only main container migrated
- [CROSS-NS] Deployment <name> references Service <svc> in another namespace — manual review needed
### Skipped Resources
- ServiceAccount, ClusterRole, RoleBinding — handled by OC platform
- NetworkPolicy — handled by OC platform
- CRD: <name> — custom resource, no OC equivalent
### Output
Inventory written to: oc-migration-inventory.json
See ../k8s-oc-migrate/reference/edge-cases.md for full details.
Key behaviors:
helm.sh/* and app.kubernetes.io/managed-by: Helm annotations from output