diff --git a/README.md b/README.md index d36d9b5..c165893 100644 --- a/README.md +++ b/README.md @@ -36,6 +36,8 @@ srvr1: port: 22 ``` +When using a jumpHost, taskAutom will create a standard ssh-based tunnel (ie: TCP-port-forwarding) to the far-end, which is the router. + --- ## Bulk Script Execution on routers ## @@ -44,19 +46,15 @@ The program needs two mandatory inputs: a) DATA file and b) a plugin, which is n ### DATA file -The DATA can be either a CSV file or an Excel file. In both cases you can define a header with column names, or not; it's optional. -- If no headers, the file must have in its first column (`_1`), the IP of the routers to which `taskAutom` will connect to. - - Using a data file without headers is discouraged. It will be deprecated. It's only here for historical reasons. -- If using headers, there must be a column named `ip` with the IP addresses of the routers to which `taskAutom` will connect to. - - You can chose a different column name by using the configuration option `-gc/--dataGroupColumn myColName`. +The DATA can be either a CSV file or an Excel file. There must be a column named `ip` with the IP addresses of the routers to which `taskAutom` will connect to. The name of this column can be changed using the configuration option `-gc/--dataGroupColumn myColName`. -The first column `_1` or the `ip` column (or eventually changed by `-gc`) allows `taskAutom` to group routers by that column when processing data. This is particularly useful if you have the same router along several rows in the DATA file. +The `ip` column (or eventually changed by `-gc`) allows `taskAutom` to group routers by that column when processing data. This is particularly useful if you have the same router along several rows in the DATA file. -If you want `taskAutom` not to group routers by the `[ip|_1]` column, you should use the `-so/--strictOrder yes` CLI parameter: this will process the routers' data in the order of the DATA file as is. +If you want `taskAutom` not to group routers by the `ip` column, you should use the `-so/--strictOrder=yes` CLI parameter: this will process the routers' data in the order of the DATA file as is. The next columns in the DATA file, are the variables that will be used in the configuration template. -**Example:** this is a CSV for two different routers, including the data to modify their interfaces. A header is being used in this case. +**Example:** this is a CSV for two different routers, including the data to modify their interfaces. ```csv ip,name,port,interName,ipAddress @@ -64,6 +62,9 @@ ip,name,port,interName,ipAddress 10.0.0.2,router2,1/3/5,inter7,192.168.2.1/30 ``` +#### Notes on the data file +There are cases where it is needed to send the complete dataFrame to the plugin. In those cases, you can do so by issuing the CLI parameter `-pbr/--passByRow=no`. When doing so, taskAutom will send the whole set of rows selected by the IP of the router, to the plugin. By deafult, `-pbr/--passByRow=yes`. + ### Plugin The plugin is a Python code which is fed with each row of the DATA file at a time, in order to render a configuration script. It consists of a function called `construir_cliLine()` which accepts four arguments: @@ -109,7 +110,7 @@ def construir_cliLine(m, datos, lenData, mop=None): ### Inventory -By default, `taskAutom` connects to each and every router that exists inside the DATA data file. Optionally, an inventory file can be provided, with per router connection parameters. If so, the default connection values are overridden by those inside the inventory file. +By default, `taskAutom` connects to each and every router that exists inside the DATA data file (identifying the routers by the `ip` column). Optionally, an inventory file can be provided, with per router connection parameters. If so, the default connection values are overridden by those inside the inventory file. ip|username|password|useSSHTunnel|readTimeOut|deviceType|jumpHost| --|--------|--------|------------|----------|--------|--------- @@ -119,9 +120,11 @@ ip|username|password|useSSHTunnel|readTimeOut|deviceType|jumpHost| If fieds in the inventory CSV file are left empty, default values are used. -### MOP +### MOP: Method of Procedure + +When writing a plugin, is important to help `taskAutom` understand which string should be considered as a title if you intend to generate a Word document out of the combination of the data file and the plugin. -When writing a plugin, is important to help `taskAutom` understand which string should be considered as a title. You do so be adding a prefix `Heading_2` to the `tiltle` variable, under the `if mop:` statement. After this, a MOP is created with the intended information. There is also the possibility of using the prefix `Heading_3`. +You do so be adding a prefix `Heading_2` to the `tiltle` variable, under the `if mop:` statement. After this, a MOP is created with the intended information. There is also the possibility of using the prefix `Heading_3`. ### Result diff --git a/changelog.md b/changelog.md index 0a04eb6..fab049e 100644 --- a/changelog.md +++ b/changelog.md @@ -1,5 +1,13 @@ # Versions # +## [8.2.1] - 2024-03-16 + +- Update of libraries: + - `pandas >= 1.5.2,<=2.0.3` + - `netmiko == 4.3.0` +- The Timos version is now added to the json file per router as a new key. +- The default hostname is now `NA_#`, where # is the threadnumber. This changes if the hostname is detected later on. + ## [8.1.1] - 2023-09-17 - Update to have taskAutom support access to SRLinux devices. A new device type `nokia_srl` has been included under the `DICT_VENDOR` general dictionary. diff --git a/setup.py b/setup.py index 10700e9..463a209 100644 --- a/setup.py +++ b/setup.py @@ -2,7 +2,7 @@ setup( name='taskAutom', - version='8.1.1', + version='8.2.1', description='A simple task automation tool', long_description='A simple task automation tool for NOKIA SROS based routers', long_description_content_type='text/x-rst', @@ -12,8 +12,8 @@ license='BSD 3-clause', packages=['src/taskAutom'], install_requires=['sshtunnel==0.4.0', - 'netmiko==4.2.0', - 'pandas==1.5.2', + 'netmiko==4.3.0', + 'pandas>=1.5.2,<=2.0.3', 'pyyaml==5.3.1', 'python-docx==0.8.11', ], diff --git a/src/taskAutom/__init__.py b/src/taskAutom/__init__.py index 3cf06c1..0b331ab 100644 --- a/src/taskAutom/__init__.py +++ b/src/taskAutom/__init__.py @@ -1,2 +1,2 @@ -__version__ = "8.1.1" +__version__ = "8.2.1" __author__ = 'Lucas Aimaretto' \ No newline at end of file diff --git a/src/taskAutom/taskAutom.py b/src/taskAutom/taskAutom.py index 9f690b4..d201769 100755 --- a/src/taskAutom/taskAutom.py +++ b/src/taskAutom/taskAutom.py @@ -38,7 +38,7 @@ from docx.shared import Pt -LATEST_VERSION = '8.1.1' +LATEST_VERSION = '8.2.1' # Constants IP_LOCALHOST = "127.0.0.1" @@ -952,10 +952,10 @@ def __init__(self, thrdNum, routerInfo, dictParam): 'remotePort':-1, 'controlPlaneAccess': False, 'aluLogged': False, - 'aluLogReason':"N/A", - 'hostname':"N/A", - 'timos':"N/A", - 'hwType':"N/A", + 'aluLogReason':"NA", + 'hostname':"NA_" + str(thrdNum), + 'timos':"NA", + 'hwType':"NA", 'cronTime':dictParam['cronTime'], 'sshServer': None, 'conn2rtr': None, @@ -1227,8 +1227,8 @@ def fncConnectToRouter(self, connInfo): connInfo['conn2rtr'] = None connInfo['aluLogged'] = False - connInfo['username'] = "N/A" - connInfo['password'] = "N/A" + connInfo['username'] = "NA" + connInfo['password'] = "NA" return connInfo @@ -1447,7 +1447,7 @@ def routerLogin(self, connInfo): aluLogged = False aluLogReason = str(e).replace('\n',' ').lstrip() aluLogUser = tempUser - aluPass = "PassN/A" + aluPass = "PassNA" fncPrintConsole(connInfo['strConn'] + aluLogReason + ": " + systemIP) connInfo['conn2rtr'] = conn2rtr @@ -1512,9 +1512,9 @@ def routerRunRoutine(self, connInfo): def logData(self, connInfo, logInfo, logsDirTimestamp, plugin, logsDirectory): - writeCmd = 'n/a' - writeRx = 'n/a' - writeJson = 'n/a' + writeCmd = 'na' + writeRx = 'na' + writeJson = 'na' if self.outputJob == 2: pluginScript = connInfo['pluginScript'] @@ -1566,6 +1566,7 @@ def logData(self, connInfo, logInfo, logsDirTimestamp, plugin, logsDirectory): with open(aluFileOutRxJson,'w') as fj: outRxJson['name'] = connInfo['hostname'] outRxJson['ip'] = connInfo['systemIP'] + outRxJson['version'] = connInfo['timos'] json.dump(outRxJson,fj) fj.close() writeJson = 'yes'