{{define "ips_page"}} {{template "html_head" .}}
{{template "sidebar_nav" .}}
{{template "topbar_mobile" .}}
{{template "banner_inner" .Banner}}
{{template "ips_content" .}}
{{end}} {{define "ips_content"}}

Очередь IP

Новый адрес встаёт в очередь; уже завершённый (done/failed) запускается заново (тот же вызов); тот, что сейчас проверяется, не трогается. Кнопка «Сканировать Floating IP» ниже делает то же самое автоматически: находит в проекте OpenStack все свободные (не привязанные к порту) Floating IP и сразу передаёт их в очередь на проверку — сканирование идёт в фоне, прогресс виден в панели под кнопкой. Полная история проверок по каждому адресу — включая уже удалённые из очереди — доступна в реестре.

{{template "scan_progress" .Scan}}
{{template "ips_table_wrap" .}} {{end}} {{/* #ips-table-wrap is the swap target of every table mutation, the filter form and the pager (all hx-swap="outerHTML", so the wrapper's own hx-get always points at the page/filter it currently shows). It listens for the scan-finished event (HX-Trigger from the scan progress panel) and reloads itself. hx-disinherit="*": its attributes must not leak into the buttons inside. */}} {{define "ips_table_wrap"}}
{{template "ips_table" .}}
{{end}} {{/* Scan progress panel. Lives outside #ips-form (no checkbox payload, survives table swaps). While the job runs it polls itself; the response that finds it finished has no hx-trigger and carries HX-Trigger: scan-finished. */}} {{define "scan_progress"}} {{$s := .Status}}
{{if and $s.State (ne $s.State "idle")}}{{$s.StateLabel}}{{if $s.DryRun}} пробный запуск: очередь не меняется{{end}}{{else}}Найти все свободные Floating IP проекта и поставить их в очередь.{{end}}
{{if and $s.State (ne $s.State "idle")}} {{if or $s.Running (eq $s.State "done")}} {{if $s.Indeterminate}} {{else if eq $s.State "done"}} {{else}}{{end}} {{end}}
прочитано страниц
{{$s.Pages}}
найдено адресов
{{$s.Discovered}}
свободных
{{$s.Free}}
добавлено
{{$s.Added}}
повторно
{{$s.Requeued}}
переупорядочено
{{$s.Reordered}}
{{if $s.SkippedInProgress}}
уже в работе
{{$s.SkippedInProgress}}
{{end}} {{with $s.Elapsed}}
время
{{.}}
{{end}}
{{if $s.Error}}

{{$s.Error}}

{{end}} {{end}}
{{end}} {{define "ips_table"}}
Выбрано на странице: 0 из {{len .Items}} {{if gt .Total (len .Items)}}Выбрать все {{.Total}} по фильтру Выбраны все {{.Total}} {{pluralAddr .Total}} по фильтру (не только на этой странице).{{end}}
{{range .Items}} {{$b := ipBadge .State .OverallResult .FIPAssociatedAt $.FIPSettleSeconds}} {{$terminal := or (eq .State "done") (eq .State "failed") (eq .State "occupied")}} {{end}}
АдресСостояниеВалидаторПопыткаОбновлено
{{.IPAddress}} {{$b.Label}} {{deref .OwnerValidatorID}} {{.AttemptNumber}} {{fmtTime .UpdatedAt}}
{{if $terminal}} {{else}} {{end}}
{{template "pager" .Pager}}
{{if not .Items}}

{{if .Filter.Active}}Ничего не найдено по текущему фильтру.{{else}}Очередь пуста.{{end}}

{{end}} {{end}} {{define "pager"}}{{if .Total}}
Показано {{.From}}–{{.To}} из {{.Total}} {{if .PrevURL}}{{else}}‹{{end}} {{.Page}} / {{.Pages}} {{if .NextURL}}{{else}}›{{end}}
{{end}}{{end}}