-
Notifications
You must be signed in to change notification settings - Fork 3
/
cb_status.py
executable file
·162 lines (134 loc) · 5.42 KB
/
cb_status.py
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
#!/usr/bin/env - python
import tornado.escape
import tornado.gen
import tornado.httpclient
from tornado.httpclient import AsyncHTTPClient, HTTPRequest
from txcouchbase.bucket import Bucket
import settings
BOOTSTRAP_NODES = settings.CLUSTER_NODES
BUCKET_URL = "/pools/default/buckets"
NODE_URL = "/pools/default/serverGroups"
INDEX_URL = "/indexStatus"
SERVICE_URL = "/pools/default/nodeServices"
FTS_URL = "/api/index/cbex"
XDCR_URL = "/pools/default/remoteClusters"
USERNAME = settings.ADMIN_USER
PASSWORD = settings.ADMIN_PASS
bucket_name = settings.BUCKET_NAME
user = settings.USERNAME
password = settings.PASSWORD
aws = settings.AWS
bucket = Bucket('couchbase://{0}/{1}'.format(",".join(BOOTSTRAP_NODES),
bucket_name),
username=user,
password=password)
http_client = AsyncHTTPClient()
def get_image_for_product(product):
print("erm....get_image_for_product")
return None
@tornado.gen.coroutine
def get_url(endpoint, host_list=bucket.server_nodes, raise_exception=False):
exceptions = []
while True:
for host in host_list:
host = "http://" + host
target_url = host + endpoint
request = HTTPRequest(
url=target_url,
auth_username=USERNAME,
auth_password=PASSWORD,
auth_mode='basic', request_timeout=0.3)
try:
response = yield http_client.fetch(request)
raise tornado.gen.Return((tornado.escape.json_decode(response.body), host))
except tornado.httpclient.HTTPError as e:
print(("Could not retrieve URL: " + str(target_url) + str(e)))
exceptions.append(e)
if len(exceptions) == len(host_list) and raise_exception:
raise exceptions[0]
else:
exceptions = []
yield tornado.gen.sleep(1)
# Returns a list of nodes and their statuses
@tornado.gen.coroutine
def get_node_status():
default_status = {"hostname": "n/a", "ops": 0, "status": "out"}
node_list = [dict(default_status) for _ in range(5)]
if not aws:
node_list[0]['ops'] = 400
raise tornado.gen.Return(node_list)
kv_nodes = index = 0
node_response, _ = yield get_url(NODE_URL)
for node_info in node_response['groups'][0]['nodes']:
if "kv" in node_info['services']:
index = kv_nodes
kv_nodes += 1
elif "n1ql" in node_info['services']:
index = 3
elif "fts" in node_info['services']:
index = 4
node_list[index]['hostname'] = node_info['hostname']
# First check for nodes that are fully fledged members of the cluster
# And if they are KV nodes, check how many ops they're doing
if node_info['status'] == "healthy" and node_info[
'clusterMembership'] == "active":
node_list[index]['status'] = "ok"
if "kv" in node_info['services'] and 'cmd_get' in node_info[
'interestingStats']:
node_list[index]['ops'] = node_info['interestingStats']['cmd_get']
# Check for cluster members that are unhealthy (in risk of being failed)
# We will highlight these with a red border
elif node_info['clusterMembership'] == "active" and \
node_info['status'] == "unhealthy":
node_list[index]['status'] = "trouble"
# Then, nodes that are either failed over, warming up or not rebalanced in
# These will appear as faded
elif node_info['clusterMembership'] == "inactiveFailed" or \
node_info['clusterMembership'] == "inactiveAdded" or \
(node_info['clusterMembership'] == "active" and
node_info['status'] == "warmup"):
node_list[index]['status'] = "dormant"
# Any other status we'll just hide
else:
node_list[index]['status'] = "out"
raise tornado.gen.Return(node_list)
def strip_host(hostname):
stripped_host = hostname.replace("http://", "")
stripped_host = stripped_host.replace(":8091", "")
return stripped_host
@tornado.gen.coroutine
def fts_nodes():
response, node = yield get_url(SERVICE_URL)
fts_nodes = []
for node_info in response["nodesExt"]:
if 'fts' in node_info['services']:
if 'thisNode' in node_info and node_info['thisNode']:
fts_nodes.append(strip_host(node))
else:
fts_nodes.append(strip_host(node_info['hostname']))
raise tornado.gen.Return(fts_nodes)
@tornado.gen.coroutine
def fts_enabled():
nodes_to_query = yield fts_nodes()
nodes_to_query = ["{}:8094".format(node) for node in nodes_to_query]
if not nodes_to_query:
raise tornado.gen.Return(False)
try:
yield get_url(FTS_URL, host_list=nodes_to_query,
raise_exception=True)
except Exception:
raise tornado.gen.Return(False)
else:
raise tornado.gen.Return(True)
@tornado.gen.coroutine
def n1ql_enabled():
index_response, _ = yield get_url(INDEX_URL)
raise tornado.gen.Return('indexes' in index_response and any(
index['index'] == 'category' and index['status'] == 'Ready' for index
in index_response['indexes']))
@tornado.gen.coroutine
def xdcr_enabled():
if not aws:
raise tornado.gen.Return(True)
xdcr_response, _ = yield get_url(XDCR_URL)
raise tornado.gen.Return(len(xdcr_response) > 0)