Files
musicland/functions/deleteAllCloudFunctions.sh
Thomas Demirdjian d1be3c19a2 Fixes and tickets
2025-10-28 15:43:18 +01:00

746 lines
26 KiB
Bash
Executable File

#!/bin/bash
# Script interactif pour supprimer toutes les Cloud Functions d'un projet Firebase
# Utilise les flèches pour naviguer et Entrée pour sélectionner
# Couleurs pour l'affichage
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
BOLD='\033[1m'
# Fonction pour afficher le menu avec sélection
show_menu() {
local options=("$@")
local selected=0
local num_options=${#options[@]}
while true; do
clear
echo -e "${BLUE}${BOLD}=== Gestionnaire Cloud Functions Firebase ===${NC}\n"
if [ ! -z "$CURRENT_PROJECT" ]; then
echo -e "${GREEN}Projet actuel: ${BOLD}$CURRENT_PROJECT${NC}\n"
fi
echo "Utilisez les flèches ↑↓ pour naviguer et Entrée pour sélectionner:\n"
for i in "${!options[@]}"; do
if [ $i -eq $selected ]; then
echo -e "${GREEN}${options[$i]}${NC}"
else
echo -e " ${options[$i]}"
fi
done
# Lire une seule touche
read -rsn1 key
case $key in
$'\033') # Séquence d'échappement pour les flèches
read -rsn2 key
case $key in
'[A') # Flèche haut
((selected--))
if [ $selected -lt 0 ]; then
selected=$((num_options-1))
fi
;;
'[B') # Flèche bas
((selected++))
if [ $selected -ge $num_options ]; then
selected=0
fi
;;
esac
;;
'') # Entrée
return $selected
;;
'q'|'Q') # Quitter
echo -e "\n${YELLOW}Au revoir!${NC}"
exit 0
;;
esac
done
}
# Fonction pour vérifier si gcloud est installé
check_gcloud() {
if ! command -v gcloud &> /dev/null; then
echo -e "${RED}Erreur: gcloud CLI n'est pas installé.${NC}"
echo "Veuillez installer Google Cloud SDK: https://cloud.google.com/sdk/docs/install"
exit 1
fi
}
# Fonction pour obtenir le projet actuel
get_current_project() {
CURRENT_PROJECT=$(gcloud config get-value project 2>/dev/null)
if [ -z "$CURRENT_PROJECT" ]; then
echo -e "${YELLOW}Aucun projet configuré.${NC}"
CURRENT_PROJECT="Aucun"
fi
}
# Fonction pour afficher les informations de débogage
show_debug_info() {
clear
echo -e "${BLUE}${BOLD}=== Informations de débogage ===${NC}\n"
echo -e "${YELLOW}1. Version de gcloud:${NC}"
gcloud version 2>/dev/null || echo "Erreur lors de la récupération de la version"
echo ""
echo -e "${YELLOW}2. Configuration actuelle:${NC}"
gcloud config list 2>/dev/null || echo "Erreur lors de la récupération de la configuration"
echo ""
echo -e "${YELLOW}3. Comptes authentifiés:${NC}"
gcloud auth list 2>/dev/null || echo "Erreur lors de la récupération des comptes"
echo ""
echo -e "${YELLOW}4. Test de la commande projects list (brute):${NC}"
echo "Commande: gcloud projects list"
gcloud projects list 2>&1 || echo "Erreur lors de l'exécution"
echo ""
echo -e "${YELLOW}5. Test avec format JSON:${NC}"
echo "Commande: gcloud projects list --format=json"
gcloud projects list --format="json" 2>&1 | head -20 || echo "Erreur lors de l'exécution"
echo ""
echo -e "${YELLOW}6. Permissions et quotas:${NC}"
echo "Commande: gcloud projects list --limit=1"
gcloud projects list --limit=1 2>&1 || echo "Erreur lors de l'exécution"
echo ""
}
# Fonction pour gérer l'authentification
handle_authentication() {
clear
echo -e "${RED}${BOLD}=== Erreur d'authentification ===${NC}\n"
echo -e "${YELLOW}Aucun projet trouvé ou erreur d'authentification.${NC}\n"
local auth_options=("Se connecter maintenant (gcloud auth login)" "Réessayer" "← Retour au menu principal")
echo "Que souhaitez-vous faire ?\n"
show_menu "${auth_options[@]}"
local choice=$?
case $choice in
0) # Se connecter
echo -e "\n${BLUE}Lancement de l'authentification...${NC}"
echo -e "${YELLOW}Une page web va s'ouvrir pour vous connecter.${NC}\n"
if gcloud auth login; then
echo -e "\n${GREEN}Authentification réussie!${NC}"
sleep 2
return 0
else
echo -e "\n${RED}Échec de l'authentification.${NC}"
read -p "Appuyez sur Entrée pour continuer..."
return 1
fi
;;
1) # Réessayer
return 0
;;
2) # Retour
return 1
;;
esac
}
# Fonction pour récupérer la liste des projets
get_projects_list() {
local projects=()
# Vérifier si l'utilisateur est connecté
local auth_status=$(gcloud auth list --format="value(account)" 2>/dev/null | head -1)
if [ -z "$auth_status" ]; then
echo -e "${RED}Vous n'êtes pas connecté à GCP.${NC}"
return 1
fi
echo -e "${BLUE}Récupération des projets...${NC}"
# Méthode 1: Utiliser --format=json pour éviter les problèmes de parsing
local temp_file=$(mktemp)
gcloud projects list --format="json" > "$temp_file" 2>/dev/null
if [ -s "$temp_file" ]; then
# Extraire les IDs de projet du JSON
while read -r project_id; do
if [ ! -z "$project_id" ]; then
projects+=("$project_id")
fi
done < <(cat "$temp_file" | grep -o '"projectId": "[^"]*"' | cut -d '"' -f 4)
else
# Méthode 2: Essayer avec la méthode originale
gcloud projects list --format="table(projectId)" --sort-by=projectId > "$temp_file" 2>&1
while IFS= read -r line; do
if [[ $line =~ ^[a-zA-Z0-9-]+[[:space:]] ]]; then
project_id=$(echo "$line" | awk '{print $1}')
if [ ! -z "$project_id" ]; then
projects+=("$project_id")
fi
fi
done < <(cat "$temp_file" | tail -n +2)
fi
# Nettoyer le fichier temporaire
rm -f "$temp_file"
# Retourner les projets via une variable globale
PROJECTS_LIST=("${projects[@]}")
return 0
}
# Fonction pour sélectionner un projet de manière interactive avec filtrage
select_project_interactive() {
echo -e "\n${BLUE}Récupération de la liste des projets...${NC}"
# Récupérer tous les projets disponibles
local all_projects=()
if ! get_projects_list; then
if ! handle_authentication; then
return 1
fi
if ! get_projects_list; then
echo -e "${RED}Impossible de récupérer la liste des projets.${NC}"
read -p "Appuyez sur Entrée pour continuer..."
return 1
fi
fi
all_projects=("${PROJECTS_LIST[@]}")
if [ ${#all_projects[@]} -eq 0 ]; then
echo -e "${RED}Aucun projet accessible trouvé.${NC}"
echo -e "${YELLOW}Cela peut être dû à:${NC}"
echo -e " • Aucun projet associé à votre compte"
echo -e " • Permissions insuffisantes"
echo -e " • Problème de configuration gcloud"
echo ""
local retry_options=("Réessayer" "Se reconnecter" "Spécifier manuellement l'ID du projet" "Afficher les détails de débogage" "← Retour au menu principal")
echo "Que souhaitez-vous faire ?\n"
show_menu "${retry_options[@]}"
local retry_choice=$?
case $retry_choice in
0) # Réessayer
return select_project_interactive
;;
1) # Se reconnecter
if handle_authentication; then
return select_project_interactive
else
return 1
fi
;;
2) # Spécifier manuellement l'ID du projet
clear
echo -e "${BLUE}${BOLD}=== Spécifier l'ID du projet ===${NC}\n"
echo -e "${YELLOW}Entrez l'ID du projet Firebase/GCP:${NC}"
echo -e "(exemple: my-project-12345)\n"
read -p "> " manual_project_id
if [ -z "$manual_project_id" ]; then
echo -e "\n${RED}Aucun ID de projet spécifié.${NC}"
read -p "Appuyez sur Entrée pour continuer..."
return 1
fi
echo -e "\n${BLUE}Vérification du projet: $manual_project_id${NC}"
if gcloud projects describe "$manual_project_id" &>/dev/null; then
echo -e "${GREEN}Projet trouvé!${NC}"
all_projects=("$manual_project_id")
else
echo -e "${RED}Projet non trouvé ou vous n'avez pas les permissions nécessaires.${NC}"
read -p "Appuyez sur Entrée pour continuer..."
return 1
fi
;;
3) # Afficher les détails de débogage
show_debug_info
read -p "Appuyez sur Entrée pour continuer..."
return 1
;;
4) # Retour
return 1
;;
esac
fi
# Ajouter option de retour
all_projects+=("← Retour au menu principal")
local selected=0
local filter=""
local filtered_projects=()
# Fonction pour filtrer les projets
filter_projects() {
filtered_projects=()
for project in "${all_projects[@]}"; do
if [[ "$project" == *"$filter"* ]]; then
filtered_projects+=("$project")
fi
done
# Réajuster la sélection si nécessaire
if [ $selected -ge ${#filtered_projects[@]} ]; then
selected=0
fi
}
# Initialiser le filtre
filter_projects
while true; do
clear
echo -e "${BLUE}${BOLD}=== Sélection du projet ===${NC}\n"
echo -e "${YELLOW}Projet actuel: ${BOLD}${CURRENT_PROJECT:-"Aucun"}${NC}"
echo ""
echo -e "${YELLOW}Tapez pour filtrer, utilisez ↑↓ pour naviguer, Entrée pour sélectionner:${NC}"
echo -e "Filtre: ${BOLD}$filter${NC}"
echo ""
# Afficher les projets filtrés
if [ ${#filtered_projects[@]} -eq 0 ]; then
echo -e "${RED}Aucun projet trouvé pour le filtre '$filter'${NC}"
else
for i in "${!filtered_projects[@]}"; do
if [ $i -eq $selected ]; then
echo -e "${GREEN}${filtered_projects[$i]}${NC}"
else
echo -e " ${filtered_projects[$i]}"
fi
done
fi
echo -e "\n${BLUE}Commandes: [Backspace] Effacer filtre | [Esc] Annuler${NC}"
# Lire une seule touche
read -rsn1 key
case $key in
$'\033') # Séquence d'échappement
read -rsn2 key
case $key in
'[A') # Flèche haut
if [ ${#filtered_projects[@]} -gt 0 ]; then
((selected--))
if [ $selected -lt 0 ]; then
selected=$((${#filtered_projects[@]}-1))
fi
fi
;;
'[B') # Flèche bas
if [ ${#filtered_projects[@]} -gt 0 ]; then
((selected++))
if [ $selected -ge ${#filtered_projects[@]} ]; then
selected=0
fi
fi
;;
esac
;;
'') # Entrée
if [ ${#filtered_projects[@]} -gt 0 ]; then
local chosen_project="${filtered_projects[$selected]}"
if [[ "$chosen_project" == "← Retour au menu principal" ]]; then
return 1
else
echo -e "\n${BLUE}Configuration du projet: $chosen_project${NC}"
if gcloud config set project "$chosen_project" &>/dev/null; then
CURRENT_PROJECT="$chosen_project"
echo -e "${GREEN}Projet configuré avec succès!${NC}"
sleep 2
return 0
else
echo -e "${RED}Erreur lors de la configuration du projet.${NC}"
read -p "Appuyez sur Entrée pour continuer..."
return 1
fi
fi
fi
;;
$'\177'|$'\b') # Backspace
if [ ${#filter} -gt 0 ]; then
filter="${filter%?}"
filter_projects
fi
;;
$'\e') # Escape
return 1
;;
*) # Caractère normal
if [[ "$key" =~ [a-zA-Z0-9-] ]]; then
filter="$filter$key"
filter_projects
fi
;;
esac
done
}
# Fonction pour lister et sélectionner un projet (version simplifiée)
select_project() {
select_project_interactive
}
# Fonction pour afficher les informations de débogage des Cloud Functions
show_functions_debug_info() {
clear
echo -e "${BLUE}${BOLD}=== Débogage Cloud Functions ===${NC}\n"
echo -e "${YELLOW}1. Test Cloud Functions Gen1 (toutes régions):${NC}"
gcloud functions list 2>&1 || echo "Erreur lors de la récupération des fonctions Gen1"
echo ""
echo -e "${YELLOW}2. Test Cloud Functions Gen2 (Cloud Run):${NC}"
gcloud run services list 2>&1 || echo "Erreur lors de la récupération des services Cloud Run"
echo ""
echo -e "${YELLOW}3. Régions disponibles pour Cloud Functions:${NC}"
gcloud functions regions list 2>&1 || echo "Erreur lors de la récupération des régions"
echo ""
echo -e "${YELLOW}4. Configuration actuelle:${NC}"
echo "Projet: $(gcloud config get-value project 2>/dev/null)"
echo "Région par défaut: $(gcloud config get-value functions/region 2>/dev/null || echo 'Non définie')"
echo ""
echo -e "${YELLOW}5. APIs activées:${NC}"
gcloud services list --enabled --filter="name:cloudfunctions OR name:run OR name:cloudbuild" 2>&1 || echo "Erreur lors de la vérification des APIs"
echo ""
}
# Fonction pour sélectionner une région de manière interactive avec filtrage
select_region_interactive() {
echo -e "\n${BLUE}Récupération des régions disponibles...${NC}"
# Récupérer toutes les régions disponibles
local all_regions=()
while IFS= read -r region; do
if [[ -n "$region" ]]; then
all_regions+=("$region")
fi
done < <(gcloud functions regions list --format="value(name)" 2>/dev/null | sort)
if [ ${#all_regions[@]} -eq 0 ]; then
echo -e "${RED}Impossible de récupérer la liste des régions.${NC}"
read -p "Appuyez sur Entrée pour continuer..."
return 1
fi
# Ajouter option de retour
all_regions+=("← Retour au menu précédent")
local selected=0
local filter=""
local filtered_regions=()
# Fonction pour filtrer les régions
filter_regions() {
filtered_regions=()
for region in "${all_regions[@]}"; do
if [[ "$region" == *"$filter"* ]]; then
filtered_regions+=("$region")
fi
done
# Réajuster la sélection si nécessaire
if [ $selected -ge ${#filtered_regions[@]} ]; then
selected=0
fi
}
# Initialiser le filtre
filter_regions
while true; do
clear
echo -e "${BLUE}${BOLD}=== Sélection de région ===${NC}\n"
echo -e "${YELLOW}Configuration actuelle:${NC}"
echo "Région par défaut: $(gcloud config get-value functions/region 2>/dev/null || echo 'Non définie')"
echo ""
echo -e "${YELLOW}Tapez pour filtrer, utilisez ↑↓ pour naviguer, Entrée pour sélectionner:${NC}"
echo -e "Filtre: ${BOLD}$filter${NC}"
echo ""
# Afficher les régions filtrées
if [ ${#filtered_regions[@]} -eq 0 ]; then
echo -e "${RED}Aucune région trouvée pour le filtre '$filter'${NC}"
else
for i in "${!filtered_regions[@]}"; do
if [ $i -eq $selected ]; then
echo -e "${GREEN}${filtered_regions[$i]}${NC}"
else
echo -e " ${filtered_regions[$i]}"
fi
done
fi
echo -e "\n${BLUE}Commandes: [Backspace] Effacer filtre | [Esc] Annuler${NC}"
# Lire une seule touche
read -rsn1 key
case $key in
$'\033') # Séquence d'échappement
read -rsn2 key
case $key in
'[A') # Flèche haut
if [ ${#filtered_regions[@]} -gt 0 ]; then
((selected--))
if [ $selected -lt 0 ]; then
selected=$((${#filtered_regions[@]}-1))
fi
fi
;;
'[B') # Flèche bas
if [ ${#filtered_regions[@]} -gt 0 ]; then
((selected++))
if [ $selected -ge ${#filtered_regions[@]} ]; then
selected=0
fi
fi
;;
esac
;;
'') # Entrée
if [ ${#filtered_regions[@]} -gt 0 ]; then
local chosen_region="${filtered_regions[$selected]}"
if [[ "$chosen_region" == "← Retour au menu précédent" ]]; then
return 1
else
echo -e "\n${BLUE}Configuration de la région $chosen_region...${NC}"
if gcloud config set functions/region "$chosen_region" 2>/dev/null; then
echo -e "${GREEN}✓ Région configurée: $chosen_region${NC}"
echo -e "\n${BLUE}Nouvelle tentative de récupération des fonctions...${NC}"
sleep 2
return 0
else
echo -e "${RED}✗ Erreur lors de la configuration de la région${NC}"
read -p "Appuyez sur Entrée pour continuer..."
return 1
fi
fi
fi
;;
$'\177'|$'\b') # Backspace
if [ ${#filter} -gt 0 ]; then
filter="${filter%?}"
filter_regions
fi
;;
$'\e') # Escape
return 1
;;
*) # Caractère normal
if [[ "$key" =~ [a-zA-Z0-9-] ]]; then
filter="$filter$key"
filter_regions
fi
;;
esac
done
}
# Fonction pour spécifier une région et réessayer (version simplifiée)
specify_region_and_retry() {
if select_region_interactive; then
delete_all_functions
fi
}
# Fonction pour supprimer toutes les Cloud Functions
delete_all_functions() {
# Ne pas clear ici pour garder les informations du menu principal visible
echo -e "${BLUE}Récupération des Cloud Functions du projet $CURRENT_PROJECT...${NC}"
# Obtenir toutes les fonctions (sans distinction Gen1/Gen2)
local all_functions=()
local function_names=()
local function_regions=()
echo -e "\n${YELLOW}Recherche de toutes les Cloud Functions...${NC}"
# Récupérer tous les noms de fonctions avec leurs régions
while read -r line; do
if [[ -n "$line" && "$line" != *"NAME"* ]]; then
# Extraire le nom et la région de la fonction
name=$(echo "$line" | awk '{print $1}')
region=$(echo "$line" | awk '{print $4}')
if [[ -n "$name" && "$name" != "NAME" && -n "$region" ]]; then
function_names+=("$name")
function_regions+=("$region")
all_functions+=("$name ($region)")
fi
fi
done < <(gcloud functions list --format="table(name,state,trigger,region)" 2>/dev/null | tail -n +2)
echo -e "${GREEN}Total des fonctions trouvées: ${#function_names[@]}${NC}\n"
if [ ${#function_names[@]} -eq 0 ]; then
echo -e "${YELLOW}Aucune Cloud Function trouvée dans le projet $CURRENT_PROJECT.${NC}"
echo -e "${YELLOW}Cela peut être dû à:${NC}"
echo -e " • Aucune fonction déployée"
echo -e " • Fonctions dans une région non configurée"
echo -e " • APIs Cloud Functions/Cloud Run non activées"
echo -e " • Permissions insuffisantes"
echo ""
local debug_options=("Afficher les informations de débogage" "Spécifier une région" "← Retour au menu principal")
echo "Que souhaitez-vous faire ?\n"
show_menu "${debug_options[@]}"
local debug_choice=$?
case $debug_choice in
0) # Afficher debug
show_functions_debug_info
read -p "Appuyez sur Entrée pour continuer..."
;;
1) # Spécifier région
specify_region_and_retry
;;
2) # Retour
return
;;
esac
return
fi
echo -e "\n${YELLOW}${BOLD}Fonctions trouvées (${#function_names[@]}):${NC}"
for func in "${function_names[@]}"; do
echo -e " • $func"
done
echo -e "\n${RED}${BOLD}⚠️ ATTENTION: Cette action supprimera TOUTES les Cloud Functions du projet!${NC}"
echo -e "${RED}Cette action est IRRÉVERSIBLE!${NC}\n"
local confirm_options=("Oui, supprimer toutes les fonctions" "Non, annuler")
show_menu "${confirm_options[@]}"
local confirm=$?
if [ $confirm -eq 0 ]; then
echo -e "\n${RED}Suppression en cours...${NC}\n"
local success_count=0
local error_count=0
# Supprimer toutes les fonctions avec leur région spécifique
for i in "${!function_names[@]}"; do
local func="${function_names[$i]}"
local region="${function_regions[$i]}"
echo -e "Suppression de: ${BOLD}$func${NC} (région: $region)"
# Capturer l'erreur détaillée avec la région spécifique
local error_output
error_output=$(gcloud functions delete "$func" --region="$region" --quiet 2>&1)
local exit_code=$?
if [ $exit_code -eq 0 ]; then
echo -e "${GREEN}$func supprimée${NC}"
((success_count++))
else
echo -e "${RED}✗ Erreur lors de la suppression de $func${NC}"
echo -e "${RED} Détail: $error_output${NC}"
((error_count++))
fi
# Petite pause pour éviter les erreurs de rate limiting
sleep 0.5
done
echo -e "\n${BOLD}Résumé:${NC}"
echo -e "${GREEN}• Fonctions supprimées: $success_count${NC}"
if [ $error_count -gt 0 ]; then
echo -e "${RED}• Erreurs: $error_count${NC}"
echo -e "${YELLOW}Il y a eu des erreurs lors de la suppression.${NC}"
echo -e "${YELLOW}Vérifiez les permissions et l'état des fonctions.${NC}"
echo -e "${YELLOW}Les erreurs détaillées sont affichées ci-dessus.${NC}"
else
echo -e "${GREEN}Toutes les fonctions ont été supprimées avec succès!${NC}"
fi
echo -e "\n${BLUE}Appuyez sur Entrée pour continuer...${NC}"
read -r
else
echo -e "\n${YELLOW}Suppression annulée.${NC}"
echo -e "\n${BLUE}Appuyez sur Entrée pour continuer...${NC}"
read -r
fi
read -p "Appuyez sur Entrée pour continuer..."
}
# Fonction principale
main() {
clear
check_gcloud
while true; do
get_current_project
local main_options=()
if [ "$CURRENT_PROJECT" != "Aucun" ]; then
main_options=("Supprimer toutes les Cloud Functions" "Changer de projet" "Se connecter à GCP" "Quitter")
else
main_options=("Changer de projet" "Se connecter à GCP" "Quitter")
fi
show_menu "${main_options[@]}"
local choice=$?
if [ "$CURRENT_PROJECT" != "Aucun" ]; then
case $choice in
0) # Supprimer toutes les fonctions
delete_all_functions
;;
1) # Changer de projet
select_project
;;
2) # Se connecter à GCP
handle_authentication
;;
3) # Quitter
echo -e "\n${YELLOW}Au revoir!${NC}"
exit 0
;;
esac
else
case $choice in
0) # Changer de projet
select_project
;;
1) # Se connecter à GCP
handle_authentication
;;
2) # Quitter
echo -e "\n${YELLOW}Au revoir!${NC}"
exit 0
;;
esac
fi
done
}
# Gestion des signaux pour un arrêt propre
trap 'echo -e "\n${YELLOW}Script interrompu.${NC}"; exit 0' INT TERM
# Lancement du script
main