deploy_kds: scoped DB role instead of sharing kitchen's credential
- Generate KDS_DB_PASS (matching KITCHEN_DB_PASS's pattern), add to --only dispatch's _append_secret list - Create a scoped `kds` Postgres role: SELECT/INSERT/UPDATE/DELETE on kds_tickets/kds_course_bumps, read-only on resos_bookings/resos_opening_hours, column-scoped SELECT+UPDATE on just the kds_* columns of kitchen_settings (not the NewBook/ResOS/Nextcloud/Dext/SambaPOS/Azure/Anthropic credentials that live in the same table). Runs in two passes since kds_tickets/ kds_course_bumps don't exist until KDS's own migrations create them. - kds .env now carries DATABASE_URL (scoped `kds` role, runtime) and MIGRATION_DATABASE_URL (privileged `kitchen` role, migrations only) - Fix KDS theme_color seed (teal -> orange, matched kitchen's tile before) See kitchen-port-log.md E17. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
parent
dbf9e90164
commit
2088cb5577
1 changed files with 61 additions and 2 deletions
|
|
@ -2189,6 +2189,12 @@ deploy_kds() {
|
||||||
msg_error "KITCHEN_DB_PASS not set — deploy kitchen first, or add it to ${CREDS_FILE}"
|
msg_error "KITCHEN_DB_PASS not set — deploy kitchen first, or add it to ${CREDS_FILE}"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if [[ -z "${KDS_DB_PASS:-}" ]]; then
|
||||||
|
KDS_DB_PASS=$(openssl rand -base64 24 | tr -dc 'a-zA-Z0-9' | head -c 24)
|
||||||
|
printf '\nKDS_DB_PASS=%s\n' "$KDS_DB_PASS" >> "$CREDS_FILE"
|
||||||
|
msg_ok "Generated KDS_DB_PASS → ${CREDS_FILE}"
|
||||||
|
fi
|
||||||
|
|
||||||
msg_info "Creating LXC 125"
|
msg_info "Creating LXC 125"
|
||||||
create_lxc 125 "10.10.10.125" "kds" 1024 1
|
create_lxc 125 "10.10.10.125" "kds" 1024 1
|
||||||
msg_ok "LXC 125 created"
|
msg_ok "LXC 125 created"
|
||||||
|
|
@ -2198,12 +2204,54 @@ deploy_kds() {
|
||||||
install_mgmt_key 125
|
install_mgmt_key 125
|
||||||
msg_ok "Docker + SSH ready"
|
msg_ok "Docker + SSH ready"
|
||||||
|
|
||||||
|
# Scoped `kds` DB role — E17: KDS used to share the `kitchen` role wholesale
|
||||||
|
# (full read/write on all 74 kitchen_db tables). Grant only what KDS
|
||||||
|
# actually touches: its own tables, read-only ResOS bookings, and the
|
||||||
|
# kds_* columns on kitchen_settings — not NewBook/ResOS/Nextcloud/Dext/
|
||||||
|
# SambaPOS-sales/Azure/Anthropic credentials that live in the same table.
|
||||||
|
# kds_tickets/kds_course_bumps don't exist yet at this point (KDS's own
|
||||||
|
# migrations create them on first boot, run via the privileged connection
|
||||||
|
# below) — that grant runs in a second pass after the container is up.
|
||||||
|
msg_info "Scoping kds DB role"
|
||||||
|
pct exec 100 -- docker exec hotel-manage-postgres psql -U postgres -d kitchen_db -c "
|
||||||
|
DO \$\$ BEGIN
|
||||||
|
CREATE ROLE kds LOGIN PASSWORD '${KDS_DB_PASS}';
|
||||||
|
EXCEPTION WHEN duplicate_object THEN
|
||||||
|
ALTER ROLE kds WITH PASSWORD '${KDS_DB_PASS}';
|
||||||
|
END \$\$;
|
||||||
|
GRANT CONNECT ON DATABASE kitchen_db TO kds;
|
||||||
|
GRANT USAGE ON SCHEMA public TO kds;
|
||||||
|
GRANT SELECT ON resos_bookings, resos_opening_hours TO kds;
|
||||||
|
GRANT SELECT (
|
||||||
|
id, kitchen_id, kds_enabled, kds_graphql_url, kds_graphql_username,
|
||||||
|
kds_graphql_password, kds_graphql_client_id, kds_poll_interval_seconds,
|
||||||
|
kds_timer_green_seconds, kds_timer_amber_seconds, kds_timer_red_seconds,
|
||||||
|
kds_course_order, kds_show_completed_for_seconds,
|
||||||
|
kds_away_timer_green_seconds, kds_away_timer_amber_seconds,
|
||||||
|
kds_away_timer_red_seconds, kds_bookings_refresh_seconds
|
||||||
|
) ON kitchen_settings TO kds;
|
||||||
|
GRANT UPDATE (
|
||||||
|
kds_enabled, kds_graphql_url, kds_graphql_username, kds_graphql_password,
|
||||||
|
kds_graphql_client_id, kds_poll_interval_seconds, kds_timer_green_seconds,
|
||||||
|
kds_timer_amber_seconds, kds_timer_red_seconds, kds_course_order,
|
||||||
|
kds_show_completed_for_seconds, kds_away_timer_green_seconds,
|
||||||
|
kds_away_timer_amber_seconds, kds_away_timer_red_seconds,
|
||||||
|
kds_bookings_refresh_seconds
|
||||||
|
) ON kitchen_settings TO kds;
|
||||||
|
" &>/dev/null \
|
||||||
|
&& msg_ok "kds DB role scoped" \
|
||||||
|
|| msg_warn "kds role setup failed — check LXC 100 postgres logs"
|
||||||
|
|
||||||
msg_info "Deploying kds"
|
msg_info "Deploying kds"
|
||||||
deploy_service 125 "kds" "${REPO_ROOT}/kds" /opt/kds
|
deploy_service 125 "kds" "${REPO_ROOT}/kds" /opt/kds
|
||||||
|
|
||||||
|
# DATABASE_URL is the scoped `kds` role (runtime queries). MIGRATION_DATABASE_URL
|
||||||
|
# is the privileged `kitchen` role, used only at startup to create KDS's own
|
||||||
|
# tables and ALTER kitchen_settings — never touched by request handling.
|
||||||
push_file 125 /opt/kds/.env <<EOF
|
push_file 125 /opt/kds/.env <<EOF
|
||||||
APP_SLUG=kds
|
APP_SLUG=kds
|
||||||
DATABASE_URL=postgresql://kitchen:${KITCHEN_DB_PASS}@10.10.10.100:5432/kitchen_db
|
DATABASE_URL=postgresql://kds:${KDS_DB_PASS}@10.10.10.100:5432/kitchen_db
|
||||||
|
MIGRATION_DATABASE_URL=postgresql://kitchen:${KITCHEN_DB_PASS}@10.10.10.100:5432/kitchen_db
|
||||||
CENTRAL_AUTH_SECRET=${CENTRAL_AUTH_SECRET}
|
CENTRAL_AUTH_SECRET=${CENTRAL_AUTH_SECRET}
|
||||||
VITE_HOTEL_NAME=${SITE_NAME:-Hotel}
|
VITE_HOTEL_NAME=${SITE_NAME:-Hotel}
|
||||||
EOF
|
EOF
|
||||||
|
|
@ -2214,6 +2262,15 @@ EOF
|
||||||
${build_out}"
|
${build_out}"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# Second grants pass — kds_tickets/kds_course_bumps now exist (created by
|
||||||
|
# KDS's own migrations on the boot above, via the privileged connection).
|
||||||
|
msg_info "Granting kds role access to its own tables"
|
||||||
|
pct exec 100 -- docker exec hotel-manage-postgres psql -U postgres -d kitchen_db -c "
|
||||||
|
GRANT SELECT, INSERT, UPDATE, DELETE ON kds_tickets, kds_course_bumps TO kds;
|
||||||
|
" &>/dev/null \
|
||||||
|
&& msg_ok "kds table grants applied" \
|
||||||
|
|| msg_warn "kds table grants failed — check kds_tickets/kds_course_bumps exist, then re-run"
|
||||||
|
|
||||||
msg_info "Waiting for kds"
|
msg_info "Waiting for kds"
|
||||||
wait_healthy 125 "http://localhost:3080/kds/health" 200 \
|
wait_healthy 125 "http://localhost:3080/kds/health" 200 \
|
||||||
&& msg_ok "KDS running at 10.10.10.125:3080" \
|
&& msg_ok "KDS running at 10.10.10.125:3080" \
|
||||||
|
|
@ -2222,7 +2279,7 @@ ${build_out}"
|
||||||
msg_info "Seeding kds into auth DB"
|
msg_info "Seeding kds into auth DB"
|
||||||
pct exec 100 -- docker exec hotel-manage-postgres psql -U postgres -d auth_db -c "
|
pct exec 100 -- docker exec hotel-manage-postgres psql -U postgres -d auth_db -c "
|
||||||
INSERT INTO apps (slug, name, description, base_path, icon, theme_color, category, internal_host, internal_port)
|
INSERT INTO apps (slug, name, description, base_path, icon, theme_color, category, internal_host, internal_port)
|
||||||
VALUES ('kds', 'Kitchen Display', 'SambaPOS ticket feed and course flow display', '/kds', 'Monitor', '#0d9488', 'Kitchen', '10.10.10.125', 3080)
|
VALUES ('kds', 'Kitchen Display', 'SambaPOS ticket feed and course flow display', '/kds', 'Monitor', '#ea580c', 'Kitchen', '10.10.10.125', 3080)
|
||||||
ON CONFLICT (slug) DO UPDATE SET
|
ON CONFLICT (slug) DO UPDATE SET
|
||||||
name=EXCLUDED.name, description=EXCLUDED.description, base_path=EXCLUDED.base_path,
|
name=EXCLUDED.name, description=EXCLUDED.description, base_path=EXCLUDED.base_path,
|
||||||
icon=EXCLUDED.icon, theme_color=EXCLUDED.theme_color, category=EXCLUDED.category,
|
icon=EXCLUDED.icon, theme_color=EXCLUDED.theme_color, category=EXCLUDED.category,
|
||||||
|
|
@ -2529,6 +2586,8 @@ if [[ "${1:-}" == "--only" ]]; then
|
||||||
"$(openssl rand -base64 24 | tr -dc 'a-zA-Z0-9' | head -c 24)"
|
"$(openssl rand -base64 24 | tr -dc 'a-zA-Z0-9' | head -c 24)"
|
||||||
[[ -z "${KITCHEN_DB_PASS:-}" ]] && _append_secret KITCHEN_DB_PASS \
|
[[ -z "${KITCHEN_DB_PASS:-}" ]] && _append_secret KITCHEN_DB_PASS \
|
||||||
"$(openssl rand -base64 24 | tr -dc 'a-zA-Z0-9' | head -c 24)"
|
"$(openssl rand -base64 24 | tr -dc 'a-zA-Z0-9' | head -c 24)"
|
||||||
|
[[ -z "${KDS_DB_PASS:-}" ]] && _append_secret KDS_DB_PASS \
|
||||||
|
"$(openssl rand -base64 24 | tr -dc 'a-zA-Z0-9' | head -c 24)"
|
||||||
[[ -z "${WAGES_DB_PASS:-}" ]] && _append_secret WAGES_DB_PASS \
|
[[ -z "${WAGES_DB_PASS:-}" ]] && _append_secret WAGES_DB_PASS \
|
||||||
"$(openssl rand -base64 24 | tr -dc 'a-zA-Z0-9' | head -c 24)"
|
"$(openssl rand -base64 24 | tr -dc 'a-zA-Z0-9' | head -c 24)"
|
||||||
[[ -z "${UTILITIES_DB_PASS:-}" ]] && _append_secret UTILITIES_DB_PASS \
|
[[ -z "${UTILITIES_DB_PASS:-}" ]] && _append_secret UTILITIES_DB_PASS \
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue