Last active
May 20, 2025 23:21
-
-
Save linuxmalaysia/2f2b633c0fc70d6026efafc1df90c1cf to your computer and use it in GitHub Desktop.
A Bash script to safely delete Elasticsearch indices. It prompts for user credentials, lists indices from a generated file (deletable_indices_YYYY.MM.txt), requires explicit confirmation, and provides post-deletion cluster health status. refer to check_deletable_verbose_robust.sh https://gist.github.com/linuxmalaysia/8d0e1997a3e4c24c0777062d7d91…
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# By Harisfazillah Jamel with Google Gemini Help | |
# 20250521 | |
# | |
# A Bash script to safely delete Elasticsearch indices. It prompts for user credentials, | |
# lists indices from a generated file (deletable_indices_YYYY.MM.txt), | |
# requires explicit confirmation, and provides post-deletion cluster health status. | |
# --- Configuration --- | |
ES_HOST="localhost:9200" | |
CERT_PATH="/etc/elasticsearch/certs/http_ca.crt" # Path to your CA certificate | |
# --- Prompt for Username and Password --- | |
read -p "Enter Elasticsearch username: " ES_USER | |
read -s -p "Enter Elasticsearch password: " ES_PASS | |
echo # Add a newline after password input | |
# --- Function to execute curl with authentication and certificate --- | |
execute_curl() { | |
local method="$1" | |
local endpoint="$2" | |
local data="$3" # Optional data for POST/PUT requests | |
if [[ -n "$data" ]]; then | |
curl -s --cacert "${CERT_PATH}" -u "${ES_USER}:${ES_PASS}" -X "${method}" "https://${ES_HOST}${endpoint}" -H 'Content-Type: application/json' -d "${data}" | |
else | |
curl -s --cacert "${CERT_PATH}" -u "${ES_USER}:${ES_PASS}" -X "${method}" "https://${ES_HOST}${endpoint}" | |
fi | |
} | |
# --- Main Deletion Logic --- | |
echo "" | |
echo "*******************************************************************************" | |
echo "** ELASTICSEARCH INDEX DELETION SCRIPT **" | |
echo "*******************************************************************************" | |
echo "" | |
echo "WARNING: This script will PERMANENTLY DELETE Elasticsearch indices." | |
echo " Ensure you have backed up any critical data and confirmed the" | |
echo " indices are no longer needed. This action is irreversible." | |
echo " We are not responsible for any data loss." | |
echo "" | |
# Ask for the input file containing deletable indices | |
read -p "Enter the path to the file with deletable index names (e.g., deletable_indices_2025.02.txt): " INPUT_FILE | |
if [[ ! -f "$INPUT_FILE" ]]; then | |
echo "Error: Input file '$INPUT_FILE' not found. Please ensure the file exists." | |
exit 1 | |
fi | |
# Review Indices Before Deletion | |
echo "" | |
echo "--- Indices to be processed for deletion from '$INPUT_FILE' ---" | |
echo "-------------------------------------------------------------------------------------" | |
# Corrected way to populate array: Use mapfile to read directly into array | |
# 'tail -n +3' skips the first 2 header lines. | |
# 'awk '{print $1}'' extracts the first column (index name). | |
# 'mapfile -t INDICES_TO_DELETE' reads each line of the piped output into the array. | |
mapfile -t INDICES_TO_DELETE < <(tail -n +3 "$INPUT_FILE" | awk '{print $1}') | |
# Now, loop through the populated array to display them | |
for index_name in "${INDICES_TO_DELETE[@]}"; do | |
if [[ -n "$index_name" ]]; then | |
echo "$index_name" # Display each index name on screen | |
fi | |
done | |
if [[ ${#INDICES_TO_DELETE[@]} -eq 0 ]]; then | |
echo "No valid index names found in '$INPUT_FILE' to delete. Exiting." | |
exit 0 | |
fi | |
echo "-------------------------------------------------------------------------------------" | |
echo "Total indices identified for deletion: ${#INDICES_TO_DELETE[@]}" | |
echo "" | |
# Confirm Deletion | |
# Confirm with the user before proceeding | |
read -p "Type 'DELETE' (all caps) to confirm deletion of the listed indices, or anything else to cancel: " CONFIRMATION | |
if [[ "$CONFIRMATION" != "DELETE" ]]; then | |
echo "Deletion cancelled by user. Exiting." | |
exit 0 | |
fi | |
# Starting Deletion Process | |
echo "" | |
echo "--- Starting Index Deletion ---" | |
echo "----------------------------------------------------" | |
# Now iterate through the array of indices we collected and delete them | |
for index_to_delete in "${INDICES_TO_DELETE[@]}"; do | |
echo "Attempting to delete index: ${index_to_delete}" | |
delete_response=$(execute_curl DELETE "/${index_to_delete}") | |
if echo "$delete_response" | grep -q '"acknowledged":true'; then | |
echo " SUCCESS: Index '${index_to_delete}' deleted." | |
else | |
echo " FAILED: Could not delete index '${index_to_delete}'. Response: ${delete_response}" | |
fi | |
# Optional: Add a small delay if you anticipate rate limiting or cluster strain | |
# sleep 0.05 | |
done | |
echo "----------------------------------------------------" | |
echo "Index deletion process complete." | |
echo "" | |
echo "It is recommended to run your 'check_deletable_verbose_robust.sh' script again" | |
echo "to verify the current state of your indices." | |
echo "*******************************************************************************" | |
--- | |
## Cluster Health Status | |
echo "" | |
echo "--- Fetching Elasticsearch Cluster Health Status ---" | |
echo "----------------------------------------------------" | |
CLUSTER_HEALTH_OUTPUT=$(execute_curl GET "/_cluster/health?pretty") | |
if [[ -z "$CLUSTER_HEALTH_OUTPUT" ]]; then | |
echo "Could not retrieve cluster health. Check network connectivity or Elasticsearch status." | |
else | |
# Extract and display key health metrics | |
CLUSTER_STATUS=$(echo "$CLUSTER_HEALTH_OUTPUT" | jq -r '.status') | |
NUMBER_OF_NODES=$(echo "$CLUSTER_HEALTH_OUTPUT" | jq -r '.number_of_nodes') | |
ACTIVE_SHARDS=$(echo "$CLUSTER_HEALTH_OUTPUT" | jq -r '.active_shards') | |
UNASSIGNED_SHARDS=$(echo "$CLUSTER_HEALTH_OUTPUT" | jq -r '.unassigned_shards') | |
echo "Cluster Name: $(echo "$CLUSTER_HEALTH_OUTPUT" | jq -r '.cluster_name')" | |
echo "Cluster Status: ${CLUSTER_STATUS}" | |
echo "Number of Nodes: ${NUMBER_OF_NODES}" | |
echo "Active Shards: ${ACTIVE_SHARDS}" | |
echo "Unassigned Shards: ${UNASSIGNED_SHARDS}" | |
# Provide a direct link to the full health output for detailed review | |
echo "" | |
echo "Full Cluster Health JSON:" | |
echo "$CLUSTER_HEALTH_OUTPUT" | |
fi | |
echo "----------------------------------------------------" | |
echo "Script finished." |
WARNING: This script identifies indices that may be deletable based on common criteria. However, it's crucial that you MANUALLY VERIFY the purpose and contents of each listed index before proceeding with any deletion. Indices related to Elasticsearch's internal functions, Kibana, or specific applications might be flagged as 'DELETABLE' but are essential for your cluster's operation.
**PROCEED WITH EXTREME CAUTION. We are not responsible for any data loss or operational issues resulting from the deletion of indices identified by this script.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.