Files
ACORE/scripts/silo_bootstrap.sh
lokses 030bbc98fd projects: модуль проектов с шагами по отделам и Task.
Шаблоны/ручное создание, access_projects, сид «Открытие аптеки». Плюс SILO/S3 для Django media.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-23 16:26:45 +03:00

134 lines
3.9 KiB
Bash
Executable File

#!/usr/bin/env bash
# Bootstrap SILO (MinIO-compatible): buckets + scoped access keys for ACORE / Nextcloud.
#
# Prerequisites: mcli (or mc) client, SILO API reachable, openssl.
# Usage:
# export SILO_ENDPOINT=https://s3.example.local:9000
# export SILO_ROOT_USER=...
# export SILO_ROOT_PASSWORD=...
# ./scripts/silo_bootstrap.sh
#
# Optional: ACORE_MEDIA_BUCKET, NEXTCLOUD_BUCKET, ALIAS
set -euo pipefail
ENDPOINT="${SILO_ENDPOINT:?Set SILO_ENDPOINT (e.g. https://s3.example.local:9000)}"
ROOT_USER="${SILO_ROOT_USER:?Set SILO_ROOT_USER}"
ROOT_PASSWORD="${SILO_ROOT_PASSWORD:?Set SILO_ROOT_PASSWORD}"
ACORE_MEDIA_BUCKET="${ACORE_MEDIA_BUCKET:-acore-media}"
NEXTCLOUD_BUCKET="${NEXTCLOUD_BUCKET:-nextcloud}"
ALIAS="${ALIAS:-acore-silo}"
if command -v mcli >/dev/null 2>&1; then
MC=mcli
elif command -v mc >/dev/null 2>&1; then
MC=mc
else
echo "Need mcli or mc in PATH" >&2
exit 1
fi
echo "==> Alias ${ALIAS} → ${ENDPOINT}"
"${MC}" alias set "${ALIAS}" "${ENDPOINT}" "${ROOT_USER}" "${ROOT_PASSWORD}"
echo "==> Buckets"
"${MC}" mb --ignore-existing "${ALIAS}/${ACORE_MEDIA_BUCKET}"
"${MC}" mb --ignore-existing "${ALIAS}/${NEXTCLOUD_BUCKET}"
echo "==> Versioning"
"${MC}" version enable "${ALIAS}/${ACORE_MEDIA_BUCKET}" || true
"${MC}" version enable "${ALIAS}/${NEXTCLOUD_BUCKET}" || true
POLICY_DIR="$(mktemp -d)"
trap 'rm -rf "${POLICY_DIR}"' EXIT
cat >"${POLICY_DIR}/acore-media-rw.json" <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": ["s3:*"],
"Resource": [
"arn:aws:s3:::${ACORE_MEDIA_BUCKET}",
"arn:aws:s3:::${ACORE_MEDIA_BUCKET}/*"
]
}
]
}
EOF
cat >"${POLICY_DIR}/nextcloud-rw.json" <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": ["s3:*"],
"Resource": [
"arn:aws:s3:::${NEXTCLOUD_BUCKET}",
"arn:aws:s3:::${NEXTCLOUD_BUCKET}/*"
]
}
]
}
EOF
_policy_upsert() {
local name="$1" file="$2"
if "${MC}" admin policy create "${ALIAS}" "${name}" "${file}" 2>/dev/null; then
return 0
fi
if "${MC}" admin policy add "${ALIAS}" "${name}" "${file}" 2>/dev/null; then
return 0
fi
"${MC}" admin policy set "${ALIAS}" "${name}" "${file}"
}
echo "==> Policies"
_policy_upsert acore-media-rw "${POLICY_DIR}/acore-media-rw.json"
_policy_upsert nextcloud-rw "${POLICY_DIR}/nextcloud-rw.json"
ACORE_PASS="$(openssl rand -hex 24)"
NC_PASS="$(openssl rand -hex 24)"
_user_ensure() {
local user="$1" pass="$2" policy="$3"
if ! "${MC}" admin user info "${ALIAS}" "${user}" >/dev/null 2>&1; then
"${MC}" admin user add "${ALIAS}" "${user}" "${pass}"
else
"${MC}" admin user svcacct add "${ALIAS}" "${user}" 2>/dev/null || true
echo "User ${user} already exists — set password manually if needed:" >&2
echo " ${MC} admin user add ${ALIAS} ${user} <new-secret>" >&2
fi
if "${MC}" admin policy attach "${ALIAS}" "${policy}" --user "${user}" 2>/dev/null; then
return 0
fi
"${MC}" admin policy set "${ALIAS}" "${policy}" "user=${user}" 2>/dev/null || true
}
echo "==> Users"
_user_ensure acore-media-rw "${ACORE_PASS}" acore-media-rw
_user_ensure nextcloud-rw "${NC_PASS}" nextcloud-rw
echo "==> Smoke put/get (acore-media)"
SMOKE_KEY="silo-bootstrap-smoke-$(date +%s).txt"
echo "ok $(date -Iseconds)" | "${MC}" pipe "${ALIAS}/${ACORE_MEDIA_BUCKET}/${SMOKE_KEY}"
"${MC}" cat "${ALIAS}/${ACORE_MEDIA_BUCKET}/${SMOKE_KEY}" >/dev/null
"${MC}" rm --force "${ALIAS}/${ACORE_MEDIA_BUCKET}/${SMOKE_KEY}"
echo
echo "=== ACORE (.env) ==="
echo "S3_ENDPOINT=${ENDPOINT}"
echo "S3_ACCESS_KEY=acore-media-rw"
echo "S3_SECRET_KEY=${ACORE_PASS}"
echo "S3_MEDIA_BUCKET=${ACORE_MEDIA_BUCKET}"
echo "S3_REGION=us-east-1"
echo
echo "=== Nextcloud object store ==="
echo "key = nextcloud-rw"
echo "secret = ${NC_PASS}"
echo "bucket = ${NEXTCLOUD_BUCKET}"
echo "endpoint = ${ENDPOINT}"
echo
echo "Done. Store secrets offline; do not commit them."