Files
ep-stalwart-v2/migration/generate-account-plan.sh
T

70 lines
2.2 KiB
Bash

#!/usr/bin/env bash
# Generates a stalwart-cli apply NDJSON plan (Domain + Account/User + aliases)
# from a migration accounts.csv file. Requires jq.
set -euo pipefail
usage() { echo "Usage: $0 -c accounts.csv -d domain.tld -o accounts-plan.ndjson" >&2; exit 1; }
while getopts "c:d:o:" opt; do
case "$opt" in
c) CSV="$OPTARG" ;;
d) DOMAIN="$OPTARG" ;;
o) OUT="$OPTARG" ;;
*) usage ;;
esac
done
[[ -z "${CSV:-}" || -z "${DOMAIN:-}" || -z "${OUT:-}" ]] && usage
command -v jq >/dev/null || { echo "jq is required" >&2; exit 1; }
: > "$OUT"
jq -nc --arg domain "$DOMAIN" \
'{"@type":"upsert","object":"Domain","matchOn":["name"],"value":{"dom":{"name":$domain}}}' >> "$OUT"
accounts_file=$(mktemp)
trap 'rm -f "$accounts_file"' EXIT
# Process substitution keeps the loop in the current shell, so a missing
# password can abort the whole script instead of just a pipeline subshell.
while IFS=',' read -r email new_password old_password aliases quota_mb; do
[[ -z "$email" ]] && continue
if [[ -z "$new_password" ]]; then
echo "Missing new_password for $email" >&2
exit 1
fi
local_part="${email%%@*}"
aliases_json=$(jq -n --arg aliases "$aliases" '
($aliases | split(";") | map(select(length > 0))) as $names
| reduce $names[] as $n ({}; . + {("alias-" + $n): {name: $n, domainId: "#dom"}})')
quotas_json="{}"
if [[ -n "$quota_mb" ]]; then
quotas_json=$(jq -n --argjson mb "$quota_mb" '{"maxDiskQuota": ($mb * 1048576)}')
fi
jq -n --arg id "acct-$local_part" --arg name "$local_part" --arg secret "$new_password" \
--argjson aliases "$aliases_json" --argjson quotas "$quotas_json" '
{ ($id): {
"@type": "User",
name: $name,
domainId: "#dom",
credentials: { "0": { "@type": "Password", secret: $secret } },
memberGroupIds: {},
roles: { "@type": "User" },
permissions: { "@type": "Inherit" },
quotas: $quotas,
aliases: $aliases,
encryptionAtRest: { "@type": "Disabled" }
}
}' >> "$accounts_file"
done < <(tail -n +2 "$CSV")
accounts_value=$(jq -s 'add' "$accounts_file")
jq -nc --argjson value "$accounts_value" \
'{"@type":"upsert","object":"Account","matchOn":["name"],"value":$value}' >> "$OUT"
echo "Wrote plan to $OUT"