mirror of
				https://github.com/CiscoDevNet/cml-community.git
				synced 2025-10-31 03:53:36 +00:00 
			
		
		
		
	Breakout tool update add mac support (#25)
* breakout update and MAC OS support Added getAllNodes function to cmlApiCalls.py. Added Mac OS support into main.py Added new logic to get all nodes, find label and node_definition, sort by label and add the SecureCRT ini files. This matched what the breakout tool provided for my machine. * Update main.py * Using Lab_title Changed to use the LabTitle for the Directory/CRT. This makes it more human readable when you have multiple labs.
This commit is contained in:
		| @@ -21,6 +21,21 @@ class CML: | ||||
|         access_token = "Bearer " + json.loads(response.text) | ||||
|         return(access_token) | ||||
|  | ||||
|     def getLabInfo(auth, server, lab): | ||||
|         headers = { | ||||
|         'accept': 'application/json', | ||||
|         'Authorization': auth, | ||||
|         } | ||||
|  | ||||
|         response = requests.get(f'https://{server}/api/v0/labs/{lab}/?simplified=true', headers=headers, verify=False) | ||||
|  | ||||
|         lab_info = json.loads(response.text) | ||||
|  | ||||
|         if response.status_code == 200: | ||||
|             return(lab_info) | ||||
|         else: | ||||
|             return("end of list") | ||||
|  | ||||
|     def getNodesByID(auth, server, lab, node_id): | ||||
|         headers = { | ||||
|         'accept': 'application/json', | ||||
| @@ -35,3 +50,17 @@ class CML: | ||||
|             return(node) | ||||
|         else: | ||||
|             return("end of list") | ||||
|     def getAllNodes(auth, server, lab ): | ||||
|         headers = { | ||||
|         'accept': 'application/json', | ||||
|         'Authorization': auth, | ||||
|         } | ||||
|  | ||||
|         response = requests.get(f'https://{server}/api/v0/labs/{lab}/nodes/?simplified=true', headers=headers, verify=False) | ||||
|          | ||||
|         nodes = json.loads(response.text) | ||||
|  | ||||
|         if response.status_code == 200: | ||||
|             return(nodes) | ||||
|         else: | ||||
|             return("end of list") | ||||
|   | ||||
| @@ -62,7 +62,7 @@ D:"Disable Directory Tree Detection"=00000002 | ||||
| D:"Disable MLSX"=00000000 | ||||
| D:"Log Mode"=00000000 | ||||
| D:"Disable Pass Through Printing"=00000000 | ||||
| S:"Hostname"=127.0.0.1 | ||||
| S:"Hostname"=localhost | ||||
| D:"Server Requires Bare CR"=00000000 | ||||
| D:"Disable Resize"=00000002 | ||||
| D:"Enable 80-132 Column Switching"=00000001 | ||||
|   | ||||
| @@ -2,6 +2,7 @@ import requests | ||||
| import json | ||||
| import os | ||||
| import yaml | ||||
| import sys | ||||
| requests.packages.urllib3.disable_warnings() | ||||
| from cmlApiCalls import CML as cml | ||||
|  | ||||
| @@ -23,71 +24,81 @@ auth = cml.auth(server, username, password) | ||||
|  | ||||
| # get all nodes from the cml server (funtion in cmlApiCalls.py) | ||||
| allNodes = cml.getAllNodes(auth, server, lab) | ||||
| # print(allNodes) -- for troubleshooting | ||||
| N = True | ||||
| n_id = 0 | ||||
| # print(allNodes) # -- for troubleshooting | ||||
|  | ||||
| port = 9000 | ||||
| try: | ||||
|     os.mkdir(rf"C:/Users/{user}/AppData/Roaming/VanDyke/Config/Sessions/CML-{lab}") | ||||
| except: | ||||
|  | ||||
| ## Changing to use Lab title vs Lab ID. | ||||
| labInfo = cml.getLabInfo(auth, server, lab) | ||||
| labName = labInfo.get("lab_title") | ||||
|  | ||||
| ## Adding some code to determine if it is running on Mac OS. | ||||
| ## Not yet tested on Win OS. | ||||
|  | ||||
| crtPath = "VanDyke/SecureCRT/Config/Sessions" | ||||
| if sys.platform == 'darwin': | ||||
|     appPath = "/Users/{}/Library/Application Support/{}/CML-{}".format(user,crtPath,labName) | ||||
|     pathMode = 0o777 | ||||
| else:  | ||||
|     appPath = "C:/Users/{}/AppData/Roaming/{}/CML-{}".format(user,crtPath,labName) | ||||
|  | ||||
| if os.path.exists(appPath): | ||||
|     print("directory already exists... continue...") | ||||
| else: | ||||
|     os.mkdir(appPath,pathMode) | ||||
|  | ||||
| # Create a Dict consisting of all (label:node_definition) from CML | ||||
| nodeDict = {} | ||||
|  | ||||
| while n_id < 100: | ||||
|     node_id = f"n{n_id}" | ||||
|     response = cml.getNodesByID(auth, server, lab, node_id) | ||||
|     # print(response) -- for troubleshooting | ||||
|     # if node does not exists, check the next node | ||||
|     if response == "end of list": | ||||
|         print("Node " + node_id + " does not exist, will check all nodes from n0 to n99.") | ||||
|         # increment node number | ||||
|         n_id = n_id + 1 | ||||
| for n_id in allNodes: | ||||
|     response = cml.getNodesByID(auth, server, lab, n_id) | ||||
|     nodeDict.update({response.get("label"): response.get("node_definition")}) | ||||
|  | ||||
| # Sort keys to match breakout tool.  Tool assigned ports based on label. | ||||
|  | ||||
| for node in sorted(nodeDict): | ||||
|     # dont count devices that cannot be consoled into     | ||||
|     elif (response.get("node_definition") == "external_connector" or | ||||
|             response.get("node_definition") == "unmanaged_switch"): | ||||
|         # increment node number | ||||
|         n_id = n_id + 1     | ||||
|          | ||||
|     if (nodeDict.get(node) == "external_connector" or | ||||
|             nodeDict.get(node) == "unmanaged_switch"): | ||||
|         print ("Found {}, skipping".format(nodeDict.get(node))) | ||||
|     else: | ||||
|         # get label | ||||
|         node_label = response.get("label") | ||||
|         node_label = node | ||||
|  | ||||
|         # turn port number into hex | ||||
|         # strip "0x2233" and make it only 4 charators    | ||||
|         hexport = hex(port).split('x')[-1] | ||||
|         # node definition is also printed for troubleshooting | ||||
|         print("creating: " + node_label + " Node Definition: " + response.get("node_definition")) | ||||
|         print("creating: " + node_label + " Node Definition: " + nodeDict.get(node)) | ||||
|         # create a secureCRT Session | ||||
|         with open("config.ini", "r") as config: | ||||
|             temp = config.read() | ||||
|             temp = temp.replace("REPLACE", "0000" + hexport) | ||||
|             location = rf"C:/Users/{user}/AppData/Roaming/VanDyke/Config/Sessions/CML-{lab}/{port}-{node_label}.ini" | ||||
|             location = rf"{appPath}/{port}-{node_label}.ini" | ||||
|             with open( location, "w") as config2write: | ||||
|                 config2write.write(temp) | ||||
|  | ||||
|         # if any custom nodes are added, and they dont add by 2 ports in the breakout tool | ||||
|         # add the node definition to the if statement below to only add by 1 port.  | ||||
|         if (response.get("node_definition") == "wan_emulator" or  | ||||
|                 response.get("node_definition") == "asav" or  | ||||
|                 response.get("node_definition") == "ftdv" or | ||||
|                 response.get("node_definition") == "server" or | ||||
|                 response.get("node_definition") == "alpine" or | ||||
|                 response.get("node_definition") == "coreos" or | ||||
|                 response.get("node_definition") == "desktop" or | ||||
|                 response.get("node_definition") == "trex" or    | ||||
|                 response.get("node_definition") == "ubuntu"): | ||||
|         # if any custom nodes are added, and they dont add by 2 ports  | ||||
|         # in the breakout tool add the node definition to the if  | ||||
|         # statement below to only add by 1 port.  | ||||
|         if (nodeDict.get(node) == "wan_emulator" or | ||||
|                 nodeDict.get(node) == "asav" or | ||||
|                 nodeDict.get(node) == "ftdv" or | ||||
|                 nodeDict.get(node) == "server" or | ||||
|                 nodeDict.get(node) == "alpine" or | ||||
|                 nodeDict.get(node) == "coreos" or | ||||
|                 nodeDict.get(node) == "desktop" or | ||||
|                 nodeDict.get(node) == "trex" or | ||||
|                 nodeDict.get(node) == "viptela-bond" or | ||||
|                 nodeDict.get(node) == "viptela-smart" or | ||||
|                 nodeDict.get(node) == "viptela-manage" or | ||||
|                 nodeDict.get(node) == "ubuntu"): | ||||
|             # only add 1 to port number for the next device | ||||
|             port = port + 1 | ||||
|         # else add 2 to port number for the next device | ||||
|         else: | ||||
|             port = port + 2 | ||||
|         # increment node number     | ||||
|         n_id = n_id + 1 | ||||
| #  | ||||
| print("Nodes 0-99 checked. if you need more, increase the number checked in the while loop") | ||||
| print("example change to: while n_id < 150:") | ||||
|  | ||||
| print("exiting...") | ||||
|  | ||||
|  | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user