Skip to content

Instantly share code, notes, and snippets.

@thedoc31
Last active November 7, 2022 12:53
Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save thedoc31/628beeee934f9c84648c108d4ad89f05 to your computer and use it in GitHub Desktop.
Save thedoc31/628beeee934f9c84648c108d4ad89f05 to your computer and use it in GitHub Desktop.
Bash script to batch Import dashboard JSON files into Grafana. Verified working on v6.3. This script is based on the Grafana dashboard export script originated on https://gist.github.com/crisidev/bd52bdcc7f029be2f295
#!/bin/bash
#
# add the "-x" option to the shebang line if you want a more verbose output
#
#
OPTSPEC=":hp:t:k:"
show_help() {
cat << EOF
Usage: $0 [-p PATH] [-t TARGET_HOST] [-k API_KEY]
Script to import dashboards into Grafana
-p Required. Root path containing JSON exports of the dashboards you want imported.
-t Required. The full URL of the target host
-k Required. The API key to use on the target host
-h Display this help and exit.
EOF
}
###### Check script invocation options ######
while getopts "$OPTSPEC" optchar; do
case "$optchar" in
h)
show_help
exit
;;
p)
DASH_DIR="$OPTARG";;
t)
HOST="$OPTARG";;
k)
KEY="$OPTARG";;
\?)
echo "Invalid option: -$OPTARG" >&2
exit 1
;;
:)
echo "Option -$OPTARG requires an argument." >&2
exit 1
;;
esac
done
if [ -z "$DASH_DIR" ] || [ -z "$HOST" ] || [ -z "$KEY" ]; then
show_help
exit 1
fi
# set some colors for status OK, FAIL and titles
SETCOLOR_SUCCESS="echo -en \\033[0;32m"
SETCOLOR_FAILURE="echo -en \\033[1;31m"
SETCOLOR_NORMAL="echo -en \\033[0;39m"
SETCOLOR_TITLE_PURPLE="echo -en \\033[0;35m" # purple
# usage log "string to log" "color option"
function log_success() {
if [ $# -lt 1 ]; then
${SETCOLOR_FAILURE}
echo "Not enough arguments for log function! Expecting 1 argument got $#"
exit 1
fi
timestamp=$(date "+%Y-%m-%d %H:%M:%S %Z")
${SETCOLOR_SUCCESS}
printf "[%s] $1\n" "$timestamp"
${SETCOLOR_NORMAL}
}
function log_failure() {
if [ $# -lt 1 ]; then
${SETCOLOR_FAILURE}
echo "Not enough arguments for log function! Expecting 1 argument got $#"
exit 1
fi
timestamp=$(date "+%Y-%m-%d %H:%M:%S %Z")
${SETCOLOR_FAILURE}
printf "[%s] $1\n" "$timestamp"
${SETCOLOR_NORMAL}
}
function log_title() {
if [ $# -lt 1 ]; then
${SETCOLOR_FAILURE}
log_failure "Not enough arguments for log function! Expecting 1 argument got $#"
exit 1
fi
${SETCOLOR_TITLE_PURPLE}
printf "|-------------------------------------------------------------------------|\n"
printf "|%s|\n" "$1";
printf "|-------------------------------------------------------------------------|\n"
${SETCOLOR_NORMAL}
}
if [ -d "$DASH_DIR" ]; then
DASH_LIST=$(find "$DASH_DIR" -mindepth 1 -name \*.json)
if [ -z "$DASH_LIST" ]; then
log_title "----------------- $DASH_DIR contains no JSON files! -----------------"
log_failure "Directory $DASH_DIR does not appear to contain any JSON files for import. Check your path and try again."
exit 1
else
FILESTOTAL=$(echo "$DASH_LIST" | wc -l)
log_title "----------------- Starting import of $FILESTOTAL dashboards -----------------"
fi
else
log_title "----------------- $DASH_DIR directory not found! -----------------"
log_failure "Directory $DASH_DIR does not exist. Check your path and try again."
exit 1
fi
NUMSUCCESS=0
NUMFAILURE=0
COUNTER=0
for DASH_FILE in $DASH_LIST; do
COUNTER=$((COUNTER + 1))
echo "Import $COUNTER/$FILESTOTAL: $DASH_FILE..."
RESULT=$(cat "$DASH_FILE" | jq '. * {overwrite: true, dashboard: {id: null}}' | curl -s -X POST -H "Content-Type: application/json" -H "Authorization: Bearer $KEY" "$HOST"/api/dashboards/db -d @-)
if [[ "$RESULT" == *"success"* ]]; then
log_success "$RESULT"
NUMSUCCESS=$((NUMSUCCESS + 1))
else
log_failure "$RESULT"
NUMFAILURE=$((NUMFAILURE + 1))
fi
done
log_title "Import complete. $NUMSUCCESS dashboards were successfully imported. $NUMFAILURE dashboard imports failed.";
log_title "------------------------------ FINISHED ---------------------------------";
@Pobek
Copy link

Pobek commented Sep 2, 2019

Would add the option to supply a basic authentication. Other than that, good script!

@thedoc31
Copy link
Author

thedoc31 commented Sep 3, 2019

Thank you! Will consider adding that in the future; didn't add it to this script as the export script I based it from only uses an API key.

@Aminechakr
Copy link

Aminechakr commented Aug 5, 2020

Hello,
I was in need to do that because of our project, providing a lot of grafana consumer's a step on their pipeline that can let them import dashboards with only providing there grafana user/password and the host, the script is managing the generation of a random Api_KEY that leaves only 1hour, it's a little module that i've added, hope tihs be useful for someone 👍

#!/bin/bash
#
# add the "-x" option to the shebang line if you want a more verbose output
#
# 

#set -x 
#set +x
OPTSPEC=":hp:t:u:w:"

show_help() {
cat << EOF
Usage: $0 [-u Grafana_User] [-w Grafana_Password] [-p PATH] [-t TARGET_HOST]
Script to import dashboards into Grafana
    -u      Required. Grafana User
    -w      Required. Grafana Password
    -p      Required. Root path containing JSON exports of the dashboards you want imported.
    -t      Required. The full URL of the target host
    
    -h      Display this help and exit.
EOF
}

###### Check script invocation options ######
while getopts "$OPTSPEC" optchar; do
    case "$optchar" in
        h)
            show_help
            exit
            ;;
        p)
            DASH_DIR="$OPTARG";;
        t)
            TARGET_HOST="$OPTARG";;
        u)
            GRAFANA_USER="$OPTARG";;
        w)
            GRAFANA_PASSWORD="$OPTARG";;
        \?)
          echo "Invalid option: -$OPTARG" >&2
          exit 1
          ;;
        :)
          echo "Option -$OPTARG requires an argument." >&2
          exit 1
          ;;
    esac
done

if [ -z "$DASH_DIR" ] || [ -z "$TARGET_HOST" ] || [ -z "$GRAFANA_USER" ] || [ -z "$GRAFANA_PASSWORD" ]; then
    show_help
    exit 1
fi

# set some colors for status OK, FAIL and titles
SETCOLOR_SUCCESS="echo -en \\033[0;32m"
SETCOLOR_FAILURE="echo -en \\033[1;31m"
SETCOLOR_NORMAL="echo -en \\033[0;39m"
SETCOLOR_TITLE_PURPLE="echo -en \\033[0;35m" # purple 

# usage log "string to log" "color option"
function log_success() {
   if [ $# -lt 1 ]; then
       ${SETCOLOR_FAILURE}
       echo "Not enough arguments for log function! Expecting 1 argument got $#"
       exit 1
   fi

   timestamp=$(date "+%Y-%m-%d %H:%M:%S %Z")

   ${SETCOLOR_SUCCESS}
   printf "[%s] $1\n" "$timestamp"
   ${SETCOLOR_NORMAL}
}

function log_failure() {
   if [ $# -lt 1 ]; then
       ${SETCOLOR_FAILURE}
       echo "Not enough arguments for log function! Expecting 1 argument got $#"
       exit 1
   fi

   timestamp=$(date "+%Y-%m-%d %H:%M:%S %Z")

   ${SETCOLOR_FAILURE}
   printf "[%s] $1\n" "$timestamp"
   ${SETCOLOR_NORMAL}
}

function log_title() {
   if [ $# -lt 1 ]; then
       ${SETCOLOR_FAILURE}
       log_failure "Not enough arguments for log function! Expecting 1 argument got $#"
       exit 1
   fi

   ${SETCOLOR_TITLE_PURPLE}
   printf "|------------------------------------------------------------------------------------------------------------------------|\n"
   printf "|%s|\n" "$1";
   printf "|------------------------------------------------------------------------------------------------------------------------|\n"
   ${SETCOLOR_NORMAL}
}

### API KEY GENERATION 

KEYNAME=$(head -3 /dev/urandom | tr -cd '[:alnum:]' | cut -c -7)
KEYLENGTH=70
GENERATE_POST_DATA="{\"name\": \"${KEYNAME}\", \"role\": \"Admin\", \"secondsToLive\": 3600 }"

if [ -n "$GRAFANA_USER" ] || [ -n "$GRAFANA_PASSWORD" ] || [ -n "$TARGET_HOST" ]; then
    KEY=$(curl -X POST -H "Content-Type: application/json" -d "${GENERATE_POST_DATA}" "https://"${GRAFANA_USER}":"${GRAFANA_PASSWORD}"@"${TARGET_HOST}"/api/auth/keys" | jq -r '.key')
    if [ ${#KEY} -ge $KEYLENGTH ]; then
        log_title "---- API Key Generated successfully, correct character number generated in API Key, we're going into the next step -----"
    else
        log_title "------------------------------------------------- API Key is not valid ! ----------------------------------------------"
        log_failure "$KEY does not contain the correct information to do API actions. Please Check, and try again."
        exit 1
        
    fi
else  
    log_title "----------------- One of the parameters is not correct -----------------"
    log_failure "Set correct parameters and try again."
    exit 1
fi

if [ -d "$DASH_DIR" ]; then
    DASH_LIST=$(find "$DASH_DIR" -mindepth 1 -name \*.json)
    if [ -z "$DASH_LIST" ]; then
        log_title "----------------- $DASH_DIR contains no JSON files! -----------------"
        log_failure "Directory $DASH_DIR does not appear to contain any JSON files for import. Check your path and try again."
        exit 1
    else
        FILESTOTAL=$(echo "$DASH_LIST" | wc -l)
        log_title "------------------------------------------- Starting import of $FILESTOTAL dashboards -------------------------------------------"
    fi
else
    log_title "----------------- $DASH_DIR directory not found! -----------------"
    log_failure "Directory $DASH_DIR does not exist. Check your path and try again."
    exit 1
fi

NUMSUCCESS=0
NUMFAILURE=0
COUNTER=0

for DASH_FILE in $DASH_LIST; do 
    COUNTER=$((COUNTER + 1))
    echo "Import $COUNTER/$FILESTOTAL: $DASH_FILE..."
    RESULT=$(cat "$DASH_FILE" | jq '. * {overwrite: true, dashboard: {id: null}}' | curl -s -X POST -H "Content-Type: application/json" -H "Authorization: Bearer $KEY" "https://$TARGET_HOST/api/dashboards/db" -d @-)
    if [[ "$RESULT" == *"success"* ]]; then
        log_success "$RESULT"
        NUMSUCCESS=$((NUMSUCCESS + 1))
    else
        log_failure "$RESULT"
        NUMFAILURE=$((NUMFAILURE + 1))
    fi
done

log_title "------------ Import complete. $NUMSUCCESS dashboards were successfully imported. $NUMFAILURE dashboard imports failed.------------";
log_title "-------------------------------------------------------- FINISHED ------------------------------------------------------";

@heinzz-da-ketchup
Copy link

Thank you both for this script, it has saved me a lot of time and worked great out-of-the box!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment