Files
elmprodvpn/selective-vpn-api/app/transport_singbox_profiles_flow_apply_exec.go

91 lines
2.7 KiB
Go

package app
import (
"net/http"
"time"
)
func executeTransportSingBoxProfileApplyLocked(
id string,
body SingBoxProfileApplyRequest,
checkBinary bool,
restart bool,
) (int, SingBoxProfileApplyResponse) {
st := loadSingBoxProfilesState()
idx := findSingBoxProfileIndex(st.Items, id)
if idx < 0 {
return http.StatusNotFound, SingBoxProfileApplyResponse{
OK: false,
Code: singBoxProfileCodeNotFound,
Message: "not found",
}
}
cur := st.Items[idx]
if body.BaseRevision > 0 && body.BaseRevision != cur.ProfileRevision {
return http.StatusConflict, SingBoxProfileApplyResponse{
OK: false,
Code: singBoxProfileCodeRevisionMismatch,
Message: "base_revision mismatch",
ProfileID: cur.ID,
ProfileRevision: cur.ProfileRevision,
RenderRevision: cur.RenderRevision,
}
}
eval := evaluateSingBoxProfile(cur, checkBinary)
now := time.Now().UTC().Format(time.RFC3339Nano)
if !eval.Valid {
cur.LastValidatedAt = now
cur.LastError = joinSingBoxIssueMessages(eval.Errors)
cur.UpdatedAt = now
st.Items[idx] = cur
_ = saveSingBoxProfilesState(st)
_ = appendSingBoxHistory(singBoxProfileHistoryRecord{
At: now,
ProfileID: cur.ID,
Action: "apply",
Status: "failed",
Code: singBoxProfileCodeValidationFailed,
Message: "apply blocked by validation errors",
ProfileRevision: cur.ProfileRevision,
RenderRevision: cur.RenderRevision,
Errors: eval.Errors,
Warnings: eval.Warnings,
Diff: eval.Diff,
})
events.push("singbox_profile_failed", map[string]any{
"id": cur.ID,
"step": "apply-validate",
})
return http.StatusOK, SingBoxProfileApplyResponse{
OK: false,
Message: "apply blocked by validation errors",
Code: singBoxProfileCodeValidationFailed,
ProfileID: cur.ID,
ProfileRevision: cur.ProfileRevision,
RenderRevision: cur.RenderRevision,
Valid: false,
Errors: eval.Errors,
Warnings: eval.Warnings,
Diff: eval.Diff,
}
}
renderPath, err := writeSingBoxRenderedConfig(cur.ID, eval.Config)
if err != nil {
return http.StatusInternalServerError, SingBoxProfileApplyResponse{
OK: false,
Code: singBoxProfileCodeRenderFailed,
Message: "write rendered config failed: " + err.Error(),
ProfileID: cur.ID,
ProfileRevision: cur.ProfileRevision,
RenderRevision: cur.RenderRevision,
Valid: true,
Warnings: eval.Warnings,
Diff: eval.Diff,
}
}
return executeTransportSingBoxProfileApplyRenderedLocked(st, idx, cur, body, eval, now, renderPath, restart)
}