@vaharoni/devops 1.0.47

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 (342) hide show
  1. package/README.md +51 -0
  2. package/dist/app-support/crypto/index.d.ts +15 -0
  3. package/dist/app-support/crypto/index.d.ts.map +1 -0
  4. package/dist/app-support/crypto/index.js +30 -0
  5. package/dist/app-support/crypto/internal-token.d.ts +20 -0
  6. package/dist/app-support/crypto/internal-token.d.ts.map +1 -0
  7. package/dist/app-support/crypto/internal-token.js +42 -0
  8. package/dist/app-support/crypto/internal-token.spec.d.ts +2 -0
  9. package/dist/app-support/crypto/internal-token.spec.d.ts.map +1 -0
  10. package/dist/app-support/crypto/internal-token.spec.js +45 -0
  11. package/dist/app-support/crypto/secret.d.ts +3 -0
  12. package/dist/app-support/crypto/secret.d.ts.map +1 -0
  13. package/dist/app-support/crypto/secret.js +12 -0
  14. package/dist/app-support/crypto/secret.spec.d.ts +2 -0
  15. package/dist/app-support/crypto/secret.spec.d.ts.map +1 -0
  16. package/dist/app-support/crypto/secret.spec.js +15 -0
  17. package/dist/app-support/discovery/dev-discovery-loader.d.ts +2 -0
  18. package/dist/app-support/discovery/dev-discovery-loader.d.ts.map +1 -0
  19. package/dist/app-support/discovery/dev-discovery-loader.js +30 -0
  20. package/dist/app-support/discovery/service-endpoint.d.ts +2 -0
  21. package/dist/app-support/discovery/service-endpoint.d.ts.map +1 -0
  22. package/dist/app-support/discovery/service-endpoint.js +10 -0
  23. package/dist/cli/affected.d.ts +11 -0
  24. package/dist/cli/affected.d.ts.map +1 -0
  25. package/dist/cli/affected.js +103 -0
  26. package/dist/cli/common.d.ts +89 -0
  27. package/dist/cli/common.d.ts.map +1 -0
  28. package/dist/cli/common.js +236 -0
  29. package/dist/cli/common.spec.d.ts +2 -0
  30. package/dist/cli/common.spec.d.ts.map +1 -0
  31. package/dist/cli/common.spec.js +64 -0
  32. package/dist/cli/console.d.ts +11 -0
  33. package/dist/cli/console.d.ts.map +1 -0
  34. package/dist/cli/console.js +35 -0
  35. package/dist/cli/constant.d.ts +11 -0
  36. package/dist/cli/constant.d.ts.map +1 -0
  37. package/dist/cli/constant.js +22 -0
  38. package/dist/cli/db.d.ts +11 -0
  39. package/dist/cli/db.d.ts.map +1 -0
  40. package/dist/cli/db.js +119 -0
  41. package/dist/cli/dml.d.ts +11 -0
  42. package/dist/cli/dml.d.ts.map +1 -0
  43. package/dist/cli/dml.js +116 -0
  44. package/dist/cli/env.d.ts +11 -0
  45. package/dist/cli/env.d.ts.map +1 -0
  46. package/dist/cli/env.js +67 -0
  47. package/dist/cli/exec.d.ts +11 -0
  48. package/dist/cli/exec.d.ts.map +1 -0
  49. package/dist/cli/exec.js +50 -0
  50. package/dist/cli/image.d.ts +11 -0
  51. package/dist/cli/image.d.ts.map +1 -0
  52. package/dist/cli/image.js +140 -0
  53. package/dist/cli/init.d.ts +11 -0
  54. package/dist/cli/init.d.ts.map +1 -0
  55. package/dist/cli/init.js +66 -0
  56. package/dist/cli/internal-curl.d.ts +11 -0
  57. package/dist/cli/internal-curl.d.ts.map +1 -0
  58. package/dist/cli/internal-curl.js +43 -0
  59. package/dist/cli/job.d.ts +11 -0
  60. package/dist/cli/job.d.ts.map +1 -0
  61. package/dist/cli/job.js +67 -0
  62. package/dist/cli/jwt.d.ts +11 -0
  63. package/dist/cli/jwt.d.ts.map +1 -0
  64. package/dist/cli/jwt.js +27 -0
  65. package/dist/cli/namespace.d.ts +11 -0
  66. package/dist/cli/namespace.d.ts.map +1 -0
  67. package/dist/cli/namespace.js +70 -0
  68. package/dist/cli/prep-build.d.ts +11 -0
  69. package/dist/cli/prep-build.d.ts.map +1 -0
  70. package/dist/cli/prep-build.js +82 -0
  71. package/dist/cli/prisma.d.ts +11 -0
  72. package/dist/cli/prisma.d.ts.map +1 -0
  73. package/dist/cli/prisma.js +25 -0
  74. package/dist/cli/redis.d.ts +11 -0
  75. package/dist/cli/redis.d.ts.map +1 -0
  76. package/dist/cli/redis.js +76 -0
  77. package/dist/cli/registry.d.ts +11 -0
  78. package/dist/cli/registry.d.ts.map +1 -0
  79. package/dist/cli/registry.js +58 -0
  80. package/dist/cli/run-many.d.ts +11 -0
  81. package/dist/cli/run-many.d.ts.map +1 -0
  82. package/dist/cli/run-many.js +50 -0
  83. package/dist/cli/run.d.ts +11 -0
  84. package/dist/cli/run.d.ts.map +1 -0
  85. package/dist/cli/run.js +37 -0
  86. package/dist/cli/template.d.ts +11 -0
  87. package/dist/cli/template.d.ts.map +1 -0
  88. package/dist/cli/template.js +123 -0
  89. package/dist/cli/test.d.ts +11 -0
  90. package/dist/cli/test.d.ts.map +1 -0
  91. package/dist/cli/test.js +28 -0
  92. package/dist/devops.d.ts +3 -0
  93. package/dist/devops.d.ts.map +1 -0
  94. package/dist/devops.js +103 -0
  95. package/dist/index.d.ts +4 -0
  96. package/dist/index.d.ts.map +1 -0
  97. package/dist/index.js +3 -0
  98. package/dist/libs/affected-entities.d.ts +15 -0
  99. package/dist/libs/affected-entities.d.ts.map +1 -0
  100. package/dist/libs/affected-entities.js +52 -0
  101. package/dist/libs/config.d.ts +6 -0
  102. package/dist/libs/config.d.ts.map +1 -0
  103. package/dist/libs/config.js +98 -0
  104. package/dist/libs/dependencies.d.ts +19 -0
  105. package/dist/libs/dependencies.d.ts.map +1 -0
  106. package/dist/libs/dependencies.js +62 -0
  107. package/dist/libs/dependencies.spec.d.ts +2 -0
  108. package/dist/libs/dependencies.spec.d.ts.map +1 -0
  109. package/dist/libs/dependencies.spec.js +21 -0
  110. package/dist/libs/digital-ocean/container-reg.d.ts +6 -0
  111. package/dist/libs/digital-ocean/container-reg.d.ts.map +1 -0
  112. package/dist/libs/digital-ocean/container-reg.js +69 -0
  113. package/dist/libs/discovery/dependencies.d.ts +19 -0
  114. package/dist/libs/discovery/dependencies.d.ts.map +1 -0
  115. package/dist/libs/discovery/dependencies.js +62 -0
  116. package/dist/libs/discovery/dependencies.spec.d.ts +2 -0
  117. package/dist/libs/discovery/dependencies.spec.d.ts.map +1 -0
  118. package/dist/libs/discovery/dependencies.spec.js +21 -0
  119. package/dist/libs/discovery/images.d.ts +5 -0
  120. package/dist/libs/discovery/images.d.ts.map +1 -0
  121. package/dist/libs/discovery/images.js +45 -0
  122. package/dist/libs/discovery/index.d.ts +5 -0
  123. package/dist/libs/discovery/index.d.ts.map +1 -0
  124. package/dist/libs/discovery/index.js +55 -0
  125. package/dist/libs/discovery/package-json-processor.d.ts +3 -0
  126. package/dist/libs/discovery/package-json-processor.d.ts.map +1 -0
  127. package/dist/libs/discovery/package-json-processor.js +34 -0
  128. package/dist/libs/discovery/process-common.d.ts +25 -0
  129. package/dist/libs/discovery/process-common.d.ts.map +1 -0
  130. package/dist/libs/discovery/process-common.js +40 -0
  131. package/dist/libs/discovery/process-package-json.d.ts +3 -0
  132. package/dist/libs/discovery/process-package-json.d.ts.map +1 -0
  133. package/dist/libs/discovery/process-package-json.js +34 -0
  134. package/dist/libs/discovery/process-pyproject-toml.d.ts +3 -0
  135. package/dist/libs/discovery/process-pyproject-toml.d.ts.map +1 -0
  136. package/dist/libs/discovery/process-pyproject-toml.js +36 -0
  137. package/dist/libs/discovery/pyproject-toml-processor.d.ts +3 -0
  138. package/dist/libs/discovery/pyproject-toml-processor.d.ts.map +1 -0
  139. package/dist/libs/discovery/pyproject-toml-processor.js +39 -0
  140. package/dist/libs/git-helpers.d.ts +8 -0
  141. package/dist/libs/git-helpers.d.ts.map +1 -0
  142. package/dist/libs/git-helpers.js +20 -0
  143. package/dist/libs/hetzner/reg-secret.d.ts +3 -0
  144. package/dist/libs/hetzner/reg-secret.d.ts.map +1 -0
  145. package/dist/libs/hetzner/reg-secret.js +39 -0
  146. package/dist/libs/k8s-constants.d.ts +12 -0
  147. package/dist/libs/k8s-constants.d.ts.map +1 -0
  148. package/dist/libs/k8s-constants.js +66 -0
  149. package/dist/libs/k8s-db.d.ts +18 -0
  150. package/dist/libs/k8s-db.d.ts.map +1 -0
  151. package/dist/libs/k8s-db.js +73 -0
  152. package/dist/libs/k8s-generate.d.ts +17 -0
  153. package/dist/libs/k8s-generate.d.ts.map +1 -0
  154. package/dist/libs/k8s-generate.js +179 -0
  155. package/dist/libs/k8s-helpers.d.ts +11 -0
  156. package/dist/libs/k8s-helpers.d.ts.map +1 -0
  157. package/dist/libs/k8s-helpers.js +42 -0
  158. package/dist/libs/k8s-image-config.d.ts +8 -0
  159. package/dist/libs/k8s-image-config.d.ts.map +1 -0
  160. package/dist/libs/k8s-image-config.js +113 -0
  161. package/dist/libs/k8s-job-waiter.d.ts +8 -0
  162. package/dist/libs/k8s-job-waiter.d.ts.map +1 -0
  163. package/dist/libs/k8s-job-waiter.js +84 -0
  164. package/dist/libs/k8s-namespace.d.ts +7 -0
  165. package/dist/libs/k8s-namespace.d.ts.map +1 -0
  166. package/dist/libs/k8s-namespace.js +27 -0
  167. package/dist/libs/k8s-redis.d.ts +6 -0
  168. package/dist/libs/k8s-redis.d.ts.map +1 -0
  169. package/dist/libs/k8s-redis.js +31 -0
  170. package/dist/libs/k8s-secrets-manager.d.ts +5 -0
  171. package/dist/libs/k8s-secrets-manager.d.ts.map +1 -0
  172. package/dist/libs/k8s-secrets-manager.js +61 -0
  173. package/dist/libs/validate-env.d.ts +56 -0
  174. package/dist/libs/validate-env.d.ts.map +1 -0
  175. package/dist/libs/validate-env.js +214 -0
  176. package/dist/libs/validate-env.spec.d.ts +2 -0
  177. package/dist/libs/validate-env.spec.d.ts.map +1 -0
  178. package/dist/libs/validate-env.spec.js +168 -0
  179. package/dist/libs/workspace-discovery.d.ts +2 -0
  180. package/dist/libs/workspace-discovery.d.ts.map +1 -0
  181. package/dist/libs/workspace-discovery.js +75 -0
  182. package/dist/test.d.ts +2 -0
  183. package/dist/test.d.ts.map +1 -0
  184. package/dist/test.js +1 -0
  185. package/dist/types/index.d.ts +925 -0
  186. package/dist/types/index.d.ts.map +1 -0
  187. package/dist/types/index.js +79 -0
  188. package/package.json +55 -0
  189. package/src/app-support/crypto/index.ts +31 -0
  190. package/src/app-support/crypto/internal-token.spec.ts +53 -0
  191. package/src/app-support/crypto/internal-token.ts +82 -0
  192. package/src/app-support/crypto/secret.spec.ts +18 -0
  193. package/src/app-support/crypto/secret.ts +13 -0
  194. package/src/app-support/discovery/dev-discovery-loader.ts +35 -0
  195. package/src/app-support/discovery/service-endpoint.ts +12 -0
  196. package/src/cli/affected.ts +116 -0
  197. package/src/cli/common.spec.ts +78 -0
  198. package/src/cli/common.ts +323 -0
  199. package/src/cli/console.ts +46 -0
  200. package/src/cli/constant.ts +25 -0
  201. package/src/cli/db.ts +133 -0
  202. package/src/cli/dml.ts +126 -0
  203. package/src/cli/env.ts +87 -0
  204. package/src/cli/exec.sh +21 -0
  205. package/src/cli/exec.ts +57 -0
  206. package/src/cli/image.ts +197 -0
  207. package/src/cli/init.ts +75 -0
  208. package/src/cli/internal-curl.ts +48 -0
  209. package/src/cli/job.ts +80 -0
  210. package/src/cli/jwt.ts +32 -0
  211. package/src/cli/namespace.ts +78 -0
  212. package/src/cli/prep-build.ts +96 -0
  213. package/src/cli/prisma.ts +33 -0
  214. package/src/cli/redis.ts +83 -0
  215. package/src/cli/registry.ts +76 -0
  216. package/src/cli/run-many.ts +61 -0
  217. package/src/cli/run.ts +46 -0
  218. package/src/cli/template.ts +169 -0
  219. package/src/cli/test.ts +30 -0
  220. package/src/devops.ts +119 -0
  221. package/src/index.ts +3 -0
  222. package/src/libs/affected-entities.ts +71 -0
  223. package/src/libs/config.ts +117 -0
  224. package/src/libs/digital-ocean/container-reg.ts +81 -0
  225. package/src/libs/discovery/dependencies.spec.ts +25 -0
  226. package/src/libs/discovery/dependencies.ts +73 -0
  227. package/src/libs/discovery/images.ts +57 -0
  228. package/src/libs/discovery/index.ts +60 -0
  229. package/src/libs/discovery/process-common.ts +55 -0
  230. package/src/libs/discovery/process-package-json.ts +47 -0
  231. package/src/libs/discovery/process-pyproject-toml.ts +43 -0
  232. package/src/libs/git-helpers.ts +32 -0
  233. package/src/libs/hetzner/reg-secret.ts +54 -0
  234. package/src/libs/k8s-constants.ts +83 -0
  235. package/src/libs/k8s-db.ts +83 -0
  236. package/src/libs/k8s-generate.ts +211 -0
  237. package/src/libs/k8s-helpers.ts +59 -0
  238. package/src/libs/k8s-image-config.ts +165 -0
  239. package/src/libs/k8s-job-waiter.ts +124 -0
  240. package/src/libs/k8s-namespace.ts +41 -0
  241. package/src/libs/k8s-redis.ts +31 -0
  242. package/src/libs/k8s-secrets-manager.ts +79 -0
  243. package/src/libs/validate-env.spec.ts +223 -0
  244. package/src/libs/validate-env.ts +266 -0
  245. package/src/target-templates/.devops/config/constants.yaml +17 -0
  246. package/src/target-templates/.devops/config/images.yaml +88 -0
  247. package/src/target-templates/.devops/docker-images/common/docker-common.sh +23 -0
  248. package/src/target-templates/.devops/docker-images/node-services/node-exec.sh +8 -0
  249. package/src/target-templates/.devops/docker-images/node-services/node-run.sh +8 -0
  250. package/src/target-templates/.devops/docker-images/node-services.Dockerfile +34 -0
  251. package/src/target-templates/.devops/docker-images/python-services/python-exec.sh +8 -0
  252. package/src/target-templates/.devops/docker-images/python-services/python-run.sh +8 -0
  253. package/src/target-templates/.devops/docker-images/python-services.Dockerfile +29 -0
  254. package/src/target-templates/.devops/env.example.yaml +23 -0
  255. package/src/target-templates/.devops/infra/hetzner/abandoned/harbor-values.yaml +30 -0
  256. package/src/target-templates/.devops/infra/hetzner/abandoned/hcloud-config.yaml +134 -0
  257. package/src/target-templates/.devops/infra/hetzner/cert-manager.yaml +25 -0
  258. package/src/target-templates/.devops/infra/hetzner/harbor-cert.yaml +13 -0
  259. package/src/target-templates/.devops/infra/hetzner/harbor-values.yaml +76 -0
  260. package/src/target-templates/.devops/infra/hetzner/hcloud-config.yaml +113 -0
  261. package/src/target-templates/.devops/infra/hetzner/ingress-nginx-annotations.yaml +49 -0
  262. package/src/target-templates/.devops/infra/hetzner/ingress-nginx-configmap.yaml +8 -0
  263. package/src/target-templates/.devops/infra/hetzner/retain-storage-class.yaml +8 -0
  264. package/src/target-templates/.devops/infra/monitoring-ingress.yaml +62 -0
  265. package/src/target-templates/.devops/infra/stackgres-ui-ingress.yaml +35 -0
  266. package/src/target-templates/.devops/infra/test.yaml +60 -0
  267. package/src/target-templates/.devops/manifests/_index.yaml +21 -0
  268. package/src/target-templates/.devops/manifests/cron-jobs.yaml.hb +55 -0
  269. package/src/target-templates/.devops/manifests/db-migrate-job.yaml.hb +42 -0
  270. package/src/target-templates/.devops/manifests/deployment-debug.yaml.hb +44 -0
  271. package/src/target-templates/.devops/manifests/deployment-process.yaml.hb +47 -0
  272. package/src/target-templates/.devops/manifests/deployment-web.yaml.hb +53 -0
  273. package/src/target-templates/.devops/manifests/ingress.yaml.hb +21 -0
  274. package/src/target-templates/.devops/manifests/prefect.yaml.hb +62 -0
  275. package/src/target-templates/.devops/manifests/service.yaml.hb +15 -0
  276. package/src/target-templates/.devops/milvus/production/milvus-values.yaml +2 -0
  277. package/src/target-templates/.devops/milvus/staging/milvus-values.yaml +2 -0
  278. package/src/target-templates/.devops/postgres/DailyOperatorRestart.yaml +54 -0
  279. package/src/target-templates/.devops/postgres/production/cluster/PodDisruptionBudget.yaml +27 -0
  280. package/src/target-templates/.devops/postgres/production/cluster/SGCluster.yaml +47 -0
  281. package/src/target-templates/.devops/postgres/production/cluster/StackGres-alerts.yaml +191 -0
  282. package/src/target-templates/.devops/postgres/production/configurations/06-SGDistributedLogs.yaml +11 -0
  283. package/src/target-templates/.devops/postgres/production/configurations/07-SGObjectStorage.yaml +18 -0
  284. package/src/target-templates/.devops/postgres/production/configurations/08-SGScript.yaml +12 -0
  285. package/src/target-templates/.devops/postgres/staging/cluster/SGCluster.yaml +42 -0
  286. package/src/target-templates/.devops/postgres/staging/configurations/07-SGObjectStorage.yaml +18 -0
  287. package/src/target-templates/.devops/postgres/staging/configurations/08-SGScript.yaml +12 -0
  288. package/src/target-templates/.devops/prefect/production/prefect-values.yaml +14 -0
  289. package/src/target-templates/.devops/prefect/staging/prefect-values.yaml +14 -0
  290. package/src/target-templates/.devops/redis/production/redis-values.yaml +20 -0
  291. package/src/target-templates/.devops/redis/staging/redis-values.yaml +8 -0
  292. package/src/target-templates/.envrc +5 -0
  293. package/src/target-templates/.github/actions/build-image@v1/action.yaml +86 -0
  294. package/src/target-templates/.github/actions/connect-to-digital-ocean@v1/action.yaml +29 -0
  295. package/src/target-templates/.github/actions/connect-to-hetzner@v1/action.yaml +31 -0
  296. package/src/target-templates/.github/actions/connect-to-infra@v1/action.yaml +46 -0
  297. package/src/target-templates/.github/actions/db-migrate@v1/action.yaml +23 -0
  298. package/src/target-templates/.github/actions/deploy-image@v1/action.yaml +33 -0
  299. package/src/target-templates/.github/actions/setup-prereq@v1/action.yaml +29 -0
  300. package/src/target-templates/.github/workflows/k8s-build.yaml +84 -0
  301. package/src/target-templates/applications/example-data-pipeline/pyproject.toml +14 -0
  302. package/src/target-templates/applications/example-data-pipeline/src/example_data_pipeline/main.py +38 -0
  303. package/src/target-templates/applications/example-node/index.ts +30 -0
  304. package/src/target-templates/applications/example-node/package.json +26 -0
  305. package/src/target-templates/applications/example-node/tsconfig.json +3 -0
  306. package/src/target-templates/applications/example-python/pyproject.toml +20 -0
  307. package/src/target-templates/applications/example-python/src/example_python/__init__.py +0 -0
  308. package/src/target-templates/applications/example-python/src/example_python/main.py +13 -0
  309. package/src/target-templates/applications/example-python/src/example_python/scripts.py +17 -0
  310. package/src/target-templates/applications/example-python/tests/__init__.py +0 -0
  311. package/src/target-templates/applications/jobs/README.md +68 -0
  312. package/src/target-templates/applications/jobs/index.ts +1 -0
  313. package/src/target-templates/applications/jobs/package.json +30 -0
  314. package/src/target-templates/applications/jobs/tsconfig.json +3 -0
  315. package/src/target-templates/config/.env.development +1 -0
  316. package/src/target-templates/config/.env.global +4 -0
  317. package/src/target-templates/config/.env.test +1 -0
  318. package/src/target-templates/db/db/__init__.py +0 -0
  319. package/src/target-templates/db/db/db_client_test.py +46 -0
  320. package/src/target-templates/db/db-client-test.ts +140 -0
  321. package/src/target-templates/db/db-client.ts +19 -0
  322. package/src/target-templates/db/env.yaml +4 -0
  323. package/src/target-templates/db/package.json +17 -0
  324. package/src/target-templates/db/prisma/schema.prisma +24 -0
  325. package/src/target-templates/db/prisma-setup-vitest.ts +27 -0
  326. package/src/target-templates/db/pyproject.toml +14 -0
  327. package/src/target-templates/db/tsconfig.json +3 -0
  328. package/src/target-templates/devops +3 -0
  329. package/src/target-templates/devopspy +3 -0
  330. package/src/target-templates/dml/package.json +7 -0
  331. package/src/target-templates/dml/tsconfig.json +3 -0
  332. package/src/target-templates/libs/example-node-lib/bun.lock +27 -0
  333. package/src/target-templates/libs/example-node-lib/index.ts +3 -0
  334. package/src/target-templates/libs/example-node-lib/package.json +12 -0
  335. package/src/target-templates/libs/example-node-lib/tsconfig.json +3 -0
  336. package/src/target-templates/libs/example-python-lib/pyproject.toml +11 -0
  337. package/src/target-templates/libs/example-python-lib/src/example_python_lib/__init__.py +2 -0
  338. package/src/target-templates/pyproject.toml +19 -0
  339. package/src/target-templates/tmp/.gitkeep +0 -0
  340. package/src/target-templates/tsconfig.json +27 -0
  341. package/src/test.ts +0 -0
  342. package/src/types/index.ts +173 -0
@@ -0,0 +1,53 @@
1
+ apiVersion: apps/v1
2
+ kind: Deployment
3
+ metadata:
4
+ labels:
5
+ app: {{app_name}}
6
+ env: {{monorepo_env}}
7
+ name: {{app_name}}
8
+ namespace: {{namespace}}
9
+ spec:
10
+ replicas: {{replicas}}
11
+ selector:
12
+ matchLabels:
13
+ app: {{app_name}}
14
+ template:
15
+ metadata:
16
+ labels:
17
+ app: {{app_name}}
18
+ env: {{monorepo_env}}
19
+ spec:
20
+ volumes:
21
+ - name: secret-injection-hook
22
+ secret:
23
+ secretName: {{env_secret_name}}
24
+ containers:
25
+ - image: {{image_path}}
26
+ name: {{app_name}}
27
+ args:
28
+ - "{{project_name}}"
29
+ env:
30
+ - name: MONOREPO_ENV
31
+ value: {{monorepo_env}}
32
+ - name: MONOREPO_NAMESPACE
33
+ value: {{namespace}}
34
+ - name: IS_KUBERNETES
35
+ value: 'true'
36
+ - name: MONOREPO_BASE_SECRET
37
+ valueFrom:
38
+ secretKeyRef:
39
+ name: {{env_secret_name}}
40
+ key: {{env_base_secret_key}}
41
+ volumeMounts:
42
+ - name: secret-injection-hook
43
+ mountPath: /etc/kubernetes/secrets
44
+ readOnly: true
45
+ startupProbe:
46
+ httpGet:
47
+ path: /healthz
48
+ port: {{port}}
49
+ failureThreshold: 50
50
+ periodSeconds: 2
51
+ resources:
52
+ requests:
53
+ memory: 250Mi
@@ -0,0 +1,21 @@
1
+ apiVersion: networking.k8s.io/v1
2
+ kind: Ingress
3
+ metadata:
4
+ name: {{app_name}}
5
+ namespace: {{namespace}}
6
+ labels:
7
+ app: {{app_name}}
8
+ env: {{monorepo_env}}
9
+ spec:
10
+ ingressClassName: nginx
11
+ rules:
12
+ - host: {{subdomain}}.{{domain_name}}
13
+ http:
14
+ paths:
15
+ - path: /
16
+ pathType: Prefix
17
+ backend:
18
+ service:
19
+ name: {{service_name}}
20
+ port:
21
+ number: 80
@@ -0,0 +1,62 @@
1
+ {{#each prefectFlows}}
2
+ apiVersion: apps/v1
3
+ kind: Deployment
4
+ metadata:
5
+ labels:
6
+ app: {{../app_name}}
7
+ env: {{../monorepo_env}}
8
+ name: {{../app_name}}-{{flow_name}}
9
+ namespace: {{../namespace}}
10
+ spec:
11
+ replicas: 1
12
+ selector:
13
+ matchLabels:
14
+ app: {{../app_name}}
15
+ template:
16
+ metadata:
17
+ labels:
18
+ app: {{../app_name}}
19
+ env: {{../monorepo_env}}
20
+ spec:
21
+ volumes:
22
+ - name: secret-injection-hook
23
+ secret:
24
+ secretName: {{../env_secret_name}}
25
+ containers:
26
+ - image: {{../image_path}}
27
+ name: {{flow_name}}
28
+ command:
29
+ - ./python-exec.sh
30
+ args:
31
+ - ./devopspy
32
+ - exec
33
+ - --in
34
+ - {{../app_name}}
35
+ - python
36
+ - -m
37
+ - {{script_path}}
38
+ env:
39
+ - name: PREFECT_API_URL
40
+ value: http://prefect-server.prefect-{{../monorepo_env}}:4200/api
41
+ - name: MONOREPO_ENV
42
+ value: {{../monorepo_env}}
43
+ - name: MONOREPO_NAMESPACE
44
+ value: {{../namespace}}
45
+ - name: IS_KUBERNETES
46
+ value: 'true'
47
+ - name: MONOREPO_BASE_SECRET
48
+ valueFrom:
49
+ secretKeyRef:
50
+ name: {{../env_secret_name}}
51
+ key: {{../env_base_secret_key}}
52
+ volumeMounts:
53
+ - name: secret-injection-hook
54
+ mountPath: /etc/kubernetes/secrets
55
+ readOnly: true
56
+ resources:
57
+ requests:
58
+ memory: 250Mi
59
+ {{#unless @last}}
60
+ ---
61
+ {{/unless}}
62
+ {{/each}}
@@ -0,0 +1,15 @@
1
+ apiVersion: v1
2
+ kind: Service
3
+ metadata:
4
+ name: {{service_name}}
5
+ labels:
6
+ app: {{app_name}}
7
+ env: {{monorepo_env}}
8
+ namespace: {{namespace}}
9
+ spec:
10
+ selector:
11
+ app: {{app_name}}
12
+ ports:
13
+ - protocol: TCP
14
+ port: 80
15
+ targetPort: {{port}}
@@ -0,0 +1,2 @@
1
+ cluster:
2
+ enabled: true
@@ -0,0 +1,2 @@
1
+ cluster:
2
+ enabled: false
@@ -0,0 +1,54 @@
1
+ # New service account for managing deployments in stackgres namespace
2
+ apiVersion: v1
3
+ kind: ServiceAccount
4
+ metadata:
5
+ name: stackgres-deployment-manager
6
+ namespace: stackgres
7
+ ---
8
+ # Role with permissions to restart deployments
9
+ apiVersion: rbac.authorization.k8s.io/v1
10
+ kind: Role
11
+ metadata:
12
+ name: deployment-manager
13
+ namespace: stackgres
14
+ rules:
15
+ - apiGroups: ["apps"]
16
+ resources: ["deployments"]
17
+ verbs: ["get", "list", "watch", "patch"]
18
+ ---
19
+ # Bind the role to the service account
20
+ apiVersion: rbac.authorization.k8s.io/v1
21
+ kind: RoleBinding
22
+ metadata:
23
+ name: stackgres-deployment-manager-binding
24
+ namespace: stackgres
25
+ subjects:
26
+ - kind: ServiceAccount
27
+ name: stackgres-deployment-manager
28
+ namespace: stackgres
29
+ roleRef:
30
+ kind: Role
31
+ name: deployment-manager
32
+ apiGroup: rbac.authorization.k8s.io
33
+ ---
34
+ apiVersion: batch/v1
35
+ kind: CronJob
36
+ metadata:
37
+ name: stackgres-operator-restart-all-deployments
38
+ namespace: stackgres
39
+ spec:
40
+ schedule: "0 2 * * *"
41
+ jobTemplate:
42
+ spec:
43
+ template:
44
+ spec:
45
+ serviceAccountName: stackgres-deployment-manager
46
+ containers:
47
+ - name: kubectl
48
+ image: bitnami/kubectl:latest
49
+ command:
50
+ - /bin/sh
51
+ - -c
52
+ # Restarts all deployments in the stackgres namespace, which include stackgres-collector, stackgres-operator, and stackgres-restapi
53
+ - kubectl rollout restart deployment -n stackgres
54
+ restartPolicy: OnFailure
@@ -0,0 +1,27 @@
1
+ apiVersion: policy/v1
2
+ kind: PodDisruptionBudget
3
+ metadata:
4
+ name: db-production-replicas-pdb
5
+ namespace: db-production
6
+ spec:
7
+ maxUnavailable: 1
8
+ selector:
9
+ matchLabels:
10
+ app: StackGresCluster
11
+ role: replica
12
+ stackgres.io/cluster-name: db-production
13
+ stackgres.io/cluster: "true"
14
+ ---
15
+ apiVersion: policy/v1
16
+ kind: PodDisruptionBudget
17
+ metadata:
18
+ name: db-production-primary-pdb
19
+ namespace: db-production
20
+ spec:
21
+ minAvailable: 1
22
+ selector:
23
+ matchLabels:
24
+ app: StackGresCluster
25
+ role: primary
26
+ stackgres.io/cluster-name: db-production
27
+ stackgres.io/cluster: "true"
@@ -0,0 +1,47 @@
1
+ apiVersion: stackgres.io/v1
2
+ kind: SGCluster
3
+ metadata:
4
+ namespace: db-production
5
+ name: db-production
6
+ spec:
7
+ postgres:
8
+ version: '17.4'
9
+ extensions:
10
+ # - name: 'pg_repack'
11
+ - name: 'pg_trgm' # required for prefect
12
+ instances: 2
13
+ # sgInstanceProfile: 'size-m'
14
+ profile: 'production'
15
+ pods:
16
+ persistentVolume:
17
+ size: '20Gi'
18
+ storageClass: 'hcloud-volumes-retain'
19
+ scheduling:
20
+ tolerations:
21
+ - key: "stackgres"
22
+ operator: "Exists"
23
+ effect: "NoSchedule"
24
+ configurations:
25
+ # sgPostgresConfig: 'pgconfig'
26
+ # sgPoolingConfig: 'poolconfig'
27
+ backups:
28
+ - sgObjectStorage: 'backupconfig'
29
+ cronSchedule: '30 02 * * *'
30
+ retention: 7
31
+ compression: lz4
32
+ performance:
33
+ maxDiskBandwidth: 26214400 #25 MB per seceod
34
+ maxNetworkBandwidth: 52428800 #50 MB per second
35
+ uploadDiskConcurrency: 2
36
+ # We do not use for now as it requires adding a few more nodes
37
+ # distributedLogs:
38
+ # sgDistributedLogs: 'distributedlogs'
39
+ managedSql:
40
+ scripts:
41
+ - sgScript: create-db-script
42
+ postgresServices:
43
+ primary:
44
+ type: ClusterIP
45
+ replicas:
46
+ type: ClusterIP
47
+ prometheusAutobind: true
@@ -0,0 +1,191 @@
1
+ apiVersion: monitoring.coreos.com/v1
2
+ kind: PrometheusRule
3
+ metadata:
4
+ labels:
5
+ app: kube-prometheus-stack
6
+ release: monitoring
7
+ name: stackgres-rules
8
+ namespace: monitoring
9
+ spec:
10
+ groups:
11
+ - name: StackGres
12
+ rules:
13
+ - alert: PostgresInstanceDown
14
+ expr: pg_up == 0
15
+ for: 1m
16
+ labels:
17
+ severity: critical
18
+ service: "PostgreSQL"
19
+ cluster: "StackGres"
20
+ annotations:
21
+ summary: "Postgres server instance is down"
22
+ description: "Postgres has not been responding for the past 1 minutes on {{ $labels.instance }}"
23
+ title: "Postgres server instance {{ $labels.instance }} is down "
24
+ - alert: PostgresExporterErrors
25
+ expr: pg_exporter_last_scrape_error == 1
26
+ for: 10m
27
+ labels:
28
+ severity: critical
29
+ service: "PostgreSQL"
30
+ cluster: "StackGres"
31
+ annotations:
32
+ summary: "Postgres Exporter is down or is showing errors"
33
+ description: "postgres-exporter is not running or it is showing errors {{ $labels.instance }}"
34
+ - alert: PostgresReplicationLagSizeTooLarge
35
+ expr: pg_replication_status_lag_size > 1e+09
36
+ for: 5m
37
+ labels:
38
+ severity: critical
39
+ service: "PostgreSQL"
40
+ cluster: "StackGres"
41
+ annotations:
42
+ summary: "Postgres replication lag size is to large"
43
+ description: "Replication lag size on server {{$labels.instance}} ({{$labels.application_name}}) is currently {{ $value | humanize1024}}B behind the leader in cluster {{$labels.cluster_name}}"
44
+ - alert: PostgresTooManyDeadTuples
45
+ expr: ((pg_stat_user_tables_n_dead_tup > 1e+06) / (pg_stat_user_tables_n_live_tup + pg_stat_user_tables_n_dead_tup)) >= 0.1
46
+ for: 30m
47
+ labels:
48
+ severity: info
49
+ service: "PostgreSQL"
50
+ cluster: "StackGres"
51
+ annotations:
52
+ summary: "PostgreSQL dead tuples is too large"
53
+ description: "The dead tuple ratio of {{$labels.relname}} on database {{$labels.datname}} is greater than 10% in cluster {{$labels.cluster_name}}"
54
+ - alert: PostgresInactiveReplicationSlots
55
+ expr: pg_replication_slots_active == 0
56
+ for: 10m
57
+ labels:
58
+ severity: warning
59
+ service: "PostgreSQL"
60
+ cluster: "StackGres"
61
+ annotations:
62
+ summary: "There are inactive replications slots"
63
+ description: "The are some inactive replication slots on {{$labels.instance}} in cluster {{$labels.cluster_name}}"
64
+ - alert: PostgresSplitBrain
65
+ expr: count by(cluster_name) (pg_replication_is_replica == 0) > 1
66
+ for: 1m
67
+ labels:
68
+ severity: critical
69
+ service: "PostgreSQL"
70
+ cluster: "StackGres"
71
+ annotations:
72
+ summary: "There are more than one instance in read-write mode"
73
+ description: "Split Brain: too many postgres databases in cluster {{$labels.cluster_name}} in read-write mode"
74
+ - alert: PostgresTooManyConnections
75
+ expr: sum by (datname) (pg_stat_activity_count{datname!~"template.*|postgres"}) > pg_settings_max_connections * 0.9
76
+ for: 5m
77
+ labels:
78
+ severity: warning
79
+ service: "PostgreSQL"
80
+ cluster: "StackGres"
81
+ annotations:
82
+ summary: Postgresql too many connections (instance {{ $labels.instance }} in cluster {{$labels.cluster_name}})
83
+ description: "PostgreSQL instance has too many connections\n VALUE = {{ $value }}\n LABELS: {{ $labels }}"
84
+ - alert: PostgresNotEnoughConnections
85
+ expr: sum by (datname) (pg_stat_activity_count{datname!~"template.*|postgres"}) < 5
86
+ for: 5m
87
+ labels:
88
+ severity: warning
89
+ service: "PostgreSQL"
90
+ cluster: "StackGres"
91
+ annotations:
92
+ summary: Postgresql not enough connections (instance {{ $labels.instance }} in cluster {{$labels.cluster_name}})
93
+ description: "PostgreSQL instance should have more connections (> 5)\n VALUE = {{ $value }}\n LABELS: {{ $labels }}"
94
+ - alert: PostgresPromotedNode
95
+ expr: pg_replication_is_replica and changes(pg_replication_is_replica[1m]) > 0
96
+ for: 5m
97
+ labels:
98
+ severity: warning
99
+ service: "PostgreSQL"
100
+ cluster: "StackGres"
101
+ annotations:
102
+ summary: "Postgresql promoted node (instance {{ $labels.instance }}, cluster {{ $labels.cluster_name }})"
103
+ description: "Postgresql standby server has been promoted as primary node\n VALUE = {{ $value }}\n LABELS: {{ $labels }}"
104
+ - alert: PostgresLongRunningTransactionLeaderNode
105
+ expr: pg_long_running_transactions_transactions>0 and on (instance)(pg_replication_is_replica == 0)
106
+ for: 10m
107
+ labels:
108
+ severity: warning
109
+ service: "PostgreSQL"
110
+ cluster: "StackGres"
111
+ annotations:
112
+ summary: "Long running transaction on the leader node, {{ $labels.instance }}
113
+ cluster {{ $labels.cluster_name }}"
114
+ description: |-
115
+ There are long running transactions on the leader node, {{ $labels.instance }}
116
+ COUNT = {{ $value }}
117
+ LABELS: {{ $labels }}
118
+ - alert: PostgresLongRunningTransactionReplicaNode
119
+ expr: pg_long_running_transactions_transactions>0 and on (instance)(pg_replication_is_replica == 1)
120
+ for: 10m
121
+ labels:
122
+ severity: warning
123
+ service: "PostgreSQL"
124
+ cluster: "StackGres"
125
+ annotations:
126
+ summary: "Long running transaction on a replica node, {{ $labels.instance }}, cluster {{ $labels.cluster_name }}"
127
+ description: |-
128
+ There are long running transactions on a replica node, {{ $labels.instance }}
129
+ COUNT = {{ $value }}
130
+ LABELS: {{ $labels }}
131
+ # Connection Pooling alerts
132
+ - alert: PgBouncerWaitingClients
133
+ expr: pgbouncer_show_pools_cl_waiting > 0
134
+ for: 10m
135
+ labels:
136
+ severity: warning
137
+ service: "PostgreSQL"
138
+ cluster: "StackGres"
139
+ annotations:
140
+ summary: PgBouncer has waiting clients on instance {{ $labels.instance }} in cluster {{$labels.cluster_name}})
141
+ description: "PgBouncer instance has waiting clients\n VALUE = {{ $value }}\n LABELS: {{ $labels }}"
142
+ - alert: PgBouncerNotEnoughConnections
143
+ expr: (sum by (database,instance) (pgbouncer_show_pools_cl_active{database!~"template.*|postgres|pgbouncer"}) + sum by (database, instance) (pgbouncer_show_pools_cl_waiting{database!~"template.*|postgres|pgbouncer"})) - on (database,instance) (pgbouncer_show_databases_pool_size{database!~"template.*|postgres|pgbouncer"}) > 0
144
+ for: 10m
145
+ labels:
146
+ severity: critical
147
+ service: "PostgreSQL"
148
+ cluster: "StackGres"
149
+ annotations:
150
+ summary: PgBouncer pool size is not enough for the current connections on {{ $labels.instance }} in cluster {{$labels.cluster_name}})
151
+ description: "PgBouncer is getting more connections than the pool size, extra connections = {{ $value }}"
152
+ - alert: PgBouncerPoolFillingUp
153
+ expr: (sum by (database,instance) (pgbouncer_show_databases_pool_size{database!~"template.*|postgres|pgbouncer"}) - on (database,instance) pgbouncer_show_databases_current_connections) <= 15
154
+ for: 1m
155
+ labels:
156
+ severity: warning
157
+ service: "PostgreSQL"
158
+ cluster: "StackGres"
159
+ annotations:
160
+ summary: PgBouncer pool is filling up on {{ $labels.instance }} in cluster {{$labels.cluster_name}})
161
+ description: "PgBouncer pool is filling up, remaining connections = {{ $value }}"
162
+ - alert: PgBouncerAvgWaitTimeTooHigh
163
+ expr: pgbouncer_show_stats_avg_wait_time > 1e+6
164
+ for: 5m
165
+ labels:
166
+ severity: warning
167
+ service: "PostgreSQL"
168
+ cluster: "StackGres"
169
+ annotations:
170
+ summary: PgBouncer time spent by clients waiting for a connections is too high on {{ $labels.instance }} in cluster {{$labels.cluster_name}})
171
+ description: "PgBouncer wait for a server connections is too high = {{ $value }}"
172
+ - alert: PgBouncerQueryTimeTooHigh
173
+ expr: pgbouncer_show_stats_avg_query_time > 5e+6
174
+ for: 5m
175
+ labels:
176
+ severity: warning
177
+ service: "PostgreSQL"
178
+ cluster: "StackGres"
179
+ annotations:
180
+ summary: PgBouncer average query duration more than 5 seconds on {{ $labels.instance }} in cluster {{$labels.cluster_name}})
181
+ description: "PgBouncer average query duration more than 5 seconds = {{ $value }}"
182
+ - alert: DatabaseLowDiskAvailable
183
+ expr: (1.0 - node_filesystem_avail_bytes{mountpoint="/var/lib/postgresql",fstype!=""} / node_filesystem_size_bytes{mountpoint="/var/lib/postgresql",fstype!=""}) * 100 >= 80
184
+ for: 15m
185
+ labels:
186
+ severity: warning
187
+ service: "PostgreSQL"
188
+ cluster: "StackGres"
189
+ annotations:
190
+ summary: Database disk is filling up currently have less than 20% available on {{ $labels.instance }} in cluster {{$labels.cluster_name}})
191
+ description: "Database disk is filling up currently have less than 20%, currently occupied {{ $value }} %"
@@ -0,0 +1,11 @@
1
+ # We do not use for now as it requires adding a few more nodes
2
+
3
+ # apiVersion: stackgres.io/v1
4
+ # kind: SGDistributedLogs
5
+ # metadata:
6
+ # name: distributedlogs
7
+ # namespace: db-production
8
+ # spec:
9
+ # persistentVolume:
10
+ # size: 10Gi
11
+
@@ -0,0 +1,18 @@
1
+ apiVersion: stackgres.io/v1beta1
2
+ kind: SGObjectStorage
3
+ metadata:
4
+ namespace: db-production
5
+ name: backupconfig
6
+ spec:
7
+ type: s3Compatible
8
+ s3Compatible:
9
+ bucket: changeme-backups
10
+ endpoint: https://hel1.your-objectstorage.com
11
+ awsCredentials:
12
+ secretKeySelectors:
13
+ accessKeyId:
14
+ name: s3-backup-bucket-secret
15
+ key: accessKey
16
+ secretAccessKey:
17
+ name: s3-backup-bucket-secret
18
+ key: secretKey
@@ -0,0 +1,12 @@
1
+ apiVersion: stackgres.io/v1
2
+ kind: SGScript
3
+ metadata:
4
+ name: create-db-script
5
+ namespace: db-production
6
+ spec:
7
+ managedVersions: true
8
+ continueOnError: false
9
+ scripts:
10
+ - name: create-database
11
+ script: |
12
+ CREATE DATABASE changeme WITH OWNER postgres;
@@ -0,0 +1,42 @@
1
+ apiVersion: stackgres.io/v1
2
+ kind: SGCluster
3
+ metadata:
4
+ namespace: db-staging
5
+ name: db-staging
6
+ spec:
7
+ postgres:
8
+ version: '17.4'
9
+ extensions:
10
+ # - name: 'pg_repack'
11
+ - name: 'pg_trgm' # required for prefect
12
+ instances: 1
13
+ # sgInstanceProfile: 'size-m'
14
+ profile: 'testing'
15
+ pods:
16
+ persistentVolume:
17
+ size: '10Gi'
18
+ storageClass: 'hcloud-volumes-retain'
19
+ scheduling:
20
+ tolerations:
21
+ - key: "stackgres"
22
+ operator: "Exists"
23
+ effect: "NoSchedule"
24
+ configurations:
25
+ # sgPostgresConfig: 'pgconfig'
26
+ # sgPoolingConfig: 'poolconfig'
27
+ backups:
28
+ - sgObjectStorage: 'backupconfig'
29
+ # cronSchedule: '30 02 */4 * *'
30
+ cronSchedule: '30 02 * * *'
31
+ retention: 4
32
+ # distributedLogs:
33
+ # sgDistributedLogs: 'distributedlogs'
34
+ managedSql:
35
+ scripts:
36
+ - sgScript: create-db-script
37
+ postgresServices:
38
+ primary:
39
+ type: ClusterIP
40
+ replicas:
41
+ type: ClusterIP
42
+ prometheusAutobind: true
@@ -0,0 +1,18 @@
1
+ apiVersion: stackgres.io/v1beta1
2
+ kind: SGObjectStorage
3
+ metadata:
4
+ namespace: db-staging
5
+ name: backupconfig
6
+ spec:
7
+ type: s3Compatible
8
+ s3Compatible:
9
+ bucket: changeme-backups
10
+ endpoint: https://hel1.your-objectstorage.com
11
+ awsCredentials:
12
+ secretKeySelectors:
13
+ accessKeyId:
14
+ name: s3-backup-bucket-secret
15
+ key: accessKey
16
+ secretAccessKey:
17
+ name: s3-backup-bucket-secret
18
+ key: secretKey
@@ -0,0 +1,12 @@
1
+ apiVersion: stackgres.io/v1
2
+ kind: SGScript
3
+ metadata:
4
+ name: create-db-script
5
+ namespace: db-staging
6
+ spec:
7
+ managedVersions: true
8
+ continueOnError: false
9
+ scripts:
10
+ - name: create-database
11
+ script: |
12
+ CREATE DATABASE changeme WITH OWNER postgres;
@@ -0,0 +1,14 @@
1
+ ingress:
2
+ enabled: true
3
+ host:
4
+ hostname: "prefect-production.staging.com"
5
+ server:
6
+ uiConfig:
7
+ prefectUiApiUrl: "https://prefect-production.staging.com/api"
8
+
9
+ # We use the environment's stackgres postgres instance
10
+ postgresql:
11
+ enabled: false
12
+ secret:
13
+ create: false
14
+ name: prefect-server-postgresql-connection
@@ -0,0 +1,14 @@
1
+ ingress:
2
+ enabled: true
3
+ host:
4
+ hostname: "prefect-staging.staging.com"
5
+ server:
6
+ uiConfig:
7
+ prefectUiApiUrl: "https://prefect-staging.staging.com/api"
8
+
9
+ # We use the environment's stackgres postgres instance
10
+ postgresql:
11
+ enabled: false
12
+ secret:
13
+ create: false
14
+ name: prefect-server-postgresql-connection
@@ -0,0 +1,20 @@
1
+ architecture: replication
2
+ global:
3
+ defaultStorageClass: hcloud-volumes-retain
4
+ master:
5
+ resources:
6
+ requests:
7
+ cpu: 1
8
+ memory: 256Mi
9
+ limits:
10
+ cpu: 3
11
+ memory: 1024Mi
12
+ replica:
13
+ replicaCount: 1
14
+ resources:
15
+ requests:
16
+ cpu: 1
17
+ memory: 256Mi
18
+ limits:
19
+ cpu: 3
20
+ memory: 1024Mi
@@ -0,0 +1,8 @@
1
+ architecture: standalone
2
+ global:
3
+ defaultStorageClass: hcloud-volumes-retain
4
+ master:
5
+ resources:
6
+ limits:
7
+ cpu: 1
8
+ memory: 256Mi
@@ -0,0 +1,5 @@
1
+ if [ -f "$PWD/config/kubeconfig" ]; then
2
+ export KUBECONFIG="$PWD/config/kubeconfig"
3
+ else
4
+ export KUBECONFIG="${HOME}/.kube/config"
5
+ fi