fix(terminal): запретить выключенные устройства и исправить средний RTT
No files matched your search
@@ -4,11 +4,11 @@ import {validatorCompiler,serializerCompiler} from "@fastify/type-provider-zod"
|
||||
import {createExecRoutes,type ExecDependencies} from "./exec.js"
|
||||
import type {servers} from "../db/schema.js"
|
||||
const outputs:Record<string,unknown>={getIdentity:{name:"test"},getResource:{}}
|
||||
const calls:unknown[][]=[];let exists=true,lookups=0
|
||||
const calls:unknown[][]=[];let exists=true,lookups=0,enabled=true,clients=0
|
||||
const names=["getIpAddresses","getInterfaces","getResource","getIdentity","getIpRoutes","getFirewallFilters","getBgpSessions","getOspfNeighbors","getOspfAreas","getOspfInstances","getOspfInterfaceTemplates","getBfdSessions","getLogs","ping"]
|
||||
const client=Object.fromEntries(names.map(key=>[key,async(...args:unknown[])=>{calls.push([key,...args]);if(outputs[key] instanceof Error)throw outputs[key];return outputs[key]??[]}])) as unknown as ReturnType<ExecDependencies["createClient"]>
|
||||
const app=Fastify();app.setValidatorCompiler(validatorCompiler);app.setSerializerCompiler(serializerCompiler)
|
||||
await app.register(createExecRoutes({getServer:async()=>{lookups++;return exists?{id:1,name:"Тест",host:"192.0.2.1",enabled:true} as typeof servers.$inferSelect:undefined},createClient:()=>client}),{prefix:"/api"})
|
||||
await app.register(createExecRoutes({getServer:async()=>{lookups++;return exists?{id:1,name:"Тест",host:"192.0.2.1",enabled} as typeof servers.$inferSelect:undefined},createClient:()=>{clients++;return client}}),{prefix:"/api"})
|
||||
const send=(command:string)=>app.inject({method:"POST",url:"/api/servers/1/exec",payload:{command}})
|
||||
for(const command of ["ip address print","interface print","system resource print","system identity print","ip route print","ip firewall filter print","routing bgp session print","routing ospf neighbor print","routing ospf area print","routing ospf instance print","routing ospf interface print","routing bfd session print","log print","/IP ADDRESS PRINT","help"]){
|
||||
const response=await send(command);assert.equal(response.statusCode,200,command);assert.equal(typeof response.json().output,"string")
|
||||
@@ -23,9 +23,15 @@ outputs.getOspfInstances=[{name:"test"}];assert.match((await send("routing ospf
|
||||
outputs.getFirewallFilters=[{".id":"*1",chain:"input",action:"accept",packets:"0"}];assert.ok((await send("ip firewall filter print")).json().output.includes("packets=0 bytes=?"))
|
||||
outputs.getResource={"free-memory":"junk"};assert.ok(!(await send("system resource print")).json().output.includes("NaN"))
|
||||
outputs.ping=[{seq:"0",status:"timeout"},{sent:"0",received:"0"}];const ping=(await send("ping 192.0.2.2 count=2")).json().output;assert.ok(ping.includes("seq=0 timeout"));assert.ok(ping.includes("sent=0 received=0 packet-loss=?"));assert.deepEqual(calls.at(-1),["ping","192.0.2.2",2])
|
||||
outputs.ping=[{seq:"0",time:"1ms"},{seq:"1",time:"9ms",sent:"2",received:"2","avg-rtt":"5ms"}];assert.match((await send("ping 192.0.2.2 count=2")).json().output,/avg-rtt=5ms/)
|
||||
outputs.ping=[{seq:"0",time:"9ms",sent:"1",received:"1"}];assert.match((await send("ping 192.0.2.2 count=1")).json().output,/avg-rtt=\?/)
|
||||
for(const average of ["junk","",undefined]){outputs.ping=[{sent:"1",received:"1",time:"9ms","avg-rtt":average}];assert.match((await send("ping 192.0.2.2 count=1")).json().output,/avg-rtt=\?/)}
|
||||
outputs.ping=[{sent:"1",received:"0","avg-rtt":"0ms"}];assert.match((await send("ping 192.0.2.2 count=1")).json().output,/avg-rtt=\?/)
|
||||
outputs.ping=[{sent:"1",received:"1","avg-rtt":"0ms"}];assert.match((await send("ping 192.0.2.2 count=1")).json().output,/avg-rtt=0ms/)
|
||||
assert.equal((await send("ping 192.0.2.2 count=99")).statusCode,200);assert.deepEqual(calls.at(-1),["ping","192.0.2.2",20])
|
||||
assert.equal((await send("log print limit=500")).statusCode,200);assert.deepEqual(calls.at(-1),["getLogs",200])
|
||||
for(const command of ["system reboot","pingbad 192.0.2.2","log printable","ping","ping 192.0.2.2 count=0","ping 192.0.2.2 count=1junk","ping 192.0.2.2 count=1 count=2","log print limit=0","log print limit=3junk"]){const before=calls.length;assert.equal((await send(command)).statusCode,400,command);assert.equal(calls.length,before)}
|
||||
exists=false;assert.equal((await send("interface print")).statusCode,404);exists=true
|
||||
enabled=false;const beforeDisabled={clients,calls:calls.length};for(const command of["interface print","ping 192.0.2.2 count=1","help"])assert.equal((await send(command)).statusCode,409);assert.deepEqual({clients,calls:calls.length},beforeDisabled);enabled=true
|
||||
const before=lookups;for(const payload of [{},{command:""},{command:"x".repeat(1025)}])assert.equal((await app.inject({method:"POST",url:"/api/servers/1/exec",payload})).statusCode,400);assert.equal(lookups,before)
|
||||
await app.close();console.log("Exec HTTP: readonly allowlist, errors/known empty, unknown versus defaults, bounded arguments and missing/bad requests; no DB/RouterOS")
|
||||
@@ -4,6 +4,7 @@ import { z } from "zod"
|
||||
import { db } from "../db/index.js"
|
||||
import { servers } from "../db/schema.js"
|
||||
import { MikrotikClient } from "../services/mikrotik.js"
|
||||
import { observedDurationMs, observedInteger } from "../services/ospf-observed-values.js"
|
||||
import { ServerIdParamSchema, type ServerIdParams } from "../types/server.js"
|
||||
import type {
|
||||
RosIpAddress, RosInterface, RosResource, RosIdentity, RosIpRoute,
|
||||
@@ -208,7 +209,9 @@ function fmtPing(results: RosPingResult[], host: string): string {
|
||||
if (sum) {
|
||||
const loss = sum["packet-loss"] ?? "?"
|
||||
lines.push(` sent=${sum.sent} received=${sum.received??"?"} packet-loss=${loss}`)
|
||||
if (sum.time) lines.push(` avg-rtt=${sum.time}`)
|
||||
const average = sum["avg-rtt"]
|
||||
const received = typeof sum.received === "string" ? observedInteger(sum.received, 1) : null
|
||||
lines.push(` avg-rtt=${received !== null && typeof average === "string" && observedDurationMs(average) !== null ? average : "?"}`)
|
||||
}
|
||||
return lines.join("\n")
|
||||
}
|
||||
@@ -316,6 +319,7 @@ export function createExecRoutes(dependencies:ExecDependencies=defaults):Fastify
|
||||
app.post("/servers/:id/exec",{schema:{params:ServerIdParamSchema,body:ExecBodySchema}},async(req,reply)=>{
|
||||
const server=await dependencies.getServer((req.params as ServerIdParams).id)
|
||||
if(!server)return reply.status(404).send({error:"Устройство не найдено"})
|
||||
if(!server.enabled)return reply.status(409).send({error:"Устройство отключено: выполнение команд недоступно"})
|
||||
try {
|
||||
const output=await dispatch(dependencies.createClient(server),req.body.command)
|
||||
return reply.send({output})
|
||||
|
||||
@@ -397,6 +397,7 @@ export interface RosPingResult {
|
||||
"sent"?: string
|
||||
"received"?: string
|
||||
"packet-loss"?: string
|
||||
"avg-rtt"?: string
|
||||
"status"?: string // "timeout" when lost
|
||||
}
|
||||
|
||||
|
||||
@@ -781,3 +781,33 @@ Request-local receipt сохраняет подтверждённые createdIds
|
||||
**Runtime/фиксация.** Одна backend сборка ux-recursive88/version1.0.0-test.recursive88, image sha256:d358ec1d6ea87ea7f29a12cc4fd3c1a6a7929b854bcdc732d956c702fe4dc587. Backend/PG healthy, frontend ux-optimizer87 сохранён и принят браузером. Context optimizer87 final-c +6 backend файлов, override SHA de4caf2aced38ba7e490f6a459a19d359cc92cb5b098564b799c05bc86be1365; label не Git SHA, рабочее состояние до коммита. Entry/node --check/pg_restore18.6, compose --wait passed, apt cached. .env backup приватный, миграций нет. Один локальный commit без push. REST метод подтверждён [RouterOS REST API](https://help.mikrotik.com/docs/spaces/ROS/pages/47579162/REST%2BAPI).
|
||||
|
||||
Следующий89 — диагностика/терминал: реальный запуск, ограниченные команды, ошибки, права и контекст. Routing alternate-path/BFD sustained failover, IPv6/scale/physical disconnect/durable retry/Portal SSO и остальные внешние границы остаются открытыми. Квота38% использовано после блока; этап12.5 открыт.
|
||||
|
||||
## 12.5.89 — диагностика и терминал: реальные ответы и JWT-права (2026-10-09)
|
||||
|
||||
**Изменения.** Exec отклоняет enabled=false до создания клиента, включая локальную help-команду. Средний Ping RTT больше не берётся из time последнего пакета: используется подтверждённый native avg-rtt при received>0. Отсутствующий/неверный average или отсутствие полученных пакетов → ?, явный0ms при полученном ответе сохраняется. RosPingResult дополнен avg-rtt. Allowlist/сетевые правила/GUI не менялись.
|
||||
|
||||
| Проверка | Доказательство |
|
||||
| --- | --- |
|
||||
| Два disabled типа | Exec и все6 probe tools:16 ответов409, probeRequests0 |
|
||||
| Native терминал | Identity/resource/routes/OSPF/BFD, Ping3/3, ограниченный log read; неизвестная команда400 |
|
||||
| Native диагностика | Ping3/3, traceroute≤3 hops/1 probe/1s timeout, active route lookup, DF MTU probe |
|
||||
| DNS приложения | example.com A; .invalid502 без ложного output |
|
||||
| Средний RTT | Compiled exec formatter сверён с avg-rtt того же native Ping запроса |
|
||||
| JWT API | 401 none/invalid,403 reader/network writer,200 server writer/admin; native factory0 до разрешения |
|
||||
| Реальный UI | 8/8: две страницы×два CHR×1280/320, Ping5/5, ошибочный command сохранён |
|
||||
|
||||
**Приёмка.** [Native/API/RBAC отчёт](ux-ui/acceptance/diagnostics-terminal-2026-10-09.json). Read-only allowlist применяется обычным production API. Текст log print limit=1 не сохранён в Git, записана только длина. DNS выполняется на backend, что явно подписано в UI; не выдаётся за RouterOS DNS. Traceroute ограничен тремя хопами и не считается полным путём. MTU — первая успешная DF проба из существующего набора до1500, не доказательство максимального MTU/jumbo/SLA. Uncapped bandwidth endpoint не запускался: capped native smoke82 остаётся отдельным доказательством.
|
||||
|
||||
JWT тест использовал изолированный экземпляр compiled exec/probes routes, реальные credentials/native reads, временный локальный secret/issuer и настоящие подписи HS256. Проверены обе API группы и отсутствие native client до разрешения. В production AUTH_REQUIRED=false сохранён, Portal SSO/browser login этой проверкой не принят. Native configuration/пароли не изменялись.
|
||||
|
||||
**Браузер.** Настоящие deployed frontend/backend, без interception/mocks. Terminal400 сохраняет ввод; следующий resource request подтверждён, вывод содержит7.24.5, поле очищено и фокус возвращён. Probes Ping5/5 с правильным source/target, reload server context, document fits/pageerror0. [Browser отчёт](ux-ui/acceptance/browser-diagnostics-2026-10-09.json), [терминал320](ux-ui/screens/terminal-real-server1-320-2026-10-09.png), [диагностика320](ux-ui/screens/probes-real-server1-320-2026-10-09.png). Последний снимок просмотрен; значения не подменены моками. Frame/ReUI композиция прежняя.
|
||||
|
||||
**Проверки и оснастка.**58 профильных E2E terminal data/layout и probes data/source passed; exec/probes HTTP, signed JWT unit, backend TypeScript/ESLint/diff passed. Probes.cancel локальный HTTP тест сначала получил sandbox EACCES, повторён только он с разрешённым loopback: passed, включая abort настоящего MikrotikClient POST к локальной HTTP-фикстуре. Это не доказательство остановки процесса на CHR; UI сохраняет соответствующее пояснение.
|
||||
|
||||
Production image не содержит dev-only jose: первый fixture import завершился до native requests, подписи заменены native crypto. Следующая RBAC попытка меняла process.env после загрузки env объекта и получила200 вместо ожидаемого401 в изолированном приложении с выключенной авторизацией. Исправлен только fixture: snapshot/config authRequired/secret/issuer и восстановление finally. Успешные phase1 native проверки не повторялись; report объединяет их с исправленным RBAC и browser phase.
|
||||
|
||||
**Контроль.** Собственные disabled DB rows удалены по id/name/host, fixture containers завершены. IDs7 native коллекций×2 совпали до/после: interfaces/addresses/routes/OSPF instances/BGP connections/BFD config/IPsec peers. Оба CHR доступны, пароли прежние; public/default routes и195.195.195.195/32 сохранены. Никаких VPN объектов в этом read-only блоке не создавалось.
|
||||
|
||||
**Runtime.** Один backend build ux-diagnostics89/version1.0.0-test.diagnostics89, image sha256:97c1cff01efd5055d3811b742e293180d5999ff1e326e42242e5c975b5f70349. Backend/PG healthy, frontend ux-optimizer87 сохранён/принят. Context recursive88 +3 exec/type files, override SHA2ca8c80d13a2dcce8b09c905f2b65d7467892ee6918cc102caad2d15d90bacbf7; label не Git SHA. Entry/node --check/pg_restore18.6/compose --wait passed, dependencies/apt cached. .env backup приватный, миграций и frontend rebuild нет. Один локальный commit без push.
|
||||
|
||||
Продолжение90 — два собственных GRE пути OSPF/BFD, потеря primary, переход на alternate, packet observations и возврат. Сохраняются sustained BFD-only/физическая WAN failure/IPv6/масштаб/максимальная производительность/Portal SSO и другие внешние границы. Квота56% использовано после блока; этап12.5 открыт.
|
||||
@@ -1,6 +1,6 @@
|
||||
# План реализации UX/UI по пятичасовым окнам
|
||||
|
||||
Актуальное продолжение 2026-10-09: 12.5.88 завершил рекурсивные маршруты: disabled guard всех6 native путей, PUT/строгий preflight/кэш transaction/partial-unknown-applied receipts. Реальный recursive gateway через свой GRE, Ping3/3×2, API apply/restore,12 disabled409/probe0 и4 live UI cases с2 добавлениями на320px. Native baseline4 коллекций×2 и прежние cache/history восстановлены. Backend ux-recursive88/frontend ux-optimizer87. Следующий12.5.89 — реальная диагностика и терминал, права/ошибки/контекст; затем оставшиеся routing failover и внешние границы. Квота38% использовано; этап12.5 открыт.
|
||||
Актуальное продолжение 2026-10-09: 12.5.89 принял терминал/диагностику: native Ping/trace/route/MTU, DNS приложения,16 disabled409/probe0,12 signed JWT gates и8 live UI cases. Исправлены exec enabled guard и avg RTT (native avg-rtt, не последний reply). Baseline7 коллекций×2 сохранён. Backend ux-diagnostics89/frontend ux-optimizer87. Следующий12.5.90 — контролируемый OSPF/BFD failover между двумя собственными GRE путями и восстановление; дальнейшие внешние ограничения сохраняются. Квота56% использовано; этап12.5 открыт.
|
||||
|
||||
Общий план проекта MikrotikManager. Основан на согласованном плане из задачи; точка продолжения обновлена 2026-10-09. Источник фактического прогресса, проверок и ограничений — [журнал реализации](ux-ui-progress.md). Этот документ задаёт объём и критерии завершения, журнал фиксирует результат.
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# UX/UI: журнал реализации
|
||||
|
||||
Актуальное продолжение 2026-10-09: 12.5.88 завершил рекурсивные маршруты: disabled guard всех6 native путей, PUT/строгий preflight/кэш transaction/partial-unknown-applied receipts. Реальный recursive gateway через свой GRE, Ping3/3×2, API apply/restore,12 disabled409/probe0 и4 live UI cases с2 добавлениями на320px. Native baseline4 коллекций×2 и прежние cache/history восстановлены. Backend ux-recursive88/frontend ux-optimizer87. Следующий12.5.89 — реальная диагностика и терминал, права/ошибки/контекст; затем оставшиеся routing failover и внешние границы. Квота38% использовано; этап12.5 открыт.
|
||||
Актуальное продолжение 2026-10-09: 12.5.89 принял терминал/диагностику: native Ping/trace/route/MTU, DNS приложения,16 disabled409/probe0,12 signed JWT gates и8 live UI cases. Исправлены exec enabled guard и avg RTT (native avg-rtt, не последний reply). Baseline7 коллекций×2 сохранён. Backend ux-diagnostics89/frontend ux-optimizer87. Следующий12.5.90 — контролируемый OSPF/BFD failover между двумя собственными GRE путями и восстановление; дальнейшие внешние ограничения сохраняются. Квота56% использовано; этап12.5 открыт.
|
||||
|
||||
Общий план: [UX/UI по этапам и пятичасовым окнам](ux-ui-plan.md). План задаёт объём, этот журнал фиксирует выполненные блоки и ограничения. Записи расположены от новых к старым; подробная история этапа12 также сохранена в [ux-ui-stage-12.md](ux-ui-stage-12.md).
|
||||
|
||||
@@ -36,7 +36,37 @@
|
||||
| 10 | Маршрутизация, диагностика, карта и терминал | Завершён в границах локальной приёмки 2026-10-01; блоки 10.1–10.71, внешние ограничения в 10.71 |
|
||||
| 11А | Пользователи, контейнеры, сертификаты и резервные копии | Завершён в границах локальной приёмки 2026-10-01; 11А.1–11А.33, внешние ограничения в 11А.33 |
|
||||
| 11Б | Оповещения, сбор данных, интеграции, релизы и настройки | Завершён в границах локальной приёмки 2026-10-03; ограничения и evidence в11Б.7 |
|
||||
| 12 | Итоговая доступность, адаптивность, производительность и регрессия | Локальная приёмка завершена в границах12.3.83; внешняя12.5 в работе, выполненные блоки1–88 и ограничения ниже. Runtime backend ux-recursive88/frontend ux-optimizer87. |
|
||||
| 12 | Итоговая доступность, адаптивность, производительность и регрессия | Локальная приёмка завершена в границах12.3.83; внешняя12.5 в работе, выполненные блоки1–89 и ограничения ниже. Runtime backend ux-diagnostics89/frontend ux-optimizer87. |
|
||||
|
||||
## 12.5.89 — диагностика и терминал: реальные ответы и JWT-права (2026-10-09)
|
||||
|
||||
**Изменения.** Exec отклоняет enabled=false до создания клиента, включая локальную help-команду. Средний Ping RTT больше не берётся из time последнего пакета: используется подтверждённый native avg-rtt при received>0. Отсутствующий/неверный average или отсутствие полученных пакетов → ?, явный0ms при полученном ответе сохраняется. RosPingResult дополнен avg-rtt. Allowlist/сетевые правила/GUI не менялись.
|
||||
|
||||
| Проверка | Доказательство |
|
||||
| --- | --- |
|
||||
| Два disabled типа | Exec и все6 probe tools:16 ответов409, probeRequests0 |
|
||||
| Native терминал | Identity/resource/routes/OSPF/BFD, Ping3/3, ограниченный log read; неизвестная команда400 |
|
||||
| Native диагностика | Ping3/3, traceroute≤3 hops/1 probe/1s timeout, active route lookup, DF MTU probe |
|
||||
| DNS приложения | example.com A; .invalid502 без ложного output |
|
||||
| Средний RTT | Compiled exec formatter сверён с avg-rtt того же native Ping запроса |
|
||||
| JWT API | 401 none/invalid,403 reader/network writer,200 server writer/admin; native factory0 до разрешения |
|
||||
| Реальный UI | 8/8: две страницы×два CHR×1280/320, Ping5/5, ошибочный command сохранён |
|
||||
|
||||
**Приёмка.** [Native/API/RBAC отчёт](ux-ui/acceptance/diagnostics-terminal-2026-10-09.json). Read-only allowlist применяется обычным production API. Текст log print limit=1 не сохранён в Git, записана только длина. DNS выполняется на backend, что явно подписано в UI; не выдаётся за RouterOS DNS. Traceroute ограничен тремя хопами и не считается полным путём. MTU — первая успешная DF проба из существующего набора до1500, не доказательство максимального MTU/jumbo/SLA. Uncapped bandwidth endpoint не запускался: capped native smoke82 остаётся отдельным доказательством.
|
||||
|
||||
JWT тест использовал изолированный экземпляр compiled exec/probes routes, реальные credentials/native reads, временный локальный secret/issuer и настоящие подписи HS256. Проверены обе API группы и отсутствие native client до разрешения. В production AUTH_REQUIRED=false сохранён, Portal SSO/browser login этой проверкой не принят. Native configuration/пароли не изменялись.
|
||||
|
||||
**Браузер.** Настоящие deployed frontend/backend, без interception/mocks. Terminal400 сохраняет ввод; следующий resource request подтверждён, вывод содержит7.24.5, поле очищено и фокус возвращён. Probes Ping5/5 с правильным source/target, reload server context, document fits/pageerror0. [Browser отчёт](ux-ui/acceptance/browser-diagnostics-2026-10-09.json), [терминал320](ux-ui/screens/terminal-real-server1-320-2026-10-09.png), [диагностика320](ux-ui/screens/probes-real-server1-320-2026-10-09.png). Последний снимок просмотрен; значения не подменены моками. Frame/ReUI композиция прежняя.
|
||||
|
||||
**Проверки и оснастка.**58 профильных E2E terminal data/layout и probes data/source passed; exec/probes HTTP, signed JWT unit, backend TypeScript/ESLint/diff passed. Probes.cancel локальный HTTP тест сначала получил sandbox EACCES, повторён только он с разрешённым loopback: passed, включая abort настоящего MikrotikClient POST к локальной HTTP-фикстуре. Это не доказательство остановки процесса на CHR; UI сохраняет соответствующее пояснение.
|
||||
|
||||
Production image не содержит dev-only jose: первый fixture import завершился до native requests, подписи заменены native crypto. Следующая RBAC попытка меняла process.env после загрузки env объекта и получила200 вместо ожидаемого401 в изолированном приложении с выключенной авторизацией. Исправлен только fixture: snapshot/config authRequired/secret/issuer и восстановление finally. Успешные phase1 native проверки не повторялись; report объединяет их с исправленным RBAC и browser phase.
|
||||
|
||||
**Контроль.** Собственные disabled DB rows удалены по id/name/host, fixture containers завершены. IDs7 native коллекций×2 совпали до/после: interfaces/addresses/routes/OSPF instances/BGP connections/BFD config/IPsec peers. Оба CHR доступны, пароли прежние; public/default routes и195.195.195.195/32 сохранены. Никаких VPN объектов в этом read-only блоке не создавалось.
|
||||
|
||||
**Runtime.** Один backend build ux-diagnostics89/version1.0.0-test.diagnostics89, image sha256:97c1cff01efd5055d3811b742e293180d5999ff1e326e42242e5c975b5f70349. Backend/PG healthy, frontend ux-optimizer87 сохранён/принят. Context recursive88 +3 exec/type files, override SHA2ca8c80d13a2dcce8b09c905f2b65d7467892ee6918cc102caad2d15d90bacbf7; label не Git SHA. Entry/node --check/pg_restore18.6/compose --wait passed, dependencies/apt cached. .env backup приватный, миграций и frontend rebuild нет. Один локальный commit без push.
|
||||
|
||||
Продолжение90 — два собственных GRE пути OSPF/BFD, потеря primary, переход на alternate, packet observations и возврат. Сохраняются sustained BFD-only/физическая WAN failure/IPv6/масштаб/максимальная производительность/Portal SSO и другие внешние границы. Квота56% использовано после блока; этап12.5 открыт.
|
||||
|
||||
## 12.5.88 — рекурсивные маршруты: реальные операции и история (2026-10-09)
|
||||
|
||||
|
||||
@@ -2090,3 +2090,33 @@ Request-local receipt сохраняет подтверждённые createdIds
|
||||
**Runtime/фиксация.** Одна backend сборка ux-recursive88/version1.0.0-test.recursive88, image sha256:d358ec1d6ea87ea7f29a12cc4fd3c1a6a7929b854bcdc732d956c702fe4dc587. Backend/PG healthy, frontend ux-optimizer87 сохранён и принят браузером. Context optimizer87 final-c +6 backend файлов, override SHA de4caf2aced38ba7e490f6a459a19d359cc92cb5b098564b799c05bc86be1365; label не Git SHA, рабочее состояние до коммита. Entry/node --check/pg_restore18.6, compose --wait passed, apt cached. .env backup приватный, миграций нет. Один локальный commit без push. REST метод подтверждён [RouterOS REST API](https://help.mikrotik.com/docs/spaces/ROS/pages/47579162/REST%2BAPI).
|
||||
|
||||
Следующий89 — диагностика/терминал: реальный запуск, ограниченные команды, ошибки, права и контекст. Routing alternate-path/BFD sustained failover, IPv6/scale/physical disconnect/durable retry/Portal SSO и остальные внешние границы остаются открытыми. Квота38% использовано после блока; этап12.5 открыт.
|
||||
|
||||
## 12.5.89 — диагностика и терминал: реальные ответы и JWT-права (2026-10-09)
|
||||
|
||||
**Изменения.** Exec отклоняет enabled=false до создания клиента, включая локальную help-команду. Средний Ping RTT больше не берётся из time последнего пакета: используется подтверждённый native avg-rtt при received>0. Отсутствующий/неверный average или отсутствие полученных пакетов → ?, явный0ms при полученном ответе сохраняется. RosPingResult дополнен avg-rtt. Allowlist/сетевые правила/GUI не менялись.
|
||||
|
||||
| Проверка | Доказательство |
|
||||
| --- | --- |
|
||||
| Два disabled типа | Exec и все6 probe tools:16 ответов409, probeRequests0 |
|
||||
| Native терминал | Identity/resource/routes/OSPF/BFD, Ping3/3, ограниченный log read; неизвестная команда400 |
|
||||
| Native диагностика | Ping3/3, traceroute≤3 hops/1 probe/1s timeout, active route lookup, DF MTU probe |
|
||||
| DNS приложения | example.com A; .invalid502 без ложного output |
|
||||
| Средний RTT | Compiled exec formatter сверён с avg-rtt того же native Ping запроса |
|
||||
| JWT API | 401 none/invalid,403 reader/network writer,200 server writer/admin; native factory0 до разрешения |
|
||||
| Реальный UI | 8/8: две страницы×два CHR×1280/320, Ping5/5, ошибочный command сохранён |
|
||||
|
||||
**Приёмка.** [Native/API/RBAC отчёт](ux-ui/acceptance/diagnostics-terminal-2026-10-09.json). Read-only allowlist применяется обычным production API. Текст log print limit=1 не сохранён в Git, записана только длина. DNS выполняется на backend, что явно подписано в UI; не выдаётся за RouterOS DNS. Traceroute ограничен тремя хопами и не считается полным путём. MTU — первая успешная DF проба из существующего набора до1500, не доказательство максимального MTU/jumbo/SLA. Uncapped bandwidth endpoint не запускался: capped native smoke82 остаётся отдельным доказательством.
|
||||
|
||||
JWT тест использовал изолированный экземпляр compiled exec/probes routes, реальные credentials/native reads, временный локальный secret/issuer и настоящие подписи HS256. Проверены обе API группы и отсутствие native client до разрешения. В production AUTH_REQUIRED=false сохранён, Portal SSO/browser login этой проверкой не принят. Native configuration/пароли не изменялись.
|
||||
|
||||
**Браузер.** Настоящие deployed frontend/backend, без interception/mocks. Terminal400 сохраняет ввод; следующий resource request подтверждён, вывод содержит7.24.5, поле очищено и фокус возвращён. Probes Ping5/5 с правильным source/target, reload server context, document fits/pageerror0. [Browser отчёт](ux-ui/acceptance/browser-diagnostics-2026-10-09.json), [терминал320](ux-ui/screens/terminal-real-server1-320-2026-10-09.png), [диагностика320](ux-ui/screens/probes-real-server1-320-2026-10-09.png). Последний снимок просмотрен; значения не подменены моками. Frame/ReUI композиция прежняя.
|
||||
|
||||
**Проверки и оснастка.**58 профильных E2E terminal data/layout и probes data/source passed; exec/probes HTTP, signed JWT unit, backend TypeScript/ESLint/diff passed. Probes.cancel локальный HTTP тест сначала получил sandbox EACCES, повторён только он с разрешённым loopback: passed, включая abort настоящего MikrotikClient POST к локальной HTTP-фикстуре. Это не доказательство остановки процесса на CHR; UI сохраняет соответствующее пояснение.
|
||||
|
||||
Production image не содержит dev-only jose: первый fixture import завершился до native requests, подписи заменены native crypto. Следующая RBAC попытка меняла process.env после загрузки env объекта и получила200 вместо ожидаемого401 в изолированном приложении с выключенной авторизацией. Исправлен только fixture: snapshot/config authRequired/secret/issuer и восстановление finally. Успешные phase1 native проверки не повторялись; report объединяет их с исправленным RBAC и browser phase.
|
||||
|
||||
**Контроль.** Собственные disabled DB rows удалены по id/name/host, fixture containers завершены. IDs7 native коллекций×2 совпали до/после: interfaces/addresses/routes/OSPF instances/BGP connections/BFD config/IPsec peers. Оба CHR доступны, пароли прежние; public/default routes и195.195.195.195/32 сохранены. Никаких VPN объектов в этом read-only блоке не создавалось.
|
||||
|
||||
**Runtime.** Один backend build ux-diagnostics89/version1.0.0-test.diagnostics89, image sha256:97c1cff01efd5055d3811b742e293180d5999ff1e326e42242e5c975b5f70349. Backend/PG healthy, frontend ux-optimizer87 сохранён/принят. Context recursive88 +3 exec/type files, override SHA2ca8c80d13a2dcce8b09c905f2b65d7467892ee6918cc102caad2d15d90bacbf7; label не Git SHA. Entry/node --check/pg_restore18.6/compose --wait passed, dependencies/apt cached. .env backup приватный, миграций и frontend rebuild нет. Один локальный commit без push.
|
||||
|
||||
Продолжение90 — два собственных GRE пути OSPF/BFD, потеря primary, переход на alternate, packet observations и возврат. Сохраняются sustained BFD-only/физическая WAN failure/IPv6/масштаб/максимальная производительность/Portal SSO и другие внешние границы. Квота56% использовано после блока; этап12.5 открыт.
|
||||
@@ -1,6 +1,6 @@
|
||||
# Тестовый сервер UX/UI — 2026-10-09
|
||||
|
||||
Сервер161.104.46.222 предоставлен для временного тестирования. Backend ux-recursive88/version1.0.0-test.recursive88, frontend ux-optimizer87/version1.0.0-test.optimizer87; backend/PG healthy, frontend HTTP/browser passed. Основной блок IPsec77 принят в границах журнала, own fixtures/fake DB rows удалены; каталог flash CHR2 сохранён из-за неподтверждённого ownership. SSH/оба CHR доступны, пароли прежние.
|
||||
Сервер161.104.46.222 предоставлен для временного тестирования. Backend ux-diagnostics89/version1.0.0-test.diagnostics89, frontend ux-optimizer87/version1.0.0-test.optimizer87; backend/PG healthy, frontend HTTP/browser passed. Основной блок IPsec77 принят в границах журнала, own fixtures/fake DB rows удалены; каталог flash CHR2 сохранён из-за неподтверждённого ownership. SSH/оба CHR доступны, пароли прежние.
|
||||
|
||||
| Параметр | Проверенное состояние |
|
||||
| --- | --- |
|
||||
@@ -715,3 +715,5 @@ flowchart LR
|
||||
12.5.87 (2026-10-09): OSPF optimizer native/API и4 browser checks passed, собственные объекты очищены, baseline7 коллекций×2 сохранён. Подробности/runtime происхождение — в журнале.
|
||||
|
||||
12.5.88 (2026-10-09): recursion/GRE/Ping, apply/restore и4 browser checks passed; native baseline4 коллекций×2, cache/history сохранены. Backend recursive88, frontend optimizer87.
|
||||
|
||||
12.5.89 (2026-10-09): терминал/диагностика/RBAC и8 live UI checks passed, baseline7 коллекций×2 сохранён. Production auth не менялся.
|
||||
@@ -0,0 +1,75 @@
|
||||
{
|
||||
"date": "2026-10-09",
|
||||
"phase": "probes 2 320",
|
||||
"cases": [
|
||||
{
|
||||
"kind": "terminal",
|
||||
"serverId": 1,
|
||||
"width": 1280,
|
||||
"unsupportedRetainsInput": true,
|
||||
"realResourceOutput": true,
|
||||
"urlRestore": true,
|
||||
"documentFits": true
|
||||
},
|
||||
{
|
||||
"kind": "probes",
|
||||
"serverId": 1,
|
||||
"width": 1280,
|
||||
"realPing5of5": true,
|
||||
"urlRestore": true,
|
||||
"documentFits": true
|
||||
},
|
||||
{
|
||||
"kind": "terminal",
|
||||
"serverId": 1,
|
||||
"width": 320,
|
||||
"unsupportedRetainsInput": true,
|
||||
"realResourceOutput": true,
|
||||
"urlRestore": true,
|
||||
"documentFits": true
|
||||
},
|
||||
{
|
||||
"kind": "probes",
|
||||
"serverId": 1,
|
||||
"width": 320,
|
||||
"realPing5of5": true,
|
||||
"urlRestore": true,
|
||||
"documentFits": true
|
||||
},
|
||||
{
|
||||
"kind": "terminal",
|
||||
"serverId": 2,
|
||||
"width": 1280,
|
||||
"unsupportedRetainsInput": true,
|
||||
"realResourceOutput": true,
|
||||
"urlRestore": true,
|
||||
"documentFits": true
|
||||
},
|
||||
{
|
||||
"kind": "probes",
|
||||
"serverId": 2,
|
||||
"width": 1280,
|
||||
"realPing5of5": true,
|
||||
"urlRestore": true,
|
||||
"documentFits": true
|
||||
},
|
||||
{
|
||||
"kind": "terminal",
|
||||
"serverId": 2,
|
||||
"width": 320,
|
||||
"unsupportedRetainsInput": true,
|
||||
"realResourceOutput": true,
|
||||
"urlRestore": true,
|
||||
"documentFits": true
|
||||
},
|
||||
{
|
||||
"kind": "probes",
|
||||
"serverId": 2,
|
||||
"width": 320,
|
||||
"realPing5of5": true,
|
||||
"urlRestore": true,
|
||||
"documentFits": true
|
||||
}
|
||||
],
|
||||
"errors": []
|
||||
}
|
||||
@@ -0,0 +1,462 @@
|
||||
{
|
||||
"date": "2026-10-09",
|
||||
"name": "mm-diag89-1791555825651",
|
||||
"exec": [
|
||||
{
|
||||
"serverId": 1,
|
||||
"command": "system identity print",
|
||||
"status": 200,
|
||||
"output": " name: CHR"
|
||||
},
|
||||
{
|
||||
"serverId": 1,
|
||||
"command": "system resource print",
|
||||
"status": 200,
|
||||
"output": " uptime: 1d21m17s\n version: 7.24.5 (stable)\n build-time: 2026-09-29 14:21:27\n free-memory: 784.5 MiB\n total-memory: 1024.0 MiB\n cpu: Intel\n cpu-count: 1\n cpu-frequency: 2197 MHz\n cpu-load: 5%\n free-hdd-space: 9708.1 MiB\n total-hdd-space: 10196.1 MiB\n architecture-name: x86_64\n board-name: CHR OpenStack Foundation OpenStack Nova\n platform: MikroTik\n identity: CHR"
|
||||
},
|
||||
{
|
||||
"serverId": 1,
|
||||
"command": "ip route print",
|
||||
"status": 200,
|
||||
"output": "Flags: X - disabled, A - active, D - dynamic, C - connect, S - static,\n r - rip, b - bgp, o - ospf, B - blackhole, U - unreachable, P - prohibit\n # DST-ADDRESS PREF-SRC GATEWAY DIST\n 0 A ?S????? 0.0.0.0/0 ? 194.226.121.1 1\n 1 AD??????? 0.0.0.0/0 ? 194.226.121.1 1\n 2 AD??????? 169.254.169.254/32 ? 194.226.121.1 1\n 3 ADC?????? 194.226.121.0/24 ? ether1 0"
|
||||
},
|
||||
{
|
||||
"serverId": 1,
|
||||
"command": "routing ospf neighbor print",
|
||||
"status": 200,
|
||||
"output": "Flags: V - virtual\n # ROUTER-ID STATE CHANGES ADJACENCY INTERFACE"
|
||||
},
|
||||
{
|
||||
"serverId": 1,
|
||||
"command": "routing bfd session print",
|
||||
"status": 200,
|
||||
"output": " # LOCAL-ADDRESS REMOTE-ADDRESS STATE UPTIME"
|
||||
},
|
||||
{
|
||||
"serverId": 1,
|
||||
"command": "ping 104.165.244.7 count=3",
|
||||
"status": 200,
|
||||
"output": "PING 104.165.244.7\n seq=0 ttl=56 time=53ms625us\n seq=1 ttl=56 time=53ms207us\n seq=2 ttl=56 time=55ms814us\n sent=3 received=3 packet-loss=0\n avg-rtt=54ms215us"
|
||||
},
|
||||
{
|
||||
"serverId": 1,
|
||||
"command": "log print limit=1",
|
||||
"status": 200,
|
||||
"outputLength": 16,
|
||||
"outputSaved": false
|
||||
},
|
||||
{
|
||||
"serverId": 1,
|
||||
"command": "unsupported-test-command",
|
||||
"status": 400,
|
||||
"body": {
|
||||
"error": "\u041a\u043e\u043c\u0430\u043d\u0434\u0430 \u043d\u0435 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442\u0441\u044f REST \u0442\u0435\u0440\u043c\u0438\u043d\u0430\u043b\u043e\u043c. \u0412\u0432\u0435\u0434\u0438\u0442\u0435 help \u0434\u043b\u044f \u0441\u043f\u0438\u0441\u043a\u0430."
|
||||
}
|
||||
},
|
||||
{
|
||||
"serverId": 2,
|
||||
"command": "system identity print",
|
||||
"status": 200,
|
||||
"output": " name: CHR"
|
||||
},
|
||||
{
|
||||
"serverId": 2,
|
||||
"command": "system resource print",
|
||||
"status": 200,
|
||||
"output": " uptime: 23h33m52s\n version: 7.24.5 (stable)\n build-time: 2026-09-29 14:21:27\n free-memory: 779.5 MiB\n total-memory: 1024.0 MiB\n cpu: Intel\n cpu-count: 1\n cpu-frequency: 2199 MHz\n cpu-load: 1%\n free-hdd-space: 9708.2 MiB\n total-hdd-space: 10196.1 MiB\n architecture-name: x86_64\n board-name: CHR OpenStack Foundation OpenStack Nova\n platform: MikroTik\n identity: CHR"
|
||||
},
|
||||
{
|
||||
"serverId": 2,
|
||||
"command": "ip route print",
|
||||
"status": 200,
|
||||
"output": "Flags: X - disabled, A - active, D - dynamic, C - connect, S - static,\n r - rip, b - bgp, o - ospf, B - blackhole, U - unreachable, P - prohibit\n # DST-ADDRESS PREF-SRC GATEWAY DIST\n 0 A ?S????? 0.0.0.0/0 ? 104.165.244.1 1\n 1 AD??????? 0.0.0.0/0 ? 104.165.244.1 1\n 2 ADC?????? 104.165.244.0/24 ? ether1 0\n 3 AD??????? 169.254.169.254/32 ? 104.165.244.2 1\n 4 ADC?????? 195.195.195.195/32 ? ether1 0"
|
||||
},
|
||||
{
|
||||
"serverId": 2,
|
||||
"command": "routing ospf neighbor print",
|
||||
"status": 200,
|
||||
"output": "Flags: V - virtual\n # ROUTER-ID STATE CHANGES ADJACENCY INTERFACE"
|
||||
},
|
||||
{
|
||||
"serverId": 2,
|
||||
"command": "routing bfd session print",
|
||||
"status": 200,
|
||||
"output": " # LOCAL-ADDRESS REMOTE-ADDRESS STATE UPTIME"
|
||||
},
|
||||
{
|
||||
"serverId": 2,
|
||||
"command": "ping 194.226.121.150 count=3",
|
||||
"status": 200,
|
||||
"output": "PING 194.226.121.150\n seq=0 ttl=52 time=53ms956us\n seq=1 ttl=52 time=56ms726us\n seq=2 ttl=52 time=53ms220us\n sent=3 received=3 packet-loss=0\n avg-rtt=54ms634us"
|
||||
},
|
||||
{
|
||||
"serverId": 2,
|
||||
"command": "log print limit=1",
|
||||
"status": 200,
|
||||
"outputLength": 16,
|
||||
"outputSaved": false
|
||||
},
|
||||
{
|
||||
"serverId": 2,
|
||||
"command": "unsupported-test-command",
|
||||
"status": 400,
|
||||
"body": {
|
||||
"error": "\u041a\u043e\u043c\u0430\u043d\u0434\u0430 \u043d\u0435 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442\u0441\u044f REST \u0442\u0435\u0440\u043c\u0438\u043d\u0430\u043b\u043e\u043c. \u0412\u0432\u0435\u0434\u0438\u0442\u0435 help \u0434\u043b\u044f \u0441\u043f\u0438\u0441\u043a\u0430."
|
||||
}
|
||||
}
|
||||
],
|
||||
"probes": [
|
||||
{
|
||||
"serverId": 1,
|
||||
"tool": "ping",
|
||||
"status": 200,
|
||||
"body": {
|
||||
"output": "PING 104.165.244.7\n seq=0 ttl=56 time=53ms295us\n seq=1 ttl=56 time=53ms199us\n seq=2 ttl=56 time=53ms307us\n sent=3 received=3 packet-loss=0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"serverId": 1,
|
||||
"tool": "traceroute",
|
||||
"status": 200,
|
||||
"body": {
|
||||
"output": " # ADDRESS LOSS LAST AVG\n 1 45.132.185.1 0 11.8 11.8\n 2 192.168.110.1 0 0.3 0.3\n 3 100.64.10.1 0 0.2 0.2"
|
||||
}
|
||||
},
|
||||
{
|
||||
"serverId": 1,
|
||||
"tool": "route",
|
||||
"status": 200,
|
||||
"body": {
|
||||
"output": "lookup 104.165.244.7 \u2192 best match:\n dst-address: 0.0.0.0/0\n gateway: 194.226.121.1\n distance: 1\n routing-mark: \u2014"
|
||||
}
|
||||
},
|
||||
{
|
||||
"serverId": 1,
|
||||
"tool": "mtu",
|
||||
"status": 200,
|
||||
"body": {
|
||||
"output": "MTU discovery (do-not-fragment ping) \u2192 104.165.244.7\n\n 1500 \u2713 ok\n\nMTU (DF): ~1500 bytes"
|
||||
}
|
||||
},
|
||||
{
|
||||
"serverId": 1,
|
||||
"tool": "dns",
|
||||
"status": 200,
|
||||
"body": {
|
||||
"output": ";; QUESTION: example.com A\n\nexample.com. IN A 8.6.112.5\nexample.com. IN A 8.47.69.5"
|
||||
}
|
||||
},
|
||||
{
|
||||
"serverId": 1,
|
||||
"tool": "dns-negative",
|
||||
"status": 502,
|
||||
"body": {
|
||||
"error": ";; QUESTION: mm-diag89-1791555825651.invalid A\n\n;; ERROR: queryA ENOTFOUND mm-diag89-1791555825651.invalid\n;; (\u0440\u0435\u0437\u043e\u043b\u0432 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f \u043d\u0430 \u0445\u043e\u0441\u0442\u0435 \u0431\u0435\u043a\u0435\u043d\u0434\u0430, \u043d\u0435 \u043d\u0430 MikroTik)"
|
||||
}
|
||||
},
|
||||
{
|
||||
"serverId": 2,
|
||||
"tool": "ping",
|
||||
"status": 200,
|
||||
"body": {
|
||||
"output": "PING 194.226.121.150\n seq=0 ttl=52 time=53ms297us\n seq=1 ttl=52 time=53ms395us\n seq=2 ttl=52 time=53ms485us\n sent=3 received=3 packet-loss=0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"serverId": 2,
|
||||
"tool": "traceroute",
|
||||
"status": 200,
|
||||
"body": {
|
||||
"output": " # ADDRESS LOSS LAST AVG\n 1 169.254.1.232 0 0.7 0.7\n 2 \u2014 0 0 \u2014\n 3 169.254.1.232 0 0.7 0.7\n 4 31.169.126.1 0 104.5 104.5\n 5 85.232.229.141 0 0.6 0.6"
|
||||
}
|
||||
},
|
||||
{
|
||||
"serverId": 2,
|
||||
"tool": "route",
|
||||
"status": 200,
|
||||
"body": {
|
||||
"output": "lookup 194.226.121.150 \u2192 best match:\n dst-address: 0.0.0.0/0\n gateway: 104.165.244.1\n distance: 1\n routing-mark: \u2014"
|
||||
}
|
||||
},
|
||||
{
|
||||
"serverId": 2,
|
||||
"tool": "mtu",
|
||||
"status": 200,
|
||||
"body": {
|
||||
"output": "MTU discovery (do-not-fragment ping) \u2192 194.226.121.150\n\n 1500 \u2713 ok\n\nMTU (DF): ~1500 bytes"
|
||||
}
|
||||
},
|
||||
{
|
||||
"serverId": 2,
|
||||
"tool": "dns",
|
||||
"status": 200,
|
||||
"body": {
|
||||
"output": ";; QUESTION: example.com A\n\nexample.com. IN A 8.6.112.0\nexample.com. IN A 8.47.69.0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"serverId": 2,
|
||||
"tool": "dns-negative",
|
||||
"status": 502,
|
||||
"body": {
|
||||
"error": ";; QUESTION: mm-diag89-1791555825651.invalid A\n\n;; ERROR: queryA ENOTFOUND mm-diag89-1791555825651.invalid\n;; (\u0440\u0435\u0437\u043e\u043b\u0432 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f \u043d\u0430 \u0445\u043e\u0441\u0442\u0435 \u0431\u0435\u043a\u0435\u043d\u0434\u0430, \u043d\u0435 \u043d\u0430 MikroTik)"
|
||||
}
|
||||
}
|
||||
],
|
||||
"disabled": [
|
||||
{
|
||||
"type": "home-router",
|
||||
"kind": "exec",
|
||||
"command": "interface print",
|
||||
"status": 409
|
||||
},
|
||||
{
|
||||
"type": "home-router",
|
||||
"kind": "exec",
|
||||
"command": "ping 127.0.0.1 count=1",
|
||||
"status": 409
|
||||
},
|
||||
{
|
||||
"type": "home-router",
|
||||
"kind": "probe",
|
||||
"tool": "ping",
|
||||
"status": 409
|
||||
},
|
||||
{
|
||||
"type": "home-router",
|
||||
"kind": "probe",
|
||||
"tool": "traceroute",
|
||||
"status": 409
|
||||
},
|
||||
{
|
||||
"type": "home-router",
|
||||
"kind": "probe",
|
||||
"tool": "mtu",
|
||||
"status": 409
|
||||
},
|
||||
{
|
||||
"type": "home-router",
|
||||
"kind": "probe",
|
||||
"tool": "route",
|
||||
"status": 409
|
||||
},
|
||||
{
|
||||
"type": "home-router",
|
||||
"kind": "probe",
|
||||
"tool": "dns",
|
||||
"status": 409
|
||||
},
|
||||
{
|
||||
"type": "home-router",
|
||||
"kind": "probe",
|
||||
"tool": "bandwidth",
|
||||
"status": 409
|
||||
},
|
||||
{
|
||||
"type": "exit-node",
|
||||
"kind": "exec",
|
||||
"command": "interface print",
|
||||
"status": 409
|
||||
},
|
||||
{
|
||||
"type": "exit-node",
|
||||
"kind": "exec",
|
||||
"command": "ping 127.0.0.1 count=1",
|
||||
"status": 409
|
||||
},
|
||||
{
|
||||
"type": "exit-node",
|
||||
"kind": "probe",
|
||||
"tool": "ping",
|
||||
"status": 409
|
||||
},
|
||||
{
|
||||
"type": "exit-node",
|
||||
"kind": "probe",
|
||||
"tool": "traceroute",
|
||||
"status": 409
|
||||
},
|
||||
{
|
||||
"type": "exit-node",
|
||||
"kind": "probe",
|
||||
"tool": "mtu",
|
||||
"status": 409
|
||||
},
|
||||
{
|
||||
"type": "exit-node",
|
||||
"kind": "probe",
|
||||
"tool": "route",
|
||||
"status": 409
|
||||
},
|
||||
{
|
||||
"type": "exit-node",
|
||||
"kind": "probe",
|
||||
"tool": "dns",
|
||||
"status": 409
|
||||
},
|
||||
{
|
||||
"type": "exit-node",
|
||||
"kind": "probe",
|
||||
"tool": "bandwidth",
|
||||
"status": 409
|
||||
}
|
||||
],
|
||||
"rbac": [
|
||||
{
|
||||
"role": "none",
|
||||
"kind": "exec",
|
||||
"status": 401,
|
||||
"nativeClientCreated": false
|
||||
},
|
||||
{
|
||||
"role": "none",
|
||||
"kind": "probes/run",
|
||||
"status": 401,
|
||||
"nativeClientCreated": false
|
||||
},
|
||||
{
|
||||
"role": "invalid",
|
||||
"kind": "exec",
|
||||
"status": 401,
|
||||
"nativeClientCreated": false
|
||||
},
|
||||
{
|
||||
"role": "invalid",
|
||||
"kind": "probes/run",
|
||||
"status": 401,
|
||||
"nativeClientCreated": false
|
||||
},
|
||||
{
|
||||
"role": "mm:servers:read",
|
||||
"kind": "exec",
|
||||
"status": 403,
|
||||
"nativeClientCreated": false
|
||||
},
|
||||
{
|
||||
"role": "mm:servers:read",
|
||||
"kind": "probes/run",
|
||||
"status": 403,
|
||||
"nativeClientCreated": false
|
||||
},
|
||||
{
|
||||
"role": "mm:network:write",
|
||||
"kind": "exec",
|
||||
"status": 403,
|
||||
"nativeClientCreated": false
|
||||
},
|
||||
{
|
||||
"role": "mm:network:write",
|
||||
"kind": "probes/run",
|
||||
"status": 403,
|
||||
"nativeClientCreated": false
|
||||
},
|
||||
{
|
||||
"role": "mm:servers:write",
|
||||
"kind": "exec",
|
||||
"status": 200,
|
||||
"nativeClientCreated": true
|
||||
},
|
||||
{
|
||||
"role": "mm:servers:write",
|
||||
"kind": "probes/run",
|
||||
"status": 200,
|
||||
"nativeClientCreated": true
|
||||
},
|
||||
{
|
||||
"role": "mm:servers:admin",
|
||||
"kind": "exec",
|
||||
"status": 200,
|
||||
"nativeClientCreated": true
|
||||
},
|
||||
{
|
||||
"role": "mm:servers:admin",
|
||||
"kind": "probes/run",
|
||||
"status": 200,
|
||||
"nativeClientCreated": true
|
||||
}
|
||||
],
|
||||
"cleanup": [
|
||||
{
|
||||
"serverId": 1,
|
||||
"/interface": true,
|
||||
"/ip/address": true,
|
||||
"/ip/route": true,
|
||||
"/routing/ospf/instance": true,
|
||||
"/routing/bgp/connection": true,
|
||||
"/routing/bfd/configuration": true,
|
||||
"/ip/ipsec/peer": true
|
||||
},
|
||||
{
|
||||
"serverId": 2,
|
||||
"/interface": true,
|
||||
"/ip/address": true,
|
||||
"/ip/route": true,
|
||||
"/routing/ospf/instance": true,
|
||||
"/routing/bgp/connection": true,
|
||||
"/routing/bfd/configuration": true,
|
||||
"/ip/ipsec/peer": true
|
||||
}
|
||||
],
|
||||
"probeRequests": 0,
|
||||
"averageProof": {
|
||||
"nativeRows": [
|
||||
{
|
||||
"avg-rtt": "53ms251us",
|
||||
"host": "104.165.244.7",
|
||||
"max-rtt": "53ms251us",
|
||||
"min-rtt": "53ms251us",
|
||||
"packet-loss": "0",
|
||||
"received": "1",
|
||||
"sent": "1",
|
||||
"seq": "0",
|
||||
"size": "56",
|
||||
"time": "53ms251us",
|
||||
"ttl": "56"
|
||||
},
|
||||
{
|
||||
"avg-rtt": "53ms225us",
|
||||
"host": "104.165.244.7",
|
||||
"max-rtt": "53ms251us",
|
||||
"min-rtt": "53ms199us",
|
||||
"packet-loss": "0",
|
||||
"received": "2",
|
||||
"sent": "2",
|
||||
"seq": "1",
|
||||
"size": "56",
|
||||
"time": "53ms199us",
|
||||
"ttl": "56"
|
||||
},
|
||||
{
|
||||
"avg-rtt": "53ms303us",
|
||||
"host": "104.165.244.7",
|
||||
"max-rtt": "53ms459us",
|
||||
"min-rtt": "53ms199us",
|
||||
"packet-loss": "0",
|
||||
"received": "3",
|
||||
"sent": "3",
|
||||
"seq": "2",
|
||||
"size": "56",
|
||||
"time": "53ms459us",
|
||||
"ttl": "56"
|
||||
}
|
||||
],
|
||||
"output": "PING 104.165.244.7\n seq=0 ttl=56 time=53ms251us\n seq=1 ttl=56 time=53ms199us\n seq=2 ttl=56 time=53ms459us\n sent=3 received=3 packet-loss=0\n avg-rtt=53ms303us",
|
||||
"sameRequest": true,
|
||||
"lastReplyIsNotUsedAsAverage": true
|
||||
},
|
||||
"initialRbacAttempt": {
|
||||
"authConfigWasLoadedBeforeEnvChange": true,
|
||||
"expected401Got200": true,
|
||||
"baselinePreserved": true
|
||||
},
|
||||
"runtime": {
|
||||
"backend": "ux-diagnostics89",
|
||||
"frontend": "ux-optimizer87",
|
||||
"labelsAreGitSha": false,
|
||||
"productionAuthChanged": false
|
||||
},
|
||||
"fixtureNotes": [
|
||||
"Initial jose import was unavailable in production image; native crypto signs HS256 instead. No native request on that attempt.",
|
||||
"AUTH config object is loaded before env mutation; isolated config corrected and restored. Successful phase1 diagnostics were retained, not repeated."
|
||||
]
|
||||
}
|
||||
|
After Width: | Height: | Size: 143 KiB |
|
After Width: | Height: | Size: 47 KiB |
|
After Width: | Height: | Size: 141 KiB |
|
After Width: | Height: | Size: 48 KiB |
|
After Width: | Height: | Size: 143 KiB |
|
After Width: | Height: | Size: 67 KiB |
|
After Width: | Height: | Size: 145 KiB |
|
After Width: | Height: | Size: 67 KiB |