A panel without VPN (e.g. after the move) can use a Prometheus that lives on a node, such as the one with history left on the old server (node #0). Both directions go through the agent's WSS: the node's Prometheus scrapes 127.0.0.1:AGENT_METRICS_PORT/metrics, the agent checks its token and asks core (metrics → metrics_res, the same exposition as /metrics, at most once per 5 s per connection); the monitor tab reads it back through the agent, which forwards only GET /-/ready and /api/v1/query[_range]. The panel finds it by itself (local first, then the lowest-id node), and the install/remove buttons work on a panel without VPN. `monitor install` on a node without its own panel picks AGENT_METRICS_PORT, writes it to cli.env and restarts the agent; on the old server it keeps the collected data. The panel works behind nginx in a subfolder: relative asset and API paths, relative directory redirects, and the client address from X-Forwarded-For / X-Real-IP only from trusted proxies (loopback, TRUST_PROXY). migrate import opens the moved SUB_PORT/NODE_PORT in UFW when it is active.
42 lines
1.4 KiB
Go
42 lines
1.4 KiB
Go
package migrate
|
|
|
|
import (
|
|
"os/exec"
|
|
"strconv"
|
|
"strings"
|
|
)
|
|
|
|
// ufw — вызов ufw (в тестах подменяется). Нет ufw — ошибка, и правила не трогаются.
|
|
var ufw = func(args ...string) ([]byte, error) {
|
|
if _, err := exec.LookPath("ufw"); err != nil {
|
|
return nil, err
|
|
}
|
|
return exec.Command("ufw", args...).CombinedOutput()
|
|
}
|
|
|
|
// OpenFirewall — открыть в UFW порты, на которые панель переезжает при приёме: подписка и хаб
|
|
// берут порты старого сервера, а install.sh открыл только те, что были при установке. Без этого
|
|
// нода #0 не дозвонится до хаба, а ретранслятор — до подписки. UFW не установлен или не активен —
|
|
// ничего не делаем (как install.sh). opened — что открыто, failed — что не удалось.
|
|
func OpenFirewall(ports ...int) (opened, failed []string) {
|
|
out, err := ufw("status")
|
|
if err != nil || !strings.Contains(strings.ToLower(string(out)), "status: active") {
|
|
return nil, nil
|
|
}
|
|
for _, p := range ports {
|
|
if p <= 0 {
|
|
continue
|
|
}
|
|
rule := strconv.Itoa(p) + "/tcp"
|
|
if _, err := ufw("allow", rule); err != nil {
|
|
failed = append(failed, rule)
|
|
} else {
|
|
opened = append(opened, rule)
|
|
}
|
|
}
|
|
if len(opened) > 0 {
|
|
ufw("reload")
|
|
}
|
|
return opened, failed
|
|
}
|