feat(agent): add durable existing-agent credential transitions
This commit is contained in:
1 parent
abf5654a25
commit
3cfb0d1abe
33 files changed
+3828
-54
No files matched your search
+236
@@ -0,0 +1,236 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
repo_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||
cd "${repo_root}"
|
||||
project_name="${MINEROPS_LEGACY_ROUTING_PROJECT:-minerops-legacy-routing-$$}"
|
||||
compose=(docker compose --project-name "${project_name}" --env-file .env.dev -f compose.dev.yaml)
|
||||
|
||||
cleanup() {
|
||||
status=$?
|
||||
if (( status != 0 )); then
|
||||
"${compose[@]}" logs --no-color --tail 160 postgres || true
|
||||
fi
|
||||
"${compose[@]}" down --volumes --remove-orphans >/dev/null 2>&1 || true
|
||||
exit "${status}"
|
||||
}
|
||||
trap cleanup EXIT
|
||||
|
||||
run_db_alembic() {
|
||||
local database="$1"
|
||||
shift
|
||||
"${compose[@]}" run --rm --no-deps -e POSTGRES_DB="${database}" backend alembic "$@"
|
||||
}
|
||||
psql_named() {
|
||||
local database="$1"
|
||||
shift
|
||||
"${compose[@]}" exec -T postgres sh -ec \
|
||||
'database="$1"; shift; exec psql -v ON_ERROR_STOP=1 -U "$POSTGRES_USER" -d "$database" "$@"' \
|
||||
sh "${database}" "$@"
|
||||
}
|
||||
create_database() {
|
||||
"${compose[@]}" exec -T postgres sh -ec \
|
||||
'exec createdb -U "$POSTGRES_USER" "$1"' sh "$1"
|
||||
}
|
||||
|
||||
[[ -f .env.dev ]] || { echo "Missing .env.dev" >&2; exit 1; }
|
||||
"${compose[@]}" up --detach postgres
|
||||
for attempt in $(seq 1 60); do
|
||||
"${compose[@]}" exec -T postgres sh -ec \
|
||||
'pg_isready -U "$POSTGRES_USER" -d "$POSTGRES_DB"' >/dev/null 2>&1 && break
|
||||
(( attempt < 60 )) || { echo "PostgreSQL did not become ready" >&2; exit 1; }
|
||||
sleep 1
|
||||
done
|
||||
"${compose[@]}" build backend
|
||||
expected_revision="0018_legacy_agent_routing"
|
||||
|
||||
echo "Testing the real single-Site production shape from 0014 -> 0018..."
|
||||
create_database legacy_routing_happy
|
||||
run_db_alembic legacy_routing_happy upgrade 0014_repair_parts_tracking
|
||||
psql_named legacy_routing_happy <<'SQL'
|
||||
DELETE FROM sites;
|
||||
INSERT INTO sites (id, name)
|
||||
VALUES (
|
||||
'191e6d8f-ce40-4488-a8f1-ad6ce1790266',
|
||||
'Plexus Mining Site'
|
||||
);
|
||||
INSERT INTO miners (id, site_id, asset_tag, first_seen_at, last_seen_at, current_mac)
|
||||
VALUES (
|
||||
'00000000-0000-4000-8000-000000001811',
|
||||
'191e6d8f-ce40-4488-a8f1-ad6ce1790266',
|
||||
'LEGACY-ROUTING-MINER', NULL, NULL, '02:00:00:00:18:11'
|
||||
);
|
||||
INSERT INTO minerops_site_agents (agent_id, site_name)
|
||||
VALUES ('plexus-windows-agent', 'Plexus');
|
||||
INSERT INTO minerops_agent_snapshots (agent_id, site_name, miner_count, payload)
|
||||
VALUES ('plexus-windows-agent', 'Plexus', 1, '{}');
|
||||
INSERT INTO minerops_agent_discoveries (
|
||||
id, agent_id, site_name, ip_address, raw_payload, discovery_status
|
||||
) VALUES (
|
||||
'legacy-routing-discovery', 'plexus-windows-agent', 'Plexus',
|
||||
'192.0.2.181', '{}', 'new'
|
||||
);
|
||||
SQL
|
||||
run_db_alembic legacy_routing_happy upgrade "${expected_revision}"
|
||||
[[ "$(psql_named legacy_routing_happy -Atc 'SELECT version_num FROM alembic_version')" == "${expected_revision}" ]]
|
||||
psql_named legacy_routing_happy <<'SQL'
|
||||
DO $$
|
||||
DECLARE
|
||||
expected_site uuid := '191e6d8f-ce40-4488-a8f1-ad6ce1790266';
|
||||
expected_zone uuid;
|
||||
BEGIN
|
||||
SELECT id INTO expected_zone FROM agent_zones
|
||||
WHERE site_id = expected_site AND lower(name) = 'default zone' AND is_enabled;
|
||||
IF expected_zone IS NULL THEN
|
||||
RAISE EXCEPTION 'Expected enabled Default Zone is missing';
|
||||
END IF;
|
||||
IF (SELECT site_id FROM minerops_site_agents
|
||||
WHERE agent_id = 'plexus-windows-agent')
|
||||
IS DISTINCT FROM expected_site THEN
|
||||
RAISE EXCEPTION 'Sole-Site legacy Agent resolution failed';
|
||||
END IF;
|
||||
IF (SELECT agent_zone_id FROM minerops_site_agents
|
||||
WHERE agent_id = 'plexus-windows-agent')
|
||||
IS DISTINCT FROM expected_zone THEN
|
||||
RAISE EXCEPTION 'Legacy Agent Zone routing failed';
|
||||
END IF;
|
||||
IF (SELECT agent_zone_id FROM miners
|
||||
WHERE id = '00000000-0000-4000-8000-000000001811')
|
||||
IS DISTINCT FROM expected_zone THEN
|
||||
RAISE EXCEPTION 'Existing miner ownership was not preserved in its Site default Zone';
|
||||
END IF;
|
||||
IF (SELECT current_mac FROM miners
|
||||
WHERE id = '00000000-0000-4000-8000-000000001811')
|
||||
IS DISTINCT FROM '02:00:00:00:18:11' THEN
|
||||
RAISE EXCEPTION 'Miner identity/history projection was rewritten';
|
||||
END IF;
|
||||
IF EXISTS (
|
||||
SELECT 1 FROM minerops_agent_snapshots
|
||||
WHERE agent_id = 'plexus-windows-agent'
|
||||
AND agent_zone_id IS DISTINCT FROM expected_zone
|
||||
) THEN
|
||||
RAISE EXCEPTION 'Legacy snapshots were not attributed to the Agent Zone';
|
||||
END IF;
|
||||
IF EXISTS (
|
||||
SELECT 1 FROM minerops_agent_discoveries
|
||||
WHERE agent_id = 'plexus-windows-agent'
|
||||
AND agent_zone_id IS DISTINCT FROM expected_zone
|
||||
) THEN
|
||||
RAISE EXCEPTION 'Legacy discoveries were not attributed to the Agent Zone';
|
||||
END IF;
|
||||
END $$;
|
||||
SQL
|
||||
|
||||
echo "Testing unmatched multi-Site data fails closed before routing writes..."
|
||||
create_database legacy_routing_missing
|
||||
run_db_alembic legacy_routing_missing upgrade 0014_repair_parts_tracking
|
||||
psql_named legacy_routing_missing <<'SQL'
|
||||
DELETE FROM sites;
|
||||
INSERT INTO sites (id, name) VALUES
|
||||
('00000000-0000-4000-8000-000000001801', 'Candidate Site A'),
|
||||
('00000000-0000-4000-8000-000000001802', 'Candidate Site B');
|
||||
SQL
|
||||
psql_named legacy_routing_missing -c \
|
||||
"INSERT INTO minerops_site_agents (agent_id, site_name) VALUES ('missing-agent', 'No Such Site')"
|
||||
run_db_alembic legacy_routing_missing upgrade 0017_agent_enrollment
|
||||
if output="$(run_db_alembic legacy_routing_missing upgrade "${expected_revision}" 2>&1)"; then
|
||||
echo "Missing Site match unexpectedly passed" >&2
|
||||
exit 1
|
||||
fi
|
||||
[[ "${output}" == *"unmatched multi-Site installations fail closed"* ]]
|
||||
[[ "${output}" == *"missing-agent"* && "${output}" == *"/'0'/'2'"* ]]
|
||||
[[ "$(psql_named legacy_routing_missing -Atc 'SELECT version_num FROM alembic_version')" == "0017_agent_enrollment" ]]
|
||||
[[ "$(psql_named legacy_routing_missing -Atc "SELECT site_id IS NULL FROM minerops_site_agents WHERE agent_id='missing-agent'")" == "t" ]]
|
||||
[[ "$(psql_named legacy_routing_missing -Atc "SELECT agent_zone_id IS NULL FROM minerops_site_agents WHERE agent_id='missing-agent'")" == "t" ]]
|
||||
|
||||
echo "Testing ambiguous normalized Site match fails closed..."
|
||||
create_database legacy_routing_ambiguous
|
||||
run_db_alembic legacy_routing_ambiguous upgrade 0014_repair_parts_tracking
|
||||
psql_named legacy_routing_ambiguous <<'SQL'
|
||||
DELETE FROM sites;
|
||||
INSERT INTO sites (id, name) VALUES
|
||||
('00000000-0000-4000-8000-000000001821', 'Ambiguous Site'),
|
||||
('00000000-0000-4000-8000-000000001822', 'ambiguous site');
|
||||
INSERT INTO minerops_site_agents (agent_id, site_name)
|
||||
VALUES ('ambiguous-agent', ' AMBIGUOUS SITE ');
|
||||
SQL
|
||||
run_db_alembic legacy_routing_ambiguous upgrade 0017_agent_enrollment
|
||||
if output="$(run_db_alembic legacy_routing_ambiguous upgrade "${expected_revision}" 2>&1)"; then
|
||||
echo "Ambiguous Site match unexpectedly passed" >&2
|
||||
exit 1
|
||||
fi
|
||||
[[ "${output}" == *"ambiguous-agent"* && "${output}" == *"/'2'"* ]]
|
||||
[[ "$(psql_named legacy_routing_ambiguous -Atc 'SELECT version_num FROM alembic_version')" == "0017_agent_enrollment" ]]
|
||||
[[ "$(psql_named legacy_routing_ambiguous -Atc "SELECT site_id IS NULL AND agent_zone_id IS NULL FROM minerops_site_agents WHERE agent_id='ambiguous-agent'")" == "t" ]]
|
||||
|
||||
echo "Testing an exact normalized match wins in a multi-Site database..."
|
||||
create_database legacy_routing_exact_multi
|
||||
run_db_alembic legacy_routing_exact_multi upgrade 0014_repair_parts_tracking
|
||||
psql_named legacy_routing_exact_multi <<'SQL'
|
||||
DELETE FROM sites;
|
||||
INSERT INTO sites (id, name) VALUES
|
||||
('00000000-0000-4000-8000-000000001825', 'Exact Site'),
|
||||
('00000000-0000-4000-8000-000000001826', 'Unrelated Site');
|
||||
INSERT INTO minerops_site_agents (agent_id, site_name)
|
||||
VALUES ('exact-multi-agent', ' eXaCt SiTe ');
|
||||
SQL
|
||||
run_db_alembic legacy_routing_exact_multi upgrade 0017_agent_enrollment
|
||||
run_db_alembic legacy_routing_exact_multi upgrade "${expected_revision}"
|
||||
[[ "$(psql_named legacy_routing_exact_multi -Atc "SELECT site_id FROM minerops_site_agents WHERE agent_id='exact-multi-agent'")" == "00000000-0000-4000-8000-000000001825" ]]
|
||||
[[ "$(psql_named legacy_routing_exact_multi -Atc "SELECT agent.agent_zone_id = zone.id FROM minerops_site_agents AS agent JOIN agent_zones AS zone ON zone.site_id=agent.site_id AND zone.name='Default Zone' WHERE agent.agent_id='exact-multi-agent'")" == "t" ]]
|
||||
|
||||
echo "Testing two legacy Agents targeting one Default Zone fails closed..."
|
||||
create_database legacy_routing_conflict
|
||||
run_db_alembic legacy_routing_conflict upgrade 0014_repair_parts_tracking
|
||||
psql_named legacy_routing_conflict <<'SQL'
|
||||
DELETE FROM sites;
|
||||
INSERT INTO sites (id, name)
|
||||
VALUES ('00000000-0000-4000-8000-000000001831', 'Sole Durable Site');
|
||||
INSERT INTO minerops_site_agents (agent_id, site_name) VALUES
|
||||
('conflict-agent-a', 'Legacy Display A'),
|
||||
('conflict-agent-b', 'Legacy Display B');
|
||||
SQL
|
||||
run_db_alembic legacy_routing_conflict upgrade 0017_agent_enrollment
|
||||
if output="$(run_db_alembic legacy_routing_conflict upgrade "${expected_revision}" 2>&1)"; then
|
||||
echo "One-Agent-per-Zone conflict unexpectedly passed" >&2
|
||||
exit 1
|
||||
fi
|
||||
[[ "${output}" == *"one-Agent-per-Zone would be violated"* ]]
|
||||
[[ "$(psql_named legacy_routing_conflict -Atc 'SELECT version_num FROM alembic_version')" == "0017_agent_enrollment" ]]
|
||||
[[ "$(psql_named legacy_routing_conflict -Atc 'SELECT count(*) FROM minerops_site_agents WHERE site_id IS NOT NULL')" == "0" ]]
|
||||
[[ "$(psql_named legacy_routing_conflict -Atc 'SELECT count(*) FROM minerops_site_agents WHERE agent_zone_id IS NOT NULL')" == "0" ]]
|
||||
|
||||
echo "Testing explicit Site and Zone assignments win..."
|
||||
create_database legacy_routing_explicit
|
||||
run_db_alembic legacy_routing_explicit upgrade 0017_agent_enrollment
|
||||
psql_named legacy_routing_explicit <<'SQL'
|
||||
INSERT INTO sites (id, name)
|
||||
VALUES ('00000000-0000-4000-8000-000000001841', 'Explicit Site');
|
||||
INSERT INTO agent_zones (
|
||||
id, site_id, name
|
||||
) VALUES (
|
||||
'00000000-0000-4000-8000-000000001842',
|
||||
'00000000-0000-4000-8000-000000001841',
|
||||
'Explicit Zone'
|
||||
);
|
||||
INSERT INTO minerops_site_agents (
|
||||
agent_id, site_id, agent_zone_id, site_name
|
||||
) VALUES (
|
||||
'explicit-agent',
|
||||
'00000000-0000-4000-8000-000000001841',
|
||||
'00000000-0000-4000-8000-000000001842',
|
||||
'A Different Display Name'
|
||||
);
|
||||
SQL
|
||||
run_db_alembic legacy_routing_explicit upgrade "${expected_revision}"
|
||||
[[ "$(psql_named legacy_routing_explicit -Atc "SELECT site_id || '/' || agent_zone_id FROM minerops_site_agents WHERE agent_id='explicit-agent'")" == "00000000-0000-4000-8000-000000001841/00000000-0000-4000-8000-000000001842" ]]
|
||||
|
||||
echo "Testing conservative downgrade refusal..."
|
||||
if output="$(run_db_alembic legacy_routing_happy downgrade 0017_agent_enrollment 2>&1)"; then
|
||||
echo "0018 downgrade unexpectedly discarded routing attribution" >&2
|
||||
exit 1
|
||||
fi
|
||||
[[ "${output}" == *"Restore the pre-upgrade database backup"* ]]
|
||||
[[ "$(psql_named legacy_routing_happy -Atc 'SELECT version_num FROM alembic_version')" == "${expected_revision}" ]]
|
||||
|
||||
echo "Legacy Agent routing migration lifecycle checks passed."
|
||||
Reference in new issue
Block a user