From 08ace57ab5b570c2d3478ef947e6d24ca48c3b2e Mon Sep 17 00:00:00 2001 From: Kirk Byers Date: Thu, 1 Oct 2020 13:18:31 -0700 Subject: [PATCH 01/49] Adding in performance graphs (#1985) --- release_process.txt | 2 +- tests_new/performance/arista1.out | 23 ------ tests_new/performance/gen_graph.py | 81 +++++++++++++++++++ tests_new/performance/netmiko_arista_eos.svg | 4 + tests_new/performance/netmiko_cisco_ios.svg | 4 + tests_new/performance/netmiko_cisco_nxos.svg | 4 + tests_new/performance/netmiko_cisco_xe.svg | 4 + tests_new/performance/netmiko_cisco_xr.svg | 4 + tests_new/performance/netmiko_performance.csv | 36 +++++++++ .../netmiko_performance_releases.csv | 35 ++++++++ tests_new/performance/test_devices.yml | 4 - tests_new/performance/test_netmiko.py | 4 +- 12 files changed, 175 insertions(+), 30 deletions(-) delete mode 100644 tests_new/performance/arista1.out create mode 100644 tests_new/performance/gen_graph.py create mode 100644 tests_new/performance/netmiko_arista_eos.svg create mode 100644 tests_new/performance/netmiko_cisco_ios.svg create mode 100644 tests_new/performance/netmiko_cisco_nxos.svg create mode 100644 tests_new/performance/netmiko_cisco_xe.svg create mode 100644 tests_new/performance/netmiko_cisco_xr.svg create mode 100644 tests_new/performance/netmiko_performance_releases.csv diff --git a/release_process.txt b/release_process.txt index c85325239..e1e55c622 100644 --- a/release_process.txt +++ b/release_process.txt @@ -20,6 +20,6 @@ $ pdoc3 --html --output-dir docs netmiko --force # Run ./_release.sh # Create a tag for the version -$ git tag -a v3.2.0 -m "Version 3.2.0 Release" +$ git tag -a v3.3.2 -m "Version 3.3.2 Release" $ git push origin diff --git a/tests_new/performance/arista1.out b/tests_new/performance/arista1.out deleted file mode 100644 index 555557981..000000000 --- a/tests_new/performance/arista1.out +++ /dev/null @@ -1,23 +0,0 @@ -Last login: Wed Sep 23 17:35:27 2020 from 13.57.229.17 - -terminal width 511 -terminal width 511 -arista1#terminal width 511 -Width set to 511 columns. -arista1#terminal length 0 -Pagination disabled. -arista1# -arista1# -arista1# -arista1# -arista1# -arista1# -arista1#configure terminal -arista1(config)# -arista1(config)#no ip access-list netmiko_test_large_acl -! Hardware not present. ACL(s) not programmed in the hardware. -arista1(config)# -arista1(config)#end -arista1# -arista1# -arista1#exit diff --git a/tests_new/performance/gen_graph.py b/tests_new/performance/gen_graph.py new file mode 100644 index 000000000..5fa06b1bf --- /dev/null +++ b/tests_new/performance/gen_graph.py @@ -0,0 +1,81 @@ +import pygal +import csv +from pprint import pprint + + +def convert_time(time_str): + """Convert time_str to seconds (float).""" + results = time_str.split(":") + hours, mins, secs = [float(my_time) for my_time in results] + if hours != 0 or mins != 0: + raise ValueError("Invalid Time Received") + return secs + + +def read_csv(device): + csv_file = "netmiko_performance_releases.csv" + entries = [] + with open(csv_file) as f: + read_csv = csv.DictReader(f) + for entry in read_csv: + entry = dict(entry) + if entry["device_name"] == device: + entries.append(entry) + + return entries + + +if __name__ == "__main__": + + cisco1 = { + "device": "cisco1", + "title": "Netmiko: Cisco IOS Performance (Cisco 881)", + "outfile": "netmiko_cisco_ios.svg", + } + cisco3 = { + "device": "cisco3", + "title": "Netmiko: Cisco IOS-XE Performance (Cisco C1111-4P)", + "outfile": "netmiko_cisco_xe.svg", + } + nxos1 = { + "device": "nxos1", + "title": "Netmiko: Cisco NX-OS Performance (nx9k virtual)", + "outfile": "netmiko_cisco_nxos.svg", + } + xr_azure = { + "device": "cisco_xr_azure", + "title": "Netmiko: Cisco IOS-XR Performance (cisco IOS-XRv 9000)", + "outfile": "netmiko_cisco_xr.svg", + } + arista1 = { + "device": "arista1", + "title": "Netmiko: Arista EOS Performance (vEOS)", + "outfile": "netmiko_arista_eos.svg", + } + + test_device = cisco1 + + device = test_device["device"] + title = test_device["title"] + outfile = test_device["outfile"] + entries = read_csv(device) + + # Create relevant lists + netmiko_versions = [v["netmiko_version"] for v in entries] + connect = [convert_time(v["connect"]) for v in entries] + send_command = [convert_time(v["send_command_simple"]) for v in entries] + send_config = [convert_time(v["send_config_simple"]) for v in entries] + send_config_acl = [convert_time(v["send_config_large_acl"]) for v in entries] + pprint(entries) + print(netmiko_versions) + print(connect) + + # Graph It + line_chart = pygal.Line(include_x_axis=True) + line_chart.title = title + line_chart.x_labels = netmiko_versions + line_chart.add("Connect", connect) + line_chart.add("Show Command", send_command) + line_chart.add("Simple Config", send_config) + line_chart.add("Large ACL", send_config_acl) + line_chart.render_to_file(outfile) diff --git a/tests_new/performance/netmiko_arista_eos.svg b/tests_new/performance/netmiko_arista_eos.svg new file mode 100644 index 000000000..73484b335 --- /dev/null +++ b/tests_new/performance/netmiko_arista_eos.svg @@ -0,0 +1,4 @@ + +Netmiko: Arista EOS Performance (vEOS)00448812121616202024242828323236362.4.23.0.03.1.13.2.03.3.03.3.2Netmiko: Arista EOS Performance (vEOS)5.5825411.669230769230769433.19608434793482.4.26.239377128.36153846153843424.8517786322983.0.06.183318245.05384615384614425.5639392354813.1.18.302358361.7461538461538398.64414393822623.2.08.134659478.4384615384615400.77455334604973.3.02.452651595.1307692307691472.95747213822173.3.26.27885711.669230769230769424.35023382033812.4.26.815281128.36153846153843417.535627077409863.0.07.020729245.05384615384614414.92566308228453.1.19.39506361.7461538461538384.762709816689553.2.08.788801478.4384615384615392.464484288676153.3.02.962302595.1307692307691466.482983410759633.3.210.81279511.669230769230769366.75213144829942.4.26.880786128.36153846153843416.70346666942013.0.07.157726245.05384615384614413.185284799506463.1.117.180089361.7461538461538285.86349740767783.2.016.972578478.4384615384615288.499669278868853.3.04.549834595.1307692307691446.315343126554753.3.217.30861611.669230769230769284.23072005086992.4.235.616451128.3615384615384351.652207830280763.0.034.818646245.0538461538461461.787338496585453.1.133.984633361.746153846153872.38244724170093.2.038.904262478.43846153846159.8846153846154723.3.020.658814595.1307692307691241.670577549891853.3.2ConnectShow CommandSimple ConfigLarge ACL \ No newline at end of file diff --git a/tests_new/performance/netmiko_cisco_ios.svg b/tests_new/performance/netmiko_cisco_ios.svg new file mode 100644 index 000000000..c89defdcd --- /dev/null +++ b/tests_new/performance/netmiko_cisco_ios.svg @@ -0,0 +1,4 @@ + +Netmiko: Cisco IOS Performance (Cisco 881)0022446688101012121414161618182.4.23.0.03.1.13.2.03.3.03.3.2Netmiko: Cisco IOS Performance (Cisco 881)5.02858511.669230769230769369.62138316992412.4.25.651217128.36153846153843352.968533688809663.0.07.806983245.05384615384614295.31064473593833.1.17.72758361.7461538461538297.43434895825413.2.01.057334478.4384615384615475.83604151502253.3.01.065231595.1307692307691475.624829190001663.3.25.43725511.669230769230769358.691138663623352.4.26.045608128.36153846153843342.42019380312083.0.08.139146245.05384615384614286.42664834289163.1.18.128382361.7461538461538286.714541146047743.2.01.145539478.4384615384615473.476919933604053.3.01.137782595.1307692307691473.684387833463063.3.27.69867911.669230769230769298.207332041124352.4.25.959159128.36153846153843344.732349594652363.0.08.046488245.05384615384614288.904869390353.1.18.053055361.7461538461538288.72922910436653.2.01.136542478.4384615384615473.717552742039233.3.01.158154595.1307692307691473.13952048062983.3.212.7572111.669230769230769162.91239805354992.4.216.530688128.3615384615384361.987355405088523.0.018.478753245.053846153846149.8846153846153023.1.118.472529361.746153846153810.051081828952423.2.03.578422478.4384615384615408.407289069526773.3.03.521735595.1307692307691409.92343356344283.3.2ConnectShow CommandSimple ConfigLarge ACL \ No newline at end of file diff --git a/tests_new/performance/netmiko_cisco_nxos.svg b/tests_new/performance/netmiko_cisco_nxos.svg new file mode 100644 index 000000000..e90f19609 --- /dev/null +++ b/tests_new/performance/netmiko_cisco_nxos.svg @@ -0,0 +1,4 @@ + +Netmiko: Cisco NX-OS Performance (nx9k virtual)0022446688101012121414161618182.4.23.0.03.1.13.2.03.3.03.3.2Netmiko: Cisco NX-OS Performance (nx9k virtual)5.15328411.669230769230769375.36386152675452.4.25.588956128.36153846153843364.478873707905453.0.07.964798245.05384615384614305.11997244844893.1.17.799504361.7461538461538309.24973790624473.2.07.540102478.4384615384615315.73073188838063.3.02.734803595.1307692307691435.788071081460433.3.25.52567711.669230769230769366.059859275463052.4.26.181356128.36153846153843349.6781364930143.0.08.249629245.05384615384614298.00365107496013.1.18.571515361.7461538461538289.96153409462163.2.08.18971478.4384615384615299.50068917958383.3.03.088356595.1307692307691426.9547742473343.3.29.67551911.669230769230769262.37869633603122.4.25.75762128.36153846153843360.264910943536053.0.07.851845245.05384615384614307.94203131177373.1.110.34345361.7461538461538245.690865126241083.2.07.905628478.4384615384615306.598297264460263.3.03.310996595.1307692307691421.39225545340523.3.213.63876711.669230769230769163.359465806922512.4.216.768586128.3615384615384385.162928755649323.0.019.554242245.0538461538461415.5650853608391343.1.119.781603361.74615384615389.8846153846153583.2.018.15447478.438461538461550.537498481640913.3.010.974893595.1307692307691229.91466338893073.3.2ConnectShow CommandSimple ConfigLarge ACL \ No newline at end of file diff --git a/tests_new/performance/netmiko_cisco_xe.svg b/tests_new/performance/netmiko_cisco_xe.svg new file mode 100644 index 000000000..331a00dcb --- /dev/null +++ b/tests_new/performance/netmiko_cisco_xe.svg @@ -0,0 +1,4 @@ + +Netmiko: Cisco IOS-XE Performance0022446688101012121414161618182.4.23.0.03.1.13.2.03.3.03.3.2Netmiko: Cisco IOS-XE Performance4.92715211.669230769230769373.48655457270662.4.25.645057128.36153846153843354.45343153696733.0.07.729597245.05384615384614299.18803250378063.1.17.777652361.7461538461538297.91399662510243.2.00.875415478.4384615384615480.90635082632943.3.00.918163595.1307692307691479.77301432145513.3.25.23240611.669230769230769365.393649607353842.4.25.845269128.36153846153843349.14540383242233.0.07.950239245.05384615384614293.33836390856043.1.18.132597361.7461538461538288.503682090560233.2.00.992161478.4384615384615477.811176698930353.3.01.004805595.1307692307691477.475958518720063.3.27.64034111.669230769230769301.554390768004852.4.25.798335128.36153846153843350.38971971900813.0.07.866845245.05384615384614295.549308619131353.1.18.067485361.7461538461538290.229933763278953.2.01.208776478.4384615384615472.0682720717353.3.01.442458595.1307692307691465.87288653014163.3.213.06811711.669230769230769157.652999332602232.4.216.498583128.3615384615384366.704362050621633.0.018.641751245.053846153846149.8846153846153583.1.118.482892361.746153846153814.0962908741780673.2.07.719809478.4384615384615299.447532309846573.3.07.69763595.1307692307691300.035542751074443.3.2ConnectShow CommandSimple ConfigLarge ACL \ No newline at end of file diff --git a/tests_new/performance/netmiko_cisco_xr.svg b/tests_new/performance/netmiko_cisco_xr.svg new file mode 100644 index 000000000..c4b0ecd32 --- /dev/null +++ b/tests_new/performance/netmiko_cisco_xr.svg @@ -0,0 +1,4 @@ + +Netmiko: Cisco IOS-XR Performance (cisco IOS-XRv 9000)00224466881010121214141616181820202.4.23.0.03.1.13.2.03.3.03.3.2Netmiko: Cisco IOS-XR Performance (cisco IOS-XRv 9000)5.91577811.669230769230769366.31246194740142.4.26.427159128.36153846153843354.40028464851093.0.06.490066245.05384615384614352.93492059051633.1.16.461798361.7461538461538353.59339915715263.2.06.234565478.4384615384615358.88659500165763.3.02.930152595.1307692307691435.86003266312473.3.26.43476811.669230769230769354.22303958647832.4.27.046878128.36153846153843339.96446751120793.0.07.04186245.05384615384614340.081357473263273.1.17.073962361.7461538461538339.33356919867153.2.06.842288478.4384615384615344.730214290184853.3.03.613495595.1307692307691419.94214957408593.3.213.79702111.669230769230769182.72573512016342.4.212.135259128.36153846153843221.435041043846353.0.012.120415245.05384615384614221.780819161971073.1.112.47734361.7461538461538213.466560551646243.2.012.086207478.4384615384615222.57766488177773.3.03.982863595.1307692307691411.33804206024283.3.218.67149911.66923076923076969.178993697347042.4.220.613338128.3615384615384323.9455367368806833.0.021.216963245.053846153846149.8846153846154153.1.120.898713361.746153846153817.297973380653393.2.020.716205478.438461538461521.549339103012873.3.011.274209595.1307692307691241.49245472016533.3.2ConnectShow CommandSimple ConfigLarge ACL \ No newline at end of file diff --git a/tests_new/performance/netmiko_performance.csv b/tests_new/performance/netmiko_performance.csv index 1812cb906..c1fb494bf 100644 --- a/tests_new/performance/netmiko_performance.csv +++ b/tests_new/performance/netmiko_performance.csv @@ -33,3 +33,39 @@ date,netmiko_version,device_name,connect,send_command_simple,send_config_simple, 2020-9-4 8:56:12,3.3.2_dev,cisco_xr_azure,0:00:03.118182,0:00:03.106151,0:00:04.676095,0:00:12.314846 2020-9-23 15:33:32,3.3.0,arista1,0:00:08.096496,0:00:08.734566,0:00:19.013243,0:00:39.441913 2020-9-23 17:35:49,3.3.2_dev2,arista1,0:00:02.365521,0:00:02.964974,0:00:04.584866,0:00:19.276065 +2020-10-1 10:1:53,3.3.0,cisco1,0:00:01.057334,0:00:01.145539,0:00:01.136542,0:00:03.578422 +2020-10-1 10:2:5,3.3.0,cisco3,0:00:00.875415,0:00:00.992161,0:00:01.208776,0:00:07.719809 +2020-10-1 10:2:25,3.3.0,cisco5,0:00:01.871565,0:00:01.979273,0:00:02.183958,0:00:11.259029 +2020-10-1 10:3:15,3.3.0,nxos1,0:00:07.540102,0:00:08.189710,0:00:07.905628,0:00:18.154470 +2020-10-1 10:4:13,3.3.0,cisco_xr_azure,0:00:06.234565,0:00:06.842288,0:00:12.086207,0:00:20.716205 +2020-10-1 10:5:43,3.3.0,arista1,0:00:08.134659,0:00:08.788801,0:00:16.972578,0:00:38.904262 +2020-10-1 10:6:40,3.3.2,cisco1,0:00:01.065231,0:00:01.137782,0:00:01.158154,0:00:03.521735 +2020-10-1 10:6:52,3.3.2,cisco3,0:00:00.918163,0:00:01.004805,0:00:01.442458,0:00:07.697630 +2020-10-1 10:7:12,3.3.2,cisco5,0:00:01.908010,0:00:01.547097,0:00:01.848588,0:00:12.151116 +2020-10-1 10:7:36,3.3.2,nxos1,0:00:02.734803,0:00:03.088356,0:00:03.310996,0:00:10.974893 +2020-10-1 10:8:2,3.3.2,cisco_xr_azure,0:00:02.930152,0:00:03.613495,0:00:03.982863,0:00:11.274209 +2020-10-1 10:8:37,3.3.2,arista1,0:00:02.452651,0:00:02.962302,0:00:04.549834,0:00:20.658814 +2020-10-1 10:53:39,2.4.2,cisco1,0:00:05.037346,0:00:05.452299,0:00:07.732086,0:00:12.734187 +2020-10-1 10:54:18,2.4.2,cisco3,0:00:05.036440,0:00:05.355380,0:00:07.580386,0:00:13.354270 +2020-10-1 10:54:59,2.4.2,cisco5,0:00:05.290465,0:00:05.316632,0:00:07.898353,0:00:14.108584 +2020-10-1 10:55:42,2.4.2,nxos1,0:00:05.153284,0:00:05.525677,0:00:09.675519,0:00:13.638767 +2020-10-1 10:56:41,2.4.2,cisco_xr_azure,0:00:05.915778,0:00:06.434768,0:00:13.797021,0:00:18.671499 +2020-10-1 10:57:32,2.4.2,arista1,0:00:05.582540,0:00:06.278857,0:00:10.812795,0:00:17.308616 +2020-10-1 11:3:55,3.0.0,cisco1,0:00:05.634554,0:00:06.060734,0:00:05.969321,0:00:16.416379 +2020-10-1 11:4:35,3.0.0,cisco3,0:00:05.629272,0:00:06.063464,0:00:05.742221,0:00:16.464965 +2020-10-1 11:5:23,3.0.0,cisco5,0:00:06.027503,0:00:06.504281,0:00:06.631968,0:00:22.599977 +2020-10-1 11:6:3,3.0.0,nxos1,0:00:05.588956,0:00:06.181356,0:00:05.757620,0:00:16.768586 +2020-10-1 11:7:2,3.0.0,cisco_xr_azure,0:00:06.427159,0:00:07.046878,0:00:12.135259,0:00:20.613338 +2020-10-1 11:8:4,3.0.0,arista1,0:00:06.239377,0:00:06.815281,0:00:06.880786,0:00:35.616451 +2020-10-1 11:9:39,3.1.1,cisco1,0:00:07.730258,0:00:08.150364,0:00:08.077263,0:00:18.437251 +2020-10-1 11:10:29,3.1.1,cisco3,0:00:07.562568,0:00:07.957404,0:00:07.734837,0:00:18.734258 +2020-10-1 11:11:25,3.1.1,cisco5,0:00:08.101109,0:00:08.089924,0:00:08.062089,0:00:22.614042 +2020-10-1 11:12:17,3.1.1,nxos1,0:00:07.964798,0:00:08.249629,0:00:07.851845,0:00:19.554242 +2020-10-1 11:13:16,3.1.1,cisco_xr_azure,0:00:06.490066,0:00:07.041860,0:00:12.120415,0:00:21.216963 +2020-10-1 11:14:18,3.1.1,arista1,0:00:06.183318,0:00:07.020729,0:00:07.157726,0:00:34.818646 +2020-10-1 11:16:35,3.2.0,cisco1,0:00:07.741972,0:00:08.147338,0:00:08.073503,0:00:18.470662 +2020-10-1 11:17:25,3.2.0,cisco3,0:00:07.551468,0:00:08.159441,0:00:07.834617,0:00:18.620422 +2020-10-1 11:18:24,3.2.0,cisco5,0:00:08.093645,0:00:10.167814,0:00:08.480911,0:00:23.642333 +2020-10-1 11:19:19,3.2.0,nxos1,0:00:07.799504,0:00:08.571515,0:00:10.343450,0:00:19.781603 +2020-10-1 11:20:18,3.2.0,cisco_xr_azure,0:00:06.461798,0:00:07.073962,0:00:12.477340,0:00:20.898713 +2020-10-1 11:21:46,3.2.0,arista1,0:00:08.302358,0:00:09.395060,0:00:17.180089,0:00:33.984633 diff --git a/tests_new/performance/netmiko_performance_releases.csv b/tests_new/performance/netmiko_performance_releases.csv new file mode 100644 index 000000000..6ea5a48b7 --- /dev/null +++ b/tests_new/performance/netmiko_performance_releases.csv @@ -0,0 +1,35 @@ +date,netmiko_version,device_name,connect,send_command_simple,send_config_simple,send_config_large_acl +2020-8-28 9:35:2,2.4.2,cisco1,0:00:05.028585,0:00:05.437255,0:00:07.698679,0:00:12.757210 +2020-8-28 9:42:3,3.0.0,cisco1,0:00:05.651217,0:00:06.045608,0:00:05.959159,0:00:16.530688 +2020-8-28 9:47:49,3.1.1,cisco1,0:00:07.806983,0:00:08.139146,0:00:08.046488,0:00:18.478753 +2020-8-28 9:54:10,3.2.0,cisco1,0:00:07.727580,0:00:08.128382,0:00:08.053055,0:00:18.472529 +2020-10-1 10:1:53,3.3.0,cisco1,0:00:01.057334,0:00:01.145539,0:00:01.136542,0:00:03.578422 +2020-10-1 10:6:40,3.3.2,cisco1,0:00:01.065231,0:00:01.137782,0:00:01.158154,0:00:03.521735 +2020-8-28 9:35:32,2.4.2,cisco3,0:00:04.927152,0:00:05.232406,0:00:07.640341,0:00:13.068117 +2020-8-28 9:42:37,3.0.0,cisco3,0:00:05.645057,0:00:05.845269,0:00:05.798335,0:00:16.498583 +2020-8-28 9:48:32,3.1.1,cisco3,0:00:07.729597,0:00:07.950239,0:00:07.866845,0:00:18.641751 +2020-8-28 9:54:52,3.2.0,cisco3,0:00:07.777652,0:00:08.132597,0:00:08.067485,0:00:18.482892 +2020-10-1 10:2:5,3.3.0,cisco3,0:00:00.875415,0:00:00.992161,0:00:01.208776,0:00:07.719809 +2020-10-1 10:6:52,3.3.2,cisco3,0:00:00.918163,0:00:01.004805,0:00:01.442458,0:00:07.697630 +2020-8-28 9:36:9,2.4.2,cisco5,0:00:05.433502,0:00:05.890628,0:00:08.300116,0:00:16.665863 +2020-8-28 9:43:19,3.0.0,cisco5,0:00:05.973869,0:00:06.512771,0:00:06.646396,0:00:23.656478 +2020-8-28 9:49:21,3.1.1,cisco5,0:00:08.058890,0:00:08.118542,0:00:08.236710,0:00:24.947753 +2020-8-28 9:55:41,3.2.0,cisco5,0:00:08.128708,0:00:08.072531,0:00:08.230244,0:00:24.599200 +2020-10-1 10:55:42,2.4.2,nxos1,0:00:05.153284,0:00:05.525677,0:00:09.675519,0:00:13.638767 +2020-10-1 11:6:3,3.0.0,nxos1,0:00:05.588956,0:00:06.181356,0:00:05.757620,0:00:16.768586 +2020-10-1 11:12:17,3.1.1,nxos1,0:00:07.964798,0:00:08.249629,0:00:07.851845,0:00:19.554242 +2020-10-1 11:19:19,3.2.0,nxos1,0:00:07.799504,0:00:08.571515,0:00:10.343450,0:00:19.781603 +2020-10-1 10:3:15,3.3.0,nxos1,0:00:07.540102,0:00:08.189710,0:00:07.905628,0:00:18.154470 +2020-10-1 10:7:36,3.3.2,nxos1,0:00:02.734803,0:00:03.088356,0:00:03.310996,0:00:10.974893 +2020-10-1 10:56:41,2.4.2,cisco_xr_azure,0:00:05.915778,0:00:06.434768,0:00:13.797021,0:00:18.671499 +2020-10-1 11:7:2,3.0.0,cisco_xr_azure,0:00:06.427159,0:00:07.046878,0:00:12.135259,0:00:20.613338 +2020-10-1 11:13:16,3.1.1,cisco_xr_azure,0:00:06.490066,0:00:07.041860,0:00:12.120415,0:00:21.216963 +2020-10-1 11:20:18,3.2.0,cisco_xr_azure,0:00:06.461798,0:00:07.073962,0:00:12.477340,0:00:20.898713 +2020-10-1 10:4:13,3.3.0,cisco_xr_azure,0:00:06.234565,0:00:06.842288,0:00:12.086207,0:00:20.716205 +2020-10-1 10:8:2,3.3.2,cisco_xr_azure,0:00:02.930152,0:00:03.613495,0:00:03.982863,0:00:11.274209 +2020-10-1 10:57:32,2.4.2,arista1,0:00:05.582540,0:00:06.278857,0:00:10.812795,0:00:17.308616 +2020-10-1 11:8:4,3.0.0,arista1,0:00:06.239377,0:00:06.815281,0:00:06.880786,0:00:35.616451 +2020-10-1 11:14:18,3.1.1,arista1,0:00:06.183318,0:00:07.020729,0:00:07.157726,0:00:34.818646 +2020-10-1 11:21:46,3.2.0,arista1,0:00:08.302358,0:00:09.395060,0:00:17.180089,0:00:33.984633 +2020-10-1 10:5:43,3.3.0,arista1,0:00:08.134659,0:00:08.788801,0:00:16.972578,0:00:38.904262 +2020-10-1 10:8:37,3.3.2,arista1,0:00:02.452651,0:00:02.962302,0:00:04.549834,0:00:20.658814 diff --git a/tests_new/performance/test_devices.yml b/tests_new/performance/test_devices.yml index 1e98d82d4..b918c0b2a 100644 --- a/tests_new/performance/test_devices.yml +++ b/tests_new/performance/test_devices.yml @@ -18,18 +18,14 @@ nxos1: device_type: cisco_nxos host: nxos1.lasthop.io username: pyclass - # conn_timeout: 20 - # session_log: nxos1.out cisco_xr_azure: device_type: cisco_xr host: iosxr3.lasthop.io username: pyclass secret: '' - session_log: xr.out arista1: device_type: arista_eos host: arista1.lasthop.io username: pyclass - session_log: arista1.out diff --git a/tests_new/performance/test_netmiko.py b/tests_new/performance/test_netmiko.py index 6139084c3..9157c947d 100644 --- a/tests_new/performance/test_netmiko.py +++ b/tests_new/performance/test_netmiko.py @@ -134,8 +134,8 @@ def main(): devices = read_devices() print("\n\n") for dev_name, dev_dict in devices.items(): - if dev_name != "arista1": - continue + # if dev_name != "arista1": + # continue print("-" * 80) print(f"Device name: {dev_name}") print("-" * 12) From caffa64b511b8db8c1c70acc65bcec2b7813bcc3 Mon Sep 17 00:00:00 2001 From: Kirk Byers Date: Fri, 2 Oct 2020 12:31:33 -0700 Subject: [PATCH 02/49] Save config tests (#1986) * Enable save config test for NX-OS * Add improved tests for save_config; fix cisco NX-OS failure on save_config * Fix NX-OS telnet login failure issue --- netmiko/__init__.py | 2 +- netmiko/base_connection.py | 8 ++++- netmiko/cisco/cisco_nxos_ssh.py | 33 ++++++++++++++++++++ netmiko/cisco_base_connection.py | 6 ++++ tests_new/test_arista_eos/test_arista_eos.sh | 1 + tests_new/test_cisco_ios/test_ios.sh | 1 + tests_new/test_cisco_nxos/test_cisco_nxos.sh | 1 + tests_new/test_cisco_xe/test_cisco_xe.sh | 9 +++--- tests_new/test_netmiko_save.py | 18 +++++++++++ 9 files changed, 73 insertions(+), 6 deletions(-) create mode 100755 tests_new/test_netmiko_save.py diff --git a/netmiko/__init__.py b/netmiko/__init__.py index dbef5b566..2a731fbfb 100644 --- a/netmiko/__init__.py +++ b/netmiko/__init__.py @@ -23,7 +23,7 @@ # Alternate naming Netmiko = ConnectHandler -__version__ = "3.3.2" +__version__ = "3.3.3a_dev" __all__ = ( "ConnectHandler", "ssh_dispatcher", diff --git a/netmiko/base_connection.py b/netmiko/base_connection.py index 189558065..4cdbaaa85 100644 --- a/netmiko/base_connection.py +++ b/netmiko/base_connection.py @@ -708,6 +708,12 @@ def telnet_login( (default: 20) """ delay_factor = self.select_delay_factor(delay_factor) + + # FIX: Cleanup in future versions of Netmiko + if delay_factor < 1: + if not self._legacy_mode and self.fast_cli: + delay_factor = 1 + time.sleep(1 * delay_factor) output = "" @@ -1275,7 +1281,7 @@ def send_command_timing( output = "" delay_factor = self.select_delay_factor(delay_factor) - # Cleanup in future versions of Netmiko + # FIX: Cleanup in future versions of Netmiko if delay_factor < 1: if not self._legacy_mode and self.fast_cli: delay_factor = 1 diff --git a/netmiko/cisco/cisco_nxos_ssh.py b/netmiko/cisco/cisco_nxos_ssh.py index 88721bbb7..993bbb5be 100644 --- a/netmiko/cisco/cisco_nxos_ssh.py +++ b/netmiko/cisco/cisco_nxos_ssh.py @@ -32,6 +32,39 @@ def check_config_mode(self, check_string=")#", pattern="#"): """Checks if the device is in configuration mode or not.""" return super().check_config_mode(check_string=check_string, pattern=pattern) + def save_config( + self, + cmd="copy running-config startup-config", + confirm=False, + confirm_response="", + ): + self.enable() + + if confirm: + output = self.send_command_timing( + command_string=cmd, strip_prompt=False, strip_command=False + ) + if confirm_response: + output += self.send_command_timing( + confirm_response, strip_prompt=False, strip_command=False + ) + else: + # Send enter by default + output += self.send_command_timing( + self.RETURN, strip_prompt=False, strip_command=False + ) + else: + # NX-OS is very slow on save_config ensure it waits long enough. + # FIX: this is a hack as delay_factor will be set to .1 via fast_cli=True in + # send_command so increase max_loops. + output = self.send_command( + command_string=cmd, + strip_prompt=False, + strip_command=False, + max_loops=5000, + ) + return output + class CiscoNxosFileTransfer(CiscoFileTransfer): """Cisco NXOS SCP File Transfer driver.""" diff --git a/netmiko/cisco_base_connection.py b/netmiko/cisco_base_connection.py index 25a4a59e4..3907c98c8 100644 --- a/netmiko/cisco_base_connection.py +++ b/netmiko/cisco_base_connection.py @@ -81,6 +81,12 @@ def telnet_login( ): """Telnet login. Can be username/password or just password.""" delay_factor = self.select_delay_factor(delay_factor) + + # FIX: Cleanup in future versions of Netmiko + if delay_factor < 1: + if not self._legacy_mode and self.fast_cli: + delay_factor = 1 + time.sleep(1 * delay_factor) output = "" diff --git a/tests_new/test_arista_eos/test_arista_eos.sh b/tests_new/test_arista_eos/test_arista_eos.sh index 95b85b731..35d7f43c8 100755 --- a/tests_new/test_arista_eos/test_arista_eos.sh +++ b/tests_new/test_arista_eos/test_arista_eos.sh @@ -6,6 +6,7 @@ echo "Starting tests...good luck:" \ && echo "Arista EOS" \ && cd .. \ && py.test -s -x -v test_netmiko_show.py --test_device arista_sw \ +&& py.test -s -x -v test_netmiko_save.py --test_device arista_sw \ && py.test -s -x -v test_netmiko_config.py --test_device arista_sw \ && py.test -s -x -v test_netmiko_config_acl.py --test_device arista_sw \ && py.test -s -x -v test_netmiko_scp.py --test_device arista_sw \ diff --git a/tests_new/test_cisco_ios/test_ios.sh b/tests_new/test_cisco_ios/test_ios.sh index fca55379e..ebcfa9267 100755 --- a/tests_new/test_cisco_ios/test_ios.sh +++ b/tests_new/test_cisco_ios/test_ios.sh @@ -6,6 +6,7 @@ echo "Starting tests...good luck:" \ && echo "Cisco IOS" \ && cd .. \ && py.test -s -x -v test_netmiko_show.py --test_device cisco1 \ +&& py.test -s -x -v test_netmiko_save.py --test_device cisco1 \ && py.test -s -x -v test_netmiko_cmd_verify.py --test_device cisco1 \ && py.test -s -x -v test_netmiko_config.py --test_device cisco1 \ && py.test -s -x -v test_netmiko_config_acl.py --test_device cisco1 \ diff --git a/tests_new/test_cisco_nxos/test_cisco_nxos.sh b/tests_new/test_cisco_nxos/test_cisco_nxos.sh index c06de0657..27a4af710 100755 --- a/tests_new/test_cisco_nxos/test_cisco_nxos.sh +++ b/tests_new/test_cisco_nxos/test_cisco_nxos.sh @@ -6,6 +6,7 @@ echo "Starting tests...good luck:" \ && echo "Cisco NXOS" \ && cd .. \ && py.test -v -s -x test_netmiko_show.py --test_device nxos1 \ +&& py.test -v -s -x test_netmiko_save.py --test_device nxos1 \ && py.test -v -s -x test_netmiko_config.py --test_device nxos1 \ && py.test -v -s -x test_netmiko_config_acl.py --test_device nxos1 \ && py.test -v -s -x test_netmiko_scp.py --test_device nxos1 \ diff --git a/tests_new/test_cisco_xe/test_cisco_xe.sh b/tests_new/test_cisco_xe/test_cisco_xe.sh index 71fa61630..2d117fe29 100755 --- a/tests_new/test_cisco_xe/test_cisco_xe.sh +++ b/tests_new/test_cisco_xe/test_cisco_xe.sh @@ -5,10 +5,11 @@ RETURN_CODE=0 echo "Starting tests...good luck:" \ && cd .. \ && echo "Cisco IOS-XE" \ -&& py.test -v test_netmiko_show.py --test_device cisco3 \ -&& py.test -v test_netmiko_config.py --test_device cisco3 \ -&& py.test -v test_netmiko_config_acl.py --test_device cisco3 \ -&& py.test -v test_netmiko_scp.py --test_device cisco3 \ +&& py.test -s -x -v test_netmiko_show.py --test_device cisco3 \ +&& py.test -s -x -v test_netmiko_save.py --test_device cisco3 \ +&& py.test -s -x -v test_netmiko_config.py --test_device cisco3 \ +&& py.test -s -x -v test_netmiko_config_acl.py --test_device cisco3 \ +&& py.test -s -x -v test_netmiko_scp.py --test_device cisco3 \ || RETURN_CODE=1 exit $RETURN_CODE diff --git a/tests_new/test_netmiko_save.py b/tests_new/test_netmiko_save.py new file mode 100755 index 000000000..00b051efd --- /dev/null +++ b/tests_new/test_netmiko_save.py @@ -0,0 +1,18 @@ +#!/usr/bin/env python + + +def test_save_base(net_connect, commands, expected_responses): + """ + Test save config with no options. + """ + save_verify = expected_responses["save_config"] + + cmd_response = net_connect.save_config() + assert save_verify in cmd_response + + +def test_disconnect(net_connect, commands, expected_responses): + """ + Terminate the SSH session + """ + net_connect.disconnect() From 29a89ea70f88dc2fa5d89eebf9f829b81321c162 Mon Sep 17 00:00:00 2001 From: Kirk Byers Date: Sun, 4 Oct 2020 21:07:48 -0700 Subject: [PATCH 03/49] Juniper performance improvements (#1989) --- netmiko/__init__.py | 2 +- netmiko/juniper/juniper.py | 64 ++++++++++--------- tests_new/network_utilities.py | 39 +++++++++++ tests_new/performance/netmiko_performance.csv | 5 ++ tests_new/performance/test_devices.yml | 6 ++ tests_new/performance/test_netmiko.py | 11 ++-- tests_new/run_live_tests.sh | 4 ++ tests_new/test_juniper_junos/test9.txt | 1 + .../test_juniper_junos/test_juniper_junos.sh | 17 +++++ tests_new/test_juniper_junos/testx.txt | 1 + tests_new/test_netmiko_config_acl.py | 29 +++++++-- 11 files changed, 136 insertions(+), 43 deletions(-) create mode 100644 tests_new/test_juniper_junos/test9.txt create mode 100755 tests_new/test_juniper_junos/test_juniper_junos.sh create mode 100644 tests_new/test_juniper_junos/testx.txt diff --git a/netmiko/__init__.py b/netmiko/__init__.py index 2a731fbfb..e74cf0547 100644 --- a/netmiko/__init__.py +++ b/netmiko/__init__.py @@ -23,7 +23,7 @@ # Alternate naming Netmiko = ConnectHandler -__version__ = "3.3.3a_dev" +__version__ = "3.3.3b_dev" __all__ = ( "ConnectHandler", "ssh_dispatcher", diff --git a/netmiko/juniper/juniper.py b/netmiko/juniper/juniper.py index c012ce1fa..c902db492 100644 --- a/netmiko/juniper/juniper.py +++ b/netmiko/juniper/juniper.py @@ -13,22 +13,26 @@ class JuniperBase(BaseConnection): methods. Overrides several methods for Juniper-specific compatibility. """ - def session_preparation(self): - """ - Prepare the session after the connection has been established. + def __init__(self, *args, **kwargs): + # Cisco-IOS defaults to fast_cli=True and legacy_mode=False + kwargs.setdefault("fast_cli", True) + kwargs.setdefault("_legacy_mode", False) + return super().__init__(*args, **kwargs) - Disable paging (the '--more--' prompts). - Set the base prompt for interaction ('>'). - """ - self._test_channel_read() + def session_preparation(self): + """Prepare the session after the connection has been established.""" self.enter_cli_mode() + cmd = "set cli screen-width 511" + self.set_terminal_width(command=cmd, pattern=r"Screen width set to") + # Overloading disable_paging which is confusing + self.disable_paging( + command="set cli complete-on-space off", + pattern=r"Disabling complete-on-space", + ) + self.disable_paging( + command="set cli screen-length 0", pattern=r"Screen length set to" + ) self.set_base_prompt() - self._disable_complete_on_space() - self.set_terminal_width(command="set cli screen-width 511", pattern="set") - self.disable_paging(command="set cli screen-length 0") - # Clear the read buffer - time.sleep(0.3 * self.global_delay_factor) - self.clear_buffer() def _enter_shell(self): """Enter the Bourne Shell.""" @@ -38,21 +42,6 @@ def _return_cli(self): """Return to the Juniper CLI.""" return self.send_command("exit", expect_string=r"[#>]") - def _disable_complete_on_space(self): - """ - Juniper tries to auto complete commands when you type a "space" character. - - This is a bad idea for automation as what your program is sending no longer matches - the command echo from the device. So we disable this behavior. - """ - delay_factor = self.select_delay_factor(delay_factor=0) - time.sleep(delay_factor * 0.1) - command = "set cli complete-on-space off" - self.write_channel(self.normalize_cmd(command)) - time.sleep(delay_factor * 0.1) - output = self.read_channel() - return output - def enter_cli_mode(self): """Check if at shell prompt root@ and go into CLI.""" delay_factor = self.select_delay_factor(delay_factor=0) @@ -87,9 +76,16 @@ def check_config_mode(self, check_string="]"): """Checks if the device is in configuration mode or not.""" return super().check_config_mode(check_string=check_string) - def config_mode(self, config_command="configure"): + def config_mode( + self, + config_command="configure", + pattern=r"Entering configuration mode", + **kwargs, + ): """Enter configuration mode.""" - return super().config_mode(config_command=config_command) + return super().config_mode( + config_command=config_command, pattern=pattern, **kwargs + ) def exit_config_mode(self, exit_config="exit configuration-mode"): """Exit configuration mode.""" @@ -139,6 +135,12 @@ def commit( """ delay_factor = self.select_delay_factor(delay_factor) + # Commit is very slow so this is needed. + # FIX: Cleanup in future versions of Netmiko + if delay_factor < 1: + if not self._legacy_mode and self.fast_cli: + delay_factor = 1 + if check and (confirm or confirm_delay or comment): raise ValueError("Invalid arguments supplied with commit check") @@ -183,7 +185,7 @@ def commit( delay_factor=delay_factor, ) else: - output += self.send_command_expect( + output += self.send_command( command_string, strip_prompt=False, strip_command=False, diff --git a/tests_new/network_utilities.py b/tests_new/network_utilities.py index 9d7b4bfe5..7fadfa908 100644 --- a/tests_new/network_utilities.py +++ b/tests_new/network_utilities.py @@ -73,6 +73,20 @@ def generate_cisco_xr_acl( return acl +def generate_juniper_junos_acl( + acl_name="netmiko_test_large_acl", + entries=100, + base_cmd="set firewall family inet filter", + base_addr="192.168.0.0", +): + acl = [] + for i in range(1, entries + 1): + addr = ip_address(base_addr) + cmd = f"{base_cmd} {acl_name} term 10 from address {addr + i}" + acl.append(cmd) + return acl + + if __name__ == "__main__": # Test code acl = generate_ios_acl(entries=10) @@ -123,3 +137,28 @@ def generate_cisco_xr_acl( "permit ipv4 host 192.168.0.10 any", ] assert acl == xr_ref_acl + + acl = generate_juniper_junos_acl(entries=10) + ref_acl = [ + "set firewall family inet filter netmiko_test_large_acl term 10 from address " + "192.168.0.1", + "set firewall family inet filter netmiko_test_large_acl term 10 from address " + "192.168.0.2", + "set firewall family inet filter netmiko_test_large_acl term 10 from address " + "192.168.0.3", + "set firewall family inet filter netmiko_test_large_acl term 10 from address " + "192.168.0.4", + "set firewall family inet filter netmiko_test_large_acl term 10 from address " + "192.168.0.5", + "set firewall family inet filter netmiko_test_large_acl term 10 from address " + "192.168.0.6", + "set firewall family inet filter netmiko_test_large_acl term 10 from address " + "192.168.0.7", + "set firewall family inet filter netmiko_test_large_acl term 10 from address " + "192.168.0.8", + "set firewall family inet filter netmiko_test_large_acl term 10 from address " + "192.168.0.9", + "set firewall family inet filter netmiko_test_large_acl term 10 from address " + "192.168.0.10", + ] + assert acl == ref_acl diff --git a/tests_new/performance/netmiko_performance.csv b/tests_new/performance/netmiko_performance.csv index c1fb494bf..4a1ef6a2c 100644 --- a/tests_new/performance/netmiko_performance.csv +++ b/tests_new/performance/netmiko_performance.csv @@ -69,3 +69,8 @@ date,netmiko_version,device_name,connect,send_command_simple,send_config_simple, 2020-10-1 11:19:19,3.2.0,nxos1,0:00:07.799504,0:00:08.571515,0:00:10.343450,0:00:19.781603 2020-10-1 11:20:18,3.2.0,cisco_xr_azure,0:00:06.461798,0:00:07.073962,0:00:12.477340,0:00:20.898713 2020-10-1 11:21:46,3.2.0,arista1,0:00:08.302358,0:00:09.395060,0:00:17.180089,0:00:33.984633 +2020-10-4 12:37:29,3.3.3b_dev,juniper_vmx,0:00:07.568813,0:00:08.447671,0:00:20.560866,0:00:38.832646 +2020-10-4 12:47:39,3.3.3b_dev,juniper_vmx,0:00:03.703944,0:00:04.303898,0:00:05.223612,0:00:17.476638 +2020-10-4 12:49:13,3.3.3b_dev,juniper_vmx,0:00:03.699167,0:00:04.342398,0:00:05.202968,0:00:17.827907 +2020-10-4 12:50:0,3.3.3b_dev,juniper_vmx,0:00:03.759221,0:00:04.258517,0:00:05.200514,0:00:17.528799 +2020-10-4 12:52:55,3.3.3b_dev,juniper_vmx,0:00:03.563157,0:00:04.210571,0:00:05.075814,0:00:17.671961 diff --git a/tests_new/performance/test_devices.yml b/tests_new/performance/test_devices.yml index b918c0b2a..dbc07641c 100644 --- a/tests_new/performance/test_devices.yml +++ b/tests_new/performance/test_devices.yml @@ -29,3 +29,9 @@ arista1: device_type: arista_eos host: arista1.lasthop.io username: pyclass + +juniper_vmx: + device_type: juniper_junos + host: vmx1.lasthop.io + username: pyclass + session_log: vmx1.out diff --git a/tests_new/performance/test_netmiko.py b/tests_new/performance/test_netmiko.py index 9157c947d..da5f5d828 100644 --- a/tests_new/performance/test_netmiko.py +++ b/tests_new/performance/test_netmiko.py @@ -117,8 +117,11 @@ def cleanup(device): # Results will be marginally distorted by generating the ACL here. platform = device["device_type"] - base_acl_cmd = commands(platform)["config_long_acl"]["base_cmd"] - remove_acl_cmd = f"no {base_acl_cmd}" + if "juniper_junos" in platform: + remove_acl_cmd = "rollback 0" + else: + base_acl_cmd = commands(platform)["config_long_acl"]["base_cmd"] + remove_acl_cmd = f"no {base_acl_cmd}" cleanup_generic(device, remove_acl_cmd) @@ -134,8 +137,8 @@ def main(): devices = read_devices() print("\n\n") for dev_name, dev_dict in devices.items(): - # if dev_name != "arista1": - # continue + if dev_name != "juniper_vmx": + continue print("-" * 80) print(f"Device name: {dev_name}") print("-" * 12) diff --git a/tests_new/run_live_tests.sh b/tests_new/run_live_tests.sh index d6398418a..1ff8940ec 100755 --- a/tests_new/run_live_tests.sh +++ b/tests_new/run_live_tests.sh @@ -17,3 +17,7 @@ cd test_cisco_xr cd .. cd test_arista_eos ./test_arista_eos.sh > ../test_out/test_arista_eos.out 2> ../test_out/test_arista_eos.stderr & + +cd .. +cd test_juniper_junos +./test_juniper_junos.sh > ../test_out/test_juniper_junos.out 2> ../test_out/test_juniper_junos.stderr & diff --git a/tests_new/test_juniper_junos/test9.txt b/tests_new/test_juniper_junos/test9.txt new file mode 100644 index 000000000..acc8e3dd5 --- /dev/null +++ b/tests_new/test_juniper_junos/test9.txt @@ -0,0 +1 @@ +no logging console diff --git a/tests_new/test_juniper_junos/test_juniper_junos.sh b/tests_new/test_juniper_junos/test_juniper_junos.sh new file mode 100755 index 000000000..b09c3380a --- /dev/null +++ b/tests_new/test_juniper_junos/test_juniper_junos.sh @@ -0,0 +1,17 @@ +#!/bin/sh + +RETURN_CODE=0 + +echo "Starting tests...good luck:" \ +&& cd .. \ +&& echo "Juniper vMX" \ +&& py.test -s -x -v test_netmiko_show.py --test_device juniper_vmx \ +&& py.test -s -x -v test_netmiko_config.py --test_device juniper_vmx \ +&& py.test -s -x -v test_netmiko_config_acl.py --test_device juniper_vmx \ +&& py.test -s -x -v test_netmiko_commit.py --test_device juniper_vmx \ +&& py.test -s -x -v test_netmiko_scp.py --test_device juniper_vmx \ +&& py.test -s -x -v test_netmiko_autodetect.py --test_device juniper_vmx \ +|| RETURN_CODE=1 + +exit $RETURN_CODE + diff --git a/tests_new/test_juniper_junos/testx.txt b/tests_new/test_juniper_junos/testx.txt new file mode 100644 index 000000000..acc8e3dd5 --- /dev/null +++ b/tests_new/test_juniper_junos/testx.txt @@ -0,0 +1 @@ +no logging console diff --git a/tests_new/test_netmiko_config_acl.py b/tests_new/test_netmiko_config_acl.py index c2d3b27cc..df420bdf2 100755 --- a/tests_new/test_netmiko_config_acl.py +++ b/tests_new/test_netmiko_config_acl.py @@ -1,14 +1,16 @@ #!/usr/bin/env python import re import pytest -from network_utilities import generate_ios_acl, generate_nxos_acl +from network_utilities import generate_ios_acl +from network_utilities import generate_cisco_nxos_acl # noqa from network_utilities import generate_cisco_xr_acl # noqa from network_utilities import generate_arista_eos_acl # noqa +from network_utilities import generate_juniper_junos_acl # noqa def remove_acl(net_connect, cmd, commit=False): """Ensure ACL is removed.""" - net_connect.send_config_set(f"no {cmd}") + net_connect.send_config_set(cmd) if commit: net_connect.commit() net_connect.exit_config_mode() @@ -20,19 +22,24 @@ def test_large_acl(net_connect, commands, expected_responses, acl_entries=100): acl_config = commands.get("config_long_acl") base_cmd = acl_config["base_cmd"] verify_cmd = acl_config["verify_cmd"] + delete_cmd = acl_config.get("delete_cmd") offset = acl_config["offset"] else: pytest.skip("Platform not supported for ACL test") + platform = net_connect.device_type support_commit = commands.get("support_commit") - remove_acl(net_connect, cmd=base_cmd, commit=support_commit) + + if "juniper_junos" in platform: + cmd = delete_cmd + else: + cmd = f"no {base_cmd}" + remove_acl(net_connect, cmd=cmd, commit=support_commit) # Generate the ACL platform = net_connect.device_type if "cisco_ios" in net_connect.device_type or "cisco_xe" in net_connect.device_type: cfg_lines = generate_ios_acl() - elif "cisco_nxos" in net_connect.device_type: - cfg_lines = generate_nxos_acl() else: func_name = f"generate_{platform}_acl" acl_func = globals()[func_name] @@ -56,7 +63,15 @@ def test_large_acl(net_connect, commands, expected_responses, acl_entries=100): # IOS-XR potentially has a timestamp on the show command if "UTC" in verify_list[0]: verify_list.pop(0) - assert len(verify_list) == len(cfg_lines) + if "juniper_junos" in platform: + offset = 6 + assert len(verify_list) - offset == len(cfg_lines) + else: + assert len(verify_list) == len(cfg_lines) - remove_acl(net_connect, cmd=base_cmd, commit=support_commit) + if "juniper_junos" in platform: + cmd = delete_cmd + else: + cmd = f"no {base_cmd}" + remove_acl(net_connect, cmd=cmd, commit=support_commit) net_connect.disconnect() From 44b714b5f0f28e11fbc472b6d5e27f472f1bb480 Mon Sep 17 00:00:00 2001 From: JosephWhite Date: Sun, 25 Oct 2020 20:28:54 -0500 Subject: [PATCH 04/49] add telnet support to AdtranOS (#2018) Co-authored-by: jmw398 --- netmiko/adtran/__init__.py | 4 ++-- netmiko/adtran/adtran.py | 7 +++++++ netmiko/ssh_dispatcher.py | 3 ++- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/netmiko/adtran/__init__.py b/netmiko/adtran/__init__.py index a80d312d5..354eae20a 100644 --- a/netmiko/adtran/__init__.py +++ b/netmiko/adtran/__init__.py @@ -1,3 +1,3 @@ -from netmiko.adtran.adtran import AdtranOSSSH +from netmiko.adtran.adtran import AdtranOSSSH, AdtranOSTelnet -__all__ = ["AdtranOSSSH"] +__all__ = ["AdtranOSSSH", "AdtranOSTelnet"] diff --git a/netmiko/adtran/adtran.py b/netmiko/adtran/adtran.py index f6acd732f..489f7e85a 100644 --- a/netmiko/adtran/adtran.py +++ b/netmiko/adtran/adtran.py @@ -49,3 +49,10 @@ def set_base_prompt( class AdtranOSSSH(AdtranOSBase): pass + + +class AdtranOSTelnet(AdtranOSBase): + def __init__(self, *args, **kwargs): + default_enter = kwargs.get("default_enter") + kwargs["default_enter"] = "\r\n" if default_enter is None else default_enter + super().__init__(*args, **kwargs) diff --git a/netmiko/ssh_dispatcher.py b/netmiko/ssh_dispatcher.py index 64bfe6a7c..405512318 100755 --- a/netmiko/ssh_dispatcher.py +++ b/netmiko/ssh_dispatcher.py @@ -1,7 +1,7 @@ """Controls selection of proper class based on the device type.""" from netmiko.a10 import A10SSH from netmiko.accedian import AccedianSSH -from netmiko.adtran import AdtranOSSSH +from netmiko.adtran import AdtranOSSSH, AdtranOSTelnet from netmiko.alcatel import AlcatelAosSSH from netmiko.arista import AristaSSH, AristaTelnet from netmiko.arista import AristaFileTransfer @@ -238,6 +238,7 @@ FILE_TRANSFER_MAP = new_mapper # Add telnet drivers +CLASS_MAPPER["adtran_os_telnet"] = AdtranOSTelnet CLASS_MAPPER["apresia_aeos_telnet"] = ApresiaAeosTelnet CLASS_MAPPER["arista_eos_telnet"] = AristaTelnet CLASS_MAPPER["aruba_procurve_telnet"] = HPProcurveTelnet From f80dfe44111e4d19aba662d35a8233d819654286 Mon Sep 17 00:00:00 2001 From: JosephWhite Date: Mon, 26 Oct 2020 10:43:11 -0500 Subject: [PATCH 05/49] adtran's enable pattern is akin to cisco's (#2019) Co-authored-by: jmw398 --- netmiko/adtran/adtran.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/netmiko/adtran/adtran.py b/netmiko/adtran/adtran.py index 489f7e85a..933dcf0b7 100644 --- a/netmiko/adtran/adtran.py +++ b/netmiko/adtran/adtran.py @@ -22,7 +22,7 @@ def session_preparation(self): def check_enable_mode(self, check_string="#"): return super().check_enable_mode(check_string=check_string) - def enable(self, cmd="enable", pattern="", re_flags=re.IGNORECASE): + def enable(self, cmd="enable", pattern="ssword", re_flags=re.IGNORECASE): return super().enable(cmd=cmd, pattern=pattern, re_flags=re_flags) def exit_enable_mode(self, exit_command="disable"): From 16ebf604587aa90eb5a906a9628ff8a5ea2c5a10 Mon Sep 17 00:00:00 2001 From: Kirk Byers Date: Fri, 6 Nov 2020 14:25:38 -0800 Subject: [PATCH 06/49] Fix authentication exception handling. (#2030) paramiko.ssh_exception.AuthenticationException is a child class of paramiko.ssh_exception.SSHException so the order needed to be changed. --- netmiko/base_connection.py | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/netmiko/base_connection.py b/netmiko/base_connection.py index 4cdbaaa85..bb94aed54 100644 --- a/netmiko/base_connection.py +++ b/netmiko/base_connection.py @@ -946,16 +946,6 @@ def establish_connection(self, width=511, height=1000): msg = msg.lstrip() raise NetmikoTimeoutException(msg) - except paramiko.ssh_exception.SSHException as no_session_err: - self.paramiko_cleanup() - if "No existing session" in str(no_session_err): - msg = ( - "Paramiko: 'No existing session' error: " - "try increasing 'conn_timeout' to 10 seconds or larger." - ) - raise NetmikoTimeoutException(msg) - else: - raise except paramiko.ssh_exception.AuthenticationException as auth_err: self.paramiko_cleanup() msg = f"""Authentication to device failed. @@ -971,6 +961,16 @@ def establish_connection(self, width=511, height=1000): msg += self.RETURN + str(auth_err) raise NetmikoAuthenticationException(msg) + except paramiko.ssh_exception.SSHException as no_session_err: + self.paramiko_cleanup() + if "No existing session" in str(no_session_err): + msg = ( + "Paramiko: 'No existing session' error: " + "try increasing 'conn_timeout' to 10 seconds or larger." + ) + raise NetmikoTimeoutException(msg) + else: + raise if self.verbose: print(f"SSH connection established to {self.host}:{self.port}") From 66dccecf5e59bb002ab9b5c91c297b285b2b996c Mon Sep 17 00:00:00 2001 From: Kirk Byers Date: Fri, 6 Nov 2020 20:57:41 -0800 Subject: [PATCH 07/49] Fixing ssh_autodetect so most common command happens first. (#2032) * Fixing autodetect so show version is always first * Black --- .github/workflows/commit.yaml | 1 + netmiko/ssh_autodetect.py | 18 ++++++++++++++++-- tests/unit/test_ssh_autodetect.py | 7 +++++++ 3 files changed, 24 insertions(+), 2 deletions(-) create mode 100755 tests/unit/test_ssh_autodetect.py diff --git a/.github/workflows/commit.yaml b/.github/workflows/commit.yaml index 81baf6a08..1e807b2ce 100644 --- a/.github/workflows/commit.yaml +++ b/.github/workflows/commit.yaml @@ -38,4 +38,5 @@ jobs: py.test -v -s tests/test_import_netmiko.py py.test -v -s tests/unit/test_base_connection.py py.test -v -s tests/unit/test_utilities.py + py.test -v -s tests/unit/test_ssh_autodetect.py diff --git a/netmiko/ssh_autodetect.py b/netmiko/ssh_autodetect.py index d2491893f..b6fef787d 100644 --- a/netmiko/ssh_autodetect.py +++ b/netmiko/ssh_autodetect.py @@ -10,7 +10,7 @@ connection (see the *netmiko.ssh_dispatacher.ConnectHandler* function). The only acceptable value for the 'device_type' argument is 'autodetect'. -The auto-detection is solely based on the *SSH_MAPPER_BASE* dictionary. The keys are the name of +The auto-detection is solely based on *SSH_MAPPER_BASE*. The keys are the name of the 'device_type' supported for auto-detection and the value is another dictionary describing how to handle the auto-detection. @@ -189,6 +189,7 @@ "dispatch": "_autodetect_std", }, "cisco_wlc": { + "cmd": "", "dispatch": "_autodetect_remote_version", "search_patterns": [r"CISCO_WLC"], "priority": 99, @@ -207,6 +208,19 @@ }, } +# Sort SSH_MAPPER_BASE such that the most common commands are first +cmd_count = {} +for k, v in SSH_MAPPER_BASE.items(): + count = cmd_count.setdefault(v["cmd"], 0) + cmd_count[v["cmd"]] = count + 1 +cmd_count = {k: v for k, v in sorted(cmd_count.items(), key=lambda item: item[1])} + +# SSH_MAPPER_BASE will be a list after this +SSH_MAPPER_BASE = sorted( + SSH_MAPPER_BASE.items(), key=lambda item: int(cmd_count[item[1]["cmd"]]) +) +SSH_MAPPER_BASE.reverse() + class SSHDetect(object): """ @@ -259,7 +273,7 @@ def autodetect(self): best_match : str or None The device type that is currently the best to use to interact with the device """ - for device_type, autodetect_dict in SSH_MAPPER_BASE.items(): + for device_type, autodetect_dict in SSH_MAPPER_BASE: tmp_dict = autodetect_dict.copy() call_method = tmp_dict.pop("dispatch") autodetect_method = getattr(self, call_method) diff --git a/tests/unit/test_ssh_autodetect.py b/tests/unit/test_ssh_autodetect.py new file mode 100755 index 000000000..7e1cb444c --- /dev/null +++ b/tests/unit/test_ssh_autodetect.py @@ -0,0 +1,7 @@ +#!/usr/bin/env python +from netmiko.ssh_autodetect import SSH_MAPPER_BASE + + +def test_ssh_base_mapper_order(): + "SSH_MAPPER_BASE should be sorted based on the most common command used." "" + assert SSH_MAPPER_BASE[0][1]["cmd"] == "show version" From d70d30f51ea19eba760c94e5edb1414a6c7d6a98 Mon Sep 17 00:00:00 2001 From: Anirudh Kamath Date: Sat, 7 Nov 2020 21:40:21 +0400 Subject: [PATCH 08/49] Adds fortinet fortios ssh autodetect support (#2013) Co-authored-by: Anirudh Kamath --- netmiko/ssh_autodetect.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/netmiko/ssh_autodetect.py b/netmiko/ssh_autodetect.py index b6fef787d..9b1f96d26 100644 --- a/netmiko/ssh_autodetect.py +++ b/netmiko/ssh_autodetect.py @@ -206,6 +206,12 @@ "priority": 99, "dispatch": "_autodetect_std", }, + "fortinet": { + "cmd": "get system status", + "search_patterns": [r"FortiOS"], + "priority": 99, + "dispatch": "_autodetect_std", + }, } # Sort SSH_MAPPER_BASE such that the most common commands are first From 43fa087edfefc1b0512b018d1ab1cc85e18c6ade Mon Sep 17 00:00:00 2001 From: rasanentimo Date: Fri, 13 Nov 2020 17:20:55 +0200 Subject: [PATCH 09/49] fix dell_force10 autodetect (#2037) Co-authored-by: t1rasane --- netmiko/ssh_autodetect.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/netmiko/ssh_autodetect.py b/netmiko/ssh_autodetect.py index 9b1f96d26..971570244 100644 --- a/netmiko/ssh_autodetect.py +++ b/netmiko/ssh_autodetect.py @@ -101,7 +101,7 @@ }, "dell_force10": { "cmd": "show version", - "search_patterns": [r"S4048-ON"], + "search_patterns": [r"Real Time Operating System Software"], "priority": 99, "dispatch": "_autodetect_std", }, From 3a6794aeae214e0092a64515fa44c5124bc17b0d Mon Sep 17 00:00:00 2001 From: Kirk Byers Date: Sat, 14 Nov 2020 09:22:17 -0800 Subject: [PATCH 10/49] ASA performance improvements (#2038) --- netmiko/__init__.py | 2 +- netmiko/arista/arista.py | 19 ++++++--- netmiko/base_connection.py | 24 +++++++---- netmiko/cisco/cisco_asa_ssh.py | 42 +++++++++++++++---- netmiko/cisco_base_connection.py | 12 +++++- tests_new/cisco_asa_commands.txt | 3 ++ tests_new/conftest.py | 5 +++ tests_new/network_utilities.py | 29 +++++++++++++ tests_new/performance/netmiko_performance.csv | 15 +++++++ .../netmiko_performance_releases.csv | 2 + tests_new/performance/test_devices.yml | 7 ++++ tests_new/performance/test_netmiko.py | 11 ++++- tests_new/remove_delay.sh | 4 ++ tests_new/run_live_tests.sh | 4 ++ .../test_arista_eos/add_delay_cisco_xe.sh | 9 ++++ .../test_cisco_asa/add_delay_cisco_asa.sh | 9 ++++ tests_new/test_cisco_asa/test9.txt | 1 + tests_new/test_cisco_asa/test_cisco_asa.sh | 17 ++++++++ tests_new/test_cisco_asa/testx.txt | 1 + tests_new/test_netmiko_config_acl.py | 10 +++-- tests_new/test_netmiko_show.py | 4 +- 21 files changed, 201 insertions(+), 29 deletions(-) create mode 100644 tests_new/cisco_asa_commands.txt create mode 100755 tests_new/remove_delay.sh create mode 100755 tests_new/test_arista_eos/add_delay_cisco_xe.sh create mode 100755 tests_new/test_cisco_asa/add_delay_cisco_asa.sh create mode 100644 tests_new/test_cisco_asa/test9.txt create mode 100755 tests_new/test_cisco_asa/test_cisco_asa.sh create mode 100644 tests_new/test_cisco_asa/testx.txt diff --git a/netmiko/__init__.py b/netmiko/__init__.py index e74cf0547..0f95afb30 100644 --- a/netmiko/__init__.py +++ b/netmiko/__init__.py @@ -23,7 +23,7 @@ # Alternate naming Netmiko = ConnectHandler -__version__ = "3.3.3b_dev" +__version__ = "3.3.3c_dev" __all__ = ( "ConnectHandler", "ssh_dispatcher", diff --git a/netmiko/arista/arista.py b/netmiko/arista/arista.py index 8378858ac..9f5b5af39 100644 --- a/netmiko/arista/arista.py +++ b/netmiko/arista/arista.py @@ -17,7 +17,18 @@ def session_preparation(self): self.disable_paging(cmd_verify=False, pattern=r"Pagination disabled") self.set_base_prompt() - def check_config_mode(self, check_string=")#", pattern=""): + def enable( + self, + cmd="enable", + pattern="ssword", + enable_pattern=r"\#", + re_flags=re.IGNORECASE, + ): + return super().enable( + cmd=cmd, pattern=pattern, enable_pattern=enable_pattern, re_flags=re_flags + ) + + def check_config_mode(self, check_string=")#", pattern=r"[>\#]"): """ Checks if the device is in configuration mode or not. @@ -27,11 +38,7 @@ def check_config_mode(self, check_string=")#", pattern=""): Can also be (s2) """ self.write_channel(self.RETURN) - # You can encounter an issue here (on router name changes) prefer delay-based solution - if not pattern: - output = self._read_channel_timing() - else: - output = self.read_until_pattern(pattern=pattern) + output = self.read_until_pattern(pattern=pattern) output = output.replace("(s1)", "") output = output.replace("(s2)", "") return check_string in output diff --git a/netmiko/base_connection.py b/netmiko/base_connection.py index bb94aed54..bf5f97c7f 100644 --- a/netmiko/base_connection.py +++ b/netmiko/base_connection.py @@ -1649,7 +1649,9 @@ def check_enable_mode(self, check_string=""): output = self.read_until_prompt() return check_string in output - def enable(self, cmd="", pattern="ssword", re_flags=re.IGNORECASE): + def enable( + self, cmd="", pattern="ssword", enable_pattern=None, re_flags=re.IGNORECASE + ): """Enter enable mode. :param cmd: Device command to enter enable mode @@ -1658,6 +1660,9 @@ def enable(self, cmd="", pattern="ssword", re_flags=re.IGNORECASE): :param pattern: pattern to search for indicating device is waiting for password :type pattern: str + :param enable_pattern: pattern indicating you have entered enable mode + :type pattern: str + :param re_flags: Regular expression flags used in conjunction with pattern :type re_flags: int """ @@ -1669,15 +1674,20 @@ def enable(self, cmd="", pattern="ssword", re_flags=re.IGNORECASE): if not self.check_enable_mode(): self.write_channel(self.normalize_cmd(cmd)) try: - output += self.read_until_prompt_or_pattern( - pattern=pattern, re_flags=re_flags - ) + output += self.read_until_pattern(pattern=re.escape(cmd.strip())) + if pattern not in output: + output += self.read_until_prompt_or_pattern( + pattern=pattern, re_flags=re_flags + ) self.write_channel(self.normalize_cmd(self.secret)) - output += self.read_until_prompt() + if enable_pattern: + output += self.read_until_pattern(pattern=enable_pattern) + else: + output += self.read_until_prompt() + if not self.check_enable_mode(): + raise ValueError(msg) except NetmikoTimeoutException: raise ValueError(msg) - if not self.check_enable_mode(): - raise ValueError(msg) return output def exit_enable_mode(self, exit_command=""): diff --git a/netmiko/cisco/cisco_asa_ssh.py b/netmiko/cisco/cisco_asa_ssh.py index 54c15540b..09702de03 100644 --- a/netmiko/cisco/cisco_asa_ssh.py +++ b/netmiko/cisco/cisco_asa_ssh.py @@ -8,15 +8,34 @@ class CiscoAsaSSH(CiscoSSHConnection): """Subclass specific to Cisco ASA.""" + def __init__(self, *args, **kwargs): + kwargs.setdefault("fast_cli", True) + kwargs.setdefault("_legacy_mode", False) + kwargs.setdefault("allow_auto_change", True) + return super().__init__(*args, **kwargs) + + def check_config_mode(self, check_string=")#", pattern=r"[>\#]"): + return super().check_config_mode(check_string=check_string, pattern=pattern) + + def enable( + self, + cmd="enable", + pattern="ssword", + enable_pattern=r"\#", + re_flags=re.IGNORECASE, + ): + return super().enable( + cmd=cmd, pattern=pattern, enable_pattern=enable_pattern, re_flags=re_flags + ) + def session_preparation(self): """Prepare the session after the connection has been established.""" - self._test_channel_read() - self.set_base_prompt() if self.secret: self.enable() else: self.asa_login() + self.disable_paging(command="terminal pager 0") if self.allow_auto_change: try: @@ -28,11 +47,7 @@ def session_preparation(self): # Disable cmd_verify if the terminal width can't be set self.global_cmd_verify = False - self.disable_paging(command="terminal pager 0") - - # Clear the read buffer - time.sleep(0.3 * self.global_delay_factor) - self.clear_buffer() + self.set_base_prompt() def send_command_timing(self, *args, **kwargs): """ @@ -104,9 +119,10 @@ def asa_login(self): i = 1 max_attempts = 10 self.write_channel("login" + self.RETURN) + output = self.read_until_pattern(pattern=r"login") while i <= max_attempts: time.sleep(0.5 * delay_factor) - output = self.read_channel() + output += self.read_channel() if "sername" in output: self.write_channel(self.username + self.RETURN) elif "ssword" in output: @@ -126,6 +142,16 @@ def save_config(self, cmd="write mem", confirm=False, confirm_response=""): cmd=cmd, confirm=confirm, confirm_response=confirm_response ) + def normalize_linefeeds(self, a_string): + """Cisco ASA needed that extra \r\n\r""" + newline = re.compile("(\r\n\r|\r\r\r\n|\r\r\n|\r\n|\n\r)") + a_string = newline.sub(self.RESPONSE_RETURN, a_string) + if self.RESPONSE_RETURN == "\n": + # Delete any remaining \r + return re.sub("\r", "", a_string) + else: + return a_string + class CiscoAsaFileTransfer(CiscoFileTransfer): """Cisco ASA SCP File Transfer driver.""" diff --git a/netmiko/cisco_base_connection.py b/netmiko/cisco_base_connection.py index 3907c98c8..61ec7e162 100644 --- a/netmiko/cisco_base_connection.py +++ b/netmiko/cisco_base_connection.py @@ -13,9 +13,17 @@ def check_enable_mode(self, check_string="#"): """Check if in enable mode. Return boolean.""" return super().check_enable_mode(check_string=check_string) - def enable(self, cmd="enable", pattern="ssword", re_flags=re.IGNORECASE): + def enable( + self, + cmd="enable", + pattern="ssword", + enable_pattern=None, + re_flags=re.IGNORECASE, + ): """Enter enable mode.""" - return super().enable(cmd=cmd, pattern=pattern, re_flags=re_flags) + return super().enable( + cmd=cmd, pattern=pattern, enable_pattern=enable_pattern, re_flags=re_flags + ) def exit_enable_mode(self, exit_command="disable"): """Exits enable (privileged exec) mode.""" diff --git a/tests_new/cisco_asa_commands.txt b/tests_new/cisco_asa_commands.txt new file mode 100644 index 000000000..c7f32136c --- /dev/null +++ b/tests_new/cisco_asa_commands.txt @@ -0,0 +1,3 @@ +logging buffered notifications +no logging console +logging buffered warnings diff --git a/tests_new/conftest.py b/tests_new/conftest.py index 19ee55afb..ce0cb8284 100755 --- a/tests_new/conftest.py +++ b/tests_new/conftest.py @@ -496,6 +496,11 @@ def get_platform_args(): "enable_scp": True, "delete_file": delete_file_ios, }, + "cisco_asa": { + "file_system": "flash:", + "enable_scp": False, + "delete_file": delete_file_ios, + }, "juniper_junos": { "file_system": "/var/tmp", "enable_scp": False, diff --git a/tests_new/network_utilities.py b/tests_new/network_utilities.py index 7fadfa908..658ca68d4 100644 --- a/tests_new/network_utilities.py +++ b/tests_new/network_utilities.py @@ -87,6 +87,20 @@ def generate_juniper_junos_acl( return acl +def generate_cisco_asa_acl( + acl_name="netmiko_test_large_acl", + entries=100, + base_cmd=None, + base_addr="192.168.0.0", +): + acl = [] + for i in range(1, entries + 1): + addr = ip_address(base_addr) + cmd = f"access-list {acl_name} extended permit ip host {addr + i} any" + acl.append(cmd) + return acl + + if __name__ == "__main__": # Test code acl = generate_ios_acl(entries=10) @@ -162,3 +176,18 @@ def generate_juniper_junos_acl( "192.168.0.10", ] assert acl == ref_acl + + acl = generate_cisco_asa_acl(entries=10) + ref_acl = [ + "access-list netmiko_test_large_acl extended permit ip host 192.168.0.1 any", + "access-list netmiko_test_large_acl extended permit ip host 192.168.0.2 any", + "access-list netmiko_test_large_acl extended permit ip host 192.168.0.3 any", + "access-list netmiko_test_large_acl extended permit ip host 192.168.0.4 any", + "access-list netmiko_test_large_acl extended permit ip host 192.168.0.5 any", + "access-list netmiko_test_large_acl extended permit ip host 192.168.0.6 any", + "access-list netmiko_test_large_acl extended permit ip host 192.168.0.7 any", + "access-list netmiko_test_large_acl extended permit ip host 192.168.0.8 any", + "access-list netmiko_test_large_acl extended permit ip host 192.168.0.9 any", + "access-list netmiko_test_large_acl extended permit ip host 192.168.0.10 any", + ] + assert acl == ref_acl diff --git a/tests_new/performance/netmiko_performance.csv b/tests_new/performance/netmiko_performance.csv index 4a1ef6a2c..b3fa98935 100644 --- a/tests_new/performance/netmiko_performance.csv +++ b/tests_new/performance/netmiko_performance.csv @@ -74,3 +74,18 @@ date,netmiko_version,device_name,connect,send_command_simple,send_config_simple, 2020-10-4 12:49:13,3.3.3b_dev,juniper_vmx,0:00:03.699167,0:00:04.342398,0:00:05.202968,0:00:17.827907 2020-10-4 12:50:0,3.3.3b_dev,juniper_vmx,0:00:03.759221,0:00:04.258517,0:00:05.200514,0:00:17.528799 2020-10-4 12:52:55,3.3.3b_dev,juniper_vmx,0:00:03.563157,0:00:04.210571,0:00:05.075814,0:00:17.671961 +2020-11-8 14:58:27,3.3.3c_dev,cisco_asa,0:00:16.318104,0:00:16.779982,0:00:24.889048,0:00:35.191781 +2020-11-8 15:1:21,2.4.2,cisco_asa,0:00:18.067647,0:00:18.494306,0:00:29.191116,0:00:34.154877 +2020-11-8 15:12:11,3.0.0,cisco_asa,0:00:16.422504,0:00:16.952686,0:00:25.192433,0:00:35.472973 +2020-11-8 15:15:34,3.1.1,cisco_asa,0:00:16.521881,0:00:16.991102,0:00:25.264786,0:00:35.377285 +2020-11-8 15:24:9,3.2.0,cisco_asa,0:00:16.424229,0:00:16.847113,0:00:25.260711,0:00:35.294573 +2020-11-8 20:3:20,3.3.0,cisco_asa,0:00:16.023152,0:00:16.673929,0:00:24.966916,0:00:35.283717 +2020-11-8 20:6:7,3.3.2,cisco_asa,0:00:16.327899,0:00:16.746865,0:00:25.060694,0:00:35.176360 +2020-11-8 20:52:42,3.3.3c_dev,cisco_asa,0:00:01.337805,0:00:01.415179,0:00:02.254691,0:00:04.573251 +2020-11-8 20:53:1,3.3.3c_dev,cisco_asa,0:00:01.337472,0:00:01.406310,0:00:02.246537,0:00:04.565415 +2020-11-8 21:8:15,3.3.3c_dev,cisco_asa,0:00:01.373036,0:00:01.405511,0:00:02.265919,0:00:11.419664 +2020-11-8 21:9:38,3.3.3c_dev,cisco_asa,0:00:01.354220,0:00:01.416650,0:00:02.240909,0:00:04.689644 +2020-11-8 21:10:29,3.3.3c_dev,cisco_asa,0:00:01.335749 +2020-11-10 9:35:32,3.3.3c_dev,cisco_asa,0:00:02.315173,0:00:05.056590,0:00:05.385929,0:00:09.679323 +2020-11-10 9:36:38,3.3.3c_dev,cisco_asa,0:00:02.635349,0:00:04.899354,0:00:05.307428,0:00:10.969548 +2020-11-11 20:50:21,3.3.3c_dev,cisco_asa,0:00:02.912656,0:00:05.406800,0:00:04.585313,0:00:10.496970 diff --git a/tests_new/performance/netmiko_performance_releases.csv b/tests_new/performance/netmiko_performance_releases.csv index 6ea5a48b7..e4e2a9aaa 100644 --- a/tests_new/performance/netmiko_performance_releases.csv +++ b/tests_new/performance/netmiko_performance_releases.csv @@ -33,3 +33,5 @@ date,netmiko_version,device_name,connect,send_command_simple,send_config_simple, 2020-10-1 11:21:46,3.2.0,arista1,0:00:08.302358,0:00:09.395060,0:00:17.180089,0:00:33.984633 2020-10-1 10:5:43,3.3.0,arista1,0:00:08.134659,0:00:08.788801,0:00:16.972578,0:00:38.904262 2020-10-1 10:8:37,3.3.2,arista1,0:00:02.452651,0:00:02.962302,0:00:04.549834,0:00:20.658814 +2020-11-8 20:6:7,3.3.2,cisco_asa,0:00:16.327899,0:00:16.746865,0:00:25.060694,0:00:35.176360 +2020-11-11 20:50:21,3.3.3c_dev,cisco_asa,0:00:02.912656,0:00:05.406800,0:00:04.585313,0:00:10.496970 diff --git a/tests_new/performance/test_devices.yml b/tests_new/performance/test_devices.yml index dbc07641c..b83b9d9ce 100644 --- a/tests_new/performance/test_devices.yml +++ b/tests_new/performance/test_devices.yml @@ -35,3 +35,10 @@ juniper_vmx: host: vmx1.lasthop.io username: pyclass session_log: vmx1.out + +cisco_asa: + device_type: cisco_asa + ip: 184.105.247.88 + username: pyclass + allow_auto_change: True + session_log: asa1.out diff --git a/tests_new/performance/test_netmiko.py b/tests_new/performance/test_netmiko.py index da5f5d828..29a303235 100644 --- a/tests_new/performance/test_netmiko.py +++ b/tests_new/performance/test_netmiko.py @@ -10,6 +10,11 @@ import network_utilities + +# import logging +# logging.basicConfig(filename='test.log', level=logging.DEBUG) +# logger = logging.getLogger("netmiko") + PRINT_DEBUG = False PWD = path.dirname(path.realpath(__file__)) @@ -119,6 +124,8 @@ def cleanup(device): platform = device["device_type"] if "juniper_junos" in platform: remove_acl_cmd = "rollback 0" + elif "cisco_asa" in platform: + remove_acl_cmd = "clear configure access-list netmiko_test_large_acl" else: base_acl_cmd = commands(platform)["config_long_acl"]["base_cmd"] remove_acl_cmd = f"no {base_acl_cmd}" @@ -137,13 +144,15 @@ def main(): devices = read_devices() print("\n\n") for dev_name, dev_dict in devices.items(): - if dev_name != "juniper_vmx": + if dev_name != "cisco_asa": continue print("-" * 80) print(f"Device name: {dev_name}") print("-" * 12) dev_dict["password"] = PASSWORD + if dev_name == "cisco_asa": + dev_dict["secret"] = PASSWORD # Run tests operations = [ diff --git a/tests_new/remove_delay.sh b/tests_new/remove_delay.sh new file mode 100755 index 000000000..4619b5d7f --- /dev/null +++ b/tests_new/remove_delay.sh @@ -0,0 +1,4 @@ +#!/bin/bash + +# Remove delay for cisco3; must be root or sudo to execute +sudo -s /sbin/tc qdisc del dev eth0 root diff --git a/tests_new/run_live_tests.sh b/tests_new/run_live_tests.sh index 1ff8940ec..a83b5ad7c 100755 --- a/tests_new/run_live_tests.sh +++ b/tests_new/run_live_tests.sh @@ -21,3 +21,7 @@ cd test_arista_eos cd .. cd test_juniper_junos ./test_juniper_junos.sh > ../test_out/test_juniper_junos.out 2> ../test_out/test_juniper_junos.stderr & + +cd .. +cd test_cisco_asa +./test_cisco_asa.sh > ../test_out/test_cisco_asa.out 2> ../test_out/test_cisco_asa.stderr & diff --git a/tests_new/test_arista_eos/add_delay_cisco_xe.sh b/tests_new/test_arista_eos/add_delay_cisco_xe.sh new file mode 100755 index 000000000..9091873db --- /dev/null +++ b/tests_new/test_arista_eos/add_delay_cisco_xe.sh @@ -0,0 +1,9 @@ +#!/bin/bash + +# Add delay for cisco3; must be root or sudo to execute +sudo -s /sbin/tc qdisc del dev eth0 root +sudo -s /sbin/tc qdisc add dev eth0 root handle 1: prio +sudo -s /sbin/tc qdisc add dev eth0 parent 1:3 handle 30: tbf rate 20kbit buffer 1600 limit 3000 +sudo -s /sbin/tc qdisc add dev eth0 parent 30:1 handle 31: netem delay 1000ms 10ms distribution normal loss 10% +sudo -s /sbin/tc filter add dev eth0 protocol ip parent 1:0 prio 3 u32 match ip dst 184.105.247.92/32 flowid 1:3 + diff --git a/tests_new/test_cisco_asa/add_delay_cisco_asa.sh b/tests_new/test_cisco_asa/add_delay_cisco_asa.sh new file mode 100755 index 000000000..a9f4bb70a --- /dev/null +++ b/tests_new/test_cisco_asa/add_delay_cisco_asa.sh @@ -0,0 +1,9 @@ +#!/bin/bash + +# Add delay for ASA; must be root or sudo to execute +sudo -s /sbin/tc qdisc del dev eth0 root +sudo -s /sbin/tc qdisc add dev eth0 root handle 1: prio +sudo -s /sbin/tc qdisc add dev eth0 parent 1:3 handle 30: tbf rate 20kbit buffer 1600 limit 3000 +sudo -s /sbin/tc qdisc add dev eth0 parent 30:1 handle 31: netem delay 1000ms 10ms distribution normal loss 10% +sudo -s /sbin/tc filter add dev eth0 protocol ip parent 1:0 prio 3 u32 match ip dst 184.105.247.88/32 flowid 1:3 + diff --git a/tests_new/test_cisco_asa/test9.txt b/tests_new/test_cisco_asa/test9.txt new file mode 100644 index 000000000..acc8e3dd5 --- /dev/null +++ b/tests_new/test_cisco_asa/test9.txt @@ -0,0 +1 @@ +no logging console diff --git a/tests_new/test_cisco_asa/test_cisco_asa.sh b/tests_new/test_cisco_asa/test_cisco_asa.sh new file mode 100755 index 000000000..384075196 --- /dev/null +++ b/tests_new/test_cisco_asa/test_cisco_asa.sh @@ -0,0 +1,17 @@ +#!/bin/sh + +RETURN_CODE=0 + +echo "Starting tests...good luck:" \ +&& echo "Cisco ASA" \ +&& cd .. \ +&& py.test -s -v -x test_netmiko_show.py --test_device cisco_asa \ +&& py.test -s -v -x test_netmiko_config.py --test_device cisco_asa \ +&& py.test -s -x -v test_netmiko_scp.py --test_device cisco_asa \ +&& py.test -s -x -v test_netmiko_config_acl.py --test_device cisco_asa \ +&& py.test -s -v -x test_netmiko_autodetect.py --test_device cisco_asa \ +&& py.test -s -v -x test_netmiko_show.py --test_device cisco_asa_login \ +&& py.test -s -v -x test_netmiko_config.py --test_device cisco_asa_login \ +|| RETURN_CODE=1 + +exit $RETURN_CODE diff --git a/tests_new/test_cisco_asa/testx.txt b/tests_new/test_cisco_asa/testx.txt new file mode 100644 index 000000000..acc8e3dd5 --- /dev/null +++ b/tests_new/test_cisco_asa/testx.txt @@ -0,0 +1 @@ +no logging console diff --git a/tests_new/test_netmiko_config_acl.py b/tests_new/test_netmiko_config_acl.py index df420bdf2..94f6d8779 100755 --- a/tests_new/test_netmiko_config_acl.py +++ b/tests_new/test_netmiko_config_acl.py @@ -3,6 +3,7 @@ import pytest from network_utilities import generate_ios_acl from network_utilities import generate_cisco_nxos_acl # noqa +from network_utilities import generate_cisco_asa_acl # noqa from network_utilities import generate_cisco_xr_acl # noqa from network_utilities import generate_arista_eos_acl # noqa from network_utilities import generate_juniper_junos_acl # noqa @@ -30,7 +31,7 @@ def test_large_acl(net_connect, commands, expected_responses, acl_entries=100): platform = net_connect.device_type support_commit = commands.get("support_commit") - if "juniper_junos" in platform: + if "juniper_junos" in platform or "cisco_asa" in platform: cmd = delete_cmd else: cmd = f"no {base_cmd}" @@ -57,7 +58,7 @@ def test_large_acl(net_connect, commands, expected_responses, acl_entries=100): assert len(result_list) == len(cfg_lines) + offset # Check that length of lines in show of the acl matches lines configured - verify = net_connect.send_command(verify_cmd) + verify = net_connect.send_command(verify_cmd, delay_factor=10) verify_list = re.split(r"\n+", verify.strip()) # IOS-XR potentially has a timestamp on the show command @@ -66,10 +67,13 @@ def test_large_acl(net_connect, commands, expected_responses, acl_entries=100): if "juniper_junos" in platform: offset = 6 assert len(verify_list) - offset == len(cfg_lines) + elif "cisco_asa" in platform: + offset = 1 + assert len(verify_list) - offset == len(cfg_lines) else: assert len(verify_list) == len(cfg_lines) - if "juniper_junos" in platform: + if "juniper_junos" in platform or "cisco_asa" in platform: cmd = delete_cmd else: cmd = f"no {base_cmd}" diff --git a/tests_new/test_netmiko_show.py b/tests_new/test_netmiko_show.py index 3ae21b8a1..02a98219a 100755 --- a/tests_new/test_netmiko_show.py +++ b/tests_new/test_netmiko_show.py @@ -187,7 +187,9 @@ def test_send_command_genie(net_connect, commands, expected_responses): time.sleep(1) net_connect.clear_buffer() fallback_cmd = commands.get("basic") - command = commands.get("basic_textfsm", fallback_cmd) + command = commands.get("basic_genie") + if not command: + command = commands.get("basic_textfsm", fallback_cmd) show_ip_alt = net_connect.send_command(command, use_genie=True) assert isinstance(show_ip_alt, dict) From acfea3003e458fc2e95bb981d255b088ef9f0b81 Mon Sep 17 00:00:00 2001 From: JosephWhite Date: Tue, 17 Nov 2020 08:28:46 -0600 Subject: [PATCH 11/49] override dsa_checks only when TPLinkSSH is initialized (#2042) Co-authored-by: jmw398 --- netmiko/tplink/tplink_jetstream.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/netmiko/tplink/tplink_jetstream.py b/netmiko/tplink/tplink_jetstream.py index 45a61a1f6..673bff68c 100644 --- a/netmiko/tplink/tplink_jetstream.py +++ b/netmiko/tplink/tplink_jetstream.py @@ -124,7 +124,12 @@ def set_base_prompt( class TPLinkJetStreamSSH(TPLinkJetStreamBase): - def _override_check_dsa_parameters(parameters): + def __init__(self, **kwargs): + dsa._check_dsa_parameters = self._override_check_dsa_parameters + + return super().__init__(**kwargs) + + def _override_check_dsa_parameters(self, parameters): """ Override check_dsa_parameters from cryptography's dsa.py @@ -148,8 +153,6 @@ def _override_check_dsa_parameters(parameters): if not (1 < parameters.g < parameters.p): raise ValueError("g, p don't satisfy 1 < g < p.") - dsa._check_dsa_parameters = _override_check_dsa_parameters - class TPLinkJetStreamTelnet(TPLinkJetStreamBase): def telnet_login( From 4f54059e0d5c4c1093a31305640f83bd42e587fc Mon Sep 17 00:00:00 2001 From: Piter Punk <46852068+piterpunk@users.noreply.github.com> Date: Tue, 17 Nov 2020 11:43:12 -0300 Subject: [PATCH 12/49] Fix tplink_jetstream to support cryptography 3.1+ (#2043) - Replaced the use of cryptography utils bit_length() function by a direct call to parameters.q.bit_length() Co-authored-by: piterpunk --- netmiko/tplink/tplink_jetstream.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/netmiko/tplink/tplink_jetstream.py b/netmiko/tplink/tplink_jetstream.py index 673bff68c..0458007ad 100644 --- a/netmiko/tplink/tplink_jetstream.py +++ b/netmiko/tplink/tplink_jetstream.py @@ -1,7 +1,6 @@ import re import time -from cryptography import utils as crypto_utils from cryptography.hazmat.primitives.asymmetric import dsa from netmiko import log @@ -147,7 +146,7 @@ def _override_check_dsa_parameters(self, parameters): It's still not possible to remove this hack. """ - if crypto_utils.bit_length(parameters.q) not in [160, 256]: + if parameters.q.bit_length() not in [160, 256]: raise ValueError("q must be exactly 160 or 256 bits long") if not (1 < parameters.g < parameters.p): From 33c33e3f45d48f04c07dfaa7904fc46218244260 Mon Sep 17 00:00:00 2001 From: Kirk Byers Date: Thu, 19 Nov 2020 11:57:46 -0800 Subject: [PATCH 13/49] Allowing Dell OS10 to support hyphen or space (#2047) --- netmiko/ssh_autodetect.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/netmiko/ssh_autodetect.py b/netmiko/ssh_autodetect.py index 971570244..92f8dacf8 100644 --- a/netmiko/ssh_autodetect.py +++ b/netmiko/ssh_autodetect.py @@ -116,7 +116,7 @@ }, "dell_os10": { "cmd": "show version", - "search_patterns": [r"Dell EMC Networking OS10-Enterprise"], + "search_patterns": [r"Dell EMC Networking OS10.Enterprise"], "priority": 99, "dispatch": "_autodetect_std", }, From 753cb53aca7692e8e67d3386b7614788f2b34d06 Mon Sep 17 00:00:00 2001 From: DylanHamel Date: Sat, 21 Nov 2020 19:01:16 +0100 Subject: [PATCH 14/49] Add Ericsson IPOS support (#1524) Co-authored-by: Dylan Hamel --- netmiko/ericsson/__init__.py | 3 + netmiko/ericsson/ericsson_ipos.py | 144 ++++++++++++++++++++++++++++++ netmiko/ssh_dispatcher.py | 2 + netmiko/utilities.py | 1 + tests/test_ericsson_ipos.py | 34 +++++++ 5 files changed, 184 insertions(+) create mode 100644 netmiko/ericsson/__init__.py create mode 100644 netmiko/ericsson/ericsson_ipos.py create mode 100755 tests/test_ericsson_ipos.py diff --git a/netmiko/ericsson/__init__.py b/netmiko/ericsson/__init__.py new file mode 100644 index 000000000..0e66db056 --- /dev/null +++ b/netmiko/ericsson/__init__.py @@ -0,0 +1,3 @@ +from netmiko.ericsson.ericsson_ipos import EricssonIposSSH + +__all__ = ["EricssonIposSSH"] diff --git a/netmiko/ericsson/ericsson_ipos.py b/netmiko/ericsson/ericsson_ipos.py new file mode 100644 index 000000000..2ef33517e --- /dev/null +++ b/netmiko/ericsson/ericsson_ipos.py @@ -0,0 +1,144 @@ +import re + +from netmiko.base_connection import BaseConnection + + +class EricssonIposSSH(BaseConnection): + def check_enable_mode(self, check_string="#"): + """ + Check if in enable mode. Return boolean. + """ + return super().check_enable_mode(check_string=check_string) + + def enable(self, cmd="enable 15", pattern="ssword", re_flags=re.IGNORECASE): + """Enter enable mode.""" + return super().enable(cmd=cmd, pattern=pattern, re_flags=re_flags) + + def disable_paging(self, command="terminal length 0", delay_factor=1): + """Disable paging default to a Cisco CLI method. + + :param command: Device command to disable pagination of output + :type command: str + + :param delay_factor: See __init__: global_delay_factor + :type delay_factor: int + """ + return super().disable_paging(command=command, delay_factor=delay_factor) + + def set_terminal_width(self, command="terminal width 512", delay_factor=1): + """CLI terminals try to automatically adjust the line based on the width of the terminal. + This causes the output to get distorted when accessed programmatically. + + Set terminal width to 511 which works on a broad set of devices. + + :param command: Command string to send to the device + :type command: str + + :param delay_factor: See __init__: global_delay_factor + :type delay_factor: int + """ + return super().set_terminal_width(command=command, delay_factor=delay_factor) + + def send_config_set(self, config_commands=None, exit_config_mode=False, **kwargs): + """Ericsson IPOS requires you not exit from configuration mode.""" + return super().send_config_set( + config_commands=config_commands, exit_config_mode=exit_config_mode, **kwargs + ) + + def exit_enable_mode(self, exit_command="disable"): + """ + Exits enable (privileged exec) mode. + """ + return super().exit_enable_mode(exit_command=exit_command) + + def check_config_mode(self, check_string=")#", pattern=""): + """ + Checks if the device is in configuration mode or not. + """ + return super().check_config_mode(check_string=check_string, pattern=pattern) + + def config_mode(self, config_command="configure", pattern=""): + """ + Enter into configuration mode on remote device. + """ + if not pattern: + pattern = re.escape(self.base_prompt[:16]) + return super().config_mode(config_command=config_command, pattern=pattern) + + def exit_config_mode(self, exit_config="end", pattern="#"): + """ + Exit from configuration mode. + Ercisson output : + end Commit configuration changes and return to exec mode + """ + return super().exit_config_mode(exit_config=exit_config, pattern=pattern) + + def save_config(self, cmd="save config", confirm=True, confirm_response="yes"): + """Saves configuration""" + if confirm: + output = self.send_command_timing( + command_string=cmd, strip_prompt=False, strip_command=False + ) + + if confirm_response: + output += self.send_command_timing( + confirm_response, strip_prompt=False, strip_command=False + ) + else: + output += self.send_command_timing( + self.RETURN, strip_prompt=False, strip_command=False + ) + else: + output = self.send_command( + command_string=cmd, strip_prompt=False, strip_command=False + ) + return output + + def commit(self, confirm=False, confirm_delay=None, comment="", delay_factor=1): + """ + Commit the candidate configuration. + + Commit the entered configuration. Raise an error and return the failure + if the commit fails. + + Automatically enters configuration mode + + """ + + delay_factor = self.select_delay_factor(delay_factor) + + if confirm_delay and not confirm: + raise ValueError( + "Invalid arguments supplied to commit method both confirm and check" + ) + + command_string = "commit" + commit_marker = "Transaction committed" + if confirm: + if confirm_delay: + command_string = f"commit confirmed {confirm_delay}" + else: + command_string = "commit confirmed" + commit_marker = "Commit confirmed ,it will be rolled back within" + + if comment: + if '"' in comment: + raise ValueError("Invalid comment contains double quote") + comment = f'"{comment}"' + command_string += f" comment {comment}" + + output = self.config_mode() + + output += self.send_command_expect( + command_string, + strip_prompt=False, + strip_command=False, + delay_factor=delay_factor, + ) + + if commit_marker not in output: + raise ValueError(f"Commit failed with the following errors:\n\n{output}") + + self.exit_config_mode() + + return output diff --git a/netmiko/ssh_dispatcher.py b/netmiko/ssh_dispatcher.py index 405512318..3188f9631 100755 --- a/netmiko/ssh_dispatcher.py +++ b/netmiko/ssh_dispatcher.py @@ -39,6 +39,7 @@ from netmiko.eltex import EltexSSH, EltexEsrSSH from netmiko.endace import EndaceSSH from netmiko.enterasys import EnterasysSSH +from netmiko.ericsson import EricssonIposSSH from netmiko.extreme import ExtremeErsSSH from netmiko.extreme import ExtremeExosSSH from netmiko.extreme import ExtremeExosTelnet @@ -146,6 +147,7 @@ "eltex": EltexSSH, "eltex_esr": EltexEsrSSH, "enterasys": EnterasysSSH, + "ericsson_ipos": EricssonIposSSH, "extreme": ExtremeExosSSH, "extreme_ers": ExtremeErsSSH, "extreme_exos": ExtremeExosSSH, diff --git a/netmiko/utilities.py b/netmiko/utilities.py index 9acfd448c..c9da0f534 100644 --- a/netmiko/utilities.py +++ b/netmiko/utilities.py @@ -52,6 +52,7 @@ "extreme_vdx": "show running-config", "extreme_vsp": "show running-config", "extreme_wing": "show running-config", + "ericsson_ipos": "show configuration", "hp_comware": "display current-configuration", "huawei": "display current-configuration", "fortinet": "show full-configuration", diff --git a/tests/test_ericsson_ipos.py b/tests/test_ericsson_ipos.py new file mode 100755 index 000000000..3144b730f --- /dev/null +++ b/tests/test_ericsson_ipos.py @@ -0,0 +1,34 @@ +#!/usr/bin/env python + +""" +This will run an ssh command successfully on an Ericsson IPPOS. +SSH must be enabled on the device + +""" + +from netmiko.ssh_dispatcher import ConnectHandler + + +def main(): + """ + This will run an ssh command successfully on an Ericsson IPPOS. + SSH must be enabled on the device + """ + + ericsson_connect = { + "device_type": "ericsson_ipos", + "ip": "1.1.1.1", + "username": "admin", + "password": "admin", + } + + net_connect = ConnectHandler(**ericsson_connect) + output = net_connect.send_command("show ip int brief") + print(output) + + output_commit = net_connect.commit() + print(output_commit) + + +if __name__ == "__main__": + main() From bc9700a803ccd89e29672dbe544368b946352aa0 Mon Sep 17 00:00:00 2001 From: wvandeun <7521270+wvandeun@users.noreply.github.com> Date: Fri, 8 Jan 2021 18:51:39 +0100 Subject: [PATCH 15/49] fixes an issue with ssh _autodetect_remote_version (#2102) * fixes an issue with ssh _autodetect_remote_version In #2032 a cmd key was introduced for the cisco_wlc dict. Modified _autodetect_remote_version to accept args and kwargs. * removes *args arg from _autodetect_remote_version Co-authored-by: Wim Van Deun <7521270+enzzzy@users.noreply.github.com> --- netmiko/ssh_autodetect.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/netmiko/ssh_autodetect.py b/netmiko/ssh_autodetect.py index 92f8dacf8..b343d5784 100644 --- a/netmiko/ssh_autodetect.py +++ b/netmiko/ssh_autodetect.py @@ -347,7 +347,7 @@ def _send_command_wrapper(self, cmd): return cached_results def _autodetect_remote_version( - self, search_patterns=None, re_flags=re.IGNORECASE, priority=99 + self, search_patterns=None, re_flags=re.IGNORECASE, priority=99, **kwargs ): """ Method to try auto-detect the device type, by matching a regular expression on the reported From 1f5b5054e961d63800a6fc8255446fa679836c56 Mon Sep 17 00:00:00 2001 From: MrPaulAR <3765696+MrPaulAR@users.noreply.github.com> Date: Wed, 20 Jan 2021 12:06:46 -0600 Subject: [PATCH 16/49] Added missing imports to a sample (#2118) The TTP didn't include the imports so added them. --- EXAMPLES.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/EXAMPLES.md b/EXAMPLES.md index 92c62fd82..2d25834af 100644 --- a/EXAMPLES.md +++ b/EXAMPLES.md @@ -407,6 +407,10 @@ Password: ## Using TTP ```py +from netmiko import ConnectHandler +from getpass import getpass +from pprint import pprint + cisco1 = { "device_type": "cisco_ios", "host": "cisco1.lasthop.io", From 8c976ce411f0ad17eea93af7d0f981239c1afad1 Mon Sep 17 00:00:00 2001 From: Nasr <77995052+Nasr81@users.noreply.github.com> Date: Tue, 26 Jan 2021 00:11:36 +0100 Subject: [PATCH 17/49] fix unbalanced parenthesis error from regex engine (#2124) Co-authored-by: sahnetlink3 --- netmiko/netgear/netgear_prosafe_ssh.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/netmiko/netgear/netgear_prosafe_ssh.py b/netmiko/netgear/netgear_prosafe_ssh.py index b25110a92..8ccf746e0 100644 --- a/netmiko/netgear/netgear_prosafe_ssh.py +++ b/netmiko/netgear/netgear_prosafe_ssh.py @@ -25,7 +25,7 @@ def session_preparation(self): def check_config_mode(self, check_string="(Config)#"): return super().check_config_mode(check_string=check_string) - def config_mode(self, config_command="configure", pattern=r")#"): + def config_mode(self, config_command="configure", pattern=r"\)#"): return super().config_mode(config_command=config_command, pattern=pattern) def exit_config_mode(self, exit_config="exit", pattern="#"): From 9c58845025f20ea29d17e2a0e6a86c30750cea93 Mon Sep 17 00:00:00 2001 From: Kirk Byers Date: Wed, 27 Jan 2021 14:03:46 -0800 Subject: [PATCH 18/49] Fixing broken examples URL (#2126) --- EXAMPLES.md | 2 +- netmiko/netgear/netgear_prosafe_ssh.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/EXAMPLES.md b/EXAMPLES.md index 2d25834af..7d5c4ecd6 100644 --- a/EXAMPLES.md +++ b/EXAMPLES.md @@ -33,7 +33,7 @@ A set of common Netmiko use cases. - [Genie example](#using-genie) #### Configuration Changes -- [Configuration changes](#configuration-changes) +- [Configuration changes](#configuration-changes-1) - [Configuration changes from a file](#configuration-changes-from-a-file) #### SSH keys and SSH config_file diff --git a/netmiko/netgear/netgear_prosafe_ssh.py b/netmiko/netgear/netgear_prosafe_ssh.py index 8ccf746e0..5842b40d9 100644 --- a/netmiko/netgear/netgear_prosafe_ssh.py +++ b/netmiko/netgear/netgear_prosafe_ssh.py @@ -25,10 +25,10 @@ def session_preparation(self): def check_config_mode(self, check_string="(Config)#"): return super().check_config_mode(check_string=check_string) - def config_mode(self, config_command="configure", pattern=r"\)#"): + def config_mode(self, config_command="configure", pattern=r"\)\#"): return super().config_mode(config_command=config_command, pattern=pattern) - def exit_config_mode(self, exit_config="exit", pattern="#"): + def exit_config_mode(self, exit_config="exit", pattern=r"\#"): return super().exit_config_mode(exit_config=exit_config, pattern=pattern) def save_config( From 14317e3d48ae9d528af3c7dd9bf26f9e01d607c9 Mon Sep 17 00:00:00 2001 From: Kirk Byers Date: Wed, 27 Jan 2021 20:40:56 -0800 Subject: [PATCH 19/49] Fix newlines on Cisco NX-OS (#2127) --- netmiko/cisco/cisco_nxos_ssh.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/netmiko/cisco/cisco_nxos_ssh.py b/netmiko/cisco/cisco_nxos_ssh.py index 993bbb5be..2c59ae9c6 100644 --- a/netmiko/cisco/cisco_nxos_ssh.py +++ b/netmiko/cisco/cisco_nxos_ssh.py @@ -24,7 +24,7 @@ def session_preparation(self): def normalize_linefeeds(self, a_string): """Convert '\r\n' or '\r\r\n' to '\n, and remove extra '\r's in the text.""" - newline = re.compile(r"(\r\r\n|\r\n)") + newline = re.compile(r"(\r\r\n\r|\r\r\n|\r\n)") # NX-OS fix for incorrect MD5 on 9K (due to strange patterns on NX-OS) return newline.sub(self.RESPONSE_RETURN, a_string).replace("\r", "\n") From 9df9b9b1eb1be0299923d8e2ce17dbd9906ae69b Mon Sep 17 00:00:00 2001 From: AJ Acevedo Date: Thu, 28 Jan 2021 23:05:08 -0500 Subject: [PATCH 20/49] Updated the Slack invitation link in the README (#2128) When visiting the current Slack invitation link you reach a page that displays the message "This link is no longer active" This commit updates the Slack invitation link in the README Questions/Discussion section. https://join.slack.com/t/pynet/shared_invite/zt-km2k3upf-AkWHY4YEx3sI1R5irMmc7Q Fixes #2122 modified: README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index a7f7def87..5a3d65359 100644 --- a/README.md +++ b/README.md @@ -176,7 +176,7 @@ For all code contributions, please ensure that you have ran `black` against the If you find an issue with Netmiko, then you can open an issue on this projects issue page here: [https://github.com/ktbyers/netmiko/issues](https://github.com/ktbyers/netmiko/issues). Please make sure you've read through the common issues and examples prior to opening an issue. Please only open issues for bugs, feature requests, or other topics related to development of Netmiko. If you simply have a question, join us on Slack... -If you have questions or would like to discuss Netmiko, a #netmiko channel exists in [this Slack](https://pynet.slack.com) workspace. To join, use [this invitation](https://join.slack.com/t/pynet/shared_invite/enQtNTA2MDI3NjU0MTM0LTIyZDdhMTBlOWNmNDJhNjkxZTEyMDg3NTRkOWIxMTUwOTAzYmQ0ZjMwMGMyNTM4N2E1YzA3YWQ1MWFiOWM1YzU). Once you have entered the workspace, then you can join the #netmiko channel. +If you have questions or would like to discuss Netmiko, a #netmiko channel exists in [this Slack](https://pynet.slack.com) workspace. To join, use [this invitation](https://join.slack.com/t/pynet/shared_invite/zt-km2k3upf-AkWHY4YEx3sI1R5irMmc7Q). Once you have entered the workspace, then you can join the #netmiko channel. --- From 772af185cab1e2e564d41c79fb4b6ea92f920f81 Mon Sep 17 00:00:00 2001 From: Kirk Byers Date: Mon, 1 Feb 2021 12:07:04 -0800 Subject: [PATCH 21/49] Release fixes (#2131) * Moving delay_factor fix for _timing to be lower level * Remove Nokia from test suite --- netmiko/base_connection.py | 12 ++++++------ netmiko/cisco/cisco_asa_ssh.py | 2 +- netmiko/juniper/juniper.py | 18 ++++++++++-------- tests/test_suite_alt.sh | 22 +++++++++++----------- 4 files changed, 28 insertions(+), 26 deletions(-) diff --git a/netmiko/base_connection.py b/netmiko/base_connection.py index bf5f97c7f..403ba3881 100644 --- a/netmiko/base_connection.py +++ b/netmiko/base_connection.py @@ -619,6 +619,11 @@ def _read_channel_timing(self, delay_factor=1, max_loops=150): if delay_factor == 1 and max_loops == 150: max_loops = int(self.timeout / loop_delay) + # FIX: Cleanup in future versions of Netmiko + if delay_factor < 1: + if not self._legacy_mode and self.fast_cli: + delay_factor = 1 + channel_data = "" i = 0 while i <= max_loops: @@ -1279,16 +1284,10 @@ def send_command_timing( cmd_verify = cmd_echo output = "" - delay_factor = self.select_delay_factor(delay_factor) - # FIX: Cleanup in future versions of Netmiko - if delay_factor < 1: - if not self._legacy_mode and self.fast_cli: - delay_factor = 1 if normalize: command_string = self.normalize_cmd(command_string) - self.write_channel(command_string) cmd = command_string.strip() @@ -1452,6 +1451,7 @@ def send_command( :param cmd_verify: Verify command echo before proceeding (default: True). :type cmd_verify: bool """ + # Time to delay in each read loop loop_delay = 0.2 diff --git a/netmiko/cisco/cisco_asa_ssh.py b/netmiko/cisco/cisco_asa_ssh.py index 09702de03..92dfc393e 100644 --- a/netmiko/cisco/cisco_asa_ssh.py +++ b/netmiko/cisco/cisco_asa_ssh.py @@ -122,7 +122,7 @@ def asa_login(self): output = self.read_until_pattern(pattern=r"login") while i <= max_attempts: time.sleep(0.5 * delay_factor) - output += self.read_channel() + output = self.read_channel() if "sername" in output: self.write_channel(self.username + self.RETURN) elif "ssword" in output: diff --git a/netmiko/juniper/juniper.py b/netmiko/juniper/juniper.py index c902db492..e8aa393c6 100644 --- a/netmiko/juniper/juniper.py +++ b/netmiko/juniper/juniper.py @@ -175,22 +175,24 @@ def commit( # Enter config mode (if necessary) output = self.config_mode() # and_quit will get out of config mode on commit + if and_quit: - prompt = self.base_prompt - output += self.send_command_expect( - command_string, - expect_string=prompt, - strip_prompt=False, - strip_command=False, - delay_factor=delay_factor, - ) + expect_string = re.escape(self.base_prompt) else: + expect_string = None + + try: + fast_cli_state = self.fast_cli + self.fast_cli = False output += self.send_command( command_string, + expect_string=expect_string, strip_prompt=False, strip_command=False, delay_factor=delay_factor, ) + finally: + self.fast_cli = fast_cli_state if commit_marker not in output: raise ValueError(f"Commit failed with the following errors:\n\n{output}") diff --git a/tests/test_suite_alt.sh b/tests/test_suite_alt.sh index 879df98b8..bffa96ec1 100755 --- a/tests/test_suite_alt.sh +++ b/tests/test_suite_alt.sh @@ -11,17 +11,6 @@ echo "Starting tests...good luck:" \ && py.test -x -s -v test_netmiko_show.py --test_device juniper_vmx \ && py.test -x -s -v test_netmiko_config.py --test_device juniper_vmx \ \ -&& echo "Nokia SR-OS CLI" \ -&& py.test -x -s -v test_netmiko_show.py --test_device sros2 \ -&& py.test -x -s -v test_netmiko_config.py --test_device sros2 \ -&& py.test -x -s -v test_netmiko_scp.py --test_device sros2 \ -\ -&& echo "SR-OS MD" \ -&& py.test -x -s -v test_netmiko_show.py --test_device sros1_md \ -&& py.test -x -s -v test_netmiko_config.py --test_device sros1_md \ -&& py.test -x -s -v test_netmiko_scp.py --test_device sros1_md \ -&& py.test -x -s -v test_netmiko_commit.py --test_device sros1_md \ -\ && echo "Cisco IOS-XE SSH (including SCP)" \ && py.test -v test_netmiko_scp.py --test_device cisco3 \ && py.test -v test_netmiko_show.py --test_device cisco3 \ @@ -128,3 +117,14 @@ exit $RETURN_CODE # && py.test -v test_netmiko_commit.py --test_device cisco_xr_azure \ # # && py.test -v test_netmiko_session_log.py --test_device cisco881_slog \ +#&& echo "Nokia SR-OS CLI" \ +#&& py.test -x -s -v test_netmiko_show.py --test_device sros2 \ +#&& py.test -x -s -v test_netmiko_config.py --test_device sros2 \ +#&& py.test -x -s -v test_netmiko_scp.py --test_device sros2 \ +#\ +#&& echo "SR-OS MD" \ +#&& py.test -x -s -v test_netmiko_show.py --test_device sros1_md \ +#&& py.test -x -s -v test_netmiko_config.py --test_device sros1_md \ +#&& py.test -x -s -v test_netmiko_scp.py --test_device sros1_md \ +#&& py.test -x -s -v test_netmiko_commit.py --test_device sros1_md \ +#\ From f2091240fdfcfe9bebedfa8b004a326361e3fcac Mon Sep 17 00:00:00 2001 From: Kirk Byers Date: Mon, 1 Feb 2021 12:10:02 -0800 Subject: [PATCH 22/49] Release 3.3.3 --- netmiko/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/netmiko/__init__.py b/netmiko/__init__.py index 0f95afb30..e6a0cb17a 100644 --- a/netmiko/__init__.py +++ b/netmiko/__init__.py @@ -23,7 +23,7 @@ # Alternate naming Netmiko = ConnectHandler -__version__ = "3.3.3c_dev" +__version__ = "3.3.3" __all__ = ( "ConnectHandler", "ssh_dispatcher", From bed65d8a9a0377b0c8f23884e2dc70d02c134e6f Mon Sep 17 00:00:00 2001 From: Kirk Byers Date: Mon, 1 Feb 2021 12:41:33 -0800 Subject: [PATCH 23/49] Doc update (#2133) --- docs/netmiko/adtran/adtran.html | 215 ++++- docs/netmiko/adtran/index.html | 205 ++++- docs/netmiko/arista/arista.html | 48 +- docs/netmiko/base_connection.html | 186 +++-- docs/netmiko/cisco/cisco_asa_ssh.html | 114 ++- docs/netmiko/cisco/cisco_nxos_ssh.html | 74 +- docs/netmiko/cisco/index.html | 113 ++- docs/netmiko/cisco_base_connection.html | 56 +- docs/netmiko/ericsson/ericsson_ipos.html | 738 ++++++++++++++++++ docs/netmiko/ericsson/index.html | 609 +++++++++++++++ docs/netmiko/hp/hp_procurve.html | 2 +- docs/netmiko/index.html | 137 ++-- docs/netmiko/juniper/index.html | 2 +- docs/netmiko/juniper/juniper.html | 237 +++--- docs/netmiko/linux/index.html | 2 +- docs/netmiko/linux/linux_ssh.html | 2 +- docs/netmiko/mellanox/index.html | 2 +- .../netmiko/mellanox/mellanox_mlnxos_ssh.html | 2 +- docs/netmiko/mrv/index.html | 2 +- docs/netmiko/mrv/mrv_ssh.html | 2 +- docs/netmiko/netgear/index.html | 4 +- docs/netmiko/netgear/netgear_prosafe_ssh.html | 8 +- docs/netmiko/nokia/index.html | 2 +- docs/netmiko/nokia/nokia_sros_ssh.html | 2 +- docs/netmiko/ruckus/ruckus_fastiron.html | 2 +- docs/netmiko/ssh_autodetect.html | 38 +- docs/netmiko/tplink/index.html | 13 +- docs/netmiko/tplink/tplink_jetstream.html | 27 +- docs/netmiko/utilities.html | 1 + 29 files changed, 2494 insertions(+), 351 deletions(-) create mode 100644 docs/netmiko/ericsson/ericsson_ipos.html create mode 100644 docs/netmiko/ericsson/index.html diff --git a/docs/netmiko/adtran/adtran.html b/docs/netmiko/adtran/adtran.html index ebe0ae08d..2c19c553b 100644 --- a/docs/netmiko/adtran/adtran.html +++ b/docs/netmiko/adtran/adtran.html @@ -46,7 +46,7 @@

Module netmiko.adtran.adtran

def check_enable_mode(self, check_string="#"): return super().check_enable_mode(check_string=check_string) - def enable(self, cmd="enable", pattern="", re_flags=re.IGNORECASE): + def enable(self, cmd="enable", pattern="ssword", re_flags=re.IGNORECASE): return super().enable(cmd=cmd, pattern=pattern, re_flags=re_flags) def exit_enable_mode(self, exit_command="disable"): @@ -72,7 +72,14 @@

Module netmiko.adtran.adtran

class AdtranOSSSH(AdtranOSBase): - pass + pass + + +class AdtranOSTelnet(AdtranOSBase): + def __init__(self, *args, **kwargs): + default_enter = kwargs.get("default_enter") + kwargs["default_enter"] = "\r\n" if default_enter is None else default_enter + super().__init__(*args, **kwargs)
@@ -241,7 +248,7 @@

Classes

def check_enable_mode(self, check_string="#"): return super().check_enable_mode(check_string=check_string) - def enable(self, cmd="enable", pattern="", re_flags=re.IGNORECASE): + def enable(self, cmd="enable", pattern="ssword", re_flags=re.IGNORECASE): return super().enable(cmd=cmd, pattern=pattern, re_flags=re_flags) def exit_enable_mode(self, exit_command="disable"): @@ -273,6 +280,7 @@

Ancestors

Subclasses

Methods

@@ -537,6 +545,204 @@

Inherited members

+
+class AdtranOSTelnet +(*args, **kwargs) +
+
+

Base Class for cisco-like behavior.

+
    Initialize attributes for establishing connection to target device.
+
+    :param ip: IP address of target device. Not required if `host` is
+        provided.
+    :type ip: str
+
+    :param host: Hostname of target device. Not required if `ip` is
+            provided.
+    :type host: str
+
+    :param username: Username to authenticate against target device if
+            required.
+    :type username: str
+
+    :param password: Password to authenticate against target device if
+            required.
+    :type password: str
+
+    :param secret: The enable password if target device requires one.
+    :type secret: str
+
+    :param port: The destination port used to connect to the target
+            device.
+    :type port: int or None
+
+    :param device_type: Class selection based on device type.
+    :type device_type: str
+
+    :param verbose: Enable additional messages to standard output.
+    :type verbose: bool
+
+    :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+    :type global_delay_factor: int
+
+    :param use_keys: Connect to target device using SSH keys.
+    :type use_keys: bool
+
+    :param key_file: Filename path of the SSH key file to use.
+    :type key_file: str
+
+    :param pkey: SSH key object to use.
+    :type pkey: paramiko.PKey
+
+    :param passphrase: Passphrase to use for encrypted key; password will be used for key
+            decryption if not specified.
+    :type passphrase: str
+
+    :param allow_agent: Enable use of SSH key-agent.
+    :type allow_agent: bool
+
+    :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+            means unknown SSH host keys will be accepted).
+    :type ssh_strict: bool
+
+    :param system_host_keys: Load host keys from the users known_hosts file.
+    :type system_host_keys: bool
+    :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+            alt_key_file.
+    :type alt_host_keys: bool
+
+    :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+    :type alt_key_file: str
+
+    :param ssh_config_file: File name of OpenSSH configuration file.
+    :type ssh_config_file: str
+
+    :param timeout: Connection timeout.
+    :type timeout: float
+
+    :param session_timeout: Set a timeout for parallel requests.
+    :type session_timeout: float
+
+    :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+    :type auth_timeout: float
+
+    :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+    :type banner_timeout: float
+
+    :param keepalive: Send SSH keepalive packets at a specific interval, in seconds.
+            Currently defaults to 0, for backwards compatibility (it will not attempt
+            to keep the connection alive).
+    :type keepalive: int
+
+    :param default_enter: Character(s) to send to correspond to enter key (default:
+
+

). +:type default_enter: str

+
    :param response_return: Character(s) to use in normalized return data to represent
+            enter key (default:
+
+

) +:type response_return: str

+
    :param fast_cli: Provide a way to optimize for performance. Converts select_delay_factor
+            to select smallest of global and specific. Sets default global_delay_factor to .1
+            (default: False)
+    :type fast_cli: boolean
+
+    :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+    :type session_log: str
+
+    :param session_log_record_writes: The session log generally only records channel reads due
+            to eliminate command duplication due to command echo. You can enable this if you
+            want to record both channel reads and channel writes in the log (default: False).
+    :type session_log_record_writes: boolean
+
+    :param session_log_file_mode: "write" or "append" for session_log file mode
+            (default: "write")
+    :type session_log_file_mode: str
+
+    :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+            (default: False)
+    :type allow_auto_change: bool
+
+    :param encoding: Encoding to be used when writing bytes to the output channel.
+            (default: ascii)
+    :type encoding: str
+
+    :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+            communication to the target host (default: None).
+    :type sock: socket
+
+    :param global_cmd_verify: Control whether command echo verification is enabled or disabled
+            (default: None). Global attribute takes precedence over function `cmd_verify`
+            argument. Value of `None` indicates to use function `cmd_verify` argument.
+    :type global_cmd_verify: bool|None
+
+    :param auto_connect: Control whether Netmiko automatically establishes the connection as
+            part of the object creation (default: True).
+    :type auto_connect: bool
+
+
+Source code +
class AdtranOSTelnet(AdtranOSBase):
+    def __init__(self, *args, **kwargs):
+        default_enter = kwargs.get("default_enter")
+        kwargs["default_enter"] = "\r\n" if default_enter is None else default_enter
+        super().__init__(*args, **kwargs)
+
+

Ancestors

+ +

Inherited members

+ +
@@ -562,6 +768,9 @@

AdtranOSSSH

+
  • +

    AdtranOSTelnet

    +
  • diff --git a/docs/netmiko/adtran/index.html b/docs/netmiko/adtran/index.html index db33db62a..6b9386fb4 100644 --- a/docs/netmiko/adtran/index.html +++ b/docs/netmiko/adtran/index.html @@ -22,9 +22,9 @@

    Module netmiko.adtran

    Source code -
    from netmiko.adtran.adtran import AdtranOSSSH
    +
    from netmiko.adtran.adtran import AdtranOSSSH, AdtranOSTelnet
     
    -__all__ = ["AdtranOSSSH"]
    +__all__ = ["AdtranOSSSH", "AdtranOSTelnet"]
    @@ -238,6 +238,204 @@

    Inherited members

    +
    +class AdtranOSTelnet +(*args, **kwargs) +
    +
    +

    Base Class for cisco-like behavior.

    +
        Initialize attributes for establishing connection to target device.
    +
    +    :param ip: IP address of target device. Not required if `host` is
    +        provided.
    +    :type ip: str
    +
    +    :param host: Hostname of target device. Not required if `ip` is
    +            provided.
    +    :type host: str
    +
    +    :param username: Username to authenticate against target device if
    +            required.
    +    :type username: str
    +
    +    :param password: Password to authenticate against target device if
    +            required.
    +    :type password: str
    +
    +    :param secret: The enable password if target device requires one.
    +    :type secret: str
    +
    +    :param port: The destination port used to connect to the target
    +            device.
    +    :type port: int or None
    +
    +    :param device_type: Class selection based on device type.
    +    :type device_type: str
    +
    +    :param verbose: Enable additional messages to standard output.
    +    :type verbose: bool
    +
    +    :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
    +    :type global_delay_factor: int
    +
    +    :param use_keys: Connect to target device using SSH keys.
    +    :type use_keys: bool
    +
    +    :param key_file: Filename path of the SSH key file to use.
    +    :type key_file: str
    +
    +    :param pkey: SSH key object to use.
    +    :type pkey: paramiko.PKey
    +
    +    :param passphrase: Passphrase to use for encrypted key; password will be used for key
    +            decryption if not specified.
    +    :type passphrase: str
    +
    +    :param allow_agent: Enable use of SSH key-agent.
    +    :type allow_agent: bool
    +
    +    :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
    +            means unknown SSH host keys will be accepted).
    +    :type ssh_strict: bool
    +
    +    :param system_host_keys: Load host keys from the users known_hosts file.
    +    :type system_host_keys: bool
    +    :param alt_host_keys: If `True` host keys will be loaded from the file specified in
    +            alt_key_file.
    +    :type alt_host_keys: bool
    +
    +    :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
    +    :type alt_key_file: str
    +
    +    :param ssh_config_file: File name of OpenSSH configuration file.
    +    :type ssh_config_file: str
    +
    +    :param timeout: Connection timeout.
    +    :type timeout: float
    +
    +    :param session_timeout: Set a timeout for parallel requests.
    +    :type session_timeout: float
    +
    +    :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
    +    :type auth_timeout: float
    +
    +    :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
    +    :type banner_timeout: float
    +
    +    :param keepalive: Send SSH keepalive packets at a specific interval, in seconds.
    +            Currently defaults to 0, for backwards compatibility (it will not attempt
    +            to keep the connection alive).
    +    :type keepalive: int
    +
    +    :param default_enter: Character(s) to send to correspond to enter key (default:
    +
    +

    ). +:type default_enter: str

    +
        :param response_return: Character(s) to use in normalized return data to represent
    +            enter key (default:
    +
    +

    ) +:type response_return: str

    +
        :param fast_cli: Provide a way to optimize for performance. Converts select_delay_factor
    +            to select smallest of global and specific. Sets default global_delay_factor to .1
    +            (default: False)
    +    :type fast_cli: boolean
    +
    +    :param session_log: File path or BufferedIOBase subclass object to write the session log to.
    +    :type session_log: str
    +
    +    :param session_log_record_writes: The session log generally only records channel reads due
    +            to eliminate command duplication due to command echo. You can enable this if you
    +            want to record both channel reads and channel writes in the log (default: False).
    +    :type session_log_record_writes: boolean
    +
    +    :param session_log_file_mode: "write" or "append" for session_log file mode
    +            (default: "write")
    +    :type session_log_file_mode: str
    +
    +    :param allow_auto_change: Allow automatic configuration changes for terminal settings.
    +            (default: False)
    +    :type allow_auto_change: bool
    +
    +    :param encoding: Encoding to be used when writing bytes to the output channel.
    +            (default: ascii)
    +    :type encoding: str
    +
    +    :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
    +            communication to the target host (default: None).
    +    :type sock: socket
    +
    +    :param global_cmd_verify: Control whether command echo verification is enabled or disabled
    +            (default: None). Global attribute takes precedence over function `cmd_verify`
    +            argument. Value of `None` indicates to use function `cmd_verify` argument.
    +    :type global_cmd_verify: bool|None
    +
    +    :param auto_connect: Control whether Netmiko automatically establishes the connection as
    +            part of the object creation (default: True).
    +    :type auto_connect: bool
    +
    +
    +Source code +
    class AdtranOSTelnet(AdtranOSBase):
    +    def __init__(self, *args, **kwargs):
    +        default_enter = kwargs.get("default_enter")
    +        kwargs["default_enter"] = "\r\n" if default_enter is None else default_enter
    +        super().__init__(*args, **kwargs)
    +
    +

    Ancestors

    + +

    Inherited members

    + +
    @@ -262,6 +460,9 @@

    Index

  • AdtranOSSSH

  • +
  • +

    AdtranOSTelnet

    +
  • diff --git a/docs/netmiko/arista/arista.html b/docs/netmiko/arista/arista.html index 02f218488..c849f7302 100644 --- a/docs/netmiko/arista/arista.html +++ b/docs/netmiko/arista/arista.html @@ -41,7 +41,18 @@

    Module netmiko.arista.arista

    self.disable_paging(cmd_verify=False, pattern=r"Pagination disabled") self.set_base_prompt() - def check_config_mode(self, check_string=")#", pattern=""): + def enable( + self, + cmd="enable", + pattern="ssword", + enable_pattern=r"\#", + re_flags=re.IGNORECASE, + ): + return super().enable( + cmd=cmd, pattern=pattern, enable_pattern=enable_pattern, re_flags=re_flags + ) + + def check_config_mode(self, check_string=")#", pattern=r"[>\#]"): """ Checks if the device is in configuration mode or not. @@ -51,11 +62,7 @@

    Module netmiko.arista.arista

    Can also be (s2) """ self.write_channel(self.RETURN) - # You can encounter an issue here (on router name changes) prefer delay-based solution - if not pattern: - output = self._read_channel_timing() - else: - output = self.read_until_pattern(pattern=pattern) + output = self.read_until_pattern(pattern=pattern) output = output.replace("(s1)", "") output = output.replace("(s2)", "") return check_string in output @@ -310,7 +317,18 @@

    Classes

    self.disable_paging(cmd_verify=False, pattern=r"Pagination disabled") self.set_base_prompt() - def check_config_mode(self, check_string=")#", pattern=""): + def enable( + self, + cmd="enable", + pattern="ssword", + enable_pattern=r"\#", + re_flags=re.IGNORECASE, + ): + return super().enable( + cmd=cmd, pattern=pattern, enable_pattern=enable_pattern, re_flags=re_flags + ) + + def check_config_mode(self, check_string=")#", pattern=r"[>\#]"): """ Checks if the device is in configuration mode or not. @@ -320,11 +338,7 @@

    Classes

    Can also be (s2) """ self.write_channel(self.RETURN) - # You can encounter an issue here (on router name changes) prefer delay-based solution - if not pattern: - output = self._read_channel_timing() - else: - output = self.read_until_pattern(pattern=pattern) + output = self.read_until_pattern(pattern=pattern) output = output.replace("(s1)", "") output = output.replace("(s2)", "") return check_string in output @@ -365,7 +379,7 @@

    Subclasses

    Methods

    -def check_config_mode(self, check_string=')#', pattern='') +def check_config_mode(self, check_string=')#', pattern='[>\\#]')

    Checks if the device is in configuration mode or not.

    @@ -374,7 +388,7 @@

    Methods

    Can also be (s2)

    Source code -
    def check_config_mode(self, check_string=")#", pattern=""):
    +
    def check_config_mode(self, check_string=")#", pattern=r"[>\#]"):
         """
         Checks if the device is in configuration mode or not.
     
    @@ -384,11 +398,7 @@ 

    Methods

    Can also be (s2) """ self.write_channel(self.RETURN) - # You can encounter an issue here (on router name changes) prefer delay-based solution - if not pattern: - output = self._read_channel_timing() - else: - output = self.read_until_pattern(pattern=pattern) + output = self.read_until_pattern(pattern=pattern) output = output.replace("(s1)", "") output = output.replace("(s2)", "") return check_string in output
    diff --git a/docs/netmiko/base_connection.html b/docs/netmiko/base_connection.html index 890587101..c86939989 100644 --- a/docs/netmiko/base_connection.html +++ b/docs/netmiko/base_connection.html @@ -647,6 +647,11 @@

    Module netmiko.base_connection

    if delay_factor == 1 and max_loops == 150: max_loops = int(self.timeout / loop_delay) + # FIX: Cleanup in future versions of Netmiko + if delay_factor < 1: + if not self._legacy_mode and self.fast_cli: + delay_factor = 1 + channel_data = "" i = 0 while i <= max_loops: @@ -736,6 +741,12 @@

    Module netmiko.base_connection

    (default: 20) """ delay_factor = self.select_delay_factor(delay_factor) + + # FIX: Cleanup in future versions of Netmiko + if delay_factor < 1: + if not self._legacy_mode and self.fast_cli: + delay_factor = 1 + time.sleep(1 * delay_factor) output = "" @@ -968,16 +979,6 @@

    Module netmiko.base_connection

    msg = msg.lstrip() raise NetmikoTimeoutException(msg) - except paramiko.ssh_exception.SSHException as no_session_err: - self.paramiko_cleanup() - if "No existing session" in str(no_session_err): - msg = ( - "Paramiko: 'No existing session' error: " - "try increasing 'conn_timeout' to 10 seconds or larger." - ) - raise NetmikoTimeoutException(msg) - else: - raise except paramiko.ssh_exception.AuthenticationException as auth_err: self.paramiko_cleanup() msg = f"""Authentication to device failed. @@ -993,6 +994,16 @@

    Module netmiko.base_connection

    msg += self.RETURN + str(auth_err) raise NetmikoAuthenticationException(msg) + except paramiko.ssh_exception.SSHException as no_session_err: + self.paramiko_cleanup() + if "No existing session" in str(no_session_err): + msg = ( + "Paramiko: 'No existing session' error: " + "try increasing 'conn_timeout' to 10 seconds or larger." + ) + raise NetmikoTimeoutException(msg) + else: + raise if self.verbose: print(f"SSH connection established to {self.host}:{self.port}") @@ -1301,16 +1312,10 @@

    Module netmiko.base_connection

    cmd_verify = cmd_echo output = "" - delay_factor = self.select_delay_factor(delay_factor) - # Cleanup in future versions of Netmiko - if delay_factor < 1: - if not self._legacy_mode and self.fast_cli: - delay_factor = 1 if normalize: command_string = self.normalize_cmd(command_string) - self.write_channel(command_string) cmd = command_string.strip() @@ -1474,6 +1479,7 @@

    Module netmiko.base_connection

    :param cmd_verify: Verify command echo before proceeding (default: True). :type cmd_verify: bool """ + # Time to delay in each read loop loop_delay = 0.2 @@ -1671,7 +1677,9 @@

    Module netmiko.base_connection

    output = self.read_until_prompt() return check_string in output - def enable(self, cmd="", pattern="ssword", re_flags=re.IGNORECASE): + def enable( + self, cmd="", pattern="ssword", enable_pattern=None, re_flags=re.IGNORECASE + ): """Enter enable mode. :param cmd: Device command to enter enable mode @@ -1680,6 +1688,9 @@

    Module netmiko.base_connection

    :param pattern: pattern to search for indicating device is waiting for password :type pattern: str + :param enable_pattern: pattern indicating you have entered enable mode + :type pattern: str + :param re_flags: Regular expression flags used in conjunction with pattern :type re_flags: int """ @@ -1691,15 +1702,20 @@

    Module netmiko.base_connection

    if not self.check_enable_mode(): self.write_channel(self.normalize_cmd(cmd)) try: - output += self.read_until_prompt_or_pattern( - pattern=pattern, re_flags=re_flags - ) + output += self.read_until_pattern(pattern=re.escape(cmd.strip())) + if pattern not in output: + output += self.read_until_prompt_or_pattern( + pattern=pattern, re_flags=re_flags + ) self.write_channel(self.normalize_cmd(self.secret)) - output += self.read_until_prompt() + if enable_pattern: + output += self.read_until_pattern(pattern=enable_pattern) + else: + output += self.read_until_prompt() + if not self.check_enable_mode(): + raise ValueError(msg) except NetmikoTimeoutException: raise ValueError(msg) - if not self.check_enable_mode(): - raise ValueError(msg) return output def exit_enable_mode(self, exit_command=""): @@ -2784,6 +2800,11 @@

    Classes

    if delay_factor == 1 and max_loops == 150: max_loops = int(self.timeout / loop_delay) + # FIX: Cleanup in future versions of Netmiko + if delay_factor < 1: + if not self._legacy_mode and self.fast_cli: + delay_factor = 1 + channel_data = "" i = 0 while i <= max_loops: @@ -2873,6 +2894,12 @@

    Classes

    (default: 20) """ delay_factor = self.select_delay_factor(delay_factor) + + # FIX: Cleanup in future versions of Netmiko + if delay_factor < 1: + if not self._legacy_mode and self.fast_cli: + delay_factor = 1 + time.sleep(1 * delay_factor) output = "" @@ -3105,16 +3132,6 @@

    Classes

    msg = msg.lstrip() raise NetmikoTimeoutException(msg) - except paramiko.ssh_exception.SSHException as no_session_err: - self.paramiko_cleanup() - if "No existing session" in str(no_session_err): - msg = ( - "Paramiko: 'No existing session' error: " - "try increasing 'conn_timeout' to 10 seconds or larger." - ) - raise NetmikoTimeoutException(msg) - else: - raise except paramiko.ssh_exception.AuthenticationException as auth_err: self.paramiko_cleanup() msg = f"""Authentication to device failed. @@ -3130,6 +3147,16 @@

    Classes

    msg += self.RETURN + str(auth_err) raise NetmikoAuthenticationException(msg) + except paramiko.ssh_exception.SSHException as no_session_err: + self.paramiko_cleanup() + if "No existing session" in str(no_session_err): + msg = ( + "Paramiko: 'No existing session' error: " + "try increasing 'conn_timeout' to 10 seconds or larger." + ) + raise NetmikoTimeoutException(msg) + else: + raise if self.verbose: print(f"SSH connection established to {self.host}:{self.port}") @@ -3438,16 +3465,10 @@

    Classes

    cmd_verify = cmd_echo output = "" - delay_factor = self.select_delay_factor(delay_factor) - # Cleanup in future versions of Netmiko - if delay_factor < 1: - if not self._legacy_mode and self.fast_cli: - delay_factor = 1 if normalize: command_string = self.normalize_cmd(command_string) - self.write_channel(command_string) cmd = command_string.strip() @@ -3611,6 +3632,7 @@

    Classes

    :param cmd_verify: Verify command echo before proceeding (default: True). :type cmd_verify: bool """ + # Time to delay in each read loop loop_delay = 0.2 @@ -3808,7 +3830,9 @@

    Classes

    output = self.read_until_prompt() return check_string in output - def enable(self, cmd="", pattern="ssword", re_flags=re.IGNORECASE): + def enable( + self, cmd="", pattern="ssword", enable_pattern=None, re_flags=re.IGNORECASE + ): """Enter enable mode. :param cmd: Device command to enter enable mode @@ -3817,6 +3841,9 @@

    Classes

    :param pattern: pattern to search for indicating device is waiting for password :type pattern: str + :param enable_pattern: pattern indicating you have entered enable mode + :type pattern: str + :param re_flags: Regular expression flags used in conjunction with pattern :type re_flags: int """ @@ -3828,15 +3855,20 @@

    Classes

    if not self.check_enable_mode(): self.write_channel(self.normalize_cmd(cmd)) try: - output += self.read_until_prompt_or_pattern( - pattern=pattern, re_flags=re_flags - ) + output += self.read_until_pattern(pattern=re.escape(cmd.strip())) + if pattern not in output: + output += self.read_until_prompt_or_pattern( + pattern=pattern, re_flags=re_flags + ) self.write_channel(self.normalize_cmd(self.secret)) - output += self.read_until_prompt() + if enable_pattern: + output += self.read_until_pattern(pattern=enable_pattern) + else: + output += self.read_until_prompt() + if not self.check_enable_mode(): + raise ValueError(msg) except NetmikoTimeoutException: raise ValueError(msg) - if not self.check_enable_mode(): - raise ValueError(msg) return output def exit_enable_mode(self, exit_command=""): @@ -4194,6 +4226,7 @@

    Subclasses

  • CiscoWlcSSH
  • NetscalerSSH
  • DellIsilonSSH
  • +
  • EricssonIposSSH
  • F5TmshSSH
  • FlexvnfSSH
  • JuniperBase
  • @@ -4447,7 +4480,7 @@

    Methods

    -def enable(self, cmd='', pattern='ssword', re_flags=re.IGNORECASE) +def enable(self, cmd='', pattern='ssword', enable_pattern=None, re_flags=)

    Enter enable mode.

    @@ -4455,11 +4488,15 @@

    Methods

    :type cmd: str

    :param pattern: pattern to search for indicating device is waiting for password :type pattern: str

    +

    :param enable_pattern: pattern indicating you have entered enable mode +:type pattern: str

    :param re_flags: Regular expression flags used in conjunction with pattern :type re_flags: int

    Source code -
    def enable(self, cmd="", pattern="ssword", re_flags=re.IGNORECASE):
    +
    def enable(
    +    self, cmd="", pattern="ssword", enable_pattern=None, re_flags=re.IGNORECASE
    +):
         """Enter enable mode.
     
         :param cmd: Device command to enter enable mode
    @@ -4468,6 +4505,9 @@ 

    Methods

    :param pattern: pattern to search for indicating device is waiting for password :type pattern: str + :param enable_pattern: pattern indicating you have entered enable mode + :type pattern: str + :param re_flags: Regular expression flags used in conjunction with pattern :type re_flags: int """ @@ -4479,15 +4519,20 @@

    Methods

    if not self.check_enable_mode(): self.write_channel(self.normalize_cmd(cmd)) try: - output += self.read_until_prompt_or_pattern( - pattern=pattern, re_flags=re_flags - ) + output += self.read_until_pattern(pattern=re.escape(cmd.strip())) + if pattern not in output: + output += self.read_until_prompt_or_pattern( + pattern=pattern, re_flags=re_flags + ) self.write_channel(self.normalize_cmd(self.secret)) - output += self.read_until_prompt() + if enable_pattern: + output += self.read_until_pattern(pattern=enable_pattern) + else: + output += self.read_until_prompt() + if not self.check_enable_mode(): + raise ValueError(msg) except NetmikoTimeoutException: raise ValueError(msg) - if not self.check_enable_mode(): - raise ValueError(msg) return output
    @@ -4553,16 +4598,6 @@

    Methods

    msg = msg.lstrip() raise NetmikoTimeoutException(msg) - except paramiko.ssh_exception.SSHException as no_session_err: - self.paramiko_cleanup() - if "No existing session" in str(no_session_err): - msg = ( - "Paramiko: 'No existing session' error: " - "try increasing 'conn_timeout' to 10 seconds or larger." - ) - raise NetmikoTimeoutException(msg) - else: - raise except paramiko.ssh_exception.AuthenticationException as auth_err: self.paramiko_cleanup() msg = f"""Authentication to device failed. @@ -4578,6 +4613,16 @@

    Methods

    msg += self.RETURN + str(auth_err) raise NetmikoAuthenticationException(msg) + except paramiko.ssh_exception.SSHException as no_session_err: + self.paramiko_cleanup() + if "No existing session" in str(no_session_err): + msg = ( + "Paramiko: 'No existing session' error: " + "try increasing 'conn_timeout' to 10 seconds or larger." + ) + raise NetmikoTimeoutException(msg) + else: + raise if self.verbose: print(f"SSH connection established to {self.host}:{self.port}") @@ -5047,6 +5092,7 @@

    Methods

    :param cmd_verify: Verify command echo before proceeding (default: True). :type cmd_verify: bool """ + # Time to delay in each read loop loop_delay = 0.2 @@ -5288,16 +5334,10 @@

    Methods

    cmd_verify = cmd_echo output = "" - delay_factor = self.select_delay_factor(delay_factor) - # Cleanup in future versions of Netmiko - if delay_factor < 1: - if not self._legacy_mode and self.fast_cli: - delay_factor = 1 if normalize: command_string = self.normalize_cmd(command_string) - self.write_channel(command_string) cmd = command_string.strip() @@ -5938,6 +5978,12 @@

    Methods

    (default: 20) """ delay_factor = self.select_delay_factor(delay_factor) + + # FIX: Cleanup in future versions of Netmiko + if delay_factor < 1: + if not self._legacy_mode and self.fast_cli: + delay_factor = 1 + time.sleep(1 * delay_factor) output = "" diff --git a/docs/netmiko/cisco/cisco_asa_ssh.html b/docs/netmiko/cisco/cisco_asa_ssh.html index acf297fa4..cddb53cd7 100644 --- a/docs/netmiko/cisco/cisco_asa_ssh.html +++ b/docs/netmiko/cisco/cisco_asa_ssh.html @@ -33,15 +33,34 @@

    Module netmiko.cisco.cisco_asa_ssh

    class CiscoAsaSSH(CiscoSSHConnection): """Subclass specific to Cisco ASA.""" + def __init__(self, *args, **kwargs): + kwargs.setdefault("fast_cli", True) + kwargs.setdefault("_legacy_mode", False) + kwargs.setdefault("allow_auto_change", True) + return super().__init__(*args, **kwargs) + + def check_config_mode(self, check_string=")#", pattern=r"[>\#]"): + return super().check_config_mode(check_string=check_string, pattern=pattern) + + def enable( + self, + cmd="enable", + pattern="ssword", + enable_pattern=r"\#", + re_flags=re.IGNORECASE, + ): + return super().enable( + cmd=cmd, pattern=pattern, enable_pattern=enable_pattern, re_flags=re_flags + ) + def session_preparation(self): """Prepare the session after the connection has been established.""" - self._test_channel_read() - self.set_base_prompt() if self.secret: self.enable() else: self.asa_login() + self.disable_paging(command="terminal pager 0") if self.allow_auto_change: try: @@ -53,11 +72,7 @@

    Module netmiko.cisco.cisco_asa_ssh

    # Disable cmd_verify if the terminal width can't be set self.global_cmd_verify = False - self.disable_paging(command="terminal pager 0") - - # Clear the read buffer - time.sleep(0.3 * self.global_delay_factor) - self.clear_buffer() + self.set_base_prompt() def send_command_timing(self, *args, **kwargs): """ @@ -129,6 +144,7 @@

    Module netmiko.cisco.cisco_asa_ssh

    i = 1 max_attempts = 10 self.write_channel("login" + self.RETURN) + output = self.read_until_pattern(pattern=r"login") while i <= max_attempts: time.sleep(0.5 * delay_factor) output = self.read_channel() @@ -151,6 +167,16 @@

    Module netmiko.cisco.cisco_asa_ssh

    cmd=cmd, confirm=confirm, confirm_response=confirm_response ) + def normalize_linefeeds(self, a_string): + """Cisco ASA needed that extra \r\n\r""" + newline = re.compile("(\r\n\r|\r\r\r\n|\r\r\n|\r\n|\n\r)") + a_string = newline.sub(self.RESPONSE_RETURN, a_string) + if self.RESPONSE_RETURN == "\n": + # Delete any remaining \r + return re.sub("\r", "", a_string) + else: + return a_string + class CiscoAsaFileTransfer(CiscoFileTransfer): """Cisco ASA SCP File Transfer driver.""" @@ -212,7 +238,7 @@

    Inherited members

    class CiscoAsaSSH -(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=5, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=False, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True) +(*args, **kwargs)

    Subclass specific to Cisco ASA.

    @@ -351,15 +377,34 @@

    Inherited members

    class CiscoAsaSSH(CiscoSSHConnection):
         """Subclass specific to Cisco ASA."""
     
    +    def __init__(self, *args, **kwargs):
    +        kwargs.setdefault("fast_cli", True)
    +        kwargs.setdefault("_legacy_mode", False)
    +        kwargs.setdefault("allow_auto_change", True)
    +        return super().__init__(*args, **kwargs)
    +
    +    def check_config_mode(self, check_string=")#", pattern=r"[>\#]"):
    +        return super().check_config_mode(check_string=check_string, pattern=pattern)
    +
    +    def enable(
    +        self,
    +        cmd="enable",
    +        pattern="ssword",
    +        enable_pattern=r"\#",
    +        re_flags=re.IGNORECASE,
    +    ):
    +        return super().enable(
    +            cmd=cmd, pattern=pattern, enable_pattern=enable_pattern, re_flags=re_flags
    +        )
    +
         def session_preparation(self):
             """Prepare the session after the connection has been established."""
    -        self._test_channel_read()
    -        self.set_base_prompt()
     
             if self.secret:
                 self.enable()
             else:
                 self.asa_login()
    +        self.disable_paging(command="terminal pager 0")
     
             if self.allow_auto_change:
                 try:
    @@ -371,11 +416,7 @@ 

    Inherited members

    # Disable cmd_verify if the terminal width can't be set self.global_cmd_verify = False - self.disable_paging(command="terminal pager 0") - - # Clear the read buffer - time.sleep(0.3 * self.global_delay_factor) - self.clear_buffer() + self.set_base_prompt() def send_command_timing(self, *args, **kwargs): """ @@ -447,6 +488,7 @@

    Inherited members

    i = 1 max_attempts = 10 self.write_channel("login" + self.RETURN) + output = self.read_until_pattern(pattern=r"login") while i <= max_attempts: time.sleep(0.5 * delay_factor) output = self.read_channel() @@ -467,7 +509,17 @@

    Inherited members

    """Saves Config""" return super().save_config( cmd=cmd, confirm=confirm, confirm_response=confirm_response - )
    + ) + + def normalize_linefeeds(self, a_string): + """Cisco ASA needed that extra \r\n\r""" + newline = re.compile("(\r\n\r|\r\r\r\n|\r\r\n|\r\n|\n\r)") + a_string = newline.sub(self.RESPONSE_RETURN, a_string) + if self.RESPONSE_RETURN == "\n": + # Delete any remaining \r + return re.sub("\r", "", a_string) + else: + return a_string

    Ancestors

      @@ -503,6 +555,7 @@

      Methods

      i = 1 max_attempts = 10 self.write_channel("login" + self.RETURN) + output = self.read_until_pattern(pattern=r"login") while i <= max_attempts: time.sleep(0.5 * delay_factor) output = self.read_channel() @@ -520,6 +573,24 @@

      Methods

      raise NetmikoAuthenticationException(msg)
    +
    +def normalize_linefeeds(self, a_string) +
    +
    +

    Cisco ASA needed that extra

    +
    +Source code +
    def normalize_linefeeds(self, a_string):
    +    """Cisco ASA needed that extra \r\n\r"""
    +    newline = re.compile("(\r\n\r|\r\r\r\n|\r\r\n|\r\n|\n\r)")
    +    a_string = newline.sub(self.RESPONSE_RETURN, a_string)
    +    if self.RESPONSE_RETURN == "\n":
    +        # Delete any remaining \r
    +        return re.sub("\r", "", a_string)
    +    else:
    +        return a_string
    +
    +
    def save_config(self, cmd='write mem', confirm=False, confirm_response='')
    @@ -609,13 +680,12 @@

    Methods

    Source code
    def session_preparation(self):
         """Prepare the session after the connection has been established."""
    -    self._test_channel_read()
    -    self.set_base_prompt()
     
         if self.secret:
             self.enable()
         else:
             self.asa_login()
    +    self.disable_paging(command="terminal pager 0")
     
         if self.allow_auto_change:
             try:
    @@ -627,11 +697,7 @@ 

    Methods

    # Disable cmd_verify if the terminal width can't be set self.global_cmd_verify = False - self.disable_paging(command="terminal pager 0") - - # Clear the read buffer - time.sleep(0.3 * self.global_delay_factor) - self.clear_buffer()
    + self.set_base_prompt()
    @@ -681,7 +747,6 @@

    Inherited members

  • find_prompt
  • is_alive
  • normalize_cmd
  • -
  • normalize_linefeeds
  • open_session_log
  • paramiko_cleanup
  • read_channel
  • @@ -726,6 +791,7 @@

    CiscoAsaSSH

    • asa_login
    • +
    • normalize_linefeeds
    • save_config
    • send_command
    • send_command_expect
    • diff --git a/docs/netmiko/cisco/cisco_nxos_ssh.html b/docs/netmiko/cisco/cisco_nxos_ssh.html index 696572719..7eef4b436 100644 --- a/docs/netmiko/cisco/cisco_nxos_ssh.html +++ b/docs/netmiko/cisco/cisco_nxos_ssh.html @@ -48,7 +48,7 @@

      Module netmiko.cisco.cisco_nxos_ssh

      def normalize_linefeeds(self, a_string): """Convert '\r\n' or '\r\r\n' to '\n, and remove extra '\r's in the text.""" - newline = re.compile(r"(\r\r\n|\r\n)") + newline = re.compile(r"(\r\r\n\r|\r\r\n|\r\n)") # NX-OS fix for incorrect MD5 on 9K (due to strange <enter> patterns on NX-OS) return newline.sub(self.RESPONSE_RETURN, a_string).replace("\r", "\n") @@ -56,6 +56,39 @@

      Module netmiko.cisco.cisco_nxos_ssh

      """Checks if the device is in configuration mode or not.""" return super().check_config_mode(check_string=check_string, pattern=pattern) + def save_config( + self, + cmd="copy running-config startup-config", + confirm=False, + confirm_response="", + ): + self.enable() + + if confirm: + output = self.send_command_timing( + command_string=cmd, strip_prompt=False, strip_command=False + ) + if confirm_response: + output += self.send_command_timing( + confirm_response, strip_prompt=False, strip_command=False + ) + else: + # Send enter by default + output += self.send_command_timing( + self.RETURN, strip_prompt=False, strip_command=False + ) + else: + # NX-OS is very slow on save_config ensure it waits long enough. + # FIX: this is a hack as delay_factor will be set to .1 via fast_cli=True in + # send_command so increase max_loops. + output = self.send_command( + command_string=cmd, + strip_prompt=False, + strip_command=False, + max_loops=5000, + ) + return output + class CiscoNxosFileTransfer(CiscoFileTransfer): """Cisco NXOS SCP File Transfer driver.""" @@ -474,13 +507,46 @@

      Inherited members

      def normalize_linefeeds(self, a_string): """Convert '\r\n' or '\r\r\n' to '\n, and remove extra '\r's in the text.""" - newline = re.compile(r"(\r\r\n|\r\n)") + newline = re.compile(r"(\r\r\n\r|\r\r\n|\r\n)") # NX-OS fix for incorrect MD5 on 9K (due to strange <enter> patterns on NX-OS) return newline.sub(self.RESPONSE_RETURN, a_string).replace("\r", "\n") def check_config_mode(self, check_string=")#", pattern="#"): """Checks if the device is in configuration mode or not.""" - return super().check_config_mode(check_string=check_string, pattern=pattern)
      + return super().check_config_mode(check_string=check_string, pattern=pattern) + + def save_config( + self, + cmd="copy running-config startup-config", + confirm=False, + confirm_response="", + ): + self.enable() + + if confirm: + output = self.send_command_timing( + command_string=cmd, strip_prompt=False, strip_command=False + ) + if confirm_response: + output += self.send_command_timing( + confirm_response, strip_prompt=False, strip_command=False + ) + else: + # Send enter by default + output += self.send_command_timing( + self.RETURN, strip_prompt=False, strip_command=False + ) + else: + # NX-OS is very slow on save_config ensure it waits long enough. + # FIX: this is a hack as delay_factor will be set to .1 via fast_cli=True in + # send_command so increase max_loops. + output = self.send_command( + command_string=cmd, + strip_prompt=False, + strip_command=False, + max_loops=5000, + ) + return output

      Ancestors

        @@ -515,7 +581,7 @@

        Methods

        Source code
        def normalize_linefeeds(self, a_string):
             """Convert '\r\n' or '\r\r\n' to '\n, and remove extra '\r's in the text."""
        -    newline = re.compile(r"(\r\r\n|\r\n)")
        +    newline = re.compile(r"(\r\r\n\r|\r\r\n|\r\n)")
             # NX-OS fix for incorrect MD5 on 9K (due to strange <enter> patterns on NX-OS)
             return newline.sub(self.RESPONSE_RETURN, a_string).replace("\r", "\n")
        diff --git a/docs/netmiko/cisco/index.html b/docs/netmiko/cisco/index.html index b15d31ee8..a6e756f32 100644 --- a/docs/netmiko/cisco/index.html +++ b/docs/netmiko/cisco/index.html @@ -150,7 +150,7 @@

        Inherited members

        class CiscoAsaSSH -(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=5, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=False, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True) +(*args, **kwargs)

        Subclass specific to Cisco ASA.

        @@ -289,15 +289,34 @@

        Inherited members

        class CiscoAsaSSH(CiscoSSHConnection):
             """Subclass specific to Cisco ASA."""
         
        +    def __init__(self, *args, **kwargs):
        +        kwargs.setdefault("fast_cli", True)
        +        kwargs.setdefault("_legacy_mode", False)
        +        kwargs.setdefault("allow_auto_change", True)
        +        return super().__init__(*args, **kwargs)
        +
        +    def check_config_mode(self, check_string=")#", pattern=r"[>\#]"):
        +        return super().check_config_mode(check_string=check_string, pattern=pattern)
        +
        +    def enable(
        +        self,
        +        cmd="enable",
        +        pattern="ssword",
        +        enable_pattern=r"\#",
        +        re_flags=re.IGNORECASE,
        +    ):
        +        return super().enable(
        +            cmd=cmd, pattern=pattern, enable_pattern=enable_pattern, re_flags=re_flags
        +        )
        +
             def session_preparation(self):
                 """Prepare the session after the connection has been established."""
        -        self._test_channel_read()
        -        self.set_base_prompt()
         
                 if self.secret:
                     self.enable()
                 else:
                     self.asa_login()
        +        self.disable_paging(command="terminal pager 0")
         
                 if self.allow_auto_change:
                     try:
        @@ -309,11 +328,7 @@ 

        Inherited members

        # Disable cmd_verify if the terminal width can't be set self.global_cmd_verify = False - self.disable_paging(command="terminal pager 0") - - # Clear the read buffer - time.sleep(0.3 * self.global_delay_factor) - self.clear_buffer() + self.set_base_prompt() def send_command_timing(self, *args, **kwargs): """ @@ -385,6 +400,7 @@

        Inherited members

        i = 1 max_attempts = 10 self.write_channel("login" + self.RETURN) + output = self.read_until_pattern(pattern=r"login") while i <= max_attempts: time.sleep(0.5 * delay_factor) output = self.read_channel() @@ -405,7 +421,17 @@

        Inherited members

        """Saves Config""" return super().save_config( cmd=cmd, confirm=confirm, confirm_response=confirm_response - )
        + ) + + def normalize_linefeeds(self, a_string): + """Cisco ASA needed that extra \r\n\r""" + newline = re.compile("(\r\n\r|\r\r\r\n|\r\r\n|\r\n|\n\r)") + a_string = newline.sub(self.RESPONSE_RETURN, a_string) + if self.RESPONSE_RETURN == "\n": + # Delete any remaining \r + return re.sub("\r", "", a_string) + else: + return a_string

        Ancestors

          @@ -441,6 +467,7 @@

          Methods

          i = 1 max_attempts = 10 self.write_channel("login" + self.RETURN) + output = self.read_until_pattern(pattern=r"login") while i <= max_attempts: time.sleep(0.5 * delay_factor) output = self.read_channel() @@ -458,6 +485,24 @@

          Methods

          raise NetmikoAuthenticationException(msg)
        +
        +def normalize_linefeeds(self, a_string) +
        +
        +

        Cisco ASA needed that extra

        +
        +Source code +
        def normalize_linefeeds(self, a_string):
        +    """Cisco ASA needed that extra \r\n\r"""
        +    newline = re.compile("(\r\n\r|\r\r\r\n|\r\r\n|\r\n|\n\r)")
        +    a_string = newline.sub(self.RESPONSE_RETURN, a_string)
        +    if self.RESPONSE_RETURN == "\n":
        +        # Delete any remaining \r
        +        return re.sub("\r", "", a_string)
        +    else:
        +        return a_string
        +
        +
        def save_config(self, cmd='write mem', confirm=False, confirm_response='')
        @@ -547,13 +592,12 @@

        Methods

        Source code
        def session_preparation(self):
             """Prepare the session after the connection has been established."""
        -    self._test_channel_read()
        -    self.set_base_prompt()
         
             if self.secret:
                 self.enable()
             else:
                 self.asa_login()
        +    self.disable_paging(command="terminal pager 0")
         
             if self.allow_auto_change:
                 try:
        @@ -565,11 +609,7 @@ 

        Methods

        # Disable cmd_verify if the terminal width can't be set self.global_cmd_verify = False - self.disable_paging(command="terminal pager 0") - - # Clear the read buffer - time.sleep(0.3 * self.global_delay_factor) - self.clear_buffer()
        + self.set_base_prompt()
        @@ -619,7 +659,6 @@

        Inherited members

      • find_prompt
      • is_alive
      • normalize_cmd
      • -
      • normalize_linefeeds
      • open_session_log
      • paramiko_cleanup
      • read_channel
      • @@ -2122,13 +2161,46 @@

        Inherited members

        def normalize_linefeeds(self, a_string): """Convert '\r\n' or '\r\r\n' to '\n, and remove extra '\r's in the text.""" - newline = re.compile(r"(\r\r\n|\r\n)") + newline = re.compile(r"(\r\r\n\r|\r\r\n|\r\n)") # NX-OS fix for incorrect MD5 on 9K (due to strange <enter> patterns on NX-OS) return newline.sub(self.RESPONSE_RETURN, a_string).replace("\r", "\n") def check_config_mode(self, check_string=")#", pattern="#"): """Checks if the device is in configuration mode or not.""" - return super().check_config_mode(check_string=check_string, pattern=pattern)
        + return super().check_config_mode(check_string=check_string, pattern=pattern) + + def save_config( + self, + cmd="copy running-config startup-config", + confirm=False, + confirm_response="", + ): + self.enable() + + if confirm: + output = self.send_command_timing( + command_string=cmd, strip_prompt=False, strip_command=False + ) + if confirm_response: + output += self.send_command_timing( + confirm_response, strip_prompt=False, strip_command=False + ) + else: + # Send enter by default + output += self.send_command_timing( + self.RETURN, strip_prompt=False, strip_command=False + ) + else: + # NX-OS is very slow on save_config ensure it waits long enough. + # FIX: this is a hack as delay_factor will be set to .1 via fast_cli=True in + # send_command so increase max_loops. + output = self.send_command( + command_string=cmd, + strip_prompt=False, + strip_command=False, + max_loops=5000, + ) + return output

        Ancestors

          @@ -2163,7 +2235,7 @@

          Methods

          Source code
          def normalize_linefeeds(self, a_string):
               """Convert '\r\n' or '\r\r\n' to '\n, and remove extra '\r's in the text."""
          -    newline = re.compile(r"(\r\r\n|\r\n)")
          +    newline = re.compile(r"(\r\r\n\r|\r\r\n|\r\n)")
               # NX-OS fix for incorrect MD5 on 9K (due to strange <enter> patterns on NX-OS)
               return newline.sub(self.RESPONSE_RETURN, a_string).replace("\r", "\n")
          @@ -4296,6 +4368,7 @@

          CiscoAsaSSH

          • asa_login
          • +
          • normalize_linefeeds
          • save_config
          • send_command
          • send_command_expect
          • diff --git a/docs/netmiko/cisco_base_connection.html b/docs/netmiko/cisco_base_connection.html index 579cd59b8..9cecdc5fb 100644 --- a/docs/netmiko/cisco_base_connection.html +++ b/docs/netmiko/cisco_base_connection.html @@ -38,9 +38,17 @@

            Module netmiko.cisco_base_connection

            """Check if in enable mode. Return boolean.""" return super().check_enable_mode(check_string=check_string) - def enable(self, cmd="enable", pattern="ssword", re_flags=re.IGNORECASE): + def enable( + self, + cmd="enable", + pattern="ssword", + enable_pattern=None, + re_flags=re.IGNORECASE, + ): """Enter enable mode.""" - return super().enable(cmd=cmd, pattern=pattern, re_flags=re_flags) + return super().enable( + cmd=cmd, pattern=pattern, enable_pattern=enable_pattern, re_flags=re_flags + ) def exit_enable_mode(self, exit_command="disable"): """Exits enable (privileged exec) mode.""" @@ -106,6 +114,12 @@

            Module netmiko.cisco_base_connection

            ): """Telnet login. Can be username/password or just password.""" delay_factor = self.select_delay_factor(delay_factor) + + # FIX: Cleanup in future versions of Netmiko + if delay_factor < 1: + if not self._legacy_mode and self.fast_cli: + delay_factor = 1 + time.sleep(1 * delay_factor) output = "" @@ -422,9 +436,17 @@

            Classes

            """Check if in enable mode. Return boolean.""" return super().check_enable_mode(check_string=check_string) - def enable(self, cmd="enable", pattern="ssword", re_flags=re.IGNORECASE): + def enable( + self, + cmd="enable", + pattern="ssword", + enable_pattern=None, + re_flags=re.IGNORECASE, + ): """Enter enable mode.""" - return super().enable(cmd=cmd, pattern=pattern, re_flags=re_flags) + return super().enable( + cmd=cmd, pattern=pattern, enable_pattern=enable_pattern, re_flags=re_flags + ) def exit_enable_mode(self, exit_command="disable"): """Exits enable (privileged exec) mode.""" @@ -490,6 +512,12 @@

            Classes

            ): """Telnet login. Can be username/password or just password.""" delay_factor = self.select_delay_factor(delay_factor) + + # FIX: Cleanup in future versions of Netmiko + if delay_factor < 1: + if not self._legacy_mode and self.fast_cli: + delay_factor = 1 + time.sleep(1 * delay_factor) output = "" @@ -737,15 +765,23 @@

            Methods

            -def enable(self, cmd='enable', pattern='ssword', re_flags=re.IGNORECASE) +def enable(self, cmd='enable', pattern='ssword', enable_pattern=None, re_flags=)

            Enter enable mode.

            Source code -
            def enable(self, cmd="enable", pattern="ssword", re_flags=re.IGNORECASE):
            +
            def enable(
            +    self,
            +    cmd="enable",
            +    pattern="ssword",
            +    enable_pattern=None,
            +    re_flags=re.IGNORECASE,
            +):
                 """Enter enable mode."""
            -    return super().enable(cmd=cmd, pattern=pattern, re_flags=re_flags)
            + return super().enable( + cmd=cmd, pattern=pattern, enable_pattern=enable_pattern, re_flags=re_flags + )
            @@ -859,6 +895,12 @@

            Methods

            ): """Telnet login. Can be username/password or just password.""" delay_factor = self.select_delay_factor(delay_factor) + + # FIX: Cleanup in future versions of Netmiko + if delay_factor < 1: + if not self._legacy_mode and self.fast_cli: + delay_factor = 1 + time.sleep(1 * delay_factor) output = "" diff --git a/docs/netmiko/ericsson/ericsson_ipos.html b/docs/netmiko/ericsson/ericsson_ipos.html new file mode 100644 index 000000000..f07bc973f --- /dev/null +++ b/docs/netmiko/ericsson/ericsson_ipos.html @@ -0,0 +1,738 @@ + + + + + + +netmiko.ericsson.ericsson_ipos API documentation + + + + + + + + + +
            +
            +
            +

            Module netmiko.ericsson.ericsson_ipos

            +
            +
            +
            +Source code +
            import re
            +
            +from netmiko.base_connection import BaseConnection
            +
            +
            +class EricssonIposSSH(BaseConnection):
            +    def check_enable_mode(self, check_string="#"):
            +        """
            +        Check if in enable mode. Return boolean.
            +        """
            +        return super().check_enable_mode(check_string=check_string)
            +
            +    def enable(self, cmd="enable 15", pattern="ssword", re_flags=re.IGNORECASE):
            +        """Enter enable mode."""
            +        return super().enable(cmd=cmd, pattern=pattern, re_flags=re_flags)
            +
            +    def disable_paging(self, command="terminal length 0", delay_factor=1):
            +        """Disable paging default to a Cisco CLI method.
            +
            +        :param command: Device command to disable pagination of output
            +        :type command: str
            +
            +        :param delay_factor: See __init__: global_delay_factor
            +        :type delay_factor: int
            +        """
            +        return super().disable_paging(command=command, delay_factor=delay_factor)
            +
            +    def set_terminal_width(self, command="terminal width 512", delay_factor=1):
            +        """CLI terminals try to automatically adjust the line based on the width of the terminal.
            +        This causes the output to get distorted when accessed programmatically.
            +
            +        Set terminal width to 511 which works on a broad set of devices.
            +
            +        :param command: Command string to send to the device
            +        :type command: str
            +
            +        :param delay_factor: See __init__: global_delay_factor
            +        :type delay_factor: int
            +        """
            +        return super().set_terminal_width(command=command, delay_factor=delay_factor)
            +
            +    def send_config_set(self, config_commands=None, exit_config_mode=False, **kwargs):
            +        """Ericsson IPOS requires you not exit from configuration mode."""
            +        return super().send_config_set(
            +            config_commands=config_commands, exit_config_mode=exit_config_mode, **kwargs
            +        )
            +
            +    def exit_enable_mode(self, exit_command="disable"):
            +        """
            +        Exits enable (privileged exec) mode.
            +        """
            +        return super().exit_enable_mode(exit_command=exit_command)
            +
            +    def check_config_mode(self, check_string=")#", pattern=""):
            +        """
            +        Checks if the device is in configuration mode or not.
            +        """
            +        return super().check_config_mode(check_string=check_string, pattern=pattern)
            +
            +    def config_mode(self, config_command="configure", pattern=""):
            +        """
            +        Enter into configuration mode on remote device.
            +        """
            +        if not pattern:
            +            pattern = re.escape(self.base_prompt[:16])
            +        return super().config_mode(config_command=config_command, pattern=pattern)
            +
            +    def exit_config_mode(self, exit_config="end", pattern="#"):
            +        """
            +        Exit from configuration mode.
            +        Ercisson output :
            +            end                   Commit configuration changes and return to exec mode
            +        """
            +        return super().exit_config_mode(exit_config=exit_config, pattern=pattern)
            +
            +    def save_config(self, cmd="save config", confirm=True, confirm_response="yes"):
            +        """Saves configuration"""
            +        if confirm:
            +            output = self.send_command_timing(
            +                command_string=cmd, strip_prompt=False, strip_command=False
            +            )
            +
            +            if confirm_response:
            +                output += self.send_command_timing(
            +                    confirm_response, strip_prompt=False, strip_command=False
            +                )
            +            else:
            +                output += self.send_command_timing(
            +                    self.RETURN, strip_prompt=False, strip_command=False
            +                )
            +        else:
            +            output = self.send_command(
            +                command_string=cmd, strip_prompt=False, strip_command=False
            +            )
            +        return output
            +
            +    def commit(self, confirm=False, confirm_delay=None, comment="", delay_factor=1):
            +        """
            +        Commit the candidate configuration.
            +
            +        Commit the entered configuration. Raise an error and return the failure
            +        if the commit fails.
            +
            +        Automatically enters configuration mode
            +
            +        """
            +
            +        delay_factor = self.select_delay_factor(delay_factor)
            +
            +        if confirm_delay and not confirm:
            +            raise ValueError(
            +                "Invalid arguments supplied to commit method both confirm and check"
            +            )
            +
            +        command_string = "commit"
            +        commit_marker = "Transaction committed"
            +        if confirm:
            +            if confirm_delay:
            +                command_string = f"commit confirmed {confirm_delay}"
            +            else:
            +                command_string = "commit confirmed"
            +            commit_marker = "Commit confirmed ,it will be rolled back within"
            +
            +        if comment:
            +            if '"' in comment:
            +                raise ValueError("Invalid comment contains double quote")
            +            comment = f'"{comment}"'
            +            command_string += f" comment {comment}"
            +
            +        output = self.config_mode()
            +
            +        output += self.send_command_expect(
            +            command_string,
            +            strip_prompt=False,
            +            strip_command=False,
            +            delay_factor=delay_factor,
            +        )
            +
            +        if commit_marker not in output:
            +            raise ValueError(f"Commit failed with the following errors:\n\n{output}")
            +
            +        self.exit_config_mode()
            +
            +        return output
            +
            +
            +
            +
            +
            +
            +
            +
            +
            +

            Classes

            +
            +
            +class EricssonIposSSH +(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=5, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=False, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True) +
            +
            +

            Defines vendor independent methods.

            +

            Otherwise method left as a stub method.

            +
                Initialize attributes for establishing connection to target device.
            +
            +    :param ip: IP address of target device. Not required if `host` is
            +        provided.
            +    :type ip: str
            +
            +    :param host: Hostname of target device. Not required if `ip` is
            +            provided.
            +    :type host: str
            +
            +    :param username: Username to authenticate against target device if
            +            required.
            +    :type username: str
            +
            +    :param password: Password to authenticate against target device if
            +            required.
            +    :type password: str
            +
            +    :param secret: The enable password if target device requires one.
            +    :type secret: str
            +
            +    :param port: The destination port used to connect to the target
            +            device.
            +    :type port: int or None
            +
            +    :param device_type: Class selection based on device type.
            +    :type device_type: str
            +
            +    :param verbose: Enable additional messages to standard output.
            +    :type verbose: bool
            +
            +    :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
            +    :type global_delay_factor: int
            +
            +    :param use_keys: Connect to target device using SSH keys.
            +    :type use_keys: bool
            +
            +    :param key_file: Filename path of the SSH key file to use.
            +    :type key_file: str
            +
            +    :param pkey: SSH key object to use.
            +    :type pkey: paramiko.PKey
            +
            +    :param passphrase: Passphrase to use for encrypted key; password will be used for key
            +            decryption if not specified.
            +    :type passphrase: str
            +
            +    :param allow_agent: Enable use of SSH key-agent.
            +    :type allow_agent: bool
            +
            +    :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
            +            means unknown SSH host keys will be accepted).
            +    :type ssh_strict: bool
            +
            +    :param system_host_keys: Load host keys from the users known_hosts file.
            +    :type system_host_keys: bool
            +    :param alt_host_keys: If `True` host keys will be loaded from the file specified in
            +            alt_key_file.
            +    :type alt_host_keys: bool
            +
            +    :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
            +    :type alt_key_file: str
            +
            +    :param ssh_config_file: File name of OpenSSH configuration file.
            +    :type ssh_config_file: str
            +
            +    :param timeout: Connection timeout.
            +    :type timeout: float
            +
            +    :param session_timeout: Set a timeout for parallel requests.
            +    :type session_timeout: float
            +
            +    :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
            +    :type auth_timeout: float
            +
            +    :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
            +    :type banner_timeout: float
            +
            +    :param keepalive: Send SSH keepalive packets at a specific interval, in seconds.
            +            Currently defaults to 0, for backwards compatibility (it will not attempt
            +            to keep the connection alive).
            +    :type keepalive: int
            +
            +    :param default_enter: Character(s) to send to correspond to enter key (default:
            +
            +

            ). +:type default_enter: str

            +
                :param response_return: Character(s) to use in normalized return data to represent
            +            enter key (default:
            +
            +

            ) +:type response_return: str

            +
                :param fast_cli: Provide a way to optimize for performance. Converts select_delay_factor
            +            to select smallest of global and specific. Sets default global_delay_factor to .1
            +            (default: False)
            +    :type fast_cli: boolean
            +
            +    :param session_log: File path or BufferedIOBase subclass object to write the session log to.
            +    :type session_log: str
            +
            +    :param session_log_record_writes: The session log generally only records channel reads due
            +            to eliminate command duplication due to command echo. You can enable this if you
            +            want to record both channel reads and channel writes in the log (default: False).
            +    :type session_log_record_writes: boolean
            +
            +    :param session_log_file_mode: "write" or "append" for session_log file mode
            +            (default: "write")
            +    :type session_log_file_mode: str
            +
            +    :param allow_auto_change: Allow automatic configuration changes for terminal settings.
            +            (default: False)
            +    :type allow_auto_change: bool
            +
            +    :param encoding: Encoding to be used when writing bytes to the output channel.
            +            (default: ascii)
            +    :type encoding: str
            +
            +    :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
            +            communication to the target host (default: None).
            +    :type sock: socket
            +
            +    :param global_cmd_verify: Control whether command echo verification is enabled or disabled
            +            (default: None). Global attribute takes precedence over function `cmd_verify`
            +            argument. Value of `None` indicates to use function `cmd_verify` argument.
            +    :type global_cmd_verify: bool|None
            +
            +    :param auto_connect: Control whether Netmiko automatically establishes the connection as
            +            part of the object creation (default: True).
            +    :type auto_connect: bool
            +
            +
            +Source code +
            class EricssonIposSSH(BaseConnection):
            +    def check_enable_mode(self, check_string="#"):
            +        """
            +        Check if in enable mode. Return boolean.
            +        """
            +        return super().check_enable_mode(check_string=check_string)
            +
            +    def enable(self, cmd="enable 15", pattern="ssword", re_flags=re.IGNORECASE):
            +        """Enter enable mode."""
            +        return super().enable(cmd=cmd, pattern=pattern, re_flags=re_flags)
            +
            +    def disable_paging(self, command="terminal length 0", delay_factor=1):
            +        """Disable paging default to a Cisco CLI method.
            +
            +        :param command: Device command to disable pagination of output
            +        :type command: str
            +
            +        :param delay_factor: See __init__: global_delay_factor
            +        :type delay_factor: int
            +        """
            +        return super().disable_paging(command=command, delay_factor=delay_factor)
            +
            +    def set_terminal_width(self, command="terminal width 512", delay_factor=1):
            +        """CLI terminals try to automatically adjust the line based on the width of the terminal.
            +        This causes the output to get distorted when accessed programmatically.
            +
            +        Set terminal width to 511 which works on a broad set of devices.
            +
            +        :param command: Command string to send to the device
            +        :type command: str
            +
            +        :param delay_factor: See __init__: global_delay_factor
            +        :type delay_factor: int
            +        """
            +        return super().set_terminal_width(command=command, delay_factor=delay_factor)
            +
            +    def send_config_set(self, config_commands=None, exit_config_mode=False, **kwargs):
            +        """Ericsson IPOS requires you not exit from configuration mode."""
            +        return super().send_config_set(
            +            config_commands=config_commands, exit_config_mode=exit_config_mode, **kwargs
            +        )
            +
            +    def exit_enable_mode(self, exit_command="disable"):
            +        """
            +        Exits enable (privileged exec) mode.
            +        """
            +        return super().exit_enable_mode(exit_command=exit_command)
            +
            +    def check_config_mode(self, check_string=")#", pattern=""):
            +        """
            +        Checks if the device is in configuration mode or not.
            +        """
            +        return super().check_config_mode(check_string=check_string, pattern=pattern)
            +
            +    def config_mode(self, config_command="configure", pattern=""):
            +        """
            +        Enter into configuration mode on remote device.
            +        """
            +        if not pattern:
            +            pattern = re.escape(self.base_prompt[:16])
            +        return super().config_mode(config_command=config_command, pattern=pattern)
            +
            +    def exit_config_mode(self, exit_config="end", pattern="#"):
            +        """
            +        Exit from configuration mode.
            +        Ercisson output :
            +            end                   Commit configuration changes and return to exec mode
            +        """
            +        return super().exit_config_mode(exit_config=exit_config, pattern=pattern)
            +
            +    def save_config(self, cmd="save config", confirm=True, confirm_response="yes"):
            +        """Saves configuration"""
            +        if confirm:
            +            output = self.send_command_timing(
            +                command_string=cmd, strip_prompt=False, strip_command=False
            +            )
            +
            +            if confirm_response:
            +                output += self.send_command_timing(
            +                    confirm_response, strip_prompt=False, strip_command=False
            +                )
            +            else:
            +                output += self.send_command_timing(
            +                    self.RETURN, strip_prompt=False, strip_command=False
            +                )
            +        else:
            +            output = self.send_command(
            +                command_string=cmd, strip_prompt=False, strip_command=False
            +            )
            +        return output
            +
            +    def commit(self, confirm=False, confirm_delay=None, comment="", delay_factor=1):
            +        """
            +        Commit the candidate configuration.
            +
            +        Commit the entered configuration. Raise an error and return the failure
            +        if the commit fails.
            +
            +        Automatically enters configuration mode
            +
            +        """
            +
            +        delay_factor = self.select_delay_factor(delay_factor)
            +
            +        if confirm_delay and not confirm:
            +            raise ValueError(
            +                "Invalid arguments supplied to commit method both confirm and check"
            +            )
            +
            +        command_string = "commit"
            +        commit_marker = "Transaction committed"
            +        if confirm:
            +            if confirm_delay:
            +                command_string = f"commit confirmed {confirm_delay}"
            +            else:
            +                command_string = "commit confirmed"
            +            commit_marker = "Commit confirmed ,it will be rolled back within"
            +
            +        if comment:
            +            if '"' in comment:
            +                raise ValueError("Invalid comment contains double quote")
            +            comment = f'"{comment}"'
            +            command_string += f" comment {comment}"
            +
            +        output = self.config_mode()
            +
            +        output += self.send_command_expect(
            +            command_string,
            +            strip_prompt=False,
            +            strip_command=False,
            +            delay_factor=delay_factor,
            +        )
            +
            +        if commit_marker not in output:
            +            raise ValueError(f"Commit failed with the following errors:\n\n{output}")
            +
            +        self.exit_config_mode()
            +
            +        return output
            +
            +

            Ancestors

            + +

            Methods

            +
            +
            +def check_config_mode(self, check_string=')#', pattern='') +
            +
            +

            Checks if the device is in configuration mode or not.

            +
            +Source code +
            def check_config_mode(self, check_string=")#", pattern=""):
            +    """
            +    Checks if the device is in configuration mode or not.
            +    """
            +    return super().check_config_mode(check_string=check_string, pattern=pattern)
            +
            +
            +
            +def check_enable_mode(self, check_string='#') +
            +
            +

            Check if in enable mode. Return boolean.

            +
            +Source code +
            def check_enable_mode(self, check_string="#"):
            +    """
            +    Check if in enable mode. Return boolean.
            +    """
            +    return super().check_enable_mode(check_string=check_string)
            +
            +
            +
            +def commit(self, confirm=False, confirm_delay=None, comment='', delay_factor=1) +
            +
            +

            Commit the candidate configuration.

            +

            Commit the entered configuration. Raise an error and return the failure +if the commit fails.

            +

            Automatically enters configuration mode

            +
            +Source code +
            def commit(self, confirm=False, confirm_delay=None, comment="", delay_factor=1):
            +    """
            +    Commit the candidate configuration.
            +
            +    Commit the entered configuration. Raise an error and return the failure
            +    if the commit fails.
            +
            +    Automatically enters configuration mode
            +
            +    """
            +
            +    delay_factor = self.select_delay_factor(delay_factor)
            +
            +    if confirm_delay and not confirm:
            +        raise ValueError(
            +            "Invalid arguments supplied to commit method both confirm and check"
            +        )
            +
            +    command_string = "commit"
            +    commit_marker = "Transaction committed"
            +    if confirm:
            +        if confirm_delay:
            +            command_string = f"commit confirmed {confirm_delay}"
            +        else:
            +            command_string = "commit confirmed"
            +        commit_marker = "Commit confirmed ,it will be rolled back within"
            +
            +    if comment:
            +        if '"' in comment:
            +            raise ValueError("Invalid comment contains double quote")
            +        comment = f'"{comment}"'
            +        command_string += f" comment {comment}"
            +
            +    output = self.config_mode()
            +
            +    output += self.send_command_expect(
            +        command_string,
            +        strip_prompt=False,
            +        strip_command=False,
            +        delay_factor=delay_factor,
            +    )
            +
            +    if commit_marker not in output:
            +        raise ValueError(f"Commit failed with the following errors:\n\n{output}")
            +
            +    self.exit_config_mode()
            +
            +    return output
            +
            +
            +
            +def config_mode(self, config_command='configure', pattern='') +
            +
            +

            Enter into configuration mode on remote device.

            +
            +Source code +
            def config_mode(self, config_command="configure", pattern=""):
            +    """
            +    Enter into configuration mode on remote device.
            +    """
            +    if not pattern:
            +        pattern = re.escape(self.base_prompt[:16])
            +    return super().config_mode(config_command=config_command, pattern=pattern)
            +
            +
            +
            +def enable(self, cmd='enable 15', pattern='ssword', re_flags=) +
            +
            +

            Enter enable mode.

            +
            +Source code +
            def enable(self, cmd="enable 15", pattern="ssword", re_flags=re.IGNORECASE):
            +    """Enter enable mode."""
            +    return super().enable(cmd=cmd, pattern=pattern, re_flags=re_flags)
            +
            +
            +
            +def exit_config_mode(self, exit_config='end', pattern='#') +
            +
            +

            Exit from configuration mode. +Ercisson output : +end +Commit configuration changes and return to exec mode

            +
            +Source code +
            def exit_config_mode(self, exit_config="end", pattern="#"):
            +    """
            +    Exit from configuration mode.
            +    Ercisson output :
            +        end                   Commit configuration changes and return to exec mode
            +    """
            +    return super().exit_config_mode(exit_config=exit_config, pattern=pattern)
            +
            +
            +
            +def exit_enable_mode(self, exit_command='disable') +
            +
            +

            Exits enable (privileged exec) mode.

            +
            +Source code +
            def exit_enable_mode(self, exit_command="disable"):
            +    """
            +    Exits enable (privileged exec) mode.
            +    """
            +    return super().exit_enable_mode(exit_command=exit_command)
            +
            +
            +
            +def save_config(self, cmd='save config', confirm=True, confirm_response='yes') +
            +
            +

            Saves configuration

            +
            +Source code +
            def save_config(self, cmd="save config", confirm=True, confirm_response="yes"):
            +    """Saves configuration"""
            +    if confirm:
            +        output = self.send_command_timing(
            +            command_string=cmd, strip_prompt=False, strip_command=False
            +        )
            +
            +        if confirm_response:
            +            output += self.send_command_timing(
            +                confirm_response, strip_prompt=False, strip_command=False
            +            )
            +        else:
            +            output += self.send_command_timing(
            +                self.RETURN, strip_prompt=False, strip_command=False
            +            )
            +    else:
            +        output = self.send_command(
            +            command_string=cmd, strip_prompt=False, strip_command=False
            +        )
            +    return output
            +
            +
            +
            +def send_config_set(self, config_commands=None, exit_config_mode=False, **kwargs) +
            +
            +

            Ericsson IPOS requires you not exit from configuration mode.

            +
            +Source code +
            def send_config_set(self, config_commands=None, exit_config_mode=False, **kwargs):
            +    """Ericsson IPOS requires you not exit from configuration mode."""
            +    return super().send_config_set(
            +        config_commands=config_commands, exit_config_mode=exit_config_mode, **kwargs
            +    )
            +
            +
            +
            +

            Inherited members

            + +
            +
            +
            +
            + +
            + + + + + \ No newline at end of file diff --git a/docs/netmiko/ericsson/index.html b/docs/netmiko/ericsson/index.html new file mode 100644 index 000000000..4a45ad5d9 --- /dev/null +++ b/docs/netmiko/ericsson/index.html @@ -0,0 +1,609 @@ + + + + + + +netmiko.ericsson API documentation + + + + + + + + + +
            +
            +
            +

            Module netmiko.ericsson

            +
            +
            +
            +Source code +
            from netmiko.ericsson.ericsson_ipos import EricssonIposSSH
            +
            +__all__ = ["EricssonIposSSH"]
            +
            +
            +
            +

            Sub-modules

            +
            +
            netmiko.ericsson.ericsson_ipos
            +
            +
            +
            +
            +
            +
            +
            +
            +
            +
            +

            Classes

            +
            +
            +class EricssonIposSSH +(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=5, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=False, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True) +
            +
            +

            Defines vendor independent methods.

            +

            Otherwise method left as a stub method.

            +
                Initialize attributes for establishing connection to target device.
            +
            +    :param ip: IP address of target device. Not required if `host` is
            +        provided.
            +    :type ip: str
            +
            +    :param host: Hostname of target device. Not required if `ip` is
            +            provided.
            +    :type host: str
            +
            +    :param username: Username to authenticate against target device if
            +            required.
            +    :type username: str
            +
            +    :param password: Password to authenticate against target device if
            +            required.
            +    :type password: str
            +
            +    :param secret: The enable password if target device requires one.
            +    :type secret: str
            +
            +    :param port: The destination port used to connect to the target
            +            device.
            +    :type port: int or None
            +
            +    :param device_type: Class selection based on device type.
            +    :type device_type: str
            +
            +    :param verbose: Enable additional messages to standard output.
            +    :type verbose: bool
            +
            +    :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
            +    :type global_delay_factor: int
            +
            +    :param use_keys: Connect to target device using SSH keys.
            +    :type use_keys: bool
            +
            +    :param key_file: Filename path of the SSH key file to use.
            +    :type key_file: str
            +
            +    :param pkey: SSH key object to use.
            +    :type pkey: paramiko.PKey
            +
            +    :param passphrase: Passphrase to use for encrypted key; password will be used for key
            +            decryption if not specified.
            +    :type passphrase: str
            +
            +    :param allow_agent: Enable use of SSH key-agent.
            +    :type allow_agent: bool
            +
            +    :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
            +            means unknown SSH host keys will be accepted).
            +    :type ssh_strict: bool
            +
            +    :param system_host_keys: Load host keys from the users known_hosts file.
            +    :type system_host_keys: bool
            +    :param alt_host_keys: If `True` host keys will be loaded from the file specified in
            +            alt_key_file.
            +    :type alt_host_keys: bool
            +
            +    :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
            +    :type alt_key_file: str
            +
            +    :param ssh_config_file: File name of OpenSSH configuration file.
            +    :type ssh_config_file: str
            +
            +    :param timeout: Connection timeout.
            +    :type timeout: float
            +
            +    :param session_timeout: Set a timeout for parallel requests.
            +    :type session_timeout: float
            +
            +    :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
            +    :type auth_timeout: float
            +
            +    :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
            +    :type banner_timeout: float
            +
            +    :param keepalive: Send SSH keepalive packets at a specific interval, in seconds.
            +            Currently defaults to 0, for backwards compatibility (it will not attempt
            +            to keep the connection alive).
            +    :type keepalive: int
            +
            +    :param default_enter: Character(s) to send to correspond to enter key (default:
            +
            +

            ). +:type default_enter: str

            +
                :param response_return: Character(s) to use in normalized return data to represent
            +            enter key (default:
            +
            +

            ) +:type response_return: str

            +
                :param fast_cli: Provide a way to optimize for performance. Converts select_delay_factor
            +            to select smallest of global and specific. Sets default global_delay_factor to .1
            +            (default: False)
            +    :type fast_cli: boolean
            +
            +    :param session_log: File path or BufferedIOBase subclass object to write the session log to.
            +    :type session_log: str
            +
            +    :param session_log_record_writes: The session log generally only records channel reads due
            +            to eliminate command duplication due to command echo. You can enable this if you
            +            want to record both channel reads and channel writes in the log (default: False).
            +    :type session_log_record_writes: boolean
            +
            +    :param session_log_file_mode: "write" or "append" for session_log file mode
            +            (default: "write")
            +    :type session_log_file_mode: str
            +
            +    :param allow_auto_change: Allow automatic configuration changes for terminal settings.
            +            (default: False)
            +    :type allow_auto_change: bool
            +
            +    :param encoding: Encoding to be used when writing bytes to the output channel.
            +            (default: ascii)
            +    :type encoding: str
            +
            +    :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
            +            communication to the target host (default: None).
            +    :type sock: socket
            +
            +    :param global_cmd_verify: Control whether command echo verification is enabled or disabled
            +            (default: None). Global attribute takes precedence over function `cmd_verify`
            +            argument. Value of `None` indicates to use function `cmd_verify` argument.
            +    :type global_cmd_verify: bool|None
            +
            +    :param auto_connect: Control whether Netmiko automatically establishes the connection as
            +            part of the object creation (default: True).
            +    :type auto_connect: bool
            +
            +
            +Source code +
            class EricssonIposSSH(BaseConnection):
            +    def check_enable_mode(self, check_string="#"):
            +        """
            +        Check if in enable mode. Return boolean.
            +        """
            +        return super().check_enable_mode(check_string=check_string)
            +
            +    def enable(self, cmd="enable 15", pattern="ssword", re_flags=re.IGNORECASE):
            +        """Enter enable mode."""
            +        return super().enable(cmd=cmd, pattern=pattern, re_flags=re_flags)
            +
            +    def disable_paging(self, command="terminal length 0", delay_factor=1):
            +        """Disable paging default to a Cisco CLI method.
            +
            +        :param command: Device command to disable pagination of output
            +        :type command: str
            +
            +        :param delay_factor: See __init__: global_delay_factor
            +        :type delay_factor: int
            +        """
            +        return super().disable_paging(command=command, delay_factor=delay_factor)
            +
            +    def set_terminal_width(self, command="terminal width 512", delay_factor=1):
            +        """CLI terminals try to automatically adjust the line based on the width of the terminal.
            +        This causes the output to get distorted when accessed programmatically.
            +
            +        Set terminal width to 511 which works on a broad set of devices.
            +
            +        :param command: Command string to send to the device
            +        :type command: str
            +
            +        :param delay_factor: See __init__: global_delay_factor
            +        :type delay_factor: int
            +        """
            +        return super().set_terminal_width(command=command, delay_factor=delay_factor)
            +
            +    def send_config_set(self, config_commands=None, exit_config_mode=False, **kwargs):
            +        """Ericsson IPOS requires you not exit from configuration mode."""
            +        return super().send_config_set(
            +            config_commands=config_commands, exit_config_mode=exit_config_mode, **kwargs
            +        )
            +
            +    def exit_enable_mode(self, exit_command="disable"):
            +        """
            +        Exits enable (privileged exec) mode.
            +        """
            +        return super().exit_enable_mode(exit_command=exit_command)
            +
            +    def check_config_mode(self, check_string=")#", pattern=""):
            +        """
            +        Checks if the device is in configuration mode or not.
            +        """
            +        return super().check_config_mode(check_string=check_string, pattern=pattern)
            +
            +    def config_mode(self, config_command="configure", pattern=""):
            +        """
            +        Enter into configuration mode on remote device.
            +        """
            +        if not pattern:
            +            pattern = re.escape(self.base_prompt[:16])
            +        return super().config_mode(config_command=config_command, pattern=pattern)
            +
            +    def exit_config_mode(self, exit_config="end", pattern="#"):
            +        """
            +        Exit from configuration mode.
            +        Ercisson output :
            +            end                   Commit configuration changes and return to exec mode
            +        """
            +        return super().exit_config_mode(exit_config=exit_config, pattern=pattern)
            +
            +    def save_config(self, cmd="save config", confirm=True, confirm_response="yes"):
            +        """Saves configuration"""
            +        if confirm:
            +            output = self.send_command_timing(
            +                command_string=cmd, strip_prompt=False, strip_command=False
            +            )
            +
            +            if confirm_response:
            +                output += self.send_command_timing(
            +                    confirm_response, strip_prompt=False, strip_command=False
            +                )
            +            else:
            +                output += self.send_command_timing(
            +                    self.RETURN, strip_prompt=False, strip_command=False
            +                )
            +        else:
            +            output = self.send_command(
            +                command_string=cmd, strip_prompt=False, strip_command=False
            +            )
            +        return output
            +
            +    def commit(self, confirm=False, confirm_delay=None, comment="", delay_factor=1):
            +        """
            +        Commit the candidate configuration.
            +
            +        Commit the entered configuration. Raise an error and return the failure
            +        if the commit fails.
            +
            +        Automatically enters configuration mode
            +
            +        """
            +
            +        delay_factor = self.select_delay_factor(delay_factor)
            +
            +        if confirm_delay and not confirm:
            +            raise ValueError(
            +                "Invalid arguments supplied to commit method both confirm and check"
            +            )
            +
            +        command_string = "commit"
            +        commit_marker = "Transaction committed"
            +        if confirm:
            +            if confirm_delay:
            +                command_string = f"commit confirmed {confirm_delay}"
            +            else:
            +                command_string = "commit confirmed"
            +            commit_marker = "Commit confirmed ,it will be rolled back within"
            +
            +        if comment:
            +            if '"' in comment:
            +                raise ValueError("Invalid comment contains double quote")
            +            comment = f'"{comment}"'
            +            command_string += f" comment {comment}"
            +
            +        output = self.config_mode()
            +
            +        output += self.send_command_expect(
            +            command_string,
            +            strip_prompt=False,
            +            strip_command=False,
            +            delay_factor=delay_factor,
            +        )
            +
            +        if commit_marker not in output:
            +            raise ValueError(f"Commit failed with the following errors:\n\n{output}")
            +
            +        self.exit_config_mode()
            +
            +        return output
            +
            +

            Ancestors

            + +

            Methods

            +
            +
            +def check_config_mode(self, check_string=')#', pattern='') +
            +
            +

            Checks if the device is in configuration mode or not.

            +
            +Source code +
            def check_config_mode(self, check_string=")#", pattern=""):
            +    """
            +    Checks if the device is in configuration mode or not.
            +    """
            +    return super().check_config_mode(check_string=check_string, pattern=pattern)
            +
            +
            +
            +def check_enable_mode(self, check_string='#') +
            +
            +

            Check if in enable mode. Return boolean.

            +
            +Source code +
            def check_enable_mode(self, check_string="#"):
            +    """
            +    Check if in enable mode. Return boolean.
            +    """
            +    return super().check_enable_mode(check_string=check_string)
            +
            +
            +
            +def commit(self, confirm=False, confirm_delay=None, comment='', delay_factor=1) +
            +
            +

            Commit the candidate configuration.

            +

            Commit the entered configuration. Raise an error and return the failure +if the commit fails.

            +

            Automatically enters configuration mode

            +
            +Source code +
            def commit(self, confirm=False, confirm_delay=None, comment="", delay_factor=1):
            +    """
            +    Commit the candidate configuration.
            +
            +    Commit the entered configuration. Raise an error and return the failure
            +    if the commit fails.
            +
            +    Automatically enters configuration mode
            +
            +    """
            +
            +    delay_factor = self.select_delay_factor(delay_factor)
            +
            +    if confirm_delay and not confirm:
            +        raise ValueError(
            +            "Invalid arguments supplied to commit method both confirm and check"
            +        )
            +
            +    command_string = "commit"
            +    commit_marker = "Transaction committed"
            +    if confirm:
            +        if confirm_delay:
            +            command_string = f"commit confirmed {confirm_delay}"
            +        else:
            +            command_string = "commit confirmed"
            +        commit_marker = "Commit confirmed ,it will be rolled back within"
            +
            +    if comment:
            +        if '"' in comment:
            +            raise ValueError("Invalid comment contains double quote")
            +        comment = f'"{comment}"'
            +        command_string += f" comment {comment}"
            +
            +    output = self.config_mode()
            +
            +    output += self.send_command_expect(
            +        command_string,
            +        strip_prompt=False,
            +        strip_command=False,
            +        delay_factor=delay_factor,
            +    )
            +
            +    if commit_marker not in output:
            +        raise ValueError(f"Commit failed with the following errors:\n\n{output}")
            +
            +    self.exit_config_mode()
            +
            +    return output
            +
            +
            +
            +def config_mode(self, config_command='configure', pattern='') +
            +
            +

            Enter into configuration mode on remote device.

            +
            +Source code +
            def config_mode(self, config_command="configure", pattern=""):
            +    """
            +    Enter into configuration mode on remote device.
            +    """
            +    if not pattern:
            +        pattern = re.escape(self.base_prompt[:16])
            +    return super().config_mode(config_command=config_command, pattern=pattern)
            +
            +
            +
            +def enable(self, cmd='enable 15', pattern='ssword', re_flags=) +
            +
            +

            Enter enable mode.

            +
            +Source code +
            def enable(self, cmd="enable 15", pattern="ssword", re_flags=re.IGNORECASE):
            +    """Enter enable mode."""
            +    return super().enable(cmd=cmd, pattern=pattern, re_flags=re_flags)
            +
            +
            +
            +def exit_config_mode(self, exit_config='end', pattern='#') +
            +
            +

            Exit from configuration mode. +Ercisson output : +end +Commit configuration changes and return to exec mode

            +
            +Source code +
            def exit_config_mode(self, exit_config="end", pattern="#"):
            +    """
            +    Exit from configuration mode.
            +    Ercisson output :
            +        end                   Commit configuration changes and return to exec mode
            +    """
            +    return super().exit_config_mode(exit_config=exit_config, pattern=pattern)
            +
            +
            +
            +def exit_enable_mode(self, exit_command='disable') +
            +
            +

            Exits enable (privileged exec) mode.

            +
            +Source code +
            def exit_enable_mode(self, exit_command="disable"):
            +    """
            +    Exits enable (privileged exec) mode.
            +    """
            +    return super().exit_enable_mode(exit_command=exit_command)
            +
            +
            +
            +def save_config(self, cmd='save config', confirm=True, confirm_response='yes') +
            +
            +

            Saves configuration

            +
            +Source code +
            def save_config(self, cmd="save config", confirm=True, confirm_response="yes"):
            +    """Saves configuration"""
            +    if confirm:
            +        output = self.send_command_timing(
            +            command_string=cmd, strip_prompt=False, strip_command=False
            +        )
            +
            +        if confirm_response:
            +            output += self.send_command_timing(
            +                confirm_response, strip_prompt=False, strip_command=False
            +            )
            +        else:
            +            output += self.send_command_timing(
            +                self.RETURN, strip_prompt=False, strip_command=False
            +            )
            +    else:
            +        output = self.send_command(
            +            command_string=cmd, strip_prompt=False, strip_command=False
            +        )
            +    return output
            +
            +
            +
            +def send_config_set(self, config_commands=None, exit_config_mode=False, **kwargs) +
            +
            +

            Ericsson IPOS requires you not exit from configuration mode.

            +
            +Source code +
            def send_config_set(self, config_commands=None, exit_config_mode=False, **kwargs):
            +    """Ericsson IPOS requires you not exit from configuration mode."""
            +    return super().send_config_set(
            +        config_commands=config_commands, exit_config_mode=exit_config_mode, **kwargs
            +    )
            +
            +
            +
            +

            Inherited members

            + +
            +
            +
            +
            + +
            + + + + + \ No newline at end of file diff --git a/docs/netmiko/hp/hp_procurve.html b/docs/netmiko/hp/hp_procurve.html index a968592bd..e2a9237eb 100644 --- a/docs/netmiko/hp/hp_procurve.html +++ b/docs/netmiko/hp/hp_procurve.html @@ -483,7 +483,7 @@

            Subclasses

            Methods

            -def enable(self, cmd='enable', pattern='password', re_flags=re.IGNORECASE, default_username='manager') +def enable(self, cmd='enable', pattern='password', re_flags=, default_username='manager')

            Enter enable mode

            diff --git a/docs/netmiko/index.html b/docs/netmiko/index.html index 3a390eb33..4dd78cbf1 100644 --- a/docs/netmiko/index.html +++ b/docs/netmiko/index.html @@ -47,7 +47,7 @@

            Module netmiko

            # Alternate naming Netmiko = ConnectHandler -__version__ = "3.3.2" +__version__ = "3.3.3" __all__ = ( "ConnectHandler", "ssh_dispatcher", @@ -166,6 +166,10 @@

            Sub-modules

            +
            netmiko.ericsson
            +
            +
            +
            netmiko.extreme
            @@ -1314,6 +1318,11 @@

            Classes

            if delay_factor == 1 and max_loops == 150: max_loops = int(self.timeout / loop_delay) + # FIX: Cleanup in future versions of Netmiko + if delay_factor < 1: + if not self._legacy_mode and self.fast_cli: + delay_factor = 1 + channel_data = "" i = 0 while i <= max_loops: @@ -1403,6 +1412,12 @@

            Classes

            (default: 20) """ delay_factor = self.select_delay_factor(delay_factor) + + # FIX: Cleanup in future versions of Netmiko + if delay_factor < 1: + if not self._legacy_mode and self.fast_cli: + delay_factor = 1 + time.sleep(1 * delay_factor) output = "" @@ -1635,16 +1650,6 @@

            Classes

            msg = msg.lstrip() raise NetmikoTimeoutException(msg) - except paramiko.ssh_exception.SSHException as no_session_err: - self.paramiko_cleanup() - if "No existing session" in str(no_session_err): - msg = ( - "Paramiko: 'No existing session' error: " - "try increasing 'conn_timeout' to 10 seconds or larger." - ) - raise NetmikoTimeoutException(msg) - else: - raise except paramiko.ssh_exception.AuthenticationException as auth_err: self.paramiko_cleanup() msg = f"""Authentication to device failed. @@ -1660,6 +1665,16 @@

            Classes

            msg += self.RETURN + str(auth_err) raise NetmikoAuthenticationException(msg) + except paramiko.ssh_exception.SSHException as no_session_err: + self.paramiko_cleanup() + if "No existing session" in str(no_session_err): + msg = ( + "Paramiko: 'No existing session' error: " + "try increasing 'conn_timeout' to 10 seconds or larger." + ) + raise NetmikoTimeoutException(msg) + else: + raise if self.verbose: print(f"SSH connection established to {self.host}:{self.port}") @@ -1968,16 +1983,10 @@

            Classes

            cmd_verify = cmd_echo output = "" - delay_factor = self.select_delay_factor(delay_factor) - # Cleanup in future versions of Netmiko - if delay_factor < 1: - if not self._legacy_mode and self.fast_cli: - delay_factor = 1 if normalize: command_string = self.normalize_cmd(command_string) - self.write_channel(command_string) cmd = command_string.strip() @@ -2141,6 +2150,7 @@

            Classes

            :param cmd_verify: Verify command echo before proceeding (default: True). :type cmd_verify: bool """ + # Time to delay in each read loop loop_delay = 0.2 @@ -2338,7 +2348,9 @@

            Classes

            output = self.read_until_prompt() return check_string in output - def enable(self, cmd="", pattern="ssword", re_flags=re.IGNORECASE): + def enable( + self, cmd="", pattern="ssword", enable_pattern=None, re_flags=re.IGNORECASE + ): """Enter enable mode. :param cmd: Device command to enter enable mode @@ -2347,6 +2359,9 @@

            Classes

            :param pattern: pattern to search for indicating device is waiting for password :type pattern: str + :param enable_pattern: pattern indicating you have entered enable mode + :type pattern: str + :param re_flags: Regular expression flags used in conjunction with pattern :type re_flags: int """ @@ -2358,15 +2373,20 @@

            Classes

            if not self.check_enable_mode(): self.write_channel(self.normalize_cmd(cmd)) try: - output += self.read_until_prompt_or_pattern( - pattern=pattern, re_flags=re_flags - ) + output += self.read_until_pattern(pattern=re.escape(cmd.strip())) + if pattern not in output: + output += self.read_until_prompt_or_pattern( + pattern=pattern, re_flags=re_flags + ) self.write_channel(self.normalize_cmd(self.secret)) - output += self.read_until_prompt() + if enable_pattern: + output += self.read_until_pattern(pattern=enable_pattern) + else: + output += self.read_until_prompt() + if not self.check_enable_mode(): + raise ValueError(msg) except NetmikoTimeoutException: raise ValueError(msg) - if not self.check_enable_mode(): - raise ValueError(msg) return output def exit_enable_mode(self, exit_command=""): @@ -2724,6 +2744,7 @@

            Subclasses

          • CiscoWlcSSH
          • NetscalerSSH
          • DellIsilonSSH
          • +
          • EricssonIposSSH
          • F5TmshSSH
          • FlexvnfSSH
          • JuniperBase
          • @@ -2977,7 +2998,7 @@

            Methods

            -def enable(self, cmd='', pattern='ssword', re_flags=re.IGNORECASE) +def enable(self, cmd='', pattern='ssword', enable_pattern=None, re_flags=)

            Enter enable mode.

            @@ -2985,11 +3006,15 @@

            Methods

            :type cmd: str

            :param pattern: pattern to search for indicating device is waiting for password :type pattern: str

            +

            :param enable_pattern: pattern indicating you have entered enable mode +:type pattern: str

            :param re_flags: Regular expression flags used in conjunction with pattern :type re_flags: int

            Source code -
            def enable(self, cmd="", pattern="ssword", re_flags=re.IGNORECASE):
            +
            def enable(
            +    self, cmd="", pattern="ssword", enable_pattern=None, re_flags=re.IGNORECASE
            +):
                 """Enter enable mode.
             
                 :param cmd: Device command to enter enable mode
            @@ -2998,6 +3023,9 @@ 

            Methods

            :param pattern: pattern to search for indicating device is waiting for password :type pattern: str + :param enable_pattern: pattern indicating you have entered enable mode + :type pattern: str + :param re_flags: Regular expression flags used in conjunction with pattern :type re_flags: int """ @@ -3009,15 +3037,20 @@

            Methods

            if not self.check_enable_mode(): self.write_channel(self.normalize_cmd(cmd)) try: - output += self.read_until_prompt_or_pattern( - pattern=pattern, re_flags=re_flags - ) + output += self.read_until_pattern(pattern=re.escape(cmd.strip())) + if pattern not in output: + output += self.read_until_prompt_or_pattern( + pattern=pattern, re_flags=re_flags + ) self.write_channel(self.normalize_cmd(self.secret)) - output += self.read_until_prompt() + if enable_pattern: + output += self.read_until_pattern(pattern=enable_pattern) + else: + output += self.read_until_prompt() + if not self.check_enable_mode(): + raise ValueError(msg) except NetmikoTimeoutException: raise ValueError(msg) - if not self.check_enable_mode(): - raise ValueError(msg) return output
            @@ -3083,16 +3116,6 @@

            Methods

            msg = msg.lstrip() raise NetmikoTimeoutException(msg) - except paramiko.ssh_exception.SSHException as no_session_err: - self.paramiko_cleanup() - if "No existing session" in str(no_session_err): - msg = ( - "Paramiko: 'No existing session' error: " - "try increasing 'conn_timeout' to 10 seconds or larger." - ) - raise NetmikoTimeoutException(msg) - else: - raise except paramiko.ssh_exception.AuthenticationException as auth_err: self.paramiko_cleanup() msg = f"""Authentication to device failed. @@ -3108,6 +3131,16 @@

            Methods

            msg += self.RETURN + str(auth_err) raise NetmikoAuthenticationException(msg) + except paramiko.ssh_exception.SSHException as no_session_err: + self.paramiko_cleanup() + if "No existing session" in str(no_session_err): + msg = ( + "Paramiko: 'No existing session' error: " + "try increasing 'conn_timeout' to 10 seconds or larger." + ) + raise NetmikoTimeoutException(msg) + else: + raise if self.verbose: print(f"SSH connection established to {self.host}:{self.port}") @@ -3577,6 +3610,7 @@

            Methods

            :param cmd_verify: Verify command echo before proceeding (default: True). :type cmd_verify: bool """ + # Time to delay in each read loop loop_delay = 0.2 @@ -3818,16 +3852,10 @@

            Methods

            cmd_verify = cmd_echo output = "" - delay_factor = self.select_delay_factor(delay_factor) - # Cleanup in future versions of Netmiko - if delay_factor < 1: - if not self._legacy_mode and self.fast_cli: - delay_factor = 1 if normalize: command_string = self.normalize_cmd(command_string) - self.write_channel(command_string) cmd = command_string.strip() @@ -4468,6 +4496,12 @@

            Methods

            (default: 20) """ delay_factor = self.select_delay_factor(delay_factor) + + # FIX: Cleanup in future versions of Netmiko + if delay_factor < 1: + if not self._legacy_mode and self.fast_cli: + delay_factor = 1 + time.sleep(1 * delay_factor) output = "" @@ -5104,7 +5138,7 @@

            Methods

            best_match : str or None The device type that is currently the best to use to interact with the device """ - for device_type, autodetect_dict in SSH_MAPPER_BASE.items(): + for device_type, autodetect_dict in SSH_MAPPER_BASE: tmp_dict = autodetect_dict.copy() call_method = tmp_dict.pop("dispatch") autodetect_method = getattr(self, call_method) @@ -5172,7 +5206,7 @@

            Methods

            return cached_results def _autodetect_remote_version( - self, search_patterns=None, re_flags=re.IGNORECASE, priority=99 + self, search_patterns=None, re_flags=re.IGNORECASE, priority=99, **kwargs ): """ Method to try auto-detect the device type, by matching a regular expression on the reported @@ -5276,7 +5310,7 @@

            Returns

            best_match : str or None The device type that is currently the best to use to interact with the device """ - for device_type, autodetect_dict in SSH_MAPPER_BASE.items(): + for device_type, autodetect_dict in SSH_MAPPER_BASE: tmp_dict = autodetect_dict.copy() call_method = tmp_dict.pop("dispatch") autodetect_method = getattr(self, call_method) @@ -5337,6 +5371,7 @@

            Index

          • netmiko.eltex
          • netmiko.endace
          • netmiko.enterasys
          • +
          • netmiko.ericsson
          • netmiko.extreme
          • netmiko.f5
          • netmiko.flexvnf
          • diff --git a/docs/netmiko/juniper/index.html b/docs/netmiko/juniper/index.html index c6d600cbc..42d649532 100644 --- a/docs/netmiko/juniper/index.html +++ b/docs/netmiko/juniper/index.html @@ -131,7 +131,7 @@

            Inherited members

            class JuniperSSH -(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=5, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=False, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True) +(*args, **kwargs)

            Implement methods for interacting with Juniper Networks devices.

            diff --git a/docs/netmiko/juniper/juniper.html b/docs/netmiko/juniper/juniper.html index db24d4cf0..19a489f30 100644 --- a/docs/netmiko/juniper/juniper.html +++ b/docs/netmiko/juniper/juniper.html @@ -37,22 +37,26 @@

            Module netmiko.juniper.juniper

            methods. Overrides several methods for Juniper-specific compatibility. """ - def session_preparation(self): - """ - Prepare the session after the connection has been established. + def __init__(self, *args, **kwargs): + # Cisco-IOS defaults to fast_cli=True and legacy_mode=False + kwargs.setdefault("fast_cli", True) + kwargs.setdefault("_legacy_mode", False) + return super().__init__(*args, **kwargs) - Disable paging (the '--more--' prompts). - Set the base prompt for interaction ('>'). - """ - self._test_channel_read() + def session_preparation(self): + """Prepare the session after the connection has been established.""" self.enter_cli_mode() + cmd = "set cli screen-width 511" + self.set_terminal_width(command=cmd, pattern=r"Screen width set to") + # Overloading disable_paging which is confusing + self.disable_paging( + command="set cli complete-on-space off", + pattern=r"Disabling complete-on-space", + ) + self.disable_paging( + command="set cli screen-length 0", pattern=r"Screen length set to" + ) self.set_base_prompt() - self._disable_complete_on_space() - self.set_terminal_width(command="set cli screen-width 511", pattern="set") - self.disable_paging(command="set cli screen-length 0") - # Clear the read buffer - time.sleep(0.3 * self.global_delay_factor) - self.clear_buffer() def _enter_shell(self): """Enter the Bourne Shell.""" @@ -62,21 +66,6 @@

            Module netmiko.juniper.juniper

            """Return to the Juniper CLI.""" return self.send_command("exit", expect_string=r"[#>]") - def _disable_complete_on_space(self): - """ - Juniper tries to auto complete commands when you type a "space" character. - - This is a bad idea for automation as what your program is sending no longer matches - the command echo from the device. So we disable this behavior. - """ - delay_factor = self.select_delay_factor(delay_factor=0) - time.sleep(delay_factor * 0.1) - command = "set cli complete-on-space off" - self.write_channel(self.normalize_cmd(command)) - time.sleep(delay_factor * 0.1) - output = self.read_channel() - return output - def enter_cli_mode(self): """Check if at shell prompt root@ and go into CLI.""" delay_factor = self.select_delay_factor(delay_factor=0) @@ -111,9 +100,16 @@

            Module netmiko.juniper.juniper

            """Checks if the device is in configuration mode or not.""" return super().check_config_mode(check_string=check_string) - def config_mode(self, config_command="configure"): + def config_mode( + self, + config_command="configure", + pattern=r"Entering configuration mode", + **kwargs, + ): """Enter configuration mode.""" - return super().config_mode(config_command=config_command) + return super().config_mode( + config_command=config_command, pattern=pattern, **kwargs + ) def exit_config_mode(self, exit_config="exit configuration-mode"): """Exit configuration mode.""" @@ -163,6 +159,12 @@

            Module netmiko.juniper.juniper

            """ delay_factor = self.select_delay_factor(delay_factor) + # Commit is very slow so this is needed. + # FIX: Cleanup in future versions of Netmiko + if delay_factor < 1: + if not self._legacy_mode and self.fast_cli: + delay_factor = 1 + if check and (confirm or confirm_delay or comment): raise ValueError("Invalid arguments supplied with commit check") @@ -197,22 +199,24 @@

            Module netmiko.juniper.juniper

            # Enter config mode (if necessary) output = self.config_mode() # and_quit will get out of config mode on commit + if and_quit: - prompt = self.base_prompt - output += self.send_command_expect( - command_string, - expect_string=prompt, - strip_prompt=False, - strip_command=False, - delay_factor=delay_factor, - ) + expect_string = re.escape(self.base_prompt) else: - output += self.send_command_expect( + expect_string = None + + try: + fast_cli_state = self.fast_cli + self.fast_cli = False + output += self.send_command( command_string, + expect_string=expect_string, strip_prompt=False, strip_command=False, delay_factor=delay_factor, ) + finally: + self.fast_cli = fast_cli_state if commit_marker not in output: raise ValueError(f"Commit failed with the following errors:\n\n{output}") @@ -332,7 +336,7 @@

            Classes

            class JuniperBase -(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=5, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=False, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True) +(*args, **kwargs)

            Implement methods for interacting with Juniper Networks devices.

            @@ -479,22 +483,26 @@

            Classes

            methods. Overrides several methods for Juniper-specific compatibility. """ - def session_preparation(self): - """ - Prepare the session after the connection has been established. + def __init__(self, *args, **kwargs): + # Cisco-IOS defaults to fast_cli=True and legacy_mode=False + kwargs.setdefault("fast_cli", True) + kwargs.setdefault("_legacy_mode", False) + return super().__init__(*args, **kwargs) - Disable paging (the '--more--' prompts). - Set the base prompt for interaction ('>'). - """ - self._test_channel_read() + def session_preparation(self): + """Prepare the session after the connection has been established.""" self.enter_cli_mode() + cmd = "set cli screen-width 511" + self.set_terminal_width(command=cmd, pattern=r"Screen width set to") + # Overloading disable_paging which is confusing + self.disable_paging( + command="set cli complete-on-space off", + pattern=r"Disabling complete-on-space", + ) + self.disable_paging( + command="set cli screen-length 0", pattern=r"Screen length set to" + ) self.set_base_prompt() - self._disable_complete_on_space() - self.set_terminal_width(command="set cli screen-width 511", pattern="set") - self.disable_paging(command="set cli screen-length 0") - # Clear the read buffer - time.sleep(0.3 * self.global_delay_factor) - self.clear_buffer() def _enter_shell(self): """Enter the Bourne Shell.""" @@ -504,21 +512,6 @@

            Classes

            """Return to the Juniper CLI.""" return self.send_command("exit", expect_string=r"[#>]") - def _disable_complete_on_space(self): - """ - Juniper tries to auto complete commands when you type a "space" character. - - This is a bad idea for automation as what your program is sending no longer matches - the command echo from the device. So we disable this behavior. - """ - delay_factor = self.select_delay_factor(delay_factor=0) - time.sleep(delay_factor * 0.1) - command = "set cli complete-on-space off" - self.write_channel(self.normalize_cmd(command)) - time.sleep(delay_factor * 0.1) - output = self.read_channel() - return output - def enter_cli_mode(self): """Check if at shell prompt root@ and go into CLI.""" delay_factor = self.select_delay_factor(delay_factor=0) @@ -553,9 +546,16 @@

            Classes

            """Checks if the device is in configuration mode or not.""" return super().check_config_mode(check_string=check_string) - def config_mode(self, config_command="configure"): + def config_mode( + self, + config_command="configure", + pattern=r"Entering configuration mode", + **kwargs, + ): """Enter configuration mode.""" - return super().config_mode(config_command=config_command) + return super().config_mode( + config_command=config_command, pattern=pattern, **kwargs + ) def exit_config_mode(self, exit_config="exit configuration-mode"): """Exit configuration mode.""" @@ -605,6 +605,12 @@

            Classes

            """ delay_factor = self.select_delay_factor(delay_factor) + # Commit is very slow so this is needed. + # FIX: Cleanup in future versions of Netmiko + if delay_factor < 1: + if not self._legacy_mode and self.fast_cli: + delay_factor = 1 + if check and (confirm or confirm_delay or comment): raise ValueError("Invalid arguments supplied with commit check") @@ -639,22 +645,24 @@

            Classes

            # Enter config mode (if necessary) output = self.config_mode() # and_quit will get out of config mode on commit + if and_quit: - prompt = self.base_prompt - output += self.send_command_expect( - command_string, - expect_string=prompt, - strip_prompt=False, - strip_command=False, - delay_factor=delay_factor, - ) + expect_string = re.escape(self.base_prompt) else: - output += self.send_command_expect( + expect_string = None + + try: + fast_cli_state = self.fast_cli + self.fast_cli = False + output += self.send_command( command_string, + expect_string=expect_string, strip_prompt=False, strip_command=False, delay_factor=delay_factor, ) + finally: + self.fast_cli = fast_cli_state if commit_marker not in output: raise ValueError(f"Commit failed with the following errors:\n\n{output}") @@ -816,6 +824,12 @@

            Methods

            """ delay_factor = self.select_delay_factor(delay_factor) + # Commit is very slow so this is needed. + # FIX: Cleanup in future versions of Netmiko + if delay_factor < 1: + if not self._legacy_mode and self.fast_cli: + delay_factor = 1 + if check and (confirm or confirm_delay or comment): raise ValueError("Invalid arguments supplied with commit check") @@ -850,22 +864,24 @@

            Methods

            # Enter config mode (if necessary) output = self.config_mode() # and_quit will get out of config mode on commit + if and_quit: - prompt = self.base_prompt - output += self.send_command_expect( - command_string, - expect_string=prompt, - strip_prompt=False, - strip_command=False, - delay_factor=delay_factor, - ) + expect_string = re.escape(self.base_prompt) else: - output += self.send_command_expect( + expect_string = None + + try: + fast_cli_state = self.fast_cli + self.fast_cli = False + output += self.send_command( command_string, + expect_string=expect_string, strip_prompt=False, strip_command=False, delay_factor=delay_factor, ) + finally: + self.fast_cli = fast_cli_state if commit_marker not in output: raise ValueError(f"Commit failed with the following errors:\n\n{output}") @@ -874,15 +890,22 @@

            Methods

            -def config_mode(self, config_command='configure') +def config_mode(self, config_command='configure', pattern='Entering configuration mode', **kwargs)

            Enter configuration mode.

            Source code -
            def config_mode(self, config_command="configure"):
            +
            def config_mode(
            +    self,
            +    config_command="configure",
            +    pattern=r"Entering configuration mode",
            +    **kwargs,
            +):
                 """Enter configuration mode."""
            -    return super().config_mode(config_command=config_command)
            + return super().config_mode( + config_command=config_command, pattern=pattern, **kwargs + )
            @@ -962,27 +985,23 @@

            Methods

            def session_preparation(self)
            -

            Prepare the session after the connection has been established.

            -

            Disable paging (the '–more–' prompts). -Set the base prompt for interaction ('>').

            +

            Prepare the session after the connection has been established.

            Source code
            def session_preparation(self):
            -    """
            -    Prepare the session after the connection has been established.
            -
            -    Disable paging (the '--more--' prompts).
            -    Set the base prompt for interaction ('>').
            -    """
            -    self._test_channel_read()
            +    """Prepare the session after the connection has been established."""
                 self.enter_cli_mode()
            -    self.set_base_prompt()
            -    self._disable_complete_on_space()
            -    self.set_terminal_width(command="set cli screen-width 511", pattern="set")
            -    self.disable_paging(command="set cli screen-length 0")
            -    # Clear the read buffer
            -    time.sleep(0.3 * self.global_delay_factor)
            -    self.clear_buffer()
            + cmd = "set cli screen-width 511" + self.set_terminal_width(command=cmd, pattern=r"Screen width set to") + # Overloading disable_paging which is confusing + self.disable_paging( + command="set cli complete-on-space off", + pattern=r"Disabling complete-on-space", + ) + self.disable_paging( + command="set cli screen-length 0", pattern=r"Screen length set to" + ) + self.set_base_prompt()
            @@ -1161,7 +1180,7 @@

            Inherited members

            class JuniperSSH -(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=5, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=False, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True) +(*args, **kwargs)

            Implement methods for interacting with Juniper Networks devices.

            diff --git a/docs/netmiko/linux/index.html b/docs/netmiko/linux/index.html index e7d1dc966..578792223 100644 --- a/docs/netmiko/linux/index.html +++ b/docs/netmiko/linux/index.html @@ -456,7 +456,7 @@

            Methods

            -def enable(self, cmd='sudo -s', pattern='ssword', re_flags=re.IGNORECASE) +def enable(self, cmd='sudo -s', pattern='ssword', re_flags=)

            Attempt to become root.

            diff --git a/docs/netmiko/linux/linux_ssh.html b/docs/netmiko/linux/linux_ssh.html index ea20fa72f..df2201010 100644 --- a/docs/netmiko/linux/linux_ssh.html +++ b/docs/netmiko/linux/linux_ssh.html @@ -622,7 +622,7 @@

            Methods

            -def enable(self, cmd='sudo -s', pattern='ssword', re_flags=re.IGNORECASE) +def enable(self, cmd='sudo -s', pattern='ssword', re_flags=)

            Attempt to become root.

            diff --git a/docs/netmiko/mellanox/index.html b/docs/netmiko/mellanox/index.html index 1a096d111..273433703 100644 --- a/docs/netmiko/mellanox/index.html +++ b/docs/netmiko/mellanox/index.html @@ -246,7 +246,7 @@

            Ancestors

            Methods

            -def enable(self, cmd='enable', pattern='#', re_flags=re.IGNORECASE) +def enable(self, cmd='enable', pattern='#', re_flags=)

            Enter into enable mode.

            diff --git a/docs/netmiko/mellanox/mellanox_mlnxos_ssh.html b/docs/netmiko/mellanox/mellanox_mlnxos_ssh.html index 2265ddab4..3706ca0c4 100644 --- a/docs/netmiko/mellanox/mellanox_mlnxos_ssh.html +++ b/docs/netmiko/mellanox/mellanox_mlnxos_ssh.html @@ -298,7 +298,7 @@

            Ancestors

            Methods

            -def enable(self, cmd='enable', pattern='#', re_flags=re.IGNORECASE) +def enable(self, cmd='enable', pattern='#', re_flags=)

            Enter into enable mode.

            diff --git a/docs/netmiko/mrv/index.html b/docs/netmiko/mrv/index.html index 5b9436858..7240ff880 100644 --- a/docs/netmiko/mrv/index.html +++ b/docs/netmiko/mrv/index.html @@ -494,7 +494,7 @@

            Ancestors

            Methods

            -def enable(self, cmd='enable', pattern='#', re_flags=re.IGNORECASE) +def enable(self, cmd='enable', pattern='#', re_flags=)

            Enable mode on MRV uses no password.

            diff --git a/docs/netmiko/mrv/mrv_ssh.html b/docs/netmiko/mrv/mrv_ssh.html index 229094cd6..884d51b82 100644 --- a/docs/netmiko/mrv/mrv_ssh.html +++ b/docs/netmiko/mrv/mrv_ssh.html @@ -259,7 +259,7 @@

            Ancestors

            Methods

            -def enable(self, cmd='enable', pattern='#', re_flags=re.IGNORECASE) +def enable(self, cmd='enable', pattern='#', re_flags=)

            Enable mode on MRV uses no password.

            diff --git a/docs/netmiko/netgear/index.html b/docs/netmiko/netgear/index.html index 9fdc4c5dd..0cd288cf3 100644 --- a/docs/netmiko/netgear/index.html +++ b/docs/netmiko/netgear/index.html @@ -203,10 +203,10 @@

            Classes

            def check_config_mode(self, check_string="(Config)#"): return super().check_config_mode(check_string=check_string) - def config_mode(self, config_command="configure", pattern=r")#"): + def config_mode(self, config_command="configure", pattern=r"\)\#"): return super().config_mode(config_command=config_command, pattern=pattern) - def exit_config_mode(self, exit_config="exit", pattern="#"): + def exit_config_mode(self, exit_config="exit", pattern=r"\#"): return super().exit_config_mode(exit_config=exit_config, pattern=pattern) def save_config( diff --git a/docs/netmiko/netgear/netgear_prosafe_ssh.html b/docs/netmiko/netgear/netgear_prosafe_ssh.html index f6851bcd5..526a8b3f6 100644 --- a/docs/netmiko/netgear/netgear_prosafe_ssh.html +++ b/docs/netmiko/netgear/netgear_prosafe_ssh.html @@ -50,10 +50,10 @@

            Module netmiko.netgear.netgear_prosafe_ssh

            def check_config_mode(self, check_string="(Config)#"): return super().check_config_mode(check_string=check_string) - def config_mode(self, config_command="configure", pattern=r")#"): + def config_mode(self, config_command="configure", pattern=r"\)\#"): return super().config_mode(config_command=config_command, pattern=pattern) - def exit_config_mode(self, exit_config="exit", pattern="#"): + def exit_config_mode(self, exit_config="exit", pattern=r"\#"): return super().exit_config_mode(exit_config=exit_config, pattern=pattern) def save_config( @@ -238,10 +238,10 @@

            Classes

            def check_config_mode(self, check_string="(Config)#"): return super().check_config_mode(check_string=check_string) - def config_mode(self, config_command="configure", pattern=r")#"): + def config_mode(self, config_command="configure", pattern=r"\)\#"): return super().config_mode(config_command=config_command, pattern=pattern) - def exit_config_mode(self, exit_config="exit", pattern="#"): + def exit_config_mode(self, exit_config="exit", pattern=r"\#"): return super().exit_config_mode(exit_config=exit_config, pattern=pattern) def save_config( diff --git a/docs/netmiko/nokia/index.html b/docs/netmiko/nokia/index.html index dfffb52e2..c4cc956af 100644 --- a/docs/netmiko/nokia/index.html +++ b/docs/netmiko/nokia/index.html @@ -683,7 +683,7 @@

            Methods

            -def enable(self, cmd='enable', pattern='ssword', re_flags=re.IGNORECASE) +def enable(self, cmd='enable', pattern='ssword', re_flags=)

            Enable SR OS administrative mode

            diff --git a/docs/netmiko/nokia/nokia_sros_ssh.html b/docs/netmiko/nokia/nokia_sros_ssh.html index 3482f6336..0f59ad2de 100644 --- a/docs/netmiko/nokia/nokia_sros_ssh.html +++ b/docs/netmiko/nokia/nokia_sros_ssh.html @@ -989,7 +989,7 @@

            Methods

            -def enable(self, cmd='enable', pattern='ssword', re_flags=re.IGNORECASE) +def enable(self, cmd='enable', pattern='ssword', re_flags=)

            Enable SR OS administrative mode

            diff --git a/docs/netmiko/ruckus/ruckus_fastiron.html b/docs/netmiko/ruckus/ruckus_fastiron.html index b868f32c7..9b6a4565a 100644 --- a/docs/netmiko/ruckus/ruckus_fastiron.html +++ b/docs/netmiko/ruckus/ruckus_fastiron.html @@ -347,7 +347,7 @@

            Subclasses

            Methods

            -def enable(self, cmd='enable', pattern='(ssword|User Name)', re_flags=re.IGNORECASE) +def enable(self, cmd='enable', pattern='(ssword|User Name)', re_flags=)

            Enter enable mode. diff --git a/docs/netmiko/ssh_autodetect.html b/docs/netmiko/ssh_autodetect.html index 27a02c70f..666bfab41 100644 --- a/docs/netmiko/ssh_autodetect.html +++ b/docs/netmiko/ssh_autodetect.html @@ -28,7 +28,7 @@

            Notes

            The SSHDetect class is instantiated using the same parameters than a standard Netmiko connection (see the netmiko.ssh_dispatacher.ConnectHandler function). The only acceptable value for the 'device_type' argument is 'autodetect'.

            -

            The auto-detection is solely based on the SSH_MAPPER_BASE dictionary. The keys are the name of +

            The auto-detection is solely based on SSH_MAPPER_BASE. The keys are the name of the 'device_type' supported for auto-detection and the value is another dictionary describing how to handle the auto-detection.

              @@ -71,7 +71,7 @@

              Netmiko connection creation section connection (see the *netmiko.ssh_dispatacher.ConnectHandler* function). The only acceptable value for the 'device_type' argument is 'autodetect'. -The auto-detection is solely based on the *SSH_MAPPER_BASE* dictionary. The keys are the name of +The auto-detection is solely based on *SSH_MAPPER_BASE*. The keys are the name of the 'device_type' supported for auto-detection and the value is another dictionary describing how to handle the auto-detection. @@ -162,7 +162,7 @@

              Netmiko connection creation section }, "dell_force10": { "cmd": "show version", - "search_patterns": [r"S4048-ON"], + "search_patterns": [r"Real Time Operating System Software"], "priority": 99, "dispatch": "_autodetect_std", }, @@ -177,7 +177,7 @@

              Netmiko connection creation section }, "dell_os10": { "cmd": "show version", - "search_patterns": [r"Dell EMC Networking OS10-Enterprise"], + "search_patterns": [r"Dell EMC Networking OS10.Enterprise"], "priority": 99, "dispatch": "_autodetect_std", }, @@ -250,6 +250,7 @@

              Netmiko connection creation section "dispatch": "_autodetect_std", }, "cisco_wlc": { + "cmd": "", "dispatch": "_autodetect_remote_version", "search_patterns": [r"CISCO_WLC"], "priority": 99, @@ -266,8 +267,27 @@

              Netmiko connection creation section "priority": 99, "dispatch": "_autodetect_std", }, + "fortinet": { + "cmd": "get system status", + "search_patterns": [r"FortiOS"], + "priority": 99, + "dispatch": "_autodetect_std", + }, } +# Sort SSH_MAPPER_BASE such that the most common commands are first +cmd_count = {} +for k, v in SSH_MAPPER_BASE.items(): + count = cmd_count.setdefault(v["cmd"], 0) + cmd_count[v["cmd"]] = count + 1 +cmd_count = {k: v for k, v in sorted(cmd_count.items(), key=lambda item: item[1])} + +# SSH_MAPPER_BASE will be a list after this +SSH_MAPPER_BASE = sorted( + SSH_MAPPER_BASE.items(), key=lambda item: int(cmd_count[item[1]["cmd"]]) +) +SSH_MAPPER_BASE.reverse() + class SSHDetect(object): """ @@ -320,7 +340,7 @@

              Netmiko connection creation section best_match : str or None The device type that is currently the best to use to interact with the device """ - for device_type, autodetect_dict in SSH_MAPPER_BASE.items(): + for device_type, autodetect_dict in SSH_MAPPER_BASE: tmp_dict = autodetect_dict.copy() call_method = tmp_dict.pop("dispatch") autodetect_method = getattr(self, call_method) @@ -388,7 +408,7 @@

              Netmiko connection creation section return cached_results def _autodetect_remote_version( - self, search_patterns=None, re_flags=re.IGNORECASE, priority=99 + self, search_patterns=None, re_flags=re.IGNORECASE, priority=99, **kwargs ): """ Method to try auto-detect the device type, by matching a regular expression on the reported @@ -559,7 +579,7 @@

              Methods

              best_match : str or None The device type that is currently the best to use to interact with the device """ - for device_type, autodetect_dict in SSH_MAPPER_BASE.items(): + for device_type, autodetect_dict in SSH_MAPPER_BASE: tmp_dict = autodetect_dict.copy() call_method = tmp_dict.pop("dispatch") autodetect_method = getattr(self, call_method) @@ -627,7 +647,7 @@

              Methods

              return cached_results def _autodetect_remote_version( - self, search_patterns=None, re_flags=re.IGNORECASE, priority=99 + self, search_patterns=None, re_flags=re.IGNORECASE, priority=99, **kwargs ): """ Method to try auto-detect the device type, by matching a regular expression on the reported @@ -731,7 +751,7 @@

              Returns

              best_match : str or None The device type that is currently the best to use to interact with the device """ - for device_type, autodetect_dict in SSH_MAPPER_BASE.items(): + for device_type, autodetect_dict in SSH_MAPPER_BASE: tmp_dict = autodetect_dict.copy() call_method = tmp_dict.pop("dispatch") autodetect_method = getattr(self, call_method) diff --git a/docs/netmiko/tplink/index.html b/docs/netmiko/tplink/index.html index 1fd93ecf1..5eb7455e4 100644 --- a/docs/netmiko/tplink/index.html +++ b/docs/netmiko/tplink/index.html @@ -182,7 +182,12 @@

              Classes

              Source code
              class TPLinkJetStreamSSH(TPLinkJetStreamBase):
              -    def _override_check_dsa_parameters(parameters):
              +    def __init__(self, **kwargs):
              +        dsa._check_dsa_parameters = self._override_check_dsa_parameters
              +
              +        return super().__init__(**kwargs)
              +
              +    def _override_check_dsa_parameters(self, parameters):
                       """
                       Override check_dsa_parameters from cryptography's dsa.py
               
              @@ -200,13 +205,11 @@ 

              Classes

              It's still not possible to remove this hack. """ - if crypto_utils.bit_length(parameters.q) not in [160, 256]: + if parameters.q.bit_length() not in [160, 256]: raise ValueError("q must be exactly 160 or 256 bits long") if not (1 < parameters.g < parameters.p): - raise ValueError("g, p don't satisfy 1 < g < p.") - - dsa._check_dsa_parameters = _override_check_dsa_parameters
              + raise ValueError("g, p don't satisfy 1 < g < p.")

              Ancestors

                diff --git a/docs/netmiko/tplink/tplink_jetstream.html b/docs/netmiko/tplink/tplink_jetstream.html index f345b0fca..298f8d098 100644 --- a/docs/netmiko/tplink/tplink_jetstream.html +++ b/docs/netmiko/tplink/tplink_jetstream.html @@ -25,7 +25,6 @@

                Module netmiko.tplink.tplink_jetstream

                import re
                 import time
                 
                -from cryptography import utils as crypto_utils
                 from cryptography.hazmat.primitives.asymmetric import dsa
                 
                 from netmiko import log
                @@ -148,7 +147,12 @@ 

                Module netmiko.tplink.tplink_jetstream

                class TPLinkJetStreamSSH(TPLinkJetStreamBase): - def _override_check_dsa_parameters(parameters): + def __init__(self, **kwargs): + dsa._check_dsa_parameters = self._override_check_dsa_parameters + + return super().__init__(**kwargs) + + def _override_check_dsa_parameters(self, parameters): """ Override check_dsa_parameters from cryptography's dsa.py @@ -166,14 +170,12 @@

                Module netmiko.tplink.tplink_jetstream

                It's still not possible to remove this hack. """ - if crypto_utils.bit_length(parameters.q) not in [160, 256]: + if parameters.q.bit_length() not in [160, 256]: raise ValueError("q must be exactly 160 or 256 bits long") if not (1 < parameters.g < parameters.p): raise ValueError("g, p don't satisfy 1 < g < p.") - dsa._check_dsa_parameters = _override_check_dsa_parameters - class TPLinkJetStreamTelnet(TPLinkJetStreamBase): def telnet_login( @@ -494,7 +496,7 @@

                Methods

            TPLink JetStream requires you to first execute "enable" and then execute "enable-admin". @@ -813,7 +815,12 @@

            Inherited members

            Source code
            class TPLinkJetStreamSSH(TPLinkJetStreamBase):
            -    def _override_check_dsa_parameters(parameters):
            +    def __init__(self, **kwargs):
            +        dsa._check_dsa_parameters = self._override_check_dsa_parameters
            +
            +        return super().__init__(**kwargs)
            +
            +    def _override_check_dsa_parameters(self, parameters):
                     """
                     Override check_dsa_parameters from cryptography's dsa.py
             
            @@ -831,13 +838,11 @@ 

            Inherited members

            It's still not possible to remove this hack. """ - if crypto_utils.bit_length(parameters.q) not in [160, 256]: + if parameters.q.bit_length() not in [160, 256]: raise ValueError("q must be exactly 160 or 256 bits long") if not (1 < parameters.g < parameters.p): - raise ValueError("g, p don't satisfy 1 < g < p.") - - dsa._check_dsa_parameters = _override_check_dsa_parameters
            + raise ValueError("g, p don't satisfy 1 < g < p.")

            Ancestors

              diff --git a/docs/netmiko/utilities.html b/docs/netmiko/utilities.html index f60fb6700..fd8e1bfbe 100644 --- a/docs/netmiko/utilities.html +++ b/docs/netmiko/utilities.html @@ -77,6 +77,7 @@

              Module netmiko.utilities

              "extreme_vdx": "show running-config", "extreme_vsp": "show running-config", "extreme_wing": "show running-config", + "ericsson_ipos": "show configuration", "hp_comware": "display current-configuration", "huawei": "display current-configuration", "fortinet": "show full-configuration", From fe3fd7e39a876c481912c2153fd74f14c33be5b7 Mon Sep 17 00:00:00 2001 From: Kirk Byers Date: Tue, 2 Feb 2021 20:44:57 -0800 Subject: [PATCH 24/49] Yamaha telnet fix (#2135) * modify telnet default enter * Minor updates to Yamaha telnet fix * Setting default_enter back to newline * Move newline to be on the sending of 'N' Co-authored-by: Tachashi --- netmiko/yamaha/yamaha.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/netmiko/yamaha/yamaha.py b/netmiko/yamaha/yamaha.py index 650f2c7b8..666ae6208 100644 --- a/netmiko/yamaha/yamaha.py +++ b/netmiko/yamaha/yamaha.py @@ -28,7 +28,7 @@ def exit_enable_mode(self, exit_command="exit"): time.sleep(1) output = self.read_channel() if "(Y/N)" in output: - self.write_channel("N") + self.write_channel(f"N{self.default_enter}") output += self.read_until_prompt() if self.check_enable_mode(): raise ValueError("Failed to exit enable mode.") @@ -67,4 +67,7 @@ class YamahaSSH(YamahaBase): class YamahaTelnet(YamahaBase): """Yamaha Telnet driver.""" - pass + def __init__(self, *args, **kwargs): + default_enter = kwargs.get("default_enter") + kwargs["default_enter"] = "\n" if default_enter is None else default_enter + super().__init__(*args, **kwargs) From f1bf928a6862323c87c61e9ad2a8c32824aec902 Mon Sep 17 00:00:00 2001 From: Trasmontinho <53441739+Trasmontinho@users.noreply.github.com> Date: Wed, 10 Feb 2021 20:05:47 +0100 Subject: [PATCH 25/49] create an example of commands.yml for F5 (#2149) --- tests/f5_commands.yml | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 tests/f5_commands.yml diff --git a/tests/f5_commands.yml b/tests/f5_commands.yml new file mode 100644 index 000000000..6205599db --- /dev/null +++ b/tests/f5_commands.yml @@ -0,0 +1,9 @@ +f5_tmsh: + version: "show sys version" + basic: "show sys ip-address" + extended_output: "show sys version" + config: + - "modify cli preference history-size 400" # base command + - "modify cli preference history-size 500" # something you can verify has changed + config_verification: "show running-config all-properties | grep history-size" + support_commit: False From a49a420d2a3920238f9c30f59105cf1d60391d0b Mon Sep 17 00:00:00 2001 From: Trasmontinho <53441739+Trasmontinho@users.noreply.github.com> Date: Wed, 10 Feb 2021 20:07:55 +0100 Subject: [PATCH 26/49] bash file for F5 testing purpose (#2150) --- tests/test_f5.sh | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 tests/test_f5.sh diff --git a/tests/test_f5.sh b/tests/test_f5.sh new file mode 100644 index 000000000..0acae4ed8 --- /dev/null +++ b/tests/test_f5.sh @@ -0,0 +1,11 @@ +#!/bin/sh + +RETURN_CODE=0 + +# Exit on the first test failure and set RETURN_CODE = 1 +echo "Starting tests...good luck:" \ +&& py.test -v test_netmiko_show.py --test_device f5 \ +&& py.test -v test_netmiko_config.py --test_device f5 \ +|| RETURN_CODE=1 + +exit $RETURN_CODE From f0d11bf0e2878ce58581405be98188f70ad51dbd Mon Sep 17 00:00:00 2001 From: Kirk Byers Date: Wed, 10 Feb 2021 20:21:10 -0800 Subject: [PATCH 27/49] Brocade fabric os support (#2134) * Create __init__.py * Create brocade_fsos.py * Update ssh_dispatcher.py * Update utilities.py * Create test_brocade_fs.txt * Rename brocade_fsos.py to brocade_fsos_ssh.py * Rename brocade_fsos_ssh.py to brocade_fs_ssh.py * Update brocade_fs_ssh.py * Update PLATFORMS.md * Minor updates to Brocade Driver * Standardize config mode * Fixing device_type name and removing a few unneeded items Co-authored-by: DanielWeeber --- PLATFORMS.md | 1 + netmiko/brocade/__init__.py | 3 +++ netmiko/brocade/brocade_fos_ssh.py | 42 +++++++++++++++++++++++++++++ netmiko/ssh_dispatcher.py | 2 ++ netmiko/utilities.py | 1 + tests/brocade_fastiron_commands.txt | 3 --- tests/brocade_netiron_commands.txt | 3 --- 7 files changed, 49 insertions(+), 6 deletions(-) create mode 100644 netmiko/brocade/__init__.py create mode 100644 netmiko/brocade/brocade_fos_ssh.py delete mode 100644 tests/brocade_fastiron_commands.txt delete mode 100644 tests/brocade_netiron_commands.txt diff --git a/PLATFORMS.md b/PLATFORMS.md index ff3790b70..d87bee015 100644 --- a/PLATFORMS.md +++ b/PLATFORMS.md @@ -59,6 +59,7 @@ - A10 - Accedian - Aruba +- Brocade Fabric OS - Ciena SAOS - Citrix Netscaler - Cisco Telepresence diff --git a/netmiko/brocade/__init__.py b/netmiko/brocade/__init__.py new file mode 100644 index 000000000..a244ca541 --- /dev/null +++ b/netmiko/brocade/__init__.py @@ -0,0 +1,3 @@ +from netmiko.brocade.brocade_fos_ssh import BrocadeFOSSSH + +__all__ = ["BrocadeFOSSSH"] diff --git a/netmiko/brocade/brocade_fos_ssh.py b/netmiko/brocade/brocade_fos_ssh.py new file mode 100644 index 000000000..3953ef5e2 --- /dev/null +++ b/netmiko/brocade/brocade_fos_ssh.py @@ -0,0 +1,42 @@ +import time +import re +from netmiko.cisco_base_connection import CiscoSSHConnection + + +class BrocadeFOSSSH(CiscoSSHConnection): + """Brocade Fabric OS support""" + + def __init__(self, **kwargs): + if kwargs.get("default_enter") is None: + kwargs["default_enter"] = "\r" + return super().__init__(**kwargs) + + def session_preparation(self): + self._test_channel_read() + self.set_base_prompt() + + # Clear the read buffer + time.sleep(0.3 * self.global_delay_factor) + self.clear_buffer() + + def check_enable_mode(self, check_string=">"): + """No enable mode. Always return True.""" + return True + + def enable(self, cmd="", pattern="", enable_pattern=None, re_flags=re.IGNORECASE): + """No Enable Mode.""" + return "" + + def exit_enable_mode(self, exit_command=""): + """No Enable Mode.""" + return "" + + def check_config_mode(self, check_string="", pattern=""): + return True + + def config_mode(self, config_command="", pattern="", re_flags=0): + """No config mode.""" + return "" + + def exit_config_mode(self, exit_config="", pattern="#"): + return "" diff --git a/netmiko/ssh_dispatcher.py b/netmiko/ssh_dispatcher.py index 3188f9631..39f5c5c46 100755 --- a/netmiko/ssh_dispatcher.py +++ b/netmiko/ssh_dispatcher.py @@ -7,6 +7,7 @@ from netmiko.arista import AristaFileTransfer from netmiko.apresia import ApresiaAeosSSH, ApresiaAeosTelnet from netmiko.aruba import ArubaSSH +from netmiko.brocade import BrocadeFOSSSH from netmiko.broadcom import BroadcomIcosSSH from netmiko.calix import CalixB6SSH, CalixB6Telnet from netmiko.centec import CentecOSSSH, CentecOSTelnet @@ -115,6 +116,7 @@ "avaya_ers": ExtremeErsSSH, "avaya_vsp": ExtremeVspSSH, "broadcom_icos": BroadcomIcosSSH, + "brocade_fos": BrocadeFOSSSH, "brocade_fastiron": RuckusFastironSSH, "brocade_netiron": ExtremeNetironSSH, "brocade_nos": ExtremeNosSSH, diff --git a/netmiko/utilities.py b/netmiko/utilities.py index c9da0f534..fa142ebe0 100644 --- a/netmiko/utilities.py +++ b/netmiko/utilities.py @@ -41,6 +41,7 @@ # Dictionary mapping 'show run' for vendors with different command SHOW_RUN_MAPPER = { + "brocade_fos": "configShow", "juniper": "show configuration", "juniper_junos": "show configuration", "extreme": "show configuration", diff --git a/tests/brocade_fastiron_commands.txt b/tests/brocade_fastiron_commands.txt deleted file mode 100644 index d0f9bce11..000000000 --- a/tests/brocade_fastiron_commands.txt +++ /dev/null @@ -1,3 +0,0 @@ -logging buffered 4000 -logging buffered 3000 -no logging console diff --git a/tests/brocade_netiron_commands.txt b/tests/brocade_netiron_commands.txt deleted file mode 100644 index d0f9bce11..000000000 --- a/tests/brocade_netiron_commands.txt +++ /dev/null @@ -1,3 +0,0 @@ -logging buffered 4000 -logging buffered 3000 -no logging console From bcbfaf096bfbf070d6bb3d169fde8f611b389988 Mon Sep 17 00:00:00 2001 From: Kirk Byers Date: Wed, 10 Feb 2021 20:37:48 -0800 Subject: [PATCH 28/49] Allied telesis alliedware plus driver (#2136) * Add Allied Telesis AlliedWare Plus Support * Updates to allied telesis driver * Fixing Cisco regex escaping issue Co-authored-by: Mai --- PLATFORMS.md | 1 + netmiko/allied_telesis/__init__.py | 3 ++ .../allied_telesis/allied_telesis_awplus.py | 46 +++++++++++++++++++ netmiko/cisco_base_connection.py | 6 +-- netmiko/ssh_dispatcher.py | 2 + 5 files changed, 55 insertions(+), 3 deletions(-) create mode 100644 netmiko/allied_telesis/__init__.py create mode 100644 netmiko/allied_telesis/allied_telesis_awplus.py diff --git a/PLATFORMS.md b/PLATFORMS.md index d87bee015..081cbb957 100644 --- a/PLATFORMS.md +++ b/PLATFORMS.md @@ -58,6 +58,7 @@ - A10 - Accedian +- Allied Telesis AlliedWare Plus - Aruba - Brocade Fabric OS - Ciena SAOS diff --git a/netmiko/allied_telesis/__init__.py b/netmiko/allied_telesis/__init__.py new file mode 100644 index 000000000..c1041b3b2 --- /dev/null +++ b/netmiko/allied_telesis/__init__.py @@ -0,0 +1,3 @@ +from netmiko.allied_telesis.allied_telesis_awplus import AlliedTelesisAwplusSSH + +__all__ = ["AlliedTelesisAwplusSSH"] diff --git a/netmiko/allied_telesis/allied_telesis_awplus.py b/netmiko/allied_telesis/allied_telesis_awplus.py new file mode 100644 index 000000000..fec35f12f --- /dev/null +++ b/netmiko/allied_telesis/allied_telesis_awplus.py @@ -0,0 +1,46 @@ +from netmiko.cisco_base_connection import CiscoBaseConnection +import time + + +class AlliedTelesisAwplusBase(CiscoBaseConnection): + """Implement methods for interacting with Allied Telesis devices.""" + + def session_preparation(self): + """ + Prepare the session after the connection has been established. + + Disable paging (the '--more--' prompts). + Set the base prompt for interaction ('>'). + """ + """ AWPlus Configuration """ + + self.disable_paging() + self.set_base_prompt() + time.sleep(0.3 * self.global_delay_factor) + + def _enter_shell(self): + """Enter the Bourne Shell.""" + return self.send_command("start shell sh", expect_string=r"[\$#]") + + def _return_cli(self): + """Return to the Awplus CLI.""" + return self.send_command("exit", expect_string=r"[#>]") + + def exit_config_mode(self, exit_config="exit", pattern=""): + """Exit configuration mode.""" + output = "" + if self.check_config_mode(): + output = self.send_command_timing( + exit_config, strip_prompt=False, strip_command=False + ) + if "Exit with uncommitted changes?" in output: + output += self.send_command_timing( + "yes", strip_prompt=False, strip_command=False + ) + if self.check_config_mode(): + raise ValueError("Failed to exit configuration mode") + return output + + +class AlliedTelesisAwplusSSH(AlliedTelesisAwplusBase): + pass diff --git a/netmiko/cisco_base_connection.py b/netmiko/cisco_base_connection.py index 61ec7e162..9f4cef77d 100644 --- a/netmiko/cisco_base_connection.py +++ b/netmiko/cisco_base_connection.py @@ -49,13 +49,13 @@ def config_mode(self, config_command="configure terminal", pattern="", re_flags= config_command=config_command, pattern=pattern, re_flags=re_flags ) - def exit_config_mode(self, exit_config="end", pattern="#"): + def exit_config_mode(self, exit_config="end", pattern=r"\#"): """Exit from configuration mode.""" return super().exit_config_mode(exit_config=exit_config, pattern=pattern) def serial_login( self, - pri_prompt_terminator=r"#\s*$", + pri_prompt_terminator=r"\#\s*$", alt_prompt_terminator=r">\s*$", username_pattern=r"(?:user:|username|login)", pwd_pattern=r"assword", @@ -80,7 +80,7 @@ def serial_login( def telnet_login( self, - pri_prompt_terminator=r"#\s*$", + pri_prompt_terminator=r"\#\s*$", alt_prompt_terminator=r">\s*$", username_pattern=r"(?:user:|username|login|user name)", pwd_pattern=r"assword", diff --git a/netmiko/ssh_dispatcher.py b/netmiko/ssh_dispatcher.py index 39f5c5c46..5f7894d77 100755 --- a/netmiko/ssh_dispatcher.py +++ b/netmiko/ssh_dispatcher.py @@ -7,6 +7,7 @@ from netmiko.arista import AristaFileTransfer from netmiko.apresia import ApresiaAeosSSH, ApresiaAeosTelnet from netmiko.aruba import ArubaSSH +from netmiko.allied_telesis import AlliedTelesisAwplusSSH from netmiko.brocade import BrocadeFOSSSH from netmiko.broadcom import BroadcomIcosSSH from netmiko.calix import CalixB6SSH, CalixB6Telnet @@ -115,6 +116,7 @@ "aruba_procurve": HPProcurveSSH, "avaya_ers": ExtremeErsSSH, "avaya_vsp": ExtremeVspSSH, + "allied_telesis_awplus": AlliedTelesisAwplusSSH, "broadcom_icos": BroadcomIcosSSH, "brocade_fos": BrocadeFOSSSH, "brocade_fastiron": RuckusFastironSSH, From 301859030a0fd49b2d9654b1f9fb158f61580279 Mon Sep 17 00:00:00 2001 From: Kirk Byers Date: Thu, 11 Feb 2021 10:32:52 -0800 Subject: [PATCH 29/49] F5 TMOS driver update (#2153) * Update f5_tmsh_ssh.py * Fixing exit_config_mode test problem Co-authored-by: Trasmontinho <53441739+Trasmontinho@users.noreply.github.com> --- netmiko/base_connection.py | 2 ++ netmiko/f5/f5_tmsh_ssh.py | 13 +++++++++++++ tests/test_netmiko_config.py | 14 ++++++++------ 3 files changed, 23 insertions(+), 6 deletions(-) diff --git a/netmiko/base_connection.py b/netmiko/base_connection.py index 403ba3881..202a4bddb 100644 --- a/netmiko/base_connection.py +++ b/netmiko/base_connection.py @@ -220,6 +220,8 @@ def __init__( :type auto_connect: bool """ self.remote_conn = None + # Does the platform support a configuration mode + self._config_mode = True self.TELNET_RETURN = "\r\n" if default_enter is None: diff --git a/netmiko/f5/f5_tmsh_ssh.py b/netmiko/f5/f5_tmsh_ssh.py index 9885cbec9..38ec8de98 100644 --- a/netmiko/f5/f5_tmsh_ssh.py +++ b/netmiko/f5/f5_tmsh_ssh.py @@ -9,6 +9,7 @@ def session_preparation(self): self.set_base_prompt() self.tmsh_mode() self.set_base_prompt() + self._config_mode = False cmd = 'run /util bash -c "stty cols 255"' self.set_terminal_width(command=cmd, pattern="run") self.disable_paging( @@ -25,3 +26,15 @@ def tmsh_mode(self, delay_factor=1): time.sleep(1 * delay_factor) self.clear_buffer() return None + + def check_config_mode(self, check_string="", pattern=""): + """Checks if the device is in configuration mode or not.""" + return True + + def config_mode(self, config_command=""): + """No config mode for F5 devices.""" + return "" + + def exit_config_mode(self, exit_config=""): + """No config mode for F5 devices.""" + return "" diff --git a/tests/test_netmiko_config.py b/tests/test_netmiko_config.py index e8d11c6ca..51ff15c04 100755 --- a/tests/test_netmiko_config.py +++ b/tests/test_netmiko_config.py @@ -1,4 +1,5 @@ #!/usr/bin/env python +import pytest def test_ssh_connect(net_connect, commands, expected_responses): @@ -31,15 +32,16 @@ def test_config_mode(net_connect, commands, expected_responses): if net_connect.config_mode() != "": assert net_connect.check_config_mode() is True else: - assert True + pytest.skip("Platform doesn't support config mode.") def test_exit_config_mode(net_connect, commands, expected_responses): - """ - Test exit config mode - """ - net_connect.exit_config_mode() - assert net_connect.check_config_mode() is False + """Test exit config mode.""" + if net_connect._config_mode: + net_connect.exit_config_mode() + assert net_connect.check_config_mode() is False + else: + pytest.skip("Platform doesn't support config mode.") def test_config_set(net_connect, commands, expected_responses): From 0ba5e1fd3925690c78dc6a9472465b728bb3b195 Mon Sep 17 00:00:00 2001 From: 777GE90 Date: Wed, 17 Feb 2021 17:26:32 +0000 Subject: [PATCH 30/49] Added Palo Alto auto detection entry in SSH_MAPPER_BASE (#2158) Co-authored-by: Killer Kode --- netmiko/ssh_autodetect.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/netmiko/ssh_autodetect.py b/netmiko/ssh_autodetect.py index b343d5784..c94003154 100644 --- a/netmiko/ssh_autodetect.py +++ b/netmiko/ssh_autodetect.py @@ -212,6 +212,12 @@ "priority": 99, "dispatch": "_autodetect_std", }, + "paloalto_panos": { + "cmd": "show system info", + "search_patterns": [r"model:\s+PA"], + "priority": 99, + "dispatch": "_autodetect_std", + }, } # Sort SSH_MAPPER_BASE such that the most common commands are first From ee045a031d0e7573c700110e5519a4fb05ec462c Mon Sep 17 00:00:00 2001 From: Kirk Byers Date: Fri, 19 Feb 2021 11:01:56 -0800 Subject: [PATCH 31/49] Fix yamaha enter issue on exit enable mode (#2160) --- netmiko/yamaha/yamaha.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/netmiko/yamaha/yamaha.py b/netmiko/yamaha/yamaha.py index 666ae6208..69013e8fc 100644 --- a/netmiko/yamaha/yamaha.py +++ b/netmiko/yamaha/yamaha.py @@ -29,7 +29,8 @@ def exit_enable_mode(self, exit_command="exit"): output = self.read_channel() if "(Y/N)" in output: self.write_channel(f"N{self.default_enter}") - output += self.read_until_prompt() + if self.base_prompt not in output: + output += self.read_until_prompt() if self.check_enable_mode(): raise ValueError("Failed to exit enable mode.") return output From 2d716523f4d7481154c5c30c00a69972bbac38f6 Mon Sep 17 00:00:00 2001 From: Kirk Byers Date: Fri, 19 Feb 2021 11:22:30 -0800 Subject: [PATCH 32/49] Add Ericsson IPOS to platforms (#2050) --- PLATFORMS.md | 1 + 1 file changed, 1 insertion(+) diff --git a/PLATFORMS.md b/PLATFORMS.md index 081cbb957..ae2776c25 100644 --- a/PLATFORMS.md +++ b/PLATFORMS.md @@ -27,6 +27,7 @@ - Dell OS9 (Force10) - Dell OS10 - Dell PowerConnect +- Ericsson IPOS - Extreme ERS (Avaya) - Extreme VSP (Avaya) - Extreme VDX (Brocade) From d0dc0c0dc8d2a52c0c5b92d60cd1427e71878d4c Mon Sep 17 00:00:00 2001 From: Kirk Byers Date: Mon, 22 Feb 2021 11:34:26 -0800 Subject: [PATCH 33/49] Fix yamaha telnet enter issue (#2163) * Fix yamaha telnet enter issue * not an f-string --- netmiko/yamaha/yamaha.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/netmiko/yamaha/yamaha.py b/netmiko/yamaha/yamaha.py index 69013e8fc..484de7617 100644 --- a/netmiko/yamaha/yamaha.py +++ b/netmiko/yamaha/yamaha.py @@ -28,7 +28,7 @@ def exit_enable_mode(self, exit_command="exit"): time.sleep(1) output = self.read_channel() if "(Y/N)" in output: - self.write_channel(f"N{self.default_enter}") + self.write_channel("N") if self.base_prompt not in output: output += self.read_until_prompt() if self.check_enable_mode(): From 5dcabcca7aa64c1d337a704c5f7f71fc23014c60 Mon Sep 17 00:00:00 2001 From: kielpi <46385193+kielpi@users.noreply.github.com> Date: Tue, 16 Mar 2021 02:05:52 +0100 Subject: [PATCH 34/49] Nokia sros telnet (#1980) * nokia_sros_telnet driver added as a link to nokia_sros * Nokia drivers refactor to meet naming convenction Co-authored-by: Kielpinski --- netmiko/nokia/__init__.py | 8 ++++++-- .../nokia/{nokia_sros_ssh.py => nokia_sros.py} | 17 +++++++++++++++-- netmiko/ssh_dispatcher.py | 3 ++- 3 files changed, 23 insertions(+), 5 deletions(-) rename netmiko/nokia/{nokia_sros_ssh.py => nokia_sros.py} (97%) mode change 100755 => 100644 diff --git a/netmiko/nokia/__init__.py b/netmiko/nokia/__init__.py index c921cc047..41f573d2d 100755 --- a/netmiko/nokia/__init__.py +++ b/netmiko/nokia/__init__.py @@ -1,3 +1,7 @@ -from netmiko.nokia.nokia_sros_ssh import NokiaSrosSSH, NokiaSrosFileTransfer +from netmiko.nokia.nokia_sros import ( + NokiaSrosSSH, + NokiaSrosTelnet, + NokiaSrosFileTransfer, +) -__all__ = ["NokiaSrosSSH", "NokiaSrosFileTransfer"] +__all__ = ["NokiaSrosSSH", "NokiaSrosFileTransfer", "NokiaSrosTelnet"] diff --git a/netmiko/nokia/nokia_sros_ssh.py b/netmiko/nokia/nokia_sros.py old mode 100755 new mode 100644 similarity index 97% rename from netmiko/nokia/nokia_sros_ssh.py rename to netmiko/nokia/nokia_sros.py index 3a9b59ca8..c56948ad8 --- a/netmiko/nokia/nokia_sros_ssh.py +++ b/netmiko/nokia/nokia_sros.py @@ -15,9 +15,10 @@ from netmiko.scp_handler import BaseFileTransfer -class NokiaSrosSSH(BaseConnection): +class NokiaSros(BaseConnection): """ - Implement methods for interacting with Nokia SR OS devices. + Implement methods for interacting with Nokia SR OS devices + for both SSH and telnet. Not applicable in Nokia SR OS (disabled): - exit_enable_mode() @@ -217,6 +218,18 @@ def cleanup(self, command="logout"): self.write_channel(command + self.RETURN) +class NokiaSrosSSH(NokiaSros): + """Nokia SR OS SSH driver.""" + + pass + + +class NokiaSrosTelnet(NokiaSros): + """Nokia SR OS Telnet driver.""" + + pass + + class NokiaSrosFileTransfer(BaseFileTransfer): def __init__( self, ssh_conn, source_file, dest_file, hash_supported=False, **kwargs diff --git a/netmiko/ssh_dispatcher.py b/netmiko/ssh_dispatcher.py index 5f7894d77..9bd038d91 100755 --- a/netmiko/ssh_dispatcher.py +++ b/netmiko/ssh_dispatcher.py @@ -69,7 +69,7 @@ from netmiko.mrv import MrvLxSSH from netmiko.mrv import MrvOptiswitchSSH from netmiko.netapp import NetAppcDotSSH -from netmiko.nokia import NokiaSrosSSH, NokiaSrosFileTransfer +from netmiko.nokia import NokiaSrosSSH, NokiaSrosFileTransfer, NokiaSrosTelnet from netmiko.netgear import NetgearProSafeSSH from netmiko.oneaccess import OneaccessOneOSTelnet, OneaccessOneOSSSH from netmiko.ovs import OvsLinuxSSH @@ -278,6 +278,7 @@ CLASS_MAPPER["tplink_jetstream_telnet"] = TPLinkJetStreamTelnet CLASS_MAPPER["yamaha_telnet"] = YamahaTelnet CLASS_MAPPER["zte_zxros_telnet"] = ZteZxrosTelnet +CLASS_MAPPER["nokia_sros_telnet"] = NokiaSrosTelnet # Add serial drivers CLASS_MAPPER["cisco_ios_serial"] = CiscoIosSerial From 3ffb3c4ad08fe350da78889c4df2ebc16d72939d Mon Sep 17 00:00:00 2001 From: Kirk Byers Date: Mon, 15 Mar 2021 18:19:03 -0700 Subject: [PATCH 35/49] SR-OS remote file size (#2190) * SCP nokia_sros: Fix to remote_file_size() * black formatted * / instead of \\ used as a separator between file_system and dest_file Co-authored-by: Kierklo Jakub --- netmiko/nokia/nokia_sros.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/netmiko/nokia/nokia_sros.py b/netmiko/nokia/nokia_sros.py index c56948ad8..31d5149f9 100644 --- a/netmiko/nokia/nokia_sros.py +++ b/netmiko/nokia/nokia_sros.py @@ -292,10 +292,11 @@ def remote_file_size(self, remote_cmd=None, remote_file=None): if "File Not Found" in remote_out: raise IOError("Unable to find file on remote system") + dest_file_name = remote_file.replace("\\", "/").split("/")[-1] # Parse dir output for filename. Output format is: - # "10/16/2019 10:00p 6738 {filename}" + # "10/16/2019 10:00p 6738 {dest_file_name}" - pattern = r"\S+\s+\S+\s+(\d+)\s+{}".format(re.escape(remote_file)) + pattern = r"\S+\s+\S+\s+(\d+)\s+{}".format(re.escape(dest_file_name)) match = re.search(pattern, remote_out) if not match: From bf7c64db0308fe604e3a7cebe8c246bb48e45855 Mon Sep 17 00:00:00 2001 From: Kirk Byers Date: Mon, 15 Mar 2021 21:28:59 -0700 Subject: [PATCH 36/49] Fixing issue with remote_file_size parsing failure (#2191) --- netmiko/scp_handler.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/netmiko/scp_handler.py b/netmiko/scp_handler.py index 70d387333..6b4939bed 100644 --- a/netmiko/scp_handler.py +++ b/netmiko/scp_handler.py @@ -257,6 +257,9 @@ def remote_file_size(self, remote_cmd="", remote_file=None): line = match.group(0) # Format will be 26 -rw- 6738 Jul 30 2016 19:49:50 -07:00 filename file_size = line.split()[2] + else: + raise IOError("Unable to parse 'dir' output in remote_file_size method") + if "Error opening" in remote_out or "No such file or directory" in remote_out: raise IOError("Unable to find file on remote system") else: From 1d3e3ff711cc832a83741e2f8507e797c8dd2b1e Mon Sep 17 00:00:00 2001 From: Kirk Byers Date: Tue, 16 Mar 2021 14:51:06 -0700 Subject: [PATCH 37/49] Fix ASA enable() issue in session_preparation (#2182) * In cases where end-users were already in enable-mode, session_preparation would incorrectly believe you were not in enable mode (in other words check_enable_mode() would fail due to the base_prompt not being set). This would generate an exception for the end-user. * Fixes to ASA driver related to performance improvements and reliability --- netmiko/cisco/cisco_asa_ssh.py | 35 ++++++++++++++++++++-------------- 1 file changed, 21 insertions(+), 14 deletions(-) diff --git a/netmiko/cisco/cisco_asa_ssh.py b/netmiko/cisco/cisco_asa_ssh.py index 92dfc393e..544a79ed5 100644 --- a/netmiko/cisco/cisco_asa_ssh.py +++ b/netmiko/cisco/cisco_asa_ssh.py @@ -14,23 +14,16 @@ def __init__(self, *args, **kwargs): kwargs.setdefault("allow_auto_change", True) return super().__init__(*args, **kwargs) - def check_config_mode(self, check_string=")#", pattern=r"[>\#]"): - return super().check_config_mode(check_string=check_string, pattern=pattern) - - def enable( - self, - cmd="enable", - pattern="ssword", - enable_pattern=r"\#", - re_flags=re.IGNORECASE, - ): - return super().enable( - cmd=cmd, pattern=pattern, enable_pattern=enable_pattern, re_flags=re_flags - ) - def session_preparation(self): """Prepare the session after the connection has been established.""" + # Make sure the ASA is ready + command = "show curpriv\n" + self.write_channel(command) + self.read_until_pattern(pattern=re.escape(command.strip())) + + # The 'enable' call requires the base_prompt to be set. + self.set_base_prompt() if self.secret: self.enable() else: @@ -49,6 +42,20 @@ def session_preparation(self): self.set_base_prompt() + def check_config_mode(self, check_string=")#", pattern=r"[>\#]"): + return super().check_config_mode(check_string=check_string, pattern=pattern) + + def enable( + self, + cmd="enable", + pattern="ssword", + enable_pattern=r"\#", + re_flags=re.IGNORECASE, + ): + return super().enable( + cmd=cmd, pattern=pattern, enable_pattern=enable_pattern, re_flags=re_flags + ) + def send_command_timing(self, *args, **kwargs): """ If the ASA is in multi-context mode, then the base_prompt needs to be From c08c5ebb3484383f034e22b9576f88be07525f72 Mon Sep 17 00:00:00 2001 From: nikeix Date: Wed, 24 Mar 2021 18:25:08 +0200 Subject: [PATCH 38/49] Reraise original exception in set_base_prompt (#2198) (#2199) * Reraise original exception in set_base_prompt (#2198) * Reformatted code Co-authored-by: Aviv Mamon --- netmiko/base_connection.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/netmiko/base_connection.py b/netmiko/base_connection.py index 202a4bddb..110387682 100644 --- a/netmiko/base_connection.py +++ b/netmiko/base_connection.py @@ -1133,7 +1133,9 @@ def set_terminal_width( # Retry by sleeping .33 and then double sleep until 5 attempts (.33, .66, 1.32, etc) @retry( - wait=wait_exponential(multiplier=0.33, min=0, max=5), stop=stop_after_attempt(5) + wait=wait_exponential(multiplier=0.33, min=0, max=5), + stop=stop_after_attempt(5), + reraise=True, ) def set_base_prompt( self, pri_prompt_terminator="#", alt_prompt_terminator=">", delay_factor=1 From 66d4d33a6f9d02e2ed2ae99d18b93c7a0d94bb2a Mon Sep 17 00:00:00 2001 From: dmulyalin Date: Sun, 11 Apr 2021 04:21:56 +1000 Subject: [PATCH 39/49] Add run_ttp method to base connection (#2208) * added run_ttp_method to base connection, added tests * added test for errored template * blacked test_ttp_run_template one more time * run black and pylama against the new code * run black -> pylama again --- netmiko/base_connection.py | 36 ++ netmiko/utilities.py | 68 ++++ tests/test_ttp_run_template.py | 560 ++++++++++++++++++++++++++++++ tests/test_ttp_run_template_1.txt | 24 ++ 4 files changed, 688 insertions(+) create mode 100644 tests/test_ttp_run_template.py create mode 100644 tests/test_ttp_run_template_1.txt diff --git a/netmiko/base_connection.py b/netmiko/base_connection.py index 110387682..24e00d3e2 100644 --- a/netmiko/base_connection.py +++ b/netmiko/base_connection.py @@ -31,6 +31,7 @@ get_structured_data, get_structured_data_genie, get_structured_data_ttp, + run_ttp_template, select_cmd_verify, ) from netmiko.utilities import m_exec_time # noqa @@ -2040,6 +2041,41 @@ def close_session_log(self): self.session_log.close() self.session_log = None + def run_ttp(self, template, res_kwargs={}, **kwargs): + """ + Run TTP template parsing by using input parameters to collect + devices output. + + :param template: template content, OS path to template or reference + to template within TTP templates collection in + ttp://path/to/template.txt format + :type template: str + + :param res_kwargs: ``**res_kwargs`` arguments to pass to TTP result method + :type res_kwargs: dict + + :param kwargs: any other ``**kwargs`` to use for TTP object instantiation + :type kwargs: dict + + TTP template must have inputs defined together with below parameters. + + :param method: name of Netmiko connection object method to call, default ``send_command`` + :type method: str + + :param kwargs: Netmiko connection object method arguments + :type kwargs: dict + + :param commands: list of commands to collect + :type commands: list + + Inputs' load could be of one of the supported formats and controlled by input's ``load`` + attribute, supported values - python, yaml or json. For each input output collected + from device and parsed accordingly. + """ + return run_ttp_template( + connection=self, template=template, res_kwargs=res_kwargs, **kwargs + ) + class TelnetConnection(BaseConnection): pass diff --git a/netmiko/utilities.py b/netmiko/utilities.py index fa142ebe0..0b9bfb9a9 100644 --- a/netmiko/utilities.py +++ b/netmiko/utilities.py @@ -8,6 +8,7 @@ from datetime import datetime from netmiko._textfsm import _clitable as clitable from netmiko._textfsm._clitable import CliTableError +from netmiko import log try: from ttp import ttp @@ -373,6 +374,73 @@ def get_structured_data_ttp(raw_output, template=None): return raw_output +def run_ttp_template(connection, template, res_kwargs, **kwargs): + """ + Helper function to run TTP template parsing. + + :param connection: Netmiko connection object + :type connection: obj + + :param template: TTP template + :type template: str + + :param res_kwargs: ``**res_kwargs`` arguments for TTP result method + :type res_kwargs: dict + + :param kwargs: ``**kwargs`` for TTP object instantiation + :type kwargs: dict + """ + if not TTP_INSTALLED: + msg = "\nTTP is not installed. Please PIP install ttp:\n" "pip install ttp\n" + raise ValueError(msg) + + parser = ttp(template=template, **kwargs) + + # get inputs load for TTP template + ttp_inputs_load = parser.get_input_load() + log.debug("run_ttp_template: inputs load - {}".format(ttp_inputs_load)) + + # go over template's inputs and collect output from devices + for template_name, inputs in ttp_inputs_load.items(): + for input_name, input_params in inputs.items(): + method = input_params.get("method", "send_command") + method_kwargs = input_params.get("kwargs", {}) + commands = input_params.get("commands", None) + + # run sanity checks + if method not in dir(connection): + log.warning( + "run_ttp_template: '{}' input, unsupported method '{}', skipping".format( + input_name, method + ) + ) + continue + elif not commands: + log.warning( + "run_ttp_template: '{}' input no commands to collect, skipping".format( + input_name + ) + ) + continue + + # collect commands output from device + output = [ + getattr(connection, method)(command_string=command, **method_kwargs) + for command in commands + ] + output = "\n".join(output) + + # add collected output to TTP parser object + parser.add_input( + data=output, input_name=input_name, template_name=template_name + ) + + # run parsing in single process + parser.parse(one=True) + + return parser.result(**res_kwargs) + + def get_structured_data_genie(raw_output, platform, command): if not sys.version_info >= (3, 4): raise ValueError("Genie requires Python >= 3.4") diff --git a/tests/test_ttp_run_template.py b/tests/test_ttp_run_template.py new file mode 100644 index 000000000..a05da55e5 --- /dev/null +++ b/tests/test_ttp_run_template.py @@ -0,0 +1,560 @@ +import sys +import pytest + +sys.path.insert(0, "..") # need it to run "python test_ttp_run_template.py" + +from netmiko import ConnectHandler # noqa + +try: + from ttp import ttp # noqa + + TTP_INSTALLED = True + +except ImportError: + TTP_INSTALLED = False + +try: + from ttp_templates import get_template # noqa + + TTP_TEMPLATES_INSTALLED = True + +except ImportError: + TTP_TEMPLATES_INSTALLED = False + +skip_if_no_ttp = pytest.mark.skipif( + TTP_INSTALLED is False, reason="Failed to import TTP module" +) +skip_if_no_ttp_templates = pytest.mark.skipif( + TTP_TEMPLATES_INSTALLED is False, reason="Failed to import TTP templates module" +) + +lab = { + "device_type": "cisco_ios", + "host": "1.2.3.4", + "username": "cisco", + "password": "cisco", + "auto_connect": False, # stop Netmiko trying connect to device +} + + +@skip_if_no_ttp +def mock_output(command_string, *args, **kwargs): + outputs = { + "show run | inc ntp": """ +ntp server 8.8.8.8 +ntp server 7.7.7.8 +ntp server 1.1.1.2 +ntp server 3.3.3.3 +ntp server 7.7.7.7 + """, + "show run | inc aaa": """ +aaa new-model +aaa authentication login default local +aaa authorization exec default local +aaa session-id common + """, + "show run | sec interface": """ +interface Loopback0 + description Routing Loopback + ip address 10.0.0.10 255.255.255.255 + ip ospf 1 area 0 + ipv6 address 2001::10/128 +interface Loopback100 + ip address 1.1.1.100 255.255.255.255 +interface Ethernet0/0 + description Main Interface for L3 features testing + no ip address + duplex auto +interface Ethernet0/0.102 + description to_vIOS1_Gi0/0.102 + encapsulation dot1Q 102 + ip address 10.1.102.10 255.255.255.0 + ipv6 address 2001:102::10/64 +interface Ethernet0/0.107 + description to_IOL2_Eth0/0.107 + encapsulation dot1Q 107 + ip address 10.1.107.10 255.255.255.0 + ip ospf network point-to-point + ip ospf 1 area 0 + ipv6 address 2001:107::10/64 +interface Ethernet0/0.2000 + encapsulation dot1Q 2000 + vrf forwarding MGMT + ip address 192.168.217.10 255.255.255.0 +interface Ethernet0/1 + no ip address + duplex auto +interface Ethernet0/2 + no ip address + duplex auto +interface Ethernet0/3 + no ip address + shutdown + duplex auto + """, + } + return outputs[command_string] + + +connection = ConnectHandler(**lab) + +# override send command method to return mock data +setattr(connection, "send_command", mock_output) + + +@skip_if_no_ttp +def test_run_ttp_template_from_text(): + template = """ + +commands: + - show run | inc ntp + - show run | inc aaa + + + +commands = [ + "show run | sec interface" +] + + + +ntp server {{ ntp_servers | joinmatches(",") }} +aaa authentication login {{ authen | PHRASE }} +aaa authorization exec {{ author_exec | PHRASE }} + + + +interface {{ interface }} + description {{ description | re(".+") }} + encapsulation dot1Q {{ dot1q }} + ip address {{ ip }} {{ mask }} + + """ + res = connection.run_ttp(template) + assert res == [ + [ + { + "misc": [ + {"ntp_servers": "8.8.8.8"}, + {"ntp_servers": "7.7.7.8"}, + {"ntp_servers": "1.1.1.2"}, + {"ntp_servers": "3.3.3.3"}, + { + "authen": "default local", + "author_exec": "default local", + "ntp_servers": "7.7.7.7", + }, + ] + }, + { + "interfaces": [ + { + "description": "Routing Loopback", + "interface": "Loopback0", + "ip": "10.0.0.10", + "mask": "255.255.255.255", + }, + { + "interface": "Loopback100", + "ip": "1.1.1.100", + "mask": "255.255.255.255", + }, + { + "description": "Main Interface for L3 features testing", + "interface": "Ethernet0/0", + }, + { + "description": "to_vIOS1_Gi0/0.102", + "dot1q": "102", + "interface": "Ethernet0/0.102", + "ip": "10.1.102.10", + "mask": "255.255.255.0", + }, + { + "description": "to_IOL2_Eth0/0.107", + "dot1q": "107", + "interface": "Ethernet0/0.107", + "ip": "10.1.107.10", + "mask": "255.255.255.0", + }, + { + "dot1q": "2000", + "interface": "Ethernet0/0.2000", + "ip": "192.168.217.10", + "mask": "255.255.255.0", + }, + {"interface": "Ethernet0/1"}, + {"interface": "Ethernet0/2"}, + {"interface": "Ethernet0/3"}, + ] + }, + ] + ] + + +@skip_if_no_ttp +def test_run_ttp_template_from_text_with_res_kwargs(): + template = """ + +commands: + - show run | inc ntp + - show run | inc aaa + + + +commands = [ + "show run | sec interface" +] + + + +ntp server {{ ntp_servers | joinmatches(",") }} +aaa authentication login {{ authen | PHRASE }} +aaa authorization exec {{ author_exec | PHRASE }} + + + +interface {{ interface }} + description {{ description | re(".+") }} + encapsulation dot1Q {{ dot1q }} + ip address {{ ip }} {{ mask }} + + """ + res = connection.run_ttp(template, res_kwargs={"structure": "flat_list"}) + assert res == [ + { + "misc": [ + {"ntp_servers": "8.8.8.8"}, + {"ntp_servers": "7.7.7.8"}, + {"ntp_servers": "1.1.1.2"}, + {"ntp_servers": "3.3.3.3"}, + { + "authen": "default local", + "author_exec": "default local", + "ntp_servers": "7.7.7.7", + }, + ] + }, + { + "interfaces": [ + { + "description": "Routing Loopback", + "interface": "Loopback0", + "ip": "10.0.0.10", + "mask": "255.255.255.255", + }, + { + "interface": "Loopback100", + "ip": "1.1.1.100", + "mask": "255.255.255.255", + }, + { + "description": "Main Interface for L3 features testing", + "interface": "Ethernet0/0", + }, + { + "description": "to_vIOS1_Gi0/0.102", + "dot1q": "102", + "interface": "Ethernet0/0.102", + "ip": "10.1.102.10", + "mask": "255.255.255.0", + }, + { + "description": "to_IOL2_Eth0/0.107", + "dot1q": "107", + "interface": "Ethernet0/0.107", + "ip": "10.1.107.10", + "mask": "255.255.255.0", + }, + { + "dot1q": "2000", + "interface": "Ethernet0/0.2000", + "ip": "192.168.217.10", + "mask": "255.255.255.0", + }, + {"interface": "Ethernet0/1"}, + {"interface": "Ethernet0/2"}, + {"interface": "Ethernet0/3"}, + ] + }, + ] + + +@skip_if_no_ttp +def test_run_ttp_template_from_file(): + template = "./test_ttp_run_template_1.txt" + res = connection.run_ttp(template) + assert res == [ + [ + { + "misc": [ + {"ntp_servers": "8.8.8.8"}, + {"ntp_servers": "7.7.7.8"}, + {"ntp_servers": "1.1.1.2"}, + {"ntp_servers": "3.3.3.3"}, + { + "authen": "default local", + "author_exec": "default local", + "ntp_servers": "7.7.7.7", + }, + ] + }, + { + "interfaces": [ + { + "description": "Routing Loopback", + "interface": "Loopback0", + "ip": "10.0.0.10", + "mask": "255.255.255.255", + }, + { + "interface": "Loopback100", + "ip": "1.1.1.100", + "mask": "255.255.255.255", + }, + { + "description": "Main Interface for L3 features testing", + "interface": "Ethernet0/0", + }, + { + "description": "to_vIOS1_Gi0/0.102", + "dot1q": "102", + "interface": "Ethernet0/0.102", + "ip": "10.1.102.10", + "mask": "255.255.255.0", + }, + { + "description": "to_IOL2_Eth0/0.107", + "dot1q": "107", + "interface": "Ethernet0/0.107", + "ip": "10.1.107.10", + "mask": "255.255.255.0", + }, + { + "dot1q": "2000", + "interface": "Ethernet0/0.2000", + "ip": "192.168.217.10", + "mask": "255.255.255.0", + }, + {"interface": "Ethernet0/1"}, + {"interface": "Ethernet0/2"}, + {"interface": "Ethernet0/3"}, + ] + }, + ] + ] + + +@skip_if_no_ttp +@skip_if_no_ttp_templates +def test_run_ttp_template_from_ttp_templates(): + template = "ttp://misc/ttp_templates_tests/netmiko_cisco_ios_interfaces.txt" + res = connection.run_ttp(template) + assert res == [ + { + "intf_cfg": [ + { + "description": "Routing Loopback", + "interface": "Loopback0", + "ip": "10.0.0.10", + "mask": "255.255.255.255", + }, + { + "interface": "Loopback100", + "ip": "1.1.1.100", + "mask": "255.255.255.255", + }, + { + "description": "Main Interface for L3 features testing", + "interface": "Ethernet0/0", + }, + { + "description": "to_vIOS1_Gi0/0.102", + "interface": "Ethernet0/0.102", + "ip": "10.1.102.10", + "mask": "255.255.255.0", + }, + { + "description": "to_IOL2_Eth0/0.107", + "interface": "Ethernet0/0.107", + "ip": "10.1.107.10", + "mask": "255.255.255.0", + }, + { + "interface": "Ethernet0/0.2000", + "ip": "192.168.217.10", + "mask": "255.255.255.0", + }, + {"interface": "Ethernet0/1"}, + {"interface": "Ethernet0/2"}, + {"interface": "Ethernet0/3"}, + ] + } + ] + + +@skip_if_no_ttp +def test_run_ttp_template_default_input(): + template = """ + +This template used in to test Netmiko run_ttp method + + + + """ + res = connection.run_ttp(template) + assert res == [ + { + "intf_cfg": [ + { + "description": "Routing Loopback", + "interface": "Loopback0", + "ip": "10.0.0.10", + "mask": "255.255.255.255", + }, + { + "interface": "Loopback100", + "ip": "1.1.1.100", + "mask": "255.255.255.255", + }, + { + "description": "Main Interface for L3 features testing", + "interface": "Ethernet0/0", + }, + { + "description": "to_vIOS1_Gi0/0.102", + "interface": "Ethernet0/0.102", + "ip": "10.1.102.10", + "mask": "255.255.255.0", + }, + { + "description": "to_IOL2_Eth0/0.107", + "interface": "Ethernet0/0.107", + "ip": "10.1.107.10", + "mask": "255.255.255.0", + }, + { + "interface": "Ethernet0/0.2000", + "ip": "192.168.217.10", + "mask": "255.255.255.0", + }, + {"interface": "Ethernet0/1"}, + {"interface": "Ethernet0/2"}, + {"interface": "Ethernet0/3"}, + ] + } + ] + + +@skip_if_no_ttp +def test_run_ttp_template_dict_struct(): + template = """ + +This template used in to test Netmiko run_ttp method + + + + """ + res = connection.run_ttp(template, res_kwargs={"structure": "dictionary"}) + assert res == { + "interfaces": { + "intf_cfg": [ + { + "description": "Routing Loopback", + "interface": "Loopback0", + "ip": "10.0.0.10", + "mask": "255.255.255.255", + }, + { + "interface": "Loopback100", + "ip": "1.1.1.100", + "mask": "255.255.255.255", + }, + { + "description": "Main Interface for L3 features " "testing", + "interface": "Ethernet0/0", + }, + { + "description": "to_vIOS1_Gi0/0.102", + "interface": "Ethernet0/0.102", + "ip": "10.1.102.10", + "mask": "255.255.255.0", + }, + { + "description": "to_IOL2_Eth0/0.107", + "interface": "Ethernet0/0.107", + "ip": "10.1.107.10", + "mask": "255.255.255.0", + }, + { + "interface": "Ethernet0/0.2000", + "ip": "192.168.217.10", + "mask": "255.255.255.0", + }, + {"interface": "Ethernet0/1"}, + {"interface": "Ethernet0/2"}, + {"interface": "Ethernet0/3"}, + ] + } + } + + +@skip_if_no_ttp +def test_run_ttp_template_with_errors(): + """ + Input ntp_and_aaa does not have command parameter. + Input interfaces_cfg has wrong method. + """ + template = """ + +commmmmands: + - show run | inc ntp + - show run | inc aaa + + + +method = "does_not_exist" +commands = [ + "show run | sec interface" +] + + + +ntp server {{ ntp_servers | joinmatches(",") }} +aaa authentication login {{ authen | PHRASE }} +aaa authorization exec {{ author_exec | PHRASE }} + + + +interface {{ interface }} + description {{ description | re(".+") }} + encapsulation dot1Q {{ dot1q }} + ip address {{ ip }} {{ mask }} + + """ + res = connection.run_ttp(template) + assert res == [[]] diff --git a/tests/test_ttp_run_template_1.txt b/tests/test_ttp_run_template_1.txt new file mode 100644 index 000000000..2e9b799b2 --- /dev/null +++ b/tests/test_ttp_run_template_1.txt @@ -0,0 +1,24 @@ + +commands: + - show run | inc ntp + - show run | inc aaa + + + +commands = [ + "show run | sec interface" +] + + + +ntp server {{ ntp_servers | joinmatches(",") }} +aaa authentication login {{ authen | PHRASE }} +aaa authorization exec {{ author_exec | PHRASE }} + + + +interface {{ interface }} + description {{ description | re(".+") }} + encapsulation dot1Q {{ dot1q }} + ip address {{ ip }} {{ mask }} + \ No newline at end of file From 9961640042e21bad1bfc9ec852e0517cc610dad3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 10 Apr 2021 11:27:51 -0700 Subject: [PATCH 40/49] Bump pyyaml from 5.3.1 to 5.4 (#2202) Bumps [pyyaml](https://github.com/yaml/pyyaml) from 5.3.1 to 5.4. - [Release notes](https://github.com/yaml/pyyaml/releases) - [Changelog](https://github.com/yaml/pyyaml/blob/master/CHANGES) - [Commits](https://github.com/yaml/pyyaml/compare/5.3.1...5.4) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- requirements-dev.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-dev.txt b/requirements-dev.txt index 85ea63a32..ded8934e9 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -1,5 +1,5 @@ black==18.9b0 -PyYAML==5.3.1 +PyYAML==5.4 pytest==5.1.2 pylama==7.7.1 twine==1.13.0 From 84c6c3c296d159be42f29725390b029e8286933a Mon Sep 17 00:00:00 2001 From: Kirk Byers Date: Mon, 12 Apr 2021 21:37:43 -0700 Subject: [PATCH 41/49] Fix XR exit_config_mode issue (#2218) Co-authored-by: Adam Rootes --- netmiko/cisco/cisco_xr.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/netmiko/cisco/cisco_xr.py b/netmiko/cisco/cisco_xr.py index 8978aa842..636a92f6e 100644 --- a/netmiko/cisco/cisco_xr.py +++ b/netmiko/cisco/cisco_xr.py @@ -136,6 +136,9 @@ def exit_config_mode(self, exit_config="end", pattern=""): output += self.read_until_pattern( pattern=re.escape(exit_config.strip()) ) + # Read until we detect either an Uncommitted change or the end prompt + if not re.search(r"(Uncommitted|#$)", output): + output += self.read_until_pattern(pattern=r"(Uncommitted|#$)") if "Uncommitted changes found" in output: self.write_channel(self.normalize_cmd("no\n")) output += self.read_until_pattern(pattern=r"[>#]") From ab3b07298012e1d8480a598c44748aea45206d0c Mon Sep 17 00:00:00 2001 From: Kirk Byers Date: Tue, 13 Apr 2021 09:58:24 -0700 Subject: [PATCH 42/49] Fixing some enable method state issues (#2220) * Fixing some enable state issues * enable method state issues --- netmiko/base_connection.py | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/netmiko/base_connection.py b/netmiko/base_connection.py index 24e00d3e2..25aca0280 100644 --- a/netmiko/base_connection.py +++ b/netmiko/base_connection.py @@ -1676,19 +1676,32 @@ def enable( "Failed to enter enable mode. Please ensure you pass " "the 'secret' argument to ConnectHandler." ) + + # Check if in enable mode if not self.check_enable_mode(): + # Send "enable" mode command self.write_channel(self.normalize_cmd(cmd)) try: - output += self.read_until_pattern(pattern=re.escape(cmd.strip())) - if pattern not in output: + # Read the command echo + end_data = "" + if self.global_cmd_verify is not False: + output += self.read_until_pattern(pattern=re.escape(cmd.strip())) + end_data = output.split(cmd.strip())[-1] + + # Search for trailing prompt or password pattern + if pattern not in output and self.base_prompt not in end_data: output += self.read_until_prompt_or_pattern( pattern=pattern, re_flags=re_flags ) - self.write_channel(self.normalize_cmd(self.secret)) - if enable_pattern: + # Send the "secret" in response to password pattern + if re.search(pattern, output): + self.write_channel(self.normalize_cmd(self.secret)) + output += self.read_until_prompt() + + # Search for terminating pattern if defined + if enable_pattern and not re.search(enable_pattern, output): output += self.read_until_pattern(pattern=enable_pattern) else: - output += self.read_until_prompt() if not self.check_enable_mode(): raise ValueError(msg) except NetmikoTimeoutException: From 14017fcc6da1539d713f37aa6919f98db1f72502 Mon Sep 17 00:00:00 2001 From: Kirk Byers Date: Tue, 13 Apr 2021 10:46:59 -0700 Subject: [PATCH 43/49] C-DOT CROS updated driver (#2222) Signed-off-by: Maloy Ghosh Co-authored-by: Maloy Ghosh --- PLATFORMS.md | 1 + netmiko/cdot/__init__.py | 3 + netmiko/cdot/cdot_cros_ssh.py | 104 ++++++++++++++++++++++++++++++++++ netmiko/ssh_dispatcher.py | 6 +- netmiko/utilities.py | 1 + tests/test_cros_mtbr.py | 42 ++++++++++++++ 6 files changed, 155 insertions(+), 2 deletions(-) create mode 100644 netmiko/cdot/__init__.py create mode 100644 netmiko/cdot/cdot_cros_ssh.py create mode 100755 tests/test_cros_mtbr.py diff --git a/PLATFORMS.md b/PLATFORMS.md index ae2776c25..af5e5d793 100644 --- a/PLATFORMS.md +++ b/PLATFORMS.md @@ -62,6 +62,7 @@ - Allied Telesis AlliedWare Plus - Aruba - Brocade Fabric OS +- C-DOT CROS - Ciena SAOS - Citrix Netscaler - Cisco Telepresence diff --git a/netmiko/cdot/__init__.py b/netmiko/cdot/__init__.py new file mode 100644 index 000000000..199ab7c9e --- /dev/null +++ b/netmiko/cdot/__init__.py @@ -0,0 +1,3 @@ +from netmiko.cdot.cdot_cros_ssh import CdotCrosSSH + +__all__ = ["CdotCrosSSH"] diff --git a/netmiko/cdot/cdot_cros_ssh.py b/netmiko/cdot/cdot_cros_ssh.py new file mode 100644 index 000000000..136be5ff7 --- /dev/null +++ b/netmiko/cdot/cdot_cros_ssh.py @@ -0,0 +1,104 @@ +#!/usr/bin/env python +# CDOT = Centre for Development of Telematics, India +# CROS = CDOT Router OS +# Script: cros_ssh.py +# Author: Maloy Ghosh +# +# Purpose: Provide basic SSH connection to CROS based router products + +from netmiko.cisco_base_connection import CiscoBaseConnection +import time + + +class CdotCrosSSH(CiscoBaseConnection): + """Implement methods for interacting with CROS network devices.""" + + def session_preparation(self): + """Prepare the session after the connection has been established.""" + self._test_channel_read() + self.set_base_prompt() + self._disable_complete_on_space() + self.disable_paging(command="screen-length 0") + self.set_terminal_width(command="screen-width 511") + time.sleep(0.3 * self.global_delay_factor) + self.clear_buffer() + return + + def send_config_set(self, config_commands=None, exit_config_mode=False, **kwargs): + """CROS requires you not exit from configuration mode.""" + return super().send_config_set( + config_commands=config_commands, exit_config_mode=exit_config_mode, **kwargs + ) + + def check_config_mode(self, check_string=")#", pattern=r"[#\$]"): + """Checks if device is in configuration mode""" + return super().check_config_mode(check_string=check_string, pattern=pattern) + + def config_mode(self, config_command="config", pattern=""): + """Enter configuration mode.""" + return super().config_mode(config_command=config_command, pattern=pattern) + + def commit(self, comment="", delay_factor=1, and_quit=True): + """ + Commit the candidate configuration. + + Commit the entered configuration. Raise an error and return the failure + if the commit fails. + + default: + command_string = commit + comment: + command_string = commit comment + + """ + + delay_factor = self.select_delay_factor(delay_factor) + + command_string = "commit" + commit_marker = ["Commit complete", "No modifications to commit"] + + if comment: + if '"' in comment: + raise ValueError("Invalid comment contains double quote") + command_string += f' comment "{comment}"' + + output = self.config_mode() + output += self.send_command( + command_string, + strip_prompt=False, + strip_command=True, + delay_factor=delay_factor, + ) + + if not (any(x in output for x in commit_marker)): + raise ValueError(f"Commit failed with the following errors:\n\n{output}") + if and_quit: + self.exit_config_mode() + return output + + def check_enable_mode(self, *args, **kwargs): + """No enable mode on CROS.""" + return True + + def enable(self, *args, **kwargs): + """No enable mode on CROS.""" + return "" + + def exit_enable_mode(self, *args, **kwargs): + """No enable mode on CROS.""" + return "" + + def _disable_complete_on_space(self): + """ + CROS tries to auto complete commands when you type a "space" character. + + This is a bad idea for automation as what your program is sending no longer matches + the command echo from the device. So we disable this behavior. + """ + delay_factor = self.select_delay_factor(delay_factor=0) + time.sleep(delay_factor * 0.1) + command = "complete-on-space false" + self.write_channel(self.normalize_cmd(command)) + time.sleep(delay_factor * 0.1) + output = self.read_channel() + return output diff --git a/netmiko/ssh_dispatcher.py b/netmiko/ssh_dispatcher.py index 9bd038d91..d53213194 100755 --- a/netmiko/ssh_dispatcher.py +++ b/netmiko/ssh_dispatcher.py @@ -3,14 +3,15 @@ from netmiko.accedian import AccedianSSH from netmiko.adtran import AdtranOSSSH, AdtranOSTelnet from netmiko.alcatel import AlcatelAosSSH +from netmiko.allied_telesis import AlliedTelesisAwplusSSH from netmiko.arista import AristaSSH, AristaTelnet from netmiko.arista import AristaFileTransfer from netmiko.apresia import ApresiaAeosSSH, ApresiaAeosTelnet from netmiko.aruba import ArubaSSH -from netmiko.allied_telesis import AlliedTelesisAwplusSSH from netmiko.brocade import BrocadeFOSSSH from netmiko.broadcom import BroadcomIcosSSH from netmiko.calix import CalixB6SSH, CalixB6Telnet +from netmiko.cdot import CdotCrosSSH from netmiko.centec import CentecOSSSH, CentecOSTelnet from netmiko.checkpoint import CheckPointGaiaSSH from netmiko.ciena import CienaSaosSSH, CienaSaosTelnet, CienaSaosFileTransfer @@ -109,6 +110,7 @@ "adtran_os": AdtranOSSSH, "alcatel_aos": AlcatelAosSSH, "alcatel_sros": NokiaSrosSSH, + "allied_telesis_awplus": AlliedTelesisAwplusSSH, "apresia_aeos": ApresiaAeosSSH, "arista_eos": AristaSSH, "aruba_os": ArubaSSH, @@ -116,7 +118,6 @@ "aruba_procurve": HPProcurveSSH, "avaya_ers": ExtremeErsSSH, "avaya_vsp": ExtremeVspSSH, - "allied_telesis_awplus": AlliedTelesisAwplusSSH, "broadcom_icos": BroadcomIcosSSH, "brocade_fos": BrocadeFOSSSH, "brocade_fastiron": RuckusFastironSSH, @@ -126,6 +127,7 @@ "brocade_vyos": VyOSSSH, "checkpoint_gaia": CheckPointGaiaSSH, "calix_b6": CalixB6SSH, + "cdot_cros": CdotCrosSSH, "centec_os": CentecOSSSH, "ciena_saos": CienaSaosSSH, "cisco_asa": CiscoAsaSSH, diff --git a/netmiko/utilities.py b/netmiko/utilities.py index 0b9bfb9a9..1d3b2acaa 100644 --- a/netmiko/utilities.py +++ b/netmiko/utilities.py @@ -69,6 +69,7 @@ "brocade_fastiron": "show running-config", "brocade_netiron": "show running-config", "alcatel_aos": "show configuration snapshot", + "cros_mtbr": "show running-config", } # Expand SHOW_RUN_MAPPER to include '_ssh' key diff --git a/tests/test_cros_mtbr.py b/tests/test_cros_mtbr.py new file mode 100755 index 000000000..e3f48b801 --- /dev/null +++ b/tests/test_cros_mtbr.py @@ -0,0 +1,42 @@ +#!/usr/bin/env python + +# Script: test_cros_mtbr.py +# Author: Maloy Ghosh +# +# Purpose: + +from netmiko import ConnectHandler + + +cros = { + "device_type": "cros_mtbr", + "host": "10.0.3.3", + "username": "rootsystem", + "password": "Root@123", +} + + +def main(): + nc = ConnectHandler(**cros) + + output = nc.send_command("show interface configuration brief") + print(output) + + output = nc.send_config_set( + [ + "interface physical 7/1/3", + "admin-status up", + "ipv4 address 1.1.1.1 prefix 24", + ] + ) + print(output) + + output = nc.commit() + print(output) + + output = nc.send_command("show interface configuration brief") + print(output) + + +if __name__ == "__main__": + main() From ca64e84281e4ccae18c82178a13448134347519a Mon Sep 17 00:00:00 2001 From: Kirk Byers Date: Tue, 13 Apr 2021 11:01:08 -0700 Subject: [PATCH 44/49] Fixing PA line repaint issue (#2223) --- netmiko/paloalto/paloalto_panos.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/netmiko/paloalto/paloalto_panos.py b/netmiko/paloalto/paloalto_panos.py index 4676b1b5b..3cb935c99 100644 --- a/netmiko/paloalto/paloalto_panos.py +++ b/netmiko/paloalto/paloalto_panos.py @@ -18,9 +18,11 @@ def session_preparation(self): Disable paging (the '--more--' prompts). Set the base prompt for interaction ('>'). """ + self.ansi_escape_codes = True self._test_channel_read() self.set_base_prompt(delay_factor=20) self.disable_paging(command="set cli pager off") + self.disable_paging(command="set cli scripting-mode on") # Clear the read buffer time.sleep(0.3 * self.global_delay_factor) self.clear_buffer() From b636ed902c2f31df2c3c9046ae43d0593271a896 Mon Sep 17 00:00:00 2001 From: Kirk Byers Date: Tue, 13 Apr 2021 15:16:00 -0700 Subject: [PATCH 45/49] Fixing F5 TMSH disconnect process (#2225) --- netmiko/f5/f5_tmsh_ssh.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/netmiko/f5/f5_tmsh_ssh.py b/netmiko/f5/f5_tmsh_ssh.py index 38ec8de98..ad6975ecb 100644 --- a/netmiko/f5/f5_tmsh_ssh.py +++ b/netmiko/f5/f5_tmsh_ssh.py @@ -27,6 +27,22 @@ def tmsh_mode(self, delay_factor=1): self.clear_buffer() return None + def exit_tmsh(self): + output = self.send_command("quit", expect_string=r"#") + self.set_base_prompt() + return output + + def cleanup(self, command="exit"): + """Gracefully exit the SSH session.""" + try: + self.exit_tmsh() + except Exception: + pass + + # Always try to send final 'exit' (command) + self._session_log_fin = True + self.write_channel(command + self.RETURN) + def check_config_mode(self, check_string="", pattern=""): """Checks if the device is in configuration mode or not.""" return True From 4cfd6e7ff6679d394b77abecb91859f934d01e2d Mon Sep 17 00:00:00 2001 From: Kirk Byers Date: Wed, 14 Apr 2021 09:51:19 -0700 Subject: [PATCH 46/49] Netiron improvements (#2226) * Add MLX token to autodetect pattern, add extreme_netiron platform autodetect section * extreme_netiron platform require disable paging command while session open * Code style changes for linting pass * Consolidate extreme and brocade to extreme in autodetect for netiron Co-authored-by: Eugene Peregudov --- netmiko/extreme/extreme_netiron.py | 12 ++++++++++++ netmiko/ssh_autodetect.py | 4 ++-- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/netmiko/extreme/extreme_netiron.py b/netmiko/extreme/extreme_netiron.py index b12a5ac9b..c075d228b 100644 --- a/netmiko/extreme/extreme_netiron.py +++ b/netmiko/extreme/extreme_netiron.py @@ -1,3 +1,4 @@ +import time from netmiko.cisco_base_connection import CiscoSSHConnection @@ -8,6 +9,17 @@ def save_config(self, cmd="write memory", confirm=False, confirm_response=""): cmd=cmd, confirm=confirm, confirm_response=confirm_response ) + def session_preparation(self): + """Prepare the session after the connection has been established.""" + self._test_channel_read() + self.set_base_prompt() + self.disable_paging(command="skip-page-display") + self.set_terminal_width() + + # Clear the read buffer + time.sleep(0.3 * self.global_delay_factor) + self.clear_buffer() + class ExtremeNetironSSH(ExtremeNetironBase): pass diff --git a/netmiko/ssh_autodetect.py b/netmiko/ssh_autodetect.py index c94003154..9e449e279 100644 --- a/netmiko/ssh_autodetect.py +++ b/netmiko/ssh_autodetect.py @@ -170,9 +170,9 @@ "priority": 99, "dispatch": "_autodetect_std", }, - "brocade_netiron": { + "extreme_netiron": { "cmd": "show version", - "search_patterns": [r"NetIron"], + "search_patterns": [r"(NetIron|MLX)"], "priority": 99, "dispatch": "_autodetect_std", }, From 353db2dc92264cdbfef5fcaeb8bc80862fe8a23d Mon Sep 17 00:00:00 2001 From: Kirk Byers Date: Fri, 16 Apr 2021 14:18:58 -0700 Subject: [PATCH 47/49] Netmiko create an exception in send_config_set based on pattern (#1609) --- netmiko/__init__.py | 2 ++ netmiko/base_connection.py | 34 +++++++++++++++++++++++++++----- netmiko/ssh_exception.py | 6 ++++++ tests/etc/commands.yml.example | 1 + tests_new/test_netmiko_config.py | 32 ++++++++++++++++++++++++++++++ 5 files changed, 70 insertions(+), 5 deletions(-) diff --git a/netmiko/__init__.py b/netmiko/__init__.py index e6a0cb17a..cba949358 100644 --- a/netmiko/__init__.py +++ b/netmiko/__init__.py @@ -16,6 +16,7 @@ NetmikoAuthenticationException, NetMikoAuthenticationException, ) +from netmiko.ssh_exception import ConfigInvalidException from netmiko.ssh_autodetect import SSHDetect from netmiko.base_connection import BaseConnection from netmiko.scp_functions import file_transfer, progress_bar @@ -32,6 +33,7 @@ "FileTransfer", "NetmikoTimeoutException", "NetmikoAuthenticationException", + "ConfigInvalidException", "NetMikoTimeoutException", "NetMikoAuthenticationException", "InLineTransfer", diff --git a/netmiko/base_connection.py b/netmiko/base_connection.py index 25aca0280..161bcd25c 100644 --- a/netmiko/base_connection.py +++ b/netmiko/base_connection.py @@ -24,6 +24,7 @@ from netmiko.ssh_exception import ( NetmikoTimeoutException, NetmikoAuthenticationException, + ConfigInvalidException, ) from netmiko.utilities import ( write_bytes, @@ -1818,6 +1819,7 @@ def send_config_set( config_mode_command=None, cmd_verify=True, enter_config_mode=True, + error_pattern="", ): """ Send configuration commands down the SSH channel. @@ -1854,6 +1856,9 @@ def send_config_set( :param enter_config_mode: Do you enter config mode before sending config commands :type exit_config_mode: bool + :param error_pattern: Regular expression pattern to detect config errors in the + output. + :type error_pattern: str """ delay_factor = self.select_delay_factor(delay_factor) if config_commands is None: @@ -1870,21 +1875,35 @@ def send_config_set( cfg_mode_args = (config_mode_command,) if config_mode_command else tuple() output += self.config_mode(*cfg_mode_args) - if self.fast_cli and self._legacy_mode: + # If error_pattern is perform output gathering line by line and not fast_cli mode. + if self.fast_cli and self._legacy_mode and not error_pattern: for cmd in config_commands: self.write_channel(self.normalize_cmd(cmd)) # Gather output output += self._read_channel_timing( delay_factor=delay_factor, max_loops=max_loops ) + elif not cmd_verify: for cmd in config_commands: self.write_channel(self.normalize_cmd(cmd)) time.sleep(delay_factor * 0.05) - # Gather output - output += self._read_channel_timing( - delay_factor=delay_factor, max_loops=max_loops - ) + + # Gather the output incrementally due to error_pattern requirements + if error_pattern: + output += self._read_channel_timing( + delay_factor=delay_factor, max_loops=max_loops + ) + if re.search(error_pattern, output, flags=re.M): + msg = f"Invalid input detected at command: {cmd}" + raise ConfigInvalidException(msg) + + # Standard output gathering (no error_pattern) + if not error_pattern: + output += self._read_channel_timing( + delay_factor=delay_factor, max_loops=max_loops + ) + else: for cmd in config_commands: self.write_channel(self.normalize_cmd(cmd)) @@ -1902,6 +1921,11 @@ def send_config_set( new_output = self.read_until_pattern(pattern=pattern) output += new_output + if error_pattern: + if re.search(error_pattern, output, flags=re.M): + msg = f"Invalid input detected at command: {cmd}" + raise ConfigInvalidException(msg) + if exit_config_mode: output += self.exit_config_mode() output = self._sanitize_output(output) diff --git a/netmiko/ssh_exception.py b/netmiko/ssh_exception.py index 8e553e686..cb0468927 100644 --- a/netmiko/ssh_exception.py +++ b/netmiko/ssh_exception.py @@ -14,5 +14,11 @@ class NetmikoAuthenticationException(AuthenticationException): pass +class ConfigInvalidException(Exception): + """Exception raised for invalid configuration error.""" + + pass + + NetMikoTimeoutException = NetmikoTimeoutException NetMikoAuthenticationException = NetmikoAuthenticationException diff --git a/tests/etc/commands.yml.example b/tests/etc/commands.yml.example index 0149b1042..0910babca 100644 --- a/tests/etc/commands.yml.example +++ b/tests/etc/commands.yml.example @@ -52,6 +52,7 @@ cisco_s300: config_verification: "show run" config_file: "cisco_ios_commands.txt" save_config_confirm: True + save_config_response: '' cisco_asa: version: "show version" diff --git a/tests_new/test_netmiko_config.py b/tests_new/test_netmiko_config.py index 89eab7860..772929a82 100755 --- a/tests_new/test_netmiko_config.py +++ b/tests_new/test_netmiko_config.py @@ -1,5 +1,6 @@ #!/usr/bin/env python import pytest +from netmiko import ConfigInvalidException def test_ssh_connect(net_connect, commands, expected_responses): @@ -111,6 +112,37 @@ def test_config_from_file(net_connect, commands, expected_responses): net_connect.save_config() +def test_config_error_pattern(net_connect, commands, expected_responses): + """ + Raise exception when config_error_str is present in output + """ + config_base = commands.get("config") + config_err = commands.get("invalid_config") + config_list = config_base + [config_err] + error_pattern = commands.get("error_pattern") + + # Should not raise an exception since error_pattern not specified + output = net_connect.send_config_set(config_commands=config_list) + print(output) + + if config_list and error_pattern: + with pytest.raises(ConfigInvalidException): + output = net_connect.send_config_set( + config_commands=config_list, error_pattern=error_pattern + ) + + # Try it with cmd_verify=True also + with pytest.raises(ConfigInvalidException): + output = net_connect.send_config_set( + config_commands=config_list, + error_pattern=error_pattern, + cmd_verify=True, + ) + + else: + print("Skipping test: no error_pattern supplied.") + + def test_disconnect(net_connect, commands, expected_responses): """ Terminate the SSH session From 58548971da2ce6b73e97f8ffce2daf31a52a195d Mon Sep 17 00:00:00 2001 From: Kirk Byers Date: Wed, 21 Apr 2021 19:00:18 -0700 Subject: [PATCH 48/49] Supermicro Driver (#2231) Co-authored-by: sandyw777 Co-authored-by: puffc --- PLATFORMS.md | 1 + netmiko/ssh_autodetect.py | 6 ++++ netmiko/ssh_dispatcher.py | 8 ++++-- netmiko/supermicro/__init__.py | 3 ++ netmiko/supermicro/smci_smis.py | 44 ++++++++++++++++++++++++++++++ tests/etc/commands.yml.example | 13 +++++++++ tests/etc/responses.yml.example | 11 ++++++++ tests/etc/test_devices.yml.example | 6 ++++ tests/test_supermicro.sh | 11 ++++++++ 9 files changed, 101 insertions(+), 2 deletions(-) create mode 100644 netmiko/supermicro/__init__.py create mode 100644 netmiko/supermicro/smci_smis.py create mode 100644 tests/test_supermicro.sh diff --git a/PLATFORMS.md b/PLATFORMS.md index af5e5d793..66d3246ab 100644 --- a/PLATFORMS.md +++ b/PLATFORMS.md @@ -49,6 +49,7 @@ - Pluribus - Ruckus ICX/FastIron - Ruijie Networks +- Supermicro SMIS - TPLink JetStream - Ubiquiti EdgeSwitch - Vyatta VyOS diff --git a/netmiko/ssh_autodetect.py b/netmiko/ssh_autodetect.py index 9e449e279..c610db7cc 100644 --- a/netmiko/ssh_autodetect.py +++ b/netmiko/ssh_autodetect.py @@ -218,6 +218,12 @@ "priority": 99, "dispatch": "_autodetect_std", }, + "supermicro_smis": { + "cmd": "show system info", + "search_patterns": [r"Super Micro Computer"], + "priority": 99, + "dispatch": "_autodetect_std", + }, } # Sort SSH_MAPPER_BASE such that the most common commands are first diff --git a/netmiko/ssh_dispatcher.py b/netmiko/ssh_dispatcher.py index d53213194..99cde1699 100755 --- a/netmiko/ssh_dispatcher.py +++ b/netmiko/ssh_dispatcher.py @@ -99,6 +99,8 @@ from netmiko.yamaha import YamahaTelnet from netmiko.zte import ZteZxrosSSH from netmiko.zte import ZteZxrosTelnet +from netmiko.supermicro import SmciSwitchSmisSSH +from netmiko.supermicro import SmciSwitchSmisTelnet GenericSSH = TerminalServerSSH GenericTelnet = TerminalServerTelnet @@ -204,6 +206,7 @@ "ruijie_os": RuijieOSSSH, "sixwind_os": SixwindOSSSH, "sophos_sfos": SophosSfosSSH, + "supermicro_smis": SmciSwitchSmisSSH, "tplink_jetstream": TPLinkJetStreamSSH, "ubiquiti_edge": UbiquitiEdgeSSH, "ubiquiti_edgerouter": UbiquitiEdgeRouterSSH, @@ -271,16 +274,17 @@ CLASS_MAPPER["huawei_olt_telnet"] = HuaweiSmartAXSSH CLASS_MAPPER["ipinfusion_ocnos_telnet"] = IpInfusionOcNOSTelnet CLASS_MAPPER["juniper_junos_telnet"] = JuniperTelnet -CLASS_MAPPER["paloalto_panos_telnet"] = PaloAltoPanosTelnet +CLASS_MAPPER["nokia_sros_telnet"] = NokiaSrosTelnet CLASS_MAPPER["oneaccess_oneos_telnet"] = OneaccessOneOSTelnet +CLASS_MAPPER["paloalto_panos_telnet"] = PaloAltoPanosTelnet CLASS_MAPPER["rad_etx_telnet"] = RadETXTelnet CLASS_MAPPER["raisecom_telnet"] = RaisecomRoapTelnet CLASS_MAPPER["ruckus_fastiron_telnet"] = RuckusFastironTelnet CLASS_MAPPER["ruijie_os_telnet"] = RuijieOSTelnet +CLASS_MAPPER["supermicro_smis_telnet"] = SmciSwitchSmisTelnet CLASS_MAPPER["tplink_jetstream_telnet"] = TPLinkJetStreamTelnet CLASS_MAPPER["yamaha_telnet"] = YamahaTelnet CLASS_MAPPER["zte_zxros_telnet"] = ZteZxrosTelnet -CLASS_MAPPER["nokia_sros_telnet"] = NokiaSrosTelnet # Add serial drivers CLASS_MAPPER["cisco_ios_serial"] = CiscoIosSerial diff --git a/netmiko/supermicro/__init__.py b/netmiko/supermicro/__init__.py new file mode 100644 index 000000000..6a04c1613 --- /dev/null +++ b/netmiko/supermicro/__init__.py @@ -0,0 +1,3 @@ +from netmiko.supermicro.smci_smis import SmciSwitchSmisTelnet, SmciSwitchSmisSSH + +__all__ = ["SmciSwitchSmisSSH", "SmciSwitchSmisTelnet"] diff --git a/netmiko/supermicro/smci_smis.py b/netmiko/supermicro/smci_smis.py new file mode 100644 index 000000000..560c68a77 --- /dev/null +++ b/netmiko/supermicro/smci_smis.py @@ -0,0 +1,44 @@ +from netmiko.cisco_base_connection import CiscoBaseConnection +import time + + +class SmciSwitchSmisBase(CiscoBaseConnection): + def session_preparation(self): + """Prepare the session after the connection has been established.""" + self._test_channel_read(pattern=r"[>#]") + self.set_base_prompt() + self.config_mode() + self.disable_paging(command="set cli pagination off") + self.set_terminal_width(command="terminal width 511") + self.exit_config_mode() + # Clear the read buffer + time.sleep(0.3 * self.global_delay_factor) + self.clear_buffer() + + def check_enable_mode(self, check_string="#"): + """Check if in enable mode. Return boolean.""" + return super().check_enable_mode(check_string=check_string) + + def enable(self, *args, **kwargs): + """Supermicro switch does not support enable-mode command""" + return "" + + def exit_enable_mode(self, *args, **kwargs): + """Supermicro switch does not support enable-mode command""" + return "" + + def save_config( + self, cmd="write startup-config", confirm=False, confirm_response="" + ): + """Save config""" + return super().save_config( + cmd=cmd, confirm=confirm, confirm_response=confirm_response + ) + + +class SmciSwitchSmisSSH(SmciSwitchSmisBase): + pass + + +class SmciSwitchSmisTelnet(SmciSwitchSmisBase): + pass diff --git a/tests/etc/commands.yml.example b/tests/etc/commands.yml.example index 0910babca..d2a81aa70 100644 --- a/tests/etc/commands.yml.example +++ b/tests/etc/commands.yml.example @@ -426,6 +426,19 @@ centec_os: save_config_cmd: 'write' save_config_response: 'OK' +supermicro_nos: + version: "show version" + basic: "show ip interface" + extended_output: "show version" + config: + - "logging buffered 110" + - "logging buffered 110" + config_verification: "show run" + save_config_cmd: "write startup-config" + save_config_confirm: False + save_config_response: '[OK]' + support_commit: False + sophos_sfos: version: "system diagnostics show version-info" basic: "system diagnostics utilities route lookup 172.16.16.16" diff --git a/tests/etc/responses.yml.example b/tests/etc/responses.yml.example index e001f330e..2fa4173d8 100644 --- a/tests/etc/responses.yml.example +++ b/tests/etc/responses.yml.example @@ -268,6 +268,17 @@ centec_os: version_banner: "Centec Networks" multiple_line_output: "" +supermicro_nos: + base_prompt: SMIS + router_prompt: SMIS> + enable_prompt: SMIS# + interface_ip: 192.168.10.15 + version_banner: "Firmware Version" + multiple_line_output: "" + save_config: '[OK]' + cmd_response_init: "logging buffered 110" + cmd_response_final: "logging buffered 110" + sophos_sfos: base_prompt: "console" router_prompt: "console>" diff --git a/tests/etc/test_devices.yml.example b/tests/etc/test_devices.yml.example index ab79e71e6..d3dc90338 100644 --- a/tests/etc/test_devices.yml.example +++ b/tests/etc/test_devices.yml.example @@ -204,6 +204,12 @@ centec_os: password: centec secret: centec +supermicro_nos: + device_type: supermicro_nos + ip: 192.168.10.15 + username: ADMIN + password: ADMIN + sophos_sfos: device_type: sophos_sfos ip: 172.16.16.16 diff --git a/tests/test_supermicro.sh b/tests/test_supermicro.sh new file mode 100644 index 000000000..ef004d273 --- /dev/null +++ b/tests/test_supermicro.sh @@ -0,0 +1,11 @@ +#!/bin/sh + +RETURN_CODE=0 + +# Exit on the first test failure and set RETURN_CODE = 1 +echo "Starting tests...good luck:" \ +&& py.test -v test_netmiko_show.py --test_device supermicro_nos \ +&& py.test -v test_netmiko_config.py --test_device supermicro_nos \ +|| RETURN_CODE=1 + +exit $RETURN_CODE From cf90f8a7a73c6e52ae7d49ebd551fd97cc42f4a5 Mon Sep 17 00:00:00 2001 From: Kirk Byers Date: Fri, 23 Apr 2021 12:24:23 -0700 Subject: [PATCH 49/49] Netmiko Release 3.4.0 (#2234) --- docs/netmiko/a10/a10_ssh.html | 1 + docs/netmiko/a10/index.html | 1 + docs/netmiko/accedian/accedian_ssh.html | 1 + docs/netmiko/accedian/index.html | 1 + docs/netmiko/adtran/adtran.html | 3 + docs/netmiko/adtran/index.html | 2 + docs/netmiko/alcatel/alcatel_aos_ssh.html | 1 + docs/netmiko/alcatel/index.html | 1 + .../allied_telesis/allied_telesis_awplus.html | 597 ++++++ docs/netmiko/allied_telesis/index.html | 277 +++ docs/netmiko/apresia/apresia_aeos.html | 3 + docs/netmiko/apresia/index.html | 2 + docs/netmiko/arista/arista.html | 3 + docs/netmiko/arista/index.html | 2 + docs/netmiko/aruba/aruba_ssh.html | 1 + docs/netmiko/aruba/index.html | 1 + docs/netmiko/base_connection.html | 331 +++- docs/netmiko/broadcom/broadcom_icos_ssh.html | 1 + docs/netmiko/broadcom/index.html | 1 + docs/netmiko/brocade/brocade_fos_ssh.html | 392 ++++ docs/netmiko/brocade/index.html | 365 ++++ docs/netmiko/calix/calix_b6.html | 3 + docs/netmiko/calix/index.html | 2 + docs/netmiko/cdot/cdot_cros_ssh.html | 605 ++++++ docs/netmiko/cdot/index.html | 516 ++++++ docs/netmiko/centec/centec_os.html | 3 + docs/netmiko/centec/index.html | 2 + .../checkpoint/checkpoint_gaia_ssh.html | 1 + docs/netmiko/checkpoint/index.html | 1 + docs/netmiko/ciena/ciena_saos.html | 3 + docs/netmiko/ciena/index.html | 2 + docs/netmiko/cisco/cisco_asa_ssh.html | 78 +- docs/netmiko/cisco/cisco_ftd_ssh.html | 1 + docs/netmiko/cisco/cisco_ios.html | 4 + docs/netmiko/cisco/cisco_nxos_ssh.html | 1 + docs/netmiko/cisco/cisco_s300.html | 1 + docs/netmiko/cisco/cisco_tp_tcce.html | 1 + docs/netmiko/cisco/cisco_wlc_ssh.html | 1 + docs/netmiko/cisco/cisco_xr.html | 12 + docs/netmiko/cisco/index.html | 54 +- docs/netmiko/cisco_base_connection.html | 30 +- docs/netmiko/citrix/index.html | 1 + docs/netmiko/citrix/netscaler_ssh.html | 1 + docs/netmiko/cloudgenix/cloudgenix_ion.html | 1 + docs/netmiko/cloudgenix/index.html | 1 + docs/netmiko/coriant/coriant_ssh.html | 1 + docs/netmiko/coriant/index.html | 1 + docs/netmiko/dell/dell_dnos6.html | 3 + docs/netmiko/dell/dell_force10_ssh.html | 1 + docs/netmiko/dell/dell_isilon_ssh.html | 1 + docs/netmiko/dell/dell_os10_ssh.html | 1 + docs/netmiko/dell/dell_powerconnect.html | 3 + docs/netmiko/dell/index.html | 7 + docs/netmiko/dlink/dlink_ds.html | 3 + docs/netmiko/dlink/index.html | 2 + docs/netmiko/eltex/eltex_esr_ssh.html | 1 + docs/netmiko/eltex/eltex_ssh.html | 1 + docs/netmiko/eltex/index.html | 2 + docs/netmiko/endace/endace_ssh.html | 1 + docs/netmiko/endace/index.html | 1 + docs/netmiko/enterasys/enterasys_ssh.html | 1 + docs/netmiko/enterasys/index.html | 1 + docs/netmiko/ericsson/ericsson_ipos.html | 1 + docs/netmiko/ericsson/index.html | 1 + docs/netmiko/extreme/extreme_ers_ssh.html | 1 + docs/netmiko/extreme/extreme_exos.html | 3 + docs/netmiko/extreme/extreme_netiron.html | 55 +- docs/netmiko/extreme/extreme_nos_ssh.html | 1 + docs/netmiko/extreme/extreme_slx_ssh.html | 1 + docs/netmiko/extreme/extreme_vsp_ssh.html | 1 + docs/netmiko/extreme/extreme_wing_ssh.html | 1 + docs/netmiko/extreme/index.html | 13 +- docs/netmiko/f5/f5_linux_ssh.html | 1 + docs/netmiko/f5/f5_tmsh_ssh.html | 143 +- docs/netmiko/f5/index.html | 113 +- docs/netmiko/flexvnf/flexvnf_ssh.html | 1 + docs/netmiko/flexvnf/index.html | 1 + docs/netmiko/fortinet/fortinet_ssh.html | 1 + docs/netmiko/fortinet/index.html | 1 + docs/netmiko/hp/hp_comware.html | 3 + docs/netmiko/hp/hp_procurve.html | 3 + docs/netmiko/hp/index.html | 4 + docs/netmiko/huawei/huawei.html | 4 + docs/netmiko/huawei/huawei_smartax.html | 1 + docs/netmiko/huawei/index.html | 4 + docs/netmiko/index.html | 275 ++- docs/netmiko/ipinfusion/index.html | 2 + docs/netmiko/ipinfusion/ipinfusion_ocnos.html | 3 + docs/netmiko/juniper/index.html | 3 + docs/netmiko/juniper/juniper.html | 3 + docs/netmiko/juniper/juniper_screenos.html | 1 + docs/netmiko/keymile/index.html | 2 + docs/netmiko/keymile/keymile_nos_ssh.html | 1 + docs/netmiko/keymile/keymile_ssh.html | 1 + docs/netmiko/linux/index.html | 1 + docs/netmiko/linux/linux_ssh.html | 1 + docs/netmiko/mellanox/index.html | 1 + .../netmiko/mellanox/mellanox_mlnxos_ssh.html | 1 + docs/netmiko/mikrotik/index.html | 2 + docs/netmiko/mikrotik/mikrotik_ssh.html | 3 + docs/netmiko/mrv/index.html | 2 + docs/netmiko/mrv/mrv_lx.html | 1 + docs/netmiko/mrv/mrv_ssh.html | 1 + docs/netmiko/netapp/index.html | 1 + docs/netmiko/netapp/netapp_cdot_ssh.html | 1 + docs/netmiko/netgear/index.html | 1 + docs/netmiko/netgear/netgear_prosafe_ssh.html | 1 + docs/netmiko/nokia/index.html | 726 +++----- docs/netmiko/nokia/nokia_sros.html | 1619 +++++++++++++++++ docs/netmiko/oneaccess/index.html | 2 + docs/netmiko/oneaccess/oneaccess_oneos.html | 3 + docs/netmiko/ovs/index.html | 1 + docs/netmiko/ovs/ovs_linux_ssh.html | 1 + docs/netmiko/paloalto/index.html | 2 + docs/netmiko/paloalto/paloalto_panos.html | 9 + docs/netmiko/pluribus/index.html | 1 + docs/netmiko/pluribus/pluribus_ssh.html | 1 + docs/netmiko/quanta/index.html | 1 + docs/netmiko/quanta/quanta_mesh_ssh.html | 1 + docs/netmiko/rad/index.html | 2 + docs/netmiko/rad/rad_etx.html | 3 + docs/netmiko/raisecom/index.html | 2 + docs/netmiko/raisecom/raisecom_roap.html | 3 + docs/netmiko/ruckus/index.html | 2 + docs/netmiko/ruckus/ruckus_fastiron.html | 3 + docs/netmiko/ruijie/index.html | 2 + docs/netmiko/ruijie/ruijie_os.html | 3 + docs/netmiko/scp_handler.html | 11 +- docs/netmiko/sixwind/index.html | 1 + docs/netmiko/sixwind/sixwind_os.html | 2 + docs/netmiko/sophos/index.html | 1 + docs/netmiko/sophos/sophos_sfos_ssh.html | 1 + docs/netmiko/ssh_autodetect.html | 16 +- docs/netmiko/ssh_exception.html | 28 + docs/netmiko/supermicro/index.html | 476 +++++ docs/netmiko/supermicro/smci_smis.html | 803 ++++++++ docs/netmiko/terminal_server/index.html | 2 + .../terminal_server/terminal_server.html | 3 + docs/netmiko/tplink/index.html | 2 + docs/netmiko/tplink/tplink_jetstream.html | 3 + docs/netmiko/ubiquiti/edge_ssh.html | 1 + docs/netmiko/ubiquiti/edgerouter_ssh.html | 1 + docs/netmiko/ubiquiti/index.html | 3 + docs/netmiko/ubiquiti/unifiswitch_ssh.html | 1 + docs/netmiko/utilities.html | 153 ++ docs/netmiko/vyos/index.html | 1 + docs/netmiko/vyos/vyos_ssh.html | 1 + docs/netmiko/watchguard/fireware_ssh.html | 1 + docs/netmiko/watchguard/index.html | 1 + docs/netmiko/yamaha/index.html | 9 +- docs/netmiko/yamaha/yamaha.html | 24 +- docs/netmiko/zte/index.html | 2 + docs/netmiko/zte/zte_zxros.html | 3 + netmiko/__init__.py | 2 +- release_process.txt | 4 +- tests_new/test_netmiko_config.py | 9 +- 156 files changed, 7332 insertions(+), 629 deletions(-) create mode 100644 docs/netmiko/allied_telesis/allied_telesis_awplus.html create mode 100644 docs/netmiko/allied_telesis/index.html create mode 100644 docs/netmiko/brocade/brocade_fos_ssh.html create mode 100644 docs/netmiko/brocade/index.html create mode 100644 docs/netmiko/cdot/cdot_cros_ssh.html create mode 100644 docs/netmiko/cdot/index.html create mode 100644 docs/netmiko/nokia/nokia_sros.html create mode 100644 docs/netmiko/supermicro/index.html create mode 100644 docs/netmiko/supermicro/smci_smis.html diff --git a/docs/netmiko/a10/a10_ssh.html b/docs/netmiko/a10/a10_ssh.html index 43cde3613..842617403 100644 --- a/docs/netmiko/a10/a10_ssh.html +++ b/docs/netmiko/a10/a10_ssh.html @@ -288,6 +288,7 @@

              Inherited members

            • read_until_pattern
            • read_until_prompt
            • read_until_prompt_or_pattern
            • +
            • run_ttp
            • select_delay_factor
            • send_command
            • send_command_expect
            • diff --git a/docs/netmiko/a10/index.html b/docs/netmiko/a10/index.html index 7d22e4798..e9bc02dba 100644 --- a/docs/netmiko/a10/index.html +++ b/docs/netmiko/a10/index.html @@ -272,6 +272,7 @@

              Inherited members

            • read_until_pattern
            • read_until_prompt
            • read_until_prompt_or_pattern
            • +
            • run_ttp
            • select_delay_factor
            • send_command
            • send_command_expect
            • diff --git a/docs/netmiko/accedian/accedian_ssh.html b/docs/netmiko/accedian/accedian_ssh.html index 2e180dd02..6eb8fafc4 100644 --- a/docs/netmiko/accedian/accedian_ssh.html +++ b/docs/netmiko/accedian/accedian_ssh.html @@ -362,6 +362,7 @@

              Inherited members

            • read_until_pattern
            • read_until_prompt
            • read_until_prompt_or_pattern
            • +
            • run_ttp
            • select_delay_factor
            • send_command
            • send_command_expect
            • diff --git a/docs/netmiko/accedian/index.html b/docs/netmiko/accedian/index.html index bda9fb0bf..5129c6543 100644 --- a/docs/netmiko/accedian/index.html +++ b/docs/netmiko/accedian/index.html @@ -325,6 +325,7 @@

              Inherited members

            • read_until_pattern
            • read_until_prompt
            • read_until_prompt_or_pattern
            • +
            • run_ttp
            • select_delay_factor
            • send_command
            • send_command_expect
            • diff --git a/docs/netmiko/adtran/adtran.html b/docs/netmiko/adtran/adtran.html index 2c19c553b..e3eda974c 100644 --- a/docs/netmiko/adtran/adtran.html +++ b/docs/netmiko/adtran/adtran.html @@ -330,6 +330,7 @@

              Inherited members

            • read_until_pattern
            • read_until_prompt
            • read_until_prompt_or_pattern
            • +
            • run_ttp
            • save_config
            • select_delay_factor
            • send_command
            • @@ -524,6 +525,7 @@

              Inherited members

            • read_until_pattern
            • read_until_prompt
            • read_until_prompt_or_pattern
            • +
            • run_ttp
            • save_config
            • select_delay_factor
            • send_command
            • @@ -722,6 +724,7 @@

              Inherited members

            • read_until_pattern
            • read_until_prompt
            • read_until_prompt_or_pattern
            • +
            • run_ttp
            • save_config
            • select_delay_factor
            • send_command
            • diff --git a/docs/netmiko/adtran/index.html b/docs/netmiko/adtran/index.html index 6b9386fb4..43bc6695f 100644 --- a/docs/netmiko/adtran/index.html +++ b/docs/netmiko/adtran/index.html @@ -217,6 +217,7 @@

              Inherited members

            • read_until_pattern
            • read_until_prompt
            • read_until_prompt_or_pattern
            • +
            • run_ttp
            • save_config
            • select_delay_factor
            • send_command
            • @@ -415,6 +416,7 @@

              Inherited members

            • read_until_pattern
            • read_until_prompt
            • read_until_prompt_or_pattern
            • +
            • run_ttp
            • save_config
            • select_delay_factor
            • send_command
            • diff --git a/docs/netmiko/alcatel/alcatel_aos_ssh.html b/docs/netmiko/alcatel/alcatel_aos_ssh.html index ca743956c..93c9c3d88 100644 --- a/docs/netmiko/alcatel/alcatel_aos_ssh.html +++ b/docs/netmiko/alcatel/alcatel_aos_ssh.html @@ -380,6 +380,7 @@

              Inherited members

            • read_until_pattern
            • read_until_prompt
            • read_until_prompt_or_pattern
            • +
            • run_ttp
            • select_delay_factor
            • send_command
            • send_command_expect
            • diff --git a/docs/netmiko/alcatel/index.html b/docs/netmiko/alcatel/index.html index 078d561b8..2a79906db 100644 --- a/docs/netmiko/alcatel/index.html +++ b/docs/netmiko/alcatel/index.html @@ -342,6 +342,7 @@

              Inherited members

            • read_until_pattern
            • read_until_prompt
            • read_until_prompt_or_pattern
            • +
            • run_ttp
            • select_delay_factor
            • send_command
            • send_command_expect
            • diff --git a/docs/netmiko/allied_telesis/allied_telesis_awplus.html b/docs/netmiko/allied_telesis/allied_telesis_awplus.html new file mode 100644 index 000000000..6f462da97 --- /dev/null +++ b/docs/netmiko/allied_telesis/allied_telesis_awplus.html @@ -0,0 +1,597 @@ + + + + + + +netmiko.allied_telesis.allied_telesis_awplus API documentation + + + + + + + + + +
              +
              +
              +

              Module netmiko.allied_telesis.allied_telesis_awplus

              +
              +
              +
              +Source code +
              from netmiko.cisco_base_connection import CiscoBaseConnection
              +import time
              +
              +
              +class AlliedTelesisAwplusBase(CiscoBaseConnection):
              +    """Implement methods for interacting with Allied Telesis devices."""
              +
              +    def session_preparation(self):
              +        """
              +        Prepare the session after the connection has been established.
              +
              +        Disable paging (the '--more--' prompts).
              +        Set the base prompt for interaction ('>').
              +        """
              +        """ AWPlus Configuration """
              +
              +        self.disable_paging()
              +        self.set_base_prompt()
              +        time.sleep(0.3 * self.global_delay_factor)
              +
              +    def _enter_shell(self):
              +        """Enter the Bourne Shell."""
              +        return self.send_command("start shell sh", expect_string=r"[\$#]")
              +
              +    def _return_cli(self):
              +        """Return to the Awplus CLI."""
              +        return self.send_command("exit", expect_string=r"[#>]")
              +
              +    def exit_config_mode(self, exit_config="exit", pattern=""):
              +        """Exit configuration mode."""
              +        output = ""
              +        if self.check_config_mode():
              +            output = self.send_command_timing(
              +                exit_config, strip_prompt=False, strip_command=False
              +            )
              +            if "Exit with uncommitted changes?" in output:
              +                output += self.send_command_timing(
              +                    "yes", strip_prompt=False, strip_command=False
              +                )
              +            if self.check_config_mode():
              +                raise ValueError("Failed to exit configuration mode")
              +        return output
              +
              +
              +class AlliedTelesisAwplusSSH(AlliedTelesisAwplusBase):
              +    pass
              +
              +
              +
              +
              +
              +
              +
              +
              +
              +

              Classes

              +
              +
              +class AlliedTelesisAwplusBase +(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=5, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=False, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True) +
              +
              +

              Implement methods for interacting with Allied Telesis devices.

              +
                  Initialize attributes for establishing connection to target device.
              +
              +    :param ip: IP address of target device. Not required if `host` is
              +        provided.
              +    :type ip: str
              +
              +    :param host: Hostname of target device. Not required if `ip` is
              +            provided.
              +    :type host: str
              +
              +    :param username: Username to authenticate against target device if
              +            required.
              +    :type username: str
              +
              +    :param password: Password to authenticate against target device if
              +            required.
              +    :type password: str
              +
              +    :param secret: The enable password if target device requires one.
              +    :type secret: str
              +
              +    :param port: The destination port used to connect to the target
              +            device.
              +    :type port: int or None
              +
              +    :param device_type: Class selection based on device type.
              +    :type device_type: str
              +
              +    :param verbose: Enable additional messages to standard output.
              +    :type verbose: bool
              +
              +    :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
              +    :type global_delay_factor: int
              +
              +    :param use_keys: Connect to target device using SSH keys.
              +    :type use_keys: bool
              +
              +    :param key_file: Filename path of the SSH key file to use.
              +    :type key_file: str
              +
              +    :param pkey: SSH key object to use.
              +    :type pkey: paramiko.PKey
              +
              +    :param passphrase: Passphrase to use for encrypted key; password will be used for key
              +            decryption if not specified.
              +    :type passphrase: str
              +
              +    :param allow_agent: Enable use of SSH key-agent.
              +    :type allow_agent: bool
              +
              +    :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
              +            means unknown SSH host keys will be accepted).
              +    :type ssh_strict: bool
              +
              +    :param system_host_keys: Load host keys from the users known_hosts file.
              +    :type system_host_keys: bool
              +    :param alt_host_keys: If `True` host keys will be loaded from the file specified in
              +            alt_key_file.
              +    :type alt_host_keys: bool
              +
              +    :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
              +    :type alt_key_file: str
              +
              +    :param ssh_config_file: File name of OpenSSH configuration file.
              +    :type ssh_config_file: str
              +
              +    :param timeout: Connection timeout.
              +    :type timeout: float
              +
              +    :param session_timeout: Set a timeout for parallel requests.
              +    :type session_timeout: float
              +
              +    :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
              +    :type auth_timeout: float
              +
              +    :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
              +    :type banner_timeout: float
              +
              +    :param keepalive: Send SSH keepalive packets at a specific interval, in seconds.
              +            Currently defaults to 0, for backwards compatibility (it will not attempt
              +            to keep the connection alive).
              +    :type keepalive: int
              +
              +    :param default_enter: Character(s) to send to correspond to enter key (default:
              +
              +

              ). +:type default_enter: str

              +
                  :param response_return: Character(s) to use in normalized return data to represent
              +            enter key (default:
              +
              +

              ) +:type response_return: str

              +
                  :param fast_cli: Provide a way to optimize for performance. Converts select_delay_factor
              +            to select smallest of global and specific. Sets default global_delay_factor to .1
              +            (default: False)
              +    :type fast_cli: boolean
              +
              +    :param session_log: File path or BufferedIOBase subclass object to write the session log to.
              +    :type session_log: str
              +
              +    :param session_log_record_writes: The session log generally only records channel reads due
              +            to eliminate command duplication due to command echo. You can enable this if you
              +            want to record both channel reads and channel writes in the log (default: False).
              +    :type session_log_record_writes: boolean
              +
              +    :param session_log_file_mode: "write" or "append" for session_log file mode
              +            (default: "write")
              +    :type session_log_file_mode: str
              +
              +    :param allow_auto_change: Allow automatic configuration changes for terminal settings.
              +            (default: False)
              +    :type allow_auto_change: bool
              +
              +    :param encoding: Encoding to be used when writing bytes to the output channel.
              +            (default: ascii)
              +    :type encoding: str
              +
              +    :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
              +            communication to the target host (default: None).
              +    :type sock: socket
              +
              +    :param global_cmd_verify: Control whether command echo verification is enabled or disabled
              +            (default: None). Global attribute takes precedence over function `cmd_verify`
              +            argument. Value of `None` indicates to use function `cmd_verify` argument.
              +    :type global_cmd_verify: bool|None
              +
              +    :param auto_connect: Control whether Netmiko automatically establishes the connection as
              +            part of the object creation (default: True).
              +    :type auto_connect: bool
              +
              +
              +Source code +
              class AlliedTelesisAwplusBase(CiscoBaseConnection):
              +    """Implement methods for interacting with Allied Telesis devices."""
              +
              +    def session_preparation(self):
              +        """
              +        Prepare the session after the connection has been established.
              +
              +        Disable paging (the '--more--' prompts).
              +        Set the base prompt for interaction ('>').
              +        """
              +        """ AWPlus Configuration """
              +
              +        self.disable_paging()
              +        self.set_base_prompt()
              +        time.sleep(0.3 * self.global_delay_factor)
              +
              +    def _enter_shell(self):
              +        """Enter the Bourne Shell."""
              +        return self.send_command("start shell sh", expect_string=r"[\$#]")
              +
              +    def _return_cli(self):
              +        """Return to the Awplus CLI."""
              +        return self.send_command("exit", expect_string=r"[#>]")
              +
              +    def exit_config_mode(self, exit_config="exit", pattern=""):
              +        """Exit configuration mode."""
              +        output = ""
              +        if self.check_config_mode():
              +            output = self.send_command_timing(
              +                exit_config, strip_prompt=False, strip_command=False
              +            )
              +            if "Exit with uncommitted changes?" in output:
              +                output += self.send_command_timing(
              +                    "yes", strip_prompt=False, strip_command=False
              +                )
              +            if self.check_config_mode():
              +                raise ValueError("Failed to exit configuration mode")
              +        return output
              +
              +

              Ancestors

              + +

              Subclasses

              + +

              Methods

              +
              +
              +def exit_config_mode(self, exit_config='exit', pattern='') +
              +
              +

              Exit configuration mode.

              +
              +Source code +
              def exit_config_mode(self, exit_config="exit", pattern=""):
              +    """Exit configuration mode."""
              +    output = ""
              +    if self.check_config_mode():
              +        output = self.send_command_timing(
              +            exit_config, strip_prompt=False, strip_command=False
              +        )
              +        if "Exit with uncommitted changes?" in output:
              +            output += self.send_command_timing(
              +                "yes", strip_prompt=False, strip_command=False
              +            )
              +        if self.check_config_mode():
              +            raise ValueError("Failed to exit configuration mode")
              +    return output
              +
              +
              +
              +def session_preparation(self) +
              +
              +

              Prepare the session after the connection has been established.

              +

              Disable paging (the '–more–' prompts). +Set the base prompt for interaction ('>').

              +
              +Source code +
              def session_preparation(self):
              +    """
              +    Prepare the session after the connection has been established.
              +
              +    Disable paging (the '--more--' prompts).
              +    Set the base prompt for interaction ('>').
              +    """
              +    """ AWPlus Configuration """
              +
              +    self.disable_paging()
              +    self.set_base_prompt()
              +    time.sleep(0.3 * self.global_delay_factor)
              +
              +
              +
              +

              Inherited members

              + +
              +
              +class AlliedTelesisAwplusSSH +(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=5, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=False, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True) +
              +
              +

              Implement methods for interacting with Allied Telesis devices.

              +
                  Initialize attributes for establishing connection to target device.
              +
              +    :param ip: IP address of target device. Not required if `host` is
              +        provided.
              +    :type ip: str
              +
              +    :param host: Hostname of target device. Not required if `ip` is
              +            provided.
              +    :type host: str
              +
              +    :param username: Username to authenticate against target device if
              +            required.
              +    :type username: str
              +
              +    :param password: Password to authenticate against target device if
              +            required.
              +    :type password: str
              +
              +    :param secret: The enable password if target device requires one.
              +    :type secret: str
              +
              +    :param port: The destination port used to connect to the target
              +            device.
              +    :type port: int or None
              +
              +    :param device_type: Class selection based on device type.
              +    :type device_type: str
              +
              +    :param verbose: Enable additional messages to standard output.
              +    :type verbose: bool
              +
              +    :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
              +    :type global_delay_factor: int
              +
              +    :param use_keys: Connect to target device using SSH keys.
              +    :type use_keys: bool
              +
              +    :param key_file: Filename path of the SSH key file to use.
              +    :type key_file: str
              +
              +    :param pkey: SSH key object to use.
              +    :type pkey: paramiko.PKey
              +
              +    :param passphrase: Passphrase to use for encrypted key; password will be used for key
              +            decryption if not specified.
              +    :type passphrase: str
              +
              +    :param allow_agent: Enable use of SSH key-agent.
              +    :type allow_agent: bool
              +
              +    :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
              +            means unknown SSH host keys will be accepted).
              +    :type ssh_strict: bool
              +
              +    :param system_host_keys: Load host keys from the users known_hosts file.
              +    :type system_host_keys: bool
              +    :param alt_host_keys: If `True` host keys will be loaded from the file specified in
              +            alt_key_file.
              +    :type alt_host_keys: bool
              +
              +    :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
              +    :type alt_key_file: str
              +
              +    :param ssh_config_file: File name of OpenSSH configuration file.
              +    :type ssh_config_file: str
              +
              +    :param timeout: Connection timeout.
              +    :type timeout: float
              +
              +    :param session_timeout: Set a timeout for parallel requests.
              +    :type session_timeout: float
              +
              +    :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
              +    :type auth_timeout: float
              +
              +    :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
              +    :type banner_timeout: float
              +
              +    :param keepalive: Send SSH keepalive packets at a specific interval, in seconds.
              +            Currently defaults to 0, for backwards compatibility (it will not attempt
              +            to keep the connection alive).
              +    :type keepalive: int
              +
              +    :param default_enter: Character(s) to send to correspond to enter key (default:
              +
              +

              ). +:type default_enter: str

              +
                  :param response_return: Character(s) to use in normalized return data to represent
              +            enter key (default:
              +
              +

              ) +:type response_return: str

              +
                  :param fast_cli: Provide a way to optimize for performance. Converts select_delay_factor
              +            to select smallest of global and specific. Sets default global_delay_factor to .1
              +            (default: False)
              +    :type fast_cli: boolean
              +
              +    :param session_log: File path or BufferedIOBase subclass object to write the session log to.
              +    :type session_log: str
              +
              +    :param session_log_record_writes: The session log generally only records channel reads due
              +            to eliminate command duplication due to command echo. You can enable this if you
              +            want to record both channel reads and channel writes in the log (default: False).
              +    :type session_log_record_writes: boolean
              +
              +    :param session_log_file_mode: "write" or "append" for session_log file mode
              +            (default: "write")
              +    :type session_log_file_mode: str
              +
              +    :param allow_auto_change: Allow automatic configuration changes for terminal settings.
              +            (default: False)
              +    :type allow_auto_change: bool
              +
              +    :param encoding: Encoding to be used when writing bytes to the output channel.
              +            (default: ascii)
              +    :type encoding: str
              +
              +    :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
              +            communication to the target host (default: None).
              +    :type sock: socket
              +
              +    :param global_cmd_verify: Control whether command echo verification is enabled or disabled
              +            (default: None). Global attribute takes precedence over function `cmd_verify`
              +            argument. Value of `None` indicates to use function `cmd_verify` argument.
              +    :type global_cmd_verify: bool|None
              +
              +    :param auto_connect: Control whether Netmiko automatically establishes the connection as
              +            part of the object creation (default: True).
              +    :type auto_connect: bool
              +
              +
              +Source code +
              class AlliedTelesisAwplusSSH(AlliedTelesisAwplusBase):
              +    pass
              +
              +

              Ancestors

              + +

              Inherited members

              + +
              +
              +
              +
              + +
              + + + + + \ No newline at end of file diff --git a/docs/netmiko/allied_telesis/index.html b/docs/netmiko/allied_telesis/index.html new file mode 100644 index 000000000..accdd643b --- /dev/null +++ b/docs/netmiko/allied_telesis/index.html @@ -0,0 +1,277 @@ + + + + + + +netmiko.allied_telesis API documentation + + + + + + + + + +
              +
              +
              +

              Module netmiko.allied_telesis

              +
              +
              +
              +Source code +
              from netmiko.allied_telesis.allied_telesis_awplus import AlliedTelesisAwplusSSH
              +
              +__all__ = ["AlliedTelesisAwplusSSH"]
              +
              +
              +
              +

              Sub-modules

              +
              +
              netmiko.allied_telesis.allied_telesis_awplus
              +
              +
              +
              +
              +
              +
              +
              +
              +
              +
              +

              Classes

              +
              +
              +class AlliedTelesisAwplusSSH +(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=5, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=False, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True) +
              +
              +

              Implement methods for interacting with Allied Telesis devices.

              +
                  Initialize attributes for establishing connection to target device.
              +
              +    :param ip: IP address of target device. Not required if `host` is
              +        provided.
              +    :type ip: str
              +
              +    :param host: Hostname of target device. Not required if `ip` is
              +            provided.
              +    :type host: str
              +
              +    :param username: Username to authenticate against target device if
              +            required.
              +    :type username: str
              +
              +    :param password: Password to authenticate against target device if
              +            required.
              +    :type password: str
              +
              +    :param secret: The enable password if target device requires one.
              +    :type secret: str
              +
              +    :param port: The destination port used to connect to the target
              +            device.
              +    :type port: int or None
              +
              +    :param device_type: Class selection based on device type.
              +    :type device_type: str
              +
              +    :param verbose: Enable additional messages to standard output.
              +    :type verbose: bool
              +
              +    :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
              +    :type global_delay_factor: int
              +
              +    :param use_keys: Connect to target device using SSH keys.
              +    :type use_keys: bool
              +
              +    :param key_file: Filename path of the SSH key file to use.
              +    :type key_file: str
              +
              +    :param pkey: SSH key object to use.
              +    :type pkey: paramiko.PKey
              +
              +    :param passphrase: Passphrase to use for encrypted key; password will be used for key
              +            decryption if not specified.
              +    :type passphrase: str
              +
              +    :param allow_agent: Enable use of SSH key-agent.
              +    :type allow_agent: bool
              +
              +    :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
              +            means unknown SSH host keys will be accepted).
              +    :type ssh_strict: bool
              +
              +    :param system_host_keys: Load host keys from the users known_hosts file.
              +    :type system_host_keys: bool
              +    :param alt_host_keys: If `True` host keys will be loaded from the file specified in
              +            alt_key_file.
              +    :type alt_host_keys: bool
              +
              +    :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
              +    :type alt_key_file: str
              +
              +    :param ssh_config_file: File name of OpenSSH configuration file.
              +    :type ssh_config_file: str
              +
              +    :param timeout: Connection timeout.
              +    :type timeout: float
              +
              +    :param session_timeout: Set a timeout for parallel requests.
              +    :type session_timeout: float
              +
              +    :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
              +    :type auth_timeout: float
              +
              +    :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
              +    :type banner_timeout: float
              +
              +    :param keepalive: Send SSH keepalive packets at a specific interval, in seconds.
              +            Currently defaults to 0, for backwards compatibility (it will not attempt
              +            to keep the connection alive).
              +    :type keepalive: int
              +
              +    :param default_enter: Character(s) to send to correspond to enter key (default:
              +
              +

              ). +:type default_enter: str

              +
                  :param response_return: Character(s) to use in normalized return data to represent
              +            enter key (default:
              +
              +

              ) +:type response_return: str

              +
                  :param fast_cli: Provide a way to optimize for performance. Converts select_delay_factor
              +            to select smallest of global and specific. Sets default global_delay_factor to .1
              +            (default: False)
              +    :type fast_cli: boolean
              +
              +    :param session_log: File path or BufferedIOBase subclass object to write the session log to.
              +    :type session_log: str
              +
              +    :param session_log_record_writes: The session log generally only records channel reads due
              +            to eliminate command duplication due to command echo. You can enable this if you
              +            want to record both channel reads and channel writes in the log (default: False).
              +    :type session_log_record_writes: boolean
              +
              +    :param session_log_file_mode: "write" or "append" for session_log file mode
              +            (default: "write")
              +    :type session_log_file_mode: str
              +
              +    :param allow_auto_change: Allow automatic configuration changes for terminal settings.
              +            (default: False)
              +    :type allow_auto_change: bool
              +
              +    :param encoding: Encoding to be used when writing bytes to the output channel.
              +            (default: ascii)
              +    :type encoding: str
              +
              +    :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
              +            communication to the target host (default: None).
              +    :type sock: socket
              +
              +    :param global_cmd_verify: Control whether command echo verification is enabled or disabled
              +            (default: None). Global attribute takes precedence over function `cmd_verify`
              +            argument. Value of `None` indicates to use function `cmd_verify` argument.
              +    :type global_cmd_verify: bool|None
              +
              +    :param auto_connect: Control whether Netmiko automatically establishes the connection as
              +            part of the object creation (default: True).
              +    :type auto_connect: bool
              +
              +
              +Source code +
              class AlliedTelesisAwplusSSH(AlliedTelesisAwplusBase):
              +    pass
              +
              +

              Ancestors

              + +

              Inherited members

              + +
              +
              +
              +
              + +
              + + + + + \ No newline at end of file diff --git a/docs/netmiko/apresia/apresia_aeos.html b/docs/netmiko/apresia/apresia_aeos.html index f1cbd8913..cd3dfd6fd 100644 --- a/docs/netmiko/apresia/apresia_aeos.html +++ b/docs/netmiko/apresia/apresia_aeos.html @@ -281,6 +281,7 @@

              Inherited members

            • read_until_pattern
            • read_until_prompt
            • read_until_prompt_or_pattern
            • +
            • run_ttp
            • save_config
            • select_delay_factor
            • send_command
            • @@ -476,6 +477,7 @@

              Inherited members

            • read_until_pattern
            • read_until_prompt
            • read_until_prompt_or_pattern
            • +
            • run_ttp
            • save_config
            • select_delay_factor
            • send_command
            • @@ -675,6 +677,7 @@

              Inherited members

            • read_until_pattern
            • read_until_prompt
            • read_until_prompt_or_pattern
            • +
            • run_ttp
            • save_config
            • select_delay_factor
            • send_command
            • diff --git a/docs/netmiko/apresia/index.html b/docs/netmiko/apresia/index.html index 22f48fea4..1c569d740 100644 --- a/docs/netmiko/apresia/index.html +++ b/docs/netmiko/apresia/index.html @@ -218,6 +218,7 @@

              Inherited members

            • read_until_pattern
            • read_until_prompt
            • read_until_prompt_or_pattern
            • +
            • run_ttp
            • save_config
            • select_delay_factor
            • send_command
            • @@ -417,6 +418,7 @@

              Inherited members

            • read_until_pattern
            • read_until_prompt
            • read_until_prompt_or_pattern
            • +
            • run_ttp
            • save_config
            • select_delay_factor
            • send_command
            • diff --git a/docs/netmiko/arista/arista.html b/docs/netmiko/arista/arista.html index c849f7302..59b03bb3e 100644 --- a/docs/netmiko/arista/arista.html +++ b/docs/netmiko/arista/arista.html @@ -468,6 +468,7 @@

              Inherited members

            • read_until_pattern
            • read_until_prompt
            • read_until_prompt_or_pattern
            • +
            • run_ttp
            • save_config
            • select_delay_factor
            • send_command
            • @@ -755,6 +756,7 @@

              Inherited members

            • read_until_pattern
            • read_until_prompt
            • read_until_prompt_or_pattern
            • +
            • run_ttp
            • save_config
            • select_delay_factor
            • send_command
            • @@ -954,6 +956,7 @@

              Inherited members

            • read_until_pattern
            • read_until_prompt
            • read_until_prompt_or_pattern
            • +
            • run_ttp
            • save_config
            • select_delay_factor
            • send_command
            • diff --git a/docs/netmiko/arista/index.html b/docs/netmiko/arista/index.html index f68d8cd46..a9a4e1087 100644 --- a/docs/netmiko/arista/index.html +++ b/docs/netmiko/arista/index.html @@ -310,6 +310,7 @@

              Inherited members

            • read_until_pattern
            • read_until_prompt
            • read_until_prompt_or_pattern
            • +
            • run_ttp
            • save_config
            • select_delay_factor
            • send_command
            • @@ -509,6 +510,7 @@

              Inherited members

            • read_until_pattern
            • read_until_prompt
            • read_until_prompt_or_pattern
            • +
            • run_ttp
            • save_config
            • select_delay_factor
            • send_command
            • diff --git a/docs/netmiko/aruba/aruba_ssh.html b/docs/netmiko/aruba/aruba_ssh.html index 4ff52af1d..e38861c6d 100644 --- a/docs/netmiko/aruba/aruba_ssh.html +++ b/docs/netmiko/aruba/aruba_ssh.html @@ -357,6 +357,7 @@

              Inherited members

            • read_until_pattern
            • read_until_prompt
            • read_until_prompt_or_pattern
            • +
            • run_ttp
            • save_config
            • select_delay_factor
            • send_command
            • diff --git a/docs/netmiko/aruba/index.html b/docs/netmiko/aruba/index.html index 7b5031e92..e071fc610 100644 --- a/docs/netmiko/aruba/index.html +++ b/docs/netmiko/aruba/index.html @@ -313,6 +313,7 @@

              Inherited members

            • read_until_pattern
            • read_until_prompt
            • read_until_prompt_or_pattern
            • +
            • run_ttp
            • save_config
            • select_delay_factor
            • send_command
            • diff --git a/docs/netmiko/base_connection.html b/docs/netmiko/base_connection.html index c86939989..1b793275c 100644 --- a/docs/netmiko/base_connection.html +++ b/docs/netmiko/base_connection.html @@ -52,6 +52,7 @@

              Module netmiko.base_connection

              from netmiko.ssh_exception import ( NetmikoTimeoutException, NetmikoAuthenticationException, + ConfigInvalidException, ) from netmiko.utilities import ( write_bytes, @@ -59,6 +60,7 @@

              Module netmiko.base_connection

              get_structured_data, get_structured_data_genie, get_structured_data_ttp, + run_ttp_template, select_cmd_verify, ) from netmiko.utilities import m_exec_time # noqa @@ -248,6 +250,8 @@

              Module netmiko.base_connection

              :type auto_connect: bool """ self.remote_conn = None + # Does the platform support a configuration mode + self._config_mode = True self.TELNET_RETURN = "\r\n" if default_enter is None: @@ -1159,7 +1163,9 @@

              Module netmiko.base_connection

              # Retry by sleeping .33 and then double sleep until 5 attempts (.33, .66, 1.32, etc) @retry( - wait=wait_exponential(multiplier=0.33, min=0, max=5), stop=stop_after_attempt(5) + wait=wait_exponential(multiplier=0.33, min=0, max=5), + stop=stop_after_attempt(5), + reraise=True, ) def set_base_prompt( self, pri_prompt_terminator="#", alt_prompt_terminator=">", delay_factor=1 @@ -1699,19 +1705,32 @@

              Module netmiko.base_connection

              "Failed to enter enable mode. Please ensure you pass " "the 'secret' argument to ConnectHandler." ) + + # Check if in enable mode if not self.check_enable_mode(): + # Send "enable" mode command self.write_channel(self.normalize_cmd(cmd)) try: - output += self.read_until_pattern(pattern=re.escape(cmd.strip())) - if pattern not in output: + # Read the command echo + end_data = "" + if self.global_cmd_verify is not False: + output += self.read_until_pattern(pattern=re.escape(cmd.strip())) + end_data = output.split(cmd.strip())[-1] + + # Search for trailing prompt or password pattern + if pattern not in output and self.base_prompt not in end_data: output += self.read_until_prompt_or_pattern( pattern=pattern, re_flags=re_flags ) - self.write_channel(self.normalize_cmd(self.secret)) - if enable_pattern: + # Send the "secret" in response to password pattern + if re.search(pattern, output): + self.write_channel(self.normalize_cmd(self.secret)) + output += self.read_until_prompt() + + # Search for terminating pattern if defined + if enable_pattern and not re.search(enable_pattern, output): output += self.read_until_pattern(pattern=enable_pattern) else: - output += self.read_until_prompt() if not self.check_enable_mode(): raise ValueError(msg) except NetmikoTimeoutException: @@ -1828,6 +1847,7 @@

              Module netmiko.base_connection

              config_mode_command=None, cmd_verify=True, enter_config_mode=True, + error_pattern="", ): """ Send configuration commands down the SSH channel. @@ -1864,6 +1884,9 @@

              Module netmiko.base_connection

              :param enter_config_mode: Do you enter config mode before sending config commands :type exit_config_mode: bool + :param error_pattern: Regular expression pattern to detect config errors in the + output. + :type error_pattern: str """ delay_factor = self.select_delay_factor(delay_factor) if config_commands is None: @@ -1880,21 +1903,35 @@

              Module netmiko.base_connection

              cfg_mode_args = (config_mode_command,) if config_mode_command else tuple() output += self.config_mode(*cfg_mode_args) - if self.fast_cli and self._legacy_mode: + # If error_pattern is perform output gathering line by line and not fast_cli mode. + if self.fast_cli and self._legacy_mode and not error_pattern: for cmd in config_commands: self.write_channel(self.normalize_cmd(cmd)) # Gather output output += self._read_channel_timing( delay_factor=delay_factor, max_loops=max_loops ) + elif not cmd_verify: for cmd in config_commands: self.write_channel(self.normalize_cmd(cmd)) time.sleep(delay_factor * 0.05) - # Gather output - output += self._read_channel_timing( - delay_factor=delay_factor, max_loops=max_loops - ) + + # Gather the output incrementally due to error_pattern requirements + if error_pattern: + output += self._read_channel_timing( + delay_factor=delay_factor, max_loops=max_loops + ) + if re.search(error_pattern, output, flags=re.M): + msg = f"Invalid input detected at command: {cmd}" + raise ConfigInvalidException(msg) + + # Standard output gathering (no error_pattern) + if not error_pattern: + output += self._read_channel_timing( + delay_factor=delay_factor, max_loops=max_loops + ) + else: for cmd in config_commands: self.write_channel(self.normalize_cmd(cmd)) @@ -1912,6 +1949,11 @@

              Module netmiko.base_connection

              new_output = self.read_until_pattern(pattern=pattern) output += new_output + if error_pattern: + if re.search(error_pattern, output, flags=re.M): + msg = f"Invalid input detected at command: {cmd}" + raise ConfigInvalidException(msg) + if exit_config_mode: output += self.exit_config_mode() output = self._sanitize_output(output) @@ -2064,6 +2106,41 @@

              Module netmiko.base_connection

              self.session_log.close() self.session_log = None + def run_ttp(self, template, res_kwargs={}, **kwargs): + """ + Run TTP template parsing by using input parameters to collect + devices output. + + :param template: template content, OS path to template or reference + to template within TTP templates collection in + ttp://path/to/template.txt format + :type template: str + + :param res_kwargs: ``**res_kwargs`` arguments to pass to TTP result method + :type res_kwargs: dict + + :param kwargs: any other ``**kwargs`` to use for TTP object instantiation + :type kwargs: dict + + TTP template must have inputs defined together with below parameters. + + :param method: name of Netmiko connection object method to call, default ``send_command`` + :type method: str + + :param kwargs: Netmiko connection object method arguments + :type kwargs: dict + + :param commands: list of commands to collect + :type commands: list + + Inputs' load could be of one of the supported formats and controlled by input's ``load`` + attribute, supported values - python, yaml or json. For each input output collected + from device and parsed accordingly. + """ + return run_ttp_template( + connection=self, template=template, res_kwargs=res_kwargs, **kwargs + ) + class TelnetConnection(BaseConnection): pass
              @@ -2401,6 +2478,8 @@

              Classes

              :type auto_connect: bool """ self.remote_conn = None + # Does the platform support a configuration mode + self._config_mode = True self.TELNET_RETURN = "\r\n" if default_enter is None: @@ -3312,7 +3391,9 @@

              Classes

              # Retry by sleeping .33 and then double sleep until 5 attempts (.33, .66, 1.32, etc) @retry( - wait=wait_exponential(multiplier=0.33, min=0, max=5), stop=stop_after_attempt(5) + wait=wait_exponential(multiplier=0.33, min=0, max=5), + stop=stop_after_attempt(5), + reraise=True, ) def set_base_prompt( self, pri_prompt_terminator="#", alt_prompt_terminator=">", delay_factor=1 @@ -3852,19 +3933,32 @@

              Classes

              "Failed to enter enable mode. Please ensure you pass " "the 'secret' argument to ConnectHandler." ) + + # Check if in enable mode if not self.check_enable_mode(): + # Send "enable" mode command self.write_channel(self.normalize_cmd(cmd)) try: - output += self.read_until_pattern(pattern=re.escape(cmd.strip())) - if pattern not in output: + # Read the command echo + end_data = "" + if self.global_cmd_verify is not False: + output += self.read_until_pattern(pattern=re.escape(cmd.strip())) + end_data = output.split(cmd.strip())[-1] + + # Search for trailing prompt or password pattern + if pattern not in output and self.base_prompt not in end_data: output += self.read_until_prompt_or_pattern( pattern=pattern, re_flags=re_flags ) - self.write_channel(self.normalize_cmd(self.secret)) - if enable_pattern: + # Send the "secret" in response to password pattern + if re.search(pattern, output): + self.write_channel(self.normalize_cmd(self.secret)) + output += self.read_until_prompt() + + # Search for terminating pattern if defined + if enable_pattern and not re.search(enable_pattern, output): output += self.read_until_pattern(pattern=enable_pattern) else: - output += self.read_until_prompt() if not self.check_enable_mode(): raise ValueError(msg) except NetmikoTimeoutException: @@ -3981,6 +4075,7 @@

              Classes

              config_mode_command=None, cmd_verify=True, enter_config_mode=True, + error_pattern="", ): """ Send configuration commands down the SSH channel. @@ -4017,6 +4112,9 @@

              Classes

              :param enter_config_mode: Do you enter config mode before sending config commands :type exit_config_mode: bool + :param error_pattern: Regular expression pattern to detect config errors in the + output. + :type error_pattern: str """ delay_factor = self.select_delay_factor(delay_factor) if config_commands is None: @@ -4033,21 +4131,35 @@

              Classes

              cfg_mode_args = (config_mode_command,) if config_mode_command else tuple() output += self.config_mode(*cfg_mode_args) - if self.fast_cli and self._legacy_mode: + # If error_pattern is perform output gathering line by line and not fast_cli mode. + if self.fast_cli and self._legacy_mode and not error_pattern: for cmd in config_commands: self.write_channel(self.normalize_cmd(cmd)) # Gather output output += self._read_channel_timing( delay_factor=delay_factor, max_loops=max_loops ) + elif not cmd_verify: for cmd in config_commands: self.write_channel(self.normalize_cmd(cmd)) time.sleep(delay_factor * 0.05) - # Gather output - output += self._read_channel_timing( - delay_factor=delay_factor, max_loops=max_loops - ) + + # Gather the output incrementally due to error_pattern requirements + if error_pattern: + output += self._read_channel_timing( + delay_factor=delay_factor, max_loops=max_loops + ) + if re.search(error_pattern, output, flags=re.M): + msg = f"Invalid input detected at command: {cmd}" + raise ConfigInvalidException(msg) + + # Standard output gathering (no error_pattern) + if not error_pattern: + output += self._read_channel_timing( + delay_factor=delay_factor, max_loops=max_loops + ) + else: for cmd in config_commands: self.write_channel(self.normalize_cmd(cmd)) @@ -4065,6 +4177,11 @@

              Classes

              new_output = self.read_until_pattern(pattern=pattern) output += new_output + if error_pattern: + if re.search(error_pattern, output, flags=re.M): + msg = f"Invalid input detected at command: {cmd}" + raise ConfigInvalidException(msg) + if exit_config_mode: output += self.exit_config_mode() output = self._sanitize_output(output) @@ -4215,7 +4332,42 @@

              Classes

              """Close the session_log file (if it is a file that we opened).""" if self.session_log is not None and self._session_log_close: self.session_log.close() - self.session_log = None + self.session_log = None + + def run_ttp(self, template, res_kwargs={}, **kwargs): + """ + Run TTP template parsing by using input parameters to collect + devices output. + + :param template: template content, OS path to template or reference + to template within TTP templates collection in + ttp://path/to/template.txt format + :type template: str + + :param res_kwargs: ``**res_kwargs`` arguments to pass to TTP result method + :type res_kwargs: dict + + :param kwargs: any other ``**kwargs`` to use for TTP object instantiation + :type kwargs: dict + + TTP template must have inputs defined together with below parameters. + + :param method: name of Netmiko connection object method to call, default ``send_command`` + :type method: str + + :param kwargs: Netmiko connection object method arguments + :type kwargs: dict + + :param commands: list of commands to collect + :type commands: list + + Inputs' load could be of one of the supported formats and controlled by input's ``load`` + attribute, supported values - python, yaml or json. For each input output collected + from device and parsed accordingly. + """ + return run_ttp_template( + connection=self, template=template, res_kwargs=res_kwargs, **kwargs + )

              Subclasses

                @@ -4232,7 +4384,7 @@

                Subclasses

              • JuniperBase
              • JuniperScreenOsSSH
              • NetAppcDotSSH
              • -
              • NokiaSrosSSH
              • +
              • NokiaSros
              • PaloAltoPanosBase
              • PluribusSSH
              • RadETXBase
              • @@ -4516,19 +4668,32 @@

                Methods

                "Failed to enter enable mode. Please ensure you pass " "the 'secret' argument to ConnectHandler." ) + + # Check if in enable mode if not self.check_enable_mode(): + # Send "enable" mode command self.write_channel(self.normalize_cmd(cmd)) try: - output += self.read_until_pattern(pattern=re.escape(cmd.strip())) - if pattern not in output: + # Read the command echo + end_data = "" + if self.global_cmd_verify is not False: + output += self.read_until_pattern(pattern=re.escape(cmd.strip())) + end_data = output.split(cmd.strip())[-1] + + # Search for trailing prompt or password pattern + if pattern not in output and self.base_prompt not in end_data: output += self.read_until_prompt_or_pattern( pattern=pattern, re_flags=re_flags ) - self.write_channel(self.normalize_cmd(self.secret)) - if enable_pattern: + # Send the "secret" in response to password pattern + if re.search(pattern, output): + self.write_channel(self.normalize_cmd(self.secret)) + output += self.read_until_prompt() + + # Search for terminating pattern if defined + if enable_pattern and not re.search(enable_pattern, output): output += self.read_until_pattern(pattern=enable_pattern) else: - output += self.read_until_prompt() if not self.check_enable_mode(): raise ValueError(msg) except NetmikoTimeoutException: @@ -4946,6 +5111,68 @@

                Methods

                return self._read_channel_expect(combined_pattern, re_flags=re_flags)
            +
            +def run_ttp(self, template, res_kwargs={}, **kwargs) +
            +
            +

            Run TTP template parsing by using input parameters to collect +devices output.

            +

            :param template: template content, OS path to template or reference +to template within TTP templates collection in +ttp://path/to/template.txt format +:type template: str

            +

            :param res_kwargs: **res_kwargs arguments to pass to TTP result method +:type res_kwargs: dict

            +

            :param kwargs: any other **kwargs to use for TTP object instantiation +:type kwargs: dict

            +

            TTP template must have inputs defined together with below parameters.

            +

            :param method: name of Netmiko connection object method to call, default send_command +:type method: str

            +

            :param kwargs: Netmiko connection object method arguments +:type kwargs: dict

            +

            :param commands: list of commands to collect +:type commands: list

            +

            Inputs' load could be of one of the supported formats and controlled by input's load +attribute, supported values - python, yaml or json. For each input output collected +from device and parsed accordingly.

            +
            +Source code +
            def run_ttp(self, template, res_kwargs={}, **kwargs):
            +    """
            +    Run TTP template parsing by using input parameters to collect
            +    devices output.
            +
            +    :param template: template content, OS path to template or reference
            +        to template within TTP templates collection in
            +        ttp://path/to/template.txt format
            +    :type template: str
            +
            +    :param res_kwargs: ``**res_kwargs`` arguments to pass to TTP result method
            +    :type res_kwargs: dict
            +
            +    :param kwargs: any other ``**kwargs`` to use for TTP object instantiation
            +    :type kwargs: dict
            +
            +    TTP template must have inputs defined together with below parameters.
            +
            +    :param method: name of Netmiko connection object method to call, default ``send_command``
            +    :type method: str
            +
            +    :param kwargs: Netmiko connection object method arguments
            +    :type kwargs: dict
            +
            +    :param commands: list of commands to collect
            +    :type commands: list
            +
            +    Inputs' load could be of one of the supported formats and controlled by input's ``load``
            +    attribute, supported values - python, yaml or json. For each input output collected
            +    from device and parsed accordingly.
            +    """
            +    return run_ttp_template(
            +        connection=self, template=template, res_kwargs=res_kwargs, **kwargs
            +    )
            +
            +
            def save_config(self, *args, **kwargs)
            @@ -5431,7 +5658,7 @@

            Methods

            -def send_config_set(self, config_commands=None, exit_config_mode=True, delay_factor=1, max_loops=150, strip_prompt=False, strip_command=False, config_mode_command=None, cmd_verify=True, enter_config_mode=True) +def send_config_set(self, config_commands=None, exit_config_mode=True, delay_factor=1, max_loops=150, strip_prompt=False, strip_command=False, config_mode_command=None, cmd_verify=True, enter_config_mode=True, error_pattern='')

            Send configuration commands down the SSH channel.

            @@ -5455,7 +5682,10 @@

            Methods

            :param cmd_verify: Whether or not to verify command echo for each command in config_set :type cmd_verify: bool

            :param enter_config_mode: Do you enter config mode before sending config commands -:type exit_config_mode: bool

            +:type exit_config_mode: bool

            +

            :param error_pattern: Regular expression pattern to detect config errors in the +output. +:type error_pattern: str

            Source code
            def send_config_set(
            @@ -5469,6 +5699,7 @@ 

            Methods

            config_mode_command=None, cmd_verify=True, enter_config_mode=True, + error_pattern="", ): """ Send configuration commands down the SSH channel. @@ -5505,6 +5736,9 @@

            Methods

            :param enter_config_mode: Do you enter config mode before sending config commands :type exit_config_mode: bool + :param error_pattern: Regular expression pattern to detect config errors in the + output. + :type error_pattern: str """ delay_factor = self.select_delay_factor(delay_factor) if config_commands is None: @@ -5521,21 +5755,35 @@

            Methods

            cfg_mode_args = (config_mode_command,) if config_mode_command else tuple() output += self.config_mode(*cfg_mode_args) - if self.fast_cli and self._legacy_mode: + # If error_pattern is perform output gathering line by line and not fast_cli mode. + if self.fast_cli and self._legacy_mode and not error_pattern: for cmd in config_commands: self.write_channel(self.normalize_cmd(cmd)) # Gather output output += self._read_channel_timing( delay_factor=delay_factor, max_loops=max_loops ) + elif not cmd_verify: for cmd in config_commands: self.write_channel(self.normalize_cmd(cmd)) time.sleep(delay_factor * 0.05) - # Gather output - output += self._read_channel_timing( - delay_factor=delay_factor, max_loops=max_loops - ) + + # Gather the output incrementally due to error_pattern requirements + if error_pattern: + output += self._read_channel_timing( + delay_factor=delay_factor, max_loops=max_loops + ) + if re.search(error_pattern, output, flags=re.M): + msg = f"Invalid input detected at command: {cmd}" + raise ConfigInvalidException(msg) + + # Standard output gathering (no error_pattern) + if not error_pattern: + output += self._read_channel_timing( + delay_factor=delay_factor, max_loops=max_loops + ) + else: for cmd in config_commands: self.write_channel(self.normalize_cmd(cmd)) @@ -5553,6 +5801,11 @@

            Methods

            new_output = self.read_until_pattern(pattern=pattern) output += new_output + if error_pattern: + if re.search(error_pattern, output, flags=re.M): + msg = f"Invalid input detected at command: {cmd}" + raise ConfigInvalidException(msg) + if exit_config_mode: output += self.exit_config_mode() output = self._sanitize_output(output) @@ -5644,7 +5897,9 @@

            Methods

            Source code
            @retry(
            -    wait=wait_exponential(multiplier=0.33, min=0, max=5), stop=stop_after_attempt(5)
            +    wait=wait_exponential(multiplier=0.33, min=0, max=5),
            +    stop=stop_after_attempt(5),
            +    reraise=True,
             )
             def set_base_prompt(
                 self, pri_prompt_terminator="#", alt_prompt_terminator=">", delay_factor=1
            @@ -6241,6 +6496,7 @@ 

            Inherited members

          • read_until_pattern
          • read_until_prompt
          • read_until_prompt_or_pattern
          • +
          • run_ttp
          • save_config
          • select_delay_factor
          • send_command
          • @@ -6304,6 +6560,7 @@

            read_until_pattern
          • read_until_prompt
          • read_until_prompt_or_pattern
          • +
          • run_ttp
          • save_config
          • select_delay_factor
          • send_command
          • diff --git a/docs/netmiko/broadcom/broadcom_icos_ssh.html b/docs/netmiko/broadcom/broadcom_icos_ssh.html index fb2306629..f4965990e 100644 --- a/docs/netmiko/broadcom/broadcom_icos_ssh.html +++ b/docs/netmiko/broadcom/broadcom_icos_ssh.html @@ -349,6 +349,7 @@

            Inherited members

          • read_until_pattern
          • read_until_prompt
          • read_until_prompt_or_pattern
          • +
          • run_ttp
          • select_delay_factor
          • send_command
          • send_command_expect
          • diff --git a/docs/netmiko/broadcom/index.html b/docs/netmiko/broadcom/index.html index 0b92484e4..9d0ad8181 100644 --- a/docs/netmiko/broadcom/index.html +++ b/docs/netmiko/broadcom/index.html @@ -317,6 +317,7 @@

            Inherited members

          • read_until_pattern
          • read_until_prompt
          • read_until_prompt_or_pattern
          • +
          • run_ttp
          • select_delay_factor
          • send_command
          • send_command_expect
          • diff --git a/docs/netmiko/brocade/brocade_fos_ssh.html b/docs/netmiko/brocade/brocade_fos_ssh.html new file mode 100644 index 000000000..a4233c5ff --- /dev/null +++ b/docs/netmiko/brocade/brocade_fos_ssh.html @@ -0,0 +1,392 @@ + + + + + + +netmiko.brocade.brocade_fos_ssh API documentation + + + + + + + + + +
            +
            +
            +

            Module netmiko.brocade.brocade_fos_ssh

            +
            +
            +
            +Source code +
            import time
            +import re
            +from netmiko.cisco_base_connection import CiscoSSHConnection
            +
            +
            +class BrocadeFOSSSH(CiscoSSHConnection):
            +    """Brocade Fabric OS support"""
            +
            +    def __init__(self, **kwargs):
            +        if kwargs.get("default_enter") is None:
            +            kwargs["default_enter"] = "\r"
            +        return super().__init__(**kwargs)
            +
            +    def session_preparation(self):
            +        self._test_channel_read()
            +        self.set_base_prompt()
            +
            +        # Clear the read buffer
            +        time.sleep(0.3 * self.global_delay_factor)
            +        self.clear_buffer()
            +
            +    def check_enable_mode(self, check_string=">"):
            +        """No enable mode. Always return True."""
            +        return True
            +
            +    def enable(self, cmd="", pattern="", enable_pattern=None, re_flags=re.IGNORECASE):
            +        """No Enable Mode."""
            +        return ""
            +
            +    def exit_enable_mode(self, exit_command=""):
            +        """No Enable Mode."""
            +        return ""
            +
            +    def check_config_mode(self, check_string="", pattern=""):
            +        return True
            +
            +    def config_mode(self, config_command="", pattern="", re_flags=0):
            +        """No config mode."""
            +        return ""
            +
            +    def exit_config_mode(self, exit_config="", pattern="#"):
            +        return ""
            +
            +
            +
            +
            +
            +
            +
            +
            +
            +

            Classes

            +
            +
            +class BrocadeFOSSSH +(**kwargs) +
            +
            +

            Brocade Fabric OS support

            +
                Initialize attributes for establishing connection to target device.
            +
            +    :param ip: IP address of target device. Not required if `host` is
            +        provided.
            +    :type ip: str
            +
            +    :param host: Hostname of target device. Not required if `ip` is
            +            provided.
            +    :type host: str
            +
            +    :param username: Username to authenticate against target device if
            +            required.
            +    :type username: str
            +
            +    :param password: Password to authenticate against target device if
            +            required.
            +    :type password: str
            +
            +    :param secret: The enable password if target device requires one.
            +    :type secret: str
            +
            +    :param port: The destination port used to connect to the target
            +            device.
            +    :type port: int or None
            +
            +    :param device_type: Class selection based on device type.
            +    :type device_type: str
            +
            +    :param verbose: Enable additional messages to standard output.
            +    :type verbose: bool
            +
            +    :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
            +    :type global_delay_factor: int
            +
            +    :param use_keys: Connect to target device using SSH keys.
            +    :type use_keys: bool
            +
            +    :param key_file: Filename path of the SSH key file to use.
            +    :type key_file: str
            +
            +    :param pkey: SSH key object to use.
            +    :type pkey: paramiko.PKey
            +
            +    :param passphrase: Passphrase to use for encrypted key; password will be used for key
            +            decryption if not specified.
            +    :type passphrase: str
            +
            +    :param allow_agent: Enable use of SSH key-agent.
            +    :type allow_agent: bool
            +
            +    :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
            +            means unknown SSH host keys will be accepted).
            +    :type ssh_strict: bool
            +
            +    :param system_host_keys: Load host keys from the users known_hosts file.
            +    :type system_host_keys: bool
            +    :param alt_host_keys: If `True` host keys will be loaded from the file specified in
            +            alt_key_file.
            +    :type alt_host_keys: bool
            +
            +    :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
            +    :type alt_key_file: str
            +
            +    :param ssh_config_file: File name of OpenSSH configuration file.
            +    :type ssh_config_file: str
            +
            +    :param timeout: Connection timeout.
            +    :type timeout: float
            +
            +    :param session_timeout: Set a timeout for parallel requests.
            +    :type session_timeout: float
            +
            +    :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
            +    :type auth_timeout: float
            +
            +    :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
            +    :type banner_timeout: float
            +
            +    :param keepalive: Send SSH keepalive packets at a specific interval, in seconds.
            +            Currently defaults to 0, for backwards compatibility (it will not attempt
            +            to keep the connection alive).
            +    :type keepalive: int
            +
            +    :param default_enter: Character(s) to send to correspond to enter key (default:
            +
            +

            ). +:type default_enter: str

            +
                :param response_return: Character(s) to use in normalized return data to represent
            +            enter key (default:
            +
            +

            ) +:type response_return: str

            +
                :param fast_cli: Provide a way to optimize for performance. Converts select_delay_factor
            +            to select smallest of global and specific. Sets default global_delay_factor to .1
            +            (default: False)
            +    :type fast_cli: boolean
            +
            +    :param session_log: File path or BufferedIOBase subclass object to write the session log to.
            +    :type session_log: str
            +
            +    :param session_log_record_writes: The session log generally only records channel reads due
            +            to eliminate command duplication due to command echo. You can enable this if you
            +            want to record both channel reads and channel writes in the log (default: False).
            +    :type session_log_record_writes: boolean
            +
            +    :param session_log_file_mode: "write" or "append" for session_log file mode
            +            (default: "write")
            +    :type session_log_file_mode: str
            +
            +    :param allow_auto_change: Allow automatic configuration changes for terminal settings.
            +            (default: False)
            +    :type allow_auto_change: bool
            +
            +    :param encoding: Encoding to be used when writing bytes to the output channel.
            +            (default: ascii)
            +    :type encoding: str
            +
            +    :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
            +            communication to the target host (default: None).
            +    :type sock: socket
            +
            +    :param global_cmd_verify: Control whether command echo verification is enabled or disabled
            +            (default: None). Global attribute takes precedence over function `cmd_verify`
            +            argument. Value of `None` indicates to use function `cmd_verify` argument.
            +    :type global_cmd_verify: bool|None
            +
            +    :param auto_connect: Control whether Netmiko automatically establishes the connection as
            +            part of the object creation (default: True).
            +    :type auto_connect: bool
            +
            +
            +Source code +
            class BrocadeFOSSSH(CiscoSSHConnection):
            +    """Brocade Fabric OS support"""
            +
            +    def __init__(self, **kwargs):
            +        if kwargs.get("default_enter") is None:
            +            kwargs["default_enter"] = "\r"
            +        return super().__init__(**kwargs)
            +
            +    def session_preparation(self):
            +        self._test_channel_read()
            +        self.set_base_prompt()
            +
            +        # Clear the read buffer
            +        time.sleep(0.3 * self.global_delay_factor)
            +        self.clear_buffer()
            +
            +    def check_enable_mode(self, check_string=">"):
            +        """No enable mode. Always return True."""
            +        return True
            +
            +    def enable(self, cmd="", pattern="", enable_pattern=None, re_flags=re.IGNORECASE):
            +        """No Enable Mode."""
            +        return ""
            +
            +    def exit_enable_mode(self, exit_command=""):
            +        """No Enable Mode."""
            +        return ""
            +
            +    def check_config_mode(self, check_string="", pattern=""):
            +        return True
            +
            +    def config_mode(self, config_command="", pattern="", re_flags=0):
            +        """No config mode."""
            +        return ""
            +
            +    def exit_config_mode(self, exit_config="", pattern="#"):
            +        return ""
            +
            +

            Ancestors

            + +

            Methods

            +
            +
            +def check_enable_mode(self, check_string='>') +
            +
            +

            No enable mode. Always return True.

            +
            +Source code +
            def check_enable_mode(self, check_string=">"):
            +    """No enable mode. Always return True."""
            +    return True
            +
            +
            +
            +def config_mode(self, config_command='', pattern='', re_flags=0) +
            +
            +

            No config mode.

            +
            +Source code +
            def config_mode(self, config_command="", pattern="", re_flags=0):
            +    """No config mode."""
            +    return ""
            +
            +
            +
            +def enable(self, cmd='', pattern='', enable_pattern=None, re_flags=) +
            +
            +

            No Enable Mode.

            +
            +Source code +
            def enable(self, cmd="", pattern="", enable_pattern=None, re_flags=re.IGNORECASE):
            +    """No Enable Mode."""
            +    return ""
            +
            +
            +
            +def exit_enable_mode(self, exit_command='') +
            +
            +

            No Enable Mode.

            +
            +Source code +
            def exit_enable_mode(self, exit_command=""):
            +    """No Enable Mode."""
            +    return ""
            +
            +
            +
            +

            Inherited members

            + +
            +
            +
            +
            + +
            + + + + + \ No newline at end of file diff --git a/docs/netmiko/brocade/index.html b/docs/netmiko/brocade/index.html new file mode 100644 index 000000000..4df5e4f46 --- /dev/null +++ b/docs/netmiko/brocade/index.html @@ -0,0 +1,365 @@ + + + + + + +netmiko.brocade API documentation + + + + + + + + + +
            +
            +
            +

            Module netmiko.brocade

            +
            +
            +
            +Source code +
            from netmiko.brocade.brocade_fos_ssh import BrocadeFOSSSH
            +
            +__all__ = ["BrocadeFOSSSH"]
            +
            +
            +
            +

            Sub-modules

            +
            +
            netmiko.brocade.brocade_fos_ssh
            +
            +
            +
            +
            +
            +
            +
            +
            +
            +
            +

            Classes

            +
            +
            +class BrocadeFOSSSH +(**kwargs) +
            +
            +

            Brocade Fabric OS support

            +
                Initialize attributes for establishing connection to target device.
            +
            +    :param ip: IP address of target device. Not required if `host` is
            +        provided.
            +    :type ip: str
            +
            +    :param host: Hostname of target device. Not required if `ip` is
            +            provided.
            +    :type host: str
            +
            +    :param username: Username to authenticate against target device if
            +            required.
            +    :type username: str
            +
            +    :param password: Password to authenticate against target device if
            +            required.
            +    :type password: str
            +
            +    :param secret: The enable password if target device requires one.
            +    :type secret: str
            +
            +    :param port: The destination port used to connect to the target
            +            device.
            +    :type port: int or None
            +
            +    :param device_type: Class selection based on device type.
            +    :type device_type: str
            +
            +    :param verbose: Enable additional messages to standard output.
            +    :type verbose: bool
            +
            +    :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
            +    :type global_delay_factor: int
            +
            +    :param use_keys: Connect to target device using SSH keys.
            +    :type use_keys: bool
            +
            +    :param key_file: Filename path of the SSH key file to use.
            +    :type key_file: str
            +
            +    :param pkey: SSH key object to use.
            +    :type pkey: paramiko.PKey
            +
            +    :param passphrase: Passphrase to use for encrypted key; password will be used for key
            +            decryption if not specified.
            +    :type passphrase: str
            +
            +    :param allow_agent: Enable use of SSH key-agent.
            +    :type allow_agent: bool
            +
            +    :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
            +            means unknown SSH host keys will be accepted).
            +    :type ssh_strict: bool
            +
            +    :param system_host_keys: Load host keys from the users known_hosts file.
            +    :type system_host_keys: bool
            +    :param alt_host_keys: If `True` host keys will be loaded from the file specified in
            +            alt_key_file.
            +    :type alt_host_keys: bool
            +
            +    :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
            +    :type alt_key_file: str
            +
            +    :param ssh_config_file: File name of OpenSSH configuration file.
            +    :type ssh_config_file: str
            +
            +    :param timeout: Connection timeout.
            +    :type timeout: float
            +
            +    :param session_timeout: Set a timeout for parallel requests.
            +    :type session_timeout: float
            +
            +    :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
            +    :type auth_timeout: float
            +
            +    :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
            +    :type banner_timeout: float
            +
            +    :param keepalive: Send SSH keepalive packets at a specific interval, in seconds.
            +            Currently defaults to 0, for backwards compatibility (it will not attempt
            +            to keep the connection alive).
            +    :type keepalive: int
            +
            +    :param default_enter: Character(s) to send to correspond to enter key (default:
            +
            +

            ). +:type default_enter: str

            +
                :param response_return: Character(s) to use in normalized return data to represent
            +            enter key (default:
            +
            +

            ) +:type response_return: str

            +
                :param fast_cli: Provide a way to optimize for performance. Converts select_delay_factor
            +            to select smallest of global and specific. Sets default global_delay_factor to .1
            +            (default: False)
            +    :type fast_cli: boolean
            +
            +    :param session_log: File path or BufferedIOBase subclass object to write the session log to.
            +    :type session_log: str
            +
            +    :param session_log_record_writes: The session log generally only records channel reads due
            +            to eliminate command duplication due to command echo. You can enable this if you
            +            want to record both channel reads and channel writes in the log (default: False).
            +    :type session_log_record_writes: boolean
            +
            +    :param session_log_file_mode: "write" or "append" for session_log file mode
            +            (default: "write")
            +    :type session_log_file_mode: str
            +
            +    :param allow_auto_change: Allow automatic configuration changes for terminal settings.
            +            (default: False)
            +    :type allow_auto_change: bool
            +
            +    :param encoding: Encoding to be used when writing bytes to the output channel.
            +            (default: ascii)
            +    :type encoding: str
            +
            +    :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
            +            communication to the target host (default: None).
            +    :type sock: socket
            +
            +    :param global_cmd_verify: Control whether command echo verification is enabled or disabled
            +            (default: None). Global attribute takes precedence over function `cmd_verify`
            +            argument. Value of `None` indicates to use function `cmd_verify` argument.
            +    :type global_cmd_verify: bool|None
            +
            +    :param auto_connect: Control whether Netmiko automatically establishes the connection as
            +            part of the object creation (default: True).
            +    :type auto_connect: bool
            +
            +
            +Source code +
            class BrocadeFOSSSH(CiscoSSHConnection):
            +    """Brocade Fabric OS support"""
            +
            +    def __init__(self, **kwargs):
            +        if kwargs.get("default_enter") is None:
            +            kwargs["default_enter"] = "\r"
            +        return super().__init__(**kwargs)
            +
            +    def session_preparation(self):
            +        self._test_channel_read()
            +        self.set_base_prompt()
            +
            +        # Clear the read buffer
            +        time.sleep(0.3 * self.global_delay_factor)
            +        self.clear_buffer()
            +
            +    def check_enable_mode(self, check_string=">"):
            +        """No enable mode. Always return True."""
            +        return True
            +
            +    def enable(self, cmd="", pattern="", enable_pattern=None, re_flags=re.IGNORECASE):
            +        """No Enable Mode."""
            +        return ""
            +
            +    def exit_enable_mode(self, exit_command=""):
            +        """No Enable Mode."""
            +        return ""
            +
            +    def check_config_mode(self, check_string="", pattern=""):
            +        return True
            +
            +    def config_mode(self, config_command="", pattern="", re_flags=0):
            +        """No config mode."""
            +        return ""
            +
            +    def exit_config_mode(self, exit_config="", pattern="#"):
            +        return ""
            +
            +

            Ancestors

            + +

            Methods

            +
            +
            +def check_enable_mode(self, check_string='>') +
            +
            +

            No enable mode. Always return True.

            +
            +Source code +
            def check_enable_mode(self, check_string=">"):
            +    """No enable mode. Always return True."""
            +    return True
            +
            +
            +
            +def config_mode(self, config_command='', pattern='', re_flags=0) +
            +
            +

            No config mode.

            +
            +Source code +
            def config_mode(self, config_command="", pattern="", re_flags=0):
            +    """No config mode."""
            +    return ""
            +
            +
            +
            +def enable(self, cmd='', pattern='', enable_pattern=None, re_flags=) +
            +
            +

            No Enable Mode.

            +
            +Source code +
            def enable(self, cmd="", pattern="", enable_pattern=None, re_flags=re.IGNORECASE):
            +    """No Enable Mode."""
            +    return ""
            +
            +
            +
            +def exit_enable_mode(self, exit_command='') +
            +
            +

            No Enable Mode.

            +
            +Source code +
            def exit_enable_mode(self, exit_command=""):
            +    """No Enable Mode."""
            +    return ""
            +
            +
            +
            +

            Inherited members

            + +
            +
            +
            +
            + +
            + + + + + \ No newline at end of file diff --git a/docs/netmiko/calix/calix_b6.html b/docs/netmiko/calix/calix_b6.html index b7fd423cb..b8742242d 100644 --- a/docs/netmiko/calix/calix_b6.html +++ b/docs/netmiko/calix/calix_b6.html @@ -433,6 +433,7 @@

            Inherited members

          • read_until_pattern
          • read_until_prompt
          • read_until_prompt_or_pattern
          • +
          • run_ttp
          • save_config
          • select_delay_factor
          • send_command
          • @@ -652,6 +653,7 @@

            Inherited members

          • read_until_pattern
          • read_until_prompt
          • read_until_prompt_or_pattern
          • +
          • run_ttp
          • save_config
          • select_delay_factor
          • send_command
          • @@ -850,6 +852,7 @@

            Inherited members

          • read_until_pattern
          • read_until_prompt
          • read_until_prompt_or_pattern
          • +
          • run_ttp
          • save_config
          • select_delay_factor
          • send_command
          • diff --git a/docs/netmiko/calix/index.html b/docs/netmiko/calix/index.html index 4b3118726..16f1c1cc8 100644 --- a/docs/netmiko/calix/index.html +++ b/docs/netmiko/calix/index.html @@ -243,6 +243,7 @@

            Inherited members

          • read_until_pattern
          • read_until_prompt
          • read_until_prompt_or_pattern
          • +
          • run_ttp
          • save_config
          • select_delay_factor
          • send_command
          • @@ -441,6 +442,7 @@

            Inherited members

          • read_until_pattern
          • read_until_prompt
          • read_until_prompt_or_pattern
          • +
          • run_ttp
          • save_config
          • select_delay_factor
          • send_command
          • diff --git a/docs/netmiko/cdot/cdot_cros_ssh.html b/docs/netmiko/cdot/cdot_cros_ssh.html new file mode 100644 index 000000000..4ad2f6f79 --- /dev/null +++ b/docs/netmiko/cdot/cdot_cros_ssh.html @@ -0,0 +1,605 @@ + + + + + + +netmiko.cdot.cdot_cros_ssh API documentation + + + + + + + + + +
            +
            +
            +

            Module netmiko.cdot.cdot_cros_ssh

            +
            +
            +
            +Source code +
            #!/usr/bin/env python
            +# CDOT = Centre for Development of Telematics, India
            +# CROS = CDOT Router OS
            +# Script: cros_ssh.py
            +# Author: Maloy Ghosh <mghosh@cdot.in>
            +#
            +# Purpose: Provide basic SSH connection to CROS based router products
            +
            +from netmiko.cisco_base_connection import CiscoBaseConnection
            +import time
            +
            +
            +class CdotCrosSSH(CiscoBaseConnection):
            +    """Implement methods for interacting with CROS network devices."""
            +
            +    def session_preparation(self):
            +        """Prepare the session after the connection has been established."""
            +        self._test_channel_read()
            +        self.set_base_prompt()
            +        self._disable_complete_on_space()
            +        self.disable_paging(command="screen-length 0")
            +        self.set_terminal_width(command="screen-width 511")
            +        time.sleep(0.3 * self.global_delay_factor)
            +        self.clear_buffer()
            +        return
            +
            +    def send_config_set(self, config_commands=None, exit_config_mode=False, **kwargs):
            +        """CROS requires you not exit from configuration mode."""
            +        return super().send_config_set(
            +            config_commands=config_commands, exit_config_mode=exit_config_mode, **kwargs
            +        )
            +
            +    def check_config_mode(self, check_string=")#", pattern=r"[#\$]"):
            +        """Checks if device is in configuration mode"""
            +        return super().check_config_mode(check_string=check_string, pattern=pattern)
            +
            +    def config_mode(self, config_command="config", pattern=""):
            +        """Enter configuration mode."""
            +        return super().config_mode(config_command=config_command, pattern=pattern)
            +
            +    def commit(self, comment="", delay_factor=1, and_quit=True):
            +        """
            +        Commit the candidate configuration.
            +
            +        Commit the entered configuration. Raise an error and return the failure
            +        if the commit fails.
            +
            +        default:
            +           command_string = commit
            +        comment:
            +           command_string = commit comment <comment>
            +
            +        """
            +
            +        delay_factor = self.select_delay_factor(delay_factor)
            +
            +        command_string = "commit"
            +        commit_marker = ["Commit complete", "No modifications to commit"]
            +
            +        if comment:
            +            if '"' in comment:
            +                raise ValueError("Invalid comment contains double quote")
            +            command_string += f' comment "{comment}"'
            +
            +        output = self.config_mode()
            +        output += self.send_command(
            +            command_string,
            +            strip_prompt=False,
            +            strip_command=True,
            +            delay_factor=delay_factor,
            +        )
            +
            +        if not (any(x in output for x in commit_marker)):
            +            raise ValueError(f"Commit failed with the following errors:\n\n{output}")
            +        if and_quit:
            +            self.exit_config_mode()
            +        return output
            +
            +    def check_enable_mode(self, *args, **kwargs):
            +        """No enable mode on CROS."""
            +        return True
            +
            +    def enable(self, *args, **kwargs):
            +        """No enable mode on CROS."""
            +        return ""
            +
            +    def exit_enable_mode(self, *args, **kwargs):
            +        """No enable mode on CROS."""
            +        return ""
            +
            +    def _disable_complete_on_space(self):
            +        """
            +        CROS tries to auto complete commands when you type a "space" character.
            +
            +        This is a bad idea for automation as what your program is sending no longer matches
            +        the command echo from the device. So we disable this behavior.
            +        """
            +        delay_factor = self.select_delay_factor(delay_factor=0)
            +        time.sleep(delay_factor * 0.1)
            +        command = "complete-on-space false"
            +        self.write_channel(self.normalize_cmd(command))
            +        time.sleep(delay_factor * 0.1)
            +        output = self.read_channel()
            +        return output
            +
            +
            +
            +
            +
            +
            +
            +
            +
            +

            Classes

            +
            +
            +class CdotCrosSSH +(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=5, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=False, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True) +
            +
            +

            Implement methods for interacting with CROS network devices.

            +
                Initialize attributes for establishing connection to target device.
            +
            +    :param ip: IP address of target device. Not required if `host` is
            +        provided.
            +    :type ip: str
            +
            +    :param host: Hostname of target device. Not required if `ip` is
            +            provided.
            +    :type host: str
            +
            +    :param username: Username to authenticate against target device if
            +            required.
            +    :type username: str
            +
            +    :param password: Password to authenticate against target device if
            +            required.
            +    :type password: str
            +
            +    :param secret: The enable password if target device requires one.
            +    :type secret: str
            +
            +    :param port: The destination port used to connect to the target
            +            device.
            +    :type port: int or None
            +
            +    :param device_type: Class selection based on device type.
            +    :type device_type: str
            +
            +    :param verbose: Enable additional messages to standard output.
            +    :type verbose: bool
            +
            +    :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
            +    :type global_delay_factor: int
            +
            +    :param use_keys: Connect to target device using SSH keys.
            +    :type use_keys: bool
            +
            +    :param key_file: Filename path of the SSH key file to use.
            +    :type key_file: str
            +
            +    :param pkey: SSH key object to use.
            +    :type pkey: paramiko.PKey
            +
            +    :param passphrase: Passphrase to use for encrypted key; password will be used for key
            +            decryption if not specified.
            +    :type passphrase: str
            +
            +    :param allow_agent: Enable use of SSH key-agent.
            +    :type allow_agent: bool
            +
            +    :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
            +            means unknown SSH host keys will be accepted).
            +    :type ssh_strict: bool
            +
            +    :param system_host_keys: Load host keys from the users known_hosts file.
            +    :type system_host_keys: bool
            +    :param alt_host_keys: If `True` host keys will be loaded from the file specified in
            +            alt_key_file.
            +    :type alt_host_keys: bool
            +
            +    :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
            +    :type alt_key_file: str
            +
            +    :param ssh_config_file: File name of OpenSSH configuration file.
            +    :type ssh_config_file: str
            +
            +    :param timeout: Connection timeout.
            +    :type timeout: float
            +
            +    :param session_timeout: Set a timeout for parallel requests.
            +    :type session_timeout: float
            +
            +    :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
            +    :type auth_timeout: float
            +
            +    :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
            +    :type banner_timeout: float
            +
            +    :param keepalive: Send SSH keepalive packets at a specific interval, in seconds.
            +            Currently defaults to 0, for backwards compatibility (it will not attempt
            +            to keep the connection alive).
            +    :type keepalive: int
            +
            +    :param default_enter: Character(s) to send to correspond to enter key (default:
            +
            +

            ). +:type default_enter: str

            +
                :param response_return: Character(s) to use in normalized return data to represent
            +            enter key (default:
            +
            +

            ) +:type response_return: str

            +
                :param fast_cli: Provide a way to optimize for performance. Converts select_delay_factor
            +            to select smallest of global and specific. Sets default global_delay_factor to .1
            +            (default: False)
            +    :type fast_cli: boolean
            +
            +    :param session_log: File path or BufferedIOBase subclass object to write the session log to.
            +    :type session_log: str
            +
            +    :param session_log_record_writes: The session log generally only records channel reads due
            +            to eliminate command duplication due to command echo. You can enable this if you
            +            want to record both channel reads and channel writes in the log (default: False).
            +    :type session_log_record_writes: boolean
            +
            +    :param session_log_file_mode: "write" or "append" for session_log file mode
            +            (default: "write")
            +    :type session_log_file_mode: str
            +
            +    :param allow_auto_change: Allow automatic configuration changes for terminal settings.
            +            (default: False)
            +    :type allow_auto_change: bool
            +
            +    :param encoding: Encoding to be used when writing bytes to the output channel.
            +            (default: ascii)
            +    :type encoding: str
            +
            +    :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
            +            communication to the target host (default: None).
            +    :type sock: socket
            +
            +    :param global_cmd_verify: Control whether command echo verification is enabled or disabled
            +            (default: None). Global attribute takes precedence over function `cmd_verify`
            +            argument. Value of `None` indicates to use function `cmd_verify` argument.
            +    :type global_cmd_verify: bool|None
            +
            +    :param auto_connect: Control whether Netmiko automatically establishes the connection as
            +            part of the object creation (default: True).
            +    :type auto_connect: bool
            +
            +
            +Source code +
            class CdotCrosSSH(CiscoBaseConnection):
            +    """Implement methods for interacting with CROS network devices."""
            +
            +    def session_preparation(self):
            +        """Prepare the session after the connection has been established."""
            +        self._test_channel_read()
            +        self.set_base_prompt()
            +        self._disable_complete_on_space()
            +        self.disable_paging(command="screen-length 0")
            +        self.set_terminal_width(command="screen-width 511")
            +        time.sleep(0.3 * self.global_delay_factor)
            +        self.clear_buffer()
            +        return
            +
            +    def send_config_set(self, config_commands=None, exit_config_mode=False, **kwargs):
            +        """CROS requires you not exit from configuration mode."""
            +        return super().send_config_set(
            +            config_commands=config_commands, exit_config_mode=exit_config_mode, **kwargs
            +        )
            +
            +    def check_config_mode(self, check_string=")#", pattern=r"[#\$]"):
            +        """Checks if device is in configuration mode"""
            +        return super().check_config_mode(check_string=check_string, pattern=pattern)
            +
            +    def config_mode(self, config_command="config", pattern=""):
            +        """Enter configuration mode."""
            +        return super().config_mode(config_command=config_command, pattern=pattern)
            +
            +    def commit(self, comment="", delay_factor=1, and_quit=True):
            +        """
            +        Commit the candidate configuration.
            +
            +        Commit the entered configuration. Raise an error and return the failure
            +        if the commit fails.
            +
            +        default:
            +           command_string = commit
            +        comment:
            +           command_string = commit comment <comment>
            +
            +        """
            +
            +        delay_factor = self.select_delay_factor(delay_factor)
            +
            +        command_string = "commit"
            +        commit_marker = ["Commit complete", "No modifications to commit"]
            +
            +        if comment:
            +            if '"' in comment:
            +                raise ValueError("Invalid comment contains double quote")
            +            command_string += f' comment "{comment}"'
            +
            +        output = self.config_mode()
            +        output += self.send_command(
            +            command_string,
            +            strip_prompt=False,
            +            strip_command=True,
            +            delay_factor=delay_factor,
            +        )
            +
            +        if not (any(x in output for x in commit_marker)):
            +            raise ValueError(f"Commit failed with the following errors:\n\n{output}")
            +        if and_quit:
            +            self.exit_config_mode()
            +        return output
            +
            +    def check_enable_mode(self, *args, **kwargs):
            +        """No enable mode on CROS."""
            +        return True
            +
            +    def enable(self, *args, **kwargs):
            +        """No enable mode on CROS."""
            +        return ""
            +
            +    def exit_enable_mode(self, *args, **kwargs):
            +        """No enable mode on CROS."""
            +        return ""
            +
            +    def _disable_complete_on_space(self):
            +        """
            +        CROS tries to auto complete commands when you type a "space" character.
            +
            +        This is a bad idea for automation as what your program is sending no longer matches
            +        the command echo from the device. So we disable this behavior.
            +        """
            +        delay_factor = self.select_delay_factor(delay_factor=0)
            +        time.sleep(delay_factor * 0.1)
            +        command = "complete-on-space false"
            +        self.write_channel(self.normalize_cmd(command))
            +        time.sleep(delay_factor * 0.1)
            +        output = self.read_channel()
            +        return output
            +
            +

            Ancestors

            + +

            Methods

            +
            +
            +def check_config_mode(self, check_string=')#', pattern='[#\\$]') +
            +
            +

            Checks if device is in configuration mode

            +
            +Source code +
            def check_config_mode(self, check_string=")#", pattern=r"[#\$]"):
            +    """Checks if device is in configuration mode"""
            +    return super().check_config_mode(check_string=check_string, pattern=pattern)
            +
            +
            +
            +def check_enable_mode(self, *args, **kwargs) +
            +
            +

            No enable mode on CROS.

            +
            +Source code +
            def check_enable_mode(self, *args, **kwargs):
            +    """No enable mode on CROS."""
            +    return True
            +
            +
            +
            +def commit(self, comment='', delay_factor=1, and_quit=True) +
            +
            +

            Commit the candidate configuration.

            +

            Commit the entered configuration. Raise an error and return the failure +if the commit fails.

            +

            default: +command_string = commit +comment: +command_string = commit comment

            +
            +Source code +
            def commit(self, comment="", delay_factor=1, and_quit=True):
            +    """
            +    Commit the candidate configuration.
            +
            +    Commit the entered configuration. Raise an error and return the failure
            +    if the commit fails.
            +
            +    default:
            +       command_string = commit
            +    comment:
            +       command_string = commit comment <comment>
            +
            +    """
            +
            +    delay_factor = self.select_delay_factor(delay_factor)
            +
            +    command_string = "commit"
            +    commit_marker = ["Commit complete", "No modifications to commit"]
            +
            +    if comment:
            +        if '"' in comment:
            +            raise ValueError("Invalid comment contains double quote")
            +        command_string += f' comment "{comment}"'
            +
            +    output = self.config_mode()
            +    output += self.send_command(
            +        command_string,
            +        strip_prompt=False,
            +        strip_command=True,
            +        delay_factor=delay_factor,
            +    )
            +
            +    if not (any(x in output for x in commit_marker)):
            +        raise ValueError(f"Commit failed with the following errors:\n\n{output}")
            +    if and_quit:
            +        self.exit_config_mode()
            +    return output
            +
            +
            +
            +def config_mode(self, config_command='config', pattern='') +
            +
            +

            Enter configuration mode.

            +
            +Source code +
            def config_mode(self, config_command="config", pattern=""):
            +    """Enter configuration mode."""
            +    return super().config_mode(config_command=config_command, pattern=pattern)
            +
            +
            +
            +def enable(self, *args, **kwargs) +
            +
            +

            No enable mode on CROS.

            +
            +Source code +
            def enable(self, *args, **kwargs):
            +    """No enable mode on CROS."""
            +    return ""
            +
            +
            +
            +def exit_enable_mode(self, *args, **kwargs) +
            +
            +

            No enable mode on CROS.

            +
            +Source code +
            def exit_enable_mode(self, *args, **kwargs):
            +    """No enable mode on CROS."""
            +    return ""
            +
            +
            +
            +def send_config_set(self, config_commands=None, exit_config_mode=False, **kwargs) +
            +
            +

            CROS requires you not exit from configuration mode.

            +
            +Source code +
            def send_config_set(self, config_commands=None, exit_config_mode=False, **kwargs):
            +    """CROS requires you not exit from configuration mode."""
            +    return super().send_config_set(
            +        config_commands=config_commands, exit_config_mode=exit_config_mode, **kwargs
            +    )
            +
            +
            +
            +def session_preparation(self) +
            +
            +

            Prepare the session after the connection has been established.

            +
            +Source code +
            def session_preparation(self):
            +    """Prepare the session after the connection has been established."""
            +    self._test_channel_read()
            +    self.set_base_prompt()
            +    self._disable_complete_on_space()
            +    self.disable_paging(command="screen-length 0")
            +    self.set_terminal_width(command="screen-width 511")
            +    time.sleep(0.3 * self.global_delay_factor)
            +    self.clear_buffer()
            +    return
            +
            +
            +
            +

            Inherited members

            + +
            +
            +
            +
            + +
            + + + + + \ No newline at end of file diff --git a/docs/netmiko/cdot/index.html b/docs/netmiko/cdot/index.html new file mode 100644 index 000000000..4f80bf97e --- /dev/null +++ b/docs/netmiko/cdot/index.html @@ -0,0 +1,516 @@ + + + + + + +netmiko.cdot API documentation + + + + + + + + + +
            +
            +
            +

            Module netmiko.cdot

            +
            +
            +
            +Source code +
            from netmiko.cdot.cdot_cros_ssh import CdotCrosSSH
            +
            +__all__ = ["CdotCrosSSH"]
            +
            +
            +
            +

            Sub-modules

            +
            +
            netmiko.cdot.cdot_cros_ssh
            +
            +
            +
            +
            +
            +
            +
            +
            +
            +
            +

            Classes

            +
            +
            +class CdotCrosSSH +(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=5, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=False, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True) +
            +
            +

            Implement methods for interacting with CROS network devices.

            +
                Initialize attributes for establishing connection to target device.
            +
            +    :param ip: IP address of target device. Not required if `host` is
            +        provided.
            +    :type ip: str
            +
            +    :param host: Hostname of target device. Not required if `ip` is
            +            provided.
            +    :type host: str
            +
            +    :param username: Username to authenticate against target device if
            +            required.
            +    :type username: str
            +
            +    :param password: Password to authenticate against target device if
            +            required.
            +    :type password: str
            +
            +    :param secret: The enable password if target device requires one.
            +    :type secret: str
            +
            +    :param port: The destination port used to connect to the target
            +            device.
            +    :type port: int or None
            +
            +    :param device_type: Class selection based on device type.
            +    :type device_type: str
            +
            +    :param verbose: Enable additional messages to standard output.
            +    :type verbose: bool
            +
            +    :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
            +    :type global_delay_factor: int
            +
            +    :param use_keys: Connect to target device using SSH keys.
            +    :type use_keys: bool
            +
            +    :param key_file: Filename path of the SSH key file to use.
            +    :type key_file: str
            +
            +    :param pkey: SSH key object to use.
            +    :type pkey: paramiko.PKey
            +
            +    :param passphrase: Passphrase to use for encrypted key; password will be used for key
            +            decryption if not specified.
            +    :type passphrase: str
            +
            +    :param allow_agent: Enable use of SSH key-agent.
            +    :type allow_agent: bool
            +
            +    :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
            +            means unknown SSH host keys will be accepted).
            +    :type ssh_strict: bool
            +
            +    :param system_host_keys: Load host keys from the users known_hosts file.
            +    :type system_host_keys: bool
            +    :param alt_host_keys: If `True` host keys will be loaded from the file specified in
            +            alt_key_file.
            +    :type alt_host_keys: bool
            +
            +    :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
            +    :type alt_key_file: str
            +
            +    :param ssh_config_file: File name of OpenSSH configuration file.
            +    :type ssh_config_file: str
            +
            +    :param timeout: Connection timeout.
            +    :type timeout: float
            +
            +    :param session_timeout: Set a timeout for parallel requests.
            +    :type session_timeout: float
            +
            +    :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
            +    :type auth_timeout: float
            +
            +    :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
            +    :type banner_timeout: float
            +
            +    :param keepalive: Send SSH keepalive packets at a specific interval, in seconds.
            +            Currently defaults to 0, for backwards compatibility (it will not attempt
            +            to keep the connection alive).
            +    :type keepalive: int
            +
            +    :param default_enter: Character(s) to send to correspond to enter key (default:
            +
            +

            ). +:type default_enter: str

            +
                :param response_return: Character(s) to use in normalized return data to represent
            +            enter key (default:
            +
            +

            ) +:type response_return: str

            +
                :param fast_cli: Provide a way to optimize for performance. Converts select_delay_factor
            +            to select smallest of global and specific. Sets default global_delay_factor to .1
            +            (default: False)
            +    :type fast_cli: boolean
            +
            +    :param session_log: File path or BufferedIOBase subclass object to write the session log to.
            +    :type session_log: str
            +
            +    :param session_log_record_writes: The session log generally only records channel reads due
            +            to eliminate command duplication due to command echo. You can enable this if you
            +            want to record both channel reads and channel writes in the log (default: False).
            +    :type session_log_record_writes: boolean
            +
            +    :param session_log_file_mode: "write" or "append" for session_log file mode
            +            (default: "write")
            +    :type session_log_file_mode: str
            +
            +    :param allow_auto_change: Allow automatic configuration changes for terminal settings.
            +            (default: False)
            +    :type allow_auto_change: bool
            +
            +    :param encoding: Encoding to be used when writing bytes to the output channel.
            +            (default: ascii)
            +    :type encoding: str
            +
            +    :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
            +            communication to the target host (default: None).
            +    :type sock: socket
            +
            +    :param global_cmd_verify: Control whether command echo verification is enabled or disabled
            +            (default: None). Global attribute takes precedence over function `cmd_verify`
            +            argument. Value of `None` indicates to use function `cmd_verify` argument.
            +    :type global_cmd_verify: bool|None
            +
            +    :param auto_connect: Control whether Netmiko automatically establishes the connection as
            +            part of the object creation (default: True).
            +    :type auto_connect: bool
            +
            +
            +Source code +
            class CdotCrosSSH(CiscoBaseConnection):
            +    """Implement methods for interacting with CROS network devices."""
            +
            +    def session_preparation(self):
            +        """Prepare the session after the connection has been established."""
            +        self._test_channel_read()
            +        self.set_base_prompt()
            +        self._disable_complete_on_space()
            +        self.disable_paging(command="screen-length 0")
            +        self.set_terminal_width(command="screen-width 511")
            +        time.sleep(0.3 * self.global_delay_factor)
            +        self.clear_buffer()
            +        return
            +
            +    def send_config_set(self, config_commands=None, exit_config_mode=False, **kwargs):
            +        """CROS requires you not exit from configuration mode."""
            +        return super().send_config_set(
            +            config_commands=config_commands, exit_config_mode=exit_config_mode, **kwargs
            +        )
            +
            +    def check_config_mode(self, check_string=")#", pattern=r"[#\$]"):
            +        """Checks if device is in configuration mode"""
            +        return super().check_config_mode(check_string=check_string, pattern=pattern)
            +
            +    def config_mode(self, config_command="config", pattern=""):
            +        """Enter configuration mode."""
            +        return super().config_mode(config_command=config_command, pattern=pattern)
            +
            +    def commit(self, comment="", delay_factor=1, and_quit=True):
            +        """
            +        Commit the candidate configuration.
            +
            +        Commit the entered configuration. Raise an error and return the failure
            +        if the commit fails.
            +
            +        default:
            +           command_string = commit
            +        comment:
            +           command_string = commit comment <comment>
            +
            +        """
            +
            +        delay_factor = self.select_delay_factor(delay_factor)
            +
            +        command_string = "commit"
            +        commit_marker = ["Commit complete", "No modifications to commit"]
            +
            +        if comment:
            +            if '"' in comment:
            +                raise ValueError("Invalid comment contains double quote")
            +            command_string += f' comment "{comment}"'
            +
            +        output = self.config_mode()
            +        output += self.send_command(
            +            command_string,
            +            strip_prompt=False,
            +            strip_command=True,
            +            delay_factor=delay_factor,
            +        )
            +
            +        if not (any(x in output for x in commit_marker)):
            +            raise ValueError(f"Commit failed with the following errors:\n\n{output}")
            +        if and_quit:
            +            self.exit_config_mode()
            +        return output
            +
            +    def check_enable_mode(self, *args, **kwargs):
            +        """No enable mode on CROS."""
            +        return True
            +
            +    def enable(self, *args, **kwargs):
            +        """No enable mode on CROS."""
            +        return ""
            +
            +    def exit_enable_mode(self, *args, **kwargs):
            +        """No enable mode on CROS."""
            +        return ""
            +
            +    def _disable_complete_on_space(self):
            +        """
            +        CROS tries to auto complete commands when you type a "space" character.
            +
            +        This is a bad idea for automation as what your program is sending no longer matches
            +        the command echo from the device. So we disable this behavior.
            +        """
            +        delay_factor = self.select_delay_factor(delay_factor=0)
            +        time.sleep(delay_factor * 0.1)
            +        command = "complete-on-space false"
            +        self.write_channel(self.normalize_cmd(command))
            +        time.sleep(delay_factor * 0.1)
            +        output = self.read_channel()
            +        return output
            +
            +

            Ancestors

            + +

            Methods

            +
            +
            +def check_config_mode(self, check_string=')#', pattern='[#\\$]') +
            +
            +

            Checks if device is in configuration mode

            +
            +Source code +
            def check_config_mode(self, check_string=")#", pattern=r"[#\$]"):
            +    """Checks if device is in configuration mode"""
            +    return super().check_config_mode(check_string=check_string, pattern=pattern)
            +
            +
            +
            +def check_enable_mode(self, *args, **kwargs) +
            +
            +

            No enable mode on CROS.

            +
            +Source code +
            def check_enable_mode(self, *args, **kwargs):
            +    """No enable mode on CROS."""
            +    return True
            +
            +
            +
            +def commit(self, comment='', delay_factor=1, and_quit=True) +
            +
            +

            Commit the candidate configuration.

            +

            Commit the entered configuration. Raise an error and return the failure +if the commit fails.

            +

            default: +command_string = commit +comment: +command_string = commit comment

            +
            +Source code +
            def commit(self, comment="", delay_factor=1, and_quit=True):
            +    """
            +    Commit the candidate configuration.
            +
            +    Commit the entered configuration. Raise an error and return the failure
            +    if the commit fails.
            +
            +    default:
            +       command_string = commit
            +    comment:
            +       command_string = commit comment <comment>
            +
            +    """
            +
            +    delay_factor = self.select_delay_factor(delay_factor)
            +
            +    command_string = "commit"
            +    commit_marker = ["Commit complete", "No modifications to commit"]
            +
            +    if comment:
            +        if '"' in comment:
            +            raise ValueError("Invalid comment contains double quote")
            +        command_string += f' comment "{comment}"'
            +
            +    output = self.config_mode()
            +    output += self.send_command(
            +        command_string,
            +        strip_prompt=False,
            +        strip_command=True,
            +        delay_factor=delay_factor,
            +    )
            +
            +    if not (any(x in output for x in commit_marker)):
            +        raise ValueError(f"Commit failed with the following errors:\n\n{output}")
            +    if and_quit:
            +        self.exit_config_mode()
            +    return output
            +
            +
            +
            +def config_mode(self, config_command='config', pattern='') +
            +
            +

            Enter configuration mode.

            +
            +Source code +
            def config_mode(self, config_command="config", pattern=""):
            +    """Enter configuration mode."""
            +    return super().config_mode(config_command=config_command, pattern=pattern)
            +
            +
            +
            +def enable(self, *args, **kwargs) +
            +
            +

            No enable mode on CROS.

            +
            +Source code +
            def enable(self, *args, **kwargs):
            +    """No enable mode on CROS."""
            +    return ""
            +
            +
            +
            +def exit_enable_mode(self, *args, **kwargs) +
            +
            +

            No enable mode on CROS.

            +
            +Source code +
            def exit_enable_mode(self, *args, **kwargs):
            +    """No enable mode on CROS."""
            +    return ""
            +
            +
            +
            +def send_config_set(self, config_commands=None, exit_config_mode=False, **kwargs) +
            +
            +

            CROS requires you not exit from configuration mode.

            +
            +Source code +
            def send_config_set(self, config_commands=None, exit_config_mode=False, **kwargs):
            +    """CROS requires you not exit from configuration mode."""
            +    return super().send_config_set(
            +        config_commands=config_commands, exit_config_mode=exit_config_mode, **kwargs
            +    )
            +
            +
            +
            +def session_preparation(self) +
            +
            +

            Prepare the session after the connection has been established.

            +
            +Source code +
            def session_preparation(self):
            +    """Prepare the session after the connection has been established."""
            +    self._test_channel_read()
            +    self.set_base_prompt()
            +    self._disable_complete_on_space()
            +    self.disable_paging(command="screen-length 0")
            +    self.set_terminal_width(command="screen-width 511")
            +    time.sleep(0.3 * self.global_delay_factor)
            +    self.clear_buffer()
            +    return
            +
            +
            +
            +

            Inherited members

            + +
            +
            +
            +
            + +
            + + + + + \ No newline at end of file diff --git a/docs/netmiko/centec/centec_os.html b/docs/netmiko/centec/centec_os.html index 3ef16b736..4b1c21a02 100644 --- a/docs/netmiko/centec/centec_os.html +++ b/docs/netmiko/centec/centec_os.html @@ -289,6 +289,7 @@

            Inherited members

          • read_until_pattern
          • read_until_prompt
          • read_until_prompt_or_pattern
          • +
          • run_ttp
          • select_delay_factor
          • send_command
          • send_command_expect
          • @@ -483,6 +484,7 @@

            Inherited members

          • read_until_pattern
          • read_until_prompt
          • read_until_prompt_or_pattern
          • +
          • run_ttp
          • save_config
          • select_delay_factor
          • send_command
          • @@ -679,6 +681,7 @@

            Inherited members

          • read_until_pattern
          • read_until_prompt
          • read_until_prompt_or_pattern
          • +
          • run_ttp
          • save_config
          • select_delay_factor
          • send_command
          • diff --git a/docs/netmiko/centec/index.html b/docs/netmiko/centec/index.html index 5aac05519..bdd6aa767 100644 --- a/docs/netmiko/centec/index.html +++ b/docs/netmiko/centec/index.html @@ -218,6 +218,7 @@

            Inherited members

          • read_until_pattern
          • read_until_prompt
          • read_until_prompt_or_pattern
          • +
          • run_ttp
          • save_config
          • select_delay_factor
          • send_command
          • @@ -414,6 +415,7 @@

            Inherited members

          • read_until_pattern
          • read_until_prompt
          • read_until_prompt_or_pattern
          • +
          • run_ttp
          • save_config
          • select_delay_factor
          • send_command
          • diff --git a/docs/netmiko/checkpoint/checkpoint_gaia_ssh.html b/docs/netmiko/checkpoint/checkpoint_gaia_ssh.html index c5a3f9123..bf196d8fc 100644 --- a/docs/netmiko/checkpoint/checkpoint_gaia_ssh.html +++ b/docs/netmiko/checkpoint/checkpoint_gaia_ssh.html @@ -315,6 +315,7 @@

            Inherited members

          • read_until_pattern
          • read_until_prompt
          • read_until_prompt_or_pattern
          • +
          • run_ttp
          • save_config
          • select_delay_factor
          • send_command
          • diff --git a/docs/netmiko/checkpoint/index.html b/docs/netmiko/checkpoint/index.html index 526163f23..51284305d 100644 --- a/docs/netmiko/checkpoint/index.html +++ b/docs/netmiko/checkpoint/index.html @@ -291,6 +291,7 @@

            Inherited members

          • read_until_pattern
          • read_until_prompt
          • read_until_prompt_or_pattern
          • +
          • run_ttp
          • save_config
          • select_delay_factor
          • send_command
          • diff --git a/docs/netmiko/ciena/ciena_saos.html b/docs/netmiko/ciena/ciena_saos.html index a484ff1dd..4e33c21ad 100644 --- a/docs/netmiko/ciena/ciena_saos.html +++ b/docs/netmiko/ciena/ciena_saos.html @@ -566,6 +566,7 @@

            Inherited members

          • read_until_pattern
          • read_until_prompt
          • read_until_prompt_or_pattern
          • +
          • run_ttp
          • select_delay_factor
          • send_command
          • send_command_expect
          • @@ -997,6 +998,7 @@

            Inherited members

          • read_until_pattern
          • read_until_prompt
          • read_until_prompt_or_pattern
          • +
          • run_ttp
          • save_config
          • select_delay_factor
          • send_command
          • @@ -1197,6 +1199,7 @@

            Inherited members

          • read_until_pattern
          • read_until_prompt
          • read_until_prompt_or_pattern
          • +
          • run_ttp
          • save_config
          • select_delay_factor
          • send_command
          • diff --git a/docs/netmiko/ciena/index.html b/docs/netmiko/ciena/index.html index b556618e6..608b89c15 100644 --- a/docs/netmiko/ciena/index.html +++ b/docs/netmiko/ciena/index.html @@ -458,6 +458,7 @@

            Inherited members

          • read_until_pattern
          • read_until_prompt
          • read_until_prompt_or_pattern
          • +
          • run_ttp
          • save_config
          • select_delay_factor
          • send_command
          • @@ -658,6 +659,7 @@

            Inherited members

          • read_until_pattern
          • read_until_prompt
          • read_until_prompt_or_pattern
          • +
          • run_ttp
          • save_config
          • select_delay_factor
          • send_command
          • diff --git a/docs/netmiko/cisco/cisco_asa_ssh.html b/docs/netmiko/cisco/cisco_asa_ssh.html index cddb53cd7..c352342c4 100644 --- a/docs/netmiko/cisco/cisco_asa_ssh.html +++ b/docs/netmiko/cisco/cisco_asa_ssh.html @@ -39,23 +39,16 @@

            Module netmiko.cisco.cisco_asa_ssh

            kwargs.setdefault("allow_auto_change", True) return super().__init__(*args, **kwargs) - def check_config_mode(self, check_string=")#", pattern=r"[>\#]"): - return super().check_config_mode(check_string=check_string, pattern=pattern) - - def enable( - self, - cmd="enable", - pattern="ssword", - enable_pattern=r"\#", - re_flags=re.IGNORECASE, - ): - return super().enable( - cmd=cmd, pattern=pattern, enable_pattern=enable_pattern, re_flags=re_flags - ) - def session_preparation(self): """Prepare the session after the connection has been established.""" + # Make sure the ASA is ready + command = "show curpriv\n" + self.write_channel(command) + self.read_until_pattern(pattern=re.escape(command.strip())) + + # The 'enable' call requires the base_prompt to be set. + self.set_base_prompt() if self.secret: self.enable() else: @@ -74,6 +67,20 @@

            Module netmiko.cisco.cisco_asa_ssh

            self.set_base_prompt() + def check_config_mode(self, check_string=")#", pattern=r"[>\#]"): + return super().check_config_mode(check_string=check_string, pattern=pattern) + + def enable( + self, + cmd="enable", + pattern="ssword", + enable_pattern=r"\#", + re_flags=re.IGNORECASE, + ): + return super().enable( + cmd=cmd, pattern=pattern, enable_pattern=enable_pattern, re_flags=re_flags + ) + def send_command_timing(self, *args, **kwargs): """ If the ASA is in multi-context mode, then the base_prompt needs to be @@ -383,23 +390,16 @@

            Inherited members

            kwargs.setdefault("allow_auto_change", True) return super().__init__(*args, **kwargs) - def check_config_mode(self, check_string=")#", pattern=r"[>\#]"): - return super().check_config_mode(check_string=check_string, pattern=pattern) - - def enable( - self, - cmd="enable", - pattern="ssword", - enable_pattern=r"\#", - re_flags=re.IGNORECASE, - ): - return super().enable( - cmd=cmd, pattern=pattern, enable_pattern=enable_pattern, re_flags=re_flags - ) - def session_preparation(self): """Prepare the session after the connection has been established.""" + # Make sure the ASA is ready + command = "show curpriv\n" + self.write_channel(command) + self.read_until_pattern(pattern=re.escape(command.strip())) + + # The 'enable' call requires the base_prompt to be set. + self.set_base_prompt() if self.secret: self.enable() else: @@ -418,6 +418,20 @@

            Inherited members

            self.set_base_prompt() + def check_config_mode(self, check_string=")#", pattern=r"[>\#]"): + return super().check_config_mode(check_string=check_string, pattern=pattern) + + def enable( + self, + cmd="enable", + pattern="ssword", + enable_pattern=r"\#", + re_flags=re.IGNORECASE, + ): + return super().enable( + cmd=cmd, pattern=pattern, enable_pattern=enable_pattern, re_flags=re_flags + ) + def send_command_timing(self, *args, **kwargs): """ If the ASA is in multi-context mode, then the base_prompt needs to be @@ -681,6 +695,13 @@

            Methods

            def session_preparation(self):
                 """Prepare the session after the connection has been established."""
             
            +    # Make sure the ASA is ready
            +    command = "show curpriv\n"
            +    self.write_channel(command)
            +    self.read_until_pattern(pattern=re.escape(command.strip()))
            +
            +    # The 'enable' call requires the base_prompt to be set.
            +    self.set_base_prompt()
                 if self.secret:
                     self.enable()
                 else:
            @@ -753,6 +774,7 @@ 

            Inherited members

          • read_until_pattern
          • read_until_prompt
          • read_until_prompt_or_pattern
          • +
          • run_ttp
          • select_delay_factor
          • send_config_from_file
          • send_config_set
          • diff --git a/docs/netmiko/cisco/cisco_ftd_ssh.html b/docs/netmiko/cisco/cisco_ftd_ssh.html index ca075cf96..d882b2366 100644 --- a/docs/netmiko/cisco/cisco_ftd_ssh.html +++ b/docs/netmiko/cisco/cisco_ftd_ssh.html @@ -317,6 +317,7 @@

            Inherited members

          • read_until_pattern
          • read_until_prompt
          • read_until_prompt_or_pattern
          • +
          • run_ttp
          • save_config
          • select_delay_factor
          • send_command
          • diff --git a/docs/netmiko/cisco/cisco_ios.html b/docs/netmiko/cisco/cisco_ios.html index c57618454..aa49abe6a 100644 --- a/docs/netmiko/cisco/cisco_ios.html +++ b/docs/netmiko/cisco/cisco_ios.html @@ -519,6 +519,7 @@

            Inherited members

          • read_until_pattern
          • read_until_prompt
          • read_until_prompt_or_pattern
          • +
          • run_ttp
          • select_delay_factor
          • send_command
          • send_command_expect
          • @@ -761,6 +762,7 @@

            Inherited members

          • read_until_pattern
          • read_until_prompt
          • read_until_prompt_or_pattern
          • +
          • run_ttp
          • save_config
          • select_delay_factor
          • send_command
          • @@ -958,6 +960,7 @@

            Inherited members

          • read_until_pattern
          • read_until_prompt
          • read_until_prompt_or_pattern
          • +
          • run_ttp
          • save_config
          • select_delay_factor
          • send_command
          • @@ -1155,6 +1158,7 @@

            Inherited members

          • read_until_pattern
          • read_until_prompt
          • read_until_prompt_or_pattern
          • +
          • run_ttp
          • save_config
          • select_delay_factor
          • send_command
          • diff --git a/docs/netmiko/cisco/cisco_nxos_ssh.html b/docs/netmiko/cisco/cisco_nxos_ssh.html index 7eef4b436..372985221 100644 --- a/docs/netmiko/cisco/cisco_nxos_ssh.html +++ b/docs/netmiko/cisco/cisco_nxos_ssh.html @@ -631,6 +631,7 @@

            Inherited members

          • read_until_pattern
          • read_until_prompt
          • read_until_prompt_or_pattern
          • +
          • run_ttp
          • save_config
          • select_delay_factor
          • send_command
          • diff --git a/docs/netmiko/cisco/cisco_s300.html b/docs/netmiko/cisco/cisco_s300.html index 4a23e2092..c53e768c4 100644 --- a/docs/netmiko/cisco/cisco_s300.html +++ b/docs/netmiko/cisco/cisco_s300.html @@ -281,6 +281,7 @@

            Inherited members

          • read_until_pattern
          • read_until_prompt
          • read_until_prompt_or_pattern
          • +
          • run_ttp
          • save_config
          • select_delay_factor
          • send_command
          • diff --git a/docs/netmiko/cisco/cisco_tp_tcce.html b/docs/netmiko/cisco/cisco_tp_tcce.html index f51acba62..ed73e9eec 100644 --- a/docs/netmiko/cisco/cisco_tp_tcce.html +++ b/docs/netmiko/cisco/cisco_tp_tcce.html @@ -496,6 +496,7 @@

            Inherited members

          • read_until_pattern
          • read_until_prompt
          • read_until_prompt_or_pattern
          • +
          • run_ttp
          • select_delay_factor
          • send_command_expect
          • send_command_timing
          • diff --git a/docs/netmiko/cisco/cisco_wlc_ssh.html b/docs/netmiko/cisco/cisco_wlc_ssh.html index ddc6c5a4c..4a0973d99 100644 --- a/docs/netmiko/cisco/cisco_wlc_ssh.html +++ b/docs/netmiko/cisco/cisco_wlc_ssh.html @@ -836,6 +836,7 @@

            Inherited members

          • read_until_pattern
          • read_until_prompt
          • read_until_prompt_or_pattern
          • +
          • run_ttp
          • select_delay_factor
          • send_command
          • send_command_expect
          • diff --git a/docs/netmiko/cisco/cisco_xr.html b/docs/netmiko/cisco/cisco_xr.html index f590b5480..19f1538f1 100644 --- a/docs/netmiko/cisco/cisco_xr.html +++ b/docs/netmiko/cisco/cisco_xr.html @@ -160,6 +160,9 @@

            Module netmiko.cisco.cisco_xr

            output += self.read_until_pattern( pattern=re.escape(exit_config.strip()) ) + # Read until we detect either an Uncommitted change or the end prompt + if not re.search(r"(Uncommitted|#$)", output): + output += self.read_until_pattern(pattern=r"(Uncommitted|#$)") if "Uncommitted changes found" in output: self.write_channel(self.normalize_cmd("no\n")) output += self.read_until_pattern(pattern=r"[>#]") @@ -508,6 +511,9 @@

            Classes

            output += self.read_until_pattern( pattern=re.escape(exit_config.strip()) ) + # Read until we detect either an Uncommitted change or the end prompt + if not re.search(r"(Uncommitted|#$)", output): + output += self.read_until_pattern(pattern=r"(Uncommitted|#$)") if "Uncommitted changes found" in output: self.write_channel(self.normalize_cmd("no\n")) output += self.read_until_pattern(pattern=r"[>#]") @@ -701,6 +707,9 @@

            Methods

            output += self.read_until_pattern( pattern=re.escape(exit_config.strip()) ) + # Read until we detect either an Uncommitted change or the end prompt + if not re.search(r"(Uncommitted|#$)", output): + output += self.read_until_pattern(pattern=r"(Uncommitted|#$)") if "Uncommitted changes found" in output: self.write_channel(self.normalize_cmd("no\n")) output += self.read_until_pattern(pattern=r"[>#]") @@ -779,6 +788,7 @@

            Inherited members

          • read_until_pattern
          • read_until_prompt
          • read_until_prompt_or_pattern
          • +
          • run_ttp
          • select_delay_factor
          • send_command
          • send_command_expect
          • @@ -1104,6 +1114,7 @@

            Inherited members

          • read_until_pattern
          • read_until_prompt
          • read_until_prompt_or_pattern
          • +
          • run_ttp
          • save_config
          • select_delay_factor
          • send_command
          • @@ -1301,6 +1312,7 @@

            Inherited members

          • read_until_pattern
          • read_until_prompt
          • read_until_prompt_or_pattern
          • +
          • run_ttp
          • save_config
          • select_delay_factor
          • send_command
          • diff --git a/docs/netmiko/cisco/index.html b/docs/netmiko/cisco/index.html index a6e756f32..be5e9fe1b 100644 --- a/docs/netmiko/cisco/index.html +++ b/docs/netmiko/cisco/index.html @@ -295,23 +295,16 @@

            Inherited members

            kwargs.setdefault("allow_auto_change", True) return super().__init__(*args, **kwargs) - def check_config_mode(self, check_string=")#", pattern=r"[>\#]"): - return super().check_config_mode(check_string=check_string, pattern=pattern) - - def enable( - self, - cmd="enable", - pattern="ssword", - enable_pattern=r"\#", - re_flags=re.IGNORECASE, - ): - return super().enable( - cmd=cmd, pattern=pattern, enable_pattern=enable_pattern, re_flags=re_flags - ) - def session_preparation(self): """Prepare the session after the connection has been established.""" + # Make sure the ASA is ready + command = "show curpriv\n" + self.write_channel(command) + self.read_until_pattern(pattern=re.escape(command.strip())) + + # The 'enable' call requires the base_prompt to be set. + self.set_base_prompt() if self.secret: self.enable() else: @@ -330,6 +323,20 @@

            Inherited members

            self.set_base_prompt() + def check_config_mode(self, check_string=")#", pattern=r"[>\#]"): + return super().check_config_mode(check_string=check_string, pattern=pattern) + + def enable( + self, + cmd="enable", + pattern="ssword", + enable_pattern=r"\#", + re_flags=re.IGNORECASE, + ): + return super().enable( + cmd=cmd, pattern=pattern, enable_pattern=enable_pattern, re_flags=re_flags + ) + def send_command_timing(self, *args, **kwargs): """ If the ASA is in multi-context mode, then the base_prompt needs to be @@ -593,6 +600,13 @@

            Methods

            def session_preparation(self):
                 """Prepare the session after the connection has been established."""
             
            +    # Make sure the ASA is ready
            +    command = "show curpriv\n"
            +    self.write_channel(command)
            +    self.read_until_pattern(pattern=re.escape(command.strip()))
            +
            +    # The 'enable' call requires the base_prompt to be set.
            +    self.set_base_prompt()
                 if self.secret:
                     self.enable()
                 else:
            @@ -665,6 +679,7 @@ 

            Inherited members

          • read_until_pattern
          • read_until_prompt
          • read_until_prompt_or_pattern
          • +
          • run_ttp
          • select_delay_factor
          • send_config_from_file
          • send_config_set
          • @@ -936,6 +951,7 @@

            Inherited members

          • read_until_pattern
          • read_until_prompt
          • read_until_prompt_or_pattern
          • +
          • run_ttp
          • save_config
          • select_delay_factor
          • send_command
          • @@ -1195,6 +1211,7 @@

            Inherited members

          • read_until_pattern
          • read_until_prompt
          • read_until_prompt_or_pattern
          • +
          • run_ttp
          • select_delay_factor
          • send_command
          • send_command_expect
          • @@ -1437,6 +1454,7 @@

            Inherited members

          • read_until_pattern
          • read_until_prompt
          • read_until_prompt_or_pattern
          • +
          • run_ttp
          • save_config
          • select_delay_factor
          • send_command
          • @@ -1634,6 +1652,7 @@

            Inherited members

          • read_until_pattern
          • read_until_prompt
          • read_until_prompt_or_pattern
          • +
          • run_ttp
          • save_config
          • select_delay_factor
          • send_command
          • @@ -1831,6 +1850,7 @@

            Inherited members

          • read_until_pattern
          • read_until_prompt
          • read_until_prompt_or_pattern
          • +
          • run_ttp
          • save_config
          • select_delay_factor
          • send_command
          • @@ -2285,6 +2305,7 @@

            Inherited members

          • read_until_pattern
          • read_until_prompt
          • read_until_prompt_or_pattern
          • +
          • run_ttp
          • save_config
          • select_delay_factor
          • send_command
          • @@ -2525,6 +2546,7 @@

            Inherited members

          • read_until_pattern
          • read_until_prompt
          • read_until_prompt_or_pattern
          • +
          • run_ttp
          • save_config
          • select_delay_factor
          • send_command
          • @@ -2919,6 +2941,7 @@

            Inherited members

          • read_until_pattern
          • read_until_prompt
          • read_until_prompt_or_pattern
          • +
          • run_ttp
          • select_delay_factor
          • send_command_expect
          • send_command_timing
          • @@ -3537,6 +3560,7 @@

            Inherited members

          • read_until_pattern
          • read_until_prompt
          • read_until_prompt_or_pattern
          • +
          • run_ttp
          • select_delay_factor
          • send_command
          • send_command_expect
          • @@ -3862,6 +3886,7 @@

            Inherited members

          • read_until_pattern
          • read_until_prompt
          • read_until_prompt_or_pattern
          • +
          • run_ttp
          • save_config
          • select_delay_factor
          • send_command
          • @@ -4059,6 +4084,7 @@

            Inherited members

          • read_until_pattern
          • read_until_prompt
          • read_until_prompt_or_pattern
          • +
          • run_ttp
          • save_config
          • select_delay_factor
          • send_command
          • diff --git a/docs/netmiko/cisco_base_connection.html b/docs/netmiko/cisco_base_connection.html index 9cecdc5fb..f4734a5ef 100644 --- a/docs/netmiko/cisco_base_connection.html +++ b/docs/netmiko/cisco_base_connection.html @@ -74,13 +74,13 @@

            Module netmiko.cisco_base_connection

            config_command=config_command, pattern=pattern, re_flags=re_flags ) - def exit_config_mode(self, exit_config="end", pattern="#"): + def exit_config_mode(self, exit_config="end", pattern=r"\#"): """Exit from configuration mode.""" return super().exit_config_mode(exit_config=exit_config, pattern=pattern) def serial_login( self, - pri_prompt_terminator=r"#\s*$", + pri_prompt_terminator=r"\#\s*$", alt_prompt_terminator=r">\s*$", username_pattern=r"(?:user:|username|login)", pwd_pattern=r"assword", @@ -105,7 +105,7 @@

            Module netmiko.cisco_base_connection

            def telnet_login( self, - pri_prompt_terminator=r"#\s*$", + pri_prompt_terminator=r"\#\s*$", alt_prompt_terminator=r">\s*$", username_pattern=r"(?:user:|username|login|user name)", pwd_pattern=r"assword", @@ -472,13 +472,13 @@

            Classes

            config_command=config_command, pattern=pattern, re_flags=re_flags ) - def exit_config_mode(self, exit_config="end", pattern="#"): + def exit_config_mode(self, exit_config="end", pattern=r"\#"): """Exit from configuration mode.""" return super().exit_config_mode(exit_config=exit_config, pattern=pattern) def serial_login( self, - pri_prompt_terminator=r"#\s*$", + pri_prompt_terminator=r"\#\s*$", alt_prompt_terminator=r">\s*$", username_pattern=r"(?:user:|username|login)", pwd_pattern=r"assword", @@ -503,7 +503,7 @@

            Classes

            def telnet_login( self, - pri_prompt_terminator=r"#\s*$", + pri_prompt_terminator=r"\#\s*$", alt_prompt_terminator=r">\s*$", username_pattern=r"(?:user:|username|login|user name)", pwd_pattern=r"assword", @@ -679,6 +679,8 @@

            Subclasses

            Methods

            @@ -785,13 +788,13 @@

            Methods

            -def exit_config_mode(self, exit_config='end', pattern='#') +def exit_config_mode(self, exit_config='end', pattern='\\#')

            Exit from configuration mode.

            Source code -
            def exit_config_mode(self, exit_config="end", pattern="#"):
            +
            def exit_config_mode(self, exit_config="end", pattern=r"\#"):
                 """Exit from configuration mode."""
                 return super().exit_config_mode(exit_config=exit_config, pattern=pattern)
            @@ -845,7 +848,7 @@

            Methods

            -def serial_login(self, pri_prompt_terminator='#\\s*$', alt_prompt_terminator='>\\s*$', username_pattern='(?:user:|username|login)', pwd_pattern='assword', delay_factor=1, max_loops=20) +def serial_login(self, pri_prompt_terminator='\\#\\s*$', alt_prompt_terminator='>\\s*$', username_pattern='(?:user:|username|login)', pwd_pattern='assword', delay_factor=1, max_loops=20)
            @@ -853,7 +856,7 @@

            Methods

            Source code
            def serial_login(
                 self,
            -    pri_prompt_terminator=r"#\s*$",
            +    pri_prompt_terminator=r"\#\s*$",
                 alt_prompt_terminator=r">\s*$",
                 username_pattern=r"(?:user:|username|login)",
                 pwd_pattern=r"assword",
            @@ -878,7 +881,7 @@ 

            Methods

            -def telnet_login(self, pri_prompt_terminator='#\\s*$', alt_prompt_terminator='>\\s*$', username_pattern='(?:user:|username|login|user name)', pwd_pattern='assword', delay_factor=1, max_loops=20) +def telnet_login(self, pri_prompt_terminator='\\#\\s*$', alt_prompt_terminator='>\\s*$', username_pattern='(?:user:|username|login|user name)', pwd_pattern='assword', delay_factor=1, max_loops=20)

            Telnet login. Can be username/password or just password.

            @@ -886,7 +889,7 @@

            Methods

            Source code
            def telnet_login(
                 self,
            -    pri_prompt_terminator=r"#\s*$",
            +    pri_prompt_terminator=r"\#\s*$",
                 alt_prompt_terminator=r">\s*$",
                 username_pattern=r"(?:user:|username|login|user name)",
                 pwd_pattern=r"assword",
            @@ -1012,6 +1015,7 @@ 

            Inherited members

          • read_until_pattern
          • read_until_prompt
          • read_until_prompt_or_pattern
          • +
          • run_ttp
          • select_delay_factor
          • send_command
          • send_command_expect
          • @@ -1234,6 +1238,7 @@

            Subclasses

          • AristaBase
          • ApresiaAeosBase
          • ArubaSSH
          • +
          • BrocadeFOSSSH
          • BroadcomIcosSSH
          • CalixB6Base
          • CiscoAsaSSH
          • @@ -1300,6 +1305,7 @@

            Inherited members

          • read_until_pattern
          • read_until_prompt
          • read_until_prompt_or_pattern
          • +
          • run_ttp
          • save_config
          • select_delay_factor
          • send_command
          • diff --git a/docs/netmiko/citrix/index.html b/docs/netmiko/citrix/index.html index 0cc670143..a0db84726 100644 --- a/docs/netmiko/citrix/index.html +++ b/docs/netmiko/citrix/index.html @@ -370,6 +370,7 @@

            Inherited members

          • read_until_pattern
          • read_until_prompt
          • read_until_prompt_or_pattern
          • +
          • run_ttp
          • save_config
          • select_delay_factor
          • send_command
          • diff --git a/docs/netmiko/citrix/netscaler_ssh.html b/docs/netmiko/citrix/netscaler_ssh.html index f9bfd3e27..532d9100b 100644 --- a/docs/netmiko/citrix/netscaler_ssh.html +++ b/docs/netmiko/citrix/netscaler_ssh.html @@ -420,6 +420,7 @@

            Inherited members

          • read_until_pattern
          • read_until_prompt
          • read_until_prompt_or_pattern
          • +
          • run_ttp
          • save_config
          • select_delay_factor
          • send_command
          • diff --git a/docs/netmiko/cloudgenix/cloudgenix_ion.html b/docs/netmiko/cloudgenix/cloudgenix_ion.html index 418978380..d969c030f 100644 --- a/docs/netmiko/cloudgenix/cloudgenix_ion.html +++ b/docs/netmiko/cloudgenix/cloudgenix_ion.html @@ -374,6 +374,7 @@

            Inherited members

          • read_until_pattern
          • read_until_prompt
          • read_until_prompt_or_pattern
          • +
          • run_ttp
          • select_delay_factor
          • send_command
          • send_command_expect
          • diff --git a/docs/netmiko/cloudgenix/index.html b/docs/netmiko/cloudgenix/index.html index c69e9ad9a..c5ec0399a 100644 --- a/docs/netmiko/cloudgenix/index.html +++ b/docs/netmiko/cloudgenix/index.html @@ -335,6 +335,7 @@

            Inherited members

          • read_until_pattern
          • read_until_prompt
          • read_until_prompt_or_pattern
          • +
          • run_ttp
          • select_delay_factor
          • send_command
          • send_command_expect
          • diff --git a/docs/netmiko/coriant/coriant_ssh.html b/docs/netmiko/coriant/coriant_ssh.html index 1c3885f2f..9c2d0c950 100644 --- a/docs/netmiko/coriant/coriant_ssh.html +++ b/docs/netmiko/coriant/coriant_ssh.html @@ -355,6 +355,7 @@

            Inherited members

          • read_until_pattern
          • read_until_prompt
          • read_until_prompt_or_pattern
          • +
          • run_ttp
          • select_delay_factor
          • send_command
          • send_command_expect
          • diff --git a/docs/netmiko/coriant/index.html b/docs/netmiko/coriant/index.html index 5f7a096d1..cf3590288 100644 --- a/docs/netmiko/coriant/index.html +++ b/docs/netmiko/coriant/index.html @@ -322,6 +322,7 @@

            Inherited members

          • read_until_pattern
          • read_until_prompt
          • read_until_prompt_or_pattern
          • +
          • run_ttp
          • select_delay_factor
          • send_command
          • send_command_expect
          • diff --git a/docs/netmiko/dell/dell_dnos6.html b/docs/netmiko/dell/dell_dnos6.html index 467920ada..306b5d77e 100644 --- a/docs/netmiko/dell/dell_dnos6.html +++ b/docs/netmiko/dell/dell_dnos6.html @@ -292,6 +292,7 @@

            Inherited members

          • read_until_pattern
          • read_until_prompt
          • read_until_prompt_or_pattern
          • +
          • run_ttp
          • select_delay_factor
          • send_command
          • send_command_expect
          • @@ -487,6 +488,7 @@

            Inherited members

          • read_until_pattern
          • read_until_prompt
          • read_until_prompt_or_pattern
          • +
          • run_ttp
          • save_config
          • select_delay_factor
          • send_command
          • @@ -683,6 +685,7 @@

            Inherited members

          • read_until_pattern
          • read_until_prompt
          • read_until_prompt_or_pattern
          • +
          • run_ttp
          • save_config
          • select_delay_factor
          • send_command
          • diff --git a/docs/netmiko/dell/dell_force10_ssh.html b/docs/netmiko/dell/dell_force10_ssh.html index 6dda48fea..8d7d9d94f 100644 --- a/docs/netmiko/dell/dell_force10_ssh.html +++ b/docs/netmiko/dell/dell_force10_ssh.html @@ -258,6 +258,7 @@

            Inherited members

          • read_until_pattern
          • read_until_prompt
          • read_until_prompt_or_pattern
          • +
          • run_ttp
          • select_delay_factor
          • send_command
          • send_command_expect
          • diff --git a/docs/netmiko/dell/dell_isilon_ssh.html b/docs/netmiko/dell/dell_isilon_ssh.html index a096ccee9..8aaf4ef7a 100644 --- a/docs/netmiko/dell/dell_isilon_ssh.html +++ b/docs/netmiko/dell/dell_isilon_ssh.html @@ -532,6 +532,7 @@

            Inherited members

          • read_until_pattern
          • read_until_prompt
          • read_until_prompt_or_pattern
          • +
          • run_ttp
          • save_config
          • select_delay_factor
          • send_command
          • diff --git a/docs/netmiko/dell/dell_os10_ssh.html b/docs/netmiko/dell/dell_os10_ssh.html index 89d62655e..154e9466a 100644 --- a/docs/netmiko/dell/dell_os10_ssh.html +++ b/docs/netmiko/dell/dell_os10_ssh.html @@ -502,6 +502,7 @@

            Inherited members

          • read_until_pattern
          • read_until_prompt
          • read_until_prompt_or_pattern
          • +
          • run_ttp
          • select_delay_factor
          • send_command
          • send_command_expect
          • diff --git a/docs/netmiko/dell/dell_powerconnect.html b/docs/netmiko/dell/dell_powerconnect.html index 9f847af6b..a04d1d874 100644 --- a/docs/netmiko/dell/dell_powerconnect.html +++ b/docs/netmiko/dell/dell_powerconnect.html @@ -419,6 +419,7 @@

            Inherited members

          • read_until_pattern
          • read_until_prompt
          • read_until_prompt_or_pattern
          • +
          • run_ttp
          • save_config
          • select_delay_factor
          • send_command
          • @@ -705,6 +706,7 @@

            Inherited members

          • read_until_pattern
          • read_until_prompt
          • read_until_prompt_or_pattern
          • +
          • run_ttp
          • save_config
          • select_delay_factor
          • send_command
          • @@ -901,6 +903,7 @@

            Inherited members

          • read_until_pattern
          • read_until_prompt
          • read_until_prompt_or_pattern
          • +
          • run_ttp
          • save_config
          • select_delay_factor
          • send_command
          • diff --git a/docs/netmiko/dell/index.html b/docs/netmiko/dell/index.html index ffadc0543..86aabe5e6 100644 --- a/docs/netmiko/dell/index.html +++ b/docs/netmiko/dell/index.html @@ -249,6 +249,7 @@

            Inherited members

          • read_until_pattern
          • read_until_prompt
          • read_until_prompt_or_pattern
          • +
          • run_ttp
          • save_config
          • select_delay_factor
          • send_command
          • @@ -445,6 +446,7 @@

            Inherited members

          • read_until_pattern
          • read_until_prompt
          • read_until_prompt_or_pattern
          • +
          • run_ttp
          • save_config
          • select_delay_factor
          • send_command
          • @@ -673,6 +675,7 @@

            Inherited members

          • read_until_pattern
          • read_until_prompt
          • read_until_prompt_or_pattern
          • +
          • run_ttp
          • select_delay_factor
          • send_command
          • send_command_expect
          • @@ -1106,6 +1109,7 @@

            Inherited members

          • read_until_pattern
          • read_until_prompt
          • read_until_prompt_or_pattern
          • +
          • run_ttp
          • save_config
          • select_delay_factor
          • send_command
          • @@ -1480,6 +1484,7 @@

            Inherited members

          • read_until_pattern
          • read_until_prompt
          • read_until_prompt_or_pattern
          • +
          • run_ttp
          • select_delay_factor
          • send_command
          • send_command_expect
          • @@ -1767,6 +1772,7 @@

            Inherited members

          • read_until_pattern
          • read_until_prompt
          • read_until_prompt_or_pattern
          • +
          • run_ttp
          • save_config
          • select_delay_factor
          • send_command
          • @@ -1963,6 +1969,7 @@

            Inherited members

          • read_until_pattern
          • read_until_prompt
          • read_until_prompt_or_pattern
          • +
          • run_ttp
          • save_config
          • select_delay_factor
          • send_command
          • diff --git a/docs/netmiko/dlink/dlink_ds.html b/docs/netmiko/dlink/dlink_ds.html index 3d06b24d1..3bceabf2c 100644 --- a/docs/netmiko/dlink/dlink_ds.html +++ b/docs/netmiko/dlink/dlink_ds.html @@ -438,6 +438,7 @@

            Inherited members

          • read_until_pattern
          • read_until_prompt
          • read_until_prompt_or_pattern
          • +
          • run_ttp
          • select_delay_factor
          • send_command
          • send_command_expect
          • @@ -632,6 +633,7 @@

            Inherited members

          • read_until_pattern
          • read_until_prompt
          • read_until_prompt_or_pattern
          • +
          • run_ttp
          • save_config
          • select_delay_factor
          • send_command
          • @@ -831,6 +833,7 @@

            Inherited members

          • read_until_pattern
          • read_until_prompt
          • read_until_prompt_or_pattern
          • +
          • run_ttp
          • save_config
          • select_delay_factor
          • send_command
          • diff --git a/docs/netmiko/dlink/index.html b/docs/netmiko/dlink/index.html index 38fbf8741..4bd27985c 100644 --- a/docs/netmiko/dlink/index.html +++ b/docs/netmiko/dlink/index.html @@ -218,6 +218,7 @@

            Inherited members

          • read_until_pattern
          • read_until_prompt
          • read_until_prompt_or_pattern
          • +
          • run_ttp
          • save_config
          • select_delay_factor
          • send_command
          • @@ -417,6 +418,7 @@

            Inherited members

          • read_until_pattern
          • read_until_prompt
          • read_until_prompt_or_pattern
          • +
          • run_ttp
          • save_config
          • select_delay_factor
          • send_command
          • diff --git a/docs/netmiko/eltex/eltex_esr_ssh.html b/docs/netmiko/eltex/eltex_esr_ssh.html index c5feb34b2..144a29113 100644 --- a/docs/netmiko/eltex/eltex_esr_ssh.html +++ b/docs/netmiko/eltex/eltex_esr_ssh.html @@ -502,6 +502,7 @@

            Inherited members

          • read_until_pattern
          • read_until_prompt
          • read_until_prompt_or_pattern
          • +
          • run_ttp
          • select_delay_factor
          • send_command
          • send_command_expect
          • diff --git a/docs/netmiko/eltex/eltex_ssh.html b/docs/netmiko/eltex/eltex_ssh.html index c6a8bd050..e3bb667bd 100644 --- a/docs/netmiko/eltex/eltex_ssh.html +++ b/docs/netmiko/eltex/eltex_ssh.html @@ -273,6 +273,7 @@

            Inherited members

          • read_until_pattern
          • read_until_prompt
          • read_until_prompt_or_pattern
          • +
          • run_ttp
          • select_delay_factor
          • send_command
          • send_command_expect
          • diff --git a/docs/netmiko/eltex/index.html b/docs/netmiko/eltex/index.html index df4a2d96c..b0cb50dbb 100644 --- a/docs/netmiko/eltex/index.html +++ b/docs/netmiko/eltex/index.html @@ -414,6 +414,7 @@

            Inherited members

          • read_until_pattern
          • read_until_prompt
          • read_until_prompt_or_pattern
          • +
          • run_ttp
          • select_delay_factor
          • send_command
          • send_command_expect
          • @@ -654,6 +655,7 @@

            Inherited members

          • read_until_pattern
          • read_until_prompt
          • read_until_prompt_or_pattern
          • +
          • run_ttp
          • select_delay_factor
          • send_command
          • send_command_expect
          • diff --git a/docs/netmiko/endace/endace_ssh.html b/docs/netmiko/endace/endace_ssh.html index 0793fba89..e078295a5 100644 --- a/docs/netmiko/endace/endace_ssh.html +++ b/docs/netmiko/endace/endace_ssh.html @@ -279,6 +279,7 @@

            Inherited members

          • read_until_pattern
          • read_until_prompt
          • read_until_prompt_or_pattern
          • +
          • run_ttp
          • save_config
          • select_delay_factor
          • send_command
          • diff --git a/docs/netmiko/endace/index.html b/docs/netmiko/endace/index.html index efcbc258a..fb9c1ece6 100644 --- a/docs/netmiko/endace/index.html +++ b/docs/netmiko/endace/index.html @@ -250,6 +250,7 @@

            Inherited members

          • read_until_pattern
          • read_until_prompt
          • read_until_prompt_or_pattern
          • +
          • run_ttp
          • save_config
          • select_delay_factor
          • send_command
          • diff --git a/docs/netmiko/enterasys/enterasys_ssh.html b/docs/netmiko/enterasys/enterasys_ssh.html index ab6fdf143..de7d31964 100644 --- a/docs/netmiko/enterasys/enterasys_ssh.html +++ b/docs/netmiko/enterasys/enterasys_ssh.html @@ -273,6 +273,7 @@

            Inherited members

          • read_until_pattern
          • read_until_prompt
          • read_until_prompt_or_pattern
          • +
          • run_ttp
          • select_delay_factor
          • send_command
          • send_command_expect
          • diff --git a/docs/netmiko/enterasys/index.html b/docs/netmiko/enterasys/index.html index 2b15ddf31..a7abe932e 100644 --- a/docs/netmiko/enterasys/index.html +++ b/docs/netmiko/enterasys/index.html @@ -262,6 +262,7 @@

            Inherited members

          • read_until_pattern
          • read_until_prompt
          • read_until_prompt_or_pattern
          • +
          • run_ttp
          • select_delay_factor
          • send_command
          • send_command_expect
          • diff --git a/docs/netmiko/ericsson/ericsson_ipos.html b/docs/netmiko/ericsson/ericsson_ipos.html index f07bc973f..a8d09ac0f 100644 --- a/docs/netmiko/ericsson/ericsson_ipos.html +++ b/docs/netmiko/ericsson/ericsson_ipos.html @@ -675,6 +675,7 @@

            Inherited members

          • read_until_pattern
          • read_until_prompt
          • read_until_prompt_or_pattern
          • +
          • run_ttp
          • select_delay_factor
          • send_command
          • send_command_expect
          • diff --git a/docs/netmiko/ericsson/index.html b/docs/netmiko/ericsson/index.html index 4a45ad5d9..524ea6576 100644 --- a/docs/netmiko/ericsson/index.html +++ b/docs/netmiko/ericsson/index.html @@ -541,6 +541,7 @@

            Inherited members

          • read_until_pattern
          • read_until_prompt
          • read_until_prompt_or_pattern
          • +
          • run_ttp
          • select_delay_factor
          • send_command
          • send_command_expect
          • diff --git a/docs/netmiko/extreme/extreme_ers_ssh.html b/docs/netmiko/extreme/extreme_ers_ssh.html index 3fef18979..4b2a41fd5 100644 --- a/docs/netmiko/extreme/extreme_ers_ssh.html +++ b/docs/netmiko/extreme/extreme_ers_ssh.html @@ -337,6 +337,7 @@

            Inherited members

          • read_until_pattern
          • read_until_prompt
          • read_until_prompt_or_pattern
          • +
          • run_ttp
          • select_delay_factor
          • send_command
          • send_command_expect
          • diff --git a/docs/netmiko/extreme/extreme_exos.html b/docs/netmiko/extreme/extreme_exos.html index e338fe543..18fe7a9db 100644 --- a/docs/netmiko/extreme/extreme_exos.html +++ b/docs/netmiko/extreme/extreme_exos.html @@ -477,6 +477,7 @@

            Inherited members

          • read_until_pattern
          • read_until_prompt
          • read_until_prompt_or_pattern
          • +
          • run_ttp
          • select_delay_factor
          • send_command_expect
          • send_command_timing
          • @@ -671,6 +672,7 @@

            Inherited members

          • read_until_pattern
          • read_until_prompt
          • read_until_prompt_or_pattern
          • +
          • run_ttp
          • save_config
          • select_delay_factor
          • send_command
          • @@ -871,6 +873,7 @@

            Inherited members

          • read_until_pattern
          • read_until_prompt
          • read_until_prompt_or_pattern
          • +
          • run_ttp
          • save_config
          • select_delay_factor
          • send_command
          • diff --git a/docs/netmiko/extreme/extreme_netiron.html b/docs/netmiko/extreme/extreme_netiron.html index fbda2da10..872893a17 100644 --- a/docs/netmiko/extreme/extreme_netiron.html +++ b/docs/netmiko/extreme/extreme_netiron.html @@ -22,7 +22,8 @@

            Module netmiko.extreme.extreme_netiron

            Source code -
            from netmiko.cisco_base_connection import CiscoSSHConnection
            +
            import time
            +from netmiko.cisco_base_connection import CiscoSSHConnection
             
             
             class ExtremeNetironBase(CiscoSSHConnection):
            @@ -32,6 +33,17 @@ 

            Module netmiko.extreme.extreme_netiron

            cmd=cmd, confirm=confirm, confirm_response=confirm_response ) + def session_preparation(self): + """Prepare the session after the connection has been established.""" + self._test_channel_read() + self.set_base_prompt() + self.disable_paging(command="skip-page-display") + self.set_terminal_width() + + # Clear the read buffer + time.sleep(0.3 * self.global_delay_factor) + self.clear_buffer() + class ExtremeNetironSSH(ExtremeNetironBase): pass @@ -196,7 +208,18 @@

            Classes

            """Save Config""" return super().save_config( cmd=cmd, confirm=confirm, confirm_response=confirm_response - )
            + ) + + def session_preparation(self): + """Prepare the session after the connection has been established.""" + self._test_channel_read() + self.set_base_prompt() + self.disable_paging(command="skip-page-display") + self.set_terminal_width() + + # Clear the read buffer + time.sleep(0.3 * self.global_delay_factor) + self.clear_buffer()

            Ancestors

              @@ -225,6 +248,25 @@

              Methods

              )
            +
            +def session_preparation(self) +
            +
            +

            Prepare the session after the connection has been established.

            +
            +Source code +
            def session_preparation(self):
            +    """Prepare the session after the connection has been established."""
            +    self._test_channel_read()
            +    self.set_base_prompt()
            +    self.disable_paging(command="skip-page-display")
            +    self.set_terminal_width()
            +
            +    # Clear the read buffer
            +    time.sleep(0.3 * self.global_delay_factor)
            +    self.clear_buffer()
            +
            +

            Inherited members

            -def send_config_set(self, config_commands=None, exit_config_mode=True, delay_factor=1, max_loops=150, strip_prompt=False, strip_command=False, config_mode_command=None, cmd_verify=True, enter_config_mode=True) +def send_config_set(self, config_commands=None, exit_config_mode=True, delay_factor=1, max_loops=150, strip_prompt=False, strip_command=False, config_mode_command=None, cmd_verify=True, enter_config_mode=True, error_pattern='')

            Send configuration commands down the SSH channel.

            @@ -3973,7 +4141,10 @@

            Methods

            :param cmd_verify: Whether or not to verify command echo for each command in config_set :type cmd_verify: bool

            :param enter_config_mode: Do you enter config mode before sending config commands -:type exit_config_mode: bool

            +:type exit_config_mode: bool

            +

            :param error_pattern: Regular expression pattern to detect config errors in the +output. +:type error_pattern: str

            Source code
            def send_config_set(
            @@ -3987,6 +4158,7 @@ 

            Methods

            config_mode_command=None, cmd_verify=True, enter_config_mode=True, + error_pattern="", ): """ Send configuration commands down the SSH channel. @@ -4023,6 +4195,9 @@

            Methods

            :param enter_config_mode: Do you enter config mode before sending config commands :type exit_config_mode: bool + :param error_pattern: Regular expression pattern to detect config errors in the + output. + :type error_pattern: str """ delay_factor = self.select_delay_factor(delay_factor) if config_commands is None: @@ -4039,21 +4214,35 @@

            Methods

            cfg_mode_args = (config_mode_command,) if config_mode_command else tuple() output += self.config_mode(*cfg_mode_args) - if self.fast_cli and self._legacy_mode: + # If error_pattern is perform output gathering line by line and not fast_cli mode. + if self.fast_cli and self._legacy_mode and not error_pattern: for cmd in config_commands: self.write_channel(self.normalize_cmd(cmd)) # Gather output output += self._read_channel_timing( delay_factor=delay_factor, max_loops=max_loops ) + elif not cmd_verify: for cmd in config_commands: self.write_channel(self.normalize_cmd(cmd)) time.sleep(delay_factor * 0.05) - # Gather output - output += self._read_channel_timing( - delay_factor=delay_factor, max_loops=max_loops - ) + + # Gather the output incrementally due to error_pattern requirements + if error_pattern: + output += self._read_channel_timing( + delay_factor=delay_factor, max_loops=max_loops + ) + if re.search(error_pattern, output, flags=re.M): + msg = f"Invalid input detected at command: {cmd}" + raise ConfigInvalidException(msg) + + # Standard output gathering (no error_pattern) + if not error_pattern: + output += self._read_channel_timing( + delay_factor=delay_factor, max_loops=max_loops + ) + else: for cmd in config_commands: self.write_channel(self.normalize_cmd(cmd)) @@ -4071,6 +4260,11 @@

            Methods

            new_output = self.read_until_pattern(pattern=pattern) output += new_output + if error_pattern: + if re.search(error_pattern, output, flags=re.M): + msg = f"Invalid input detected at command: {cmd}" + raise ConfigInvalidException(msg) + if exit_config_mode: output += self.exit_config_mode() output = self._sanitize_output(output) @@ -4162,7 +4356,9 @@

            Methods

            Source code
            @retry(
            -    wait=wait_exponential(multiplier=0.33, min=0, max=5), stop=stop_after_attempt(5)
            +    wait=wait_exponential(multiplier=0.33, min=0, max=5),
            +    stop=stop_after_attempt(5),
            +    reraise=True,
             )
             def set_base_prompt(
                 self, pri_prompt_terminator="#", alt_prompt_terminator=">", delay_factor=1
            @@ -4586,6 +4782,25 @@ 

            Methods

            +
            +class ConfigInvalidException +(*args, **kwargs) +
            +
            +

            Exception raised for invalid configuration error.

            +
            +Source code +
            class ConfigInvalidException(Exception):
            +    """Exception raised for invalid configuration error."""
            +
            +    pass
            +
            +

            Ancestors

            +
              +
            • builtins.Exception
            • +
            • builtins.BaseException
            • +
            +
            class InLineTransfer (ssh_conn, source_file=None, dest_file=None, file_system=None, direction='put', source_config=None, socket_timeout=10.0, progress=None, progress4=None) @@ -5352,12 +5567,15 @@

            Index

          • netmiko.accedian
          • netmiko.adtran
          • netmiko.alcatel
          • +
          • netmiko.allied_telesis
          • netmiko.apresia
          • netmiko.arista
          • netmiko.aruba
          • netmiko.base_connection
          • netmiko.broadcom
          • +
          • netmiko.brocade
          • netmiko.calix
          • +
          • netmiko.cdot
          • netmiko.centec
          • netmiko.checkpoint
          • netmiko.ciena
          • @@ -5405,6 +5623,7 @@

            Index

          • netmiko.sophos
          • netmiko.ssh_autodetect
          • netmiko.ssh_exception
          • +
          • netmiko.supermicro
          • netmiko.terminal_server
          • netmiko.tplink
          • netmiko.ubiquiti
          • @@ -5454,6 +5673,7 @@

            BaseC
          • read_until_pattern
          • read_until_prompt
          • read_until_prompt_or_pattern
          • +
          • run_ttp
          • save_config
          • select_delay_factor
          • send_command
          • @@ -5475,6 +5695,9 @@

            BaseC

        • +

          ConfigInvalidException

          +
        • +
        • InLineTransfer

        -

        Implement methods for interacting with Nokia SR OS devices.

        -

        Not applicable in Nokia SR OS (disabled): -- exit_enable_mode()

        -

        Overriden methods to adapt Nokia SR OS behavior (changed): -- session_preparation() -- set_base_prompt() -- config_mode() -- exit_config_mode() -- check_config_mode() -- save_config() -- commit() -- strip_prompt() -- enable() -- check_enable_mode()

        +

        Nokia SR OS SSH driver.

            Initialize attributes for establishing connection to target device.
         
             :param ip: IP address of target device. Not required if `host` is
        @@ -377,461 +369,258 @@ 

        Inherited members

        Source code -
        class NokiaSrosSSH(BaseConnection):
        -    """
        -    Implement methods for interacting with Nokia SR OS devices.
        -
        -    Not applicable in Nokia SR OS (disabled):
        -        - exit_enable_mode()
        -
        -    Overriden methods to adapt Nokia SR OS behavior (changed):
        -        - session_preparation()
        -        - set_base_prompt()
        -        - config_mode()
        -        - exit_config_mode()
        -        - check_config_mode()
        -        - save_config()
        -        - commit()
        -        - strip_prompt()
        -        - enable()
        -        - check_enable_mode()
        -    """
        -
        -    def session_preparation(self):
        -        self._test_channel_read()
        -        self.set_base_prompt()
        -        # "@" indicates model-driven CLI (vs Classical CLI)
        -        if "@" in self.base_prompt:
        -            self._disable_complete_on_space()
        -            self.set_terminal_width(
        -                command="environment console width 512", pattern="environment"
        -            )
        -            self.disable_paging(command="environment more false")
        -            # To perform file operations we need to disable paging in classical-CLI also
        -            self.disable_paging(command="//environment no more")
        -        else:
        -            # Classical CLI has no method to set the terminal width nor to disable command
        -            # complete on space; consequently, cmd_verify needs disabled.
        -            self.global_cmd_verify = False
        -            self.disable_paging(command="environment no more", pattern="environment")
        -
        -        # Clear the read buffer
        -        time.sleep(0.3 * self.global_delay_factor)
        -        self.clear_buffer()
        -
        -    def set_base_prompt(self, *args, **kwargs):
        -        """Remove the > when navigating into the different config level."""
        -        cur_base_prompt = super().set_base_prompt(*args, **kwargs)
        -        match = re.search(r"\*?(.*?)(>.*)*#", cur_base_prompt)
        -        if match:
        -            # strip off >... from base_prompt; strip off leading *
        -            self.base_prompt = match.group(1)
        -            return self.base_prompt
        -
        -    def _disable_complete_on_space(self):
        -        """
        -        SR-OS tries to auto complete commands when you type a "space" character.
        +
        class NokiaSrosSSH(NokiaSros):
        +    """Nokia SR OS SSH driver."""
         
        -        This is a bad idea for automation as what your program is sending no longer matches
        -        the command echo from the device, so we disable this behavior.
        -        """
        -        delay_factor = self.select_delay_factor(delay_factor=0)
        -        time.sleep(delay_factor * 0.1)
        -        command = "environment command-completion space false"
        -        self.write_channel(self.normalize_cmd(command))
        -        time.sleep(delay_factor * 0.1)
        -        return self.read_channel()
        -
        -    def enable(self, cmd="enable", pattern="ssword", re_flags=re.IGNORECASE):
        -        """Enable SR OS administrative mode"""
        -        if "@" not in self.base_prompt:
        -            cmd = "enable-admin"
        -        return super().enable(cmd=cmd, pattern=pattern, re_flags=re_flags)
        -
        -    def check_enable_mode(self, check_string="in admin mode"):
        -        """Check if in enable mode."""
        -        cmd = "enable"
        -        if "@" not in self.base_prompt:
        -            cmd = "enable-admin"
        -        self.write_channel(self.normalize_cmd(cmd))
        -        output = self.read_until_prompt_or_pattern(pattern="ssword")
        -        if "ssword" in output:
        -            self.write_channel(self.RETURN)  # send ENTER to pass the password prompt
        -            self.read_until_prompt()
        -        return check_string in output
        -
        -    def exit_enable_mode(self, *args, **kwargs):
        -        """Nokia SR OS does not have a notion of exiting administrative mode"""
        -        return ""
        -
        -    def config_mode(self, config_command="edit-config exclusive", pattern=r"\(ex\)\["):
        -        """Enable config edit-mode for Nokia SR OS"""
        -        output = ""
        -        # Only model-driven CLI supports config-mode
        -        if "@" in self.base_prompt:
        -            output += super().config_mode(
        -                config_command=config_command, pattern=pattern
        -            )
        -        return output
        -
        -    def exit_config_mode(self, *args, **kwargs):
        -        """Disable config edit-mode for Nokia SR OS"""
        -        output = self._exit_all()
        -        # Model-driven CLI
        -        if "@" in self.base_prompt and "(ex)[" in output:
        -            # Asterisk indicates changes were made.
        -            if "*(ex)[" in output:
        -                log.warning("Uncommitted changes! Discarding changes!")
        -                output += self._discard()
        -            cmd = "quit-config"
        -            self.write_channel(self.normalize_cmd(cmd))
        -            if self.global_cmd_verify is not False:
        -                output += self.read_until_pattern(pattern=re.escape(cmd))
        -            else:
        -                output += self.read_until_prompt()
        -        if self.check_config_mode():
        -            raise ValueError("Failed to exit configuration mode")
        -        return output
        -
        -    def check_config_mode(self, check_string=r"(ex)[", pattern=r"@"):
        -        """Check config mode for Nokia SR OS"""
        -        if "@" not in self.base_prompt:
        -            # Classical CLI
        -            return False
        -        else:
        -            # Model-driven CLI look for "exclusive"
        -            return super().check_config_mode(check_string=check_string, pattern=pattern)
        -
        -    def save_config(self, *args, **kwargs):
        -        """Persist configuration to cflash for Nokia SR OS"""
        -        return self.send_command(command_string="/admin save", expect_string=r"#")
        -
        -    def send_config_set(self, config_commands=None, exit_config_mode=None, **kwargs):
        -        """Model driven CLI requires you not exit from configuration mode."""
        -        if exit_config_mode is None:
        -            # Set to False if model-driven CLI
        -            exit_config_mode = False if "@" in self.base_prompt else True
        -        return super().send_config_set(
        -            config_commands=config_commands, exit_config_mode=exit_config_mode, **kwargs
        -        )
        -
        -    def commit(self, *args, **kwargs):
        -        """Activate changes from private candidate for Nokia SR OS"""
        -        output = self._exit_all()
        -        if "@" in self.base_prompt and "*(ex)[" in output:
        -            log.info("Apply uncommitted changes!")
        -            cmd = "commit"
        -            self.write_channel(self.normalize_cmd(cmd))
        -            new_output = ""
        -            if self.global_cmd_verify is not False:
        -                new_output += self.read_until_pattern(pattern=re.escape(cmd))
        -            if "@" not in new_output:
        -                new_output += self.read_until_pattern(r"@")
        -            output += new_output
        -        return output
        -
        -    def _exit_all(self):
        -        """Return to the 'root' context."""
        -        output = ""
        -        exit_cmd = "exit all"
        -        self.write_channel(self.normalize_cmd(exit_cmd))
        -        # Make sure you read until you detect the command echo (avoid getting out of sync)
        -        if self.global_cmd_verify is not False:
        -            output += self.read_until_pattern(pattern=re.escape(exit_cmd))
        -        else:
        -            output += self.read_until_prompt()
        -        return output
        -
        -    def _discard(self):
        -        """Discard changes from private candidate for Nokia SR OS"""
        -        output = ""
        -        if "@" in self.base_prompt:
        -            cmd = "discard"
        -            self.write_channel(self.normalize_cmd(cmd))
        -            new_output = ""
        -            if self.global_cmd_verify is not False:
        -                new_output += self.read_until_pattern(pattern=re.escape(cmd))
        -            if "@" not in new_output:
        -                new_output += self.read_until_prompt()
        -            output += new_output
        -        return output
        -
        -    def strip_prompt(self, *args, **kwargs):
        -        """Strip prompt from the output."""
        -        output = super().strip_prompt(*args, **kwargs)
        -        if "@" in self.base_prompt:
        -            # Remove context prompt too
        -            strips = r"[\r\n]*\!?\*?(\((ex|gl|pr|ro)\))?\[\S*\][\r\n]*"
        -            return re.sub(strips, "", output)
        -        else:
        -            return output
        -
        -    def cleanup(self, command="logout"):
        -        """Gracefully exit the SSH session."""
        -        try:
        -            # The pattern="" forces use of send_command_timing
        -            if self.check_config_mode(pattern=""):
        -                self.exit_config_mode()
        -        except Exception:
        -            pass
        -        # Always try to send final 'logout'.
        -        self._session_log_fin = True
        -        self.write_channel(command + self.RETURN)
        + pass

        Ancestors

        -

        Methods

        -
        -
        -def check_config_mode(self, check_string='(ex)[', pattern='@') -
        -
        -

        Check config mode for Nokia SR OS

        -
        -Source code -
        def check_config_mode(self, check_string=r"(ex)[", pattern=r"@"):
        -    """Check config mode for Nokia SR OS"""
        -    if "@" not in self.base_prompt:
        -        # Classical CLI
        -        return False
        -    else:
        -        # Model-driven CLI look for "exclusive"
        -        return super().check_config_mode(check_string=check_string, pattern=pattern)
        -
        -
        -
        -def check_enable_mode(self, check_string='in admin mode') -
        -
        -

        Check if in enable mode.

        -
        -Source code -
        def check_enable_mode(self, check_string="in admin mode"):
        -    """Check if in enable mode."""
        -    cmd = "enable"
        -    if "@" not in self.base_prompt:
        -        cmd = "enable-admin"
        -    self.write_channel(self.normalize_cmd(cmd))
        -    output = self.read_until_prompt_or_pattern(pattern="ssword")
        -    if "ssword" in output:
        -        self.write_channel(self.RETURN)  # send ENTER to pass the password prompt
        -        self.read_until_prompt()
        -    return check_string in output
        -
        -
        -
        -def cleanup(self, command='logout') -
        -
        -

        Gracefully exit the SSH session.

        -
        -Source code -
        def cleanup(self, command="logout"):
        -    """Gracefully exit the SSH session."""
        -    try:
        -        # The pattern="" forces use of send_command_timing
        -        if self.check_config_mode(pattern=""):
        -            self.exit_config_mode()
        -    except Exception:
        -        pass
        -    # Always try to send final 'logout'.
        -    self._session_log_fin = True
        -    self.write_channel(command + self.RETURN)
        -
        -
        -
        -def commit(self, *args, **kwargs) -
        -
        -

        Activate changes from private candidate for Nokia SR OS

        -
        -Source code -
        def commit(self, *args, **kwargs):
        -    """Activate changes from private candidate for Nokia SR OS"""
        -    output = self._exit_all()
        -    if "@" in self.base_prompt and "*(ex)[" in output:
        -        log.info("Apply uncommitted changes!")
        -        cmd = "commit"
        -        self.write_channel(self.normalize_cmd(cmd))
        -        new_output = ""
        -        if self.global_cmd_verify is not False:
        -            new_output += self.read_until_pattern(pattern=re.escape(cmd))
        -        if "@" not in new_output:
        -            new_output += self.read_until_pattern(r"@")
        -        output += new_output
        -    return output
        -
        -
        -
        -def config_mode(self, config_command='edit-config exclusive', pattern='\\(ex\\)\\[') -
        -
        -

        Enable config edit-mode for Nokia SR OS

        -
        -Source code -
        def config_mode(self, config_command="edit-config exclusive", pattern=r"\(ex\)\["):
        -    """Enable config edit-mode for Nokia SR OS"""
        -    output = ""
        -    # Only model-driven CLI supports config-mode
        -    if "@" in self.base_prompt:
        -        output += super().config_mode(
        -            config_command=config_command, pattern=pattern
        -        )
        -    return output
        -
        -
        -
        -def enable(self, cmd='enable', pattern='ssword', re_flags=) -
        -
        -

        Enable SR OS administrative mode

        -
        -Source code -
        def enable(self, cmd="enable", pattern="ssword", re_flags=re.IGNORECASE):
        -    """Enable SR OS administrative mode"""
        -    if "@" not in self.base_prompt:
        -        cmd = "enable-admin"
        -    return super().enable(cmd=cmd, pattern=pattern, re_flags=re_flags)
        -
        -
        -
        -def exit_config_mode(self, *args, **kwargs) -
        -
        -

        Disable config edit-mode for Nokia SR OS

        -
        -Source code -
        def exit_config_mode(self, *args, **kwargs):
        -    """Disable config edit-mode for Nokia SR OS"""
        -    output = self._exit_all()
        -    # Model-driven CLI
        -    if "@" in self.base_prompt and "(ex)[" in output:
        -        # Asterisk indicates changes were made.
        -        if "*(ex)[" in output:
        -            log.warning("Uncommitted changes! Discarding changes!")
        -            output += self._discard()
        -        cmd = "quit-config"
        -        self.write_channel(self.normalize_cmd(cmd))
        -        if self.global_cmd_verify is not False:
        -            output += self.read_until_pattern(pattern=re.escape(cmd))
        -        else:
        -            output += self.read_until_prompt()
        -    if self.check_config_mode():
        -        raise ValueError("Failed to exit configuration mode")
        -    return output
        -
        -
        -
        -def exit_enable_mode(self, *args, **kwargs) -
        -
        -

        Nokia SR OS does not have a notion of exiting administrative mode

        -
        -Source code -
        def exit_enable_mode(self, *args, **kwargs):
        -    """Nokia SR OS does not have a notion of exiting administrative mode"""
        -    return ""
        -
        -
        -
        -def save_config(self, *args, **kwargs) -
        -
        -

        Persist configuration to cflash for Nokia SR OS

        -
        -Source code -
        def save_config(self, *args, **kwargs):
        -    """Persist configuration to cflash for Nokia SR OS"""
        -    return self.send_command(command_string="/admin save", expect_string=r"#")
        -
        -
        -
        -def send_config_set(self, config_commands=None, exit_config_mode=None, **kwargs) -
        -
        -

        Model driven CLI requires you not exit from configuration mode.

        -
        -Source code -
        def send_config_set(self, config_commands=None, exit_config_mode=None, **kwargs):
        -    """Model driven CLI requires you not exit from configuration mode."""
        -    if exit_config_mode is None:
        -        # Set to False if model-driven CLI
        -        exit_config_mode = False if "@" in self.base_prompt else True
        -    return super().send_config_set(
        -        config_commands=config_commands, exit_config_mode=exit_config_mode, **kwargs
        -    )
        -
        -
        -
        -def set_base_prompt(self, *args, **kwargs) -
        -
        -

        Remove the > when navigating into the different config level.

        -
        -Source code -
        def set_base_prompt(self, *args, **kwargs):
        -    """Remove the > when navigating into the different config level."""
        -    cur_base_prompt = super().set_base_prompt(*args, **kwargs)
        -    match = re.search(r"\*?(.*?)(>.*)*#", cur_base_prompt)
        -    if match:
        -        # strip off >... from base_prompt; strip off leading *
        -        self.base_prompt = match.group(1)
        -        return self.base_prompt
        -
        +

        Inherited members

        +
        -
        -def strip_prompt(self, *args, **kwargs) +
        +class NokiaSrosTelnet +(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=5, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=False, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True)
        -

        Strip prompt from the output.

        +

        Nokia SR OS Telnet driver.

        +
            Initialize attributes for establishing connection to target device.
        +
        +    :param ip: IP address of target device. Not required if `host` is
        +        provided.
        +    :type ip: str
        +
        +    :param host: Hostname of target device. Not required if `ip` is
        +            provided.
        +    :type host: str
        +
        +    :param username: Username to authenticate against target device if
        +            required.
        +    :type username: str
        +
        +    :param password: Password to authenticate against target device if
        +            required.
        +    :type password: str
        +
        +    :param secret: The enable password if target device requires one.
        +    :type secret: str
        +
        +    :param port: The destination port used to connect to the target
        +            device.
        +    :type port: int or None
        +
        +    :param device_type: Class selection based on device type.
        +    :type device_type: str
        +
        +    :param verbose: Enable additional messages to standard output.
        +    :type verbose: bool
        +
        +    :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
        +    :type global_delay_factor: int
        +
        +    :param use_keys: Connect to target device using SSH keys.
        +    :type use_keys: bool
        +
        +    :param key_file: Filename path of the SSH key file to use.
        +    :type key_file: str
        +
        +    :param pkey: SSH key object to use.
        +    :type pkey: paramiko.PKey
        +
        +    :param passphrase: Passphrase to use for encrypted key; password will be used for key
        +            decryption if not specified.
        +    :type passphrase: str
        +
        +    :param allow_agent: Enable use of SSH key-agent.
        +    :type allow_agent: bool
        +
        +    :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
        +            means unknown SSH host keys will be accepted).
        +    :type ssh_strict: bool
        +
        +    :param system_host_keys: Load host keys from the users known_hosts file.
        +    :type system_host_keys: bool
        +    :param alt_host_keys: If `True` host keys will be loaded from the file specified in
        +            alt_key_file.
        +    :type alt_host_keys: bool
        +
        +    :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
        +    :type alt_key_file: str
        +
        +    :param ssh_config_file: File name of OpenSSH configuration file.
        +    :type ssh_config_file: str
        +
        +    :param timeout: Connection timeout.
        +    :type timeout: float
        +
        +    :param session_timeout: Set a timeout for parallel requests.
        +    :type session_timeout: float
        +
        +    :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
        +    :type auth_timeout: float
        +
        +    :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
        +    :type banner_timeout: float
        +
        +    :param keepalive: Send SSH keepalive packets at a specific interval, in seconds.
        +            Currently defaults to 0, for backwards compatibility (it will not attempt
        +            to keep the connection alive).
        +    :type keepalive: int
        +
        +    :param default_enter: Character(s) to send to correspond to enter key (default:
        +
        +

        ). +:type default_enter: str

        +
            :param response_return: Character(s) to use in normalized return data to represent
        +            enter key (default:
        +
        +

        ) +:type response_return: str

        +
            :param fast_cli: Provide a way to optimize for performance. Converts select_delay_factor
        +            to select smallest of global and specific. Sets default global_delay_factor to .1
        +            (default: False)
        +    :type fast_cli: boolean
        +
        +    :param session_log: File path or BufferedIOBase subclass object to write the session log to.
        +    :type session_log: str
        +
        +    :param session_log_record_writes: The session log generally only records channel reads due
        +            to eliminate command duplication due to command echo. You can enable this if you
        +            want to record both channel reads and channel writes in the log (default: False).
        +    :type session_log_record_writes: boolean
        +
        +    :param session_log_file_mode: "write" or "append" for session_log file mode
        +            (default: "write")
        +    :type session_log_file_mode: str
        +
        +    :param allow_auto_change: Allow automatic configuration changes for terminal settings.
        +            (default: False)
        +    :type allow_auto_change: bool
        +
        +    :param encoding: Encoding to be used when writing bytes to the output channel.
        +            (default: ascii)
        +    :type encoding: str
        +
        +    :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
        +            communication to the target host (default: None).
        +    :type sock: socket
        +
        +    :param global_cmd_verify: Control whether command echo verification is enabled or disabled
        +            (default: None). Global attribute takes precedence over function `cmd_verify`
        +            argument. Value of `None` indicates to use function `cmd_verify` argument.
        +    :type global_cmd_verify: bool|None
        +
        +    :param auto_connect: Control whether Netmiko automatically establishes the connection as
        +            part of the object creation (default: True).
        +    :type auto_connect: bool
        +
        Source code -
        def strip_prompt(self, *args, **kwargs):
        -    """Strip prompt from the output."""
        -    output = super().strip_prompt(*args, **kwargs)
        -    if "@" in self.base_prompt:
        -        # Remove context prompt too
        -        strips = r"[\r\n]*\!?\*?(\((ex|gl|pr|ro)\))?\[\S*\][\r\n]*"
        -        return re.sub(strips, "", output)
        -    else:
        -        return output
        +
        class NokiaSrosTelnet(NokiaSros):
        +    """Nokia SR OS Telnet driver."""
        +
        +    pass
        -
        -
        +

        Ancestors

        +

        Inherited members

        @@ -852,7 +641,7 @@

        Index

      • Sub-modules

      • Classes

        @@ -866,20 +655,9 @@

        NokiaSrosSSH

        - +
      • +
      • +

        NokiaSrosTelnet

      diff --git a/docs/netmiko/nokia/nokia_sros.html b/docs/netmiko/nokia/nokia_sros.html new file mode 100644 index 000000000..9b1b55578 --- /dev/null +++ b/docs/netmiko/nokia/nokia_sros.html @@ -0,0 +1,1619 @@ + + + + + + +netmiko.nokia.nokia_sros API documentation + + + + + + + + + +
      +
      +
      +

      Module netmiko.nokia.nokia_sros

      +
      +
      +
      +Source code +
      #!/usr/bin/python
      +# -*- coding: utf-8 -*-
      +# Copyright (c) 2014 - 2020 Kirk Byers
      +# Copyright (c) 2014 - 2020 Twin Bridges Technology
      +# Copyright (c) 2019 - 2020 NOKIA Inc.
      +# MIT License - See License file at:
      +#   https://github.com/ktbyers/netmiko/blob/develop/LICENSE
      +
      +import re
      +import os
      +import time
      +
      +from netmiko import log
      +from netmiko.base_connection import BaseConnection
      +from netmiko.scp_handler import BaseFileTransfer
      +
      +
      +class NokiaSros(BaseConnection):
      +    """
      +    Implement methods for interacting with Nokia SR OS devices
      +    for both SSH and telnet.
      +
      +    Not applicable in Nokia SR OS (disabled):
      +        - exit_enable_mode()
      +
      +    Overriden methods to adapt Nokia SR OS behavior (changed):
      +        - session_preparation()
      +        - set_base_prompt()
      +        - config_mode()
      +        - exit_config_mode()
      +        - check_config_mode()
      +        - save_config()
      +        - commit()
      +        - strip_prompt()
      +        - enable()
      +        - check_enable_mode()
      +    """
      +
      +    def session_preparation(self):
      +        self._test_channel_read()
      +        self.set_base_prompt()
      +        # "@" indicates model-driven CLI (vs Classical CLI)
      +        if "@" in self.base_prompt:
      +            self._disable_complete_on_space()
      +            self.set_terminal_width(
      +                command="environment console width 512", pattern="environment"
      +            )
      +            self.disable_paging(command="environment more false")
      +            # To perform file operations we need to disable paging in classical-CLI also
      +            self.disable_paging(command="//environment no more")
      +        else:
      +            # Classical CLI has no method to set the terminal width nor to disable command
      +            # complete on space; consequently, cmd_verify needs disabled.
      +            self.global_cmd_verify = False
      +            self.disable_paging(command="environment no more", pattern="environment")
      +
      +        # Clear the read buffer
      +        time.sleep(0.3 * self.global_delay_factor)
      +        self.clear_buffer()
      +
      +    def set_base_prompt(self, *args, **kwargs):
      +        """Remove the > when navigating into the different config level."""
      +        cur_base_prompt = super().set_base_prompt(*args, **kwargs)
      +        match = re.search(r"\*?(.*?)(>.*)*#", cur_base_prompt)
      +        if match:
      +            # strip off >... from base_prompt; strip off leading *
      +            self.base_prompt = match.group(1)
      +            return self.base_prompt
      +
      +    def _disable_complete_on_space(self):
      +        """
      +        SR-OS tries to auto complete commands when you type a "space" character.
      +
      +        This is a bad idea for automation as what your program is sending no longer matches
      +        the command echo from the device, so we disable this behavior.
      +        """
      +        delay_factor = self.select_delay_factor(delay_factor=0)
      +        time.sleep(delay_factor * 0.1)
      +        command = "environment command-completion space false"
      +        self.write_channel(self.normalize_cmd(command))
      +        time.sleep(delay_factor * 0.1)
      +        return self.read_channel()
      +
      +    def enable(self, cmd="enable", pattern="ssword", re_flags=re.IGNORECASE):
      +        """Enable SR OS administrative mode"""
      +        if "@" not in self.base_prompt:
      +            cmd = "enable-admin"
      +        return super().enable(cmd=cmd, pattern=pattern, re_flags=re_flags)
      +
      +    def check_enable_mode(self, check_string="in admin mode"):
      +        """Check if in enable mode."""
      +        cmd = "enable"
      +        if "@" not in self.base_prompt:
      +            cmd = "enable-admin"
      +        self.write_channel(self.normalize_cmd(cmd))
      +        output = self.read_until_prompt_or_pattern(pattern="ssword")
      +        if "ssword" in output:
      +            self.write_channel(self.RETURN)  # send ENTER to pass the password prompt
      +            self.read_until_prompt()
      +        return check_string in output
      +
      +    def exit_enable_mode(self, *args, **kwargs):
      +        """Nokia SR OS does not have a notion of exiting administrative mode"""
      +        return ""
      +
      +    def config_mode(self, config_command="edit-config exclusive", pattern=r"\(ex\)\["):
      +        """Enable config edit-mode for Nokia SR OS"""
      +        output = ""
      +        # Only model-driven CLI supports config-mode
      +        if "@" in self.base_prompt:
      +            output += super().config_mode(
      +                config_command=config_command, pattern=pattern
      +            )
      +        return output
      +
      +    def exit_config_mode(self, *args, **kwargs):
      +        """Disable config edit-mode for Nokia SR OS"""
      +        output = self._exit_all()
      +        # Model-driven CLI
      +        if "@" in self.base_prompt and "(ex)[" in output:
      +            # Asterisk indicates changes were made.
      +            if "*(ex)[" in output:
      +                log.warning("Uncommitted changes! Discarding changes!")
      +                output += self._discard()
      +            cmd = "quit-config"
      +            self.write_channel(self.normalize_cmd(cmd))
      +            if self.global_cmd_verify is not False:
      +                output += self.read_until_pattern(pattern=re.escape(cmd))
      +            else:
      +                output += self.read_until_prompt()
      +        if self.check_config_mode():
      +            raise ValueError("Failed to exit configuration mode")
      +        return output
      +
      +    def check_config_mode(self, check_string=r"(ex)[", pattern=r"@"):
      +        """Check config mode for Nokia SR OS"""
      +        if "@" not in self.base_prompt:
      +            # Classical CLI
      +            return False
      +        else:
      +            # Model-driven CLI look for "exclusive"
      +            return super().check_config_mode(check_string=check_string, pattern=pattern)
      +
      +    def save_config(self, *args, **kwargs):
      +        """Persist configuration to cflash for Nokia SR OS"""
      +        return self.send_command(command_string="/admin save", expect_string=r"#")
      +
      +    def send_config_set(self, config_commands=None, exit_config_mode=None, **kwargs):
      +        """Model driven CLI requires you not exit from configuration mode."""
      +        if exit_config_mode is None:
      +            # Set to False if model-driven CLI
      +            exit_config_mode = False if "@" in self.base_prompt else True
      +        return super().send_config_set(
      +            config_commands=config_commands, exit_config_mode=exit_config_mode, **kwargs
      +        )
      +
      +    def commit(self, *args, **kwargs):
      +        """Activate changes from private candidate for Nokia SR OS"""
      +        output = self._exit_all()
      +        if "@" in self.base_prompt and "*(ex)[" in output:
      +            log.info("Apply uncommitted changes!")
      +            cmd = "commit"
      +            self.write_channel(self.normalize_cmd(cmd))
      +            new_output = ""
      +            if self.global_cmd_verify is not False:
      +                new_output += self.read_until_pattern(pattern=re.escape(cmd))
      +            if "@" not in new_output:
      +                new_output += self.read_until_pattern(r"@")
      +            output += new_output
      +        return output
      +
      +    def _exit_all(self):
      +        """Return to the 'root' context."""
      +        output = ""
      +        exit_cmd = "exit all"
      +        self.write_channel(self.normalize_cmd(exit_cmd))
      +        # Make sure you read until you detect the command echo (avoid getting out of sync)
      +        if self.global_cmd_verify is not False:
      +            output += self.read_until_pattern(pattern=re.escape(exit_cmd))
      +        else:
      +            output += self.read_until_prompt()
      +        return output
      +
      +    def _discard(self):
      +        """Discard changes from private candidate for Nokia SR OS"""
      +        output = ""
      +        if "@" in self.base_prompt:
      +            cmd = "discard"
      +            self.write_channel(self.normalize_cmd(cmd))
      +            new_output = ""
      +            if self.global_cmd_verify is not False:
      +                new_output += self.read_until_pattern(pattern=re.escape(cmd))
      +            if "@" not in new_output:
      +                new_output += self.read_until_prompt()
      +            output += new_output
      +        return output
      +
      +    def strip_prompt(self, *args, **kwargs):
      +        """Strip prompt from the output."""
      +        output = super().strip_prompt(*args, **kwargs)
      +        if "@" in self.base_prompt:
      +            # Remove context prompt too
      +            strips = r"[\r\n]*\!?\*?(\((ex|gl|pr|ro)\))?\[\S*\][\r\n]*"
      +            return re.sub(strips, "", output)
      +        else:
      +            return output
      +
      +    def cleanup(self, command="logout"):
      +        """Gracefully exit the SSH session."""
      +        try:
      +            # The pattern="" forces use of send_command_timing
      +            if self.check_config_mode(pattern=""):
      +                self.exit_config_mode()
      +        except Exception:
      +            pass
      +        # Always try to send final 'logout'.
      +        self._session_log_fin = True
      +        self.write_channel(command + self.RETURN)
      +
      +
      +class NokiaSrosSSH(NokiaSros):
      +    """Nokia SR OS SSH driver."""
      +
      +    pass
      +
      +
      +class NokiaSrosTelnet(NokiaSros):
      +    """Nokia SR OS Telnet driver."""
      +
      +    pass
      +
      +
      +class NokiaSrosFileTransfer(BaseFileTransfer):
      +    def __init__(
      +        self, ssh_conn, source_file, dest_file, hash_supported=False, **kwargs
      +    ):
      +        super().__init__(
      +            ssh_conn, source_file, dest_file, hash_supported=hash_supported, **kwargs
      +        )
      +
      +    def _file_cmd_prefix(self):
      +        """
      +        Allow MD-CLI to execute file operations by using classical CLI.
      +
      +        Returns "//" if the current prompt is MD-CLI (empty string otherwise).
      +        """
      +        return "//" if "@" in self.ssh_ctl_chan.base_prompt else ""
      +
      +    def remote_space_available(self, search_pattern=r"(\d+)\s+\w+\s+free"):
      +        """Return space available on remote device."""
      +
      +        # Sample text for search_pattern.
      +        # "               3 Dir(s)               961531904 bytes free."
      +        remote_cmd = self._file_cmd_prefix() + "file dir {}".format(self.file_system)
      +        remote_output = self.ssh_ctl_chan.send_command(remote_cmd)
      +        match = re.search(search_pattern, remote_output)
      +        return int(match.group(1))
      +
      +    def check_file_exists(self, remote_cmd=""):
      +        """Check if destination file exists (returns boolean)."""
      +
      +        if self.direction == "put":
      +            if not remote_cmd:
      +                remote_cmd = self._file_cmd_prefix() + "file dir {}/{}".format(
      +                    self.file_system, self.dest_file
      +                )
      +            dest_file_name = self.dest_file.replace("\\", "/").split("/")[-1]
      +            remote_out = self.ssh_ctl_chan.send_command(remote_cmd)
      +            if "File Not Found" in remote_out:
      +                return False
      +            elif dest_file_name in remote_out:
      +                return True
      +            else:
      +                raise ValueError("Unexpected output from check_file_exists")
      +        elif self.direction == "get":
      +            return os.path.exists(self.dest_file)
      +
      +    def remote_file_size(self, remote_cmd=None, remote_file=None):
      +        """Get the file size of the remote file."""
      +
      +        if remote_file is None:
      +            if self.direction == "put":
      +                remote_file = self.dest_file
      +            elif self.direction == "get":
      +                remote_file = self.source_file
      +        if not remote_cmd:
      +            remote_cmd = self._file_cmd_prefix() + "file dir {}/{}".format(
      +                self.file_system, remote_file
      +            )
      +        remote_out = self.ssh_ctl_chan.send_command(remote_cmd)
      +
      +        if "File Not Found" in remote_out:
      +            raise IOError("Unable to find file on remote system")
      +
      +        dest_file_name = remote_file.replace("\\", "/").split("/")[-1]
      +        # Parse dir output for filename. Output format is:
      +        # "10/16/2019  10:00p                6738 {dest_file_name}"
      +
      +        pattern = r"\S+\s+\S+\s+(\d+)\s+{}".format(re.escape(dest_file_name))
      +        match = re.search(pattern, remote_out)
      +
      +        if not match:
      +            raise ValueError("Filename entry not found in dir output")
      +
      +        file_size = int(match.group(1))
      +        return file_size
      +
      +    def verify_file(self):
      +        """Verify the file has been transferred correctly based on filesize."""
      +        if self.direction == "put":
      +            return os.stat(self.source_file).st_size == self.remote_file_size(
      +                remote_file=self.dest_file
      +            )
      +        elif self.direction == "get":
      +            return (
      +                self.remote_file_size(remote_file=self.source_file)
      +                == os.stat(self.dest_file).st_size
      +            )
      +
      +    def file_md5(self, **kwargs):
      +        raise AttributeError("SR-OS does not support an MD5-hash operation.")
      +
      +    def process_md5(self, **kwargs):
      +        raise AttributeError("SR-OS does not support an MD5-hash operation.")
      +
      +    def compare_md5(self, **kwargs):
      +        raise AttributeError("SR-OS does not support an MD5-hash operation.")
      +
      +    def remote_md5(self, **kwargs):
      +        raise AttributeError("SR-OS does not support an MD5-hash operation.")
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +

      Classes

      +
      +
      +class NokiaSros +(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=5, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=False, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True) +
      +
      +

      Implement methods for interacting with Nokia SR OS devices +for both SSH and telnet.

      +

      Not applicable in Nokia SR OS (disabled): +- exit_enable_mode()

      +

      Overriden methods to adapt Nokia SR OS behavior (changed): +- session_preparation() +- set_base_prompt() +- config_mode() +- exit_config_mode() +- check_config_mode() +- save_config() +- commit() +- strip_prompt() +- enable() +- check_enable_mode()

      +
          Initialize attributes for establishing connection to target device.
      +
      +    :param ip: IP address of target device. Not required if `host` is
      +        provided.
      +    :type ip: str
      +
      +    :param host: Hostname of target device. Not required if `ip` is
      +            provided.
      +    :type host: str
      +
      +    :param username: Username to authenticate against target device if
      +            required.
      +    :type username: str
      +
      +    :param password: Password to authenticate against target device if
      +            required.
      +    :type password: str
      +
      +    :param secret: The enable password if target device requires one.
      +    :type secret: str
      +
      +    :param port: The destination port used to connect to the target
      +            device.
      +    :type port: int or None
      +
      +    :param device_type: Class selection based on device type.
      +    :type device_type: str
      +
      +    :param verbose: Enable additional messages to standard output.
      +    :type verbose: bool
      +
      +    :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
      +    :type global_delay_factor: int
      +
      +    :param use_keys: Connect to target device using SSH keys.
      +    :type use_keys: bool
      +
      +    :param key_file: Filename path of the SSH key file to use.
      +    :type key_file: str
      +
      +    :param pkey: SSH key object to use.
      +    :type pkey: paramiko.PKey
      +
      +    :param passphrase: Passphrase to use for encrypted key; password will be used for key
      +            decryption if not specified.
      +    :type passphrase: str
      +
      +    :param allow_agent: Enable use of SSH key-agent.
      +    :type allow_agent: bool
      +
      +    :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
      +            means unknown SSH host keys will be accepted).
      +    :type ssh_strict: bool
      +
      +    :param system_host_keys: Load host keys from the users known_hosts file.
      +    :type system_host_keys: bool
      +    :param alt_host_keys: If `True` host keys will be loaded from the file specified in
      +            alt_key_file.
      +    :type alt_host_keys: bool
      +
      +    :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
      +    :type alt_key_file: str
      +
      +    :param ssh_config_file: File name of OpenSSH configuration file.
      +    :type ssh_config_file: str
      +
      +    :param timeout: Connection timeout.
      +    :type timeout: float
      +
      +    :param session_timeout: Set a timeout for parallel requests.
      +    :type session_timeout: float
      +
      +    :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
      +    :type auth_timeout: float
      +
      +    :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
      +    :type banner_timeout: float
      +
      +    :param keepalive: Send SSH keepalive packets at a specific interval, in seconds.
      +            Currently defaults to 0, for backwards compatibility (it will not attempt
      +            to keep the connection alive).
      +    :type keepalive: int
      +
      +    :param default_enter: Character(s) to send to correspond to enter key (default:
      +
      +

      ). +:type default_enter: str

      +
          :param response_return: Character(s) to use in normalized return data to represent
      +            enter key (default:
      +
      +

      ) +:type response_return: str

      +
          :param fast_cli: Provide a way to optimize for performance. Converts select_delay_factor
      +            to select smallest of global and specific. Sets default global_delay_factor to .1
      +            (default: False)
      +    :type fast_cli: boolean
      +
      +    :param session_log: File path or BufferedIOBase subclass object to write the session log to.
      +    :type session_log: str
      +
      +    :param session_log_record_writes: The session log generally only records channel reads due
      +            to eliminate command duplication due to command echo. You can enable this if you
      +            want to record both channel reads and channel writes in the log (default: False).
      +    :type session_log_record_writes: boolean
      +
      +    :param session_log_file_mode: "write" or "append" for session_log file mode
      +            (default: "write")
      +    :type session_log_file_mode: str
      +
      +    :param allow_auto_change: Allow automatic configuration changes for terminal settings.
      +            (default: False)
      +    :type allow_auto_change: bool
      +
      +    :param encoding: Encoding to be used when writing bytes to the output channel.
      +            (default: ascii)
      +    :type encoding: str
      +
      +    :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
      +            communication to the target host (default: None).
      +    :type sock: socket
      +
      +    :param global_cmd_verify: Control whether command echo verification is enabled or disabled
      +            (default: None). Global attribute takes precedence over function `cmd_verify`
      +            argument. Value of `None` indicates to use function `cmd_verify` argument.
      +    :type global_cmd_verify: bool|None
      +
      +    :param auto_connect: Control whether Netmiko automatically establishes the connection as
      +            part of the object creation (default: True).
      +    :type auto_connect: bool
      +
      +
      +Source code +
      class NokiaSros(BaseConnection):
      +    """
      +    Implement methods for interacting with Nokia SR OS devices
      +    for both SSH and telnet.
      +
      +    Not applicable in Nokia SR OS (disabled):
      +        - exit_enable_mode()
      +
      +    Overriden methods to adapt Nokia SR OS behavior (changed):
      +        - session_preparation()
      +        - set_base_prompt()
      +        - config_mode()
      +        - exit_config_mode()
      +        - check_config_mode()
      +        - save_config()
      +        - commit()
      +        - strip_prompt()
      +        - enable()
      +        - check_enable_mode()
      +    """
      +
      +    def session_preparation(self):
      +        self._test_channel_read()
      +        self.set_base_prompt()
      +        # "@" indicates model-driven CLI (vs Classical CLI)
      +        if "@" in self.base_prompt:
      +            self._disable_complete_on_space()
      +            self.set_terminal_width(
      +                command="environment console width 512", pattern="environment"
      +            )
      +            self.disable_paging(command="environment more false")
      +            # To perform file operations we need to disable paging in classical-CLI also
      +            self.disable_paging(command="//environment no more")
      +        else:
      +            # Classical CLI has no method to set the terminal width nor to disable command
      +            # complete on space; consequently, cmd_verify needs disabled.
      +            self.global_cmd_verify = False
      +            self.disable_paging(command="environment no more", pattern="environment")
      +
      +        # Clear the read buffer
      +        time.sleep(0.3 * self.global_delay_factor)
      +        self.clear_buffer()
      +
      +    def set_base_prompt(self, *args, **kwargs):
      +        """Remove the > when navigating into the different config level."""
      +        cur_base_prompt = super().set_base_prompt(*args, **kwargs)
      +        match = re.search(r"\*?(.*?)(>.*)*#", cur_base_prompt)
      +        if match:
      +            # strip off >... from base_prompt; strip off leading *
      +            self.base_prompt = match.group(1)
      +            return self.base_prompt
      +
      +    def _disable_complete_on_space(self):
      +        """
      +        SR-OS tries to auto complete commands when you type a "space" character.
      +
      +        This is a bad idea for automation as what your program is sending no longer matches
      +        the command echo from the device, so we disable this behavior.
      +        """
      +        delay_factor = self.select_delay_factor(delay_factor=0)
      +        time.sleep(delay_factor * 0.1)
      +        command = "environment command-completion space false"
      +        self.write_channel(self.normalize_cmd(command))
      +        time.sleep(delay_factor * 0.1)
      +        return self.read_channel()
      +
      +    def enable(self, cmd="enable", pattern="ssword", re_flags=re.IGNORECASE):
      +        """Enable SR OS administrative mode"""
      +        if "@" not in self.base_prompt:
      +            cmd = "enable-admin"
      +        return super().enable(cmd=cmd, pattern=pattern, re_flags=re_flags)
      +
      +    def check_enable_mode(self, check_string="in admin mode"):
      +        """Check if in enable mode."""
      +        cmd = "enable"
      +        if "@" not in self.base_prompt:
      +            cmd = "enable-admin"
      +        self.write_channel(self.normalize_cmd(cmd))
      +        output = self.read_until_prompt_or_pattern(pattern="ssword")
      +        if "ssword" in output:
      +            self.write_channel(self.RETURN)  # send ENTER to pass the password prompt
      +            self.read_until_prompt()
      +        return check_string in output
      +
      +    def exit_enable_mode(self, *args, **kwargs):
      +        """Nokia SR OS does not have a notion of exiting administrative mode"""
      +        return ""
      +
      +    def config_mode(self, config_command="edit-config exclusive", pattern=r"\(ex\)\["):
      +        """Enable config edit-mode for Nokia SR OS"""
      +        output = ""
      +        # Only model-driven CLI supports config-mode
      +        if "@" in self.base_prompt:
      +            output += super().config_mode(
      +                config_command=config_command, pattern=pattern
      +            )
      +        return output
      +
      +    def exit_config_mode(self, *args, **kwargs):
      +        """Disable config edit-mode for Nokia SR OS"""
      +        output = self._exit_all()
      +        # Model-driven CLI
      +        if "@" in self.base_prompt and "(ex)[" in output:
      +            # Asterisk indicates changes were made.
      +            if "*(ex)[" in output:
      +                log.warning("Uncommitted changes! Discarding changes!")
      +                output += self._discard()
      +            cmd = "quit-config"
      +            self.write_channel(self.normalize_cmd(cmd))
      +            if self.global_cmd_verify is not False:
      +                output += self.read_until_pattern(pattern=re.escape(cmd))
      +            else:
      +                output += self.read_until_prompt()
      +        if self.check_config_mode():
      +            raise ValueError("Failed to exit configuration mode")
      +        return output
      +
      +    def check_config_mode(self, check_string=r"(ex)[", pattern=r"@"):
      +        """Check config mode for Nokia SR OS"""
      +        if "@" not in self.base_prompt:
      +            # Classical CLI
      +            return False
      +        else:
      +            # Model-driven CLI look for "exclusive"
      +            return super().check_config_mode(check_string=check_string, pattern=pattern)
      +
      +    def save_config(self, *args, **kwargs):
      +        """Persist configuration to cflash for Nokia SR OS"""
      +        return self.send_command(command_string="/admin save", expect_string=r"#")
      +
      +    def send_config_set(self, config_commands=None, exit_config_mode=None, **kwargs):
      +        """Model driven CLI requires you not exit from configuration mode."""
      +        if exit_config_mode is None:
      +            # Set to False if model-driven CLI
      +            exit_config_mode = False if "@" in self.base_prompt else True
      +        return super().send_config_set(
      +            config_commands=config_commands, exit_config_mode=exit_config_mode, **kwargs
      +        )
      +
      +    def commit(self, *args, **kwargs):
      +        """Activate changes from private candidate for Nokia SR OS"""
      +        output = self._exit_all()
      +        if "@" in self.base_prompt and "*(ex)[" in output:
      +            log.info("Apply uncommitted changes!")
      +            cmd = "commit"
      +            self.write_channel(self.normalize_cmd(cmd))
      +            new_output = ""
      +            if self.global_cmd_verify is not False:
      +                new_output += self.read_until_pattern(pattern=re.escape(cmd))
      +            if "@" not in new_output:
      +                new_output += self.read_until_pattern(r"@")
      +            output += new_output
      +        return output
      +
      +    def _exit_all(self):
      +        """Return to the 'root' context."""
      +        output = ""
      +        exit_cmd = "exit all"
      +        self.write_channel(self.normalize_cmd(exit_cmd))
      +        # Make sure you read until you detect the command echo (avoid getting out of sync)
      +        if self.global_cmd_verify is not False:
      +            output += self.read_until_pattern(pattern=re.escape(exit_cmd))
      +        else:
      +            output += self.read_until_prompt()
      +        return output
      +
      +    def _discard(self):
      +        """Discard changes from private candidate for Nokia SR OS"""
      +        output = ""
      +        if "@" in self.base_prompt:
      +            cmd = "discard"
      +            self.write_channel(self.normalize_cmd(cmd))
      +            new_output = ""
      +            if self.global_cmd_verify is not False:
      +                new_output += self.read_until_pattern(pattern=re.escape(cmd))
      +            if "@" not in new_output:
      +                new_output += self.read_until_prompt()
      +            output += new_output
      +        return output
      +
      +    def strip_prompt(self, *args, **kwargs):
      +        """Strip prompt from the output."""
      +        output = super().strip_prompt(*args, **kwargs)
      +        if "@" in self.base_prompt:
      +            # Remove context prompt too
      +            strips = r"[\r\n]*\!?\*?(\((ex|gl|pr|ro)\))?\[\S*\][\r\n]*"
      +            return re.sub(strips, "", output)
      +        else:
      +            return output
      +
      +    def cleanup(self, command="logout"):
      +        """Gracefully exit the SSH session."""
      +        try:
      +            # The pattern="" forces use of send_command_timing
      +            if self.check_config_mode(pattern=""):
      +                self.exit_config_mode()
      +        except Exception:
      +            pass
      +        # Always try to send final 'logout'.
      +        self._session_log_fin = True
      +        self.write_channel(command + self.RETURN)
      +
      +

      Ancestors

      + +

      Subclasses

      + +

      Methods

      +
      +
      +def check_config_mode(self, check_string='(ex)[', pattern='@') +
      +
      +

      Check config mode for Nokia SR OS

      +
      +Source code +
      def check_config_mode(self, check_string=r"(ex)[", pattern=r"@"):
      +    """Check config mode for Nokia SR OS"""
      +    if "@" not in self.base_prompt:
      +        # Classical CLI
      +        return False
      +    else:
      +        # Model-driven CLI look for "exclusive"
      +        return super().check_config_mode(check_string=check_string, pattern=pattern)
      +
      +
      +
      +def check_enable_mode(self, check_string='in admin mode') +
      +
      +

      Check if in enable mode.

      +
      +Source code +
      def check_enable_mode(self, check_string="in admin mode"):
      +    """Check if in enable mode."""
      +    cmd = "enable"
      +    if "@" not in self.base_prompt:
      +        cmd = "enable-admin"
      +    self.write_channel(self.normalize_cmd(cmd))
      +    output = self.read_until_prompt_or_pattern(pattern="ssword")
      +    if "ssword" in output:
      +        self.write_channel(self.RETURN)  # send ENTER to pass the password prompt
      +        self.read_until_prompt()
      +    return check_string in output
      +
      +
      +
      +def cleanup(self, command='logout') +
      +
      +

      Gracefully exit the SSH session.

      +
      +Source code +
      def cleanup(self, command="logout"):
      +    """Gracefully exit the SSH session."""
      +    try:
      +        # The pattern="" forces use of send_command_timing
      +        if self.check_config_mode(pattern=""):
      +            self.exit_config_mode()
      +    except Exception:
      +        pass
      +    # Always try to send final 'logout'.
      +    self._session_log_fin = True
      +    self.write_channel(command + self.RETURN)
      +
      +
      +
      +def commit(self, *args, **kwargs) +
      +
      +

      Activate changes from private candidate for Nokia SR OS

      +
      +Source code +
      def commit(self, *args, **kwargs):
      +    """Activate changes from private candidate for Nokia SR OS"""
      +    output = self._exit_all()
      +    if "@" in self.base_prompt and "*(ex)[" in output:
      +        log.info("Apply uncommitted changes!")
      +        cmd = "commit"
      +        self.write_channel(self.normalize_cmd(cmd))
      +        new_output = ""
      +        if self.global_cmd_verify is not False:
      +            new_output += self.read_until_pattern(pattern=re.escape(cmd))
      +        if "@" not in new_output:
      +            new_output += self.read_until_pattern(r"@")
      +        output += new_output
      +    return output
      +
      +
      +
      +def config_mode(self, config_command='edit-config exclusive', pattern='\\(ex\\)\\[') +
      +
      +

      Enable config edit-mode for Nokia SR OS

      +
      +Source code +
      def config_mode(self, config_command="edit-config exclusive", pattern=r"\(ex\)\["):
      +    """Enable config edit-mode for Nokia SR OS"""
      +    output = ""
      +    # Only model-driven CLI supports config-mode
      +    if "@" in self.base_prompt:
      +        output += super().config_mode(
      +            config_command=config_command, pattern=pattern
      +        )
      +    return output
      +
      +
      +
      +def enable(self, cmd='enable', pattern='ssword', re_flags=) +
      +
      +

      Enable SR OS administrative mode

      +
      +Source code +
      def enable(self, cmd="enable", pattern="ssword", re_flags=re.IGNORECASE):
      +    """Enable SR OS administrative mode"""
      +    if "@" not in self.base_prompt:
      +        cmd = "enable-admin"
      +    return super().enable(cmd=cmd, pattern=pattern, re_flags=re_flags)
      +
      +
      +
      +def exit_config_mode(self, *args, **kwargs) +
      +
      +

      Disable config edit-mode for Nokia SR OS

      +
      +Source code +
      def exit_config_mode(self, *args, **kwargs):
      +    """Disable config edit-mode for Nokia SR OS"""
      +    output = self._exit_all()
      +    # Model-driven CLI
      +    if "@" in self.base_prompt and "(ex)[" in output:
      +        # Asterisk indicates changes were made.
      +        if "*(ex)[" in output:
      +            log.warning("Uncommitted changes! Discarding changes!")
      +            output += self._discard()
      +        cmd = "quit-config"
      +        self.write_channel(self.normalize_cmd(cmd))
      +        if self.global_cmd_verify is not False:
      +            output += self.read_until_pattern(pattern=re.escape(cmd))
      +        else:
      +            output += self.read_until_prompt()
      +    if self.check_config_mode():
      +        raise ValueError("Failed to exit configuration mode")
      +    return output
      +
      +
      +
      +def exit_enable_mode(self, *args, **kwargs) +
      +
      +

      Nokia SR OS does not have a notion of exiting administrative mode

      +
      +Source code +
      def exit_enable_mode(self, *args, **kwargs):
      +    """Nokia SR OS does not have a notion of exiting administrative mode"""
      +    return ""
      +
      +
      +
      +def save_config(self, *args, **kwargs) +
      +
      +

      Persist configuration to cflash for Nokia SR OS

      +
      +Source code +
      def save_config(self, *args, **kwargs):
      +    """Persist configuration to cflash for Nokia SR OS"""
      +    return self.send_command(command_string="/admin save", expect_string=r"#")
      +
      +
      +
      +def send_config_set(self, config_commands=None, exit_config_mode=None, **kwargs) +
      +
      +

      Model driven CLI requires you not exit from configuration mode.

      +
      +Source code +
      def send_config_set(self, config_commands=None, exit_config_mode=None, **kwargs):
      +    """Model driven CLI requires you not exit from configuration mode."""
      +    if exit_config_mode is None:
      +        # Set to False if model-driven CLI
      +        exit_config_mode = False if "@" in self.base_prompt else True
      +    return super().send_config_set(
      +        config_commands=config_commands, exit_config_mode=exit_config_mode, **kwargs
      +    )
      +
      +
      +
      +def set_base_prompt(self, *args, **kwargs) +
      +
      +

      Remove the > when navigating into the different config level.

      +
      +Source code +
      def set_base_prompt(self, *args, **kwargs):
      +    """Remove the > when navigating into the different config level."""
      +    cur_base_prompt = super().set_base_prompt(*args, **kwargs)
      +    match = re.search(r"\*?(.*?)(>.*)*#", cur_base_prompt)
      +    if match:
      +        # strip off >... from base_prompt; strip off leading *
      +        self.base_prompt = match.group(1)
      +        return self.base_prompt
      +
      +
      +
      +def strip_prompt(self, *args, **kwargs) +
      +
      +

      Strip prompt from the output.

      +
      +Source code +
      def strip_prompt(self, *args, **kwargs):
      +    """Strip prompt from the output."""
      +    output = super().strip_prompt(*args, **kwargs)
      +    if "@" in self.base_prompt:
      +        # Remove context prompt too
      +        strips = r"[\r\n]*\!?\*?(\((ex|gl|pr|ro)\))?\[\S*\][\r\n]*"
      +        return re.sub(strips, "", output)
      +    else:
      +        return output
      +
      +
      +
      +

      Inherited members

      + +
      +
      +class NokiaSrosFileTransfer +(ssh_conn, source_file, dest_file, hash_supported=False, **kwargs) +
      +
      +

      Class to manage SCP file transfer and associated SSH control channel.

      +
      +Source code +
      class NokiaSrosFileTransfer(BaseFileTransfer):
      +    def __init__(
      +        self, ssh_conn, source_file, dest_file, hash_supported=False, **kwargs
      +    ):
      +        super().__init__(
      +            ssh_conn, source_file, dest_file, hash_supported=hash_supported, **kwargs
      +        )
      +
      +    def _file_cmd_prefix(self):
      +        """
      +        Allow MD-CLI to execute file operations by using classical CLI.
      +
      +        Returns "//" if the current prompt is MD-CLI (empty string otherwise).
      +        """
      +        return "//" if "@" in self.ssh_ctl_chan.base_prompt else ""
      +
      +    def remote_space_available(self, search_pattern=r"(\d+)\s+\w+\s+free"):
      +        """Return space available on remote device."""
      +
      +        # Sample text for search_pattern.
      +        # "               3 Dir(s)               961531904 bytes free."
      +        remote_cmd = self._file_cmd_prefix() + "file dir {}".format(self.file_system)
      +        remote_output = self.ssh_ctl_chan.send_command(remote_cmd)
      +        match = re.search(search_pattern, remote_output)
      +        return int(match.group(1))
      +
      +    def check_file_exists(self, remote_cmd=""):
      +        """Check if destination file exists (returns boolean)."""
      +
      +        if self.direction == "put":
      +            if not remote_cmd:
      +                remote_cmd = self._file_cmd_prefix() + "file dir {}/{}".format(
      +                    self.file_system, self.dest_file
      +                )
      +            dest_file_name = self.dest_file.replace("\\", "/").split("/")[-1]
      +            remote_out = self.ssh_ctl_chan.send_command(remote_cmd)
      +            if "File Not Found" in remote_out:
      +                return False
      +            elif dest_file_name in remote_out:
      +                return True
      +            else:
      +                raise ValueError("Unexpected output from check_file_exists")
      +        elif self.direction == "get":
      +            return os.path.exists(self.dest_file)
      +
      +    def remote_file_size(self, remote_cmd=None, remote_file=None):
      +        """Get the file size of the remote file."""
      +
      +        if remote_file is None:
      +            if self.direction == "put":
      +                remote_file = self.dest_file
      +            elif self.direction == "get":
      +                remote_file = self.source_file
      +        if not remote_cmd:
      +            remote_cmd = self._file_cmd_prefix() + "file dir {}/{}".format(
      +                self.file_system, remote_file
      +            )
      +        remote_out = self.ssh_ctl_chan.send_command(remote_cmd)
      +
      +        if "File Not Found" in remote_out:
      +            raise IOError("Unable to find file on remote system")
      +
      +        dest_file_name = remote_file.replace("\\", "/").split("/")[-1]
      +        # Parse dir output for filename. Output format is:
      +        # "10/16/2019  10:00p                6738 {dest_file_name}"
      +
      +        pattern = r"\S+\s+\S+\s+(\d+)\s+{}".format(re.escape(dest_file_name))
      +        match = re.search(pattern, remote_out)
      +
      +        if not match:
      +            raise ValueError("Filename entry not found in dir output")
      +
      +        file_size = int(match.group(1))
      +        return file_size
      +
      +    def verify_file(self):
      +        """Verify the file has been transferred correctly based on filesize."""
      +        if self.direction == "put":
      +            return os.stat(self.source_file).st_size == self.remote_file_size(
      +                remote_file=self.dest_file
      +            )
      +        elif self.direction == "get":
      +            return (
      +                self.remote_file_size(remote_file=self.source_file)
      +                == os.stat(self.dest_file).st_size
      +            )
      +
      +    def file_md5(self, **kwargs):
      +        raise AttributeError("SR-OS does not support an MD5-hash operation.")
      +
      +    def process_md5(self, **kwargs):
      +        raise AttributeError("SR-OS does not support an MD5-hash operation.")
      +
      +    def compare_md5(self, **kwargs):
      +        raise AttributeError("SR-OS does not support an MD5-hash operation.")
      +
      +    def remote_md5(self, **kwargs):
      +        raise AttributeError("SR-OS does not support an MD5-hash operation.")
      +
      +

      Ancestors

      + +

      Methods

      +
      +
      +def check_file_exists(self, remote_cmd='') +
      +
      +

      Check if destination file exists (returns boolean).

      +
      +Source code +
      def check_file_exists(self, remote_cmd=""):
      +    """Check if destination file exists (returns boolean)."""
      +
      +    if self.direction == "put":
      +        if not remote_cmd:
      +            remote_cmd = self._file_cmd_prefix() + "file dir {}/{}".format(
      +                self.file_system, self.dest_file
      +            )
      +        dest_file_name = self.dest_file.replace("\\", "/").split("/")[-1]
      +        remote_out = self.ssh_ctl_chan.send_command(remote_cmd)
      +        if "File Not Found" in remote_out:
      +            return False
      +        elif dest_file_name in remote_out:
      +            return True
      +        else:
      +            raise ValueError("Unexpected output from check_file_exists")
      +    elif self.direction == "get":
      +        return os.path.exists(self.dest_file)
      +
      +
      +
      +def verify_file(self) +
      +
      +

      Verify the file has been transferred correctly based on filesize.

      +
      +Source code +
      def verify_file(self):
      +    """Verify the file has been transferred correctly based on filesize."""
      +    if self.direction == "put":
      +        return os.stat(self.source_file).st_size == self.remote_file_size(
      +            remote_file=self.dest_file
      +        )
      +    elif self.direction == "get":
      +        return (
      +            self.remote_file_size(remote_file=self.source_file)
      +            == os.stat(self.dest_file).st_size
      +        )
      +
      +
      +
      +

      Inherited members

      + +
      +
      +class NokiaSrosSSH +(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=5, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=False, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True) +
      +
      +

      Nokia SR OS SSH driver.

      +
          Initialize attributes for establishing connection to target device.
      +
      +    :param ip: IP address of target device. Not required if `host` is
      +        provided.
      +    :type ip: str
      +
      +    :param host: Hostname of target device. Not required if `ip` is
      +            provided.
      +    :type host: str
      +
      +    :param username: Username to authenticate against target device if
      +            required.
      +    :type username: str
      +
      +    :param password: Password to authenticate against target device if
      +            required.
      +    :type password: str
      +
      +    :param secret: The enable password if target device requires one.
      +    :type secret: str
      +
      +    :param port: The destination port used to connect to the target
      +            device.
      +    :type port: int or None
      +
      +    :param device_type: Class selection based on device type.
      +    :type device_type: str
      +
      +    :param verbose: Enable additional messages to standard output.
      +    :type verbose: bool
      +
      +    :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
      +    :type global_delay_factor: int
      +
      +    :param use_keys: Connect to target device using SSH keys.
      +    :type use_keys: bool
      +
      +    :param key_file: Filename path of the SSH key file to use.
      +    :type key_file: str
      +
      +    :param pkey: SSH key object to use.
      +    :type pkey: paramiko.PKey
      +
      +    :param passphrase: Passphrase to use for encrypted key; password will be used for key
      +            decryption if not specified.
      +    :type passphrase: str
      +
      +    :param allow_agent: Enable use of SSH key-agent.
      +    :type allow_agent: bool
      +
      +    :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
      +            means unknown SSH host keys will be accepted).
      +    :type ssh_strict: bool
      +
      +    :param system_host_keys: Load host keys from the users known_hosts file.
      +    :type system_host_keys: bool
      +    :param alt_host_keys: If `True` host keys will be loaded from the file specified in
      +            alt_key_file.
      +    :type alt_host_keys: bool
      +
      +    :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
      +    :type alt_key_file: str
      +
      +    :param ssh_config_file: File name of OpenSSH configuration file.
      +    :type ssh_config_file: str
      +
      +    :param timeout: Connection timeout.
      +    :type timeout: float
      +
      +    :param session_timeout: Set a timeout for parallel requests.
      +    :type session_timeout: float
      +
      +    :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
      +    :type auth_timeout: float
      +
      +    :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
      +    :type banner_timeout: float
      +
      +    :param keepalive: Send SSH keepalive packets at a specific interval, in seconds.
      +            Currently defaults to 0, for backwards compatibility (it will not attempt
      +            to keep the connection alive).
      +    :type keepalive: int
      +
      +    :param default_enter: Character(s) to send to correspond to enter key (default:
      +
      +

      ). +:type default_enter: str

      +
          :param response_return: Character(s) to use in normalized return data to represent
      +            enter key (default:
      +
      +

      ) +:type response_return: str

      +
          :param fast_cli: Provide a way to optimize for performance. Converts select_delay_factor
      +            to select smallest of global and specific. Sets default global_delay_factor to .1
      +            (default: False)
      +    :type fast_cli: boolean
      +
      +    :param session_log: File path or BufferedIOBase subclass object to write the session log to.
      +    :type session_log: str
      +
      +    :param session_log_record_writes: The session log generally only records channel reads due
      +            to eliminate command duplication due to command echo. You can enable this if you
      +            want to record both channel reads and channel writes in the log (default: False).
      +    :type session_log_record_writes: boolean
      +
      +    :param session_log_file_mode: "write" or "append" for session_log file mode
      +            (default: "write")
      +    :type session_log_file_mode: str
      +
      +    :param allow_auto_change: Allow automatic configuration changes for terminal settings.
      +            (default: False)
      +    :type allow_auto_change: bool
      +
      +    :param encoding: Encoding to be used when writing bytes to the output channel.
      +            (default: ascii)
      +    :type encoding: str
      +
      +    :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
      +            communication to the target host (default: None).
      +    :type sock: socket
      +
      +    :param global_cmd_verify: Control whether command echo verification is enabled or disabled
      +            (default: None). Global attribute takes precedence over function `cmd_verify`
      +            argument. Value of `None` indicates to use function `cmd_verify` argument.
      +    :type global_cmd_verify: bool|None
      +
      +    :param auto_connect: Control whether Netmiko automatically establishes the connection as
      +            part of the object creation (default: True).
      +    :type auto_connect: bool
      +
      +
      +Source code +
      class NokiaSrosSSH(NokiaSros):
      +    """Nokia SR OS SSH driver."""
      +
      +    pass
      +
      +

      Ancestors

      + +

      Inherited members

      + +
      +
      +class NokiaSrosTelnet +(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=5, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=False, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True) +
      +
      +

      Nokia SR OS Telnet driver.

      +
          Initialize attributes for establishing connection to target device.
      +
      +    :param ip: IP address of target device. Not required if `host` is
      +        provided.
      +    :type ip: str
      +
      +    :param host: Hostname of target device. Not required if `ip` is
      +            provided.
      +    :type host: str
      +
      +    :param username: Username to authenticate against target device if
      +            required.
      +    :type username: str
      +
      +    :param password: Password to authenticate against target device if
      +            required.
      +    :type password: str
      +
      +    :param secret: The enable password if target device requires one.
      +    :type secret: str
      +
      +    :param port: The destination port used to connect to the target
      +            device.
      +    :type port: int or None
      +
      +    :param device_type: Class selection based on device type.
      +    :type device_type: str
      +
      +    :param verbose: Enable additional messages to standard output.
      +    :type verbose: bool
      +
      +    :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
      +    :type global_delay_factor: int
      +
      +    :param use_keys: Connect to target device using SSH keys.
      +    :type use_keys: bool
      +
      +    :param key_file: Filename path of the SSH key file to use.
      +    :type key_file: str
      +
      +    :param pkey: SSH key object to use.
      +    :type pkey: paramiko.PKey
      +
      +    :param passphrase: Passphrase to use for encrypted key; password will be used for key
      +            decryption if not specified.
      +    :type passphrase: str
      +
      +    :param allow_agent: Enable use of SSH key-agent.
      +    :type allow_agent: bool
      +
      +    :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
      +            means unknown SSH host keys will be accepted).
      +    :type ssh_strict: bool
      +
      +    :param system_host_keys: Load host keys from the users known_hosts file.
      +    :type system_host_keys: bool
      +    :param alt_host_keys: If `True` host keys will be loaded from the file specified in
      +            alt_key_file.
      +    :type alt_host_keys: bool
      +
      +    :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
      +    :type alt_key_file: str
      +
      +    :param ssh_config_file: File name of OpenSSH configuration file.
      +    :type ssh_config_file: str
      +
      +    :param timeout: Connection timeout.
      +    :type timeout: float
      +
      +    :param session_timeout: Set a timeout for parallel requests.
      +    :type session_timeout: float
      +
      +    :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
      +    :type auth_timeout: float
      +
      +    :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
      +    :type banner_timeout: float
      +
      +    :param keepalive: Send SSH keepalive packets at a specific interval, in seconds.
      +            Currently defaults to 0, for backwards compatibility (it will not attempt
      +            to keep the connection alive).
      +    :type keepalive: int
      +
      +    :param default_enter: Character(s) to send to correspond to enter key (default:
      +
      +

      ). +:type default_enter: str

      +
          :param response_return: Character(s) to use in normalized return data to represent
      +            enter key (default:
      +
      +

      ) +:type response_return: str

      +
          :param fast_cli: Provide a way to optimize for performance. Converts select_delay_factor
      +            to select smallest of global and specific. Sets default global_delay_factor to .1
      +            (default: False)
      +    :type fast_cli: boolean
      +
      +    :param session_log: File path or BufferedIOBase subclass object to write the session log to.
      +    :type session_log: str
      +
      +    :param session_log_record_writes: The session log generally only records channel reads due
      +            to eliminate command duplication due to command echo. You can enable this if you
      +            want to record both channel reads and channel writes in the log (default: False).
      +    :type session_log_record_writes: boolean
      +
      +    :param session_log_file_mode: "write" or "append" for session_log file mode
      +            (default: "write")
      +    :type session_log_file_mode: str
      +
      +    :param allow_auto_change: Allow automatic configuration changes for terminal settings.
      +            (default: False)
      +    :type allow_auto_change: bool
      +
      +    :param encoding: Encoding to be used when writing bytes to the output channel.
      +            (default: ascii)
      +    :type encoding: str
      +
      +    :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
      +            communication to the target host (default: None).
      +    :type sock: socket
      +
      +    :param global_cmd_verify: Control whether command echo verification is enabled or disabled
      +            (default: None). Global attribute takes precedence over function `cmd_verify`
      +            argument. Value of `None` indicates to use function `cmd_verify` argument.
      +    :type global_cmd_verify: bool|None
      +
      +    :param auto_connect: Control whether Netmiko automatically establishes the connection as
      +            part of the object creation (default: True).
      +    :type auto_connect: bool
      +
      +
      +Source code +
      class NokiaSrosTelnet(NokiaSros):
      +    """Nokia SR OS Telnet driver."""
      +
      +    pass
      +
      +

      Ancestors

      + +

      Inherited members

      + +
      +
      +
      +
      + +
      + + + + + \ No newline at end of file diff --git a/docs/netmiko/oneaccess/index.html b/docs/netmiko/oneaccess/index.html index 025a3c4b4..595a997e6 100644 --- a/docs/netmiko/oneaccess/index.html +++ b/docs/netmiko/oneaccess/index.html @@ -88,6 +88,7 @@

      Inherited members

    • read_until_pattern
    • read_until_prompt
    • read_until_prompt_or_pattern
    • +
    • run_ttp
    • save_config
    • select_delay_factor
    • send_command
    • @@ -154,6 +155,7 @@

      Inherited members

    • read_until_pattern
    • read_until_prompt
    • read_until_prompt_or_pattern
    • +
    • run_ttp
    • save_config
    • select_delay_factor
    • send_command
    • diff --git a/docs/netmiko/oneaccess/oneaccess_oneos.html b/docs/netmiko/oneaccess/oneaccess_oneos.html index b36328b77..053679cf2 100644 --- a/docs/netmiko/oneaccess/oneaccess_oneos.html +++ b/docs/netmiko/oneaccess/oneaccess_oneos.html @@ -173,6 +173,7 @@

      Inherited members

    • read_until_pattern
    • read_until_prompt
    • read_until_prompt_or_pattern
    • +
    • run_ttp
    • select_delay_factor
    • send_command
    • send_command_expect
    • @@ -237,6 +238,7 @@

      Inherited members

    • read_until_pattern
    • read_until_prompt
    • read_until_prompt_or_pattern
    • +
    • run_ttp
    • save_config
    • select_delay_factor
    • send_command
    • @@ -303,6 +305,7 @@

      Inherited members

    • read_until_pattern
    • read_until_prompt
    • read_until_prompt_or_pattern
    • +
    • run_ttp
    • save_config
    • select_delay_factor
    • send_command
    • diff --git a/docs/netmiko/ovs/index.html b/docs/netmiko/ovs/index.html index 73bac68bd..09ad98cdd 100644 --- a/docs/netmiko/ovs/index.html +++ b/docs/netmiko/ovs/index.html @@ -218,6 +218,7 @@

      Inherited members

    • read_until_pattern
    • read_until_prompt
    • read_until_prompt_or_pattern
    • +
    • run_ttp
    • save_config
    • select_delay_factor
    • send_command
    • diff --git a/docs/netmiko/ovs/ovs_linux_ssh.html b/docs/netmiko/ovs/ovs_linux_ssh.html index 60bf21eea..db0c5126d 100644 --- a/docs/netmiko/ovs/ovs_linux_ssh.html +++ b/docs/netmiko/ovs/ovs_linux_ssh.html @@ -213,6 +213,7 @@

      Inherited members

    • read_until_pattern
    • read_until_prompt
    • read_until_prompt_or_pattern
    • +
    • run_ttp
    • save_config
    • select_delay_factor
    • send_command
    • diff --git a/docs/netmiko/paloalto/index.html b/docs/netmiko/paloalto/index.html index b2e60fdda..b7d0f4ecd 100644 --- a/docs/netmiko/paloalto/index.html +++ b/docs/netmiko/paloalto/index.html @@ -219,6 +219,7 @@

      Inherited members

    • read_until_pattern
    • read_until_prompt
    • read_until_prompt_or_pattern
    • +
    • run_ttp
    • save_config
    • select_delay_factor
    • send_command
    • @@ -417,6 +418,7 @@

      Inherited members

    • read_until_pattern
    • read_until_prompt
    • read_until_prompt_or_pattern
    • +
    • run_ttp
    • save_config
    • select_delay_factor
    • send_command
    • diff --git a/docs/netmiko/paloalto/paloalto_panos.html b/docs/netmiko/paloalto/paloalto_panos.html index 8f7df22fe..e90cc228a 100644 --- a/docs/netmiko/paloalto/paloalto_panos.html +++ b/docs/netmiko/paloalto/paloalto_panos.html @@ -42,9 +42,11 @@

      Module netmiko.paloalto.paloalto_panos

      Disable paging (the '--more--' prompts). Set the base prompt for interaction ('>'). """ + self.ansi_escape_codes = True self._test_channel_read() self.set_base_prompt(delay_factor=20) self.disable_paging(command="set cli pager off") + self.disable_paging(command="set cli scripting-mode on") # Clear the read buffer time.sleep(0.3 * self.global_delay_factor) self.clear_buffer() @@ -372,9 +374,11 @@

      Classes

      Disable paging (the '--more--' prompts). Set the base prompt for interaction ('>'). """ + self.ansi_escape_codes = True self._test_channel_read() self.set_base_prompt(delay_factor=20) self.disable_paging(command="set cli pager off") + self.disable_paging(command="set cli scripting-mode on") # Clear the read buffer time.sleep(0.3 * self.global_delay_factor) self.clear_buffer() @@ -757,9 +761,11 @@

      Methods

      Disable paging (the '--more--' prompts). Set the base prompt for interaction ('>'). """ + self.ansi_escape_codes = True self._test_channel_read() self.set_base_prompt(delay_factor=20) self.disable_paging(command="set cli pager off") + self.disable_paging(command="set cli scripting-mode on") # Clear the read buffer time.sleep(0.3 * self.global_delay_factor) self.clear_buffer()
      @@ -847,6 +853,7 @@

      Inherited members

    • read_until_pattern
    • read_until_prompt
    • read_until_prompt_or_pattern
    • +
    • run_ttp
    • save_config
    • select_delay_factor
    • send_command_timing
    • @@ -1039,6 +1046,7 @@

      Inherited members

    • read_until_pattern
    • read_until_prompt
    • read_until_prompt_or_pattern
    • +
    • run_ttp
    • save_config
    • select_delay_factor
    • send_command
    • @@ -1237,6 +1245,7 @@

      Inherited members

    • read_until_pattern
    • read_until_prompt
    • read_until_prompt_or_pattern
    • +
    • run_ttp
    • save_config
    • select_delay_factor
    • send_command
    • diff --git a/docs/netmiko/pluribus/index.html b/docs/netmiko/pluribus/index.html index 4e4ced627..c2fdcc9ea 100644 --- a/docs/netmiko/pluribus/index.html +++ b/docs/netmiko/pluribus/index.html @@ -320,6 +320,7 @@

      Inherited members

    • read_until_pattern
    • read_until_prompt
    • read_until_prompt_or_pattern
    • +
    • run_ttp
    • save_config
    • select_delay_factor
    • send_command
    • diff --git a/docs/netmiko/pluribus/pluribus_ssh.html b/docs/netmiko/pluribus/pluribus_ssh.html index d8fc8b621..cc8a4f640 100644 --- a/docs/netmiko/pluribus/pluribus_ssh.html +++ b/docs/netmiko/pluribus/pluribus_ssh.html @@ -349,6 +349,7 @@

      Inherited members

    • read_until_pattern
    • read_until_prompt
    • read_until_prompt_or_pattern
    • +
    • run_ttp
    • save_config
    • select_delay_factor
    • send_command
    • diff --git a/docs/netmiko/quanta/index.html b/docs/netmiko/quanta/index.html index f8bd86a9e..4d8e221c6 100644 --- a/docs/netmiko/quanta/index.html +++ b/docs/netmiko/quanta/index.html @@ -278,6 +278,7 @@

      Inherited members

    • read_until_pattern
    • read_until_prompt
    • read_until_prompt_or_pattern
    • +
    • run_ttp
    • select_delay_factor
    • send_command
    • send_command_expect
    • diff --git a/docs/netmiko/quanta/quanta_mesh_ssh.html b/docs/netmiko/quanta/quanta_mesh_ssh.html index f5f38ec30..e13d85053 100644 --- a/docs/netmiko/quanta/quanta_mesh_ssh.html +++ b/docs/netmiko/quanta/quanta_mesh_ssh.html @@ -290,6 +290,7 @@

      Inherited members

    • read_until_pattern
    • read_until_prompt
    • read_until_prompt_or_pattern
    • +
    • run_ttp
    • select_delay_factor
    • send_command
    • send_command_expect
    • diff --git a/docs/netmiko/rad/index.html b/docs/netmiko/rad/index.html index 886706144..825e20b77 100644 --- a/docs/netmiko/rad/index.html +++ b/docs/netmiko/rad/index.html @@ -222,6 +222,7 @@

      Inherited members

    • read_until_pattern
    • read_until_prompt
    • read_until_prompt_or_pattern
    • +
    • run_ttp
    • save_config
    • select_delay_factor
    • send_command
    • @@ -463,6 +464,7 @@

      Inherited members

    • read_until_pattern
    • read_until_prompt
    • read_until_prompt_or_pattern
    • +
    • run_ttp
    • save_config
    • select_delay_factor
    • send_command
    • diff --git a/docs/netmiko/rad/rad_etx.html b/docs/netmiko/rad/rad_etx.html index 7e8cb946d..ca2a9d06c 100644 --- a/docs/netmiko/rad/rad_etx.html +++ b/docs/netmiko/rad/rad_etx.html @@ -442,6 +442,7 @@

      Inherited members

    • read_until_pattern
    • read_until_prompt
    • read_until_prompt_or_pattern
    • +
    • run_ttp
    • select_delay_factor
    • send_command
    • send_command_expect
    • @@ -640,6 +641,7 @@

      Inherited members

    • read_until_pattern
    • read_until_prompt
    • read_until_prompt_or_pattern
    • +
    • run_ttp
    • save_config
    • select_delay_factor
    • send_command
    • @@ -881,6 +883,7 @@

      Inherited members

    • read_until_pattern
    • read_until_prompt
    • read_until_prompt_or_pattern
    • +
    • run_ttp
    • save_config
    • select_delay_factor
    • send_command
    • diff --git a/docs/netmiko/raisecom/index.html b/docs/netmiko/raisecom/index.html index 8ea4ed9e2..68c39301b 100644 --- a/docs/netmiko/raisecom/index.html +++ b/docs/netmiko/raisecom/index.html @@ -277,6 +277,7 @@

      Inherited members

    • read_until_pattern
    • read_until_prompt
    • read_until_prompt_or_pattern
    • +
    • run_ttp
    • save_config
    • select_delay_factor
    • send_command
    • @@ -557,6 +558,7 @@

      Inherited members

    • read_until_pattern
    • read_until_prompt
    • read_until_prompt_or_pattern
    • +
    • run_ttp
    • save_config
    • select_delay_factor
    • send_command
    • diff --git a/docs/netmiko/raisecom/raisecom_roap.html b/docs/netmiko/raisecom/raisecom_roap.html index 31fcfddcf..856c614e7 100644 --- a/docs/netmiko/raisecom/raisecom_roap.html +++ b/docs/netmiko/raisecom/raisecom_roap.html @@ -418,6 +418,7 @@

      Inherited members

    • read_until_pattern
    • read_until_prompt
    • read_until_prompt_or_pattern
    • +
    • run_ttp
    • save_config
    • select_delay_factor
    • send_command
    • @@ -671,6 +672,7 @@

      Inherited members

    • read_until_pattern
    • read_until_prompt
    • read_until_prompt_or_pattern
    • +
    • run_ttp
    • save_config
    • select_delay_factor
    • send_command
    • @@ -951,6 +953,7 @@

      Inherited members

    • read_until_pattern
    • read_until_prompt
    • read_until_prompt_or_pattern
    • +
    • run_ttp
    • save_config
    • select_delay_factor
    • send_command
    • diff --git a/docs/netmiko/ruckus/index.html b/docs/netmiko/ruckus/index.html index c4c9bc63e..af23054e6 100644 --- a/docs/netmiko/ruckus/index.html +++ b/docs/netmiko/ruckus/index.html @@ -219,6 +219,7 @@

      Inherited members

    • read_until_pattern
    • read_until_prompt
    • read_until_prompt_or_pattern
    • +
    • run_ttp
    • save_config
    • select_delay_factor
    • send_command
    • @@ -436,6 +437,7 @@

      Inherited members

    • read_until_pattern
    • read_until_prompt
    • read_until_prompt_or_pattern
    • +
    • run_ttp
    • save_config
    • select_delay_factor
    • send_command
    • diff --git a/docs/netmiko/ruckus/ruckus_fastiron.html b/docs/netmiko/ruckus/ruckus_fastiron.html index 9b6a4565a..ef80ee44c 100644 --- a/docs/netmiko/ruckus/ruckus_fastiron.html +++ b/docs/netmiko/ruckus/ruckus_fastiron.html @@ -463,6 +463,7 @@

      Inherited members

    • read_until_pattern
    • read_until_prompt
    • read_until_prompt_or_pattern
    • +
    • run_ttp
    • select_delay_factor
    • send_command
    • send_command_expect
    • @@ -657,6 +658,7 @@

      Inherited members

    • read_until_pattern
    • read_until_prompt
    • read_until_prompt_or_pattern
    • +
    • run_ttp
    • save_config
    • select_delay_factor
    • send_command
    • @@ -874,6 +876,7 @@

      Inherited members

    • read_until_pattern
    • read_until_prompt
    • read_until_prompt_or_pattern
    • +
    • run_ttp
    • save_config
    • select_delay_factor
    • send_command
    • diff --git a/docs/netmiko/ruijie/index.html b/docs/netmiko/ruijie/index.html index b775fc10f..b4b99f115 100644 --- a/docs/netmiko/ruijie/index.html +++ b/docs/netmiko/ruijie/index.html @@ -218,6 +218,7 @@

      Inherited members

    • read_until_pattern
    • read_until_prompt
    • read_until_prompt_or_pattern
    • +
    • run_ttp
    • save_config
    • select_delay_factor
    • send_command
    • @@ -416,6 +417,7 @@

      Inherited members

    • read_until_pattern
    • read_until_prompt
    • read_until_prompt_or_pattern
    • +
    • run_ttp
    • save_config
    • select_delay_factor
    • send_command
    • diff --git a/docs/netmiko/ruijie/ruijie_os.html b/docs/netmiko/ruijie/ruijie_os.html index a6bfa1b94..e32fa7aaf 100644 --- a/docs/netmiko/ruijie/ruijie_os.html +++ b/docs/netmiko/ruijie/ruijie_os.html @@ -300,6 +300,7 @@

      Inherited members

    • read_until_pattern
    • read_until_prompt
    • read_until_prompt_or_pattern
    • +
    • run_ttp
    • select_delay_factor
    • send_command
    • send_command_expect
    • @@ -494,6 +495,7 @@

      Inherited members

    • read_until_pattern
    • read_until_prompt
    • read_until_prompt_or_pattern
    • +
    • run_ttp
    • save_config
    • select_delay_factor
    • send_command
    • @@ -692,6 +694,7 @@

      Inherited members

    • read_until_pattern
    • read_until_prompt
    • read_until_prompt_or_pattern
    • +
    • run_ttp
    • save_config
    • select_delay_factor
    • send_command
    • diff --git a/docs/netmiko/scp_handler.html b/docs/netmiko/scp_handler.html index aa3533ce1..4a49cc433 100644 --- a/docs/netmiko/scp_handler.html +++ b/docs/netmiko/scp_handler.html @@ -285,6 +285,9 @@

      Module netmiko.scp_handler

      line = match.group(0) # Format will be 26 -rw- 6738 Jul 30 2016 19:49:50 -07:00 filename file_size = line.split()[2] + else: + raise IOError("Unable to parse 'dir' output in remote_file_size method") + if "Error opening" in remote_out or "No such file or directory" in remote_out: raise IOError("Unable to find file on remote system") else: @@ -640,6 +643,9 @@

      Classes

      line = match.group(0) # Format will be 26 -rw- 6738 Jul 30 2016 19:49:50 -07:00 filename file_size = line.split()[2] + else: + raise IOError("Unable to parse 'dir' output in remote_file_size method") + if "Error opening" in remote_out or "No such file or directory" in remote_out: raise IOError("Unable to find file on remote system") else: @@ -791,7 +797,7 @@

      Subclasses

    • CienaSaosFileTransfer
    • DellOS10FileTransfer
    • JuniperFileTransfer
    • -
    • NokiaSrosFileTransfer
    • +
    • NokiaSrosFileTransfer

    Static methods

    @@ -1059,6 +1065,9 @@

    Args

    line = match.group(0) # Format will be 26 -rw- 6738 Jul 30 2016 19:49:50 -07:00 filename file_size = line.split()[2] + else: + raise IOError("Unable to parse 'dir' output in remote_file_size method") + if "Error opening" in remote_out or "No such file or directory" in remote_out: raise IOError("Unable to find file on remote system") else: diff --git a/docs/netmiko/sixwind/index.html b/docs/netmiko/sixwind/index.html index 87a8b7363..e4fd355a5 100644 --- a/docs/netmiko/sixwind/index.html +++ b/docs/netmiko/sixwind/index.html @@ -218,6 +218,7 @@

    Inherited members

  • read_until_pattern
  • read_until_prompt
  • read_until_prompt_or_pattern
  • +
  • run_ttp
  • save_config
  • select_delay_factor
  • send_command
  • diff --git a/docs/netmiko/sixwind/sixwind_os.html b/docs/netmiko/sixwind/sixwind_os.html index 883da569d..082d12150 100644 --- a/docs/netmiko/sixwind/sixwind_os.html +++ b/docs/netmiko/sixwind/sixwind_os.html @@ -577,6 +577,7 @@

    Inherited members

  • read_until_pattern
  • read_until_prompt
  • read_until_prompt_or_pattern
  • +
  • run_ttp
  • select_delay_factor
  • send_command
  • send_command_expect
  • @@ -770,6 +771,7 @@

    Inherited members

  • read_until_pattern
  • read_until_prompt
  • read_until_prompt_or_pattern
  • +
  • run_ttp
  • save_config
  • select_delay_factor
  • send_command
  • diff --git a/docs/netmiko/sophos/index.html b/docs/netmiko/sophos/index.html index 026d103f1..c1fdb11c3 100644 --- a/docs/netmiko/sophos/index.html +++ b/docs/netmiko/sophos/index.html @@ -384,6 +384,7 @@

    Inherited members

  • read_until_pattern
  • read_until_prompt
  • read_until_prompt_or_pattern
  • +
  • run_ttp
  • select_delay_factor
  • send_command
  • send_command_expect
  • diff --git a/docs/netmiko/sophos/sophos_sfos_ssh.html b/docs/netmiko/sophos/sophos_sfos_ssh.html index 5ca165a62..bfb528c2b 100644 --- a/docs/netmiko/sophos/sophos_sfos_ssh.html +++ b/docs/netmiko/sophos/sophos_sfos_ssh.html @@ -434,6 +434,7 @@

    Inherited members

  • read_until_pattern
  • read_until_prompt
  • read_until_prompt_or_pattern
  • +
  • run_ttp
  • select_delay_factor
  • send_command
  • send_command_expect
  • diff --git a/docs/netmiko/ssh_autodetect.html b/docs/netmiko/ssh_autodetect.html index 666bfab41..b501cbe61 100644 --- a/docs/netmiko/ssh_autodetect.html +++ b/docs/netmiko/ssh_autodetect.html @@ -231,9 +231,9 @@

    Netmiko connection creation section "priority": 99, "dispatch": "_autodetect_std", }, - "brocade_netiron": { + "extreme_netiron": { "cmd": "show version", - "search_patterns": [r"NetIron"], + "search_patterns": [r"(NetIron|MLX)"], "priority": 99, "dispatch": "_autodetect_std", }, @@ -273,6 +273,18 @@

    Netmiko connection creation section "priority": 99, "dispatch": "_autodetect_std", }, + "paloalto_panos": { + "cmd": "show system info", + "search_patterns": [r"model:\s+PA"], + "priority": 99, + "dispatch": "_autodetect_std", + }, + "supermicro_smis": { + "cmd": "show system info", + "search_patterns": [r"Super Micro Computer"], + "priority": 99, + "dispatch": "_autodetect_std", + }, } # Sort SSH_MAPPER_BASE such that the most common commands are first diff --git a/docs/netmiko/ssh_exception.html b/docs/netmiko/ssh_exception.html index 41b78ca27..ebadb55ba 100644 --- a/docs/netmiko/ssh_exception.html +++ b/docs/netmiko/ssh_exception.html @@ -38,6 +38,12 @@

    Module netmiko.ssh_exception

    pass +class ConfigInvalidException(Exception): + """Exception raised for invalid configuration error.""" + + pass + + NetMikoTimeoutException = NetmikoTimeoutException NetMikoAuthenticationException = NetmikoAuthenticationException
    @@ -51,6 +57,25 @@

    Module netmiko.ssh_exception

    Classes

    +
    +class ConfigInvalidException +(*args, **kwargs) +
    +
    +

    Exception raised for invalid configuration error.

    +
    +Source code +
    class ConfigInvalidException(Exception):
    +    """Exception raised for invalid configuration error."""
    +
    +    pass
    +
    +

    Ancestors

    +
      +
    • builtins.Exception
    • +
    • builtins.BaseException
    • +
    +
    class NetMikoAuthenticationException (*args, **kwargs) @@ -150,6 +175,9 @@

    Index

  • Classes

    • +

      ConfigInvalidException

      +
    • +
    • NetmikoAuthenticationException

    • diff --git a/docs/netmiko/supermicro/index.html b/docs/netmiko/supermicro/index.html new file mode 100644 index 000000000..a95c7ef44 --- /dev/null +++ b/docs/netmiko/supermicro/index.html @@ -0,0 +1,476 @@ + + + + + + +netmiko.supermicro API documentation + + + + + + + + + +
      +
      +
      +

      Module netmiko.supermicro

      +
      +
      +
      +Source code +
      from netmiko.supermicro.smci_smis import SmciSwitchSmisTelnet, SmciSwitchSmisSSH
      +
      +__all__ = ["SmciSwitchSmisSSH", "SmciSwitchSmisTelnet"]
      +
      +
      +
      +

      Sub-modules

      +
      +
      netmiko.supermicro.smci_smis
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +

      Classes

      +
      +
      +class SmciSwitchSmisSSH +(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=5, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=False, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True) +
      +
      +

      Base Class for cisco-like behavior.

      +
          Initialize attributes for establishing connection to target device.
      +
      +    :param ip: IP address of target device. Not required if `host` is
      +        provided.
      +    :type ip: str
      +
      +    :param host: Hostname of target device. Not required if `ip` is
      +            provided.
      +    :type host: str
      +
      +    :param username: Username to authenticate against target device if
      +            required.
      +    :type username: str
      +
      +    :param password: Password to authenticate against target device if
      +            required.
      +    :type password: str
      +
      +    :param secret: The enable password if target device requires one.
      +    :type secret: str
      +
      +    :param port: The destination port used to connect to the target
      +            device.
      +    :type port: int or None
      +
      +    :param device_type: Class selection based on device type.
      +    :type device_type: str
      +
      +    :param verbose: Enable additional messages to standard output.
      +    :type verbose: bool
      +
      +    :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
      +    :type global_delay_factor: int
      +
      +    :param use_keys: Connect to target device using SSH keys.
      +    :type use_keys: bool
      +
      +    :param key_file: Filename path of the SSH key file to use.
      +    :type key_file: str
      +
      +    :param pkey: SSH key object to use.
      +    :type pkey: paramiko.PKey
      +
      +    :param passphrase: Passphrase to use for encrypted key; password will be used for key
      +            decryption if not specified.
      +    :type passphrase: str
      +
      +    :param allow_agent: Enable use of SSH key-agent.
      +    :type allow_agent: bool
      +
      +    :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
      +            means unknown SSH host keys will be accepted).
      +    :type ssh_strict: bool
      +
      +    :param system_host_keys: Load host keys from the users known_hosts file.
      +    :type system_host_keys: bool
      +    :param alt_host_keys: If `True` host keys will be loaded from the file specified in
      +            alt_key_file.
      +    :type alt_host_keys: bool
      +
      +    :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
      +    :type alt_key_file: str
      +
      +    :param ssh_config_file: File name of OpenSSH configuration file.
      +    :type ssh_config_file: str
      +
      +    :param timeout: Connection timeout.
      +    :type timeout: float
      +
      +    :param session_timeout: Set a timeout for parallel requests.
      +    :type session_timeout: float
      +
      +    :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
      +    :type auth_timeout: float
      +
      +    :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
      +    :type banner_timeout: float
      +
      +    :param keepalive: Send SSH keepalive packets at a specific interval, in seconds.
      +            Currently defaults to 0, for backwards compatibility (it will not attempt
      +            to keep the connection alive).
      +    :type keepalive: int
      +
      +    :param default_enter: Character(s) to send to correspond to enter key (default:
      +
      +

      ). +:type default_enter: str

      +
          :param response_return: Character(s) to use in normalized return data to represent
      +            enter key (default:
      +
      +

      ) +:type response_return: str

      +
          :param fast_cli: Provide a way to optimize for performance. Converts select_delay_factor
      +            to select smallest of global and specific. Sets default global_delay_factor to .1
      +            (default: False)
      +    :type fast_cli: boolean
      +
      +    :param session_log: File path or BufferedIOBase subclass object to write the session log to.
      +    :type session_log: str
      +
      +    :param session_log_record_writes: The session log generally only records channel reads due
      +            to eliminate command duplication due to command echo. You can enable this if you
      +            want to record both channel reads and channel writes in the log (default: False).
      +    :type session_log_record_writes: boolean
      +
      +    :param session_log_file_mode: "write" or "append" for session_log file mode
      +            (default: "write")
      +    :type session_log_file_mode: str
      +
      +    :param allow_auto_change: Allow automatic configuration changes for terminal settings.
      +            (default: False)
      +    :type allow_auto_change: bool
      +
      +    :param encoding: Encoding to be used when writing bytes to the output channel.
      +            (default: ascii)
      +    :type encoding: str
      +
      +    :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
      +            communication to the target host (default: None).
      +    :type sock: socket
      +
      +    :param global_cmd_verify: Control whether command echo verification is enabled or disabled
      +            (default: None). Global attribute takes precedence over function `cmd_verify`
      +            argument. Value of `None` indicates to use function `cmd_verify` argument.
      +    :type global_cmd_verify: bool|None
      +
      +    :param auto_connect: Control whether Netmiko automatically establishes the connection as
      +            part of the object creation (default: True).
      +    :type auto_connect: bool
      +
      +
      +Source code +
      class SmciSwitchSmisSSH(SmciSwitchSmisBase):
      +    pass
      +
      +

      Ancestors

      + +

      Inherited members

      + +
      +
      +class SmciSwitchSmisTelnet +(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=5, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=False, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True) +
      +
      +

      Base Class for cisco-like behavior.

      +
          Initialize attributes for establishing connection to target device.
      +
      +    :param ip: IP address of target device. Not required if `host` is
      +        provided.
      +    :type ip: str
      +
      +    :param host: Hostname of target device. Not required if `ip` is
      +            provided.
      +    :type host: str
      +
      +    :param username: Username to authenticate against target device if
      +            required.
      +    :type username: str
      +
      +    :param password: Password to authenticate against target device if
      +            required.
      +    :type password: str
      +
      +    :param secret: The enable password if target device requires one.
      +    :type secret: str
      +
      +    :param port: The destination port used to connect to the target
      +            device.
      +    :type port: int or None
      +
      +    :param device_type: Class selection based on device type.
      +    :type device_type: str
      +
      +    :param verbose: Enable additional messages to standard output.
      +    :type verbose: bool
      +
      +    :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
      +    :type global_delay_factor: int
      +
      +    :param use_keys: Connect to target device using SSH keys.
      +    :type use_keys: bool
      +
      +    :param key_file: Filename path of the SSH key file to use.
      +    :type key_file: str
      +
      +    :param pkey: SSH key object to use.
      +    :type pkey: paramiko.PKey
      +
      +    :param passphrase: Passphrase to use for encrypted key; password will be used for key
      +            decryption if not specified.
      +    :type passphrase: str
      +
      +    :param allow_agent: Enable use of SSH key-agent.
      +    :type allow_agent: bool
      +
      +    :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
      +            means unknown SSH host keys will be accepted).
      +    :type ssh_strict: bool
      +
      +    :param system_host_keys: Load host keys from the users known_hosts file.
      +    :type system_host_keys: bool
      +    :param alt_host_keys: If `True` host keys will be loaded from the file specified in
      +            alt_key_file.
      +    :type alt_host_keys: bool
      +
      +    :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
      +    :type alt_key_file: str
      +
      +    :param ssh_config_file: File name of OpenSSH configuration file.
      +    :type ssh_config_file: str
      +
      +    :param timeout: Connection timeout.
      +    :type timeout: float
      +
      +    :param session_timeout: Set a timeout for parallel requests.
      +    :type session_timeout: float
      +
      +    :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
      +    :type auth_timeout: float
      +
      +    :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
      +    :type banner_timeout: float
      +
      +    :param keepalive: Send SSH keepalive packets at a specific interval, in seconds.
      +            Currently defaults to 0, for backwards compatibility (it will not attempt
      +            to keep the connection alive).
      +    :type keepalive: int
      +
      +    :param default_enter: Character(s) to send to correspond to enter key (default:
      +
      +

      ). +:type default_enter: str

      +
          :param response_return: Character(s) to use in normalized return data to represent
      +            enter key (default:
      +
      +

      ) +:type response_return: str

      +
          :param fast_cli: Provide a way to optimize for performance. Converts select_delay_factor
      +            to select smallest of global and specific. Sets default global_delay_factor to .1
      +            (default: False)
      +    :type fast_cli: boolean
      +
      +    :param session_log: File path or BufferedIOBase subclass object to write the session log to.
      +    :type session_log: str
      +
      +    :param session_log_record_writes: The session log generally only records channel reads due
      +            to eliminate command duplication due to command echo. You can enable this if you
      +            want to record both channel reads and channel writes in the log (default: False).
      +    :type session_log_record_writes: boolean
      +
      +    :param session_log_file_mode: "write" or "append" for session_log file mode
      +            (default: "write")
      +    :type session_log_file_mode: str
      +
      +    :param allow_auto_change: Allow automatic configuration changes for terminal settings.
      +            (default: False)
      +    :type allow_auto_change: bool
      +
      +    :param encoding: Encoding to be used when writing bytes to the output channel.
      +            (default: ascii)
      +    :type encoding: str
      +
      +    :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
      +            communication to the target host (default: None).
      +    :type sock: socket
      +
      +    :param global_cmd_verify: Control whether command echo verification is enabled or disabled
      +            (default: None). Global attribute takes precedence over function `cmd_verify`
      +            argument. Value of `None` indicates to use function `cmd_verify` argument.
      +    :type global_cmd_verify: bool|None
      +
      +    :param auto_connect: Control whether Netmiko automatically establishes the connection as
      +            part of the object creation (default: True).
      +    :type auto_connect: bool
      +
      +
      +Source code +
      class SmciSwitchSmisTelnet(SmciSwitchSmisBase):
      +    pass
      +
      +

      Ancestors

      + +

      Inherited members

      + +
      +
      +
      +
      + +
      + + + + + \ No newline at end of file diff --git a/docs/netmiko/supermicro/smci_smis.html b/docs/netmiko/supermicro/smci_smis.html new file mode 100644 index 000000000..55a55bcae --- /dev/null +++ b/docs/netmiko/supermicro/smci_smis.html @@ -0,0 +1,803 @@ + + + + + + +netmiko.supermicro.smci_smis API documentation + + + + + + + + + +
      +
      +
      +

      Module netmiko.supermicro.smci_smis

      +
      +
      +
      +Source code +
      from netmiko.cisco_base_connection import CiscoBaseConnection
      +import time
      +
      +
      +class SmciSwitchSmisBase(CiscoBaseConnection):
      +    def session_preparation(self):
      +        """Prepare the session after the connection has been established."""
      +        self._test_channel_read(pattern=r"[>#]")
      +        self.set_base_prompt()
      +        self.config_mode()
      +        self.disable_paging(command="set cli pagination off")
      +        self.set_terminal_width(command="terminal width 511")
      +        self.exit_config_mode()
      +        # Clear the read buffer
      +        time.sleep(0.3 * self.global_delay_factor)
      +        self.clear_buffer()
      +
      +    def check_enable_mode(self, check_string="#"):
      +        """Check if in enable mode. Return boolean."""
      +        return super().check_enable_mode(check_string=check_string)
      +
      +    def enable(self, *args, **kwargs):
      +        """Supermicro switch does not support enable-mode command"""
      +        return ""
      +
      +    def exit_enable_mode(self, *args, **kwargs):
      +        """Supermicro switch does not support enable-mode command"""
      +        return ""
      +
      +    def save_config(
      +        self, cmd="write startup-config", confirm=False, confirm_response=""
      +    ):
      +        """Save config"""
      +        return super().save_config(
      +            cmd=cmd, confirm=confirm, confirm_response=confirm_response
      +        )
      +
      +
      +class SmciSwitchSmisSSH(SmciSwitchSmisBase):
      +    pass
      +
      +
      +class SmciSwitchSmisTelnet(SmciSwitchSmisBase):
      +    pass
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +

      Classes

      +
      +
      +class SmciSwitchSmisBase +(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=5, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=False, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True) +
      +
      +

      Base Class for cisco-like behavior.

      +
          Initialize attributes for establishing connection to target device.
      +
      +    :param ip: IP address of target device. Not required if `host` is
      +        provided.
      +    :type ip: str
      +
      +    :param host: Hostname of target device. Not required if `ip` is
      +            provided.
      +    :type host: str
      +
      +    :param username: Username to authenticate against target device if
      +            required.
      +    :type username: str
      +
      +    :param password: Password to authenticate against target device if
      +            required.
      +    :type password: str
      +
      +    :param secret: The enable password if target device requires one.
      +    :type secret: str
      +
      +    :param port: The destination port used to connect to the target
      +            device.
      +    :type port: int or None
      +
      +    :param device_type: Class selection based on device type.
      +    :type device_type: str
      +
      +    :param verbose: Enable additional messages to standard output.
      +    :type verbose: bool
      +
      +    :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
      +    :type global_delay_factor: int
      +
      +    :param use_keys: Connect to target device using SSH keys.
      +    :type use_keys: bool
      +
      +    :param key_file: Filename path of the SSH key file to use.
      +    :type key_file: str
      +
      +    :param pkey: SSH key object to use.
      +    :type pkey: paramiko.PKey
      +
      +    :param passphrase: Passphrase to use for encrypted key; password will be used for key
      +            decryption if not specified.
      +    :type passphrase: str
      +
      +    :param allow_agent: Enable use of SSH key-agent.
      +    :type allow_agent: bool
      +
      +    :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
      +            means unknown SSH host keys will be accepted).
      +    :type ssh_strict: bool
      +
      +    :param system_host_keys: Load host keys from the users known_hosts file.
      +    :type system_host_keys: bool
      +    :param alt_host_keys: If `True` host keys will be loaded from the file specified in
      +            alt_key_file.
      +    :type alt_host_keys: bool
      +
      +    :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
      +    :type alt_key_file: str
      +
      +    :param ssh_config_file: File name of OpenSSH configuration file.
      +    :type ssh_config_file: str
      +
      +    :param timeout: Connection timeout.
      +    :type timeout: float
      +
      +    :param session_timeout: Set a timeout for parallel requests.
      +    :type session_timeout: float
      +
      +    :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
      +    :type auth_timeout: float
      +
      +    :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
      +    :type banner_timeout: float
      +
      +    :param keepalive: Send SSH keepalive packets at a specific interval, in seconds.
      +            Currently defaults to 0, for backwards compatibility (it will not attempt
      +            to keep the connection alive).
      +    :type keepalive: int
      +
      +    :param default_enter: Character(s) to send to correspond to enter key (default:
      +
      +

      ). +:type default_enter: str

      +
          :param response_return: Character(s) to use in normalized return data to represent
      +            enter key (default:
      +
      +

      ) +:type response_return: str

      +
          :param fast_cli: Provide a way to optimize for performance. Converts select_delay_factor
      +            to select smallest of global and specific. Sets default global_delay_factor to .1
      +            (default: False)
      +    :type fast_cli: boolean
      +
      +    :param session_log: File path or BufferedIOBase subclass object to write the session log to.
      +    :type session_log: str
      +
      +    :param session_log_record_writes: The session log generally only records channel reads due
      +            to eliminate command duplication due to command echo. You can enable this if you
      +            want to record both channel reads and channel writes in the log (default: False).
      +    :type session_log_record_writes: boolean
      +
      +    :param session_log_file_mode: "write" or "append" for session_log file mode
      +            (default: "write")
      +    :type session_log_file_mode: str
      +
      +    :param allow_auto_change: Allow automatic configuration changes for terminal settings.
      +            (default: False)
      +    :type allow_auto_change: bool
      +
      +    :param encoding: Encoding to be used when writing bytes to the output channel.
      +            (default: ascii)
      +    :type encoding: str
      +
      +    :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
      +            communication to the target host (default: None).
      +    :type sock: socket
      +
      +    :param global_cmd_verify: Control whether command echo verification is enabled or disabled
      +            (default: None). Global attribute takes precedence over function `cmd_verify`
      +            argument. Value of `None` indicates to use function `cmd_verify` argument.
      +    :type global_cmd_verify: bool|None
      +
      +    :param auto_connect: Control whether Netmiko automatically establishes the connection as
      +            part of the object creation (default: True).
      +    :type auto_connect: bool
      +
      +
      +Source code +
      class SmciSwitchSmisBase(CiscoBaseConnection):
      +    def session_preparation(self):
      +        """Prepare the session after the connection has been established."""
      +        self._test_channel_read(pattern=r"[>#]")
      +        self.set_base_prompt()
      +        self.config_mode()
      +        self.disable_paging(command="set cli pagination off")
      +        self.set_terminal_width(command="terminal width 511")
      +        self.exit_config_mode()
      +        # Clear the read buffer
      +        time.sleep(0.3 * self.global_delay_factor)
      +        self.clear_buffer()
      +
      +    def check_enable_mode(self, check_string="#"):
      +        """Check if in enable mode. Return boolean."""
      +        return super().check_enable_mode(check_string=check_string)
      +
      +    def enable(self, *args, **kwargs):
      +        """Supermicro switch does not support enable-mode command"""
      +        return ""
      +
      +    def exit_enable_mode(self, *args, **kwargs):
      +        """Supermicro switch does not support enable-mode command"""
      +        return ""
      +
      +    def save_config(
      +        self, cmd="write startup-config", confirm=False, confirm_response=""
      +    ):
      +        """Save config"""
      +        return super().save_config(
      +            cmd=cmd, confirm=confirm, confirm_response=confirm_response
      +        )
      +
      +

      Ancestors

      + +

      Subclasses

      + +

      Methods

      +
      +
      +def enable(self, *args, **kwargs) +
      +
      +

      Supermicro switch does not support enable-mode command

      +
      +Source code +
      def enable(self, *args, **kwargs):
      +    """Supermicro switch does not support enable-mode command"""
      +    return ""
      +
      +
      +
      +def exit_enable_mode(self, *args, **kwargs) +
      +
      +

      Supermicro switch does not support enable-mode command

      +
      +Source code +
      def exit_enable_mode(self, *args, **kwargs):
      +    """Supermicro switch does not support enable-mode command"""
      +    return ""
      +
      +
      +
      +def save_config(self, cmd='write startup-config', confirm=False, confirm_response='') +
      +
      +

      Save config

      +
      +Source code +
      def save_config(
      +    self, cmd="write startup-config", confirm=False, confirm_response=""
      +):
      +    """Save config"""
      +    return super().save_config(
      +        cmd=cmd, confirm=confirm, confirm_response=confirm_response
      +    )
      +
      +
      +
      +def session_preparation(self) +
      +
      +

      Prepare the session after the connection has been established.

      +
      +Source code +
      def session_preparation(self):
      +    """Prepare the session after the connection has been established."""
      +    self._test_channel_read(pattern=r"[>#]")
      +    self.set_base_prompt()
      +    self.config_mode()
      +    self.disable_paging(command="set cli pagination off")
      +    self.set_terminal_width(command="terminal width 511")
      +    self.exit_config_mode()
      +    # Clear the read buffer
      +    time.sleep(0.3 * self.global_delay_factor)
      +    self.clear_buffer()
      +
      +
      +
      +

      Inherited members

      + +
      +
      +class SmciSwitchSmisSSH +(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=5, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=False, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True) +
      +
      +

      Base Class for cisco-like behavior.

      +
          Initialize attributes for establishing connection to target device.
      +
      +    :param ip: IP address of target device. Not required if `host` is
      +        provided.
      +    :type ip: str
      +
      +    :param host: Hostname of target device. Not required if `ip` is
      +            provided.
      +    :type host: str
      +
      +    :param username: Username to authenticate against target device if
      +            required.
      +    :type username: str
      +
      +    :param password: Password to authenticate against target device if
      +            required.
      +    :type password: str
      +
      +    :param secret: The enable password if target device requires one.
      +    :type secret: str
      +
      +    :param port: The destination port used to connect to the target
      +            device.
      +    :type port: int or None
      +
      +    :param device_type: Class selection based on device type.
      +    :type device_type: str
      +
      +    :param verbose: Enable additional messages to standard output.
      +    :type verbose: bool
      +
      +    :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
      +    :type global_delay_factor: int
      +
      +    :param use_keys: Connect to target device using SSH keys.
      +    :type use_keys: bool
      +
      +    :param key_file: Filename path of the SSH key file to use.
      +    :type key_file: str
      +
      +    :param pkey: SSH key object to use.
      +    :type pkey: paramiko.PKey
      +
      +    :param passphrase: Passphrase to use for encrypted key; password will be used for key
      +            decryption if not specified.
      +    :type passphrase: str
      +
      +    :param allow_agent: Enable use of SSH key-agent.
      +    :type allow_agent: bool
      +
      +    :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
      +            means unknown SSH host keys will be accepted).
      +    :type ssh_strict: bool
      +
      +    :param system_host_keys: Load host keys from the users known_hosts file.
      +    :type system_host_keys: bool
      +    :param alt_host_keys: If `True` host keys will be loaded from the file specified in
      +            alt_key_file.
      +    :type alt_host_keys: bool
      +
      +    :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
      +    :type alt_key_file: str
      +
      +    :param ssh_config_file: File name of OpenSSH configuration file.
      +    :type ssh_config_file: str
      +
      +    :param timeout: Connection timeout.
      +    :type timeout: float
      +
      +    :param session_timeout: Set a timeout for parallel requests.
      +    :type session_timeout: float
      +
      +    :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
      +    :type auth_timeout: float
      +
      +    :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
      +    :type banner_timeout: float
      +
      +    :param keepalive: Send SSH keepalive packets at a specific interval, in seconds.
      +            Currently defaults to 0, for backwards compatibility (it will not attempt
      +            to keep the connection alive).
      +    :type keepalive: int
      +
      +    :param default_enter: Character(s) to send to correspond to enter key (default:
      +
      +

      ). +:type default_enter: str

      +
          :param response_return: Character(s) to use in normalized return data to represent
      +            enter key (default:
      +
      +

      ) +:type response_return: str

      +
          :param fast_cli: Provide a way to optimize for performance. Converts select_delay_factor
      +            to select smallest of global and specific. Sets default global_delay_factor to .1
      +            (default: False)
      +    :type fast_cli: boolean
      +
      +    :param session_log: File path or BufferedIOBase subclass object to write the session log to.
      +    :type session_log: str
      +
      +    :param session_log_record_writes: The session log generally only records channel reads due
      +            to eliminate command duplication due to command echo. You can enable this if you
      +            want to record both channel reads and channel writes in the log (default: False).
      +    :type session_log_record_writes: boolean
      +
      +    :param session_log_file_mode: "write" or "append" for session_log file mode
      +            (default: "write")
      +    :type session_log_file_mode: str
      +
      +    :param allow_auto_change: Allow automatic configuration changes for terminal settings.
      +            (default: False)
      +    :type allow_auto_change: bool
      +
      +    :param encoding: Encoding to be used when writing bytes to the output channel.
      +            (default: ascii)
      +    :type encoding: str
      +
      +    :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
      +            communication to the target host (default: None).
      +    :type sock: socket
      +
      +    :param global_cmd_verify: Control whether command echo verification is enabled or disabled
      +            (default: None). Global attribute takes precedence over function `cmd_verify`
      +            argument. Value of `None` indicates to use function `cmd_verify` argument.
      +    :type global_cmd_verify: bool|None
      +
      +    :param auto_connect: Control whether Netmiko automatically establishes the connection as
      +            part of the object creation (default: True).
      +    :type auto_connect: bool
      +
      +
      +Source code +
      class SmciSwitchSmisSSH(SmciSwitchSmisBase):
      +    pass
      +
      +

      Ancestors

      + +

      Inherited members

      + +
      +
      +class SmciSwitchSmisTelnet +(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=5, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=False, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True) +
      +
      +

      Base Class for cisco-like behavior.

      +
          Initialize attributes for establishing connection to target device.
      +
      +    :param ip: IP address of target device. Not required if `host` is
      +        provided.
      +    :type ip: str
      +
      +    :param host: Hostname of target device. Not required if `ip` is
      +            provided.
      +    :type host: str
      +
      +    :param username: Username to authenticate against target device if
      +            required.
      +    :type username: str
      +
      +    :param password: Password to authenticate against target device if
      +            required.
      +    :type password: str
      +
      +    :param secret: The enable password if target device requires one.
      +    :type secret: str
      +
      +    :param port: The destination port used to connect to the target
      +            device.
      +    :type port: int or None
      +
      +    :param device_type: Class selection based on device type.
      +    :type device_type: str
      +
      +    :param verbose: Enable additional messages to standard output.
      +    :type verbose: bool
      +
      +    :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
      +    :type global_delay_factor: int
      +
      +    :param use_keys: Connect to target device using SSH keys.
      +    :type use_keys: bool
      +
      +    :param key_file: Filename path of the SSH key file to use.
      +    :type key_file: str
      +
      +    :param pkey: SSH key object to use.
      +    :type pkey: paramiko.PKey
      +
      +    :param passphrase: Passphrase to use for encrypted key; password will be used for key
      +            decryption if not specified.
      +    :type passphrase: str
      +
      +    :param allow_agent: Enable use of SSH key-agent.
      +    :type allow_agent: bool
      +
      +    :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
      +            means unknown SSH host keys will be accepted).
      +    :type ssh_strict: bool
      +
      +    :param system_host_keys: Load host keys from the users known_hosts file.
      +    :type system_host_keys: bool
      +    :param alt_host_keys: If `True` host keys will be loaded from the file specified in
      +            alt_key_file.
      +    :type alt_host_keys: bool
      +
      +    :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
      +    :type alt_key_file: str
      +
      +    :param ssh_config_file: File name of OpenSSH configuration file.
      +    :type ssh_config_file: str
      +
      +    :param timeout: Connection timeout.
      +    :type timeout: float
      +
      +    :param session_timeout: Set a timeout for parallel requests.
      +    :type session_timeout: float
      +
      +    :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
      +    :type auth_timeout: float
      +
      +    :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
      +    :type banner_timeout: float
      +
      +    :param keepalive: Send SSH keepalive packets at a specific interval, in seconds.
      +            Currently defaults to 0, for backwards compatibility (it will not attempt
      +            to keep the connection alive).
      +    :type keepalive: int
      +
      +    :param default_enter: Character(s) to send to correspond to enter key (default:
      +
      +

      ). +:type default_enter: str

      +
          :param response_return: Character(s) to use in normalized return data to represent
      +            enter key (default:
      +
      +

      ) +:type response_return: str

      +
          :param fast_cli: Provide a way to optimize for performance. Converts select_delay_factor
      +            to select smallest of global and specific. Sets default global_delay_factor to .1
      +            (default: False)
      +    :type fast_cli: boolean
      +
      +    :param session_log: File path or BufferedIOBase subclass object to write the session log to.
      +    :type session_log: str
      +
      +    :param session_log_record_writes: The session log generally only records channel reads due
      +            to eliminate command duplication due to command echo. You can enable this if you
      +            want to record both channel reads and channel writes in the log (default: False).
      +    :type session_log_record_writes: boolean
      +
      +    :param session_log_file_mode: "write" or "append" for session_log file mode
      +            (default: "write")
      +    :type session_log_file_mode: str
      +
      +    :param allow_auto_change: Allow automatic configuration changes for terminal settings.
      +            (default: False)
      +    :type allow_auto_change: bool
      +
      +    :param encoding: Encoding to be used when writing bytes to the output channel.
      +            (default: ascii)
      +    :type encoding: str
      +
      +    :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
      +            communication to the target host (default: None).
      +    :type sock: socket
      +
      +    :param global_cmd_verify: Control whether command echo verification is enabled or disabled
      +            (default: None). Global attribute takes precedence over function `cmd_verify`
      +            argument. Value of `None` indicates to use function `cmd_verify` argument.
      +    :type global_cmd_verify: bool|None
      +
      +    :param auto_connect: Control whether Netmiko automatically establishes the connection as
      +            part of the object creation (default: True).
      +    :type auto_connect: bool
      +
      +
      +Source code +
      class SmciSwitchSmisTelnet(SmciSwitchSmisBase):
      +    pass
      +
      +

      Ancestors

      + +

      Inherited members

      + +
      +
      +
      +
      + +
      + + + + + \ No newline at end of file diff --git a/docs/netmiko/terminal_server/index.html b/docs/netmiko/terminal_server/index.html index 26f873dd5..658cecf4d 100644 --- a/docs/netmiko/terminal_server/index.html +++ b/docs/netmiko/terminal_server/index.html @@ -219,6 +219,7 @@

      Inherited members

    • read_until_pattern
    • read_until_prompt
    • read_until_prompt_or_pattern
    • +
    • run_ttp
    • save_config
    • select_delay_factor
    • send_command
    • @@ -434,6 +435,7 @@

      Inherited members

    • read_until_pattern
    • read_until_prompt
    • read_until_prompt_or_pattern
    • +
    • run_ttp
    • save_config
    • select_delay_factor
    • send_command
    • diff --git a/docs/netmiko/terminal_server/terminal_server.html b/docs/netmiko/terminal_server/terminal_server.html index c3422ca2a..fa98044c0 100644 --- a/docs/netmiko/terminal_server/terminal_server.html +++ b/docs/netmiko/terminal_server/terminal_server.html @@ -267,6 +267,7 @@

      Inherited members

    • read_until_pattern
    • read_until_prompt
    • read_until_prompt_or_pattern
    • +
    • run_ttp
    • save_config
    • select_delay_factor
    • send_command
    • @@ -462,6 +463,7 @@

      Inherited members

    • read_until_pattern
    • read_until_prompt
    • read_until_prompt_or_pattern
    • +
    • run_ttp
    • save_config
    • select_delay_factor
    • send_command
    • @@ -677,6 +679,7 @@

      Inherited members

    • read_until_pattern
    • read_until_prompt
    • read_until_prompt_or_pattern
    • +
    • run_ttp
    • save_config
    • select_delay_factor
    • send_command
    • diff --git a/docs/netmiko/tplink/index.html b/docs/netmiko/tplink/index.html index 5eb7455e4..920c2f37a 100644 --- a/docs/netmiko/tplink/index.html +++ b/docs/netmiko/tplink/index.html @@ -245,6 +245,7 @@

      Inherited members

    • read_until_pattern
    • read_until_prompt
    • read_until_prompt_or_pattern
    • +
    • run_ttp
    • save_config
    • select_delay_factor
    • send_command
    • @@ -488,6 +489,7 @@

      Inherited members

    • read_until_pattern
    • read_until_prompt
    • read_until_prompt_or_pattern
    • +
    • run_ttp
    • save_config
    • select_delay_factor
    • send_command
    • diff --git a/docs/netmiko/tplink/tplink_jetstream.html b/docs/netmiko/tplink/tplink_jetstream.html index 298f8d098..36f53f13b 100644 --- a/docs/netmiko/tplink/tplink_jetstream.html +++ b/docs/netmiko/tplink/tplink_jetstream.html @@ -657,6 +657,7 @@

      Inherited members

    • read_until_pattern
    • read_until_prompt
    • read_until_prompt_or_pattern
    • +
    • run_ttp
    • save_config
    • select_delay_factor
    • send_command
    • @@ -878,6 +879,7 @@

      Inherited members

    • read_until_pattern
    • read_until_prompt
    • read_until_prompt_or_pattern
    • +
    • run_ttp
    • save_config
    • select_delay_factor
    • send_command
    • @@ -1121,6 +1123,7 @@

      Inherited members

    • read_until_pattern
    • read_until_prompt
    • read_until_prompt_or_pattern
    • +
    • run_ttp
    • save_config
    • select_delay_factor
    • send_command
    • diff --git a/docs/netmiko/ubiquiti/edge_ssh.html b/docs/netmiko/ubiquiti/edge_ssh.html index d42dbacd2..402cbea11 100644 --- a/docs/netmiko/ubiquiti/edge_ssh.html +++ b/docs/netmiko/ubiquiti/edge_ssh.html @@ -360,6 +360,7 @@

      Inherited members

    • read_until_pattern
    • read_until_prompt
    • read_until_prompt_or_pattern
    • +
    • run_ttp
    • select_delay_factor
    • send_command
    • send_command_expect
    • diff --git a/docs/netmiko/ubiquiti/edgerouter_ssh.html b/docs/netmiko/ubiquiti/edgerouter_ssh.html index 6fb2f9cd2..b257382de 100644 --- a/docs/netmiko/ubiquiti/edgerouter_ssh.html +++ b/docs/netmiko/ubiquiti/edgerouter_ssh.html @@ -272,6 +272,7 @@

      Inherited members

    • read_until_pattern
    • read_until_prompt
    • read_until_prompt_or_pattern
    • +
    • run_ttp
    • select_delay_factor
    • send_command
    • send_command_expect
    • diff --git a/docs/netmiko/ubiquiti/index.html b/docs/netmiko/ubiquiti/index.html index 9827fde53..e3197ce7f 100644 --- a/docs/netmiko/ubiquiti/index.html +++ b/docs/netmiko/ubiquiti/index.html @@ -272,6 +272,7 @@

      Inherited members

    • read_until_pattern
    • read_until_prompt
    • read_until_prompt_or_pattern
    • +
    • run_ttp
    • select_delay_factor
    • send_command
    • send_command_expect
    • @@ -573,6 +574,7 @@

      Inherited members

    • read_until_pattern
    • read_until_prompt
    • read_until_prompt_or_pattern
    • +
    • run_ttp
    • select_delay_factor
    • send_command
    • send_command_expect
    • @@ -841,6 +843,7 @@

      Inherited members

    • read_until_pattern
    • read_until_prompt
    • read_until_prompt_or_pattern
    • +
    • run_ttp
    • save_config
    • select_delay_factor
    • send_command
    • diff --git a/docs/netmiko/ubiquiti/unifiswitch_ssh.html b/docs/netmiko/ubiquiti/unifiswitch_ssh.html index b221741cd..b79ab6250 100644 --- a/docs/netmiko/ubiquiti/unifiswitch_ssh.html +++ b/docs/netmiko/ubiquiti/unifiswitch_ssh.html @@ -321,6 +321,7 @@

      Inherited members

    • read_until_pattern
    • read_until_prompt
    • read_until_prompt_or_pattern
    • +
    • run_ttp
    • save_config
    • select_delay_factor
    • send_command
    • diff --git a/docs/netmiko/utilities.html b/docs/netmiko/utilities.html index fd8e1bfbe..190c4020d 100644 --- a/docs/netmiko/utilities.html +++ b/docs/netmiko/utilities.html @@ -33,6 +33,7 @@

      Module netmiko.utilities

      from datetime import datetime from netmiko._textfsm import _clitable as clitable from netmiko._textfsm._clitable import CliTableError +from netmiko import log try: from ttp import ttp @@ -66,6 +67,7 @@

      Module netmiko.utilities

      # Dictionary mapping 'show run' for vendors with different command SHOW_RUN_MAPPER = { + "brocade_fos": "configShow", "juniper": "show configuration", "juniper_junos": "show configuration", "extreme": "show configuration", @@ -92,6 +94,7 @@

      Module netmiko.utilities

      "brocade_fastiron": "show running-config", "brocade_netiron": "show running-config", "alcatel_aos": "show configuration snapshot", + "cros_mtbr": "show running-config", } # Expand SHOW_RUN_MAPPER to include '_ssh' key @@ -397,6 +400,73 @@

      Module netmiko.utilities

      return raw_output +def run_ttp_template(connection, template, res_kwargs, **kwargs): + """ + Helper function to run TTP template parsing. + + :param connection: Netmiko connection object + :type connection: obj + + :param template: TTP template + :type template: str + + :param res_kwargs: ``**res_kwargs`` arguments for TTP result method + :type res_kwargs: dict + + :param kwargs: ``**kwargs`` for TTP object instantiation + :type kwargs: dict + """ + if not TTP_INSTALLED: + msg = "\nTTP is not installed. Please PIP install ttp:\n" "pip install ttp\n" + raise ValueError(msg) + + parser = ttp(template=template, **kwargs) + + # get inputs load for TTP template + ttp_inputs_load = parser.get_input_load() + log.debug("run_ttp_template: inputs load - {}".format(ttp_inputs_load)) + + # go over template's inputs and collect output from devices + for template_name, inputs in ttp_inputs_load.items(): + for input_name, input_params in inputs.items(): + method = input_params.get("method", "send_command") + method_kwargs = input_params.get("kwargs", {}) + commands = input_params.get("commands", None) + + # run sanity checks + if method not in dir(connection): + log.warning( + "run_ttp_template: '{}' input, unsupported method '{}', skipping".format( + input_name, method + ) + ) + continue + elif not commands: + log.warning( + "run_ttp_template: '{}' input no commands to collect, skipping".format( + input_name + ) + ) + continue + + # collect commands output from device + output = [ + getattr(connection, method)(command_string=command, **method_kwargs) + for command in commands + ] + output = "\n".join(output) + + # add collected output to TTP parser object + parser.add_input( + data=output, input_name=input_name, template_name=template_name + ) + + # run parsing in single process + parser.parse(one=True) + + return parser.result(**res_kwargs) + + def get_structured_data_genie(raw_output, platform, command): if not sys.version_info >= (3, 4): raise ValueError("Genie requires Python >= 3.4") @@ -941,6 +1011,88 @@

      Functions

      return f"{netmiko_full_dir}/{device_name}.txt"
      +
      +def run_ttp_template(connection, template, res_kwargs, **kwargs) +
      +
      +

      Helper function to run TTP template parsing.

      +

      :param connection: Netmiko connection object +:type connection: obj

      +

      :param template: TTP template +:type template: str

      +

      :param res_kwargs: **res_kwargs arguments for TTP result method +:type res_kwargs: dict

      +

      :param kwargs: **kwargs for TTP object instantiation +:type kwargs: dict

      +
      +Source code +
      def run_ttp_template(connection, template, res_kwargs, **kwargs):
      +    """
      +    Helper function to run TTP template parsing.
      +
      +    :param connection: Netmiko connection object
      +    :type connection: obj
      +
      +    :param template: TTP template
      +    :type template: str
      +
      +    :param res_kwargs: ``**res_kwargs`` arguments for TTP result method
      +    :type res_kwargs: dict
      +
      +    :param kwargs: ``**kwargs`` for TTP object instantiation
      +    :type kwargs: dict
      +    """
      +    if not TTP_INSTALLED:
      +        msg = "\nTTP is not installed. Please PIP install ttp:\n" "pip install ttp\n"
      +        raise ValueError(msg)
      +
      +    parser = ttp(template=template, **kwargs)
      +
      +    # get inputs load for TTP template
      +    ttp_inputs_load = parser.get_input_load()
      +    log.debug("run_ttp_template: inputs load - {}".format(ttp_inputs_load))
      +
      +    # go over template's inputs and collect output from devices
      +    for template_name, inputs in ttp_inputs_load.items():
      +        for input_name, input_params in inputs.items():
      +            method = input_params.get("method", "send_command")
      +            method_kwargs = input_params.get("kwargs", {})
      +            commands = input_params.get("commands", None)
      +
      +            # run sanity checks
      +            if method not in dir(connection):
      +                log.warning(
      +                    "run_ttp_template: '{}' input, unsupported method '{}', skipping".format(
      +                        input_name, method
      +                    )
      +                )
      +                continue
      +            elif not commands:
      +                log.warning(
      +                    "run_ttp_template: '{}' input no commands to collect, skipping".format(
      +                        input_name
      +                    )
      +                )
      +                continue
      +
      +            # collect commands output from device
      +            output = [
      +                getattr(connection, method)(command_string=command, **method_kwargs)
      +                for command in commands
      +            ]
      +            output = "\n".join(output)
      +
      +            # add collected output to TTP parser object
      +            parser.add_input(
      +                data=output, input_name=input_name, template_name=template_name
      +            )
      +
      +    # run parsing in single process
      +    parser.parse(one=True)
      +
      +    return parser.result(**res_kwargs)
      +
      +
      def select_cmd_verify(func)
      @@ -1031,6 +1183,7 @@

      Index

    • m_exec_time
    • obtain_all_devices
    • obtain_netmiko_filename
    • +
    • run_ttp_template
    • select_cmd_verify
    • write_bytes
    • write_tmp_file
    • diff --git a/docs/netmiko/vyos/index.html b/docs/netmiko/vyos/index.html index 815a0eb88..ef027acb5 100644 --- a/docs/netmiko/vyos/index.html +++ b/docs/netmiko/vyos/index.html @@ -511,6 +511,7 @@

      Inherited members

    • read_until_pattern
    • read_until_prompt
    • read_until_prompt_or_pattern
    • +
    • run_ttp
    • select_delay_factor
    • send_command
    • send_command_expect
    • diff --git a/docs/netmiko/vyos/vyos_ssh.html b/docs/netmiko/vyos/vyos_ssh.html index 1e9f27cc2..b713d8eb0 100644 --- a/docs/netmiko/vyos/vyos_ssh.html +++ b/docs/netmiko/vyos/vyos_ssh.html @@ -607,6 +607,7 @@

      Inherited members

    • read_until_pattern
    • read_until_prompt
    • read_until_prompt_or_pattern
    • +
    • run_ttp
    • select_delay_factor
    • send_command
    • send_command_expect
    • diff --git a/docs/netmiko/watchguard/fireware_ssh.html b/docs/netmiko/watchguard/fireware_ssh.html index 0258b3b1e..d47c6ab4f 100644 --- a/docs/netmiko/watchguard/fireware_ssh.html +++ b/docs/netmiko/watchguard/fireware_ssh.html @@ -320,6 +320,7 @@

      Inherited members

    • read_until_pattern
    • read_until_prompt
    • read_until_prompt_or_pattern
    • +
    • run_ttp
    • select_delay_factor
    • send_command
    • send_command_expect
    • diff --git a/docs/netmiko/watchguard/index.html b/docs/netmiko/watchguard/index.html index 83594f1b2..e0e24b391 100644 --- a/docs/netmiko/watchguard/index.html +++ b/docs/netmiko/watchguard/index.html @@ -294,6 +294,7 @@

      Inherited members

    • read_until_pattern
    • read_until_prompt
    • read_until_prompt_or_pattern
    • +
    • run_ttp
    • select_delay_factor
    • send_command
    • send_command_expect
    • diff --git a/docs/netmiko/yamaha/index.html b/docs/netmiko/yamaha/index.html index de5771555..91890b3dd 100644 --- a/docs/netmiko/yamaha/index.html +++ b/docs/netmiko/yamaha/index.html @@ -219,6 +219,7 @@

      Inherited members

    • read_until_pattern
    • read_until_prompt
    • read_until_prompt_or_pattern
    • +
    • run_ttp
    • save_config
    • select_delay_factor
    • send_command
    • @@ -242,7 +243,7 @@

      Inherited members

      class YamahaTelnet -(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=5, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=False, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True) +(*args, **kwargs)

      Yamaha Telnet driver.

      @@ -381,7 +382,10 @@

      Inherited members

      class YamahaTelnet(YamahaBase):
           """Yamaha Telnet driver."""
       
      -    pass
      + def __init__(self, *args, **kwargs): + default_enter = kwargs.get("default_enter") + kwargs["default_enter"] = "\n" if default_enter is None else default_enter + super().__init__(*args, **kwargs)

      Ancestors

        @@ -415,6 +419,7 @@

        Inherited members

      • read_until_pattern
      • read_until_prompt
      • read_until_prompt_or_pattern
      • +
      • run_ttp
      • save_config
      • select_delay_factor
      • send_command
      • diff --git a/docs/netmiko/yamaha/yamaha.html b/docs/netmiko/yamaha/yamaha.html index df28b0930..5e8b974e5 100644 --- a/docs/netmiko/yamaha/yamaha.html +++ b/docs/netmiko/yamaha/yamaha.html @@ -53,7 +53,8 @@

        Module netmiko.yamaha.yamaha

        output = self.read_channel() if "(Y/N)" in output: self.write_channel("N") - output += self.read_until_prompt() + if self.base_prompt not in output: + output += self.read_until_prompt() if self.check_enable_mode(): raise ValueError("Failed to exit enable mode.") return output @@ -91,7 +92,10 @@

        Module netmiko.yamaha.yamaha

        class YamahaTelnet(YamahaBase): """Yamaha Telnet driver.""" - pass
        + def __init__(self, *args, **kwargs): + default_enter = kwargs.get("default_enter") + kwargs["default_enter"] = "\n" if default_enter is None else default_enter + super().__init__(*args, **kwargs)
      @@ -269,7 +273,8 @@

      Classes

      output = self.read_channel() if "(Y/N)" in output: self.write_channel("N") - output += self.read_until_prompt() + if self.base_prompt not in output: + output += self.read_until_prompt() if self.check_enable_mode(): raise ValueError("Failed to exit enable mode.") return output @@ -368,7 +373,8 @@

      Methods

      output = self.read_channel() if "(Y/N)" in output: self.write_channel("N") - output += self.read_until_prompt() + if self.base_prompt not in output: + output += self.read_until_prompt() if self.check_enable_mode(): raise ValueError("Failed to exit enable mode.") return output
      @@ -430,6 +436,7 @@

      Inherited members

    • read_until_pattern
    • read_until_prompt
    • read_until_prompt_or_pattern
    • +
    • run_ttp
    • select_delay_factor
    • send_command
    • send_command_expect
    • @@ -624,6 +631,7 @@

      Inherited members

    • read_until_pattern
    • read_until_prompt
    • read_until_prompt_or_pattern
    • +
    • run_ttp
    • save_config
    • select_delay_factor
    • send_command
    • @@ -647,7 +655,7 @@

      Inherited members

      class YamahaTelnet -(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=5, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=False, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True) +(*args, **kwargs)

      Yamaha Telnet driver.

      @@ -786,7 +794,10 @@

      Inherited members

      class YamahaTelnet(YamahaBase):
           """Yamaha Telnet driver."""
       
      -    pass
      + def __init__(self, *args, **kwargs): + default_enter = kwargs.get("default_enter") + kwargs["default_enter"] = "\n" if default_enter is None else default_enter + super().__init__(*args, **kwargs)

      Ancestors

        @@ -820,6 +831,7 @@

        Inherited members

      • read_until_pattern
      • read_until_prompt
      • read_until_prompt_or_pattern
      • +
      • run_ttp
      • save_config
      • select_delay_factor
      • send_command
      • diff --git a/docs/netmiko/zte/index.html b/docs/netmiko/zte/index.html index ab7170fee..9bb3e5292 100644 --- a/docs/netmiko/zte/index.html +++ b/docs/netmiko/zte/index.html @@ -218,6 +218,7 @@

        Inherited members

      • read_until_pattern
      • read_until_prompt
      • read_until_prompt_or_pattern
      • +
      • run_ttp
      • save_config
      • select_delay_factor
      • send_command
      • @@ -437,6 +438,7 @@

        Inherited members

      • read_until_pattern
      • read_until_prompt
      • read_until_prompt_or_pattern
      • +
      • run_ttp
      • save_config
      • select_delay_factor
      • send_command
      • diff --git a/docs/netmiko/zte/zte_zxros.html b/docs/netmiko/zte/zte_zxros.html index 357ce04f9..504f96f93 100644 --- a/docs/netmiko/zte/zte_zxros.html +++ b/docs/netmiko/zte/zte_zxros.html @@ -335,6 +335,7 @@

        Inherited members

      • read_until_pattern
      • read_until_prompt
      • read_until_prompt_or_pattern
      • +
      • run_ttp
      • select_delay_factor
      • send_command
      • send_command_expect
      • @@ -528,6 +529,7 @@

        Inherited members

      • read_until_pattern
      • read_until_prompt
      • read_until_prompt_or_pattern
      • +
      • run_ttp
      • save_config
      • select_delay_factor
      • send_command
      • @@ -747,6 +749,7 @@

        Inherited members

      • read_until_pattern
      • read_until_prompt
      • read_until_prompt_or_pattern
      • +
      • run_ttp
      • save_config
      • select_delay_factor
      • send_command
      • diff --git a/netmiko/__init__.py b/netmiko/__init__.py index cba949358..e426b46bc 100644 --- a/netmiko/__init__.py +++ b/netmiko/__init__.py @@ -24,7 +24,7 @@ # Alternate naming Netmiko = ConnectHandler -__version__ = "3.3.3" +__version__ = "3.4.0" __all__ = ( "ConnectHandler", "ssh_dispatcher", diff --git a/release_process.txt b/release_process.txt index 33bb9e675..c145cbb5a 100644 --- a/release_process.txt +++ b/release_process.txt @@ -9,12 +9,12 @@ $ pdoc3 --html --output-dir docs netmiko --force # README.md is entry point at https://ktbyers.github.io/netmiko/ which then links to... # https://ktbyers.github.io/netmiko/docs/netmiko/index.html for full docs -# python setup.py sdist bdist_wheel - # Make sure you have rolled the version in __init__.py # Merge into master / checkout master (use PR in GitHub for this) +# python setup.py sdist bdist_wheel + # Check FIX issues in _release.sh # Run ./_release.sh diff --git a/tests_new/test_netmiko_config.py b/tests_new/test_netmiko_config.py index 772929a82..767dffba2 100755 --- a/tests_new/test_netmiko_config.py +++ b/tests_new/test_netmiko_config.py @@ -90,9 +90,11 @@ def test_config_hostname(net_connect, commands, expected_responses): net_connect.send_config_set(command) new_hostname = net_connect.find_prompt() assert hostname in new_hostname + # Reset prompt back to original value net_connect.set_base_prompt() net_connect.send_config_set(f"hostname {current_hostname}") + net_connect.set_base_prompt() def test_config_from_file(net_connect, commands, expected_responses): @@ -122,18 +124,17 @@ def test_config_error_pattern(net_connect, commands, expected_responses): error_pattern = commands.get("error_pattern") # Should not raise an exception since error_pattern not specified - output = net_connect.send_config_set(config_commands=config_list) - print(output) + net_connect.send_config_set(config_commands=config_list) if config_list and error_pattern: with pytest.raises(ConfigInvalidException): - output = net_connect.send_config_set( + net_connect.send_config_set( config_commands=config_list, error_pattern=error_pattern ) # Try it with cmd_verify=True also with pytest.raises(ConfigInvalidException): - output = net_connect.send_config_set( + net_connect.send_config_set( config_commands=config_list, error_pattern=error_pattern, cmd_verify=True,