From da1bb6472f9f2e7af055a2616692555e3cf3755e Mon Sep 17 00:00:00 2001 From: david Date: Fri, 27 Oct 2023 11:42:58 +0200 Subject: [PATCH] renamed restic-repos.sh --- restic-repos.sh | 201 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 201 insertions(+) create mode 100755 restic-repos.sh diff --git a/restic-repos.sh b/restic-repos.sh new file mode 100755 index 0000000..cb48674 --- /dev/null +++ b/restic-repos.sh @@ -0,0 +1,201 @@ +#!/usr/bin/env bash + + + ## ## ## ## ## ## ## ## ## ## ## ## ## ## + ## ## + ## restic-repos.sh ## + ## ## + ## Repository/user management script for ## + ## Restic's REST server ## + ## ## + ## ## ## ## ## ## ## ## ## ## ## ## ## ## + + +# Information +NAME="rest-repos.sh" +DESCRIPTION="Repository/user management script for Restic's REST server" +VERSION="0.1.0" +AUTHOR="david@socialnerds.org" +LICENSE="MIT" +WEBSITE="https://git.socialnerds.org/david/scripts" + + +# Configuration +RR_DATA_PATH="/srv/backup/rest-server" +RR_NGINX_PATH="/etc/nginx/rest-server.conf.d" +RR_NGINX_TEMPLATE="$RR_NGINX_PATH/rest-server.conf.template" +RR_LOG_FILE="/var/log/rest-repos.log" +RR_HOST="backup.socialnerds.org" +RR_PROTOCOL="https" + + +# Initialization +RR_DEPS="htpasswd tr head systemctl find awk sed sort" + + +# Text formatting +CLEAR="\e[0m" +BOLD="\e[1m" +RED="\e[31m" + + +# Functions +function rr_output() { + # Print text/messages to screen + if [[ "$1" =~ ^\! ]]; then + printf "$RED%b$CLEAR\n" "${1#\!}" + else + if [[ "$RR_Q" -ne 1 ]]; then + printf "%b\n" "$1" + fi + fi +} + +function rr_help() { + # Print help information + rr_output "$DESCRIPTION\n\nUsage:\n$NAME \n\nOptions: + -l, --list\t\tList repositories + -r, --remove\t\tRemove repository + -h, --help\t\tHelp screen + -v, --version\t\tVersion information + -q, --quiet\t\tNo output except errors" + exit 0 +} + +function rr_version() { + # Print version information + rr_output "Version: $BOLD$VERSION$CLEAR\nAuthor: $AUTHOR\nLicense: $LICENSE" + exit 0 +} + +function rr_passwd() { + # Generate random password + LC_ALL=C tr -dc 'a-zA-Z0-9' < /dev/urandom | head -c 16; echo +} + +function rr_list() { + # List all existing repositories + for RR_REPO in $(find $RR_DATA_PATH -maxdepth 1 -mindepth 1 -type d -printf "%f\n" | sort); do + local RR_SIZE=$(du -s -h $RR_DATA_PATH/$RR_REPO | awk '{print $1}') + if [[ -f $RR_NGINX_PATH/$RR_REPO.conf && -f $RR_NGINX_PATH/$RR_REPO.htpasswd ]]; then + rr_output "$BOLD$RR_REPO$CLEAR[$RR_SIZE]" + else + local RR_DISABLED="$RR_DISABLED $RR_REPO[$RR_SIZE]" + fi + done + for RR_REPO in $RR_DISABLED; do + rr_output "$RR_REPO" + done +} + +function rr_add() { + # Enable or create a repository + if [ -n "$1" ]; then + if [[ ! -d "$RR_DATA_PATH/$1" ]]; then + mkdir "$RR_DATA_PATH/$1" + chown rest-server:rest-server "$RR_DATA_PATH/$1" + chmod 700 "$RR_DATA_PATH/$1" + fi + if [[ ! -f "$RR_NGINX_PATH/$1.conf" && ! -f "$RR_NGINX_PATH/$1.htpasswd" ]]; then + sed "s/RR_REPO/$1/g" $RR_NGINX_TEMPLATE > "$RR_NGINX_PATH/$1.conf" + RR_PASSWD="$(rr_passwd)" + htpasswd -n -b "$1" "$RR_PASSWD" > "$RR_NGINX_PATH/$1.htpasswd" + rr_output "Repository has been added [$1]\nRepository URL:$BOLD rest:$RR_PROTOCOL://$1:$RR_PASSWD@$RR_HOST/$1/$CLEAR" + else + rr_output "!Repository does already exist and is enabled\nTry removing it first with -r or --remove" + exit 1 + fi + fi +} + +function rr_remove() { + # Remove a repository + if [[ -n "$1" ]]; then + rm $RR_NGINX_PATH/$1.conf &>/dev/null + rm $RR_NGINX_PATH/$1.htpasswd &>/dev/null + if [[ -d $RR_DATA_PATH/$1 ]]; then + rr_output "Repository has been removed [$1]\nThe data needs to be deleted manually [$RR_DATA_PATH/$1]" + else + rr_output "!Repository does not exist [$1]" + exit 1 + fi + fi +} + + +# Preflight +for RR_DEP in $RR_DEPS; do + if ! $(command -v $RR_DEP &>/dev/null); then + RR_MISS="$RR_MISS, $RR_DEP" + fi +done +if [[ -n $RR_MISS ]]; then + rr_output "!One or more missing dependencies [${RR_MISS#, }]\nTry installing them with your package manager" + exit 1 +fi + +#TODO: check if nginx path and data path exists and both are writeable + + +# Option handler +while [[ "$1" =~ ^- && ! "$1" == "--" ]]; do + case $1 in + -v|--version) + RR_V=1 + ;; + -h|--help) + RR_H=1 + ;; + -l|--list) + RR_L=1 + ;; + -r|--remove) + RR_R=1 + ;; + -q|--quiet) + RR_Q=1 + ;; + *) + rr_output "!Unknown option [$1]\nTry --help or -h for available options" + exit 1 + ;; + esac + shift +done + +if [[ "$1" == '--' ]]; then + shift +fi + +if [[ $RR_L -eq 1 ]]; then + rr_list + exit 0 +elif [[ $RR_H -eq 1 ]]; then + rr_help + exit 0 +elif [[ $RR_V -eq 1 ]]; then + rr_version + exit 0 +fi + +if [[ -z "$1" ]]; then + rr_list + exit 0 +else + if [[ "$1" =~ ^[a-zA-Z0-9_-]{3,20}$ ]]; then + if [[ $RR_R -eq 1 ]]; then + rr_remove "$1" + else + rr_add "$1" + fi + # Reloading Nginx after config changes + systemctl reload nginx.service + else + rr_output "!Invalid repository name [$1]\nMust be an alphanumeric string between 3 and 20 characters" + exit 1 + fi +fi + + +# Here be dragons +exit 0