-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathcbping.py
More file actions
306 lines (224 loc) · 11.4 KB
/
cbping.py
File metadata and controls
306 lines (224 loc) · 11.4 KB
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
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
# !/usr/bin/env python # uncomment to make life easier on sh-compatible systems.
import json
import requests
import sys
import socket
import time
import pprint
from requests.auth import HTTPBasicAuth
import argparse
parser = argparse.ArgumentParser()
#set up the four arguments that can be passed into the script from the command line.
#parser.add_argument('-P', '--port', help='Server port to test.', type=int, required=True)
parser.add_argument('-P', '--port', help='Server port to test.', type=int, required=False, default=8091)
parser.add_argument('-b', '--bucketname', dest='bucketname', help='The name of the bucket to insert into.', action='store_true')
parser.add_argument('-H', '--hostname', dest='hostname', help='Host name or IP Address of Couchbase cluster', required=True)
parser.add_argument('-u', '--username', dest='username', help='Administrative username.', required=False, default='Administrator')
parser.add_argument('-p', '--password', dest='password', help='Administrative password.', required=False, default='password')
parser.add_argument('-c', '--cluster', dest='clusterMode', help='Check the whole cluster?', default=False, action='store_true')
parser.add_argument('-s', '--single-node', dest='singleNodeMode', help='Only check a single node?', default=False, action='store_true')
parser.add_argument('-rc', '--rcluster', dest='rcluster', help='Check connectivity to XDCR clusters', default=False, action='store_true')
parser.add_argument('-v', '--verbose', dest='beverbose', help='Be verbose', default=False, action='store_true')
args = parser.parse_args()
pprinter = pprint.PrettyPrinter(indent=4)
# This helpful function came from
# http://stackoverflow.com/questions/33489209/print-unique-json-keys-in-dot-notation-using-python
def walk_keys(obj, path=""):
if isinstance(obj, dict):
for k, v in obj.iteritems():
for r in walk_keys(v, path + "." + k if path else k):
yield r
elif isinstance(obj, list):
for i, v in enumerate(obj):
s = "[" + str(i) + "]"
for r in walk_keys(v, path + s if path else s):
yield r
else:
yield path
def testPortsOnNode(nodeWithAHostname):
currentHostname = nodeWithAHostname['hostname']
hostnamepart, justThePort = currentHostname.split(":", 1)
# For reference please see http://developer.couchbase.com/documentation/server/current/install/install-ports.html
allThePorts = (justThePort, 8092, 8093, 8094, 9100, 9102, 9103, 9104, 9105, 9998, 9999, 11207, 11209, 11210, 11211, 11214, 11215, 18091, 18092, 18093, 4369, 21100)
portsDesc = [ "Console REST/HTTP", # 8091 (default)
"Views, queries, XDCR, design documents", # 8092
"Query services REST/HTTP", # 8093
"Search service external HTTP", # 8094
"Internal index admin", # 9100
"Internal index HTTP", # 9102
"Internal index build", # 9103
"Internal index build", # 9104
"Internal index maintenance", # 9105
"Internal REST", # 9998
"Internal GSI for internal admins", # 9999
"Memcached SSL for smart client libraries", # 11207
"Internal Bucket", # 11209
"Memcached for smart client lib or Moxi", # 11210
"Pre-existing Couchbase Server & memcached (non-smart) client libraries (such as Moxi)", # 11211
"SSL XDCR data encryption", # 11214
"SSL XDCR data encryption", # 11215
"Web Console SSL REST/HTTP traffic", # 18091
"SSL for views access, run queries, XDCR & update design documents", # 18092
"N1QL SSL", # 18093
"Erlang Port Mapper", # 4369
"Node data exchange" # 21100 to 21299 (inclusive)
]
if args.beverbose:
formatString3 = "%-20s %-10s %-39s %-15s %-20s"
print (formatString3 % ("Hostname", "Port", "Result", "Elapsed Time*", "Description"))
print (formatString3 % ("--------", "----", "------", "------------", "-----------" ))
else:
formatString3 = "%-20s %-10s %-39s %-15s"
print (formatString3 % ("Hostname", "Port", "Result", "Elapsed Time*"))
print (formatString3 % ("--------", "----", "------", "------------"))
testLoop = 0
for eachPortToTest in allThePorts:
eachaddress2 = (hostnamepart, int(eachPortToTest))
sock2 = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock2.settimeout(10)
t1 = time.clock()
t2 = 0
elapsed = 0
msg = "-"
try:
sock2.connect(eachaddress2)
msg = "SUCCESS"
except Exception as e:
msg = str(e)
finally:
t2 = time.clock()
#get the elapsed time and convert to microseconds
elapsed = (t2 - t1) * 1000000
#elapsed = "%.6f" % (t2 - t1)
sock2.close()
if args.beverbose:
print (formatString3 % (hostnamepart, eachPortToTest, msg, str(elapsed), portsDesc[testLoop]))
else:
print (formatString3 % (hostnamepart, eachPortToTest, msg, str(elapsed)))
testLoop += 1
print "*Elapsed time is in microseconds."
#Test XDCR cluster if requested to
def checkRemoteCluster():
print '---------- Remote Clusters (XDCR) ----------'
remoteClusters = json_dict['remoteClusters']
# Remote Clusters Requires Authentication otherwise you get a 401 Unauthorized
remoteClustersUriEnd = remoteClusters['uri']
remoteClustersUri = 'http://' + args.hostname + ':' + str(args.port) + remoteClustersUriEnd
print
print 'I will get the info from: ' + remoteClustersUri
remoteclusters = requests.get(remoteClustersUri,auth=HTTPBasicAuth(args.username, args.password))
rchttpstatuscode = remoteclusters.status_code
if (rchttpstatuscode == 200):
print
rcResponsejson = remoteclusters.json()
# Useful for JSON reference
#for s in sorted(walk_keys(rcResponsejson)):
# print s
rcformatstring = "%-10s %-25s %-20s %-50s"
print (rcformatstring % ('deleted', 'hostname', 'name', 'uri'))
print (rcformatstring % ('-------', '--------', '----', '---'))
# rcformatstring = "%-10s %-25s %-20s %-50s %-20s %-35s %-20s"
# print (rcformatstring % ('deleted', 'hostname', 'name', 'uri', 'username', 'uuid', 'validateURI'))
# print (rcformatstring % ('-------', '--------', '----', '---', '--------', '----', '-----------'))
rcresponsetext = remoteclusters.text
rcjson_dict = json.loads(rcresponsetext)
for eachrc in rcjson_dict:
# print (rcformatstring % (str(eachrc['deleted']), eachrc['hostname'], eachrc['name'], eachrc['uri'], eachrc['username'], eachrc['uuid'], eachrc['validateURI']))
print (rcformatstring % (str(eachrc['deleted']), eachrc['hostname'], eachrc['name'], eachrc['uri']))
print
for eachrc in rcjson_dict:
# print 'Working on Remote Cluster host: ' + eachrc['hostname']
testPortsOnNode(eachrc)
print
else:
print 'RC: Got http error code:' + str(rchttpstatuscode)
#############################################
if (args.clusterMode == True):
print 'I see that you want cluster mode'
if (args.singleNodeMode == True):
print 'I see that you want single-node mode'
if ((args.clusterMode == False) and (args.singleNodeMode == False)):
print 'I will assume that you meant cluster mode'
# Look at the command line arguments
httpstatuscode = 0
poolsdefaulturl = 'http://' + args.hostname + ':' + str(args.port) + '/pools/default'
# Okay lets get started
if (args.singleNodeMode == True):
singleNodeDict = dict()
singleNodeDict['hostname'] = args.hostname + ':' + str(args.port)
testPortsOnNode(singleNodeDict)
sys.exit(0)
# Cluster mode
print 'I will connect to: ' + poolsdefaulturl + ' and run some tests.'
poolsdefault = requests.get(poolsdefaulturl,auth=HTTPBasicAuth(args.username, args.password))
#httpstatuscode = poolsdefault.status_code
if (poolsdefault.status_code == 200):
# print 'I was able to connect and get a response'
responsejson = poolsdefault.json()
# Useful for JSON reference
#for s in sorted(walk_keys(responsejson)):
# print s
responsetext = poolsdefault.text
json_dict = json.loads(responsetext)
name = json_dict['name']
#print
#print 'The name of the node I connected to is: ' + name
nodes = json_dict['nodes']
print 'This cluster says there are ' + str(len(nodes)) + ' nodes in the cluster.'
#print type(nodes)
formattingstring = "%-30s %-15s %-30s"
print
print (formattingstring % ('Cluster Node','Node Status', 'Node CB version'))
print (formattingstring % ('------------','-----------', '---------------'))
for eachNode in nodes:
print (formattingstring % (eachNode['hostname'] , eachNode['status'], eachNode['version']))
print
# print 'I will now check each of these nodes:'
for eachNode in nodes:
eachHostname = eachNode['hostname']
testPortsOnNode(eachNode)
print
# Done iterating over the nodes in the first http get
#Do we check remote clusters or not?
if (args.rcluster == True):
checkRemoteCluster()
# Move on to the next uri
print '-------------- Bucket Information --------------'
poolsdefaultbucketsurl = 'http://' + args.hostname + ':' + str(args.port) + '/pools/default/buckets'
print
print 'I will get bucket info from: ' + poolsdefaultbucketsurl
poolsdefaultbuckets = requests.get(poolsdefaultbucketsurl)
pdbhttpstatuscode = poolsdefaultbuckets.status_code
if (pdbhttpstatuscode == 200):
# print 'PDB: It worked'
pdbresponsejson = poolsdefaultbuckets.json()
# Useful for JSON reference
#for s in sorted(walk_keys(pdbresponsejson)):
# print s
pdbresponsetext = poolsdefaultbuckets.text
pdbjson_dict = json.loads(pdbresponsetext)
print
rcformatstring = "%-20s %-10s %-15s"
print (rcformatstring % ('Bucket Name', 'itemCount', 'Bucket Type'))
print (rcformatstring % ('-----------', '---------', '-----------'))
for bucket in pdbjson_dict:
bucketnodes = bucket['nodes']
basicStats = bucket['basicStats']
itemCount = basicStats['itemCount']
bucketType = bucket['bucketType']
if (bucketType == 'membase'):
bucketType = 'Couchbase'
print (rcformatstring % (bucket['name'], itemCount, bucketType))
for bucketNode in bucketnodes:
hostname = bucketNode['hostname']
# print hostname
replication = bucketNode['replication']
# print replication
else:
print 'PDB: Got http error code:' + str(httpstatuscode)
# end of section where first http get was successful
else:
print 'PD: Got http error code:' + str(httpstatuscode)
print
print 'Goodbye'
# EOF