kuberoku 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (232) hide show
  1. kuberoku-0.1.0/.editorconfig +15 -0
  2. kuberoku-0.1.0/.github/ISSUE_TEMPLATE/bug_report.yml +32 -0
  3. kuberoku-0.1.0/.github/ISSUE_TEMPLATE/feature_request.yml +17 -0
  4. kuberoku-0.1.0/.github/workflows/compat.yml +37 -0
  5. kuberoku-0.1.0/.github/workflows/release.yml +226 -0
  6. kuberoku-0.1.0/.github/workflows/tests.yml +144 -0
  7. kuberoku-0.1.0/.gitignore +35 -0
  8. kuberoku-0.1.0/CHANGELOG.md +22 -0
  9. kuberoku-0.1.0/CLAUDE.md +98 -0
  10. kuberoku-0.1.0/CODEOWNERS +2 -0
  11. kuberoku-0.1.0/CONTRIBUTING.md +147 -0
  12. kuberoku-0.1.0/LICENSE +190 -0
  13. kuberoku-0.1.0/PKG-INFO +326 -0
  14. kuberoku-0.1.0/README.md +289 -0
  15. kuberoku-0.1.0/SECURITY.md +34 -0
  16. kuberoku-0.1.0/docs/NORTHSTAR.txt +8751 -0
  17. kuberoku-0.1.0/docs/PROGRESS.md +389 -0
  18. kuberoku-0.1.0/kuberoku.spec +78 -0
  19. kuberoku-0.1.0/pyproject.toml +98 -0
  20. kuberoku-0.1.0/scripts/_common.sh +62 -0
  21. kuberoku-0.1.0/scripts/act-local.sh +36 -0
  22. kuberoku-0.1.0/scripts/dev-setup.sh +129 -0
  23. kuberoku-0.1.0/scripts/install.ps1 +72 -0
  24. kuberoku-0.1.0/scripts/install.sh +170 -0
  25. kuberoku-0.1.0/scripts/lint.sh +49 -0
  26. kuberoku-0.1.0/scripts/secure.sh +41 -0
  27. kuberoku-0.1.0/scripts/test-install.sh +179 -0
  28. kuberoku-0.1.0/scripts/test.sh +86 -0
  29. kuberoku-0.1.0/src/kuberoku/__init__.py +6 -0
  30. kuberoku-0.1.0/src/kuberoku/__main__.py +5 -0
  31. kuberoku-0.1.0/src/kuberoku/_version.py +1 -0
  32. kuberoku-0.1.0/src/kuberoku/addons/__init__.py +78 -0
  33. kuberoku-0.1.0/src/kuberoku/addons/_types.py +46 -0
  34. kuberoku-0.1.0/src/kuberoku/addons/postgres.py +95 -0
  35. kuberoku-0.1.0/src/kuberoku/addons/redis.py +52 -0
  36. kuberoku-0.1.0/src/kuberoku/branding.py +43 -0
  37. kuberoku-0.1.0/src/kuberoku/cli/__init__.py +0 -0
  38. kuberoku-0.1.0/src/kuberoku/cli/addons.py +473 -0
  39. kuberoku-0.1.0/src/kuberoku/cli/apps.py +282 -0
  40. kuberoku-0.1.0/src/kuberoku/cli/clusters.py +238 -0
  41. kuberoku-0.1.0/src/kuberoku/cli/config.py +155 -0
  42. kuberoku-0.1.0/src/kuberoku/cli/context.py +88 -0
  43. kuberoku-0.1.0/src/kuberoku/cli/deploy.py +77 -0
  44. kuberoku-0.1.0/src/kuberoku/cli/domains.py +147 -0
  45. kuberoku-0.1.0/src/kuberoku/cli/main.py +101 -0
  46. kuberoku-0.1.0/src/kuberoku/cli/output.py +92 -0
  47. kuberoku-0.1.0/src/kuberoku/cli/plugins.py +81 -0
  48. kuberoku-0.1.0/src/kuberoku/cli/ps.py +216 -0
  49. kuberoku-0.1.0/src/kuberoku/cli/releases.py +91 -0
  50. kuberoku-0.1.0/src/kuberoku/cli/services.py +475 -0
  51. kuberoku-0.1.0/src/kuberoku/client.py +97 -0
  52. kuberoku-0.1.0/src/kuberoku/config/__init__.py +0 -0
  53. kuberoku-0.1.0/src/kuberoku/config/project.py +196 -0
  54. kuberoku-0.1.0/src/kuberoku/config/user.py +179 -0
  55. kuberoku-0.1.0/src/kuberoku/exceptions.py +365 -0
  56. kuberoku-0.1.0/src/kuberoku/factory.py +246 -0
  57. kuberoku-0.1.0/src/kuberoku/k8s/__init__.py +0 -0
  58. kuberoku-0.1.0/src/kuberoku/k8s/client.py +598 -0
  59. kuberoku-0.1.0/src/kuberoku/k8s/labels.py +52 -0
  60. kuberoku-0.1.0/src/kuberoku/k8s/protocols.py +233 -0
  61. kuberoku-0.1.0/src/kuberoku/k8s/resources.py +669 -0
  62. kuberoku-0.1.0/src/kuberoku/models.py +293 -0
  63. kuberoku-0.1.0/src/kuberoku/plugins/__init__.py +5 -0
  64. kuberoku-0.1.0/src/kuberoku/plugins/loader.py +79 -0
  65. kuberoku-0.1.0/src/kuberoku/py.typed +0 -0
  66. kuberoku-0.1.0/src/kuberoku/sdk/__init__.py +0 -0
  67. kuberoku-0.1.0/src/kuberoku/sdk/addons.py +1645 -0
  68. kuberoku-0.1.0/src/kuberoku/sdk/apps.py +700 -0
  69. kuberoku-0.1.0/src/kuberoku/sdk/build.py +193 -0
  70. kuberoku-0.1.0/src/kuberoku/sdk/checks.py +837 -0
  71. kuberoku-0.1.0/src/kuberoku/sdk/clusters.py +186 -0
  72. kuberoku-0.1.0/src/kuberoku/sdk/config.py +462 -0
  73. kuberoku-0.1.0/src/kuberoku/sdk/deploy.py +566 -0
  74. kuberoku-0.1.0/src/kuberoku/sdk/doctor.py +78 -0
  75. kuberoku-0.1.0/src/kuberoku/sdk/domains.py +438 -0
  76. kuberoku-0.1.0/src/kuberoku/sdk/gateway.py +332 -0
  77. kuberoku-0.1.0/src/kuberoku/sdk/ingress.py +167 -0
  78. kuberoku-0.1.0/src/kuberoku/sdk/plugins.py +155 -0
  79. kuberoku-0.1.0/src/kuberoku/sdk/procfile.py +34 -0
  80. kuberoku-0.1.0/src/kuberoku/sdk/ps.py +476 -0
  81. kuberoku-0.1.0/src/kuberoku/sdk/rbac.py +252 -0
  82. kuberoku-0.1.0/src/kuberoku/sdk/registry.py +136 -0
  83. kuberoku-0.1.0/src/kuberoku/sdk/releases.py +323 -0
  84. kuberoku-0.1.0/src/kuberoku/sdk/services.py +1144 -0
  85. kuberoku-0.1.0/tests/__init__.py +0 -0
  86. kuberoku-0.1.0/tests/addons/__init__.py +0 -0
  87. kuberoku-0.1.0/tests/addons/test_cli_addons.py +138 -0
  88. kuberoku-0.1.0/tests/addons/test_connect.py +37 -0
  89. kuberoku-0.1.0/tests/addons/test_create.py +144 -0
  90. kuberoku-0.1.0/tests/addons/test_credentials.py +38 -0
  91. kuberoku-0.1.0/tests/addons/test_destroy.py +100 -0
  92. kuberoku-0.1.0/tests/addons/test_ephemeral.py +34 -0
  93. kuberoku-0.1.0/tests/addons/test_expose.py +152 -0
  94. kuberoku-0.1.0/tests/addons/test_expose_gateway.py +170 -0
  95. kuberoku-0.1.0/tests/addons/test_external.py +29 -0
  96. kuberoku-0.1.0/tests/addons/test_info.py +30 -0
  97. kuberoku-0.1.0/tests/addons/test_list.py +42 -0
  98. kuberoku-0.1.0/tests/addons/test_multi_instance.py +85 -0
  99. kuberoku-0.1.0/tests/addons/test_upgrade.py +29 -0
  100. kuberoku-0.1.0/tests/addons/test_versioning.py +409 -0
  101. kuberoku-0.1.0/tests/apps/__init__.py +0 -0
  102. kuberoku-0.1.0/tests/apps/conftest.py +14 -0
  103. kuberoku-0.1.0/tests/apps/test_create.py +153 -0
  104. kuberoku-0.1.0/tests/apps/test_destroy.py +200 -0
  105. kuberoku-0.1.0/tests/apps/test_info.py +106 -0
  106. kuberoku-0.1.0/tests/apps/test_link.py +245 -0
  107. kuberoku-0.1.0/tests/apps/test_list.py +62 -0
  108. kuberoku-0.1.0/tests/apps/test_maintenance.py +158 -0
  109. kuberoku-0.1.0/tests/apps/test_rename.py +169 -0
  110. kuberoku-0.1.0/tests/apps/test_status.py +140 -0
  111. kuberoku-0.1.0/tests/backends/__init__.py +0 -0
  112. kuberoku-0.1.0/tests/backends/fake.py +551 -0
  113. kuberoku-0.1.0/tests/backends/real.py +387 -0
  114. kuberoku-0.1.0/tests/clusters/__init__.py +0 -0
  115. kuberoku-0.1.0/tests/clusters/test_checks.py +290 -0
  116. kuberoku-0.1.0/tests/clusters/test_checks_phase9.py +154 -0
  117. kuberoku-0.1.0/tests/clusters/test_cli_clusters.py +359 -0
  118. kuberoku-0.1.0/tests/clusters/test_clusters.py +231 -0
  119. kuberoku-0.1.0/tests/config/__init__.py +0 -0
  120. kuberoku-0.1.0/tests/config/conftest.py +24 -0
  121. kuberoku-0.1.0/tests/config/test_get.py +110 -0
  122. kuberoku-0.1.0/tests/config/test_list.py +194 -0
  123. kuberoku-0.1.0/tests/config/test_set.py +289 -0
  124. kuberoku-0.1.0/tests/config/test_unset.py +141 -0
  125. kuberoku-0.1.0/tests/conftest.py +324 -0
  126. kuberoku-0.1.0/tests/contract/__init__.py +0 -0
  127. kuberoku-0.1.0/tests/contract/conftest.py +46 -0
  128. kuberoku-0.1.0/tests/contract/test_configmap_crud.py +124 -0
  129. kuberoku-0.1.0/tests/contract/test_deployment_crud.py +123 -0
  130. kuberoku-0.1.0/tests/contract/test_ingress_crud.py +196 -0
  131. kuberoku-0.1.0/tests/contract/test_namespace_crud.py +48 -0
  132. kuberoku-0.1.0/tests/contract/test_network_policy_crud.py +156 -0
  133. kuberoku-0.1.0/tests/contract/test_pvc_crud.py +85 -0
  134. kuberoku-0.1.0/tests/contract/test_secret_crud.py +111 -0
  135. kuberoku-0.1.0/tests/contract/test_service_crud.py +90 -0
  136. kuberoku-0.1.0/tests/contract/test_statefulset_crud.py +100 -0
  137. kuberoku-0.1.0/tests/deploy/__init__.py +0 -0
  138. kuberoku-0.1.0/tests/deploy/test_auto_domain_deploy.py +163 -0
  139. kuberoku-0.1.0/tests/deploy/test_build.py +230 -0
  140. kuberoku-0.1.0/tests/deploy/test_deploy_retry.py +85 -0
  141. kuberoku-0.1.0/tests/deploy/test_image.py +235 -0
  142. kuberoku-0.1.0/tests/deploy/test_multi_app.py +354 -0
  143. kuberoku-0.1.0/tests/deploy/test_procfile_deploy.py +101 -0
  144. kuberoku-0.1.0/tests/deploy/test_release_create.py +159 -0
  145. kuberoku-0.1.0/tests/deploy/test_releases_list.py +57 -0
  146. kuberoku-0.1.0/tests/deploy/test_releases_prune.py +44 -0
  147. kuberoku-0.1.0/tests/deploy/test_rollback.py +72 -0
  148. kuberoku-0.1.0/tests/deploy/test_wait.py +128 -0
  149. kuberoku-0.1.0/tests/domains/__init__.py +0 -0
  150. kuberoku-0.1.0/tests/domains/conftest.py +117 -0
  151. kuberoku-0.1.0/tests/domains/test_add.py +363 -0
  152. kuberoku-0.1.0/tests/domains/test_auto_domain.py +149 -0
  153. kuberoku-0.1.0/tests/domains/test_clear.py +50 -0
  154. kuberoku-0.1.0/tests/domains/test_cli_domains.py +316 -0
  155. kuberoku-0.1.0/tests/domains/test_list.py +42 -0
  156. kuberoku-0.1.0/tests/domains/test_remove.py +134 -0
  157. kuberoku-0.1.0/tests/e2e/__init__.py +0 -0
  158. kuberoku-0.1.0/tests/e2e/conftest.py +47 -0
  159. kuberoku-0.1.0/tests/e2e/helpers.py +476 -0
  160. kuberoku-0.1.0/tests/e2e/test_addon_lifecycle.py +786 -0
  161. kuberoku-0.1.0/tests/e2e/test_addon_versioning.py +522 -0
  162. kuberoku-0.1.0/tests/e2e/test_apps_rename.py +96 -0
  163. kuberoku-0.1.0/tests/e2e/test_clusters_config.py +115 -0
  164. kuberoku-0.1.0/tests/e2e/test_config_lifecycle.py +243 -0
  165. kuberoku-0.1.0/tests/e2e/test_doctor_setup.py +200 -0
  166. kuberoku-0.1.0/tests/e2e/test_domains_lifecycle.py +202 -0
  167. kuberoku-0.1.0/tests/e2e/test_expose_connect.py +283 -0
  168. kuberoku-0.1.0/tests/e2e/test_git_deploy.py +399 -0
  169. kuberoku-0.1.0/tests/e2e/test_hello_world.py +353 -0
  170. kuberoku-0.1.0/tests/e2e/test_link_lifecycle.py +116 -0
  171. kuberoku-0.1.0/tests/e2e/test_maintenance_lifecycle.py +350 -0
  172. kuberoku-0.1.0/tests/e2e/test_multi_port.py +119 -0
  173. kuberoku-0.1.0/tests/e2e/test_network_isolation.py +189 -0
  174. kuberoku-0.1.0/tests/e2e/test_plugins.py +85 -0
  175. kuberoku-0.1.0/tests/e2e/test_releases_prune.py +102 -0
  176. kuberoku-0.1.0/tests/e2e/test_services_logs_exec.py +277 -0
  177. kuberoku-0.1.0/tests/infrastructure/__init__.py +0 -0
  178. kuberoku-0.1.0/tests/infrastructure/test_addon_types.py +118 -0
  179. kuberoku-0.1.0/tests/infrastructure/test_branding.py +46 -0
  180. kuberoku-0.1.0/tests/infrastructure/test_cli_logs_exec.py +292 -0
  181. kuberoku-0.1.0/tests/infrastructure/test_cli_networking.py +226 -0
  182. kuberoku-0.1.0/tests/infrastructure/test_cli_phase4.py +311 -0
  183. kuberoku-0.1.0/tests/infrastructure/test_client.py +54 -0
  184. kuberoku-0.1.0/tests/infrastructure/test_colon_commands.py +36 -0
  185. kuberoku-0.1.0/tests/infrastructure/test_context.py +144 -0
  186. kuberoku-0.1.0/tests/infrastructure/test_doctor.py +372 -0
  187. kuberoku-0.1.0/tests/infrastructure/test_duration.py +51 -0
  188. kuberoku-0.1.0/tests/infrastructure/test_error_boundary.py +91 -0
  189. kuberoku-0.1.0/tests/infrastructure/test_exceptions.py +269 -0
  190. kuberoku-0.1.0/tests/infrastructure/test_factory.py +105 -0
  191. kuberoku-0.1.0/tests/infrastructure/test_gateway.py +256 -0
  192. kuberoku-0.1.0/tests/infrastructure/test_idempotent_cleanup.py +609 -0
  193. kuberoku-0.1.0/tests/infrastructure/test_ingress_detection.py +353 -0
  194. kuberoku-0.1.0/tests/infrastructure/test_k8s_client.py +487 -0
  195. kuberoku-0.1.0/tests/infrastructure/test_labels.py +62 -0
  196. kuberoku-0.1.0/tests/infrastructure/test_models.py +269 -0
  197. kuberoku-0.1.0/tests/infrastructure/test_networking_resources.py +132 -0
  198. kuberoku-0.1.0/tests/infrastructure/test_output.py +33 -0
  199. kuberoku-0.1.0/tests/infrastructure/test_port_parsing.py +49 -0
  200. kuberoku-0.1.0/tests/infrastructure/test_procfile.py +73 -0
  201. kuberoku-0.1.0/tests/infrastructure/test_rbac.py +335 -0
  202. kuberoku-0.1.0/tests/infrastructure/test_registry.py +262 -0
  203. kuberoku-0.1.0/tests/infrastructure/test_resources.py +382 -0
  204. kuberoku-0.1.0/tests/infrastructure/test_user_config.py +203 -0
  205. kuberoku-0.1.0/tests/plugins/__init__.py +0 -0
  206. kuberoku-0.1.0/tests/plugins/test_cli_plugins.py +121 -0
  207. kuberoku-0.1.0/tests/plugins/test_loader.py +195 -0
  208. kuberoku-0.1.0/tests/plugins/test_plugins_service.py +195 -0
  209. kuberoku-0.1.0/tests/ps/__init__.py +0 -0
  210. kuberoku-0.1.0/tests/ps/conftest.py +39 -0
  211. kuberoku-0.1.0/tests/ps/test_commands.py +23 -0
  212. kuberoku-0.1.0/tests/ps/test_list.py +52 -0
  213. kuberoku-0.1.0/tests/ps/test_restart.py +82 -0
  214. kuberoku-0.1.0/tests/ps/test_scale.py +48 -0
  215. kuberoku-0.1.0/tests/ps/test_set.py +82 -0
  216. kuberoku-0.1.0/tests/ps/test_stop.py +20 -0
  217. kuberoku-0.1.0/tests/ps/test_type.py +83 -0
  218. kuberoku-0.1.0/tests/services/__init__.py +0 -0
  219. kuberoku-0.1.0/tests/services/conftest.py +121 -0
  220. kuberoku-0.1.0/tests/services/test_connect.py +57 -0
  221. kuberoku-0.1.0/tests/services/test_exec.py +182 -0
  222. kuberoku-0.1.0/tests/services/test_expose.py +88 -0
  223. kuberoku-0.1.0/tests/services/test_expose_gateway.py +178 -0
  224. kuberoku-0.1.0/tests/services/test_logs.py +140 -0
  225. kuberoku-0.1.0/tests/services/test_logs_follow.py +145 -0
  226. kuberoku-0.1.0/tests/services/test_maintenance.py +148 -0
  227. kuberoku-0.1.0/tests/services/test_name_resolution.py +44 -0
  228. kuberoku-0.1.0/tests/services/test_open.py +192 -0
  229. kuberoku-0.1.0/tests/services/test_ports_add.py +141 -0
  230. kuberoku-0.1.0/tests/services/test_ports_list.py +52 -0
  231. kuberoku-0.1.0/tests/services/test_ports_remove.py +173 -0
  232. kuberoku-0.1.0/tests/services/test_unexpose.py +103 -0
@@ -0,0 +1,15 @@
1
+ root = true
2
+
3
+ [*]
4
+ charset = utf-8
5
+ end_of_line = lf
6
+ insert_final_newline = true
7
+ trim_trailing_whitespace = true
8
+ indent_style = space
9
+ indent_size = 4
10
+
11
+ [*.{yml,yaml,toml}]
12
+ indent_size = 2
13
+
14
+ [Makefile]
15
+ indent_style = tab
@@ -0,0 +1,32 @@
1
+ name: Bug Report
2
+ description: Something isn't working as expected.
3
+ labels: ["bug"]
4
+ body:
5
+ - type: textarea
6
+ id: what-happened
7
+ attributes:
8
+ label: What happened?
9
+ description: Describe the bug. What did you expect vs. what actually happened?
10
+ validations:
11
+ required: true
12
+
13
+ - type: textarea
14
+ id: reproduce
15
+ attributes:
16
+ label: Steps to reproduce
17
+ description: Minimal commands to reproduce the issue.
18
+ placeholder: |
19
+ kuberoku apps:create myapp
20
+ kuberoku deploy --app myapp --image nginx:1.27 --port 80/tcp
21
+ # error happens here
22
+
23
+ - type: textarea
24
+ id: environment
25
+ attributes:
26
+ label: Environment
27
+ description: Paste the output of the commands below.
28
+ placeholder: |
29
+ kuberoku --version
30
+ kubectl version
31
+ python --version
32
+ uname -a
@@ -0,0 +1,17 @@
1
+ name: Feature Request
2
+ description: Suggest an idea or improvement.
3
+ labels: ["enhancement"]
4
+ body:
5
+ - type: textarea
6
+ id: description
7
+ attributes:
8
+ label: What would you like?
9
+ description: Describe the feature or improvement.
10
+ validations:
11
+ required: true
12
+
13
+ - type: textarea
14
+ id: use-case
15
+ attributes:
16
+ label: Use case
17
+ description: Why do you need this? What problem does it solve?
@@ -0,0 +1,37 @@
1
+ name: Compatibility Tests
2
+
3
+ on:
4
+ schedule:
5
+ - cron: "0 6 * * 1" # Weekly: Monday 06:00 UTC
6
+ workflow_dispatch: # Manual trigger
7
+
8
+ jobs:
9
+ compat:
10
+ name: Compat (kind) — K8s ${{ matrix.k8s-version }}
11
+ runs-on: ubuntu-latest
12
+ strategy:
13
+ fail-fast: false
14
+ matrix:
15
+ k8s-version: ["v1.33.0", "v1.34.0", "v1.35.0"]
16
+
17
+ steps:
18
+ - uses: actions/checkout@v4
19
+
20
+ - name: Set up Python
21
+ uses: actions/setup-python@v5
22
+ with:
23
+ python-version: "3.12"
24
+
25
+ - name: Create kind cluster
26
+ uses: helm/kind-action@v1
27
+ with:
28
+ cluster_name: kuberoku-compat
29
+ node_image: kindest/node:${{ matrix.k8s-version }}
30
+
31
+ - name: Install dependencies
32
+ run: |
33
+ python -m pip install --upgrade pip
34
+ pip install -e ".[dev]"
35
+
36
+ - name: All tests against real K8s (kind)
37
+ run: pytest tests/ --backend real -v
@@ -0,0 +1,226 @@
1
+ name: Release
2
+
3
+ on:
4
+ push:
5
+ tags: ["v*"]
6
+
7
+ permissions:
8
+ contents: read
9
+ actions: read
10
+
11
+ jobs:
12
+ gate:
13
+ name: Release gate — verify CI passed on this commit
14
+ runs-on: ubuntu-latest
15
+ steps:
16
+ - uses: actions/checkout@v4
17
+
18
+ - name: Verify CI passed on this commit
19
+ env:
20
+ GH_TOKEN: ${{ github.token }}
21
+ run: |
22
+ SHA=$(git rev-parse HEAD)
23
+ echo "Checking CI status for commit $SHA..."
24
+
25
+ # Wait up to 5 minutes for the Tests workflow to complete (tag push may race with CI)
26
+ for i in $(seq 1 30); do
27
+ RUN_JSON=$(gh run list --commit "$SHA" --workflow "Tests" --json status,conclusion --limit 1)
28
+ RUN_STATUS=$(echo "$RUN_JSON" | jq -r '.[0].status // "none"')
29
+ RUN_CONCLUSION=$(echo "$RUN_JSON" | jq -r '.[0].conclusion // "none"')
30
+ echo " Attempt $i: status=$RUN_STATUS conclusion=$RUN_CONCLUSION"
31
+
32
+ if [ "$RUN_STATUS" = "completed" ]; then
33
+ if [ "$RUN_CONCLUSION" = "success" ]; then
34
+ echo "Tests workflow passed."
35
+ exit 0
36
+ else
37
+ echo "::error::Tests workflow failed ($RUN_CONCLUSION). Fix tests before releasing."
38
+ exit 1
39
+ fi
40
+ fi
41
+
42
+ # not found or still running — wait and retry
43
+ sleep 10
44
+ done
45
+
46
+ echo "::error::Tests workflow did not complete within 5 minutes. Push to main first and wait for green CI."
47
+ exit 1
48
+
49
+ - name: Verify tag matches package version
50
+ run: |
51
+ TAG="${GITHUB_REF#refs/tags/v}"
52
+ PKG_VERSION=$(python3 -c "exec(open('src/kuberoku/_version.py').read()); print(__version__)")
53
+ if [ "$TAG" != "$PKG_VERSION" ]; then
54
+ echo "::error::Tag v${TAG} does not match _version.py (${PKG_VERSION})"
55
+ exit 1
56
+ fi
57
+
58
+ # ── Publish to PyPI ──────────────────────────────────────────────
59
+
60
+ publish:
61
+ name: Publish to PyPI
62
+ needs: gate
63
+ runs-on: ubuntu-latest
64
+ environment: pypi
65
+ permissions:
66
+ contents: read
67
+ id-token: write
68
+ steps:
69
+ - uses: actions/checkout@v4
70
+
71
+ - name: Set up Python
72
+ uses: actions/setup-python@v5
73
+ with:
74
+ python-version: "3.12"
75
+
76
+ - name: Install build tools
77
+ run: python -m pip install --upgrade pip build
78
+
79
+ - name: Verify tag matches package version
80
+ run: |
81
+ TAG="${GITHUB_REF#refs/tags/v}"
82
+ PKG_VERSION=$(python -c "exec(open('src/kuberoku/_version.py').read()); print(__version__)")
83
+ if [ "$TAG" != "$PKG_VERSION" ]; then
84
+ echo "::error::Tag v${TAG} does not match _version.py (${PKG_VERSION})"
85
+ exit 1
86
+ fi
87
+
88
+ - name: Build sdist and wheel
89
+ run: python -m build
90
+
91
+ - name: Publish to PyPI
92
+ uses: pypa/gh-action-pypi-publish@release/v1
93
+
94
+ # ── Native binaries (4 targets) ─────────────────────────────────
95
+
96
+ binaries:
97
+ name: Binary — ${{ matrix.os }}-${{ matrix.arch }}
98
+ needs: gate
99
+ runs-on: ${{ matrix.runner }}
100
+ strategy:
101
+ fail-fast: false
102
+ matrix:
103
+ include:
104
+ - os: linux
105
+ arch: amd64
106
+ runner: ubuntu-latest
107
+ asset: kuberoku-linux-amd64
108
+ - os: darwin
109
+ arch: arm64
110
+ runner: macos-latest
111
+ asset: kuberoku-darwin-arm64
112
+ - os: darwin
113
+ arch: amd64
114
+ runner: macos-15-intel
115
+ asset: kuberoku-darwin-amd64
116
+ - os: windows
117
+ arch: amd64
118
+ runner: windows-latest
119
+ asset: kuberoku-windows-amd64.exe
120
+
121
+ steps:
122
+ - uses: actions/checkout@v4
123
+
124
+ - name: Set up Python
125
+ uses: actions/setup-python@v5
126
+ with:
127
+ python-version: "3.12"
128
+
129
+ - name: Install dependencies
130
+ run: |
131
+ python -m pip install --upgrade pip
132
+ pip install .
133
+ pip install pyinstaller
134
+
135
+ - name: Build binary
136
+ run: pyinstaller kuberoku.spec
137
+
138
+ - name: Rename binary (unix)
139
+ if: matrix.os != 'windows'
140
+ run: mv dist/kuberoku dist/${{ matrix.asset }}
141
+
142
+ - name: Rename binary (windows)
143
+ if: matrix.os == 'windows'
144
+ shell: bash
145
+ run: mv dist/kuberoku.exe dist/${{ matrix.asset }}
146
+
147
+ - name: Smoke test
148
+ if: matrix.os != 'windows'
149
+ run: ./dist/${{ matrix.asset }} --version
150
+
151
+ - name: Smoke test (windows)
152
+ if: matrix.os == 'windows'
153
+ shell: bash
154
+ run: ./dist/${{ matrix.asset }} --version
155
+
156
+ - name: Upload artifact
157
+ uses: actions/upload-artifact@v4
158
+ with:
159
+ name: ${{ matrix.asset }}
160
+ path: dist/${{ matrix.asset }}
161
+
162
+ # ── Linux ARM64 via QEMU ────────────────────────────────────────
163
+
164
+ binary-linux-arm64:
165
+ name: Binary — linux-arm64 (QEMU)
166
+ needs: gate
167
+ runs-on: ubuntu-latest
168
+ steps:
169
+ - uses: actions/checkout@v4
170
+
171
+ - name: Set up QEMU
172
+ uses: docker/setup-qemu-action@v3
173
+
174
+ - name: Build in ARM64 container
175
+ run: |
176
+ docker run --rm --platform linux/arm64 \
177
+ -v "${{ github.workspace }}:/work" \
178
+ -w /work \
179
+ python:3.12-slim \
180
+ sh -c '
181
+ apt-get update && apt-get install -y --no-install-recommends binutils &&
182
+ pip install --upgrade pip &&
183
+ pip install . &&
184
+ pip install pyinstaller &&
185
+ pyinstaller kuberoku.spec &&
186
+ mv dist/kuberoku dist/kuberoku-linux-arm64
187
+ '
188
+
189
+ - name: Upload artifact
190
+ uses: actions/upload-artifact@v4
191
+ with:
192
+ name: kuberoku-linux-arm64
193
+ path: dist/kuberoku-linux-arm64
194
+
195
+ # ── GitHub Release ──────────────────────────────────────────────
196
+
197
+ release:
198
+ name: Create GitHub Release
199
+ needs: [publish, binaries, binary-linux-arm64]
200
+ runs-on: ubuntu-latest
201
+ permissions:
202
+ contents: write
203
+ steps:
204
+ - uses: actions/checkout@v4
205
+
206
+ - name: Download all artifacts
207
+ uses: actions/download-artifact@v4
208
+ with:
209
+ path: artifacts
210
+ merge-multiple: true
211
+
212
+ - name: List artifacts
213
+ run: ls -lhR artifacts/
214
+
215
+ - name: Create release
216
+ uses: softprops/action-gh-release@v2
217
+ with:
218
+ generate_release_notes: true
219
+ files: |
220
+ artifacts/kuberoku-linux-amd64
221
+ artifacts/kuberoku-linux-arm64
222
+ artifacts/kuberoku-darwin-amd64
223
+ artifacts/kuberoku-darwin-arm64
224
+ artifacts/kuberoku-windows-amd64.exe
225
+ scripts/install.sh
226
+ scripts/install.ps1
@@ -0,0 +1,144 @@
1
+ name: Tests
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+ branches: [main]
8
+
9
+ jobs:
10
+ lint:
11
+ name: Lint & Type Check
12
+ runs-on: ubuntu-latest
13
+ steps:
14
+ - uses: actions/checkout@v4
15
+
16
+ - name: Set up Python
17
+ uses: actions/setup-python@v5
18
+ with:
19
+ python-version: "3.12"
20
+
21
+ - name: Install dependencies
22
+ run: |
23
+ python -m pip install --upgrade pip
24
+ pip install -e ".[dev]"
25
+
26
+ - name: Lint
27
+ run: ruff check src/ tests/
28
+
29
+ - name: Format check
30
+ run: ruff format --check src/ tests/
31
+
32
+ - name: Type check
33
+ run: mypy --strict src/kuberoku/
34
+
35
+ fake:
36
+ name: Tests (fake) — Python ${{ matrix.python-version }}
37
+ runs-on: ubuntu-latest
38
+ needs: lint
39
+ strategy:
40
+ fail-fast: false
41
+ matrix:
42
+ python-version: ["3.11", "3.12", "3.13"]
43
+
44
+ steps:
45
+ - uses: actions/checkout@v4
46
+
47
+ - name: Set up Python ${{ matrix.python-version }}
48
+ uses: actions/setup-python@v5
49
+ with:
50
+ python-version: ${{ matrix.python-version }}
51
+
52
+ - name: Install dependencies
53
+ run: |
54
+ python -m pip install --upgrade pip
55
+ pip install -e ".[dev]"
56
+
57
+ - name: Tests with coverage
58
+ run: pytest tests/ -v --backend fake -n auto --dist loadfile --cov=kuberoku --cov-report=term-missing
59
+
60
+ - name: Enforce coverage threshold
61
+ if: matrix.python-version == '3.12'
62
+ run: pytest tests/ -q --backend fake -n auto --dist loadfile --cov=kuberoku --cov-fail-under=90
63
+
64
+ integration:
65
+ name: Tests (real) — k3d K8s ${{ matrix.k8s-version }}
66
+ runs-on: ubuntu-latest
67
+ needs: lint
68
+ strategy:
69
+ fail-fast: false
70
+ matrix:
71
+ k8s-version: ["v1.33.7", "v1.34.3", "v1.35.0"]
72
+
73
+ steps:
74
+ - uses: actions/checkout@v4
75
+
76
+ - name: Set up Python
77
+ uses: actions/setup-python@v5
78
+ with:
79
+ python-version: "3.12"
80
+
81
+ - name: Configure Docker for k3d insecure registry
82
+ run: |
83
+ echo '{"insecure-registries": ["k3d-registry.localhost:5000"]}' | sudo tee /etc/docker/daemon.json
84
+ sudo systemctl restart docker
85
+
86
+ - uses: AbsaOSS/k3d-action@v2
87
+ with:
88
+ cluster-name: kuberoku-test
89
+ k3d-version: v5.8.3
90
+ args: >-
91
+ --image rancher/k3s:${{ matrix.k8s-version }}-k3s1
92
+ --registry-create k3d-registry.localhost:5000
93
+
94
+ - name: Install dependencies
95
+ run: |
96
+ python -m pip install --upgrade pip
97
+ pip install -e ".[dev]"
98
+
99
+ - name: Setup cluster (cert-manager, etc.)
100
+ run: kuberoku clusters:setup
101
+
102
+ - name: All tests against real K8s
103
+ run: pytest tests/ --backend real -v -n4 --dist loadfile --runslow
104
+ env:
105
+ KUBEROKU_REGISTRY: k3d-registry.localhost:5000
106
+
107
+ smoke:
108
+ name: Smoke test (installed package)
109
+ needs: lint
110
+ runs-on: ubuntu-latest
111
+ steps:
112
+ - uses: actions/checkout@v4
113
+
114
+ - name: Set up Python
115
+ uses: actions/setup-python@v5
116
+ with:
117
+ python-version: "3.12"
118
+
119
+ - name: Install from built package
120
+ run: |
121
+ python -m pip install --upgrade pip
122
+ pip install .
123
+
124
+ - name: Verify entry point
125
+ run: |
126
+ kuberoku --version
127
+ kuberoku --help
128
+
129
+ - name: Verify SDK import
130
+ run: |
131
+ python -c "from kuberoku import Kuberoku, __version__; print('SDK OK: ' + __version__)"
132
+
133
+ installer:
134
+ name: Test install script (multi-distro)
135
+ needs: lint
136
+ runs-on: ubuntu-latest
137
+ steps:
138
+ - uses: actions/checkout@v4
139
+
140
+ - name: Install shellcheck
141
+ run: sudo apt-get install -y shellcheck
142
+
143
+ - name: Run installer test suite
144
+ run: sh scripts/test-install.sh
@@ -0,0 +1,35 @@
1
+ # Python
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+ *.egg-info/
6
+ *.egg
7
+ dist/
8
+ build/
9
+
10
+ # Virtual environments
11
+ .venv/
12
+ venv/
13
+
14
+ # Type checking / linting
15
+ .mypy_cache/
16
+ .ruff_cache/
17
+
18
+ # Testing
19
+ .pytest_cache/
20
+ .coverage
21
+ htmlcov/
22
+
23
+ # IDE
24
+ .idea/
25
+ .vscode/
26
+ *.swp
27
+ *.swo
28
+ *~
29
+
30
+ # OS
31
+ .DS_Store
32
+ Thumbs.db
33
+
34
+ # Project
35
+ .kuberoku
@@ -0,0 +1,22 @@
1
+ # Changelog
2
+
3
+ ## 0.1.0 (unreleased)
4
+
5
+ Initial alpha release.
6
+
7
+ ### Added
8
+
9
+ - **Apps**: create, destroy, info, rename, status, link, maintenance
10
+ - **Config**: set, get, unset with secret masking and optimistic concurrency
11
+ - **Deploy**: image deploy, build-from-git, multi-process types
12
+ - **PS**: scale, restart, stop, type, set commands
13
+ - **Releases**: info, rollback, prune with full audit trail
14
+ - **Services**: expose, ports, logs, exec, connect, maintenance
15
+ - **Addons**: PostgreSQL and Redis with credentials, backup, exec, connect
16
+ - **Addon versioning**: create with `--version`, `addons:migrate` (backup → PVC wipe → restore for Postgres), `addons:migrate-rollback`
17
+ - **Plugins**: install, uninstall, search via PyPI entry points
18
+ - **Domains**: add, remove, clear with Ingress management
19
+ - **Clusters**: add, remove, switch, current, info, doctor, setup
20
+ - **Networking**: default-deny NetworkPolicies, per-process allow rules
21
+ - **SDK**: full Python API matching CLI 1:1, frozen dataclasses, typed exceptions
22
+ - **Distribution**: PyPI package, pre-built binaries (Linux, macOS, Windows), curl installer
@@ -0,0 +1,98 @@
1
+ # Agent Instructions for kuberoku
2
+
3
+ Run `pytest tests/ -v && mypy src/kuberoku/ --strict && ruff check src/ tests/ && ruff format --check src/ tests/` to verify any file edits before prompting for input.
4
+
5
+ ## What this is
6
+
7
+ Kuberoku is a Python CLI + SDK that gives developers Heroku-like DX on vanilla Kubernetes. Zero server-side components — CLI/SDK only, K8s is the database. The complete specification is in `docs/NORTHSTAR.txt` (~8000 lines, 19 sections).
8
+
9
+ ## Architecture (strict three-layer)
10
+
11
+ ```
12
+ CLI (Click) --> SDK (business logic) --> K8s (protocol + client)
13
+ ```
14
+
15
+ - **CLI never touches K8s directly.** Calls one SDK method, formats the result.
16
+ - **SDK never prints.** Returns frozen dataclasses, raises typed exceptions, progress via `on_step` callback.
17
+ - **K8s client returns `dict[str, Any]`.** No K8s model objects leak upward. `typing.Protocol` defines the interface.
18
+ - **KuberokuFactory** is the DI container. Tests inject `FakeK8sClient`.
19
+
20
+ ## Required before each commit
21
+
22
+ ```bash
23
+ pytest tests/ -v # tests pass
24
+ mypy src/kuberoku/ --strict # types check
25
+ ruff check src/ tests/ # lint clean
26
+ ruff format --check src/ tests/ # format clean
27
+ ```
28
+
29
+ ## Source layout
30
+
31
+ ```
32
+ src/kuberoku/
33
+ branding.py # TOOL_NAME + all derived constants (single source)
34
+ models.py # Frozen dataclasses (App, Release, Dyno, etc.)
35
+ exceptions.py # KuberokuError hierarchy
36
+ factory.py # KuberokuFactory (DI container)
37
+ client.py # Public facade: from kuberoku import Kuberoku
38
+ k8s/
39
+ protocols.py # K8sClientProtocol (typing.Protocol)
40
+ client.py # Real K8s client (wraps kubernetes library)
41
+ labels.py # Label builders: for_app(), for_process(), selector()
42
+ resources.py # Resource dict builders: build_deployment(), safe_name()
43
+ sdk/ # One service per command group (apps.py, config.py, deploy.py, ...)
44
+ cli/ # One file per command group, mirrors sdk/ 1:1
45
+ main.py # ColonCommandGroup (colon commands), root group, entry point
46
+ tests/
47
+ backends/fake.py # FakeK8sClient (in-memory, implements K8sClientProtocol)
48
+ {feature}/ # tests/{apps,config,deploy,...}/test_{command}.py
49
+ infrastructure/ # tests for labels, resources, models, branding, factory
50
+ contract/ # FakeK8sClient matches real K8s behavior
51
+ ```
52
+
53
+ ## Key rules
54
+
55
+ - **Branding**: All identity constants derive from `branding.py`. No hardcoded "kuberoku" strings elsewhere.
56
+ - **Resource names**: `{PREFIX}-{type}-{app}[-{suffix}]`. Use `safe_name()` for 63-char K8s limit.
57
+ - **Labels**: `{DOMAIN}/managed-by`, `{DOMAIN}/app`, `{DOMAIN}/process-type`. See `k8s/labels.py`.
58
+ - **Optimistic concurrency**: All ConfigMap/Secret updates use `resourceVersion` + retry on 409.
59
+ - **Colon commands**: `apps:create` and `apps create` both work via `ColonCommandGroup.resolve_command()`.
60
+ - **LazyGroup**: Don't import sdk/ or k8s/ at CLI module level. Keeps `--help` under 100ms.
61
+ - **Cross-platform**: pathlib everywhere, no `shell=True`. Windows + Linux + macOS.
62
+
63
+ ## Development workflow (TDD per command)
64
+
65
+ 1. Write `tests/{feature}/test_{command}.py` first — SDK + CLI tests in same file
66
+ 2. Implement SDK method in `src/kuberoku/sdk/`
67
+ 3. Wire CLI command in `src/kuberoku/cli/`
68
+ 4. Verify: tests, mypy, ruff all pass
69
+
70
+ ## NORTHSTAR.txt section index
71
+
72
+ Read the relevant section when you need deeper context:
73
+
74
+ - Section 1: Vision & positioning
75
+ - Section 2: Branding & naming
76
+ - Section 3: End-to-end user experience
77
+ - Section 4: Command reference (all 62 commands)
78
+ - Section 5: Colon command implementation
79
+ - Section 6: SDK API design
80
+ - Section 7: Non-HTTP services & multi-port
81
+ - Section 8: Networking
82
+ - Section 9: Architecture & data storage
83
+ - Section 10: Data models
84
+ - Section 11: Exception hierarchy
85
+ - Section 12: Testing strategy (backends, fixtures, contract tests, TDD workflow)
86
+ - Section 13: Dependencies
87
+ - Section 14: Distribution
88
+ - Section 15: Plugin system
89
+ - Section 16: Implementation phases (0-14)
90
+ - Section 17: Cross-platform
91
+ - Section 18: Error UX
92
+ - Section 19: CI pipeline
93
+
94
+ ## Dependencies
95
+
96
+ - Runtime: click >=8.1, kubernetes >=35, rich >=13, pyyaml >=6
97
+ - Dev: pytest, pytest-cov, pytest-mock, mypy (--strict), ruff, vulture, pip-audit, types-PyYAML
98
+ - Build: hatchling. Entry point: `kuberoku = "kuberoku.cli.main:run"`
@@ -0,0 +1,2 @@
1
+ # Default owner for everything
2
+ * @amanjain