Skip to content

Instantly share code, notes, and snippets.

@rleap-m
Created July 2, 2025 15:44
Show Gist options
  • Save rleap-m/6aa8ace96b9b17eeba30d9b1abf8c476 to your computer and use it in GitHub Desktop.
Save rleap-m/6aa8ace96b9b17eeba30d9b1abf8c476 to your computer and use it in GitHub Desktop.
Script to delete MSR4 project and the repos they contain.
#!/bin/bash
set -euo pipefail
PAGE_SIZE=100
# Default values from environment, can be overridden via CLI
HARBOR_URL="${HARBOR_URL:-}"
HARBOR_USER="${HARBOR_USER:-}"
HARBOR_PWD="${HARBOR_PWD:-}"
DRY_RUN=false
ONLY_PROJECTS=""
SHOW_HELP=false
print_help() {
cat <<EOF
Usage: $0 --url HARBOR_URL --user USERNAME --password PASSWORD [OPTIONS]
Options:
--url URL Harbor base URL (e.g., https://harbor.example.com)
--user USERNAME Harbor username
--password PASSWORD Harbor password
--dry-run Show what would be deleted without performing deletions
--only PROJECTS Comma-separated list of project names or prefixes to include
--help Show this help message and exit
You can also set environment variables instead of providing --url, --user, --password.
EOF
}
# --- CLI Argument Parsing ---
while [[ $# -gt 0 ]]; do
case "$1" in
--url) HARBOR_URL="$2"; shift 2 ;;
--user) HARBOR_USER="$2"; shift 2 ;;
--password) HARBOR_PWD="$2"; shift 2 ;;
--dry-run) DRY_RUN=true; shift ;;
--only) ONLY_PROJECTS="$2"; shift 2 ;;
--help) SHOW_HELP=true; shift ;;
*)
echo "Unknown option: $1"
print_help
exit 1
;;
esac
done
if [[ "$SHOW_HELP" == true ]]; then
print_help
exit 0
fi
# --- Validate required input ---
if [[ -z "$HARBOR_URL" || -z "$HARBOR_USER" || -z "$HARBOR_PWD" ]]; then
echo "Error: --url, --user, and --password are required."
print_help
exit 1
fi
# Convert comma-separated --only input into array
IFS=',' read -ra ONLY_FILTER <<< "$ONLY_PROJECTS"
# --- Get all project names ---
projects=$(curl -s -u "$HARBOR_USER:$HARBOR_PWD" \
"$HARBOR_URL/api/v2.0/projects?page_size=$PAGE_SIZE" | jq -r '.[].name')
for project in $projects; do
if [[ "$project" == "library" ]]; then
echo "Skipping default project: $project"
continue
fi
# If --only is set, skip non-matching projects
if [[ -n "$ONLY_PROJECTS" ]]; then
match=false
for prefix in "${ONLY_FILTER[@]}"; do
if [[ "$project" == "$prefix"* ]]; then
match=true
break
fi
done
[[ "$match" == false ]] && continue
fi
echo "Processing project: $project"
# Get all repositories in the project
repos=$(curl -s -u "$HARBOR_USER:$HARBOR_PWD" \
"$HARBOR_URL/api/v2.0/projects/$project/repositories?page_size=$PAGE_SIZE" \
| jq -r '.[].name')
for repo in $repos; do
echo " Repository found: $repo"
repo_path="${repo#"$project/"}"
encoded_once=$(echo -n "$repo_path" | jq -sRr @uri)
encoded_twice=$(echo -n "$encoded_once" | jq -sRr @uri)
if [[ "$DRY_RUN" == true ]]; then
echo " [Dry Run] Would delete repository: $repo"
else
response=$(curl -s -o /dev/null -w "%{http_code}" \
-u "$HARBOR_USER:$HARBOR_PWD" -X DELETE \
"$HARBOR_URL/api/v2.0/projects/$project/repositories/$encoded_twice")
if [[ "$response" == "200" ]]; then
echo " Repository deleted successfully."
else
echo " Failed to delete repository. HTTP status: $response"
fi
fi
done
if [[ "$DRY_RUN" == true ]]; then
echo "[Dry Run] Would delete project: $project"
else
echo " Attempting to delete project: $project"
project_delete_status=$(curl -s -o /dev/null -w "%{http_code}" \
-u "$HARBOR_USER:$HARBOR_PWD" -X DELETE \
"$HARBOR_URL/api/v2.0/projects/$project")
if [[ "$project_delete_status" == "200" ]]; then
echo " Project deleted successfully."
else
echo " Failed to delete project. HTTP status: $project_delete_status"
fi
fi
echo
done
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment