storage/init/minio-bootstrap.sh
Sergei Poljanski 61e93b64c8
All checks were successful
Deploy storage stack / deploy (push) Successful in 20s
Give the bingo photos their own bucket
The datacenter bingo photos sat under bingo/ in asxpio-invoices, next to
the invoice PDFs, guarded only by a prefix policy. Move them to a
datacenterbingo-photos bucket: asxpio's user gets read-write for the
admin's uploads, the bingo user read-only on the whole bucket.

Existing objects are mirrored over with their keys unchanged, so the
database rows stay valid. Both users keep their old access until the
apps are switched and the old prefix is removed.

Assisted-by: Claude:opus-5
2026-10-12 04:07:41 +04:00

99 lines
3.1 KiB
Bash

#!/bin/sh
# Idempotent MinIO bootstrap: bucket + per-app service account scoped to that
# bucket. Re-running just refreshes the policy and resets the access key.
set -eu
mc alias set local http://minio:9000 "${MINIO_ROOT_USER}" "${MINIO_ROOT_PASSWORD}"
ensure_bucket() {
bucket="$1"
if ! mc ls "local/${bucket}" >/dev/null 2>&1; then
mc mb "local/${bucket}"
fi
mc anonymous set none "local/${bucket}" >/dev/null
}
write_policy() {
name="$1"
bucket="$2"
cat > "/tmp/${name}.json" <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": ["s3:ListBucket", "s3:GetBucketLocation"],
"Resource": ["arn:aws:s3:::${bucket}"]
},
{
"Effect": "Allow",
"Action": ["s3:GetObject", "s3:PutObject", "s3:DeleteObject"],
"Resource": ["arn:aws:s3:::${bucket}/*"]
}
]
}
EOF
mc admin policy create local "${name}" "/tmp/${name}.json" 2>/dev/null \
|| mc admin policy update local "${name}" "/tmp/${name}.json"
}
# Read-only on one prefix of a bucket.
write_ro_prefix_policy() {
name="$1"
bucket="$2"
prefix="$3"
cat > "/tmp/${name}.json" <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": ["s3:GetObject"],
"Resource": ["arn:aws:s3:::${bucket}/${prefix}*"]
}
]
}
EOF
mc admin policy create local "${name}" "/tmp/${name}.json" 2>/dev/null \
|| mc admin policy update local "${name}" "/tmp/${name}.json"
}
# $3: one or more policy names, space-separated.
ensure_user() {
access="$1"
secret="$2"
policies="$3"
if mc admin user info local "${access}" >/dev/null 2>&1; then
# Rotate secret to match desired state.
mc admin user remove local "${access}" >/dev/null
fi
mc admin user add local "${access}" "${secret}"
# shellcheck disable=SC2086 # word-split the policy list on purpose
mc admin policy attach local ${policies} --user "${access}" 2>/dev/null || true
}
ensure_bucket "asxpio-invoices"
write_policy "asxpio-invoices-rw" "asxpio-invoices"
# Datacenter bingo photos: uploaded and resized by asxpio's admin, served by
# datacenterbingo. Keys keep their bingo/ prefix, so DB rows stay valid.
ensure_bucket "datacenterbingo-photos"
write_policy "datacenterbingo-photos-rw" "datacenterbingo-photos"
write_ro_prefix_policy "datacenterbingo-photos-ro" "datacenterbingo-photos" ""
# Migration from asxpio-invoices/bingo/: copy whatever is missing. Remove
# this (and the old bingo-ro policy below) once the old prefix is deleted.
if mc ls "local/asxpio-invoices/bingo/" 2>/dev/null | grep -q .; then
mc mirror --quiet "local/asxpio-invoices/bingo" "local/datacenterbingo-photos/bingo"
fi
ensure_user "${ASXPIO_S3_ACCESS_KEY}" "${ASXPIO_S3_SECRET_KEY}" "asxpio-invoices-rw datacenterbingo-photos-rw"
if [ -n "${BINGO_S3_ACCESS_KEY:-}" ] && [ -n "${BINGO_S3_SECRET_KEY:-}" ]; then
write_ro_prefix_policy "asxpio-invoices-bingo-ro" "asxpio-invoices" "bingo/"
ensure_user "${BINGO_S3_ACCESS_KEY}" "${BINGO_S3_SECRET_KEY}" "datacenterbingo-photos-ro asxpio-invoices-bingo-ro"
else
echo "minio-init: BINGO_S3_* unset, skipping bingo user"
fi
echo "minio-init: done"