-
Notifications
You must be signed in to change notification settings - Fork 2
/
check_couchdb_replication.sh
executable file
·202 lines (184 loc) · 9.34 KB
/
check_couchdb_replication.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
#!/bin/bash
################################################################################
# Script: check_couchdb_replication.sh #
# Author: Claudio Kuenzler www.claudiokuenzler.com #
# Purpose: Monitor CouchDB replication #
# Licence: GPLv2 #
# Licence : GNU General Public Licence (GPL) http://www.gnu.org/ #
# This program is free software; you can redistribute it and/or #
# modify it under the terms of the GNU General Public License #
# as published by the Free Software Foundation; either version 2 #
# of the License, or (at your option) any later version. #
# #
# This program is distributed in the hope that it will be useful, #
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
# #
# GNU General Public License for more details. #
# #
# You should have received a copy of the GNU General Public License #
# along with this program; if not, write to the Free Software #
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA #
# 02110-1301, USA. #
# #
# (c) 2018, 2022 Claudio Kuenzler #
# #
# History: #
# 20180105: Created plugin #
# 20180108: Added -d detection #
# 20180108: Handle connection problems properly #
# 20180326: Input sanitation (either -d or -r are required) #
# 20180326: Avoid confusion about wrong credentials (issue 4) #
# 20180326: Add possibility to check all replications at once (-r ALL) #
# 20180326: Handle authentication error "You are not a server admin." #
# 20220221: Replace jshon with jq #
# 20220221: Improve output of detected replications #
# 20220222: Handle "One Time" replications, add -i parameter (issue #5) #
# 20220222: Improve all HTTP requests with a dedicated function #
# 20220223: Add (basic) performance data when checking ALL replications #
################################################################################
#Variables and defaults
STATE_OK=0 # define the exit code if status is OK
STATE_WARNING=1 # define the exit code if status is Warning
STATE_CRITICAL=2 # define the exit code if status is Critical
STATE_UNKNOWN=3 # define the exit code if status is Unknown
export PATH=$PATH:/usr/local/bin:/usr/bin:/bin # Set path
port=5984
protocol=http
ignore_one_time=true
################################################################################
#Functions
help () {
echo -e "$0 (c) 2018-$(date +%Y) Claudio Kuenzler et al (published under GPL licence)
Usage: ./check_couchdb_replication.sh -H MyCouchDBHost [-P port] [-S] [-u user] [-p pass] (-r replication|-d)
Options:
* -H Hostname or ip address of CouchDB Host (or Cluster IP)
-P Port (defaults to 5984)
-S Use https
-u Username if authentication is required
-p Password if authentication is required
** -r Replication ID to monitor (doc_id) or use 'ALL' for all replications
** -d Dynamically detect and list all available replications
-i Include 'One time' replications in alerting
-h Help!
*-H is mandatory for all ways of running the script
**-r is mandatory to check a defined replication (doc_id or ALL)
**-d is mandatory if no replication check (-r) is set
Requirements: curl, jq, tr"
exit $STATE_UNKNOWN;
}
authlogic () {
if [[ -z $user ]] && [[ -z $pass ]]; then echo "COUCHDB REPLICATION UNKNOWN - Authentication required but missing username and password"; exit $STATE_UNKNOWN
elif [[ -n $user ]] && [[ -z $pass ]]; then echo "COUCHDB REPLICATION UNKNOWN - Authentication required but missing password"; exit $STATE_UNKNOWN
elif [[ -n $pass ]] && [[ -z $user ]]; then echo "COUCHDB REPLICATION UNKNOWN - Missing username"; exit $STATE_UNKNOWN
fi
}
httpget() {
url=$1
if [[ -n $user && -n $pass ]]
then authlogic; cdburl="${protocol}://${user}:${pass}@${host}:${port}${url}"
else cdburl="${protocol}://${host}:${port}${url}"
fi
cdbresp=$(curl -k -s $cdburl)
if [[ -n $(echo $cdbresp | grep -i "Name or password is incorrect") ]]; then
echo "COUCHDB REPLICATION CRITICAL - Unable to authenticate user $user"
exit $STATE_CRITICAL
elif [[ -n $(echo $cdbresp | grep -i "401 Authorization Required") ]]; then
echo "COUCHDB REPLICATION CRITICAL - Unable to authenticate user $user"
exit $STATE_CRITICAL
elif [[ -n $(echo $cdbresp | grep -i "You are not a server admin") ]]; then
echo "COUCHDB REPLICATION CRITICAL - You are not a server admin"
exit $STATE_CRITICAL
elif [[ -n $(echo $cdbresp | grep -i '"error":"not_found"') ]]; then
echo "COUCHDB REPLICATION CRITICAL - Unable to find replication ($url)"
exit $STATE_CRITICAL
elif [[ -z $cdbresp ]]; then
echo "COUCHDB REPLICATION CRITICAL - Unable to connect to CouchDB on ${protocol}://${host}:${port}"
exit $STATE_CRITICAL
fi
}
################################################################################
# Check requirements
for cmd in curl jq tr awk; do
if ! `which ${cmd} 1>/dev/null`; then
echo "UNKNOWN: ${cmd} does not exist, please check if command exists and PATH is correct"
exit ${STATE_UNKNOWN}
fi
done
################################################################################
# Check for people who need help - aren't we all nice ;-)
if [ "${1}" = "--help" -o "${#}" = "0" ]; then help; exit $STATE_UNKNOWN; fi
################################################################################
# Get user-given variables
while getopts "H:P:Su:p:r:di" Input;
do
case ${Input} in
H) host=${OPTARG};;
P) port=${OPTARG};;
S) protocol=https;;
u) user=${OPTARG};;
p) pass=${OPTARG};;
r) repid=${OPTARG};;
d) detect=1;;
i) ignore_one_time=false;;
*) help;;
esac
done
# Check for mandatory opts
if [ -z ${host} ]; then help; exit $STATE_UNKNOWN; fi
if [ -z ${detect} ] && [ -z ${repid} ]; then help; exit $STATE_UNKNOWN; fi
################################################################################
# If -d (detection) is used, present list of replications
if [[ ${detect} -eq 1 ]]; then
httpget "/_active_tasks"
replist=$(echo $cdbresp | jq -r '.[] | {doc_id, source} | join (" ")' | while read docid source; do echo "${docid} (${source})"; done | tr "\n" " ")
if [[ -n $replist ]]; then
echo "COUCHDB AVAILABLE REPLICATIONS: $replist"
exit $STATE_OK
else
echo "COUCHDB AVAILABLE REPLICATIONS: no replications found"
exit $STATE_WARNING
fi
fi
# Do the replication check for all replications
if [[ "${repid}" == "ALL" ]]; then
httpget "/_scheduler/docs/_replicator"
# Create stats array from response
declare -a successrepls=( $(echo "$cdbresp" | jq -r '.docs[] | select(.state == "running").doc_id') )
declare -a failedrepls=( $(echo "$cdbresp" | jq -r '.docs[] | select(.state != "running").doc_id') )
declare -a error_count=( $(echo "$cdbresp" | jq -r '.docs[] | select(.state != "running").error_count') )
declare -a state=( $(echo "$cdbresp" | jq -r '.docs[] | select(.state != "running").state') )
if [[ ${#failedrepls[*]} -gt 0 ]]; then
declare -a failedinfo=("")
r=0
for docid in ${failedrepls[*]}; do
#echo "Handling $docid" # Debug
if [[ $ignore_one_time == true ]]; then
httpget "/_replicator/${docid}"
continuous=$(echo "$cdbresp" | jq -r '.continuous' )
if [[ ${continuous} == false ]]; then
unset "failedrepls[${r}]"
fi
fi
failedinfo[${r}]="${docid} (state: ${state[${r}]}, error count: ${error_count[${r}]}) "
let r++
done
fi
if [[ ${#failedrepls[*]} -gt 0 ]]; then
echo "COUCHDB REPLICATION CRITICAL: ${#failedrepls[*]} continuous replications not running - Details: ${failedinfo[*]} | replok=${#successrepls[*]};;;; replfail=${#failedrepls[*]};;;;"
exit $STATE_CRITICAL
else
echo "COUCHDB REPLICATION OK - All ${#successrepls[*]} continuous replications running | replok=${#successrepls[*]};;;; replfail=${#failedrepls[*]};;;;"; exit $STATE_OK
fi
else
# Do the replication check for a single replication
httpget "/_scheduler/docs/_replicator/${repid}"
repstatus=$(echo $cdbresp | jq -r '.state')
if [[ "$repstatus" == "running" ]]; then
echo "COUCHDB REPLICATION OK - Replication $repid is $repstatus"
exit $STATE_OK
else
echo "COUCHDB REPLICATION CRITICAL - Replication $repid is $repstatus"
exit $STATE_CRITICAL
fi
fi