fix(gre): не подменять неизвестные флаги состоянием туннеля
This commit is contained in:
1 parent
9c4a0992d7
commit
51a579d370
18 files changed
+877
-17
No files matched your search
@@ -0,0 +1,27 @@
|
|||||||
|
import assert from 'node:assert/strict'
|
||||||
|
import fs from 'node:fs'
|
||||||
|
import {createServer} from 'node:http'
|
||||||
|
import {randomBytes} from 'node:crypto'
|
||||||
|
const database=process.env.MMAPP_OWN_SQL_DB,url=new URL(process.env.DATABASE_URL)
|
||||||
|
assert(/^mm_accept_166_\d+$/.test(database??''));assert.equal(url.pathname,'/'+database);assert.equal(url.username,database)
|
||||||
|
process.env.AUTH_REQUIRED='true';process.env.AUTH_JWT_SECRET=randomBytes(32).toString('hex');process.env.AUTH_ISSUER='https://own220.invalid';process.env.AUTH_PORTAL_URL='https://own220.invalid'
|
||||||
|
const {pool,closePool}=await import('/app/backend/dist/db/index.js'),{initDatabase}=await import('/app/backend/dist/db/bootstrap.js'),{collectGreBgpSnapshotOnce}=await import('/app/backend/dist/services/gre-bgp-snapshot-collector.js'),{buildApp}=await import('/app/backend/dist/index.js')
|
||||||
|
assert.equal((await pool.query('SELECT current_database() AS name')).rows[0].name,database);assert(Object.values((await pool.query('SELECT rolsuper,rolcreatedb,rolcreaterole,rolbypassrls FROM pg_roles WHERE rolname=current_user')).rows[0]).every(v=>v===false))
|
||||||
|
const baseline=process.env.MMAPP_BASELINE==='true',cases=[];let app,nativeCalls=0,nativeWrites=0,disabledCalls=0,flags={running:'true',disabled:'false'}
|
||||||
|
const fixture=label=>createServer((req,res)=>{nativeCalls++;if(label==='disabled')disabledCalls++;if(req.method!=='GET')nativeWrites++;res.setHeader('content-type','application/json');const gre=req.url==='/rest/interface/gre',bgp=req.url==='/rest/routing/bgp/session',row=gre?{'.id':'*1',name:'own220-gre',...(label==='second'?flags:{running:'true',disabled:'false'})}:{'.id':'*1',name:'own220-peer',established:'true','remote.as':'65220','local.as':'65221'};res.end(JSON.stringify(gre||bgp?[row]:[]))})
|
||||||
|
const natives=['first','second','disabled'].map(fixture);for(const n of natives)await new Promise(r=>n.listen(0,'127.0.0.1',r))
|
||||||
|
const report={date:'2026-10-14',block:'12.5.220',baseline,database,cases,scope:'Actual compiled GRE operational flags and actual snapshot collector, owned SQL/native HTTP fixture; signed reader/authenticated GRE API',passed:false}
|
||||||
|
try{
|
||||||
|
await initDatabase();for(let i=0;i<natives.length;i++)await pool.query("INSERT INTO servers(name,host,port,use_ssl,enabled,username,password,type) VALUES($1,'127.0.0.1',$2,false,$3,'fixture','fixture',$4)",['own220-'+i,natives[i].address().port,i<2,i===2?'home-router':'exit-node'])
|
||||||
|
app=await buildApp({logger:false,startScheduler:false});await app.ready();const token=app.jwt.sign({sub:'own220-reader',apps:['mm'],permissions:['mm:network:read'],iss:process.env.AUTH_ISSUER},{expiresIn:'5m'}),headers={authorization:'Bearer '+token};
|
||||||
|
const flagCases=[{name:'up',flags:{running:'true',disabled:'false'}},{name:'degraded',flags:{running:'false',disabled:'false'}},{name:'down',flags:{running:'false',disabled:'true'}},{name:'yes-up',flags:{running:'yes',disabled:'no'}},{name:'yes-degraded',flags:{running:'no',disabled:'no'}},{name:'yes-down',flags:{running:'no',disabled:'yes'}},{name:'missing-disabled',flags:{running:'true'}},{name:'missing-running',flags:{disabled:'false'}},{name:'blank-disabled',flags:{running:'true',disabled:''}},{name:'invalid-running',flags:{running:'junk',disabled:'false'}},{name:'invalid-disabled',flags:{running:'true',disabled:'junk'}},{name:'both-missing',flags:{}},{name:'disabled-missing-running',flags:{disabled:'true'}},{name:'disabled-invalid-running',flags:{disabled:'true',running:'junk'}},{name:'recovery',flags:{running:'true',disabled:'false'}}]
|
||||||
|
for(const item of flagCases){
|
||||||
|
flags=item.flags;const off=['true','yes'].includes(flags.disabled??''),on=['false','no'].includes(flags.disabled??''),runningKnown=['true','yes','false','no'].includes(flags.running??''),unknown=!off&&!(on&&runningKnown),before=nativeCalls,snapshot=await collectGreBgpSnapshotOnce()
|
||||||
|
assert.equal(snapshot.greWritten,unknown&&!baseline?0:2);assert.equal(snapshot.bgpWritten,2);assert.equal(snapshot.errors.length,unknown&&!baseline?1:0);assert.equal(snapshot.fatalError,undefined)
|
||||||
|
if(unknown&&!baseline){assert.match(snapshot.errors[0],/Не подтверждено состояние GRE/)}else{const row=snapshot.greTunnels.find(row=>row.targetLabel.endsWith('own220-1'));assert(row);const expected=baseline?flags.disabled==='true'?'down':flags.running==='true'?'up':'degraded':off?'down':['true','yes'].includes(flags.running??'')?'up':'degraded';assert.equal(row.status,expected)}
|
||||||
|
const api=await app.inject({method:'GET',url:'/api/gre/tunnels',headers}),body=api.json();assert.equal(api.statusCode,200);assert.equal(body.failures.length,unknown&&!baseline?1:0);assert.equal(body.tunnels.length,unknown&&!baseline?1:2);cases.push({phase:item.name,endpoint:'GRE authenticated catalog',status:200,tunnels:body.tunnels.length,failures:body.failures.length});
|
||||||
|
cases.push({phase:item.name,flags,greWritten:snapshot.greWritten,bgpWritten:2,sourceErrors:snapshot.errors.length,secondStatus:snapshot.greTunnels.find(row=>row.targetLabel.endsWith('own220-1'))?.status??null,nativeCalls:nativeCalls-before})
|
||||||
|
}
|
||||||
|
|
||||||
|
assert.equal(nativeWrites,0);assert.equal(disabledCalls,0);report.passed=true
|
||||||
|
}catch(e){report.errorName=e.name;fs.writeFileSync('/app/backend/acceptance/gre220-private.log',String(e.stack??e),{mode:0o600})}finally{if(app)await app.close();for(const n of natives){n.closeAllConnections();await new Promise(r=>n.close(r))}await closePool();report.nativeWrites=nativeWrites;report.disabledHomeRouterCalls=disabledCalls;fs.writeFileSync('/app/backend/acceptance/gre220-'+(baseline?'baseline':'fixed')+'.json',JSON.stringify(report,null,2));console.log(JSON.stringify(report))}if(!report.passed)process.exitCode=1
|
||||||
@@ -5,7 +5,7 @@ import { MikrotikClient } from "./mikrotik.js"
|
|||||||
import type { servers } from "../db/schema.js"
|
import type { servers } from "../db/schema.js"
|
||||||
|
|
||||||
const server = { id: 1, name: "CHR", enabled: true } as typeof servers.$inferSelect
|
const server = { id: 1, name: "CHR", enabled: true } as typeof servers.$inferSelect
|
||||||
const raw = [{ ".id": "*g", name: "own-gre", "remote-address": "192.0.2.1", running: "true" }]
|
const raw = [{ ".id": "*g", name: "own-gre", "remote-address": "192.0.2.1", running: "true", disabled: "false" }]
|
||||||
const rows = [
|
const rows = [
|
||||||
{ ".id": "*1", interface: "own-gre", address: "10.1.0.1/30" },
|
{ ".id": "*1", interface: "own-gre", address: "10.1.0.1/30" },
|
||||||
{ ".id": "*1", interface: "own-gre", address: "fd00:151::1/64", advertise: "yes" },
|
{ ".id": "*1", interface: "own-gre", address: "fd00:151::1/64", advertise: "yes" },
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import {
|
|||||||
type GreSnapshot,
|
type GreSnapshot,
|
||||||
} from "./entity-snapshots.js"
|
} from "./entity-snapshots.js"
|
||||||
import { captureAndAppendRevision } from "./config-revisions.js"
|
import { captureAndAppendRevision } from "./config-revisions.js"
|
||||||
|
import { readGreObservedState } from "./gre-observed-state.js"
|
||||||
|
|
||||||
type ServerRow = typeof servers.$inferSelect
|
type ServerRow = typeof servers.$inferSelect
|
||||||
|
|
||||||
@@ -142,8 +143,7 @@ export function mapGreLive(
|
|||||||
ifaceAddrs.sort((a, b) => Number(Boolean(a.disabled)) - Number(Boolean(b.disabled)) || a.address.localeCompare(b.address))
|
ifaceAddrs.sort((a, b) => Number(Boolean(a.disabled)) - Number(Boolean(b.disabled)) || a.address.localeCompare(b.address))
|
||||||
const localInnerIp = ifaceAddrs[0]?.address || fromComment.localInnerIp
|
const localInnerIp = ifaceAddrs[0]?.address || fromComment.localInnerIp
|
||||||
const secret = (g["ipsec-secret"] ?? "").trim()
|
const secret = (g["ipsec-secret"] ?? "").trim()
|
||||||
const disabled = rosDisabled(g.disabled)
|
const { disabled, status } = readGreObservedState(g, name)
|
||||||
const running = g.running === "true" || g.running === "yes"
|
|
||||||
|
|
||||||
gre.push({
|
gre.push({
|
||||||
name,
|
name,
|
||||||
@@ -183,7 +183,7 @@ export function mapGreLive(
|
|||||||
allowFastPath: g["allow-fast-path"] !== "false" && g["allow-fast-path"] !== "no",
|
allowFastPath: g["allow-fast-path"] !== "false" && g["allow-fast-path"] !== "no",
|
||||||
comment: readGreComment(g.comment).comment,
|
comment: readGreComment(g.comment).comment,
|
||||||
enabled: !disabled,
|
enabled: !disabled,
|
||||||
status: disabled ? "down" : running ? "up" : "degraded",
|
status,
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,12 @@
|
|||||||
|
import { observedBoolean } from "./ospf-observed-values.js"
|
||||||
|
|
||||||
|
/** Disabled is authoritative; an enabled interface also needs a known running flag. */
|
||||||
|
export function readGreObservedState(flags: { running?: string; disabled?: string }, name: string) {
|
||||||
|
const disabled = observedBoolean(flags.disabled)
|
||||||
|
const running = observedBoolean(flags.running)
|
||||||
|
if (disabled === null || (disabled === false && running === null)) {
|
||||||
|
throw new Error(`Не подтверждено состояние GRE ${name}`)
|
||||||
|
}
|
||||||
|
const status: "up" | "down" | "degraded" = disabled ? "down" : running ? "up" : "degraded"
|
||||||
|
return { disabled, status }
|
||||||
|
}
|
||||||
@@ -12,3 +12,13 @@ for(const phase of ['populated','empty','partial','failed','disabled','sync-fail
|
|||||||
if(phase==='disabled')assert.equal(calls,0)
|
if(phase==='disabled')assert.equal(calls,0)
|
||||||
}
|
}
|
||||||
console.log('GRE alert source: populated/empty/partial/all-failed/disabled/sync error; BGP control preserved, per-device errors retained')
|
console.log('GRE alert source: populated/empty/partial/all-failed/disabled/sync error; BGP control preserved, per-device errors retained')
|
||||||
|
import {mapGreLive} from './gre-live.js'
|
||||||
|
import {mapGreAlertRow} from './gre-tunnels-live.js'
|
||||||
|
let combinations=0
|
||||||
|
for(const disabled of ['true','yes','false','no',undefined,'','junk'])for(const running of ['true','yes','false','no',undefined,'','junk']){
|
||||||
|
const row={'.id':'*1',name:'own-flags',disabled,running},off=['true','yes'].includes(disabled??''),on=['false','no'].includes(disabled??''),runningKnown=['true','yes','false','no'].includes(running??'')
|
||||||
|
if(off||on&&runningKnown){const expected=off?'down':['true','yes'].includes(running??'')?'up':'degraded';assert.equal(mapGreAlertRow(devices[0],row).status,expected);assert.equal(mapGreLive(devices[0],[row],[]).tunnels[0].status,expected)}
|
||||||
|
else {assert.throws(()=>mapGreAlertRow(devices[0],row),/Не подтверждено состояние GRE/);assert.throws(()=>mapGreLive(devices[0],[row],[]),/Не подтверждено состояние GRE/)}
|
||||||
|
combinations++
|
||||||
|
}
|
||||||
|
console.log('GRE flags: '+combinations+' combinations; true/false/yes/no, absent/blank/invalid, disabled state independent of running')
|
||||||
@@ -3,6 +3,7 @@ import { db } from "../db/index.js"
|
|||||||
import { servers } from "../db/schema.js"
|
import { servers } from "../db/schema.js"
|
||||||
import { MikrotikClient } from "./mikrotik.js"
|
import { MikrotikClient } from "./mikrotik.js"
|
||||||
import { readInternetPathRows } from "./internet-path-snapshot.js"
|
import { readInternetPathRows } from "./internet-path-snapshot.js"
|
||||||
|
import { readGreObservedState } from "./gre-observed-state.js"
|
||||||
|
|
||||||
type ServerRow = typeof servers.$inferSelect
|
type ServerRow = typeof servers.$inferSelect
|
||||||
|
|
||||||
@@ -29,10 +30,8 @@ export type GreTunnelLiveRow = {
|
|||||||
status: GreTunnelLiveStatus
|
status: GreTunnelLiveStatus
|
||||||
}
|
}
|
||||||
|
|
||||||
function mapGreRow(server: ServerRow, g: RosGre, idx: number): GreTunnelLiveRow {
|
export function mapGreAlertRow(server: ServerRow, g: RosGre, idx = 0): GreTunnelLiveRow {
|
||||||
const running = g.running === "true"
|
const { status } = readGreObservedState(g, g.name ?? g[".id"] ?? "")
|
||||||
const disabled = g.disabled === "true"
|
|
||||||
const status: GreTunnelLiveStatus = disabled ? "down" : running ? "up" : "degraded"
|
|
||||||
const sn = String(server.name ?? "").trim() || String(server.host ?? "").trim() || String(server.id)
|
const sn = String(server.name ?? "").trim() || String(server.host ?? "").trim() || String(server.id)
|
||||||
const tn = (String(g.name ?? "").trim() || String(g[".id"] ?? "").trim() || `gre-${idx + 1}`).trim()
|
const tn = (String(g.name ?? "").trim() || String(g[".id"] ?? "").trim() || `gre-${idx + 1}`).trim()
|
||||||
const label = `${tn} / ${sn}`.trim()
|
const label = `${tn} / ${sn}`.trim()
|
||||||
@@ -43,7 +42,7 @@ async function fetchGreForServer(server: ServerRow): Promise<GreTunnelLiveRow[]>
|
|||||||
const client = MikrotikClient.fromServer(server)
|
const client = MikrotikClient.fromServer(server)
|
||||||
const greRaw = readInternetPathRows(await client.get<unknown>("/interface/gre"), "GRE alert source", [".id", "name"])
|
const greRaw = readInternetPathRows(await client.get<unknown>("/interface/gre"), "GRE alert source", [".id", "name"])
|
||||||
if (new Set(greRaw.map(row => row[".id"])).size !== greRaw.length) throw new Error("Повторяющиеся ID GRE")
|
if (new Set(greRaw.map(row => row[".id"])).size !== greRaw.length) throw new Error("Повторяющиеся ID GRE")
|
||||||
return greRaw.map((g, idx) => mapGreRow(server, g, idx))
|
return greRaw.map((g, idx) => mapGreAlertRow(server, g, idx))
|
||||||
}
|
}
|
||||||
|
|
||||||
interface GreAlertDependencies {
|
interface GreAlertDependencies {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# UX/UI: протокол внешней приёмки 12.5
|
# UX/UI: протокол внешней приёмки 12.5
|
||||||
|
|
||||||
Актуальное продолжение 2026-10-14: блок219 завершён. GRE source snapshots больше не подавляет per-device ошибки; повреждённые records/duplicate native IDs отклоняются. BGP observations сохраняются при GRE failure. Четыре профиля, SQL/native10, compiled actual source2own GRE и UI1440/320 прошли; own DB/roles/tunnels удалены. Backend ux-gre219/compiled1052/source486 matched, frontend ux-routing218. Следующий220 — неизвестные/некорректные GRE operational flags в snapshots. Этап12.5 открыт.
|
Актуальное продолжение 2026-10-14: блок220 завершён. GRE catalog/config snapshots/alert source используют одну модель подтверждённых operational flags. Unknown flags не превращаются в degraded/up. Local49, profiles14+6, production30, real up→down/degraded→up/Ping3/3×2 и source/UI прошли; own objects удалены. Первичный native401104.165.244.7 после перепроверки не повторился, причина неизвестна. Backend ux-gre220/compiled1056/source488 matched, frontend ux-routing218. Следующий221 — native GRE identity/duplicate guards для каталога и snapshots. Этап12.5 открыт.
|
||||||
|
|
||||||
IPsec78: реальный PSK responder established, mode-config198.18.78.10 и online=true подтверждены API; точные собственные объекты удалены. Сертификатный/DN online, late failure и history restore остаются открытыми. [Отчёт](ux-ui/acceptance/ipsec-mode-config-2026-10-09.json), [журнал](ux-ui-progress.md).
|
IPsec78: реальный PSK responder established, mode-config198.18.78.10 и online=true подтверждены API; точные собственные объекты удалены. Сертификатный/DN online, late failure и history restore остаются открытыми. [Отчёт](ux-ui/acceptance/ipsec-mode-config-2026-10-09.json), [журнал](ux-ui-progress.md).
|
||||||
|
|
||||||
@@ -2603,3 +2603,7 @@ BGP/OSPF contrast: baseline22/fixed104 cells0 violations; E2E22 и real UI8 pass
|
|||||||
## 12.5.219 — GRE snapshot source (2026-10-14)
|
## 12.5.219 — GRE snapshot source (2026-10-14)
|
||||||
|
|
||||||
Ошибки GRE source отражаются в snapshot; BGP при GRE failure сохраняется. SQL/native10 и actual compiled source2own GRE/UI passed; временные объекты удалены. Подробности и границы — [журнал](ux-ui-progress.md). Backend ux-gre219, frontend ux-routing218; следующий220 — неизвестные GRE flags.
|
Ошибки GRE source отражаются в snapshot; BGP при GRE failure сохраняется. SQL/native10 и actual compiled source2own GRE/UI passed; временные объекты удалены. Подробности и границы — [журнал](ux-ui-progress.md). Backend ux-gre219, frontend ux-routing218; следующий220 — неизвестные GRE flags.
|
||||||
|
|
||||||
|
## 12.5.220 — GRE operational flags (2026-10-14)
|
||||||
|
|
||||||
|
Общий reader catalog/config/alerts не подменяет неизвестные flags. Production30/local49 и цельный native lifecycle/Ping/source/UI прошли, own objects удалены. Первичный401 сохранён, причина неизвестна. Подробности и границы — [журнал](ux-ui-progress.md). Backend ux-gre220, frontend ux-routing218; следующий221 — GRE identity guards.
|
||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
# План реализации UX/UI по пятичасовым окнам
|
# План реализации UX/UI по пятичасовым окнам
|
||||||
|
|
||||||
Актуальное продолжение 2026-10-14: блок219 завершён. GRE source snapshots больше не подавляет per-device ошибки; повреждённые records/duplicate native IDs отклоняются. BGP observations сохраняются при GRE failure. Четыре профиля, SQL/native10, compiled actual source2own GRE и UI1440/320 прошли; own DB/roles/tunnels удалены. Backend ux-gre219/compiled1052/source486 matched, frontend ux-routing218. Следующий220 — неизвестные/некорректные GRE operational flags в snapshots. Этап12.5 открыт.
|
Актуальное продолжение 2026-10-14: блок220 завершён. GRE catalog/config snapshots/alert source используют одну модель подтверждённых operational flags. Unknown flags не превращаются в degraded/up. Local49, profiles14+6, production30, real up→down/degraded→up/Ping3/3×2 и source/UI прошли; own objects удалены. Первичный native401104.165.244.7 после перепроверки не повторился, причина неизвестна. Backend ux-gre220/compiled1056/source488 matched, frontend ux-routing218. Следующий221 — native GRE identity/duplicate guards для каталога и snapshots. Этап12.5 открыт.
|
||||||
|
|
||||||
Общий план проекта MikrotikManager. Основан на согласованном плане из задачи; точка продолжения обновлена 2026-10-13. Источник фактического прогресса, проверок и ограничений — [журнал реализации](ux-ui-progress.md). Этот документ задаёт объём и критерии завершения, журнал фиксирует результат.
|
Общий план проекта MikrotikManager. Основан на согласованном плане из задачи; точка продолжения обновлена 2026-10-13. Источник фактического прогресса, проверок и ограничений — [журнал реализации](ux-ui-progress.md). Этот документ задаёт объём и критерии завершения, журнал фиксирует результат.
|
||||||
|
|
||||||
|
|||||||
+13
-1
@@ -1,6 +1,6 @@
|
|||||||
# UX/UI: журнал реализации
|
# UX/UI: журнал реализации
|
||||||
|
|
||||||
Актуальное продолжение 2026-10-14: блок219 завершён. GRE source snapshots больше не подавляет per-device ошибки; повреждённые records/duplicate native IDs отклоняются. BGP observations сохраняются при GRE failure. Четыре профиля, SQL/native10, compiled actual source2own GRE и UI1440/320 прошли; own DB/roles/tunnels удалены. Backend ux-gre219/compiled1052/source486 matched, frontend ux-routing218. Следующий220 — неизвестные/некорректные GRE operational flags в snapshots. Этап12.5 открыт.
|
Актуальное продолжение 2026-10-14: блок220 завершён. GRE catalog/config snapshots/alert source используют одну модель подтверждённых operational flags. Unknown flags не превращаются в degraded/up. Local49, profiles14+6, production30, real up→down/degraded→up/Ping3/3×2 и source/UI прошли; own objects удалены. Первичный native401104.165.244.7 после перепроверки не повторился, причина неизвестна. Backend ux-gre220/compiled1056/source488 matched, frontend ux-routing218. Следующий221 — native GRE identity/duplicate guards для каталога и snapshots. Этап12.5 открыт.
|
||||||
|
|
||||||
Общий план: [UX/UI по этапам и пятичасовым окнам](ux-ui-plan.md). План задаёт объём, этот журнал фиксирует выполненные блоки и ограничения. Записи расположены от новых к старым; подробная история этапа12 также сохранена в [ux-ui-stage-12.md](ux-ui-stage-12.md).
|
Общий план: [UX/UI по этапам и пятичасовым окнам](ux-ui-plan.md). План задаёт объём, этот журнал фиксирует выполненные блоки и ограничения. Записи расположены от новых к старым; подробная история этапа12 также сохранена в [ux-ui-stage-12.md](ux-ui-stage-12.md).
|
||||||
|
|
||||||
@@ -38,6 +38,18 @@
|
|||||||
| 11Б | Оповещения, сбор данных, интеграции, релизы и настройки | Завершён в границах локальной приёмки 2026-10-03; ограничения и evidence в11Б.7 |
|
| 11Б | Оповещения, сбор данных, интеграции, релизы и настройки | Завершён в границах локальной приёмки 2026-10-03; ограничения и evidence в11Б.7 |
|
||||||
| 12 | Итоговая доступность, адаптивность, производительность и регрессия | Локальная приёмка завершена в границах12.3.83; внешняя12.5 в работе, выполненные блоки1–196 и ограничения ниже. Runtime backend/frontend ux-peak196. |
|
| 12 | Итоговая доступность, адаптивность, производительность и регрессия | Локальная приёмка завершена в границах12.3.83; внешняя12.5 в работе, выполненные блоки1–196 и ограничения ниже. Runtime backend/frontend ux-peak196. |
|
||||||
|
|
||||||
|
## 12.5.220 — подтверждённые operational flags GRE (2026-10-14)
|
||||||
|
|
||||||
|
Общий readGreObservedState используется в live catalog/config snapshot и alert source. true/false/yes/no читаются одинаково; disabled=true подтверждает down независимо от running. При неизвестном disabled или running у enabled interface опрос устройства отклоняется. Достоверные up/down/degraded сохранены; главная API-envelope по-прежнему передаёт failures по устройствам, а source snapshot сообщает GRE error и сохраняет BGP. Unknown metadata больше не выдаётся за подтверждённый operational status. Другие параметры/defaults GRE этим блоком не объявляются полностью проверенными.
|
||||||
|
|
||||||
|
Local49 комбинаций проверили оба reader пути. Профили live-maps14 и config-sync6, build прошли; optional SQL branch network-disabled-server без его специального env skipped, не считается новой SQL приёмкой. Первая IPv6 fixture имела running=true, но не имела disabled: дополнена explicit false, повтор passed. Baseline ux-gre219/fixed ux-gre220 по30 production checks:15 flags через compiled snapshot collector и signed reader GRE API. Unknown flags дают sourceError и per-device API failure; здоровое устройство остаётся в catalog. BGP2 control rows сохраняются. Own DB/roles удалены, native writes0.
|
||||||
|
|
||||||
|
Backend ux-gre220 compiled1056/source488 matched, healthy; frontend ux-routing218 сохранён. Первая live попытка прервана native401104.165.244.7; точный failed request path не записан. Cleanup созданных own GRE сообщил успех. Шесть последующих native checks200 на обоих CHR с теми же credentials; root cause не установлен. Новый цельный run использовал Connection close в прямых контрольных REST calls; это не causal proof причины401 и не production auth retry.
|
||||||
|
|
||||||
|
В повторном run own GRE2/IPv4inner поднялись up, Ping3/3 в обе стороны. Actual compiled collector read lab DB/native и подтвердил own up2/sourceErrors0 без scheduler history write. UI1440/320 показал own rows без page errors/mutations. Disable одного: native/API down + peer degraded; enable: recovery up/up и повторный Ping3/3 обоих. Own interfaces/addresses удалены, absence API/native проверен; пароли не менялись. Это controlled краткая loss/recovery, не physical WAN/SLA/длительная устойчивость.
|
||||||
|
|
||||||
|
Протоколы: [baseline](ux-ui/acceptance/gre220-baseline.json), [fixed](ux-ui/acceptance/gre220-fixed.json), [build](ux-ui/acceptance/gre220-build-proof-2026-10-14.json), [deployment](ux-ui/acceptance/gre220-deployment-2026-10-14.json), [initial401](ux-ui/acceptance/gre220-initial-native-failure-2026-10-14.json), [whole native/UI/cleanup](ux-ui/acceptance/gre220-native-live-2026-10-14.json). Следующий221 — отклонять missing/duplicate native GRE identity в каталоге/config snapshots; сейчас mapGreLive допускает выдуманные fallback IDs/names.
|
||||||
|
|
||||||
## 12.5.219 — ошибки реального GRE source для snapshots (2026-10-14)
|
## 12.5.219 — ошибки реального GRE source для snapshots (2026-10-14)
|
||||||
|
|
||||||
fetchGreTunnelLiveRows подавлял native failures через[] и collector принимал пустой/неполный источник без ошибки. Теперь per-device reads settled независимо, все ошибки агрегируются по устройствам и неполный источник отклоняется; collector записывает GRE source error и сохраняет независимо прочитанный BGP. Raw GRE должен быть корректной коллекцией string records с native .id/name; duplicate IDs отклоняются. Правила сигналов/доставки и существующая трактовка running/disabled пока не менялись: неизвестные operational flags — следующий220.
|
fetchGreTunnelLiveRows подавлял native failures через[] и collector принимал пустой/неполный источник без ошибки. Теперь per-device reads settled независимо, все ошибки агрегируются по устройствам и неполный источник отклоняется; collector записывает GRE source error и сохраняет независимо прочитанный BGP. Raw GRE должен быть корректной коллекцией string records с native .id/name; duplicate IDs отклоняются. Правила сигналов/доставки и существующая трактовка running/disabled пока не менялись: неизвестные operational flags — следующий220.
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
# Оставшаяся внешняя приёмка — 2026-10-13
|
# Оставшаяся внешняя приёмка — 2026-10-13
|
||||||
|
|
||||||
Актуальное продолжение 2026-10-14: блок219 завершён. GRE source snapshots больше не подавляет per-device ошибки; повреждённые records/duplicate native IDs отклоняются. BGP observations сохраняются при GRE failure. Четыре профиля, SQL/native10, compiled actual source2own GRE и UI1440/320 прошли; own DB/roles/tunnels удалены. Backend ux-gre219/compiled1052/source486 matched, frontend ux-routing218. Следующий220 — неизвестные/некорректные GRE operational flags в snapshots. Этап12.5 открыт.
|
Актуальное продолжение 2026-10-14: блок220 завершён. GRE catalog/config snapshots/alert source используют одну модель подтверждённых operational flags. Unknown flags не превращаются в degraded/up. Local49, profiles14+6, production30, real up→down/degraded→up/Ping3/3×2 и source/UI прошли; own objects удалены. Первичный native401104.165.244.7 после перепроверки не повторился, причина неизвестна. Backend ux-gre220/compiled1056/source488 matched, frontend ux-routing218. Следующий221 — native GRE identity/duplicate guards для каталога и snapshots. Этап12.5 открыт.
|
||||||
|
|
||||||
Это актуальная матрица после 12.5.219. Исторические записи сохраняют версии и ограничения на момент выполнения; поздние проверки ниже уточняют их. Этап 12.5 открыт. Успех в двух CHR и одном backend не означает приёмку всех конфигураций, интеграций или полной регрессии.
|
Это актуальная матрица после 12.5.220. Исторические записи сохраняют версии и ограничения на момент выполнения; поздние проверки ниже уточняют их. Этап 12.5 открыт. Успех в двух CHR и одном backend не означает приёмку всех конфигураций, интеграций или полной регрессии.
|
||||||
|
|
||||||
Стенд: Debian13/Compose, PostgreSQL18.6, два CHR RouterOS7.24.5. Backend `ux-gre219`, frontend `ux-routing218`; production lab с195 использует AUTH_REQUIRED=true и Portal1.3.1. Подписанные JWT/RBAC проверялись в изолированных процессах. Все собственные объекты112 удалены, исходные13 коллекций×2 (включая logging/certificates/files/routes) проверены; пароли не менялись.
|
Стенд: Debian13/Compose, PostgreSQL18.6, два CHR RouterOS7.24.5. Backend `ux-gre220`, frontend `ux-routing218`; production lab с195 использует AUTH_REQUIRED=true и Portal1.3.1. Подписанные JWT/RBAC проверялись в изолированных процессах. Все собственные объекты112 удалены, исходные13 коллекций×2 (включая logging/certificates/files/routes) проверены; пароли не менялись.
|
||||||
|
|
||||||
| Раздел | Подтверждено | Осталось / условие завершения |
|
| Раздел | Подтверждено | Осталось / условие завершения |
|
||||||
| --- | --- | --- |
|
| --- | --- | --- |
|
||||||
@@ -1521,3 +1521,7 @@ BGP/OSPF contrast: baseline22/fixed104 cells0 violations; E2E22 и real UI8 pass
|
|||||||
## 12.5.219 — GRE snapshot source (2026-10-14)
|
## 12.5.219 — GRE snapshot source (2026-10-14)
|
||||||
|
|
||||||
Ошибки GRE source отражаются в snapshot; BGP при GRE failure сохраняется. SQL/native10 и actual compiled source2own GRE/UI passed; временные объекты удалены. Подробности и границы — [журнал](ux-ui-progress.md). Backend ux-gre219, frontend ux-routing218; следующий220 — неизвестные GRE flags.
|
Ошибки GRE source отражаются в snapshot; BGP при GRE failure сохраняется. SQL/native10 и actual compiled source2own GRE/UI passed; временные объекты удалены. Подробности и границы — [журнал](ux-ui-progress.md). Backend ux-gre219, frontend ux-routing218; следующий220 — неизвестные GRE flags.
|
||||||
|
|
||||||
|
## 12.5.220 — GRE operational flags (2026-10-14)
|
||||||
|
|
||||||
|
Общий reader catalog/config/alerts не подменяет неизвестные flags. Production30/local49 и цельный native lifecycle/Ping/source/UI прошли, own objects удалены. Первичный401 сохранён, причина неизвестна. Подробности и границы — [журнал](ux-ui-progress.md). Backend ux-gre220, frontend ux-routing218; следующий221 — GRE identity guards.
|
||||||
+14
-1
@@ -1,6 +1,6 @@
|
|||||||
# Этап 12: итоговая приёмка UX/UI
|
# Этап 12: итоговая приёмка UX/UI
|
||||||
|
|
||||||
Актуальное продолжение 2026-10-14: блок219 завершён. GRE source snapshots больше не подавляет per-device ошибки; повреждённые records/duplicate native IDs отклоняются. BGP observations сохраняются при GRE failure. Четыре профиля, SQL/native10, compiled actual source2own GRE и UI1440/320 прошли; own DB/roles/tunnels удалены. Backend ux-gre219/compiled1052/source486 matched, frontend ux-routing218. Следующий220 — неизвестные/некорректные GRE operational flags в snapshots. Этап12.5 открыт.
|
Актуальное продолжение 2026-10-14: блок220 завершён. GRE catalog/config snapshots/alert source используют одну модель подтверждённых operational flags. Unknown flags не превращаются в degraded/up. Local49, profiles14+6, production30, real up→down/degraded→up/Ping3/3×2 и source/UI прошли; own objects удалены. Первичный native401104.165.244.7 после перепроверки не повторился, причина неизвестна. Backend ux-gre220/compiled1056/source488 matched, frontend ux-routing218. Следующий221 — native GRE identity/duplicate guards для каталога и snapshots. Этап12.5 открыт.
|
||||||
|
|
||||||
План: [ux-ui-plan.md](ux-ui-plan.md). Фактические результаты: [ux-ui-progress.md](ux-ui-progress.md). Подготовлен после сводных проверок 11Б; завершение каждого блока требует локального коммита без push.
|
План: [ux-ui-plan.md](ux-ui-plan.md). Фактические результаты: [ux-ui-progress.md](ux-ui-progress.md). Подготовлен после сводных проверок 11Б; завершение каждого блока требует локального коммита без push.
|
||||||
|
|
||||||
@@ -3978,3 +3978,16 @@ Backend ux-gre219 compiled1052/source486 matched, healthy; frontend ux-routing21
|
|||||||
|
|
||||||
Протоколы: [baseline](ux-ui/acceptance/gre219-baseline.json), [fixed](ux-ui/acceptance/gre219-fixed.json), [build](ux-ui/acceptance/gre219-build-proof-2026-10-14.json), [deployment](ux-ui/acceptance/gre219-deployment-2026-10-14.json), [native source/UI/cleanup](ux-ui/acceptance/gre219-native-live-2026-10-14.json). Следующий220 — не подтверждать degraded/up/down по отсутствующим/повреждённым GRE flags; валидные native состояния сохранить.
|
Протоколы: [baseline](ux-ui/acceptance/gre219-baseline.json), [fixed](ux-ui/acceptance/gre219-fixed.json), [build](ux-ui/acceptance/gre219-build-proof-2026-10-14.json), [deployment](ux-ui/acceptance/gre219-deployment-2026-10-14.json), [native source/UI/cleanup](ux-ui/acceptance/gre219-native-live-2026-10-14.json). Следующий220 — не подтверждать degraded/up/down по отсутствующим/повреждённым GRE flags; валидные native состояния сохранить.
|
||||||
|
|
||||||
|
|
||||||
|
## 12.5.220 — подтверждённые operational flags GRE (2026-10-14)
|
||||||
|
|
||||||
|
Общий readGreObservedState используется в live catalog/config snapshot и alert source. true/false/yes/no читаются одинаково; disabled=true подтверждает down независимо от running. При неизвестном disabled или running у enabled interface опрос устройства отклоняется. Достоверные up/down/degraded сохранены; главная API-envelope по-прежнему передаёт failures по устройствам, а source snapshot сообщает GRE error и сохраняет BGP. Unknown metadata больше не выдаётся за подтверждённый operational status. Другие параметры/defaults GRE этим блоком не объявляются полностью проверенными.
|
||||||
|
|
||||||
|
Local49 комбинаций проверили оба reader пути. Профили live-maps14 и config-sync6, build прошли; optional SQL branch network-disabled-server без его специального env skipped, не считается новой SQL приёмкой. Первая IPv6 fixture имела running=true, но не имела disabled: дополнена explicit false, повтор passed. Baseline ux-gre219/fixed ux-gre220 по30 production checks:15 flags через compiled snapshot collector и signed reader GRE API. Unknown flags дают sourceError и per-device API failure; здоровое устройство остаётся в catalog. BGP2 control rows сохраняются. Own DB/roles удалены, native writes0.
|
||||||
|
|
||||||
|
Backend ux-gre220 compiled1056/source488 matched, healthy; frontend ux-routing218 сохранён. Первая live попытка прервана native401104.165.244.7; точный failed request path не записан. Cleanup созданных own GRE сообщил успех. Шесть последующих native checks200 на обоих CHR с теми же credentials; root cause не установлен. Новый цельный run использовал Connection close в прямых контрольных REST calls; это не causal proof причины401 и не production auth retry.
|
||||||
|
|
||||||
|
В повторном run own GRE2/IPv4inner поднялись up, Ping3/3 в обе стороны. Actual compiled collector read lab DB/native и подтвердил own up2/sourceErrors0 без scheduler history write. UI1440/320 показал own rows без page errors/mutations. Disable одного: native/API down + peer degraded; enable: recovery up/up и повторный Ping3/3 обоих. Own interfaces/addresses удалены, absence API/native проверен; пароли не менялись. Это controlled краткая loss/recovery, не physical WAN/SLA/длительная устойчивость.
|
||||||
|
|
||||||
|
Протоколы: [baseline](ux-ui/acceptance/gre220-baseline.json), [fixed](ux-ui/acceptance/gre220-fixed.json), [build](ux-ui/acceptance/gre220-build-proof-2026-10-14.json), [deployment](ux-ui/acceptance/gre220-deployment-2026-10-14.json), [initial401](ux-ui/acceptance/gre220-initial-native-failure-2026-10-14.json), [whole native/UI/cleanup](ux-ui/acceptance/gre220-native-live-2026-10-14.json). Следующий221 — отклонять missing/duplicate native GRE identity в каталоге/config snapshots; сейчас mapGreLive допускает выдуманные fallback IDs/names.
|
||||||
|
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
# Тестовый сервер UX/UI — 2026-10-10
|
# Тестовый сервер UX/UI — 2026-10-10
|
||||||
|
|
||||||
Актуальное продолжение 2026-10-14: блок219 завершён. GRE source snapshots больше не подавляет per-device ошибки; повреждённые records/duplicate native IDs отклоняются. BGP observations сохраняются при GRE failure. Четыре профиля, SQL/native10, compiled actual source2own GRE и UI1440/320 прошли; own DB/roles/tunnels удалены. Backend ux-gre219/compiled1052/source486 matched, frontend ux-routing218. Следующий220 — неизвестные/некорректные GRE operational flags в snapshots. Этап12.5 открыт.
|
Актуальное продолжение 2026-10-14: блок220 завершён. GRE catalog/config snapshots/alert source используют одну модель подтверждённых operational flags. Unknown flags не превращаются в degraded/up. Local49, profiles14+6, production30, real up→down/degraded→up/Ping3/3×2 и source/UI прошли; own objects удалены. Первичный native401104.165.244.7 после перепроверки не повторился, причина неизвестна. Backend ux-gre220/compiled1056/source488 matched, frontend ux-routing218. Следующий221 — native GRE identity/duplicate guards для каталога и snapshots. Этап12.5 открыт.
|
||||||
|
|
||||||
| Параметр | Проверенное состояние |
|
| Параметр | Проверенное состояние |
|
||||||
| --- | --- |
|
| --- | --- |
|
||||||
@@ -2334,3 +2334,7 @@ BGP/OSPF contrast: baseline22/fixed104 cells0 violations; E2E22 и real UI8 pass
|
|||||||
## 12.5.219 — GRE snapshot source (2026-10-14)
|
## 12.5.219 — GRE snapshot source (2026-10-14)
|
||||||
|
|
||||||
Ошибки GRE source отражаются в snapshot; BGP при GRE failure сохраняется. SQL/native10 и actual compiled source2own GRE/UI passed; временные объекты удалены. Подробности и границы — [журнал](ux-ui-progress.md). Backend ux-gre219, frontend ux-routing218; следующий220 — неизвестные GRE flags.
|
Ошибки GRE source отражаются в snapshot; BGP при GRE failure сохраняется. SQL/native10 и actual compiled source2own GRE/UI passed; временные объекты удалены. Подробности и границы — [журнал](ux-ui-progress.md). Backend ux-gre219, frontend ux-routing218; следующий220 — неизвестные GRE flags.
|
||||||
|
|
||||||
|
## 12.5.220 — GRE operational flags (2026-10-14)
|
||||||
|
|
||||||
|
Общий reader catalog/config/alerts не подменяет неизвестные flags. Production30/local49 и цельный native lifecycle/Ping/source/UI прошли, own objects удалены. Первичный401 сохранён, причина неизвестна. Подробности и границы — [журнал](ux-ui-progress.md). Backend ux-gre220, frontend ux-routing218; следующий221 — GRE identity guards.
|
||||||
@@ -0,0 +1,292 @@
|
|||||||
|
{
|
||||||
|
"date": "2026-10-14",
|
||||||
|
"block": "12.5.220",
|
||||||
|
"baseline": true,
|
||||||
|
"database": "mm_accept_166_1791916058621",
|
||||||
|
"cases": [
|
||||||
|
{
|
||||||
|
"phase": "up",
|
||||||
|
"endpoint": "GRE authenticated catalog",
|
||||||
|
"status": 200,
|
||||||
|
"tunnels": 2,
|
||||||
|
"failures": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"phase": "up",
|
||||||
|
"flags": {
|
||||||
|
"running": "true",
|
||||||
|
"disabled": "false"
|
||||||
|
},
|
||||||
|
"greWritten": 2,
|
||||||
|
"bgpWritten": 2,
|
||||||
|
"sourceErrors": 0,
|
||||||
|
"secondStatus": "up",
|
||||||
|
"nativeCalls": 10
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"phase": "degraded",
|
||||||
|
"endpoint": "GRE authenticated catalog",
|
||||||
|
"status": 200,
|
||||||
|
"tunnels": 2,
|
||||||
|
"failures": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"phase": "degraded",
|
||||||
|
"flags": {
|
||||||
|
"running": "false",
|
||||||
|
"disabled": "false"
|
||||||
|
},
|
||||||
|
"greWritten": 2,
|
||||||
|
"bgpWritten": 2,
|
||||||
|
"sourceErrors": 0,
|
||||||
|
"secondStatus": "degraded",
|
||||||
|
"nativeCalls": 10
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"phase": "down",
|
||||||
|
"endpoint": "GRE authenticated catalog",
|
||||||
|
"status": 200,
|
||||||
|
"tunnels": 2,
|
||||||
|
"failures": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"phase": "down",
|
||||||
|
"flags": {
|
||||||
|
"running": "false",
|
||||||
|
"disabled": "true"
|
||||||
|
},
|
||||||
|
"greWritten": 2,
|
||||||
|
"bgpWritten": 2,
|
||||||
|
"sourceErrors": 0,
|
||||||
|
"secondStatus": "down",
|
||||||
|
"nativeCalls": 10
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"phase": "yes-up",
|
||||||
|
"endpoint": "GRE authenticated catalog",
|
||||||
|
"status": 200,
|
||||||
|
"tunnels": 2,
|
||||||
|
"failures": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"phase": "yes-up",
|
||||||
|
"flags": {
|
||||||
|
"running": "yes",
|
||||||
|
"disabled": "no"
|
||||||
|
},
|
||||||
|
"greWritten": 2,
|
||||||
|
"bgpWritten": 2,
|
||||||
|
"sourceErrors": 0,
|
||||||
|
"secondStatus": "degraded",
|
||||||
|
"nativeCalls": 10
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"phase": "yes-degraded",
|
||||||
|
"endpoint": "GRE authenticated catalog",
|
||||||
|
"status": 200,
|
||||||
|
"tunnels": 2,
|
||||||
|
"failures": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"phase": "yes-degraded",
|
||||||
|
"flags": {
|
||||||
|
"running": "no",
|
||||||
|
"disabled": "no"
|
||||||
|
},
|
||||||
|
"greWritten": 2,
|
||||||
|
"bgpWritten": 2,
|
||||||
|
"sourceErrors": 0,
|
||||||
|
"secondStatus": "degraded",
|
||||||
|
"nativeCalls": 10
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"phase": "yes-down",
|
||||||
|
"endpoint": "GRE authenticated catalog",
|
||||||
|
"status": 200,
|
||||||
|
"tunnels": 2,
|
||||||
|
"failures": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"phase": "yes-down",
|
||||||
|
"flags": {
|
||||||
|
"running": "no",
|
||||||
|
"disabled": "yes"
|
||||||
|
},
|
||||||
|
"greWritten": 2,
|
||||||
|
"bgpWritten": 2,
|
||||||
|
"sourceErrors": 0,
|
||||||
|
"secondStatus": "degraded",
|
||||||
|
"nativeCalls": 10
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"phase": "missing-disabled",
|
||||||
|
"endpoint": "GRE authenticated catalog",
|
||||||
|
"status": 200,
|
||||||
|
"tunnels": 2,
|
||||||
|
"failures": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"phase": "missing-disabled",
|
||||||
|
"flags": {
|
||||||
|
"running": "true"
|
||||||
|
},
|
||||||
|
"greWritten": 2,
|
||||||
|
"bgpWritten": 2,
|
||||||
|
"sourceErrors": 0,
|
||||||
|
"secondStatus": "up",
|
||||||
|
"nativeCalls": 10
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"phase": "missing-running",
|
||||||
|
"endpoint": "GRE authenticated catalog",
|
||||||
|
"status": 200,
|
||||||
|
"tunnels": 2,
|
||||||
|
"failures": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"phase": "missing-running",
|
||||||
|
"flags": {
|
||||||
|
"disabled": "false"
|
||||||
|
},
|
||||||
|
"greWritten": 2,
|
||||||
|
"bgpWritten": 2,
|
||||||
|
"sourceErrors": 0,
|
||||||
|
"secondStatus": "degraded",
|
||||||
|
"nativeCalls": 10
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"phase": "blank-disabled",
|
||||||
|
"endpoint": "GRE authenticated catalog",
|
||||||
|
"status": 200,
|
||||||
|
"tunnels": 2,
|
||||||
|
"failures": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"phase": "blank-disabled",
|
||||||
|
"flags": {
|
||||||
|
"running": "true",
|
||||||
|
"disabled": ""
|
||||||
|
},
|
||||||
|
"greWritten": 2,
|
||||||
|
"bgpWritten": 2,
|
||||||
|
"sourceErrors": 0,
|
||||||
|
"secondStatus": "up",
|
||||||
|
"nativeCalls": 10
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"phase": "invalid-running",
|
||||||
|
"endpoint": "GRE authenticated catalog",
|
||||||
|
"status": 200,
|
||||||
|
"tunnels": 2,
|
||||||
|
"failures": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"phase": "invalid-running",
|
||||||
|
"flags": {
|
||||||
|
"running": "junk",
|
||||||
|
"disabled": "false"
|
||||||
|
},
|
||||||
|
"greWritten": 2,
|
||||||
|
"bgpWritten": 2,
|
||||||
|
"sourceErrors": 0,
|
||||||
|
"secondStatus": "degraded",
|
||||||
|
"nativeCalls": 10
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"phase": "invalid-disabled",
|
||||||
|
"endpoint": "GRE authenticated catalog",
|
||||||
|
"status": 200,
|
||||||
|
"tunnels": 2,
|
||||||
|
"failures": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"phase": "invalid-disabled",
|
||||||
|
"flags": {
|
||||||
|
"running": "true",
|
||||||
|
"disabled": "junk"
|
||||||
|
},
|
||||||
|
"greWritten": 2,
|
||||||
|
"bgpWritten": 2,
|
||||||
|
"sourceErrors": 0,
|
||||||
|
"secondStatus": "up",
|
||||||
|
"nativeCalls": 10
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"phase": "both-missing",
|
||||||
|
"endpoint": "GRE authenticated catalog",
|
||||||
|
"status": 200,
|
||||||
|
"tunnels": 2,
|
||||||
|
"failures": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"phase": "both-missing",
|
||||||
|
"flags": {},
|
||||||
|
"greWritten": 2,
|
||||||
|
"bgpWritten": 2,
|
||||||
|
"sourceErrors": 0,
|
||||||
|
"secondStatus": "degraded",
|
||||||
|
"nativeCalls": 10
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"phase": "disabled-missing-running",
|
||||||
|
"endpoint": "GRE authenticated catalog",
|
||||||
|
"status": 200,
|
||||||
|
"tunnels": 2,
|
||||||
|
"failures": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"phase": "disabled-missing-running",
|
||||||
|
"flags": {
|
||||||
|
"disabled": "true"
|
||||||
|
},
|
||||||
|
"greWritten": 2,
|
||||||
|
"bgpWritten": 2,
|
||||||
|
"sourceErrors": 0,
|
||||||
|
"secondStatus": "down",
|
||||||
|
"nativeCalls": 10
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"phase": "disabled-invalid-running",
|
||||||
|
"endpoint": "GRE authenticated catalog",
|
||||||
|
"status": 200,
|
||||||
|
"tunnels": 2,
|
||||||
|
"failures": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"phase": "disabled-invalid-running",
|
||||||
|
"flags": {
|
||||||
|
"disabled": "true",
|
||||||
|
"running": "junk"
|
||||||
|
},
|
||||||
|
"greWritten": 2,
|
||||||
|
"bgpWritten": 2,
|
||||||
|
"sourceErrors": 0,
|
||||||
|
"secondStatus": "down",
|
||||||
|
"nativeCalls": 10
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"phase": "recovery",
|
||||||
|
"endpoint": "GRE authenticated catalog",
|
||||||
|
"status": 200,
|
||||||
|
"tunnels": 2,
|
||||||
|
"failures": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"phase": "recovery",
|
||||||
|
"flags": {
|
||||||
|
"running": "true",
|
||||||
|
"disabled": "false"
|
||||||
|
},
|
||||||
|
"greWritten": 2,
|
||||||
|
"bgpWritten": 2,
|
||||||
|
"sourceErrors": 0,
|
||||||
|
"secondStatus": "up",
|
||||||
|
"nativeCalls": 10
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"scope": "Actual compiled GRE operational flags and actual snapshot collector, owned SQL/native HTTP fixture; signed reader/authenticated GRE API",
|
||||||
|
"passed": true,
|
||||||
|
"nativeWrites": 0,
|
||||||
|
"disabledHomeRouterCalls": 0,
|
||||||
|
"ownedDatabaseAndRoleRemoved": true
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
{
|
||||||
|
"date": "2026-10-14",
|
||||||
|
"block": "12.5.220",
|
||||||
|
"compiled": {
|
||||||
|
"matched": 1056,
|
||||||
|
"missing": 0,
|
||||||
|
"different": 0
|
||||||
|
},
|
||||||
|
"source": [
|
||||||
|
{
|
||||||
|
"kind": "backend",
|
||||||
|
"matched": 488
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"profileScripts": {
|
||||||
|
"liveMaps": 14,
|
||||||
|
"configSync": 6,
|
||||||
|
"greFlagCombinations": 49
|
||||||
|
},
|
||||||
|
"optionalDisabledSqlProfileSkipped": true,
|
||||||
|
"productionCases": 30,
|
||||||
|
"initialLocalFixtureFailure": "GRE IPv6 fixture omitted disabled; updated to explicit false, repeated configSync passed"
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
{
|
||||||
|
"date": "2026-10-14",
|
||||||
|
"block": "12.5.220",
|
||||||
|
"backendSourceMatched": 488,
|
||||||
|
"compiledMatched": 1056,
|
||||||
|
"frontendChanged": false,
|
||||||
|
"services": {
|
||||||
|
"backend": {
|
||||||
|
"image": "mmapp-test/backend:ux-gre220",
|
||||||
|
"imageId": "sha256:ccec71e8e2e1fd3a13e98be145cba26cdd2dc85409053e00e88d3ca81de5329d",
|
||||||
|
"running": true,
|
||||||
|
"health": "healthy"
|
||||||
|
},
|
||||||
|
"frontend": {
|
||||||
|
"image": "mmapp-test/frontend:ux-routing218",
|
||||||
|
"imageId": "sha256:ec658b9da88c19d60987be5bfc0c15fb339a0310d7a42dc761b40a70a3428c5a",
|
||||||
|
"running": true,
|
||||||
|
"health": null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,292 @@
|
|||||||
|
{
|
||||||
|
"date": "2026-10-14",
|
||||||
|
"block": "12.5.220",
|
||||||
|
"baseline": false,
|
||||||
|
"database": "mm_accept_166_1791916217951",
|
||||||
|
"cases": [
|
||||||
|
{
|
||||||
|
"phase": "up",
|
||||||
|
"endpoint": "GRE authenticated catalog",
|
||||||
|
"status": 200,
|
||||||
|
"tunnels": 2,
|
||||||
|
"failures": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"phase": "up",
|
||||||
|
"flags": {
|
||||||
|
"running": "true",
|
||||||
|
"disabled": "false"
|
||||||
|
},
|
||||||
|
"greWritten": 2,
|
||||||
|
"bgpWritten": 2,
|
||||||
|
"sourceErrors": 0,
|
||||||
|
"secondStatus": "up",
|
||||||
|
"nativeCalls": 10
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"phase": "degraded",
|
||||||
|
"endpoint": "GRE authenticated catalog",
|
||||||
|
"status": 200,
|
||||||
|
"tunnels": 2,
|
||||||
|
"failures": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"phase": "degraded",
|
||||||
|
"flags": {
|
||||||
|
"running": "false",
|
||||||
|
"disabled": "false"
|
||||||
|
},
|
||||||
|
"greWritten": 2,
|
||||||
|
"bgpWritten": 2,
|
||||||
|
"sourceErrors": 0,
|
||||||
|
"secondStatus": "degraded",
|
||||||
|
"nativeCalls": 10
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"phase": "down",
|
||||||
|
"endpoint": "GRE authenticated catalog",
|
||||||
|
"status": 200,
|
||||||
|
"tunnels": 2,
|
||||||
|
"failures": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"phase": "down",
|
||||||
|
"flags": {
|
||||||
|
"running": "false",
|
||||||
|
"disabled": "true"
|
||||||
|
},
|
||||||
|
"greWritten": 2,
|
||||||
|
"bgpWritten": 2,
|
||||||
|
"sourceErrors": 0,
|
||||||
|
"secondStatus": "down",
|
||||||
|
"nativeCalls": 10
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"phase": "yes-up",
|
||||||
|
"endpoint": "GRE authenticated catalog",
|
||||||
|
"status": 200,
|
||||||
|
"tunnels": 2,
|
||||||
|
"failures": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"phase": "yes-up",
|
||||||
|
"flags": {
|
||||||
|
"running": "yes",
|
||||||
|
"disabled": "no"
|
||||||
|
},
|
||||||
|
"greWritten": 2,
|
||||||
|
"bgpWritten": 2,
|
||||||
|
"sourceErrors": 0,
|
||||||
|
"secondStatus": "up",
|
||||||
|
"nativeCalls": 10
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"phase": "yes-degraded",
|
||||||
|
"endpoint": "GRE authenticated catalog",
|
||||||
|
"status": 200,
|
||||||
|
"tunnels": 2,
|
||||||
|
"failures": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"phase": "yes-degraded",
|
||||||
|
"flags": {
|
||||||
|
"running": "no",
|
||||||
|
"disabled": "no"
|
||||||
|
},
|
||||||
|
"greWritten": 2,
|
||||||
|
"bgpWritten": 2,
|
||||||
|
"sourceErrors": 0,
|
||||||
|
"secondStatus": "degraded",
|
||||||
|
"nativeCalls": 10
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"phase": "yes-down",
|
||||||
|
"endpoint": "GRE authenticated catalog",
|
||||||
|
"status": 200,
|
||||||
|
"tunnels": 2,
|
||||||
|
"failures": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"phase": "yes-down",
|
||||||
|
"flags": {
|
||||||
|
"running": "no",
|
||||||
|
"disabled": "yes"
|
||||||
|
},
|
||||||
|
"greWritten": 2,
|
||||||
|
"bgpWritten": 2,
|
||||||
|
"sourceErrors": 0,
|
||||||
|
"secondStatus": "down",
|
||||||
|
"nativeCalls": 10
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"phase": "missing-disabled",
|
||||||
|
"endpoint": "GRE authenticated catalog",
|
||||||
|
"status": 200,
|
||||||
|
"tunnels": 1,
|
||||||
|
"failures": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"phase": "missing-disabled",
|
||||||
|
"flags": {
|
||||||
|
"running": "true"
|
||||||
|
},
|
||||||
|
"greWritten": 0,
|
||||||
|
"bgpWritten": 2,
|
||||||
|
"sourceErrors": 1,
|
||||||
|
"secondStatus": null,
|
||||||
|
"nativeCalls": 10
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"phase": "missing-running",
|
||||||
|
"endpoint": "GRE authenticated catalog",
|
||||||
|
"status": 200,
|
||||||
|
"tunnels": 1,
|
||||||
|
"failures": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"phase": "missing-running",
|
||||||
|
"flags": {
|
||||||
|
"disabled": "false"
|
||||||
|
},
|
||||||
|
"greWritten": 0,
|
||||||
|
"bgpWritten": 2,
|
||||||
|
"sourceErrors": 1,
|
||||||
|
"secondStatus": null,
|
||||||
|
"nativeCalls": 10
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"phase": "blank-disabled",
|
||||||
|
"endpoint": "GRE authenticated catalog",
|
||||||
|
"status": 200,
|
||||||
|
"tunnels": 1,
|
||||||
|
"failures": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"phase": "blank-disabled",
|
||||||
|
"flags": {
|
||||||
|
"running": "true",
|
||||||
|
"disabled": ""
|
||||||
|
},
|
||||||
|
"greWritten": 0,
|
||||||
|
"bgpWritten": 2,
|
||||||
|
"sourceErrors": 1,
|
||||||
|
"secondStatus": null,
|
||||||
|
"nativeCalls": 10
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"phase": "invalid-running",
|
||||||
|
"endpoint": "GRE authenticated catalog",
|
||||||
|
"status": 200,
|
||||||
|
"tunnels": 1,
|
||||||
|
"failures": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"phase": "invalid-running",
|
||||||
|
"flags": {
|
||||||
|
"running": "junk",
|
||||||
|
"disabled": "false"
|
||||||
|
},
|
||||||
|
"greWritten": 0,
|
||||||
|
"bgpWritten": 2,
|
||||||
|
"sourceErrors": 1,
|
||||||
|
"secondStatus": null,
|
||||||
|
"nativeCalls": 10
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"phase": "invalid-disabled",
|
||||||
|
"endpoint": "GRE authenticated catalog",
|
||||||
|
"status": 200,
|
||||||
|
"tunnels": 1,
|
||||||
|
"failures": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"phase": "invalid-disabled",
|
||||||
|
"flags": {
|
||||||
|
"running": "true",
|
||||||
|
"disabled": "junk"
|
||||||
|
},
|
||||||
|
"greWritten": 0,
|
||||||
|
"bgpWritten": 2,
|
||||||
|
"sourceErrors": 1,
|
||||||
|
"secondStatus": null,
|
||||||
|
"nativeCalls": 10
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"phase": "both-missing",
|
||||||
|
"endpoint": "GRE authenticated catalog",
|
||||||
|
"status": 200,
|
||||||
|
"tunnels": 1,
|
||||||
|
"failures": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"phase": "both-missing",
|
||||||
|
"flags": {},
|
||||||
|
"greWritten": 0,
|
||||||
|
"bgpWritten": 2,
|
||||||
|
"sourceErrors": 1,
|
||||||
|
"secondStatus": null,
|
||||||
|
"nativeCalls": 10
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"phase": "disabled-missing-running",
|
||||||
|
"endpoint": "GRE authenticated catalog",
|
||||||
|
"status": 200,
|
||||||
|
"tunnels": 2,
|
||||||
|
"failures": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"phase": "disabled-missing-running",
|
||||||
|
"flags": {
|
||||||
|
"disabled": "true"
|
||||||
|
},
|
||||||
|
"greWritten": 2,
|
||||||
|
"bgpWritten": 2,
|
||||||
|
"sourceErrors": 0,
|
||||||
|
"secondStatus": "down",
|
||||||
|
"nativeCalls": 10
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"phase": "disabled-invalid-running",
|
||||||
|
"endpoint": "GRE authenticated catalog",
|
||||||
|
"status": 200,
|
||||||
|
"tunnels": 2,
|
||||||
|
"failures": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"phase": "disabled-invalid-running",
|
||||||
|
"flags": {
|
||||||
|
"disabled": "true",
|
||||||
|
"running": "junk"
|
||||||
|
},
|
||||||
|
"greWritten": 2,
|
||||||
|
"bgpWritten": 2,
|
||||||
|
"sourceErrors": 0,
|
||||||
|
"secondStatus": "down",
|
||||||
|
"nativeCalls": 10
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"phase": "recovery",
|
||||||
|
"endpoint": "GRE authenticated catalog",
|
||||||
|
"status": 200,
|
||||||
|
"tunnels": 2,
|
||||||
|
"failures": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"phase": "recovery",
|
||||||
|
"flags": {
|
||||||
|
"running": "true",
|
||||||
|
"disabled": "false"
|
||||||
|
},
|
||||||
|
"greWritten": 2,
|
||||||
|
"bgpWritten": 2,
|
||||||
|
"sourceErrors": 0,
|
||||||
|
"secondStatus": "up",
|
||||||
|
"nativeCalls": 10
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"scope": "Actual compiled GRE operational flags and actual snapshot collector, owned SQL/native HTTP fixture; signed reader/authenticated GRE API",
|
||||||
|
"passed": true,
|
||||||
|
"nativeWrites": 0,
|
||||||
|
"disabledHomeRouterCalls": 0,
|
||||||
|
"ownedDatabaseAndRoleRemoved": true
|
||||||
|
}
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
{
|
||||||
|
"date": "2026-10-14",
|
||||||
|
"block": "12.5.220",
|
||||||
|
"host": "104.165.244.7",
|
||||||
|
"status": 401,
|
||||||
|
"failedRequestPathNotRecorded": true,
|
||||||
|
"wholeLiveAttemptAborted": true,
|
||||||
|
"ownedGreCleanupReported": true,
|
||||||
|
"causeKnown": false,
|
||||||
|
"subsequentAccessCheck": {
|
||||||
|
"date": "2026-10-14",
|
||||||
|
"cases": [
|
||||||
|
{
|
||||||
|
"host": "194.226.121.150",
|
||||||
|
"path": "/system/resource",
|
||||||
|
"status": 200
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"host": "194.226.121.150",
|
||||||
|
"path": "/ip/address",
|
||||||
|
"status": 200
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"host": "194.226.121.150",
|
||||||
|
"path": "/interface/gre",
|
||||||
|
"status": 200
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"host": "104.165.244.7",
|
||||||
|
"path": "/system/resource",
|
||||||
|
"status": 200
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"host": "104.165.244.7",
|
||||||
|
"path": "/ip/address",
|
||||||
|
"status": 200
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"host": "104.165.244.7",
|
||||||
|
"path": "/interface/gre",
|
||||||
|
"status": 200
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"probeDifference": "Independent recheck uses Connection close; no causal claim",
|
||||||
|
"passwordsNotChanged": true
|
||||||
|
}
|
||||||
@@ -0,0 +1,100 @@
|
|||||||
|
{
|
||||||
|
"date": "2026-10-14",
|
||||||
|
"block": "12.5.220",
|
||||||
|
"backend": "ux-gre220",
|
||||||
|
"frontend": "ux-routing218",
|
||||||
|
"nativeCases": [
|
||||||
|
{
|
||||||
|
"host": "194.226.121.150",
|
||||||
|
"nativeGetStatus": 200,
|
||||||
|
"applicationStatus": "degraded",
|
||||||
|
"nativeDisabled": "false",
|
||||||
|
"nativeRunning": "false",
|
||||||
|
"nativeIdPresent": true,
|
||||||
|
"nativeNamePresent": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"host": "104.165.244.7",
|
||||||
|
"nativeGetStatus": 200,
|
||||||
|
"applicationStatus": "degraded",
|
||||||
|
"nativeDisabled": "false",
|
||||||
|
"nativeRunning": "false",
|
||||||
|
"nativeIdPresent": true,
|
||||||
|
"nativeNamePresent": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"source": {
|
||||||
|
"date": "2026-10-14",
|
||||||
|
"name": "own220-gre-1791916454934",
|
||||||
|
"passed": true,
|
||||||
|
"mode": "Actual compiled helper reads lab PostgreSQL/native enabled GRE and BGP; no scheduler history write",
|
||||||
|
"ownedGreRows": [
|
||||||
|
{
|
||||||
|
"targetLabel": "own220-gre-1791916454934-1 / CHR",
|
||||||
|
"status": "up"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"targetLabel": "own220-gre-1791916454934-2 / CHR",
|
||||||
|
"status": "up"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"sourceErrors": 0
|
||||||
|
},
|
||||||
|
"ui": [
|
||||||
|
{
|
||||||
|
"width": 1440,
|
||||||
|
"ownedNativeRowVisible": true,
|
||||||
|
"pageErrors": 0,
|
||||||
|
"mutationRequests": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"width": 320,
|
||||||
|
"ownedNativeRowVisible": true,
|
||||||
|
"pageErrors": 0,
|
||||||
|
"mutationRequests": 0
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"transitions": [
|
||||||
|
{
|
||||||
|
"phase": "both-up",
|
||||||
|
"nativeFlagsConfirmed": true,
|
||||||
|
"ping": [
|
||||||
|
{
|
||||||
|
"host": "194.226.121.150",
|
||||||
|
"received": 3
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"host": "104.165.244.7",
|
||||||
|
"received": 3
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"phase": "one-disabled-peer-degraded",
|
||||||
|
"nativeFlagsConfirmed": true,
|
||||||
|
"applicationStatuses": [
|
||||||
|
"down",
|
||||||
|
"degraded"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"phase": "recovered-up",
|
||||||
|
"nativeFlagsConfirmed": true,
|
||||||
|
"ping": [
|
||||||
|
{
|
||||||
|
"host": "194.226.121.150",
|
||||||
|
"received": 3
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"host": "104.165.244.7",
|
||||||
|
"received": 3
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"realPortalJWT": true,
|
||||||
|
"apiMocks": false,
|
||||||
|
"cleanupCompleted": true,
|
||||||
|
"scope": "Actual compiled collector and API read confirmed GRE flags; controlled peer disable/recovery and short IPv4 Ping; no physical WAN loss/SLA or durable snapshot write",
|
||||||
|
"passwordsUnchanged": true
|
||||||
|
}
|
||||||
Reference in new issue
Block a user