From 4cda072155f84f28ee8cb4697c234fbf6af14956 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CNaeel=E2=80=9D?= Date: Mon, 9 Mar 2026 20:29:27 +0400 Subject: [PATCH] docs: update progress.md, errors/log.md; add gitignore for dist/ and tfstate backups MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - doc/progress.md: обновлена версия до operator v0.1.18 / provider v0.1.11, добавлен блок source_dir + fix destroy cleanup (2026-03-09), уточнены комментарии к контроллерам и trigger_resource - doc/errors/log.md: добавлены две записи — source_dir/hashicorp/archive, destroy route cleanup bug (три причины + решения) - .gitignore: добавлены examples/*/dist/ и terraform.tfstate.*.backup - examples/: удалены dist/ zip и tfstate.*.backup из трекинга --- DESTROY_ROUTE_CLEANUP_BUG.md | 143 +++++++ hello-node/dist/handler-http.zip | Bin 419 -> 0 bytes hello-node/dist/handler-job.zip | Bin 506 -> 0 bytes .../terraform.tfstate.1772954131.backup | 168 -------- .../terraform.tfstate.1773029146.backup | 209 ---------- notes-python/dist/notes-list.zip | Bin 962 -> 0 bytes notes-python/dist/notes.zip | Bin 1490 -> 0 bytes notes-python/dist/sql-runner.zip | Bin 1039 -> 0 bytes .../terraform.tfstate.1773036471.backup | 369 ------------------ .../terraform.tfstate.1773036482.backup | 365 ----------------- .../terraform.tfstate.1773036493.backup | 365 ----------------- .../terraform.tfstate.1773036504.backup | 360 ----------------- run_terraform_examples.sh | 333 ++++++++++++++++ simple-node/dist/time_display.zip | Bin 682 -> 0 bytes simple-node/dist/time_getter.zip | Bin 574 -> 0 bytes simple-python/dist/time_display.zip | Bin 695 -> 0 bytes simple-python/dist/time_getter.zip | Bin 674 -> 0 bytes 17 files changed, 476 insertions(+), 1836 deletions(-) create mode 100644 DESTROY_ROUTE_CLEANUP_BUG.md delete mode 100644 hello-node/dist/handler-http.zip delete mode 100644 hello-node/dist/handler-job.zip delete mode 100644 hello-node/terraform.tfstate.1772954131.backup delete mode 100644 hello-node/terraform.tfstate.1773029146.backup delete mode 100644 notes-python/dist/notes-list.zip delete mode 100644 notes-python/dist/notes.zip delete mode 100644 notes-python/dist/sql-runner.zip delete mode 100644 notes-python/terraform.tfstate.1773036471.backup delete mode 100644 notes-python/terraform.tfstate.1773036482.backup delete mode 100644 notes-python/terraform.tfstate.1773036493.backup delete mode 100644 notes-python/terraform.tfstate.1773036504.backup create mode 100755 run_terraform_examples.sh delete mode 100644 simple-node/dist/time_display.zip delete mode 100644 simple-node/dist/time_getter.zip delete mode 100644 simple-python/dist/time_display.zip delete mode 100644 simple-python/dist/time_getter.zip diff --git a/DESTROY_ROUTE_CLEANUP_BUG.md b/DESTROY_ROUTE_CLEANUP_BUG.md new file mode 100644 index 0000000..4dba243 --- /dev/null +++ b/DESTROY_ROUTE_CLEANUP_BUG.md @@ -0,0 +1,143 @@ +# Bug Report: HTTP route is not removed after Terraform destroy + +## Summary + +При удалении примера `hello-node` через Terraform команда `terraform destroy` завершается успешно, но публичный HTTP endpoint не удаляется. + +Фактическое поведение после `destroy` такое: + +1. Сразу после удаления endpoint ещё некоторое время отвечает `HTTP 200` и возвращает корректный ответ функции. +2. Затем backend функции действительно исчезает, но публичный маршрут остаётся опубликованным и начинает отвечать `HTTP 502 function unreachable`. +3. Даже через 120 секунд endpoint не исчезает. + +Это выглядит как баг cleanup в platform/backend/provider lifecycle для HTTP trigger/route. + +## Affected Example + +- Example: `hello-node` +- Terraform files: `hello-node/main.tf`, `hello-node/http.tf`, `hello-node/job.tf` +- Public URL: `https://sless-api.kube5s.ru/fn/default/hello-http` +- Function name: `hello-http` +- Trigger name: `hello-http-trigger` + +## Reproduction + +Использовался репозиторий examples и скрипт: + +- Script: `./run_terraform_examples.sh` + +Шаги воспроизведения: + +1. Выполнить `terraform init` в `hello-node` +2. Выполнить `terraform apply` +3. Убедиться, что endpoint живой +4. Выполнить `terraform destroy` +5. Проверять публичный URL после destroy + +Логика проверки встроена в `run_terraform_examples.sh`: + +1. После `apply` endpoint обязан отвечать `200` +2. После `destroy` endpoint должен исчезнуть +3. Скрипт ждёт до 120 секунд и перепроверяет endpoint каждые 5 секунд + +## Expected Result + +После успешного `terraform destroy`: + +1. Публичный URL должен перестать существовать +2. Запрос на URL должен вернуть `404` или другой явный признак отсутствия маршрута +3. Provider не должен возвращать успешный destroy раньше, чем cleanup HTTP route завершён + +## Actual Result + +После успешного `terraform destroy`: + +1. Terraform сообщает `Destroy complete! Resources: 4 destroyed.` +2. Endpoint `https://sless-api.kube5s.ru/fn/default/hello-http` продолжает отвечать `200` +3. Через некоторое время тот же endpoint начинает отвечать `502` +4. Тело ответа на `502`: + +```json +{"error":"function unreachable: Post \"http://hello-http.sless-fn-default.svc.cluster.local:8080\": dial tcp 10.106.128.167:8080: connect: operation not permitted"} +``` + +Это означает: + +1. внешний HTTP маршрут всё ещё существует; +2. запрос по нему всё ещё направляется внутрь платформы; +3. backend функции уже удалён или недоступен; +4. cleanup маршрута не завершён. + +## Timeline From Real Run + +Подтверждённая последовательность из фактического прогона: + +1. `terraform destroy` завершился успешно +2. первые проверки после destroy возвращали `HTTP 200` +3. затем проверки начали возвращать `HTTP 502 function unreachable` +4. в течение всех 24 проверок по 5 секунд endpoint не исчез +5. итоговое время ожидания: 120 секунд + +Итоговый summary из скрипта: + +```text +ERROR SUMMARY +example: hello-node +step: endpoint cleanup after clean destroy +reason: route cleanup bug: public endpoint still exists but backend is already gone (HTTP 502 function unreachable); endpoint was still published after 120s +``` + +## Why This Is A Real Platform Bug + +Это не похоже на проблему тестового скрипта или Terraform CLI по следующим причинам: + +1. `terraform destroy` завершается без ошибки +2. state Terraform очищается как ожидалось +3. сначала endpoint отвечает `200`, значит маршрут реально жив после destroy +4. потом endpoint отвечает `502 function unreachable`, значит backend уже исчез, но route ещё остался +5. скрипт ждёт 120 секунд, то есть это не мгновенная eventual consistency на 1-2 секунды + +Иными словами: удаление backend и удаление публичного маршрута расходятся по времени, а route cleanup либо не выполняется, либо не дожидается завершения. + +## Most Likely Broken Layer + +Наиболее вероятные точки проблемы: + +1. API/backend destroy trigger возвращает success до фактического удаления HTTP route +2. Controller удаляет function workload, но не удаляет route/ingress/virtualservice/gateway mapping +3. Удаление route запускается асинхронно, но его результат не awaited +4. В системе остаётся запись маршрута на имя функции, хотя service/backend уже удалён + +## What To Check In The Development Repo + +Нужно проверить destroy flow именно для HTTP trigger: + +1. Удаляется ли объект trigger только в metadata/storage или реально удаляется и внешний маршрут +2. Какие Kubernetes/ingress объекты создаются для HTTP trigger и все ли они удаляются +3. Есть ли race condition между удалением function/service и удалением route +4. Не возвращает ли provider success раньше, чем backend подтверждает полное удаление маршрута +5. Есть ли финальный polling/wait на исчезновение route перед возвратом успешного destroy + +Если архитектура использует отдельные сущности route/service/function, то destroy должен идти в таком порядке: + +1. disable/remove public routing +2. дождаться, что endpoint больше не публикуется снаружи +3. удалить backend/service/workload +4. завершить destroy success + +Сейчас по фактическому поведению порядок либо обратный, либо неполный. + +## Minimal Acceptance Criteria For Fix + +Исправление можно считать рабочим, если после `terraform destroy` для `hello-node` выполняются все условия: + +1. URL `https://sless-api.kube5s.ru/fn/default/hello-http` перестаёт отвечать как живой маршрут +2. URL не возвращает `502 function unreachable` +3. URL исчезает в разумное время после destroy +4. `./run_terraform_examples.sh` проходит шаг `endpoint cleanup after clean destroy` + +## Current Status + +На данный момент массовый прогон examples корректно останавливается на `hello-node`, потому что это первый воспроизводимый failure. + +Дальше прогонять остальные примеры без исправления destroy cleanup смысла нет: тест уже доказал platform bug на базовом HTTP сценарии. \ No newline at end of file diff --git a/hello-node/dist/handler-http.zip b/hello-node/dist/handler-http.zip deleted file mode 100644 index eb7a08c39dc9e992694803eb92910f08ba303b8a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 419 zcmWIWW@Zs#-~d7f2E{HQ0SEj*Rz_l8N=|B#ZbnH-fnHXz&V=(>j{+o)ey{8jmIz3k z)WLjsfkpQ8SdQ3h3&e9fJMUCSM}>Uw*POC#$IC_iiVKr&3DvfK-s?1fiOSngAO4=} z?-yptxFTJ@_m}+of9E-wdJa_xXuj=TGxvu$+x+hIl3jO&{qs`K&Us&S+{et<;Avy^ zvP}=d-tBzq7xo}f?92=?$7!3APW4#t7x?Tt&F0eq{>mqD*X&QQZEES9VwfH_pTFH} zaa2O;Zw2XRXP!3ZPf&kWqsuE<9C@|IJ=R|+xA*^F<69hOeebx3#;&|^?ZUtQmCOu( zRm{W+E%au5dNDoG%=xLw#fu9rX<4p)v$W6fXoRFNU#RfjzOF@2%=nXdnXv02iX7W&i*H diff --git a/hello-node/dist/handler-job.zip b/hello-node/dist/handler-job.zip deleted file mode 100644 index 5074c2f2c0a6de5a4e53260378065ac00abac461..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 506 zcmWIWW@Zs#-~d7f2E{HQ0SA0QRz_l8N=|B#ZdQJhURH6;1mCRN4l+l-TOEzQRg$yP zFS@Jua&t?-lam71Efz26zc7i#q%c!lH|4TxzoJv?)gQ{?75}xrsJIF#shxiKzi$6` ziTlSjB=$pst;_ zGgWoxnut@fPpq{I?`&XLZ56QpeZ&@bbxZGm5BpS4C*D1J|Iv>lw&tHEzYbIKd#A{E z@{-EQ_e)m(s{)c$X<_DA49QnBM{*N`(CT=Xe{qoLKML!vB zyOPgdc_KTqAIuTmuA_SVWOnPsLlX~4w{BlP?`MtV(M+S9|IEQHC&gD^%(nV9L+ljh=m$&0p6@^AW=pjv;op9 JfMzl<007fr)ky#V diff --git a/hello-node/terraform.tfstate.1772954131.backup b/hello-node/terraform.tfstate.1772954131.backup deleted file mode 100644 index f804125..0000000 --- a/hello-node/terraform.tfstate.1772954131.backup +++ /dev/null @@ -1,168 +0,0 @@ -{ - "version": 4, - "terraform_version": "1.12.2", - "serial": 22, - "lineage": "d12fc078-7aee-39d1-629d-358c3c135820", - "outputs": { - "trigger_url": { - "value": "https://sless-api.kube5s.ru/fn/default/hello-http", - "type": "string" - } - }, - "resources": [ - { - "mode": "data", - "type": "archive_file", - "name": "handler_http", - "provider": "provider[\"registry.terraform.io/hashicorp/archive\"]", - "instances": [ - { - "schema_version": 0, - "attributes": { - "exclude_symlink_directories": null, - "excludes": null, - "id": "16650367fe534ed2feb81be322fd4a9d80f77388", - "output_base64sha256": "/fY9RigPle6Yx9R9B9yEYmi5+jgL6PV3fmPlVK5ia3g=", - "output_base64sha512": "yKvMpTCZBynqV3LlE3wTZGMIS0EG0tY8LE+1iIETCuWGoc+bv4+Hlnve14bBWGOnvQHdqE84y4UDi8Pmnz1A2A==", - "output_file_mode": null, - "output_md5": "a74ae4ccb7337659439eacaf1831194d", - "output_path": "./handler-http.zip", - "output_sha": "16650367fe534ed2feb81be322fd4a9d80f77388", - "output_sha256": "fdf63d46280f95ee98c7d47d07dc846268b9fa380be8f5777e63e554ae626b78", - "output_sha512": "c8abcca530990729ea5772e5137c136463084b4106d2d63c2c4fb58881130ae586a1cf9bbf8f87967bded786c15863a7bd01dda84f38cb85038bc3e69f3d40d8", - "output_size": 409, - "source": [], - "source_content": null, - "source_content_filename": null, - "source_dir": null, - "source_file": "./code/handler-http.js", - "type": "zip" - }, - "sensitive_attributes": [], - "identity_schema_version": 0 - } - ] - }, - { - "mode": "data", - "type": "archive_file", - "name": "handler_job", - "provider": "provider[\"registry.terraform.io/hashicorp/archive\"]", - "instances": [ - { - "schema_version": 0, - "attributes": { - "exclude_symlink_directories": null, - "excludes": null, - "id": "27327ec4d4ab6d5d6fdc3f82a5ab768c68146a66", - "output_base64sha256": "cI+JbO5lWW+3qo4DSDg5HXLQS7EXHze2W6vGCNk0iOI=", - "output_base64sha512": "4D841Y2OT5EVlRbi/NwGh7SHnRzKgZ6AF1Rx+AIspPKthrbsZi8oGY6qLYe/NJ4t46j1Y8WkZ4tJ6iBpL5g7uw==", - "output_file_mode": null, - "output_md5": "2c5c498c77ec002df7cbeac94f626af8", - "output_path": "./handler-job.zip", - "output_sha": "27327ec4d4ab6d5d6fdc3f82a5ab768c68146a66", - "output_sha256": "708f896cee65596fb7aa8e034838391d72d04bb1171f37b65babc608d93488e2", - "output_sha512": "e03f38d58d8e4f91159516e2fcdc0687b4879d1cca819e80175471f8022ca4f2ad86b6ec662f28198eaa2d87bf349e2de3a8f563c5a4678b49ea20692f983bbb", - "output_size": 489, - "source": [], - "source_content": null, - "source_content_filename": null, - "source_dir": null, - "source_file": "./code/handler-job.js", - "type": "zip" - }, - "sensitive_attributes": [], - "identity_schema_version": 0 - } - ] - }, - { - "mode": "managed", - "type": "sless_function", - "name": "hello_http", - "provider": "provider[\"terra.k8c.ru/naeel/sless\"]", - "instances": [ - { - "schema_version": 0, - "attributes": { - "build_timeout_sec": 300, - "code_hash": "a74ae4ccb7337659439eacaf1831194d", - "code_path": "./handler-http.zip", - "entrypoint": "handler-http.handle", - "env_vars": null, - "image_ref": "pearlharbor.registryk8s.services.ngcloud.ru/sless/sless-default-hello-http:latest", - "memory_mb": 128, - "name": "hello-http", - "namespace": "default", - "phase": "Ready", - "runtime": "nodejs20", - "timeout_sec": 30 - }, - "sensitive_attributes": [], - "identity_schema_version": 0, - "dependencies": [ - "data.archive_file.handler_http" - ] - } - ] - }, - { - "mode": "managed", - "type": "sless_function", - "name": "hello_job", - "provider": "provider[\"terra.k8c.ru/naeel/sless\"]", - "instances": [ - { - "schema_version": 0, - "attributes": { - "build_timeout_sec": 300, - "code_hash": "2c5c498c77ec002df7cbeac94f626af8", - "code_path": "./handler-job.zip", - "entrypoint": "handler-job.handle", - "env_vars": null, - "image_ref": "pearlharbor.registryk8s.services.ngcloud.ru/sless/sless-default-hello-job:latest", - "memory_mb": 128, - "name": "hello-job", - "namespace": "default", - "phase": "Ready", - "runtime": "nodejs20", - "timeout_sec": 30 - }, - "sensitive_attributes": [], - "identity_schema_version": 0, - "dependencies": [ - "data.archive_file.handler_job" - ] - } - ] - }, - { - "mode": "managed", - "type": "sless_trigger", - "name": "hello_http", - "provider": "provider[\"terra.k8c.ru/naeel/sless\"]", - "instances": [ - { - "schema_version": 0, - "attributes": { - "active": true, - "enabled": true, - "function": "hello-http", - "name": "hello-http-trigger", - "namespace": "default", - "schedule": null, - "type": "http", - "url": "https://sless-api.kube5s.ru/fn/default/hello-http" - }, - "sensitive_attributes": [], - "identity_schema_version": 0, - "dependencies": [ - "data.archive_file.handler_http", - "sless_function.hello_http" - ] - } - ] - } - ], - "check_results": null -} diff --git a/hello-node/terraform.tfstate.1773029146.backup b/hello-node/terraform.tfstate.1773029146.backup deleted file mode 100644 index 1681c79..0000000 --- a/hello-node/terraform.tfstate.1773029146.backup +++ /dev/null @@ -1,209 +0,0 @@ -{ - "version": 4, - "terraform_version": "1.12.2", - "serial": 68, - "lineage": "d12fc078-7aee-39d1-629d-358c3c135820", - "outputs": { - "job_completion_time": { - "value": "2026-03-08T17:10:15Z", - "type": "string" - }, - "job_message": { - "value": "completed successfully", - "type": "string" - }, - "job_phase": { - "value": "Succeeded", - "type": "string" - }, - "trigger_url": { - "value": "https://sless-api.kube5s.ru/fn/default/hello-http", - "type": "string" - } - }, - "resources": [ - { - "mode": "data", - "type": "archive_file", - "name": "handler_http", - "provider": "provider[\"registry.terraform.io/hashicorp/archive\"]", - "instances": [ - { - "schema_version": 0, - "attributes": { - "exclude_symlink_directories": null, - "excludes": null, - "id": "af56405ad089f54b3382b1f8bbf648e9a4020186", - "output_base64sha256": "5k1JGBxCX5TLgrWRw8F4O3rMWu/4dprgLd9EH+maLx4=", - "output_base64sha512": "E6SsXf62mq4oPTpoiH9LXKdCy0nq4o8bANVfkYqd5JTvIGxXr/ow7DYqotFvJc1GIFMyo4etB54CKVduAEzWDw==", - "output_file_mode": null, - "output_md5": "8f2434a1fe0b8f791c4c39848c1c1db0", - "output_path": "./handler-http.zip", - "output_sha": "af56405ad089f54b3382b1f8bbf648e9a4020186", - "output_sha256": "e64d49181c425f94cb82b591c3c1783b7acc5aeff8769ae02ddf441fe99a2f1e", - "output_sha512": "13a4ac5dfeb69aae283d3a68887f4b5ca742cb49eae28f1b00d55f918a9de494ef206c57affa30ec362aa2d16f25cd46205332a387ad079e0229576e004cd60f", - "output_size": 419, - "source": [], - "source_content": null, - "source_content_filename": null, - "source_dir": null, - "source_file": "./code/handler-http.js", - "type": "zip" - }, - "sensitive_attributes": [], - "identity_schema_version": 0 - } - ] - }, - { - "mode": "data", - "type": "archive_file", - "name": "handler_job", - "provider": "provider[\"registry.terraform.io/hashicorp/archive\"]", - "instances": [ - { - "schema_version": 0, - "attributes": { - "exclude_symlink_directories": null, - "excludes": null, - "id": "e9056d193119214fe75cb187ca287199eaf326c9", - "output_base64sha256": "MbwoybKGBrsT3T/MrloAK0g+lu4qPCnAo1M0vAqR83Y=", - "output_base64sha512": "CHrmv338w4YGroUNZC7zR5vlgJvmrep5jToVJlPWjzEVeMO9J+eucD9LXzg89kzDsN/lVgCfQ3TvRE5RsOxugA==", - "output_file_mode": null, - "output_md5": "4aeae366572f35f199937c40c3708120", - "output_path": "./handler-job.zip", - "output_sha": "e9056d193119214fe75cb187ca287199eaf326c9", - "output_sha256": "31bc28c9b28606bb13dd3fccae5a002b483e96ee2a3c29c0a35334bc0a91f376", - "output_sha512": "087ae6bf7dfcc38606ae850d642ef3479be5809be6adea798d3a152653d68f311578c3bd27e7ae703f4b5f383cf64cc3b0dfe556009f4374ef444e51b0ec6e80", - "output_size": 506, - "source": [], - "source_content": null, - "source_content_filename": null, - "source_dir": null, - "source_file": "./code/handler-job.js", - "type": "zip" - }, - "sensitive_attributes": [], - "identity_schema_version": 0 - } - ] - }, - { - "mode": "managed", - "type": "sless_function", - "name": "hello_http", - "provider": "provider[\"terra.k8c.ru/naeel/sless\"]", - "instances": [ - { - "schema_version": 0, - "attributes": { - "build_timeout_sec": 300, - "code_hash": "c9755d3a41cd22734918ed9c6350394cb70ddc4104031bcd8edd5e5fed9a1963", - "code_path": "./handler-http.zip", - "entrypoint": "handler-http.handle", - "env_vars": null, - "image_ref": "naeel/sless-default-hello-http:072b89774248", - "memory_mb": 128, - "name": "hello-http", - "namespace": "default", - "phase": "Ready", - "runtime": "nodejs20", - "timeout_sec": 30 - }, - "sensitive_attributes": [], - "identity_schema_version": 0, - "dependencies": [ - "data.archive_file.handler_http" - ] - } - ] - }, - { - "mode": "managed", - "type": "sless_function", - "name": "hello_job", - "provider": "provider[\"terra.k8c.ru/naeel/sless\"]", - "instances": [ - { - "schema_version": 0, - "attributes": { - "build_timeout_sec": 300, - "code_hash": "4155f9367b1999fb0f80460e919dac79b6af559a603cf938d70a2a322fccc7ec", - "code_path": "./handler-job.zip", - "entrypoint": "handler-job.handle", - "env_vars": null, - "image_ref": "naeel/sless-default-hello-job:67f12d5519e3", - "memory_mb": 128, - "name": "hello-job", - "namespace": "default", - "phase": "Ready", - "runtime": "nodejs20", - "timeout_sec": 30 - }, - "sensitive_attributes": [], - "identity_schema_version": 0, - "dependencies": [ - "data.archive_file.handler_job" - ] - } - ] - }, - { - "mode": "managed", - "type": "sless_job", - "name": "hello_run", - "provider": "provider[\"terra.k8c.ru/naeel/sless\"]", - "instances": [ - { - "schema_version": 0, - "attributes": { - "completion_time": "2026-03-08T17:10:15Z", - "event_json": "{\"numbers\":[10,20,30,40,50]}", - "function": "hello-job", - "message": "completed successfully", - "name": "hello-run", - "namespace": "default", - "phase": "Succeeded", - "run_id": 8, - "start_time": "2026-03-08T17:10:05Z", - "wait_timeout_sec": 600 - }, - "sensitive_attributes": [], - "identity_schema_version": 0, - "dependencies": [ - "data.archive_file.handler_job", - "sless_function.hello_job" - ] - } - ] - }, - { - "mode": "managed", - "type": "sless_trigger", - "name": "hello_http", - "provider": "provider[\"terra.k8c.ru/naeel/sless\"]", - "instances": [ - { - "schema_version": 0, - "attributes": { - "active": true, - "enabled": true, - "function": "hello-http", - "name": "hello-http-trigger", - "namespace": "default", - "schedule": null, - "type": "http", - "url": "https://sless-api.kube5s.ru/fn/default/hello-http" - }, - "sensitive_attributes": [], - "identity_schema_version": 0, - "dependencies": [ - "data.archive_file.handler_http", - "sless_function.hello_http" - ] - } - ] - } - ], - "check_results": null -} diff --git a/notes-python/dist/notes-list.zip b/notes-python/dist/notes-list.zip deleted file mode 100644 index bcf1f18c3e5824027b89214691d1bfaf91317062..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 962 zcmWIWW@Zs#-~d7f2E{HQ0SCN5R$hKdYH@r{W^svLL1oG0hgpx^1di{2t;zPYIW^#l zN#iB1PfIsW4!UJ=qcOYSH*9OlPm=Ig_@IxW{@mkw=q9ywzv-SYPh>oR(b zW0Lxe4`}ulxcz57XLz{!%vHgBhT=KQy@rSTcN~}#cVUT(rQ6XJ4Ev7rJl}DoXPsPx zUV>xto?|`7zHohzV9?ata+3q-i*Rz25P$v-72 zPAy^Css|ei7fHn=@Et$<&C_z~tjxxv=KsIUl+gOxbBSHnD|3;S-9sVn*2Po)ExvBD zOmOc-rTmQtEd4?`_r{$3b0<$OS2IxRB1iF@TUmWgK~maGVirfE&%^|T%(>+9bLTe0 zaNjc;v94>TFIhC(R6Wwa zv%YyLb^LvI3-{`pl3nxkcS^jo%{-fFsK2Ux-<|83TYV=SW;^rVJIyw3RsYSrKbLOU zHyUhkl+J1{x_Ix$^VslBjV;Y#pRa$~+w}a};To6qQ(6C;2O58Ay_|aK|LJa}Y~@oa z@ka`zTJ~*m;oTL}&|q*ab!l?WgU$0=+UiwV2ddcA% z-HUvkw@wxGpAl-jkA;EZ|Nj7Qc8+gnC$=qNVqmBTiUiZo0?Zr ztXEP|qNTCU=bXNW`6b^|XS{V*Jz;{Ic|ES-rx;KNNLPS2Ba;X-BGVw-2g)=su%r>h mLdintT9J(f84UwV8t(%=fbP5iZ&o&t3ML?|1k%RLARYj}pN*ve diff --git a/notes-python/dist/notes.zip b/notes-python/dist/notes.zip deleted file mode 100644 index 628ff161aa7ed89599101bd78487c5523f105fe5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1490 zcmWIWW@Zs#-~d7f2E{HQ0SCN5R$hKdYH@sWQE7@^LFJjSyIIoiBKxif%cRVSJyrq zOrB!AdsFzN+)LeC?nZBVmAL=M=DJ?zz0Voy4orOa$Yc9iv%Z4)Z9DpF?_RaFIbg?E zBL2alyujgidIbrMXSY}tq$@!Ugr+l}4;8Ff%-9Jh8U5j^D zIMfR0v@*dgzjyo&3W~K>h;om8}7(%HiM5fHGidF@b!J*;O|w*-(0hQFOy}Sk^jfrO;h*nC=6wD zGEqeN_G#-C=3!*=r|)VGx8uX+CNhQyMWX=hTo zl~i3n{JA5Mw$XvT&(p`sy_}`r^RDN{$rG4n8a>wf?as7gzjrks|0VvH?YHZR>Yk^vC)Cd^2waqW zuc30Ekm6Eri^_9Tb0z2Lu&;4l{Xpoy@9ef`f1X_lJiPGffp30_>3lyD9SWYWy)@_d zskFce3K}=PZka4k=2R7a{A**6Q>ME8)?Lq62W;~Sp0ZQ)o$0ie_3vgSXZlsS{M|EM zC_*mznyc94X?o045{xzP_^f4WF}m%y=~ctjGV8h*|6-0@%2B(bbIz^HYVWeiZzi)| zRNmQ@%5Yn3y3v#{!AV>WE($->bX3x>opYHY?>#-g&_3+WyvEb^5plZVt3D*`{H5`; zoZ&Wu)v{)$n)2rlqbfz;{5;Y4bH#-Dt_@y0cZEgPZK&aADOM1E+n~R5xy9uWla*LHD;JndKJ3$Hn2IpL>Rb&gY!IhxsMn zQ)j$&Ry|yj(J-*2 Z@jcLLbms+lv$BCyFacpDkalJT@c^vPk17BF diff --git a/notes-python/dist/sql-runner.zip b/notes-python/dist/sql-runner.zip deleted file mode 100644 index 6ae5e844a0ad54732caefd241b4634599c86dbe6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1039 zcmWIWW@Zs#-~d7f2E{HQ0S5v=R#9qUX=YJsZfaghv0h0v0V~#eh0Mx&m;T$qSS%F3gE9D$UDFEz&EfED5=rCG9S<@BVU& z2yyMky{391S|41aRA#RlDZ7=r5J0Jz>)(?bvnU&AA%;^nJxQgx0QISG#G`uaBo*EsyJ*w7BB_wyj}i z8FMe}pF6+vyn$OAW80mFdcSr&2)<2ob zQNN&H@Ysvb**tTvZ19r!@U!RO^gEBa54BjIn3&koC?lfhT*RmRWjVvUPnL;FR}(t6 zzetXG;Br5=&qG#wF59Djuh$suJJ507;E7!M&q*KD?>#90(|Z3y+QgYhv^>ArbK-Y^OKw zco=?S!cMpUk5r5%ne0&Cq*sxcCUIKCKc#HB^54de2gUCmx}EtM)3rlhv`+P^2lK?o zdLI@Yp0-hQX3DoKUVcuOtF}F>jB_?Ux$SFRk;wE|Wvx*Erc9Mt*G{T5UOGO}wCZ~O zpQrzho!hqmd7rpblz!XynO>*=)!dI?c6V;#RiChwZs}P)ffKvAE*B|Z3|@a_-kGb1w=FF_&Ut8?Z;x*HyYsV- zo!Z{4^fw`q)iyvs-u+%1FFoBE z`t*w6)$V|;L92GE8qMMp3c6Z8cTMNx^Ysk%~kwbN$Fm(3P-mHw(dzKc$Y zzTXc_`;fe{vDNX`M?j2IVyvSkf2* XWTND}0B=?{kTeqzRs!h;W)KemGFHrS diff --git a/notes-python/terraform.tfstate.1773036471.backup b/notes-python/terraform.tfstate.1773036471.backup deleted file mode 100644 index f0b6146..0000000 --- a/notes-python/terraform.tfstate.1773036471.backup +++ /dev/null @@ -1,369 +0,0 @@ -{ - "version": 4, - "terraform_version": "1.12.2", - "serial": 15, - "lineage": "46b43916-6d6b-060c-ad36-6176e18b5f7b", - "outputs": { - "notes_list_url": { - "value": "https://sless-api.kube5s.ru/fn/default/notes-list", - "type": "string" - }, - "notes_url": { - "value": "https://sless-api.kube5s.ru/fn/default/notes", - "type": "string" - } - }, - "resources": [ - { - "mode": "data", - "type": "archive_file", - "name": "notes", - "provider": "provider[\"registry.terraform.io/hashicorp/archive\"]", - "instances": [ - { - "schema_version": 0, - "attributes": { - "exclude_symlink_directories": null, - "excludes": null, - "id": "d1fed6f90a4b4fde556aa2cd18e6ffaa9877c377", - "output_base64sha256": "HMlgBvSu0gccGVilru2ybzC7v31uzG1Zy96bK4p+C1E=", - "output_base64sha512": "GoV68HbQgbVaBtR4v1kLUhh+kMpJRIoBz30SrgYlVGz13SzV1wZ/lPvedqYvhmirG0fQf63wHYThOmvOR7lvgQ==", - "output_file_mode": null, - "output_md5": "cf96673e4f09c58d2e49c1664cdee1c2", - "output_path": "./dist/notes.zip", - "output_sha": "d1fed6f90a4b4fde556aa2cd18e6ffaa9877c377", - "output_sha256": "1cc96006f4aed2071c1958a5aeedb26f30bbbf7d6ecc6d59cbde9b2b8a7e0b51", - "output_sha512": "1a857af076d081b55a06d478bf590b52187e90ca49448a01cf7d12ae0625546cf5dd2cd5d7067f94fbde76a62f8668ab1b47d07fadf01d84e13a6bce47b96f81", - "output_size": 1226, - "source": [], - "source_content": null, - "source_content_filename": null, - "source_dir": "./code/notes", - "source_file": null, - "type": "zip" - }, - "sensitive_attributes": [], - "identity_schema_version": 0 - } - ] - }, - { - "mode": "data", - "type": "archive_file", - "name": "notes_list", - "provider": "provider[\"registry.terraform.io/hashicorp/archive\"]", - "instances": [ - { - "schema_version": 0, - "attributes": { - "exclude_symlink_directories": null, - "excludes": null, - "id": "b5730a0d98ae778f80c27881147e14d060151fce", - "output_base64sha256": "1pbtfCE8qjpAP5Ddz9c9afhOUXq3aq56ordi5t4vX00=", - "output_base64sha512": "nTUnbRKT4d5g5g3HANTGxZi5FmUIaM3C660XzZmGQLJIQ+WNYNLJ/no/H30KzafwE1mJf2qkdcZ8cT3xZdciNg==", - "output_file_mode": null, - "output_md5": "090088f39e1ef9d8d7d152944441edb7", - "output_path": "./dist/notes-list.zip", - "output_sha": "b5730a0d98ae778f80c27881147e14d060151fce", - "output_sha256": "d696ed7c213caa3a403f90ddcfd73d69f84e517ab76aae7aa2b762e6de2f5f4d", - "output_sha512": "9d35276d1293e1de60e60dc700d4c6c598b916650868cdc2ebad17cd998640b24843e58d60d2c9fe7a3f1f7d0acda7f01359897f6aa475c67c713df165d72236", - "output_size": 746, - "source": [], - "source_content": null, - "source_content_filename": null, - "source_dir": "./code/notes-list", - "source_file": null, - "type": "zip" - }, - "sensitive_attributes": [], - "identity_schema_version": 0 - } - ] - }, - { - "mode": "data", - "type": "archive_file", - "name": "sql_runner", - "provider": "provider[\"registry.terraform.io/hashicorp/archive\"]", - "instances": [ - { - "schema_version": 0, - "attributes": { - "exclude_symlink_directories": null, - "excludes": null, - "id": "241f12b31b5d970c697341292954b220e44f8d2a", - "output_base64sha256": "w/IUipIki9V1lf33x06/gHq+KWVdfJO9Ni98DkhC+Xw=", - "output_base64sha512": "aLpBXApQ5Nltm6ODUqQc6VZQCoxgn68mHlcrOF8bFrdem8psnz7dujkJE5PYvB5VDNKmdsViDAKPNTwHxut4XA==", - "output_file_mode": null, - "output_md5": "1fe2ab7afe4730b1141146363d69bd23", - "output_path": "./dist/sql-runner.zip", - "output_sha": "241f12b31b5d970c697341292954b220e44f8d2a", - "output_sha256": "c3f2148a92248bd57595fdf7c74ebf807abe29655d7c93bd362f7c0e4842f97c", - "output_sha512": "68ba415c0a50e4d96d9ba38352a41ce956500a8c609faf261e572b385f1b16b75e9bca6c9f3eddba39091393d8bc1e550cd2a676c5620c028f353c07c6eb785c", - "output_size": 796, - "source": [], - "source_content": null, - "source_content_filename": null, - "source_dir": "./code/sql-runner", - "source_file": null, - "type": "zip" - }, - "sensitive_attributes": [], - "identity_schema_version": 0 - } - ] - }, - { - "mode": "managed", - "type": "sless_function", - "name": "notes", - "provider": "provider[\"terra.k8c.ru/naeel/sless\"]", - "instances": [ - { - "schema_version": 0, - "attributes": { - "build_timeout_sec": 300, - "code_hash": "aaefd6de16697af6ac7331c7e1795a5446c71e351e6cacc3f4b490b683feb0cb", - "code_path": "./dist/notes.zip", - "entrypoint": "handler.handle", - "env_vars": { - "PG_DSN": "postgres://sless:sless-pg-password@postgres.sless.svc.cluster.local:5432/sless?sslmode=disable" - }, - "image_ref": "naeel/sless-default-notes:80b15a8b73f5", - "memory_mb": 128, - "name": "notes", - "namespace": "default", - "phase": "Ready", - "runtime": "python3.11", - "timeout_sec": 30 - }, - "sensitive_attributes": [ - [ - { - "type": "get_attr", - "value": "env_vars" - }, - { - "type": "index", - "value": { - "value": "PG_DSN", - "type": "string" - } - } - ] - ], - "identity_schema_version": 0, - "dependencies": [ - "data.archive_file.notes" - ] - } - ] - }, - { - "mode": "managed", - "type": "sless_function", - "name": "notes_list", - "provider": "provider[\"terra.k8c.ru/naeel/sless\"]", - "instances": [ - { - "schema_version": 0, - "attributes": { - "build_timeout_sec": 300, - "code_hash": "4091f7c79ca8c9c5663c812eb08f25ef5257af217bf2b412add670a4737b9d7f", - "code_path": "./dist/notes-list.zip", - "entrypoint": "handler.handle", - "env_vars": { - "PG_DSN": "postgres://sless:sless-pg-password@postgres.sless.svc.cluster.local:5432/sless?sslmode=disable" - }, - "image_ref": "naeel/sless-default-notes-list:07f2d5ae5ee4", - "memory_mb": 128, - "name": "notes-list", - "namespace": "default", - "phase": "Ready", - "runtime": "python3.11", - "timeout_sec": 30 - }, - "sensitive_attributes": [ - [ - { - "type": "get_attr", - "value": "env_vars" - }, - { - "type": "index", - "value": { - "value": "PG_DSN", - "type": "string" - } - } - ] - ], - "identity_schema_version": 0, - "dependencies": [ - "data.archive_file.notes_list" - ] - } - ] - }, - { - "mode": "managed", - "type": "sless_function", - "name": "sql_runner", - "provider": "provider[\"terra.k8c.ru/naeel/sless\"]", - "instances": [ - { - "schema_version": 0, - "attributes": { - "build_timeout_sec": 300, - "code_hash": "fcde93e59e6fd7f3db426482da7667d5d402aaaaaf56f79a7a60bb1722ec603a", - "code_path": "./dist/sql-runner.zip", - "entrypoint": "handler.handle", - "env_vars": { - "PG_DSN": "postgres://sless:sless-pg-password@postgres.sless.svc.cluster.local:5432/sless?sslmode=disable" - }, - "image_ref": "naeel/sless-default-sql-runner:22bce581a299", - "memory_mb": 128, - "name": "sql-runner", - "namespace": "default", - "phase": "Ready", - "runtime": "python3.11", - "timeout_sec": 30 - }, - "sensitive_attributes": [ - [ - { - "type": "get_attr", - "value": "env_vars" - }, - { - "type": "index", - "value": { - "value": "PG_DSN", - "type": "string" - } - } - ] - ], - "identity_schema_version": 0, - "dependencies": [ - "data.archive_file.sql_runner" - ] - } - ] - }, - { - "mode": "managed", - "type": "sless_job", - "name": "create_index", - "provider": "provider[\"terra.k8c.ru/naeel/sless\"]", - "instances": [ - { - "schema_version": 0, - "attributes": { - "completion_time": "2026-03-09T05:44:59Z", - "event_json": "{\"statements\":[\"CREATE INDEX IF NOT EXISTS notes_created_idx ON notes(created_at DESC)\"]}", - "function": "sql-runner", - "message": "completed successfully", - "name": "notes-create-index", - "namespace": "default", - "phase": "Succeeded", - "run_id": 1, - "start_time": "2026-03-09T05:44:54Z", - "wait_timeout_sec": 60 - }, - "sensitive_attributes": [], - "identity_schema_version": 0, - "dependencies": [ - "data.archive_file.sql_runner", - "sless_function.sql_runner", - "sless_job.create_table" - ] - } - ] - }, - { - "mode": "managed", - "type": "sless_job", - "name": "create_table", - "provider": "provider[\"terra.k8c.ru/naeel/sless\"]", - "instances": [ - { - "schema_version": 0, - "attributes": { - "completion_time": "2026-03-09T05:44:54Z", - "event_json": "{\"statements\":[\"CREATE TABLE IF NOT EXISTS notes (id serial PRIMARY KEY, title text NOT NULL, body text, created_at timestamp DEFAULT now())\"]}", - "function": "sql-runner", - "message": "completed successfully", - "name": "notes-create-table", - "namespace": "default", - "phase": "Succeeded", - "run_id": 1, - "start_time": "2026-03-09T05:44:39Z", - "wait_timeout_sec": 120 - }, - "sensitive_attributes": [], - "identity_schema_version": 0, - "dependencies": [ - "data.archive_file.sql_runner", - "sless_function.sql_runner" - ] - } - ] - }, - { - "mode": "managed", - "type": "sless_trigger", - "name": "notes_http", - "provider": "provider[\"terra.k8c.ru/naeel/sless\"]", - "instances": [ - { - "schema_version": 0, - "attributes": { - "active": true, - "enabled": true, - "function": "notes", - "name": "notes-http", - "namespace": "default", - "schedule": null, - "type": "http", - "url": "https://sless-api.kube5s.ru/fn/default/notes" - }, - "sensitive_attributes": [], - "identity_schema_version": 0, - "dependencies": [ - "data.archive_file.notes", - "sless_function.notes" - ] - } - ] - }, - { - "mode": "managed", - "type": "sless_trigger", - "name": "notes_list_http", - "provider": "provider[\"terra.k8c.ru/naeel/sless\"]", - "instances": [ - { - "schema_version": 0, - "attributes": { - "active": true, - "enabled": true, - "function": "notes-list", - "name": "notes-list-http", - "namespace": "default", - "schedule": null, - "type": "http", - "url": "https://sless-api.kube5s.ru/fn/default/notes-list" - }, - "sensitive_attributes": [], - "identity_schema_version": 0, - "dependencies": [ - "data.archive_file.notes_list", - "sless_function.notes_list" - ] - } - ] - } - ], - "check_results": null -} diff --git a/notes-python/terraform.tfstate.1773036482.backup b/notes-python/terraform.tfstate.1773036482.backup deleted file mode 100644 index b6402da..0000000 --- a/notes-python/terraform.tfstate.1773036482.backup +++ /dev/null @@ -1,365 +0,0 @@ -{ - "version": 4, - "terraform_version": "1.12.2", - "serial": 16, - "lineage": "46b43916-6d6b-060c-ad36-6176e18b5f7b", - "outputs": { - "notes_list_url": { - "value": "https://sless-api.kube5s.ru/fn/default/notes-list", - "type": "string" - }, - "notes_url": { - "value": "https://sless-api.kube5s.ru/fn/default/notes", - "type": "string" - } - }, - "resources": [ - { - "mode": "data", - "type": "archive_file", - "name": "notes", - "provider": "provider[\"registry.terraform.io/hashicorp/archive\"]", - "instances": [ - { - "schema_version": 0, - "attributes": { - "exclude_symlink_directories": null, - "excludes": null, - "id": "d1fed6f90a4b4fde556aa2cd18e6ffaa9877c377", - "output_base64sha256": "HMlgBvSu0gccGVilru2ybzC7v31uzG1Zy96bK4p+C1E=", - "output_base64sha512": "GoV68HbQgbVaBtR4v1kLUhh+kMpJRIoBz30SrgYlVGz13SzV1wZ/lPvedqYvhmirG0fQf63wHYThOmvOR7lvgQ==", - "output_file_mode": null, - "output_md5": "cf96673e4f09c58d2e49c1664cdee1c2", - "output_path": "./dist/notes.zip", - "output_sha": "d1fed6f90a4b4fde556aa2cd18e6ffaa9877c377", - "output_sha256": "1cc96006f4aed2071c1958a5aeedb26f30bbbf7d6ecc6d59cbde9b2b8a7e0b51", - "output_sha512": "1a857af076d081b55a06d478bf590b52187e90ca49448a01cf7d12ae0625546cf5dd2cd5d7067f94fbde76a62f8668ab1b47d07fadf01d84e13a6bce47b96f81", - "output_size": 1226, - "source": [], - "source_content": null, - "source_content_filename": null, - "source_dir": "./code/notes", - "source_file": null, - "type": "zip" - }, - "sensitive_attributes": [], - "identity_schema_version": 0 - } - ] - }, - { - "mode": "data", - "type": "archive_file", - "name": "notes_list", - "provider": "provider[\"registry.terraform.io/hashicorp/archive\"]", - "instances": [ - { - "schema_version": 0, - "attributes": { - "exclude_symlink_directories": null, - "excludes": null, - "id": "b5730a0d98ae778f80c27881147e14d060151fce", - "output_base64sha256": "1pbtfCE8qjpAP5Ddz9c9afhOUXq3aq56ordi5t4vX00=", - "output_base64sha512": "nTUnbRKT4d5g5g3HANTGxZi5FmUIaM3C660XzZmGQLJIQ+WNYNLJ/no/H30KzafwE1mJf2qkdcZ8cT3xZdciNg==", - "output_file_mode": null, - "output_md5": "090088f39e1ef9d8d7d152944441edb7", - "output_path": "./dist/notes-list.zip", - "output_sha": "b5730a0d98ae778f80c27881147e14d060151fce", - "output_sha256": "d696ed7c213caa3a403f90ddcfd73d69f84e517ab76aae7aa2b762e6de2f5f4d", - "output_sha512": "9d35276d1293e1de60e60dc700d4c6c598b916650868cdc2ebad17cd998640b24843e58d60d2c9fe7a3f1f7d0acda7f01359897f6aa475c67c713df165d72236", - "output_size": 746, - "source": [], - "source_content": null, - "source_content_filename": null, - "source_dir": "./code/notes-list", - "source_file": null, - "type": "zip" - }, - "sensitive_attributes": [], - "identity_schema_version": 0 - } - ] - }, - { - "mode": "data", - "type": "archive_file", - "name": "sql_runner", - "provider": "provider[\"registry.terraform.io/hashicorp/archive\"]", - "instances": [ - { - "schema_version": 0, - "attributes": { - "exclude_symlink_directories": null, - "excludes": null, - "id": "241f12b31b5d970c697341292954b220e44f8d2a", - "output_base64sha256": "w/IUipIki9V1lf33x06/gHq+KWVdfJO9Ni98DkhC+Xw=", - "output_base64sha512": "aLpBXApQ5Nltm6ODUqQc6VZQCoxgn68mHlcrOF8bFrdem8psnz7dujkJE5PYvB5VDNKmdsViDAKPNTwHxut4XA==", - "output_file_mode": null, - "output_md5": "1fe2ab7afe4730b1141146363d69bd23", - "output_path": "./dist/sql-runner.zip", - "output_sha": "241f12b31b5d970c697341292954b220e44f8d2a", - "output_sha256": "c3f2148a92248bd57595fdf7c74ebf807abe29655d7c93bd362f7c0e4842f97c", - "output_sha512": "68ba415c0a50e4d96d9ba38352a41ce956500a8c609faf261e572b385f1b16b75e9bca6c9f3eddba39091393d8bc1e550cd2a676c5620c028f353c07c6eb785c", - "output_size": 796, - "source": [], - "source_content": null, - "source_content_filename": null, - "source_dir": "./code/sql-runner", - "source_file": null, - "type": "zip" - }, - "sensitive_attributes": [], - "identity_schema_version": 0 - } - ] - }, - { - "mode": "managed", - "type": "sless_function", - "name": "notes_crud", - "provider": "provider[\"terra.k8c.ru/naeel/sless\"]", - "instances": [ - { - "schema_version": 0, - "attributes": { - "build_timeout_sec": 300, - "code_hash": "aaefd6de16697af6ac7331c7e1795a5446c71e351e6cacc3f4b490b683feb0cb", - "code_path": "./dist/notes.zip", - "entrypoint": "handler.handle", - "env_vars": { - "PG_DSN": "postgres://sless:sless-pg-password@postgres.sless.svc.cluster.local:5432/sless?sslmode=disable" - }, - "image_ref": "naeel/sless-default-notes:80b15a8b73f5", - "memory_mb": 128, - "name": "notes", - "namespace": "default", - "phase": "Ready", - "runtime": "python3.11", - "timeout_sec": 30 - }, - "sensitive_attributes": [ - [ - { - "type": "get_attr", - "value": "env_vars" - }, - { - "type": "index", - "value": { - "value": "PG_DSN", - "type": "string" - } - } - ] - ], - "identity_schema_version": 0, - "dependencies": [ - "data.archive_file.notes" - ] - } - ] - }, - { - "mode": "managed", - "type": "sless_function", - "name": "notes_list", - "provider": "provider[\"terra.k8c.ru/naeel/sless\"]", - "instances": [ - { - "schema_version": 0, - "attributes": { - "build_timeout_sec": 300, - "code_hash": "4091f7c79ca8c9c5663c812eb08f25ef5257af217bf2b412add670a4737b9d7f", - "code_path": "./dist/notes-list.zip", - "entrypoint": "handler.handle", - "env_vars": { - "PG_DSN": "postgres://sless:sless-pg-password@postgres.sless.svc.cluster.local:5432/sless?sslmode=disable" - }, - "image_ref": "naeel/sless-default-notes-list:07f2d5ae5ee4", - "memory_mb": 128, - "name": "notes-list", - "namespace": "default", - "phase": "Ready", - "runtime": "python3.11", - "timeout_sec": 30 - }, - "sensitive_attributes": [ - [ - { - "type": "get_attr", - "value": "env_vars" - }, - { - "type": "index", - "value": { - "value": "PG_DSN", - "type": "string" - } - } - ] - ], - "identity_schema_version": 0, - "dependencies": [ - "data.archive_file.notes_list" - ] - } - ] - }, - { - "mode": "managed", - "type": "sless_function", - "name": "sql_runner", - "provider": "provider[\"terra.k8c.ru/naeel/sless\"]", - "instances": [ - { - "schema_version": 0, - "attributes": { - "build_timeout_sec": 300, - "code_hash": "fcde93e59e6fd7f3db426482da7667d5d402aaaaaf56f79a7a60bb1722ec603a", - "code_path": "./dist/sql-runner.zip", - "entrypoint": "handler.handle", - "env_vars": { - "PG_DSN": "postgres://sless:sless-pg-password@postgres.sless.svc.cluster.local:5432/sless?sslmode=disable" - }, - "image_ref": "naeel/sless-default-sql-runner:22bce581a299", - "memory_mb": 128, - "name": "sql-runner", - "namespace": "default", - "phase": "Ready", - "runtime": "python3.11", - "timeout_sec": 30 - }, - "sensitive_attributes": [ - [ - { - "type": "get_attr", - "value": "env_vars" - }, - { - "type": "index", - "value": { - "value": "PG_DSN", - "type": "string" - } - } - ] - ], - "identity_schema_version": 0, - "dependencies": [ - "data.archive_file.sql_runner" - ] - } - ] - }, - { - "mode": "managed", - "type": "sless_job", - "name": "create_index", - "provider": "provider[\"terra.k8c.ru/naeel/sless\"]", - "instances": [ - { - "schema_version": 0, - "attributes": { - "completion_time": "2026-03-09T05:44:59Z", - "event_json": "{\"statements\":[\"CREATE INDEX IF NOT EXISTS notes_created_idx ON notes(created_at DESC)\"]}", - "function": "sql-runner", - "message": "completed successfully", - "name": "notes-create-index", - "namespace": "default", - "phase": "Succeeded", - "run_id": 1, - "start_time": "2026-03-09T05:44:54Z", - "wait_timeout_sec": 60 - }, - "sensitive_attributes": [], - "identity_schema_version": 0, - "dependencies": [ - "data.archive_file.sql_runner", - "sless_function.sql_runner", - "sless_job.create_table" - ] - } - ] - }, - { - "mode": "managed", - "type": "sless_job", - "name": "create_table", - "provider": "provider[\"terra.k8c.ru/naeel/sless\"]", - "instances": [ - { - "schema_version": 0, - "attributes": { - "completion_time": "2026-03-09T05:44:54Z", - "event_json": "{\"statements\":[\"CREATE TABLE IF NOT EXISTS notes (id serial PRIMARY KEY, title text NOT NULL, body text, created_at timestamp DEFAULT now())\"]}", - "function": "sql-runner", - "message": "completed successfully", - "name": "notes-create-table", - "namespace": "default", - "phase": "Succeeded", - "run_id": 1, - "start_time": "2026-03-09T05:44:39Z", - "wait_timeout_sec": 120 - }, - "sensitive_attributes": [], - "identity_schema_version": 0, - "dependencies": [ - "data.archive_file.sql_runner", - "sless_function.sql_runner" - ] - } - ] - }, - { - "mode": "managed", - "type": "sless_trigger", - "name": "notes_http", - "provider": "provider[\"terra.k8c.ru/naeel/sless\"]", - "instances": [ - { - "schema_version": 0, - "attributes": { - "active": true, - "enabled": true, - "function": "notes", - "name": "notes-http", - "namespace": "default", - "schedule": null, - "type": "http", - "url": "https://sless-api.kube5s.ru/fn/default/notes" - }, - "sensitive_attributes": [], - "identity_schema_version": 0 - } - ] - }, - { - "mode": "managed", - "type": "sless_trigger", - "name": "notes_list_http", - "provider": "provider[\"terra.k8c.ru/naeel/sless\"]", - "instances": [ - { - "schema_version": 0, - "attributes": { - "active": true, - "enabled": true, - "function": "notes-list", - "name": "notes-list-http", - "namespace": "default", - "schedule": null, - "type": "http", - "url": "https://sless-api.kube5s.ru/fn/default/notes-list" - }, - "sensitive_attributes": [], - "identity_schema_version": 0, - "dependencies": [ - "data.archive_file.notes_list", - "sless_function.notes_list" - ] - } - ] - } - ], - "check_results": null -} diff --git a/notes-python/terraform.tfstate.1773036493.backup b/notes-python/terraform.tfstate.1773036493.backup deleted file mode 100644 index a4b3e6a..0000000 --- a/notes-python/terraform.tfstate.1773036493.backup +++ /dev/null @@ -1,365 +0,0 @@ -{ - "version": 4, - "terraform_version": "1.12.2", - "serial": 17, - "lineage": "46b43916-6d6b-060c-ad36-6176e18b5f7b", - "outputs": { - "notes_list_url": { - "value": "https://sless-api.kube5s.ru/fn/default/notes-list", - "type": "string" - }, - "notes_url": { - "value": "https://sless-api.kube5s.ru/fn/default/notes", - "type": "string" - } - }, - "resources": [ - { - "mode": "data", - "type": "archive_file", - "name": "notes", - "provider": "provider[\"registry.terraform.io/hashicorp/archive\"]", - "instances": [ - { - "schema_version": 0, - "attributes": { - "exclude_symlink_directories": null, - "excludes": null, - "id": "d1fed6f90a4b4fde556aa2cd18e6ffaa9877c377", - "output_base64sha256": "HMlgBvSu0gccGVilru2ybzC7v31uzG1Zy96bK4p+C1E=", - "output_base64sha512": "GoV68HbQgbVaBtR4v1kLUhh+kMpJRIoBz30SrgYlVGz13SzV1wZ/lPvedqYvhmirG0fQf63wHYThOmvOR7lvgQ==", - "output_file_mode": null, - "output_md5": "cf96673e4f09c58d2e49c1664cdee1c2", - "output_path": "./dist/notes.zip", - "output_sha": "d1fed6f90a4b4fde556aa2cd18e6ffaa9877c377", - "output_sha256": "1cc96006f4aed2071c1958a5aeedb26f30bbbf7d6ecc6d59cbde9b2b8a7e0b51", - "output_sha512": "1a857af076d081b55a06d478bf590b52187e90ca49448a01cf7d12ae0625546cf5dd2cd5d7067f94fbde76a62f8668ab1b47d07fadf01d84e13a6bce47b96f81", - "output_size": 1226, - "source": [], - "source_content": null, - "source_content_filename": null, - "source_dir": "./code/notes", - "source_file": null, - "type": "zip" - }, - "sensitive_attributes": [], - "identity_schema_version": 0 - } - ] - }, - { - "mode": "data", - "type": "archive_file", - "name": "notes_list", - "provider": "provider[\"registry.terraform.io/hashicorp/archive\"]", - "instances": [ - { - "schema_version": 0, - "attributes": { - "exclude_symlink_directories": null, - "excludes": null, - "id": "b5730a0d98ae778f80c27881147e14d060151fce", - "output_base64sha256": "1pbtfCE8qjpAP5Ddz9c9afhOUXq3aq56ordi5t4vX00=", - "output_base64sha512": "nTUnbRKT4d5g5g3HANTGxZi5FmUIaM3C660XzZmGQLJIQ+WNYNLJ/no/H30KzafwE1mJf2qkdcZ8cT3xZdciNg==", - "output_file_mode": null, - "output_md5": "090088f39e1ef9d8d7d152944441edb7", - "output_path": "./dist/notes-list.zip", - "output_sha": "b5730a0d98ae778f80c27881147e14d060151fce", - "output_sha256": "d696ed7c213caa3a403f90ddcfd73d69f84e517ab76aae7aa2b762e6de2f5f4d", - "output_sha512": "9d35276d1293e1de60e60dc700d4c6c598b916650868cdc2ebad17cd998640b24843e58d60d2c9fe7a3f1f7d0acda7f01359897f6aa475c67c713df165d72236", - "output_size": 746, - "source": [], - "source_content": null, - "source_content_filename": null, - "source_dir": "./code/notes-list", - "source_file": null, - "type": "zip" - }, - "sensitive_attributes": [], - "identity_schema_version": 0 - } - ] - }, - { - "mode": "data", - "type": "archive_file", - "name": "sql_runner", - "provider": "provider[\"registry.terraform.io/hashicorp/archive\"]", - "instances": [ - { - "schema_version": 0, - "attributes": { - "exclude_symlink_directories": null, - "excludes": null, - "id": "241f12b31b5d970c697341292954b220e44f8d2a", - "output_base64sha256": "w/IUipIki9V1lf33x06/gHq+KWVdfJO9Ni98DkhC+Xw=", - "output_base64sha512": "aLpBXApQ5Nltm6ODUqQc6VZQCoxgn68mHlcrOF8bFrdem8psnz7dujkJE5PYvB5VDNKmdsViDAKPNTwHxut4XA==", - "output_file_mode": null, - "output_md5": "1fe2ab7afe4730b1141146363d69bd23", - "output_path": "./dist/sql-runner.zip", - "output_sha": "241f12b31b5d970c697341292954b220e44f8d2a", - "output_sha256": "c3f2148a92248bd57595fdf7c74ebf807abe29655d7c93bd362f7c0e4842f97c", - "output_sha512": "68ba415c0a50e4d96d9ba38352a41ce956500a8c609faf261e572b385f1b16b75e9bca6c9f3eddba39091393d8bc1e550cd2a676c5620c028f353c07c6eb785c", - "output_size": 796, - "source": [], - "source_content": null, - "source_content_filename": null, - "source_dir": "./code/sql-runner", - "source_file": null, - "type": "zip" - }, - "sensitive_attributes": [], - "identity_schema_version": 0 - } - ] - }, - { - "mode": "managed", - "type": "sless_function", - "name": "notes_crud", - "provider": "provider[\"terra.k8c.ru/naeel/sless\"]", - "instances": [ - { - "schema_version": 0, - "attributes": { - "build_timeout_sec": 300, - "code_hash": "aaefd6de16697af6ac7331c7e1795a5446c71e351e6cacc3f4b490b683feb0cb", - "code_path": "./dist/notes.zip", - "entrypoint": "handler.handle", - "env_vars": { - "PG_DSN": "postgres://sless:sless-pg-password@postgres.sless.svc.cluster.local:5432/sless?sslmode=disable" - }, - "image_ref": "naeel/sless-default-notes:80b15a8b73f5", - "memory_mb": 128, - "name": "notes", - "namespace": "default", - "phase": "Ready", - "runtime": "python3.11", - "timeout_sec": 30 - }, - "sensitive_attributes": [ - [ - { - "type": "get_attr", - "value": "env_vars" - }, - { - "type": "index", - "value": { - "value": "PG_DSN", - "type": "string" - } - } - ] - ], - "identity_schema_version": 0, - "dependencies": [ - "data.archive_file.notes" - ] - } - ] - }, - { - "mode": "managed", - "type": "sless_function", - "name": "notes_list", - "provider": "provider[\"terra.k8c.ru/naeel/sless\"]", - "instances": [ - { - "schema_version": 0, - "attributes": { - "build_timeout_sec": 300, - "code_hash": "4091f7c79ca8c9c5663c812eb08f25ef5257af217bf2b412add670a4737b9d7f", - "code_path": "./dist/notes-list.zip", - "entrypoint": "handler.handle", - "env_vars": { - "PG_DSN": "postgres://sless:sless-pg-password@postgres.sless.svc.cluster.local:5432/sless?sslmode=disable" - }, - "image_ref": "naeel/sless-default-notes-list:07f2d5ae5ee4", - "memory_mb": 128, - "name": "notes-list", - "namespace": "default", - "phase": "Ready", - "runtime": "python3.11", - "timeout_sec": 30 - }, - "sensitive_attributes": [ - [ - { - "type": "get_attr", - "value": "env_vars" - }, - { - "type": "index", - "value": { - "value": "PG_DSN", - "type": "string" - } - } - ] - ], - "identity_schema_version": 0, - "dependencies": [ - "data.archive_file.notes_list" - ] - } - ] - }, - { - "mode": "managed", - "type": "sless_function", - "name": "sql_runner", - "provider": "provider[\"terra.k8c.ru/naeel/sless\"]", - "instances": [ - { - "schema_version": 0, - "attributes": { - "build_timeout_sec": 300, - "code_hash": "fcde93e59e6fd7f3db426482da7667d5d402aaaaaf56f79a7a60bb1722ec603a", - "code_path": "./dist/sql-runner.zip", - "entrypoint": "handler.handle", - "env_vars": { - "PG_DSN": "postgres://sless:sless-pg-password@postgres.sless.svc.cluster.local:5432/sless?sslmode=disable" - }, - "image_ref": "naeel/sless-default-sql-runner:22bce581a299", - "memory_mb": 128, - "name": "sql-runner", - "namespace": "default", - "phase": "Ready", - "runtime": "python3.11", - "timeout_sec": 30 - }, - "sensitive_attributes": [ - [ - { - "type": "get_attr", - "value": "env_vars" - }, - { - "type": "index", - "value": { - "value": "PG_DSN", - "type": "string" - } - } - ] - ], - "identity_schema_version": 0, - "dependencies": [ - "data.archive_file.sql_runner" - ] - } - ] - }, - { - "mode": "managed", - "type": "sless_job", - "name": "create_index", - "provider": "provider[\"terra.k8c.ru/naeel/sless\"]", - "instances": [ - { - "schema_version": 0, - "attributes": { - "completion_time": "2026-03-09T05:44:59Z", - "event_json": "{\"statements\":[\"CREATE INDEX IF NOT EXISTS notes_created_idx ON notes(created_at DESC)\"]}", - "function": "sql-runner", - "message": "completed successfully", - "name": "notes-create-index", - "namespace": "default", - "phase": "Succeeded", - "run_id": 1, - "start_time": "2026-03-09T05:44:54Z", - "wait_timeout_sec": 60 - }, - "sensitive_attributes": [], - "identity_schema_version": 0, - "dependencies": [ - "data.archive_file.sql_runner", - "sless_function.sql_runner", - "sless_job.create_table" - ] - } - ] - }, - { - "mode": "managed", - "type": "sless_job", - "name": "create_table", - "provider": "provider[\"terra.k8c.ru/naeel/sless\"]", - "instances": [ - { - "schema_version": 0, - "attributes": { - "completion_time": "2026-03-09T05:44:54Z", - "event_json": "{\"statements\":[\"CREATE TABLE IF NOT EXISTS notes (id serial PRIMARY KEY, title text NOT NULL, body text, created_at timestamp DEFAULT now())\"]}", - "function": "sql-runner", - "message": "completed successfully", - "name": "notes-create-table", - "namespace": "default", - "phase": "Succeeded", - "run_id": 1, - "start_time": "2026-03-09T05:44:39Z", - "wait_timeout_sec": 120 - }, - "sensitive_attributes": [], - "identity_schema_version": 0, - "dependencies": [ - "data.archive_file.sql_runner", - "sless_function.sql_runner" - ] - } - ] - }, - { - "mode": "managed", - "type": "sless_trigger", - "name": "notes_crud_http", - "provider": "provider[\"terra.k8c.ru/naeel/sless\"]", - "instances": [ - { - "schema_version": 0, - "attributes": { - "active": true, - "enabled": true, - "function": "notes", - "name": "notes-http", - "namespace": "default", - "schedule": null, - "type": "http", - "url": "https://sless-api.kube5s.ru/fn/default/notes" - }, - "sensitive_attributes": [], - "identity_schema_version": 0 - } - ] - }, - { - "mode": "managed", - "type": "sless_trigger", - "name": "notes_list_http", - "provider": "provider[\"terra.k8c.ru/naeel/sless\"]", - "instances": [ - { - "schema_version": 0, - "attributes": { - "active": true, - "enabled": true, - "function": "notes-list", - "name": "notes-list-http", - "namespace": "default", - "schedule": null, - "type": "http", - "url": "https://sless-api.kube5s.ru/fn/default/notes-list" - }, - "sensitive_attributes": [], - "identity_schema_version": 0, - "dependencies": [ - "data.archive_file.notes_list", - "sless_function.notes_list" - ] - } - ] - } - ], - "check_results": null -} diff --git a/notes-python/terraform.tfstate.1773036504.backup b/notes-python/terraform.tfstate.1773036504.backup deleted file mode 100644 index 13a4818..0000000 --- a/notes-python/terraform.tfstate.1773036504.backup +++ /dev/null @@ -1,360 +0,0 @@ -{ - "version": 4, - "terraform_version": "1.12.2", - "serial": 18, - "lineage": "46b43916-6d6b-060c-ad36-6176e18b5f7b", - "outputs": { - "notes_list_url": { - "value": "https://sless-api.kube5s.ru/fn/default/notes-list", - "type": "string" - }, - "notes_url": { - "value": "https://sless-api.kube5s.ru/fn/default/notes", - "type": "string" - } - }, - "resources": [ - { - "mode": "data", - "type": "archive_file", - "name": "notes", - "provider": "provider[\"registry.terraform.io/hashicorp/archive\"]", - "instances": [ - { - "schema_version": 0, - "attributes": { - "exclude_symlink_directories": null, - "excludes": null, - "id": "d1fed6f90a4b4fde556aa2cd18e6ffaa9877c377", - "output_base64sha256": "HMlgBvSu0gccGVilru2ybzC7v31uzG1Zy96bK4p+C1E=", - "output_base64sha512": "GoV68HbQgbVaBtR4v1kLUhh+kMpJRIoBz30SrgYlVGz13SzV1wZ/lPvedqYvhmirG0fQf63wHYThOmvOR7lvgQ==", - "output_file_mode": null, - "output_md5": "cf96673e4f09c58d2e49c1664cdee1c2", - "output_path": "./dist/notes.zip", - "output_sha": "d1fed6f90a4b4fde556aa2cd18e6ffaa9877c377", - "output_sha256": "1cc96006f4aed2071c1958a5aeedb26f30bbbf7d6ecc6d59cbde9b2b8a7e0b51", - "output_sha512": "1a857af076d081b55a06d478bf590b52187e90ca49448a01cf7d12ae0625546cf5dd2cd5d7067f94fbde76a62f8668ab1b47d07fadf01d84e13a6bce47b96f81", - "output_size": 1226, - "source": [], - "source_content": null, - "source_content_filename": null, - "source_dir": "./code/notes", - "source_file": null, - "type": "zip" - }, - "sensitive_attributes": [], - "identity_schema_version": 0 - } - ] - }, - { - "mode": "data", - "type": "archive_file", - "name": "notes_list", - "provider": "provider[\"registry.terraform.io/hashicorp/archive\"]", - "instances": [ - { - "schema_version": 0, - "attributes": { - "exclude_symlink_directories": null, - "excludes": null, - "id": "b5730a0d98ae778f80c27881147e14d060151fce", - "output_base64sha256": "1pbtfCE8qjpAP5Ddz9c9afhOUXq3aq56ordi5t4vX00=", - "output_base64sha512": "nTUnbRKT4d5g5g3HANTGxZi5FmUIaM3C660XzZmGQLJIQ+WNYNLJ/no/H30KzafwE1mJf2qkdcZ8cT3xZdciNg==", - "output_file_mode": null, - "output_md5": "090088f39e1ef9d8d7d152944441edb7", - "output_path": "./dist/notes-list.zip", - "output_sha": "b5730a0d98ae778f80c27881147e14d060151fce", - "output_sha256": "d696ed7c213caa3a403f90ddcfd73d69f84e517ab76aae7aa2b762e6de2f5f4d", - "output_sha512": "9d35276d1293e1de60e60dc700d4c6c598b916650868cdc2ebad17cd998640b24843e58d60d2c9fe7a3f1f7d0acda7f01359897f6aa475c67c713df165d72236", - "output_size": 746, - "source": [], - "source_content": null, - "source_content_filename": null, - "source_dir": "./code/notes-list", - "source_file": null, - "type": "zip" - }, - "sensitive_attributes": [], - "identity_schema_version": 0 - } - ] - }, - { - "mode": "data", - "type": "archive_file", - "name": "sql_runner", - "provider": "provider[\"registry.terraform.io/hashicorp/archive\"]", - "instances": [ - { - "schema_version": 0, - "attributes": { - "exclude_symlink_directories": null, - "excludes": null, - "id": "241f12b31b5d970c697341292954b220e44f8d2a", - "output_base64sha256": "w/IUipIki9V1lf33x06/gHq+KWVdfJO9Ni98DkhC+Xw=", - "output_base64sha512": "aLpBXApQ5Nltm6ODUqQc6VZQCoxgn68mHlcrOF8bFrdem8psnz7dujkJE5PYvB5VDNKmdsViDAKPNTwHxut4XA==", - "output_file_mode": null, - "output_md5": "1fe2ab7afe4730b1141146363d69bd23", - "output_path": "./dist/sql-runner.zip", - "output_sha": "241f12b31b5d970c697341292954b220e44f8d2a", - "output_sha256": "c3f2148a92248bd57595fdf7c74ebf807abe29655d7c93bd362f7c0e4842f97c", - "output_sha512": "68ba415c0a50e4d96d9ba38352a41ce956500a8c609faf261e572b385f1b16b75e9bca6c9f3eddba39091393d8bc1e550cd2a676c5620c028f353c07c6eb785c", - "output_size": 796, - "source": [], - "source_content": null, - "source_content_filename": null, - "source_dir": "./code/sql-runner", - "source_file": null, - "type": "zip" - }, - "sensitive_attributes": [], - "identity_schema_version": 0 - } - ] - }, - { - "mode": "managed", - "type": "sless_function", - "name": "notes_crud", - "provider": "provider[\"terra.k8c.ru/naeel/sless\"]", - "instances": [ - { - "schema_version": 0, - "attributes": { - "build_timeout_sec": 300, - "code_hash": "aaefd6de16697af6ac7331c7e1795a5446c71e351e6cacc3f4b490b683feb0cb", - "code_path": "./dist/notes.zip", - "entrypoint": "handler.handle", - "env_vars": { - "PG_DSN": "postgres://sless:sless-pg-password@postgres.sless.svc.cluster.local:5432/sless?sslmode=disable" - }, - "image_ref": "naeel/sless-default-notes:80b15a8b73f5", - "memory_mb": 128, - "name": "notes", - "namespace": "default", - "phase": "Ready", - "runtime": "python3.11", - "timeout_sec": 30 - }, - "sensitive_attributes": [ - [ - { - "type": "get_attr", - "value": "env_vars" - }, - { - "type": "index", - "value": { - "value": "PG_DSN", - "type": "string" - } - } - ] - ], - "identity_schema_version": 0, - "dependencies": [ - "data.archive_file.notes" - ] - } - ] - }, - { - "mode": "managed", - "type": "sless_function", - "name": "notes_list", - "provider": "provider[\"terra.k8c.ru/naeel/sless\"]", - "instances": [ - { - "schema_version": 0, - "attributes": { - "build_timeout_sec": 300, - "code_hash": "4091f7c79ca8c9c5663c812eb08f25ef5257af217bf2b412add670a4737b9d7f", - "code_path": "./dist/notes-list.zip", - "entrypoint": "handler.handle", - "env_vars": { - "PG_DSN": "postgres://sless:sless-pg-password@postgres.sless.svc.cluster.local:5432/sless?sslmode=disable" - }, - "image_ref": "naeel/sless-default-notes-list:07f2d5ae5ee4", - "memory_mb": 128, - "name": "notes-list", - "namespace": "default", - "phase": "Ready", - "runtime": "python3.11", - "timeout_sec": 30 - }, - "sensitive_attributes": [ - [ - { - "type": "get_attr", - "value": "env_vars" - }, - { - "type": "index", - "value": { - "value": "PG_DSN", - "type": "string" - } - } - ] - ], - "identity_schema_version": 0, - "dependencies": [ - "data.archive_file.notes_list" - ] - } - ] - }, - { - "mode": "managed", - "type": "sless_function", - "name": "sql_runner", - "provider": "provider[\"terra.k8c.ru/naeel/sless\"]", - "instances": [ - { - "schema_version": 0, - "attributes": { - "build_timeout_sec": 300, - "code_hash": "fcde93e59e6fd7f3db426482da7667d5d402aaaaaf56f79a7a60bb1722ec603a", - "code_path": "./dist/sql-runner.zip", - "entrypoint": "handler.handle", - "env_vars": { - "PG_DSN": "postgres://sless:sless-pg-password@postgres.sless.svc.cluster.local:5432/sless?sslmode=disable" - }, - "image_ref": "naeel/sless-default-sql-runner:22bce581a299", - "memory_mb": 128, - "name": "sql-runner", - "namespace": "default", - "phase": "Ready", - "runtime": "python3.11", - "timeout_sec": 30 - }, - "sensitive_attributes": [ - [ - { - "type": "get_attr", - "value": "env_vars" - }, - { - "type": "index", - "value": { - "value": "PG_DSN", - "type": "string" - } - } - ] - ], - "identity_schema_version": 0, - "dependencies": [ - "data.archive_file.sql_runner" - ] - } - ] - }, - { - "mode": "managed", - "type": "sless_job", - "name": "create_index", - "provider": "provider[\"terra.k8c.ru/naeel/sless\"]", - "instances": [ - { - "schema_version": 0, - "attributes": { - "completion_time": "2026-03-09T05:44:59Z", - "event_json": "{\"statements\":[\"CREATE INDEX IF NOT EXISTS notes_created_idx ON notes(created_at DESC)\"]}", - "function": "sql-runner", - "message": "completed successfully", - "name": "notes-create-index", - "namespace": "default", - "phase": "Succeeded", - "run_id": 1, - "start_time": "2026-03-09T05:44:54Z", - "wait_timeout_sec": 60 - }, - "sensitive_attributes": [], - "identity_schema_version": 0 - } - ] - }, - { - "mode": "managed", - "type": "sless_job", - "name": "notes_table_init", - "provider": "provider[\"terra.k8c.ru/naeel/sless\"]", - "instances": [ - { - "schema_version": 0, - "attributes": { - "completion_time": "2026-03-09T05:44:54Z", - "event_json": "{\"statements\":[\"CREATE TABLE IF NOT EXISTS notes (id serial PRIMARY KEY, title text NOT NULL, body text, created_at timestamp DEFAULT now())\"]}", - "function": "sql-runner", - "message": "completed successfully", - "name": "notes-create-table", - "namespace": "default", - "phase": "Succeeded", - "run_id": 1, - "start_time": "2026-03-09T05:44:39Z", - "wait_timeout_sec": 120 - }, - "sensitive_attributes": [], - "identity_schema_version": 0, - "dependencies": [ - "data.archive_file.sql_runner", - "sless_function.sql_runner" - ] - } - ] - }, - { - "mode": "managed", - "type": "sless_trigger", - "name": "notes_crud_http", - "provider": "provider[\"terra.k8c.ru/naeel/sless\"]", - "instances": [ - { - "schema_version": 0, - "attributes": { - "active": true, - "enabled": true, - "function": "notes", - "name": "notes-http", - "namespace": "default", - "schedule": null, - "type": "http", - "url": "https://sless-api.kube5s.ru/fn/default/notes" - }, - "sensitive_attributes": [], - "identity_schema_version": 0 - } - ] - }, - { - "mode": "managed", - "type": "sless_trigger", - "name": "notes_list_http", - "provider": "provider[\"terra.k8c.ru/naeel/sless\"]", - "instances": [ - { - "schema_version": 0, - "attributes": { - "active": true, - "enabled": true, - "function": "notes-list", - "name": "notes-list-http", - "namespace": "default", - "schedule": null, - "type": "http", - "url": "https://sless-api.kube5s.ru/fn/default/notes-list" - }, - "sensitive_attributes": [], - "identity_schema_version": 0, - "dependencies": [ - "data.archive_file.notes_list", - "sless_function.notes_list" - ] - } - ] - } - ], - "check_results": null -} diff --git a/run_terraform_examples.sh b/run_terraform_examples.sh new file mode 100755 index 0000000..0ea985a --- /dev/null +++ b/run_terraform_examples.sh @@ -0,0 +1,333 @@ +#!/usr/bin/env bash + +set -euo pipefail + +ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +LOG_DIR="$ROOT_DIR/.test-logs" +mkdir -p "$LOG_DIR" + +EXAMPLES=( + "hello-node" + "simple-node" + "simple-python" + "notes-python" +) + +declare -A CHECK_METHOD=( + [hello-node]="POST" + [simple-node]="GET" + [simple-python]="GET" + [notes-python]="GET" +) + +declare -A CHECK_URL=( + [hello-node]="https://sless-api.kube5s.ru/fn/default/hello-http" + [simple-node]="https://sless-api.kube5s.ru/fn/default/simple-node-time-display" + [simple-python]="https://sless-api.kube5s.ru/fn/default/simple-py-time-display" + [notes-python]="https://sless-api.kube5s.ru/fn/default/notes-list" +) + +declare -A CHECK_DATA=( + [hello-node]='{"name":"Smoke"}' + [simple-node]='' + [simple-python]='' + [notes-python]='' +) + +declare -a PREEXISTING_EXAMPLES=() +LAST_LOG_FILE="" +CURRENT_EXAMPLE="" +CURRENT_STEP="" +LAST_ERROR_SUMMARY="" + +fail_run() { + local example="$1" + local step="$2" + local details="$3" + + echo + echo "ERROR SUMMARY" + echo "example: $example" + echo "step: $step" + echo "reason: $details" + + if [ -n "$LAST_LOG_FILE" ] && [ -f "$LAST_LOG_FILE" ]; then + echo "log: $LAST_LOG_FILE" + echo "last log lines:" + tail -n 20 "$LAST_LOG_FILE" + fi + + exit 1 +} + +run_step() { + local example="$1" + local step="$2" + shift 2 + + CURRENT_EXAMPLE="$example" + CURRENT_STEP="$step" + LAST_ERROR_SUMMARY="" + + if ! "$@"; then + local details="$LAST_ERROR_SUMMARY" + if [ -z "$details" ]; then + details="step failed without explicit summary" + fi + fail_run "$example" "$step" "$details" + fi +} + +restore_any_backups() { + local backup + while IFS= read -r backup; do + [ -n "$backup" ] || continue + if [ -f "$backup" ]; then + mv "$backup" "${backup%.copilot.bak}" + fi + done < <(find "$ROOT_DIR" -name '*.copilot.bak' | sort) +} + +trap restore_any_backups EXIT + +clean_local_artifacts() { + local example="$1" + rm -rf \ + "$ROOT_DIR/$example/.terraform" \ + "$ROOT_DIR/$example/.terraform.lock.hcl" \ + "$ROOT_DIR/$example/terraform.tfstate" \ + "$ROOT_DIR/$example/terraform.tfstate.backup" \ + "$ROOT_DIR/$example"/terraform.tfstate.*.backup \ + "$ROOT_DIR/$example/dist" +} + +retry_tf() { + local example="$1" + local label="$2" + shift 2 + + local attempt=1 + while [ "$attempt" -le 3 ]; do + LAST_LOG_FILE="$LOG_DIR/${example//\//_}-${label// /_}-${attempt}.log" + echo "==> [$example] $label (attempt $attempt/3)" + + ( + cd "$ROOT_DIR/$example" + "$@" + ) 2>&1 | tee "$LAST_LOG_FILE" + + local status=${PIPESTATUS[0]} + if [ "$status" -eq 0 ]; then + return 0 + fi + + if grep -Eiq 'Unauthorized|401|403' "$LAST_LOG_FILE"; then + LAST_ERROR_SUMMARY="authorization error during $label" + echo "[$example] authorization error during $label" + return 41 + fi + + if grep -Eiq 'TLS handshake timeout|tls:.*timeout|i/o timeout|Client\.Timeout exceeded while awaiting headers|context deadline exceeded|unexpected EOF' "$LAST_LOG_FILE" && [ "$attempt" -lt 3 ]; then + attempt=$((attempt + 1)) + sleep 2 + continue + fi + + if grep -Eiq 'TLS handshake timeout|tls:.*timeout|i/o timeout|Client\.Timeout exceeded while awaiting headers|context deadline exceeded|unexpected EOF' "$LAST_LOG_FILE"; then + LAST_ERROR_SUMMARY="network/provider download failure during $label after retries" + else + LAST_ERROR_SUMMARY="terraform command failed during $label with exit code $status" + fi + + return "$status" + done + + LAST_ERROR_SUMMARY="terraform command failed during $label after exhausting retries" + return 1 +} + +record_preexisting_if_needed() { + local example="$1" + if grep -Fq 'No changes. Your infrastructure matches the configuration.' "$LAST_LOG_FILE"; then + PREEXISTING_EXAMPLES+=("$example") + echo "[$example] detected preexisting remote resources on clean apply" + fi +} + +probe_endpoint() { + local example="$1" + local body_file="$LOG_DIR/${example//\//_}-endpoint-body.txt" + local status_file="$LOG_DIR/${example//\//_}-endpoint-status.txt" + local method="${CHECK_METHOD[$example]}" + local url="${CHECK_URL[$example]}" + local data="${CHECK_DATA[$example]}" + + if [ "$method" = "POST" ]; then + curl -sS -X POST -H 'Content-Type: application/json' -d "$data" -o "$body_file" -w '%{http_code}' "$url" > "$status_file" + else + curl -sS -o "$body_file" -w '%{http_code}' "$url" > "$status_file" + fi +} + +assert_live_endpoint() { + local example="$1" + probe_endpoint "$example" + + local body_file="$LOG_DIR/${example//\//_}-endpoint-body.txt" + local status + status="$(cat "$LOG_DIR/${example//\//_}-endpoint-status.txt")" + + if [ "$status" != "200" ]; then + LAST_ERROR_SUMMARY="live endpoint check failed with HTTP $status" + echo "[$example] live endpoint check failed with HTTP $status" + cat "$body_file" + return 1 + fi + + if grep -Fq 'function unreachable' "$body_file"; then + LAST_ERROR_SUMMARY="live endpoint returned function unreachable" + echo "[$example] live endpoint check returned unreachable function" + cat "$body_file" + return 1 + fi +} + +assert_destroyed_endpoint() { + local example="$1" + probe_endpoint "$example" + + local body_file="$LOG_DIR/${example//\//_}-endpoint-body.txt" + local status + status="$(cat "$LOG_DIR/${example//\//_}-endpoint-status.txt")" + + if [ "$status" = "404" ] || [ "$status" = "000" ]; then + return 0 + fi + + if grep -Eiq 'not found|404 page not found' "$body_file"; then + return 0 + fi + + if [ "$status" = "502" ] && grep -Fq 'function unreachable' "$body_file"; then + LAST_ERROR_SUMMARY="route cleanup bug: public endpoint still exists but backend is already gone (HTTP 502 function unreachable)" + echo "[$example] route still exists after destroy, but backend is already gone (HTTP 502 function unreachable)" + cat "$body_file" + return 1 + fi + + LAST_ERROR_SUMMARY="endpoint still responds after destroy with HTTP $status" + echo "[$example] endpoint still responds after destroy with HTTP $status" + cat "$body_file" + return 1 +} + +wait_for_destroyed_endpoint() { + local example="$1" + local attempts=24 + local sleep_sec=5 + local try=1 + + while [ "$try" -le "$attempts" ]; do + if assert_destroyed_endpoint "$example"; then + echo "[$example] endpoint disappeared after destroy" + return 0 + fi + + echo "[$example] endpoint still present after destroy, waiting (${try}/${attempts})" + try=$((try + 1)) + sleep "$sleep_sec" + done + + echo "[$example] endpoint did not disappear after destroy within $((attempts * sleep_sec))s" + if [ -z "$LAST_ERROR_SUMMARY" ]; then + LAST_ERROR_SUMMARY="endpoint remained reachable for more than $((attempts * sleep_sec))s after destroy" + else + LAST_ERROR_SUMMARY="$LAST_ERROR_SUMMARY; endpoint was still published after $((attempts * sleep_sec))s" + fi + return 1 +} + +backup_and_modify() { + local example="$1" + case "$example" in + hello-node) + cp "$ROOT_DIR/$example/http.tf" "$ROOT_DIR/$example/http.tf.copilot.bak" + perl -0pi -e 's/enabled\s+=\s+true/enabled = false/' "$ROOT_DIR/$example/http.tf" + ;; + simple-node) + cp "$ROOT_DIR/$example/time-display.tf" "$ROOT_DIR/$example/time-display.tf.copilot.bak" + perl -0pi -e 's/memory_mb\s+=\s+64/memory_mb = 96/' "$ROOT_DIR/$example/time-display.tf" + ;; + simple-python) + cp "$ROOT_DIR/$example/time-display.tf" "$ROOT_DIR/$example/time-display.tf.copilot.bak" + perl -0pi -e 's/memory_mb\s+=\s+64/memory_mb = 96/' "$ROOT_DIR/$example/time-display.tf" + ;; + notes-python) + cp "$ROOT_DIR/$example/notes-list.tf" "$ROOT_DIR/$example/notes-list.tf.copilot.bak" + perl -0pi -e 's/memory_mb\s+=\s+128/memory_mb = 160/' "$ROOT_DIR/$example/notes-list.tf" + ;; + esac +} + +restore_modified_files() { + local example="$1" + case "$example" in + hello-node) + mv "$ROOT_DIR/$example/http.tf.copilot.bak" "$ROOT_DIR/$example/http.tf" + ;; + simple-node) + mv "$ROOT_DIR/$example/time-display.tf.copilot.bak" "$ROOT_DIR/$example/time-display.tf" + ;; + simple-python) + mv "$ROOT_DIR/$example/time-display.tf.copilot.bak" "$ROOT_DIR/$example/time-display.tf" + ;; + notes-python) + mv "$ROOT_DIR/$example/notes-list.tf.copilot.bak" "$ROOT_DIR/$example/notes-list.tf" + ;; + esac +} + +run_example() { + local example="$1" + + echo + echo "==== $example ====" + + clean_local_artifacts "$example" + run_step "$example" "terraform init" retry_tf "$example" "terraform init" terraform init -input=false -no-color + run_step "$example" "terraform apply clean" retry_tf "$example" "terraform apply clean" terraform apply -auto-approve -input=false -no-color + record_preexisting_if_needed "$example" + run_step "$example" "endpoint check after clean apply" assert_live_endpoint "$example" + + run_step "$example" "terraform destroy clean" retry_tf "$example" "terraform destroy clean" terraform destroy -auto-approve -input=false -no-color + run_step "$example" "endpoint cleanup after clean destroy" wait_for_destroyed_endpoint "$example" + + run_step "$example" "terraform apply second" retry_tf "$example" "terraform apply second" terraform apply -auto-approve -input=false -no-color + run_step "$example" "endpoint check after second apply" assert_live_endpoint "$example" + + backup_and_modify "$example" + run_step "$example" "terraform apply modified" retry_tf "$example" "terraform apply modified" terraform apply -auto-approve -input=false -no-color + restore_modified_files "$example" + + run_step "$example" "terraform destroy final" retry_tf "$example" "terraform destroy final" terraform destroy -auto-approve -input=false -no-color + run_step "$example" "endpoint cleanup after final destroy" wait_for_destroyed_endpoint "$example" + clean_local_artifacts "$example" +} + +main() { + local example + for example in "${EXAMPLES[@]}"; do + run_example "$example" + done + + if [ "${#PREEXISTING_EXAMPLES[@]}" -gt 0 ]; then + echo + echo "Preexisting remote resources were detected on first apply for: ${PREEXISTING_EXAMPLES[*]}" + exit 2 + fi + + echo + echo "All Terraform example lifecycles completed successfully." +} + +main "$@" \ No newline at end of file diff --git a/simple-node/dist/time_display.zip b/simple-node/dist/time_display.zip deleted file mode 100644 index 1b3ce4e78a8426793243cb2623a8420f47a8dd30..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 682 zcmWIWW@Zs#-~d7f2E{HQ0SEj*R!L@VYJ5s&aY0UErCwHXOwif9%RVA^e`~&bGF*bPxu-sgpXXP8Ly3N!$cjYaQpN%PjE-bIOOO9T1nK7fqVtv6o?Ju4e ze0-WB;(p&LK4+V5(_hfeBV6O&W4TG_ZO(g}JGbgKZ2f!Uqs^t>X)EMRL#}+$zZ>lO zeQtDB+{!)o9(})aTqamf;i;hL28Uy@?-U;kKAZ8Gx9*a#py}b$(>P52`itINalKV% zSDSeJ#3Ft}p?4EG&SmERFWma+(bLPmheT#ReOWNyexg{=uj31I1jRgdG#{yWdj5{` zk{J`SxR$P3{&1o8`KGMc4BaKSg}i>2Zk)2qwJH9Df%(53%~uSf6Xg^(9&4XbwBM!r zp@@g_|BUnbDmrE zRfx9+X@}2k5ufVjeL+w5xe05b9#iZR?e-I&!vY1q=Pq)yJ|NXU)q-T%8jy*Bm{6qj8TC86O9bZg<~WBV7xcBMoJd+j{-@zl|; zrnxa&%}?Z+TT?g%x$!Lx_=^Y+-XTdB{>fyw0m{{U}xj$`q7y`T*nM9Zo j2@6>cl(1l6Nh64bmdpaYS=m6sj6i4$q{D%RGB5xDUSc3< diff --git a/simple-node/dist/time_getter.zip b/simple-node/dist/time_getter.zip deleted file mode 100644 index c85ffec457f32832992daa67522b41ffcef696e1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 574 zcmWIWW@Zs#-~d7f2E{HQ0SA0QR!L@VYJ7TXNl9vvURH6=q`O(djv~k3f7d*h%2YNf zgyYtuUU_lO3_YRshmZLko|dxxjL)JVuDiYR9Zec>-1`phD!XZFb~*gV{O}K+Da$mw zzPvJc{`mj=&$BbPa@hO|Hi^C>vy=kTyDJF|Ma#O9e&r%KV^%oJMcdC%cWZ~ zD%_9fzFsSl<@f)kL#O<`nO}UeZ0)?%oOB;$vlXu_wU{c$qLV)72eOE9OAaDM_zCdtCX9>OQisNt8VuX~Nkt#e`e*a_4`YYLU~=zZjTox+tRd zl9%0i@uG@b8JAwx73`A#!^yz#|9^ltJBQ01mxUV`85oM07#IS)8JR?w5wVRd2a0VN bSkee$p~iiHH!B-Rlo1GRfb<)nnG6g7j|T2G diff --git a/simple-python/dist/time_display.zip b/simple-python/dist/time_display.zip deleted file mode 100644 index 04a485d5778a02e267c4c7815e1fd056723f6d00..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 695 zcmWIWW@Zs#-~d7f2E{HQ0SEj*R!L@VYJ5s&aY0UErCvd0&ZLW3!u}FR-+$M%Q#0rM zU-ExxQ^EpqFYTxcT+iw}XJzhEy~(+G^0ff2%tdcqk1qJaTJ`j;R8OSv=E~O3d!6RH zq?xT1+;jV;ZSlFEb@#KaXV)J0o^_X=?Z1a<<_6tnH;MA7t@G}` zycqkxEiPnrzS$33{*4EE^e2Am=!#H!%q^$zSWqnDgK6ERzBgM!*6S)e{|^jpKfCOT z>V0j2eM(Omg?uU;jI0*!{hRLi_37%nMu}}_ZhomeG5>_e+U$0(?VR2|JNi3wPtC7% z@GxAuL-nzRMObNk`Qindy%TTcpSDeZ}@t;M5_8pkx?zc@TS$)=pyHCZd?)CEdtWYZ2q-u2Lr}8rG@Fjm5e`H-P&07B1 zRzIhFidl)w>KFeakIs8;`b6=l`zw&HaZQR>>H8|5NA-cHTA$y04@@)v{|9)pbFAL9 zL`j{Afgy^Sfg!+~kx7IZk;;(eK&cD{mNbG`XlX9Mo0SbD%m{?GKsp6zC<6lkLR&TO diff --git a/simple-python/dist/time_getter.zip b/simple-python/dist/time_getter.zip deleted file mode 100644 index 4f35be2f8acf3ad2b4c5af93d012f51ddbbefe81..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 674 zcmWIWW@Zs#-~d7f2E{HQ0SA0QR!L@VYJ7TXNl9vvUO{Efr2Agd{vyZUKiA~@sK&j^ zrCwn_*S#%YoECm{sP65rRH%-)-9J5S4G zpZ^zDCq6r4dH?;-Ih$R6F!gh;GdRRk*L*E1`?dDk|6x)5SA=$&82`Fpk>0hV+R6T$ zerNnA*0dR)vakGUG&snyz2+dZkD=31XSoxbW0q~1`#xA$E<9-VdBa02a>+k5!n|Aj z9jkO0>#C>w-rjBP-^u<#gh@0nAW`jke3aosg5%a6Hp z7M8rcRe8R%z;=D>EcX4i4z2l)GfpK3Py3~DzrTClUiAqxH~H}S9$+}{EcdCkK{>rk z>E#nww_@k1HlN+)x^A!-_x$k9SnT$7b%2hgLN_&+&nN!YTAq39n%5h&D%YwcW6reY%U(*q zUc~F_@9;Qo5ixVcV&Oo@7?Nk{+rz0uYXN%aQ`^g#BZASpz?ro$d7$KMqDwU zt9>4}{wUlf|AgytRqN8rZ4#L|I%kfV)!*CmUHbbSN0H^JdIrMRd(KS>%52}V%`hX4NqyxBQKo-&GxFflM#Ff%X&cr!AIFe6eFvK%Ny d!N8J65DPVZ1$eWvfkYXB&<02c0L^4z0076NA!z^r