From 94108eec48740b47ecf50e016acc28db604e352d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CNaeel=E2=80=9D?= Date: Fri, 14 Aug 2026 13:45:06 +0400 Subject: [PATCH] =?UTF-8?q?v0.1.32:=20=D0=B3=D0=BB=D0=B0=D0=B2=D0=BD=D0=B0?= =?UTF-8?q?=D1=8F=20=E2=80=94=20=D0=BF=D0=BE=D1=88=D0=B0=D0=B3=D0=BE=D0=B2?= =?UTF-8?q?=D1=8B=D0=B9=20=D1=81=D1=82=D0=B0=D1=80=D1=82;=20=D0=BF=D1=80?= =?UTF-8?q?=D0=B8=D0=BC=D0=B5=D1=80=D1=8B=20=D0=BA=D0=BE=D0=BC=D0=B0=D0=BD?= =?UTF-8?q?=D0=B4=20=E2=80=94=20=D0=BD=D0=B0=20/examples=20=D0=BA=D1=80?= =?UTF-8?q?=D1=83=D0=BF=D0=BD=D1=8B=D0=BC=20=D1=88=D1=80=D0=B8=D1=84=D1=82?= =?UTF-8?q?=D0=BE=D0=BC;=20=D0=BA=D0=BE=D0=BD=D1=81=D0=BE=D0=BB=D1=8C=20?= =?UTF-8?q?=D1=81=D1=80=D0=B0=D0=B7=D1=83=20=D0=B2=20=D0=B0=D0=BA=D0=BA?= =?UTF-8?q?=D0=B0=D1=83=D0=BD=D1=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Makefile | 2 +- app/router/router.go | 5 + app/ui/embed.go | 16 ++- app/ui/examples.html | 228 +++++++++++++++++++++++++++++++++++++++++++ app/ui/index.html | 15 +-- app/ui/info.html | 146 ++++++++++++++++----------- 6 files changed, 346 insertions(+), 66 deletions(-) create mode 100644 app/ui/examples.html diff --git a/Makefile b/Makefile index 64abb83..2e56dc2 100644 --- a/Makefile +++ b/Makefile @@ -3,7 +3,7 @@ # Registry: Docker Hub (naeel/shared-sqs) IMAGE_REPO=naeel/shared-sqs -VERSION=v0.1.31 +VERSION=v0.1.32 LDFLAGS=-X shared-sqs/app/models.Version=$(VERSION) BINARY=shared-sqs diff --git a/app/router/router.go b/app/router/router.go index 78f1323..cbf4046 100644 --- a/app/router/router.go +++ b/app/router/router.go @@ -45,6 +45,11 @@ func New(tenantStore *tenant.TenantStore, adminToken string) http.Handler { // /metrics — Prometheus endpoint для Victoria Metrics scrape r.Handle("/metrics", promhttp.Handler()).Methods("GET") + // Страница примеров команд — публично + r.HandleFunc("/examples", func(w http.ResponseWriter, req *http.Request) { + ui.ExamplesHandler(models.Version).ServeHTTP(w, req) + }).Methods("GET") + // Админ-консоль — статика. Регистрируем ДО admin subrouter, // иначе PathPrefix("/admin") с bearer-auth перехватит GET /admin. r.HandleFunc("/admin", func(w http.ResponseWriter, req *http.Request) { diff --git a/app/ui/embed.go b/app/ui/embed.go index e4351cb..aa8fe9f 100644 --- a/app/ui/embed.go +++ b/app/ui/embed.go @@ -10,7 +10,7 @@ import ( "strings" ) -//go:embed index.html info.html admin.html static +//go:embed index.html info.html admin.html examples.html static var content embed.FS // Handler — возвращает http.Handler, раздающий встроенный index.html @@ -46,6 +46,20 @@ func AdminHandler(version string) http.Handler { }) } +// ExamplesHandler — страница примеров команд (GET /examples) с подстановкой версии +func ExamplesHandler(version string) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + body, err := content.ReadFile("examples.html") + if err != nil { + http.Error(w, "examples page unavailable", http.StatusInternalServerError) + return + } + html := strings.ReplaceAll(string(body), "{{VERSION}}", version) + w.Header().Set("Content-Type", "text/html; charset=utf-8") + _, _ = w.Write([]byte(html)) + }) +} + // StaticHandler — раздаёт /static/* (логотип, favicon) для публичных страниц func StaticHandler() http.Handler { sub, err := fs.Sub(content, "static") diff --git a/app/ui/examples.html b/app/ui/examples.html new file mode 100644 index 0000000..6b4d041 --- /dev/null +++ b/app/ui/examples.html @@ -0,0 +1,228 @@ + + + + + + +Примеры команд — shared-sqs + + + + + +
+ nubes + Nubes + · очередь + + ← На главную + {{VERSION}} +
+ +
+ +
+
+

Примеры команд

+

Пошаговое подключение к SQS API через AWS CLI. Ключи бери в консоли: /ui → кнопка Credentials.

+
+
+ +
+
Шаг 1. Укажи ключи доступа
+
+

AПеременные окружения (действуют в текущей сессии терминала):

+
export AWS_ACCESS_KEY_ID=<Access Key>
+export AWS_SECRET_ACCESS_KEY=<Secret Key>
+

BФайл ~/.aws/credentials (постоянно, для всех команд):

+
[sqs]
+aws_access_key_id = <Access Key>
+aws_secret_access_key = <Secret Key>
+

Для способа B добавляй --profile sqs к каждой команде.

+
+
+ +
+
Шаг 2. Создай очередь
+
+
aws sqs create-queue --queue-name demo \
+  --endpoint-url https://sqs.containerk8s.dev.nubes.ru \
+  --region us-east-1 --profile sqs
+

В ответе будет QueueUrl — используй его в следующих командах.

+
+
+ +
+
Шаг 3. Отправь сообщение
+
+
aws sqs send-message \
+  --queue-url <QueueUrl> \
+  --message-body "hello nubes" \
+  --endpoint-url https://sqs.containerk8s.dev.nubes.ru \
+  --region us-east-1 --profile sqs
+
+
+ +
+
Шаг 4. Получи и удали сообщение
+
+
aws sqs receive-message \
+  --queue-url <QueueUrl> \
+  --endpoint-url https://sqs.containerk8s.dev.nubes.ru \
+  --region us-east-1 --profile sqs
+
+aws sqs delete-message \
+  --queue-url <QueueUrl> \
+  --receipt-handle <ReceiptHandle из ответа receive-message> \
+  --endpoint-url https://sqs.containerk8s.dev.nubes.ru \
+  --region us-east-1 --profile sqs
+
+
+ +
+
Все команды SQS API
+
+

Все команды отправляются на POST https://sqs.containerk8s.dev.nubes.ru/ с параметром Action (AWS CLI делает это сам).

+
+ + + + + + + + + + + + + + + + + + + + + + + +
ActionОписание
CreateQueueСоздать очередь
ListQueuesСписок очередей
GetQueueUrlURL очереди по имени
GetQueueAttributesАтрибуты очереди
SetQueueAttributesИзменить атрибуты очереди
SendMessageОтправить сообщение
SendMessageBatchОтправить до 10 сообщений разом
ReceiveMessageПолучить сообщения (long polling до 20с)
DeleteMessageУдалить сообщение
DeleteMessageBatchУдалить до 10 сообщений разом
ChangeMessageVisibilityИзменить таймаут видимости сообщения
ChangeMessageVisibilityBatchПакетно изменить таймаут видимости
PurgeQueueОчистить очередь
DeleteQueueУдалить очередь
TagQueueНазначить теги очереди
UntagQueueСнять теги с очереди
ListQueueTagsСписок тегов очереди
+
+
+
+ + + +
+ + diff --git a/app/ui/index.html b/app/ui/index.html index 79f1c98..e951d50 100644 --- a/app/ui/index.html +++ b/app/ui/index.html @@ -384,7 +384,7 @@ td.msg-expand { padding: 0 !important; border-bottom: 1px solid var(--border); }
Админ-консоль: /admin (вход по admin-токену)
Realm: iot-naeel · Persistence: Managed Redis
Версия:
-
Образ: naeel/shared-sqs:v0.1.31
+
Образ: naeel/shared-sqs:v0.1.32
Статус: тестирование
@@ -609,7 +609,13 @@ function enterApp() { document.getElementById('login-page').classList.add('hidden'); document.getElementById('app').classList.remove('hidden'); document.getElementById('user-email').textContent = sessionEmail || ''; - showDashboard(); + // Юзер сразу попадает в свой аккаунт — без промежуточного дашборда с таблицей. + api('/tenants') + .then(list => { + if (list && list.length > 0) showTenant(list[0].id); + else showDashboard(); + }) + .catch(() => showDashboard()); } // ===== API HELPER ===== @@ -741,11 +747,6 @@ function renderTenant(tenant, queues) { const el = document.getElementById('view-tenant'); const totalMsgs = (queues || []).reduce((s, q) => s + q.messages + q.not_visible, 0); el.innerHTML = ` -
${(queues || []).length}
diff --git a/app/ui/info.html b/app/ui/info.html index 97b61f2..6a6435d 100644 --- a/app/ui/info.html +++ b/app/ui/info.html @@ -127,6 +127,52 @@ pre code { background: none; border: none; padding: 0; } .cmd-label:first-child { margin-top: 0; } .status-ok { color: var(--success); font-weight: 600; } .footer { color: var(--text-muted); font-size: 12px; text-align: center; margin-top: 32px; } + +/* Быстрый старт — шаги */ +.step { display: flex; gap: 14px; margin-bottom: 18px; } +.step:last-child { margin-bottom: 0; } +.step-num { + flex: 0 0 30px; + height: 30px; + border-radius: 999px; + background: var(--brand-primary); + color: #fff; + font-weight: 700; + display: flex; + align-items: center; + justify-content: center; + font-size: 15px; +} +.step-body { flex: 1; } +.step-title { font-weight: 600; font-size: 15px; margin-bottom: 2px; } +.step-body p { color: #374151; margin: 4px 0; } +.btn-hero { + display: inline-flex; + align-items: center; + gap: 8px; + background: var(--brand-primary); + color: #fff !important; + text-decoration: none !important; + font-size: 15px; + font-weight: 600; + padding: 10px 20px; + border-radius: 8px; + margin-top: 8px; +} +.btn-hero:hover { background: var(--brand-primary-dark); } +.link-card { text-align: center; padding: 8px 0 4px; } +.link-card a { font-size: 15px; font-weight: 600; } +.hint-box { + font-size: 14px; + color: #374151; + background: var(--brand-grey-light); + border: 1px solid var(--brand-gray); + border-radius: 8px; + padding: 10px 14px; + margin-top: 10px; + line-height: 1.7; +} +.hint-box code { font-family: ui-monospace, Menlo, Consolas, monospace; font-size: 13px; } @@ -145,7 +191,43 @@ pre code { background: none; border: none; padding: 0; } nubes

shared-sqs тестирование

-

Multi-tenant очередь, совместимая с AWS SQS API. Каждый тенант получает изолированное пространство очередей.

+

Очередь, совместимая с AWS SQS API. Твои очереди и сообщения — в одном месте, доступ по протоколу AWS.

+
+
+ +
+
Как начать — 3 шага
+
+
+
1
+
+
Войди в консоль
+

Возьми API-токен в панели Nubes и вставь его на странице входа.

+ Открыть консоль → +
+
+
+
2
+
+
Получи ключи доступа
+

В консоли нажми кнопку Credentials — там будут Access Key и Secret Key. Это и есть креды для подключения.

+
+
+
+
3
+
+
Подключи свой клиент
+

Укажи ключи в AWS CLI/SDK и работай с очередями как с обычным AWS SQS.

+
+ Быстрый вариант — переменные окружения:
+ export AWS_ACCESS_KEY_ID=<Access Key>
+ export AWS_SECRET_ACCESS_KEY=<Secret Key>
+ aws sqs list-queues --endpoint-url https://sqs.containerk8s.dev.nubes.ru --region us-east-1 +
+

Все примеры команд и способ через файл ~/.aws/credentials — на отдельной странице:

+ Примеры команд → +
+
@@ -159,9 +241,9 @@ pre code { background: none; border: none; padding: 0; }
Регион
us-east-1
Аутентификация
-
Access Key / Secret Key тенанта (выдаются в консоли /ui)
+
Access Key / Secret Key — получи в консоли /ui (кнопка Credentials)
Консоль
-
/ui — веб-интерфейс (вход по токену Nubes)
+
/ui — веб-интерфейс (вход по API-токену Nubes)
Health
Метрики
@@ -172,64 +254,14 @@ pre code { background: none; border: none; padding: 0; }
-
Команды SQS API
+
Команды и примеры
-

Все команды отправляются на корень POST https://sqs.containerk8s.dev.nubes.ru/ с параметром Action.

-
- - - - - - - - - - - - - - - - - - - - - - - -
ActionОписание
CreateQueueСоздать очередь
ListQueuesСписок очередей тенанта
GetQueueUrlURL очереди по имени
GetQueueAttributesАтрибуты очереди
SetQueueAttributesИзменить атрибуты очереди
SendMessageОтправить сообщение
SendMessageBatchОтправить до 10 сообщений разом
ReceiveMessageПолучить сообщения (long polling до 20с)
DeleteMessageУдалить сообщение
DeleteMessageBatchУдалить до 10 сообщений разом
ChangeMessageVisibilityИзменить таймаут видимости сообщения
ChangeMessageVisibilityBatchПакетно изменить таймаут видимости
PurgeQueueОчистить очередь
DeleteQueueУдалить очередь
TagQueueНазначить теги очереди
UntagQueueСнять теги с очереди
ListQueueTagsСписок тегов очереди
-
+

Полный список команд SQS API и подробные примеры для AWS CLI — на отдельной странице с крупным шрифтом.

+
-
-
Примеры (AWS CLI)
-
-
Ключи тенанта
-
export AWS_ACCESS_KEY_ID=<Access Key из /ui>
-export AWS_SECRET_ACCESS_KEY=<Secret Key из /ui>
-
Создать очередь
-
aws sqs create-queue --queue-name demo \
-  --endpoint-url https://sqs.containerk8s.dev.nubes.ru \
-  --region us-east-1
-
Отправить сообщение (QueueUrl — из ответа create-queue)
-
aws sqs send-message --queue-url <QueueUrl> \
-  --message-body "hello nubes" \
-  --endpoint-url https://sqs.containerk8s.dev.nubes.ru \
-  --region us-east-1
-
Получить и удалить сообщение
-
aws sqs receive-message --queue-url <QueueUrl> \
-  --endpoint-url https://sqs.containerk8s.dev.nubes.ru --region us-east-1
-
-aws sqs delete-message --queue-url <QueueUrl> \
-  --receipt-handle <ReceiptHandle> \
-  --endpoint-url https://sqs.containerk8s.dev.nubes.ru --region us-east-1
-
-
- - +