Files
fission-console/doc/CODEX_UI_PLAN.md
T

806 lines
40 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Fission Console — план разработки UI
Дата: 2026-04-15
Автор: Claude Opus → план для GPT 5.3 Codex
Статус: ПЛАН (к реализации)
---
## Цель
Создать веб-консоль для Fission — аналог `sless-funcs-service` из проекта sless.
Консоль позволяет: смотреть функции, создавать, редактировать код, вызывать, управлять триггерами.
## Референсные файлы (ОБЯЗАТЕЛЬНО ИЗУЧИТЬ)
Перед написанием кода — прочитай эти файлы из sless (монтирован рядом на VM):
| Файл | Зачем |
|------|-------|
| `~/terra/sless/services/funcs/main.go` (942 строки) | **Главный референс** — Go backend funcs-service. Роутинг, proxy к оператору, рендеринг HTML с JSON data injection |
| `~/terra/sless/services/funcs/index.html` (1146 строк) | **Главный референс** — UI. Vanilla JS SPA, карточки функций, создание, редактирование, highlight.js, build polling |
| `~/terra/sless/services/funcs/Dockerfile` | Multi-stage Go+embed сборка |
| `~/terra/sless/services/funcs/funcs-service.yaml` | K8s Deployment+Service+Ingress |
| `~/terra/sless/internal/api/ui/iot-console.html` (1330 строк) | Референс для IoT-стиля UI (Nubes branding, login, табы, модалки) |
| `~/terra/sless/shared-sqs/app/ui/embed.go` | Паттерн go:embed |
| `~/terra/sless/shared-sqs/app/ui/index.html` (932 строки) | Ещё один референс SPA (queue CRUD) |
| `~/terra/sless/doc/decisions/funcs_console_editor.md` | Архитектурные решения по редактору кода |
## Архитектура
### Компоненты
```
User Browser
└─► https://fission.kube5s.ru/console
└─► nginx Ingress (уже есть для fission router)
└─► fission-console:8090 (новый pod в namespace fission)
├─► GET /console → HTML SPA (go:embed)
├─► GET /api/environments → kubectl proxy → CRD list
├─► GET /api/functions → kubectl proxy → CRD list
├─► GET /api/packages → kubectl proxy → CRD list
├─► GET /api/triggers → kubectl proxy → CRD list
├─► POST /api/functions → create CRD
├─► POST /api/functions/{name}/code → update package literal
├─► POST /api/functions/{name}/invoke → proxy → router
├─► DELETE /api/functions/{name} → delete CRD
└─► GET /api/functions/{name}/status → pod status
```
### Технологии
- **Backend:** Go, net/http, k8s client-go (dynamic client)
- **Frontend:** Vanilla HTML/CSS/JS (один файл, go:embed)
- **Подсветка кода:** highlight.js (CDN)
- **Стиль:** Nubes dark theme (идентичный sless/IoT)
- **Деплой:** Docker multi-stage → K8s Deployment + Service + Ingress
### Почему dynamic client (не REST API):
Fission в нашем кластере НЕ имеет REST `/v2` API.
Все данные — через Kubernetes CRD (environments.fission.io, functions.fission.io итд).
Текущий Terraform provider уже работает через dynamic client — переиспользуем тот же подход.
---
## Структура файлов (создать)
```
console/
├── main.go # HTTP server + API handlers + k8s client
├── ui/
│ ├── embed.go # go:embed index.html
│ └── index.html # SPA: весь CSS + JS
├── go.mod
├── Dockerfile # multi-stage: Go → alpine
└── deploy/
└── console.yaml # K8s Deployment + Service + Ingress rule
```
---
## Этап 1: Backend (main.go) — ~400-500 строк Go
### 1.1 Инициализация
```go
// Переменные окружения:
// KUBECONFIG — путь к kubeconfig (dev) или in-cluster
// FISSION_NAMESPACE — namespace с функциями (default: "default")
// FISSION_ROUTER_URL — внутренний URL роутера (default: "http://router.fission.svc.cluster.local")
// PORT — порт (default: "8090")
```
- Создать dynamic client (как в terraform provider — client.go)
- Маршруты: `/console` (UI), `/api/*` (JSON API), `/health`
### 1.2 API endpoints
| Метод | Путь | Что делает |
|-------|------|-----------|
| GET | /api/environments | List environments.fission.io → JSON array |
| GET | /api/packages | List packages.fission.io → JSON array |
| GET | /api/functions | List functions.fission.io → JSON array |
| GET | /api/httptriggers | List httptriggers.fission.io → JSON array |
| GET | /api/timetriggers | List timetriggers.fission.io → JSON array |
| GET | /api/functions/{name} | Get function + связанный package + trigger info |
| POST | /api/functions | Create: environment → package → function → httptrigger (всё за один вызов) |
| PUT | /api/functions/{name}/code | Update package spec.deployment.literal (новый код) |
| POST | /api/functions/{name}/invoke | Proxy → fission router: POST http://router/fission-function/v2/functions/{name} |
| DELETE | /api/functions/{name} | Delete function + httptrigger + package (каскадно) |
| GET | /api/pods | List pods по label svc=... в namespace "default" (показать runtime pods) |
### 1.3 Формат ответа (JSON)
Для листинга функций — объединённая структура:
```json
{
"functions": [
{
"name": "hello",
"environment": "python",
"package": "hello-pkg",
"entrypoint": "main.main",
"code": "def main():\n return hello\n",
"trigger_url": "/hello",
"trigger_methods": ["GET"],
"invoke_url": "https://fission.kube5s.ru/hello",
"created": "2026-04-14T18:30:00Z"
}
],
"environments": [
{"name": "python", "image": "ghcr.io/fission/python-env", "version": 3}
]
}
```
### 1.4 Create function — полный flow
POST /api/functions с телом:
```json
{
"name": "my-func",
"environment": "python",
"code": "def main():\n return {hello: world}\n",
"entrypoint": "main.main",
"route": "/my-func",
"methods": ["GET", "POST"]
}
```
Backend создаёт 3 CRD объекта:
1. Package (`{name}-pkg`) — spec.environment + spec.deployment.literal (base64 код)
2. Function (`{name}`) — spec.environment + spec.package + spec.invokeStrategy
3. HTTPTrigger (`{name}-route`) — spec.functionref + spec.relativeurl + spec.methods
Если environment не существует — вернуть ошибку (не создавать).
### 1.5 Update code
PUT /api/functions/{name}/code с телом: `{"code": "..."}`
1. Найти function CRD → получить package name
2. Обновить package spec.deployment.literal (base64 encode)
3. Вернуть 200
### 1.6 Invoke
POST /api/functions/{name}/invoke с телом: произвольный JSON
Proxy → `http://router.fission.svc.cluster.local/fission-function/v2/functions/{name}`
Вернуть: status code + body + latency
### 1.7 Каскадное удаление
DELETE /api/functions/{name}:
1. Получить function → имя package и trigger
2. Удалить httptrigger(s) связанные с функцией
3. Удалить function
4. Удалить package
---
## Этап 2: Frontend (index.html) — ~800-1000 строк
### 2.1 Дизайн — Nubes dark theme
CSS переменные (скопировать из sless):
```css
:root {
--bg-page: #001120;
--bg-surface: #001929;
--bg-navbar: #001C34;
--border: #0b2d50;
--accent: #1a7fd4;
--text-primary: #e2ecf6;
--text-secondary: #6b8eaa;
--danger: #e74c3c;
--success: #27ae60;
}
```
### 2.2 Страницы/секции
#### Navbar
```
[Nubes logo] [/] [Fission Console] [namespace: default] [↻ Refresh] [+ Создать функцию]
```
#### Секция: Dashboard (summary)
```
Environments: 3 | Functions: 8 | Triggers: 7 | Router: fission.kube5s.ru
```
#### Секция: Карточки функций (как в sless funcs-service)
Каждая функция — карточка:
```
┌────────────────────────────────────────────────────────────┐
│ hello-fn [python] [Ready] https://fission.kube5s.ru/hello │
│ ✎ Edit ▶ Invoke ✕ Delete │
├────────────────────────────────────────────────────────────┤
│ (expand) → показать код с подсветкой (highlight.js) │
│ (edit mode) → textarea + Save │
│ (invoke mode) → JSON input + Send + Response display │
└────────────────────────────────────────────────────────────┘
```
#### Модалка: Создать функцию
```
┌─── Создать функцию ──────────────────────────┐
│ Environment: [python ▾] [nodejs ▾] [go ▾] │
│ Имя: [my-func_________] │
│ Entrypoint: [main.main_______] │
│ Route: [/my-func________] │
│ Файл: main.py │
│ ┌──────────────────────────────────────┐ │
│ │ def main(): │ │
│ │ return {"hello": "world"} │ │
│ └──────────────────────────────────────┘ │
│ [Отмена] [Создать] │
└───────────────────────────────────────────────┘
```
При смене environment → обновить шаблон кода/файла:
- python → main.py, `def main(): ...`
- nodejs → main.js, `module.exports = async function(req) { ... }`
- go → main.go, `func Handler(w http.ResponseWriter, r *http.Request) { ... }`
#### Inline: Invoke функции
```
┌─── Invoke: hello-fn ─────────────────────────┐
│ Input JSON: │
│ ┌──────────────────────────────────┐ │
│ │ {"name": "world"} │ │
│ └──────────────────────────────────┘ │
│ [▶ Send] │
│ │
│ Response (200, 34ms): │
│ ┌──────────────────────────────────┐ │
│ │ {"hello": "world"} │ │
│ └──────────────────────────────────┘ │
└────────────────────────────────────────────────┘
```
### 2.3 JavaScript — SPA логика
Принципы (из sless referenceов):
- Весь state в объекте `S = { functions: [], environments: [], ... }`
- `render()` — главный диспетчер
- Partial DOM updates по ID (не полный re-render)
- `fetch(/api/...)` для всех операций
- `h()` — HTML escape utility
- Карточки: expand/collapse для кода, inline edit, inline invoke
---
## Этап 3: Сборка и деплой
### 3.1 go.mod
```
module fission-console
go 1.24.0
require (
k8s.io/apimachinery v0.32.3
k8s.io/client-go v0.32.3
)
```
Важно: использовать те же версии k8s что в terraform/provider/go.mod.
### 3.2 Dockerfile
```dockerfile
FROM golang:1.24-alpine AS builder
WORKDIR /build
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build -trimpath -ldflags="-s -w" -o fission-console .
FROM alpine:3.20
RUN apk add --no-cache ca-certificates
COPY --from=builder /build/fission-console /fission-console
EXPOSE 8090
ENTRYPOINT ["/fission-console"]
```
### 3.3 K8s manifest (deploy/console.yaml)
```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: fission-console
namespace: fission
spec:
replicas: 1
selector:
matchLabels:
app: fission-console
template:
metadata:
labels:
app: fission-console
spec:
serviceAccountName: fission-console
containers:
- name: console
image: naeel/fission-console:v0.1.0
ports:
- containerPort: 8090
env:
- name: FISSION_NAMESPACE
value: "default"
- name: FISSION_ROUTER_URL
value: "http://router.fission.svc.cluster.local"
- name: PORT
value: "8090"
livenessProbe:
httpGet: {path: /health, port: 8090}
initialDelaySeconds: 5
resources:
requests: {cpu: 10m, memory: 16Mi}
limits: {cpu: 100m, memory: 64Mi}
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: fission-console
namespace: fission
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: fission-console
rules:
- apiGroups: ["fission.io"]
resources: ["environments", "packages", "functions", "httptriggers", "timetriggers"]
verbs: ["get", "list", "create", "update", "patch", "delete"]
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "list"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: fission-console
subjects:
- kind: ServiceAccount
name: fission-console
namespace: fission
roleRef:
kind: ClusterRole
name: fission-console
apiGroup: rbac.authorization.k8s.io
---
apiVersion: v1
kind: Service
metadata:
name: fission-console
namespace: fission
spec:
selector:
app: fission-console
ports:
- port: 8090
targetPort: 8090
---
# Ingress: добавить path /console к существующему fission ingress
# ИЛИ создать отдельный Ingress для fission-console
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: fission-console
namespace: fission
annotations:
nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
spec:
ingressClassName: nginx
rules:
- host: fission.kube5s.ru
http:
paths:
- path: /console
pathType: Prefix
backend:
service:
name: fission-console
port:
number: 8090
tls:
- hosts: [fission.kube5s.ru]
secretName: fission-tls # проверить имя секрета
```
---
## Этап 4: Тестирование
### 4.1 Smoke test (вручную в браузере)
1. Открыть https://fission.kube5s.ru/console
2. Увидеть список существующих функций
3. Создать новую функцию (Python) → увидеть в списке
4. Отредактировать код → сохранить
5. Invoke → получить ответ
6. Удалить → исчезла из списка
### 4.2 curl smoke
```bash
# API листинг
curl -s https://fission.kube5s.ru/console/api/functions | jq .
# Создать функцию
curl -s -X POST https://fission.kube5s.ru/console/api/functions \
-H Content-Type: application/json \
-d name:test-ui
# Invoke
curl -s -X POST https://fission.kube5s.ru/console/api/functions/test-ui/invoke
# Удалить
curl -s -X DELETE https://fission.kube5s.ru/console/api/functions/test-ui
```
---
## Порядок выполнения (для Codex)
| # | Шаг | Файл(ы) | Критерий готовности |
|---|-----|---------|-------------------|
| 1 | Создать структуру console/ + go.mod | console/ | `go mod tidy` проходит |
| 2 | Написать main.go — HTTP server + k8s client init + health endpoint | main.go | Компилируется, /health отвечает |
| 3 | Написать API handlers: list environments/functions/packages/triggers | main.go | `curl /api/functions` возвращает JSON |
| 4 | Написать API handler: create function (env→pkg→fn→trigger) | main.go | POST создаёт 3 CRD |
| 5 | Написать API handler: update code (package literal) | main.go | PUT обновляет пакет |
| 6 | Написать API handler: invoke (proxy → router) | main.go | POST вызывает функцию |
| 7 | Написать API handler: delete (каскадно) | main.go | DELETE удаляет fn+pkg+trigger |
| 8 | Создать ui/embed.go | ui/embed.go | — |
| 9 | Создать index.html — CSS (Nubes dark theme) + navbar + layout | ui/index.html | Открывается с правильным стилем |
| 10 | JS: загрузка данных + рендер карточек функций | ui/index.html | Карточки отображаются |
| 11 | JS: expand карточки → показать код с подсветкой | ui/index.html | Код виден |
| 12 | JS: модалка создания функции + шаблоны Python/JS/Go | ui/index.html | Функция создаётся через UI |
| 13 | JS: inline edit mode + save | ui/index.html | Код обновляется |
| 14 | JS: inline invoke панель | ui/index.html | Вызов и ответ показываются |
| 15 | JS: delete с подтверждением | ui/index.html | Удаление работает |
| 16 | Dockerfile + добавить в .gitignore | Dockerfile, .gitignore | `docker build` проходит |
| 17 | K8s manifest + RBAC | deploy/console.yaml | Pod запускается, /health OK |
| 18 | Ingress → smoke test в браузере | deploy/console.yaml | UI доступен по HTTPS |
| 19 | Commit + push | — | Всё в git |
---
## КРИТИЧЕСКИЕ ПРАВИЛА ВЫПОЛНЕНИЯ
1. **ВСЁ через SSH на VM**`ssh naeel@5.172.178.213`. Файлы писать локально (sshfs mount), команды — по SSH.
2. **Образы на Docker Hub** (`naeel/fission-console`). НЕ использовать pearlharbor.
3. **Nubes branding** — идентичный sless. CSS variables из референса.
4. **Vanilla JS** — без React/Vue/Angular. Один HTML файл.
5. **go:embed** — index.html встраивается в бинарник.
6. **Рабочая директория:** `~/terra/fission/console/`
7. **Проверять go.mod версии** — взять k8s-* из `~/terra/fission/terraform/provider/go.mod`
8. **Не ломать существующий provider** — console/ отдельный Go module
9. **Перед docker build** — убедиться что бинарник в .gitignore
10. **Commit + push** после каждого рабочего этапа
---
## Что НЕ делать
- Auth/login — пока не нужен (демо-режим, без токенов)
- Multi-namespace — работаем с одним namespace (default)
- Управление environments через UI — только листинг (создание через terraform)
- Логи функций (stdout/stderr) — отложить
- Version history — отложить
- TimeTriggers CRUD — только отображение (создание — terraform)
ENDOFPLAN application/json \
-d environment:python
# Invoke
curl -s -X POST https://fission.kube5s.ru/console/api/functions/test-ui/invoke
# Удалить
curl -s -X DELETE https://fission.kube5s.ru/console/api/functions/test-ui
```
---
## Порядок выполнения (для Codex)
| # | Шаг | Файл(ы) | Критерий готовности |
|---|-----|---------|-------------------|
| 1 | Создать структуру console/ + go.mod | console/ | `go mod tidy` проходит |
| 2 | Написать main.go — HTTP server + k8s client init + health endpoint | main.go | Компилируется, /health отвечает |
| 3 | Написать API handlers: list environments/functions/packages/triggers | main.go | `curl /api/functions` возвращает JSON |
| 4 | Написать API handler: create function (env→pkg→fn→trigger) | main.go | POST создаёт 3 CRD |
| 5 | Написать API handler: update code (package literal) | main.go | PUT обновляет пакет |
| 6 | Написать API handler: invoke (proxy → router) | main.go | POST вызывает функцию |
| 7 | Написать API handler: delete (каскадно) | main.go | DELETE удаляет fn+pkg+trigger |
| 8 | Создать ui/embed.go | ui/embed.go | — |
| 9 | Создать index.html — CSS (Nubes dark theme) + navbar + layout | ui/index.html | Открывается с правильным стилем |
| 10 | JS: загрузка данных + рендер карточек функций | ui/index.html | Карточки отображаются |
| 11 | JS: expand карточки → показать код с подсветкой | ui/index.html | Код виден |
| 12 | JS: модалка создания функции + шаблоны Python/JS/Go | ui/index.html | Функция создаётся через UI |
| 13 | JS: inline edit mode + save | ui/index.html | Код обновляется |
| 14 | JS: inline invoke панель | ui/index.html | Вызов и ответ показываются |
| 15 | JS: delete с подтверждением | ui/index.html | Удаление работает |
| 16 | Dockerfile + добавить в .gitignore | Dockerfile, .gitignore | `docker build` проходит |
| 17 | K8s manifest + RBAC | deploy/console.yaml | Pod запускается, /health OK |
| 18 | Ingress → smoke test в браузере | deploy/console.yaml | UI доступен по HTTPS |
| 19 | Commit + push | — | Всё в git |
---
## КРИТИЧЕСКИЕ ПРАВИЛА ВЫПОЛНЕНИЯ
1. **ВСЁ через SSH на VM** — `ssh naeel@5.172.178.213`. Файлы писать локально (sshfs mount), команды — по SSH.
2. **Образы на Docker Hub** (`naeel/fission-console`). НЕ использовать pearlharbor.
3. **Nubes branding** — идентичный sless. CSS variables из референса.
4. **Vanilla JS** — без React/Vue/Angular. Один HTML файл.
5. **go:embed** — index.html встраивается в бинарник.
6. **Рабочая директория:** `~/terra/fission/console/`
7. **Проверять go.mod версии** — взять k8s-* из `~/terra/fission/terraform/provider/go.mod`
8. **Не ломать существующий provider** — console/ отдельный Go module
9. **Перед docker build** — убедиться что бинарник в .gitignore
10. **Commit + push** после каждого рабочего этапа
---
## Что НЕ делать
- Auth/login — пока не нужен (демо-режим, без токенов)
- Multi-namespace — работаем с одним namespace (default)
- Управление environments через UI — только листинг (создание через terraform)
- Логи функций (stdout/stderr) — отложить
- Version history — отложить
- TimeTriggers CRUD — только отображение (создание — terraform)
ENDOFPLAN application/json \
-d code:def main():\n return {"ok":true}
# Invoke
curl -s -X POST https://fission.kube5s.ru/console/api/functions/test-ui/invoke
# Удалить
curl -s -X DELETE https://fission.kube5s.ru/console/api/functions/test-ui
```
---
## Порядок выполнения (для Codex)
| # | Шаг | Файл(ы) | Критерий готовности |
|---|-----|---------|-------------------|
| 1 | Создать структуру console/ + go.mod | console/ | `go mod tidy` проходит |
| 2 | Написать main.go — HTTP server + k8s client init + health endpoint | main.go | Компилируется, /health отвечает |
| 3 | Написать API handlers: list environments/functions/packages/triggers | main.go | `curl /api/functions` возвращает JSON |
| 4 | Написать API handler: create function (env→pkg→fn→trigger) | main.go | POST создаёт 3 CRD |
| 5 | Написать API handler: update code (package literal) | main.go | PUT обновляет пакет |
| 6 | Написать API handler: invoke (proxy → router) | main.go | POST вызывает функцию |
| 7 | Написать API handler: delete (каскадно) | main.go | DELETE удаляет fn+pkg+trigger |
| 8 | Создать ui/embed.go | ui/embed.go | — |
| 9 | Создать index.html — CSS (Nubes dark theme) + navbar + layout | ui/index.html | Открывается с правильным стилем |
| 10 | JS: загрузка данных + рендер карточек функций | ui/index.html | Карточки отображаются |
| 11 | JS: expand карточки → показать код с подсветкой | ui/index.html | Код виден |
| 12 | JS: модалка создания функции + шаблоны Python/JS/Go | ui/index.html | Функция создаётся через UI |
| 13 | JS: inline edit mode + save | ui/index.html | Код обновляется |
| 14 | JS: inline invoke панель | ui/index.html | Вызов и ответ показываются |
| 15 | JS: delete с подтверждением | ui/index.html | Удаление работает |
| 16 | Dockerfile + добавить в .gitignore | Dockerfile, .gitignore | `docker build` проходит |
| 17 | K8s manifest + RBAC | deploy/console.yaml | Pod запускается, /health OK |
| 18 | Ingress → smoke test в браузере | deploy/console.yaml | UI доступен по HTTPS |
| 19 | Commit + push | — | Всё в git |
---
## КРИТИЧЕСКИЕ ПРАВИЛА ВЫПОЛНЕНИЯ
1. **ВСЁ через SSH на VM**`ssh naeel@5.172.178.213`. Файлы писать локально (sshfs mount), команды — по SSH.
2. **Образы на Docker Hub** (`naeel/fission-console`). НЕ использовать pearlharbor.
3. **Nubes branding** — идентичный sless. CSS variables из референса.
4. **Vanilla JS** — без React/Vue/Angular. Один HTML файл.
5. **go:embed** — index.html встраивается в бинарник.
6. **Рабочая директория:** `~/terra/fission/console/`
7. **Проверять go.mod версии** — взять k8s-* из `~/terra/fission/terraform/provider/go.mod`
8. **Не ломать существующий provider** — console/ отдельный Go module
9. **Перед docker build** — убедиться что бинарник в .gitignore
10. **Commit + push** после каждого рабочего этапа
---
## Что НЕ делать
- Auth/login — пока не нужен (демо-режим, без токенов)
- Multi-namespace — работаем с одним namespace (default)
- Управление environments через UI — только листинг (создание через terraform)
- Логи функций (stdout/stderr) — отложить
- Version history — отложить
- TimeTriggers CRUD — только отображение (создание — terraform)
ENDOFPLAN application/json \
-d entrypoint:main.main
# Invoke
curl -s -X POST https://fission.kube5s.ru/console/api/functions/test-ui/invoke
# Удалить
curl -s -X DELETE https://fission.kube5s.ru/console/api/functions/test-ui
```
---
## Порядок выполнения (для Codex)
| # | Шаг | Файл(ы) | Критерий готовности |
|---|-----|---------|-------------------|
| 1 | Создать структуру console/ + go.mod | console/ | `go mod tidy` проходит |
| 2 | Написать main.go — HTTP server + k8s client init + health endpoint | main.go | Компилируется, /health отвечает |
| 3 | Написать API handlers: list environments/functions/packages/triggers | main.go | `curl /api/functions` возвращает JSON |
| 4 | Написать API handler: create function (env→pkg→fn→trigger) | main.go | POST создаёт 3 CRD |
| 5 | Написать API handler: update code (package literal) | main.go | PUT обновляет пакет |
| 6 | Написать API handler: invoke (proxy → router) | main.go | POST вызывает функцию |
| 7 | Написать API handler: delete (каскадно) | main.go | DELETE удаляет fn+pkg+trigger |
| 8 | Создать ui/embed.go | ui/embed.go | — |
| 9 | Создать index.html — CSS (Nubes dark theme) + navbar + layout | ui/index.html | Открывается с правильным стилем |
| 10 | JS: загрузка данных + рендер карточек функций | ui/index.html | Карточки отображаются |
| 11 | JS: expand карточки → показать код с подсветкой | ui/index.html | Код виден |
| 12 | JS: модалка создания функции + шаблоны Python/JS/Go | ui/index.html | Функция создаётся через UI |
| 13 | JS: inline edit mode + save | ui/index.html | Код обновляется |
| 14 | JS: inline invoke панель | ui/index.html | Вызов и ответ показываются |
| 15 | JS: delete с подтверждением | ui/index.html | Удаление работает |
| 16 | Dockerfile + добавить в .gitignore | Dockerfile, .gitignore | `docker build` проходит |
| 17 | K8s manifest + RBAC | deploy/console.yaml | Pod запускается, /health OK |
| 18 | Ingress → smoke test в браузере | deploy/console.yaml | UI доступен по HTTPS |
| 19 | Commit + push | — | Всё в git |
---
## КРИТИЧЕСКИЕ ПРАВИЛА ВЫПОЛНЕНИЯ
1. **ВСЁ через SSH на VM** — `ssh naeel@5.172.178.213`. Файлы писать локально (sshfs mount), команды — по SSH.
2. **Образы на Docker Hub** (`naeel/fission-console`). НЕ использовать pearlharbor.
3. **Nubes branding** — идентичный sless. CSS variables из референса.
4. **Vanilla JS** — без React/Vue/Angular. Один HTML файл.
5. **go:embed** — index.html встраивается в бинарник.
6. **Рабочая директория:** `~/terra/fission/console/`
7. **Проверять go.mod версии** — взять k8s-* из `~/terra/fission/terraform/provider/go.mod`
8. **Не ломать существующий provider** — console/ отдельный Go module
9. **Перед docker build** — убедиться что бинарник в .gitignore
10. **Commit + push** после каждого рабочего этапа
---
## Что НЕ делать
- Auth/login — пока не нужен (демо-режим, без токенов)
- Multi-namespace — работаем с одним namespace (default)
- Управление environments через UI — только листинг (создание через terraform)
- Логи функций (stdout/stderr) — отложить
- Version history — отложить
- TimeTriggers CRUD — только отображение (создание — terraform)
ENDOFPLAN application/json \
-d route:/test-ui
# Invoke
curl -s -X POST https://fission.kube5s.ru/console/api/functions/test-ui/invoke
# Удалить
curl -s -X DELETE https://fission.kube5s.ru/console/api/functions/test-ui
```
---
## Порядок выполнения (для Codex)
| # | Шаг | Файл(ы) | Критерий готовности |
|---|-----|---------|-------------------|
| 1 | Создать структуру console/ + go.mod | console/ | `go mod tidy` проходит |
| 2 | Написать main.go — HTTP server + k8s client init + health endpoint | main.go | Компилируется, /health отвечает |
| 3 | Написать API handlers: list environments/functions/packages/triggers | main.go | `curl /api/functions` возвращает JSON |
| 4 | Написать API handler: create function (env→pkg→fn→trigger) | main.go | POST создаёт 3 CRD |
| 5 | Написать API handler: update code (package literal) | main.go | PUT обновляет пакет |
| 6 | Написать API handler: invoke (proxy → router) | main.go | POST вызывает функцию |
| 7 | Написать API handler: delete (каскадно) | main.go | DELETE удаляет fn+pkg+trigger |
| 8 | Создать ui/embed.go | ui/embed.go | — |
| 9 | Создать index.html — CSS (Nubes dark theme) + navbar + layout | ui/index.html | Открывается с правильным стилем |
| 10 | JS: загрузка данных + рендер карточек функций | ui/index.html | Карточки отображаются |
| 11 | JS: expand карточки → показать код с подсветкой | ui/index.html | Код виден |
| 12 | JS: модалка создания функции + шаблоны Python/JS/Go | ui/index.html | Функция создаётся через UI |
| 13 | JS: inline edit mode + save | ui/index.html | Код обновляется |
| 14 | JS: inline invoke панель | ui/index.html | Вызов и ответ показываются |
| 15 | JS: delete с подтверждением | ui/index.html | Удаление работает |
| 16 | Dockerfile + добавить в .gitignore | Dockerfile, .gitignore | `docker build` проходит |
| 17 | K8s manifest + RBAC | deploy/console.yaml | Pod запускается, /health OK |
| 18 | Ingress → smoke test в браузере | deploy/console.yaml | UI доступен по HTTPS |
| 19 | Commit + push | — | Всё в git |
---
## КРИТИЧЕСКИЕ ПРАВИЛА ВЫПОЛНЕНИЯ
1. **ВСЁ через SSH на VM**`ssh naeel@5.172.178.213`. Файлы писать локально (sshfs mount), команды — по SSH.
2. **Образы на Docker Hub** (`naeel/fission-console`). НЕ использовать pearlharbor.
3. **Nubes branding** — идентичный sless. CSS variables из референса.
4. **Vanilla JS** — без React/Vue/Angular. Один HTML файл.
5. **go:embed** — index.html встраивается в бинарник.
6. **Рабочая директория:** `~/terra/fission/console/`
7. **Проверять go.mod версии** — взять k8s-* из `~/terra/fission/terraform/provider/go.mod`
8. **Не ломать существующий provider** — console/ отдельный Go module
9. **Перед docker build** — убедиться что бинарник в .gitignore
10. **Commit + push** после каждого рабочего этапа
---
## Что НЕ делать
- Auth/login — пока не нужен (демо-режим, без токенов)
- Multi-namespace — работаем с одним namespace (default)
- Управление environments через UI — только листинг (создание через terraform)
- Логи функций (stdout/stderr) — отложить
- Version history — отложить
- TimeTriggers CRUD — только отображение (создание — terraform)
ENDOFPLAN application/json \
-d methods:[GET]
# Invoke
curl -s -X POST https://fission.kube5s.ru/console/api/functions/test-ui/invoke
# Удалить
curl -s -X DELETE https://fission.kube5s.ru/console/api/functions/test-ui
```
---
## Порядок выполнения (для Codex)
| # | Шаг | Файл(ы) | Критерий готовности |
|---|-----|---------|-------------------|
| 1 | Создать структуру console/ + go.mod | console/ | `go mod tidy` проходит |
| 2 | Написать main.go — HTTP server + k8s client init + health endpoint | main.go | Компилируется, /health отвечает |
| 3 | Написать API handlers: list environments/functions/packages/triggers | main.go | `curl /api/functions` возвращает JSON |
| 4 | Написать API handler: create function (env→pkg→fn→trigger) | main.go | POST создаёт 3 CRD |
| 5 | Написать API handler: update code (package literal) | main.go | PUT обновляет пакет |
| 6 | Написать API handler: invoke (proxy → router) | main.go | POST вызывает функцию |
| 7 | Написать API handler: delete (каскадно) | main.go | DELETE удаляет fn+pkg+trigger |
| 8 | Создать ui/embed.go | ui/embed.go | — |
| 9 | Создать index.html — CSS (Nubes dark theme) + navbar + layout | ui/index.html | Открывается с правильным стилем |
| 10 | JS: загрузка данных + рендер карточек функций | ui/index.html | Карточки отображаются |
| 11 | JS: expand карточки → показать код с подсветкой | ui/index.html | Код виден |
| 12 | JS: модалка создания функции + шаблоны Python/JS/Go | ui/index.html | Функция создаётся через UI |
| 13 | JS: inline edit mode + save | ui/index.html | Код обновляется |
| 14 | JS: inline invoke панель | ui/index.html | Вызов и ответ показываются |
| 15 | JS: delete с подтверждением | ui/index.html | Удаление работает |
| 16 | Dockerfile + добавить в .gitignore | Dockerfile, .gitignore | `docker build` проходит |
| 17 | K8s manifest + RBAC | deploy/console.yaml | Pod запускается, /health OK |
| 18 | Ingress → smoke test в браузере | deploy/console.yaml | UI доступен по HTTPS |
| 19 | Commit + push | — | Всё в git |
---
## КРИТИЧЕСКИЕ ПРАВИЛА ВЫПОЛНЕНИЯ
1. **ВСЁ через SSH на VM** — `ssh naeel@5.172.178.213`. Файлы писать локально (sshfs mount), команды — по SSH.
2. **Образы на Docker Hub** (`naeel/fission-console`). НЕ использовать pearlharbor.
3. **Nubes branding** — идентичный sless. CSS variables из референса.
4. **Vanilla JS** — без React/Vue/Angular. Один HTML файл.
5. **go:embed** — index.html встраивается в бинарник.
6. **Рабочая директория:** `~/terra/fission/console/`
7. **Проверять go.mod версии** — взять k8s-* из `~/terra/fission/terraform/provider/go.mod`
8. **Не ломать существующий provider** — console/ отдельный Go module
9. **Перед docker build** — убедиться что бинарник в .gitignore
10. **Commit + push** после каждого рабочего этапа
---
## Что НЕ делать
- Auth/login — пока не нужен (демо-режим, без токенов)
- Multi-namespace — работаем с одним namespace (default)
- Управление environments через UI — только листинг (создание через terraform)
- Логи функций (stdout/stderr) — отложить
- Version history — отложить
- TimeTriggers CRUD — только отображение (создание — terraform)