nix-config/scripts/truenas-rbac-setup.sh

88 lines
3.2 KiB
Bash
Executable file

#!/usr/bin/env bash
set -euo pipefail
# This script automates the creation of a restricted TrueNAS user (forgejo-ci)
# and assigns it a custom privilege role strictly limited to ZFS cloning/snapshots.
echo "=========================================="
echo " TrueNAS RBAC Setup for CI/CD"
echo "=========================================="
echo "This script will create a custom Privilege Role and a Restricted User."
echo ""
read -p "Enter your TrueNAS IP (e.g., 192.168.0.11): " TRUENAS_IP
read -s -p "Enter your current TrueNAS Admin Token (root): " ADMIN_TOKEN
echo ""
read -p "Enter a password for the new 'forgejo-ci' user: " CI_PASSWORD
BASE_URL="http://${TRUENAS_IP}/api/v2.0"
HEADERS=(
"-H" "Authorization: Bearer ${ADMIN_TOKEN}"
"-H" "Content-Type: application/json"
)
echo ""
echo "1. Creating Custom Privilege (ci-runner-role)..."
# In TrueNAS SCALE, we create a privilege that allows specific methods
PRIV_PAYLOAD=$(cat <<EOF
{
"name": "ci-runner-role",
"allowlist": [
{"method": "zfs.snapshot.create"},
{"method": "zfs.snapshot.clone"},
{"method": "zfs.dataset.delete"},
{"method": "zfs.snapshot.delete"},
{"method": "zfs.snapshot.query"},
{"method": "zfs.dataset.query"}
]
}
EOF
)
# Attempt to create privilege (ignore if it already exists)
HTTP_STATUS=$(curl -s -o /dev/null -w "%{http_code}" -X POST "${BASE_URL}/privilege" "${HEADERS[@]}" -d "${PRIV_PAYLOAD}")
if [ "$HTTP_STATUS" -eq 200 ]; then
echo " -> Privilege created successfully."
elif [ "$HTTP_STATUS" -eq 409 ] || [ "$HTTP_STATUS" -eq 422 ]; then
echo " -> Privilege already exists or validation failed (code ${HTTP_STATUS}). Skipping."
else
echo " -> Warning: Privilege creation returned HTTP ${HTTP_STATUS}. (Your TrueNAS version might handle RBAC differently)."
fi
echo "2. Creating Restricted User (forgejo-ci)..."
USER_PAYLOAD=$(cat <<EOF
{
"username": "forgejo-ci",
"full_name": "Forgejo CI Runner",
"password": "${CI_PASSWORD}",
"password_disabled": false,
"group_create": true,
"attributes": {}
}
EOF
)
HTTP_STATUS=$(curl -s -o /tmp/truenas_user.json -w "%{http_code}" -X POST "${BASE_URL}/user" "${HEADERS[@]}" -d "${USER_PAYLOAD}")
if [ "$HTTP_STATUS" -eq 200 ]; then
echo " -> User created successfully."
elif [ "$HTTP_STATUS" -eq 409 ] || [ "$HTTP_STATUS" -eq 422 ]; then
echo " -> User already exists. Skipping."
else
echo " -> Warning: User creation returned HTTP ${HTTP_STATUS}."
cat /tmp/truenas_user.json
fi
echo ""
echo "=========================================="
echo " Setup Complete (or mostly complete)!"
echo "=========================================="
echo "Because TrueNAS prevents root from generating API tokens for other users,"
echo "you must complete the final step manually:"
echo ""
echo "1. Log into the TrueNAS Web UI at http://${TRUENAS_IP}"
echo "2. If the script failed to attach the privilege automatically, go to Credentials > Local Users,"
echo " edit 'forgejo-ci', and assign it the ZFS roles."
echo "3. Log in as 'forgejo-ci' (or use the API Keys menu as Admin to generate a key for that user)."
echo "4. Copy the newly generated token."
echo "5. Update the TRUENAS_API_KEY secret in your Forgejo repository."
echo "=========================================="