Files
getpgdata/history/2026-08-18.md
T

144 lines
9.3 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.
# История getpgdata — 2026-08-18
## Суть проекта
`getpgdata` — отдельное приложение для доступа к PostgreSQL (managed k8s, internal-only).
Разворачивается на платформе Nubes как **NodeJS managed service** (`nodejsk8s`).
Репозиторий: `https://gitea.services.ngcloud.ru/Nail/getpgdata.git` (ветка `master`).
Локальный путь: `/home/naeel/ipwhitelist-app/getpgdata`.
## 1. Создание (Flask-версия, ошибочная)
Первоначально приложение было собрано как **Flask (Python)** по howto `~/nubes/howto-flask-nubes.md`
(структура `site/app.py` + `requirements.txt`). Запушено коммитом `5c5e11c`.
**Функции Flask-версии:** главная со списком таблиц, просмотр таблицы, SQL-консоль (read-only), `/healthz`.
## 2. Ошибка пользователя и замена на Node.js
Пользователь указал, что перепутал стек — нужно **Node.js**, а не Flask.
**Решение:** Flask-файлы (`site/`, `requirements.txt`) удалены, создана Node.js структура
по образцу рабочего `ipwhitelist-app`:
```
getpgdata/
├── package.json # version 1.0.x; main server.js; start: node server.js
├── server.js # точка входа: Express + pg Pool
├── public/style.css
└── views/
├── index.ejs # главная: подключение + список таблиц
├── table.ejs # просмотр таблицы с пагинацией
├── query.ejs # SQL-консоль (read-only, только SELECT)
└── error.ejs
```
Коммит замены: `b061dcd`.
**Проверено:** `node -c server.js`, `npm install` (90 пакетов), реальный запуск сервера:
- `GET /` → 200 (рендер страницы)
- `GET /healthz` при недоступной БД → 503 (degraded, приложение не падает)
- `GET /table` без имени → 302 redirect
- `POST /query` не-SELECT → блокируется (read-only)
- статика `/public/style.css` → 200
## 3. Настройки подключения к БД
- Хост: `postgresqlk8s-master.60bdf3e3-5087-41ff-b760-fe6ea544a80e.svc.cluster.local`
- Порт: `5432`
- БД: `ipwhitelist` (коммит `102689d` — дефолт изменён с `postgres` на `ipwhitelist`)
- Пользователи: `super` (полный доступ) и `contracts` — оба с паролями из jsonEnv
- `DB_SSLMODE`: `disable`
Пароли в коде НЕ хранятся (читаются через `process.env.DB_PASS`). Готовые jsonEnv-блоки
на обоих пользователей добавлены в `README.md` (коммит `a890bb9`).
## 4. Проблема деплоя: под `nodejsk8s` не стартует
**Симптом (Nubes UI):**
> Приложение не запустилось. Производится полный откат установки.
> Error: jlib.k8s [correctReplicaActive] | ERROR | Под(ы) не работают: 'nodejsk8s' (Deployment).
**Диагноз (сравнение с работающим `whitelist`):**
| Параметр | `whitelist` (работает) | `getpgdata` (падал) |
|---|---|---|
| Точка входа | `server.js`, `main` в package.json | `server.js` ✓ |
| `npm start` | `node server.js` | `node server.js` ✓ |
| **Дефолтный порт** | **3000** | **5000** ✗ |
| Liveness | `/healthz` | `/healthz` ✓ |
| Старт без доступной БД | стартует | стартует ✓ |
**Гипотеза:** дефолтный порт `5000` (перенесён из Flask-версии) не совпадает с портом `3000`,
который ожидает платформа Nubes для NodeJS managed service. Health-проба не находила сервис →
под не Ready → «не работает nodejsk8s» → откат.
**Исправление:** дефолтный `PORT` в `server.js` изменён с `5000` на `3000`;
в `README.md` jsonEnv-блоки обновлены (`PORT: 3000`); `package.json` version → `1.0.1`.
**Проверено:** сервер запущен без env `PORT` → слушает `0.0.0.0:3000`, `/` → 200, `/healthz` → 503 (degraded).
**⚠️ НЕ проверено:** доступ к кластеру Nubes с этой машины отсутствует (`iot-naeel` и
`naeel-test-3` требуют OIDC-аутентификацию, managed-сервисы в них не видны). Поэтому
точную причину «почему под упал» по логам пода подтвердить нельзя — требуется лог пода
из Nubes UI. Если деплой после фикса порта снова не поднимется — смотреть логи пода
(`nodejsk8s` Deployment) в UI, а не только полагаться на гипотезу о порте.
## 5. Прочее
- `package-lock.json` закоммичен (зависимости: express, ejs, pg).
- `node_modules/` в `.gitignore`.
- Версия в `package.json` повышается при каждой правке кода (правило проекта).
## 6. Минимальный вывод на экран (фикс падения пода)
Несмотря на фикс порта (п.4), деплой снова упал — под `nodejsk8s` не поднялся.
**Требование пользователя:** «сделай код минимальным. Сам код не удаляй — сделай вывод
на экран какой-то информации и всё».
**Решение (коммит c8a776e, версия 1.0.2):**
- Роут `GET /` переписан так, чтобы **не зависеть от EJS-шаблонов**: отдаёт простой HTML
напрямую (`res.send`), выводя:
- версию Node, `APP_ENV`, PID
- конфиг БД (host, port, database, user)
- статус подключения к БД (или текст ошибки)
- список таблиц (или сообщение об ошибке)
- Каждая попытка работы с БД обёрнута в try/catch, поэтому страница **всегда** отдаёт 200
с информацией, даже если БД недоступна.
- Весь остальной код (роуты `/table`, `/query`, `/healthz`, `dbConfig`, `pool`) **не удалён**
только главная страница упрощена.
**Проверено:** синтаксис OK; запуск без env `PORT` → слушает `0.0.0.0:3000`;
`GET /` → 200 (HTML с конфигом и статусом БД), `GET /healthz` при недоступной БД → 503 degraded.
**⚠️ Точная причина падения пода по-прежнему не подтверждена** (нет доступа к логам Nubes).
Если под не поднимется и после этого — смотреть логи `nodejsk8s` Deployment в Nubes UI:
replica не активна (CrashLoopBackOff, invalidImage, порт/health, зависший старт).
## 7. JSON API POST /api/sql (перенос данных в новую ПГ)
**Контекст:** нужно перенести белые списки (IP, кто создал, когда) из прежней БД в **новую**
PostgreSQL (тот же realm k8s). Доступ к новой БД — через Keycloak, автоматизировать нельзя.
Решение: код в репе `getpgdata` + передеплой с кредами новой ПГ.
**Что добавлено (версия 1.0.3):**
- Эндпоинт **`POST /api/sql`** — JSON API для произвольных SQL-команд.
Body: `{ "sql": "...", "params": [...] }` (params → `$1..$n`).
- `SELECT`/`WITH``{ ok:true, fields, rows, rowCount }` (всегда доступен)
- `INSERT`/`UPDATE`/`DELETE`/DDL → `{ ok:true, rowCount }` **только при `WRITE_SQL=1`**
- иначе → HTTP 403 «Write-SQL отключён»
- **Защита:** выполняется только первый statement (split по `;`) — блокирует мульти-команды
вроде `SELECT 1; DROP TABLE ...`.
- Флаг в env: `WRITE_SQL=1` включает запись.
**Логика переноса:**
1. Приложение подключено к прежней БД — читать данные через `/api/sql` (SELECT).
2. Сменить креды в jsonEnv на новую ПГ (+ `WRITE_SQL=1`).
3. Передеплой — теперь `/api/sql` выполняет запросы уже в новой БД; выполнить INSERT данных.
**Проверено:** `node -c server.js` OK; локально: пустой SQL → 400; SELECT → идёт в БД;
`INSERT` без `WRITE_SQL` → 403 (до попытки подключения); `WRITE_SQL=1` + мульти-statement →
берётся только первый; процесс проверки остановлен.