Advertisement
Guest User

Untitled

a guest
Oct 11th, 2016
163
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 15.32 KB | None | 0 0
  1. #!/usr/bin/python
  2. import json
  3.  
  4. import sys
  5. import getopt
  6. import ConfigParser
  7. import threading
  8. import time
  9. from gmshelper import GmsHelper
  10. from portalhelper import PortalHelper
  11. from vxoahelper import VxoaHelper
  12.  
  13. # this script is run when a lab instance is created from the blueprint.
  14.  
  15.  
  16. class Main:
  17. def __init__(self, argv):
  18. self.argv = argv
  19. self.configfile = ""
  20. self.opts = None
  21. self.args = None
  22. self.config = None
  23. self.portal_url = "cloudportal.silver-peak.com"
  24. self.portal_account_name = "foo"
  25. self.portal_account_key = "bar"
  26. self.gms_url = ""
  27. self.gms_user = "admin"
  28. self.gms_password = "admin"
  29. self.lan_labels = []
  30. self.wan_labels = []
  31. self.lan_label_ids = {}
  32. self.wan_label_ids = {}
  33. self.reverse_lan_label_map = {}
  34. self.reverse_wan_label_map = {}
  35. self.appliance_list = []
  36.  
  37. def run(self):
  38. try:
  39. self.opts, self.args = getopt.getopt(self.argv, "",
  40. ["help", "config="])
  41. except getopt.GetoptError:
  42. self.usage()
  43. sys.exit(2)
  44.  
  45. for opt, arg in self.opts:
  46. if opt == '--help':
  47. self.usage()
  48. sys.exit(0)
  49. elif opt == "--config":
  50. self.configfile = arg
  51.  
  52. if self.configfile == "":
  53. self.usage()
  54. sys.exit(1)
  55.  
  56. print 'Config file: ', self.configfile
  57.  
  58. self.config = ConfigParser.RawConfigParser()
  59. self.config.read(self.configfile)
  60.  
  61. portal_api = PortalHelper(self.portal_url, "", "")
  62. response = portal_api.create_account()
  63. if response is None:
  64. print "Unable to create portal account"
  65. return
  66. self.portal_account_key = response['key']
  67. self.portal_account_name = response['name']
  68.  
  69. self.gms_url = self.config.get('gms', 'ip_address')
  70.  
  71. self.lan_labels = json.loads(self.config.get('gms', 'lan_labels'))
  72. self.wan_labels = json.loads(self.config.get('gms', 'wan_labels'))
  73. self.lan_label_ids = {}
  74. self.wan_label_ids = {}
  75. count = 1
  76. for item in self.wan_labels:
  77. self.wan_label_ids[str(count)] = item
  78. self.reverse_wan_label_map[item] = str(count)
  79. count += 1
  80.  
  81. for item in self.lan_labels:
  82. self.lan_label_ids[str(count)] = item
  83. self.reverse_lan_label_map[item] = str(count)
  84. count += 1
  85.  
  86. print "Setting up Orchestrator"
  87. if not self.setup_orchestrator():
  88. print "Failed to set up Orchestrator"
  89. return
  90.  
  91. self.appliance_list = json.loads(self.config.get('gms', 'appliances'))
  92. appliance_setup_workers = []
  93. for appliance in self.appliance_list:
  94. t = threading.Thread(target=self.setup_appliance, args=[appliance])
  95. appliance_setup_workers.append(t)
  96. t.start()
  97.  
  98. for worker in appliance_setup_workers:
  99. worker.join()
  100.  
  101. # wait till portal and orchestrator get the appliances discovered - otherwise, approval
  102. # will fail.
  103. self.wait_for_discovery()
  104.  
  105. # now approve all the appliances on the Orchestrator
  106. # wait till all appliances are discovered
  107. # each appliance has to go in the group configured for that appliance
  108. for appliance in self.appliance_list:
  109. group = self.config.get(appliance, 'group')
  110. self.approve_appliances(appliance, group)
  111.  
  112. # wait for orchestrator to sync with appliances
  113. self.wait_for_sync()
  114.  
  115. # create overlays on the Orchestrator
  116. self.create_overlays()
  117.  
  118. # assign appliances to overlays
  119. self.associate_appliances_to_overlays()
  120.  
  121. # save changes on appliances
  122. self.save_changes()
  123.  
  124. def save_changes(self):
  125. for appliance in self.appliance_list:
  126. vxoaapi = VxoaHelper(appliance, self.config.get(appliance, 'ip_address'))
  127. vxoaapi.login()
  128. vxoaapi.save_changes()
  129. vxoaapi.logout()
  130.  
  131. def wait_for_sync(self):
  132. count = 0
  133. gmsapi = GmsHelper(self.gms_url, self.gms_user, self.gms_password)
  134. gmsapi.login()
  135. while True:
  136. alist = gmsapi.get_appliances()
  137. total_count = len(self.appliance_list)
  138. sync_count = 0
  139. for item in alist:
  140. if item["softwareVersion"] is not None:
  141. if item["softwareVersion"].startswith("8."):
  142. sync_count += 1
  143.  
  144. if total_count <= sync_count:
  145. print "Everything is in sync"
  146. break
  147.  
  148. print "Waiting for appliances to get synced"
  149. time.sleep(10)
  150. count += 10
  151. if count > 300:
  152. print "Giving up on syncing - proceeding"
  153. break
  154.  
  155. gmsapi.logout()
  156.  
  157. def wait_for_discovery(self):
  158. count = 0
  159. gmsapi = GmsHelper(self.gms_url, self.gms_user, self.gms_password)
  160. gmsapi.login()
  161. while True:
  162. alist = gmsapi.get_discovered_appliances()
  163. if len(alist) >= len(self.appliance_list):
  164. # let us make sure all of them are reachable
  165. reachable_count = 0
  166. for item in alist:
  167. if item["applianceInfo"]["reachabilityStatus"] == 1:
  168. reachable_count += 1
  169. print "Appliance {0} is reachable".format(item["applianceInfo"]["hostname"])
  170. else:
  171. print "Appliance {0} is UNREACHABLE".format(item["applianceInfo"]["hostname"])
  172.  
  173. if reachable_count >= len(self.appliance_list):
  174. print "Discovered all the appliances"
  175. break
  176.  
  177. print "Waiting for appliances to get discovered: currently discovered: {0}".format(len(alist))
  178. time.sleep(10)
  179. count += 10
  180. if count > 300:
  181. print "Giving up on discovery. Check network connectivity of appliances/Orchestrator to the Portal"
  182. break
  183. # trigger a reachability update
  184. gmsapi.put("/appliance/discovered/update", "")
  185. time.sleep(10)
  186.  
  187. gmsapi.logout()
  188.  
  189. def associate_appliances_to_overlays(self):
  190. gmsapi = GmsHelper(self.gms_url, self.gms_user, self.gms_password)
  191. gmsapi.login()
  192. data = {}
  193. orch_appl_list = gmsapi.get_appliances()
  194.  
  195. r = gmsapi.get("/gms/overlays/config")
  196. overlay_config = r.json()
  197.  
  198. overlay_list = json.loads(self.config.get('gms', 'overlays'))
  199. for overlay_name in overlay_list:
  200. overlay_id = ""
  201. found = False
  202. for item in overlay_config:
  203. if item['name'] == overlay_name:
  204. overlay_id = item['id']
  205. found = True
  206. print "Found overlay {0} and its id is {1}".format(overlay_name, overlay_id)
  207. break
  208.  
  209. if not found:
  210. print "Unable to find overlay {0} on Orchestrator".format(overlay_name)
  211. sys.exit(1)
  212.  
  213. data[overlay_id] = list()
  214. appliance_list = json.loads(self.config.get(overlay_name, 'appliances'))
  215. for appliance in appliance_list:
  216. for orch_appliance in orch_appl_list:
  217. if orch_appliance['hostName'] == appliance:
  218. data[overlay_id].append(orch_appliance['id'])
  219.  
  220. try:
  221. r = gmsapi.post("/gms/overlays/association", data)
  222. if r.status_code != 200 and r.status_code != 204:
  223. print "Unable to associate overlays to appliances on Orchestrator: {0}".format(r.text)
  224. sys.exit(1)
  225. except Exception as e:
  226. print "Unable to associate overlays to appliances on Orchestrator: {0}".format(e)
  227. sys.exit(1)
  228.  
  229. gmsapi.logout()
  230. return True
  231.  
  232. def create_overlays(self):
  233. overlay_list = json.loads(self.config.get('gms', 'overlays'))
  234. gmsapi = GmsHelper(self.gms_url, self.gms_user, self.gms_password)
  235. gmsapi.login()
  236. for overlay_name in overlay_list:
  237. bonding_policy = self.config.get(overlay_name, 'bonding_policy')
  238. bonding_policy_enum = 1
  239. if bonding_policy == 'HQ':
  240. bonding_policy_enum = 2
  241. elif bonding_policy == 'HT':
  242. bonding_policy_enum = 3
  243. elif bonding_policy == 'HE':
  244. bonding_policy_enum = 4
  245. data = {
  246. "name": overlay_name,
  247. "topology": {
  248. "topologyType": 2 if (self.config.get(overlay_name, 'topology') == "hub") else 1,
  249. "hubs": []
  250. },
  251. "match": {
  252. },
  253. "brownoutThresholds": {
  254. "loss": float(self.config.get(overlay_name, 'loss')),
  255. "latency": int(self.config.get(overlay_name, 'latency')),
  256. "jitter": int(self.config.get(overlay_name, 'jitter'))
  257. },
  258. "wanPorts": {
  259. "primary": [],
  260. "backup": []
  261. },
  262. "bondingPolicy": bonding_policy_enum,
  263. "crossConnect": bool(self.config.get(overlay_name, 'cross_connect')),
  264. "useBackupOnBrownout": bool(self.config.get(overlay_name, 'use_backup_on_brownout')),
  265. "trafficClass": self.config.get(overlay_name, 'traffic_class'),
  266. "boostTraffic": bool(self.config.get(overlay_name, 'boost')),
  267. "overlayFallbackOption": 2 if (self.config.get(overlay_name, 'fallback') == 'Drop') else 1
  268. }
  269. match_condition = self.config.get(overlay_name, 'match')
  270. match_info = match_condition.split(':')
  271. if match_info[0] == 'acl':
  272. data['match'] = {"acl": match_info[1]}
  273. else:
  274. data['match'] = {'interfaceLabel': self.reverse_lan_label_map[match_info[1]]}
  275. wan_port_list = json.loads(self.config.get(overlay_name, 'primary_ports'))
  276. backup_port_list = json.loads(self.config.get(overlay_name, 'backup_ports'))
  277. for item in wan_port_list:
  278. data['wanPorts']['primary'].extend(self.reverse_wan_label_map[item])
  279. for item in backup_port_list:
  280. data['wanPorts']['backup'].extend(self.reverse_wan_label_map[item])
  281.  
  282. hub_list = json.loads(self.config.get(overlay_name, 'hubs'))
  283. # find the nepk for this hub
  284. appliance_list = gmsapi.get_appliances()
  285. nepk_list = list()
  286. for item in hub_list:
  287. for appl in appliance_list:
  288. if appl['hostName'] == item:
  289. nepk_list.append(appl['id'])
  290.  
  291. if len(nepk_list) > 0:
  292. data['topology']['hubs'] = nepk_list
  293.  
  294. try:
  295. print "Overlay JSON to be posted: {0}".format(json.dumps(data))
  296. print "Creating overlay {0}".format(overlay_name)
  297. r = gmsapi.post('/gms/overlays/config', data)
  298. if r.status_code != 200:
  299. print "Unable to create overlay {1} on Orchestrator: {0}".format(r.text, overlay_name)
  300. sys.exit(1)
  301.  
  302. except Exception as e:
  303. print "Unable to create overlay {1} on Orchestrator: {0}".format(e, overlay_name)
  304. sys.exit(1)
  305.  
  306. gmsapi.logout()
  307.  
  308. def setup_appliance(self, cfg_name):
  309. print "Setting up appliance: {0}".format(cfg_name)
  310. vxoaapi = VxoaHelper(cfg_name, self.config.get(cfg_name, 'ip_address'))
  311. vxoaapi.wait_for_webserver_restart()
  312. vxoaapi.login()
  313.  
  314. try:
  315. print "Setting up portal configuration on :{0}".format(cfg_name)
  316. vxoaapi.set_portal(self.portal_url, True, self.portal_account_key,
  317. self.portal_account_name, self.config.get(cfg_name, 'tag'))
  318. print "Setting up EdgeConnect licensing on :{0}".format(cfg_name)
  319. vxoaapi.set_eclicense(True, self.config.get(cfg_name, 'boost_bw'))
  320.  
  321. vxoaapi.save_changes()
  322. time.sleep(5)
  323. finally:
  324. vxoaapi.logout()
  325.  
  326. return True
  327.  
  328. def setup_orchestrator(self):
  329. gmsapi = GmsHelper(self.gms_url, self.gms_user, self.gms_password)
  330. gmsapi.login()
  331.  
  332. # set account name and key
  333. print "Setting Orchestrator Portal Config"
  334. try:
  335. r = gmsapi.get("/spPortal/config")
  336. if r.status_code != 200:
  337. print "Unable to get current Portal configuration for Orchestrator: {0}".format(r.text)
  338. sys.exit(1)
  339.  
  340. data = r.json()
  341. data["registration"]["account"] = self.portal_account_name
  342. data["registration"]["key"] = self.portal_account_key
  343.  
  344. r = gmsapi.post("/spPortal/config", data)
  345. if r.status_code != 200 and r.status_code != 204:
  346. print "Unable to POST Portal configuration for Orchestrator: {0}".format(r.text)
  347. sys.exit(1)
  348.  
  349. # trigger registration
  350. gmsapi.post("/spPortal/registration", data)
  351.  
  352. except Exception as e:
  353. print "Unable to apply account name and key for Orchestrator: {0}".format(e)
  354. sys.exit(1)
  355.  
  356. gmsapi.logout()
  357. return True
  358.  
  359. def approve_appliances(self, appliance, group):
  360. print "Approving appliance on Orchestrator: {0}".format(appliance)
  361. gmsapi = GmsHelper(self.gms_url, self.gms_user, self.gms_password)
  362. gmsapi.login()
  363. try:
  364. appliance_list = gmsapi.get_discovered_appliances()
  365. r = gmsapi.get("/gms/group")
  366. group_list = r.json()
  367. group_pk = None
  368. for item in group_list:
  369. if item['name'] == group:
  370. group_pk = item['id']
  371. print "Found group primary key {0} for group {1}".format(group_pk, group)
  372. break
  373.  
  374. found = False
  375. for discovered_item in appliance_list:
  376. if discovered_item['applianceInfo']['hostname'] == appliance:
  377. print "Found appliance: {0}. Trying to approve".format(appliance)
  378. gmsapi.approve_appliance(discovered_item['id'], group_pk)
  379. return True
  380.  
  381. if not found:
  382. print "Could not find appliance {0} in discovered table. Check if appliances can connect to Portal".format(appliance)
  383. return False
  384.  
  385. except Exception as e:
  386. print "Unable to approve appliance {0}. Error: {1}".format(appliance, e)
  387. return False
  388. finally:
  389. gmsapi.logout()
  390.  
  391. @staticmethod
  392. def usage():
  393. print "USAGE: main.py -c <configfile>"
  394.  
  395. if __name__ == "__main__":
  396. main_obj = Main(sys.argv[1:])
  397. main_obj.run()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement