mirror of
https://github.com/CiscoDevNet/cml-community.git
synced 2025-10-23 07:42:03 +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:
@@ -4,7 +4,7 @@ requests.packages.urllib3.disable_warnings()
|
||||
|
||||
|
||||
class CML:
|
||||
|
||||
|
||||
def auth(server, username, password):
|
||||
headers = {
|
||||
"accept": "application/json",
|
||||
@@ -20,7 +20,22 @@ 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',
|
||||
@@ -28,10 +43,24 @@ class CML:
|
||||
}
|
||||
|
||||
response = requests.get(f'https://{server}/api/v0/labs/{lab}/nodes/{node_id}?simplified=true', headers=headers, verify=False)
|
||||
|
||||
|
||||
node = json.loads(response.text)
|
||||
|
||||
if response.status_code == 200:
|
||||
return(node)
|
||||
else:
|
||||
return("end of list")
|
||||
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)
|
||||
|
||||
|
||||
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
|
||||
# Create a Dict consisting of all (label:node_definition) from CML
|
||||
nodeDict = {}
|
||||
|
||||
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...")
|
||||
|
||||
|
||||
print("exiting...")
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user