Andrea Campanella | 8ec8484 | 2017-09-13 12:36:19 +0200 | [diff] [blame] | 1 | #!/usr/bin/env python |
| 2 | |
| 3 | import sys |
| 4 | import glob |
| 5 | import json |
| 6 | import argparse |
| 7 | |
| 8 | sys.path.append('thrift/gen-py') |
| 9 | |
| 10 | from pltfm_pm_rpc.pltfm_pm_rpc import Client |
| 11 | from pltfm_pm_rpc.ttypes import InvalidPltfmPmOperation |
| 12 | from pltfm_pm_rpc.ttypes import pltfm_pm_port_speed_t, pltfm_pm_fec_type_t |
| 13 | from pltfm_pm_rpc.ttypes import pltfm_pm_board_type_t |
| 14 | from thrift import Thrift |
| 15 | from thrift.transport import TSocket |
| 16 | from thrift.transport import TTransport |
| 17 | from thrift.protocol import TBinaryProtocol |
| 18 | from thrift.protocol import TMultiplexedProtocol |
| 19 | |
| 20 | |
| 21 | class PortMgr: |
| 22 | """ Port Manager """ |
| 23 | |
| 24 | def __init__(self, serverIp, serverPort=9095, portsDef={}): |
| 25 | self.serverIp = serverIp |
| 26 | self.serverPort = serverPort |
| 27 | self.portsDef = portsDef |
| 28 | self.broadType = None |
| 29 | self.transport = TSocket.TSocket(serverIp, serverPort) |
| 30 | self.transport = TTransport.TBufferedTransport(self.transport) |
| 31 | self.protocol = TBinaryProtocol.TBinaryProtocol(self.transport) |
| 32 | self.protocol = TMultiplexedProtocol.TMultiplexedProtocol(self.protocol, "pltfm_pm_rpc") |
| 33 | self.client = Client(self.protocol) |
| 34 | |
| 35 | def __enter__(self): |
| 36 | self.transport.open() |
| 37 | bd_id = self.getBroadType() |
| 38 | self.broadType = pltfm_pm_board_type_t._VALUES_TO_NAMES[bd_id] |
| 39 | self.log("Connected, broad type: %s" % (self.broadType)) |
| 40 | return self |
| 41 | |
| 42 | def __exit__(self, type, value, traceback): |
| 43 | self.transport.close() |
| 44 | self.log("Disconnected") |
| 45 | |
| 46 | def log(self, msg): |
| 47 | print "[%s] %s" % (self.serverIp, msg) |
| 48 | |
| 49 | def portCleanup(self, deviceId=0): |
| 50 | self.log("Cleaning up all ports") |
| 51 | # clean up is not working..... |
| 52 | # return self.client.pltfm_pm_switchd_port_cleanup(deviceId) |
| 53 | # try disable all ports and delete all ports |
| 54 | for portDef in self.portsDef[self.broadType]: |
| 55 | for dp in portDef: |
| 56 | try: |
| 57 | if self._getPortStatus(dp, deviceId) != -1: |
| 58 | self.client.pltfm_pm_port_dis(deviceId, dp) |
| 59 | self.client.pltfm_pm_port_del(deviceId, dp) |
| 60 | except Exception as e: |
| 61 | raise e |
| 62 | |
| 63 | def getPortStatus(self, portNum, channelNum=0, deviceId=0): |
| 64 | dp = self.portsDef[self.broadType][portNum][channelNum] |
| 65 | return self._getPortStatus(dp, deviceId) |
| 66 | |
| 67 | def _getPortStatus(self, dp, deviceId=0): |
| 68 | try: |
| 69 | result = self.client.pltfm_pm_port_oper_status_get(deviceId, dp) |
| 70 | return result |
| 71 | except InvalidPltfmPmOperation as e: |
| 72 | return -1 |
| 73 | |
| 74 | def addPort(self, portNum, channelNum=0, deviceId=0, |
| 75 | speed=pltfm_pm_port_speed_t.BF_SPEED_100G, |
| 76 | fecType=pltfm_pm_fec_type_t.BF_FEC_TYP_NONE): |
| 77 | self.log("Adding port %d/%d with speed %s fec %s" |
| 78 | % (portNum, channelNum, speed, fecType)) |
| 79 | dp = self.portsDef[self.broadType][portNum][channelNum] |
| 80 | try: |
| 81 | result = self.client.pltfm_pm_port_add(deviceId, dp, speed, fecType) |
| 82 | self.log("Port %d/%d added" % (portNum, channelNum)) |
| 83 | return result |
| 84 | except InvalidPltfmPmOperation as e: |
| 85 | self.log("Can't add port %d/%d, code: %d" % (portNum, channelNum, e.code)) |
| 86 | |
| 87 | def enablePort(self, portNum, channelNum=0, deviceId=0): |
| 88 | self.log("Enabling port %d/%d" % (portNum, channelNum)) |
| 89 | dp = self.portsDef[self.broadType][portNum][channelNum] |
| 90 | try: |
| 91 | result = self.client.pltfm_pm_port_enable(deviceId, dp) |
| 92 | self.log("Port %d/%d enabled" % (portNum, channelNum)) |
| 93 | return result |
| 94 | except Exception as e: |
| 95 | self.log("Can't enable port %d/%d, code: %d" % (portNum, channelNum, e.code)) |
| 96 | |
| 97 | def getBroadType(self): |
| 98 | return self.client.pltfm_pm_board_type_get(); |
| 99 | |
| 100 | |
| 101 | def main(args): |
| 102 | with open(args.ports_file) as portsFile: |
| 103 | portsDef = json.load(portsFile) |
| 104 | with PortMgr(args.ip, args.port, portsDef) as portMgr: |
| 105 | if args.do_cleanup: |
| 106 | portMgr.portCleanup() |
| 107 | with open(args.port_config) as portConfig: |
| 108 | for line in portConfig: |
| 109 | if len(line) == 0: |
| 110 | continue |
| 111 | line = line.strip() |
| 112 | info = line.split(' ') |
| 113 | portChannel = info[0] |
| 114 | speed = pltfm_pm_port_speed_t._NAMES_TO_VALUES[info[1]] |
| 115 | fecType = pltfm_pm_fec_type_t._NAMES_TO_VALUES[info[2]] |
| 116 | portNum = int(portChannel.split('/')[0]) |
| 117 | channelNum = int(portChannel.split('/')[1]) |
| 118 | portMgr.addPort(portNum, channelNum, speed=speed, fecType=fecType) |
| 119 | portMgr.enablePort(portNum, channelNum) |
| 120 | |
| 121 | |
| 122 | if __name__ == '__main__': |
| 123 | parser = argparse.ArgumentParser(description='Tofino port manager tool') |
| 124 | parser.add_argument('ip', help='IP of BF-Platfrom') |
| 125 | parser.add_argument('port_config', help='Port configuration') |
| 126 | parser.add_argument('--port', type=int, help='Port of BF-Platfrom', default=9095) |
| 127 | parser.add_argument('--ports-file', help='A json file which defines ports', |
| 128 | default='ports.json') |
| 129 | parser.add_argument('--do-cleanup', help='Performs port cleanup', |
| 130 | type=bool, default=False) |
| 131 | |
| 132 | args = parser.parse_args() |
| 133 | main(args) |