v1.1.44: 5 fixes — null-guard + try/catch in toggleInstance/selectService/refreshInstances/CMDB
This commit is contained in:
@@ -0,0 +1,19 @@
|
|||||||
|
# Sonnet 4.6 — Финальный аудит
|
||||||
|
|
||||||
|
Дата: 2026-07-30
|
||||||
|
|
||||||
|
## 5 багов в app.js
|
||||||
|
|
||||||
|
| # | Баг | Строка |
|
||||||
|
|---|-----|--------|
|
||||||
|
| 🔴1 | `d.operations.filter` без null-guard | toggleInstance |
|
||||||
|
| 🔴2 | toggleInstance без try/catch | toggleInstance |
|
||||||
|
| 🔴3 | selectService без try/catch | selectService |
|
||||||
|
| 🔴4 | refreshInstances без try/catch | refreshInstances |
|
||||||
|
| 🟡5 | CMDB OK + refreshInstances → ошибка перезаписывает успех | executeOp |
|
||||||
|
|
||||||
|
## redeploy без _send_params_terraform
|
||||||
|
Намеренно — redeploy переиспользует текущие params из state.
|
||||||
|
|
||||||
|
## Бэкенд чист
|
||||||
|
api_test.py, main.py, get_params.py, http_client.py — багов нет.
|
||||||
+1
-1
@@ -18,7 +18,7 @@ from routes.api import bp as api_bp
|
|||||||
from routes.api_test import bp as api_test_bp
|
from routes.api_test import bp as api_test_bp
|
||||||
|
|
||||||
# Версия — меняется при КАЖДОМ изменении кода. Показывается в топбаре UI.
|
# Версия — меняется при КАЖДОМ изменении кода. Показывается в топбаре UI.
|
||||||
VERSION = "1.1.43"
|
VERSION = "1.1.44"
|
||||||
|
|
||||||
app = Flask(__name__, template_folder="templates", static_folder="static")
|
app = Flask(__name__, template_folder="templates", static_folder="static")
|
||||||
app.config["NUBES_API_ENDPOINT"] = os.getenv("NUBES_API_ENDPOINT", "https://lk-api-gateway-test.ngcloud.ru/api/v1/svc")
|
app.config["NUBES_API_ENDPOINT"] = os.getenv("NUBES_API_ENDPOINT", "https://lk-api-gateway-test.ngcloud.ru/api/v1/svc")
|
||||||
|
|||||||
+9
-3
@@ -46,6 +46,7 @@ async function selectService(svcId){
|
|||||||
const svcEl=document.querySelector(`.svc-item[onclick*="${svcId}"]`);
|
const svcEl=document.querySelector(`.svc-item[onclick*="${svcId}"]`);
|
||||||
if(svcEl) svcEl.classList.add('active');
|
if(svcEl) svcEl.classList.add('active');
|
||||||
|
|
||||||
|
try{
|
||||||
const r=await fetch('/api/operations/'+svcId);
|
const r=await fetch('/api/operations/'+svcId);
|
||||||
const d=await r.json();
|
const d=await r.json();
|
||||||
svcInstances=d.instances||[];
|
svcInstances=d.instances||[];
|
||||||
@@ -67,6 +68,7 @@ async function selectService(svcId){
|
|||||||
html+=`<div class="inst-ops" id="ops-${i.instanceUid}"></div>`;
|
html+=`<div class="inst-ops" id="ops-${i.instanceUid}"></div>`;
|
||||||
});
|
});
|
||||||
document.getElementById('inst-list').innerHTML=html;
|
document.getElementById('inst-list').innerHTML=html;
|
||||||
|
}catch(e){document.getElementById('inst-list').innerHTML='<span style="color:var(--destructive);font-size:11px;">Ошибка загрузки</span>';}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function toggleInstance(iuid){
|
async function toggleInstance(iuid){
|
||||||
@@ -81,9 +83,10 @@ async function toggleInstance(iuid){
|
|||||||
// Операции для ИНСТАНСА, не для выбранного сервиса
|
// Операции для ИНСТАНСА, не для выбранного сервиса
|
||||||
const inst=svcInstances.find(x=>x.instanceUid===iuid);
|
const inst=svcInstances.find(x=>x.instanceUid===iuid);
|
||||||
const svcId=inst?inst.serviceId:currentSvcId;
|
const svcId=inst?inst.serviceId:currentSvcId;
|
||||||
|
try{
|
||||||
const r=await fetch('/api/operations/'+svcId);
|
const r=await fetch('/api/operations/'+svcId);
|
||||||
const d=await r.json();
|
const d=await r.json();
|
||||||
let ops=d.operations.filter(o=>o.operation!=='reconcile'&&o.operation!=='create');
|
let ops=(d.operations||[]).filter(o=>o.operation!=='reconcile'&&o.operation!=='create');
|
||||||
if(inst&&(inst.status||inst.explainedStatus)==='not created'){
|
if(inst&&(inst.status||inst.explainedStatus)==='not created'){
|
||||||
ops=ops.filter(o=>o.operation==='delete');
|
ops=ops.filter(o=>o.operation==='delete');
|
||||||
}
|
}
|
||||||
@@ -91,6 +94,7 @@ async function toggleInstance(iuid){
|
|||||||
`<button class="btn btn-sm op-btn ${opClass(o.operation)}" onclick="runOp('${o.operation}',${o.svcOperationId})">${o.operation}</button>`
|
`<button class="btn btn-sm op-btn ${opClass(o.operation)}" onclick="runOp('${o.operation}',${o.svcOperationId})">${o.operation}</button>`
|
||||||
).join('');
|
).join('');
|
||||||
opsEl.classList.add('open');
|
opsEl.classList.add('open');
|
||||||
|
}catch(e){opsEl.innerHTML='<span style="color:var(--destructive);font-size:11px;">Ошибка загрузки</span>';opsEl.classList.add('open');}
|
||||||
}
|
}
|
||||||
|
|
||||||
function opClass(opName){
|
function opClass(opName){
|
||||||
@@ -338,8 +342,8 @@ async function executeOp(params){
|
|||||||
if(d.status==='OK'&&(d.opUid||'').startsWith('cmdb-')){
|
if(d.status==='OK'&&(d.opUid||'').startsWith('cmdb-')){
|
||||||
busy=false;
|
busy=false;
|
||||||
setFinishedState('OK','badge-success','',0,d.displayName);
|
setFinishedState('OK','badge-success','',0,d.displayName);
|
||||||
await refreshInstances();
|
try{await refreshInstances();}catch(e){}
|
||||||
if(historyOpen) await loadHistory();
|
if(historyOpen) try{await loadHistory();}catch(e){}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// start polling
|
// start polling
|
||||||
@@ -390,6 +394,7 @@ function stopPoll(){
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function refreshInstances(){
|
async function refreshInstances(){
|
||||||
|
try{
|
||||||
const r=await fetch('/api/operations/'+currentSvcId);
|
const r=await fetch('/api/operations/'+currentSvcId);
|
||||||
const d=await r.json();
|
const d=await r.json();
|
||||||
const newInsts=d.instances||[];
|
const newInsts=d.instances||[];
|
||||||
@@ -406,6 +411,7 @@ async function refreshInstances(){
|
|||||||
html+=`<div class="inst-ops" id="ops-${i.instanceUid}"></div>`;
|
html+=`<div class="inst-ops" id="ops-${i.instanceUid}"></div>`;
|
||||||
});
|
});
|
||||||
document.getElementById('inst-list').innerHTML=html;
|
document.getElementById('inst-list').innerHTML=html;
|
||||||
|
}catch(e){}
|
||||||
}
|
}
|
||||||
|
|
||||||
// === История тестов ===
|
// === История тестов ===
|
||||||
|
|||||||
Reference in New Issue
Block a user