diff --git a/simple-node/code/time_display/time_display.js b/simple-node/code/time_display/time_display.js new file mode 100644 index 0000000..a711b3e --- /dev/null +++ b/simple-node/code/time_display/time_display.js @@ -0,0 +1,20 @@ +// Создано: 2026-03-09 +// time_display.js — HTTP-функция (постоянный Deployment + Trigger). +// Читает env JOB_TIME, которую terraform передаёт из sless_job.run_getter.message. +// Демонстрирует цепочку: Job вычисляет данные → Function использует их через env. + +exports.showTime = function(event) { + // JOB_TIME устанавливается terraform из статуса джоба (JSON строка) + const jobTimeRaw = process.env.JOB_TIME || '{}'; + let jobTime; + try { + const parsed = JSON.parse(jobTimeRaw); + jobTime = parsed.time || jobTimeRaw; + } catch (e) { + jobTime = jobTimeRaw; + } + return { + message: `Сервис запустился в: ${jobTime}`, + path: event._path || '/', + }; +}; diff --git a/simple-node/code/time_getter/time_getter.js b/simple-node/code/time_getter/time_getter.js new file mode 100644 index 0000000..a750c17 --- /dev/null +++ b/simple-node/code/time_getter/time_getter.js @@ -0,0 +1,10 @@ +// Создано: 2026-03-09 +// time_getter.js — функция запускается как Job (одноразово). +// Возвращает JSON со временем запуска. Оператор v0.1.16 захватывает stdout +// и записывает его в sless_job.run_getter.message — оттуда terraform передаёт +// значение в sless_function.display через env_var JOB_TIME. + +exports.getTime = function(event) { + // Возвращаем время в ISO 8601 UTC — без зависимостей, только stdlib + return { time: new Date().toISOString() }; +}; diff --git a/simple-node/dist/time_display.zip b/simple-node/dist/time_display.zip new file mode 100644 index 0000000..1b3ce4e Binary files /dev/null and b/simple-node/dist/time_display.zip differ diff --git a/simple-node/dist/time_getter.zip b/simple-node/dist/time_getter.zip new file mode 100644 index 0000000..c85ffec Binary files /dev/null and b/simple-node/dist/time_getter.zip differ diff --git a/simple-node/main.tf b/simple-node/main.tf new file mode 100644 index 0000000..76bb8eb --- /dev/null +++ b/simple-node/main.tf @@ -0,0 +1,22 @@ +# Создано: 2026-03-09 +# main.tf — точка входа для примера simple-node. +# Демонстрирует цепочку: sless_job (one-shot) → sless_function (http). +# Аналог simple-python, но на Node.js 20. + +terraform { + required_providers { + sless = { + source = "terra.k8c.ru/naeel/sless" + version = "~> 0.1.8" + } + archive = { + source = "hashicorp/archive" + version = "~> 2.0" + } + } +} + +provider "sless" { + endpoint = "https://sless-api.kube5s.ru" + token = "dev-token-change-me" +} diff --git a/simple-node/outputs.tf b/simple-node/outputs.tf new file mode 100644 index 0000000..06204e2 --- /dev/null +++ b/simple-node/outputs.tf @@ -0,0 +1,12 @@ +# Создано: 2026-03-09 +# outputs.tf — полезные значения после terraform apply. + +output "display_url" { + description = "URL HTTP-триггера функции time_display" + value = sless_trigger.display_http.url +} + +output "job_result" { + description = "Stdout джоба (return value функции getTime)" + value = sless_job.run_getter.message +} diff --git a/simple-node/time-display.tf b/simple-node/time-display.tf new file mode 100644 index 0000000..33ee0d3 --- /dev/null +++ b/simple-node/time-display.tf @@ -0,0 +1,36 @@ +# Создано: 2026-03-09 +# time-display.tf — постоянная HTTP-функция, получающая данные от джоба. + +# Упаковываем код функции в zip +data "archive_file" "time_display_zip" { + type = "zip" + source_dir = "${path.module}/code/time_display" + output_path = "${path.module}/dist/time_display.zip" +} + +# HTTP-функция: постоянный Deployment, читает JOB_TIME из env +resource "sless_function" "time_display" { + namespace = "default" + name = "simple-node-time-display" + runtime = "nodejs20" + entrypoint = "time_display.showTime" + memory_mb = 64 + + # Значение вычислено джобом при apply и зафиксировано в state + env_vars = { + JOB_TIME = sless_job.run_getter.message + } + + code_path = data.archive_file.time_display_zip.output_path + code_hash = filesha256("${path.module}/code/time_display/time_display.js") + + depends_on = [sless_job.run_getter] +} + +# HTTP-триггер — публикует функцию по URL +resource "sless_trigger" "display_http" { + namespace = "default" + name = "simple-node-display-http" + type = "http" + function = sless_function.time_display.name +} diff --git a/simple-node/time-getter.tf b/simple-node/time-getter.tf new file mode 100644 index 0000000..2edea62 --- /dev/null +++ b/simple-node/time-getter.tf @@ -0,0 +1,36 @@ +# Создано: 2026-03-09 +# time-getter.tf — одноразовая функция + джоб запускающий её при apply. +# sless_job.run_getter.message после apply содержит stdout runner-а: +# {"time":"2026-03-09T12:34:56.789Z"} +# Это значение terraform записывает в env JOB_TIME функции time_display. + +# Упаковываем код функции в zip +data "archive_file" "time_getter_zip" { + type = "zip" + source_dir = "${path.module}/code/time_getter" + output_path = "${path.module}/dist/time_getter.zip" +} + +# Функция-вычислитель: запускается только джобом, не имеет HTTP-триггера +resource "sless_function" "time_getter" { + namespace = "default" + name = "simple-node-time-getter" + runtime = "nodejs20" + entrypoint = "time_getter.getTime" + memory_mb = 64 + + code_path = data.archive_file.time_getter_zip.output_path + code_hash = filesha256("${path.module}/code/time_getter/time_getter.js") +} + +# Джоб: запускает time_getter один раз при terraform apply. +resource "sless_job" "run_getter" { + namespace = "default" + name = "simple-node-getter-run" + function = sless_function.time_getter.name + run_id = 1 + wait_timeout_sec = 120 + event_json = "{}" + + depends_on = [sless_function.time_getter] +} diff --git a/simple-python/code/time_display/time_display.py b/simple-python/code/time_display/time_display.py new file mode 100644 index 0000000..789cd44 --- /dev/null +++ b/simple-python/code/time_display/time_display.py @@ -0,0 +1,20 @@ +# Создано: 2026-03-09 +# time_display.py — HTTP-функция (постоянный Deployment + Trigger). +# Читает env JOB_TIME, которую terraform передаёт из sless_job.run_getter.message. +# Демонстрирует цепочку: Job вычисляет данные → Function использует их через env. + +import json +import os + + +def show_time(event): + # JOB_TIME устанавливается terraform из статуса джоба (JSON строка) + job_time_raw = os.environ.get("JOB_TIME", "{}") + try: + job_time = json.loads(job_time_raw).get("time", job_time_raw) + except (json.JSONDecodeError, AttributeError): + job_time = job_time_raw + return { + "message": f"Сервис запустился в: {job_time}", + "path": event.get("_path", "/"), + } diff --git a/simple-python/code/time_getter/time_getter.py b/simple-python/code/time_getter/time_getter.py new file mode 100644 index 0000000..05c47f6 --- /dev/null +++ b/simple-python/code/time_getter/time_getter.py @@ -0,0 +1,18 @@ +# Создано: 2026-03-09 +# time_getter.py — функция запускается как Job (одноразово). +# Возвращает JSON со временем запуска. Оператор v0.1.16 захватывает stdout +# и записывает его в sless_job.run_getter.message — оттуда terraform передаёт +# значение в sless_function.display через env_var JOB_TIME. + +import json +from datetime import datetime, timezone + + +def get_time(event): + # Возвращаем время в ISO 8601 UTC — без зависимостей, только stdlib + return {"time": datetime.now(timezone.utc).isoformat()} + + +if __name__ == "__main__": + # Для локального тестирования без оператора + print(json.dumps(get_time({}))) diff --git a/simple-python/dist/time_display.zip b/simple-python/dist/time_display.zip new file mode 100644 index 0000000..04a485d Binary files /dev/null and b/simple-python/dist/time_display.zip differ diff --git a/simple-python/dist/time_getter.zip b/simple-python/dist/time_getter.zip new file mode 100644 index 0000000..4f35be2 Binary files /dev/null and b/simple-python/dist/time_getter.zip differ diff --git a/simple-python/main.tf b/simple-python/main.tf new file mode 100644 index 0000000..4b7c748 --- /dev/null +++ b/simple-python/main.tf @@ -0,0 +1,23 @@ +# Создано: 2026-03-09 +# main.tf — точка входа для примера simple-python. +# Демонстрирует цепочку: sless_job (one-shot) → sless_function (http). +# Джоб запускается при terraform apply, его stdout (JSON) попадает в +# sless_job.run_getter.message и передаётся функции через env_vars. + +terraform { + required_providers { + sless = { + source = "terra.k8c.ru/naeel/sless" + version = "~> 0.1.8" + } + archive = { + source = "hashicorp/archive" + version = "~> 2.0" + } + } +} + +provider "sless" { + endpoint = "https://sless-api.kube5s.ru" + token = "dev-token-change-me" +} diff --git a/simple-python/outputs.tf b/simple-python/outputs.tf new file mode 100644 index 0000000..b4c03b3 --- /dev/null +++ b/simple-python/outputs.tf @@ -0,0 +1,14 @@ +# Создано: 2026-03-09 +# outputs.tf — полезные значения после terraform apply. + +# URL HTTP-триггера для тестирования функции display +output "display_url" { + description = "URL HTTP-триггера функции time_display" + value = sless_trigger.display_http.url +} + +# Результат джоба — JSON строка {"time": "..."} из stdout функции get_time() +output "job_result" { + description = "Stdout джоба (return value функции get_time)" + value = sless_job.run_getter.message +} diff --git a/simple-python/time-display.tf b/simple-python/time-display.tf new file mode 100644 index 0000000..861c938 --- /dev/null +++ b/simple-python/time-display.tf @@ -0,0 +1,40 @@ +# Создано: 2026-03-09 +# time-display.tf — постоянная HTTP-функция, получающая данные от джоба. +# JOB_TIME берётся из sless_job.run_getter.message (stdout джоба) — +# это JSON строка {"time": "..."}, terraform передаёт её в env целиком. +# Функция парсит её через os.environ, а не через event — демонстрирует +# паттерн "данные вычислены один раз при деплое, используются на каждый запрос". + +# Упаковываем код функции в zip +data "archive_file" "time_display_zip" { + type = "zip" + source_dir = "${path.module}/code/time_display" + output_path = "${path.module}/dist/time_display.zip" +} + +# HTTP-функция: постоянный Deployment, читает JOB_TIME из env +resource "sless_function" "time_display" { + namespace = "default" + name = "simple-py-time-display" + runtime = "python3.11" + entrypoint = "time_display.show_time" + memory_mb = 64 + + # Значение вычислено джобом при apply и зафиксировано в state + env_vars = { + JOB_TIME = sless_job.run_getter.message + } + + code_path = data.archive_file.time_display_zip.output_path + code_hash = filesha256("${path.module}/code/time_display/time_display.py") + + depends_on = [sless_job.run_getter] +} + +# HTTP-триггер — публикует функцию по URL +resource "sless_trigger" "display_http" { + namespace = "default" + name = "simple-py-display-http" + type = "http" + function = sless_function.time_display.name +} diff --git a/simple-python/time-getter.tf b/simple-python/time-getter.tf new file mode 100644 index 0000000..b833025 --- /dev/null +++ b/simple-python/time-getter.tf @@ -0,0 +1,38 @@ +# Создано: 2026-03-09 +# time-getter.tf — одноразовая функция + джоб запускающий её при apply. +# sless_job.run_getter.message после apply содержит stdout runner-а: +# {"time": "2026-03-09T12:34:56.789012+00:00"} +# Это значение terraform записывает в env JOB_TIME функции time_display. + +# Упаковываем код функции в zip +data "archive_file" "time_getter_zip" { + type = "zip" + source_dir = "${path.module}/code/time_getter" + output_path = "${path.module}/dist/time_getter.zip" +} + +# Функция-вычислитель: запускается только джобом, не имеет HTTP-триггера +resource "sless_function" "time_getter" { + namespace = "default" + name = "simple-py-time-getter" + runtime = "python3.11" + entrypoint = "time_getter.get_time" + memory_mb = 64 + + code_path = data.archive_file.time_getter_zip.output_path + code_hash = filesha256("${path.module}/code/time_getter/time_getter.py") +} + +# Джоб: запускает time_getter один раз при terraform apply. +# run_id > 0 — разрешение на запуск (run_id=0 пропускается оператором). +# После завершения message = stdout пода = json возвращённый get_time(). +resource "sless_job" "run_getter" { + namespace = "default" + name = "simple-py-getter-run" + function = sless_function.time_getter.name + run_id = 1 + wait_timeout_sec = 120 + event_json = "{}" + + depends_on = [sless_function.time_getter] +}