mirror of
https://github.com/taylanbakircioglu/haproxy-openmanager.git
synced 2026-09-16 23:55:13 +00:00
a1192e602d
Manage highly-available virtual IPs backed by Keepalived (VRRP) directly from the OpenManager
UI — no more SSHing into nodes to install/configure Keepalived by hand. Builds on the agent
pull-architecture: define the VIP centrally, click Apply, and the agents converge.
Highlights:
- New "HA / VIP" tab: create a virtual IP, pick a per-node interface, select which pool nodes
participate (MASTER/BACKUP roles + priorities); live MASTER/BACKUP/FAULT per node.
- On Apply, agents install & configure Keepalived (unicast VRRP, cloud-safe default) across the
major distros (Debian/Ubuntu, RHEL/CentOS/Alma/Rocky, Fedora, SUSE/openSUSE, Alpine) with a
HAProxy health-check, so the VIP fails over automatically when HAProxy drops.
- Single-node (a managed floating IP without failover) and multi-node VRRP failover both work.
- VIP changes ride the standard Apply Management flow with the standard "View Change" diff.
- Approval-gated deletion (safety): deleting a running VIP is staged for approval and the VIP
keeps running, untouched, until you approve it — an agent never tears a VIP down without an
explicit human approval. Per-VIP Diagnostics view; opt-in package uninstall (only on nodes
where OpenManager installed it). A node already running a hand-managed Keepalived is detected
and never overwritten ("externally managed").
- Fully opt-in and backward compatible: nodes/clusters without a VIP are unaffected. Adds
vip_instances + vip_members tables (idempotent SCHEMA_VERSION bump; existing data and
passwords unaffected) and a `vip` RBAC permission group.
- Also includes a HAProxy config-generator robustness fix: auto-inject a stick-table when a
frontend uses a stick counter (track-sc / sc_*_rate) but declares none.
On-prem / L2 (VRRP) scope; the UI notes the cloud caveat.
35 lines
1.6 KiB
Python
35 lines
1.6 KiB
Python
"""v1.7.5 — guard for the HA/VIP "View Change" diff.
|
|
|
|
Editing a VIP (e.g. priority + virtual IP) must show a REAL line diff (only the changed lines)
|
|
against the previous applied vip-* config — not the whole keepalived.conf marked as "added", and
|
|
without the doubled "+ +" prefix (the line must be stored WITHOUT a +/- prefix; the UI adds it
|
|
from `type`, exactly like the standard haproxy diff). Pure source guard (the behavioural diff
|
|
test needs a DB); locks the wiring so it can't regress."""
|
|
from __future__ import annotations
|
|
|
|
import os
|
|
|
|
ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
|
|
|
|
|
def _cluster_src() -> str:
|
|
with open(os.path.join(ROOT, "routers", "cluster.py"), encoding="utf-8") as f:
|
|
return f.read()
|
|
|
|
|
|
def test_vip_diff_uses_real_difflib_against_previous_applied():
|
|
s = _cluster_src()
|
|
# The previous APPLIED vip-* config for this VIP is fetched as the diff baseline.
|
|
assert "AND status='APPLIED' AND cluster_id=$2 AND id < $3 ORDER BY id DESC LIMIT 1" in s
|
|
# And the diff is a real unified_diff of old vs new (not "everything added").
|
|
assert "difflib.unified_diff(old_content.split('\\n'), new_content.split('\\n')" in s
|
|
|
|
|
|
def test_vip_diff_stores_lines_without_prefix():
|
|
s = _cluster_src()
|
|
# The old vip bug prepended "+ {line}", doubling the UI prefix ("+ +"). The vip diff now
|
|
# stores the stripped diff line (dl[1:]) — the UI adds the +/- from `type`. `dl` is unique
|
|
# to the vip branch (the standard haproxy diff uses `line`), so this targets the vip fix
|
|
# only and does not touch the (separate, out-of-scope) SSL diff branch.
|
|
assert '"line": dl[1:], "line_number": line_number' in s
|