v0.1.32: главная — пошаговый старт; примеры команд — на /examples крупным шрифтом; консоль сразу в аккаунт
This commit is contained in:
@@ -3,7 +3,7 @@
|
|||||||
# Registry: Docker Hub (naeel/shared-sqs)
|
# Registry: Docker Hub (naeel/shared-sqs)
|
||||||
|
|
||||||
IMAGE_REPO=naeel/shared-sqs
|
IMAGE_REPO=naeel/shared-sqs
|
||||||
VERSION=v0.1.31
|
VERSION=v0.1.32
|
||||||
LDFLAGS=-X shared-sqs/app/models.Version=$(VERSION)
|
LDFLAGS=-X shared-sqs/app/models.Version=$(VERSION)
|
||||||
BINARY=shared-sqs
|
BINARY=shared-sqs
|
||||||
|
|
||||||
|
|||||||
@@ -45,6 +45,11 @@ func New(tenantStore *tenant.TenantStore, adminToken string) http.Handler {
|
|||||||
// /metrics — Prometheus endpoint для Victoria Metrics scrape
|
// /metrics — Prometheus endpoint для Victoria Metrics scrape
|
||||||
r.Handle("/metrics", promhttp.Handler()).Methods("GET")
|
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,
|
// Админ-консоль — статика. Регистрируем ДО admin subrouter,
|
||||||
// иначе PathPrefix("/admin") с bearer-auth перехватит GET /admin.
|
// иначе PathPrefix("/admin") с bearer-auth перехватит GET /admin.
|
||||||
r.HandleFunc("/admin", func(w http.ResponseWriter, req *http.Request) {
|
r.HandleFunc("/admin", func(w http.ResponseWriter, req *http.Request) {
|
||||||
|
|||||||
+15
-1
@@ -10,7 +10,7 @@ import (
|
|||||||
"strings"
|
"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
|
var content embed.FS
|
||||||
|
|
||||||
// Handler — возвращает http.Handler, раздающий встроенный index.html
|
// 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) для публичных страниц
|
// StaticHandler — раздаёт /static/* (логотип, favicon) для публичных страниц
|
||||||
func StaticHandler() http.Handler {
|
func StaticHandler() http.Handler {
|
||||||
sub, err := fs.Sub(content, "static")
|
sub, err := fs.Sub(content, "static")
|
||||||
|
|||||||
@@ -0,0 +1,228 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<!-- app/ui/examples.html — примеры команд SQS API (отдельная страница, крупный шрифт) -->
|
||||||
|
<html lang="ru">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<title>Примеры команд — shared-sqs</title>
|
||||||
|
<link rel="icon" type="image/svg+xml" href="/static/favicon.svg">
|
||||||
|
<style>
|
||||||
|
:root {
|
||||||
|
--brand-primary: #2563eb;
|
||||||
|
--brand-primary-dark: #1d4ed8;
|
||||||
|
--brand-gray: #d1d5db;
|
||||||
|
--brand-grey-light: #f3f4f6;
|
||||||
|
--text-primary: #1a1a1a;
|
||||||
|
--text-muted: #6b7280;
|
||||||
|
--success: #16a34a;
|
||||||
|
--warning: #d97706;
|
||||||
|
}
|
||||||
|
* { box-sizing: border-box; }
|
||||||
|
body {
|
||||||
|
margin: 0;
|
||||||
|
font-family: system-ui, "Segoe UI", Roboto, sans-serif;
|
||||||
|
font-size: 15px;
|
||||||
|
color: var(--text-primary);
|
||||||
|
background: #fafafa;
|
||||||
|
line-height: 1.6;
|
||||||
|
}
|
||||||
|
.topbar {
|
||||||
|
height: 56px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 8px;
|
||||||
|
padding: 0 16px;
|
||||||
|
background: #fff;
|
||||||
|
border-bottom: 1px solid var(--brand-gray);
|
||||||
|
position: sticky;
|
||||||
|
top: 0;
|
||||||
|
}
|
||||||
|
.topbar .brand { font-weight: 600; }
|
||||||
|
.topbar .muted { color: var(--text-muted); }
|
||||||
|
.topbar .spacer { flex: 1; }
|
||||||
|
.chip {
|
||||||
|
font-family: ui-monospace, monospace;
|
||||||
|
font-size: 12px;
|
||||||
|
color: var(--brand-primary);
|
||||||
|
background: #eff6ff;
|
||||||
|
border: 1px solid #bfdbfe;
|
||||||
|
border-radius: 999px;
|
||||||
|
padding: 2px 10px;
|
||||||
|
}
|
||||||
|
a { color: var(--brand-primary); text-decoration: none; }
|
||||||
|
a:hover { color: var(--brand-primary-dark); text-decoration: underline; }
|
||||||
|
.container { max-width: 960px; margin: 0 auto; padding: 24px 16px 48px; }
|
||||||
|
.hero { display: flex; align-items: center; gap: 16px; margin-bottom: 24px; }
|
||||||
|
.hero h1 { font-size: 26px; margin: 0; }
|
||||||
|
.hero .sub { color: var(--text-muted); margin: 4px 0 0; }
|
||||||
|
.card {
|
||||||
|
background: #fff;
|
||||||
|
border: 1px solid var(--brand-gray);
|
||||||
|
border-radius: 12px;
|
||||||
|
box-shadow: 0 1px 2px rgba(0,0,0,0.05);
|
||||||
|
margin-bottom: 20px;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
.card-header { background: var(--brand-grey-light); padding: 12px 16px; font-weight: 600; font-size: 16px; }
|
||||||
|
.card-body { padding: 16px; }
|
||||||
|
.card-body p { margin: 8px 0; color: #374151; }
|
||||||
|
.step-num {
|
||||||
|
display: inline-flex;
|
||||||
|
width: 26px;
|
||||||
|
height: 26px;
|
||||||
|
border-radius: 999px;
|
||||||
|
background: var(--brand-primary);
|
||||||
|
color: #fff;
|
||||||
|
font-weight: 700;
|
||||||
|
font-size: 14px;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
margin-right: 8px;
|
||||||
|
}
|
||||||
|
pre {
|
||||||
|
background: var(--brand-grey-light);
|
||||||
|
border: 1px solid var(--brand-gray);
|
||||||
|
border-radius: 8px;
|
||||||
|
padding: 14px 16px;
|
||||||
|
overflow-x: auto;
|
||||||
|
font-family: ui-monospace, Menlo, Consolas, monospace;
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 1.7;
|
||||||
|
margin: 10px 0 16px;
|
||||||
|
}
|
||||||
|
pre code { background: none; border: none; padding: 0; }
|
||||||
|
.note {
|
||||||
|
font-size: 13px;
|
||||||
|
color: var(--text-muted);
|
||||||
|
margin: -8px 0 14px;
|
||||||
|
}
|
||||||
|
.tbl-wrap { border: 1px solid var(--brand-gray); border-radius: 8px; overflow-x: auto; }
|
||||||
|
table { width: 100%; border-collapse: collapse; font-size: 14px; }
|
||||||
|
th {
|
||||||
|
background: var(--brand-grey-light);
|
||||||
|
text-align: left;
|
||||||
|
text-transform: uppercase;
|
||||||
|
font-size: 12px;
|
||||||
|
letter-spacing: 0.3px;
|
||||||
|
padding: 8px 12px;
|
||||||
|
border-right: 1px solid var(--brand-gray);
|
||||||
|
color: var(--text-muted);
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
td { padding: 8px 12px; border-right: 1px solid var(--brand-gray); border-bottom: 1px solid var(--brand-gray); }
|
||||||
|
tr:last-child td { border-bottom: none; }
|
||||||
|
td:last-child, th:last-child { border-right: none; }
|
||||||
|
tr:hover td { background: rgba(243,244,246,0.5); }
|
||||||
|
td code { font-family: ui-monospace, Menlo, Consolas, monospace; font-size: 13px; }
|
||||||
|
.footer { color: var(--text-muted); font-size: 13px; text-align: center; margin-top: 32px; }
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<div class="topbar">
|
||||||
|
<img src="/static/logo.svg" height="18" alt="nubes">
|
||||||
|
<span class="brand">Nubes</span>
|
||||||
|
<span class="muted">· очередь</span>
|
||||||
|
<span class="spacer"></span>
|
||||||
|
<a href="/">← На главную</a>
|
||||||
|
<span class="chip">{{VERSION}}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="container">
|
||||||
|
|
||||||
|
<div class="hero">
|
||||||
|
<div>
|
||||||
|
<h1>Примеры команд</h1>
|
||||||
|
<p class="sub">Пошаговое подключение к SQS API через AWS CLI. Ключи бери в консоли: <a href="/ui">/ui</a> → кнопка Credentials.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-header">Шаг 1. Укажи ключи доступа</div>
|
||||||
|
<div class="card-body">
|
||||||
|
<p><span class="step-num">A</span><strong>Переменные окружения</strong> (действуют в текущей сессии терминала):</p>
|
||||||
|
<pre><code>export AWS_ACCESS_KEY_ID=<Access Key>
|
||||||
|
export AWS_SECRET_ACCESS_KEY=<Secret Key></code></pre>
|
||||||
|
<p><span class="step-num">B</span><strong>Файл ~/.aws/credentials</strong> (постоянно, для всех команд):</p>
|
||||||
|
<pre><code>[sqs]
|
||||||
|
aws_access_key_id = <Access Key>
|
||||||
|
aws_secret_access_key = <Secret Key></code></pre>
|
||||||
|
<p class="note">Для способа B добавляй <code>--profile sqs</code> к каждой команде.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-header">Шаг 2. Создай очередь</div>
|
||||||
|
<div class="card-body">
|
||||||
|
<pre><code>aws sqs create-queue --queue-name demo \
|
||||||
|
--endpoint-url https://sqs.containerk8s.dev.nubes.ru \
|
||||||
|
--region us-east-1 --profile sqs</code></pre>
|
||||||
|
<p>В ответе будет <code>QueueUrl</code> — используй его в следующих командах.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-header">Шаг 3. Отправь сообщение</div>
|
||||||
|
<div class="card-body">
|
||||||
|
<pre><code>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</code></pre>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-header">Шаг 4. Получи и удали сообщение</div>
|
||||||
|
<div class="card-body">
|
||||||
|
<pre><code>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</code></pre>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-header">Все команды SQS API</div>
|
||||||
|
<div class="card-body">
|
||||||
|
<p>Все команды отправляются на <code>POST https://sqs.containerk8s.dev.nubes.ru/</code> с параметром <code>Action</code> (AWS CLI делает это сам).</p>
|
||||||
|
<div class="tbl-wrap">
|
||||||
|
<table>
|
||||||
|
<thead>
|
||||||
|
<tr><th>Action</th><th>Описание</th></tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr><td><code>CreateQueue</code></td><td>Создать очередь</td></tr>
|
||||||
|
<tr><td><code>ListQueues</code></td><td>Список очередей</td></tr>
|
||||||
|
<tr><td><code>GetQueueUrl</code></td><td>URL очереди по имени</td></tr>
|
||||||
|
<tr><td><code>GetQueueAttributes</code></td><td>Атрибуты очереди</td></tr>
|
||||||
|
<tr><td><code>SetQueueAttributes</code></td><td>Изменить атрибуты очереди</td></tr>
|
||||||
|
<tr><td><code>SendMessage</code></td><td>Отправить сообщение</td></tr>
|
||||||
|
<tr><td><code>SendMessageBatch</code></td><td>Отправить до 10 сообщений разом</td></tr>
|
||||||
|
<tr><td><code>ReceiveMessage</code></td><td>Получить сообщения (long polling до 20с)</td></tr>
|
||||||
|
<tr><td><code>DeleteMessage</code></td><td>Удалить сообщение</td></tr>
|
||||||
|
<tr><td><code>DeleteMessageBatch</code></td><td>Удалить до 10 сообщений разом</td></tr>
|
||||||
|
<tr><td><code>ChangeMessageVisibility</code></td><td>Изменить таймаут видимости сообщения</td></tr>
|
||||||
|
<tr><td><code>ChangeMessageVisibilityBatch</code></td><td>Пакетно изменить таймаут видимости</td></tr>
|
||||||
|
<tr><td><code>PurgeQueue</code></td><td>Очистить очередь</td></tr>
|
||||||
|
<tr><td><code>DeleteQueue</code></td><td>Удалить очередь</td></tr>
|
||||||
|
<tr><td><code>TagQueue</code></td><td>Назначить теги очереди</td></tr>
|
||||||
|
<tr><td><code>UntagQueue</code></td><td>Снять теги с очереди</td></tr>
|
||||||
|
<tr><td><code>ListQueueTags</code></td><td>Список тегов очереди</td></tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="footer">shared-sqs · версия {{VERSION}} · <a href="/">на главную</a> · <a href="/ui">консоль</a> · <a href="/health">health</a></div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
+8
-7
@@ -384,7 +384,7 @@ td.msg-expand { padding: 0 !important; border-bottom: 1px solid var(--border); }
|
|||||||
<div>Админ-консоль: <a href="/admin">/admin</a> (вход по admin-токену)</div>
|
<div>Админ-консоль: <a href="/admin">/admin</a> (вход по admin-токену)</div>
|
||||||
<div>Realm: <span style="font-family:monospace">iot-naeel</span> · Persistence: Managed Redis</div>
|
<div>Realm: <span style="font-family:monospace">iot-naeel</span> · Persistence: Managed Redis</div>
|
||||||
<div>Версия: <span id="svc-version" style="font-family:monospace">—</span></div>
|
<div>Версия: <span id="svc-version" style="font-family:monospace">—</span></div>
|
||||||
<div>Образ: <span style="font-family:monospace">naeel/shared-sqs:v0.1.31</span></div>
|
<div>Образ: <span style="font-family:monospace">naeel/shared-sqs:v0.1.32</span></div>
|
||||||
<div style="margin-top:8px;color:var(--warning)">Статус: тестирование</div>
|
<div style="margin-top:8px;color:var(--warning)">Статус: тестирование</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -609,7 +609,13 @@ function enterApp() {
|
|||||||
document.getElementById('login-page').classList.add('hidden');
|
document.getElementById('login-page').classList.add('hidden');
|
||||||
document.getElementById('app').classList.remove('hidden');
|
document.getElementById('app').classList.remove('hidden');
|
||||||
document.getElementById('user-email').textContent = sessionEmail || '';
|
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 =====
|
// ===== API HELPER =====
|
||||||
@@ -741,11 +747,6 @@ function renderTenant(tenant, queues) {
|
|||||||
const el = document.getElementById('view-tenant');
|
const el = document.getElementById('view-tenant');
|
||||||
const totalMsgs = (queues || []).reduce((s, q) => s + q.messages + q.not_visible, 0);
|
const totalMsgs = (queues || []).reduce((s, q) => s + q.messages + q.not_visible, 0);
|
||||||
el.innerHTML = `
|
el.innerHTML = `
|
||||||
<div class="breadcrumb">
|
|
||||||
<a href="#" onclick="event.preventDefault();showDashboard()">Мой аккаунт</a>
|
|
||||||
<span>›</span>
|
|
||||||
${esc(tenant.name)}
|
|
||||||
</div>
|
|
||||||
<div class="stats-grid">
|
<div class="stats-grid">
|
||||||
<div class="stat-card">
|
<div class="stat-card">
|
||||||
<div class="stat-value">${(queues || []).length}</div>
|
<div class="stat-value">${(queues || []).length}</div>
|
||||||
|
|||||||
+89
-57
@@ -127,6 +127,52 @@ pre code { background: none; border: none; padding: 0; }
|
|||||||
.cmd-label:first-child { margin-top: 0; }
|
.cmd-label:first-child { margin-top: 0; }
|
||||||
.status-ok { color: var(--success); font-weight: 600; }
|
.status-ok { color: var(--success); font-weight: 600; }
|
||||||
.footer { color: var(--text-muted); font-size: 12px; text-align: center; margin-top: 32px; }
|
.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; }
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
@@ -145,7 +191,43 @@ pre code { background: none; border: none; padding: 0; }
|
|||||||
<img src="/static/logo.svg" height="28" alt="nubes">
|
<img src="/static/logo.svg" height="28" alt="nubes">
|
||||||
<div>
|
<div>
|
||||||
<h1>shared-sqs <span class="badge">тестирование</span></h1>
|
<h1>shared-sqs <span class="badge">тестирование</span></h1>
|
||||||
<p class="sub">Multi-tenant очередь, совместимая с AWS SQS API. Каждый тенант получает изолированное пространство очередей.</p>
|
<p class="sub">Очередь, совместимая с AWS SQS API. Твои очереди и сообщения — в одном месте, доступ по протоколу AWS.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-header">Как начать — 3 шага</div>
|
||||||
|
<div class="card-body">
|
||||||
|
<div class="step">
|
||||||
|
<div class="step-num">1</div>
|
||||||
|
<div class="step-body">
|
||||||
|
<div class="step-title">Войди в консоль</div>
|
||||||
|
<p>Возьми API-токен в панели Nubes и вставь его на странице входа.</p>
|
||||||
|
<a class="btn-hero" href="/ui">Открыть консоль →</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="step">
|
||||||
|
<div class="step-num">2</div>
|
||||||
|
<div class="step-body">
|
||||||
|
<div class="step-title">Получи ключи доступа</div>
|
||||||
|
<p>В консоли нажми кнопку <code>Credentials</code> — там будут <strong>Access Key</strong> и <strong>Secret Key</strong>. Это и есть креды для подключения.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="step">
|
||||||
|
<div class="step-num">3</div>
|
||||||
|
<div class="step-body">
|
||||||
|
<div class="step-title">Подключи свой клиент</div>
|
||||||
|
<p>Укажи ключи в AWS CLI/SDK и работай с очередями как с обычным AWS SQS.</p>
|
||||||
|
<div class="hint-box">
|
||||||
|
Быстрый вариант — переменные окружения:<br>
|
||||||
|
<code>export AWS_ACCESS_KEY_ID=<Access Key></code><br>
|
||||||
|
<code>export AWS_SECRET_ACCESS_KEY=<Secret Key></code><br>
|
||||||
|
<code>aws sqs list-queues --endpoint-url https://sqs.containerk8s.dev.nubes.ru --region us-east-1</code>
|
||||||
|
</div>
|
||||||
|
<p style="margin-top:10px">Все примеры команд и способ через файл <code>~/.aws/credentials</code> — на отдельной странице:</p>
|
||||||
|
<a class="btn-hero" href="/examples">Примеры команд →</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -159,9 +241,9 @@ pre code { background: none; border: none; padding: 0; }
|
|||||||
<div class="k">Регион</div>
|
<div class="k">Регион</div>
|
||||||
<div class="v">us-east-1</div>
|
<div class="v">us-east-1</div>
|
||||||
<div class="k">Аутентификация</div>
|
<div class="k">Аутентификация</div>
|
||||||
<div class="v">Access Key / Secret Key тенанта (выдаются в консоли <a href="/ui">/ui</a>)</div>
|
<div class="v">Access Key / Secret Key — получи в консоли <a href="/ui">/ui</a> (кнопка Credentials)</div>
|
||||||
<div class="k">Консоль</div>
|
<div class="k">Консоль</div>
|
||||||
<div class="v"><a href="/ui">/ui</a> — веб-интерфейс (вход по токену Nubes)</div>
|
<div class="v"><a href="/ui">/ui</a> — веб-интерфейс (вход по API-токену Nubes)</div>
|
||||||
<div class="k">Health</div>
|
<div class="k">Health</div>
|
||||||
<div class="v"><a href="/health">GET /health</a> <span class="status-ok">● ok</span></div>
|
<div class="v"><a href="/health">GET /health</a> <span class="status-ok">● ok</span></div>
|
||||||
<div class="k">Метрики</div>
|
<div class="k">Метрики</div>
|
||||||
@@ -172,64 +254,14 @@ pre code { background: none; border: none; padding: 0; }
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="card">
|
<div class="card">
|
||||||
<div class="card-header">Команды SQS API</div>
|
<div class="card-header">Команды и примеры</div>
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<p>Все команды отправляются на корень <code>POST https://sqs.containerk8s.dev.nubes.ru/</code> с параметром <code>Action</code>.</p>
|
<p style="color:#374151">Полный список команд SQS API и подробные примеры для AWS CLI — на отдельной странице с крупным шрифтом.</p>
|
||||||
<div class="tbl-wrap">
|
<div class="link-card"><a href="/examples">Открыть примеры команд →</a></div>
|
||||||
<table>
|
|
||||||
<thead>
|
|
||||||
<tr><th>Action</th><th>Описание</th></tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
<tr><td><code>CreateQueue</code></td><td>Создать очередь</td></tr>
|
|
||||||
<tr><td><code>ListQueues</code></td><td>Список очередей тенанта</td></tr>
|
|
||||||
<tr><td><code>GetQueueUrl</code></td><td>URL очереди по имени</td></tr>
|
|
||||||
<tr><td><code>GetQueueAttributes</code></td><td>Атрибуты очереди</td></tr>
|
|
||||||
<tr><td><code>SetQueueAttributes</code></td><td>Изменить атрибуты очереди</td></tr>
|
|
||||||
<tr><td><code>SendMessage</code></td><td>Отправить сообщение</td></tr>
|
|
||||||
<tr><td><code>SendMessageBatch</code></td><td>Отправить до 10 сообщений разом</td></tr>
|
|
||||||
<tr><td><code>ReceiveMessage</code></td><td>Получить сообщения (long polling до 20с)</td></tr>
|
|
||||||
<tr><td><code>DeleteMessage</code></td><td>Удалить сообщение</td></tr>
|
|
||||||
<tr><td><code>DeleteMessageBatch</code></td><td>Удалить до 10 сообщений разом</td></tr>
|
|
||||||
<tr><td><code>ChangeMessageVisibility</code></td><td>Изменить таймаут видимости сообщения</td></tr>
|
|
||||||
<tr><td><code>ChangeMessageVisibilityBatch</code></td><td>Пакетно изменить таймаут видимости</td></tr>
|
|
||||||
<tr><td><code>PurgeQueue</code></td><td>Очистить очередь</td></tr>
|
|
||||||
<tr><td><code>DeleteQueue</code></td><td>Удалить очередь</td></tr>
|
|
||||||
<tr><td><code>TagQueue</code></td><td>Назначить теги очереди</td></tr>
|
|
||||||
<tr><td><code>UntagQueue</code></td><td>Снять теги с очереди</td></tr>
|
|
||||||
<tr><td><code>ListQueueTags</code></td><td>Список тегов очереди</td></tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="card">
|
<div class="footer">shared-sqs · realm iot-naeel · версия {{VERSION}} · <a href="/examples">примеры</a> · <a href="/metrics">метрики</a> · <a href="/health">health</a> · <a href="/admin">админ</a></div>
|
||||||
<div class="card-header">Примеры (AWS CLI)</div>
|
|
||||||
<div class="card-body">
|
|
||||||
<div class="cmd-label">Ключи тенанта</div>
|
|
||||||
<pre><code>export AWS_ACCESS_KEY_ID=<Access Key из /ui>
|
|
||||||
export AWS_SECRET_ACCESS_KEY=<Secret Key из /ui></code></pre>
|
|
||||||
<div class="cmd-label">Создать очередь</div>
|
|
||||||
<pre><code>aws sqs create-queue --queue-name demo \
|
|
||||||
--endpoint-url https://sqs.containerk8s.dev.nubes.ru \
|
|
||||||
--region us-east-1</code></pre>
|
|
||||||
<div class="cmd-label">Отправить сообщение (QueueUrl — из ответа create-queue)</div>
|
|
||||||
<pre><code>aws sqs send-message --queue-url <QueueUrl> \
|
|
||||||
--message-body "hello nubes" \
|
|
||||||
--endpoint-url https://sqs.containerk8s.dev.nubes.ru \
|
|
||||||
--region us-east-1</code></pre>
|
|
||||||
<div class="cmd-label">Получить и удалить сообщение</div>
|
|
||||||
<pre><code>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</code></pre>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="footer">shared-sqs · realm iot-naeel · версия {{VERSION}} · <a href="/metrics">метрики</a> · <a href="/health">health</a></div>
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
|
|||||||
Reference in New Issue
Block a user