Skip to content
This repository was archived by the owner on Dec 12, 2023. It is now read-only.

Commit 988b4d3

Browse files
authored
Jlinoff 20210122 upload (#24)
PR-24: add upload-json-dashboard.sh Add upload-json-dashboard.sh tool to upload dashboards from the CLI.
1 parent 9605f48 commit 988b4d3

4 files changed

Lines changed: 315 additions & 1 deletion

File tree

README.md

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ Grafana Prototyping Environment
2929
1. [Postres](#postgres)
3030
1. [pgAdmin](#pgadmin)
3131
1. [runpga.sh](#runpgash)
32+
1. [upload-json-dashboard.sh](#upload-json-dashboardsh)
3233
1. [Acknowledgments](#acknowledgments)
3334

3435
</details>
@@ -454,6 +455,28 @@ When it completes it prints out the information necessary to
454455
login into the pgAdmin and connect to the database.
455456

456457

458+
#### upload-json-dashboard.sh
459+
There is a script called `tools/upload-json-dashboard.sh` that will upload
460+
a JSON dashboard to a Grafana server from the command line.
461+
462+
The upload is limited to servers with simple authentication based on a
463+
username and password unless you override it using `-x` and `-n`.
464+
465+
The local dashboard JSON file is creatined by exporting the dashboard
466+
from the Grafana UI with the "Export for sharing externally" checkbox
467+
checked.
468+
469+
This script is useful for transferring a single dashboard from one
470+
server to another.
471+
472+
Although the same function can be accomplished in the UI, this script
473+
allows updates to be automated from the command line.
474+
475+
This script requires that "curl" is installed.
476+
477+
See the script help (`-h`) for more information and examples.
478+
479+
457480
### Acknowledgments
458481

459482
* Many thanks to Deron Ferguson for helping me track down and debug problems on windows 10.

grape/__version__

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
0.4.4
1+
0.4.5

tools/runpga.sh

100644100755
File mode changed.

tools/upload-json-dashboard.sh

Lines changed: 291 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,291 @@
1+
#!/usr/bin/env bash
2+
# shellcheck disable=SC2059
3+
#
4+
# This can be customized from the command line by setting the variable
5+
# values like this if jq is installed.
6+
#
7+
# $ ./upload-json-dashboard.sh -j external.json -d mypg -g 6300
8+
#
9+
# Or like this if it isn't.
10+
#
11+
# $ ./upload-json-dashboard.sh -j external.json -d mypg -g 6300 -n DS_EXTERNALPG
12+
#
13+
# Help is available, by specifying the -h option.
14+
#
15+
# Note that you can run grape status -v to see the available
16+
# servers.
17+
#
18+
# This script was linted by shellcheck.
19+
20+
# ================================================================
21+
# Functions
22+
# ================================================================
23+
function _help() {
24+
cat <<EOF
25+
USAGE
26+
$0 -h
27+
28+
DESCRIPTION
29+
Uploads a dashboard JSON file to a Grafana server.
30+
31+
The upload is limited to servers with simple authentication based
32+
on a username and password unless you override it using "-x" and
33+
"-n".
34+
35+
The local dashboard JSON file is created by exporting the
36+
dashboard from the Grafana UI with the "Export for sharing
37+
externally" checkbox checked.
38+
39+
This script is useful for transferring dashboards from one server
40+
to another.
41+
42+
Although the same function can be accomplished in the UI, this
43+
script allows updates to be automated from the command line.
44+
45+
This script requires that "curl" is installed.
46+
47+
OPTIONS
48+
-d NAME The Grafana data source name.
49+
50+
-f INT The Grafana dashboard parent folder id.
51+
If not specified, the top level is assumed.
52+
53+
-g PORT The Grafana URL prefix.
54+
An example might be something like:
55+
http://localhost:6300
56+
57+
-h This help message.
58+
59+
-i NAME The plugin id.
60+
The default is 'postgres'
61+
62+
-j FILE The dashboard JSON file to upload.
63+
64+
-n NAME The name of the Grafana datasource variable.
65+
If not specified, the name will be extracted
66+
from the JSON file if the jq program is present.
67+
68+
-N Do not use simple authentication.
69+
The user is expected to use the -x option to add extra
70+
data.
71+
72+
-p PASSWORD The Grafana password.
73+
Normally you would want to use -P to prompt with no
74+
echo.
75+
76+
-P Prompt for the Grafana password.
77+
78+
-u USERNAME The Grafana username.
79+
80+
-v Increase the level of verbosity.
81+
82+
-x STRING Add extra curl arguments.
83+
84+
EXAMPLES
85+
# Example 1.
86+
# Get help
87+
\$ $0 -h
88+
89+
# Example 2.
90+
# Upload to a grape Grafana server.
91+
# The -u and -p options do not need to be specified.
92+
# Pipe the curl output in jq to make it more readable.
93+
# They are only shown for clarity.
94+
\$ grape server -v # find the port
95+
\$ $0 -u admin -p admin -g http://localhost:6400 -j x.json -d mypg -n DS_MYDB | jq
96+
97+
# Example 3.
98+
# Upload to a grape Grafana server.
99+
# Pipe the curl output in jq to make it more readable.
100+
# Use your own auth.
101+
\$ grape server -v # find the port
102+
\$ $0 -g http://localhost:6400 -j x.json -d mypg -N -x '-u admin:admin' -n DS_MYDB | jq
103+
104+
EOF
105+
exit 0
106+
}
107+
108+
# ================================================================
109+
# Constants.
110+
# ================================================================
111+
ERRFMT='\x1b[31mERROR:%d: %s\x1b[0m\n'
112+
113+
# ================================================================
114+
# Command line argument processing.
115+
# ================================================================
116+
set -e
117+
DASH_AUTH=1
118+
DASH_DS=
119+
DASH_EXTRA_CURL=()
120+
DASH_FOLDER=0
121+
DASH_JSON=
122+
DASH_NAME=
123+
DASH_PLUGIN='postgres'
124+
DASH_PASSWORD='admin'
125+
DASH_USERNAME='admin'
126+
DASH_URL=
127+
VERBOSE=0
128+
129+
while getopts ':f:hd:g:i:j:n:Np:Pu:vx:' options ; do
130+
case ${options} in
131+
h )
132+
_help
133+
;;
134+
d )
135+
DASH_DS=${OPTARG}
136+
;;
137+
f )
138+
DASH_FOLDER=${OPTARG}
139+
;;
140+
g )
141+
DASH_URL=${OPTARG}
142+
;;
143+
i )
144+
DASH_PLUGIN=${OPTARG}
145+
;;
146+
j )
147+
DASH_JSON=${OPTARG}
148+
;;
149+
n )
150+
DASH_NAME=${OPTARG}
151+
;;
152+
N )
153+
DASH_AUTH=0
154+
;;
155+
p )
156+
DASH_PASSWORD=${OPTARG}
157+
;;
158+
P )
159+
read -r -p 'Password: ' -s DASH_PASSWORD
160+
printf '\n'
161+
;;
162+
u )
163+
DASH_USERNAME=${OPTARG}
164+
;;
165+
v )
166+
VERBOSE=$(( VERBOSE + 1 ))
167+
;;
168+
x )
169+
DASH_EXTRA_CURL=("${OPTARG//[ ]/}")
170+
;;
171+
'?' )
172+
printf "$ERRFMT" $LINENO "invalid option: -$OPTARG" 1>&2
173+
exit 1
174+
;;
175+
esac
176+
done
177+
shift $((OPTIND -1))
178+
179+
# ================================================================
180+
# Check required options.
181+
# ================================================================
182+
if [ -n "$DASH_JSON" ] && [ -z "$DASH_NAME" ] ; then
183+
if jq --version &>/dev/null ; then
184+
# If jq is available, extract the variable name.
185+
DASH_NAME=$(jq '.__inputs[0].name' "$DASH_JSON" | awk -F'"' '{print $2}')
186+
fi
187+
fi
188+
# need bash 4 or later
189+
BASH_MAJOR=$(echo "$BASH_VERSION" | awk -F. '{print $1}')
190+
if (( BASH_MAJOR < 4 )) ; then
191+
# Need 4 or later to support "declare -A".
192+
printf "$ERRFMT" $LINENO "this version of bash is too old, must be 4 or later: $BASH_VERSION" 1>&2
193+
exit 1
194+
fi
195+
196+
ERRCNT=0
197+
declare -A ROPTS=( ['-d']="$DASH_DS" ['-j']="$DASH_JSON" ['-g']="$DASH_URL" ['-n']="$DASH_NAME")
198+
for RKEY in "${!ROPTS[@]}" ; do
199+
RVAL=${ROPTS[$RKEY]}
200+
if [ -z "$RVAL" ] ; then
201+
printf "$ERRFMT" \
202+
$LINENO \
203+
"missing required option: '$RKEY', see the help (-h) for more information" \
204+
1>&2
205+
ERRCNT=$(( ERRCNT += 1))
206+
fi
207+
done
208+
if (( ERRCNT )) ; then exit 1 ; fi
209+
210+
# ================================================================
211+
# Report the setup.
212+
# ================================================================
213+
if (( VERBOSE )) ; then
214+
cat <<EOF
215+
Setup
216+
BASH_VERSION : $BASH_VERSION
217+
DASH_AUTH : $DASH_AUTH
218+
DASH_DS : $DASH_DS
219+
DASH_FOLDER : $DASH_FOLDER
220+
DASH_JSON : $DASH_JSON
221+
DASH_NAME : $DASH_NAME
222+
DASH_URL : $DASH_URL
223+
DASH_USERNAME : $DASH_USERNAME
224+
DASH_EXTRA_CURL : ${DASH_EXTRA_CURL[@]}
225+
VERBOSE : $VERBOSE
226+
EOF
227+
fi
228+
229+
# ================================================================
230+
# Other prerequisite checks.
231+
# ================================================================
232+
if [ ! -f "$DASH_JSON" ] ; then
233+
printf "$ERRFMT" $LINENO "file does not exist: $DASH_JSON" 1>&2
234+
exit 1
235+
fi
236+
if ! grep '"__inputs"' "$DASH_JSON" &>/dev/null ; then
237+
printf "$ERRFMT" $LINENO "missing required record '__inputs' in $DASH_JSON" 1>&2
238+
exit 1
239+
fi
240+
if ! curl --version &>/dev/null ; then
241+
printf "$ERRFMT" $LINENO "curl is not installed, cannot continue" 1>&2
242+
exit 1
243+
fi
244+
245+
# ================================================================
246+
# Create the JSON with the variables set.
247+
#
248+
# Note the the "inputs" record MUST appear before the "dashboard"
249+
# record because the import operation picks up the first input
250+
# specification and ignores the rest.
251+
#
252+
# This is relevant because there are two sources of external variable
253+
# definitions in the dashboard description. The first is the "inputs"
254+
# record at the top level (shown below) and the other is the
255+
# "__inputs" record under each dashboard (not shown) which is created
256+
# by Grafana when it exports the dashboard. The top level definition
257+
# overrides all subsequent low level definitions which is why it must
258+
# appear first.
259+
# ================================================================
260+
cat >x.json <<EOF
261+
{
262+
"inputs": [{
263+
"name": "${DASH_NAME}",
264+
"type": "datasource",
265+
"pluginId": "${DASH_PLUGIN}",
266+
"value": "${DASH_DS}"
267+
}],
268+
"dashboard": $(cat "${DASH_JSON}"),
269+
"folderId": ${DASH_FOLDER},
270+
"overwrite": true
271+
}
272+
EOF
273+
274+
# ================================================================
275+
# Upload to the Grafana server.
276+
# ================================================================
277+
if (( DASH_AUTH )) ; then
278+
AUTH=('-u' "${DASH_USERNAME}:${DASH_PASSWORD}")
279+
else
280+
AUTH=()
281+
fi
282+
if (( VERBOSE )) ; then set -x ; fi
283+
curl "${AUTH[@]}" "${DASH_EXTRA_CURL[@]}" \
284+
-s \
285+
-k \
286+
-X POST \
287+
-H "Accept: application/json" \
288+
-H "Content-Type: application/json" \
289+
-d @x.json \
290+
"${DASH_URL}"/api/dashboards/import
291+
if (( VERBOSE )) ; then { set +x; } 2>/dev/null ; fi

0 commit comments

Comments
 (0)