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
from config import CLUSTER_INFO, BRICK_PATH, GLUSTER_PEERS_DNS, CLUSTER_IPS, PUBLIC_IPS, TIMEOUTS
from utils import make_request, make_ws_request, wait_on_job
from helpers import ctdb_healthy
from exceptions import JobTimeOut
import json
GPD = GLUSTER_PEERS_DNS
URLS = [f'http://{ip}/api/v2.0' for ip in CLUSTER_IPS]
def generate_auth_tokens():
# generate a temporary auth token for node
# defaults to 600 second ttl
tokens = []
for ip in CLUSTER_IPS:
res = make_ws_request(ip, {
'msg': 'method',
'method': 'auth.generate_token',
})
assert res.get('error') is None, str(res)
tokens.append(res['result'])
return tokens
def create_cluster():
tokens = generate_auth_tokens()
assert len(tokens) == 3
peers_config = [{
'private_address': CLUSTER_INFO[f'NODE_{node[1]}_IP'],
'hostname': CLUSTER_INFO[f'NODE_{node[1]}_DNS'],
'brick_path': BRICK_PATH,
'remote_credential': {'auth_token': tokens[node[0]]}
} for node in ((1, 'B'), (2, 'C'))]
local_node = {
'private_address': CLUSTER_INFO['NODE_A_IP'],
'hostname': CLUSTER_INFO['NODE_A_DNS'],
'brick_path': BRICK_PATH,
}
# TODO: once we have more VMs available for cluster this
# should be switched to a more reasonable brick configuration
payload = {
'msg': 'method',
'method': 'cluster.management.cluster_create',
'params': [{
'volume_configuration': {
'name': CLUSTER_INFO['GLUSTER_VOLUME'],
'brick_layout': {'distribute_bricks': 3}
},
'local_node_configuration': local_node,
'peers': peers_config,
}]
}
res = make_ws_request(CLUSTER_INFO['NODE_A_IP'], payload)
assert res.get('error') is None, str(res)
try:
status = wait_on_job(res['result'], CLUSTER_INFO['NODE_A_IP'], TIMEOUTS['VOLUME_TIMEOUT'])
except JobTimeOut:
assert False, JobTimeOut
else:
assert status['state'] == 'SUCCESS', status
def wait_on_ctdb():
assert ctdb_healthy(timeout=300), 'CTDB Not healthy after 300 seconds'
def add_public_ips_to_ctdb():
for priv_ip in CLUSTER_IPS:
res = make_request('post', f'http://{priv_ip}/api/v2.0/ctdb/general/status', data={'all_nodes': False})
this_node = res.json()['nodemap']['nodes'][0]['pnn']
for pub_ip in PUBLIC_IPS:
payload = {
'pnn': this_node,
'ip': pub_ip,
'netmask': CLUSTER_INFO['NETMASK'],
'interface': CLUSTER_INFO['INTERFACE']
}
res = make_request('post', f'http://{priv_ip}/api/v2.0/ctdb/public/ips', data=payload)
assert res.status_code == 200, res.text
try:
status = wait_on_job(res.json(), priv_ip, TIMEOUTS['CTDB_IP_TIMEOUT'])
except JobTimeOut:
assert False, JobTimeOut
else:
assert status['state'] == 'SUCCESS', status
def generate_cluster_summary():
res = make_ws_request(CLUSTER_INFO['NODE_A_IP'], {
'msg': 'method',
'method': 'cluster.management.summary',
'params': []
})
assert res.get('error') is None, str(res)
print(json.dumps(res['result'], indent=4))
def init():
print('Creating cluster.')
create_cluster()
print('Waiting on CTDB to become healthy')
wait_on_ctdb()
print('Adding CTDB public IPs to cluster')
add_public_ips_to_ctdb()
print('Generating summary')
generate_cluster_summary()