From 71971ac06c7e38f4d40bea445b01331d646a8a6f Mon Sep 17 00:00:00 2001 From: Marek Aufart Date: Fri, 24 Apr 2026 14:55:42 +0200 Subject: [PATCH 1/2] Add transform scenarios docs Adding docs and examples for crane transform using kustomize and multistage, including wordpress sample application files. Note, the transform-scenarios folder in docs/ might not be part of agreed docs structure, but I can modify it in follow-up if needed. Signed-off-by: Marek Aufart --- docs/kustomize-multistage.md | 532 ----------- docs/transform-scenarios/01-overview.md | 250 +++++ docs/transform-scenarios/02-quickstart.md | 499 ++++++++++ docs/transform-scenarios/03-multistage.md | 356 +++++++ .../transform-scenarios/05-troubleshooting.md | 871 ++++++++++++++++++ docs/transform-scenarios/README.md | 296 ++++++ .../wordpress-demo/README.md | 43 + ...onfigMap__v1_default_kube-root-ca.crt.yaml | 48 + .../ConfigMap__v1_default_nginx-config.yaml | 58 ++ ...yment_apps_v1_default_wordpress-mysql.yaml | 209 +++++ .../Deployment_apps_v1_default_wordpress.yaml | 268 ++++++ ...iscovery.k8s.io_v1_default_kubernetes.yaml | 35 + ...s.io_v1_default_wordpress-mysql-jlwnp.yaml | 64 ++ ...ery.k8s.io_v1_default_wordpress-wpfqk.yaml | 64 ++ .../Endpoints__v1_default_kubernetes.yaml | 29 + ...Endpoints__v1_default_wordpress-mysql.yaml | 41 + .../Endpoints__v1_default_wordpress.yaml | 41 + ...ob_batch_v1_default_wordpress-install.yaml | 276 ++++++ ...olumeClaim__v1_default_mysql-pv-claim.yaml | 82 ++ ...eClaim__v1_default_wordpress-pv-claim.yaml | 82 ++ ...v1_default_wordpress-74b89cc84c-nm9f8.yaml | 383 ++++++++ ...d__v1_default_wordpress-install-xrqtc.yaml | 381 ++++++++ ...efault_wordpress-mysql-9474c86b-fr65w.yaml | 280 ++++++ ..._apps_v1_default_wordpress-74b89cc84c.yaml | 245 +++++ ...s_v1_default_wordpress-mysql-9474c86b.yaml | 186 ++++ ..._default_wordpress-secrets-hg692g82th.yaml | 33 + .../ServiceAccount__v1_default_default.yaml | 8 + .../Service__v1_default_kubernetes.yaml | 54 ++ .../Service__v1_default_wordpress-mysql.yaml | 58 ++ .../Service__v1_default_wordpress.yaml | 63 ++ .../wordpress-demo/output/output.yaml | 429 +++++++++ ...1_new-migrated-namespace_nginx-config.yaml | 36 + ...ew-migrated-namespace_wordpress-mysql.yaml | 66 ++ ...s_v1_new-migrated-namespace_wordpress.yaml | 93 ++ ...-migrated-namespace_wordpress-install.yaml | 144 +++ ...amespace_wordpress-secrets-hg692g82th.yaml | 12 + ..._v1_new-migrated-namespace_kubernetes.yaml | 23 + ...ew-migrated-namespace_wordpress-mysql.yaml | 23 + ...__v1_new-migrated-namespace_wordpress.yaml | 25 + ...onfigMap__v1_default_kube-root-ca.crt.yaml | 48 + .../ConfigMap__v1_default_nginx-config.yaml | 58 ++ ...yment_apps_v1_default_wordpress-mysql.yaml | 209 +++++ .../Deployment_apps_v1_default_wordpress.yaml | 268 ++++++ ...iscovery.k8s.io_v1_default_kubernetes.yaml | 35 + ...s.io_v1_default_wordpress-mysql-jlwnp.yaml | 64 ++ ...ery.k8s.io_v1_default_wordpress-wpfqk.yaml | 64 ++ .../Endpoints__v1_default_kubernetes.yaml | 29 + ...Endpoints__v1_default_wordpress-mysql.yaml | 41 + .../Endpoints__v1_default_wordpress.yaml | 41 + ...ob_batch_v1_default_wordpress-install.yaml | 276 ++++++ ...olumeClaim__v1_default_mysql-pv-claim.yaml | 82 ++ ...eClaim__v1_default_wordpress-pv-claim.yaml | 82 ++ ...v1_default_wordpress-74b89cc84c-nm9f8.yaml | 383 ++++++++ ...d__v1_default_wordpress-install-xrqtc.yaml | 381 ++++++++ ...efault_wordpress-mysql-9474c86b-fr65w.yaml | 280 ++++++ ..._apps_v1_default_wordpress-74b89cc84c.yaml | 245 +++++ ...s_v1_default_wordpress-mysql-9474c86b.yaml | 186 ++++ ..._default_wordpress-secrets-hg692g82th.yaml | 33 + .../ServiceAccount__v1_default_default.yaml | 8 + .../Service__v1_default_kubernetes.yaml | 54 ++ .../Service__v1_default_wordpress-mysql.yaml | 58 ++ .../Service__v1_default_wordpress.yaml | 63 ++ .../ConfigMap__v1_default_nginx-config.yaml | 35 + ...yment_apps_v1_default_wordpress-mysql.yaml | 63 ++ .../Deployment_apps_v1_default_wordpress.yaml | 90 ++ ...ob_batch_v1_default_wordpress-install.yaml | 141 +++ ..._default_wordpress-secrets-hg692g82th.yaml | 10 + .../Service__v1_default_kubernetes.yaml | 20 + .../Service__v1_default_wordpress-mysql.yaml | 21 + .../Service__v1_default_wordpress.yaml | 23 + .../ConfigMap__v1_default_nginx-config.yaml | 35 + ...yment_apps_v1_default_wordpress-mysql.yaml | 63 ++ .../Deployment_apps_v1_default_wordpress.yaml | 90 ++ ...ob_batch_v1_default_wordpress-install.yaml | 141 +++ ..._default_wordpress-secrets-hg692g82th.yaml | 10 + .../Service__v1_default_kubernetes.yaml | 20 + .../Service__v1_default_wordpress-mysql.yaml | 21 + .../Service__v1_default_wordpress.yaml | 23 + .../ConfigMap__v1_default_nginx-config.yaml | 35 + ...yment_apps_v1_default_wordpress-mysql.yaml | 63 ++ .../Deployment_apps_v1_default_wordpress.yaml | 90 ++ ...ob_batch_v1_default_wordpress-install.yaml | 141 +++ ..._default_wordpress-secrets-hg692g82th.yaml | 10 + .../Service__v1_default_kubernetes.yaml | 20 + .../Service__v1_default_wordpress-mysql.yaml | 21 + .../Service__v1_default_wordpress.yaml | 23 + .../10_KubernetesPlugin/kustomization.yaml | 81 ++ ...v1--Deployment--wordpress-mysql.patch.yaml | 14 + ...-apps-v1--Deployment--wordpress.patch.yaml | 14 + ...atch-v1--Job--wordpress-install.patch.yaml | 14 + ...lt--v1--ConfigMap--nginx-config.patch.yaml | 10 + ...t--wordpress-secrets-hg692g82th.patch.yaml | 10 + ...efault--v1--Service--kubernetes.patch.yaml | 14 + ...t--v1--Service--wordpress-mysql.patch.yaml | 16 + ...default--v1--Service--wordpress.patch.yaml | 18 + ...onfigMap__v1_default_kube-root-ca.crt.yaml | 48 + .../ConfigMap__v1_default_nginx-config.yaml | 58 ++ ...yment_apps_v1_default_wordpress-mysql.yaml | 209 +++++ .../Deployment_apps_v1_default_wordpress.yaml | 268 ++++++ ...iscovery.k8s.io_v1_default_kubernetes.yaml | 35 + ...s.io_v1_default_wordpress-mysql-jlwnp.yaml | 64 ++ ...ery.k8s.io_v1_default_wordpress-wpfqk.yaml | 64 ++ .../Endpoints__v1_default_kubernetes.yaml | 29 + ...Endpoints__v1_default_wordpress-mysql.yaml | 41 + .../Endpoints__v1_default_wordpress.yaml | 41 + ...ob_batch_v1_default_wordpress-install.yaml | 276 ++++++ ...olumeClaim__v1_default_mysql-pv-claim.yaml | 82 ++ ...eClaim__v1_default_wordpress-pv-claim.yaml | 82 ++ ...v1_default_wordpress-74b89cc84c-nm9f8.yaml | 383 ++++++++ ...d__v1_default_wordpress-install-xrqtc.yaml | 381 ++++++++ ...efault_wordpress-mysql-9474c86b-fr65w.yaml | 280 ++++++ ..._apps_v1_default_wordpress-74b89cc84c.yaml | 245 +++++ ...s_v1_default_wordpress-mysql-9474c86b.yaml | 186 ++++ ..._default_wordpress-secrets-hg692g82th.yaml | 33 + .../ServiceAccount__v1_default_default.yaml | 8 + .../Service__v1_default_kubernetes.yaml | 54 ++ .../Service__v1_default_wordpress-mysql.yaml | 58 ++ .../Service__v1_default_wordpress.yaml | 63 ++ .../kustomization.yaml | 16 + .../ConfigMap__v1_default_nginx-config.yaml | 35 + ...yment_apps_v1_default_wordpress-mysql.yaml | 63 ++ .../Deployment_apps_v1_default_wordpress.yaml | 90 ++ ...ob_batch_v1_default_wordpress-install.yaml | 141 +++ ..._default_wordpress-secrets-hg692g82th.yaml | 10 + .../Service__v1_default_kubernetes.yaml | 20 + .../Service__v1_default_wordpress-mysql.yaml | 21 + .../Service__v1_default_wordpress.yaml | 23 + docs/transform.md | 621 ++++--------- 128 files changed, 14132 insertions(+), 970 deletions(-) delete mode 100644 docs/kustomize-multistage.md create mode 100644 docs/transform-scenarios/01-overview.md create mode 100644 docs/transform-scenarios/02-quickstart.md create mode 100644 docs/transform-scenarios/03-multistage.md create mode 100644 docs/transform-scenarios/05-troubleshooting.md create mode 100644 docs/transform-scenarios/README.md create mode 100644 docs/transform-scenarios/wordpress-demo/README.md create mode 100644 docs/transform-scenarios/wordpress-demo/export/resources/default/ConfigMap__v1_default_kube-root-ca.crt.yaml create mode 100644 docs/transform-scenarios/wordpress-demo/export/resources/default/ConfigMap__v1_default_nginx-config.yaml create mode 100644 docs/transform-scenarios/wordpress-demo/export/resources/default/Deployment_apps_v1_default_wordpress-mysql.yaml create mode 100644 docs/transform-scenarios/wordpress-demo/export/resources/default/Deployment_apps_v1_default_wordpress.yaml create mode 100644 docs/transform-scenarios/wordpress-demo/export/resources/default/EndpointSlice_discovery.k8s.io_v1_default_kubernetes.yaml create mode 100644 docs/transform-scenarios/wordpress-demo/export/resources/default/EndpointSlice_discovery.k8s.io_v1_default_wordpress-mysql-jlwnp.yaml create mode 100644 docs/transform-scenarios/wordpress-demo/export/resources/default/EndpointSlice_discovery.k8s.io_v1_default_wordpress-wpfqk.yaml create mode 100644 docs/transform-scenarios/wordpress-demo/export/resources/default/Endpoints__v1_default_kubernetes.yaml create mode 100644 docs/transform-scenarios/wordpress-demo/export/resources/default/Endpoints__v1_default_wordpress-mysql.yaml create mode 100644 docs/transform-scenarios/wordpress-demo/export/resources/default/Endpoints__v1_default_wordpress.yaml create mode 100644 docs/transform-scenarios/wordpress-demo/export/resources/default/Job_batch_v1_default_wordpress-install.yaml create mode 100644 docs/transform-scenarios/wordpress-demo/export/resources/default/PersistentVolumeClaim__v1_default_mysql-pv-claim.yaml create mode 100644 docs/transform-scenarios/wordpress-demo/export/resources/default/PersistentVolumeClaim__v1_default_wordpress-pv-claim.yaml create mode 100644 docs/transform-scenarios/wordpress-demo/export/resources/default/Pod__v1_default_wordpress-74b89cc84c-nm9f8.yaml create mode 100644 docs/transform-scenarios/wordpress-demo/export/resources/default/Pod__v1_default_wordpress-install-xrqtc.yaml create mode 100644 docs/transform-scenarios/wordpress-demo/export/resources/default/Pod__v1_default_wordpress-mysql-9474c86b-fr65w.yaml create mode 100644 docs/transform-scenarios/wordpress-demo/export/resources/default/ReplicaSet_apps_v1_default_wordpress-74b89cc84c.yaml create mode 100644 docs/transform-scenarios/wordpress-demo/export/resources/default/ReplicaSet_apps_v1_default_wordpress-mysql-9474c86b.yaml create mode 100644 docs/transform-scenarios/wordpress-demo/export/resources/default/Secret__v1_default_wordpress-secrets-hg692g82th.yaml create mode 100644 docs/transform-scenarios/wordpress-demo/export/resources/default/ServiceAccount__v1_default_default.yaml create mode 100644 docs/transform-scenarios/wordpress-demo/export/resources/default/Service__v1_default_kubernetes.yaml create mode 100644 docs/transform-scenarios/wordpress-demo/export/resources/default/Service__v1_default_wordpress-mysql.yaml create mode 100644 docs/transform-scenarios/wordpress-demo/export/resources/default/Service__v1_default_wordpress.yaml create mode 100644 docs/transform-scenarios/wordpress-demo/output/output.yaml create mode 100644 docs/transform-scenarios/wordpress-demo/output/resources/new-migrated-namespace/ConfigMap__v1_new-migrated-namespace_nginx-config.yaml create mode 100644 docs/transform-scenarios/wordpress-demo/output/resources/new-migrated-namespace/Deployment_apps_v1_new-migrated-namespace_wordpress-mysql.yaml create mode 100644 docs/transform-scenarios/wordpress-demo/output/resources/new-migrated-namespace/Deployment_apps_v1_new-migrated-namespace_wordpress.yaml create mode 100644 docs/transform-scenarios/wordpress-demo/output/resources/new-migrated-namespace/Job_batch_v1_new-migrated-namespace_wordpress-install.yaml create mode 100644 docs/transform-scenarios/wordpress-demo/output/resources/new-migrated-namespace/Secret__v1_new-migrated-namespace_wordpress-secrets-hg692g82th.yaml create mode 100644 docs/transform-scenarios/wordpress-demo/output/resources/new-migrated-namespace/Service__v1_new-migrated-namespace_kubernetes.yaml create mode 100644 docs/transform-scenarios/wordpress-demo/output/resources/new-migrated-namespace/Service__v1_new-migrated-namespace_wordpress-mysql.yaml create mode 100644 docs/transform-scenarios/wordpress-demo/output/resources/new-migrated-namespace/Service__v1_new-migrated-namespace_wordpress.yaml create mode 100644 docs/transform-scenarios/wordpress-demo/transform/.work/10_KubernetesPlugin/input/default/ConfigMap__v1_default_kube-root-ca.crt.yaml create mode 100644 docs/transform-scenarios/wordpress-demo/transform/.work/10_KubernetesPlugin/input/default/ConfigMap__v1_default_nginx-config.yaml create mode 100644 docs/transform-scenarios/wordpress-demo/transform/.work/10_KubernetesPlugin/input/default/Deployment_apps_v1_default_wordpress-mysql.yaml create mode 100644 docs/transform-scenarios/wordpress-demo/transform/.work/10_KubernetesPlugin/input/default/Deployment_apps_v1_default_wordpress.yaml create mode 100644 docs/transform-scenarios/wordpress-demo/transform/.work/10_KubernetesPlugin/input/default/EndpointSlice_discovery.k8s.io_v1_default_kubernetes.yaml create mode 100644 docs/transform-scenarios/wordpress-demo/transform/.work/10_KubernetesPlugin/input/default/EndpointSlice_discovery.k8s.io_v1_default_wordpress-mysql-jlwnp.yaml create mode 100644 docs/transform-scenarios/wordpress-demo/transform/.work/10_KubernetesPlugin/input/default/EndpointSlice_discovery.k8s.io_v1_default_wordpress-wpfqk.yaml create mode 100644 docs/transform-scenarios/wordpress-demo/transform/.work/10_KubernetesPlugin/input/default/Endpoints__v1_default_kubernetes.yaml create mode 100644 docs/transform-scenarios/wordpress-demo/transform/.work/10_KubernetesPlugin/input/default/Endpoints__v1_default_wordpress-mysql.yaml create mode 100644 docs/transform-scenarios/wordpress-demo/transform/.work/10_KubernetesPlugin/input/default/Endpoints__v1_default_wordpress.yaml create mode 100644 docs/transform-scenarios/wordpress-demo/transform/.work/10_KubernetesPlugin/input/default/Job_batch_v1_default_wordpress-install.yaml create mode 100644 docs/transform-scenarios/wordpress-demo/transform/.work/10_KubernetesPlugin/input/default/PersistentVolumeClaim__v1_default_mysql-pv-claim.yaml create mode 100644 docs/transform-scenarios/wordpress-demo/transform/.work/10_KubernetesPlugin/input/default/PersistentVolumeClaim__v1_default_wordpress-pv-claim.yaml create mode 100644 docs/transform-scenarios/wordpress-demo/transform/.work/10_KubernetesPlugin/input/default/Pod__v1_default_wordpress-74b89cc84c-nm9f8.yaml create mode 100644 docs/transform-scenarios/wordpress-demo/transform/.work/10_KubernetesPlugin/input/default/Pod__v1_default_wordpress-install-xrqtc.yaml create mode 100644 docs/transform-scenarios/wordpress-demo/transform/.work/10_KubernetesPlugin/input/default/Pod__v1_default_wordpress-mysql-9474c86b-fr65w.yaml create mode 100644 docs/transform-scenarios/wordpress-demo/transform/.work/10_KubernetesPlugin/input/default/ReplicaSet_apps_v1_default_wordpress-74b89cc84c.yaml create mode 100644 docs/transform-scenarios/wordpress-demo/transform/.work/10_KubernetesPlugin/input/default/ReplicaSet_apps_v1_default_wordpress-mysql-9474c86b.yaml create mode 100644 docs/transform-scenarios/wordpress-demo/transform/.work/10_KubernetesPlugin/input/default/Secret__v1_default_wordpress-secrets-hg692g82th.yaml create mode 100644 docs/transform-scenarios/wordpress-demo/transform/.work/10_KubernetesPlugin/input/default/ServiceAccount__v1_default_default.yaml create mode 100644 docs/transform-scenarios/wordpress-demo/transform/.work/10_KubernetesPlugin/input/default/Service__v1_default_kubernetes.yaml create mode 100644 docs/transform-scenarios/wordpress-demo/transform/.work/10_KubernetesPlugin/input/default/Service__v1_default_wordpress-mysql.yaml create mode 100644 docs/transform-scenarios/wordpress-demo/transform/.work/10_KubernetesPlugin/input/default/Service__v1_default_wordpress.yaml create mode 100644 docs/transform-scenarios/wordpress-demo/transform/.work/10_KubernetesPlugin/output/default/ConfigMap__v1_default_nginx-config.yaml create mode 100644 docs/transform-scenarios/wordpress-demo/transform/.work/10_KubernetesPlugin/output/default/Deployment_apps_v1_default_wordpress-mysql.yaml create mode 100644 docs/transform-scenarios/wordpress-demo/transform/.work/10_KubernetesPlugin/output/default/Deployment_apps_v1_default_wordpress.yaml create mode 100644 docs/transform-scenarios/wordpress-demo/transform/.work/10_KubernetesPlugin/output/default/Job_batch_v1_default_wordpress-install.yaml create mode 100644 docs/transform-scenarios/wordpress-demo/transform/.work/10_KubernetesPlugin/output/default/Secret__v1_default_wordpress-secrets-hg692g82th.yaml create mode 100644 docs/transform-scenarios/wordpress-demo/transform/.work/10_KubernetesPlugin/output/default/Service__v1_default_kubernetes.yaml create mode 100644 docs/transform-scenarios/wordpress-demo/transform/.work/10_KubernetesPlugin/output/default/Service__v1_default_wordpress-mysql.yaml create mode 100644 docs/transform-scenarios/wordpress-demo/transform/.work/10_KubernetesPlugin/output/default/Service__v1_default_wordpress.yaml create mode 100644 docs/transform-scenarios/wordpress-demo/transform/.work/50_CustomLabelsAndNamespace/input/default/ConfigMap__v1_default_nginx-config.yaml create mode 100644 docs/transform-scenarios/wordpress-demo/transform/.work/50_CustomLabelsAndNamespace/input/default/Deployment_apps_v1_default_wordpress-mysql.yaml create mode 100644 docs/transform-scenarios/wordpress-demo/transform/.work/50_CustomLabelsAndNamespace/input/default/Deployment_apps_v1_default_wordpress.yaml create mode 100644 docs/transform-scenarios/wordpress-demo/transform/.work/50_CustomLabelsAndNamespace/input/default/Job_batch_v1_default_wordpress-install.yaml create mode 100644 docs/transform-scenarios/wordpress-demo/transform/.work/50_CustomLabelsAndNamespace/input/default/Secret__v1_default_wordpress-secrets-hg692g82th.yaml create mode 100644 docs/transform-scenarios/wordpress-demo/transform/.work/50_CustomLabelsAndNamespace/input/default/Service__v1_default_kubernetes.yaml create mode 100644 docs/transform-scenarios/wordpress-demo/transform/.work/50_CustomLabelsAndNamespace/input/default/Service__v1_default_wordpress-mysql.yaml create mode 100644 docs/transform-scenarios/wordpress-demo/transform/.work/50_CustomLabelsAndNamespace/input/default/Service__v1_default_wordpress.yaml create mode 100644 docs/transform-scenarios/wordpress-demo/transform/.work/50_CustomLabelsAndNamespace/output/default/ConfigMap__v1_default_nginx-config.yaml create mode 100644 docs/transform-scenarios/wordpress-demo/transform/.work/50_CustomLabelsAndNamespace/output/default/Deployment_apps_v1_default_wordpress-mysql.yaml create mode 100644 docs/transform-scenarios/wordpress-demo/transform/.work/50_CustomLabelsAndNamespace/output/default/Deployment_apps_v1_default_wordpress.yaml create mode 100644 docs/transform-scenarios/wordpress-demo/transform/.work/50_CustomLabelsAndNamespace/output/default/Job_batch_v1_default_wordpress-install.yaml create mode 100644 docs/transform-scenarios/wordpress-demo/transform/.work/50_CustomLabelsAndNamespace/output/default/Secret__v1_default_wordpress-secrets-hg692g82th.yaml create mode 100644 docs/transform-scenarios/wordpress-demo/transform/.work/50_CustomLabelsAndNamespace/output/default/Service__v1_default_kubernetes.yaml create mode 100644 docs/transform-scenarios/wordpress-demo/transform/.work/50_CustomLabelsAndNamespace/output/default/Service__v1_default_wordpress-mysql.yaml create mode 100644 docs/transform-scenarios/wordpress-demo/transform/.work/50_CustomLabelsAndNamespace/output/default/Service__v1_default_wordpress.yaml create mode 100644 docs/transform-scenarios/wordpress-demo/transform/10_KubernetesPlugin/kustomization.yaml create mode 100644 docs/transform-scenarios/wordpress-demo/transform/10_KubernetesPlugin/patches/default--apps-v1--Deployment--wordpress-mysql.patch.yaml create mode 100644 docs/transform-scenarios/wordpress-demo/transform/10_KubernetesPlugin/patches/default--apps-v1--Deployment--wordpress.patch.yaml create mode 100644 docs/transform-scenarios/wordpress-demo/transform/10_KubernetesPlugin/patches/default--batch-v1--Job--wordpress-install.patch.yaml create mode 100644 docs/transform-scenarios/wordpress-demo/transform/10_KubernetesPlugin/patches/default--v1--ConfigMap--nginx-config.patch.yaml create mode 100644 docs/transform-scenarios/wordpress-demo/transform/10_KubernetesPlugin/patches/default--v1--Secret--wordpress-secrets-hg692g82th.patch.yaml create mode 100644 docs/transform-scenarios/wordpress-demo/transform/10_KubernetesPlugin/patches/default--v1--Service--kubernetes.patch.yaml create mode 100644 docs/transform-scenarios/wordpress-demo/transform/10_KubernetesPlugin/patches/default--v1--Service--wordpress-mysql.patch.yaml create mode 100644 docs/transform-scenarios/wordpress-demo/transform/10_KubernetesPlugin/patches/default--v1--Service--wordpress.patch.yaml create mode 100644 docs/transform-scenarios/wordpress-demo/transform/10_KubernetesPlugin/resources/ConfigMap__v1_default_kube-root-ca.crt.yaml create mode 100644 docs/transform-scenarios/wordpress-demo/transform/10_KubernetesPlugin/resources/ConfigMap__v1_default_nginx-config.yaml create mode 100644 docs/transform-scenarios/wordpress-demo/transform/10_KubernetesPlugin/resources/Deployment_apps_v1_default_wordpress-mysql.yaml create mode 100644 docs/transform-scenarios/wordpress-demo/transform/10_KubernetesPlugin/resources/Deployment_apps_v1_default_wordpress.yaml create mode 100644 docs/transform-scenarios/wordpress-demo/transform/10_KubernetesPlugin/resources/EndpointSlice_discovery.k8s.io_v1_default_kubernetes.yaml create mode 100644 docs/transform-scenarios/wordpress-demo/transform/10_KubernetesPlugin/resources/EndpointSlice_discovery.k8s.io_v1_default_wordpress-mysql-jlwnp.yaml create mode 100644 docs/transform-scenarios/wordpress-demo/transform/10_KubernetesPlugin/resources/EndpointSlice_discovery.k8s.io_v1_default_wordpress-wpfqk.yaml create mode 100644 docs/transform-scenarios/wordpress-demo/transform/10_KubernetesPlugin/resources/Endpoints__v1_default_kubernetes.yaml create mode 100644 docs/transform-scenarios/wordpress-demo/transform/10_KubernetesPlugin/resources/Endpoints__v1_default_wordpress-mysql.yaml create mode 100644 docs/transform-scenarios/wordpress-demo/transform/10_KubernetesPlugin/resources/Endpoints__v1_default_wordpress.yaml create mode 100644 docs/transform-scenarios/wordpress-demo/transform/10_KubernetesPlugin/resources/Job_batch_v1_default_wordpress-install.yaml create mode 100644 docs/transform-scenarios/wordpress-demo/transform/10_KubernetesPlugin/resources/PersistentVolumeClaim__v1_default_mysql-pv-claim.yaml create mode 100644 docs/transform-scenarios/wordpress-demo/transform/10_KubernetesPlugin/resources/PersistentVolumeClaim__v1_default_wordpress-pv-claim.yaml create mode 100644 docs/transform-scenarios/wordpress-demo/transform/10_KubernetesPlugin/resources/Pod__v1_default_wordpress-74b89cc84c-nm9f8.yaml create mode 100644 docs/transform-scenarios/wordpress-demo/transform/10_KubernetesPlugin/resources/Pod__v1_default_wordpress-install-xrqtc.yaml create mode 100644 docs/transform-scenarios/wordpress-demo/transform/10_KubernetesPlugin/resources/Pod__v1_default_wordpress-mysql-9474c86b-fr65w.yaml create mode 100644 docs/transform-scenarios/wordpress-demo/transform/10_KubernetesPlugin/resources/ReplicaSet_apps_v1_default_wordpress-74b89cc84c.yaml create mode 100644 docs/transform-scenarios/wordpress-demo/transform/10_KubernetesPlugin/resources/ReplicaSet_apps_v1_default_wordpress-mysql-9474c86b.yaml create mode 100644 docs/transform-scenarios/wordpress-demo/transform/10_KubernetesPlugin/resources/Secret__v1_default_wordpress-secrets-hg692g82th.yaml create mode 100644 docs/transform-scenarios/wordpress-demo/transform/10_KubernetesPlugin/resources/ServiceAccount__v1_default_default.yaml create mode 100644 docs/transform-scenarios/wordpress-demo/transform/10_KubernetesPlugin/resources/Service__v1_default_kubernetes.yaml create mode 100644 docs/transform-scenarios/wordpress-demo/transform/10_KubernetesPlugin/resources/Service__v1_default_wordpress-mysql.yaml create mode 100644 docs/transform-scenarios/wordpress-demo/transform/10_KubernetesPlugin/resources/Service__v1_default_wordpress.yaml create mode 100644 docs/transform-scenarios/wordpress-demo/transform/50_CustomLabelsAndNamespace/kustomization.yaml create mode 100644 docs/transform-scenarios/wordpress-demo/transform/50_CustomLabelsAndNamespace/resources/ConfigMap__v1_default_nginx-config.yaml create mode 100644 docs/transform-scenarios/wordpress-demo/transform/50_CustomLabelsAndNamespace/resources/Deployment_apps_v1_default_wordpress-mysql.yaml create mode 100644 docs/transform-scenarios/wordpress-demo/transform/50_CustomLabelsAndNamespace/resources/Deployment_apps_v1_default_wordpress.yaml create mode 100644 docs/transform-scenarios/wordpress-demo/transform/50_CustomLabelsAndNamespace/resources/Job_batch_v1_default_wordpress-install.yaml create mode 100644 docs/transform-scenarios/wordpress-demo/transform/50_CustomLabelsAndNamespace/resources/Secret__v1_default_wordpress-secrets-hg692g82th.yaml create mode 100644 docs/transform-scenarios/wordpress-demo/transform/50_CustomLabelsAndNamespace/resources/Service__v1_default_kubernetes.yaml create mode 100644 docs/transform-scenarios/wordpress-demo/transform/50_CustomLabelsAndNamespace/resources/Service__v1_default_wordpress-mysql.yaml create mode 100644 docs/transform-scenarios/wordpress-demo/transform/50_CustomLabelsAndNamespace/resources/Service__v1_default_wordpress.yaml diff --git a/docs/kustomize-multistage.md b/docs/kustomize-multistage.md deleted file mode 100644 index b69f4f4d..00000000 --- a/docs/kustomize-multistage.md +++ /dev/null @@ -1,532 +0,0 @@ -# Multi-Stage Kustomize Transform Pipeline - -This document describes the multi-stage Kustomize transform pipeline feature for Crane, which replaces the previous JSONPatch file-per-resource workflow with a more flexible, scalable approach. - -## Overview - -The multi-stage pipeline allows transformations to be organized into sequential stages, where each stage can apply a different set of plugins to resources. Stages are processed in order based on their priority, and the output of one stage becomes the input for the next. - -## Key Concepts - -### Stage Directory Structure - -Each stage is a directory following the naming convention `_`: - -``` -transform/ -├── 10_KubernetesPlugin/ -│ ├── resources/ -│ │ ├── deployment.yaml # Grouped by resource type -│ │ ├── service.yaml -│ │ └── configmap.yaml -│ ├── patches/ -│ │ ├── deployment-myapp-default.yaml -│ │ └── service-myapp-default.yaml -│ ├── kustomization.yaml # Generated Kustomize file -│ ├── whiteout-report.yaml # Resources excluded from output -│ ├── ignored-patches-report.yaml # Patches discarded due to conflicts -│ └── .crane-metadata.json # Stage metadata with content hashes -├── 20_OpenshiftPlugin/ -│ └── ... -└── 30_ImagestreamPlugin/ - └── ... -``` - -### Resource Grouping - -Resources are grouped by type (kind + API group) into multi-document YAML files: -- Core resources: `deployment.yaml`, `service.yaml`, `pod.yaml` -- Non-core resources: `route.route.openshift.io.yaml`, `imagestream.image.openshift.io.yaml` - -### Kustomization File - -Each stage contains a `kustomization.yaml` that references: -- **resources**: List of resource files from the `resources/` directory -- **patches**: Strategic merge patches or JSON patches with target selectors - -Example: -```yaml -apiVersion: kustomize.config.k8s.io/v1beta1 -kind: Kustomization -resources: -- resources/deployment.yaml -- resources/service.yaml -patches: -- path: patches/deployment-myapp-default.yaml - target: - group: apps - version: v1 - kind: Deployment - name: myapp - namespace: default -``` - -### Resource Cleanup via Plugins - -Exported resources contain live/runtime metadata from the source cluster that must be removed before applying to a target cluster. Crane uses **plugins** to generate JSONPatch operations that clean these resources. - -**Built-in Kubernetes Plugin**: - -The `kubernetes` plugin (from `crane-lib`) automatically removes: -- `metadata.uid` - Cluster-assigned unique identifier -- `metadata.resourceVersion` - Etcd versioning field -- `metadata.creationTimestamp` - Original creation time -- `metadata.managedFields` - Server-side apply tracking -- `status` section - Runtime state - -**How it works**: - -1. **Transform phase**: Plugins analyze exported resources and generate JSONPatch operations -2. **Patches written**: Operations saved as Kustomize patches in `patches/` directory -3. **Apply phase**: `kubectl kustomize` applies patches to resources -4. **Result**: Clean, declarative manifests ready for target cluster - -**Example patch** (auto-generated by kubernetes plugin): -```yaml -- op: remove - path: /metadata/resourceVersion -- op: remove - path: /metadata/creationTimestamp -- op: remove - path: /metadata/managedFields -- op: remove - path: /status -- op: remove - path: /metadata/uid -``` - -This approach ensures: -- ✅ No conflicts with server-managed fields -- ✅ Resources can be applied to any cluster -- ✅ Idempotent operations (safe to re-apply) - -## CLI Usage - -### Transform Command - -#### Single Stage Mode (Default) - -Create a single transform stage using all available plugins: - -```bash -crane transform \ - --export-dir export \ - --transform-dir transform -``` - -This creates a `10_KubernetesPlugin` stage directory and runs all plugins (including the built-in `kubernetes` plugin) to clean exported resources. - -**Plugin Filtering** (optional): - -To run only specific plugins: - -```bash -crane transform \ - --export-dir export \ - --transform-dir transform \ - --stage-name 10_KubernetesPlugin \ - --plugin-name kubernetes -``` - -**Note**: When `--plugin-name` is omitted (default), ALL available plugins are used. This is recommended to ensure proper resource cleanup. - -#### Multi-Stage Mode - -Execute specific stages: - -```bash -# Run a specific stage -crane transform --stage 20_OpenshiftPlugin -``` - -#### Force Overwrite - -Override dirty check protection: - -```bash -crane transform --force --stage-name 10_KubernetesPlugin -``` - -### Apply Command - -#### Apply Final Stage (Default) - -Apply only the last stage in the pipeline: - -```bash -crane apply \ - --transform-dir transform \ - --output-dir output -``` - -This builds the final stage using `kubectl kustomize` and writes the result to `output/output.yaml`. - -#### Apply Specific Stages - -Apply applies all stages sequentially by default. The apply command does not support stage-specific flags as it always processes the complete pipeline to ensure sequential consistency. - -## Priority Assignment - -### Auto-Assignment - -Plugin priorities are automatically assigned from stage directory names: - -```go -// Stage directories -10_KubernetesPlugin → plugin "kubernetes" gets priority 10 -20_OpenshiftPlugin → plugin "openshift" gets priority 20 -30_ImagestreamPlugin → plugin "imagestream" gets priority 30 -``` - -### Manual Assignment - -Override auto-assigned priorities: - -```bash -crane transform \ - --plugin-priorities kubernetes:5,openshift:15,imagestream:25 -``` - -### Recommended Priority Order - -The system provides heuristic-based recommendations: - -| Plugin Type | Recommended Priority | Keywords | -|-------------------|--------------------|------------------------------| -| Kubernetes Core | 10 | kubernetes, k8s, core | -| OpenShift | 20 | openshift, ocp | -| Namespace/Project | 30 | namespace, project | -| Security | 40 | security, scc, psp | -| Network | 50 | network, route, ingress | -| Storage | 60 | storage, pvc, pv | -| Image | 70 | image, imagestream, registry | -| Build | 80 | build, buildconfig | -| Custom | 90 | custom, app, application | - -## Stage Chaining - -Stages are chained automatically based on priority order: - -``` -export/ → 10_KubernetesPlugin/ → 20_OpenshiftPlugin/ → 30_ImagestreamPlugin/ → output/ -``` - -Each stage: -1. Reads input resources (from export or previous stage) -2. Applies transformations via plugins -3. Writes output to its stage directory -4. Next stage uses this output as input - -## Workflow Examples - -### Example 1: Simple Transform and Apply - -```bash -# Export resources from source cluster -crane export --kubeconfig source.yaml --export-dir export - -# Transform resources (single stage) -crane transform --export-dir export --transform-dir transform - -# Apply transformations -crane apply --transform-dir transform --output-dir output - -# Deploy to target cluster -kubectl apply -f output/output.yaml -``` - -### Example 2: Multi-Stage Pipeline - -```bash -# Export resources -crane export --kubeconfig source.yaml --export-dir export - -# Create Kubernetes base transformations -crane transform \ - --export-dir export \ - --transform-dir transform \ - --stage-name 10_KubernetesPlugin \ - --plugin-name kubernetes - -# Create OpenShift-specific transformations -crane transform \ - --transform-dir transform \ - --stage-name 20_OpenshiftPlugin \ - --plugin-name openshift - -# Create ImageStream transformations -crane transform \ - --transform-dir transform \ - --stage-name 30_ImagestreamPlugin \ - --plugin-name imagestream - -# Apply final stage -crane apply --transform-dir transform --output-dir output -``` - -### Example 3: Iterative Development - -```bash -# Initial transform -crane transform --export-dir export --transform-dir transform - -# Make manual edits to resources in transform/10_KubernetesPlugin/resources/ -# Edit deployment.yaml to add annotations, etc. - -# Try to re-run transform (will fail due to dirty check) -crane transform --export-dir export --transform-dir transform -# Error: contains user modifications - -# Force overwrite if needed -crane transform --export-dir export --transform-dir transform --force - -# Or preserve changes by using a different stage name -crane transform --stage-name 20_custom -``` - -## Migration from JSONPatch Workflow - -### Old Workflow - -``` -transform/ -├── namespace/ -│ └── default/ -│ └── deployment/ -│ └── myapp.json # JSONPatch per resource -``` - -### New Workflow - -``` -transform/ -└── 10_KubernetesPlugin/ - ├── resources/ - │ └── deployment.yaml # Grouped by type - ├── patches/ - │ └── deployment-myapp-default.yaml - └── kustomization.yaml -``` - -### Benefits - -1. **Reduced File Count**: Resources grouped by type instead of one file per resource -2. **Standard Format**: Uses Kustomize, a widely adopted tool -3. **Stage Chaining**: Supports multi-stage pipelines for complex transformations -4. **Better Diff**: Deterministic ordering produces stable Git diffs -5. **Dirty Check**: Prevents accidental overwrites of user modifications - -## Advanced Features - -### Stage Validation - -Validate kubectl availability and stage names before applying: - -```go -import ( - "github.com/konveyor/crane/internal/apply" - "github.com/konveyor/crane/internal/transform" -) - -// Check if kubectl is available -err := apply.ValidateKubectlAvailable() -if err != nil { - fmt.Printf("kubectl validation failed: %v\n", err) -} - -// Validate stage names -stages, err := transform.DiscoverStages(transformDir) -if err != nil { - fmt.Printf("failed to discover stages: %v\n", err) -} - -for _, stage := range stages { - if err := transform.ValidateStageName(stage.DirName); err != nil { - fmt.Printf("Invalid stage name %s: %v\n", stage.DirName, err) - } -} -``` - -### Custom Stage Naming - -Generate stage names with priority numbers: - -```go -import "github.com/konveyor/crane/internal/transform" - -// Generate a stage name with priority -stageName := transform.GenerateStageName(15, "my-plugin") -// Returns: "15_my-plugin" - -// Validate a stage name -err := transform.ValidateStageName("15_my-plugin") -if err != nil { - // Handle invalid stage name -} -``` - -## Troubleshooting - -### Issue: Transform fails with "contains user modifications" - -**Cause**: Stage directory has been manually edited after creation. - -**Solution**: -1. Use `--force` to overwrite changes -2. Use a different `--stage-name` to preserve changes -3. Commit changes to Git before re-running transform - -### Issue: Apply fails with "kustomization.yaml validation failed" - -**Cause**: Invalid Kustomize syntax or missing resources. - -**Solution**: -1. Check kustomization.yaml syntax -2. Verify all resource files exist in resources/ -3. Run `kubectl kustomize transform/STAGE/` manually to see detailed error - -### Issue: Resources not appearing in output - -**Cause**: Resources may be whiteout (excluded) by plugins. - -**Solution**: -1. Check `whiteout-report.yaml` in stage directory -2. Review plugin configuration -3. Check plugin logs for whiteout decisions - -### Issue: Patches not being applied - -**Cause**: Patch file or target selector may be incorrect. - -**Solution**: -1. Verify patch file exists in patches/ -2. Check target selector matches resource metadata -3. Review `ignored-patches-report.yaml` for conflicts - -## Best Practices - -1. **Stage Naming**: Use descriptive names that indicate the transformation purpose - - Good: `10_KubernetesPlugin-base`, `20_OpenshiftPlugin-routes`, `30_security-context` - - Bad: `10_stage1`, `20_stage2` - -2. **Priority Spacing**: Leave gaps (10, 20, 30) to allow insertion of new stages - -3. **Version Control**: Commit transform directories to Git to track changes - -4. **Testing**: Always test transformed output before applying to production - -5. **Incremental Changes**: Use separate stages for different concerns (security, networking, storage) - -6. **Documentation**: Include README.md in transform directory explaining pipeline purpose - -## API Reference - -### Transform Package - -```go -// Stage discovery -stages, err := transform.DiscoverStages(transformDir) - -// Stage filtering -selector := transform.StageSelector{ - FromStage: "20_OpenshiftPlugin", - ToStage: "30_ImagestreamPlugin", -} -filtered := transform.FilterStages(stages, selector) - -// Stage navigation -first := transform.GetFirstStage(stages) -last := transform.GetLastStage(stages) -prev := transform.GetPreviousStage(stages, currentStage) -next := transform.GetNextStage(stages, currentStage) - -// Stage name validation and generation -err = transform.ValidateStageName("10_KubernetesPlugin") -stageName := transform.GenerateStageName(10, "kubernetes") -``` - -### Apply Package - -```go -// Kustomize apply -applier := &apply.KustomizeApplier{ - Log: logger, - TransformDir: transformDir, - OutputDir: outputDir, -} - -// Apply a single stage -err = applier.ApplySingleStage("10_KubernetesPlugin") - -// Apply multiple stages with selector -selector := transform.StageSelector{ - FromStage: "10_KubernetesPlugin", - ToStage: "30_ImagestreamPlugin", -} -err = applier.ApplyMultiStage(selector) - -// Apply only the final stage (most common) -err = applier.ApplyFinalStage() - -// Validate kubectl availability -err = apply.ValidateKubectlAvailable() -``` - -## Further Reading - -- [Kustomize Documentation](https://kubectl.docs.kubernetes.io/references/kustomize/) -- [Crane Plugin Development](./plugin-development.md) -- [Transform Architecture](./architecture.md) - -## Manual/Non-Plugin Stages - -Stages don't have to correspond to a plugin. If a stage directory name doesn't match any available plugin, the resources pass through unchanged. - -**Use case**: Manual transformation stages where you want to hand-edit resources. - -### Example - -```bash -# Create a multi-stage pipeline -crane transform --stage-name 10_KubernetesPlugin # Plugin-backed -crane transform --stage-name 50_ManualEdits # No matching plugin -crane transform --stage-name 90_FinalCleanup # No matching plugin -``` - -**What happens:** - -1. **10_KubernetesPlugin**: Resources transformed by KubernetesPlugin (removes metadata.uid, etc.) -2. **50_ManualEdits**: Resources copied unchanged to `transform/50_ManualEdits/resources/` - - No plugins match "ManualEdits" - - No patches generated - - You can manually edit resources in this stage -3. **90_FinalCleanup**: Resources from previous stage copied unchanged - - User can add manual patches or edits - -### Behavior - -When stage name doesn't match any plugin: -- `filterPluginsByStage()` returns empty list `[]` -- `runner.Run()` called with empty plugin list -- Resources written unchanged (no transformations) -- No patches generated -- **This is intentional** - allows user-controlled stages - -### Mixed Pipeline Example - -``` -export/ -└── resources/ - └── deployment.yaml (raw export with uid, resourceVersion, etc.) - ↓ -transform/10_KubernetesPlugin/ (plugin: removes server-managed fields) -└── resources/deployment.yaml (cleaned) - ↓ -transform/50_ManualEdits/ (no plugin: user edits) -└── resources/deployment.yaml (manually edited) - ↓ -transform/90_CustomPlugin/ (plugin: custom transformations) -└── resources/deployment.yaml (custom patches applied) - ↓ -output/output.yaml (final result) -``` diff --git a/docs/transform-scenarios/01-overview.md b/docs/transform-scenarios/01-overview.md new file mode 100644 index 00000000..8b94a328 --- /dev/null +++ b/docs/transform-scenarios/01-overview.md @@ -0,0 +1,250 @@ +# Crane Migration - Overview + +## What is Crane Transform? + +Crane Transform is the second phase in Crane's Kubernetes migration workflow. It takes exported resources from a source cluster and prepares them for deployment to a target cluster by: + +1. **Cleaning resources** - Removing cluster-specific metadata that would cause conflicts +2. **Applying transformations** - Modifying resources to work in the target environment +3. **Organizing artifacts** - Creating a Kustomize-based directory structure ready for GitOps + +## The Migration Workflow + +``` +┌──────────────┐ ┌───────────────┐ ┌─────────────┐ ┌──────────┐ ┌──────────────┐ ┌──────────────┐ +│ Source │────▶│ crane export │────▶│ crane │────▶│ crane │────▶│ kubectl │────▶│ Target │ +│ Cluster │ │ │ │ transform │ │ apply │ │ apply │ │ Cluster │ +└──────────────┘ └───────────────┘ └─────────────┘ └──────────┘ └──────────────┘ └──────────────┘ + │ │ │ + ▼ ▼ ▼ + export/resources/ transform/stages/ output/ + (raw resources) (cleaned + patches) (final YAML) +``` + +### Phase 1: Export +```bash +crane export +``` +- Captures live resources from source cluster (uses current namespace context) +- Saves to `export/resources/` directory +- Includes ALL metadata (UIDs, resourceVersions, status, etc.) + +### Phase 2: Transform (This Guide) +```bash +crane transform +``` +- Removes cluster-specific metadata +- Applies environment-specific transformations +- Creates Kustomize directory structure +- Supports multi-stage pipelines + +### Phase 3: Apply +```bash +crane apply +kubectl apply -f output/output.yaml +``` +- Builds final manifests using Kustomize +- Deploys to target cluster + +## Why Do We Need Transform? + +Exported resources contain **server-managed fields** that must be removed: + +```yaml +# Exported resource (from source cluster) +apiVersion: apps/v1 +kind: Deployment +metadata: + name: myapp + namespace: default + uid: 8fb75dcd-68b2-4939-bfb9-1c8241a7b146 # ← Cluster-specific + resourceVersion: "3213488" # ← Will conflict + creationTimestamp: "2024-01-15T10:30:00Z" # ← Old timestamp + managedFields: [...] # ← Server-managed +spec: + replicas: 3 + # ... application config ... +status: # ← Runtime state + availableReplicas: 3 + # ... current status ... +``` + +**Attempting to apply this directly to a target cluster will fail** because: +- `uid` conflicts with target cluster's UID assignment +- `resourceVersion` is etcd-specific to the source cluster +- `status` section is read-only and server-managed + +**After transform:** +```yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + name: myapp + namespace: default + # ✓ Clean metadata - no conflicts +spec: + replicas: 3 + # ... application config preserved ... +# ✓ status removed +``` + +## Key Concepts + +### Plugins + +**Plugins** analyze resources and generate transformations: + +- **Built-in KubernetesPlugin**: Removes server-managed fields (uid, resourceVersion, status, etc.) +- **OpenshiftPlugin**: Handles OpenShift-specific resources (Routes, ImageStreams, etc.) +- **Custom plugins**: Your own transformations via crane-lib + +Plugins don't modify resources directly - they generate **patches** that Kustomize applies. + +### Stages + +A **stage** is a directory containing: +- `resources/` - Kubernetes manifests (one file per resource or grouped by type) +- `patches/` - Kustomize patches (JSONPatch operations) +- `kustomization.yaml` - Kustomize configuration + +**Naming convention**: `_` +- `10_KubernetesPlugin` - Plugin-backed stage +- `50_CustomEdits` - Pass-through stage for manual editing + +### Multi-Stage Pipeline + +Complex migrations often need **multiple transformation phases**: + +``` +export/ + └─▶ 10_KubernetesPlugin/ (removes server metadata) + └─▶ 20_OpenshiftPlugin/ (converts OpenShift resources) + └─▶ 30_CustomEdits/ (manual tweaks) + └─▶ output/ +``` + +**Sequential Consistency**: Each stage processes the **fully materialized output** of the previous stage, not raw patches. + +### Kustomize-Based Architecture + +Transform generates standard **Kustomize** layouts: + +**Benefits:** +- Industry-standard tool (built into kubectl) +- Declarative transformations (patches are GitOps-friendly) +- Supports overlays, components, and advanced features +- Human-readable diffs in Git + +**Example structure:** +``` +transform/10_KubernetesPlugin/ +├── resources/ +│ ├── Deployment_apps_v1_default_myapp.yaml +│ └── Service__v1_default_myapp.yaml +├── patches/ +│ └── default--apps-v1--Deployment--myapp.patch.yaml +└── kustomization.yaml +``` + +## What Transform Does (Behind the Scenes) + +When you run `crane transform`: + +1. **Load Input**: Reads resources from `export/` (or previous stage output) +2. **Run Plugins**: Each plugin analyzes resources and generates JSONPatch operations +3. **Write Artifacts**: + - Copies resources to `resources/` + - Saves patches to `patches/` + - Generates `kustomization.yaml` +4. **Apply Transforms**: Runs `kubectl kustomize` to produce cleaned output +5. **Save Output**: Writes to `.work//output/` for next stage + +## Common Use Cases + +### Use Case 1: Simple Migration (Single Cluster Type) +**Scenario**: Migrating between two vanilla Kubernetes clusters + +```bash +crane export +crane transform # Uses default 10_KubernetesPlugin +crane apply +kubectl apply -f output/output.yaml +``` + +### Use Case 2: Cross-Platform Migration +**Scenario**: Migrating from OpenShift to vanilla Kubernetes + +```bash +crane export +crane transform --stage 10_KubernetesPlugin # Clean resources +crane transform --stage 20_OpenshiftPlugin # Convert OpenShift resources +crane apply +``` + +### Use Case 3: GitOps Workflow +**Scenario**: Preparing resources for Git repository + +```bash +crane export +crane transform +crane apply +# Review and commit transform/ directory +git add output/resources/ +git commit -m "Add transformed manifests" +git push +# ArgoCD/Flux picks up changes +``` + +### Use Case 4: Manual Customization +**Scenario**: Need to hand-edit some resources + +```bash +crane export +crane transform --stage 10_KubernetesPlugin +crane transform --stage 50_CustomEdits # Creates pass-through stage +# Edit files in transform/50_CustomEdits/resources/ with kustomize features +vim transform/50_CustomEdits/kustomize.yaml +crane apply +``` + +## Directory Structure Reference + +After running `crane transform`, your directory looks like: + +``` +. +├── export/ # Phase 1: Exported resources +│ └── resources/ +│ └── default/ +│ ├── Deployment_apps_v1_default_myapp.yaml +│ └── Service__v1_default_myapp.yaml +│ +├── transform/ # Phase 2: Transform stages +│ ├── 10_KubernetesPlugin/ +│ │ ├── resources/ # Input resources +│ │ ├── patches/ # Generated patches +│ │ └── kustomization.yaml # Kustomize config +│ └── .work/ # Intermediate artifacts (debugging) +│ └── 10_KubernetesPlugin/ +│ ├── input/ # Input snapshot +│ └── output/ # Materialized output +│ +└── output/ # Phase 3: Final manifests + ├── output.yaml # Single-file output + └── resources/ # Per-resource files + └── default/ + ├── Deployment_apps_v1_default_myapp.yaml + └── Service__v1_default_myapp.yaml +``` + +## Next Steps + +- [**Quickstart Tutorial**](./02-quickstart.md) - Hands-on walkthrough +- [**Multi-Stage Pipelines**](./03-multistage.md) - Advanced transformation workflows +- [**Troubleshooting**](./05-troubleshooting.md) - Common issues and solutions + +## Reference Documentation + +- [Transform CLI Reference](../transform.md) - Detailed directory structure and CLI options +- [Multi-Stage Kustomize](../kustomize-multistage.md) - Technical deep-dive +- [Crane README](../../README.md) - Project overview diff --git a/docs/transform-scenarios/02-quickstart.md b/docs/transform-scenarios/02-quickstart.md new file mode 100644 index 00000000..c0805711 --- /dev/null +++ b/docs/transform-scenarios/02-quickstart.md @@ -0,0 +1,499 @@ +# Quickstart Tutorial - Your First Crane Migration + +This tutorial walks you through a complete example of using `crane` to migrate a simple WordPress application (**stateless**). + +## Prerequisites + +- `crane` CLI installed (see [installation guide](../../README.md#install)) +- `kubectl` available in your PATH +- Access to a Kubernetes cluster (for export phase) + +## Stateless Tutorial Overview + +We'll migrate a WordPress + MySQL application through these steps: + +1. Deploy sample application to a cluster +2. Export resources using `crane export` +3. Transform resources using `crane transform` +4. Review the transformed output +5. Apply to generate manifest +6. Deploy to target cluster (optional) + + +## Step 1: Deploy Sample Application + +First, let's deploy a sample WordPress application to your cluster: + +```bash +# Create namespace +kubectl create namespace wordpress-demo + +# Deploy WordPress and MySQL +kubectl apply -n wordpress-demo -f - < 3306/TCP 30s +service/wordpress NodePort 10.96.234.56 80:30123/TCP 30s + +NAME READY UP-TO-DATE AVAILABLE AGE +deployment.apps/mysql 1/1 1 1 30s +deployment.apps/wordpress 1/1 1 1 30s + +NAME DESIRED CURRENT READY AGE +replicaset.apps/mysql-5d8c7b9d4f 1 1 1 30s +replicaset.apps/wordpress-7b8c9d5f6 1 1 1 30s +``` + +## Step 2: Export Resources + +Now let's export the deployed resources: + +```bash +crane export -n wordpress-demo +``` + +**What happens:** +- Crane discovers all resources in the `wordpress-demo` namespace +- Exports each resource to a YAML file +- Saves to `export/resources/wordpress-demo/` directory + +**Check the export:** +```bash +ls export/resources/wordpress-demo/ +``` + +**Expected output:** +``` +Deployment_apps_v1_wordpress-demo_mysql.yaml +Deployment_apps_v1_wordpress-demo_wordpress.yaml +Endpoints__v1_wordpress-demo_mysql.yaml +Endpoints__v1_wordpress-demo_wordpress.yaml +PersistentVolumeClaim__v1_wordpress-demo_mysql-pvc.yaml +Pod__v1_wordpress-demo_mysql-5d8c7b9d4f-x7k2p.yaml +Pod__v1_wordpress-demo_wordpress-7b8c9d5f6-q9m3n.yaml +ReplicaSet_apps_v1_wordpress-demo_mysql-5d8c7b9d4f.yaml +ReplicaSet_apps_v1_wordpress-demo_wordpress-7b8c9d5f6.yaml +Secret__v1_wordpress-demo_mysql-password.yaml +Service__v1_wordpress-demo_mysql.yaml +Service__v1_wordpress-demo_wordpress.yaml +ServiceAccount__v1_wordpress-demo_default.yaml +``` + +**Examine an exported resource:** +```bash +cat export/resources/wordpress-demo/Deployment_apps_v1_wordpress-demo_mysql.yaml +``` + +Notice the resource contains cluster-specific metadata: +```yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + name: mysql + namespace: wordpress-demo + uid: 8fb75dcd-68b2-4939-bfb9-1c8241a7b146 # ← Must be removed + resourceVersion: "12345" # ← Must be removed + creationTimestamp: "2024-04-24T10:30:00Z" # ← Must be removed + generation: 1 + managedFields: [...] # ← Must be removed +spec: + # ... your deployment spec ... +status: # ← Must be removed + availableReplicas: 1 + # ... runtime status ... +``` + +## Step 3: Transform Resources + +Run the transform command: + +```bash +crane transform +``` + +**What happens:** +- No stages exist, so Crane creates default stage: `10_KubernetesPlugin` +- Loads the built-in KubernetesPlugin +- Plugin analyzes each resource +- Generates JSONPatch operations to remove server-managed fields +- Writes transformed resources and patches to `transform/10_KubernetesPlugin/` + +**Expected output:** +``` +INFO[0000] No existing stages found, creating default stage: 10_KubernetesPlugin +INFO[0000] Populating and executing default stage +INFO[0000] Executing stage 1/1: 10_KubernetesPlugin +INFO[0000] Stage 10_KubernetesPlugin: loaded 13 input resource(s) +INFO[0001] Stage 10_KubernetesPlugin: produced 13 output resource(s) +INFO[0001] Successfully completed 1 stage(s) +``` + +**Explore the generated structure:** +```bash +tree transform/10_KubernetesPlugin/ +``` + +**Expected structure:** +``` +transform/10_KubernetesPlugin/ +├── kustomization.yaml +├── patches/ +│ ├── wordpress-demo--apps-v1--Deployment--mysql.patch.yaml +│ ├── wordpress-demo--apps-v1--Deployment--wordpress.patch.yaml +│ ├── wordpress-demo---v1--PersistentVolumeClaim--mysql-pvc.patch.yaml +│ ├── wordpress-demo---v1--Secret--mysql-password.patch.yaml +│ ├── wordpress-demo---v1--Service--mysql.patch.yaml +│ └── wordpress-demo---v1--Service--wordpress.patch.yaml +└── resources/ + ├── Deployment_apps_v1_wordpress-demo_mysql.yaml + ├── Deployment_apps_v1_wordpress-demo_wordpress.yaml + ├── PersistentVolumeClaim__v1_wordpress-demo_mysql-pvc.yaml + ├── Secret__v1_wordpress-demo_mysql-password.yaml + ├── Service__v1_wordpress-demo_mysql.yaml + └── Service__v1_wordpress-demo_wordpress.yaml +``` + +**Key points:** +- `resources/` contains the exported resources (copied from export) +- `patches/` contains JSONPatch operations generated by the plugin +- `kustomization.yaml` ties them together +- Notice: Pods, ReplicaSets, Endpoints are NOT included (handled by "whiteout" - explained later) + +## Step 4: Review Transformed Output + +**Examine a patch file:** +```bash +cat transform/10_KubernetesPlugin/patches/wordpress-demo--apps-v1--Deployment--mysql.patch.yaml +``` + +**Expected content:** +```yaml +- op: remove + path: /metadata/uid +- op: remove + path: /metadata/resourceVersion +- op: remove + path: /metadata/creationTimestamp +- op: remove + path: /metadata/generation +- op: remove + path: /metadata/managedFields +- op: remove + path: /status +``` + +These patches remove the server-managed fields we saw earlier! + +**Examine the kustomization.yaml:** +```bash +cat transform/10_KubernetesPlugin/kustomization.yaml +``` + +**Expected content:** +```yaml +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +patches: +- path: patches/wordpress-demo--apps-v1--Deployment--mysql.patch.yaml + target: + group: apps + kind: Deployment + name: mysql + namespace: wordpress-demo + version: v1 +- path: patches/wordpress-demo--apps-v1--Deployment--wordpress.patch.yaml + target: + group: apps + kind: Deployment + name: wordpress + namespace: wordpress-demo + version: v1 +# ... more patches ... +resources: +- resources/Deployment_apps_v1_wordpress-demo_mysql.yaml +- resources/Deployment_apps_v1_wordpress-demo_wordpress.yaml +- resources/PersistentVolumeClaim__v1_wordpress-demo_mysql-pvc.yaml +- resources/Secret__v1_wordpress-demo_mysql-password.yaml +- resources/Service__v1_wordpress-demo_mysql.yaml +- resources/Service__v1_wordpress-demo_wordpress.yaml +``` + +**Preview the final output:** +```bash +kubectl kustomize transform/10_KubernetesPlugin/ +``` + +This shows what will be deployed after patches are applied. Notice: +- No `uid` fields +- No `resourceVersion` fields +- No `status` sections +- Clean, declarative manifests ready for target cluster + +**Compare before and after:** +```bash +# Before (exported resource) +grep -A 5 "metadata:" export/resources/wordpress-demo/Deployment_apps_v1_wordpress-demo_mysql.yaml + +# After (transformed resource) +kubectl kustomize transform/10_KubernetesPlugin/ | grep -A 5 "kind: Deployment" | head -20 +``` + +## Step 5: Apply and Generate Final Output + +Run `crane apply` to generate the final manifests: + +```bash +crane apply +``` + +**What happens:** +- Runs `kubectl kustomize` on the final stage +- Writes output to `output/` directory +- Creates both single-file and per-resource layouts + +**Expected output:** +``` +INFO[0000] Applying final stage to output directory +INFO[0000] Applied stage 10_KubernetesPlugin +INFO[0000] Wrote 6 resources to output/output.yaml +INFO[0000] Wrote 6 individual resource files to output/resources/ +``` + +**Check the output:** +```bash +ls output/ +``` + +**Expected structure:** +``` +output/ +├── output.yaml # Single file with all resources +└── resources/ # Individual resource files + └── wordpress-demo/ + ├── Deployment_apps_v1_wordpress-demo_mysql.yaml + ├── Deployment_apps_v1_wordpress-demo_wordpress.yaml + ├── PersistentVolumeClaim__v1_wordpress-demo_mysql-pvc.yaml + ├── Secret__v1_wordpress-demo_mysql-password.yaml + ├── Service__v1_wordpress-demo_mysql.yaml + └── Service__v1_wordpress-demo_wordpress.yaml +``` + +**Review the final output:** +```bash +cat output/output.yaml +``` + +This file is ready to deploy to any target cluster! + +## Step 6: Deploy to Target Cluster (Optional) + +If you have a target cluster, you can deploy the transformed resources: + +```bash +# Create namespace on target cluster +kubectl create namespace wordpress-demo + +# Apply the transformed resources +kubectl apply -f output/output.yaml + +# Verify deployment +kubectl get all -n wordpress-demo +``` + +**Note:** For this demo, you can also apply to the same cluster (in a different namespace) to verify the transformation worked. + +## Understanding What Happened + +Let's trace what happened to one resource (mysql Deployment): + +1. **Export phase** (`crane export`): + - Read live Deployment from cluster + - Saved to `export/resources/wordpress-demo/Deployment_apps_v1_wordpress-demo_mysql.yaml` + - Contains uid, resourceVersion, status, etc. + +2. **Transform phase** (`crane transform`): + - KubernetesPlugin analyzed the Deployment + - Generated patch: `patches/wordpress-demo--apps-v1--Deployment--mysql.patch.yaml` + - Patch contains "remove" operations for server-managed fields + - Copied resource to `transform/10_KubernetesPlugin/resources/` + - Created `kustomization.yaml` to apply the patch + +3. **Apply phase** (`crane apply`): + - Ran `kubectl kustomize transform/10_KubernetesPlugin/` + - Applied patches to resources + - Wrote clean resource to `output/output.yaml` + - Result: clean Deployment ready for target cluster + +## Resource Whiteout (Why Are Some Resources Missing?) + +You might notice that Pods, ReplicaSets, and Endpoints were **not** included in the transform output. This is intentional! + +**Why?** These resources are **generated by controllers**: +- Pods → created by ReplicaSet +- ReplicaSets → created by Deployment +- Endpoints → created by Service controller + +When you deploy a Deployment and Service to the target cluster, the controllers will automatically recreate these resources. + +**Including them would cause:** +- ❌ Conflicts (Pods with old UIDs) +- ❌ Stale data (ReplicaSets from old rollouts) +- ❌ Confusion (runtime state doesn't transfer) + +The KubernetesPlugin automatically **whitelists** controller-managed resources, marking them for exclusion. + +## Next Steps + +Now that you've completed the basic workflow, explore more advanced scenarios: + +- [**Multi-Stage Pipelines**](./03-multistage.md) - Learn how to chain multiple transformation stages +- [**Troubleshooting**](./05-troubleshooting.md) - Common issues and solutions + +## Cleanup + +Remove the demo resources: + +```bash +# Delete the demo namespace +kubectl delete namespace wordpress-demo + +# Remove generated directories (optional) +rm -rf export/ transform/ output/ +``` + +## Summary + +You've successfully: +- ✅ Deployed a sample application +- ✅ Exported resources with `crane export` +- ✅ Transformed resources with `crane transform` +- ✅ Reviewed the generated patches and kustomization +- ✅ Generated final output with `crane apply` +- ✅ (Optional) Deployed to a target cluster + +**Key Takeaways:** +- Transform removes server-managed fields automatically +- Uses standard Kustomize for transformations +- Controller-managed resources are excluded (whiteout) +- Output is ready for GitOps workflows diff --git a/docs/transform-scenarios/03-multistage.md b/docs/transform-scenarios/03-multistage.md new file mode 100644 index 00000000..35267a94 --- /dev/null +++ b/docs/transform-scenarios/03-multistage.md @@ -0,0 +1,356 @@ +# Multi-Stage Transform Pipelines + +This guide covers advanced multi-stage transformation workflows, showing you when and how to use multiple stages to handle complex migration scenarios. + +## What Are Multi-Stage Pipelines? + +A multi-stage pipeline processes resources through a **sequence of transformation stages**, where each stage: + +1. Reads the **fully materialized output** from the previous stage +2. Applies its own transformations +3. Writes output for the next stage + +``` +export/ Stage 1 Stage 2 Stage 3 +resources/ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ + │ 10_Kubernetes │ │ 20_Openshift │ │ 50_CustomEdits │ +─────────────▶│ Plugin │─▶│ Plugin │─▶│ │─▶ output/ + │ │ │ │ │ │ + │ - Clean metadata│ │ - Convert Routes│ │ - Manual tweaks │ + └─────────────────┘ └─────────────────┘ └─────────────────┘ +``` + +## When to Use Multi-Stage Pipelines + +### Single Stage Is Sufficient When: +- ✅ Migrating between similar Kubernetes clusters +- ✅ Only need basic cleanup (remove UIDs, status, etc.) +- ✅ No platform-specific resources (OpenShift, etc.) +- ✅ No manual customization needed + +### Multi-Stage Is Better When: +- ✅ Cross-platform migration (OpenShift to Kubernetes, or vice versa) +- ✅ Multiple transformation concerns (cleanup, conversion, customization) +- ✅ Need to inspect intermediate results +- ✅ Want to separate automated and manual changes +- ✅ Complex transformations that benefit from separation of concerns + +## Stage Types + +### Plugin-Based Stages (Auto-Regenerate) + +Stage names ending with `Plugin` use a corresponding plugin: + +```bash +crane transform --stage 10_KubernetesPlugin # Uses KubernetesPlugin +crane transform --stage 20_OpenshiftPlugin # Uses OpenshiftPlugin +``` + +**Behavior:** +- Automatically run plugin on each transform +- Always regenerate (no `--force` needed) +- Cannot manually edit (changes will be overwritten) + +**Best for:** +- Automated transformations +- Repeatable processing +- Plugin-driven cleanup/conversion + +### Pass-Through Stages (Manual Edit Protection) + +Stage names **NOT** ending with `Plugin` create pass-through stages: + +```bash +crane transform --stage 50_CustomEdits # No plugin - pass-through +crane transform --stage 90_FinalTweaks # No plugin - pass-through +``` + +**Behavior:** +- Resources copied unchanged from previous stage +- No patches generated automatically +- Protected from accidental overwrite (requires `--force`) +- Perfect for manual editing + +**Best for:** +- Manual customizations +- Hand-crafted patches +- Environment-specific changes + +## Example: Basic Two-Stage Pipeline + +**Scenario:** Cleaning resources and then adding custom labels + +### Step 1: Export Resources + +```bash +crane export +``` + +### Step 2: Create Cleanup Stage + +```bash +crane transform # Generates default KubernetesPlugin +``` + +**Result:** +``` +transform/10_KubernetesPlugin/ +├── resources/ # Exported resources +├── patches/ # Auto-generated cleanup patches +└── kustomization.yaml +``` + +### Step 3: Create Custom Stage + +```bash +crane transform --stage 50_CustomLabels +``` + +**Result:** +``` +transform/50_CustomLabels/ +├── resources/ # Copied from 10_KubernetesPlugin OUTPUT +├── patches/ # Empty - ready for manual patches +└── kustomization.yaml +``` + +**Important:** The `resources/` in stage 50 contains the **cleaned output** from previous stage (stage 10 in this example), not the raw export! + +### Step 4: Add Custom Labels and Namespace + +Edit `kustomization.yaml` to add common labels and set target namespace: + +```bash +cat >> transform/50_CustomLabels/kustomization.yaml </ + +# Validate syntax +kubectl apply --dry-run=client -k transform// +``` + +## Troubleshooting Multi-Stage Pipelines + +### Issue: "Stage X requires output from stage Y, but output directory does not exist" + +**Cause:** You're trying to run a stage before its predecessor has been run. + +**Solution:** +```bash +# Run all stages up to the one you want +crane transform + +# Or run the missing predecessor +crane transform --stage 10_KubernetesPlugin +crane transform --stage 20_OpenshiftPlugin +``` + +### Issue: Custom stage has stale data + +**Cause:** Previous plugin stages were updated, but custom stage still has old data. + +**Solution:** +```bash +# Re-run with --force to refresh custom stage +crane transform --force +``` + +**Warning:** Manual edits in the custom stage will be lost! + +### Issue: Resources missing in later stages + +**Cause:** Earlier stage marked resources for whiteout (deletion). + +**Solution:** +```bash +# Check what was whitelisted in earlier stage (whiteouts are commented) +cat transform/10_KubernetesPlugin/kustomize.yaml + +# Inspect intermediate output +ls transform/.work/10_KubernetesPlugin/output/ +``` + +## Summary + +Multi-stage pipelines provide: +- ✅ **Separation of concerns** - Different transformations in different stages +- ✅ **Sequential consistency** - Each stage sees materialized output +- ✅ **Flexibility** - Mix plugin and manual stages +- ✅ **Debugging** - Inspect intermediate results in `.work/` +- ✅ **GitOps-friendly** - Standard Kustomize layouts + +**Key Takeaways:** +- Plugin stages auto-regenerate (no `--force` needed) +- Custom stages are protected (require `--force`) +- Each stage processes previous stage's **materialized output** +- Run `crane apply` to generate manifests (between stage and final) +- Always add manual stages last +- Use `.work/` directory for debugging + +## Next Steps + +- [**Troubleshooting**](./05-troubleshooting.md) - Common issues and solutions +- [**Transform CLI Reference**](../transform.md) - Detailed documentation diff --git a/docs/transform-scenarios/05-troubleshooting.md b/docs/transform-scenarios/05-troubleshooting.md new file mode 100644 index 00000000..9d02c2f5 --- /dev/null +++ b/docs/transform-scenarios/05-troubleshooting.md @@ -0,0 +1,871 @@ +# Troubleshooting and FAQ + +Common issues, error messages, and solutions for `crane transform`. + +## Table of Contents + +- [Common Errors](#common-errors) +- [Stage Issues](#stage-issues) +- [Kustomize Issues](#kustomize-issues) +- [Resource Issues](#resource-issues) +- [Patch Issues](#patch-issues) +- [Debugging Tips](#debugging-tips) +- [FAQ](#faq) + +## Common Errors + +### Error: "No stages found matching selector" + +**Full error:** +``` +Error: no stages found matching selector +``` + +**Cause:** No stage directories exist in `transform/` directory. + +**Solution 1:** Create default stage +```bash +crane transform # Creates 10_KubernetesPlugin automatically +``` + +**Solution 2:** Create specific stage +```bash +crane transform --stage 10_KubernetesPlugin +``` + +**Verification:** +```bash +ls transform/ +# Should show at least one stage directory +``` + +--- + +### Error: "Stage is not empty (use --force to overwrite)" + +**Full error:** +``` +Error: stage directory /path/to/transform/50_CustomEdits is not empty and is not a plugin stage (use --force to overwrite) +``` + +**Cause:** Custom stage (not ending with `Plugin`) already exists and is protected from overwrite. + +**Solutions:** + +**Option 1:** Use `--force` to overwrite (WARNING: loses manual edits) +```bash +crane transform --force +``` + +**Option 2:** Edit in place (don't re-create) +```bash +# Edit existing files +vim transform/50_CustomEdits/resources/Deployment_apps_v1_default_myapp.yaml +``` + +**Option 3:** Choose different stage name +```bash +crane transform --stage 60_MyNewEdits +``` + +**Option 4:** Commit changes first, then force +```bash +git add transform/ +git commit -m "Save custom edits" +crane transform --force +git diff # Review what changed +``` + +--- + +### Error: "Stage X requires output from stage Y, but output directory does not exist" + +**Full error:** +``` +Error: stage 20_OpenshiftPlugin requires output from stage 10_KubernetesPlugin, but output directory does not exist: transform/.work/10_KubernetesPlugin/output +``` + +**Cause:** Trying to run a later stage before earlier stages have been run. + +**Solution:** Run all previous stages first +```bash +# Option 1: Run all stages +crane transform + +# Option 2: Run missing predecessor explicitly +crane transform --stage 10_KubernetesPlugin +crane transform --stage 20_OpenshiftPlugin +``` + +**Verification:** +```bash +# Check which stages have output +ls transform/.work/*/output/ +``` + +--- + +### Error: "failed to load plugins" + +**Full error:** +``` +Error: failed to load plugins: plugin directory does not exist: /home/user/.local/share/crane/plugins +``` + +**Cause:** Plugin directory doesn't exist or no plugins installed. + +**Solution 1:** Check plugin directory +```bash +# Check default location +ls ~/.local/share/crane/plugins/ + +# Or check custom location +crane transform --plugin-dir /path/to/plugins +``` + +**Solution 2:** Install built-in plugins +The KubernetesPlugin is built-in and doesn't require installation. If you need additional plugins: + +```bash +# Check available plugins +crane transform list-plugins + +# Download additional plugins (if available) +# Consult crane-plugins repository +``` + +**Verification:** +```bash +crane transform list-plugins +# Should show at least KubernetesPlugin +``` + +--- + +### Error: "kubectl not found in PATH" + +**Full error:** +``` +Error: kubectl command not found +``` + +**Cause:** `kubectl` is not installed or not in PATH. + +**Solution:** Install kubectl +```bash +# On Linux +curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl" +chmod +x kubectl +sudo mv kubectl /usr/local/bin/ + +# On macOS +brew install kubectl + +# Verify installation +kubectl version --client +``` + +--- + +## Stage Issues + +### Issue: Stage has stale data + +**Symptoms:** +- Resources in custom stage don't match latest transform +- Custom stage has old data from previous plugin stages + +**Cause:** Plugin stages were updated, but custom stage wasn't regenerated. + +**Solution:** +```bash +# Force regenerate (WARNING: loses manual edits) +crane transform --force + +# Better: Commit first +git add transform/ +git commit -m "Save before regeneration" +crane transform --force +git diff # Review changes +``` + +**Prevention:** +Always add custom stages **last** in the pipeline. + +--- + +### Issue: Can't create new stage between existing stages + +**Scenario:** +``` +Existing: 10_KubernetesPlugin, 30_CustomEdits +Want to add: 20_OpenshiftPlugin (in between) +``` + +**Solution:** + +**Step 1:** Create the new stage +```bash +crane transform --stage 20_OpenshiftPlugin +``` + +**Step 2:** Regenerate later stages (WARNING: requires --force for custom stages) +```bash +crane transform --force +``` + +**Better approach:** Use priority spacing (10, 20, 30, ..., 90) to allow insertions. + +--- + +### Issue: Plugin stage not regenerating + +**Symptom:** Made changes to export, but plugin stage still has old data. + +**Cause:** Plugin stages should auto-regenerate, but there may be an issue. + +**Solution:** +```bash +# Explicitly re-run the plugin stage +crane transform --stage 10_KubernetesPlugin + +# Or force all stages +crane transform --force +``` + +**Verification:** +```bash +# Check stage's input snapshot +ls transform/.work/10_KubernetesPlugin/input/ + +# Compare with export +diff -r export/resources/ transform/.work/10_KubernetesPlugin/input/ +``` + +--- + +## Kustomize Issues + +### Error: "kustomization.yaml validation failed" + +**Symptoms:** +``` +Error: error building kustomization: ... +``` + +**Cause:** Invalid Kustomize syntax or missing files. + +**Debug:** +```bash +# Run kustomize manually to see detailed error +kubectl kustomize transform/10_KubernetesPlugin/ +``` + +**Common issues:** + +**Issue 1: Missing resource file** +```yaml +# kustomization.yaml references non-existent file +resources: +- resources/Deployment_apps_v1_default_missing.yaml # Doesn't exist +``` + +**Solution:** Remove reference or create the file +```bash +# Check what files exist +ls transform/10_KubernetesPlugin/resources/ + +# Edit kustomization.yaml to match +vim transform/10_KubernetesPlugin/kustomization.yaml +``` + +**Issue 2: Invalid patch syntax** +```yaml +# patches/my-patch.yaml has syntax error +- op: add + path: /metadata/labels/team + # Missing 'value' field +``` + +**Solution:** Fix patch syntax +```bash +vim transform/10_KubernetesPlugin/patches/my-patch.yaml +``` + +**Issue 3: Invalid YAML** +```yaml +# Indentation error or missing colon +resources: +- resources/deployment.yaml + - resources/service.yaml # Wrong indentation +``` + +**Solution:** Fix YAML syntax +```bash +# Use a YAML validator +yamllint transform/10_KubernetesPlugin/kustomization.yaml +``` + +--- + +### Error: "patch target not found" + +**Full error:** +``` +Error: no matches for Id ~G_v1_ConfigMap|default|myapp-config; failed to find unique target for patch +``` + +**Cause:** Patch target selector doesn't match any resources. + +**Debug:** +```bash +# Check what the patch targets +cat transform/10_KubernetesPlugin/kustomization.yaml | grep -A 7 "path: patches/my-patch.yaml" +``` + +**Example:** +```yaml +patches: +- path: patches/my-patch.yaml + target: + kind: ConfigMap + name: myapp-config # This name must match exactly + namespace: default +``` + +**Solution:** Fix target selector to match resource +```bash +# Check actual resource name +grep "name:" transform/10_KubernetesPlugin/resources/ConfigMap*.yaml + +# Update kustomization.yaml target +vim transform/10_KubernetesPlugin/kustomization.yaml +``` + +--- + +## Resource Issues + +### Issue: Resources missing from output + +**Symptom:** Expected resources don't appear in final output. + +**Possible causes:** + +**Cause 1: Resource was whitelisted** + +Crane automatically excludes controller-managed resources (Pods, ReplicaSets, etc.). + +**Check:** +```bash +# Check kustomization.yaml to see which resources are included +cat transform/10_KubernetesPlugin/kustomization.yaml | grep -A 100 "resources:" +``` + +**Explanation:** +Controller-managed resources (Pods, ReplicaSets, Endpoints) are not included in the `resources:` list in `kustomization.yaml` because they are created automatically by their controllers. + +**Solution:** This is intentional and correct. Deploy the Deployment/StatefulSet, and controllers will recreate these resources. + +**Cause 2: Resource not in kustomization.yaml** + +**Check:** +```bash +grep "myresource" transform/10_KubernetesPlugin/kustomization.yaml +``` + +**Solution:** Add to resources list +```yaml +resources: +- resources/Deployment_apps_v1_default_myapp.yaml +- resources/Service__v1_default_myapp.yaml +- resources/ConfigMap__v1_default_myconfig.yaml # Add this +``` + +**Cause 3: Resource excluded by export** + +**Check:** +```bash +ls export/resources/default/ | grep MyResource +``` + +**Solution:** Re-export with correct filters + +--- + +### Issue: Duplicate resources in output + +**Symptom:** Same resource appears multiple times in `output/output.yaml`. + +**Cause:** Resource listed multiple times in kustomization.yaml or across multiple stage resource files. + +**Debug:** +```bash +# Check for duplicates in kustomization +grep "resources/" transform/10_KubernetesPlugin/kustomization.yaml | sort | uniq -d + +# Check final output +kubectl kustomize transform/10_KubernetesPlugin/ | grep "^kind:" +``` + +**Solution:** Remove duplicates from kustomization.yaml + +--- + +## Patch Issues + +### Error: JSONPatch path escaping + +**Symptom:** +``` +Error: invalid patch: unable to parse path +``` + +**Common issue:** Forgot to escape `/` in annotation/label keys. + +**Wrong:** +```yaml +- op: remove + path: /metadata/annotations/deployment.kubernetes.io/revision +``` + +**Correct:** +```yaml +- op: remove + path: /metadata/annotations/deployment.kubernetes.io~1revision +``` + +**Rule:** Replace `/` with `~1` in path components. + +--- + +### Error: Patch trying to remove non-existent field + +**Symptom:** +``` +Error: remove operation does not apply: doc is missing path +``` + +**Cause:** Patch tries to remove a field that doesn't exist in the resource. + +**Debug:** +```bash +# Check if field exists +kubectl kustomize transform/10_KubernetesPlugin/ | yq '.metadata.annotations' +``` + +**Solution 1:** Make patch conditional (not possible with JSONPatch) + +**Solution 2:** Remove the patch operation + +**Solution 3:** Use strategic merge patch instead +```yaml +# Use patchesStrategicMerge instead of patches +patchesStrategicMerge: +- patches/my-merge-patch.yaml +``` + +--- + +### Error: Patch array index out of bounds + +**Symptom:** +``` +Error: invalid patch: index out of bounds +``` + +**Wrong:** +```yaml +- op: add + path: /spec/template/spec/containers/5/env # Only 2 containers exist + value: + - name: MY_VAR + value: my-value +``` + +**Debug:** +```bash +# Check how many containers exist +kubectl kustomize transform/10_KubernetesPlugin/ | yq '.spec.template.spec.containers | length' +``` + +**Solution:** Use correct index (0-based) +```yaml +- op: add + path: /spec/template/spec/containers/0/env + value: + - name: MY_VAR + value: my-value +``` + +--- + +## Debugging Tips + +### Tip 1: Inspect Intermediate Output + +Use `.work/` directory to debug multi-stage pipelines: + +```bash +# See what Stage 1 read as input +ls transform/.work/10_KubernetesPlugin/input/ + +# See what Stage 1 produced (input for Stage 2) +ls transform/.work/10_KubernetesPlugin/output/ + +# Compare input vs output +diff -r transform/.work/10_KubernetesPlugin/input/ \ + transform/.work/10_KubernetesPlugin/output/ +``` + +--- + +### Tip 2: Preview Before Applying + +Always preview final output: + +```bash +# Preview specific stage +kubectl kustomize transform/10_KubernetesPlugin/ + +# Preview final output +crane apply +cat output/output.yaml +``` + +--- + +### Tip 3: Validate Syntax + +```bash +# Validate kustomization.yaml +kubectl kustomize transform/10_KubernetesPlugin/ > /dev/null + +# Validate patch syntax +cat transform/10_KubernetesPlugin/patches/my-patch.yaml | jq -r '.' + +# Validate YAML +yamllint transform/10_KubernetesPlugin/ +``` + +--- + +### Tip 4: Use Dry-Run + +```bash +# Test apply without actually applying +kubectl apply --dry-run=client -f output/output.yaml + +# Server-side validation (requires cluster access) +kubectl apply --dry-run=server -f output/output.yaml +``` + +--- + +### Tip 5: Enable Debug Logging + +```bash +crane transform --debug +``` + +This shows detailed logging about: +- Plugin execution +- Resource processing +- Patch generation +- File writes + +--- + +### Tip 6: Compare Stages + +```bash +# Compare two stages +diff <(kubectl kustomize transform/10_KubernetesPlugin/) \ + <(kubectl kustomize transform/20_OpenshiftPlugin/) + +# More readable diff +diff -y <(kubectl kustomize transform/10_KubernetesPlugin/) \ + <(kubectl kustomize transform/20_OpenshiftPlugin/) | less +``` + +--- + +### Tip 7: Inspect Individual Resources + +```bash +# Extract specific resource from output +kubectl kustomize transform/10_KubernetesPlugin/ | \ + yq 'select(.kind == "Deployment" and .metadata.name == "myapp")' + +# Count resources by kind +kubectl kustomize transform/10_KubernetesPlugin/ | \ + yq '.kind' | sort | uniq -c +``` + +--- + +## FAQ + +### Q: Why are Pods/ReplicaSets missing from the output? + +**A:** These are controller-managed resources. Crane automatically excludes them by `ownerRef` because: +- Pods are created by ReplicaSets/Deployments +- ReplicaSets are created by Deployments +- Endpoints are created by Services + +Deploy the controller resource (Deployment/StatefulSet/Service), and these will be recreated automatically. + +**Verify:** +```bash +# Check which resources are included in the kustomization +cat transform/10_KubernetesPlugin/kustomization.yaml | grep -A 100 "resources:" +``` + +--- + +### Q: Can I run transform without exporting first? + +**A:** No, `crane transform` requires input resources from `crane export` (or a previous stage). + +**Workflow:** +```bash +crane export -n myapp # Required first step +crane transform # Requires export/ directory +``` + +--- + +### Q: How do I know which plugin a stage uses? + +**A:** Stage name determines the plugin: + +- `10_KubernetesPlugin` → uses `KubernetesPlugin` (default) +- `20_OpenshiftPlugin` → uses `OpenshiftPlugin` +- `50_CustomEdits` → no plugin (pass-through) + +**Check available plugins:** +```bash +crane transform list-plugins +``` + +--- + +### Q: What's the difference between `crane transform` and `crane apply`? + +**A:** +- **`crane transform`**: Generates transform stages (resources + patches) +- **`crane apply`**: Runs `kubectl kustomize` on stages to produce final output + +**Workflow:** +```bash +crane transform # Creates transform/ directory +crane apply # Creates output/ directory from transform/ +``` + +--- + +### Q: Can I edit resources in transform/*/resources/ directly? + +**A:** +- **Plugin stages** (ending with `Plugin`): No, changes will be overwritten +- **Custom stages** (not ending with `Plugin`): Yes, but prefer using patches + +**Better approach:** Use patches instead of direct edits (easier to track in Git) + +--- + +### Q: How do I skip a specific plugin? + +**A:** Use `--skip-plugins` flag: + +```bash +crane transform --skip-plugins OpenshiftPlugin,ImagestreamPlugin +``` + +**Check available plugins:** +```bash +crane transform list-plugins +``` + +--- + +### Q: Can I use transform output with ArgoCD/Flux directly wih kustomize? + +**A:** Yes! Transform output is standard Kustomize format. + +**ArgoCD example:** +```yaml +apiVersion: argoproj.io/v1alpha1 +kind: Application +metadata: + name: myapp +spec: + source: + repoURL: https://github.com/myorg/myrepo + path: transform/10_KubernetesPlugin + targetRevision: main + destination: + server: https://kubernetes.default.svc + namespace: myapp +``` + +**Flux example:** +```yaml +apiVersion: kustomize.toolkit.fluxcd.io/v1beta2 +kind: Kustomization +metadata: + name: myapp +spec: + sourceRef: + kind: GitRepository + name: myrepo + path: ./transform/10_KubernetesPlugin + prune: true +``` + +--- + +### Q: What happens if I delete the .work/ directory? + +**A:** It's regenerated on the next `crane transform` run. The `.work/` directory contains intermediate artifacts for debugging; it's safe to delete. + +```bash +# Safe to delete +rm -rf transform/.work/ + +# Regenerated on next run +crane transform +``` + +--- + +### Q: How do I migrate namespaces? + +**A:** Use Kustomize's `namespace` field in a custom stage: + +```yaml +# transform/50_ChangeNamespace/kustomization.yaml +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +namespace: new-namespace +resources: +- resources/Deployment_apps_v1_old-namespace_myapp.yaml +``` + +**Or use a patch:** +```yaml +- op: replace + path: /metadata/namespace + value: new-namespace +``` + +--- + +### Q: Can I use crane transform for non-Kubernetes resources? + +**A:** No, crane transform is designed for Kubernetes manifests only. It expects: +- Valid Kubernetes YAML +- Resources with `apiVersion`, `kind`, `metadata` + +--- + +### Q: What's the recommended Git workflow? + +**A:** + +**Commit:** +```gitignore +transform/*/resources/ +transform/*/patches/ +transform/*/kustomization.yaml +``` + +**Ignore:** +```gitignore +transform/.work/ +output/ +``` + +**Workflow:** +```bash +crane export -n myapp +crane transform +git add transform/ +git commit -m "Add transformed manifests" +git push +``` + +--- + +### Q: How do I debug "sequential consistency" issues? + +**A:** Check intermediate outputs in `.work/`: + +```bash +# What did Stage 1 output? +ls transform/.work/10_KubernetesPlugin/output/ + +# Is it what Stage 2 expects? +ls transform/.work/20_OpenshiftPlugin/input/ + +# Compare +diff -r transform/.work/10_KubernetesPlugin/output/ \ + transform/.work/20_OpenshiftPlugin/input/ +``` + +**They should be identical.** + +--- + +## Getting Help + +If you encounter issues not covered here: + +1. **Check logs:** + ```bash + crane transform --debug + ``` + +2. **Validate manually:** + ```bash + kubectl kustomize transform/10_KubernetesPlugin/ + ``` + +3. **Check GitHub issues:** + - [Crane Issues](https://github.com/konveyor/crane/issues) + +4. **File a bug report:** + ```bash + # Include: + # - crane version + # - Full error message + # - Minimal reproduction steps + ``` + +5. **Community support:** + - Konveyor Slack + - GitHub Discussions + +--- + +## Summary + +**Most common issues:** +- ✅ Custom stage protection → Use `--force` or edit in place +- ✅ Missing prerequisite stages → Run `crane transform` to run all +- ✅ Kustomize syntax errors → Validate with `kubectl kustomize` +- ✅ Missing resources → Check kustomization.yaml resources list +- ✅ JSONPatch escaping → Use `~1` for `/` in paths + +**Best practices:** +- ✅ Always preview with `kubectl kustomize` before applying +- ✅ Use `--debug` for detailed logging +- ✅ Commit to Git before using `--force` +- ✅ Test with `kubectl apply --dry-run` +- ✅ Check `.work/` directory for debugging multi-stage issues + +## Next Steps + +- [**Overview**](./01-overview.md) - Understand crane transform concepts +- [**Quickstart**](./02-quickstart.md) - Hands-on tutorial +- [**Multi-Stage Pipelines**](./03-multistage.md) - Advanced workflows diff --git a/docs/transform-scenarios/README.md b/docs/transform-scenarios/README.md new file mode 100644 index 00000000..b77b138f --- /dev/null +++ b/docs/transform-scenarios/README.md @@ -0,0 +1,296 @@ +# Crane Transform - Scenarios and Tutorials + +Welcome to the Crane Transform documentation! This directory contains comprehensive tutorials and scenario-based guides to help you master `crane transform`. + +## What is Crane Transform? + +Crane Transform is the second phase in Crane's Kubernetes migration workflow. It prepares exported resources for deployment to a target cluster by: + +- **Cleaning resources** - Removing cluster-specific metadata +- **Applying transformations** - Modifying resources for target environments +- **Organizing artifacts** - Creating Kustomize-based directory structures + +## Quick Navigation + +### For Beginners + +Start here if you're new to crane transform: + +1. **[Overview](./01-overview.md)** - Understand what crane does and key concepts +2. **[Quickstart Tutorial](./02-quickstart.md)** - Hands-on walkthrough with a real example + +### For Intermediate Users + +Explore advanced features: + +3. **[Multi-Stage Pipelines](./03-multistage.md)** - Chain multiple transformation stages + +### For Troubleshooting + +4. **[Troubleshooting & FAQ](./05-troubleshooting.md)** - Common issues, error messages, and solutions + +## What's Covered + +### 01 - Overview +- **What you'll learn:** + - What crane transform does + - Why it's needed + - Key concepts (plugins, stages, Kustomize) + - Common use cases + - Directory structure + +- **Best for:** Understanding the big picture + +### 02 - Quickstart Tutorial +- **What you'll learn:** + - Complete workflow from export to apply + - Deploy sample app + - Run your first transform + - Inspect generated artifacts + - Deploy to target cluster + +- **Best for:** Hands-on learning +- **Prerequisites:** kubectl, access to a cluster + +### 03 - Multi-Stage Pipelines +- **What you'll learn:** + - When to use multiple stages + - Plugin vs custom stages + - Sequential consistency + - Working directory structure + - Manual editing with Kustomize features + - Best practices + +- **Best for:** Complex transformations and manual customization +- **Prerequisites:** Completed quickstart + +### 05 - Troubleshooting & FAQ +- **What you'll learn:** + - Common error messages + - Debugging techniques + - Solutions to typical problems + - Frequently asked questions + +- **Best for:** Solving problems + +## Common Scenarios + +### Scenario 1: Simple Cluster-to-Cluster Migration +**Goal:** Migrate app from one Kubernetes cluster to another (same type) + +**Steps:** +1. [Quickstart Tutorial](./02-quickstart.md) - Follow the complete walkthrough +2. Deploy using `kubectl apply -f output/output.yaml` + +--- + +### Scenario 2: OpenShift to Kubernetes Migration +**Goal:** Migrate app from OpenShift to vanilla Kubernetes + +**Steps:** +1. [Multi-Stage Pipelines](./03-multistage.md) - See OpenShift migration example +2. Use `10_KubernetesPlugin` for cleanup +3. Use `20_OpenshiftPlugin` for conversion +4. Add custom stage for environment tweaks + +--- + +### Scenario 3: GitOps Workflow +**Goal:** Prepare resources for ArgoCD/Flux + +**Steps:** +1. [Quickstart Tutorial](./02-quickstart.md) - Generate transformed resources +2. Commit `transform/` directory to Git +3. Configure ArgoCD/Flux to deploy from Git + +**Reference:** [FAQ - GitOps integration](./05-troubleshooting.md#q-can-i-use-transform-output-with-argocdflux) + +--- + +### Scenario 4: Multi-Environment Deployment +**Goal:** Prepare resources for dev, staging, production + +**Steps:** +1. [Multi-Stage Pipelines](./03-multistage.md) - See environment-specific overlays +2. Create base transformation +3. Use Kustomize overlays for environments + +--- + +### Scenario 5: Manual Customization +**Goal:** Hand-edit specific resources + +**Steps:** +1. [Multi-Stage Pipelines](./03-multistage.md) - See custom stages section +2. Create custom stage +3. Add manual edits or patches with Kustomize features + +--- + +## Learning Path + +### Path 1: Quick Start +For users who want to get started quickly: + +1. Read [Overview](./01-overview.md) +2. Complete [Quickstart](./02-quickstart.md) +3. Browse [Troubleshooting](./05-troubleshooting.md) + +**Outcome:** Can perform basic transforms and migrations + +--- + +### Path 2: Comprehensive +For users who want deep understanding: + +1. Read [Overview](./01-overview.md) +2. Complete [Quickstart](./02-quickstart.md) +3. Study [Multi-Stage Pipelines](./03-multistage.md) +4. Review [Troubleshooting](./05-troubleshooting.md) + +**Outcome:** Can handle complex migrations with confidence + +--- + +### Path 3: Problem-Solving +For users encountering issues: + +1. Go directly to [Troubleshooting](./05-troubleshooting.md) +2. Search for your error message or symptom +3. Follow the solution steps + +**Outcome:** Resolve specific issues quickly + +--- + +## Additional Resources + +### Official Documentation + +- **[Transform CLI Reference](../transform.md)** - Detailed directory structure and options +- **[Multi-Stage Kustomize](../kustomize-multistage.md)** - Technical deep-dive into architecture +- **[Crane README](../../README.md)** - Project overview and installation + +### External Resources + +- **[Kustomize Documentation](https://kubectl.docs.kubernetes.io/references/kustomize/)** - Learn Kustomize features +- **[Konveyor Community](https://www.konveyor.io/)** - Crane parent project +- **[JSONPatch Specification](https://jsonpatch.com/)** - Understand patch syntax + +### Example Data + +This directory includes example exported resources in `export/resources/` for reference: +- WordPress + MySQL deployment +- Demonstrates typical exported resources +- Shows what transform processes + +## Quick Reference + +### Common Commands + +```bash +# Export from source cluster +crane export + +# Transform with default stage +crane transform + +# Create custom stage +crane transform --stage 50_CustomEdits + +# Force overwrite (WARNING: loses manual edits) +crane transform --force + +# List available plugins +crane transform list-plugins + +# Preview final output +kubectl kustomize transform/10_KubernetesPlugin/ + +# Generate final manifests +crane apply + +# Apply to target cluster +kubectl apply -f output/output.yaml +``` + +### Directory Structure + +``` +. +├── export/ # Phase 1: Exported resources +│ └── resources/ +│ +├── transform/ # Phase 2: Transform stages +│ ├── 10_KubernetesPlugin/ # Plugin-based stage +│ │ ├── resources/ +│ │ ├── patches/ +│ │ └── kustomization.yaml +│ ├── 50_CustomEdits/ # Custom stage +│ │ └── ... +│ └── .work/ # Intermediate artifacts (debugging) +│ +└── output/ # Phase 3: Final manifests + ├── output.yaml + └── resources/ +``` + +### Plugin vs Custom Stages + +| Feature | Plugin Stage | Custom Stage | +|---------|-------------|--------------| +| **Name pattern** | Ends with `Plugin` | Does NOT end with `Plugin` | +| **Example** | `10_KubernetesPlugin` | `50_CustomEdits` | +| **Behavior** | Runs plugin | Pass-through (no plugin) | +| **Regeneration** | Always (auto) | Protected (requires `--force`) | +| **Use case** | Automated cleanup | Manual customization | + +### Workflow Phases + +``` +1. crane export → export/resources/ +2. crane transform → transform/stages/ +3. crane apply → output/output.yaml +4. kubectl apply → target cluster +``` + +## Getting Help + +### Common Issues + +**Issue:** Error messages +- **Solution:** Check [Troubleshooting - Common Errors](./05-troubleshooting.md#common-errors) + +**Issue:** Resources missing from output +- **Solution:** Check [Troubleshooting - Resource Issues](./05-troubleshooting.md#resource-issues) + +**Issue:** Kustomize syntax errors +- **Solution:** Check [Troubleshooting - Kustomize Issues](./05-troubleshooting.md#kustomize-issues) + +### Support Channels + +- **GitHub Issues:** [konveyor/crane/issues](https://github.com/konveyor/crane/issues) +- **Documentation:** This directory and [docs/](../) +- **Community:** Konveyor Slack + +## Contributing + +Found an issue or want to improve these docs? + +1. **Report issues:** [File a bug](https://github.com/konveyor/crane/issues) +2. **Suggest improvements:** Open a PR +3. **Share scenarios:** Contribute new examples + +## What's Next? + +**New to crane transform?** +- Start with [Overview](./01-overview.md) + +**Want hands-on practice?** +- Jump to [Quickstart Tutorial](./02-quickstart.md) + +**Need advanced features?** +- Explore [Multi-Stage Pipelines](./03-multistage.md) + +**Encountering issues?** +- Check [Troubleshooting](./05-troubleshooting.md) diff --git a/docs/transform-scenarios/wordpress-demo/README.md b/docs/transform-scenarios/wordpress-demo/README.md new file mode 100644 index 00000000..bc2d3fc3 --- /dev/null +++ b/docs/transform-scenarios/wordpress-demo/README.md @@ -0,0 +1,43 @@ +# Example Export - WordPress Demo (stateless) + +This directory contains example exported resources from a WordPress + MySQL deployment, used in the [Quickstart Tutorial](../02-quickstart.md). + +## How It Was Generated + +```bash +# Deploy WordPress demo application +kubectl create namespace wordpress-demo +kubectl apply -n wordpress-demo -f + +# Export resources +kubectl config set-context --current --namespace=wordpress-demo +crane export +``` + +## Using This Example + +To use this example export in the tutorial workflow: + +```bash +# Start from this directory +cd docs/transform-scenarios + +# Transform the exported resources +crane transform + +# Apply to generate final manifests +crane apply + +# Result: output/output.yaml ready for deployment +``` + +## Contents + +- `resources/wordpress-demo/` - Exported Kubernetes resources + - Deployments (MySQL, WordPress) + - Services + - Secrets + - PersistentVolumeClaims + - Generated resources (Pods, ReplicaSets, Endpoints) + +See [Quickstart Tutorial](../02-quickstart.md) for detailed walkthrough. diff --git a/docs/transform-scenarios/wordpress-demo/export/resources/default/ConfigMap__v1_default_kube-root-ca.crt.yaml b/docs/transform-scenarios/wordpress-demo/export/resources/default/ConfigMap__v1_default_kube-root-ca.crt.yaml new file mode 100644 index 00000000..e49b6186 --- /dev/null +++ b/docs/transform-scenarios/wordpress-demo/export/resources/default/ConfigMap__v1_default_kube-root-ca.crt.yaml @@ -0,0 +1,48 @@ +apiVersion: v1 +data: + ca.crt: | + -----BEGIN CERTIFICATE----- + MIIDBjCCAe6gAwIBAgIBATANBgkqhkiG9w0BAQsFADAVMRMwEQYDVQQDEwptaW5p + a3ViZUNBMB4XDTIzMDgyMTEzMTEyMFoXDTMzMDgxOTEzMTEyMFowFTETMBEGA1UE + AxMKbWluaWt1YmVDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOUi + L0a0yk+ANnuYn7ESu1z4g1N/xv37Ph6WiSLVutimTpg+vc3lwBVOkW+oM9rXGm3C + DtLr70y2fPBQq5iYwhivH+AiJCT51zh+I992CBMqTZmMYq1Yf2hhuN2xUximuGJg + 7lI4lAfHbn64yYxlYIOwVu58lmmycO3tWrqRM45w0URAmjHqCw7D0z//83nmrU6F + R1f4eY06v1QNNiyBlYCnWWZdusNtYNNGNQ6dRBH5IsvBhmbjN60m6QYZrR+sA1UE + s3lHkYa2lYLkIWbugYfaTZigqxGPUl8GMBtLeYDBRTMRe0WMYW3Gl+w1vjk+2o4v + 5uyvMB5GiUq9AxXvREMCAwEAAaNhMF8wDgYDVR0PAQH/BAQDAgKkMB0GA1UdJQQW + MBQGCCsGAQUFBwMCBggrBgEFBQcDATAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQW + BBRWM9OkFUq3iXhg/okf/Ve1sP3B0jANBgkqhkiG9w0BAQsFAAOCAQEAyw49Smi7 + Dz7SpoNwOd+D44CpuWPE19vG8vdf9+XWQwUy1QhJh21dQkk/U6lF6yVU1RBv32Tm + xYmOtu87fv85bB5lH5WURk/ljAsNo+7sEKWyq9q2cD4A+vh1r2U+EkI0doXYP1um + U42UdLLL2RkxuSqCkdCfCdFpbNz2VOCRlJg93vNUkGsfNehE6xXj4LqCQYXQVHlb + hJLGuKrVtE8dS/lgxc7JmqVo521ft8KKKadHvIP7W0j45sMg9K+OHaUp8cOZ02m2 + J+gRC1xg4A08AAmWV+/q2+byAecrUDf/LQcWwNqjTDRWAELiKLkF5UmbYAIr9wia + FdCTC8qesp6BEw== + -----END CERTIFICATE----- +kind: ConfigMap +metadata: + annotations: + kubernetes.io/description: Contains a CA bundle that can be used to verify the + kube-apiserver when using internal endpoints such as the internal service IP + or kubernetes.default.svc. No other usage is guaranteed across distributions + of Kubernetes clusters. + creationTimestamp: "2026-04-10T12:10:48Z" + managedFields: + - apiVersion: v1 + fieldsType: FieldsV1 + fieldsV1: + f:data: + .: {} + f:ca.crt: {} + f:metadata: + f:annotations: + .: {} + f:kubernetes.io/description: {} + manager: kube-controller-manager + operation: Update + time: "2026-04-10T12:10:48Z" + name: kube-root-ca.crt + namespace: default + resourceVersion: "326" + uid: aa6a6275-00a5-44aa-90c4-5fa00d031c7f diff --git a/docs/transform-scenarios/wordpress-demo/export/resources/default/ConfigMap__v1_default_nginx-config.yaml b/docs/transform-scenarios/wordpress-demo/export/resources/default/ConfigMap__v1_default_nginx-config.yaml new file mode 100644 index 00000000..f43a445c --- /dev/null +++ b/docs/transform-scenarios/wordpress-demo/export/resources/default/ConfigMap__v1_default_nginx-config.yaml @@ -0,0 +1,58 @@ +apiVersion: v1 +data: + nginx.conf: | + events { + worker_connections 64; + } + + http { + include /etc/nginx/mime.types; + default_type application/octet-stream; + + server { + listen 80; + root /var/www/html; + index index.php; + client_max_body_size 32m; + + location / { + try_files $uri $uri/ /index.php?$args; + } + + location ~ \.php$ { + fastcgi_pass localhost:9000; + fastcgi_index index.php; + include fastcgi_params; + fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; + } + } + } +kind: ConfigMap +metadata: + annotations: + kubectl.kubernetes.io/last-applied-configuration: | + {"apiVersion":"v1","data":{"nginx.conf":"events {\n worker_connections 64;\n}\n\nhttp {\n include /etc/nginx/mime.types;\n default_type application/octet-stream;\n\n server {\n listen 80;\n root /var/www/html;\n index index.php;\n client_max_body_size 32m;\n\n location / {\n try_files $uri $uri/ /index.php?$args;\n }\n\n location ~ \\.php$ {\n fastcgi_pass localhost:9000;\n fastcgi_index index.php;\n include fastcgi_params;\n fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;\n }\n }\n}\n"},"kind":"ConfigMap","metadata":{"annotations":{},"labels":{"app":"wordpress"},"name":"nginx-config","namespace":"default"}} + creationTimestamp: "2026-04-10T12:15:07Z" + labels: + app: wordpress + managedFields: + - apiVersion: v1 + fieldsType: FieldsV1 + fieldsV1: + f:data: + .: {} + f:nginx.conf: {} + f:metadata: + f:annotations: + .: {} + f:kubectl.kubernetes.io/last-applied-configuration: {} + f:labels: + .: {} + f:app: {} + manager: kubectl-client-side-apply + operation: Update + time: "2026-04-10T12:15:07Z" + name: nginx-config + namespace: default + resourceVersion: "675" + uid: ced3a8c2-2b9d-47e9-90e6-0a780c2416bd diff --git a/docs/transform-scenarios/wordpress-demo/export/resources/default/Deployment_apps_v1_default_wordpress-mysql.yaml b/docs/transform-scenarios/wordpress-demo/export/resources/default/Deployment_apps_v1_default_wordpress-mysql.yaml new file mode 100644 index 00000000..a373cafc --- /dev/null +++ b/docs/transform-scenarios/wordpress-demo/export/resources/default/Deployment_apps_v1_default_wordpress-mysql.yaml @@ -0,0 +1,209 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + annotations: + deployment.kubernetes.io/revision: "1" + kubectl.kubernetes.io/last-applied-configuration: | + {"apiVersion":"apps/v1","kind":"Deployment","metadata":{"annotations":{},"labels":{"app":"wordpress"},"name":"wordpress-mysql","namespace":"default"},"spec":{"selector":{"matchLabels":{"app":"wordpress","tier":"mysql"}},"strategy":{"type":"Recreate"},"template":{"metadata":{"labels":{"app":"wordpress","tier":"mysql"}},"spec":{"containers":[{"env":[{"name":"MYSQL_ROOT_PASSWORD","valueFrom":{"secretKeyRef":{"key":"MYSQL_ROOT_PASSWORD","name":"wordpress-secrets-hg692g82th"}}},{"name":"MYSQL_DATABASE","value":"wordpress"},{"name":"MYSQL_USER","value":"wordpress"},{"name":"MYSQL_PASSWORD","valueFrom":{"secretKeyRef":{"key":"MYSQL_WORDPRESS_PASSWORD","name":"wordpress-secrets-hg692g82th"}}}],"image":"mysql:8.0","name":"mysql","ports":[{"containerPort":3306,"name":"mysql"}],"volumeMounts":[{"mountPath":"/var/lib/mysql","name":"mysql-persistent-storage"}]}],"volumes":[{"name":"mysql-persistent-storage","persistentVolumeClaim":{"claimName":"mysql-pv-claim"}}]}}}} + creationTimestamp: "2026-04-10T12:15:08Z" + generation: 1 + labels: + app: wordpress + managedFields: + - apiVersion: apps/v1 + fieldsType: FieldsV1 + fieldsV1: + f:metadata: + f:annotations: + .: {} + f:kubectl.kubernetes.io/last-applied-configuration: {} + f:labels: + .: {} + f:app: {} + f:spec: + f:progressDeadlineSeconds: {} + f:replicas: {} + f:revisionHistoryLimit: {} + f:selector: {} + f:strategy: + f:type: {} + f:template: + f:metadata: + f:labels: + .: {} + f:app: {} + f:tier: {} + f:spec: + f:containers: + k:{"name":"mysql"}: + .: {} + f:env: + .: {} + k:{"name":"MYSQL_DATABASE"}: + .: {} + f:name: {} + f:value: {} + k:{"name":"MYSQL_PASSWORD"}: + .: {} + f:name: {} + f:valueFrom: + .: {} + f:secretKeyRef: {} + k:{"name":"MYSQL_ROOT_PASSWORD"}: + .: {} + f:name: {} + f:valueFrom: + .: {} + f:secretKeyRef: {} + k:{"name":"MYSQL_USER"}: + .: {} + f:name: {} + f:value: {} + f:image: {} + f:imagePullPolicy: {} + f:name: {} + f:ports: + .: {} + k:{"containerPort":3306,"protocol":"TCP"}: + .: {} + f:containerPort: {} + f:name: {} + f:protocol: {} + f:resources: {} + f:terminationMessagePath: {} + f:terminationMessagePolicy: {} + f:volumeMounts: + .: {} + k:{"mountPath":"/var/lib/mysql"}: + .: {} + f:mountPath: {} + f:name: {} + f:dnsPolicy: {} + f:restartPolicy: {} + f:schedulerName: {} + f:securityContext: {} + f:terminationGracePeriodSeconds: {} + f:volumes: + .: {} + k:{"name":"mysql-persistent-storage"}: + .: {} + f:name: {} + f:persistentVolumeClaim: + .: {} + f:claimName: {} + manager: kubectl-client-side-apply + operation: Update + time: "2026-04-10T12:15:08Z" + - apiVersion: apps/v1 + fieldsType: FieldsV1 + fieldsV1: + f:metadata: + f:annotations: + f:deployment.kubernetes.io/revision: {} + f:status: + f:availableReplicas: {} + f:conditions: + .: {} + k:{"type":"Available"}: + .: {} + f:lastTransitionTime: {} + f:lastUpdateTime: {} + f:message: {} + f:reason: {} + f:status: {} + f:type: {} + k:{"type":"Progressing"}: + .: {} + f:lastTransitionTime: {} + f:lastUpdateTime: {} + f:message: {} + f:reason: {} + f:status: {} + f:type: {} + f:observedGeneration: {} + f:readyReplicas: {} + f:replicas: {} + f:terminatingReplicas: {} + f:updatedReplicas: {} + manager: kube-controller-manager + operation: Update + subresource: status + time: "2026-04-10T12:15:58Z" + name: wordpress-mysql + namespace: default + resourceVersion: "800" + uid: 2eba9391-46db-4860-9f9a-a1cb396faf18 +spec: + progressDeadlineSeconds: 600 + replicas: 1 + revisionHistoryLimit: 10 + selector: + matchLabels: + app: wordpress + tier: mysql + strategy: + type: Recreate + template: + metadata: + labels: + app: wordpress + tier: mysql + spec: + containers: + - env: + - name: MYSQL_ROOT_PASSWORD + valueFrom: + secretKeyRef: + key: MYSQL_ROOT_PASSWORD + name: wordpress-secrets-hg692g82th + - name: MYSQL_DATABASE + value: wordpress + - name: MYSQL_USER + value: wordpress + - name: MYSQL_PASSWORD + valueFrom: + secretKeyRef: + key: MYSQL_WORDPRESS_PASSWORD + name: wordpress-secrets-hg692g82th + image: mysql:8.0 + imagePullPolicy: IfNotPresent + name: mysql + ports: + - containerPort: 3306 + name: mysql + protocol: TCP + resources: {} + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + volumeMounts: + - mountPath: /var/lib/mysql + name: mysql-persistent-storage + dnsPolicy: ClusterFirst + restartPolicy: Always + schedulerName: default-scheduler + securityContext: {} + terminationGracePeriodSeconds: 30 + volumes: + - name: mysql-persistent-storage + persistentVolumeClaim: + claimName: mysql-pv-claim +status: + availableReplicas: 1 + conditions: + - lastTransitionTime: "2026-04-10T12:15:58Z" + lastUpdateTime: "2026-04-10T12:15:58Z" + message: Deployment has minimum availability. + reason: MinimumReplicasAvailable + status: "True" + type: Available + - lastTransitionTime: "2026-04-10T12:15:08Z" + lastUpdateTime: "2026-04-10T12:15:58Z" + message: ReplicaSet "wordpress-mysql-9474c86b" has successfully progressed. + reason: NewReplicaSetAvailable + status: "True" + type: Progressing + observedGeneration: 1 + readyReplicas: 1 + replicas: 1 + terminatingReplicas: 0 + updatedReplicas: 1 diff --git a/docs/transform-scenarios/wordpress-demo/export/resources/default/Deployment_apps_v1_default_wordpress.yaml b/docs/transform-scenarios/wordpress-demo/export/resources/default/Deployment_apps_v1_default_wordpress.yaml new file mode 100644 index 00000000..b49641ca --- /dev/null +++ b/docs/transform-scenarios/wordpress-demo/export/resources/default/Deployment_apps_v1_default_wordpress.yaml @@ -0,0 +1,268 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + annotations: + deployment.kubernetes.io/revision: "1" + kubectl.kubernetes.io/last-applied-configuration: | + {"apiVersion":"apps/v1","kind":"Deployment","metadata":{"annotations":{},"labels":{"app":"wordpress"},"name":"wordpress","namespace":"default"},"spec":{"selector":{"matchLabels":{"app":"wordpress","tier":"frontend"}},"strategy":{"type":"Recreate"},"template":{"metadata":{"labels":{"app":"wordpress","tier":"frontend"}},"spec":{"containers":[{"env":[{"name":"WORDPRESS_DB_HOST","value":"wordpress-mysql"},{"name":"WORDPRESS_DB_PASSWORD","valueFrom":{"secretKeyRef":{"key":"MYSQL_WORDPRESS_PASSWORD","name":"wordpress-secrets-hg692g82th"}}},{"name":"WORDPRESS_DB_USER","value":"wordpress"},{"name":"WORDPRESS_CONFIG_EXTRA","value":"// Set SITE URL dynamically from requests to allow reach it on different endpoints\nif (isset($_SERVER['HTTP_HOST'])) {\n $protocol = (isset($_SERVER['HTTPS']) \u0026\u0026 $_SERVER['HTTPS'] === 'on') ? 'https' : 'http';\n if (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) \u0026\u0026 $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https') {\n $protocol = 'https';\n }\n define('WP_HOME', $protocol . '://' . $_SERVER['HTTP_HOST']);\n define('WP_SITEURL', $protocol . '://' . $_SERVER['HTTP_HOST']);\n}\n"}],"image":"wordpress:6-fpm-alpine","name":"wordpress","ports":[{"containerPort":9000,"name":"fastcgi"}],"volumeMounts":[{"mountPath":"/var/www/html","name":"wordpress-persistent-storage"}]},{"image":"nginx:alpine","name":"nginx","ports":[{"containerPort":80,"name":"http"}],"volumeMounts":[{"mountPath":"/var/www/html","name":"wordpress-persistent-storage","readOnly":true},{"mountPath":"/etc/nginx/nginx.conf","name":"nginx-config","subPath":"nginx.conf"}]}],"volumes":[{"name":"wordpress-persistent-storage","persistentVolumeClaim":{"claimName":"wordpress-pv-claim"}},{"configMap":{"name":"nginx-config"},"name":"nginx-config"}]}}}} + creationTimestamp: "2026-04-10T12:15:08Z" + generation: 1 + labels: + app: wordpress + managedFields: + - apiVersion: apps/v1 + fieldsType: FieldsV1 + fieldsV1: + f:metadata: + f:annotations: + .: {} + f:kubectl.kubernetes.io/last-applied-configuration: {} + f:labels: + .: {} + f:app: {} + f:spec: + f:progressDeadlineSeconds: {} + f:replicas: {} + f:revisionHistoryLimit: {} + f:selector: {} + f:strategy: + f:type: {} + f:template: + f:metadata: + f:labels: + .: {} + f:app: {} + f:tier: {} + f:spec: + f:containers: + k:{"name":"nginx"}: + .: {} + f:image: {} + f:imagePullPolicy: {} + f:name: {} + f:ports: + .: {} + k:{"containerPort":80,"protocol":"TCP"}: + .: {} + f:containerPort: {} + f:name: {} + f:protocol: {} + f:resources: {} + f:terminationMessagePath: {} + f:terminationMessagePolicy: {} + f:volumeMounts: + .: {} + k:{"mountPath":"/etc/nginx/nginx.conf"}: + .: {} + f:mountPath: {} + f:name: {} + f:subPath: {} + k:{"mountPath":"/var/www/html"}: + .: {} + f:mountPath: {} + f:name: {} + f:readOnly: {} + k:{"name":"wordpress"}: + .: {} + f:env: + .: {} + k:{"name":"WORDPRESS_CONFIG_EXTRA"}: + .: {} + f:name: {} + f:value: {} + k:{"name":"WORDPRESS_DB_HOST"}: + .: {} + f:name: {} + f:value: {} + k:{"name":"WORDPRESS_DB_PASSWORD"}: + .: {} + f:name: {} + f:valueFrom: + .: {} + f:secretKeyRef: {} + k:{"name":"WORDPRESS_DB_USER"}: + .: {} + f:name: {} + f:value: {} + f:image: {} + f:imagePullPolicy: {} + f:name: {} + f:ports: + .: {} + k:{"containerPort":9000,"protocol":"TCP"}: + .: {} + f:containerPort: {} + f:name: {} + f:protocol: {} + f:resources: {} + f:terminationMessagePath: {} + f:terminationMessagePolicy: {} + f:volumeMounts: + .: {} + k:{"mountPath":"/var/www/html"}: + .: {} + f:mountPath: {} + f:name: {} + f:dnsPolicy: {} + f:restartPolicy: {} + f:schedulerName: {} + f:securityContext: {} + f:terminationGracePeriodSeconds: {} + f:volumes: + .: {} + k:{"name":"nginx-config"}: + .: {} + f:configMap: + .: {} + f:defaultMode: {} + f:name: {} + f:name: {} + k:{"name":"wordpress-persistent-storage"}: + .: {} + f:name: {} + f:persistentVolumeClaim: + .: {} + f:claimName: {} + manager: kubectl-client-side-apply + operation: Update + time: "2026-04-10T12:15:08Z" + - apiVersion: apps/v1 + fieldsType: FieldsV1 + fieldsV1: + f:metadata: + f:annotations: + f:deployment.kubernetes.io/revision: {} + f:status: + f:availableReplicas: {} + f:conditions: + .: {} + k:{"type":"Available"}: + .: {} + f:lastTransitionTime: {} + f:lastUpdateTime: {} + f:message: {} + f:reason: {} + f:status: {} + f:type: {} + k:{"type":"Progressing"}: + .: {} + f:lastTransitionTime: {} + f:lastUpdateTime: {} + f:message: {} + f:reason: {} + f:status: {} + f:type: {} + f:observedGeneration: {} + f:readyReplicas: {} + f:replicas: {} + f:terminatingReplicas: {} + f:updatedReplicas: {} + manager: kube-controller-manager + operation: Update + subresource: status + time: "2026-04-10T12:16:04Z" + name: wordpress + namespace: default + resourceVersion: "812" + uid: 32f30549-f011-48b1-8398-64fef74b2df1 +spec: + progressDeadlineSeconds: 600 + replicas: 1 + revisionHistoryLimit: 10 + selector: + matchLabels: + app: wordpress + tier: frontend + strategy: + type: Recreate + template: + metadata: + labels: + app: wordpress + tier: frontend + spec: + containers: + - env: + - name: WORDPRESS_DB_HOST + value: wordpress-mysql + - name: WORDPRESS_DB_PASSWORD + valueFrom: + secretKeyRef: + key: MYSQL_WORDPRESS_PASSWORD + name: wordpress-secrets-hg692g82th + - name: WORDPRESS_DB_USER + value: wordpress + - name: WORDPRESS_CONFIG_EXTRA + value: | + // Set SITE URL dynamically from requests to allow reach it on different endpoints + if (isset($_SERVER['HTTP_HOST'])) { + $protocol = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on') ? 'https' : 'http'; + if (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https') { + $protocol = 'https'; + } + define('WP_HOME', $protocol . '://' . $_SERVER['HTTP_HOST']); + define('WP_SITEURL', $protocol . '://' . $_SERVER['HTTP_HOST']); + } + image: wordpress:6-fpm-alpine + imagePullPolicy: IfNotPresent + name: wordpress + ports: + - containerPort: 9000 + name: fastcgi + protocol: TCP + resources: {} + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + volumeMounts: + - mountPath: /var/www/html + name: wordpress-persistent-storage + - image: nginx:alpine + imagePullPolicy: IfNotPresent + name: nginx + ports: + - containerPort: 80 + name: http + protocol: TCP + resources: {} + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + volumeMounts: + - mountPath: /var/www/html + name: wordpress-persistent-storage + readOnly: true + - mountPath: /etc/nginx/nginx.conf + name: nginx-config + subPath: nginx.conf + dnsPolicy: ClusterFirst + restartPolicy: Always + schedulerName: default-scheduler + securityContext: {} + terminationGracePeriodSeconds: 30 + volumes: + - name: wordpress-persistent-storage + persistentVolumeClaim: + claimName: wordpress-pv-claim + - configMap: + defaultMode: 420 + name: nginx-config + name: nginx-config +status: + availableReplicas: 1 + conditions: + - lastTransitionTime: "2026-04-10T12:16:04Z" + lastUpdateTime: "2026-04-10T12:16:04Z" + message: Deployment has minimum availability. + reason: MinimumReplicasAvailable + status: "True" + type: Available + - lastTransitionTime: "2026-04-10T12:15:08Z" + lastUpdateTime: "2026-04-10T12:16:04Z" + message: ReplicaSet "wordpress-74b89cc84c" has successfully progressed. + reason: NewReplicaSetAvailable + status: "True" + type: Progressing + observedGeneration: 1 + readyReplicas: 1 + replicas: 1 + terminatingReplicas: 0 + updatedReplicas: 1 diff --git a/docs/transform-scenarios/wordpress-demo/export/resources/default/EndpointSlice_discovery.k8s.io_v1_default_kubernetes.yaml b/docs/transform-scenarios/wordpress-demo/export/resources/default/EndpointSlice_discovery.k8s.io_v1_default_kubernetes.yaml new file mode 100644 index 00000000..27aedea1 --- /dev/null +++ b/docs/transform-scenarios/wordpress-demo/export/resources/default/EndpointSlice_discovery.k8s.io_v1_default_kubernetes.yaml @@ -0,0 +1,35 @@ +addressType: IPv4 +apiVersion: discovery.k8s.io/v1 +endpoints: +- addresses: + - 192.168.61.192 + conditions: + ready: true +kind: EndpointSlice +metadata: + creationTimestamp: "2026-04-10T12:10:43Z" + generation: 1 + labels: + kubernetes.io/service-name: kubernetes + managedFields: + - apiVersion: discovery.k8s.io/v1 + fieldsType: FieldsV1 + fieldsV1: + f:addressType: {} + f:endpoints: {} + f:metadata: + f:labels: + .: {} + f:kubernetes.io/service-name: {} + f:ports: {} + manager: kube-apiserver + operation: Update + time: "2026-04-10T12:10:43Z" + name: kubernetes + namespace: default + resourceVersion: "207" + uid: c4e8cffe-1b65-44c3-ba96-fb9dc76493ed +ports: +- name: https + port: 8443 + protocol: TCP diff --git a/docs/transform-scenarios/wordpress-demo/export/resources/default/EndpointSlice_discovery.k8s.io_v1_default_wordpress-mysql-jlwnp.yaml b/docs/transform-scenarios/wordpress-demo/export/resources/default/EndpointSlice_discovery.k8s.io_v1_default_wordpress-mysql-jlwnp.yaml new file mode 100644 index 00000000..77b44207 --- /dev/null +++ b/docs/transform-scenarios/wordpress-demo/export/resources/default/EndpointSlice_discovery.k8s.io_v1_default_wordpress-mysql-jlwnp.yaml @@ -0,0 +1,64 @@ +addressType: IPv4 +apiVersion: discovery.k8s.io/v1 +endpoints: +- addresses: + - 10.244.0.6 + conditions: + ready: true + serving: true + terminating: false + nodeName: minikube + targetRef: + kind: Pod + name: wordpress-mysql-9474c86b-fr65w + namespace: default + uid: f81b40e3-ff85-46ca-8b0a-5c826b78f0c8 +kind: EndpointSlice +metadata: + annotations: + endpoints.kubernetes.io/last-change-trigger-time: "2026-04-10T12:15:58Z" + creationTimestamp: "2026-04-10T12:15:07Z" + generateName: wordpress-mysql- + generation: 2 + labels: + app: wordpress + endpointslice.kubernetes.io/managed-by: endpointslice-controller.k8s.io + kubernetes.io/service-name: wordpress-mysql + managedFields: + - apiVersion: discovery.k8s.io/v1 + fieldsType: FieldsV1 + fieldsV1: + f:addressType: {} + f:endpoints: {} + f:metadata: + f:annotations: + .: {} + f:endpoints.kubernetes.io/last-change-trigger-time: {} + f:generateName: {} + f:labels: + .: {} + f:app: {} + f:endpointslice.kubernetes.io/managed-by: {} + f:kubernetes.io/service-name: {} + f:ownerReferences: + .: {} + k:{"uid":"ec2555f1-9fd5-45da-bfa3-f2b59bb1d218"}: {} + f:ports: {} + manager: kube-controller-manager + operation: Update + time: "2026-04-10T12:15:58Z" + name: wordpress-mysql-jlwnp + namespace: default + ownerReferences: + - apiVersion: v1 + blockOwnerDeletion: true + controller: true + kind: Service + name: wordpress-mysql + uid: ec2555f1-9fd5-45da-bfa3-f2b59bb1d218 + resourceVersion: "796" + uid: d4c94c5d-1297-4184-91ae-24e6e0bb315b +ports: +- name: "" + port: 3306 + protocol: TCP diff --git a/docs/transform-scenarios/wordpress-demo/export/resources/default/EndpointSlice_discovery.k8s.io_v1_default_wordpress-wpfqk.yaml b/docs/transform-scenarios/wordpress-demo/export/resources/default/EndpointSlice_discovery.k8s.io_v1_default_wordpress-wpfqk.yaml new file mode 100644 index 00000000..e215d23b --- /dev/null +++ b/docs/transform-scenarios/wordpress-demo/export/resources/default/EndpointSlice_discovery.k8s.io_v1_default_wordpress-wpfqk.yaml @@ -0,0 +1,64 @@ +addressType: IPv4 +apiVersion: discovery.k8s.io/v1 +endpoints: +- addresses: + - 10.244.0.5 + conditions: + ready: true + serving: true + terminating: false + nodeName: minikube + targetRef: + kind: Pod + name: wordpress-74b89cc84c-nm9f8 + namespace: default + uid: 608501ac-fd76-48a1-b9ef-058b7a6ade67 +kind: EndpointSlice +metadata: + annotations: + endpoints.kubernetes.io/last-change-trigger-time: "2026-04-10T12:16:04Z" + creationTimestamp: "2026-04-10T12:15:07Z" + generateName: wordpress- + generation: 2 + labels: + app: wordpress + endpointslice.kubernetes.io/managed-by: endpointslice-controller.k8s.io + kubernetes.io/service-name: wordpress + managedFields: + - apiVersion: discovery.k8s.io/v1 + fieldsType: FieldsV1 + fieldsV1: + f:addressType: {} + f:endpoints: {} + f:metadata: + f:annotations: + .: {} + f:endpoints.kubernetes.io/last-change-trigger-time: {} + f:generateName: {} + f:labels: + .: {} + f:app: {} + f:endpointslice.kubernetes.io/managed-by: {} + f:kubernetes.io/service-name: {} + f:ownerReferences: + .: {} + k:{"uid":"9bd59883-6312-4534-a2c1-b71911612715"}: {} + f:ports: {} + manager: kube-controller-manager + operation: Update + time: "2026-04-10T12:16:04Z" + name: wordpress-wpfqk + namespace: default + ownerReferences: + - apiVersion: v1 + blockOwnerDeletion: true + controller: true + kind: Service + name: wordpress + uid: 9bd59883-6312-4534-a2c1-b71911612715 + resourceVersion: "810" + uid: 1a4fffdb-dbcd-4729-905b-11be74b19710 +ports: +- name: "" + port: 80 + protocol: TCP diff --git a/docs/transform-scenarios/wordpress-demo/export/resources/default/Endpoints__v1_default_kubernetes.yaml b/docs/transform-scenarios/wordpress-demo/export/resources/default/Endpoints__v1_default_kubernetes.yaml new file mode 100644 index 00000000..b6b5cbb0 --- /dev/null +++ b/docs/transform-scenarios/wordpress-demo/export/resources/default/Endpoints__v1_default_kubernetes.yaml @@ -0,0 +1,29 @@ +apiVersion: v1 +kind: Endpoints +metadata: + creationTimestamp: "2026-04-10T12:10:43Z" + labels: + endpointslice.kubernetes.io/skip-mirror: "true" + managedFields: + - apiVersion: v1 + fieldsType: FieldsV1 + fieldsV1: + f:metadata: + f:labels: + .: {} + f:endpointslice.kubernetes.io/skip-mirror: {} + f:subsets: {} + manager: kube-apiserver + operation: Update + time: "2026-04-10T12:10:43Z" + name: kubernetes + namespace: default + resourceVersion: "206" + uid: 39324cbc-0a0d-4795-8712-4106fdf1424c +subsets: +- addresses: + - ip: 192.168.61.192 + ports: + - name: https + port: 8443 + protocol: TCP diff --git a/docs/transform-scenarios/wordpress-demo/export/resources/default/Endpoints__v1_default_wordpress-mysql.yaml b/docs/transform-scenarios/wordpress-demo/export/resources/default/Endpoints__v1_default_wordpress-mysql.yaml new file mode 100644 index 00000000..3653d619 --- /dev/null +++ b/docs/transform-scenarios/wordpress-demo/export/resources/default/Endpoints__v1_default_wordpress-mysql.yaml @@ -0,0 +1,41 @@ +apiVersion: v1 +kind: Endpoints +metadata: + annotations: + endpoints.kubernetes.io/last-change-trigger-time: "2026-04-10T12:15:58Z" + creationTimestamp: "2026-04-10T12:15:07Z" + labels: + app: wordpress + endpoints.kubernetes.io/managed-by: endpoint-controller + managedFields: + - apiVersion: v1 + fieldsType: FieldsV1 + fieldsV1: + f:metadata: + f:annotations: + .: {} + f:endpoints.kubernetes.io/last-change-trigger-time: {} + f:labels: + .: {} + f:app: {} + f:endpoints.kubernetes.io/managed-by: {} + f:subsets: {} + manager: kube-controller-manager + operation: Update + time: "2026-04-10T12:15:58Z" + name: wordpress-mysql + namespace: default + resourceVersion: "797" + uid: c2cf2659-9d5c-4f2e-9e3f-6da1b9c6f2c0 +subsets: +- addresses: + - ip: 10.244.0.6 + nodeName: minikube + targetRef: + kind: Pod + name: wordpress-mysql-9474c86b-fr65w + namespace: default + uid: f81b40e3-ff85-46ca-8b0a-5c826b78f0c8 + ports: + - port: 3306 + protocol: TCP diff --git a/docs/transform-scenarios/wordpress-demo/export/resources/default/Endpoints__v1_default_wordpress.yaml b/docs/transform-scenarios/wordpress-demo/export/resources/default/Endpoints__v1_default_wordpress.yaml new file mode 100644 index 00000000..6ebd61ce --- /dev/null +++ b/docs/transform-scenarios/wordpress-demo/export/resources/default/Endpoints__v1_default_wordpress.yaml @@ -0,0 +1,41 @@ +apiVersion: v1 +kind: Endpoints +metadata: + annotations: + endpoints.kubernetes.io/last-change-trigger-time: "2026-04-10T12:16:04Z" + creationTimestamp: "2026-04-10T12:15:07Z" + labels: + app: wordpress + endpoints.kubernetes.io/managed-by: endpoint-controller + managedFields: + - apiVersion: v1 + fieldsType: FieldsV1 + fieldsV1: + f:metadata: + f:annotations: + .: {} + f:endpoints.kubernetes.io/last-change-trigger-time: {} + f:labels: + .: {} + f:app: {} + f:endpoints.kubernetes.io/managed-by: {} + f:subsets: {} + manager: kube-controller-manager + operation: Update + time: "2026-04-10T12:16:04Z" + name: wordpress + namespace: default + resourceVersion: "809" + uid: 7a7a7061-0064-42f9-ad24-f4dbbd13b8b4 +subsets: +- addresses: + - ip: 10.244.0.5 + nodeName: minikube + targetRef: + kind: Pod + name: wordpress-74b89cc84c-nm9f8 + namespace: default + uid: 608501ac-fd76-48a1-b9ef-058b7a6ade67 + ports: + - port: 80 + protocol: TCP diff --git a/docs/transform-scenarios/wordpress-demo/export/resources/default/Job_batch_v1_default_wordpress-install.yaml b/docs/transform-scenarios/wordpress-demo/export/resources/default/Job_batch_v1_default_wordpress-install.yaml new file mode 100644 index 00000000..0c6f48bf --- /dev/null +++ b/docs/transform-scenarios/wordpress-demo/export/resources/default/Job_batch_v1_default_wordpress-install.yaml @@ -0,0 +1,276 @@ +apiVersion: batch/v1 +kind: Job +metadata: + annotations: + kubectl.kubernetes.io/last-applied-configuration: | + {"apiVersion":"batch/v1","kind":"Job","metadata":{"annotations":{},"name":"wordpress-install","namespace":"default"},"spec":{"backoffLimit":4,"template":{"spec":{"containers":[{"args":["-lc","set -e\ncd /var/www/html\n\necho \"Waiting for MySQL on ${WORDPRESS_DB_HOST}:3306...\"\nfor i in $(seq 1 60); do\n if mariadb-admin ping -h\"${WORDPRESS_DB_HOST}\" -u\"${WORDPRESS_DB_USER}\" -p\"${WORDPRESS_DB_PASSWORD}\" --ssl=false --silent; then\n echo \"MySQL is up.\"\n break\n fi\n echo \"MySQL not ready yet (attempt: $i)...\"\n sleep 5\ndone\n\nif ! mariadb-admin ping -h\"${WORDPRESS_DB_HOST}\" -u\"${WORDPRESS_DB_USER}\" -p\"${WORDPRESS_DB_PASSWORD}\" --ssl=false --silent; then\n echo \"MySQL did not become ready within the timeout.\"\n exit 1\nfi\n\n# Make sure WordPress core is present on the volume\nif [ ! -f wp-load.php ]; then\n echo \"WordPress core not found on the volume. Downloading...\"\n wp core download --allow-root\nfi\n\n# Create wp-config.php if missing\nif [ ! -f wp-config.php ]; then\n echo \"Creating wp-config.php...\"\n wp config create \\\n --dbname=\"${WORDPRESS_DB_NAME}\" \\\n --dbuser=\"${WORDPRESS_DB_USER}\" \\\n --dbpass=\"${WORDPRESS_DB_PASSWORD}\" \\\n --dbhost=\"${WORDPRESS_DB_HOST}\" \\\n --allow-root\nfi\n\n# Idempotent install\nif wp core is-installed --allow-root \u003e/dev/null 2\u003e\u00261; then\n echo \"WordPress is already installed. Nothing to do.\"\n exit 0\nfi\n\n# Create an installation kind of unique ID\nWORDPRESS_SEED_ID=$RANDOM\n\necho \"Running wp core install...\"\nwp core install \\\n --url=\"${WORDPRESS_SITE_URL}\" \\\n --title=\"${WORDPRESS_SITE_TITLE} #$WORDPRESS_SEED_ID\" \\\n --admin_user=\"${WORDPRESS_ADMIN_USER}\" \\\n --admin_password=\"${WORDPRESS_ADMIN_PASSWORD}\" \\\n --admin_email=\"${WORDPRESS_ADMIN_EMAIL}\" \\\n --skip-email \\\n --allow-root\n\necho \"Creating sample post...\"\nwp post create \\\n --post_type=post \\\n --post_status=publish \\\n --post_title=\"Sample post #$WORDPRESS_SEED_ID\" \\\n --post_content=\"Hello from k8s, this is a random post content: $(openssl rand -base64 200 | tr -cs 'a-zA-Z' ' ' | xargs)\"\n\necho \"WORDPRESS_SEED_ID=$WORDPRESS_SEED_ID\"\necho \"Done. WordPress has been installed.\"\n"],"command":["bash"],"env":[{"name":"WORDPRESS_DB_HOST","value":"wordpress-mysql"},{"name":"WORDPRESS_DB_USER","value":"wordpress"},{"name":"WORDPRESS_DB_NAME","value":"wordpress"},{"name":"WORDPRESS_DB_PASSWORD","valueFrom":{"secretKeyRef":{"key":"MYSQL_WORDPRESS_PASSWORD","name":"wordpress-secrets-hg692g82th"}}},{"name":"WORDPRESS_SITE_URL","value":"http://wordpress-k8s.example.local"},{"name":"WORDPRESS_SITE_TITLE","value":"My WordPress Site on k8s"},{"name":"WORDPRESS_ADMIN_USER","value":"admin"},{"name":"WORDPRESS_ADMIN_PASSWORD","valueFrom":{"secretKeyRef":{"key":"WORDPRESS_ADMIN_PASSWORD","name":"wordpress-secrets-hg692g82th"}}},{"name":"WORDPRESS_ADMIN_EMAIL","value":"admin@wordpress-k8s.example.local"}],"image":"wordpress:cli-2","imagePullPolicy":"IfNotPresent","name":"wp-install","volumeMounts":[{"mountPath":"/var/www/html","name":"wordpress-persistent-storage"}]}],"restartPolicy":"OnFailure","volumes":[{"name":"wordpress-persistent-storage","persistentVolumeClaim":{"claimName":"wordpress-pv-claim"}}]}}}} + creationTimestamp: "2026-04-10T12:15:08Z" + generation: 1 + labels: + batch.kubernetes.io/controller-uid: be719474-856d-4d84-80ad-4f4ab9ecdd30 + batch.kubernetes.io/job-name: wordpress-install + controller-uid: be719474-856d-4d84-80ad-4f4ab9ecdd30 + job-name: wordpress-install + managedFields: + - apiVersion: batch/v1 + fieldsType: FieldsV1 + fieldsV1: + f:metadata: + f:annotations: + .: {} + f:kubectl.kubernetes.io/last-applied-configuration: {} + f:spec: + f:backoffLimit: {} + f:completionMode: {} + f:completions: {} + f:manualSelector: {} + f:parallelism: {} + f:podReplacementPolicy: {} + f:suspend: {} + f:template: + f:spec: + f:containers: + k:{"name":"wp-install"}: + .: {} + f:args: {} + f:command: {} + f:env: + .: {} + k:{"name":"WORDPRESS_ADMIN_EMAIL"}: + .: {} + f:name: {} + f:value: {} + k:{"name":"WORDPRESS_ADMIN_PASSWORD"}: + .: {} + f:name: {} + f:valueFrom: + .: {} + f:secretKeyRef: {} + k:{"name":"WORDPRESS_ADMIN_USER"}: + .: {} + f:name: {} + f:value: {} + k:{"name":"WORDPRESS_DB_HOST"}: + .: {} + f:name: {} + f:value: {} + k:{"name":"WORDPRESS_DB_NAME"}: + .: {} + f:name: {} + f:value: {} + k:{"name":"WORDPRESS_DB_PASSWORD"}: + .: {} + f:name: {} + f:valueFrom: + .: {} + f:secretKeyRef: {} + k:{"name":"WORDPRESS_DB_USER"}: + .: {} + f:name: {} + f:value: {} + k:{"name":"WORDPRESS_SITE_TITLE"}: + .: {} + f:name: {} + f:value: {} + k:{"name":"WORDPRESS_SITE_URL"}: + .: {} + f:name: {} + f:value: {} + f:image: {} + f:imagePullPolicy: {} + f:name: {} + f:resources: {} + f:terminationMessagePath: {} + f:terminationMessagePolicy: {} + f:volumeMounts: + .: {} + k:{"mountPath":"/var/www/html"}: + .: {} + f:mountPath: {} + f:name: {} + f:dnsPolicy: {} + f:restartPolicy: {} + f:schedulerName: {} + f:securityContext: {} + f:terminationGracePeriodSeconds: {} + f:volumes: + .: {} + k:{"name":"wordpress-persistent-storage"}: + .: {} + f:name: {} + f:persistentVolumeClaim: + .: {} + f:claimName: {} + manager: kubectl-client-side-apply + operation: Update + time: "2026-04-10T12:15:08Z" + - apiVersion: batch/v1 + fieldsType: FieldsV1 + fieldsV1: + f:status: + f:completionTime: {} + f:conditions: {} + f:ready: {} + f:startTime: {} + f:succeeded: {} + f:terminating: {} + f:uncountedTerminatedPods: {} + manager: kube-controller-manager + operation: Update + subresource: status + time: "2026-04-10T12:16:48Z" + name: wordpress-install + namespace: default + resourceVersion: "854" + uid: be719474-856d-4d84-80ad-4f4ab9ecdd30 +spec: + backoffLimit: 4 + completionMode: NonIndexed + completions: 1 + manualSelector: false + parallelism: 1 + podReplacementPolicy: TerminatingOrFailed + selector: + matchLabels: + batch.kubernetes.io/controller-uid: be719474-856d-4d84-80ad-4f4ab9ecdd30 + suspend: false + template: + metadata: + labels: + batch.kubernetes.io/controller-uid: be719474-856d-4d84-80ad-4f4ab9ecdd30 + batch.kubernetes.io/job-name: wordpress-install + controller-uid: be719474-856d-4d84-80ad-4f4ab9ecdd30 + job-name: wordpress-install + spec: + containers: + - args: + - -lc + - | + set -e + cd /var/www/html + + echo "Waiting for MySQL on ${WORDPRESS_DB_HOST}:3306..." + for i in $(seq 1 60); do + if mariadb-admin ping -h"${WORDPRESS_DB_HOST}" -u"${WORDPRESS_DB_USER}" -p"${WORDPRESS_DB_PASSWORD}" --ssl=false --silent; then + echo "MySQL is up." + break + fi + echo "MySQL not ready yet (attempt: $i)..." + sleep 5 + done + + if ! mariadb-admin ping -h"${WORDPRESS_DB_HOST}" -u"${WORDPRESS_DB_USER}" -p"${WORDPRESS_DB_PASSWORD}" --ssl=false --silent; then + echo "MySQL did not become ready within the timeout." + exit 1 + fi + + # Make sure WordPress core is present on the volume + if [ ! -f wp-load.php ]; then + echo "WordPress core not found on the volume. Downloading..." + wp core download --allow-root + fi + + # Create wp-config.php if missing + if [ ! -f wp-config.php ]; then + echo "Creating wp-config.php..." + wp config create \ + --dbname="${WORDPRESS_DB_NAME}" \ + --dbuser="${WORDPRESS_DB_USER}" \ + --dbpass="${WORDPRESS_DB_PASSWORD}" \ + --dbhost="${WORDPRESS_DB_HOST}" \ + --allow-root + fi + + # Idempotent install + if wp core is-installed --allow-root >/dev/null 2>&1; then + echo "WordPress is already installed. Nothing to do." + exit 0 + fi + + # Create an installation kind of unique ID + WORDPRESS_SEED_ID=$RANDOM + + echo "Running wp core install..." + wp core install \ + --url="${WORDPRESS_SITE_URL}" \ + --title="${WORDPRESS_SITE_TITLE} #$WORDPRESS_SEED_ID" \ + --admin_user="${WORDPRESS_ADMIN_USER}" \ + --admin_password="${WORDPRESS_ADMIN_PASSWORD}" \ + --admin_email="${WORDPRESS_ADMIN_EMAIL}" \ + --skip-email \ + --allow-root + + echo "Creating sample post..." + wp post create \ + --post_type=post \ + --post_status=publish \ + --post_title="Sample post #$WORDPRESS_SEED_ID" \ + --post_content="Hello from k8s, this is a random post content: $(openssl rand -base64 200 | tr -cs 'a-zA-Z' ' ' | xargs)" + + echo "WORDPRESS_SEED_ID=$WORDPRESS_SEED_ID" + echo "Done. WordPress has been installed." + command: + - bash + env: + - name: WORDPRESS_DB_HOST + value: wordpress-mysql + - name: WORDPRESS_DB_USER + value: wordpress + - name: WORDPRESS_DB_NAME + value: wordpress + - name: WORDPRESS_DB_PASSWORD + valueFrom: + secretKeyRef: + key: MYSQL_WORDPRESS_PASSWORD + name: wordpress-secrets-hg692g82th + - name: WORDPRESS_SITE_URL + value: http://wordpress-k8s.example.local + - name: WORDPRESS_SITE_TITLE + value: My WordPress Site on k8s + - name: WORDPRESS_ADMIN_USER + value: admin + - name: WORDPRESS_ADMIN_PASSWORD + valueFrom: + secretKeyRef: + key: WORDPRESS_ADMIN_PASSWORD + name: wordpress-secrets-hg692g82th + - name: WORDPRESS_ADMIN_EMAIL + value: admin@wordpress-k8s.example.local + image: wordpress:cli-2 + imagePullPolicy: IfNotPresent + name: wp-install + resources: {} + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + volumeMounts: + - mountPath: /var/www/html + name: wordpress-persistent-storage + dnsPolicy: ClusterFirst + restartPolicy: OnFailure + schedulerName: default-scheduler + securityContext: {} + terminationGracePeriodSeconds: 30 + volumes: + - name: wordpress-persistent-storage + persistentVolumeClaim: + claimName: wordpress-pv-claim +status: + completionTime: "2026-04-10T12:16:48Z" + conditions: + - lastProbeTime: "2026-04-10T12:16:48Z" + lastTransitionTime: "2026-04-10T12:16:48Z" + message: Reached expected number of succeeded pods + reason: CompletionsReached + status: "True" + type: SuccessCriteriaMet + - lastProbeTime: "2026-04-10T12:16:48Z" + lastTransitionTime: "2026-04-10T12:16:48Z" + message: Reached expected number of succeeded pods + reason: CompletionsReached + status: "True" + type: Complete + ready: 0 + startTime: "2026-04-10T12:15:08Z" + succeeded: 1 + terminating: 0 + uncountedTerminatedPods: {} diff --git a/docs/transform-scenarios/wordpress-demo/export/resources/default/PersistentVolumeClaim__v1_default_mysql-pv-claim.yaml b/docs/transform-scenarios/wordpress-demo/export/resources/default/PersistentVolumeClaim__v1_default_mysql-pv-claim.yaml new file mode 100644 index 00000000..5756b493 --- /dev/null +++ b/docs/transform-scenarios/wordpress-demo/export/resources/default/PersistentVolumeClaim__v1_default_mysql-pv-claim.yaml @@ -0,0 +1,82 @@ +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + annotations: + kubectl.kubernetes.io/last-applied-configuration: | + {"apiVersion":"v1","kind":"PersistentVolumeClaim","metadata":{"annotations":{},"labels":{"app":"wordpress"},"name":"mysql-pv-claim","namespace":"default"},"spec":{"accessModes":["ReadWriteOnce"],"resources":{"requests":{"storage":"1Gi"}}}} + pv.kubernetes.io/bind-completed: "yes" + pv.kubernetes.io/bound-by-controller: "yes" + volume.beta.kubernetes.io/storage-provisioner: k8s.io/minikube-hostpath + volume.kubernetes.io/storage-provisioner: k8s.io/minikube-hostpath + creationTimestamp: "2026-04-10T12:15:07Z" + finalizers: + - kubernetes.io/pvc-protection + labels: + app: wordpress + managedFields: + - apiVersion: v1 + fieldsType: FieldsV1 + fieldsV1: + f:metadata: + f:annotations: + .: {} + f:kubectl.kubernetes.io/last-applied-configuration: {} + f:labels: + .: {} + f:app: {} + f:spec: + f:accessModes: {} + f:resources: + f:requests: + .: {} + f:storage: {} + f:volumeMode: {} + manager: kubectl-client-side-apply + operation: Update + time: "2026-04-10T12:15:07Z" + - apiVersion: v1 + fieldsType: FieldsV1 + fieldsV1: + f:metadata: + f:annotations: + f:pv.kubernetes.io/bind-completed: {} + f:pv.kubernetes.io/bound-by-controller: {} + f:volume.beta.kubernetes.io/storage-provisioner: {} + f:volume.kubernetes.io/storage-provisioner: {} + f:spec: + f:volumeName: {} + manager: kube-controller-manager + operation: Update + time: "2026-04-10T12:15:08Z" + - apiVersion: v1 + fieldsType: FieldsV1 + fieldsV1: + f:status: + f:accessModes: {} + f:capacity: + .: {} + f:storage: {} + f:phase: {} + manager: kube-controller-manager + operation: Update + subresource: status + time: "2026-04-10T12:15:08Z" + name: mysql-pv-claim + namespace: default + resourceVersion: "710" + uid: 58e67d84-b797-4121-a5df-f3beea559f74 +spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 1Gi + storageClassName: standard + volumeMode: Filesystem + volumeName: pvc-58e67d84-b797-4121-a5df-f3beea559f74 +status: + accessModes: + - ReadWriteOnce + capacity: + storage: 1Gi + phase: Bound diff --git a/docs/transform-scenarios/wordpress-demo/export/resources/default/PersistentVolumeClaim__v1_default_wordpress-pv-claim.yaml b/docs/transform-scenarios/wordpress-demo/export/resources/default/PersistentVolumeClaim__v1_default_wordpress-pv-claim.yaml new file mode 100644 index 00000000..399fd4cf --- /dev/null +++ b/docs/transform-scenarios/wordpress-demo/export/resources/default/PersistentVolumeClaim__v1_default_wordpress-pv-claim.yaml @@ -0,0 +1,82 @@ +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + annotations: + kubectl.kubernetes.io/last-applied-configuration: | + {"apiVersion":"v1","kind":"PersistentVolumeClaim","metadata":{"annotations":{},"labels":{"app":"wordpress"},"name":"wordpress-pv-claim","namespace":"default"},"spec":{"accessModes":["ReadWriteOnce"],"resources":{"requests":{"storage":"1Gi"}}}} + pv.kubernetes.io/bind-completed: "yes" + pv.kubernetes.io/bound-by-controller: "yes" + volume.beta.kubernetes.io/storage-provisioner: k8s.io/minikube-hostpath + volume.kubernetes.io/storage-provisioner: k8s.io/minikube-hostpath + creationTimestamp: "2026-04-10T12:15:08Z" + finalizers: + - kubernetes.io/pvc-protection + labels: + app: wordpress + managedFields: + - apiVersion: v1 + fieldsType: FieldsV1 + fieldsV1: + f:metadata: + f:annotations: + f:pv.kubernetes.io/bind-completed: {} + f:pv.kubernetes.io/bound-by-controller: {} + f:volume.beta.kubernetes.io/storage-provisioner: {} + f:volume.kubernetes.io/storage-provisioner: {} + f:spec: + f:volumeName: {} + manager: kube-controller-manager + operation: Update + time: "2026-04-10T12:15:08Z" + - apiVersion: v1 + fieldsType: FieldsV1 + fieldsV1: + f:status: + f:accessModes: {} + f:capacity: + .: {} + f:storage: {} + f:phase: {} + manager: kube-controller-manager + operation: Update + subresource: status + time: "2026-04-10T12:15:08Z" + - apiVersion: v1 + fieldsType: FieldsV1 + fieldsV1: + f:metadata: + f:annotations: + .: {} + f:kubectl.kubernetes.io/last-applied-configuration: {} + f:labels: + .: {} + f:app: {} + f:spec: + f:accessModes: {} + f:resources: + f:requests: + .: {} + f:storage: {} + f:volumeMode: {} + manager: kubectl-client-side-apply + operation: Update + time: "2026-04-10T12:15:08Z" + name: wordpress-pv-claim + namespace: default + resourceVersion: "729" + uid: a08d0754-6782-497d-927d-7fdac1a968fe +spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 1Gi + storageClassName: standard + volumeMode: Filesystem + volumeName: pvc-a08d0754-6782-497d-927d-7fdac1a968fe +status: + accessModes: + - ReadWriteOnce + capacity: + storage: 1Gi + phase: Bound diff --git a/docs/transform-scenarios/wordpress-demo/export/resources/default/Pod__v1_default_wordpress-74b89cc84c-nm9f8.yaml b/docs/transform-scenarios/wordpress-demo/export/resources/default/Pod__v1_default_wordpress-74b89cc84c-nm9f8.yaml new file mode 100644 index 00000000..914d966d --- /dev/null +++ b/docs/transform-scenarios/wordpress-demo/export/resources/default/Pod__v1_default_wordpress-74b89cc84c-nm9f8.yaml @@ -0,0 +1,383 @@ +apiVersion: v1 +kind: Pod +metadata: + creationTimestamp: "2026-04-10T12:15:08Z" + generateName: wordpress-74b89cc84c- + generation: 1 + labels: + app: wordpress + pod-template-hash: 74b89cc84c + tier: frontend + managedFields: + - apiVersion: v1 + fieldsType: FieldsV1 + fieldsV1: + f:metadata: + f:generateName: {} + f:labels: + .: {} + f:app: {} + f:pod-template-hash: {} + f:tier: {} + f:ownerReferences: + .: {} + k:{"uid":"7ed37255-e5ff-4e33-837d-f584a536d2b8"}: {} + f:spec: + f:containers: + k:{"name":"nginx"}: + .: {} + f:image: {} + f:imagePullPolicy: {} + f:name: {} + f:ports: + .: {} + k:{"containerPort":80,"protocol":"TCP"}: + .: {} + f:containerPort: {} + f:name: {} + f:protocol: {} + f:resources: {} + f:terminationMessagePath: {} + f:terminationMessagePolicy: {} + f:volumeMounts: + .: {} + k:{"mountPath":"/etc/nginx/nginx.conf"}: + .: {} + f:mountPath: {} + f:name: {} + f:subPath: {} + k:{"mountPath":"/var/www/html"}: + .: {} + f:mountPath: {} + f:name: {} + f:readOnly: {} + k:{"name":"wordpress"}: + .: {} + f:env: + .: {} + k:{"name":"WORDPRESS_CONFIG_EXTRA"}: + .: {} + f:name: {} + f:value: {} + k:{"name":"WORDPRESS_DB_HOST"}: + .: {} + f:name: {} + f:value: {} + k:{"name":"WORDPRESS_DB_PASSWORD"}: + .: {} + f:name: {} + f:valueFrom: + .: {} + f:secretKeyRef: {} + k:{"name":"WORDPRESS_DB_USER"}: + .: {} + f:name: {} + f:value: {} + f:image: {} + f:imagePullPolicy: {} + f:name: {} + f:ports: + .: {} + k:{"containerPort":9000,"protocol":"TCP"}: + .: {} + f:containerPort: {} + f:name: {} + f:protocol: {} + f:resources: {} + f:terminationMessagePath: {} + f:terminationMessagePolicy: {} + f:volumeMounts: + .: {} + k:{"mountPath":"/var/www/html"}: + .: {} + f:mountPath: {} + f:name: {} + f:dnsPolicy: {} + f:enableServiceLinks: {} + f:restartPolicy: {} + f:schedulerName: {} + f:securityContext: {} + f:terminationGracePeriodSeconds: {} + f:volumes: + .: {} + k:{"name":"nginx-config"}: + .: {} + f:configMap: + .: {} + f:defaultMode: {} + f:name: {} + f:name: {} + k:{"name":"wordpress-persistent-storage"}: + .: {} + f:name: {} + f:persistentVolumeClaim: + .: {} + f:claimName: {} + manager: kube-controller-manager + operation: Update + time: "2026-04-10T12:15:08Z" + - apiVersion: v1 + fieldsType: FieldsV1 + fieldsV1: + f:status: + f:conditions: + .: {} + k:{"type":"PodScheduled"}: + .: {} + f:lastProbeTime: {} + f:lastTransitionTime: {} + f:message: {} + f:reason: {} + f:status: {} + f:type: {} + manager: kube-scheduler + operation: Update + subresource: status + time: "2026-04-10T12:15:08Z" + - apiVersion: v1 + fieldsType: FieldsV1 + fieldsV1: + f:status: + f:conditions: + k:{"type":"ContainersReady"}: + .: {} + f:lastProbeTime: {} + f:lastTransitionTime: {} + f:observedGeneration: {} + f:status: {} + f:type: {} + k:{"type":"Initialized"}: + .: {} + f:lastProbeTime: {} + f:lastTransitionTime: {} + f:observedGeneration: {} + f:status: {} + f:type: {} + k:{"type":"PodReadyToStartContainers"}: + .: {} + f:lastProbeTime: {} + f:lastTransitionTime: {} + f:observedGeneration: {} + f:status: {} + f:type: {} + k:{"type":"PodScheduled"}: + f:observedGeneration: {} + k:{"type":"Ready"}: + .: {} + f:lastProbeTime: {} + f:lastTransitionTime: {} + f:observedGeneration: {} + f:status: {} + f:type: {} + f:containerStatuses: {} + f:hostIP: {} + f:hostIPs: {} + f:observedGeneration: {} + f:phase: {} + f:podIP: {} + f:podIPs: + .: {} + k:{"ip":"10.244.0.5"}: + .: {} + f:ip: {} + f:startTime: {} + manager: kubelet + operation: Update + subresource: status + time: "2026-04-10T12:16:04Z" + name: wordpress-74b89cc84c-nm9f8 + namespace: default + ownerReferences: + - apiVersion: apps/v1 + blockOwnerDeletion: true + controller: true + kind: ReplicaSet + name: wordpress-74b89cc84c + uid: 7ed37255-e5ff-4e33-837d-f584a536d2b8 + resourceVersion: "808" + uid: 608501ac-fd76-48a1-b9ef-058b7a6ade67 +spec: + containers: + - env: + - name: WORDPRESS_DB_HOST + value: wordpress-mysql + - name: WORDPRESS_DB_PASSWORD + valueFrom: + secretKeyRef: + key: MYSQL_WORDPRESS_PASSWORD + name: wordpress-secrets-hg692g82th + - name: WORDPRESS_DB_USER + value: wordpress + - name: WORDPRESS_CONFIG_EXTRA + value: | + // Set SITE URL dynamically from requests to allow reach it on different endpoints + if (isset($_SERVER['HTTP_HOST'])) { + $protocol = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on') ? 'https' : 'http'; + if (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https') { + $protocol = 'https'; + } + define('WP_HOME', $protocol . '://' . $_SERVER['HTTP_HOST']); + define('WP_SITEURL', $protocol . '://' . $_SERVER['HTTP_HOST']); + } + image: wordpress:6-fpm-alpine + imagePullPolicy: IfNotPresent + name: wordpress + ports: + - containerPort: 9000 + name: fastcgi + protocol: TCP + resources: {} + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + volumeMounts: + - mountPath: /var/www/html + name: wordpress-persistent-storage + - mountPath: /var/run/secrets/kubernetes.io/serviceaccount + name: kube-api-access-gksj7 + readOnly: true + - image: nginx:alpine + imagePullPolicy: IfNotPresent + name: nginx + ports: + - containerPort: 80 + name: http + protocol: TCP + resources: {} + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + volumeMounts: + - mountPath: /var/www/html + name: wordpress-persistent-storage + readOnly: true + - mountPath: /etc/nginx/nginx.conf + name: nginx-config + subPath: nginx.conf + - mountPath: /var/run/secrets/kubernetes.io/serviceaccount + name: kube-api-access-gksj7 + readOnly: true + dnsPolicy: ClusterFirst + enableServiceLinks: true + nodeName: minikube + preemptionPolicy: PreemptLowerPriority + priority: 0 + restartPolicy: Always + schedulerName: default-scheduler + securityContext: {} + serviceAccount: default + serviceAccountName: default + terminationGracePeriodSeconds: 30 + tolerations: + - effect: NoExecute + key: node.kubernetes.io/not-ready + operator: Exists + tolerationSeconds: 300 + - effect: NoExecute + key: node.kubernetes.io/unreachable + operator: Exists + tolerationSeconds: 300 + volumes: + - name: wordpress-persistent-storage + persistentVolumeClaim: + claimName: wordpress-pv-claim + - configMap: + defaultMode: 420 + name: nginx-config + name: nginx-config + - name: kube-api-access-gksj7 + projected: + defaultMode: 420 + sources: + - serviceAccountToken: + expirationSeconds: 3607 + path: token + - configMap: + items: + - key: ca.crt + path: ca.crt + name: kube-root-ca.crt + - downwardAPI: + items: + - fieldRef: + apiVersion: v1 + fieldPath: metadata.namespace + path: namespace +status: + conditions: + - lastProbeTime: null + lastTransitionTime: "2026-04-10T12:16:04Z" + observedGeneration: 1 + status: "True" + type: PodReadyToStartContainers + - lastProbeTime: null + lastTransitionTime: "2026-04-10T12:15:08Z" + observedGeneration: 1 + status: "True" + type: Initialized + - lastProbeTime: null + lastTransitionTime: "2026-04-10T12:16:04Z" + observedGeneration: 1 + status: "True" + type: Ready + - lastProbeTime: null + lastTransitionTime: "2026-04-10T12:16:04Z" + observedGeneration: 1 + status: "True" + type: ContainersReady + - lastProbeTime: null + lastTransitionTime: "2026-04-10T12:15:08Z" + observedGeneration: 1 + status: "True" + type: PodScheduled + containerStatuses: + - containerID: docker://9deeeda1697dc879391836b269f936362a2e1a77d5beb289889639e352d9ee13 + image: nginx:alpine + imageID: docker-pullable://nginx@sha256:582c496ccf79d8aa6f8203a79d32aaf7ffd8b13362c60a701a2f9ac64886c93d + lastState: {} + name: nginx + ready: true + resources: {} + restartCount: 0 + started: true + state: + running: + startedAt: "2026-04-10T12:16:04Z" + volumeMounts: + - mountPath: /var/www/html + name: wordpress-persistent-storage + readOnly: true + recursiveReadOnly: Disabled + - mountPath: /etc/nginx/nginx.conf + name: nginx-config + - mountPath: /var/run/secrets/kubernetes.io/serviceaccount + name: kube-api-access-gksj7 + readOnly: true + recursiveReadOnly: Disabled + - containerID: docker://dd83b5ffcde3a21dcfc1f3fedfeefcc0a7e8e7f63b31817029d370b0ddde48f4 + image: wordpress:6-fpm-alpine + imageID: docker-pullable://wordpress@sha256:658bc068c60dcd43f2e2deee4b8495ca5e37ef09481d790ad05f99e6a15f61aa + lastState: {} + name: wordpress + ready: true + resources: {} + restartCount: 0 + started: true + state: + running: + startedAt: "2026-04-10T12:15:33Z" + volumeMounts: + - mountPath: /var/www/html + name: wordpress-persistent-storage + - mountPath: /var/run/secrets/kubernetes.io/serviceaccount + name: kube-api-access-gksj7 + readOnly: true + recursiveReadOnly: Disabled + hostIP: 192.168.61.192 + hostIPs: + - ip: 192.168.61.192 + observedGeneration: 1 + phase: Running + podIP: 10.244.0.5 + podIPs: + - ip: 10.244.0.5 + qosClass: BestEffort + startTime: "2026-04-10T12:15:08Z" diff --git a/docs/transform-scenarios/wordpress-demo/export/resources/default/Pod__v1_default_wordpress-install-xrqtc.yaml b/docs/transform-scenarios/wordpress-demo/export/resources/default/Pod__v1_default_wordpress-install-xrqtc.yaml new file mode 100644 index 00000000..12399817 --- /dev/null +++ b/docs/transform-scenarios/wordpress-demo/export/resources/default/Pod__v1_default_wordpress-install-xrqtc.yaml @@ -0,0 +1,381 @@ +apiVersion: v1 +kind: Pod +metadata: + creationTimestamp: "2026-04-10T12:15:08Z" + generateName: wordpress-install- + generation: 1 + labels: + batch.kubernetes.io/controller-uid: be719474-856d-4d84-80ad-4f4ab9ecdd30 + batch.kubernetes.io/job-name: wordpress-install + controller-uid: be719474-856d-4d84-80ad-4f4ab9ecdd30 + job-name: wordpress-install + managedFields: + - apiVersion: v1 + fieldsType: FieldsV1 + fieldsV1: + f:metadata: + f:generateName: {} + f:labels: + .: {} + f:batch.kubernetes.io/controller-uid: {} + f:batch.kubernetes.io/job-name: {} + f:controller-uid: {} + f:job-name: {} + f:ownerReferences: + .: {} + k:{"uid":"be719474-856d-4d84-80ad-4f4ab9ecdd30"}: {} + f:spec: + f:containers: + k:{"name":"wp-install"}: + .: {} + f:args: {} + f:command: {} + f:env: + .: {} + k:{"name":"WORDPRESS_ADMIN_EMAIL"}: + .: {} + f:name: {} + f:value: {} + k:{"name":"WORDPRESS_ADMIN_PASSWORD"}: + .: {} + f:name: {} + f:valueFrom: + .: {} + f:secretKeyRef: {} + k:{"name":"WORDPRESS_ADMIN_USER"}: + .: {} + f:name: {} + f:value: {} + k:{"name":"WORDPRESS_DB_HOST"}: + .: {} + f:name: {} + f:value: {} + k:{"name":"WORDPRESS_DB_NAME"}: + .: {} + f:name: {} + f:value: {} + k:{"name":"WORDPRESS_DB_PASSWORD"}: + .: {} + f:name: {} + f:valueFrom: + .: {} + f:secretKeyRef: {} + k:{"name":"WORDPRESS_DB_USER"}: + .: {} + f:name: {} + f:value: {} + k:{"name":"WORDPRESS_SITE_TITLE"}: + .: {} + f:name: {} + f:value: {} + k:{"name":"WORDPRESS_SITE_URL"}: + .: {} + f:name: {} + f:value: {} + f:image: {} + f:imagePullPolicy: {} + f:name: {} + f:resources: {} + f:terminationMessagePath: {} + f:terminationMessagePolicy: {} + f:volumeMounts: + .: {} + k:{"mountPath":"/var/www/html"}: + .: {} + f:mountPath: {} + f:name: {} + f:dnsPolicy: {} + f:enableServiceLinks: {} + f:restartPolicy: {} + f:schedulerName: {} + f:securityContext: {} + f:terminationGracePeriodSeconds: {} + f:volumes: + .: {} + k:{"name":"wordpress-persistent-storage"}: + .: {} + f:name: {} + f:persistentVolumeClaim: + .: {} + f:claimName: {} + manager: kube-controller-manager + operation: Update + time: "2026-04-10T12:15:08Z" + - apiVersion: v1 + fieldsType: FieldsV1 + fieldsV1: + f:status: + f:conditions: + k:{"type":"ContainersReady"}: + .: {} + f:lastProbeTime: {} + f:lastTransitionTime: {} + f:observedGeneration: {} + f:reason: {} + f:status: {} + f:type: {} + k:{"type":"Initialized"}: + .: {} + f:lastProbeTime: {} + f:lastTransitionTime: {} + f:observedGeneration: {} + f:reason: {} + f:status: {} + f:type: {} + k:{"type":"PodReadyToStartContainers"}: + .: {} + f:lastProbeTime: {} + f:lastTransitionTime: {} + f:observedGeneration: {} + f:status: {} + f:type: {} + k:{"type":"PodScheduled"}: + f:observedGeneration: {} + k:{"type":"Ready"}: + .: {} + f:lastProbeTime: {} + f:lastTransitionTime: {} + f:observedGeneration: {} + f:reason: {} + f:status: {} + f:type: {} + f:containerStatuses: {} + f:hostIP: {} + f:hostIPs: {} + f:observedGeneration: {} + f:phase: {} + f:podIP: {} + f:podIPs: + .: {} + k:{"ip":"10.244.0.4"}: + .: {} + f:ip: {} + f:startTime: {} + manager: kubelet + operation: Update + subresource: status + time: "2026-04-10T12:16:48Z" + name: wordpress-install-xrqtc + namespace: default + ownerReferences: + - apiVersion: batch/v1 + blockOwnerDeletion: true + controller: true + kind: Job + name: wordpress-install + uid: be719474-856d-4d84-80ad-4f4ab9ecdd30 + resourceVersion: "853" + uid: 7d3fa4a3-d0a9-438b-b477-e45103965e04 +spec: + containers: + - args: + - -lc + - | + set -e + cd /var/www/html + + echo "Waiting for MySQL on ${WORDPRESS_DB_HOST}:3306..." + for i in $(seq 1 60); do + if mariadb-admin ping -h"${WORDPRESS_DB_HOST}" -u"${WORDPRESS_DB_USER}" -p"${WORDPRESS_DB_PASSWORD}" --ssl=false --silent; then + echo "MySQL is up." + break + fi + echo "MySQL not ready yet (attempt: $i)..." + sleep 5 + done + + if ! mariadb-admin ping -h"${WORDPRESS_DB_HOST}" -u"${WORDPRESS_DB_USER}" -p"${WORDPRESS_DB_PASSWORD}" --ssl=false --silent; then + echo "MySQL did not become ready within the timeout." + exit 1 + fi + + # Make sure WordPress core is present on the volume + if [ ! -f wp-load.php ]; then + echo "WordPress core not found on the volume. Downloading..." + wp core download --allow-root + fi + + # Create wp-config.php if missing + if [ ! -f wp-config.php ]; then + echo "Creating wp-config.php..." + wp config create \ + --dbname="${WORDPRESS_DB_NAME}" \ + --dbuser="${WORDPRESS_DB_USER}" \ + --dbpass="${WORDPRESS_DB_PASSWORD}" \ + --dbhost="${WORDPRESS_DB_HOST}" \ + --allow-root + fi + + # Idempotent install + if wp core is-installed --allow-root >/dev/null 2>&1; then + echo "WordPress is already installed. Nothing to do." + exit 0 + fi + + # Create an installation kind of unique ID + WORDPRESS_SEED_ID=$RANDOM + + echo "Running wp core install..." + wp core install \ + --url="${WORDPRESS_SITE_URL}" \ + --title="${WORDPRESS_SITE_TITLE} #$WORDPRESS_SEED_ID" \ + --admin_user="${WORDPRESS_ADMIN_USER}" \ + --admin_password="${WORDPRESS_ADMIN_PASSWORD}" \ + --admin_email="${WORDPRESS_ADMIN_EMAIL}" \ + --skip-email \ + --allow-root + + echo "Creating sample post..." + wp post create \ + --post_type=post \ + --post_status=publish \ + --post_title="Sample post #$WORDPRESS_SEED_ID" \ + --post_content="Hello from k8s, this is a random post content: $(openssl rand -base64 200 | tr -cs 'a-zA-Z' ' ' | xargs)" + + echo "WORDPRESS_SEED_ID=$WORDPRESS_SEED_ID" + echo "Done. WordPress has been installed." + command: + - bash + env: + - name: WORDPRESS_DB_HOST + value: wordpress-mysql + - name: WORDPRESS_DB_USER + value: wordpress + - name: WORDPRESS_DB_NAME + value: wordpress + - name: WORDPRESS_DB_PASSWORD + valueFrom: + secretKeyRef: + key: MYSQL_WORDPRESS_PASSWORD + name: wordpress-secrets-hg692g82th + - name: WORDPRESS_SITE_URL + value: http://wordpress-k8s.example.local + - name: WORDPRESS_SITE_TITLE + value: My WordPress Site on k8s + - name: WORDPRESS_ADMIN_USER + value: admin + - name: WORDPRESS_ADMIN_PASSWORD + valueFrom: + secretKeyRef: + key: WORDPRESS_ADMIN_PASSWORD + name: wordpress-secrets-hg692g82th + - name: WORDPRESS_ADMIN_EMAIL + value: admin@wordpress-k8s.example.local + image: wordpress:cli-2 + imagePullPolicy: IfNotPresent + name: wp-install + resources: {} + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + volumeMounts: + - mountPath: /var/www/html + name: wordpress-persistent-storage + - mountPath: /var/run/secrets/kubernetes.io/serviceaccount + name: kube-api-access-29z94 + readOnly: true + dnsPolicy: ClusterFirst + enableServiceLinks: true + nodeName: minikube + preemptionPolicy: PreemptLowerPriority + priority: 0 + restartPolicy: OnFailure + schedulerName: default-scheduler + securityContext: {} + serviceAccount: default + serviceAccountName: default + terminationGracePeriodSeconds: 30 + tolerations: + - effect: NoExecute + key: node.kubernetes.io/not-ready + operator: Exists + tolerationSeconds: 300 + - effect: NoExecute + key: node.kubernetes.io/unreachable + operator: Exists + tolerationSeconds: 300 + volumes: + - name: wordpress-persistent-storage + persistentVolumeClaim: + claimName: wordpress-pv-claim + - name: kube-api-access-29z94 + projected: + defaultMode: 420 + sources: + - serviceAccountToken: + expirationSeconds: 3607 + path: token + - configMap: + items: + - key: ca.crt + path: ca.crt + name: kube-root-ca.crt + - downwardAPI: + items: + - fieldRef: + apiVersion: v1 + fieldPath: metadata.namespace + path: namespace +status: + conditions: + - lastProbeTime: null + lastTransitionTime: "2026-04-10T12:16:48Z" + observedGeneration: 1 + status: "False" + type: PodReadyToStartContainers + - lastProbeTime: null + lastTransitionTime: "2026-04-10T12:15:08Z" + observedGeneration: 1 + reason: PodCompleted + status: "True" + type: Initialized + - lastProbeTime: null + lastTransitionTime: "2026-04-10T12:16:46Z" + observedGeneration: 1 + reason: PodCompleted + status: "False" + type: Ready + - lastProbeTime: null + lastTransitionTime: "2026-04-10T12:16:46Z" + observedGeneration: 1 + reason: PodCompleted + status: "False" + type: ContainersReady + - lastProbeTime: null + lastTransitionTime: "2026-04-10T12:15:08Z" + observedGeneration: 1 + status: "True" + type: PodScheduled + containerStatuses: + - containerID: docker://b1d36c9760604c47741156b29183957dc09994038288ba012d53abaedb0697e3 + image: wordpress:cli-2 + imageID: docker-pullable://wordpress@sha256:c9ecfd0ef73102cdc6666f20ccc3a0ae16c9a170160ef70bad4e9141ae856054 + lastState: {} + name: wp-install + ready: false + resources: {} + restartCount: 0 + started: false + state: + terminated: + containerID: docker://b1d36c9760604c47741156b29183957dc09994038288ba012d53abaedb0697e3 + exitCode: 0 + finishedAt: "2026-04-10T12:16:46Z" + reason: Completed + startedAt: "2026-04-10T12:15:20Z" + volumeMounts: + - mountPath: /var/www/html + name: wordpress-persistent-storage + - mountPath: /var/run/secrets/kubernetes.io/serviceaccount + name: kube-api-access-29z94 + readOnly: true + recursiveReadOnly: Disabled + hostIP: 192.168.61.192 + hostIPs: + - ip: 192.168.61.192 + observedGeneration: 1 + phase: Succeeded + podIP: 10.244.0.4 + podIPs: + - ip: 10.244.0.4 + qosClass: BestEffort + startTime: "2026-04-10T12:15:08Z" diff --git a/docs/transform-scenarios/wordpress-demo/export/resources/default/Pod__v1_default_wordpress-mysql-9474c86b-fr65w.yaml b/docs/transform-scenarios/wordpress-demo/export/resources/default/Pod__v1_default_wordpress-mysql-9474c86b-fr65w.yaml new file mode 100644 index 00000000..28b6de98 --- /dev/null +++ b/docs/transform-scenarios/wordpress-demo/export/resources/default/Pod__v1_default_wordpress-mysql-9474c86b-fr65w.yaml @@ -0,0 +1,280 @@ +apiVersion: v1 +kind: Pod +metadata: + creationTimestamp: "2026-04-10T12:15:08Z" + generateName: wordpress-mysql-9474c86b- + generation: 1 + labels: + app: wordpress + pod-template-hash: 9474c86b + tier: mysql + managedFields: + - apiVersion: v1 + fieldsType: FieldsV1 + fieldsV1: + f:metadata: + f:generateName: {} + f:labels: + .: {} + f:app: {} + f:pod-template-hash: {} + f:tier: {} + f:ownerReferences: + .: {} + k:{"uid":"c48515d5-a023-4257-b5a1-2504dc2291af"}: {} + f:spec: + f:containers: + k:{"name":"mysql"}: + .: {} + f:env: + .: {} + k:{"name":"MYSQL_DATABASE"}: + .: {} + f:name: {} + f:value: {} + k:{"name":"MYSQL_PASSWORD"}: + .: {} + f:name: {} + f:valueFrom: + .: {} + f:secretKeyRef: {} + k:{"name":"MYSQL_ROOT_PASSWORD"}: + .: {} + f:name: {} + f:valueFrom: + .: {} + f:secretKeyRef: {} + k:{"name":"MYSQL_USER"}: + .: {} + f:name: {} + f:value: {} + f:image: {} + f:imagePullPolicy: {} + f:name: {} + f:ports: + .: {} + k:{"containerPort":3306,"protocol":"TCP"}: + .: {} + f:containerPort: {} + f:name: {} + f:protocol: {} + f:resources: {} + f:terminationMessagePath: {} + f:terminationMessagePolicy: {} + f:volumeMounts: + .: {} + k:{"mountPath":"/var/lib/mysql"}: + .: {} + f:mountPath: {} + f:name: {} + f:dnsPolicy: {} + f:enableServiceLinks: {} + f:restartPolicy: {} + f:schedulerName: {} + f:securityContext: {} + f:terminationGracePeriodSeconds: {} + f:volumes: + .: {} + k:{"name":"mysql-persistent-storage"}: + .: {} + f:name: {} + f:persistentVolumeClaim: + .: {} + f:claimName: {} + manager: kube-controller-manager + operation: Update + time: "2026-04-10T12:15:08Z" + - apiVersion: v1 + fieldsType: FieldsV1 + fieldsV1: + f:status: + f:conditions: + k:{"type":"ContainersReady"}: + .: {} + f:lastProbeTime: {} + f:lastTransitionTime: {} + f:observedGeneration: {} + f:status: {} + f:type: {} + k:{"type":"Initialized"}: + .: {} + f:lastProbeTime: {} + f:lastTransitionTime: {} + f:observedGeneration: {} + f:status: {} + f:type: {} + k:{"type":"PodReadyToStartContainers"}: + .: {} + f:lastProbeTime: {} + f:lastTransitionTime: {} + f:observedGeneration: {} + f:status: {} + f:type: {} + k:{"type":"PodScheduled"}: + f:observedGeneration: {} + k:{"type":"Ready"}: + .: {} + f:lastProbeTime: {} + f:lastTransitionTime: {} + f:observedGeneration: {} + f:status: {} + f:type: {} + f:containerStatuses: {} + f:hostIP: {} + f:hostIPs: {} + f:observedGeneration: {} + f:phase: {} + f:podIP: {} + f:podIPs: + .: {} + k:{"ip":"10.244.0.6"}: + .: {} + f:ip: {} + f:startTime: {} + manager: kubelet + operation: Update + subresource: status + time: "2026-04-10T12:15:58Z" + name: wordpress-mysql-9474c86b-fr65w + namespace: default + ownerReferences: + - apiVersion: apps/v1 + blockOwnerDeletion: true + controller: true + kind: ReplicaSet + name: wordpress-mysql-9474c86b + uid: c48515d5-a023-4257-b5a1-2504dc2291af + resourceVersion: "795" + uid: f81b40e3-ff85-46ca-8b0a-5c826b78f0c8 +spec: + containers: + - env: + - name: MYSQL_ROOT_PASSWORD + valueFrom: + secretKeyRef: + key: MYSQL_ROOT_PASSWORD + name: wordpress-secrets-hg692g82th + - name: MYSQL_DATABASE + value: wordpress + - name: MYSQL_USER + value: wordpress + - name: MYSQL_PASSWORD + valueFrom: + secretKeyRef: + key: MYSQL_WORDPRESS_PASSWORD + name: wordpress-secrets-hg692g82th + image: mysql:8.0 + imagePullPolicy: IfNotPresent + name: mysql + ports: + - containerPort: 3306 + name: mysql + protocol: TCP + resources: {} + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + volumeMounts: + - mountPath: /var/lib/mysql + name: mysql-persistent-storage + - mountPath: /var/run/secrets/kubernetes.io/serviceaccount + name: kube-api-access-k5p65 + readOnly: true + dnsPolicy: ClusterFirst + enableServiceLinks: true + nodeName: minikube + preemptionPolicy: PreemptLowerPriority + priority: 0 + restartPolicy: Always + schedulerName: default-scheduler + securityContext: {} + serviceAccount: default + serviceAccountName: default + terminationGracePeriodSeconds: 30 + tolerations: + - effect: NoExecute + key: node.kubernetes.io/not-ready + operator: Exists + tolerationSeconds: 300 + - effect: NoExecute + key: node.kubernetes.io/unreachable + operator: Exists + tolerationSeconds: 300 + volumes: + - name: mysql-persistent-storage + persistentVolumeClaim: + claimName: mysql-pv-claim + - name: kube-api-access-k5p65 + projected: + defaultMode: 420 + sources: + - serviceAccountToken: + expirationSeconds: 3607 + path: token + - configMap: + items: + - key: ca.crt + path: ca.crt + name: kube-root-ca.crt + - downwardAPI: + items: + - fieldRef: + apiVersion: v1 + fieldPath: metadata.namespace + path: namespace +status: + conditions: + - lastProbeTime: null + lastTransitionTime: "2026-04-10T12:15:58Z" + observedGeneration: 1 + status: "True" + type: PodReadyToStartContainers + - lastProbeTime: null + lastTransitionTime: "2026-04-10T12:15:08Z" + observedGeneration: 1 + status: "True" + type: Initialized + - lastProbeTime: null + lastTransitionTime: "2026-04-10T12:15:58Z" + observedGeneration: 1 + status: "True" + type: Ready + - lastProbeTime: null + lastTransitionTime: "2026-04-10T12:15:58Z" + observedGeneration: 1 + status: "True" + type: ContainersReady + - lastProbeTime: null + lastTransitionTime: "2026-04-10T12:15:08Z" + observedGeneration: 1 + status: "True" + type: PodScheduled + containerStatuses: + - containerID: docker://7e196a67c97dc0a97090ed6f3e62507aa9a63ab4d28ce7b455be169edc7c53ce + image: mysql:8.0 + imageID: docker-pullable://mysql@sha256:64756cc92f707eb504496d774353990bcb0f6999ddf598b6ad188f2da66bd000 + lastState: {} + name: mysql + ready: true + resources: {} + restartCount: 0 + started: true + state: + running: + startedAt: "2026-04-10T12:15:57Z" + volumeMounts: + - mountPath: /var/lib/mysql + name: mysql-persistent-storage + - mountPath: /var/run/secrets/kubernetes.io/serviceaccount + name: kube-api-access-k5p65 + readOnly: true + recursiveReadOnly: Disabled + hostIP: 192.168.61.192 + hostIPs: + - ip: 192.168.61.192 + observedGeneration: 1 + phase: Running + podIP: 10.244.0.6 + podIPs: + - ip: 10.244.0.6 + qosClass: BestEffort + startTime: "2026-04-10T12:15:08Z" diff --git a/docs/transform-scenarios/wordpress-demo/export/resources/default/ReplicaSet_apps_v1_default_wordpress-74b89cc84c.yaml b/docs/transform-scenarios/wordpress-demo/export/resources/default/ReplicaSet_apps_v1_default_wordpress-74b89cc84c.yaml new file mode 100644 index 00000000..db3e66a7 --- /dev/null +++ b/docs/transform-scenarios/wordpress-demo/export/resources/default/ReplicaSet_apps_v1_default_wordpress-74b89cc84c.yaml @@ -0,0 +1,245 @@ +apiVersion: apps/v1 +kind: ReplicaSet +metadata: + annotations: + deployment.kubernetes.io/desired-replicas: "1" + deployment.kubernetes.io/max-replicas: "1" + deployment.kubernetes.io/revision: "1" + creationTimestamp: "2026-04-10T12:15:08Z" + generation: 1 + labels: + app: wordpress + pod-template-hash: 74b89cc84c + tier: frontend + managedFields: + - apiVersion: apps/v1 + fieldsType: FieldsV1 + fieldsV1: + f:metadata: + f:annotations: + .: {} + f:deployment.kubernetes.io/desired-replicas: {} + f:deployment.kubernetes.io/max-replicas: {} + f:deployment.kubernetes.io/revision: {} + f:labels: + .: {} + f:app: {} + f:pod-template-hash: {} + f:tier: {} + f:ownerReferences: + .: {} + k:{"uid":"32f30549-f011-48b1-8398-64fef74b2df1"}: {} + f:spec: + f:replicas: {} + f:selector: {} + f:template: + f:metadata: + f:labels: + .: {} + f:app: {} + f:pod-template-hash: {} + f:tier: {} + f:spec: + f:containers: + k:{"name":"nginx"}: + .: {} + f:image: {} + f:imagePullPolicy: {} + f:name: {} + f:ports: + .: {} + k:{"containerPort":80,"protocol":"TCP"}: + .: {} + f:containerPort: {} + f:name: {} + f:protocol: {} + f:resources: {} + f:terminationMessagePath: {} + f:terminationMessagePolicy: {} + f:volumeMounts: + .: {} + k:{"mountPath":"/etc/nginx/nginx.conf"}: + .: {} + f:mountPath: {} + f:name: {} + f:subPath: {} + k:{"mountPath":"/var/www/html"}: + .: {} + f:mountPath: {} + f:name: {} + f:readOnly: {} + k:{"name":"wordpress"}: + .: {} + f:env: + .: {} + k:{"name":"WORDPRESS_CONFIG_EXTRA"}: + .: {} + f:name: {} + f:value: {} + k:{"name":"WORDPRESS_DB_HOST"}: + .: {} + f:name: {} + f:value: {} + k:{"name":"WORDPRESS_DB_PASSWORD"}: + .: {} + f:name: {} + f:valueFrom: + .: {} + f:secretKeyRef: {} + k:{"name":"WORDPRESS_DB_USER"}: + .: {} + f:name: {} + f:value: {} + f:image: {} + f:imagePullPolicy: {} + f:name: {} + f:ports: + .: {} + k:{"containerPort":9000,"protocol":"TCP"}: + .: {} + f:containerPort: {} + f:name: {} + f:protocol: {} + f:resources: {} + f:terminationMessagePath: {} + f:terminationMessagePolicy: {} + f:volumeMounts: + .: {} + k:{"mountPath":"/var/www/html"}: + .: {} + f:mountPath: {} + f:name: {} + f:dnsPolicy: {} + f:restartPolicy: {} + f:schedulerName: {} + f:securityContext: {} + f:terminationGracePeriodSeconds: {} + f:volumes: + .: {} + k:{"name":"nginx-config"}: + .: {} + f:configMap: + .: {} + f:defaultMode: {} + f:name: {} + f:name: {} + k:{"name":"wordpress-persistent-storage"}: + .: {} + f:name: {} + f:persistentVolumeClaim: + .: {} + f:claimName: {} + manager: kube-controller-manager + operation: Update + time: "2026-04-10T12:15:08Z" + - apiVersion: apps/v1 + fieldsType: FieldsV1 + fieldsV1: + f:status: + f:availableReplicas: {} + f:fullyLabeledReplicas: {} + f:observedGeneration: {} + f:readyReplicas: {} + f:replicas: {} + f:terminatingReplicas: {} + manager: kube-controller-manager + operation: Update + subresource: status + time: "2026-04-10T12:16:04Z" + name: wordpress-74b89cc84c + namespace: default + ownerReferences: + - apiVersion: apps/v1 + blockOwnerDeletion: true + controller: true + kind: Deployment + name: wordpress + uid: 32f30549-f011-48b1-8398-64fef74b2df1 + resourceVersion: "811" + uid: 7ed37255-e5ff-4e33-837d-f584a536d2b8 +spec: + replicas: 1 + selector: + matchLabels: + app: wordpress + pod-template-hash: 74b89cc84c + tier: frontend + template: + metadata: + labels: + app: wordpress + pod-template-hash: 74b89cc84c + tier: frontend + spec: + containers: + - env: + - name: WORDPRESS_DB_HOST + value: wordpress-mysql + - name: WORDPRESS_DB_PASSWORD + valueFrom: + secretKeyRef: + key: MYSQL_WORDPRESS_PASSWORD + name: wordpress-secrets-hg692g82th + - name: WORDPRESS_DB_USER + value: wordpress + - name: WORDPRESS_CONFIG_EXTRA + value: | + // Set SITE URL dynamically from requests to allow reach it on different endpoints + if (isset($_SERVER['HTTP_HOST'])) { + $protocol = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on') ? 'https' : 'http'; + if (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https') { + $protocol = 'https'; + } + define('WP_HOME', $protocol . '://' . $_SERVER['HTTP_HOST']); + define('WP_SITEURL', $protocol . '://' . $_SERVER['HTTP_HOST']); + } + image: wordpress:6-fpm-alpine + imagePullPolicy: IfNotPresent + name: wordpress + ports: + - containerPort: 9000 + name: fastcgi + protocol: TCP + resources: {} + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + volumeMounts: + - mountPath: /var/www/html + name: wordpress-persistent-storage + - image: nginx:alpine + imagePullPolicy: IfNotPresent + name: nginx + ports: + - containerPort: 80 + name: http + protocol: TCP + resources: {} + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + volumeMounts: + - mountPath: /var/www/html + name: wordpress-persistent-storage + readOnly: true + - mountPath: /etc/nginx/nginx.conf + name: nginx-config + subPath: nginx.conf + dnsPolicy: ClusterFirst + restartPolicy: Always + schedulerName: default-scheduler + securityContext: {} + terminationGracePeriodSeconds: 30 + volumes: + - name: wordpress-persistent-storage + persistentVolumeClaim: + claimName: wordpress-pv-claim + - configMap: + defaultMode: 420 + name: nginx-config + name: nginx-config +status: + availableReplicas: 1 + fullyLabeledReplicas: 1 + observedGeneration: 1 + readyReplicas: 1 + replicas: 1 + terminatingReplicas: 0 diff --git a/docs/transform-scenarios/wordpress-demo/export/resources/default/ReplicaSet_apps_v1_default_wordpress-mysql-9474c86b.yaml b/docs/transform-scenarios/wordpress-demo/export/resources/default/ReplicaSet_apps_v1_default_wordpress-mysql-9474c86b.yaml new file mode 100644 index 00000000..d34a5904 --- /dev/null +++ b/docs/transform-scenarios/wordpress-demo/export/resources/default/ReplicaSet_apps_v1_default_wordpress-mysql-9474c86b.yaml @@ -0,0 +1,186 @@ +apiVersion: apps/v1 +kind: ReplicaSet +metadata: + annotations: + deployment.kubernetes.io/desired-replicas: "1" + deployment.kubernetes.io/max-replicas: "1" + deployment.kubernetes.io/revision: "1" + creationTimestamp: "2026-04-10T12:15:08Z" + generation: 1 + labels: + app: wordpress + pod-template-hash: 9474c86b + tier: mysql + managedFields: + - apiVersion: apps/v1 + fieldsType: FieldsV1 + fieldsV1: + f:metadata: + f:annotations: + .: {} + f:deployment.kubernetes.io/desired-replicas: {} + f:deployment.kubernetes.io/max-replicas: {} + f:deployment.kubernetes.io/revision: {} + f:labels: + .: {} + f:app: {} + f:pod-template-hash: {} + f:tier: {} + f:ownerReferences: + .: {} + k:{"uid":"2eba9391-46db-4860-9f9a-a1cb396faf18"}: {} + f:spec: + f:replicas: {} + f:selector: {} + f:template: + f:metadata: + f:labels: + .: {} + f:app: {} + f:pod-template-hash: {} + f:tier: {} + f:spec: + f:containers: + k:{"name":"mysql"}: + .: {} + f:env: + .: {} + k:{"name":"MYSQL_DATABASE"}: + .: {} + f:name: {} + f:value: {} + k:{"name":"MYSQL_PASSWORD"}: + .: {} + f:name: {} + f:valueFrom: + .: {} + f:secretKeyRef: {} + k:{"name":"MYSQL_ROOT_PASSWORD"}: + .: {} + f:name: {} + f:valueFrom: + .: {} + f:secretKeyRef: {} + k:{"name":"MYSQL_USER"}: + .: {} + f:name: {} + f:value: {} + f:image: {} + f:imagePullPolicy: {} + f:name: {} + f:ports: + .: {} + k:{"containerPort":3306,"protocol":"TCP"}: + .: {} + f:containerPort: {} + f:name: {} + f:protocol: {} + f:resources: {} + f:terminationMessagePath: {} + f:terminationMessagePolicy: {} + f:volumeMounts: + .: {} + k:{"mountPath":"/var/lib/mysql"}: + .: {} + f:mountPath: {} + f:name: {} + f:dnsPolicy: {} + f:restartPolicy: {} + f:schedulerName: {} + f:securityContext: {} + f:terminationGracePeriodSeconds: {} + f:volumes: + .: {} + k:{"name":"mysql-persistent-storage"}: + .: {} + f:name: {} + f:persistentVolumeClaim: + .: {} + f:claimName: {} + manager: kube-controller-manager + operation: Update + time: "2026-04-10T12:15:08Z" + - apiVersion: apps/v1 + fieldsType: FieldsV1 + fieldsV1: + f:status: + f:availableReplicas: {} + f:fullyLabeledReplicas: {} + f:observedGeneration: {} + f:readyReplicas: {} + f:replicas: {} + f:terminatingReplicas: {} + manager: kube-controller-manager + operation: Update + subresource: status + time: "2026-04-10T12:15:58Z" + name: wordpress-mysql-9474c86b + namespace: default + ownerReferences: + - apiVersion: apps/v1 + blockOwnerDeletion: true + controller: true + kind: Deployment + name: wordpress-mysql + uid: 2eba9391-46db-4860-9f9a-a1cb396faf18 + resourceVersion: "798" + uid: c48515d5-a023-4257-b5a1-2504dc2291af +spec: + replicas: 1 + selector: + matchLabels: + app: wordpress + pod-template-hash: 9474c86b + tier: mysql + template: + metadata: + labels: + app: wordpress + pod-template-hash: 9474c86b + tier: mysql + spec: + containers: + - env: + - name: MYSQL_ROOT_PASSWORD + valueFrom: + secretKeyRef: + key: MYSQL_ROOT_PASSWORD + name: wordpress-secrets-hg692g82th + - name: MYSQL_DATABASE + value: wordpress + - name: MYSQL_USER + value: wordpress + - name: MYSQL_PASSWORD + valueFrom: + secretKeyRef: + key: MYSQL_WORDPRESS_PASSWORD + name: wordpress-secrets-hg692g82th + image: mysql:8.0 + imagePullPolicy: IfNotPresent + name: mysql + ports: + - containerPort: 3306 + name: mysql + protocol: TCP + resources: {} + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + volumeMounts: + - mountPath: /var/lib/mysql + name: mysql-persistent-storage + dnsPolicy: ClusterFirst + restartPolicy: Always + schedulerName: default-scheduler + securityContext: {} + terminationGracePeriodSeconds: 30 + volumes: + - name: mysql-persistent-storage + persistentVolumeClaim: + claimName: mysql-pv-claim +status: + availableReplicas: 1 + fullyLabeledReplicas: 1 + observedGeneration: 1 + readyReplicas: 1 + replicas: 1 + terminatingReplicas: 0 diff --git a/docs/transform-scenarios/wordpress-demo/export/resources/default/Secret__v1_default_wordpress-secrets-hg692g82th.yaml b/docs/transform-scenarios/wordpress-demo/export/resources/default/Secret__v1_default_wordpress-secrets-hg692g82th.yaml new file mode 100644 index 00000000..f9deba91 --- /dev/null +++ b/docs/transform-scenarios/wordpress-demo/export/resources/default/Secret__v1_default_wordpress-secrets-hg692g82th.yaml @@ -0,0 +1,33 @@ +apiVersion: v1 +data: + MYSQL_ROOT_PASSWORD: eGFJMmdpdWhxc2V0TC82VDRaOVViUT09 + MYSQL_WORDPRESS_PASSWORD: QzZUa25lcFo3Vm5idTdGZVdBSUFidz09 + WORDPRESS_ADMIN_PASSWORD: d0ZoSytaZDhlU2RhVmx1Ug== +kind: Secret +metadata: + annotations: + kubectl.kubernetes.io/last-applied-configuration: | + {"apiVersion":"v1","data":{"MYSQL_ROOT_PASSWORD":"eGFJMmdpdWhxc2V0TC82VDRaOVViUT09","MYSQL_WORDPRESS_PASSWORD":"QzZUa25lcFo3Vm5idTdGZVdBSUFidz09","WORDPRESS_ADMIN_PASSWORD":"d0ZoSytaZDhlU2RhVmx1Ug=="},"kind":"Secret","metadata":{"annotations":{},"name":"wordpress-secrets-hg692g82th","namespace":"default"},"type":"Opaque"} + creationTimestamp: "2026-04-10T12:15:07Z" + managedFields: + - apiVersion: v1 + fieldsType: FieldsV1 + fieldsV1: + f:data: + .: {} + f:MYSQL_ROOT_PASSWORD: {} + f:MYSQL_WORDPRESS_PASSWORD: {} + f:WORDPRESS_ADMIN_PASSWORD: {} + f:metadata: + f:annotations: + .: {} + f:kubectl.kubernetes.io/last-applied-configuration: {} + f:type: {} + manager: kubectl-client-side-apply + operation: Update + time: "2026-04-10T12:15:07Z" + name: wordpress-secrets-hg692g82th + namespace: default + resourceVersion: "676" + uid: 0bb63c2c-fa4a-4c86-ad5d-141dccbd25ad +type: Opaque diff --git a/docs/transform-scenarios/wordpress-demo/export/resources/default/ServiceAccount__v1_default_default.yaml b/docs/transform-scenarios/wordpress-demo/export/resources/default/ServiceAccount__v1_default_default.yaml new file mode 100644 index 00000000..49a7b37e --- /dev/null +++ b/docs/transform-scenarios/wordpress-demo/export/resources/default/ServiceAccount__v1_default_default.yaml @@ -0,0 +1,8 @@ +apiVersion: v1 +kind: ServiceAccount +metadata: + creationTimestamp: "2026-04-10T12:10:49Z" + name: default + namespace: default + resourceVersion: "336" + uid: 01ad4812-cd89-4fce-914d-7eee37f8f551 diff --git a/docs/transform-scenarios/wordpress-demo/export/resources/default/Service__v1_default_kubernetes.yaml b/docs/transform-scenarios/wordpress-demo/export/resources/default/Service__v1_default_kubernetes.yaml new file mode 100644 index 00000000..0c06b485 --- /dev/null +++ b/docs/transform-scenarios/wordpress-demo/export/resources/default/Service__v1_default_kubernetes.yaml @@ -0,0 +1,54 @@ +apiVersion: v1 +kind: Service +metadata: + creationTimestamp: "2026-04-10T12:10:43Z" + labels: + component: apiserver + provider: kubernetes + managedFields: + - apiVersion: v1 + fieldsType: FieldsV1 + fieldsV1: + f:metadata: + f:labels: + .: {} + f:component: {} + f:provider: {} + f:spec: + f:clusterIP: {} + f:internalTrafficPolicy: {} + f:ipFamilyPolicy: {} + f:ports: + .: {} + k:{"port":443,"protocol":"TCP"}: + .: {} + f:name: {} + f:port: {} + f:protocol: {} + f:targetPort: {} + f:sessionAffinity: {} + f:type: {} + manager: kube-apiserver + operation: Update + time: "2026-04-10T12:10:43Z" + name: kubernetes + namespace: default + resourceVersion: "204" + uid: 5ca30343-0dc7-41ee-adcb-b3e4f821f150 +spec: + clusterIP: 10.96.0.1 + clusterIPs: + - 10.96.0.1 + internalTrafficPolicy: Cluster + ipFamilies: + - IPv4 + ipFamilyPolicy: SingleStack + ports: + - name: https + port: 443 + protocol: TCP + targetPort: 8443 + sessionAffinity: None + type: ClusterIP +status: + loadBalancer: {} diff --git a/docs/transform-scenarios/wordpress-demo/export/resources/default/Service__v1_default_wordpress-mysql.yaml b/docs/transform-scenarios/wordpress-demo/export/resources/default/Service__v1_default_wordpress-mysql.yaml new file mode 100644 index 00000000..29acff57 --- /dev/null +++ b/docs/transform-scenarios/wordpress-demo/export/resources/default/Service__v1_default_wordpress-mysql.yaml @@ -0,0 +1,58 @@ +apiVersion: v1 +kind: Service +metadata: + annotations: + kubectl.kubernetes.io/last-applied-configuration: | + {"apiVersion":"v1","kind":"Service","metadata":{"annotations":{},"labels":{"app":"wordpress"},"name":"wordpress-mysql","namespace":"default"},"spec":{"ports":[{"port":3306}],"selector":{"app":"wordpress","tier":"mysql"}}} + creationTimestamp: "2026-04-10T12:15:07Z" + labels: + app: wordpress + managedFields: + - apiVersion: v1 + fieldsType: FieldsV1 + fieldsV1: + f:metadata: + f:annotations: + .: {} + f:kubectl.kubernetes.io/last-applied-configuration: {} + f:labels: + .: {} + f:app: {} + f:spec: + f:internalTrafficPolicy: {} + f:ports: + .: {} + k:{"port":3306,"protocol":"TCP"}: + .: {} + f:port: {} + f:protocol: {} + f:targetPort: {} + f:selector: {} + f:sessionAffinity: {} + f:type: {} + manager: kubectl-client-side-apply + operation: Update + time: "2026-04-10T12:15:07Z" + name: wordpress-mysql + namespace: default + resourceVersion: "683" + uid: ec2555f1-9fd5-45da-bfa3-f2b59bb1d218 +spec: + clusterIP: 10.101.133.119 + clusterIPs: + - 10.101.133.119 + internalTrafficPolicy: Cluster + ipFamilies: + - IPv4 + ipFamilyPolicy: SingleStack + ports: + - port: 3306 + protocol: TCP + targetPort: 3306 + selector: + app: wordpress + tier: mysql + sessionAffinity: None + type: ClusterIP +status: + loadBalancer: {} diff --git a/docs/transform-scenarios/wordpress-demo/export/resources/default/Service__v1_default_wordpress.yaml b/docs/transform-scenarios/wordpress-demo/export/resources/default/Service__v1_default_wordpress.yaml new file mode 100644 index 00000000..4099abd1 --- /dev/null +++ b/docs/transform-scenarios/wordpress-demo/export/resources/default/Service__v1_default_wordpress.yaml @@ -0,0 +1,63 @@ +apiVersion: v1 +kind: Service +metadata: + annotations: + kubectl.kubernetes.io/last-applied-configuration: | + {"apiVersion":"v1","kind":"Service","metadata":{"annotations":{},"labels":{"app":"wordpress"},"name":"wordpress","namespace":"default"},"spec":{"ports":[{"port":80}],"selector":{"app":"wordpress","tier":"frontend"},"type":"LoadBalancer"}} + creationTimestamp: "2026-04-10T12:15:07Z" + labels: + app: wordpress + managedFields: + - apiVersion: v1 + fieldsType: FieldsV1 + fieldsV1: + f:metadata: + f:annotations: + .: {} + f:kubectl.kubernetes.io/last-applied-configuration: {} + f:labels: + .: {} + f:app: {} + f:spec: + f:allocateLoadBalancerNodePorts: {} + f:externalTrafficPolicy: {} + f:internalTrafficPolicy: {} + f:ports: + .: {} + k:{"port":80,"protocol":"TCP"}: + .: {} + f:port: {} + f:protocol: {} + f:targetPort: {} + f:selector: {} + f:sessionAffinity: {} + f:type: {} + manager: kubectl-client-side-apply + operation: Update + time: "2026-04-10T12:15:07Z" + name: wordpress + namespace: default + resourceVersion: "679" + uid: 9bd59883-6312-4534-a2c1-b71911612715 +spec: + allocateLoadBalancerNodePorts: true + clusterIP: 10.99.69.43 + clusterIPs: + - 10.99.69.43 + externalTrafficPolicy: Cluster + internalTrafficPolicy: Cluster + ipFamilies: + - IPv4 + ipFamilyPolicy: SingleStack + ports: + - nodePort: 32215 + port: 80 + protocol: TCP + targetPort: 80 + selector: + app: wordpress + tier: frontend + sessionAffinity: None + type: LoadBalancer +status: + loadBalancer: {} diff --git a/docs/transform-scenarios/wordpress-demo/output/output.yaml b/docs/transform-scenarios/wordpress-demo/output/output.yaml new file mode 100644 index 00000000..3b65ee7d --- /dev/null +++ b/docs/transform-scenarios/wordpress-demo/output/output.yaml @@ -0,0 +1,429 @@ +apiVersion: v1 +data: + nginx.conf: | + events { + worker_connections 64; + } + + http { + include /etc/nginx/mime.types; + default_type application/octet-stream; + + server { + listen 80; + root /var/www/html; + index index.php; + client_max_body_size 32m; + + location / { + try_files $uri $uri/ /index.php?$args; + } + + location ~ \.php$ { + fastcgi_pass localhost:9000; + fastcgi_index index.php; + include fastcgi_params; + fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; + } + } + } +kind: ConfigMap +metadata: + labels: + app: wordpress + migrated-with: crane + name: nginx-config + namespace: new-migrated-namespace +--- +apiVersion: v1 +data: + MYSQL_ROOT_PASSWORD: eGFJMmdpdWhxc2V0TC82VDRaOVViUT09 + MYSQL_WORDPRESS_PASSWORD: QzZUa25lcFo3Vm5idTdGZVdBSUFidz09 + WORDPRESS_ADMIN_PASSWORD: d0ZoSytaZDhlU2RhVmx1Ug== +kind: Secret +metadata: + labels: + migrated-with: crane + name: wordpress-secrets-hg692g82th + namespace: new-migrated-namespace +type: Opaque +--- +apiVersion: v1 +kind: Service +metadata: + labels: + component: apiserver + migrated-with: crane + provider: kubernetes + name: kubernetes + namespace: new-migrated-namespace +spec: + internalTrafficPolicy: Cluster + ipFamilies: + - IPv4 + ipFamilyPolicy: SingleStack + ports: + - name: https + port: 443 + protocol: TCP + targetPort: 8443 + selector: + migrated-with: crane + sessionAffinity: None + type: ClusterIP +--- +apiVersion: v1 +kind: Service +metadata: + labels: + app: wordpress + migrated-with: crane + name: wordpress + namespace: new-migrated-namespace +spec: + allocateLoadBalancerNodePorts: true + externalTrafficPolicy: Cluster + internalTrafficPolicy: Cluster + ipFamilies: + - IPv4 + ipFamilyPolicy: SingleStack + ports: + - port: 80 + protocol: TCP + targetPort: 80 + selector: + app: wordpress + migrated-with: crane + tier: frontend + sessionAffinity: None + type: LoadBalancer +--- +apiVersion: v1 +kind: Service +metadata: + labels: + app: wordpress + migrated-with: crane + name: wordpress-mysql + namespace: new-migrated-namespace +spec: + internalTrafficPolicy: Cluster + ipFamilies: + - IPv4 + ipFamilyPolicy: SingleStack + ports: + - port: 3306 + protocol: TCP + targetPort: 3306 + selector: + app: wordpress + migrated-with: crane + tier: mysql + sessionAffinity: None + type: ClusterIP +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + annotations: + deployment.kubernetes.io/revision: "1" + labels: + app: wordpress + migrated-with: crane + name: wordpress + namespace: new-migrated-namespace +spec: + progressDeadlineSeconds: 600 + replicas: 1 + revisionHistoryLimit: 10 + selector: + matchLabels: + app: wordpress + migrated-with: crane + tier: frontend + strategy: + type: Recreate + template: + metadata: + labels: + app: wordpress + migrated-with: crane + tier: frontend + spec: + containers: + - env: + - name: WORDPRESS_DB_HOST + value: wordpress-mysql + - name: WORDPRESS_DB_PASSWORD + valueFrom: + secretKeyRef: + key: MYSQL_WORDPRESS_PASSWORD + name: wordpress-secrets-hg692g82th + - name: WORDPRESS_DB_USER + value: wordpress + - name: WORDPRESS_CONFIG_EXTRA + value: | + // Set SITE URL dynamically from requests to allow reach it on different endpoints + if (isset($_SERVER['HTTP_HOST'])) { + $protocol = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on') ? 'https' : 'http'; + if (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https') { + $protocol = 'https'; + } + define('WP_HOME', $protocol . '://' . $_SERVER['HTTP_HOST']); + define('WP_SITEURL', $protocol . '://' . $_SERVER['HTTP_HOST']); + } + image: wordpress:6-fpm-alpine + imagePullPolicy: IfNotPresent + name: wordpress + ports: + - containerPort: 9000 + name: fastcgi + protocol: TCP + resources: {} + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + volumeMounts: + - mountPath: /var/www/html + name: wordpress-persistent-storage + - image: nginx:alpine + imagePullPolicy: IfNotPresent + name: nginx + ports: + - containerPort: 80 + name: http + protocol: TCP + resources: {} + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + volumeMounts: + - mountPath: /var/www/html + name: wordpress-persistent-storage + readOnly: true + - mountPath: /etc/nginx/nginx.conf + name: nginx-config + subPath: nginx.conf + dnsPolicy: ClusterFirst + restartPolicy: Always + schedulerName: default-scheduler + securityContext: {} + terminationGracePeriodSeconds: 30 + volumes: + - name: wordpress-persistent-storage + persistentVolumeClaim: + claimName: wordpress-pv-claim + - configMap: + defaultMode: 420 + name: nginx-config + name: nginx-config +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + annotations: + deployment.kubernetes.io/revision: "1" + labels: + app: wordpress + migrated-with: crane + name: wordpress-mysql + namespace: new-migrated-namespace +spec: + progressDeadlineSeconds: 600 + replicas: 1 + revisionHistoryLimit: 10 + selector: + matchLabels: + app: wordpress + migrated-with: crane + tier: mysql + strategy: + type: Recreate + template: + metadata: + labels: + app: wordpress + migrated-with: crane + tier: mysql + spec: + containers: + - env: + - name: MYSQL_ROOT_PASSWORD + valueFrom: + secretKeyRef: + key: MYSQL_ROOT_PASSWORD + name: wordpress-secrets-hg692g82th + - name: MYSQL_DATABASE + value: wordpress + - name: MYSQL_USER + value: wordpress + - name: MYSQL_PASSWORD + valueFrom: + secretKeyRef: + key: MYSQL_WORDPRESS_PASSWORD + name: wordpress-secrets-hg692g82th + image: mysql:8.0 + imagePullPolicy: IfNotPresent + name: mysql + ports: + - containerPort: 3306 + name: mysql + protocol: TCP + resources: {} + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + volumeMounts: + - mountPath: /var/lib/mysql + name: mysql-persistent-storage + dnsPolicy: ClusterFirst + restartPolicy: Always + schedulerName: default-scheduler + securityContext: {} + terminationGracePeriodSeconds: 30 + volumes: + - name: mysql-persistent-storage + persistentVolumeClaim: + claimName: mysql-pv-claim +--- +apiVersion: batch/v1 +kind: Job +metadata: + labels: + batch.kubernetes.io/controller-uid: be719474-856d-4d84-80ad-4f4ab9ecdd30 + batch.kubernetes.io/job-name: wordpress-install + controller-uid: be719474-856d-4d84-80ad-4f4ab9ecdd30 + job-name: wordpress-install + migrated-with: crane + name: wordpress-install + namespace: new-migrated-namespace +spec: + backoffLimit: 4 + completionMode: NonIndexed + completions: 1 + manualSelector: false + parallelism: 1 + podReplacementPolicy: TerminatingOrFailed + selector: + matchLabels: + batch.kubernetes.io/controller-uid: be719474-856d-4d84-80ad-4f4ab9ecdd30 + migrated-with: crane + suspend: false + template: + metadata: + labels: + batch.kubernetes.io/controller-uid: be719474-856d-4d84-80ad-4f4ab9ecdd30 + batch.kubernetes.io/job-name: wordpress-install + controller-uid: be719474-856d-4d84-80ad-4f4ab9ecdd30 + job-name: wordpress-install + migrated-with: crane + spec: + containers: + - args: + - -lc + - | + set -e + cd /var/www/html + + echo "Waiting for MySQL on ${WORDPRESS_DB_HOST}:3306..." + for i in $(seq 1 60); do + if mariadb-admin ping -h"${WORDPRESS_DB_HOST}" -u"${WORDPRESS_DB_USER}" -p"${WORDPRESS_DB_PASSWORD}" --ssl=false --silent; then + echo "MySQL is up." + break + fi + echo "MySQL not ready yet (attempt: $i)..." + sleep 5 + done + + if ! mariadb-admin ping -h"${WORDPRESS_DB_HOST}" -u"${WORDPRESS_DB_USER}" -p"${WORDPRESS_DB_PASSWORD}" --ssl=false --silent; then + echo "MySQL did not become ready within the timeout." + exit 1 + fi + + # Make sure WordPress core is present on the volume + if [ ! -f wp-load.php ]; then + echo "WordPress core not found on the volume. Downloading..." + wp core download --allow-root + fi + + # Create wp-config.php if missing + if [ ! -f wp-config.php ]; then + echo "Creating wp-config.php..." + wp config create \ + --dbname="${WORDPRESS_DB_NAME}" \ + --dbuser="${WORDPRESS_DB_USER}" \ + --dbpass="${WORDPRESS_DB_PASSWORD}" \ + --dbhost="${WORDPRESS_DB_HOST}" \ + --allow-root + fi + + # Idempotent install + if wp core is-installed --allow-root >/dev/null 2>&1; then + echo "WordPress is already installed. Nothing to do." + exit 0 + fi + + # Create an installation kind of unique ID + WORDPRESS_SEED_ID=$RANDOM + + echo "Running wp core install..." + wp core install \ + --url="${WORDPRESS_SITE_URL}" \ + --title="${WORDPRESS_SITE_TITLE} #$WORDPRESS_SEED_ID" \ + --admin_user="${WORDPRESS_ADMIN_USER}" \ + --admin_password="${WORDPRESS_ADMIN_PASSWORD}" \ + --admin_email="${WORDPRESS_ADMIN_EMAIL}" \ + --skip-email \ + --allow-root + + echo "Creating sample post..." + wp post create \ + --post_type=post \ + --post_status=publish \ + --post_title="Sample post #$WORDPRESS_SEED_ID" \ + --post_content="Hello from k8s, this is a random post content: $(openssl rand -base64 200 | tr -cs 'a-zA-Z' ' ' | xargs)" + + echo "WORDPRESS_SEED_ID=$WORDPRESS_SEED_ID" + echo "Done. WordPress has been installed." + command: + - bash + env: + - name: WORDPRESS_DB_HOST + value: wordpress-mysql + - name: WORDPRESS_DB_USER + value: wordpress + - name: WORDPRESS_DB_NAME + value: wordpress + - name: WORDPRESS_DB_PASSWORD + valueFrom: + secretKeyRef: + key: MYSQL_WORDPRESS_PASSWORD + name: wordpress-secrets-hg692g82th + - name: WORDPRESS_SITE_URL + value: http://wordpress-k8s.example.local + - name: WORDPRESS_SITE_TITLE + value: My WordPress Site on k8s + - name: WORDPRESS_ADMIN_USER + value: admin + - name: WORDPRESS_ADMIN_PASSWORD + valueFrom: + secretKeyRef: + key: WORDPRESS_ADMIN_PASSWORD + name: wordpress-secrets-hg692g82th + - name: WORDPRESS_ADMIN_EMAIL + value: admin@wordpress-k8s.example.local + image: wordpress:cli-2 + imagePullPolicy: IfNotPresent + name: wp-install + resources: {} + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + volumeMounts: + - mountPath: /var/www/html + name: wordpress-persistent-storage + dnsPolicy: ClusterFirst + restartPolicy: OnFailure + schedulerName: default-scheduler + securityContext: {} + terminationGracePeriodSeconds: 30 + volumes: + - name: wordpress-persistent-storage + persistentVolumeClaim: + claimName: wordpress-pv-claim diff --git a/docs/transform-scenarios/wordpress-demo/output/resources/new-migrated-namespace/ConfigMap__v1_new-migrated-namespace_nginx-config.yaml b/docs/transform-scenarios/wordpress-demo/output/resources/new-migrated-namespace/ConfigMap__v1_new-migrated-namespace_nginx-config.yaml new file mode 100644 index 00000000..37e3cc2f --- /dev/null +++ b/docs/transform-scenarios/wordpress-demo/output/resources/new-migrated-namespace/ConfigMap__v1_new-migrated-namespace_nginx-config.yaml @@ -0,0 +1,36 @@ +apiVersion: v1 +data: + nginx.conf: | + events { + worker_connections 64; + } + + http { + include /etc/nginx/mime.types; + default_type application/octet-stream; + + server { + listen 80; + root /var/www/html; + index index.php; + client_max_body_size 32m; + + location / { + try_files $uri $uri/ /index.php?$args; + } + + location ~ \.php$ { + fastcgi_pass localhost:9000; + fastcgi_index index.php; + include fastcgi_params; + fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; + } + } + } +kind: ConfigMap +metadata: + labels: + app: wordpress + migrated-with: crane + name: nginx-config + namespace: new-migrated-namespace diff --git a/docs/transform-scenarios/wordpress-demo/output/resources/new-migrated-namespace/Deployment_apps_v1_new-migrated-namespace_wordpress-mysql.yaml b/docs/transform-scenarios/wordpress-demo/output/resources/new-migrated-namespace/Deployment_apps_v1_new-migrated-namespace_wordpress-mysql.yaml new file mode 100644 index 00000000..d448589c --- /dev/null +++ b/docs/transform-scenarios/wordpress-demo/output/resources/new-migrated-namespace/Deployment_apps_v1_new-migrated-namespace_wordpress-mysql.yaml @@ -0,0 +1,66 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + annotations: + deployment.kubernetes.io/revision: "1" + labels: + app: wordpress + migrated-with: crane + name: wordpress-mysql + namespace: new-migrated-namespace +spec: + progressDeadlineSeconds: 600 + replicas: 1 + revisionHistoryLimit: 10 + selector: + matchLabels: + app: wordpress + migrated-with: crane + tier: mysql + strategy: + type: Recreate + template: + metadata: + labels: + app: wordpress + migrated-with: crane + tier: mysql + spec: + containers: + - env: + - name: MYSQL_ROOT_PASSWORD + valueFrom: + secretKeyRef: + key: MYSQL_ROOT_PASSWORD + name: wordpress-secrets-hg692g82th + - name: MYSQL_DATABASE + value: wordpress + - name: MYSQL_USER + value: wordpress + - name: MYSQL_PASSWORD + valueFrom: + secretKeyRef: + key: MYSQL_WORDPRESS_PASSWORD + name: wordpress-secrets-hg692g82th + image: mysql:8.0 + imagePullPolicy: IfNotPresent + name: mysql + ports: + - containerPort: 3306 + name: mysql + protocol: TCP + resources: {} + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + volumeMounts: + - mountPath: /var/lib/mysql + name: mysql-persistent-storage + dnsPolicy: ClusterFirst + restartPolicy: Always + schedulerName: default-scheduler + securityContext: {} + terminationGracePeriodSeconds: 30 + volumes: + - name: mysql-persistent-storage + persistentVolumeClaim: + claimName: mysql-pv-claim diff --git a/docs/transform-scenarios/wordpress-demo/output/resources/new-migrated-namespace/Deployment_apps_v1_new-migrated-namespace_wordpress.yaml b/docs/transform-scenarios/wordpress-demo/output/resources/new-migrated-namespace/Deployment_apps_v1_new-migrated-namespace_wordpress.yaml new file mode 100644 index 00000000..aa549969 --- /dev/null +++ b/docs/transform-scenarios/wordpress-demo/output/resources/new-migrated-namespace/Deployment_apps_v1_new-migrated-namespace_wordpress.yaml @@ -0,0 +1,93 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + annotations: + deployment.kubernetes.io/revision: "1" + labels: + app: wordpress + migrated-with: crane + name: wordpress + namespace: new-migrated-namespace +spec: + progressDeadlineSeconds: 600 + replicas: 1 + revisionHistoryLimit: 10 + selector: + matchLabels: + app: wordpress + migrated-with: crane + tier: frontend + strategy: + type: Recreate + template: + metadata: + labels: + app: wordpress + migrated-with: crane + tier: frontend + spec: + containers: + - env: + - name: WORDPRESS_DB_HOST + value: wordpress-mysql + - name: WORDPRESS_DB_PASSWORD + valueFrom: + secretKeyRef: + key: MYSQL_WORDPRESS_PASSWORD + name: wordpress-secrets-hg692g82th + - name: WORDPRESS_DB_USER + value: wordpress + - name: WORDPRESS_CONFIG_EXTRA + value: | + // Set SITE URL dynamically from requests to allow reach it on different endpoints + if (isset($_SERVER['HTTP_HOST'])) { + $protocol = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on') ? 'https' : 'http'; + if (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https') { + $protocol = 'https'; + } + define('WP_HOME', $protocol . '://' . $_SERVER['HTTP_HOST']); + define('WP_SITEURL', $protocol . '://' . $_SERVER['HTTP_HOST']); + } + image: wordpress:6-fpm-alpine + imagePullPolicy: IfNotPresent + name: wordpress + ports: + - containerPort: 9000 + name: fastcgi + protocol: TCP + resources: {} + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + volumeMounts: + - mountPath: /var/www/html + name: wordpress-persistent-storage + - image: nginx:alpine + imagePullPolicy: IfNotPresent + name: nginx + ports: + - containerPort: 80 + name: http + protocol: TCP + resources: {} + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + volumeMounts: + - mountPath: /var/www/html + name: wordpress-persistent-storage + readOnly: true + - mountPath: /etc/nginx/nginx.conf + name: nginx-config + subPath: nginx.conf + dnsPolicy: ClusterFirst + restartPolicy: Always + schedulerName: default-scheduler + securityContext: {} + terminationGracePeriodSeconds: 30 + volumes: + - name: wordpress-persistent-storage + persistentVolumeClaim: + claimName: wordpress-pv-claim + - configMap: + defaultMode: 420 + name: nginx-config + name: nginx-config diff --git a/docs/transform-scenarios/wordpress-demo/output/resources/new-migrated-namespace/Job_batch_v1_new-migrated-namespace_wordpress-install.yaml b/docs/transform-scenarios/wordpress-demo/output/resources/new-migrated-namespace/Job_batch_v1_new-migrated-namespace_wordpress-install.yaml new file mode 100644 index 00000000..5910a50a --- /dev/null +++ b/docs/transform-scenarios/wordpress-demo/output/resources/new-migrated-namespace/Job_batch_v1_new-migrated-namespace_wordpress-install.yaml @@ -0,0 +1,144 @@ +apiVersion: batch/v1 +kind: Job +metadata: + labels: + batch.kubernetes.io/controller-uid: be719474-856d-4d84-80ad-4f4ab9ecdd30 + batch.kubernetes.io/job-name: wordpress-install + controller-uid: be719474-856d-4d84-80ad-4f4ab9ecdd30 + job-name: wordpress-install + migrated-with: crane + name: wordpress-install + namespace: new-migrated-namespace +spec: + backoffLimit: 4 + completionMode: NonIndexed + completions: 1 + manualSelector: false + parallelism: 1 + podReplacementPolicy: TerminatingOrFailed + selector: + matchLabels: + batch.kubernetes.io/controller-uid: be719474-856d-4d84-80ad-4f4ab9ecdd30 + migrated-with: crane + suspend: false + template: + metadata: + labels: + batch.kubernetes.io/controller-uid: be719474-856d-4d84-80ad-4f4ab9ecdd30 + batch.kubernetes.io/job-name: wordpress-install + controller-uid: be719474-856d-4d84-80ad-4f4ab9ecdd30 + job-name: wordpress-install + migrated-with: crane + spec: + containers: + - args: + - -lc + - | + set -e + cd /var/www/html + + echo "Waiting for MySQL on ${WORDPRESS_DB_HOST}:3306..." + for i in $(seq 1 60); do + if mariadb-admin ping -h"${WORDPRESS_DB_HOST}" -u"${WORDPRESS_DB_USER}" -p"${WORDPRESS_DB_PASSWORD}" --ssl=false --silent; then + echo "MySQL is up." + break + fi + echo "MySQL not ready yet (attempt: $i)..." + sleep 5 + done + + if ! mariadb-admin ping -h"${WORDPRESS_DB_HOST}" -u"${WORDPRESS_DB_USER}" -p"${WORDPRESS_DB_PASSWORD}" --ssl=false --silent; then + echo "MySQL did not become ready within the timeout." + exit 1 + fi + + # Make sure WordPress core is present on the volume + if [ ! -f wp-load.php ]; then + echo "WordPress core not found on the volume. Downloading..." + wp core download --allow-root + fi + + # Create wp-config.php if missing + if [ ! -f wp-config.php ]; then + echo "Creating wp-config.php..." + wp config create \ + --dbname="${WORDPRESS_DB_NAME}" \ + --dbuser="${WORDPRESS_DB_USER}" \ + --dbpass="${WORDPRESS_DB_PASSWORD}" \ + --dbhost="${WORDPRESS_DB_HOST}" \ + --allow-root + fi + + # Idempotent install + if wp core is-installed --allow-root >/dev/null 2>&1; then + echo "WordPress is already installed. Nothing to do." + exit 0 + fi + + # Create an installation kind of unique ID + WORDPRESS_SEED_ID=$RANDOM + + echo "Running wp core install..." + wp core install \ + --url="${WORDPRESS_SITE_URL}" \ + --title="${WORDPRESS_SITE_TITLE} #$WORDPRESS_SEED_ID" \ + --admin_user="${WORDPRESS_ADMIN_USER}" \ + --admin_password="${WORDPRESS_ADMIN_PASSWORD}" \ + --admin_email="${WORDPRESS_ADMIN_EMAIL}" \ + --skip-email \ + --allow-root + + echo "Creating sample post..." + wp post create \ + --post_type=post \ + --post_status=publish \ + --post_title="Sample post #$WORDPRESS_SEED_ID" \ + --post_content="Hello from k8s, this is a random post content: $(openssl rand -base64 200 | tr -cs 'a-zA-Z' ' ' | xargs)" + + echo "WORDPRESS_SEED_ID=$WORDPRESS_SEED_ID" + echo "Done. WordPress has been installed." + command: + - bash + env: + - name: WORDPRESS_DB_HOST + value: wordpress-mysql + - name: WORDPRESS_DB_USER + value: wordpress + - name: WORDPRESS_DB_NAME + value: wordpress + - name: WORDPRESS_DB_PASSWORD + valueFrom: + secretKeyRef: + key: MYSQL_WORDPRESS_PASSWORD + name: wordpress-secrets-hg692g82th + - name: WORDPRESS_SITE_URL + value: http://wordpress-k8s.example.local + - name: WORDPRESS_SITE_TITLE + value: My WordPress Site on k8s + - name: WORDPRESS_ADMIN_USER + value: admin + - name: WORDPRESS_ADMIN_PASSWORD + valueFrom: + secretKeyRef: + key: WORDPRESS_ADMIN_PASSWORD + name: wordpress-secrets-hg692g82th + - name: WORDPRESS_ADMIN_EMAIL + value: admin@wordpress-k8s.example.local + image: wordpress:cli-2 + imagePullPolicy: IfNotPresent + name: wp-install + resources: {} + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + volumeMounts: + - mountPath: /var/www/html + name: wordpress-persistent-storage + dnsPolicy: ClusterFirst + restartPolicy: OnFailure + schedulerName: default-scheduler + securityContext: {} + terminationGracePeriodSeconds: 30 + volumes: + - name: wordpress-persistent-storage + persistentVolumeClaim: + claimName: wordpress-pv-claim diff --git a/docs/transform-scenarios/wordpress-demo/output/resources/new-migrated-namespace/Secret__v1_new-migrated-namespace_wordpress-secrets-hg692g82th.yaml b/docs/transform-scenarios/wordpress-demo/output/resources/new-migrated-namespace/Secret__v1_new-migrated-namespace_wordpress-secrets-hg692g82th.yaml new file mode 100644 index 00000000..6e481563 --- /dev/null +++ b/docs/transform-scenarios/wordpress-demo/output/resources/new-migrated-namespace/Secret__v1_new-migrated-namespace_wordpress-secrets-hg692g82th.yaml @@ -0,0 +1,12 @@ +apiVersion: v1 +data: + MYSQL_ROOT_PASSWORD: eGFJMmdpdWhxc2V0TC82VDRaOVViUT09 + MYSQL_WORDPRESS_PASSWORD: QzZUa25lcFo3Vm5idTdGZVdBSUFidz09 + WORDPRESS_ADMIN_PASSWORD: d0ZoSytaZDhlU2RhVmx1Ug== +kind: Secret +metadata: + labels: + migrated-with: crane + name: wordpress-secrets-hg692g82th + namespace: new-migrated-namespace +type: Opaque diff --git a/docs/transform-scenarios/wordpress-demo/output/resources/new-migrated-namespace/Service__v1_new-migrated-namespace_kubernetes.yaml b/docs/transform-scenarios/wordpress-demo/output/resources/new-migrated-namespace/Service__v1_new-migrated-namespace_kubernetes.yaml new file mode 100644 index 00000000..c8cbdf96 --- /dev/null +++ b/docs/transform-scenarios/wordpress-demo/output/resources/new-migrated-namespace/Service__v1_new-migrated-namespace_kubernetes.yaml @@ -0,0 +1,23 @@ +apiVersion: v1 +kind: Service +metadata: + labels: + component: apiserver + migrated-with: crane + provider: kubernetes + name: kubernetes + namespace: new-migrated-namespace +spec: + internalTrafficPolicy: Cluster + ipFamilies: + - IPv4 + ipFamilyPolicy: SingleStack + ports: + - name: https + port: 443 + protocol: TCP + targetPort: 8443 + selector: + migrated-with: crane + sessionAffinity: None + type: ClusterIP diff --git a/docs/transform-scenarios/wordpress-demo/output/resources/new-migrated-namespace/Service__v1_new-migrated-namespace_wordpress-mysql.yaml b/docs/transform-scenarios/wordpress-demo/output/resources/new-migrated-namespace/Service__v1_new-migrated-namespace_wordpress-mysql.yaml new file mode 100644 index 00000000..05e7c29d --- /dev/null +++ b/docs/transform-scenarios/wordpress-demo/output/resources/new-migrated-namespace/Service__v1_new-migrated-namespace_wordpress-mysql.yaml @@ -0,0 +1,23 @@ +apiVersion: v1 +kind: Service +metadata: + labels: + app: wordpress + migrated-with: crane + name: wordpress-mysql + namespace: new-migrated-namespace +spec: + internalTrafficPolicy: Cluster + ipFamilies: + - IPv4 + ipFamilyPolicy: SingleStack + ports: + - port: 3306 + protocol: TCP + targetPort: 3306 + selector: + app: wordpress + migrated-with: crane + tier: mysql + sessionAffinity: None + type: ClusterIP diff --git a/docs/transform-scenarios/wordpress-demo/output/resources/new-migrated-namespace/Service__v1_new-migrated-namespace_wordpress.yaml b/docs/transform-scenarios/wordpress-demo/output/resources/new-migrated-namespace/Service__v1_new-migrated-namespace_wordpress.yaml new file mode 100644 index 00000000..097e21a8 --- /dev/null +++ b/docs/transform-scenarios/wordpress-demo/output/resources/new-migrated-namespace/Service__v1_new-migrated-namespace_wordpress.yaml @@ -0,0 +1,25 @@ +apiVersion: v1 +kind: Service +metadata: + labels: + app: wordpress + migrated-with: crane + name: wordpress + namespace: new-migrated-namespace +spec: + allocateLoadBalancerNodePorts: true + externalTrafficPolicy: Cluster + internalTrafficPolicy: Cluster + ipFamilies: + - IPv4 + ipFamilyPolicy: SingleStack + ports: + - port: 80 + protocol: TCP + targetPort: 80 + selector: + app: wordpress + migrated-with: crane + tier: frontend + sessionAffinity: None + type: LoadBalancer diff --git a/docs/transform-scenarios/wordpress-demo/transform/.work/10_KubernetesPlugin/input/default/ConfigMap__v1_default_kube-root-ca.crt.yaml b/docs/transform-scenarios/wordpress-demo/transform/.work/10_KubernetesPlugin/input/default/ConfigMap__v1_default_kube-root-ca.crt.yaml new file mode 100644 index 00000000..e49b6186 --- /dev/null +++ b/docs/transform-scenarios/wordpress-demo/transform/.work/10_KubernetesPlugin/input/default/ConfigMap__v1_default_kube-root-ca.crt.yaml @@ -0,0 +1,48 @@ +apiVersion: v1 +data: + ca.crt: | + -----BEGIN CERTIFICATE----- + MIIDBjCCAe6gAwIBAgIBATANBgkqhkiG9w0BAQsFADAVMRMwEQYDVQQDEwptaW5p + a3ViZUNBMB4XDTIzMDgyMTEzMTEyMFoXDTMzMDgxOTEzMTEyMFowFTETMBEGA1UE + AxMKbWluaWt1YmVDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOUi + L0a0yk+ANnuYn7ESu1z4g1N/xv37Ph6WiSLVutimTpg+vc3lwBVOkW+oM9rXGm3C + DtLr70y2fPBQq5iYwhivH+AiJCT51zh+I992CBMqTZmMYq1Yf2hhuN2xUximuGJg + 7lI4lAfHbn64yYxlYIOwVu58lmmycO3tWrqRM45w0URAmjHqCw7D0z//83nmrU6F + R1f4eY06v1QNNiyBlYCnWWZdusNtYNNGNQ6dRBH5IsvBhmbjN60m6QYZrR+sA1UE + s3lHkYa2lYLkIWbugYfaTZigqxGPUl8GMBtLeYDBRTMRe0WMYW3Gl+w1vjk+2o4v + 5uyvMB5GiUq9AxXvREMCAwEAAaNhMF8wDgYDVR0PAQH/BAQDAgKkMB0GA1UdJQQW + MBQGCCsGAQUFBwMCBggrBgEFBQcDATAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQW + BBRWM9OkFUq3iXhg/okf/Ve1sP3B0jANBgkqhkiG9w0BAQsFAAOCAQEAyw49Smi7 + Dz7SpoNwOd+D44CpuWPE19vG8vdf9+XWQwUy1QhJh21dQkk/U6lF6yVU1RBv32Tm + xYmOtu87fv85bB5lH5WURk/ljAsNo+7sEKWyq9q2cD4A+vh1r2U+EkI0doXYP1um + U42UdLLL2RkxuSqCkdCfCdFpbNz2VOCRlJg93vNUkGsfNehE6xXj4LqCQYXQVHlb + hJLGuKrVtE8dS/lgxc7JmqVo521ft8KKKadHvIP7W0j45sMg9K+OHaUp8cOZ02m2 + J+gRC1xg4A08AAmWV+/q2+byAecrUDf/LQcWwNqjTDRWAELiKLkF5UmbYAIr9wia + FdCTC8qesp6BEw== + -----END CERTIFICATE----- +kind: ConfigMap +metadata: + annotations: + kubernetes.io/description: Contains a CA bundle that can be used to verify the + kube-apiserver when using internal endpoints such as the internal service IP + or kubernetes.default.svc. No other usage is guaranteed across distributions + of Kubernetes clusters. + creationTimestamp: "2026-04-10T12:10:48Z" + managedFields: + - apiVersion: v1 + fieldsType: FieldsV1 + fieldsV1: + f:data: + .: {} + f:ca.crt: {} + f:metadata: + f:annotations: + .: {} + f:kubernetes.io/description: {} + manager: kube-controller-manager + operation: Update + time: "2026-04-10T12:10:48Z" + name: kube-root-ca.crt + namespace: default + resourceVersion: "326" + uid: aa6a6275-00a5-44aa-90c4-5fa00d031c7f diff --git a/docs/transform-scenarios/wordpress-demo/transform/.work/10_KubernetesPlugin/input/default/ConfigMap__v1_default_nginx-config.yaml b/docs/transform-scenarios/wordpress-demo/transform/.work/10_KubernetesPlugin/input/default/ConfigMap__v1_default_nginx-config.yaml new file mode 100644 index 00000000..f43a445c --- /dev/null +++ b/docs/transform-scenarios/wordpress-demo/transform/.work/10_KubernetesPlugin/input/default/ConfigMap__v1_default_nginx-config.yaml @@ -0,0 +1,58 @@ +apiVersion: v1 +data: + nginx.conf: | + events { + worker_connections 64; + } + + http { + include /etc/nginx/mime.types; + default_type application/octet-stream; + + server { + listen 80; + root /var/www/html; + index index.php; + client_max_body_size 32m; + + location / { + try_files $uri $uri/ /index.php?$args; + } + + location ~ \.php$ { + fastcgi_pass localhost:9000; + fastcgi_index index.php; + include fastcgi_params; + fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; + } + } + } +kind: ConfigMap +metadata: + annotations: + kubectl.kubernetes.io/last-applied-configuration: | + {"apiVersion":"v1","data":{"nginx.conf":"events {\n worker_connections 64;\n}\n\nhttp {\n include /etc/nginx/mime.types;\n default_type application/octet-stream;\n\n server {\n listen 80;\n root /var/www/html;\n index index.php;\n client_max_body_size 32m;\n\n location / {\n try_files $uri $uri/ /index.php?$args;\n }\n\n location ~ \\.php$ {\n fastcgi_pass localhost:9000;\n fastcgi_index index.php;\n include fastcgi_params;\n fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;\n }\n }\n}\n"},"kind":"ConfigMap","metadata":{"annotations":{},"labels":{"app":"wordpress"},"name":"nginx-config","namespace":"default"}} + creationTimestamp: "2026-04-10T12:15:07Z" + labels: + app: wordpress + managedFields: + - apiVersion: v1 + fieldsType: FieldsV1 + fieldsV1: + f:data: + .: {} + f:nginx.conf: {} + f:metadata: + f:annotations: + .: {} + f:kubectl.kubernetes.io/last-applied-configuration: {} + f:labels: + .: {} + f:app: {} + manager: kubectl-client-side-apply + operation: Update + time: "2026-04-10T12:15:07Z" + name: nginx-config + namespace: default + resourceVersion: "675" + uid: ced3a8c2-2b9d-47e9-90e6-0a780c2416bd diff --git a/docs/transform-scenarios/wordpress-demo/transform/.work/10_KubernetesPlugin/input/default/Deployment_apps_v1_default_wordpress-mysql.yaml b/docs/transform-scenarios/wordpress-demo/transform/.work/10_KubernetesPlugin/input/default/Deployment_apps_v1_default_wordpress-mysql.yaml new file mode 100644 index 00000000..a373cafc --- /dev/null +++ b/docs/transform-scenarios/wordpress-demo/transform/.work/10_KubernetesPlugin/input/default/Deployment_apps_v1_default_wordpress-mysql.yaml @@ -0,0 +1,209 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + annotations: + deployment.kubernetes.io/revision: "1" + kubectl.kubernetes.io/last-applied-configuration: | + {"apiVersion":"apps/v1","kind":"Deployment","metadata":{"annotations":{},"labels":{"app":"wordpress"},"name":"wordpress-mysql","namespace":"default"},"spec":{"selector":{"matchLabels":{"app":"wordpress","tier":"mysql"}},"strategy":{"type":"Recreate"},"template":{"metadata":{"labels":{"app":"wordpress","tier":"mysql"}},"spec":{"containers":[{"env":[{"name":"MYSQL_ROOT_PASSWORD","valueFrom":{"secretKeyRef":{"key":"MYSQL_ROOT_PASSWORD","name":"wordpress-secrets-hg692g82th"}}},{"name":"MYSQL_DATABASE","value":"wordpress"},{"name":"MYSQL_USER","value":"wordpress"},{"name":"MYSQL_PASSWORD","valueFrom":{"secretKeyRef":{"key":"MYSQL_WORDPRESS_PASSWORD","name":"wordpress-secrets-hg692g82th"}}}],"image":"mysql:8.0","name":"mysql","ports":[{"containerPort":3306,"name":"mysql"}],"volumeMounts":[{"mountPath":"/var/lib/mysql","name":"mysql-persistent-storage"}]}],"volumes":[{"name":"mysql-persistent-storage","persistentVolumeClaim":{"claimName":"mysql-pv-claim"}}]}}}} + creationTimestamp: "2026-04-10T12:15:08Z" + generation: 1 + labels: + app: wordpress + managedFields: + - apiVersion: apps/v1 + fieldsType: FieldsV1 + fieldsV1: + f:metadata: + f:annotations: + .: {} + f:kubectl.kubernetes.io/last-applied-configuration: {} + f:labels: + .: {} + f:app: {} + f:spec: + f:progressDeadlineSeconds: {} + f:replicas: {} + f:revisionHistoryLimit: {} + f:selector: {} + f:strategy: + f:type: {} + f:template: + f:metadata: + f:labels: + .: {} + f:app: {} + f:tier: {} + f:spec: + f:containers: + k:{"name":"mysql"}: + .: {} + f:env: + .: {} + k:{"name":"MYSQL_DATABASE"}: + .: {} + f:name: {} + f:value: {} + k:{"name":"MYSQL_PASSWORD"}: + .: {} + f:name: {} + f:valueFrom: + .: {} + f:secretKeyRef: {} + k:{"name":"MYSQL_ROOT_PASSWORD"}: + .: {} + f:name: {} + f:valueFrom: + .: {} + f:secretKeyRef: {} + k:{"name":"MYSQL_USER"}: + .: {} + f:name: {} + f:value: {} + f:image: {} + f:imagePullPolicy: {} + f:name: {} + f:ports: + .: {} + k:{"containerPort":3306,"protocol":"TCP"}: + .: {} + f:containerPort: {} + f:name: {} + f:protocol: {} + f:resources: {} + f:terminationMessagePath: {} + f:terminationMessagePolicy: {} + f:volumeMounts: + .: {} + k:{"mountPath":"/var/lib/mysql"}: + .: {} + f:mountPath: {} + f:name: {} + f:dnsPolicy: {} + f:restartPolicy: {} + f:schedulerName: {} + f:securityContext: {} + f:terminationGracePeriodSeconds: {} + f:volumes: + .: {} + k:{"name":"mysql-persistent-storage"}: + .: {} + f:name: {} + f:persistentVolumeClaim: + .: {} + f:claimName: {} + manager: kubectl-client-side-apply + operation: Update + time: "2026-04-10T12:15:08Z" + - apiVersion: apps/v1 + fieldsType: FieldsV1 + fieldsV1: + f:metadata: + f:annotations: + f:deployment.kubernetes.io/revision: {} + f:status: + f:availableReplicas: {} + f:conditions: + .: {} + k:{"type":"Available"}: + .: {} + f:lastTransitionTime: {} + f:lastUpdateTime: {} + f:message: {} + f:reason: {} + f:status: {} + f:type: {} + k:{"type":"Progressing"}: + .: {} + f:lastTransitionTime: {} + f:lastUpdateTime: {} + f:message: {} + f:reason: {} + f:status: {} + f:type: {} + f:observedGeneration: {} + f:readyReplicas: {} + f:replicas: {} + f:terminatingReplicas: {} + f:updatedReplicas: {} + manager: kube-controller-manager + operation: Update + subresource: status + time: "2026-04-10T12:15:58Z" + name: wordpress-mysql + namespace: default + resourceVersion: "800" + uid: 2eba9391-46db-4860-9f9a-a1cb396faf18 +spec: + progressDeadlineSeconds: 600 + replicas: 1 + revisionHistoryLimit: 10 + selector: + matchLabels: + app: wordpress + tier: mysql + strategy: + type: Recreate + template: + metadata: + labels: + app: wordpress + tier: mysql + spec: + containers: + - env: + - name: MYSQL_ROOT_PASSWORD + valueFrom: + secretKeyRef: + key: MYSQL_ROOT_PASSWORD + name: wordpress-secrets-hg692g82th + - name: MYSQL_DATABASE + value: wordpress + - name: MYSQL_USER + value: wordpress + - name: MYSQL_PASSWORD + valueFrom: + secretKeyRef: + key: MYSQL_WORDPRESS_PASSWORD + name: wordpress-secrets-hg692g82th + image: mysql:8.0 + imagePullPolicy: IfNotPresent + name: mysql + ports: + - containerPort: 3306 + name: mysql + protocol: TCP + resources: {} + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + volumeMounts: + - mountPath: /var/lib/mysql + name: mysql-persistent-storage + dnsPolicy: ClusterFirst + restartPolicy: Always + schedulerName: default-scheduler + securityContext: {} + terminationGracePeriodSeconds: 30 + volumes: + - name: mysql-persistent-storage + persistentVolumeClaim: + claimName: mysql-pv-claim +status: + availableReplicas: 1 + conditions: + - lastTransitionTime: "2026-04-10T12:15:58Z" + lastUpdateTime: "2026-04-10T12:15:58Z" + message: Deployment has minimum availability. + reason: MinimumReplicasAvailable + status: "True" + type: Available + - lastTransitionTime: "2026-04-10T12:15:08Z" + lastUpdateTime: "2026-04-10T12:15:58Z" + message: ReplicaSet "wordpress-mysql-9474c86b" has successfully progressed. + reason: NewReplicaSetAvailable + status: "True" + type: Progressing + observedGeneration: 1 + readyReplicas: 1 + replicas: 1 + terminatingReplicas: 0 + updatedReplicas: 1 diff --git a/docs/transform-scenarios/wordpress-demo/transform/.work/10_KubernetesPlugin/input/default/Deployment_apps_v1_default_wordpress.yaml b/docs/transform-scenarios/wordpress-demo/transform/.work/10_KubernetesPlugin/input/default/Deployment_apps_v1_default_wordpress.yaml new file mode 100644 index 00000000..b49641ca --- /dev/null +++ b/docs/transform-scenarios/wordpress-demo/transform/.work/10_KubernetesPlugin/input/default/Deployment_apps_v1_default_wordpress.yaml @@ -0,0 +1,268 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + annotations: + deployment.kubernetes.io/revision: "1" + kubectl.kubernetes.io/last-applied-configuration: | + {"apiVersion":"apps/v1","kind":"Deployment","metadata":{"annotations":{},"labels":{"app":"wordpress"},"name":"wordpress","namespace":"default"},"spec":{"selector":{"matchLabels":{"app":"wordpress","tier":"frontend"}},"strategy":{"type":"Recreate"},"template":{"metadata":{"labels":{"app":"wordpress","tier":"frontend"}},"spec":{"containers":[{"env":[{"name":"WORDPRESS_DB_HOST","value":"wordpress-mysql"},{"name":"WORDPRESS_DB_PASSWORD","valueFrom":{"secretKeyRef":{"key":"MYSQL_WORDPRESS_PASSWORD","name":"wordpress-secrets-hg692g82th"}}},{"name":"WORDPRESS_DB_USER","value":"wordpress"},{"name":"WORDPRESS_CONFIG_EXTRA","value":"// Set SITE URL dynamically from requests to allow reach it on different endpoints\nif (isset($_SERVER['HTTP_HOST'])) {\n $protocol = (isset($_SERVER['HTTPS']) \u0026\u0026 $_SERVER['HTTPS'] === 'on') ? 'https' : 'http';\n if (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) \u0026\u0026 $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https') {\n $protocol = 'https';\n }\n define('WP_HOME', $protocol . '://' . $_SERVER['HTTP_HOST']);\n define('WP_SITEURL', $protocol . '://' . $_SERVER['HTTP_HOST']);\n}\n"}],"image":"wordpress:6-fpm-alpine","name":"wordpress","ports":[{"containerPort":9000,"name":"fastcgi"}],"volumeMounts":[{"mountPath":"/var/www/html","name":"wordpress-persistent-storage"}]},{"image":"nginx:alpine","name":"nginx","ports":[{"containerPort":80,"name":"http"}],"volumeMounts":[{"mountPath":"/var/www/html","name":"wordpress-persistent-storage","readOnly":true},{"mountPath":"/etc/nginx/nginx.conf","name":"nginx-config","subPath":"nginx.conf"}]}],"volumes":[{"name":"wordpress-persistent-storage","persistentVolumeClaim":{"claimName":"wordpress-pv-claim"}},{"configMap":{"name":"nginx-config"},"name":"nginx-config"}]}}}} + creationTimestamp: "2026-04-10T12:15:08Z" + generation: 1 + labels: + app: wordpress + managedFields: + - apiVersion: apps/v1 + fieldsType: FieldsV1 + fieldsV1: + f:metadata: + f:annotations: + .: {} + f:kubectl.kubernetes.io/last-applied-configuration: {} + f:labels: + .: {} + f:app: {} + f:spec: + f:progressDeadlineSeconds: {} + f:replicas: {} + f:revisionHistoryLimit: {} + f:selector: {} + f:strategy: + f:type: {} + f:template: + f:metadata: + f:labels: + .: {} + f:app: {} + f:tier: {} + f:spec: + f:containers: + k:{"name":"nginx"}: + .: {} + f:image: {} + f:imagePullPolicy: {} + f:name: {} + f:ports: + .: {} + k:{"containerPort":80,"protocol":"TCP"}: + .: {} + f:containerPort: {} + f:name: {} + f:protocol: {} + f:resources: {} + f:terminationMessagePath: {} + f:terminationMessagePolicy: {} + f:volumeMounts: + .: {} + k:{"mountPath":"/etc/nginx/nginx.conf"}: + .: {} + f:mountPath: {} + f:name: {} + f:subPath: {} + k:{"mountPath":"/var/www/html"}: + .: {} + f:mountPath: {} + f:name: {} + f:readOnly: {} + k:{"name":"wordpress"}: + .: {} + f:env: + .: {} + k:{"name":"WORDPRESS_CONFIG_EXTRA"}: + .: {} + f:name: {} + f:value: {} + k:{"name":"WORDPRESS_DB_HOST"}: + .: {} + f:name: {} + f:value: {} + k:{"name":"WORDPRESS_DB_PASSWORD"}: + .: {} + f:name: {} + f:valueFrom: + .: {} + f:secretKeyRef: {} + k:{"name":"WORDPRESS_DB_USER"}: + .: {} + f:name: {} + f:value: {} + f:image: {} + f:imagePullPolicy: {} + f:name: {} + f:ports: + .: {} + k:{"containerPort":9000,"protocol":"TCP"}: + .: {} + f:containerPort: {} + f:name: {} + f:protocol: {} + f:resources: {} + f:terminationMessagePath: {} + f:terminationMessagePolicy: {} + f:volumeMounts: + .: {} + k:{"mountPath":"/var/www/html"}: + .: {} + f:mountPath: {} + f:name: {} + f:dnsPolicy: {} + f:restartPolicy: {} + f:schedulerName: {} + f:securityContext: {} + f:terminationGracePeriodSeconds: {} + f:volumes: + .: {} + k:{"name":"nginx-config"}: + .: {} + f:configMap: + .: {} + f:defaultMode: {} + f:name: {} + f:name: {} + k:{"name":"wordpress-persistent-storage"}: + .: {} + f:name: {} + f:persistentVolumeClaim: + .: {} + f:claimName: {} + manager: kubectl-client-side-apply + operation: Update + time: "2026-04-10T12:15:08Z" + - apiVersion: apps/v1 + fieldsType: FieldsV1 + fieldsV1: + f:metadata: + f:annotations: + f:deployment.kubernetes.io/revision: {} + f:status: + f:availableReplicas: {} + f:conditions: + .: {} + k:{"type":"Available"}: + .: {} + f:lastTransitionTime: {} + f:lastUpdateTime: {} + f:message: {} + f:reason: {} + f:status: {} + f:type: {} + k:{"type":"Progressing"}: + .: {} + f:lastTransitionTime: {} + f:lastUpdateTime: {} + f:message: {} + f:reason: {} + f:status: {} + f:type: {} + f:observedGeneration: {} + f:readyReplicas: {} + f:replicas: {} + f:terminatingReplicas: {} + f:updatedReplicas: {} + manager: kube-controller-manager + operation: Update + subresource: status + time: "2026-04-10T12:16:04Z" + name: wordpress + namespace: default + resourceVersion: "812" + uid: 32f30549-f011-48b1-8398-64fef74b2df1 +spec: + progressDeadlineSeconds: 600 + replicas: 1 + revisionHistoryLimit: 10 + selector: + matchLabels: + app: wordpress + tier: frontend + strategy: + type: Recreate + template: + metadata: + labels: + app: wordpress + tier: frontend + spec: + containers: + - env: + - name: WORDPRESS_DB_HOST + value: wordpress-mysql + - name: WORDPRESS_DB_PASSWORD + valueFrom: + secretKeyRef: + key: MYSQL_WORDPRESS_PASSWORD + name: wordpress-secrets-hg692g82th + - name: WORDPRESS_DB_USER + value: wordpress + - name: WORDPRESS_CONFIG_EXTRA + value: | + // Set SITE URL dynamically from requests to allow reach it on different endpoints + if (isset($_SERVER['HTTP_HOST'])) { + $protocol = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on') ? 'https' : 'http'; + if (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https') { + $protocol = 'https'; + } + define('WP_HOME', $protocol . '://' . $_SERVER['HTTP_HOST']); + define('WP_SITEURL', $protocol . '://' . $_SERVER['HTTP_HOST']); + } + image: wordpress:6-fpm-alpine + imagePullPolicy: IfNotPresent + name: wordpress + ports: + - containerPort: 9000 + name: fastcgi + protocol: TCP + resources: {} + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + volumeMounts: + - mountPath: /var/www/html + name: wordpress-persistent-storage + - image: nginx:alpine + imagePullPolicy: IfNotPresent + name: nginx + ports: + - containerPort: 80 + name: http + protocol: TCP + resources: {} + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + volumeMounts: + - mountPath: /var/www/html + name: wordpress-persistent-storage + readOnly: true + - mountPath: /etc/nginx/nginx.conf + name: nginx-config + subPath: nginx.conf + dnsPolicy: ClusterFirst + restartPolicy: Always + schedulerName: default-scheduler + securityContext: {} + terminationGracePeriodSeconds: 30 + volumes: + - name: wordpress-persistent-storage + persistentVolumeClaim: + claimName: wordpress-pv-claim + - configMap: + defaultMode: 420 + name: nginx-config + name: nginx-config +status: + availableReplicas: 1 + conditions: + - lastTransitionTime: "2026-04-10T12:16:04Z" + lastUpdateTime: "2026-04-10T12:16:04Z" + message: Deployment has minimum availability. + reason: MinimumReplicasAvailable + status: "True" + type: Available + - lastTransitionTime: "2026-04-10T12:15:08Z" + lastUpdateTime: "2026-04-10T12:16:04Z" + message: ReplicaSet "wordpress-74b89cc84c" has successfully progressed. + reason: NewReplicaSetAvailable + status: "True" + type: Progressing + observedGeneration: 1 + readyReplicas: 1 + replicas: 1 + terminatingReplicas: 0 + updatedReplicas: 1 diff --git a/docs/transform-scenarios/wordpress-demo/transform/.work/10_KubernetesPlugin/input/default/EndpointSlice_discovery.k8s.io_v1_default_kubernetes.yaml b/docs/transform-scenarios/wordpress-demo/transform/.work/10_KubernetesPlugin/input/default/EndpointSlice_discovery.k8s.io_v1_default_kubernetes.yaml new file mode 100644 index 00000000..27aedea1 --- /dev/null +++ b/docs/transform-scenarios/wordpress-demo/transform/.work/10_KubernetesPlugin/input/default/EndpointSlice_discovery.k8s.io_v1_default_kubernetes.yaml @@ -0,0 +1,35 @@ +addressType: IPv4 +apiVersion: discovery.k8s.io/v1 +endpoints: +- addresses: + - 192.168.61.192 + conditions: + ready: true +kind: EndpointSlice +metadata: + creationTimestamp: "2026-04-10T12:10:43Z" + generation: 1 + labels: + kubernetes.io/service-name: kubernetes + managedFields: + - apiVersion: discovery.k8s.io/v1 + fieldsType: FieldsV1 + fieldsV1: + f:addressType: {} + f:endpoints: {} + f:metadata: + f:labels: + .: {} + f:kubernetes.io/service-name: {} + f:ports: {} + manager: kube-apiserver + operation: Update + time: "2026-04-10T12:10:43Z" + name: kubernetes + namespace: default + resourceVersion: "207" + uid: c4e8cffe-1b65-44c3-ba96-fb9dc76493ed +ports: +- name: https + port: 8443 + protocol: TCP diff --git a/docs/transform-scenarios/wordpress-demo/transform/.work/10_KubernetesPlugin/input/default/EndpointSlice_discovery.k8s.io_v1_default_wordpress-mysql-jlwnp.yaml b/docs/transform-scenarios/wordpress-demo/transform/.work/10_KubernetesPlugin/input/default/EndpointSlice_discovery.k8s.io_v1_default_wordpress-mysql-jlwnp.yaml new file mode 100644 index 00000000..77b44207 --- /dev/null +++ b/docs/transform-scenarios/wordpress-demo/transform/.work/10_KubernetesPlugin/input/default/EndpointSlice_discovery.k8s.io_v1_default_wordpress-mysql-jlwnp.yaml @@ -0,0 +1,64 @@ +addressType: IPv4 +apiVersion: discovery.k8s.io/v1 +endpoints: +- addresses: + - 10.244.0.6 + conditions: + ready: true + serving: true + terminating: false + nodeName: minikube + targetRef: + kind: Pod + name: wordpress-mysql-9474c86b-fr65w + namespace: default + uid: f81b40e3-ff85-46ca-8b0a-5c826b78f0c8 +kind: EndpointSlice +metadata: + annotations: + endpoints.kubernetes.io/last-change-trigger-time: "2026-04-10T12:15:58Z" + creationTimestamp: "2026-04-10T12:15:07Z" + generateName: wordpress-mysql- + generation: 2 + labels: + app: wordpress + endpointslice.kubernetes.io/managed-by: endpointslice-controller.k8s.io + kubernetes.io/service-name: wordpress-mysql + managedFields: + - apiVersion: discovery.k8s.io/v1 + fieldsType: FieldsV1 + fieldsV1: + f:addressType: {} + f:endpoints: {} + f:metadata: + f:annotations: + .: {} + f:endpoints.kubernetes.io/last-change-trigger-time: {} + f:generateName: {} + f:labels: + .: {} + f:app: {} + f:endpointslice.kubernetes.io/managed-by: {} + f:kubernetes.io/service-name: {} + f:ownerReferences: + .: {} + k:{"uid":"ec2555f1-9fd5-45da-bfa3-f2b59bb1d218"}: {} + f:ports: {} + manager: kube-controller-manager + operation: Update + time: "2026-04-10T12:15:58Z" + name: wordpress-mysql-jlwnp + namespace: default + ownerReferences: + - apiVersion: v1 + blockOwnerDeletion: true + controller: true + kind: Service + name: wordpress-mysql + uid: ec2555f1-9fd5-45da-bfa3-f2b59bb1d218 + resourceVersion: "796" + uid: d4c94c5d-1297-4184-91ae-24e6e0bb315b +ports: +- name: "" + port: 3306 + protocol: TCP diff --git a/docs/transform-scenarios/wordpress-demo/transform/.work/10_KubernetesPlugin/input/default/EndpointSlice_discovery.k8s.io_v1_default_wordpress-wpfqk.yaml b/docs/transform-scenarios/wordpress-demo/transform/.work/10_KubernetesPlugin/input/default/EndpointSlice_discovery.k8s.io_v1_default_wordpress-wpfqk.yaml new file mode 100644 index 00000000..e215d23b --- /dev/null +++ b/docs/transform-scenarios/wordpress-demo/transform/.work/10_KubernetesPlugin/input/default/EndpointSlice_discovery.k8s.io_v1_default_wordpress-wpfqk.yaml @@ -0,0 +1,64 @@ +addressType: IPv4 +apiVersion: discovery.k8s.io/v1 +endpoints: +- addresses: + - 10.244.0.5 + conditions: + ready: true + serving: true + terminating: false + nodeName: minikube + targetRef: + kind: Pod + name: wordpress-74b89cc84c-nm9f8 + namespace: default + uid: 608501ac-fd76-48a1-b9ef-058b7a6ade67 +kind: EndpointSlice +metadata: + annotations: + endpoints.kubernetes.io/last-change-trigger-time: "2026-04-10T12:16:04Z" + creationTimestamp: "2026-04-10T12:15:07Z" + generateName: wordpress- + generation: 2 + labels: + app: wordpress + endpointslice.kubernetes.io/managed-by: endpointslice-controller.k8s.io + kubernetes.io/service-name: wordpress + managedFields: + - apiVersion: discovery.k8s.io/v1 + fieldsType: FieldsV1 + fieldsV1: + f:addressType: {} + f:endpoints: {} + f:metadata: + f:annotations: + .: {} + f:endpoints.kubernetes.io/last-change-trigger-time: {} + f:generateName: {} + f:labels: + .: {} + f:app: {} + f:endpointslice.kubernetes.io/managed-by: {} + f:kubernetes.io/service-name: {} + f:ownerReferences: + .: {} + k:{"uid":"9bd59883-6312-4534-a2c1-b71911612715"}: {} + f:ports: {} + manager: kube-controller-manager + operation: Update + time: "2026-04-10T12:16:04Z" + name: wordpress-wpfqk + namespace: default + ownerReferences: + - apiVersion: v1 + blockOwnerDeletion: true + controller: true + kind: Service + name: wordpress + uid: 9bd59883-6312-4534-a2c1-b71911612715 + resourceVersion: "810" + uid: 1a4fffdb-dbcd-4729-905b-11be74b19710 +ports: +- name: "" + port: 80 + protocol: TCP diff --git a/docs/transform-scenarios/wordpress-demo/transform/.work/10_KubernetesPlugin/input/default/Endpoints__v1_default_kubernetes.yaml b/docs/transform-scenarios/wordpress-demo/transform/.work/10_KubernetesPlugin/input/default/Endpoints__v1_default_kubernetes.yaml new file mode 100644 index 00000000..b6b5cbb0 --- /dev/null +++ b/docs/transform-scenarios/wordpress-demo/transform/.work/10_KubernetesPlugin/input/default/Endpoints__v1_default_kubernetes.yaml @@ -0,0 +1,29 @@ +apiVersion: v1 +kind: Endpoints +metadata: + creationTimestamp: "2026-04-10T12:10:43Z" + labels: + endpointslice.kubernetes.io/skip-mirror: "true" + managedFields: + - apiVersion: v1 + fieldsType: FieldsV1 + fieldsV1: + f:metadata: + f:labels: + .: {} + f:endpointslice.kubernetes.io/skip-mirror: {} + f:subsets: {} + manager: kube-apiserver + operation: Update + time: "2026-04-10T12:10:43Z" + name: kubernetes + namespace: default + resourceVersion: "206" + uid: 39324cbc-0a0d-4795-8712-4106fdf1424c +subsets: +- addresses: + - ip: 192.168.61.192 + ports: + - name: https + port: 8443 + protocol: TCP diff --git a/docs/transform-scenarios/wordpress-demo/transform/.work/10_KubernetesPlugin/input/default/Endpoints__v1_default_wordpress-mysql.yaml b/docs/transform-scenarios/wordpress-demo/transform/.work/10_KubernetesPlugin/input/default/Endpoints__v1_default_wordpress-mysql.yaml new file mode 100644 index 00000000..3653d619 --- /dev/null +++ b/docs/transform-scenarios/wordpress-demo/transform/.work/10_KubernetesPlugin/input/default/Endpoints__v1_default_wordpress-mysql.yaml @@ -0,0 +1,41 @@ +apiVersion: v1 +kind: Endpoints +metadata: + annotations: + endpoints.kubernetes.io/last-change-trigger-time: "2026-04-10T12:15:58Z" + creationTimestamp: "2026-04-10T12:15:07Z" + labels: + app: wordpress + endpoints.kubernetes.io/managed-by: endpoint-controller + managedFields: + - apiVersion: v1 + fieldsType: FieldsV1 + fieldsV1: + f:metadata: + f:annotations: + .: {} + f:endpoints.kubernetes.io/last-change-trigger-time: {} + f:labels: + .: {} + f:app: {} + f:endpoints.kubernetes.io/managed-by: {} + f:subsets: {} + manager: kube-controller-manager + operation: Update + time: "2026-04-10T12:15:58Z" + name: wordpress-mysql + namespace: default + resourceVersion: "797" + uid: c2cf2659-9d5c-4f2e-9e3f-6da1b9c6f2c0 +subsets: +- addresses: + - ip: 10.244.0.6 + nodeName: minikube + targetRef: + kind: Pod + name: wordpress-mysql-9474c86b-fr65w + namespace: default + uid: f81b40e3-ff85-46ca-8b0a-5c826b78f0c8 + ports: + - port: 3306 + protocol: TCP diff --git a/docs/transform-scenarios/wordpress-demo/transform/.work/10_KubernetesPlugin/input/default/Endpoints__v1_default_wordpress.yaml b/docs/transform-scenarios/wordpress-demo/transform/.work/10_KubernetesPlugin/input/default/Endpoints__v1_default_wordpress.yaml new file mode 100644 index 00000000..6ebd61ce --- /dev/null +++ b/docs/transform-scenarios/wordpress-demo/transform/.work/10_KubernetesPlugin/input/default/Endpoints__v1_default_wordpress.yaml @@ -0,0 +1,41 @@ +apiVersion: v1 +kind: Endpoints +metadata: + annotations: + endpoints.kubernetes.io/last-change-trigger-time: "2026-04-10T12:16:04Z" + creationTimestamp: "2026-04-10T12:15:07Z" + labels: + app: wordpress + endpoints.kubernetes.io/managed-by: endpoint-controller + managedFields: + - apiVersion: v1 + fieldsType: FieldsV1 + fieldsV1: + f:metadata: + f:annotations: + .: {} + f:endpoints.kubernetes.io/last-change-trigger-time: {} + f:labels: + .: {} + f:app: {} + f:endpoints.kubernetes.io/managed-by: {} + f:subsets: {} + manager: kube-controller-manager + operation: Update + time: "2026-04-10T12:16:04Z" + name: wordpress + namespace: default + resourceVersion: "809" + uid: 7a7a7061-0064-42f9-ad24-f4dbbd13b8b4 +subsets: +- addresses: + - ip: 10.244.0.5 + nodeName: minikube + targetRef: + kind: Pod + name: wordpress-74b89cc84c-nm9f8 + namespace: default + uid: 608501ac-fd76-48a1-b9ef-058b7a6ade67 + ports: + - port: 80 + protocol: TCP diff --git a/docs/transform-scenarios/wordpress-demo/transform/.work/10_KubernetesPlugin/input/default/Job_batch_v1_default_wordpress-install.yaml b/docs/transform-scenarios/wordpress-demo/transform/.work/10_KubernetesPlugin/input/default/Job_batch_v1_default_wordpress-install.yaml new file mode 100644 index 00000000..0c6f48bf --- /dev/null +++ b/docs/transform-scenarios/wordpress-demo/transform/.work/10_KubernetesPlugin/input/default/Job_batch_v1_default_wordpress-install.yaml @@ -0,0 +1,276 @@ +apiVersion: batch/v1 +kind: Job +metadata: + annotations: + kubectl.kubernetes.io/last-applied-configuration: | + {"apiVersion":"batch/v1","kind":"Job","metadata":{"annotations":{},"name":"wordpress-install","namespace":"default"},"spec":{"backoffLimit":4,"template":{"spec":{"containers":[{"args":["-lc","set -e\ncd /var/www/html\n\necho \"Waiting for MySQL on ${WORDPRESS_DB_HOST}:3306...\"\nfor i in $(seq 1 60); do\n if mariadb-admin ping -h\"${WORDPRESS_DB_HOST}\" -u\"${WORDPRESS_DB_USER}\" -p\"${WORDPRESS_DB_PASSWORD}\" --ssl=false --silent; then\n echo \"MySQL is up.\"\n break\n fi\n echo \"MySQL not ready yet (attempt: $i)...\"\n sleep 5\ndone\n\nif ! mariadb-admin ping -h\"${WORDPRESS_DB_HOST}\" -u\"${WORDPRESS_DB_USER}\" -p\"${WORDPRESS_DB_PASSWORD}\" --ssl=false --silent; then\n echo \"MySQL did not become ready within the timeout.\"\n exit 1\nfi\n\n# Make sure WordPress core is present on the volume\nif [ ! -f wp-load.php ]; then\n echo \"WordPress core not found on the volume. Downloading...\"\n wp core download --allow-root\nfi\n\n# Create wp-config.php if missing\nif [ ! -f wp-config.php ]; then\n echo \"Creating wp-config.php...\"\n wp config create \\\n --dbname=\"${WORDPRESS_DB_NAME}\" \\\n --dbuser=\"${WORDPRESS_DB_USER}\" \\\n --dbpass=\"${WORDPRESS_DB_PASSWORD}\" \\\n --dbhost=\"${WORDPRESS_DB_HOST}\" \\\n --allow-root\nfi\n\n# Idempotent install\nif wp core is-installed --allow-root \u003e/dev/null 2\u003e\u00261; then\n echo \"WordPress is already installed. Nothing to do.\"\n exit 0\nfi\n\n# Create an installation kind of unique ID\nWORDPRESS_SEED_ID=$RANDOM\n\necho \"Running wp core install...\"\nwp core install \\\n --url=\"${WORDPRESS_SITE_URL}\" \\\n --title=\"${WORDPRESS_SITE_TITLE} #$WORDPRESS_SEED_ID\" \\\n --admin_user=\"${WORDPRESS_ADMIN_USER}\" \\\n --admin_password=\"${WORDPRESS_ADMIN_PASSWORD}\" \\\n --admin_email=\"${WORDPRESS_ADMIN_EMAIL}\" \\\n --skip-email \\\n --allow-root\n\necho \"Creating sample post...\"\nwp post create \\\n --post_type=post \\\n --post_status=publish \\\n --post_title=\"Sample post #$WORDPRESS_SEED_ID\" \\\n --post_content=\"Hello from k8s, this is a random post content: $(openssl rand -base64 200 | tr -cs 'a-zA-Z' ' ' | xargs)\"\n\necho \"WORDPRESS_SEED_ID=$WORDPRESS_SEED_ID\"\necho \"Done. WordPress has been installed.\"\n"],"command":["bash"],"env":[{"name":"WORDPRESS_DB_HOST","value":"wordpress-mysql"},{"name":"WORDPRESS_DB_USER","value":"wordpress"},{"name":"WORDPRESS_DB_NAME","value":"wordpress"},{"name":"WORDPRESS_DB_PASSWORD","valueFrom":{"secretKeyRef":{"key":"MYSQL_WORDPRESS_PASSWORD","name":"wordpress-secrets-hg692g82th"}}},{"name":"WORDPRESS_SITE_URL","value":"http://wordpress-k8s.example.local"},{"name":"WORDPRESS_SITE_TITLE","value":"My WordPress Site on k8s"},{"name":"WORDPRESS_ADMIN_USER","value":"admin"},{"name":"WORDPRESS_ADMIN_PASSWORD","valueFrom":{"secretKeyRef":{"key":"WORDPRESS_ADMIN_PASSWORD","name":"wordpress-secrets-hg692g82th"}}},{"name":"WORDPRESS_ADMIN_EMAIL","value":"admin@wordpress-k8s.example.local"}],"image":"wordpress:cli-2","imagePullPolicy":"IfNotPresent","name":"wp-install","volumeMounts":[{"mountPath":"/var/www/html","name":"wordpress-persistent-storage"}]}],"restartPolicy":"OnFailure","volumes":[{"name":"wordpress-persistent-storage","persistentVolumeClaim":{"claimName":"wordpress-pv-claim"}}]}}}} + creationTimestamp: "2026-04-10T12:15:08Z" + generation: 1 + labels: + batch.kubernetes.io/controller-uid: be719474-856d-4d84-80ad-4f4ab9ecdd30 + batch.kubernetes.io/job-name: wordpress-install + controller-uid: be719474-856d-4d84-80ad-4f4ab9ecdd30 + job-name: wordpress-install + managedFields: + - apiVersion: batch/v1 + fieldsType: FieldsV1 + fieldsV1: + f:metadata: + f:annotations: + .: {} + f:kubectl.kubernetes.io/last-applied-configuration: {} + f:spec: + f:backoffLimit: {} + f:completionMode: {} + f:completions: {} + f:manualSelector: {} + f:parallelism: {} + f:podReplacementPolicy: {} + f:suspend: {} + f:template: + f:spec: + f:containers: + k:{"name":"wp-install"}: + .: {} + f:args: {} + f:command: {} + f:env: + .: {} + k:{"name":"WORDPRESS_ADMIN_EMAIL"}: + .: {} + f:name: {} + f:value: {} + k:{"name":"WORDPRESS_ADMIN_PASSWORD"}: + .: {} + f:name: {} + f:valueFrom: + .: {} + f:secretKeyRef: {} + k:{"name":"WORDPRESS_ADMIN_USER"}: + .: {} + f:name: {} + f:value: {} + k:{"name":"WORDPRESS_DB_HOST"}: + .: {} + f:name: {} + f:value: {} + k:{"name":"WORDPRESS_DB_NAME"}: + .: {} + f:name: {} + f:value: {} + k:{"name":"WORDPRESS_DB_PASSWORD"}: + .: {} + f:name: {} + f:valueFrom: + .: {} + f:secretKeyRef: {} + k:{"name":"WORDPRESS_DB_USER"}: + .: {} + f:name: {} + f:value: {} + k:{"name":"WORDPRESS_SITE_TITLE"}: + .: {} + f:name: {} + f:value: {} + k:{"name":"WORDPRESS_SITE_URL"}: + .: {} + f:name: {} + f:value: {} + f:image: {} + f:imagePullPolicy: {} + f:name: {} + f:resources: {} + f:terminationMessagePath: {} + f:terminationMessagePolicy: {} + f:volumeMounts: + .: {} + k:{"mountPath":"/var/www/html"}: + .: {} + f:mountPath: {} + f:name: {} + f:dnsPolicy: {} + f:restartPolicy: {} + f:schedulerName: {} + f:securityContext: {} + f:terminationGracePeriodSeconds: {} + f:volumes: + .: {} + k:{"name":"wordpress-persistent-storage"}: + .: {} + f:name: {} + f:persistentVolumeClaim: + .: {} + f:claimName: {} + manager: kubectl-client-side-apply + operation: Update + time: "2026-04-10T12:15:08Z" + - apiVersion: batch/v1 + fieldsType: FieldsV1 + fieldsV1: + f:status: + f:completionTime: {} + f:conditions: {} + f:ready: {} + f:startTime: {} + f:succeeded: {} + f:terminating: {} + f:uncountedTerminatedPods: {} + manager: kube-controller-manager + operation: Update + subresource: status + time: "2026-04-10T12:16:48Z" + name: wordpress-install + namespace: default + resourceVersion: "854" + uid: be719474-856d-4d84-80ad-4f4ab9ecdd30 +spec: + backoffLimit: 4 + completionMode: NonIndexed + completions: 1 + manualSelector: false + parallelism: 1 + podReplacementPolicy: TerminatingOrFailed + selector: + matchLabels: + batch.kubernetes.io/controller-uid: be719474-856d-4d84-80ad-4f4ab9ecdd30 + suspend: false + template: + metadata: + labels: + batch.kubernetes.io/controller-uid: be719474-856d-4d84-80ad-4f4ab9ecdd30 + batch.kubernetes.io/job-name: wordpress-install + controller-uid: be719474-856d-4d84-80ad-4f4ab9ecdd30 + job-name: wordpress-install + spec: + containers: + - args: + - -lc + - | + set -e + cd /var/www/html + + echo "Waiting for MySQL on ${WORDPRESS_DB_HOST}:3306..." + for i in $(seq 1 60); do + if mariadb-admin ping -h"${WORDPRESS_DB_HOST}" -u"${WORDPRESS_DB_USER}" -p"${WORDPRESS_DB_PASSWORD}" --ssl=false --silent; then + echo "MySQL is up." + break + fi + echo "MySQL not ready yet (attempt: $i)..." + sleep 5 + done + + if ! mariadb-admin ping -h"${WORDPRESS_DB_HOST}" -u"${WORDPRESS_DB_USER}" -p"${WORDPRESS_DB_PASSWORD}" --ssl=false --silent; then + echo "MySQL did not become ready within the timeout." + exit 1 + fi + + # Make sure WordPress core is present on the volume + if [ ! -f wp-load.php ]; then + echo "WordPress core not found on the volume. Downloading..." + wp core download --allow-root + fi + + # Create wp-config.php if missing + if [ ! -f wp-config.php ]; then + echo "Creating wp-config.php..." + wp config create \ + --dbname="${WORDPRESS_DB_NAME}" \ + --dbuser="${WORDPRESS_DB_USER}" \ + --dbpass="${WORDPRESS_DB_PASSWORD}" \ + --dbhost="${WORDPRESS_DB_HOST}" \ + --allow-root + fi + + # Idempotent install + if wp core is-installed --allow-root >/dev/null 2>&1; then + echo "WordPress is already installed. Nothing to do." + exit 0 + fi + + # Create an installation kind of unique ID + WORDPRESS_SEED_ID=$RANDOM + + echo "Running wp core install..." + wp core install \ + --url="${WORDPRESS_SITE_URL}" \ + --title="${WORDPRESS_SITE_TITLE} #$WORDPRESS_SEED_ID" \ + --admin_user="${WORDPRESS_ADMIN_USER}" \ + --admin_password="${WORDPRESS_ADMIN_PASSWORD}" \ + --admin_email="${WORDPRESS_ADMIN_EMAIL}" \ + --skip-email \ + --allow-root + + echo "Creating sample post..." + wp post create \ + --post_type=post \ + --post_status=publish \ + --post_title="Sample post #$WORDPRESS_SEED_ID" \ + --post_content="Hello from k8s, this is a random post content: $(openssl rand -base64 200 | tr -cs 'a-zA-Z' ' ' | xargs)" + + echo "WORDPRESS_SEED_ID=$WORDPRESS_SEED_ID" + echo "Done. WordPress has been installed." + command: + - bash + env: + - name: WORDPRESS_DB_HOST + value: wordpress-mysql + - name: WORDPRESS_DB_USER + value: wordpress + - name: WORDPRESS_DB_NAME + value: wordpress + - name: WORDPRESS_DB_PASSWORD + valueFrom: + secretKeyRef: + key: MYSQL_WORDPRESS_PASSWORD + name: wordpress-secrets-hg692g82th + - name: WORDPRESS_SITE_URL + value: http://wordpress-k8s.example.local + - name: WORDPRESS_SITE_TITLE + value: My WordPress Site on k8s + - name: WORDPRESS_ADMIN_USER + value: admin + - name: WORDPRESS_ADMIN_PASSWORD + valueFrom: + secretKeyRef: + key: WORDPRESS_ADMIN_PASSWORD + name: wordpress-secrets-hg692g82th + - name: WORDPRESS_ADMIN_EMAIL + value: admin@wordpress-k8s.example.local + image: wordpress:cli-2 + imagePullPolicy: IfNotPresent + name: wp-install + resources: {} + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + volumeMounts: + - mountPath: /var/www/html + name: wordpress-persistent-storage + dnsPolicy: ClusterFirst + restartPolicy: OnFailure + schedulerName: default-scheduler + securityContext: {} + terminationGracePeriodSeconds: 30 + volumes: + - name: wordpress-persistent-storage + persistentVolumeClaim: + claimName: wordpress-pv-claim +status: + completionTime: "2026-04-10T12:16:48Z" + conditions: + - lastProbeTime: "2026-04-10T12:16:48Z" + lastTransitionTime: "2026-04-10T12:16:48Z" + message: Reached expected number of succeeded pods + reason: CompletionsReached + status: "True" + type: SuccessCriteriaMet + - lastProbeTime: "2026-04-10T12:16:48Z" + lastTransitionTime: "2026-04-10T12:16:48Z" + message: Reached expected number of succeeded pods + reason: CompletionsReached + status: "True" + type: Complete + ready: 0 + startTime: "2026-04-10T12:15:08Z" + succeeded: 1 + terminating: 0 + uncountedTerminatedPods: {} diff --git a/docs/transform-scenarios/wordpress-demo/transform/.work/10_KubernetesPlugin/input/default/PersistentVolumeClaim__v1_default_mysql-pv-claim.yaml b/docs/transform-scenarios/wordpress-demo/transform/.work/10_KubernetesPlugin/input/default/PersistentVolumeClaim__v1_default_mysql-pv-claim.yaml new file mode 100644 index 00000000..5756b493 --- /dev/null +++ b/docs/transform-scenarios/wordpress-demo/transform/.work/10_KubernetesPlugin/input/default/PersistentVolumeClaim__v1_default_mysql-pv-claim.yaml @@ -0,0 +1,82 @@ +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + annotations: + kubectl.kubernetes.io/last-applied-configuration: | + {"apiVersion":"v1","kind":"PersistentVolumeClaim","metadata":{"annotations":{},"labels":{"app":"wordpress"},"name":"mysql-pv-claim","namespace":"default"},"spec":{"accessModes":["ReadWriteOnce"],"resources":{"requests":{"storage":"1Gi"}}}} + pv.kubernetes.io/bind-completed: "yes" + pv.kubernetes.io/bound-by-controller: "yes" + volume.beta.kubernetes.io/storage-provisioner: k8s.io/minikube-hostpath + volume.kubernetes.io/storage-provisioner: k8s.io/minikube-hostpath + creationTimestamp: "2026-04-10T12:15:07Z" + finalizers: + - kubernetes.io/pvc-protection + labels: + app: wordpress + managedFields: + - apiVersion: v1 + fieldsType: FieldsV1 + fieldsV1: + f:metadata: + f:annotations: + .: {} + f:kubectl.kubernetes.io/last-applied-configuration: {} + f:labels: + .: {} + f:app: {} + f:spec: + f:accessModes: {} + f:resources: + f:requests: + .: {} + f:storage: {} + f:volumeMode: {} + manager: kubectl-client-side-apply + operation: Update + time: "2026-04-10T12:15:07Z" + - apiVersion: v1 + fieldsType: FieldsV1 + fieldsV1: + f:metadata: + f:annotations: + f:pv.kubernetes.io/bind-completed: {} + f:pv.kubernetes.io/bound-by-controller: {} + f:volume.beta.kubernetes.io/storage-provisioner: {} + f:volume.kubernetes.io/storage-provisioner: {} + f:spec: + f:volumeName: {} + manager: kube-controller-manager + operation: Update + time: "2026-04-10T12:15:08Z" + - apiVersion: v1 + fieldsType: FieldsV1 + fieldsV1: + f:status: + f:accessModes: {} + f:capacity: + .: {} + f:storage: {} + f:phase: {} + manager: kube-controller-manager + operation: Update + subresource: status + time: "2026-04-10T12:15:08Z" + name: mysql-pv-claim + namespace: default + resourceVersion: "710" + uid: 58e67d84-b797-4121-a5df-f3beea559f74 +spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 1Gi + storageClassName: standard + volumeMode: Filesystem + volumeName: pvc-58e67d84-b797-4121-a5df-f3beea559f74 +status: + accessModes: + - ReadWriteOnce + capacity: + storage: 1Gi + phase: Bound diff --git a/docs/transform-scenarios/wordpress-demo/transform/.work/10_KubernetesPlugin/input/default/PersistentVolumeClaim__v1_default_wordpress-pv-claim.yaml b/docs/transform-scenarios/wordpress-demo/transform/.work/10_KubernetesPlugin/input/default/PersistentVolumeClaim__v1_default_wordpress-pv-claim.yaml new file mode 100644 index 00000000..399fd4cf --- /dev/null +++ b/docs/transform-scenarios/wordpress-demo/transform/.work/10_KubernetesPlugin/input/default/PersistentVolumeClaim__v1_default_wordpress-pv-claim.yaml @@ -0,0 +1,82 @@ +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + annotations: + kubectl.kubernetes.io/last-applied-configuration: | + {"apiVersion":"v1","kind":"PersistentVolumeClaim","metadata":{"annotations":{},"labels":{"app":"wordpress"},"name":"wordpress-pv-claim","namespace":"default"},"spec":{"accessModes":["ReadWriteOnce"],"resources":{"requests":{"storage":"1Gi"}}}} + pv.kubernetes.io/bind-completed: "yes" + pv.kubernetes.io/bound-by-controller: "yes" + volume.beta.kubernetes.io/storage-provisioner: k8s.io/minikube-hostpath + volume.kubernetes.io/storage-provisioner: k8s.io/minikube-hostpath + creationTimestamp: "2026-04-10T12:15:08Z" + finalizers: + - kubernetes.io/pvc-protection + labels: + app: wordpress + managedFields: + - apiVersion: v1 + fieldsType: FieldsV1 + fieldsV1: + f:metadata: + f:annotations: + f:pv.kubernetes.io/bind-completed: {} + f:pv.kubernetes.io/bound-by-controller: {} + f:volume.beta.kubernetes.io/storage-provisioner: {} + f:volume.kubernetes.io/storage-provisioner: {} + f:spec: + f:volumeName: {} + manager: kube-controller-manager + operation: Update + time: "2026-04-10T12:15:08Z" + - apiVersion: v1 + fieldsType: FieldsV1 + fieldsV1: + f:status: + f:accessModes: {} + f:capacity: + .: {} + f:storage: {} + f:phase: {} + manager: kube-controller-manager + operation: Update + subresource: status + time: "2026-04-10T12:15:08Z" + - apiVersion: v1 + fieldsType: FieldsV1 + fieldsV1: + f:metadata: + f:annotations: + .: {} + f:kubectl.kubernetes.io/last-applied-configuration: {} + f:labels: + .: {} + f:app: {} + f:spec: + f:accessModes: {} + f:resources: + f:requests: + .: {} + f:storage: {} + f:volumeMode: {} + manager: kubectl-client-side-apply + operation: Update + time: "2026-04-10T12:15:08Z" + name: wordpress-pv-claim + namespace: default + resourceVersion: "729" + uid: a08d0754-6782-497d-927d-7fdac1a968fe +spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 1Gi + storageClassName: standard + volumeMode: Filesystem + volumeName: pvc-a08d0754-6782-497d-927d-7fdac1a968fe +status: + accessModes: + - ReadWriteOnce + capacity: + storage: 1Gi + phase: Bound diff --git a/docs/transform-scenarios/wordpress-demo/transform/.work/10_KubernetesPlugin/input/default/Pod__v1_default_wordpress-74b89cc84c-nm9f8.yaml b/docs/transform-scenarios/wordpress-demo/transform/.work/10_KubernetesPlugin/input/default/Pod__v1_default_wordpress-74b89cc84c-nm9f8.yaml new file mode 100644 index 00000000..914d966d --- /dev/null +++ b/docs/transform-scenarios/wordpress-demo/transform/.work/10_KubernetesPlugin/input/default/Pod__v1_default_wordpress-74b89cc84c-nm9f8.yaml @@ -0,0 +1,383 @@ +apiVersion: v1 +kind: Pod +metadata: + creationTimestamp: "2026-04-10T12:15:08Z" + generateName: wordpress-74b89cc84c- + generation: 1 + labels: + app: wordpress + pod-template-hash: 74b89cc84c + tier: frontend + managedFields: + - apiVersion: v1 + fieldsType: FieldsV1 + fieldsV1: + f:metadata: + f:generateName: {} + f:labels: + .: {} + f:app: {} + f:pod-template-hash: {} + f:tier: {} + f:ownerReferences: + .: {} + k:{"uid":"7ed37255-e5ff-4e33-837d-f584a536d2b8"}: {} + f:spec: + f:containers: + k:{"name":"nginx"}: + .: {} + f:image: {} + f:imagePullPolicy: {} + f:name: {} + f:ports: + .: {} + k:{"containerPort":80,"protocol":"TCP"}: + .: {} + f:containerPort: {} + f:name: {} + f:protocol: {} + f:resources: {} + f:terminationMessagePath: {} + f:terminationMessagePolicy: {} + f:volumeMounts: + .: {} + k:{"mountPath":"/etc/nginx/nginx.conf"}: + .: {} + f:mountPath: {} + f:name: {} + f:subPath: {} + k:{"mountPath":"/var/www/html"}: + .: {} + f:mountPath: {} + f:name: {} + f:readOnly: {} + k:{"name":"wordpress"}: + .: {} + f:env: + .: {} + k:{"name":"WORDPRESS_CONFIG_EXTRA"}: + .: {} + f:name: {} + f:value: {} + k:{"name":"WORDPRESS_DB_HOST"}: + .: {} + f:name: {} + f:value: {} + k:{"name":"WORDPRESS_DB_PASSWORD"}: + .: {} + f:name: {} + f:valueFrom: + .: {} + f:secretKeyRef: {} + k:{"name":"WORDPRESS_DB_USER"}: + .: {} + f:name: {} + f:value: {} + f:image: {} + f:imagePullPolicy: {} + f:name: {} + f:ports: + .: {} + k:{"containerPort":9000,"protocol":"TCP"}: + .: {} + f:containerPort: {} + f:name: {} + f:protocol: {} + f:resources: {} + f:terminationMessagePath: {} + f:terminationMessagePolicy: {} + f:volumeMounts: + .: {} + k:{"mountPath":"/var/www/html"}: + .: {} + f:mountPath: {} + f:name: {} + f:dnsPolicy: {} + f:enableServiceLinks: {} + f:restartPolicy: {} + f:schedulerName: {} + f:securityContext: {} + f:terminationGracePeriodSeconds: {} + f:volumes: + .: {} + k:{"name":"nginx-config"}: + .: {} + f:configMap: + .: {} + f:defaultMode: {} + f:name: {} + f:name: {} + k:{"name":"wordpress-persistent-storage"}: + .: {} + f:name: {} + f:persistentVolumeClaim: + .: {} + f:claimName: {} + manager: kube-controller-manager + operation: Update + time: "2026-04-10T12:15:08Z" + - apiVersion: v1 + fieldsType: FieldsV1 + fieldsV1: + f:status: + f:conditions: + .: {} + k:{"type":"PodScheduled"}: + .: {} + f:lastProbeTime: {} + f:lastTransitionTime: {} + f:message: {} + f:reason: {} + f:status: {} + f:type: {} + manager: kube-scheduler + operation: Update + subresource: status + time: "2026-04-10T12:15:08Z" + - apiVersion: v1 + fieldsType: FieldsV1 + fieldsV1: + f:status: + f:conditions: + k:{"type":"ContainersReady"}: + .: {} + f:lastProbeTime: {} + f:lastTransitionTime: {} + f:observedGeneration: {} + f:status: {} + f:type: {} + k:{"type":"Initialized"}: + .: {} + f:lastProbeTime: {} + f:lastTransitionTime: {} + f:observedGeneration: {} + f:status: {} + f:type: {} + k:{"type":"PodReadyToStartContainers"}: + .: {} + f:lastProbeTime: {} + f:lastTransitionTime: {} + f:observedGeneration: {} + f:status: {} + f:type: {} + k:{"type":"PodScheduled"}: + f:observedGeneration: {} + k:{"type":"Ready"}: + .: {} + f:lastProbeTime: {} + f:lastTransitionTime: {} + f:observedGeneration: {} + f:status: {} + f:type: {} + f:containerStatuses: {} + f:hostIP: {} + f:hostIPs: {} + f:observedGeneration: {} + f:phase: {} + f:podIP: {} + f:podIPs: + .: {} + k:{"ip":"10.244.0.5"}: + .: {} + f:ip: {} + f:startTime: {} + manager: kubelet + operation: Update + subresource: status + time: "2026-04-10T12:16:04Z" + name: wordpress-74b89cc84c-nm9f8 + namespace: default + ownerReferences: + - apiVersion: apps/v1 + blockOwnerDeletion: true + controller: true + kind: ReplicaSet + name: wordpress-74b89cc84c + uid: 7ed37255-e5ff-4e33-837d-f584a536d2b8 + resourceVersion: "808" + uid: 608501ac-fd76-48a1-b9ef-058b7a6ade67 +spec: + containers: + - env: + - name: WORDPRESS_DB_HOST + value: wordpress-mysql + - name: WORDPRESS_DB_PASSWORD + valueFrom: + secretKeyRef: + key: MYSQL_WORDPRESS_PASSWORD + name: wordpress-secrets-hg692g82th + - name: WORDPRESS_DB_USER + value: wordpress + - name: WORDPRESS_CONFIG_EXTRA + value: | + // Set SITE URL dynamically from requests to allow reach it on different endpoints + if (isset($_SERVER['HTTP_HOST'])) { + $protocol = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on') ? 'https' : 'http'; + if (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https') { + $protocol = 'https'; + } + define('WP_HOME', $protocol . '://' . $_SERVER['HTTP_HOST']); + define('WP_SITEURL', $protocol . '://' . $_SERVER['HTTP_HOST']); + } + image: wordpress:6-fpm-alpine + imagePullPolicy: IfNotPresent + name: wordpress + ports: + - containerPort: 9000 + name: fastcgi + protocol: TCP + resources: {} + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + volumeMounts: + - mountPath: /var/www/html + name: wordpress-persistent-storage + - mountPath: /var/run/secrets/kubernetes.io/serviceaccount + name: kube-api-access-gksj7 + readOnly: true + - image: nginx:alpine + imagePullPolicy: IfNotPresent + name: nginx + ports: + - containerPort: 80 + name: http + protocol: TCP + resources: {} + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + volumeMounts: + - mountPath: /var/www/html + name: wordpress-persistent-storage + readOnly: true + - mountPath: /etc/nginx/nginx.conf + name: nginx-config + subPath: nginx.conf + - mountPath: /var/run/secrets/kubernetes.io/serviceaccount + name: kube-api-access-gksj7 + readOnly: true + dnsPolicy: ClusterFirst + enableServiceLinks: true + nodeName: minikube + preemptionPolicy: PreemptLowerPriority + priority: 0 + restartPolicy: Always + schedulerName: default-scheduler + securityContext: {} + serviceAccount: default + serviceAccountName: default + terminationGracePeriodSeconds: 30 + tolerations: + - effect: NoExecute + key: node.kubernetes.io/not-ready + operator: Exists + tolerationSeconds: 300 + - effect: NoExecute + key: node.kubernetes.io/unreachable + operator: Exists + tolerationSeconds: 300 + volumes: + - name: wordpress-persistent-storage + persistentVolumeClaim: + claimName: wordpress-pv-claim + - configMap: + defaultMode: 420 + name: nginx-config + name: nginx-config + - name: kube-api-access-gksj7 + projected: + defaultMode: 420 + sources: + - serviceAccountToken: + expirationSeconds: 3607 + path: token + - configMap: + items: + - key: ca.crt + path: ca.crt + name: kube-root-ca.crt + - downwardAPI: + items: + - fieldRef: + apiVersion: v1 + fieldPath: metadata.namespace + path: namespace +status: + conditions: + - lastProbeTime: null + lastTransitionTime: "2026-04-10T12:16:04Z" + observedGeneration: 1 + status: "True" + type: PodReadyToStartContainers + - lastProbeTime: null + lastTransitionTime: "2026-04-10T12:15:08Z" + observedGeneration: 1 + status: "True" + type: Initialized + - lastProbeTime: null + lastTransitionTime: "2026-04-10T12:16:04Z" + observedGeneration: 1 + status: "True" + type: Ready + - lastProbeTime: null + lastTransitionTime: "2026-04-10T12:16:04Z" + observedGeneration: 1 + status: "True" + type: ContainersReady + - lastProbeTime: null + lastTransitionTime: "2026-04-10T12:15:08Z" + observedGeneration: 1 + status: "True" + type: PodScheduled + containerStatuses: + - containerID: docker://9deeeda1697dc879391836b269f936362a2e1a77d5beb289889639e352d9ee13 + image: nginx:alpine + imageID: docker-pullable://nginx@sha256:582c496ccf79d8aa6f8203a79d32aaf7ffd8b13362c60a701a2f9ac64886c93d + lastState: {} + name: nginx + ready: true + resources: {} + restartCount: 0 + started: true + state: + running: + startedAt: "2026-04-10T12:16:04Z" + volumeMounts: + - mountPath: /var/www/html + name: wordpress-persistent-storage + readOnly: true + recursiveReadOnly: Disabled + - mountPath: /etc/nginx/nginx.conf + name: nginx-config + - mountPath: /var/run/secrets/kubernetes.io/serviceaccount + name: kube-api-access-gksj7 + readOnly: true + recursiveReadOnly: Disabled + - containerID: docker://dd83b5ffcde3a21dcfc1f3fedfeefcc0a7e8e7f63b31817029d370b0ddde48f4 + image: wordpress:6-fpm-alpine + imageID: docker-pullable://wordpress@sha256:658bc068c60dcd43f2e2deee4b8495ca5e37ef09481d790ad05f99e6a15f61aa + lastState: {} + name: wordpress + ready: true + resources: {} + restartCount: 0 + started: true + state: + running: + startedAt: "2026-04-10T12:15:33Z" + volumeMounts: + - mountPath: /var/www/html + name: wordpress-persistent-storage + - mountPath: /var/run/secrets/kubernetes.io/serviceaccount + name: kube-api-access-gksj7 + readOnly: true + recursiveReadOnly: Disabled + hostIP: 192.168.61.192 + hostIPs: + - ip: 192.168.61.192 + observedGeneration: 1 + phase: Running + podIP: 10.244.0.5 + podIPs: + - ip: 10.244.0.5 + qosClass: BestEffort + startTime: "2026-04-10T12:15:08Z" diff --git a/docs/transform-scenarios/wordpress-demo/transform/.work/10_KubernetesPlugin/input/default/Pod__v1_default_wordpress-install-xrqtc.yaml b/docs/transform-scenarios/wordpress-demo/transform/.work/10_KubernetesPlugin/input/default/Pod__v1_default_wordpress-install-xrqtc.yaml new file mode 100644 index 00000000..12399817 --- /dev/null +++ b/docs/transform-scenarios/wordpress-demo/transform/.work/10_KubernetesPlugin/input/default/Pod__v1_default_wordpress-install-xrqtc.yaml @@ -0,0 +1,381 @@ +apiVersion: v1 +kind: Pod +metadata: + creationTimestamp: "2026-04-10T12:15:08Z" + generateName: wordpress-install- + generation: 1 + labels: + batch.kubernetes.io/controller-uid: be719474-856d-4d84-80ad-4f4ab9ecdd30 + batch.kubernetes.io/job-name: wordpress-install + controller-uid: be719474-856d-4d84-80ad-4f4ab9ecdd30 + job-name: wordpress-install + managedFields: + - apiVersion: v1 + fieldsType: FieldsV1 + fieldsV1: + f:metadata: + f:generateName: {} + f:labels: + .: {} + f:batch.kubernetes.io/controller-uid: {} + f:batch.kubernetes.io/job-name: {} + f:controller-uid: {} + f:job-name: {} + f:ownerReferences: + .: {} + k:{"uid":"be719474-856d-4d84-80ad-4f4ab9ecdd30"}: {} + f:spec: + f:containers: + k:{"name":"wp-install"}: + .: {} + f:args: {} + f:command: {} + f:env: + .: {} + k:{"name":"WORDPRESS_ADMIN_EMAIL"}: + .: {} + f:name: {} + f:value: {} + k:{"name":"WORDPRESS_ADMIN_PASSWORD"}: + .: {} + f:name: {} + f:valueFrom: + .: {} + f:secretKeyRef: {} + k:{"name":"WORDPRESS_ADMIN_USER"}: + .: {} + f:name: {} + f:value: {} + k:{"name":"WORDPRESS_DB_HOST"}: + .: {} + f:name: {} + f:value: {} + k:{"name":"WORDPRESS_DB_NAME"}: + .: {} + f:name: {} + f:value: {} + k:{"name":"WORDPRESS_DB_PASSWORD"}: + .: {} + f:name: {} + f:valueFrom: + .: {} + f:secretKeyRef: {} + k:{"name":"WORDPRESS_DB_USER"}: + .: {} + f:name: {} + f:value: {} + k:{"name":"WORDPRESS_SITE_TITLE"}: + .: {} + f:name: {} + f:value: {} + k:{"name":"WORDPRESS_SITE_URL"}: + .: {} + f:name: {} + f:value: {} + f:image: {} + f:imagePullPolicy: {} + f:name: {} + f:resources: {} + f:terminationMessagePath: {} + f:terminationMessagePolicy: {} + f:volumeMounts: + .: {} + k:{"mountPath":"/var/www/html"}: + .: {} + f:mountPath: {} + f:name: {} + f:dnsPolicy: {} + f:enableServiceLinks: {} + f:restartPolicy: {} + f:schedulerName: {} + f:securityContext: {} + f:terminationGracePeriodSeconds: {} + f:volumes: + .: {} + k:{"name":"wordpress-persistent-storage"}: + .: {} + f:name: {} + f:persistentVolumeClaim: + .: {} + f:claimName: {} + manager: kube-controller-manager + operation: Update + time: "2026-04-10T12:15:08Z" + - apiVersion: v1 + fieldsType: FieldsV1 + fieldsV1: + f:status: + f:conditions: + k:{"type":"ContainersReady"}: + .: {} + f:lastProbeTime: {} + f:lastTransitionTime: {} + f:observedGeneration: {} + f:reason: {} + f:status: {} + f:type: {} + k:{"type":"Initialized"}: + .: {} + f:lastProbeTime: {} + f:lastTransitionTime: {} + f:observedGeneration: {} + f:reason: {} + f:status: {} + f:type: {} + k:{"type":"PodReadyToStartContainers"}: + .: {} + f:lastProbeTime: {} + f:lastTransitionTime: {} + f:observedGeneration: {} + f:status: {} + f:type: {} + k:{"type":"PodScheduled"}: + f:observedGeneration: {} + k:{"type":"Ready"}: + .: {} + f:lastProbeTime: {} + f:lastTransitionTime: {} + f:observedGeneration: {} + f:reason: {} + f:status: {} + f:type: {} + f:containerStatuses: {} + f:hostIP: {} + f:hostIPs: {} + f:observedGeneration: {} + f:phase: {} + f:podIP: {} + f:podIPs: + .: {} + k:{"ip":"10.244.0.4"}: + .: {} + f:ip: {} + f:startTime: {} + manager: kubelet + operation: Update + subresource: status + time: "2026-04-10T12:16:48Z" + name: wordpress-install-xrqtc + namespace: default + ownerReferences: + - apiVersion: batch/v1 + blockOwnerDeletion: true + controller: true + kind: Job + name: wordpress-install + uid: be719474-856d-4d84-80ad-4f4ab9ecdd30 + resourceVersion: "853" + uid: 7d3fa4a3-d0a9-438b-b477-e45103965e04 +spec: + containers: + - args: + - -lc + - | + set -e + cd /var/www/html + + echo "Waiting for MySQL on ${WORDPRESS_DB_HOST}:3306..." + for i in $(seq 1 60); do + if mariadb-admin ping -h"${WORDPRESS_DB_HOST}" -u"${WORDPRESS_DB_USER}" -p"${WORDPRESS_DB_PASSWORD}" --ssl=false --silent; then + echo "MySQL is up." + break + fi + echo "MySQL not ready yet (attempt: $i)..." + sleep 5 + done + + if ! mariadb-admin ping -h"${WORDPRESS_DB_HOST}" -u"${WORDPRESS_DB_USER}" -p"${WORDPRESS_DB_PASSWORD}" --ssl=false --silent; then + echo "MySQL did not become ready within the timeout." + exit 1 + fi + + # Make sure WordPress core is present on the volume + if [ ! -f wp-load.php ]; then + echo "WordPress core not found on the volume. Downloading..." + wp core download --allow-root + fi + + # Create wp-config.php if missing + if [ ! -f wp-config.php ]; then + echo "Creating wp-config.php..." + wp config create \ + --dbname="${WORDPRESS_DB_NAME}" \ + --dbuser="${WORDPRESS_DB_USER}" \ + --dbpass="${WORDPRESS_DB_PASSWORD}" \ + --dbhost="${WORDPRESS_DB_HOST}" \ + --allow-root + fi + + # Idempotent install + if wp core is-installed --allow-root >/dev/null 2>&1; then + echo "WordPress is already installed. Nothing to do." + exit 0 + fi + + # Create an installation kind of unique ID + WORDPRESS_SEED_ID=$RANDOM + + echo "Running wp core install..." + wp core install \ + --url="${WORDPRESS_SITE_URL}" \ + --title="${WORDPRESS_SITE_TITLE} #$WORDPRESS_SEED_ID" \ + --admin_user="${WORDPRESS_ADMIN_USER}" \ + --admin_password="${WORDPRESS_ADMIN_PASSWORD}" \ + --admin_email="${WORDPRESS_ADMIN_EMAIL}" \ + --skip-email \ + --allow-root + + echo "Creating sample post..." + wp post create \ + --post_type=post \ + --post_status=publish \ + --post_title="Sample post #$WORDPRESS_SEED_ID" \ + --post_content="Hello from k8s, this is a random post content: $(openssl rand -base64 200 | tr -cs 'a-zA-Z' ' ' | xargs)" + + echo "WORDPRESS_SEED_ID=$WORDPRESS_SEED_ID" + echo "Done. WordPress has been installed." + command: + - bash + env: + - name: WORDPRESS_DB_HOST + value: wordpress-mysql + - name: WORDPRESS_DB_USER + value: wordpress + - name: WORDPRESS_DB_NAME + value: wordpress + - name: WORDPRESS_DB_PASSWORD + valueFrom: + secretKeyRef: + key: MYSQL_WORDPRESS_PASSWORD + name: wordpress-secrets-hg692g82th + - name: WORDPRESS_SITE_URL + value: http://wordpress-k8s.example.local + - name: WORDPRESS_SITE_TITLE + value: My WordPress Site on k8s + - name: WORDPRESS_ADMIN_USER + value: admin + - name: WORDPRESS_ADMIN_PASSWORD + valueFrom: + secretKeyRef: + key: WORDPRESS_ADMIN_PASSWORD + name: wordpress-secrets-hg692g82th + - name: WORDPRESS_ADMIN_EMAIL + value: admin@wordpress-k8s.example.local + image: wordpress:cli-2 + imagePullPolicy: IfNotPresent + name: wp-install + resources: {} + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + volumeMounts: + - mountPath: /var/www/html + name: wordpress-persistent-storage + - mountPath: /var/run/secrets/kubernetes.io/serviceaccount + name: kube-api-access-29z94 + readOnly: true + dnsPolicy: ClusterFirst + enableServiceLinks: true + nodeName: minikube + preemptionPolicy: PreemptLowerPriority + priority: 0 + restartPolicy: OnFailure + schedulerName: default-scheduler + securityContext: {} + serviceAccount: default + serviceAccountName: default + terminationGracePeriodSeconds: 30 + tolerations: + - effect: NoExecute + key: node.kubernetes.io/not-ready + operator: Exists + tolerationSeconds: 300 + - effect: NoExecute + key: node.kubernetes.io/unreachable + operator: Exists + tolerationSeconds: 300 + volumes: + - name: wordpress-persistent-storage + persistentVolumeClaim: + claimName: wordpress-pv-claim + - name: kube-api-access-29z94 + projected: + defaultMode: 420 + sources: + - serviceAccountToken: + expirationSeconds: 3607 + path: token + - configMap: + items: + - key: ca.crt + path: ca.crt + name: kube-root-ca.crt + - downwardAPI: + items: + - fieldRef: + apiVersion: v1 + fieldPath: metadata.namespace + path: namespace +status: + conditions: + - lastProbeTime: null + lastTransitionTime: "2026-04-10T12:16:48Z" + observedGeneration: 1 + status: "False" + type: PodReadyToStartContainers + - lastProbeTime: null + lastTransitionTime: "2026-04-10T12:15:08Z" + observedGeneration: 1 + reason: PodCompleted + status: "True" + type: Initialized + - lastProbeTime: null + lastTransitionTime: "2026-04-10T12:16:46Z" + observedGeneration: 1 + reason: PodCompleted + status: "False" + type: Ready + - lastProbeTime: null + lastTransitionTime: "2026-04-10T12:16:46Z" + observedGeneration: 1 + reason: PodCompleted + status: "False" + type: ContainersReady + - lastProbeTime: null + lastTransitionTime: "2026-04-10T12:15:08Z" + observedGeneration: 1 + status: "True" + type: PodScheduled + containerStatuses: + - containerID: docker://b1d36c9760604c47741156b29183957dc09994038288ba012d53abaedb0697e3 + image: wordpress:cli-2 + imageID: docker-pullable://wordpress@sha256:c9ecfd0ef73102cdc6666f20ccc3a0ae16c9a170160ef70bad4e9141ae856054 + lastState: {} + name: wp-install + ready: false + resources: {} + restartCount: 0 + started: false + state: + terminated: + containerID: docker://b1d36c9760604c47741156b29183957dc09994038288ba012d53abaedb0697e3 + exitCode: 0 + finishedAt: "2026-04-10T12:16:46Z" + reason: Completed + startedAt: "2026-04-10T12:15:20Z" + volumeMounts: + - mountPath: /var/www/html + name: wordpress-persistent-storage + - mountPath: /var/run/secrets/kubernetes.io/serviceaccount + name: kube-api-access-29z94 + readOnly: true + recursiveReadOnly: Disabled + hostIP: 192.168.61.192 + hostIPs: + - ip: 192.168.61.192 + observedGeneration: 1 + phase: Succeeded + podIP: 10.244.0.4 + podIPs: + - ip: 10.244.0.4 + qosClass: BestEffort + startTime: "2026-04-10T12:15:08Z" diff --git a/docs/transform-scenarios/wordpress-demo/transform/.work/10_KubernetesPlugin/input/default/Pod__v1_default_wordpress-mysql-9474c86b-fr65w.yaml b/docs/transform-scenarios/wordpress-demo/transform/.work/10_KubernetesPlugin/input/default/Pod__v1_default_wordpress-mysql-9474c86b-fr65w.yaml new file mode 100644 index 00000000..28b6de98 --- /dev/null +++ b/docs/transform-scenarios/wordpress-demo/transform/.work/10_KubernetesPlugin/input/default/Pod__v1_default_wordpress-mysql-9474c86b-fr65w.yaml @@ -0,0 +1,280 @@ +apiVersion: v1 +kind: Pod +metadata: + creationTimestamp: "2026-04-10T12:15:08Z" + generateName: wordpress-mysql-9474c86b- + generation: 1 + labels: + app: wordpress + pod-template-hash: 9474c86b + tier: mysql + managedFields: + - apiVersion: v1 + fieldsType: FieldsV1 + fieldsV1: + f:metadata: + f:generateName: {} + f:labels: + .: {} + f:app: {} + f:pod-template-hash: {} + f:tier: {} + f:ownerReferences: + .: {} + k:{"uid":"c48515d5-a023-4257-b5a1-2504dc2291af"}: {} + f:spec: + f:containers: + k:{"name":"mysql"}: + .: {} + f:env: + .: {} + k:{"name":"MYSQL_DATABASE"}: + .: {} + f:name: {} + f:value: {} + k:{"name":"MYSQL_PASSWORD"}: + .: {} + f:name: {} + f:valueFrom: + .: {} + f:secretKeyRef: {} + k:{"name":"MYSQL_ROOT_PASSWORD"}: + .: {} + f:name: {} + f:valueFrom: + .: {} + f:secretKeyRef: {} + k:{"name":"MYSQL_USER"}: + .: {} + f:name: {} + f:value: {} + f:image: {} + f:imagePullPolicy: {} + f:name: {} + f:ports: + .: {} + k:{"containerPort":3306,"protocol":"TCP"}: + .: {} + f:containerPort: {} + f:name: {} + f:protocol: {} + f:resources: {} + f:terminationMessagePath: {} + f:terminationMessagePolicy: {} + f:volumeMounts: + .: {} + k:{"mountPath":"/var/lib/mysql"}: + .: {} + f:mountPath: {} + f:name: {} + f:dnsPolicy: {} + f:enableServiceLinks: {} + f:restartPolicy: {} + f:schedulerName: {} + f:securityContext: {} + f:terminationGracePeriodSeconds: {} + f:volumes: + .: {} + k:{"name":"mysql-persistent-storage"}: + .: {} + f:name: {} + f:persistentVolumeClaim: + .: {} + f:claimName: {} + manager: kube-controller-manager + operation: Update + time: "2026-04-10T12:15:08Z" + - apiVersion: v1 + fieldsType: FieldsV1 + fieldsV1: + f:status: + f:conditions: + k:{"type":"ContainersReady"}: + .: {} + f:lastProbeTime: {} + f:lastTransitionTime: {} + f:observedGeneration: {} + f:status: {} + f:type: {} + k:{"type":"Initialized"}: + .: {} + f:lastProbeTime: {} + f:lastTransitionTime: {} + f:observedGeneration: {} + f:status: {} + f:type: {} + k:{"type":"PodReadyToStartContainers"}: + .: {} + f:lastProbeTime: {} + f:lastTransitionTime: {} + f:observedGeneration: {} + f:status: {} + f:type: {} + k:{"type":"PodScheduled"}: + f:observedGeneration: {} + k:{"type":"Ready"}: + .: {} + f:lastProbeTime: {} + f:lastTransitionTime: {} + f:observedGeneration: {} + f:status: {} + f:type: {} + f:containerStatuses: {} + f:hostIP: {} + f:hostIPs: {} + f:observedGeneration: {} + f:phase: {} + f:podIP: {} + f:podIPs: + .: {} + k:{"ip":"10.244.0.6"}: + .: {} + f:ip: {} + f:startTime: {} + manager: kubelet + operation: Update + subresource: status + time: "2026-04-10T12:15:58Z" + name: wordpress-mysql-9474c86b-fr65w + namespace: default + ownerReferences: + - apiVersion: apps/v1 + blockOwnerDeletion: true + controller: true + kind: ReplicaSet + name: wordpress-mysql-9474c86b + uid: c48515d5-a023-4257-b5a1-2504dc2291af + resourceVersion: "795" + uid: f81b40e3-ff85-46ca-8b0a-5c826b78f0c8 +spec: + containers: + - env: + - name: MYSQL_ROOT_PASSWORD + valueFrom: + secretKeyRef: + key: MYSQL_ROOT_PASSWORD + name: wordpress-secrets-hg692g82th + - name: MYSQL_DATABASE + value: wordpress + - name: MYSQL_USER + value: wordpress + - name: MYSQL_PASSWORD + valueFrom: + secretKeyRef: + key: MYSQL_WORDPRESS_PASSWORD + name: wordpress-secrets-hg692g82th + image: mysql:8.0 + imagePullPolicy: IfNotPresent + name: mysql + ports: + - containerPort: 3306 + name: mysql + protocol: TCP + resources: {} + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + volumeMounts: + - mountPath: /var/lib/mysql + name: mysql-persistent-storage + - mountPath: /var/run/secrets/kubernetes.io/serviceaccount + name: kube-api-access-k5p65 + readOnly: true + dnsPolicy: ClusterFirst + enableServiceLinks: true + nodeName: minikube + preemptionPolicy: PreemptLowerPriority + priority: 0 + restartPolicy: Always + schedulerName: default-scheduler + securityContext: {} + serviceAccount: default + serviceAccountName: default + terminationGracePeriodSeconds: 30 + tolerations: + - effect: NoExecute + key: node.kubernetes.io/not-ready + operator: Exists + tolerationSeconds: 300 + - effect: NoExecute + key: node.kubernetes.io/unreachable + operator: Exists + tolerationSeconds: 300 + volumes: + - name: mysql-persistent-storage + persistentVolumeClaim: + claimName: mysql-pv-claim + - name: kube-api-access-k5p65 + projected: + defaultMode: 420 + sources: + - serviceAccountToken: + expirationSeconds: 3607 + path: token + - configMap: + items: + - key: ca.crt + path: ca.crt + name: kube-root-ca.crt + - downwardAPI: + items: + - fieldRef: + apiVersion: v1 + fieldPath: metadata.namespace + path: namespace +status: + conditions: + - lastProbeTime: null + lastTransitionTime: "2026-04-10T12:15:58Z" + observedGeneration: 1 + status: "True" + type: PodReadyToStartContainers + - lastProbeTime: null + lastTransitionTime: "2026-04-10T12:15:08Z" + observedGeneration: 1 + status: "True" + type: Initialized + - lastProbeTime: null + lastTransitionTime: "2026-04-10T12:15:58Z" + observedGeneration: 1 + status: "True" + type: Ready + - lastProbeTime: null + lastTransitionTime: "2026-04-10T12:15:58Z" + observedGeneration: 1 + status: "True" + type: ContainersReady + - lastProbeTime: null + lastTransitionTime: "2026-04-10T12:15:08Z" + observedGeneration: 1 + status: "True" + type: PodScheduled + containerStatuses: + - containerID: docker://7e196a67c97dc0a97090ed6f3e62507aa9a63ab4d28ce7b455be169edc7c53ce + image: mysql:8.0 + imageID: docker-pullable://mysql@sha256:64756cc92f707eb504496d774353990bcb0f6999ddf598b6ad188f2da66bd000 + lastState: {} + name: mysql + ready: true + resources: {} + restartCount: 0 + started: true + state: + running: + startedAt: "2026-04-10T12:15:57Z" + volumeMounts: + - mountPath: /var/lib/mysql + name: mysql-persistent-storage + - mountPath: /var/run/secrets/kubernetes.io/serviceaccount + name: kube-api-access-k5p65 + readOnly: true + recursiveReadOnly: Disabled + hostIP: 192.168.61.192 + hostIPs: + - ip: 192.168.61.192 + observedGeneration: 1 + phase: Running + podIP: 10.244.0.6 + podIPs: + - ip: 10.244.0.6 + qosClass: BestEffort + startTime: "2026-04-10T12:15:08Z" diff --git a/docs/transform-scenarios/wordpress-demo/transform/.work/10_KubernetesPlugin/input/default/ReplicaSet_apps_v1_default_wordpress-74b89cc84c.yaml b/docs/transform-scenarios/wordpress-demo/transform/.work/10_KubernetesPlugin/input/default/ReplicaSet_apps_v1_default_wordpress-74b89cc84c.yaml new file mode 100644 index 00000000..db3e66a7 --- /dev/null +++ b/docs/transform-scenarios/wordpress-demo/transform/.work/10_KubernetesPlugin/input/default/ReplicaSet_apps_v1_default_wordpress-74b89cc84c.yaml @@ -0,0 +1,245 @@ +apiVersion: apps/v1 +kind: ReplicaSet +metadata: + annotations: + deployment.kubernetes.io/desired-replicas: "1" + deployment.kubernetes.io/max-replicas: "1" + deployment.kubernetes.io/revision: "1" + creationTimestamp: "2026-04-10T12:15:08Z" + generation: 1 + labels: + app: wordpress + pod-template-hash: 74b89cc84c + tier: frontend + managedFields: + - apiVersion: apps/v1 + fieldsType: FieldsV1 + fieldsV1: + f:metadata: + f:annotations: + .: {} + f:deployment.kubernetes.io/desired-replicas: {} + f:deployment.kubernetes.io/max-replicas: {} + f:deployment.kubernetes.io/revision: {} + f:labels: + .: {} + f:app: {} + f:pod-template-hash: {} + f:tier: {} + f:ownerReferences: + .: {} + k:{"uid":"32f30549-f011-48b1-8398-64fef74b2df1"}: {} + f:spec: + f:replicas: {} + f:selector: {} + f:template: + f:metadata: + f:labels: + .: {} + f:app: {} + f:pod-template-hash: {} + f:tier: {} + f:spec: + f:containers: + k:{"name":"nginx"}: + .: {} + f:image: {} + f:imagePullPolicy: {} + f:name: {} + f:ports: + .: {} + k:{"containerPort":80,"protocol":"TCP"}: + .: {} + f:containerPort: {} + f:name: {} + f:protocol: {} + f:resources: {} + f:terminationMessagePath: {} + f:terminationMessagePolicy: {} + f:volumeMounts: + .: {} + k:{"mountPath":"/etc/nginx/nginx.conf"}: + .: {} + f:mountPath: {} + f:name: {} + f:subPath: {} + k:{"mountPath":"/var/www/html"}: + .: {} + f:mountPath: {} + f:name: {} + f:readOnly: {} + k:{"name":"wordpress"}: + .: {} + f:env: + .: {} + k:{"name":"WORDPRESS_CONFIG_EXTRA"}: + .: {} + f:name: {} + f:value: {} + k:{"name":"WORDPRESS_DB_HOST"}: + .: {} + f:name: {} + f:value: {} + k:{"name":"WORDPRESS_DB_PASSWORD"}: + .: {} + f:name: {} + f:valueFrom: + .: {} + f:secretKeyRef: {} + k:{"name":"WORDPRESS_DB_USER"}: + .: {} + f:name: {} + f:value: {} + f:image: {} + f:imagePullPolicy: {} + f:name: {} + f:ports: + .: {} + k:{"containerPort":9000,"protocol":"TCP"}: + .: {} + f:containerPort: {} + f:name: {} + f:protocol: {} + f:resources: {} + f:terminationMessagePath: {} + f:terminationMessagePolicy: {} + f:volumeMounts: + .: {} + k:{"mountPath":"/var/www/html"}: + .: {} + f:mountPath: {} + f:name: {} + f:dnsPolicy: {} + f:restartPolicy: {} + f:schedulerName: {} + f:securityContext: {} + f:terminationGracePeriodSeconds: {} + f:volumes: + .: {} + k:{"name":"nginx-config"}: + .: {} + f:configMap: + .: {} + f:defaultMode: {} + f:name: {} + f:name: {} + k:{"name":"wordpress-persistent-storage"}: + .: {} + f:name: {} + f:persistentVolumeClaim: + .: {} + f:claimName: {} + manager: kube-controller-manager + operation: Update + time: "2026-04-10T12:15:08Z" + - apiVersion: apps/v1 + fieldsType: FieldsV1 + fieldsV1: + f:status: + f:availableReplicas: {} + f:fullyLabeledReplicas: {} + f:observedGeneration: {} + f:readyReplicas: {} + f:replicas: {} + f:terminatingReplicas: {} + manager: kube-controller-manager + operation: Update + subresource: status + time: "2026-04-10T12:16:04Z" + name: wordpress-74b89cc84c + namespace: default + ownerReferences: + - apiVersion: apps/v1 + blockOwnerDeletion: true + controller: true + kind: Deployment + name: wordpress + uid: 32f30549-f011-48b1-8398-64fef74b2df1 + resourceVersion: "811" + uid: 7ed37255-e5ff-4e33-837d-f584a536d2b8 +spec: + replicas: 1 + selector: + matchLabels: + app: wordpress + pod-template-hash: 74b89cc84c + tier: frontend + template: + metadata: + labels: + app: wordpress + pod-template-hash: 74b89cc84c + tier: frontend + spec: + containers: + - env: + - name: WORDPRESS_DB_HOST + value: wordpress-mysql + - name: WORDPRESS_DB_PASSWORD + valueFrom: + secretKeyRef: + key: MYSQL_WORDPRESS_PASSWORD + name: wordpress-secrets-hg692g82th + - name: WORDPRESS_DB_USER + value: wordpress + - name: WORDPRESS_CONFIG_EXTRA + value: | + // Set SITE URL dynamically from requests to allow reach it on different endpoints + if (isset($_SERVER['HTTP_HOST'])) { + $protocol = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on') ? 'https' : 'http'; + if (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https') { + $protocol = 'https'; + } + define('WP_HOME', $protocol . '://' . $_SERVER['HTTP_HOST']); + define('WP_SITEURL', $protocol . '://' . $_SERVER['HTTP_HOST']); + } + image: wordpress:6-fpm-alpine + imagePullPolicy: IfNotPresent + name: wordpress + ports: + - containerPort: 9000 + name: fastcgi + protocol: TCP + resources: {} + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + volumeMounts: + - mountPath: /var/www/html + name: wordpress-persistent-storage + - image: nginx:alpine + imagePullPolicy: IfNotPresent + name: nginx + ports: + - containerPort: 80 + name: http + protocol: TCP + resources: {} + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + volumeMounts: + - mountPath: /var/www/html + name: wordpress-persistent-storage + readOnly: true + - mountPath: /etc/nginx/nginx.conf + name: nginx-config + subPath: nginx.conf + dnsPolicy: ClusterFirst + restartPolicy: Always + schedulerName: default-scheduler + securityContext: {} + terminationGracePeriodSeconds: 30 + volumes: + - name: wordpress-persistent-storage + persistentVolumeClaim: + claimName: wordpress-pv-claim + - configMap: + defaultMode: 420 + name: nginx-config + name: nginx-config +status: + availableReplicas: 1 + fullyLabeledReplicas: 1 + observedGeneration: 1 + readyReplicas: 1 + replicas: 1 + terminatingReplicas: 0 diff --git a/docs/transform-scenarios/wordpress-demo/transform/.work/10_KubernetesPlugin/input/default/ReplicaSet_apps_v1_default_wordpress-mysql-9474c86b.yaml b/docs/transform-scenarios/wordpress-demo/transform/.work/10_KubernetesPlugin/input/default/ReplicaSet_apps_v1_default_wordpress-mysql-9474c86b.yaml new file mode 100644 index 00000000..d34a5904 --- /dev/null +++ b/docs/transform-scenarios/wordpress-demo/transform/.work/10_KubernetesPlugin/input/default/ReplicaSet_apps_v1_default_wordpress-mysql-9474c86b.yaml @@ -0,0 +1,186 @@ +apiVersion: apps/v1 +kind: ReplicaSet +metadata: + annotations: + deployment.kubernetes.io/desired-replicas: "1" + deployment.kubernetes.io/max-replicas: "1" + deployment.kubernetes.io/revision: "1" + creationTimestamp: "2026-04-10T12:15:08Z" + generation: 1 + labels: + app: wordpress + pod-template-hash: 9474c86b + tier: mysql + managedFields: + - apiVersion: apps/v1 + fieldsType: FieldsV1 + fieldsV1: + f:metadata: + f:annotations: + .: {} + f:deployment.kubernetes.io/desired-replicas: {} + f:deployment.kubernetes.io/max-replicas: {} + f:deployment.kubernetes.io/revision: {} + f:labels: + .: {} + f:app: {} + f:pod-template-hash: {} + f:tier: {} + f:ownerReferences: + .: {} + k:{"uid":"2eba9391-46db-4860-9f9a-a1cb396faf18"}: {} + f:spec: + f:replicas: {} + f:selector: {} + f:template: + f:metadata: + f:labels: + .: {} + f:app: {} + f:pod-template-hash: {} + f:tier: {} + f:spec: + f:containers: + k:{"name":"mysql"}: + .: {} + f:env: + .: {} + k:{"name":"MYSQL_DATABASE"}: + .: {} + f:name: {} + f:value: {} + k:{"name":"MYSQL_PASSWORD"}: + .: {} + f:name: {} + f:valueFrom: + .: {} + f:secretKeyRef: {} + k:{"name":"MYSQL_ROOT_PASSWORD"}: + .: {} + f:name: {} + f:valueFrom: + .: {} + f:secretKeyRef: {} + k:{"name":"MYSQL_USER"}: + .: {} + f:name: {} + f:value: {} + f:image: {} + f:imagePullPolicy: {} + f:name: {} + f:ports: + .: {} + k:{"containerPort":3306,"protocol":"TCP"}: + .: {} + f:containerPort: {} + f:name: {} + f:protocol: {} + f:resources: {} + f:terminationMessagePath: {} + f:terminationMessagePolicy: {} + f:volumeMounts: + .: {} + k:{"mountPath":"/var/lib/mysql"}: + .: {} + f:mountPath: {} + f:name: {} + f:dnsPolicy: {} + f:restartPolicy: {} + f:schedulerName: {} + f:securityContext: {} + f:terminationGracePeriodSeconds: {} + f:volumes: + .: {} + k:{"name":"mysql-persistent-storage"}: + .: {} + f:name: {} + f:persistentVolumeClaim: + .: {} + f:claimName: {} + manager: kube-controller-manager + operation: Update + time: "2026-04-10T12:15:08Z" + - apiVersion: apps/v1 + fieldsType: FieldsV1 + fieldsV1: + f:status: + f:availableReplicas: {} + f:fullyLabeledReplicas: {} + f:observedGeneration: {} + f:readyReplicas: {} + f:replicas: {} + f:terminatingReplicas: {} + manager: kube-controller-manager + operation: Update + subresource: status + time: "2026-04-10T12:15:58Z" + name: wordpress-mysql-9474c86b + namespace: default + ownerReferences: + - apiVersion: apps/v1 + blockOwnerDeletion: true + controller: true + kind: Deployment + name: wordpress-mysql + uid: 2eba9391-46db-4860-9f9a-a1cb396faf18 + resourceVersion: "798" + uid: c48515d5-a023-4257-b5a1-2504dc2291af +spec: + replicas: 1 + selector: + matchLabels: + app: wordpress + pod-template-hash: 9474c86b + tier: mysql + template: + metadata: + labels: + app: wordpress + pod-template-hash: 9474c86b + tier: mysql + spec: + containers: + - env: + - name: MYSQL_ROOT_PASSWORD + valueFrom: + secretKeyRef: + key: MYSQL_ROOT_PASSWORD + name: wordpress-secrets-hg692g82th + - name: MYSQL_DATABASE + value: wordpress + - name: MYSQL_USER + value: wordpress + - name: MYSQL_PASSWORD + valueFrom: + secretKeyRef: + key: MYSQL_WORDPRESS_PASSWORD + name: wordpress-secrets-hg692g82th + image: mysql:8.0 + imagePullPolicy: IfNotPresent + name: mysql + ports: + - containerPort: 3306 + name: mysql + protocol: TCP + resources: {} + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + volumeMounts: + - mountPath: /var/lib/mysql + name: mysql-persistent-storage + dnsPolicy: ClusterFirst + restartPolicy: Always + schedulerName: default-scheduler + securityContext: {} + terminationGracePeriodSeconds: 30 + volumes: + - name: mysql-persistent-storage + persistentVolumeClaim: + claimName: mysql-pv-claim +status: + availableReplicas: 1 + fullyLabeledReplicas: 1 + observedGeneration: 1 + readyReplicas: 1 + replicas: 1 + terminatingReplicas: 0 diff --git a/docs/transform-scenarios/wordpress-demo/transform/.work/10_KubernetesPlugin/input/default/Secret__v1_default_wordpress-secrets-hg692g82th.yaml b/docs/transform-scenarios/wordpress-demo/transform/.work/10_KubernetesPlugin/input/default/Secret__v1_default_wordpress-secrets-hg692g82th.yaml new file mode 100644 index 00000000..f9deba91 --- /dev/null +++ b/docs/transform-scenarios/wordpress-demo/transform/.work/10_KubernetesPlugin/input/default/Secret__v1_default_wordpress-secrets-hg692g82th.yaml @@ -0,0 +1,33 @@ +apiVersion: v1 +data: + MYSQL_ROOT_PASSWORD: eGFJMmdpdWhxc2V0TC82VDRaOVViUT09 + MYSQL_WORDPRESS_PASSWORD: QzZUa25lcFo3Vm5idTdGZVdBSUFidz09 + WORDPRESS_ADMIN_PASSWORD: d0ZoSytaZDhlU2RhVmx1Ug== +kind: Secret +metadata: + annotations: + kubectl.kubernetes.io/last-applied-configuration: | + {"apiVersion":"v1","data":{"MYSQL_ROOT_PASSWORD":"eGFJMmdpdWhxc2V0TC82VDRaOVViUT09","MYSQL_WORDPRESS_PASSWORD":"QzZUa25lcFo3Vm5idTdGZVdBSUFidz09","WORDPRESS_ADMIN_PASSWORD":"d0ZoSytaZDhlU2RhVmx1Ug=="},"kind":"Secret","metadata":{"annotations":{},"name":"wordpress-secrets-hg692g82th","namespace":"default"},"type":"Opaque"} + creationTimestamp: "2026-04-10T12:15:07Z" + managedFields: + - apiVersion: v1 + fieldsType: FieldsV1 + fieldsV1: + f:data: + .: {} + f:MYSQL_ROOT_PASSWORD: {} + f:MYSQL_WORDPRESS_PASSWORD: {} + f:WORDPRESS_ADMIN_PASSWORD: {} + f:metadata: + f:annotations: + .: {} + f:kubectl.kubernetes.io/last-applied-configuration: {} + f:type: {} + manager: kubectl-client-side-apply + operation: Update + time: "2026-04-10T12:15:07Z" + name: wordpress-secrets-hg692g82th + namespace: default + resourceVersion: "676" + uid: 0bb63c2c-fa4a-4c86-ad5d-141dccbd25ad +type: Opaque diff --git a/docs/transform-scenarios/wordpress-demo/transform/.work/10_KubernetesPlugin/input/default/ServiceAccount__v1_default_default.yaml b/docs/transform-scenarios/wordpress-demo/transform/.work/10_KubernetesPlugin/input/default/ServiceAccount__v1_default_default.yaml new file mode 100644 index 00000000..49a7b37e --- /dev/null +++ b/docs/transform-scenarios/wordpress-demo/transform/.work/10_KubernetesPlugin/input/default/ServiceAccount__v1_default_default.yaml @@ -0,0 +1,8 @@ +apiVersion: v1 +kind: ServiceAccount +metadata: + creationTimestamp: "2026-04-10T12:10:49Z" + name: default + namespace: default + resourceVersion: "336" + uid: 01ad4812-cd89-4fce-914d-7eee37f8f551 diff --git a/docs/transform-scenarios/wordpress-demo/transform/.work/10_KubernetesPlugin/input/default/Service__v1_default_kubernetes.yaml b/docs/transform-scenarios/wordpress-demo/transform/.work/10_KubernetesPlugin/input/default/Service__v1_default_kubernetes.yaml new file mode 100644 index 00000000..0c06b485 --- /dev/null +++ b/docs/transform-scenarios/wordpress-demo/transform/.work/10_KubernetesPlugin/input/default/Service__v1_default_kubernetes.yaml @@ -0,0 +1,54 @@ +apiVersion: v1 +kind: Service +metadata: + creationTimestamp: "2026-04-10T12:10:43Z" + labels: + component: apiserver + provider: kubernetes + managedFields: + - apiVersion: v1 + fieldsType: FieldsV1 + fieldsV1: + f:metadata: + f:labels: + .: {} + f:component: {} + f:provider: {} + f:spec: + f:clusterIP: {} + f:internalTrafficPolicy: {} + f:ipFamilyPolicy: {} + f:ports: + .: {} + k:{"port":443,"protocol":"TCP"}: + .: {} + f:name: {} + f:port: {} + f:protocol: {} + f:targetPort: {} + f:sessionAffinity: {} + f:type: {} + manager: kube-apiserver + operation: Update + time: "2026-04-10T12:10:43Z" + name: kubernetes + namespace: default + resourceVersion: "204" + uid: 5ca30343-0dc7-41ee-adcb-b3e4f821f150 +spec: + clusterIP: 10.96.0.1 + clusterIPs: + - 10.96.0.1 + internalTrafficPolicy: Cluster + ipFamilies: + - IPv4 + ipFamilyPolicy: SingleStack + ports: + - name: https + port: 443 + protocol: TCP + targetPort: 8443 + sessionAffinity: None + type: ClusterIP +status: + loadBalancer: {} diff --git a/docs/transform-scenarios/wordpress-demo/transform/.work/10_KubernetesPlugin/input/default/Service__v1_default_wordpress-mysql.yaml b/docs/transform-scenarios/wordpress-demo/transform/.work/10_KubernetesPlugin/input/default/Service__v1_default_wordpress-mysql.yaml new file mode 100644 index 00000000..29acff57 --- /dev/null +++ b/docs/transform-scenarios/wordpress-demo/transform/.work/10_KubernetesPlugin/input/default/Service__v1_default_wordpress-mysql.yaml @@ -0,0 +1,58 @@ +apiVersion: v1 +kind: Service +metadata: + annotations: + kubectl.kubernetes.io/last-applied-configuration: | + {"apiVersion":"v1","kind":"Service","metadata":{"annotations":{},"labels":{"app":"wordpress"},"name":"wordpress-mysql","namespace":"default"},"spec":{"ports":[{"port":3306}],"selector":{"app":"wordpress","tier":"mysql"}}} + creationTimestamp: "2026-04-10T12:15:07Z" + labels: + app: wordpress + managedFields: + - apiVersion: v1 + fieldsType: FieldsV1 + fieldsV1: + f:metadata: + f:annotations: + .: {} + f:kubectl.kubernetes.io/last-applied-configuration: {} + f:labels: + .: {} + f:app: {} + f:spec: + f:internalTrafficPolicy: {} + f:ports: + .: {} + k:{"port":3306,"protocol":"TCP"}: + .: {} + f:port: {} + f:protocol: {} + f:targetPort: {} + f:selector: {} + f:sessionAffinity: {} + f:type: {} + manager: kubectl-client-side-apply + operation: Update + time: "2026-04-10T12:15:07Z" + name: wordpress-mysql + namespace: default + resourceVersion: "683" + uid: ec2555f1-9fd5-45da-bfa3-f2b59bb1d218 +spec: + clusterIP: 10.101.133.119 + clusterIPs: + - 10.101.133.119 + internalTrafficPolicy: Cluster + ipFamilies: + - IPv4 + ipFamilyPolicy: SingleStack + ports: + - port: 3306 + protocol: TCP + targetPort: 3306 + selector: + app: wordpress + tier: mysql + sessionAffinity: None + type: ClusterIP +status: + loadBalancer: {} diff --git a/docs/transform-scenarios/wordpress-demo/transform/.work/10_KubernetesPlugin/input/default/Service__v1_default_wordpress.yaml b/docs/transform-scenarios/wordpress-demo/transform/.work/10_KubernetesPlugin/input/default/Service__v1_default_wordpress.yaml new file mode 100644 index 00000000..4099abd1 --- /dev/null +++ b/docs/transform-scenarios/wordpress-demo/transform/.work/10_KubernetesPlugin/input/default/Service__v1_default_wordpress.yaml @@ -0,0 +1,63 @@ +apiVersion: v1 +kind: Service +metadata: + annotations: + kubectl.kubernetes.io/last-applied-configuration: | + {"apiVersion":"v1","kind":"Service","metadata":{"annotations":{},"labels":{"app":"wordpress"},"name":"wordpress","namespace":"default"},"spec":{"ports":[{"port":80}],"selector":{"app":"wordpress","tier":"frontend"},"type":"LoadBalancer"}} + creationTimestamp: "2026-04-10T12:15:07Z" + labels: + app: wordpress + managedFields: + - apiVersion: v1 + fieldsType: FieldsV1 + fieldsV1: + f:metadata: + f:annotations: + .: {} + f:kubectl.kubernetes.io/last-applied-configuration: {} + f:labels: + .: {} + f:app: {} + f:spec: + f:allocateLoadBalancerNodePorts: {} + f:externalTrafficPolicy: {} + f:internalTrafficPolicy: {} + f:ports: + .: {} + k:{"port":80,"protocol":"TCP"}: + .: {} + f:port: {} + f:protocol: {} + f:targetPort: {} + f:selector: {} + f:sessionAffinity: {} + f:type: {} + manager: kubectl-client-side-apply + operation: Update + time: "2026-04-10T12:15:07Z" + name: wordpress + namespace: default + resourceVersion: "679" + uid: 9bd59883-6312-4534-a2c1-b71911612715 +spec: + allocateLoadBalancerNodePorts: true + clusterIP: 10.99.69.43 + clusterIPs: + - 10.99.69.43 + externalTrafficPolicy: Cluster + internalTrafficPolicy: Cluster + ipFamilies: + - IPv4 + ipFamilyPolicy: SingleStack + ports: + - nodePort: 32215 + port: 80 + protocol: TCP + targetPort: 80 + selector: + app: wordpress + tier: frontend + sessionAffinity: None + type: LoadBalancer +status: + loadBalancer: {} diff --git a/docs/transform-scenarios/wordpress-demo/transform/.work/10_KubernetesPlugin/output/default/ConfigMap__v1_default_nginx-config.yaml b/docs/transform-scenarios/wordpress-demo/transform/.work/10_KubernetesPlugin/output/default/ConfigMap__v1_default_nginx-config.yaml new file mode 100644 index 00000000..cd99e95c --- /dev/null +++ b/docs/transform-scenarios/wordpress-demo/transform/.work/10_KubernetesPlugin/output/default/ConfigMap__v1_default_nginx-config.yaml @@ -0,0 +1,35 @@ +apiVersion: v1 +data: + nginx.conf: | + events { + worker_connections 64; + } + + http { + include /etc/nginx/mime.types; + default_type application/octet-stream; + + server { + listen 80; + root /var/www/html; + index index.php; + client_max_body_size 32m; + + location / { + try_files $uri $uri/ /index.php?$args; + } + + location ~ \.php$ { + fastcgi_pass localhost:9000; + fastcgi_index index.php; + include fastcgi_params; + fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; + } + } + } +kind: ConfigMap +metadata: + labels: + app: wordpress + name: nginx-config + namespace: default diff --git a/docs/transform-scenarios/wordpress-demo/transform/.work/10_KubernetesPlugin/output/default/Deployment_apps_v1_default_wordpress-mysql.yaml b/docs/transform-scenarios/wordpress-demo/transform/.work/10_KubernetesPlugin/output/default/Deployment_apps_v1_default_wordpress-mysql.yaml new file mode 100644 index 00000000..0b65bd7e --- /dev/null +++ b/docs/transform-scenarios/wordpress-demo/transform/.work/10_KubernetesPlugin/output/default/Deployment_apps_v1_default_wordpress-mysql.yaml @@ -0,0 +1,63 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + annotations: + deployment.kubernetes.io/revision: "1" + labels: + app: wordpress + name: wordpress-mysql + namespace: default +spec: + progressDeadlineSeconds: 600 + replicas: 1 + revisionHistoryLimit: 10 + selector: + matchLabels: + app: wordpress + tier: mysql + strategy: + type: Recreate + template: + metadata: + labels: + app: wordpress + tier: mysql + spec: + containers: + - env: + - name: MYSQL_ROOT_PASSWORD + valueFrom: + secretKeyRef: + key: MYSQL_ROOT_PASSWORD + name: wordpress-secrets-hg692g82th + - name: MYSQL_DATABASE + value: wordpress + - name: MYSQL_USER + value: wordpress + - name: MYSQL_PASSWORD + valueFrom: + secretKeyRef: + key: MYSQL_WORDPRESS_PASSWORD + name: wordpress-secrets-hg692g82th + image: mysql:8.0 + imagePullPolicy: IfNotPresent + name: mysql + ports: + - containerPort: 3306 + name: mysql + protocol: TCP + resources: {} + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + volumeMounts: + - mountPath: /var/lib/mysql + name: mysql-persistent-storage + dnsPolicy: ClusterFirst + restartPolicy: Always + schedulerName: default-scheduler + securityContext: {} + terminationGracePeriodSeconds: 30 + volumes: + - name: mysql-persistent-storage + persistentVolumeClaim: + claimName: mysql-pv-claim diff --git a/docs/transform-scenarios/wordpress-demo/transform/.work/10_KubernetesPlugin/output/default/Deployment_apps_v1_default_wordpress.yaml b/docs/transform-scenarios/wordpress-demo/transform/.work/10_KubernetesPlugin/output/default/Deployment_apps_v1_default_wordpress.yaml new file mode 100644 index 00000000..90e2645a --- /dev/null +++ b/docs/transform-scenarios/wordpress-demo/transform/.work/10_KubernetesPlugin/output/default/Deployment_apps_v1_default_wordpress.yaml @@ -0,0 +1,90 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + annotations: + deployment.kubernetes.io/revision: "1" + labels: + app: wordpress + name: wordpress + namespace: default +spec: + progressDeadlineSeconds: 600 + replicas: 1 + revisionHistoryLimit: 10 + selector: + matchLabels: + app: wordpress + tier: frontend + strategy: + type: Recreate + template: + metadata: + labels: + app: wordpress + tier: frontend + spec: + containers: + - env: + - name: WORDPRESS_DB_HOST + value: wordpress-mysql + - name: WORDPRESS_DB_PASSWORD + valueFrom: + secretKeyRef: + key: MYSQL_WORDPRESS_PASSWORD + name: wordpress-secrets-hg692g82th + - name: WORDPRESS_DB_USER + value: wordpress + - name: WORDPRESS_CONFIG_EXTRA + value: | + // Set SITE URL dynamically from requests to allow reach it on different endpoints + if (isset($_SERVER['HTTP_HOST'])) { + $protocol = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on') ? 'https' : 'http'; + if (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https') { + $protocol = 'https'; + } + define('WP_HOME', $protocol . '://' . $_SERVER['HTTP_HOST']); + define('WP_SITEURL', $protocol . '://' . $_SERVER['HTTP_HOST']); + } + image: wordpress:6-fpm-alpine + imagePullPolicy: IfNotPresent + name: wordpress + ports: + - containerPort: 9000 + name: fastcgi + protocol: TCP + resources: {} + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + volumeMounts: + - mountPath: /var/www/html + name: wordpress-persistent-storage + - image: nginx:alpine + imagePullPolicy: IfNotPresent + name: nginx + ports: + - containerPort: 80 + name: http + protocol: TCP + resources: {} + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + volumeMounts: + - mountPath: /var/www/html + name: wordpress-persistent-storage + readOnly: true + - mountPath: /etc/nginx/nginx.conf + name: nginx-config + subPath: nginx.conf + dnsPolicy: ClusterFirst + restartPolicy: Always + schedulerName: default-scheduler + securityContext: {} + terminationGracePeriodSeconds: 30 + volumes: + - name: wordpress-persistent-storage + persistentVolumeClaim: + claimName: wordpress-pv-claim + - configMap: + defaultMode: 420 + name: nginx-config + name: nginx-config diff --git a/docs/transform-scenarios/wordpress-demo/transform/.work/10_KubernetesPlugin/output/default/Job_batch_v1_default_wordpress-install.yaml b/docs/transform-scenarios/wordpress-demo/transform/.work/10_KubernetesPlugin/output/default/Job_batch_v1_default_wordpress-install.yaml new file mode 100644 index 00000000..69198c32 --- /dev/null +++ b/docs/transform-scenarios/wordpress-demo/transform/.work/10_KubernetesPlugin/output/default/Job_batch_v1_default_wordpress-install.yaml @@ -0,0 +1,141 @@ +apiVersion: batch/v1 +kind: Job +metadata: + labels: + batch.kubernetes.io/controller-uid: be719474-856d-4d84-80ad-4f4ab9ecdd30 + batch.kubernetes.io/job-name: wordpress-install + controller-uid: be719474-856d-4d84-80ad-4f4ab9ecdd30 + job-name: wordpress-install + name: wordpress-install + namespace: default +spec: + backoffLimit: 4 + completionMode: NonIndexed + completions: 1 + manualSelector: false + parallelism: 1 + podReplacementPolicy: TerminatingOrFailed + selector: + matchLabels: + batch.kubernetes.io/controller-uid: be719474-856d-4d84-80ad-4f4ab9ecdd30 + suspend: false + template: + metadata: + labels: + batch.kubernetes.io/controller-uid: be719474-856d-4d84-80ad-4f4ab9ecdd30 + batch.kubernetes.io/job-name: wordpress-install + controller-uid: be719474-856d-4d84-80ad-4f4ab9ecdd30 + job-name: wordpress-install + spec: + containers: + - args: + - -lc + - | + set -e + cd /var/www/html + + echo "Waiting for MySQL on ${WORDPRESS_DB_HOST}:3306..." + for i in $(seq 1 60); do + if mariadb-admin ping -h"${WORDPRESS_DB_HOST}" -u"${WORDPRESS_DB_USER}" -p"${WORDPRESS_DB_PASSWORD}" --ssl=false --silent; then + echo "MySQL is up." + break + fi + echo "MySQL not ready yet (attempt: $i)..." + sleep 5 + done + + if ! mariadb-admin ping -h"${WORDPRESS_DB_HOST}" -u"${WORDPRESS_DB_USER}" -p"${WORDPRESS_DB_PASSWORD}" --ssl=false --silent; then + echo "MySQL did not become ready within the timeout." + exit 1 + fi + + # Make sure WordPress core is present on the volume + if [ ! -f wp-load.php ]; then + echo "WordPress core not found on the volume. Downloading..." + wp core download --allow-root + fi + + # Create wp-config.php if missing + if [ ! -f wp-config.php ]; then + echo "Creating wp-config.php..." + wp config create \ + --dbname="${WORDPRESS_DB_NAME}" \ + --dbuser="${WORDPRESS_DB_USER}" \ + --dbpass="${WORDPRESS_DB_PASSWORD}" \ + --dbhost="${WORDPRESS_DB_HOST}" \ + --allow-root + fi + + # Idempotent install + if wp core is-installed --allow-root >/dev/null 2>&1; then + echo "WordPress is already installed. Nothing to do." + exit 0 + fi + + # Create an installation kind of unique ID + WORDPRESS_SEED_ID=$RANDOM + + echo "Running wp core install..." + wp core install \ + --url="${WORDPRESS_SITE_URL}" \ + --title="${WORDPRESS_SITE_TITLE} #$WORDPRESS_SEED_ID" \ + --admin_user="${WORDPRESS_ADMIN_USER}" \ + --admin_password="${WORDPRESS_ADMIN_PASSWORD}" \ + --admin_email="${WORDPRESS_ADMIN_EMAIL}" \ + --skip-email \ + --allow-root + + echo "Creating sample post..." + wp post create \ + --post_type=post \ + --post_status=publish \ + --post_title="Sample post #$WORDPRESS_SEED_ID" \ + --post_content="Hello from k8s, this is a random post content: $(openssl rand -base64 200 | tr -cs 'a-zA-Z' ' ' | xargs)" + + echo "WORDPRESS_SEED_ID=$WORDPRESS_SEED_ID" + echo "Done. WordPress has been installed." + command: + - bash + env: + - name: WORDPRESS_DB_HOST + value: wordpress-mysql + - name: WORDPRESS_DB_USER + value: wordpress + - name: WORDPRESS_DB_NAME + value: wordpress + - name: WORDPRESS_DB_PASSWORD + valueFrom: + secretKeyRef: + key: MYSQL_WORDPRESS_PASSWORD + name: wordpress-secrets-hg692g82th + - name: WORDPRESS_SITE_URL + value: http://wordpress-k8s.example.local + - name: WORDPRESS_SITE_TITLE + value: My WordPress Site on k8s + - name: WORDPRESS_ADMIN_USER + value: admin + - name: WORDPRESS_ADMIN_PASSWORD + valueFrom: + secretKeyRef: + key: WORDPRESS_ADMIN_PASSWORD + name: wordpress-secrets-hg692g82th + - name: WORDPRESS_ADMIN_EMAIL + value: admin@wordpress-k8s.example.local + image: wordpress:cli-2 + imagePullPolicy: IfNotPresent + name: wp-install + resources: {} + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + volumeMounts: + - mountPath: /var/www/html + name: wordpress-persistent-storage + dnsPolicy: ClusterFirst + restartPolicy: OnFailure + schedulerName: default-scheduler + securityContext: {} + terminationGracePeriodSeconds: 30 + volumes: + - name: wordpress-persistent-storage + persistentVolumeClaim: + claimName: wordpress-pv-claim diff --git a/docs/transform-scenarios/wordpress-demo/transform/.work/10_KubernetesPlugin/output/default/Secret__v1_default_wordpress-secrets-hg692g82th.yaml b/docs/transform-scenarios/wordpress-demo/transform/.work/10_KubernetesPlugin/output/default/Secret__v1_default_wordpress-secrets-hg692g82th.yaml new file mode 100644 index 00000000..4ce42db4 --- /dev/null +++ b/docs/transform-scenarios/wordpress-demo/transform/.work/10_KubernetesPlugin/output/default/Secret__v1_default_wordpress-secrets-hg692g82th.yaml @@ -0,0 +1,10 @@ +apiVersion: v1 +data: + MYSQL_ROOT_PASSWORD: eGFJMmdpdWhxc2V0TC82VDRaOVViUT09 + MYSQL_WORDPRESS_PASSWORD: QzZUa25lcFo3Vm5idTdGZVdBSUFidz09 + WORDPRESS_ADMIN_PASSWORD: d0ZoSytaZDhlU2RhVmx1Ug== +kind: Secret +metadata: + name: wordpress-secrets-hg692g82th + namespace: default +type: Opaque diff --git a/docs/transform-scenarios/wordpress-demo/transform/.work/10_KubernetesPlugin/output/default/Service__v1_default_kubernetes.yaml b/docs/transform-scenarios/wordpress-demo/transform/.work/10_KubernetesPlugin/output/default/Service__v1_default_kubernetes.yaml new file mode 100644 index 00000000..67001d1b --- /dev/null +++ b/docs/transform-scenarios/wordpress-demo/transform/.work/10_KubernetesPlugin/output/default/Service__v1_default_kubernetes.yaml @@ -0,0 +1,20 @@ +apiVersion: v1 +kind: Service +metadata: + labels: + component: apiserver + provider: kubernetes + name: kubernetes + namespace: default +spec: + internalTrafficPolicy: Cluster + ipFamilies: + - IPv4 + ipFamilyPolicy: SingleStack + ports: + - name: https + port: 443 + protocol: TCP + targetPort: 8443 + sessionAffinity: None + type: ClusterIP diff --git a/docs/transform-scenarios/wordpress-demo/transform/.work/10_KubernetesPlugin/output/default/Service__v1_default_wordpress-mysql.yaml b/docs/transform-scenarios/wordpress-demo/transform/.work/10_KubernetesPlugin/output/default/Service__v1_default_wordpress-mysql.yaml new file mode 100644 index 00000000..a3911b15 --- /dev/null +++ b/docs/transform-scenarios/wordpress-demo/transform/.work/10_KubernetesPlugin/output/default/Service__v1_default_wordpress-mysql.yaml @@ -0,0 +1,21 @@ +apiVersion: v1 +kind: Service +metadata: + labels: + app: wordpress + name: wordpress-mysql + namespace: default +spec: + internalTrafficPolicy: Cluster + ipFamilies: + - IPv4 + ipFamilyPolicy: SingleStack + ports: + - port: 3306 + protocol: TCP + targetPort: 3306 + selector: + app: wordpress + tier: mysql + sessionAffinity: None + type: ClusterIP diff --git a/docs/transform-scenarios/wordpress-demo/transform/.work/10_KubernetesPlugin/output/default/Service__v1_default_wordpress.yaml b/docs/transform-scenarios/wordpress-demo/transform/.work/10_KubernetesPlugin/output/default/Service__v1_default_wordpress.yaml new file mode 100644 index 00000000..3c3f9941 --- /dev/null +++ b/docs/transform-scenarios/wordpress-demo/transform/.work/10_KubernetesPlugin/output/default/Service__v1_default_wordpress.yaml @@ -0,0 +1,23 @@ +apiVersion: v1 +kind: Service +metadata: + labels: + app: wordpress + name: wordpress + namespace: default +spec: + allocateLoadBalancerNodePorts: true + externalTrafficPolicy: Cluster + internalTrafficPolicy: Cluster + ipFamilies: + - IPv4 + ipFamilyPolicy: SingleStack + ports: + - port: 80 + protocol: TCP + targetPort: 80 + selector: + app: wordpress + tier: frontend + sessionAffinity: None + type: LoadBalancer diff --git a/docs/transform-scenarios/wordpress-demo/transform/.work/50_CustomLabelsAndNamespace/input/default/ConfigMap__v1_default_nginx-config.yaml b/docs/transform-scenarios/wordpress-demo/transform/.work/50_CustomLabelsAndNamespace/input/default/ConfigMap__v1_default_nginx-config.yaml new file mode 100644 index 00000000..cd99e95c --- /dev/null +++ b/docs/transform-scenarios/wordpress-demo/transform/.work/50_CustomLabelsAndNamespace/input/default/ConfigMap__v1_default_nginx-config.yaml @@ -0,0 +1,35 @@ +apiVersion: v1 +data: + nginx.conf: | + events { + worker_connections 64; + } + + http { + include /etc/nginx/mime.types; + default_type application/octet-stream; + + server { + listen 80; + root /var/www/html; + index index.php; + client_max_body_size 32m; + + location / { + try_files $uri $uri/ /index.php?$args; + } + + location ~ \.php$ { + fastcgi_pass localhost:9000; + fastcgi_index index.php; + include fastcgi_params; + fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; + } + } + } +kind: ConfigMap +metadata: + labels: + app: wordpress + name: nginx-config + namespace: default diff --git a/docs/transform-scenarios/wordpress-demo/transform/.work/50_CustomLabelsAndNamespace/input/default/Deployment_apps_v1_default_wordpress-mysql.yaml b/docs/transform-scenarios/wordpress-demo/transform/.work/50_CustomLabelsAndNamespace/input/default/Deployment_apps_v1_default_wordpress-mysql.yaml new file mode 100644 index 00000000..0b65bd7e --- /dev/null +++ b/docs/transform-scenarios/wordpress-demo/transform/.work/50_CustomLabelsAndNamespace/input/default/Deployment_apps_v1_default_wordpress-mysql.yaml @@ -0,0 +1,63 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + annotations: + deployment.kubernetes.io/revision: "1" + labels: + app: wordpress + name: wordpress-mysql + namespace: default +spec: + progressDeadlineSeconds: 600 + replicas: 1 + revisionHistoryLimit: 10 + selector: + matchLabels: + app: wordpress + tier: mysql + strategy: + type: Recreate + template: + metadata: + labels: + app: wordpress + tier: mysql + spec: + containers: + - env: + - name: MYSQL_ROOT_PASSWORD + valueFrom: + secretKeyRef: + key: MYSQL_ROOT_PASSWORD + name: wordpress-secrets-hg692g82th + - name: MYSQL_DATABASE + value: wordpress + - name: MYSQL_USER + value: wordpress + - name: MYSQL_PASSWORD + valueFrom: + secretKeyRef: + key: MYSQL_WORDPRESS_PASSWORD + name: wordpress-secrets-hg692g82th + image: mysql:8.0 + imagePullPolicy: IfNotPresent + name: mysql + ports: + - containerPort: 3306 + name: mysql + protocol: TCP + resources: {} + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + volumeMounts: + - mountPath: /var/lib/mysql + name: mysql-persistent-storage + dnsPolicy: ClusterFirst + restartPolicy: Always + schedulerName: default-scheduler + securityContext: {} + terminationGracePeriodSeconds: 30 + volumes: + - name: mysql-persistent-storage + persistentVolumeClaim: + claimName: mysql-pv-claim diff --git a/docs/transform-scenarios/wordpress-demo/transform/.work/50_CustomLabelsAndNamespace/input/default/Deployment_apps_v1_default_wordpress.yaml b/docs/transform-scenarios/wordpress-demo/transform/.work/50_CustomLabelsAndNamespace/input/default/Deployment_apps_v1_default_wordpress.yaml new file mode 100644 index 00000000..90e2645a --- /dev/null +++ b/docs/transform-scenarios/wordpress-demo/transform/.work/50_CustomLabelsAndNamespace/input/default/Deployment_apps_v1_default_wordpress.yaml @@ -0,0 +1,90 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + annotations: + deployment.kubernetes.io/revision: "1" + labels: + app: wordpress + name: wordpress + namespace: default +spec: + progressDeadlineSeconds: 600 + replicas: 1 + revisionHistoryLimit: 10 + selector: + matchLabels: + app: wordpress + tier: frontend + strategy: + type: Recreate + template: + metadata: + labels: + app: wordpress + tier: frontend + spec: + containers: + - env: + - name: WORDPRESS_DB_HOST + value: wordpress-mysql + - name: WORDPRESS_DB_PASSWORD + valueFrom: + secretKeyRef: + key: MYSQL_WORDPRESS_PASSWORD + name: wordpress-secrets-hg692g82th + - name: WORDPRESS_DB_USER + value: wordpress + - name: WORDPRESS_CONFIG_EXTRA + value: | + // Set SITE URL dynamically from requests to allow reach it on different endpoints + if (isset($_SERVER['HTTP_HOST'])) { + $protocol = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on') ? 'https' : 'http'; + if (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https') { + $protocol = 'https'; + } + define('WP_HOME', $protocol . '://' . $_SERVER['HTTP_HOST']); + define('WP_SITEURL', $protocol . '://' . $_SERVER['HTTP_HOST']); + } + image: wordpress:6-fpm-alpine + imagePullPolicy: IfNotPresent + name: wordpress + ports: + - containerPort: 9000 + name: fastcgi + protocol: TCP + resources: {} + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + volumeMounts: + - mountPath: /var/www/html + name: wordpress-persistent-storage + - image: nginx:alpine + imagePullPolicy: IfNotPresent + name: nginx + ports: + - containerPort: 80 + name: http + protocol: TCP + resources: {} + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + volumeMounts: + - mountPath: /var/www/html + name: wordpress-persistent-storage + readOnly: true + - mountPath: /etc/nginx/nginx.conf + name: nginx-config + subPath: nginx.conf + dnsPolicy: ClusterFirst + restartPolicy: Always + schedulerName: default-scheduler + securityContext: {} + terminationGracePeriodSeconds: 30 + volumes: + - name: wordpress-persistent-storage + persistentVolumeClaim: + claimName: wordpress-pv-claim + - configMap: + defaultMode: 420 + name: nginx-config + name: nginx-config diff --git a/docs/transform-scenarios/wordpress-demo/transform/.work/50_CustomLabelsAndNamespace/input/default/Job_batch_v1_default_wordpress-install.yaml b/docs/transform-scenarios/wordpress-demo/transform/.work/50_CustomLabelsAndNamespace/input/default/Job_batch_v1_default_wordpress-install.yaml new file mode 100644 index 00000000..69198c32 --- /dev/null +++ b/docs/transform-scenarios/wordpress-demo/transform/.work/50_CustomLabelsAndNamespace/input/default/Job_batch_v1_default_wordpress-install.yaml @@ -0,0 +1,141 @@ +apiVersion: batch/v1 +kind: Job +metadata: + labels: + batch.kubernetes.io/controller-uid: be719474-856d-4d84-80ad-4f4ab9ecdd30 + batch.kubernetes.io/job-name: wordpress-install + controller-uid: be719474-856d-4d84-80ad-4f4ab9ecdd30 + job-name: wordpress-install + name: wordpress-install + namespace: default +spec: + backoffLimit: 4 + completionMode: NonIndexed + completions: 1 + manualSelector: false + parallelism: 1 + podReplacementPolicy: TerminatingOrFailed + selector: + matchLabels: + batch.kubernetes.io/controller-uid: be719474-856d-4d84-80ad-4f4ab9ecdd30 + suspend: false + template: + metadata: + labels: + batch.kubernetes.io/controller-uid: be719474-856d-4d84-80ad-4f4ab9ecdd30 + batch.kubernetes.io/job-name: wordpress-install + controller-uid: be719474-856d-4d84-80ad-4f4ab9ecdd30 + job-name: wordpress-install + spec: + containers: + - args: + - -lc + - | + set -e + cd /var/www/html + + echo "Waiting for MySQL on ${WORDPRESS_DB_HOST}:3306..." + for i in $(seq 1 60); do + if mariadb-admin ping -h"${WORDPRESS_DB_HOST}" -u"${WORDPRESS_DB_USER}" -p"${WORDPRESS_DB_PASSWORD}" --ssl=false --silent; then + echo "MySQL is up." + break + fi + echo "MySQL not ready yet (attempt: $i)..." + sleep 5 + done + + if ! mariadb-admin ping -h"${WORDPRESS_DB_HOST}" -u"${WORDPRESS_DB_USER}" -p"${WORDPRESS_DB_PASSWORD}" --ssl=false --silent; then + echo "MySQL did not become ready within the timeout." + exit 1 + fi + + # Make sure WordPress core is present on the volume + if [ ! -f wp-load.php ]; then + echo "WordPress core not found on the volume. Downloading..." + wp core download --allow-root + fi + + # Create wp-config.php if missing + if [ ! -f wp-config.php ]; then + echo "Creating wp-config.php..." + wp config create \ + --dbname="${WORDPRESS_DB_NAME}" \ + --dbuser="${WORDPRESS_DB_USER}" \ + --dbpass="${WORDPRESS_DB_PASSWORD}" \ + --dbhost="${WORDPRESS_DB_HOST}" \ + --allow-root + fi + + # Idempotent install + if wp core is-installed --allow-root >/dev/null 2>&1; then + echo "WordPress is already installed. Nothing to do." + exit 0 + fi + + # Create an installation kind of unique ID + WORDPRESS_SEED_ID=$RANDOM + + echo "Running wp core install..." + wp core install \ + --url="${WORDPRESS_SITE_URL}" \ + --title="${WORDPRESS_SITE_TITLE} #$WORDPRESS_SEED_ID" \ + --admin_user="${WORDPRESS_ADMIN_USER}" \ + --admin_password="${WORDPRESS_ADMIN_PASSWORD}" \ + --admin_email="${WORDPRESS_ADMIN_EMAIL}" \ + --skip-email \ + --allow-root + + echo "Creating sample post..." + wp post create \ + --post_type=post \ + --post_status=publish \ + --post_title="Sample post #$WORDPRESS_SEED_ID" \ + --post_content="Hello from k8s, this is a random post content: $(openssl rand -base64 200 | tr -cs 'a-zA-Z' ' ' | xargs)" + + echo "WORDPRESS_SEED_ID=$WORDPRESS_SEED_ID" + echo "Done. WordPress has been installed." + command: + - bash + env: + - name: WORDPRESS_DB_HOST + value: wordpress-mysql + - name: WORDPRESS_DB_USER + value: wordpress + - name: WORDPRESS_DB_NAME + value: wordpress + - name: WORDPRESS_DB_PASSWORD + valueFrom: + secretKeyRef: + key: MYSQL_WORDPRESS_PASSWORD + name: wordpress-secrets-hg692g82th + - name: WORDPRESS_SITE_URL + value: http://wordpress-k8s.example.local + - name: WORDPRESS_SITE_TITLE + value: My WordPress Site on k8s + - name: WORDPRESS_ADMIN_USER + value: admin + - name: WORDPRESS_ADMIN_PASSWORD + valueFrom: + secretKeyRef: + key: WORDPRESS_ADMIN_PASSWORD + name: wordpress-secrets-hg692g82th + - name: WORDPRESS_ADMIN_EMAIL + value: admin@wordpress-k8s.example.local + image: wordpress:cli-2 + imagePullPolicy: IfNotPresent + name: wp-install + resources: {} + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + volumeMounts: + - mountPath: /var/www/html + name: wordpress-persistent-storage + dnsPolicy: ClusterFirst + restartPolicy: OnFailure + schedulerName: default-scheduler + securityContext: {} + terminationGracePeriodSeconds: 30 + volumes: + - name: wordpress-persistent-storage + persistentVolumeClaim: + claimName: wordpress-pv-claim diff --git a/docs/transform-scenarios/wordpress-demo/transform/.work/50_CustomLabelsAndNamespace/input/default/Secret__v1_default_wordpress-secrets-hg692g82th.yaml b/docs/transform-scenarios/wordpress-demo/transform/.work/50_CustomLabelsAndNamespace/input/default/Secret__v1_default_wordpress-secrets-hg692g82th.yaml new file mode 100644 index 00000000..4ce42db4 --- /dev/null +++ b/docs/transform-scenarios/wordpress-demo/transform/.work/50_CustomLabelsAndNamespace/input/default/Secret__v1_default_wordpress-secrets-hg692g82th.yaml @@ -0,0 +1,10 @@ +apiVersion: v1 +data: + MYSQL_ROOT_PASSWORD: eGFJMmdpdWhxc2V0TC82VDRaOVViUT09 + MYSQL_WORDPRESS_PASSWORD: QzZUa25lcFo3Vm5idTdGZVdBSUFidz09 + WORDPRESS_ADMIN_PASSWORD: d0ZoSytaZDhlU2RhVmx1Ug== +kind: Secret +metadata: + name: wordpress-secrets-hg692g82th + namespace: default +type: Opaque diff --git a/docs/transform-scenarios/wordpress-demo/transform/.work/50_CustomLabelsAndNamespace/input/default/Service__v1_default_kubernetes.yaml b/docs/transform-scenarios/wordpress-demo/transform/.work/50_CustomLabelsAndNamespace/input/default/Service__v1_default_kubernetes.yaml new file mode 100644 index 00000000..67001d1b --- /dev/null +++ b/docs/transform-scenarios/wordpress-demo/transform/.work/50_CustomLabelsAndNamespace/input/default/Service__v1_default_kubernetes.yaml @@ -0,0 +1,20 @@ +apiVersion: v1 +kind: Service +metadata: + labels: + component: apiserver + provider: kubernetes + name: kubernetes + namespace: default +spec: + internalTrafficPolicy: Cluster + ipFamilies: + - IPv4 + ipFamilyPolicy: SingleStack + ports: + - name: https + port: 443 + protocol: TCP + targetPort: 8443 + sessionAffinity: None + type: ClusterIP diff --git a/docs/transform-scenarios/wordpress-demo/transform/.work/50_CustomLabelsAndNamespace/input/default/Service__v1_default_wordpress-mysql.yaml b/docs/transform-scenarios/wordpress-demo/transform/.work/50_CustomLabelsAndNamespace/input/default/Service__v1_default_wordpress-mysql.yaml new file mode 100644 index 00000000..a3911b15 --- /dev/null +++ b/docs/transform-scenarios/wordpress-demo/transform/.work/50_CustomLabelsAndNamespace/input/default/Service__v1_default_wordpress-mysql.yaml @@ -0,0 +1,21 @@ +apiVersion: v1 +kind: Service +metadata: + labels: + app: wordpress + name: wordpress-mysql + namespace: default +spec: + internalTrafficPolicy: Cluster + ipFamilies: + - IPv4 + ipFamilyPolicy: SingleStack + ports: + - port: 3306 + protocol: TCP + targetPort: 3306 + selector: + app: wordpress + tier: mysql + sessionAffinity: None + type: ClusterIP diff --git a/docs/transform-scenarios/wordpress-demo/transform/.work/50_CustomLabelsAndNamespace/input/default/Service__v1_default_wordpress.yaml b/docs/transform-scenarios/wordpress-demo/transform/.work/50_CustomLabelsAndNamespace/input/default/Service__v1_default_wordpress.yaml new file mode 100644 index 00000000..3c3f9941 --- /dev/null +++ b/docs/transform-scenarios/wordpress-demo/transform/.work/50_CustomLabelsAndNamespace/input/default/Service__v1_default_wordpress.yaml @@ -0,0 +1,23 @@ +apiVersion: v1 +kind: Service +metadata: + labels: + app: wordpress + name: wordpress + namespace: default +spec: + allocateLoadBalancerNodePorts: true + externalTrafficPolicy: Cluster + internalTrafficPolicy: Cluster + ipFamilies: + - IPv4 + ipFamilyPolicy: SingleStack + ports: + - port: 80 + protocol: TCP + targetPort: 80 + selector: + app: wordpress + tier: frontend + sessionAffinity: None + type: LoadBalancer diff --git a/docs/transform-scenarios/wordpress-demo/transform/.work/50_CustomLabelsAndNamespace/output/default/ConfigMap__v1_default_nginx-config.yaml b/docs/transform-scenarios/wordpress-demo/transform/.work/50_CustomLabelsAndNamespace/output/default/ConfigMap__v1_default_nginx-config.yaml new file mode 100644 index 00000000..cd99e95c --- /dev/null +++ b/docs/transform-scenarios/wordpress-demo/transform/.work/50_CustomLabelsAndNamespace/output/default/ConfigMap__v1_default_nginx-config.yaml @@ -0,0 +1,35 @@ +apiVersion: v1 +data: + nginx.conf: | + events { + worker_connections 64; + } + + http { + include /etc/nginx/mime.types; + default_type application/octet-stream; + + server { + listen 80; + root /var/www/html; + index index.php; + client_max_body_size 32m; + + location / { + try_files $uri $uri/ /index.php?$args; + } + + location ~ \.php$ { + fastcgi_pass localhost:9000; + fastcgi_index index.php; + include fastcgi_params; + fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; + } + } + } +kind: ConfigMap +metadata: + labels: + app: wordpress + name: nginx-config + namespace: default diff --git a/docs/transform-scenarios/wordpress-demo/transform/.work/50_CustomLabelsAndNamespace/output/default/Deployment_apps_v1_default_wordpress-mysql.yaml b/docs/transform-scenarios/wordpress-demo/transform/.work/50_CustomLabelsAndNamespace/output/default/Deployment_apps_v1_default_wordpress-mysql.yaml new file mode 100644 index 00000000..0b65bd7e --- /dev/null +++ b/docs/transform-scenarios/wordpress-demo/transform/.work/50_CustomLabelsAndNamespace/output/default/Deployment_apps_v1_default_wordpress-mysql.yaml @@ -0,0 +1,63 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + annotations: + deployment.kubernetes.io/revision: "1" + labels: + app: wordpress + name: wordpress-mysql + namespace: default +spec: + progressDeadlineSeconds: 600 + replicas: 1 + revisionHistoryLimit: 10 + selector: + matchLabels: + app: wordpress + tier: mysql + strategy: + type: Recreate + template: + metadata: + labels: + app: wordpress + tier: mysql + spec: + containers: + - env: + - name: MYSQL_ROOT_PASSWORD + valueFrom: + secretKeyRef: + key: MYSQL_ROOT_PASSWORD + name: wordpress-secrets-hg692g82th + - name: MYSQL_DATABASE + value: wordpress + - name: MYSQL_USER + value: wordpress + - name: MYSQL_PASSWORD + valueFrom: + secretKeyRef: + key: MYSQL_WORDPRESS_PASSWORD + name: wordpress-secrets-hg692g82th + image: mysql:8.0 + imagePullPolicy: IfNotPresent + name: mysql + ports: + - containerPort: 3306 + name: mysql + protocol: TCP + resources: {} + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + volumeMounts: + - mountPath: /var/lib/mysql + name: mysql-persistent-storage + dnsPolicy: ClusterFirst + restartPolicy: Always + schedulerName: default-scheduler + securityContext: {} + terminationGracePeriodSeconds: 30 + volumes: + - name: mysql-persistent-storage + persistentVolumeClaim: + claimName: mysql-pv-claim diff --git a/docs/transform-scenarios/wordpress-demo/transform/.work/50_CustomLabelsAndNamespace/output/default/Deployment_apps_v1_default_wordpress.yaml b/docs/transform-scenarios/wordpress-demo/transform/.work/50_CustomLabelsAndNamespace/output/default/Deployment_apps_v1_default_wordpress.yaml new file mode 100644 index 00000000..90e2645a --- /dev/null +++ b/docs/transform-scenarios/wordpress-demo/transform/.work/50_CustomLabelsAndNamespace/output/default/Deployment_apps_v1_default_wordpress.yaml @@ -0,0 +1,90 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + annotations: + deployment.kubernetes.io/revision: "1" + labels: + app: wordpress + name: wordpress + namespace: default +spec: + progressDeadlineSeconds: 600 + replicas: 1 + revisionHistoryLimit: 10 + selector: + matchLabels: + app: wordpress + tier: frontend + strategy: + type: Recreate + template: + metadata: + labels: + app: wordpress + tier: frontend + spec: + containers: + - env: + - name: WORDPRESS_DB_HOST + value: wordpress-mysql + - name: WORDPRESS_DB_PASSWORD + valueFrom: + secretKeyRef: + key: MYSQL_WORDPRESS_PASSWORD + name: wordpress-secrets-hg692g82th + - name: WORDPRESS_DB_USER + value: wordpress + - name: WORDPRESS_CONFIG_EXTRA + value: | + // Set SITE URL dynamically from requests to allow reach it on different endpoints + if (isset($_SERVER['HTTP_HOST'])) { + $protocol = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on') ? 'https' : 'http'; + if (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https') { + $protocol = 'https'; + } + define('WP_HOME', $protocol . '://' . $_SERVER['HTTP_HOST']); + define('WP_SITEURL', $protocol . '://' . $_SERVER['HTTP_HOST']); + } + image: wordpress:6-fpm-alpine + imagePullPolicy: IfNotPresent + name: wordpress + ports: + - containerPort: 9000 + name: fastcgi + protocol: TCP + resources: {} + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + volumeMounts: + - mountPath: /var/www/html + name: wordpress-persistent-storage + - image: nginx:alpine + imagePullPolicy: IfNotPresent + name: nginx + ports: + - containerPort: 80 + name: http + protocol: TCP + resources: {} + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + volumeMounts: + - mountPath: /var/www/html + name: wordpress-persistent-storage + readOnly: true + - mountPath: /etc/nginx/nginx.conf + name: nginx-config + subPath: nginx.conf + dnsPolicy: ClusterFirst + restartPolicy: Always + schedulerName: default-scheduler + securityContext: {} + terminationGracePeriodSeconds: 30 + volumes: + - name: wordpress-persistent-storage + persistentVolumeClaim: + claimName: wordpress-pv-claim + - configMap: + defaultMode: 420 + name: nginx-config + name: nginx-config diff --git a/docs/transform-scenarios/wordpress-demo/transform/.work/50_CustomLabelsAndNamespace/output/default/Job_batch_v1_default_wordpress-install.yaml b/docs/transform-scenarios/wordpress-demo/transform/.work/50_CustomLabelsAndNamespace/output/default/Job_batch_v1_default_wordpress-install.yaml new file mode 100644 index 00000000..69198c32 --- /dev/null +++ b/docs/transform-scenarios/wordpress-demo/transform/.work/50_CustomLabelsAndNamespace/output/default/Job_batch_v1_default_wordpress-install.yaml @@ -0,0 +1,141 @@ +apiVersion: batch/v1 +kind: Job +metadata: + labels: + batch.kubernetes.io/controller-uid: be719474-856d-4d84-80ad-4f4ab9ecdd30 + batch.kubernetes.io/job-name: wordpress-install + controller-uid: be719474-856d-4d84-80ad-4f4ab9ecdd30 + job-name: wordpress-install + name: wordpress-install + namespace: default +spec: + backoffLimit: 4 + completionMode: NonIndexed + completions: 1 + manualSelector: false + parallelism: 1 + podReplacementPolicy: TerminatingOrFailed + selector: + matchLabels: + batch.kubernetes.io/controller-uid: be719474-856d-4d84-80ad-4f4ab9ecdd30 + suspend: false + template: + metadata: + labels: + batch.kubernetes.io/controller-uid: be719474-856d-4d84-80ad-4f4ab9ecdd30 + batch.kubernetes.io/job-name: wordpress-install + controller-uid: be719474-856d-4d84-80ad-4f4ab9ecdd30 + job-name: wordpress-install + spec: + containers: + - args: + - -lc + - | + set -e + cd /var/www/html + + echo "Waiting for MySQL on ${WORDPRESS_DB_HOST}:3306..." + for i in $(seq 1 60); do + if mariadb-admin ping -h"${WORDPRESS_DB_HOST}" -u"${WORDPRESS_DB_USER}" -p"${WORDPRESS_DB_PASSWORD}" --ssl=false --silent; then + echo "MySQL is up." + break + fi + echo "MySQL not ready yet (attempt: $i)..." + sleep 5 + done + + if ! mariadb-admin ping -h"${WORDPRESS_DB_HOST}" -u"${WORDPRESS_DB_USER}" -p"${WORDPRESS_DB_PASSWORD}" --ssl=false --silent; then + echo "MySQL did not become ready within the timeout." + exit 1 + fi + + # Make sure WordPress core is present on the volume + if [ ! -f wp-load.php ]; then + echo "WordPress core not found on the volume. Downloading..." + wp core download --allow-root + fi + + # Create wp-config.php if missing + if [ ! -f wp-config.php ]; then + echo "Creating wp-config.php..." + wp config create \ + --dbname="${WORDPRESS_DB_NAME}" \ + --dbuser="${WORDPRESS_DB_USER}" \ + --dbpass="${WORDPRESS_DB_PASSWORD}" \ + --dbhost="${WORDPRESS_DB_HOST}" \ + --allow-root + fi + + # Idempotent install + if wp core is-installed --allow-root >/dev/null 2>&1; then + echo "WordPress is already installed. Nothing to do." + exit 0 + fi + + # Create an installation kind of unique ID + WORDPRESS_SEED_ID=$RANDOM + + echo "Running wp core install..." + wp core install \ + --url="${WORDPRESS_SITE_URL}" \ + --title="${WORDPRESS_SITE_TITLE} #$WORDPRESS_SEED_ID" \ + --admin_user="${WORDPRESS_ADMIN_USER}" \ + --admin_password="${WORDPRESS_ADMIN_PASSWORD}" \ + --admin_email="${WORDPRESS_ADMIN_EMAIL}" \ + --skip-email \ + --allow-root + + echo "Creating sample post..." + wp post create \ + --post_type=post \ + --post_status=publish \ + --post_title="Sample post #$WORDPRESS_SEED_ID" \ + --post_content="Hello from k8s, this is a random post content: $(openssl rand -base64 200 | tr -cs 'a-zA-Z' ' ' | xargs)" + + echo "WORDPRESS_SEED_ID=$WORDPRESS_SEED_ID" + echo "Done. WordPress has been installed." + command: + - bash + env: + - name: WORDPRESS_DB_HOST + value: wordpress-mysql + - name: WORDPRESS_DB_USER + value: wordpress + - name: WORDPRESS_DB_NAME + value: wordpress + - name: WORDPRESS_DB_PASSWORD + valueFrom: + secretKeyRef: + key: MYSQL_WORDPRESS_PASSWORD + name: wordpress-secrets-hg692g82th + - name: WORDPRESS_SITE_URL + value: http://wordpress-k8s.example.local + - name: WORDPRESS_SITE_TITLE + value: My WordPress Site on k8s + - name: WORDPRESS_ADMIN_USER + value: admin + - name: WORDPRESS_ADMIN_PASSWORD + valueFrom: + secretKeyRef: + key: WORDPRESS_ADMIN_PASSWORD + name: wordpress-secrets-hg692g82th + - name: WORDPRESS_ADMIN_EMAIL + value: admin@wordpress-k8s.example.local + image: wordpress:cli-2 + imagePullPolicy: IfNotPresent + name: wp-install + resources: {} + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + volumeMounts: + - mountPath: /var/www/html + name: wordpress-persistent-storage + dnsPolicy: ClusterFirst + restartPolicy: OnFailure + schedulerName: default-scheduler + securityContext: {} + terminationGracePeriodSeconds: 30 + volumes: + - name: wordpress-persistent-storage + persistentVolumeClaim: + claimName: wordpress-pv-claim diff --git a/docs/transform-scenarios/wordpress-demo/transform/.work/50_CustomLabelsAndNamespace/output/default/Secret__v1_default_wordpress-secrets-hg692g82th.yaml b/docs/transform-scenarios/wordpress-demo/transform/.work/50_CustomLabelsAndNamespace/output/default/Secret__v1_default_wordpress-secrets-hg692g82th.yaml new file mode 100644 index 00000000..4ce42db4 --- /dev/null +++ b/docs/transform-scenarios/wordpress-demo/transform/.work/50_CustomLabelsAndNamespace/output/default/Secret__v1_default_wordpress-secrets-hg692g82th.yaml @@ -0,0 +1,10 @@ +apiVersion: v1 +data: + MYSQL_ROOT_PASSWORD: eGFJMmdpdWhxc2V0TC82VDRaOVViUT09 + MYSQL_WORDPRESS_PASSWORD: QzZUa25lcFo3Vm5idTdGZVdBSUFidz09 + WORDPRESS_ADMIN_PASSWORD: d0ZoSytaZDhlU2RhVmx1Ug== +kind: Secret +metadata: + name: wordpress-secrets-hg692g82th + namespace: default +type: Opaque diff --git a/docs/transform-scenarios/wordpress-demo/transform/.work/50_CustomLabelsAndNamespace/output/default/Service__v1_default_kubernetes.yaml b/docs/transform-scenarios/wordpress-demo/transform/.work/50_CustomLabelsAndNamespace/output/default/Service__v1_default_kubernetes.yaml new file mode 100644 index 00000000..67001d1b --- /dev/null +++ b/docs/transform-scenarios/wordpress-demo/transform/.work/50_CustomLabelsAndNamespace/output/default/Service__v1_default_kubernetes.yaml @@ -0,0 +1,20 @@ +apiVersion: v1 +kind: Service +metadata: + labels: + component: apiserver + provider: kubernetes + name: kubernetes + namespace: default +spec: + internalTrafficPolicy: Cluster + ipFamilies: + - IPv4 + ipFamilyPolicy: SingleStack + ports: + - name: https + port: 443 + protocol: TCP + targetPort: 8443 + sessionAffinity: None + type: ClusterIP diff --git a/docs/transform-scenarios/wordpress-demo/transform/.work/50_CustomLabelsAndNamespace/output/default/Service__v1_default_wordpress-mysql.yaml b/docs/transform-scenarios/wordpress-demo/transform/.work/50_CustomLabelsAndNamespace/output/default/Service__v1_default_wordpress-mysql.yaml new file mode 100644 index 00000000..a3911b15 --- /dev/null +++ b/docs/transform-scenarios/wordpress-demo/transform/.work/50_CustomLabelsAndNamespace/output/default/Service__v1_default_wordpress-mysql.yaml @@ -0,0 +1,21 @@ +apiVersion: v1 +kind: Service +metadata: + labels: + app: wordpress + name: wordpress-mysql + namespace: default +spec: + internalTrafficPolicy: Cluster + ipFamilies: + - IPv4 + ipFamilyPolicy: SingleStack + ports: + - port: 3306 + protocol: TCP + targetPort: 3306 + selector: + app: wordpress + tier: mysql + sessionAffinity: None + type: ClusterIP diff --git a/docs/transform-scenarios/wordpress-demo/transform/.work/50_CustomLabelsAndNamespace/output/default/Service__v1_default_wordpress.yaml b/docs/transform-scenarios/wordpress-demo/transform/.work/50_CustomLabelsAndNamespace/output/default/Service__v1_default_wordpress.yaml new file mode 100644 index 00000000..3c3f9941 --- /dev/null +++ b/docs/transform-scenarios/wordpress-demo/transform/.work/50_CustomLabelsAndNamespace/output/default/Service__v1_default_wordpress.yaml @@ -0,0 +1,23 @@ +apiVersion: v1 +kind: Service +metadata: + labels: + app: wordpress + name: wordpress + namespace: default +spec: + allocateLoadBalancerNodePorts: true + externalTrafficPolicy: Cluster + internalTrafficPolicy: Cluster + ipFamilies: + - IPv4 + ipFamilyPolicy: SingleStack + ports: + - port: 80 + protocol: TCP + targetPort: 80 + selector: + app: wordpress + tier: frontend + sessionAffinity: None + type: LoadBalancer diff --git a/docs/transform-scenarios/wordpress-demo/transform/10_KubernetesPlugin/kustomization.yaml b/docs/transform-scenarios/wordpress-demo/transform/10_KubernetesPlugin/kustomization.yaml new file mode 100644 index 00000000..b5b8cd86 --- /dev/null +++ b/docs/transform-scenarios/wordpress-demo/transform/10_KubernetesPlugin/kustomization.yaml @@ -0,0 +1,81 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +patches: +- path: patches/default--apps-v1--Deployment--wordpress-mysql.patch.yaml + target: + group: apps + kind: Deployment + name: wordpress-mysql + namespace: default + version: v1 +- path: patches/default--apps-v1--Deployment--wordpress.patch.yaml + target: + group: apps + kind: Deployment + name: wordpress + namespace: default + version: v1 +- path: patches/default--batch-v1--Job--wordpress-install.patch.yaml + target: + group: batch + kind: Job + name: wordpress-install + namespace: default + version: v1 +- path: patches/default--v1--ConfigMap--nginx-config.patch.yaml + target: + kind: ConfigMap + name: nginx-config + namespace: default + version: v1 +- path: patches/default--v1--Secret--wordpress-secrets-hg692g82th.patch.yaml + target: + kind: Secret + name: wordpress-secrets-hg692g82th + namespace: default + version: v1 +- path: patches/default--v1--Service--kubernetes.patch.yaml + target: + kind: Service + name: kubernetes + namespace: default + version: v1 +- path: patches/default--v1--Service--wordpress-mysql.patch.yaml + target: + kind: Service + name: wordpress-mysql + namespace: default + version: v1 +- path: patches/default--v1--Service--wordpress.patch.yaml + target: + kind: Service + name: wordpress + namespace: default + version: v1 +resources: +- resources/ConfigMap__v1_default_nginx-config.yaml +- resources/Deployment_apps_v1_default_wordpress-mysql.yaml +- resources/Deployment_apps_v1_default_wordpress.yaml +- resources/Job_batch_v1_default_wordpress-install.yaml +- resources/Secret__v1_default_wordpress-secrets-hg692g82th.yaml +- resources/Service__v1_default_kubernetes.yaml +- resources/Service__v1_default_wordpress-mysql.yaml +- resources/Service__v1_default_wordpress.yaml + +# Whiteout resources are written to resources/ for complete snapshot +# but excluded from active resources list above: +# - resources/ConfigMap__v1_default_kube-root-ca.crt.yaml +# - resources/EndpointSlice_discovery.k8s.io_v1_default_kubernetes.yaml +# - resources/EndpointSlice_discovery.k8s.io_v1_default_wordpress-mysql-jlwnp.yaml +# - resources/EndpointSlice_discovery.k8s.io_v1_default_wordpress-wpfqk.yaml +# - resources/Endpoints__v1_default_kubernetes.yaml +# - resources/Endpoints__v1_default_wordpress-mysql.yaml +# - resources/Endpoints__v1_default_wordpress.yaml +# - resources/PersistentVolumeClaim__v1_default_mysql-pv-claim.yaml +# - resources/PersistentVolumeClaim__v1_default_wordpress-pv-claim.yaml +# - resources/Pod__v1_default_wordpress-74b89cc84c-nm9f8.yaml +# - resources/Pod__v1_default_wordpress-install-xrqtc.yaml +# - resources/Pod__v1_default_wordpress-mysql-9474c86b-fr65w.yaml +# - resources/ReplicaSet_apps_v1_default_wordpress-74b89cc84c.yaml +# - resources/ReplicaSet_apps_v1_default_wordpress-mysql-9474c86b.yaml +# - resources/ServiceAccount__v1_default_default.yaml diff --git a/docs/transform-scenarios/wordpress-demo/transform/10_KubernetesPlugin/patches/default--apps-v1--Deployment--wordpress-mysql.patch.yaml b/docs/transform-scenarios/wordpress-demo/transform/10_KubernetesPlugin/patches/default--apps-v1--Deployment--wordpress-mysql.patch.yaml new file mode 100644 index 00000000..e37beb86 --- /dev/null +++ b/docs/transform-scenarios/wordpress-demo/transform/10_KubernetesPlugin/patches/default--apps-v1--Deployment--wordpress-mysql.patch.yaml @@ -0,0 +1,14 @@ +- op: remove + path: /metadata/uid +- op: remove + path: /metadata/resourceVersion +- op: remove + path: /metadata/creationTimestamp +- op: remove + path: /metadata/generation +- op: remove + path: /metadata/managedFields +- op: remove + path: /metadata/annotations/kubectl.kubernetes.io~1last-applied-configuration +- op: remove + path: /status diff --git a/docs/transform-scenarios/wordpress-demo/transform/10_KubernetesPlugin/patches/default--apps-v1--Deployment--wordpress.patch.yaml b/docs/transform-scenarios/wordpress-demo/transform/10_KubernetesPlugin/patches/default--apps-v1--Deployment--wordpress.patch.yaml new file mode 100644 index 00000000..393af51b --- /dev/null +++ b/docs/transform-scenarios/wordpress-demo/transform/10_KubernetesPlugin/patches/default--apps-v1--Deployment--wordpress.patch.yaml @@ -0,0 +1,14 @@ +- op: remove + path: /metadata/resourceVersion +- op: remove + path: /metadata/creationTimestamp +- op: remove + path: /metadata/generation +- op: remove + path: /metadata/managedFields +- op: remove + path: /metadata/annotations/kubectl.kubernetes.io~1last-applied-configuration +- op: remove + path: /status +- op: remove + path: /metadata/uid diff --git a/docs/transform-scenarios/wordpress-demo/transform/10_KubernetesPlugin/patches/default--batch-v1--Job--wordpress-install.patch.yaml b/docs/transform-scenarios/wordpress-demo/transform/10_KubernetesPlugin/patches/default--batch-v1--Job--wordpress-install.patch.yaml new file mode 100644 index 00000000..393af51b --- /dev/null +++ b/docs/transform-scenarios/wordpress-demo/transform/10_KubernetesPlugin/patches/default--batch-v1--Job--wordpress-install.patch.yaml @@ -0,0 +1,14 @@ +- op: remove + path: /metadata/resourceVersion +- op: remove + path: /metadata/creationTimestamp +- op: remove + path: /metadata/generation +- op: remove + path: /metadata/managedFields +- op: remove + path: /metadata/annotations/kubectl.kubernetes.io~1last-applied-configuration +- op: remove + path: /status +- op: remove + path: /metadata/uid diff --git a/docs/transform-scenarios/wordpress-demo/transform/10_KubernetesPlugin/patches/default--v1--ConfigMap--nginx-config.patch.yaml b/docs/transform-scenarios/wordpress-demo/transform/10_KubernetesPlugin/patches/default--v1--ConfigMap--nginx-config.patch.yaml new file mode 100644 index 00000000..6540de79 --- /dev/null +++ b/docs/transform-scenarios/wordpress-demo/transform/10_KubernetesPlugin/patches/default--v1--ConfigMap--nginx-config.patch.yaml @@ -0,0 +1,10 @@ +- op: remove + path: /metadata/managedFields +- op: remove + path: /metadata/annotations/kubectl.kubernetes.io~1last-applied-configuration +- op: remove + path: /metadata/uid +- op: remove + path: /metadata/resourceVersion +- op: remove + path: /metadata/creationTimestamp diff --git a/docs/transform-scenarios/wordpress-demo/transform/10_KubernetesPlugin/patches/default--v1--Secret--wordpress-secrets-hg692g82th.patch.yaml b/docs/transform-scenarios/wordpress-demo/transform/10_KubernetesPlugin/patches/default--v1--Secret--wordpress-secrets-hg692g82th.patch.yaml new file mode 100644 index 00000000..3e0d6b7a --- /dev/null +++ b/docs/transform-scenarios/wordpress-demo/transform/10_KubernetesPlugin/patches/default--v1--Secret--wordpress-secrets-hg692g82th.patch.yaml @@ -0,0 +1,10 @@ +- op: remove + path: /metadata/uid +- op: remove + path: /metadata/resourceVersion +- op: remove + path: /metadata/creationTimestamp +- op: remove + path: /metadata/managedFields +- op: remove + path: /metadata/annotations/kubectl.kubernetes.io~1last-applied-configuration diff --git a/docs/transform-scenarios/wordpress-demo/transform/10_KubernetesPlugin/patches/default--v1--Service--kubernetes.patch.yaml b/docs/transform-scenarios/wordpress-demo/transform/10_KubernetesPlugin/patches/default--v1--Service--kubernetes.patch.yaml new file mode 100644 index 00000000..e92d7e3f --- /dev/null +++ b/docs/transform-scenarios/wordpress-demo/transform/10_KubernetesPlugin/patches/default--v1--Service--kubernetes.patch.yaml @@ -0,0 +1,14 @@ +- op: remove + path: /metadata/managedFields +- op: remove + path: /status +- op: remove + path: /spec/clusterIP +- op: remove + path: /spec/clusterIPs +- op: remove + path: /metadata/uid +- op: remove + path: /metadata/resourceVersion +- op: remove + path: /metadata/creationTimestamp diff --git a/docs/transform-scenarios/wordpress-demo/transform/10_KubernetesPlugin/patches/default--v1--Service--wordpress-mysql.patch.yaml b/docs/transform-scenarios/wordpress-demo/transform/10_KubernetesPlugin/patches/default--v1--Service--wordpress-mysql.patch.yaml new file mode 100644 index 00000000..399e7639 --- /dev/null +++ b/docs/transform-scenarios/wordpress-demo/transform/10_KubernetesPlugin/patches/default--v1--Service--wordpress-mysql.patch.yaml @@ -0,0 +1,16 @@ +- op: remove + path: /spec/clusterIP +- op: remove + path: /spec/clusterIPs +- op: remove + path: /metadata/uid +- op: remove + path: /metadata/resourceVersion +- op: remove + path: /metadata/creationTimestamp +- op: remove + path: /metadata/managedFields +- op: remove + path: /metadata/annotations/kubectl.kubernetes.io~1last-applied-configuration +- op: remove + path: /status diff --git a/docs/transform-scenarios/wordpress-demo/transform/10_KubernetesPlugin/patches/default--v1--Service--wordpress.patch.yaml b/docs/transform-scenarios/wordpress-demo/transform/10_KubernetesPlugin/patches/default--v1--Service--wordpress.patch.yaml new file mode 100644 index 00000000..5ded737c --- /dev/null +++ b/docs/transform-scenarios/wordpress-demo/transform/10_KubernetesPlugin/patches/default--v1--Service--wordpress.patch.yaml @@ -0,0 +1,18 @@ +- op: remove + path: /spec/clusterIP +- op: remove + path: /spec/clusterIPs +- op: remove + path: /status +- op: remove + path: /spec/ports/0/nodePort +- op: remove + path: /metadata/uid +- op: remove + path: /metadata/resourceVersion +- op: remove + path: /metadata/creationTimestamp +- op: remove + path: /metadata/managedFields +- op: remove + path: /metadata/annotations/kubectl.kubernetes.io~1last-applied-configuration diff --git a/docs/transform-scenarios/wordpress-demo/transform/10_KubernetesPlugin/resources/ConfigMap__v1_default_kube-root-ca.crt.yaml b/docs/transform-scenarios/wordpress-demo/transform/10_KubernetesPlugin/resources/ConfigMap__v1_default_kube-root-ca.crt.yaml new file mode 100644 index 00000000..e49b6186 --- /dev/null +++ b/docs/transform-scenarios/wordpress-demo/transform/10_KubernetesPlugin/resources/ConfigMap__v1_default_kube-root-ca.crt.yaml @@ -0,0 +1,48 @@ +apiVersion: v1 +data: + ca.crt: | + -----BEGIN CERTIFICATE----- + MIIDBjCCAe6gAwIBAgIBATANBgkqhkiG9w0BAQsFADAVMRMwEQYDVQQDEwptaW5p + a3ViZUNBMB4XDTIzMDgyMTEzMTEyMFoXDTMzMDgxOTEzMTEyMFowFTETMBEGA1UE + AxMKbWluaWt1YmVDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOUi + L0a0yk+ANnuYn7ESu1z4g1N/xv37Ph6WiSLVutimTpg+vc3lwBVOkW+oM9rXGm3C + DtLr70y2fPBQq5iYwhivH+AiJCT51zh+I992CBMqTZmMYq1Yf2hhuN2xUximuGJg + 7lI4lAfHbn64yYxlYIOwVu58lmmycO3tWrqRM45w0URAmjHqCw7D0z//83nmrU6F + R1f4eY06v1QNNiyBlYCnWWZdusNtYNNGNQ6dRBH5IsvBhmbjN60m6QYZrR+sA1UE + s3lHkYa2lYLkIWbugYfaTZigqxGPUl8GMBtLeYDBRTMRe0WMYW3Gl+w1vjk+2o4v + 5uyvMB5GiUq9AxXvREMCAwEAAaNhMF8wDgYDVR0PAQH/BAQDAgKkMB0GA1UdJQQW + MBQGCCsGAQUFBwMCBggrBgEFBQcDATAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQW + BBRWM9OkFUq3iXhg/okf/Ve1sP3B0jANBgkqhkiG9w0BAQsFAAOCAQEAyw49Smi7 + Dz7SpoNwOd+D44CpuWPE19vG8vdf9+XWQwUy1QhJh21dQkk/U6lF6yVU1RBv32Tm + xYmOtu87fv85bB5lH5WURk/ljAsNo+7sEKWyq9q2cD4A+vh1r2U+EkI0doXYP1um + U42UdLLL2RkxuSqCkdCfCdFpbNz2VOCRlJg93vNUkGsfNehE6xXj4LqCQYXQVHlb + hJLGuKrVtE8dS/lgxc7JmqVo521ft8KKKadHvIP7W0j45sMg9K+OHaUp8cOZ02m2 + J+gRC1xg4A08AAmWV+/q2+byAecrUDf/LQcWwNqjTDRWAELiKLkF5UmbYAIr9wia + FdCTC8qesp6BEw== + -----END CERTIFICATE----- +kind: ConfigMap +metadata: + annotations: + kubernetes.io/description: Contains a CA bundle that can be used to verify the + kube-apiserver when using internal endpoints such as the internal service IP + or kubernetes.default.svc. No other usage is guaranteed across distributions + of Kubernetes clusters. + creationTimestamp: "2026-04-10T12:10:48Z" + managedFields: + - apiVersion: v1 + fieldsType: FieldsV1 + fieldsV1: + f:data: + .: {} + f:ca.crt: {} + f:metadata: + f:annotations: + .: {} + f:kubernetes.io/description: {} + manager: kube-controller-manager + operation: Update + time: "2026-04-10T12:10:48Z" + name: kube-root-ca.crt + namespace: default + resourceVersion: "326" + uid: aa6a6275-00a5-44aa-90c4-5fa00d031c7f diff --git a/docs/transform-scenarios/wordpress-demo/transform/10_KubernetesPlugin/resources/ConfigMap__v1_default_nginx-config.yaml b/docs/transform-scenarios/wordpress-demo/transform/10_KubernetesPlugin/resources/ConfigMap__v1_default_nginx-config.yaml new file mode 100644 index 00000000..f43a445c --- /dev/null +++ b/docs/transform-scenarios/wordpress-demo/transform/10_KubernetesPlugin/resources/ConfigMap__v1_default_nginx-config.yaml @@ -0,0 +1,58 @@ +apiVersion: v1 +data: + nginx.conf: | + events { + worker_connections 64; + } + + http { + include /etc/nginx/mime.types; + default_type application/octet-stream; + + server { + listen 80; + root /var/www/html; + index index.php; + client_max_body_size 32m; + + location / { + try_files $uri $uri/ /index.php?$args; + } + + location ~ \.php$ { + fastcgi_pass localhost:9000; + fastcgi_index index.php; + include fastcgi_params; + fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; + } + } + } +kind: ConfigMap +metadata: + annotations: + kubectl.kubernetes.io/last-applied-configuration: | + {"apiVersion":"v1","data":{"nginx.conf":"events {\n worker_connections 64;\n}\n\nhttp {\n include /etc/nginx/mime.types;\n default_type application/octet-stream;\n\n server {\n listen 80;\n root /var/www/html;\n index index.php;\n client_max_body_size 32m;\n\n location / {\n try_files $uri $uri/ /index.php?$args;\n }\n\n location ~ \\.php$ {\n fastcgi_pass localhost:9000;\n fastcgi_index index.php;\n include fastcgi_params;\n fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;\n }\n }\n}\n"},"kind":"ConfigMap","metadata":{"annotations":{},"labels":{"app":"wordpress"},"name":"nginx-config","namespace":"default"}} + creationTimestamp: "2026-04-10T12:15:07Z" + labels: + app: wordpress + managedFields: + - apiVersion: v1 + fieldsType: FieldsV1 + fieldsV1: + f:data: + .: {} + f:nginx.conf: {} + f:metadata: + f:annotations: + .: {} + f:kubectl.kubernetes.io/last-applied-configuration: {} + f:labels: + .: {} + f:app: {} + manager: kubectl-client-side-apply + operation: Update + time: "2026-04-10T12:15:07Z" + name: nginx-config + namespace: default + resourceVersion: "675" + uid: ced3a8c2-2b9d-47e9-90e6-0a780c2416bd diff --git a/docs/transform-scenarios/wordpress-demo/transform/10_KubernetesPlugin/resources/Deployment_apps_v1_default_wordpress-mysql.yaml b/docs/transform-scenarios/wordpress-demo/transform/10_KubernetesPlugin/resources/Deployment_apps_v1_default_wordpress-mysql.yaml new file mode 100644 index 00000000..a373cafc --- /dev/null +++ b/docs/transform-scenarios/wordpress-demo/transform/10_KubernetesPlugin/resources/Deployment_apps_v1_default_wordpress-mysql.yaml @@ -0,0 +1,209 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + annotations: + deployment.kubernetes.io/revision: "1" + kubectl.kubernetes.io/last-applied-configuration: | + {"apiVersion":"apps/v1","kind":"Deployment","metadata":{"annotations":{},"labels":{"app":"wordpress"},"name":"wordpress-mysql","namespace":"default"},"spec":{"selector":{"matchLabels":{"app":"wordpress","tier":"mysql"}},"strategy":{"type":"Recreate"},"template":{"metadata":{"labels":{"app":"wordpress","tier":"mysql"}},"spec":{"containers":[{"env":[{"name":"MYSQL_ROOT_PASSWORD","valueFrom":{"secretKeyRef":{"key":"MYSQL_ROOT_PASSWORD","name":"wordpress-secrets-hg692g82th"}}},{"name":"MYSQL_DATABASE","value":"wordpress"},{"name":"MYSQL_USER","value":"wordpress"},{"name":"MYSQL_PASSWORD","valueFrom":{"secretKeyRef":{"key":"MYSQL_WORDPRESS_PASSWORD","name":"wordpress-secrets-hg692g82th"}}}],"image":"mysql:8.0","name":"mysql","ports":[{"containerPort":3306,"name":"mysql"}],"volumeMounts":[{"mountPath":"/var/lib/mysql","name":"mysql-persistent-storage"}]}],"volumes":[{"name":"mysql-persistent-storage","persistentVolumeClaim":{"claimName":"mysql-pv-claim"}}]}}}} + creationTimestamp: "2026-04-10T12:15:08Z" + generation: 1 + labels: + app: wordpress + managedFields: + - apiVersion: apps/v1 + fieldsType: FieldsV1 + fieldsV1: + f:metadata: + f:annotations: + .: {} + f:kubectl.kubernetes.io/last-applied-configuration: {} + f:labels: + .: {} + f:app: {} + f:spec: + f:progressDeadlineSeconds: {} + f:replicas: {} + f:revisionHistoryLimit: {} + f:selector: {} + f:strategy: + f:type: {} + f:template: + f:metadata: + f:labels: + .: {} + f:app: {} + f:tier: {} + f:spec: + f:containers: + k:{"name":"mysql"}: + .: {} + f:env: + .: {} + k:{"name":"MYSQL_DATABASE"}: + .: {} + f:name: {} + f:value: {} + k:{"name":"MYSQL_PASSWORD"}: + .: {} + f:name: {} + f:valueFrom: + .: {} + f:secretKeyRef: {} + k:{"name":"MYSQL_ROOT_PASSWORD"}: + .: {} + f:name: {} + f:valueFrom: + .: {} + f:secretKeyRef: {} + k:{"name":"MYSQL_USER"}: + .: {} + f:name: {} + f:value: {} + f:image: {} + f:imagePullPolicy: {} + f:name: {} + f:ports: + .: {} + k:{"containerPort":3306,"protocol":"TCP"}: + .: {} + f:containerPort: {} + f:name: {} + f:protocol: {} + f:resources: {} + f:terminationMessagePath: {} + f:terminationMessagePolicy: {} + f:volumeMounts: + .: {} + k:{"mountPath":"/var/lib/mysql"}: + .: {} + f:mountPath: {} + f:name: {} + f:dnsPolicy: {} + f:restartPolicy: {} + f:schedulerName: {} + f:securityContext: {} + f:terminationGracePeriodSeconds: {} + f:volumes: + .: {} + k:{"name":"mysql-persistent-storage"}: + .: {} + f:name: {} + f:persistentVolumeClaim: + .: {} + f:claimName: {} + manager: kubectl-client-side-apply + operation: Update + time: "2026-04-10T12:15:08Z" + - apiVersion: apps/v1 + fieldsType: FieldsV1 + fieldsV1: + f:metadata: + f:annotations: + f:deployment.kubernetes.io/revision: {} + f:status: + f:availableReplicas: {} + f:conditions: + .: {} + k:{"type":"Available"}: + .: {} + f:lastTransitionTime: {} + f:lastUpdateTime: {} + f:message: {} + f:reason: {} + f:status: {} + f:type: {} + k:{"type":"Progressing"}: + .: {} + f:lastTransitionTime: {} + f:lastUpdateTime: {} + f:message: {} + f:reason: {} + f:status: {} + f:type: {} + f:observedGeneration: {} + f:readyReplicas: {} + f:replicas: {} + f:terminatingReplicas: {} + f:updatedReplicas: {} + manager: kube-controller-manager + operation: Update + subresource: status + time: "2026-04-10T12:15:58Z" + name: wordpress-mysql + namespace: default + resourceVersion: "800" + uid: 2eba9391-46db-4860-9f9a-a1cb396faf18 +spec: + progressDeadlineSeconds: 600 + replicas: 1 + revisionHistoryLimit: 10 + selector: + matchLabels: + app: wordpress + tier: mysql + strategy: + type: Recreate + template: + metadata: + labels: + app: wordpress + tier: mysql + spec: + containers: + - env: + - name: MYSQL_ROOT_PASSWORD + valueFrom: + secretKeyRef: + key: MYSQL_ROOT_PASSWORD + name: wordpress-secrets-hg692g82th + - name: MYSQL_DATABASE + value: wordpress + - name: MYSQL_USER + value: wordpress + - name: MYSQL_PASSWORD + valueFrom: + secretKeyRef: + key: MYSQL_WORDPRESS_PASSWORD + name: wordpress-secrets-hg692g82th + image: mysql:8.0 + imagePullPolicy: IfNotPresent + name: mysql + ports: + - containerPort: 3306 + name: mysql + protocol: TCP + resources: {} + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + volumeMounts: + - mountPath: /var/lib/mysql + name: mysql-persistent-storage + dnsPolicy: ClusterFirst + restartPolicy: Always + schedulerName: default-scheduler + securityContext: {} + terminationGracePeriodSeconds: 30 + volumes: + - name: mysql-persistent-storage + persistentVolumeClaim: + claimName: mysql-pv-claim +status: + availableReplicas: 1 + conditions: + - lastTransitionTime: "2026-04-10T12:15:58Z" + lastUpdateTime: "2026-04-10T12:15:58Z" + message: Deployment has minimum availability. + reason: MinimumReplicasAvailable + status: "True" + type: Available + - lastTransitionTime: "2026-04-10T12:15:08Z" + lastUpdateTime: "2026-04-10T12:15:58Z" + message: ReplicaSet "wordpress-mysql-9474c86b" has successfully progressed. + reason: NewReplicaSetAvailable + status: "True" + type: Progressing + observedGeneration: 1 + readyReplicas: 1 + replicas: 1 + terminatingReplicas: 0 + updatedReplicas: 1 diff --git a/docs/transform-scenarios/wordpress-demo/transform/10_KubernetesPlugin/resources/Deployment_apps_v1_default_wordpress.yaml b/docs/transform-scenarios/wordpress-demo/transform/10_KubernetesPlugin/resources/Deployment_apps_v1_default_wordpress.yaml new file mode 100644 index 00000000..b49641ca --- /dev/null +++ b/docs/transform-scenarios/wordpress-demo/transform/10_KubernetesPlugin/resources/Deployment_apps_v1_default_wordpress.yaml @@ -0,0 +1,268 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + annotations: + deployment.kubernetes.io/revision: "1" + kubectl.kubernetes.io/last-applied-configuration: | + {"apiVersion":"apps/v1","kind":"Deployment","metadata":{"annotations":{},"labels":{"app":"wordpress"},"name":"wordpress","namespace":"default"},"spec":{"selector":{"matchLabels":{"app":"wordpress","tier":"frontend"}},"strategy":{"type":"Recreate"},"template":{"metadata":{"labels":{"app":"wordpress","tier":"frontend"}},"spec":{"containers":[{"env":[{"name":"WORDPRESS_DB_HOST","value":"wordpress-mysql"},{"name":"WORDPRESS_DB_PASSWORD","valueFrom":{"secretKeyRef":{"key":"MYSQL_WORDPRESS_PASSWORD","name":"wordpress-secrets-hg692g82th"}}},{"name":"WORDPRESS_DB_USER","value":"wordpress"},{"name":"WORDPRESS_CONFIG_EXTRA","value":"// Set SITE URL dynamically from requests to allow reach it on different endpoints\nif (isset($_SERVER['HTTP_HOST'])) {\n $protocol = (isset($_SERVER['HTTPS']) \u0026\u0026 $_SERVER['HTTPS'] === 'on') ? 'https' : 'http';\n if (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) \u0026\u0026 $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https') {\n $protocol = 'https';\n }\n define('WP_HOME', $protocol . '://' . $_SERVER['HTTP_HOST']);\n define('WP_SITEURL', $protocol . '://' . $_SERVER['HTTP_HOST']);\n}\n"}],"image":"wordpress:6-fpm-alpine","name":"wordpress","ports":[{"containerPort":9000,"name":"fastcgi"}],"volumeMounts":[{"mountPath":"/var/www/html","name":"wordpress-persistent-storage"}]},{"image":"nginx:alpine","name":"nginx","ports":[{"containerPort":80,"name":"http"}],"volumeMounts":[{"mountPath":"/var/www/html","name":"wordpress-persistent-storage","readOnly":true},{"mountPath":"/etc/nginx/nginx.conf","name":"nginx-config","subPath":"nginx.conf"}]}],"volumes":[{"name":"wordpress-persistent-storage","persistentVolumeClaim":{"claimName":"wordpress-pv-claim"}},{"configMap":{"name":"nginx-config"},"name":"nginx-config"}]}}}} + creationTimestamp: "2026-04-10T12:15:08Z" + generation: 1 + labels: + app: wordpress + managedFields: + - apiVersion: apps/v1 + fieldsType: FieldsV1 + fieldsV1: + f:metadata: + f:annotations: + .: {} + f:kubectl.kubernetes.io/last-applied-configuration: {} + f:labels: + .: {} + f:app: {} + f:spec: + f:progressDeadlineSeconds: {} + f:replicas: {} + f:revisionHistoryLimit: {} + f:selector: {} + f:strategy: + f:type: {} + f:template: + f:metadata: + f:labels: + .: {} + f:app: {} + f:tier: {} + f:spec: + f:containers: + k:{"name":"nginx"}: + .: {} + f:image: {} + f:imagePullPolicy: {} + f:name: {} + f:ports: + .: {} + k:{"containerPort":80,"protocol":"TCP"}: + .: {} + f:containerPort: {} + f:name: {} + f:protocol: {} + f:resources: {} + f:terminationMessagePath: {} + f:terminationMessagePolicy: {} + f:volumeMounts: + .: {} + k:{"mountPath":"/etc/nginx/nginx.conf"}: + .: {} + f:mountPath: {} + f:name: {} + f:subPath: {} + k:{"mountPath":"/var/www/html"}: + .: {} + f:mountPath: {} + f:name: {} + f:readOnly: {} + k:{"name":"wordpress"}: + .: {} + f:env: + .: {} + k:{"name":"WORDPRESS_CONFIG_EXTRA"}: + .: {} + f:name: {} + f:value: {} + k:{"name":"WORDPRESS_DB_HOST"}: + .: {} + f:name: {} + f:value: {} + k:{"name":"WORDPRESS_DB_PASSWORD"}: + .: {} + f:name: {} + f:valueFrom: + .: {} + f:secretKeyRef: {} + k:{"name":"WORDPRESS_DB_USER"}: + .: {} + f:name: {} + f:value: {} + f:image: {} + f:imagePullPolicy: {} + f:name: {} + f:ports: + .: {} + k:{"containerPort":9000,"protocol":"TCP"}: + .: {} + f:containerPort: {} + f:name: {} + f:protocol: {} + f:resources: {} + f:terminationMessagePath: {} + f:terminationMessagePolicy: {} + f:volumeMounts: + .: {} + k:{"mountPath":"/var/www/html"}: + .: {} + f:mountPath: {} + f:name: {} + f:dnsPolicy: {} + f:restartPolicy: {} + f:schedulerName: {} + f:securityContext: {} + f:terminationGracePeriodSeconds: {} + f:volumes: + .: {} + k:{"name":"nginx-config"}: + .: {} + f:configMap: + .: {} + f:defaultMode: {} + f:name: {} + f:name: {} + k:{"name":"wordpress-persistent-storage"}: + .: {} + f:name: {} + f:persistentVolumeClaim: + .: {} + f:claimName: {} + manager: kubectl-client-side-apply + operation: Update + time: "2026-04-10T12:15:08Z" + - apiVersion: apps/v1 + fieldsType: FieldsV1 + fieldsV1: + f:metadata: + f:annotations: + f:deployment.kubernetes.io/revision: {} + f:status: + f:availableReplicas: {} + f:conditions: + .: {} + k:{"type":"Available"}: + .: {} + f:lastTransitionTime: {} + f:lastUpdateTime: {} + f:message: {} + f:reason: {} + f:status: {} + f:type: {} + k:{"type":"Progressing"}: + .: {} + f:lastTransitionTime: {} + f:lastUpdateTime: {} + f:message: {} + f:reason: {} + f:status: {} + f:type: {} + f:observedGeneration: {} + f:readyReplicas: {} + f:replicas: {} + f:terminatingReplicas: {} + f:updatedReplicas: {} + manager: kube-controller-manager + operation: Update + subresource: status + time: "2026-04-10T12:16:04Z" + name: wordpress + namespace: default + resourceVersion: "812" + uid: 32f30549-f011-48b1-8398-64fef74b2df1 +spec: + progressDeadlineSeconds: 600 + replicas: 1 + revisionHistoryLimit: 10 + selector: + matchLabels: + app: wordpress + tier: frontend + strategy: + type: Recreate + template: + metadata: + labels: + app: wordpress + tier: frontend + spec: + containers: + - env: + - name: WORDPRESS_DB_HOST + value: wordpress-mysql + - name: WORDPRESS_DB_PASSWORD + valueFrom: + secretKeyRef: + key: MYSQL_WORDPRESS_PASSWORD + name: wordpress-secrets-hg692g82th + - name: WORDPRESS_DB_USER + value: wordpress + - name: WORDPRESS_CONFIG_EXTRA + value: | + // Set SITE URL dynamically from requests to allow reach it on different endpoints + if (isset($_SERVER['HTTP_HOST'])) { + $protocol = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on') ? 'https' : 'http'; + if (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https') { + $protocol = 'https'; + } + define('WP_HOME', $protocol . '://' . $_SERVER['HTTP_HOST']); + define('WP_SITEURL', $protocol . '://' . $_SERVER['HTTP_HOST']); + } + image: wordpress:6-fpm-alpine + imagePullPolicy: IfNotPresent + name: wordpress + ports: + - containerPort: 9000 + name: fastcgi + protocol: TCP + resources: {} + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + volumeMounts: + - mountPath: /var/www/html + name: wordpress-persistent-storage + - image: nginx:alpine + imagePullPolicy: IfNotPresent + name: nginx + ports: + - containerPort: 80 + name: http + protocol: TCP + resources: {} + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + volumeMounts: + - mountPath: /var/www/html + name: wordpress-persistent-storage + readOnly: true + - mountPath: /etc/nginx/nginx.conf + name: nginx-config + subPath: nginx.conf + dnsPolicy: ClusterFirst + restartPolicy: Always + schedulerName: default-scheduler + securityContext: {} + terminationGracePeriodSeconds: 30 + volumes: + - name: wordpress-persistent-storage + persistentVolumeClaim: + claimName: wordpress-pv-claim + - configMap: + defaultMode: 420 + name: nginx-config + name: nginx-config +status: + availableReplicas: 1 + conditions: + - lastTransitionTime: "2026-04-10T12:16:04Z" + lastUpdateTime: "2026-04-10T12:16:04Z" + message: Deployment has minimum availability. + reason: MinimumReplicasAvailable + status: "True" + type: Available + - lastTransitionTime: "2026-04-10T12:15:08Z" + lastUpdateTime: "2026-04-10T12:16:04Z" + message: ReplicaSet "wordpress-74b89cc84c" has successfully progressed. + reason: NewReplicaSetAvailable + status: "True" + type: Progressing + observedGeneration: 1 + readyReplicas: 1 + replicas: 1 + terminatingReplicas: 0 + updatedReplicas: 1 diff --git a/docs/transform-scenarios/wordpress-demo/transform/10_KubernetesPlugin/resources/EndpointSlice_discovery.k8s.io_v1_default_kubernetes.yaml b/docs/transform-scenarios/wordpress-demo/transform/10_KubernetesPlugin/resources/EndpointSlice_discovery.k8s.io_v1_default_kubernetes.yaml new file mode 100644 index 00000000..27aedea1 --- /dev/null +++ b/docs/transform-scenarios/wordpress-demo/transform/10_KubernetesPlugin/resources/EndpointSlice_discovery.k8s.io_v1_default_kubernetes.yaml @@ -0,0 +1,35 @@ +addressType: IPv4 +apiVersion: discovery.k8s.io/v1 +endpoints: +- addresses: + - 192.168.61.192 + conditions: + ready: true +kind: EndpointSlice +metadata: + creationTimestamp: "2026-04-10T12:10:43Z" + generation: 1 + labels: + kubernetes.io/service-name: kubernetes + managedFields: + - apiVersion: discovery.k8s.io/v1 + fieldsType: FieldsV1 + fieldsV1: + f:addressType: {} + f:endpoints: {} + f:metadata: + f:labels: + .: {} + f:kubernetes.io/service-name: {} + f:ports: {} + manager: kube-apiserver + operation: Update + time: "2026-04-10T12:10:43Z" + name: kubernetes + namespace: default + resourceVersion: "207" + uid: c4e8cffe-1b65-44c3-ba96-fb9dc76493ed +ports: +- name: https + port: 8443 + protocol: TCP diff --git a/docs/transform-scenarios/wordpress-demo/transform/10_KubernetesPlugin/resources/EndpointSlice_discovery.k8s.io_v1_default_wordpress-mysql-jlwnp.yaml b/docs/transform-scenarios/wordpress-demo/transform/10_KubernetesPlugin/resources/EndpointSlice_discovery.k8s.io_v1_default_wordpress-mysql-jlwnp.yaml new file mode 100644 index 00000000..77b44207 --- /dev/null +++ b/docs/transform-scenarios/wordpress-demo/transform/10_KubernetesPlugin/resources/EndpointSlice_discovery.k8s.io_v1_default_wordpress-mysql-jlwnp.yaml @@ -0,0 +1,64 @@ +addressType: IPv4 +apiVersion: discovery.k8s.io/v1 +endpoints: +- addresses: + - 10.244.0.6 + conditions: + ready: true + serving: true + terminating: false + nodeName: minikube + targetRef: + kind: Pod + name: wordpress-mysql-9474c86b-fr65w + namespace: default + uid: f81b40e3-ff85-46ca-8b0a-5c826b78f0c8 +kind: EndpointSlice +metadata: + annotations: + endpoints.kubernetes.io/last-change-trigger-time: "2026-04-10T12:15:58Z" + creationTimestamp: "2026-04-10T12:15:07Z" + generateName: wordpress-mysql- + generation: 2 + labels: + app: wordpress + endpointslice.kubernetes.io/managed-by: endpointslice-controller.k8s.io + kubernetes.io/service-name: wordpress-mysql + managedFields: + - apiVersion: discovery.k8s.io/v1 + fieldsType: FieldsV1 + fieldsV1: + f:addressType: {} + f:endpoints: {} + f:metadata: + f:annotations: + .: {} + f:endpoints.kubernetes.io/last-change-trigger-time: {} + f:generateName: {} + f:labels: + .: {} + f:app: {} + f:endpointslice.kubernetes.io/managed-by: {} + f:kubernetes.io/service-name: {} + f:ownerReferences: + .: {} + k:{"uid":"ec2555f1-9fd5-45da-bfa3-f2b59bb1d218"}: {} + f:ports: {} + manager: kube-controller-manager + operation: Update + time: "2026-04-10T12:15:58Z" + name: wordpress-mysql-jlwnp + namespace: default + ownerReferences: + - apiVersion: v1 + blockOwnerDeletion: true + controller: true + kind: Service + name: wordpress-mysql + uid: ec2555f1-9fd5-45da-bfa3-f2b59bb1d218 + resourceVersion: "796" + uid: d4c94c5d-1297-4184-91ae-24e6e0bb315b +ports: +- name: "" + port: 3306 + protocol: TCP diff --git a/docs/transform-scenarios/wordpress-demo/transform/10_KubernetesPlugin/resources/EndpointSlice_discovery.k8s.io_v1_default_wordpress-wpfqk.yaml b/docs/transform-scenarios/wordpress-demo/transform/10_KubernetesPlugin/resources/EndpointSlice_discovery.k8s.io_v1_default_wordpress-wpfqk.yaml new file mode 100644 index 00000000..e215d23b --- /dev/null +++ b/docs/transform-scenarios/wordpress-demo/transform/10_KubernetesPlugin/resources/EndpointSlice_discovery.k8s.io_v1_default_wordpress-wpfqk.yaml @@ -0,0 +1,64 @@ +addressType: IPv4 +apiVersion: discovery.k8s.io/v1 +endpoints: +- addresses: + - 10.244.0.5 + conditions: + ready: true + serving: true + terminating: false + nodeName: minikube + targetRef: + kind: Pod + name: wordpress-74b89cc84c-nm9f8 + namespace: default + uid: 608501ac-fd76-48a1-b9ef-058b7a6ade67 +kind: EndpointSlice +metadata: + annotations: + endpoints.kubernetes.io/last-change-trigger-time: "2026-04-10T12:16:04Z" + creationTimestamp: "2026-04-10T12:15:07Z" + generateName: wordpress- + generation: 2 + labels: + app: wordpress + endpointslice.kubernetes.io/managed-by: endpointslice-controller.k8s.io + kubernetes.io/service-name: wordpress + managedFields: + - apiVersion: discovery.k8s.io/v1 + fieldsType: FieldsV1 + fieldsV1: + f:addressType: {} + f:endpoints: {} + f:metadata: + f:annotations: + .: {} + f:endpoints.kubernetes.io/last-change-trigger-time: {} + f:generateName: {} + f:labels: + .: {} + f:app: {} + f:endpointslice.kubernetes.io/managed-by: {} + f:kubernetes.io/service-name: {} + f:ownerReferences: + .: {} + k:{"uid":"9bd59883-6312-4534-a2c1-b71911612715"}: {} + f:ports: {} + manager: kube-controller-manager + operation: Update + time: "2026-04-10T12:16:04Z" + name: wordpress-wpfqk + namespace: default + ownerReferences: + - apiVersion: v1 + blockOwnerDeletion: true + controller: true + kind: Service + name: wordpress + uid: 9bd59883-6312-4534-a2c1-b71911612715 + resourceVersion: "810" + uid: 1a4fffdb-dbcd-4729-905b-11be74b19710 +ports: +- name: "" + port: 80 + protocol: TCP diff --git a/docs/transform-scenarios/wordpress-demo/transform/10_KubernetesPlugin/resources/Endpoints__v1_default_kubernetes.yaml b/docs/transform-scenarios/wordpress-demo/transform/10_KubernetesPlugin/resources/Endpoints__v1_default_kubernetes.yaml new file mode 100644 index 00000000..b6b5cbb0 --- /dev/null +++ b/docs/transform-scenarios/wordpress-demo/transform/10_KubernetesPlugin/resources/Endpoints__v1_default_kubernetes.yaml @@ -0,0 +1,29 @@ +apiVersion: v1 +kind: Endpoints +metadata: + creationTimestamp: "2026-04-10T12:10:43Z" + labels: + endpointslice.kubernetes.io/skip-mirror: "true" + managedFields: + - apiVersion: v1 + fieldsType: FieldsV1 + fieldsV1: + f:metadata: + f:labels: + .: {} + f:endpointslice.kubernetes.io/skip-mirror: {} + f:subsets: {} + manager: kube-apiserver + operation: Update + time: "2026-04-10T12:10:43Z" + name: kubernetes + namespace: default + resourceVersion: "206" + uid: 39324cbc-0a0d-4795-8712-4106fdf1424c +subsets: +- addresses: + - ip: 192.168.61.192 + ports: + - name: https + port: 8443 + protocol: TCP diff --git a/docs/transform-scenarios/wordpress-demo/transform/10_KubernetesPlugin/resources/Endpoints__v1_default_wordpress-mysql.yaml b/docs/transform-scenarios/wordpress-demo/transform/10_KubernetesPlugin/resources/Endpoints__v1_default_wordpress-mysql.yaml new file mode 100644 index 00000000..3653d619 --- /dev/null +++ b/docs/transform-scenarios/wordpress-demo/transform/10_KubernetesPlugin/resources/Endpoints__v1_default_wordpress-mysql.yaml @@ -0,0 +1,41 @@ +apiVersion: v1 +kind: Endpoints +metadata: + annotations: + endpoints.kubernetes.io/last-change-trigger-time: "2026-04-10T12:15:58Z" + creationTimestamp: "2026-04-10T12:15:07Z" + labels: + app: wordpress + endpoints.kubernetes.io/managed-by: endpoint-controller + managedFields: + - apiVersion: v1 + fieldsType: FieldsV1 + fieldsV1: + f:metadata: + f:annotations: + .: {} + f:endpoints.kubernetes.io/last-change-trigger-time: {} + f:labels: + .: {} + f:app: {} + f:endpoints.kubernetes.io/managed-by: {} + f:subsets: {} + manager: kube-controller-manager + operation: Update + time: "2026-04-10T12:15:58Z" + name: wordpress-mysql + namespace: default + resourceVersion: "797" + uid: c2cf2659-9d5c-4f2e-9e3f-6da1b9c6f2c0 +subsets: +- addresses: + - ip: 10.244.0.6 + nodeName: minikube + targetRef: + kind: Pod + name: wordpress-mysql-9474c86b-fr65w + namespace: default + uid: f81b40e3-ff85-46ca-8b0a-5c826b78f0c8 + ports: + - port: 3306 + protocol: TCP diff --git a/docs/transform-scenarios/wordpress-demo/transform/10_KubernetesPlugin/resources/Endpoints__v1_default_wordpress.yaml b/docs/transform-scenarios/wordpress-demo/transform/10_KubernetesPlugin/resources/Endpoints__v1_default_wordpress.yaml new file mode 100644 index 00000000..6ebd61ce --- /dev/null +++ b/docs/transform-scenarios/wordpress-demo/transform/10_KubernetesPlugin/resources/Endpoints__v1_default_wordpress.yaml @@ -0,0 +1,41 @@ +apiVersion: v1 +kind: Endpoints +metadata: + annotations: + endpoints.kubernetes.io/last-change-trigger-time: "2026-04-10T12:16:04Z" + creationTimestamp: "2026-04-10T12:15:07Z" + labels: + app: wordpress + endpoints.kubernetes.io/managed-by: endpoint-controller + managedFields: + - apiVersion: v1 + fieldsType: FieldsV1 + fieldsV1: + f:metadata: + f:annotations: + .: {} + f:endpoints.kubernetes.io/last-change-trigger-time: {} + f:labels: + .: {} + f:app: {} + f:endpoints.kubernetes.io/managed-by: {} + f:subsets: {} + manager: kube-controller-manager + operation: Update + time: "2026-04-10T12:16:04Z" + name: wordpress + namespace: default + resourceVersion: "809" + uid: 7a7a7061-0064-42f9-ad24-f4dbbd13b8b4 +subsets: +- addresses: + - ip: 10.244.0.5 + nodeName: minikube + targetRef: + kind: Pod + name: wordpress-74b89cc84c-nm9f8 + namespace: default + uid: 608501ac-fd76-48a1-b9ef-058b7a6ade67 + ports: + - port: 80 + protocol: TCP diff --git a/docs/transform-scenarios/wordpress-demo/transform/10_KubernetesPlugin/resources/Job_batch_v1_default_wordpress-install.yaml b/docs/transform-scenarios/wordpress-demo/transform/10_KubernetesPlugin/resources/Job_batch_v1_default_wordpress-install.yaml new file mode 100644 index 00000000..0c6f48bf --- /dev/null +++ b/docs/transform-scenarios/wordpress-demo/transform/10_KubernetesPlugin/resources/Job_batch_v1_default_wordpress-install.yaml @@ -0,0 +1,276 @@ +apiVersion: batch/v1 +kind: Job +metadata: + annotations: + kubectl.kubernetes.io/last-applied-configuration: | + {"apiVersion":"batch/v1","kind":"Job","metadata":{"annotations":{},"name":"wordpress-install","namespace":"default"},"spec":{"backoffLimit":4,"template":{"spec":{"containers":[{"args":["-lc","set -e\ncd /var/www/html\n\necho \"Waiting for MySQL on ${WORDPRESS_DB_HOST}:3306...\"\nfor i in $(seq 1 60); do\n if mariadb-admin ping -h\"${WORDPRESS_DB_HOST}\" -u\"${WORDPRESS_DB_USER}\" -p\"${WORDPRESS_DB_PASSWORD}\" --ssl=false --silent; then\n echo \"MySQL is up.\"\n break\n fi\n echo \"MySQL not ready yet (attempt: $i)...\"\n sleep 5\ndone\n\nif ! mariadb-admin ping -h\"${WORDPRESS_DB_HOST}\" -u\"${WORDPRESS_DB_USER}\" -p\"${WORDPRESS_DB_PASSWORD}\" --ssl=false --silent; then\n echo \"MySQL did not become ready within the timeout.\"\n exit 1\nfi\n\n# Make sure WordPress core is present on the volume\nif [ ! -f wp-load.php ]; then\n echo \"WordPress core not found on the volume. Downloading...\"\n wp core download --allow-root\nfi\n\n# Create wp-config.php if missing\nif [ ! -f wp-config.php ]; then\n echo \"Creating wp-config.php...\"\n wp config create \\\n --dbname=\"${WORDPRESS_DB_NAME}\" \\\n --dbuser=\"${WORDPRESS_DB_USER}\" \\\n --dbpass=\"${WORDPRESS_DB_PASSWORD}\" \\\n --dbhost=\"${WORDPRESS_DB_HOST}\" \\\n --allow-root\nfi\n\n# Idempotent install\nif wp core is-installed --allow-root \u003e/dev/null 2\u003e\u00261; then\n echo \"WordPress is already installed. Nothing to do.\"\n exit 0\nfi\n\n# Create an installation kind of unique ID\nWORDPRESS_SEED_ID=$RANDOM\n\necho \"Running wp core install...\"\nwp core install \\\n --url=\"${WORDPRESS_SITE_URL}\" \\\n --title=\"${WORDPRESS_SITE_TITLE} #$WORDPRESS_SEED_ID\" \\\n --admin_user=\"${WORDPRESS_ADMIN_USER}\" \\\n --admin_password=\"${WORDPRESS_ADMIN_PASSWORD}\" \\\n --admin_email=\"${WORDPRESS_ADMIN_EMAIL}\" \\\n --skip-email \\\n --allow-root\n\necho \"Creating sample post...\"\nwp post create \\\n --post_type=post \\\n --post_status=publish \\\n --post_title=\"Sample post #$WORDPRESS_SEED_ID\" \\\n --post_content=\"Hello from k8s, this is a random post content: $(openssl rand -base64 200 | tr -cs 'a-zA-Z' ' ' | xargs)\"\n\necho \"WORDPRESS_SEED_ID=$WORDPRESS_SEED_ID\"\necho \"Done. WordPress has been installed.\"\n"],"command":["bash"],"env":[{"name":"WORDPRESS_DB_HOST","value":"wordpress-mysql"},{"name":"WORDPRESS_DB_USER","value":"wordpress"},{"name":"WORDPRESS_DB_NAME","value":"wordpress"},{"name":"WORDPRESS_DB_PASSWORD","valueFrom":{"secretKeyRef":{"key":"MYSQL_WORDPRESS_PASSWORD","name":"wordpress-secrets-hg692g82th"}}},{"name":"WORDPRESS_SITE_URL","value":"http://wordpress-k8s.example.local"},{"name":"WORDPRESS_SITE_TITLE","value":"My WordPress Site on k8s"},{"name":"WORDPRESS_ADMIN_USER","value":"admin"},{"name":"WORDPRESS_ADMIN_PASSWORD","valueFrom":{"secretKeyRef":{"key":"WORDPRESS_ADMIN_PASSWORD","name":"wordpress-secrets-hg692g82th"}}},{"name":"WORDPRESS_ADMIN_EMAIL","value":"admin@wordpress-k8s.example.local"}],"image":"wordpress:cli-2","imagePullPolicy":"IfNotPresent","name":"wp-install","volumeMounts":[{"mountPath":"/var/www/html","name":"wordpress-persistent-storage"}]}],"restartPolicy":"OnFailure","volumes":[{"name":"wordpress-persistent-storage","persistentVolumeClaim":{"claimName":"wordpress-pv-claim"}}]}}}} + creationTimestamp: "2026-04-10T12:15:08Z" + generation: 1 + labels: + batch.kubernetes.io/controller-uid: be719474-856d-4d84-80ad-4f4ab9ecdd30 + batch.kubernetes.io/job-name: wordpress-install + controller-uid: be719474-856d-4d84-80ad-4f4ab9ecdd30 + job-name: wordpress-install + managedFields: + - apiVersion: batch/v1 + fieldsType: FieldsV1 + fieldsV1: + f:metadata: + f:annotations: + .: {} + f:kubectl.kubernetes.io/last-applied-configuration: {} + f:spec: + f:backoffLimit: {} + f:completionMode: {} + f:completions: {} + f:manualSelector: {} + f:parallelism: {} + f:podReplacementPolicy: {} + f:suspend: {} + f:template: + f:spec: + f:containers: + k:{"name":"wp-install"}: + .: {} + f:args: {} + f:command: {} + f:env: + .: {} + k:{"name":"WORDPRESS_ADMIN_EMAIL"}: + .: {} + f:name: {} + f:value: {} + k:{"name":"WORDPRESS_ADMIN_PASSWORD"}: + .: {} + f:name: {} + f:valueFrom: + .: {} + f:secretKeyRef: {} + k:{"name":"WORDPRESS_ADMIN_USER"}: + .: {} + f:name: {} + f:value: {} + k:{"name":"WORDPRESS_DB_HOST"}: + .: {} + f:name: {} + f:value: {} + k:{"name":"WORDPRESS_DB_NAME"}: + .: {} + f:name: {} + f:value: {} + k:{"name":"WORDPRESS_DB_PASSWORD"}: + .: {} + f:name: {} + f:valueFrom: + .: {} + f:secretKeyRef: {} + k:{"name":"WORDPRESS_DB_USER"}: + .: {} + f:name: {} + f:value: {} + k:{"name":"WORDPRESS_SITE_TITLE"}: + .: {} + f:name: {} + f:value: {} + k:{"name":"WORDPRESS_SITE_URL"}: + .: {} + f:name: {} + f:value: {} + f:image: {} + f:imagePullPolicy: {} + f:name: {} + f:resources: {} + f:terminationMessagePath: {} + f:terminationMessagePolicy: {} + f:volumeMounts: + .: {} + k:{"mountPath":"/var/www/html"}: + .: {} + f:mountPath: {} + f:name: {} + f:dnsPolicy: {} + f:restartPolicy: {} + f:schedulerName: {} + f:securityContext: {} + f:terminationGracePeriodSeconds: {} + f:volumes: + .: {} + k:{"name":"wordpress-persistent-storage"}: + .: {} + f:name: {} + f:persistentVolumeClaim: + .: {} + f:claimName: {} + manager: kubectl-client-side-apply + operation: Update + time: "2026-04-10T12:15:08Z" + - apiVersion: batch/v1 + fieldsType: FieldsV1 + fieldsV1: + f:status: + f:completionTime: {} + f:conditions: {} + f:ready: {} + f:startTime: {} + f:succeeded: {} + f:terminating: {} + f:uncountedTerminatedPods: {} + manager: kube-controller-manager + operation: Update + subresource: status + time: "2026-04-10T12:16:48Z" + name: wordpress-install + namespace: default + resourceVersion: "854" + uid: be719474-856d-4d84-80ad-4f4ab9ecdd30 +spec: + backoffLimit: 4 + completionMode: NonIndexed + completions: 1 + manualSelector: false + parallelism: 1 + podReplacementPolicy: TerminatingOrFailed + selector: + matchLabels: + batch.kubernetes.io/controller-uid: be719474-856d-4d84-80ad-4f4ab9ecdd30 + suspend: false + template: + metadata: + labels: + batch.kubernetes.io/controller-uid: be719474-856d-4d84-80ad-4f4ab9ecdd30 + batch.kubernetes.io/job-name: wordpress-install + controller-uid: be719474-856d-4d84-80ad-4f4ab9ecdd30 + job-name: wordpress-install + spec: + containers: + - args: + - -lc + - | + set -e + cd /var/www/html + + echo "Waiting for MySQL on ${WORDPRESS_DB_HOST}:3306..." + for i in $(seq 1 60); do + if mariadb-admin ping -h"${WORDPRESS_DB_HOST}" -u"${WORDPRESS_DB_USER}" -p"${WORDPRESS_DB_PASSWORD}" --ssl=false --silent; then + echo "MySQL is up." + break + fi + echo "MySQL not ready yet (attempt: $i)..." + sleep 5 + done + + if ! mariadb-admin ping -h"${WORDPRESS_DB_HOST}" -u"${WORDPRESS_DB_USER}" -p"${WORDPRESS_DB_PASSWORD}" --ssl=false --silent; then + echo "MySQL did not become ready within the timeout." + exit 1 + fi + + # Make sure WordPress core is present on the volume + if [ ! -f wp-load.php ]; then + echo "WordPress core not found on the volume. Downloading..." + wp core download --allow-root + fi + + # Create wp-config.php if missing + if [ ! -f wp-config.php ]; then + echo "Creating wp-config.php..." + wp config create \ + --dbname="${WORDPRESS_DB_NAME}" \ + --dbuser="${WORDPRESS_DB_USER}" \ + --dbpass="${WORDPRESS_DB_PASSWORD}" \ + --dbhost="${WORDPRESS_DB_HOST}" \ + --allow-root + fi + + # Idempotent install + if wp core is-installed --allow-root >/dev/null 2>&1; then + echo "WordPress is already installed. Nothing to do." + exit 0 + fi + + # Create an installation kind of unique ID + WORDPRESS_SEED_ID=$RANDOM + + echo "Running wp core install..." + wp core install \ + --url="${WORDPRESS_SITE_URL}" \ + --title="${WORDPRESS_SITE_TITLE} #$WORDPRESS_SEED_ID" \ + --admin_user="${WORDPRESS_ADMIN_USER}" \ + --admin_password="${WORDPRESS_ADMIN_PASSWORD}" \ + --admin_email="${WORDPRESS_ADMIN_EMAIL}" \ + --skip-email \ + --allow-root + + echo "Creating sample post..." + wp post create \ + --post_type=post \ + --post_status=publish \ + --post_title="Sample post #$WORDPRESS_SEED_ID" \ + --post_content="Hello from k8s, this is a random post content: $(openssl rand -base64 200 | tr -cs 'a-zA-Z' ' ' | xargs)" + + echo "WORDPRESS_SEED_ID=$WORDPRESS_SEED_ID" + echo "Done. WordPress has been installed." + command: + - bash + env: + - name: WORDPRESS_DB_HOST + value: wordpress-mysql + - name: WORDPRESS_DB_USER + value: wordpress + - name: WORDPRESS_DB_NAME + value: wordpress + - name: WORDPRESS_DB_PASSWORD + valueFrom: + secretKeyRef: + key: MYSQL_WORDPRESS_PASSWORD + name: wordpress-secrets-hg692g82th + - name: WORDPRESS_SITE_URL + value: http://wordpress-k8s.example.local + - name: WORDPRESS_SITE_TITLE + value: My WordPress Site on k8s + - name: WORDPRESS_ADMIN_USER + value: admin + - name: WORDPRESS_ADMIN_PASSWORD + valueFrom: + secretKeyRef: + key: WORDPRESS_ADMIN_PASSWORD + name: wordpress-secrets-hg692g82th + - name: WORDPRESS_ADMIN_EMAIL + value: admin@wordpress-k8s.example.local + image: wordpress:cli-2 + imagePullPolicy: IfNotPresent + name: wp-install + resources: {} + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + volumeMounts: + - mountPath: /var/www/html + name: wordpress-persistent-storage + dnsPolicy: ClusterFirst + restartPolicy: OnFailure + schedulerName: default-scheduler + securityContext: {} + terminationGracePeriodSeconds: 30 + volumes: + - name: wordpress-persistent-storage + persistentVolumeClaim: + claimName: wordpress-pv-claim +status: + completionTime: "2026-04-10T12:16:48Z" + conditions: + - lastProbeTime: "2026-04-10T12:16:48Z" + lastTransitionTime: "2026-04-10T12:16:48Z" + message: Reached expected number of succeeded pods + reason: CompletionsReached + status: "True" + type: SuccessCriteriaMet + - lastProbeTime: "2026-04-10T12:16:48Z" + lastTransitionTime: "2026-04-10T12:16:48Z" + message: Reached expected number of succeeded pods + reason: CompletionsReached + status: "True" + type: Complete + ready: 0 + startTime: "2026-04-10T12:15:08Z" + succeeded: 1 + terminating: 0 + uncountedTerminatedPods: {} diff --git a/docs/transform-scenarios/wordpress-demo/transform/10_KubernetesPlugin/resources/PersistentVolumeClaim__v1_default_mysql-pv-claim.yaml b/docs/transform-scenarios/wordpress-demo/transform/10_KubernetesPlugin/resources/PersistentVolumeClaim__v1_default_mysql-pv-claim.yaml new file mode 100644 index 00000000..5756b493 --- /dev/null +++ b/docs/transform-scenarios/wordpress-demo/transform/10_KubernetesPlugin/resources/PersistentVolumeClaim__v1_default_mysql-pv-claim.yaml @@ -0,0 +1,82 @@ +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + annotations: + kubectl.kubernetes.io/last-applied-configuration: | + {"apiVersion":"v1","kind":"PersistentVolumeClaim","metadata":{"annotations":{},"labels":{"app":"wordpress"},"name":"mysql-pv-claim","namespace":"default"},"spec":{"accessModes":["ReadWriteOnce"],"resources":{"requests":{"storage":"1Gi"}}}} + pv.kubernetes.io/bind-completed: "yes" + pv.kubernetes.io/bound-by-controller: "yes" + volume.beta.kubernetes.io/storage-provisioner: k8s.io/minikube-hostpath + volume.kubernetes.io/storage-provisioner: k8s.io/minikube-hostpath + creationTimestamp: "2026-04-10T12:15:07Z" + finalizers: + - kubernetes.io/pvc-protection + labels: + app: wordpress + managedFields: + - apiVersion: v1 + fieldsType: FieldsV1 + fieldsV1: + f:metadata: + f:annotations: + .: {} + f:kubectl.kubernetes.io/last-applied-configuration: {} + f:labels: + .: {} + f:app: {} + f:spec: + f:accessModes: {} + f:resources: + f:requests: + .: {} + f:storage: {} + f:volumeMode: {} + manager: kubectl-client-side-apply + operation: Update + time: "2026-04-10T12:15:07Z" + - apiVersion: v1 + fieldsType: FieldsV1 + fieldsV1: + f:metadata: + f:annotations: + f:pv.kubernetes.io/bind-completed: {} + f:pv.kubernetes.io/bound-by-controller: {} + f:volume.beta.kubernetes.io/storage-provisioner: {} + f:volume.kubernetes.io/storage-provisioner: {} + f:spec: + f:volumeName: {} + manager: kube-controller-manager + operation: Update + time: "2026-04-10T12:15:08Z" + - apiVersion: v1 + fieldsType: FieldsV1 + fieldsV1: + f:status: + f:accessModes: {} + f:capacity: + .: {} + f:storage: {} + f:phase: {} + manager: kube-controller-manager + operation: Update + subresource: status + time: "2026-04-10T12:15:08Z" + name: mysql-pv-claim + namespace: default + resourceVersion: "710" + uid: 58e67d84-b797-4121-a5df-f3beea559f74 +spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 1Gi + storageClassName: standard + volumeMode: Filesystem + volumeName: pvc-58e67d84-b797-4121-a5df-f3beea559f74 +status: + accessModes: + - ReadWriteOnce + capacity: + storage: 1Gi + phase: Bound diff --git a/docs/transform-scenarios/wordpress-demo/transform/10_KubernetesPlugin/resources/PersistentVolumeClaim__v1_default_wordpress-pv-claim.yaml b/docs/transform-scenarios/wordpress-demo/transform/10_KubernetesPlugin/resources/PersistentVolumeClaim__v1_default_wordpress-pv-claim.yaml new file mode 100644 index 00000000..399fd4cf --- /dev/null +++ b/docs/transform-scenarios/wordpress-demo/transform/10_KubernetesPlugin/resources/PersistentVolumeClaim__v1_default_wordpress-pv-claim.yaml @@ -0,0 +1,82 @@ +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + annotations: + kubectl.kubernetes.io/last-applied-configuration: | + {"apiVersion":"v1","kind":"PersistentVolumeClaim","metadata":{"annotations":{},"labels":{"app":"wordpress"},"name":"wordpress-pv-claim","namespace":"default"},"spec":{"accessModes":["ReadWriteOnce"],"resources":{"requests":{"storage":"1Gi"}}}} + pv.kubernetes.io/bind-completed: "yes" + pv.kubernetes.io/bound-by-controller: "yes" + volume.beta.kubernetes.io/storage-provisioner: k8s.io/minikube-hostpath + volume.kubernetes.io/storage-provisioner: k8s.io/minikube-hostpath + creationTimestamp: "2026-04-10T12:15:08Z" + finalizers: + - kubernetes.io/pvc-protection + labels: + app: wordpress + managedFields: + - apiVersion: v1 + fieldsType: FieldsV1 + fieldsV1: + f:metadata: + f:annotations: + f:pv.kubernetes.io/bind-completed: {} + f:pv.kubernetes.io/bound-by-controller: {} + f:volume.beta.kubernetes.io/storage-provisioner: {} + f:volume.kubernetes.io/storage-provisioner: {} + f:spec: + f:volumeName: {} + manager: kube-controller-manager + operation: Update + time: "2026-04-10T12:15:08Z" + - apiVersion: v1 + fieldsType: FieldsV1 + fieldsV1: + f:status: + f:accessModes: {} + f:capacity: + .: {} + f:storage: {} + f:phase: {} + manager: kube-controller-manager + operation: Update + subresource: status + time: "2026-04-10T12:15:08Z" + - apiVersion: v1 + fieldsType: FieldsV1 + fieldsV1: + f:metadata: + f:annotations: + .: {} + f:kubectl.kubernetes.io/last-applied-configuration: {} + f:labels: + .: {} + f:app: {} + f:spec: + f:accessModes: {} + f:resources: + f:requests: + .: {} + f:storage: {} + f:volumeMode: {} + manager: kubectl-client-side-apply + operation: Update + time: "2026-04-10T12:15:08Z" + name: wordpress-pv-claim + namespace: default + resourceVersion: "729" + uid: a08d0754-6782-497d-927d-7fdac1a968fe +spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 1Gi + storageClassName: standard + volumeMode: Filesystem + volumeName: pvc-a08d0754-6782-497d-927d-7fdac1a968fe +status: + accessModes: + - ReadWriteOnce + capacity: + storage: 1Gi + phase: Bound diff --git a/docs/transform-scenarios/wordpress-demo/transform/10_KubernetesPlugin/resources/Pod__v1_default_wordpress-74b89cc84c-nm9f8.yaml b/docs/transform-scenarios/wordpress-demo/transform/10_KubernetesPlugin/resources/Pod__v1_default_wordpress-74b89cc84c-nm9f8.yaml new file mode 100644 index 00000000..914d966d --- /dev/null +++ b/docs/transform-scenarios/wordpress-demo/transform/10_KubernetesPlugin/resources/Pod__v1_default_wordpress-74b89cc84c-nm9f8.yaml @@ -0,0 +1,383 @@ +apiVersion: v1 +kind: Pod +metadata: + creationTimestamp: "2026-04-10T12:15:08Z" + generateName: wordpress-74b89cc84c- + generation: 1 + labels: + app: wordpress + pod-template-hash: 74b89cc84c + tier: frontend + managedFields: + - apiVersion: v1 + fieldsType: FieldsV1 + fieldsV1: + f:metadata: + f:generateName: {} + f:labels: + .: {} + f:app: {} + f:pod-template-hash: {} + f:tier: {} + f:ownerReferences: + .: {} + k:{"uid":"7ed37255-e5ff-4e33-837d-f584a536d2b8"}: {} + f:spec: + f:containers: + k:{"name":"nginx"}: + .: {} + f:image: {} + f:imagePullPolicy: {} + f:name: {} + f:ports: + .: {} + k:{"containerPort":80,"protocol":"TCP"}: + .: {} + f:containerPort: {} + f:name: {} + f:protocol: {} + f:resources: {} + f:terminationMessagePath: {} + f:terminationMessagePolicy: {} + f:volumeMounts: + .: {} + k:{"mountPath":"/etc/nginx/nginx.conf"}: + .: {} + f:mountPath: {} + f:name: {} + f:subPath: {} + k:{"mountPath":"/var/www/html"}: + .: {} + f:mountPath: {} + f:name: {} + f:readOnly: {} + k:{"name":"wordpress"}: + .: {} + f:env: + .: {} + k:{"name":"WORDPRESS_CONFIG_EXTRA"}: + .: {} + f:name: {} + f:value: {} + k:{"name":"WORDPRESS_DB_HOST"}: + .: {} + f:name: {} + f:value: {} + k:{"name":"WORDPRESS_DB_PASSWORD"}: + .: {} + f:name: {} + f:valueFrom: + .: {} + f:secretKeyRef: {} + k:{"name":"WORDPRESS_DB_USER"}: + .: {} + f:name: {} + f:value: {} + f:image: {} + f:imagePullPolicy: {} + f:name: {} + f:ports: + .: {} + k:{"containerPort":9000,"protocol":"TCP"}: + .: {} + f:containerPort: {} + f:name: {} + f:protocol: {} + f:resources: {} + f:terminationMessagePath: {} + f:terminationMessagePolicy: {} + f:volumeMounts: + .: {} + k:{"mountPath":"/var/www/html"}: + .: {} + f:mountPath: {} + f:name: {} + f:dnsPolicy: {} + f:enableServiceLinks: {} + f:restartPolicy: {} + f:schedulerName: {} + f:securityContext: {} + f:terminationGracePeriodSeconds: {} + f:volumes: + .: {} + k:{"name":"nginx-config"}: + .: {} + f:configMap: + .: {} + f:defaultMode: {} + f:name: {} + f:name: {} + k:{"name":"wordpress-persistent-storage"}: + .: {} + f:name: {} + f:persistentVolumeClaim: + .: {} + f:claimName: {} + manager: kube-controller-manager + operation: Update + time: "2026-04-10T12:15:08Z" + - apiVersion: v1 + fieldsType: FieldsV1 + fieldsV1: + f:status: + f:conditions: + .: {} + k:{"type":"PodScheduled"}: + .: {} + f:lastProbeTime: {} + f:lastTransitionTime: {} + f:message: {} + f:reason: {} + f:status: {} + f:type: {} + manager: kube-scheduler + operation: Update + subresource: status + time: "2026-04-10T12:15:08Z" + - apiVersion: v1 + fieldsType: FieldsV1 + fieldsV1: + f:status: + f:conditions: + k:{"type":"ContainersReady"}: + .: {} + f:lastProbeTime: {} + f:lastTransitionTime: {} + f:observedGeneration: {} + f:status: {} + f:type: {} + k:{"type":"Initialized"}: + .: {} + f:lastProbeTime: {} + f:lastTransitionTime: {} + f:observedGeneration: {} + f:status: {} + f:type: {} + k:{"type":"PodReadyToStartContainers"}: + .: {} + f:lastProbeTime: {} + f:lastTransitionTime: {} + f:observedGeneration: {} + f:status: {} + f:type: {} + k:{"type":"PodScheduled"}: + f:observedGeneration: {} + k:{"type":"Ready"}: + .: {} + f:lastProbeTime: {} + f:lastTransitionTime: {} + f:observedGeneration: {} + f:status: {} + f:type: {} + f:containerStatuses: {} + f:hostIP: {} + f:hostIPs: {} + f:observedGeneration: {} + f:phase: {} + f:podIP: {} + f:podIPs: + .: {} + k:{"ip":"10.244.0.5"}: + .: {} + f:ip: {} + f:startTime: {} + manager: kubelet + operation: Update + subresource: status + time: "2026-04-10T12:16:04Z" + name: wordpress-74b89cc84c-nm9f8 + namespace: default + ownerReferences: + - apiVersion: apps/v1 + blockOwnerDeletion: true + controller: true + kind: ReplicaSet + name: wordpress-74b89cc84c + uid: 7ed37255-e5ff-4e33-837d-f584a536d2b8 + resourceVersion: "808" + uid: 608501ac-fd76-48a1-b9ef-058b7a6ade67 +spec: + containers: + - env: + - name: WORDPRESS_DB_HOST + value: wordpress-mysql + - name: WORDPRESS_DB_PASSWORD + valueFrom: + secretKeyRef: + key: MYSQL_WORDPRESS_PASSWORD + name: wordpress-secrets-hg692g82th + - name: WORDPRESS_DB_USER + value: wordpress + - name: WORDPRESS_CONFIG_EXTRA + value: | + // Set SITE URL dynamically from requests to allow reach it on different endpoints + if (isset($_SERVER['HTTP_HOST'])) { + $protocol = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on') ? 'https' : 'http'; + if (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https') { + $protocol = 'https'; + } + define('WP_HOME', $protocol . '://' . $_SERVER['HTTP_HOST']); + define('WP_SITEURL', $protocol . '://' . $_SERVER['HTTP_HOST']); + } + image: wordpress:6-fpm-alpine + imagePullPolicy: IfNotPresent + name: wordpress + ports: + - containerPort: 9000 + name: fastcgi + protocol: TCP + resources: {} + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + volumeMounts: + - mountPath: /var/www/html + name: wordpress-persistent-storage + - mountPath: /var/run/secrets/kubernetes.io/serviceaccount + name: kube-api-access-gksj7 + readOnly: true + - image: nginx:alpine + imagePullPolicy: IfNotPresent + name: nginx + ports: + - containerPort: 80 + name: http + protocol: TCP + resources: {} + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + volumeMounts: + - mountPath: /var/www/html + name: wordpress-persistent-storage + readOnly: true + - mountPath: /etc/nginx/nginx.conf + name: nginx-config + subPath: nginx.conf + - mountPath: /var/run/secrets/kubernetes.io/serviceaccount + name: kube-api-access-gksj7 + readOnly: true + dnsPolicy: ClusterFirst + enableServiceLinks: true + nodeName: minikube + preemptionPolicy: PreemptLowerPriority + priority: 0 + restartPolicy: Always + schedulerName: default-scheduler + securityContext: {} + serviceAccount: default + serviceAccountName: default + terminationGracePeriodSeconds: 30 + tolerations: + - effect: NoExecute + key: node.kubernetes.io/not-ready + operator: Exists + tolerationSeconds: 300 + - effect: NoExecute + key: node.kubernetes.io/unreachable + operator: Exists + tolerationSeconds: 300 + volumes: + - name: wordpress-persistent-storage + persistentVolumeClaim: + claimName: wordpress-pv-claim + - configMap: + defaultMode: 420 + name: nginx-config + name: nginx-config + - name: kube-api-access-gksj7 + projected: + defaultMode: 420 + sources: + - serviceAccountToken: + expirationSeconds: 3607 + path: token + - configMap: + items: + - key: ca.crt + path: ca.crt + name: kube-root-ca.crt + - downwardAPI: + items: + - fieldRef: + apiVersion: v1 + fieldPath: metadata.namespace + path: namespace +status: + conditions: + - lastProbeTime: null + lastTransitionTime: "2026-04-10T12:16:04Z" + observedGeneration: 1 + status: "True" + type: PodReadyToStartContainers + - lastProbeTime: null + lastTransitionTime: "2026-04-10T12:15:08Z" + observedGeneration: 1 + status: "True" + type: Initialized + - lastProbeTime: null + lastTransitionTime: "2026-04-10T12:16:04Z" + observedGeneration: 1 + status: "True" + type: Ready + - lastProbeTime: null + lastTransitionTime: "2026-04-10T12:16:04Z" + observedGeneration: 1 + status: "True" + type: ContainersReady + - lastProbeTime: null + lastTransitionTime: "2026-04-10T12:15:08Z" + observedGeneration: 1 + status: "True" + type: PodScheduled + containerStatuses: + - containerID: docker://9deeeda1697dc879391836b269f936362a2e1a77d5beb289889639e352d9ee13 + image: nginx:alpine + imageID: docker-pullable://nginx@sha256:582c496ccf79d8aa6f8203a79d32aaf7ffd8b13362c60a701a2f9ac64886c93d + lastState: {} + name: nginx + ready: true + resources: {} + restartCount: 0 + started: true + state: + running: + startedAt: "2026-04-10T12:16:04Z" + volumeMounts: + - mountPath: /var/www/html + name: wordpress-persistent-storage + readOnly: true + recursiveReadOnly: Disabled + - mountPath: /etc/nginx/nginx.conf + name: nginx-config + - mountPath: /var/run/secrets/kubernetes.io/serviceaccount + name: kube-api-access-gksj7 + readOnly: true + recursiveReadOnly: Disabled + - containerID: docker://dd83b5ffcde3a21dcfc1f3fedfeefcc0a7e8e7f63b31817029d370b0ddde48f4 + image: wordpress:6-fpm-alpine + imageID: docker-pullable://wordpress@sha256:658bc068c60dcd43f2e2deee4b8495ca5e37ef09481d790ad05f99e6a15f61aa + lastState: {} + name: wordpress + ready: true + resources: {} + restartCount: 0 + started: true + state: + running: + startedAt: "2026-04-10T12:15:33Z" + volumeMounts: + - mountPath: /var/www/html + name: wordpress-persistent-storage + - mountPath: /var/run/secrets/kubernetes.io/serviceaccount + name: kube-api-access-gksj7 + readOnly: true + recursiveReadOnly: Disabled + hostIP: 192.168.61.192 + hostIPs: + - ip: 192.168.61.192 + observedGeneration: 1 + phase: Running + podIP: 10.244.0.5 + podIPs: + - ip: 10.244.0.5 + qosClass: BestEffort + startTime: "2026-04-10T12:15:08Z" diff --git a/docs/transform-scenarios/wordpress-demo/transform/10_KubernetesPlugin/resources/Pod__v1_default_wordpress-install-xrqtc.yaml b/docs/transform-scenarios/wordpress-demo/transform/10_KubernetesPlugin/resources/Pod__v1_default_wordpress-install-xrqtc.yaml new file mode 100644 index 00000000..12399817 --- /dev/null +++ b/docs/transform-scenarios/wordpress-demo/transform/10_KubernetesPlugin/resources/Pod__v1_default_wordpress-install-xrqtc.yaml @@ -0,0 +1,381 @@ +apiVersion: v1 +kind: Pod +metadata: + creationTimestamp: "2026-04-10T12:15:08Z" + generateName: wordpress-install- + generation: 1 + labels: + batch.kubernetes.io/controller-uid: be719474-856d-4d84-80ad-4f4ab9ecdd30 + batch.kubernetes.io/job-name: wordpress-install + controller-uid: be719474-856d-4d84-80ad-4f4ab9ecdd30 + job-name: wordpress-install + managedFields: + - apiVersion: v1 + fieldsType: FieldsV1 + fieldsV1: + f:metadata: + f:generateName: {} + f:labels: + .: {} + f:batch.kubernetes.io/controller-uid: {} + f:batch.kubernetes.io/job-name: {} + f:controller-uid: {} + f:job-name: {} + f:ownerReferences: + .: {} + k:{"uid":"be719474-856d-4d84-80ad-4f4ab9ecdd30"}: {} + f:spec: + f:containers: + k:{"name":"wp-install"}: + .: {} + f:args: {} + f:command: {} + f:env: + .: {} + k:{"name":"WORDPRESS_ADMIN_EMAIL"}: + .: {} + f:name: {} + f:value: {} + k:{"name":"WORDPRESS_ADMIN_PASSWORD"}: + .: {} + f:name: {} + f:valueFrom: + .: {} + f:secretKeyRef: {} + k:{"name":"WORDPRESS_ADMIN_USER"}: + .: {} + f:name: {} + f:value: {} + k:{"name":"WORDPRESS_DB_HOST"}: + .: {} + f:name: {} + f:value: {} + k:{"name":"WORDPRESS_DB_NAME"}: + .: {} + f:name: {} + f:value: {} + k:{"name":"WORDPRESS_DB_PASSWORD"}: + .: {} + f:name: {} + f:valueFrom: + .: {} + f:secretKeyRef: {} + k:{"name":"WORDPRESS_DB_USER"}: + .: {} + f:name: {} + f:value: {} + k:{"name":"WORDPRESS_SITE_TITLE"}: + .: {} + f:name: {} + f:value: {} + k:{"name":"WORDPRESS_SITE_URL"}: + .: {} + f:name: {} + f:value: {} + f:image: {} + f:imagePullPolicy: {} + f:name: {} + f:resources: {} + f:terminationMessagePath: {} + f:terminationMessagePolicy: {} + f:volumeMounts: + .: {} + k:{"mountPath":"/var/www/html"}: + .: {} + f:mountPath: {} + f:name: {} + f:dnsPolicy: {} + f:enableServiceLinks: {} + f:restartPolicy: {} + f:schedulerName: {} + f:securityContext: {} + f:terminationGracePeriodSeconds: {} + f:volumes: + .: {} + k:{"name":"wordpress-persistent-storage"}: + .: {} + f:name: {} + f:persistentVolumeClaim: + .: {} + f:claimName: {} + manager: kube-controller-manager + operation: Update + time: "2026-04-10T12:15:08Z" + - apiVersion: v1 + fieldsType: FieldsV1 + fieldsV1: + f:status: + f:conditions: + k:{"type":"ContainersReady"}: + .: {} + f:lastProbeTime: {} + f:lastTransitionTime: {} + f:observedGeneration: {} + f:reason: {} + f:status: {} + f:type: {} + k:{"type":"Initialized"}: + .: {} + f:lastProbeTime: {} + f:lastTransitionTime: {} + f:observedGeneration: {} + f:reason: {} + f:status: {} + f:type: {} + k:{"type":"PodReadyToStartContainers"}: + .: {} + f:lastProbeTime: {} + f:lastTransitionTime: {} + f:observedGeneration: {} + f:status: {} + f:type: {} + k:{"type":"PodScheduled"}: + f:observedGeneration: {} + k:{"type":"Ready"}: + .: {} + f:lastProbeTime: {} + f:lastTransitionTime: {} + f:observedGeneration: {} + f:reason: {} + f:status: {} + f:type: {} + f:containerStatuses: {} + f:hostIP: {} + f:hostIPs: {} + f:observedGeneration: {} + f:phase: {} + f:podIP: {} + f:podIPs: + .: {} + k:{"ip":"10.244.0.4"}: + .: {} + f:ip: {} + f:startTime: {} + manager: kubelet + operation: Update + subresource: status + time: "2026-04-10T12:16:48Z" + name: wordpress-install-xrqtc + namespace: default + ownerReferences: + - apiVersion: batch/v1 + blockOwnerDeletion: true + controller: true + kind: Job + name: wordpress-install + uid: be719474-856d-4d84-80ad-4f4ab9ecdd30 + resourceVersion: "853" + uid: 7d3fa4a3-d0a9-438b-b477-e45103965e04 +spec: + containers: + - args: + - -lc + - | + set -e + cd /var/www/html + + echo "Waiting for MySQL on ${WORDPRESS_DB_HOST}:3306..." + for i in $(seq 1 60); do + if mariadb-admin ping -h"${WORDPRESS_DB_HOST}" -u"${WORDPRESS_DB_USER}" -p"${WORDPRESS_DB_PASSWORD}" --ssl=false --silent; then + echo "MySQL is up." + break + fi + echo "MySQL not ready yet (attempt: $i)..." + sleep 5 + done + + if ! mariadb-admin ping -h"${WORDPRESS_DB_HOST}" -u"${WORDPRESS_DB_USER}" -p"${WORDPRESS_DB_PASSWORD}" --ssl=false --silent; then + echo "MySQL did not become ready within the timeout." + exit 1 + fi + + # Make sure WordPress core is present on the volume + if [ ! -f wp-load.php ]; then + echo "WordPress core not found on the volume. Downloading..." + wp core download --allow-root + fi + + # Create wp-config.php if missing + if [ ! -f wp-config.php ]; then + echo "Creating wp-config.php..." + wp config create \ + --dbname="${WORDPRESS_DB_NAME}" \ + --dbuser="${WORDPRESS_DB_USER}" \ + --dbpass="${WORDPRESS_DB_PASSWORD}" \ + --dbhost="${WORDPRESS_DB_HOST}" \ + --allow-root + fi + + # Idempotent install + if wp core is-installed --allow-root >/dev/null 2>&1; then + echo "WordPress is already installed. Nothing to do." + exit 0 + fi + + # Create an installation kind of unique ID + WORDPRESS_SEED_ID=$RANDOM + + echo "Running wp core install..." + wp core install \ + --url="${WORDPRESS_SITE_URL}" \ + --title="${WORDPRESS_SITE_TITLE} #$WORDPRESS_SEED_ID" \ + --admin_user="${WORDPRESS_ADMIN_USER}" \ + --admin_password="${WORDPRESS_ADMIN_PASSWORD}" \ + --admin_email="${WORDPRESS_ADMIN_EMAIL}" \ + --skip-email \ + --allow-root + + echo "Creating sample post..." + wp post create \ + --post_type=post \ + --post_status=publish \ + --post_title="Sample post #$WORDPRESS_SEED_ID" \ + --post_content="Hello from k8s, this is a random post content: $(openssl rand -base64 200 | tr -cs 'a-zA-Z' ' ' | xargs)" + + echo "WORDPRESS_SEED_ID=$WORDPRESS_SEED_ID" + echo "Done. WordPress has been installed." + command: + - bash + env: + - name: WORDPRESS_DB_HOST + value: wordpress-mysql + - name: WORDPRESS_DB_USER + value: wordpress + - name: WORDPRESS_DB_NAME + value: wordpress + - name: WORDPRESS_DB_PASSWORD + valueFrom: + secretKeyRef: + key: MYSQL_WORDPRESS_PASSWORD + name: wordpress-secrets-hg692g82th + - name: WORDPRESS_SITE_URL + value: http://wordpress-k8s.example.local + - name: WORDPRESS_SITE_TITLE + value: My WordPress Site on k8s + - name: WORDPRESS_ADMIN_USER + value: admin + - name: WORDPRESS_ADMIN_PASSWORD + valueFrom: + secretKeyRef: + key: WORDPRESS_ADMIN_PASSWORD + name: wordpress-secrets-hg692g82th + - name: WORDPRESS_ADMIN_EMAIL + value: admin@wordpress-k8s.example.local + image: wordpress:cli-2 + imagePullPolicy: IfNotPresent + name: wp-install + resources: {} + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + volumeMounts: + - mountPath: /var/www/html + name: wordpress-persistent-storage + - mountPath: /var/run/secrets/kubernetes.io/serviceaccount + name: kube-api-access-29z94 + readOnly: true + dnsPolicy: ClusterFirst + enableServiceLinks: true + nodeName: minikube + preemptionPolicy: PreemptLowerPriority + priority: 0 + restartPolicy: OnFailure + schedulerName: default-scheduler + securityContext: {} + serviceAccount: default + serviceAccountName: default + terminationGracePeriodSeconds: 30 + tolerations: + - effect: NoExecute + key: node.kubernetes.io/not-ready + operator: Exists + tolerationSeconds: 300 + - effect: NoExecute + key: node.kubernetes.io/unreachable + operator: Exists + tolerationSeconds: 300 + volumes: + - name: wordpress-persistent-storage + persistentVolumeClaim: + claimName: wordpress-pv-claim + - name: kube-api-access-29z94 + projected: + defaultMode: 420 + sources: + - serviceAccountToken: + expirationSeconds: 3607 + path: token + - configMap: + items: + - key: ca.crt + path: ca.crt + name: kube-root-ca.crt + - downwardAPI: + items: + - fieldRef: + apiVersion: v1 + fieldPath: metadata.namespace + path: namespace +status: + conditions: + - lastProbeTime: null + lastTransitionTime: "2026-04-10T12:16:48Z" + observedGeneration: 1 + status: "False" + type: PodReadyToStartContainers + - lastProbeTime: null + lastTransitionTime: "2026-04-10T12:15:08Z" + observedGeneration: 1 + reason: PodCompleted + status: "True" + type: Initialized + - lastProbeTime: null + lastTransitionTime: "2026-04-10T12:16:46Z" + observedGeneration: 1 + reason: PodCompleted + status: "False" + type: Ready + - lastProbeTime: null + lastTransitionTime: "2026-04-10T12:16:46Z" + observedGeneration: 1 + reason: PodCompleted + status: "False" + type: ContainersReady + - lastProbeTime: null + lastTransitionTime: "2026-04-10T12:15:08Z" + observedGeneration: 1 + status: "True" + type: PodScheduled + containerStatuses: + - containerID: docker://b1d36c9760604c47741156b29183957dc09994038288ba012d53abaedb0697e3 + image: wordpress:cli-2 + imageID: docker-pullable://wordpress@sha256:c9ecfd0ef73102cdc6666f20ccc3a0ae16c9a170160ef70bad4e9141ae856054 + lastState: {} + name: wp-install + ready: false + resources: {} + restartCount: 0 + started: false + state: + terminated: + containerID: docker://b1d36c9760604c47741156b29183957dc09994038288ba012d53abaedb0697e3 + exitCode: 0 + finishedAt: "2026-04-10T12:16:46Z" + reason: Completed + startedAt: "2026-04-10T12:15:20Z" + volumeMounts: + - mountPath: /var/www/html + name: wordpress-persistent-storage + - mountPath: /var/run/secrets/kubernetes.io/serviceaccount + name: kube-api-access-29z94 + readOnly: true + recursiveReadOnly: Disabled + hostIP: 192.168.61.192 + hostIPs: + - ip: 192.168.61.192 + observedGeneration: 1 + phase: Succeeded + podIP: 10.244.0.4 + podIPs: + - ip: 10.244.0.4 + qosClass: BestEffort + startTime: "2026-04-10T12:15:08Z" diff --git a/docs/transform-scenarios/wordpress-demo/transform/10_KubernetesPlugin/resources/Pod__v1_default_wordpress-mysql-9474c86b-fr65w.yaml b/docs/transform-scenarios/wordpress-demo/transform/10_KubernetesPlugin/resources/Pod__v1_default_wordpress-mysql-9474c86b-fr65w.yaml new file mode 100644 index 00000000..28b6de98 --- /dev/null +++ b/docs/transform-scenarios/wordpress-demo/transform/10_KubernetesPlugin/resources/Pod__v1_default_wordpress-mysql-9474c86b-fr65w.yaml @@ -0,0 +1,280 @@ +apiVersion: v1 +kind: Pod +metadata: + creationTimestamp: "2026-04-10T12:15:08Z" + generateName: wordpress-mysql-9474c86b- + generation: 1 + labels: + app: wordpress + pod-template-hash: 9474c86b + tier: mysql + managedFields: + - apiVersion: v1 + fieldsType: FieldsV1 + fieldsV1: + f:metadata: + f:generateName: {} + f:labels: + .: {} + f:app: {} + f:pod-template-hash: {} + f:tier: {} + f:ownerReferences: + .: {} + k:{"uid":"c48515d5-a023-4257-b5a1-2504dc2291af"}: {} + f:spec: + f:containers: + k:{"name":"mysql"}: + .: {} + f:env: + .: {} + k:{"name":"MYSQL_DATABASE"}: + .: {} + f:name: {} + f:value: {} + k:{"name":"MYSQL_PASSWORD"}: + .: {} + f:name: {} + f:valueFrom: + .: {} + f:secretKeyRef: {} + k:{"name":"MYSQL_ROOT_PASSWORD"}: + .: {} + f:name: {} + f:valueFrom: + .: {} + f:secretKeyRef: {} + k:{"name":"MYSQL_USER"}: + .: {} + f:name: {} + f:value: {} + f:image: {} + f:imagePullPolicy: {} + f:name: {} + f:ports: + .: {} + k:{"containerPort":3306,"protocol":"TCP"}: + .: {} + f:containerPort: {} + f:name: {} + f:protocol: {} + f:resources: {} + f:terminationMessagePath: {} + f:terminationMessagePolicy: {} + f:volumeMounts: + .: {} + k:{"mountPath":"/var/lib/mysql"}: + .: {} + f:mountPath: {} + f:name: {} + f:dnsPolicy: {} + f:enableServiceLinks: {} + f:restartPolicy: {} + f:schedulerName: {} + f:securityContext: {} + f:terminationGracePeriodSeconds: {} + f:volumes: + .: {} + k:{"name":"mysql-persistent-storage"}: + .: {} + f:name: {} + f:persistentVolumeClaim: + .: {} + f:claimName: {} + manager: kube-controller-manager + operation: Update + time: "2026-04-10T12:15:08Z" + - apiVersion: v1 + fieldsType: FieldsV1 + fieldsV1: + f:status: + f:conditions: + k:{"type":"ContainersReady"}: + .: {} + f:lastProbeTime: {} + f:lastTransitionTime: {} + f:observedGeneration: {} + f:status: {} + f:type: {} + k:{"type":"Initialized"}: + .: {} + f:lastProbeTime: {} + f:lastTransitionTime: {} + f:observedGeneration: {} + f:status: {} + f:type: {} + k:{"type":"PodReadyToStartContainers"}: + .: {} + f:lastProbeTime: {} + f:lastTransitionTime: {} + f:observedGeneration: {} + f:status: {} + f:type: {} + k:{"type":"PodScheduled"}: + f:observedGeneration: {} + k:{"type":"Ready"}: + .: {} + f:lastProbeTime: {} + f:lastTransitionTime: {} + f:observedGeneration: {} + f:status: {} + f:type: {} + f:containerStatuses: {} + f:hostIP: {} + f:hostIPs: {} + f:observedGeneration: {} + f:phase: {} + f:podIP: {} + f:podIPs: + .: {} + k:{"ip":"10.244.0.6"}: + .: {} + f:ip: {} + f:startTime: {} + manager: kubelet + operation: Update + subresource: status + time: "2026-04-10T12:15:58Z" + name: wordpress-mysql-9474c86b-fr65w + namespace: default + ownerReferences: + - apiVersion: apps/v1 + blockOwnerDeletion: true + controller: true + kind: ReplicaSet + name: wordpress-mysql-9474c86b + uid: c48515d5-a023-4257-b5a1-2504dc2291af + resourceVersion: "795" + uid: f81b40e3-ff85-46ca-8b0a-5c826b78f0c8 +spec: + containers: + - env: + - name: MYSQL_ROOT_PASSWORD + valueFrom: + secretKeyRef: + key: MYSQL_ROOT_PASSWORD + name: wordpress-secrets-hg692g82th + - name: MYSQL_DATABASE + value: wordpress + - name: MYSQL_USER + value: wordpress + - name: MYSQL_PASSWORD + valueFrom: + secretKeyRef: + key: MYSQL_WORDPRESS_PASSWORD + name: wordpress-secrets-hg692g82th + image: mysql:8.0 + imagePullPolicy: IfNotPresent + name: mysql + ports: + - containerPort: 3306 + name: mysql + protocol: TCP + resources: {} + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + volumeMounts: + - mountPath: /var/lib/mysql + name: mysql-persistent-storage + - mountPath: /var/run/secrets/kubernetes.io/serviceaccount + name: kube-api-access-k5p65 + readOnly: true + dnsPolicy: ClusterFirst + enableServiceLinks: true + nodeName: minikube + preemptionPolicy: PreemptLowerPriority + priority: 0 + restartPolicy: Always + schedulerName: default-scheduler + securityContext: {} + serviceAccount: default + serviceAccountName: default + terminationGracePeriodSeconds: 30 + tolerations: + - effect: NoExecute + key: node.kubernetes.io/not-ready + operator: Exists + tolerationSeconds: 300 + - effect: NoExecute + key: node.kubernetes.io/unreachable + operator: Exists + tolerationSeconds: 300 + volumes: + - name: mysql-persistent-storage + persistentVolumeClaim: + claimName: mysql-pv-claim + - name: kube-api-access-k5p65 + projected: + defaultMode: 420 + sources: + - serviceAccountToken: + expirationSeconds: 3607 + path: token + - configMap: + items: + - key: ca.crt + path: ca.crt + name: kube-root-ca.crt + - downwardAPI: + items: + - fieldRef: + apiVersion: v1 + fieldPath: metadata.namespace + path: namespace +status: + conditions: + - lastProbeTime: null + lastTransitionTime: "2026-04-10T12:15:58Z" + observedGeneration: 1 + status: "True" + type: PodReadyToStartContainers + - lastProbeTime: null + lastTransitionTime: "2026-04-10T12:15:08Z" + observedGeneration: 1 + status: "True" + type: Initialized + - lastProbeTime: null + lastTransitionTime: "2026-04-10T12:15:58Z" + observedGeneration: 1 + status: "True" + type: Ready + - lastProbeTime: null + lastTransitionTime: "2026-04-10T12:15:58Z" + observedGeneration: 1 + status: "True" + type: ContainersReady + - lastProbeTime: null + lastTransitionTime: "2026-04-10T12:15:08Z" + observedGeneration: 1 + status: "True" + type: PodScheduled + containerStatuses: + - containerID: docker://7e196a67c97dc0a97090ed6f3e62507aa9a63ab4d28ce7b455be169edc7c53ce + image: mysql:8.0 + imageID: docker-pullable://mysql@sha256:64756cc92f707eb504496d774353990bcb0f6999ddf598b6ad188f2da66bd000 + lastState: {} + name: mysql + ready: true + resources: {} + restartCount: 0 + started: true + state: + running: + startedAt: "2026-04-10T12:15:57Z" + volumeMounts: + - mountPath: /var/lib/mysql + name: mysql-persistent-storage + - mountPath: /var/run/secrets/kubernetes.io/serviceaccount + name: kube-api-access-k5p65 + readOnly: true + recursiveReadOnly: Disabled + hostIP: 192.168.61.192 + hostIPs: + - ip: 192.168.61.192 + observedGeneration: 1 + phase: Running + podIP: 10.244.0.6 + podIPs: + - ip: 10.244.0.6 + qosClass: BestEffort + startTime: "2026-04-10T12:15:08Z" diff --git a/docs/transform-scenarios/wordpress-demo/transform/10_KubernetesPlugin/resources/ReplicaSet_apps_v1_default_wordpress-74b89cc84c.yaml b/docs/transform-scenarios/wordpress-demo/transform/10_KubernetesPlugin/resources/ReplicaSet_apps_v1_default_wordpress-74b89cc84c.yaml new file mode 100644 index 00000000..db3e66a7 --- /dev/null +++ b/docs/transform-scenarios/wordpress-demo/transform/10_KubernetesPlugin/resources/ReplicaSet_apps_v1_default_wordpress-74b89cc84c.yaml @@ -0,0 +1,245 @@ +apiVersion: apps/v1 +kind: ReplicaSet +metadata: + annotations: + deployment.kubernetes.io/desired-replicas: "1" + deployment.kubernetes.io/max-replicas: "1" + deployment.kubernetes.io/revision: "1" + creationTimestamp: "2026-04-10T12:15:08Z" + generation: 1 + labels: + app: wordpress + pod-template-hash: 74b89cc84c + tier: frontend + managedFields: + - apiVersion: apps/v1 + fieldsType: FieldsV1 + fieldsV1: + f:metadata: + f:annotations: + .: {} + f:deployment.kubernetes.io/desired-replicas: {} + f:deployment.kubernetes.io/max-replicas: {} + f:deployment.kubernetes.io/revision: {} + f:labels: + .: {} + f:app: {} + f:pod-template-hash: {} + f:tier: {} + f:ownerReferences: + .: {} + k:{"uid":"32f30549-f011-48b1-8398-64fef74b2df1"}: {} + f:spec: + f:replicas: {} + f:selector: {} + f:template: + f:metadata: + f:labels: + .: {} + f:app: {} + f:pod-template-hash: {} + f:tier: {} + f:spec: + f:containers: + k:{"name":"nginx"}: + .: {} + f:image: {} + f:imagePullPolicy: {} + f:name: {} + f:ports: + .: {} + k:{"containerPort":80,"protocol":"TCP"}: + .: {} + f:containerPort: {} + f:name: {} + f:protocol: {} + f:resources: {} + f:terminationMessagePath: {} + f:terminationMessagePolicy: {} + f:volumeMounts: + .: {} + k:{"mountPath":"/etc/nginx/nginx.conf"}: + .: {} + f:mountPath: {} + f:name: {} + f:subPath: {} + k:{"mountPath":"/var/www/html"}: + .: {} + f:mountPath: {} + f:name: {} + f:readOnly: {} + k:{"name":"wordpress"}: + .: {} + f:env: + .: {} + k:{"name":"WORDPRESS_CONFIG_EXTRA"}: + .: {} + f:name: {} + f:value: {} + k:{"name":"WORDPRESS_DB_HOST"}: + .: {} + f:name: {} + f:value: {} + k:{"name":"WORDPRESS_DB_PASSWORD"}: + .: {} + f:name: {} + f:valueFrom: + .: {} + f:secretKeyRef: {} + k:{"name":"WORDPRESS_DB_USER"}: + .: {} + f:name: {} + f:value: {} + f:image: {} + f:imagePullPolicy: {} + f:name: {} + f:ports: + .: {} + k:{"containerPort":9000,"protocol":"TCP"}: + .: {} + f:containerPort: {} + f:name: {} + f:protocol: {} + f:resources: {} + f:terminationMessagePath: {} + f:terminationMessagePolicy: {} + f:volumeMounts: + .: {} + k:{"mountPath":"/var/www/html"}: + .: {} + f:mountPath: {} + f:name: {} + f:dnsPolicy: {} + f:restartPolicy: {} + f:schedulerName: {} + f:securityContext: {} + f:terminationGracePeriodSeconds: {} + f:volumes: + .: {} + k:{"name":"nginx-config"}: + .: {} + f:configMap: + .: {} + f:defaultMode: {} + f:name: {} + f:name: {} + k:{"name":"wordpress-persistent-storage"}: + .: {} + f:name: {} + f:persistentVolumeClaim: + .: {} + f:claimName: {} + manager: kube-controller-manager + operation: Update + time: "2026-04-10T12:15:08Z" + - apiVersion: apps/v1 + fieldsType: FieldsV1 + fieldsV1: + f:status: + f:availableReplicas: {} + f:fullyLabeledReplicas: {} + f:observedGeneration: {} + f:readyReplicas: {} + f:replicas: {} + f:terminatingReplicas: {} + manager: kube-controller-manager + operation: Update + subresource: status + time: "2026-04-10T12:16:04Z" + name: wordpress-74b89cc84c + namespace: default + ownerReferences: + - apiVersion: apps/v1 + blockOwnerDeletion: true + controller: true + kind: Deployment + name: wordpress + uid: 32f30549-f011-48b1-8398-64fef74b2df1 + resourceVersion: "811" + uid: 7ed37255-e5ff-4e33-837d-f584a536d2b8 +spec: + replicas: 1 + selector: + matchLabels: + app: wordpress + pod-template-hash: 74b89cc84c + tier: frontend + template: + metadata: + labels: + app: wordpress + pod-template-hash: 74b89cc84c + tier: frontend + spec: + containers: + - env: + - name: WORDPRESS_DB_HOST + value: wordpress-mysql + - name: WORDPRESS_DB_PASSWORD + valueFrom: + secretKeyRef: + key: MYSQL_WORDPRESS_PASSWORD + name: wordpress-secrets-hg692g82th + - name: WORDPRESS_DB_USER + value: wordpress + - name: WORDPRESS_CONFIG_EXTRA + value: | + // Set SITE URL dynamically from requests to allow reach it on different endpoints + if (isset($_SERVER['HTTP_HOST'])) { + $protocol = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on') ? 'https' : 'http'; + if (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https') { + $protocol = 'https'; + } + define('WP_HOME', $protocol . '://' . $_SERVER['HTTP_HOST']); + define('WP_SITEURL', $protocol . '://' . $_SERVER['HTTP_HOST']); + } + image: wordpress:6-fpm-alpine + imagePullPolicy: IfNotPresent + name: wordpress + ports: + - containerPort: 9000 + name: fastcgi + protocol: TCP + resources: {} + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + volumeMounts: + - mountPath: /var/www/html + name: wordpress-persistent-storage + - image: nginx:alpine + imagePullPolicy: IfNotPresent + name: nginx + ports: + - containerPort: 80 + name: http + protocol: TCP + resources: {} + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + volumeMounts: + - mountPath: /var/www/html + name: wordpress-persistent-storage + readOnly: true + - mountPath: /etc/nginx/nginx.conf + name: nginx-config + subPath: nginx.conf + dnsPolicy: ClusterFirst + restartPolicy: Always + schedulerName: default-scheduler + securityContext: {} + terminationGracePeriodSeconds: 30 + volumes: + - name: wordpress-persistent-storage + persistentVolumeClaim: + claimName: wordpress-pv-claim + - configMap: + defaultMode: 420 + name: nginx-config + name: nginx-config +status: + availableReplicas: 1 + fullyLabeledReplicas: 1 + observedGeneration: 1 + readyReplicas: 1 + replicas: 1 + terminatingReplicas: 0 diff --git a/docs/transform-scenarios/wordpress-demo/transform/10_KubernetesPlugin/resources/ReplicaSet_apps_v1_default_wordpress-mysql-9474c86b.yaml b/docs/transform-scenarios/wordpress-demo/transform/10_KubernetesPlugin/resources/ReplicaSet_apps_v1_default_wordpress-mysql-9474c86b.yaml new file mode 100644 index 00000000..d34a5904 --- /dev/null +++ b/docs/transform-scenarios/wordpress-demo/transform/10_KubernetesPlugin/resources/ReplicaSet_apps_v1_default_wordpress-mysql-9474c86b.yaml @@ -0,0 +1,186 @@ +apiVersion: apps/v1 +kind: ReplicaSet +metadata: + annotations: + deployment.kubernetes.io/desired-replicas: "1" + deployment.kubernetes.io/max-replicas: "1" + deployment.kubernetes.io/revision: "1" + creationTimestamp: "2026-04-10T12:15:08Z" + generation: 1 + labels: + app: wordpress + pod-template-hash: 9474c86b + tier: mysql + managedFields: + - apiVersion: apps/v1 + fieldsType: FieldsV1 + fieldsV1: + f:metadata: + f:annotations: + .: {} + f:deployment.kubernetes.io/desired-replicas: {} + f:deployment.kubernetes.io/max-replicas: {} + f:deployment.kubernetes.io/revision: {} + f:labels: + .: {} + f:app: {} + f:pod-template-hash: {} + f:tier: {} + f:ownerReferences: + .: {} + k:{"uid":"2eba9391-46db-4860-9f9a-a1cb396faf18"}: {} + f:spec: + f:replicas: {} + f:selector: {} + f:template: + f:metadata: + f:labels: + .: {} + f:app: {} + f:pod-template-hash: {} + f:tier: {} + f:spec: + f:containers: + k:{"name":"mysql"}: + .: {} + f:env: + .: {} + k:{"name":"MYSQL_DATABASE"}: + .: {} + f:name: {} + f:value: {} + k:{"name":"MYSQL_PASSWORD"}: + .: {} + f:name: {} + f:valueFrom: + .: {} + f:secretKeyRef: {} + k:{"name":"MYSQL_ROOT_PASSWORD"}: + .: {} + f:name: {} + f:valueFrom: + .: {} + f:secretKeyRef: {} + k:{"name":"MYSQL_USER"}: + .: {} + f:name: {} + f:value: {} + f:image: {} + f:imagePullPolicy: {} + f:name: {} + f:ports: + .: {} + k:{"containerPort":3306,"protocol":"TCP"}: + .: {} + f:containerPort: {} + f:name: {} + f:protocol: {} + f:resources: {} + f:terminationMessagePath: {} + f:terminationMessagePolicy: {} + f:volumeMounts: + .: {} + k:{"mountPath":"/var/lib/mysql"}: + .: {} + f:mountPath: {} + f:name: {} + f:dnsPolicy: {} + f:restartPolicy: {} + f:schedulerName: {} + f:securityContext: {} + f:terminationGracePeriodSeconds: {} + f:volumes: + .: {} + k:{"name":"mysql-persistent-storage"}: + .: {} + f:name: {} + f:persistentVolumeClaim: + .: {} + f:claimName: {} + manager: kube-controller-manager + operation: Update + time: "2026-04-10T12:15:08Z" + - apiVersion: apps/v1 + fieldsType: FieldsV1 + fieldsV1: + f:status: + f:availableReplicas: {} + f:fullyLabeledReplicas: {} + f:observedGeneration: {} + f:readyReplicas: {} + f:replicas: {} + f:terminatingReplicas: {} + manager: kube-controller-manager + operation: Update + subresource: status + time: "2026-04-10T12:15:58Z" + name: wordpress-mysql-9474c86b + namespace: default + ownerReferences: + - apiVersion: apps/v1 + blockOwnerDeletion: true + controller: true + kind: Deployment + name: wordpress-mysql + uid: 2eba9391-46db-4860-9f9a-a1cb396faf18 + resourceVersion: "798" + uid: c48515d5-a023-4257-b5a1-2504dc2291af +spec: + replicas: 1 + selector: + matchLabels: + app: wordpress + pod-template-hash: 9474c86b + tier: mysql + template: + metadata: + labels: + app: wordpress + pod-template-hash: 9474c86b + tier: mysql + spec: + containers: + - env: + - name: MYSQL_ROOT_PASSWORD + valueFrom: + secretKeyRef: + key: MYSQL_ROOT_PASSWORD + name: wordpress-secrets-hg692g82th + - name: MYSQL_DATABASE + value: wordpress + - name: MYSQL_USER + value: wordpress + - name: MYSQL_PASSWORD + valueFrom: + secretKeyRef: + key: MYSQL_WORDPRESS_PASSWORD + name: wordpress-secrets-hg692g82th + image: mysql:8.0 + imagePullPolicy: IfNotPresent + name: mysql + ports: + - containerPort: 3306 + name: mysql + protocol: TCP + resources: {} + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + volumeMounts: + - mountPath: /var/lib/mysql + name: mysql-persistent-storage + dnsPolicy: ClusterFirst + restartPolicy: Always + schedulerName: default-scheduler + securityContext: {} + terminationGracePeriodSeconds: 30 + volumes: + - name: mysql-persistent-storage + persistentVolumeClaim: + claimName: mysql-pv-claim +status: + availableReplicas: 1 + fullyLabeledReplicas: 1 + observedGeneration: 1 + readyReplicas: 1 + replicas: 1 + terminatingReplicas: 0 diff --git a/docs/transform-scenarios/wordpress-demo/transform/10_KubernetesPlugin/resources/Secret__v1_default_wordpress-secrets-hg692g82th.yaml b/docs/transform-scenarios/wordpress-demo/transform/10_KubernetesPlugin/resources/Secret__v1_default_wordpress-secrets-hg692g82th.yaml new file mode 100644 index 00000000..f9deba91 --- /dev/null +++ b/docs/transform-scenarios/wordpress-demo/transform/10_KubernetesPlugin/resources/Secret__v1_default_wordpress-secrets-hg692g82th.yaml @@ -0,0 +1,33 @@ +apiVersion: v1 +data: + MYSQL_ROOT_PASSWORD: eGFJMmdpdWhxc2V0TC82VDRaOVViUT09 + MYSQL_WORDPRESS_PASSWORD: QzZUa25lcFo3Vm5idTdGZVdBSUFidz09 + WORDPRESS_ADMIN_PASSWORD: d0ZoSytaZDhlU2RhVmx1Ug== +kind: Secret +metadata: + annotations: + kubectl.kubernetes.io/last-applied-configuration: | + {"apiVersion":"v1","data":{"MYSQL_ROOT_PASSWORD":"eGFJMmdpdWhxc2V0TC82VDRaOVViUT09","MYSQL_WORDPRESS_PASSWORD":"QzZUa25lcFo3Vm5idTdGZVdBSUFidz09","WORDPRESS_ADMIN_PASSWORD":"d0ZoSytaZDhlU2RhVmx1Ug=="},"kind":"Secret","metadata":{"annotations":{},"name":"wordpress-secrets-hg692g82th","namespace":"default"},"type":"Opaque"} + creationTimestamp: "2026-04-10T12:15:07Z" + managedFields: + - apiVersion: v1 + fieldsType: FieldsV1 + fieldsV1: + f:data: + .: {} + f:MYSQL_ROOT_PASSWORD: {} + f:MYSQL_WORDPRESS_PASSWORD: {} + f:WORDPRESS_ADMIN_PASSWORD: {} + f:metadata: + f:annotations: + .: {} + f:kubectl.kubernetes.io/last-applied-configuration: {} + f:type: {} + manager: kubectl-client-side-apply + operation: Update + time: "2026-04-10T12:15:07Z" + name: wordpress-secrets-hg692g82th + namespace: default + resourceVersion: "676" + uid: 0bb63c2c-fa4a-4c86-ad5d-141dccbd25ad +type: Opaque diff --git a/docs/transform-scenarios/wordpress-demo/transform/10_KubernetesPlugin/resources/ServiceAccount__v1_default_default.yaml b/docs/transform-scenarios/wordpress-demo/transform/10_KubernetesPlugin/resources/ServiceAccount__v1_default_default.yaml new file mode 100644 index 00000000..49a7b37e --- /dev/null +++ b/docs/transform-scenarios/wordpress-demo/transform/10_KubernetesPlugin/resources/ServiceAccount__v1_default_default.yaml @@ -0,0 +1,8 @@ +apiVersion: v1 +kind: ServiceAccount +metadata: + creationTimestamp: "2026-04-10T12:10:49Z" + name: default + namespace: default + resourceVersion: "336" + uid: 01ad4812-cd89-4fce-914d-7eee37f8f551 diff --git a/docs/transform-scenarios/wordpress-demo/transform/10_KubernetesPlugin/resources/Service__v1_default_kubernetes.yaml b/docs/transform-scenarios/wordpress-demo/transform/10_KubernetesPlugin/resources/Service__v1_default_kubernetes.yaml new file mode 100644 index 00000000..0c06b485 --- /dev/null +++ b/docs/transform-scenarios/wordpress-demo/transform/10_KubernetesPlugin/resources/Service__v1_default_kubernetes.yaml @@ -0,0 +1,54 @@ +apiVersion: v1 +kind: Service +metadata: + creationTimestamp: "2026-04-10T12:10:43Z" + labels: + component: apiserver + provider: kubernetes + managedFields: + - apiVersion: v1 + fieldsType: FieldsV1 + fieldsV1: + f:metadata: + f:labels: + .: {} + f:component: {} + f:provider: {} + f:spec: + f:clusterIP: {} + f:internalTrafficPolicy: {} + f:ipFamilyPolicy: {} + f:ports: + .: {} + k:{"port":443,"protocol":"TCP"}: + .: {} + f:name: {} + f:port: {} + f:protocol: {} + f:targetPort: {} + f:sessionAffinity: {} + f:type: {} + manager: kube-apiserver + operation: Update + time: "2026-04-10T12:10:43Z" + name: kubernetes + namespace: default + resourceVersion: "204" + uid: 5ca30343-0dc7-41ee-adcb-b3e4f821f150 +spec: + clusterIP: 10.96.0.1 + clusterIPs: + - 10.96.0.1 + internalTrafficPolicy: Cluster + ipFamilies: + - IPv4 + ipFamilyPolicy: SingleStack + ports: + - name: https + port: 443 + protocol: TCP + targetPort: 8443 + sessionAffinity: None + type: ClusterIP +status: + loadBalancer: {} diff --git a/docs/transform-scenarios/wordpress-demo/transform/10_KubernetesPlugin/resources/Service__v1_default_wordpress-mysql.yaml b/docs/transform-scenarios/wordpress-demo/transform/10_KubernetesPlugin/resources/Service__v1_default_wordpress-mysql.yaml new file mode 100644 index 00000000..29acff57 --- /dev/null +++ b/docs/transform-scenarios/wordpress-demo/transform/10_KubernetesPlugin/resources/Service__v1_default_wordpress-mysql.yaml @@ -0,0 +1,58 @@ +apiVersion: v1 +kind: Service +metadata: + annotations: + kubectl.kubernetes.io/last-applied-configuration: | + {"apiVersion":"v1","kind":"Service","metadata":{"annotations":{},"labels":{"app":"wordpress"},"name":"wordpress-mysql","namespace":"default"},"spec":{"ports":[{"port":3306}],"selector":{"app":"wordpress","tier":"mysql"}}} + creationTimestamp: "2026-04-10T12:15:07Z" + labels: + app: wordpress + managedFields: + - apiVersion: v1 + fieldsType: FieldsV1 + fieldsV1: + f:metadata: + f:annotations: + .: {} + f:kubectl.kubernetes.io/last-applied-configuration: {} + f:labels: + .: {} + f:app: {} + f:spec: + f:internalTrafficPolicy: {} + f:ports: + .: {} + k:{"port":3306,"protocol":"TCP"}: + .: {} + f:port: {} + f:protocol: {} + f:targetPort: {} + f:selector: {} + f:sessionAffinity: {} + f:type: {} + manager: kubectl-client-side-apply + operation: Update + time: "2026-04-10T12:15:07Z" + name: wordpress-mysql + namespace: default + resourceVersion: "683" + uid: ec2555f1-9fd5-45da-bfa3-f2b59bb1d218 +spec: + clusterIP: 10.101.133.119 + clusterIPs: + - 10.101.133.119 + internalTrafficPolicy: Cluster + ipFamilies: + - IPv4 + ipFamilyPolicy: SingleStack + ports: + - port: 3306 + protocol: TCP + targetPort: 3306 + selector: + app: wordpress + tier: mysql + sessionAffinity: None + type: ClusterIP +status: + loadBalancer: {} diff --git a/docs/transform-scenarios/wordpress-demo/transform/10_KubernetesPlugin/resources/Service__v1_default_wordpress.yaml b/docs/transform-scenarios/wordpress-demo/transform/10_KubernetesPlugin/resources/Service__v1_default_wordpress.yaml new file mode 100644 index 00000000..4099abd1 --- /dev/null +++ b/docs/transform-scenarios/wordpress-demo/transform/10_KubernetesPlugin/resources/Service__v1_default_wordpress.yaml @@ -0,0 +1,63 @@ +apiVersion: v1 +kind: Service +metadata: + annotations: + kubectl.kubernetes.io/last-applied-configuration: | + {"apiVersion":"v1","kind":"Service","metadata":{"annotations":{},"labels":{"app":"wordpress"},"name":"wordpress","namespace":"default"},"spec":{"ports":[{"port":80}],"selector":{"app":"wordpress","tier":"frontend"},"type":"LoadBalancer"}} + creationTimestamp: "2026-04-10T12:15:07Z" + labels: + app: wordpress + managedFields: + - apiVersion: v1 + fieldsType: FieldsV1 + fieldsV1: + f:metadata: + f:annotations: + .: {} + f:kubectl.kubernetes.io/last-applied-configuration: {} + f:labels: + .: {} + f:app: {} + f:spec: + f:allocateLoadBalancerNodePorts: {} + f:externalTrafficPolicy: {} + f:internalTrafficPolicy: {} + f:ports: + .: {} + k:{"port":80,"protocol":"TCP"}: + .: {} + f:port: {} + f:protocol: {} + f:targetPort: {} + f:selector: {} + f:sessionAffinity: {} + f:type: {} + manager: kubectl-client-side-apply + operation: Update + time: "2026-04-10T12:15:07Z" + name: wordpress + namespace: default + resourceVersion: "679" + uid: 9bd59883-6312-4534-a2c1-b71911612715 +spec: + allocateLoadBalancerNodePorts: true + clusterIP: 10.99.69.43 + clusterIPs: + - 10.99.69.43 + externalTrafficPolicy: Cluster + internalTrafficPolicy: Cluster + ipFamilies: + - IPv4 + ipFamilyPolicy: SingleStack + ports: + - nodePort: 32215 + port: 80 + protocol: TCP + targetPort: 80 + selector: + app: wordpress + tier: frontend + sessionAffinity: None + type: LoadBalancer +status: + loadBalancer: {} diff --git a/docs/transform-scenarios/wordpress-demo/transform/50_CustomLabelsAndNamespace/kustomization.yaml b/docs/transform-scenarios/wordpress-demo/transform/50_CustomLabelsAndNamespace/kustomization.yaml new file mode 100644 index 00000000..337b7486 --- /dev/null +++ b/docs/transform-scenarios/wordpress-demo/transform/50_CustomLabelsAndNamespace/kustomization.yaml @@ -0,0 +1,16 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +resources: +- resources/ConfigMap__v1_default_nginx-config.yaml +- resources/Deployment_apps_v1_default_wordpress-mysql.yaml +- resources/Deployment_apps_v1_default_wordpress.yaml +- resources/Job_batch_v1_default_wordpress-install.yaml +- resources/Secret__v1_default_wordpress-secrets-hg692g82th.yaml +- resources/Service__v1_default_kubernetes.yaml +- resources/Service__v1_default_wordpress-mysql.yaml +- resources/Service__v1_default_wordpress.yaml + +# Custom modifications +namespace: new-migrated-namespace +commonLabels: + migrated-with: crane diff --git a/docs/transform-scenarios/wordpress-demo/transform/50_CustomLabelsAndNamespace/resources/ConfigMap__v1_default_nginx-config.yaml b/docs/transform-scenarios/wordpress-demo/transform/50_CustomLabelsAndNamespace/resources/ConfigMap__v1_default_nginx-config.yaml new file mode 100644 index 00000000..cd99e95c --- /dev/null +++ b/docs/transform-scenarios/wordpress-demo/transform/50_CustomLabelsAndNamespace/resources/ConfigMap__v1_default_nginx-config.yaml @@ -0,0 +1,35 @@ +apiVersion: v1 +data: + nginx.conf: | + events { + worker_connections 64; + } + + http { + include /etc/nginx/mime.types; + default_type application/octet-stream; + + server { + listen 80; + root /var/www/html; + index index.php; + client_max_body_size 32m; + + location / { + try_files $uri $uri/ /index.php?$args; + } + + location ~ \.php$ { + fastcgi_pass localhost:9000; + fastcgi_index index.php; + include fastcgi_params; + fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; + } + } + } +kind: ConfigMap +metadata: + labels: + app: wordpress + name: nginx-config + namespace: default diff --git a/docs/transform-scenarios/wordpress-demo/transform/50_CustomLabelsAndNamespace/resources/Deployment_apps_v1_default_wordpress-mysql.yaml b/docs/transform-scenarios/wordpress-demo/transform/50_CustomLabelsAndNamespace/resources/Deployment_apps_v1_default_wordpress-mysql.yaml new file mode 100644 index 00000000..0b65bd7e --- /dev/null +++ b/docs/transform-scenarios/wordpress-demo/transform/50_CustomLabelsAndNamespace/resources/Deployment_apps_v1_default_wordpress-mysql.yaml @@ -0,0 +1,63 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + annotations: + deployment.kubernetes.io/revision: "1" + labels: + app: wordpress + name: wordpress-mysql + namespace: default +spec: + progressDeadlineSeconds: 600 + replicas: 1 + revisionHistoryLimit: 10 + selector: + matchLabels: + app: wordpress + tier: mysql + strategy: + type: Recreate + template: + metadata: + labels: + app: wordpress + tier: mysql + spec: + containers: + - env: + - name: MYSQL_ROOT_PASSWORD + valueFrom: + secretKeyRef: + key: MYSQL_ROOT_PASSWORD + name: wordpress-secrets-hg692g82th + - name: MYSQL_DATABASE + value: wordpress + - name: MYSQL_USER + value: wordpress + - name: MYSQL_PASSWORD + valueFrom: + secretKeyRef: + key: MYSQL_WORDPRESS_PASSWORD + name: wordpress-secrets-hg692g82th + image: mysql:8.0 + imagePullPolicy: IfNotPresent + name: mysql + ports: + - containerPort: 3306 + name: mysql + protocol: TCP + resources: {} + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + volumeMounts: + - mountPath: /var/lib/mysql + name: mysql-persistent-storage + dnsPolicy: ClusterFirst + restartPolicy: Always + schedulerName: default-scheduler + securityContext: {} + terminationGracePeriodSeconds: 30 + volumes: + - name: mysql-persistent-storage + persistentVolumeClaim: + claimName: mysql-pv-claim diff --git a/docs/transform-scenarios/wordpress-demo/transform/50_CustomLabelsAndNamespace/resources/Deployment_apps_v1_default_wordpress.yaml b/docs/transform-scenarios/wordpress-demo/transform/50_CustomLabelsAndNamespace/resources/Deployment_apps_v1_default_wordpress.yaml new file mode 100644 index 00000000..90e2645a --- /dev/null +++ b/docs/transform-scenarios/wordpress-demo/transform/50_CustomLabelsAndNamespace/resources/Deployment_apps_v1_default_wordpress.yaml @@ -0,0 +1,90 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + annotations: + deployment.kubernetes.io/revision: "1" + labels: + app: wordpress + name: wordpress + namespace: default +spec: + progressDeadlineSeconds: 600 + replicas: 1 + revisionHistoryLimit: 10 + selector: + matchLabels: + app: wordpress + tier: frontend + strategy: + type: Recreate + template: + metadata: + labels: + app: wordpress + tier: frontend + spec: + containers: + - env: + - name: WORDPRESS_DB_HOST + value: wordpress-mysql + - name: WORDPRESS_DB_PASSWORD + valueFrom: + secretKeyRef: + key: MYSQL_WORDPRESS_PASSWORD + name: wordpress-secrets-hg692g82th + - name: WORDPRESS_DB_USER + value: wordpress + - name: WORDPRESS_CONFIG_EXTRA + value: | + // Set SITE URL dynamically from requests to allow reach it on different endpoints + if (isset($_SERVER['HTTP_HOST'])) { + $protocol = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on') ? 'https' : 'http'; + if (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https') { + $protocol = 'https'; + } + define('WP_HOME', $protocol . '://' . $_SERVER['HTTP_HOST']); + define('WP_SITEURL', $protocol . '://' . $_SERVER['HTTP_HOST']); + } + image: wordpress:6-fpm-alpine + imagePullPolicy: IfNotPresent + name: wordpress + ports: + - containerPort: 9000 + name: fastcgi + protocol: TCP + resources: {} + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + volumeMounts: + - mountPath: /var/www/html + name: wordpress-persistent-storage + - image: nginx:alpine + imagePullPolicy: IfNotPresent + name: nginx + ports: + - containerPort: 80 + name: http + protocol: TCP + resources: {} + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + volumeMounts: + - mountPath: /var/www/html + name: wordpress-persistent-storage + readOnly: true + - mountPath: /etc/nginx/nginx.conf + name: nginx-config + subPath: nginx.conf + dnsPolicy: ClusterFirst + restartPolicy: Always + schedulerName: default-scheduler + securityContext: {} + terminationGracePeriodSeconds: 30 + volumes: + - name: wordpress-persistent-storage + persistentVolumeClaim: + claimName: wordpress-pv-claim + - configMap: + defaultMode: 420 + name: nginx-config + name: nginx-config diff --git a/docs/transform-scenarios/wordpress-demo/transform/50_CustomLabelsAndNamespace/resources/Job_batch_v1_default_wordpress-install.yaml b/docs/transform-scenarios/wordpress-demo/transform/50_CustomLabelsAndNamespace/resources/Job_batch_v1_default_wordpress-install.yaml new file mode 100644 index 00000000..69198c32 --- /dev/null +++ b/docs/transform-scenarios/wordpress-demo/transform/50_CustomLabelsAndNamespace/resources/Job_batch_v1_default_wordpress-install.yaml @@ -0,0 +1,141 @@ +apiVersion: batch/v1 +kind: Job +metadata: + labels: + batch.kubernetes.io/controller-uid: be719474-856d-4d84-80ad-4f4ab9ecdd30 + batch.kubernetes.io/job-name: wordpress-install + controller-uid: be719474-856d-4d84-80ad-4f4ab9ecdd30 + job-name: wordpress-install + name: wordpress-install + namespace: default +spec: + backoffLimit: 4 + completionMode: NonIndexed + completions: 1 + manualSelector: false + parallelism: 1 + podReplacementPolicy: TerminatingOrFailed + selector: + matchLabels: + batch.kubernetes.io/controller-uid: be719474-856d-4d84-80ad-4f4ab9ecdd30 + suspend: false + template: + metadata: + labels: + batch.kubernetes.io/controller-uid: be719474-856d-4d84-80ad-4f4ab9ecdd30 + batch.kubernetes.io/job-name: wordpress-install + controller-uid: be719474-856d-4d84-80ad-4f4ab9ecdd30 + job-name: wordpress-install + spec: + containers: + - args: + - -lc + - | + set -e + cd /var/www/html + + echo "Waiting for MySQL on ${WORDPRESS_DB_HOST}:3306..." + for i in $(seq 1 60); do + if mariadb-admin ping -h"${WORDPRESS_DB_HOST}" -u"${WORDPRESS_DB_USER}" -p"${WORDPRESS_DB_PASSWORD}" --ssl=false --silent; then + echo "MySQL is up." + break + fi + echo "MySQL not ready yet (attempt: $i)..." + sleep 5 + done + + if ! mariadb-admin ping -h"${WORDPRESS_DB_HOST}" -u"${WORDPRESS_DB_USER}" -p"${WORDPRESS_DB_PASSWORD}" --ssl=false --silent; then + echo "MySQL did not become ready within the timeout." + exit 1 + fi + + # Make sure WordPress core is present on the volume + if [ ! -f wp-load.php ]; then + echo "WordPress core not found on the volume. Downloading..." + wp core download --allow-root + fi + + # Create wp-config.php if missing + if [ ! -f wp-config.php ]; then + echo "Creating wp-config.php..." + wp config create \ + --dbname="${WORDPRESS_DB_NAME}" \ + --dbuser="${WORDPRESS_DB_USER}" \ + --dbpass="${WORDPRESS_DB_PASSWORD}" \ + --dbhost="${WORDPRESS_DB_HOST}" \ + --allow-root + fi + + # Idempotent install + if wp core is-installed --allow-root >/dev/null 2>&1; then + echo "WordPress is already installed. Nothing to do." + exit 0 + fi + + # Create an installation kind of unique ID + WORDPRESS_SEED_ID=$RANDOM + + echo "Running wp core install..." + wp core install \ + --url="${WORDPRESS_SITE_URL}" \ + --title="${WORDPRESS_SITE_TITLE} #$WORDPRESS_SEED_ID" \ + --admin_user="${WORDPRESS_ADMIN_USER}" \ + --admin_password="${WORDPRESS_ADMIN_PASSWORD}" \ + --admin_email="${WORDPRESS_ADMIN_EMAIL}" \ + --skip-email \ + --allow-root + + echo "Creating sample post..." + wp post create \ + --post_type=post \ + --post_status=publish \ + --post_title="Sample post #$WORDPRESS_SEED_ID" \ + --post_content="Hello from k8s, this is a random post content: $(openssl rand -base64 200 | tr -cs 'a-zA-Z' ' ' | xargs)" + + echo "WORDPRESS_SEED_ID=$WORDPRESS_SEED_ID" + echo "Done. WordPress has been installed." + command: + - bash + env: + - name: WORDPRESS_DB_HOST + value: wordpress-mysql + - name: WORDPRESS_DB_USER + value: wordpress + - name: WORDPRESS_DB_NAME + value: wordpress + - name: WORDPRESS_DB_PASSWORD + valueFrom: + secretKeyRef: + key: MYSQL_WORDPRESS_PASSWORD + name: wordpress-secrets-hg692g82th + - name: WORDPRESS_SITE_URL + value: http://wordpress-k8s.example.local + - name: WORDPRESS_SITE_TITLE + value: My WordPress Site on k8s + - name: WORDPRESS_ADMIN_USER + value: admin + - name: WORDPRESS_ADMIN_PASSWORD + valueFrom: + secretKeyRef: + key: WORDPRESS_ADMIN_PASSWORD + name: wordpress-secrets-hg692g82th + - name: WORDPRESS_ADMIN_EMAIL + value: admin@wordpress-k8s.example.local + image: wordpress:cli-2 + imagePullPolicy: IfNotPresent + name: wp-install + resources: {} + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + volumeMounts: + - mountPath: /var/www/html + name: wordpress-persistent-storage + dnsPolicy: ClusterFirst + restartPolicy: OnFailure + schedulerName: default-scheduler + securityContext: {} + terminationGracePeriodSeconds: 30 + volumes: + - name: wordpress-persistent-storage + persistentVolumeClaim: + claimName: wordpress-pv-claim diff --git a/docs/transform-scenarios/wordpress-demo/transform/50_CustomLabelsAndNamespace/resources/Secret__v1_default_wordpress-secrets-hg692g82th.yaml b/docs/transform-scenarios/wordpress-demo/transform/50_CustomLabelsAndNamespace/resources/Secret__v1_default_wordpress-secrets-hg692g82th.yaml new file mode 100644 index 00000000..4ce42db4 --- /dev/null +++ b/docs/transform-scenarios/wordpress-demo/transform/50_CustomLabelsAndNamespace/resources/Secret__v1_default_wordpress-secrets-hg692g82th.yaml @@ -0,0 +1,10 @@ +apiVersion: v1 +data: + MYSQL_ROOT_PASSWORD: eGFJMmdpdWhxc2V0TC82VDRaOVViUT09 + MYSQL_WORDPRESS_PASSWORD: QzZUa25lcFo3Vm5idTdGZVdBSUFidz09 + WORDPRESS_ADMIN_PASSWORD: d0ZoSytaZDhlU2RhVmx1Ug== +kind: Secret +metadata: + name: wordpress-secrets-hg692g82th + namespace: default +type: Opaque diff --git a/docs/transform-scenarios/wordpress-demo/transform/50_CustomLabelsAndNamespace/resources/Service__v1_default_kubernetes.yaml b/docs/transform-scenarios/wordpress-demo/transform/50_CustomLabelsAndNamespace/resources/Service__v1_default_kubernetes.yaml new file mode 100644 index 00000000..67001d1b --- /dev/null +++ b/docs/transform-scenarios/wordpress-demo/transform/50_CustomLabelsAndNamespace/resources/Service__v1_default_kubernetes.yaml @@ -0,0 +1,20 @@ +apiVersion: v1 +kind: Service +metadata: + labels: + component: apiserver + provider: kubernetes + name: kubernetes + namespace: default +spec: + internalTrafficPolicy: Cluster + ipFamilies: + - IPv4 + ipFamilyPolicy: SingleStack + ports: + - name: https + port: 443 + protocol: TCP + targetPort: 8443 + sessionAffinity: None + type: ClusterIP diff --git a/docs/transform-scenarios/wordpress-demo/transform/50_CustomLabelsAndNamespace/resources/Service__v1_default_wordpress-mysql.yaml b/docs/transform-scenarios/wordpress-demo/transform/50_CustomLabelsAndNamespace/resources/Service__v1_default_wordpress-mysql.yaml new file mode 100644 index 00000000..a3911b15 --- /dev/null +++ b/docs/transform-scenarios/wordpress-demo/transform/50_CustomLabelsAndNamespace/resources/Service__v1_default_wordpress-mysql.yaml @@ -0,0 +1,21 @@ +apiVersion: v1 +kind: Service +metadata: + labels: + app: wordpress + name: wordpress-mysql + namespace: default +spec: + internalTrafficPolicy: Cluster + ipFamilies: + - IPv4 + ipFamilyPolicy: SingleStack + ports: + - port: 3306 + protocol: TCP + targetPort: 3306 + selector: + app: wordpress + tier: mysql + sessionAffinity: None + type: ClusterIP diff --git a/docs/transform-scenarios/wordpress-demo/transform/50_CustomLabelsAndNamespace/resources/Service__v1_default_wordpress.yaml b/docs/transform-scenarios/wordpress-demo/transform/50_CustomLabelsAndNamespace/resources/Service__v1_default_wordpress.yaml new file mode 100644 index 00000000..3c3f9941 --- /dev/null +++ b/docs/transform-scenarios/wordpress-demo/transform/50_CustomLabelsAndNamespace/resources/Service__v1_default_wordpress.yaml @@ -0,0 +1,23 @@ +apiVersion: v1 +kind: Service +metadata: + labels: + app: wordpress + name: wordpress + namespace: default +spec: + allocateLoadBalancerNodePorts: true + externalTrafficPolicy: Cluster + internalTrafficPolicy: Cluster + ipFamilies: + - IPv4 + ipFamilyPolicy: SingleStack + ports: + - port: 80 + protocol: TCP + targetPort: 80 + selector: + app: wordpress + tier: frontend + sessionAffinity: None + type: LoadBalancer diff --git a/docs/transform.md b/docs/transform.md index 07eaee8a..5794556d 100644 --- a/docs/transform.md +++ b/docs/transform.md @@ -1,6 +1,8 @@ -# Crane Transform Directory Structure +# Crane Transform - CLI Reference -This document explains the structure of the `transform/` directory created by Crane's multi-stage Kustomize pipeline. +This document provides a technical reference for the `transform/` directory structure and CLI options. + +> ** Looking for tutorials?** See the [Transform Scenarios & Tutorials](./transform-scenarios/README.md) for comprehensive guides and examples. ## Quick Start @@ -9,266 +11,36 @@ After running `crane transform`, you'll see: ``` transform/ └── 10_KubernetesPlugin/ - ├── resources/ - │ ├── ConfigMap__v1_default_nginx-config.yaml - │ ├── Deployment_apps_v1_default_wordpress.yaml - │ └── Service__v1_default_kubernetes.yaml - ├── patches/ - │ └── default--apps-v1--Deployment--wordpress.patch.yaml - └── kustomization.yaml + ├── resources/ # Kubernetes manifests + ├── patches/ # JSONPatch operations + └── kustomization.yaml # Kustomize configuration ``` -### What's in Each Directory? - -- **`resources/`**: Individual Kubernetes manifest files, one per resource -- **`patches/`**: Kustomize patches to apply to resources -- **`kustomization.yaml`**: Kustomize configuration file - -## Working with Transform Output - -### Viewing Final Resources - -To see what will be deployed: - +**Preview output:** ```bash kubectl kustomize transform/10_KubernetesPlugin/ ``` -### Applying to Cluster - +**Apply to cluster:** ```bash -# Option 1: Use crane apply -crane apply --transform-dir transform --output-dir output +crane apply kubectl apply -f output/output.yaml - -# Option 2: Direct apply -kubectl apply -k transform/10_KubernetesPlugin/ -``` - -### Making Manual Changes - -You can edit resources in the `resources/` directory: - -```bash -# Edit a deployment -vi transform/10_KubernetesPlugin/resources/Deployment_apps_v1_default_wordpress.yaml - -# Preview changes -kubectl kustomize transform/10_KubernetesPlugin/ - -# Apply changes -kubectl apply -k transform/10_KubernetesPlugin/ -``` - -**Important**: -- **Plugin stages** (ending with `Plugin`): Automatically regenerate on rerun - your manual edits will be overwritten -- **Custom stages** (not ending with `Plugin`): Refuse to overwrite without `--force` flag to protect your edits - -## Multi-Stage Pipelines - -For complex transformations, you can create multiple stages: - -``` -transform/ -├── 10_KubernetesPlugin/ # Base Kubernetes transformations -├── 20_OpenshiftPlugin/ # OpenShift-specific changes -└── 30_ImagestreamPlugin/ # ImageStream configurations -``` - -**Sequential Consistency**: Each stage runs on the **fully applied output** of the previous stage. This means: - -- Stage 1 reads from the export directory -- Stage 1's patches are applied, producing materialized output -- Stage 2 reads Stage 1's applied output (not the raw patches) -- Stage 2's patches are applied to the already-transformed resources -- And so on... - -This ensures that: -- Structural changes from earlier stages are visible to later stages -- Resources marked as whiteout (deleted) don't appear in subsequent stages -- Each stage sees the actual state of resources, not just patch instructions - -### Working Directory Structure - -When running multistage transforms, Crane creates a working directory structure for debugging: - -```text -transform/ -├── 10_KubernetesPlugin/ # Stage 1 transform artifacts -│ ├── resources/ -│ ├── patches/ -│ └── kustomization.yaml -├── 20_OpenshiftPlugin/ # Stage 2 transform artifacts -│ ├── resources/ -│ ├── patches/ -│ └── kustomization.yaml -└── .work/ # Intermediate working artifacts - ├── 10_KubernetesPlugin/ - │ ├── input/ # Stage 1 input snapshot (from export) - │ └── output/ # Stage 1 materialized output - └── 20_OpenshiftPlugin/ - ├── input/ # Stage 2 input snapshot (Stage 1 output) - └── output/ # Stage 2 materialized output -``` - -The `.work/` directory contains intermediate snapshots useful for debugging multi-stage pipelines. - -**Important**: The `.work/` directory contains intermediate snapshots that are regenerated on each transform run. These are useful for debugging but should not be committed to version control. Add to your `.gitignore`: - -```gitignore -# Crane intermediate artifacts (regenerated on each run) -transform/.work/ -``` - -### Running Multi-Stage Transforms - -```bash -# Default: discover and run all existing stages -# If no stages exist, creates default 10_KubernetesPlugin stage -crane transform - -# Run specific stage only (creates it if doesn't exist) -crane transform --stage 10_KubernetesPlugin - -# Create a new plugin-based stage automatically -# Stage name ending with "Plugin" will use that plugin -crane transform --stage 35_OpenshiftPlugin - -# Create a new pass-through stage for manual editing -# Stage name NOT ending with "Plugin" creates empty pass-through -crane transform --stage 40_CustomManualEdits -``` - -### Applying Transforms - -```bash -# Apply all stages sequentially -crane apply --transform-dir transform --output-dir output -``` - -**Note**: The default behavior applies **all stages** sequentially to ensure each stage output is properly materialized. This maintains sequential consistency across the entire pipeline. - -#### Output Structure - -`crane apply` creates the following output structure: - ``` -output/ -├── output.yaml # Single file with all resources -└── resources/ # Individual resource files - ├── default/ # Organized by namespace - │ ├── Deployment_apps_v1_default_myapp.yaml - │ ├── Service__v1_default_myapp.yaml - │ └── ConfigMap__v1_default_config.yaml - └── kube-system/ - └── Service__v1_kube-system_metrics.yaml -``` - -- **`output.yaml`**: All resources in a single multi-document YAML file (ready for `kubectl apply -f`) -- **`resources//`**: Individual resource files organized by namespace for easier review and selective application - -## Automatic Stage Creation - -Crane automatically creates new stages when you reference them with `--stage`. The stage name determines whether a plugin will be used or if it's a pass-through stage for manual editing. -### Stage Naming Convention - -Stage names follow the pattern `_`: - -**Plugin-based stages (name ends with "Plugin"):** -- `10_KubernetesPlugin` → uses plugin "KubernetesPlugin" -- `20_OpenshiftPlugin` → uses plugin "OpenshiftPlugin" -- `35_CustomPlugin` → uses plugin "CustomPlugin" - -**Pass-through stages (name does NOT end with "Plugin"):** -- `30_CustomEdits` → no plugin, resources pass through unchanged -- `40_ManualChanges` → no plugin, ready for manual editing -- `50_Tweaks` → no plugin, resources unchanged - -### Plugin-Based Stages - -Stage names ending with `Plugin` **must** have a corresponding plugin installed. Crane extracts the plugin name and runs it: - -```bash -# Creates a stage using OpenshiftPlugin -crane transform --stage 20_OpenshiftPlugin - -# Output: -# - resources/ (from previous stage or export) -# - patches/ (generated by OpenshiftPlugin) -# - kustomization.yaml -``` - -**If the plugin doesn't exist, you'll get an error:** - -```bash -crane transform --stage 20_NonexistentPlugin -# Error: stage 20_NonexistentPlugin requires plugin 'NonexistentPlugin' -# but it was not found (available plugins: KubernetesPlugin, NamespaceCleanup) -``` - -### Pass-Through Stages - -Stage names **not** ending with `Plugin` create pass-through stages where resources are copied unchanged, ready for manual editing: - -```bash -# Creates a pass-through stage for manual editing -crane transform --stage 30_CustomEdits - -# Output: -# - resources/ (copied unchanged from previous stage) -# - patches/ (empty - ready for your custom patches) -# - kustomization.yaml -``` - -You can then manually add custom patches: - -```bash -# Add custom patch -cat > transform/30_CustomEdits/patches/add-labels.yaml <-------.patch.yaml` -Contains Kustomize patches for modifying resources: - -- **Naming**: `-------.patch.yaml` -- **Format**: JSON patch -- **Purpose**: Apply plugin transformations - -Example patch (`default--apps-v1--Deployment--wordpress.patch.yaml`): - +Example (`default--apps-v1--Deployment--wordpress.patch.yaml`): ```yaml - op: remove path: /metadata/uid @@ -279,282 +51,255 @@ Example patch (`default--apps-v1--Deployment--wordpress.patch.yaml`): ``` ### kustomization.yaml - -Kustomize configuration that ties everything together: +Ties resources and patches together: ```yaml apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization +resources: +- resources/Deployment_apps_v1_default_wordpress.yaml +- resources/Service__v1_default_wordpress.yaml patches: - path: patches/default--apps-v1--Deployment--wordpress.patch.yaml target: group: apps + version: v1 kind: Deployment name: wordpress namespace: default - version: v1 -resources: -- resources/ConfigMap__v1_default_nginx-config.yaml -- resources/Deployment_apps_v1_default_wordpress.yaml -- resources/Service__v1_default_kubernetes.yaml - -# Whiteout resources are written to resources/ for complete snapshot -# but excluded from active resources list above: -# - resources/Pod__v1_default_wordpress-74b89cc84c-nm9f8.yaml ``` +## Multi-Stage Pipelines -## Common Workflows +Create multiple transformation stages: -### 1. Review Transformations +``` +transform/ +├── 10_KubernetesPlugin/ # Base cleanup +├── 20_OpenshiftPlugin/ # Platform conversion +└── 50_CustomEdits/ # Manual customization +``` -```bash -# View all resources after transformation -kubectl kustomize transform/10_KubernetesPlugin/ +**Sequential Consistency**: Each stage processes the **fully materialized output** of the previous stage. -# View specific resource type -kubectl kustomize transform/10_KubernetesPlugin/ | grep -A 20 "kind: Deployment" +### Working Directory Structure -# Save to file for review -kubectl kustomize transform/10_KubernetesPlugin/ > review.yaml +``` +transform/ +├── 10_KubernetesPlugin/ # Stage artifacts +│ ├── resources/ +│ ├── patches/ +│ └── kustomization.yaml +└── .work/ # Intermediate debugging artifacts + └── 10_KubernetesPlugin/ + ├── input/ # Input snapshot + └── output/ # Materialized output ``` -### 2. Customize After Transform +## Stage Types -**Note**: Plugin stages (ending with `Plugin`) will be automatically regenerated on next run, overwriting manual edits. For manual customizations, create a custom stage (not ending with `Plugin`). +### Plugin Stages +**Name ends with `Plugin`** → Runs corresponding plugin ```bash -# Create a custom stage for manual edits -crane transform --stage 40_CustomEdits - -# Edit resources -vi transform/40_CustomEdits/resources/Deployment_apps_v1_default_wordpress.yaml - -# Add custom patches -cat > transform/40_CustomEdits/patches/custom-patch.yaml < transform/50_CustomLabels/patches/add-labels.yaml <____.yaml ``` -### "kustomization.yaml validation failed" - -**Problem**: Invalid Kustomize syntax or missing files. +**Examples:** +- Core resources (no group): `Service__v1_default_myapp.yaml` +- With API group: `Deployment_apps_v1_default_myapp.yaml` +- Cluster-scoped: `Namespace__v1_clusterscoped_default.yaml` -**Solution**: -```bash -# Validate manually -kubectl kustomize transform/10_KubernetesPlugin/ +**Underscores:** +- Single `_` separates fields +- Double `__` indicates empty group (core resources) -# Check for missing files -ls -la transform/10_KubernetesPlugin/resources/ -ls -la transform/10_KubernetesPlugin/patches/ -``` +## CLI Flags Reference -### Resources Missing from Output +### transform -**Problem**: Expected resources don't appear in final output. +| Flag | Description | Default | +|------|-------------|---------| +| `--export-dir` | Export directory path | `export` | +| `--transform-dir` | Transform directory path | `transform` | +| `--plugin-dir` | Plugin directory | `~/.local/share/crane/plugins` | +| `--stage` | Run specific stage | (all stages) | +| `--force` | Force overwrite custom stages | `false` | +| `--skip-plugins` | Comma-separated plugin list to skip | - | +| `--optional-flags` | JSON string of plugin-specific flags | - | -**Solution**: -```bash -# Check input snapshot to see what was loaded -ls -la transform/.work/10_KubernetesPlugin/input/ +### apply -# Compare input vs output to see what was filtered -diff -r transform/.work/10_KubernetesPlugin/input/ transform/.work/10_KubernetesPlugin/output/ +| Flag | Description | Default | +|------|-------------|---------| +| `--transform-dir` | Transform directory path | `transform` | +| `--output-dir` | Output directory path | `output` | -# Review plugin logs for whiteout/filtering -crane transform --debug -``` +## Advanced: Kustomize Features -## Advanced: Creating Custom Kustomizations +Custom stages can use full Kustomize features: -You can extend generated kustomizations: +**commonLabels:** +```yaml +commonLabels: + environment: production + migrated-with: crane +``` -### Add ConfigMap Generator +**namespace:** +```yaml +namespace: production +``` +**replicas:** ```yaml -# Edit kustomization.yaml -apiVersion: kustomize.config.k8s.io/v1beta1 -kind: Kustomization -resources: -- resources/Deployment_apps_v1_default_wordpress.yaml +replicas: +- name: myapp + count: 5 +``` +**configMapGenerator:** +```yaml configMapGenerator: - name: app-config literals: - - DATABASE_URL=postgres://localhost + - DATABASE_URL=postgres://db/mydb + - LOG_LEVEL=info ``` -### Add Common Labels +See [Kustomize Documentation](https://kubectl.docs.kubernetes.io/references/kustomize/) for all features. -```yaml -apiVersion: kustomize.config.k8s.io/v1beta1 -kind: Kustomization -resources: -- resources/Deployment_apps_v1_default_wordpress.yaml +## Troubleshooting -commonLabels: - app: myapp - environment: production +**Stage not empty error:** +```bash +# Custom stages are protected - use force to overwrite +crane transform --force ``` -### Add Namespace +**Resources missing:** +```bash +# Check kustomization.yaml resources list +cat transform/10_KubernetesPlugin/kustomization.yaml | grep -A 100 "resources:" +``` -```yaml -apiVersion: kustomize.config.k8s.io/v1beta1 -kind: Kustomization -namespace: production +**Kustomize validation error:** +```bash +# Validate manually +kubectl kustomize transform/10_KubernetesPlugin/ +``` -resources: -- resources/Deployment_apps_v1_default_wordpress.yaml +**Debug multi-stage:** +```bash +# Check intermediate outputs +ls transform/.work/10_KubernetesPlugin/output/ +diff -r transform/.work/10_KubernetesPlugin/output/ \ + transform/.work/20_OpenshiftPlugin/input/ ``` -## Further Help +## Further Reading -- [Multi-Stage Kustomize Documentation](./kustomize-multistage.md) -- [Kustomize Official Docs](https://kubectl.docs.kubernetes.io/references/kustomize/) -- [Crane GitHub Issues](https://github.com/konveyor/crane/issues) +- **[Transform Scenarios & Tutorials](./transform-scenarios/README.md)** - Comprehensive guides and examples +- **[Multi-Stage Kustomize](./kustomize-multistage.md)** - Technical deep-dive into architecture +- **[Kustomize Official Docs](https://kubectl.docs.kubernetes.io/references/kustomize/)** - Learn Kustomize features +- **[Crane README](../README.md)** - Project overview and installation From b53e2565959c54f9f677f2b622c433fce4f0a336 Mon Sep 17 00:00:00 2001 From: Marek Aufart Date: Fri, 24 Apr 2026 15:44:22 +0200 Subject: [PATCH 2/2] Add image modification to kustomize example Signed-off-by: Marek Aufart --- docs/transform-scenarios/03-multistage.md | 13 +++++++++++-- .../wordpress-demo/output/output.yaml | 2 +- ...s_v1_new-migrated-namespace_wordpress-mysql.yaml | 2 +- .../50_CustomLabelsAndNamespace/kustomization.yaml | 6 +++++- 4 files changed, 18 insertions(+), 5 deletions(-) diff --git a/docs/transform-scenarios/03-multistage.md b/docs/transform-scenarios/03-multistage.md index 35267a94..22ee9406 100644 --- a/docs/transform-scenarios/03-multistage.md +++ b/docs/transform-scenarios/03-multistage.md @@ -116,18 +116,27 @@ transform/50_CustomLabels/ **Important:** The `resources/` in stage 50 contains the **cleaned output** from previous stage (stage 10 in this example), not the raw export! -### Step 4: Add Custom Labels and Namespace +### Step 4: Add Custom Labels, Namespace, and Images -Edit `kustomization.yaml` to add common labels and set target namespace: +Edit `kustomization.yaml` to add common labels, set target namespace, and update container images: ```bash cat >> transform/50_CustomLabels/kustomization.yaml <