-
Notifications
You must be signed in to change notification settings - Fork 3
/
userdata-cclear.bash
290 lines (243 loc) · 10.3 KB
/
userdata-cclear.bash
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
#!/bin/bash
mkdir -p /opt/cloud/
cat <<EOF_DEPLOYER >/opt/cloud/deployer.py
#!/usr/bin/env python3
from os import environ
import ipaddress
import json
import requests
from requests.auth import HTTPBasicAuth
import urllib3
from urllib.parse import urlencode
from getpass import getpass
try:
from dotenv import load_dotenv
load_dotenv()
except ImportError:
print(".env files will not be loaded. 'pip3 install python-dotenv' to install")
urllib3.disable_warnings()
debug = False
debug_mode = False
def set_debug_env(debug_dict):
for i in debug_dict:
if debug: print(i)
environ[i['key']] = i['value']
def get_user(prompt):
while True:
try:
value = input(prompt)
except ValueError:
print("Not a valid entry")
continue
if len(value) < 1:
print("Not enough characters")
continue
else:
break
return value
def get_passwd(prompt):
while True:
try:
value = getpass(prompt)
except ValueError:
print("Not a valid entry")
continue
if len(value) < 1:
print("Not enough characters")
continue
else:
break
return value
def get_valid_ip(prompt):
while True:
try:
value = input(prompt)
value = '' if len(value) < 1 else ipaddress.ip_address(value)
except ValueError:
print("This is not a valid IP address")
continue
else:
break
return str(value)
def get_valid_ips(prompt):
while True:
try:
value = input(prompt).split()
is_valid_ip = all(ipaddress.ip_address(ip) for ip in value)
except ValueError:
print("The list caused an error, does the list contain an invalid IP address?")
continue
if not is_valid_ip:
print("The list contains an invalid IP address")
continue
else:
break
return value
def get_valid_json(prompt):
while True:
try:
value = json.loads(input(prompt))
except ValueError:
print("This is not correctly formated, please check this is valid json.")
continue
else:
break
return value
def get_requests(url):
try:
s = requests.get(url, auth=HTTPBasicAuth(user, password), verify=False)
except requests.exceptions.RequestException as e:
raise SystemExit(e)
if debug: print("{} {} {}".format(url, s))
return s
def post_request(url, post_payload):
post_headers = {'Content-Type': 'application/json'}
try:
s = requests.post(url, auth=HTTPBasicAuth(user, password), verify=False, headers=post_headers, json=post_payload)
except requests.exceptions.RequestException as e:
raise SystemExit(e)
if debug: print("{} {} {}".format(url, post_payload, s))
return s
def get_system_settings(provisioning):
# the structure of the provisioning input is assumed to be a dictionary like this:
# [{"index":0,"name":"cstor-0","nic_name":"cstor-0-capture-nic","private_ip":"10.101.2.4"}]
curss = dict()
for key in provisioning:
print("getting systems settings on {}".format(key['name']), end =": ")
s = get_requests("https://{}/sys/10/getSystemSettings".format(key['private_ip']))
if 200 <= s.status_code <= 229:
curss[key['name']] = s.json()
print("OK")
elif s.status_code == 401:
print("FAILED {} Check username / password".format(s.status_code))
exit(1)
else:
print("FAILED {}".format(s.status_code))
exit(1)
return curss
def set_system_settings(t_settings, provisioning):
# the structure of the target settings (t_setttings) is assumed to be a dictionary of system settings like this:
#{ "cvu-0": {
# "cvuv_max_vxlan_ports": 3,
# "cvuv_vxlan_dev_0": "vxlan0"
# }
#}
curss = dict()
for key in provisioning:
print("setting the following systems settings on {}".format(key['name']), end =": ")
s = get_requests("https://{}/sys/10/updateASingleSystemSetting?{}".format(key['private_ip'], urlencode(t_settings[key['name']])))
if 200 <= s.status_code <= 229:
curss[key['name']] = s.json()
print("OK")
print(json.dumps(t_settings[key['name']], sort_keys=False, indent=4))
else:
print("FAILED {}".format(s.status_code))
exit(1)
return curss
def create_cvu_provisioining_settings():
t_cvu_ss = dict()
for cvukey in cvu_provisioning:
settings = None
i = 0
vxlan_id_start = 200
settings = dict(cvuv_max_vxlan_ports=num_cstors + num_tools)
settings['stats_db_server'] = cclear_ip
for cstorkey in cstor_provisioning:
settings['cvuv_vxlan_dev_{}'.format(i)] = 'vxlan{}'.format(i)
settings['cvuv_vxlan_srcip_{}'.format(i)] = cvukey['private_ip']
settings['cvuv_vxlan_remoteip_{}'.format(i)] = cstorkey['private_ip']
settings['cvuv_vxlan_id_{}'.format(i)] = vxlan_id_start + i
# only supports single interface deployment
settings['cvuv_vxlan_eth_{}'.format(i)] = 'cvuv_mirror_eth_0'
i = i + 1
for ip in cvu_tool_ip:
settings['cvuv_vxlan_dev_{}'.format(i)] = 'vxlan{}'.format(i)
settings['cvuv_vxlan_srcip_{}'.format(i)] = cvukey['private_ip']
settings['cvuv_vxlan_remoteip_{}'.format(i)] = ip
settings['cvuv_vxlan_id_{}'.format(i)] = vxlan_id_start + i
# only supports single interface deployment
settings['cvuv_vxlan_eth_{}'.format(i)] = 'cvuv_mirror_eth_0'
i = i + 1
t_cvu_ss[cvukey['name']] = settings
if debug: print(json.dumps(t_cvu_ss, sort_keys=False, indent=4))
return t_cvu_ss
def create_cstor_provisioning_settings():
t_cstor_ss = dict()
for cstorkey in cstor_provisioning:
settings = None
i = 0
settings = dict()
settings['stats_db_server'] = cclear_ip
t_cstor_ss[cstorkey['name']] = settings
if debug: print(json.dumps(t_cstor_ss, sort_keys=False, indent=4))
return t_cstor_ss
def restart_services(provisioning):
for key in provisioning:
print("Restarting Services on {}".format(key['name']), end=": ")
url = "https://{}/sys/20141028/restartAll".format(key['private_ip'])
try:
s = requests.get(url, auth=HTTPBasicAuth(user, password), verify=False)
except requests.exceptions.RequestException as e:
raise SystemExit(e)
if s.status_code in [500,200]:
print("OK")
else:
print("FAILED {}".format(s.status_code))
exit(1)
def add_devices_to_cclear(provisioning):
for key in provisioning:
print("adding {} to cclear: {}".format(key['name'], cclear_ip), end =": ")
modify_payload = {'ip': key['private_ip'], 'name': key['name'], 'deviceType': 'cstor10', 'verify_ssl': False}
modify_ss = post_request(url="https://{}/rt/data/cstor/modify".format(cclear_ip), post_payload=modify_payload)
if debug: print(json.dumps(modify_ss.json(), sort_keys=False, indent=4))
if 200 <= modify_ss.status_code <= 229:
devauth_payload = {'devId': modify_ss.json()['_id'], "user": user, "pwd": password}
devauth_ss = post_request(url="https://{}/rt/data/devauth/modify".format(cclear_ip), post_payload=devauth_payload)
if debug: print(json.dumps(devauth_ss.json(), sort_keys=False, indent=4))
if 200 <= devauth_ss.status_code <= 229:
print("OK")
else:
print("Failed {}".format(devauth_ss.status_code))
elif modify_ss.status_code == 500:
print("Device Already Exists - Skipping")
else:
print("Failed {}".format(modify_ss.status_code))
# Inputs
instruction = """
This script will configure the Azure Cloud products using the output from the ARM Templates.
After the ARM Template is finished deploying, copy/paste the output variables when prompted.
If the cVu deployment will be sending packet data to a 3rd packet tool, have the IP address(s)
of the tools ready before running this script.
This script can be re-run to reconfigure the solution.
"""
print(instruction)
cclear_ip = environ.get('CCLEAR_IP') if environ.get('CCLEAR_IP') is not None else get_valid_ip("cclear_ip: ")
if debug: print(cclear_ip)
cvu_ilb_frontend_ip = environ.get('CVU_ILB_FRONTEND_IP') if environ.get('CVU_ILB_FRONTEND_IP') is not None else get_valid_ip("cvu_ilb_frontend_ip: ")
if debug: print(cvu_ilb_frontend_ip)
cvu_provisioning = json.loads(environ.get('CVU_PROVISIONING')) if environ.get('CVU_PROVISIONING') is not None else get_valid_json("cvu_provisioning: ")
if debug: print(cvu_provisioning)
cvu_tool_ip = environ.get('CVU_TOOL_IP').split() if environ.get('CVU_TOOL_IP') is not None else get_valid_ips("cvu_3rd_party_tools: ")
if debug: print(cvu_tool_ip)
num_tools = len(cvu_tool_ip)
cstor_ilb_frontend_ip = environ.get('CSTOR_ILB_FRONTEND_IP') if environ.get('CSTOR_ILB_FRONTEND_IP') is not None else get_valid_ip("cstor_ilb_frontend_ip: ")
if debug: print(cstor_ilb_frontend_ip)
cstor_provisioning = json.loads(environ.get('CSTOR_PROVISIONING')) if environ.get('CSTOR_PROVISIONING') is not None else get_valid_json("cstor_provisioning: ")
if debug: print(cstor_provisioning)
num_cstors = len(cstor_provisioning)
user = environ.get('CPKT_USER') if environ.get('CPKT_USER') is not None else get_user("cClear Web UI Username: ")
password = environ.get('CPKT_PASSWORD') if environ.get('CPKT_PASSWORD') is not None else get_passwd("cClear Web UI Password: ")
# main
cur_ss_cvu = get_system_settings(cvu_provisioning)
cur_ss_cstor = get_system_settings(cstor_provisioning)
cur_ss_cvu = set_system_settings(create_cvu_provisioining_settings(), cvu_provisioning)
if debug: print(json.dumps(cur_ss_cvu, sort_keys=False, indent=4))
cur_ss_cstor = set_system_settings(create_cstor_provisioning_settings(), cstor_provisioning)
if debug: print(json.dumps(cur_ss_cstor, sort_keys=False, indent=4))
restart_services(cvu_provisioning)
restart_services(cstor_provisioning)
print("Finished VXLAN provisioning")
add_devices_to_cclear(cstor_provisioning)
print("Finished cClear provisioning")
EOF_DEPLOYER
chmod +x /opt/cloud/deployer.py