feat: demo managed functions with harbor-backed operator setup

This commit is contained in:
Naeel
2026-03-14 18:16:53 +03:00
parent cbd2c8c44c
commit 8dd5b676c0
14 changed files with 687 additions and 1 deletions
@@ -0,0 +1,26 @@
# Изменено: 2026-03-14
# event-cleaner: HTTP функция для демонстрации контролируемого изменения логики.
# Работает без внешних пакетов.
import json
from datetime import datetime, timezone
def handle(event):
"""Принимает delete_n и возвращает подтверждение обработки."""
payload = event if isinstance(event, dict) else {}
delete_n = int(payload.get("delete_n", 10))
delete_n = max(1, min(delete_n, 100))
now = datetime.now(timezone.utc).isoformat()
# Здесь intentionally имитируем очистку, чтобы показать реакцию на входные параметры.
return json.dumps(
{
"ok": True,
"accepted_delete_n": delete_n,
"status": "simulated-cleanup",
"generated_at": now,
}
), 200, {"Content-Type": "application/json"}
@@ -0,0 +1,25 @@
# Изменено: 2026-03-14
# event-monitor: cron-функция для демонстрации расписания и управления кодом.
# Работает без внешних библиотек и возвращает диагностический JSON.
import json
import os
from datetime import datetime, timezone
THRESHOLD = 50
def handle(request):
"""Отдаёт heartbeat для cron-запуска и видимой проверки после apply."""
rabbitmq_url = os.environ.get("RABBITMQ_URL", "not-set")
now = datetime.now(timezone.utc).isoformat()
return json.dumps(
{
"ok": True,
"monitor": "alive",
"threshold": THRESHOLD,
"rabbitmq_configured": rabbitmq_url != "not-set",
"generated_at": now,
}
), 200, {"Content-Type": "application/json"}
@@ -0,0 +1,28 @@
# Изменено: 2026-03-14
# event-writer: простая HTTP функция без внешних зависимостей.
# Правка поля response_tag в коде сразу видна в ответе после terraform apply.
import json
import os
from datetime import datetime, timezone
def handle(event):
"""Возвращает полезный JSON-ответ для визуальной проверки выката кода."""
default_message = os.environ.get("DEFAULT_MESSAGE", "writer-default")
payload = event if isinstance(event, dict) else {}
message = payload.get("message", default_message)
source = payload.get("source", "event-writer")
now = datetime.now(timezone.utc).isoformat()
# response_tag удобно менять для демонстрации hot-update кода через terraform apply.
response_tag = "writer-v2"
return {
"ok": True,
"source": source,
"message": message,
"response_tag": response_tag,
"generated_at": now,
}
@@ -0,0 +1,77 @@
# 2026-03-14
# function.tf — ресурсы managed serverless функций для демонстрации.
# Пользователь правит код в code/* и запускает terraform apply — провайдер сам пересобирает и выкатывает функции.
resource "sless_function" "event_writer" {
name = "event-writer"
runtime = "python3.11"
entrypoint = "handler.handle"
memory_mb = 128
timeout_sec = 20
source_dir = "${path.module}/code/event-writer"
env_vars = {
POSTGRES_DSN = var.pg_dsn
DEFAULT_MESSAGE = var.writer_message
}
}
resource "sless_trigger" "event_writer_http" {
name = "event-writer-http"
type = "http"
function = sless_function.event_writer.name
enabled = true
}
resource "sless_function" "event_monitor" {
name = "event-monitor"
runtime = "python3.11"
entrypoint = "handler.handle"
memory_mb = 128
timeout_sec = 20
source_dir = "${path.module}/code/event-monitor"
env_vars = {
POSTGRES_DSN = var.pg_dsn
RABBITMQ_URL = var.rabbitmq_url
}
}
resource "sless_trigger" "event_monitor_cron" {
name = "event-monitor-cron"
type = "cron"
function = sless_function.event_monitor.name
enabled = true
schedule = "*/1 * * * *"
}
resource "sless_function" "event_cleaner" {
name = "event-cleaner"
runtime = "python3.11"
entrypoint = "handler.handle"
memory_mb = 128
timeout_sec = 20
source_dir = "${path.module}/code/event-cleaner"
env_vars = {
POSTGRES_DSN = var.pg_dsn
}
}
resource "sless_trigger" "event_cleaner_http" {
name = "event-cleaner-http"
type = "http"
function = sless_function.event_cleaner.name
enabled = true
}
output "event_writer_url" {
value = sless_trigger.event_writer_http.url
}
output "event_cleaner_url" {
value = sless_trigger.event_cleaner_http.url
}
+18
View File
@@ -0,0 +1,18 @@
# 2026-03-14
# Terraform demo: managed serverless functions.
# Здесь управляем ТОЛЬКО функциями/триггерами, внешние сервисы считаем уже поднятыми.
terraform {
required_providers {
sless = {
source = "terra.k8c.ru/naeel/sless"
version = "~> 0.1.18"
}
}
}
provider "sless" {
endpoint = var.sless_endpoint
token = var.token
nubes_endpoint = var.nubes_endpoint
}
@@ -0,0 +1,11 @@
# 2026-03-14
# Скопируй в terraform.tfvars и подставь актуальный токен.
token = "PUT_TOKEN_HERE"
sless_endpoint = "http://sless-api.185.247.187.147.nip.io"
nubes_endpoint = "https://deck-test.ngcloud.ru/api/v1"
pg_dsn = "postgres://sless:sless-pg-password@postgres.sless.svc.cluster.local:5432/sless?sslmode=disable"
rabbitmq_url = "amqp://sless:sless123@rabbitmq.sless.svc.cluster.local:5672/"
writer_message = "writer-default-v1"
@@ -0,0 +1,38 @@
# 2026-03-14
# Переменные для demo-managed-functions.
variable "token" {
description = "JWT токен API"
type = string
sensitive = true
}
variable "sless_endpoint" {
description = "Endpoint sless API"
type = string
default = "http://sless-api.185.247.187.147.nip.io"
}
variable "nubes_endpoint" {
description = "Nubes endpoint (нужен провайдеру)"
type = string
default = "https://deck-test.ngcloud.ru/api/v1"
}
variable "pg_dsn" {
description = "PostgreSQL DSN для функций"
type = string
default = "postgres://sless:sless-pg-password@postgres.sless.svc.cluster.local:5432/sless?sslmode=disable"
}
variable "rabbitmq_url" {
description = "RabbitMQ URL для функций"
type = string
default = "amqp://sless:sless123@rabbitmq.sless.svc.cluster.local:5672/"
}
variable "writer_message" {
description = "Сообщение по умолчанию, которое пишет event-writer"
type = string
default = "writer-default-v1"
}